[
  {
    "path": ".gitignore",
    "content": "Pods/\nDerivedData/\nProducts/\nPodfile.lock\nout/\nxcschememanagement.plist\nxcshareddata/\n*.xcscmblueprint\nxcuserdata/\nPodfile_cp\n.DS_S*\n.DS_Store\nnode_modules\n"
  },
  {
    "path": "Android/AntFluid/.gitignore",
    "content": "*.iml\n.gradle\n/local.properties\n/.idea/caches\n/.idea/libraries\n/.idea/modules.xml\n/.idea/workspace.xml\n/.idea/navEditor.xml\n/.idea/assetWizardSettings.xml\n/.idea/*\n.DS_Store\n/build\n/captures\n.externalNativeBuild\n.cxx\nlocal.properties\n"
  },
  {
    "path": "Android/AntFluid/app-sample/.gitignore",
    "content": "/build"
  },
  {
    "path": "Android/AntFluid/app-sample/build.gradle",
    "content": "plugins {\n    alias(libs.plugins.android.application)\n    alias(libs.plugins.kotlin.android)\n    alias(libs.plugins.kotlin.compose)\n}\n\nandroid {\n    namespace 'com.fluid.afm'\n    compileSdk 35\n\n    defaultConfig {\n        applicationId \"com.fluid.afm\"\n        minSdk 21\n        targetSdk 35\n        versionCode 1\n        versionName \"1.0\"\n\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n    }\n\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n        }\n    }\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_11\n        targetCompatibility JavaVersion.VERSION_11\n    }\n    kotlinOptions {\n        jvmTarget = '11'\n    }\n}\n\ndependencies {\n    implementation libs.androidx.appcompat\n    implementation libs.androidx.core.ktx\n    implementation libs.androidx.lifecycle.runtime.ktx\n    implementation libs.androidx.activity.compose\n    implementation platform(libs.androidx.compose.bom)\n    implementation libs.androidx.ui\n    implementation libs.androidx.ui.graphics\n    implementation libs.androidx.ui.tooling.preview\n    implementation libs.androidx.material3\n    api project(':fluid-markdown')\n    implementation libs.material\n    implementation libs.androidx.activity\n    implementation libs.androidx.constraintlayout\n    testImplementation libs.junit\n    androidTestImplementation libs.androidx.junit\n    androidTestImplementation libs.androidx.espresso.core\n    androidTestImplementation platform(libs.androidx.compose.bom)\n    androidTestImplementation libs.androidx.ui.test.junit4\n    debugImplementation libs.androidx.ui.tooling\n    debugImplementation libs.androidx.ui.test.manifest\n    implementation 'com.github.bumptech.glide:glide:5.0.4'\n\n}"
  },
  {
    "path": "Android/AntFluid/app-sample/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile"
  },
  {
    "path": "Android/AntFluid/app-sample/src/androidTest/java/com/fluid/markdown/ExampleInstrumentedTest.kt",
    "content": "package com.fluid.markdown\n\nimport androidx.test.ext.junit.runners.AndroidJUnit4\nimport androidx.test.platform.app.InstrumentationRegistry\nimport org.junit.Assert.assertEquals\nimport org.junit.Test\nimport org.junit.runner.RunWith\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * See [testing documentation](http://d.android.com/tools/testing).\n */\n@RunWith(AndroidJUnit4::class)\nclass ExampleInstrumentedTest {\n    @Test\n    fun useAppContext() {\n        // Context of the app under test.\n        val appContext = InstrumentationRegistry.getInstrumentation().targetContext\n        assertEquals(\"com.fluid.afm\", appContext.packageName)\n    }\n}"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\">\n\n    <application\n        android:allowBackup=\"true\"\n        android:dataExtractionRules=\"@xml/data_extraction_rules\"\n        android:fullBackupContent=\"@xml/backup_rules\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/Theme.AntFluidMarkdown\"\n        tools:targetApi=\"31\">\n        <activity\n            android:name=\"com.fluid.markdown.demos.ListActivity\"\n            android:exported=\"false\" />\n        <activity\n            android:name=\"com.fluid.markdown.demos.PrinterActivity\"\n            android:theme=\"@style/Theme.AntFluidMarkdown\" />\n        <activity\n            android:name=\"com.fluid.markdown.MainActivity\"\n            android:exported=\"true\"\n            android:label=\"@string/app_name\"\n            android:theme=\"@style/Theme.AntFluidMarkdown\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/java/com/fluid/markdown/MainActivity.kt",
    "content": "package com.fluid.markdown\n\nimport android.content.Intent\nimport android.os.Bundle\nimport android.util.Log\nimport android.view.View\nimport android.widget.Toast\nimport androidx.appcompat.app.AppCompatActivity\nimport androidx.core.widget.NestedScrollView\nimport com.fluid.afm.AFMInitializer\nimport com.fluid.afm.R\nimport com.fluid.afm.markdown.ElementClickEventCallback\nimport com.fluid.afm.markdown.html.SpanTextClickableSpan.ClickableTextType\nimport com.fluid.afm.markdown.model.EventModel\nimport com.fluid.afm.markdown.widget.PrinterMarkDownTextView\nimport com.fluid.afm.styles.MarkdownStyles\nimport com.fluid.afm.styles.TitleStyle\nimport com.fluid.markdown.demos.ListActivity\nimport com.fluid.markdown.demos.PrinterActivity\n\n\nclass MainActivity : AppCompatActivity() {\n    companion object {\n        @JvmStatic\n        var initialed = false\n    }\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        setContentView(R.layout.layout_main)\n        val markdown = resources.getString(R.string.toPrinter) + resources.getString(R.string.toList) + resources.getString(R.string.sample)\n\n        val markdownTextView = findViewById<PrinterMarkDownTextView>(R.id.textView)\n        if (!initialed) {\n            initialed = true\n            AFMInitializer.init(this, null, MyImageHandler(), null)\n        }\n        val styles =  MarkdownStyles.getDefaultStyles()\n        styles.linkStyle().icon(\"local://mipmap/link\")\n        styles.setTitleStyle(0, TitleStyle.create(1.5f).icon(\"local://mipmap/title\"))\n        markdownTextView.init(styles, object : ElementClickEventCallback {\n                override fun onLinkClicked(params: Map<String?, Any?>?): Boolean {\n                    val url = params?.get(ElementClickEventCallback.PARAM_KEY_LINK) as String?\n                    if(url.equals(\"open://printer\")) {\n                        startActivity(Intent(this@MainActivity, PrinterActivity::class.java))\n                        return true\n                    } else if (url.equals(\"open://list_printer\")) {\n                        startActivity(Intent(this@MainActivity, ListActivity::class.java))\n                        return true\n                    }\n                    Toast.makeText(this@MainActivity, \"link click$url\", Toast.LENGTH_SHORT).show()\n                    return false\n                }\n\n                override fun onFootnoteClicked(index: String) {\n                    Toast.makeText(this@MainActivity, \"footnote click$index\", Toast.LENGTH_SHORT).show()\n\n                }\n\n                override fun onImageClicked(url: String?, description: String?) {\n                    Toast.makeText(this@MainActivity, \"onImageClicked click-$description\", Toast.LENGTH_SHORT).show()\n                }\n\n                override fun onTextClickableSpanClicked(\n                    widget: View?,\n                    link: String?,\n                    entityID: String?,\n                    type: ClickableTextType?\n                ): Boolean {\n                    Toast.makeText(this@MainActivity, \"clickable click link$link type$type entityID$entityID\", Toast.LENGTH_SHORT).show()\n                    return false\n                }\n\n                override fun exposureSpmBehavior(models: MutableList<EventModel>?) {\n                    Log.d(\"exposureSpmBehavior\", models.toString())\n                }\n            }\n        )\n\n        markdownTextView.setMarkdownText(markdown)\n        val scroller = findViewById<NestedScrollView>(R.id.scrollView)\n\n        scroller.setOnScrollChangeListener(object : NestedScrollView.OnScrollChangeListener {\n            override fun onScrollChange(\n                v: NestedScrollView,\n                scrollX: Int,\n                scrollY: Int,\n                oldScrollX: Int,\n                oldScrollY: Int\n            ) {\n                markdownTextView.handleExposureSpm()\n            }\n\n        })\n    }\n}"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/java/com/fluid/markdown/MyImageHandler.java",
    "content": "package com.fluid.markdown;\n\nimport android.content.Context;\nimport android.graphics.Bitmap;\nimport android.graphics.drawable.BitmapDrawable;\nimport android.graphics.drawable.Drawable;\nimport android.net.Uri;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.core.content.res.ResourcesCompat;\n\nimport com.bumptech.glide.Glide;\nimport com.bumptech.glide.request.RequestOptions;\nimport com.bumptech.glide.request.target.SimpleTarget;\nimport com.bumptech.glide.request.transition.Transition;\nimport com.fluid.afm.handler.ImageHandler;\n\nimport com.fluid.afm.ContextHolder;\nimport com.fluid.afm.utils.Utils;\nimport com.fluid.afm.func.Callback;\n\npublic class MyImageHandler implements ImageHandler {\n    @Override\n    public void loadImage(Context context, String url, Callback<Drawable> callback) {\n        if (url.startsWith(\"local://\")) {\n            Drawable drawable = loadDrawableResource(context, url, 0, 0);\n            if (drawable != null) {\n                callback.onSuccess(drawable);\n            }\n            return;\n        }\n        int defaultW = context.getResources().getDisplayMetrics().widthPixels - Utils.dpToPx(context, 24);\n        Glide.with(context).load(url).apply(new RequestOptions().override(defaultW)).into(new SimpleTarget<Drawable>() {\n            @Override\n            public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {\n                callback.onSuccess(resource);\n            }\n        });\n    }\n\n    private static Drawable loadDrawableResource(Context context, String url, int width, int height) {\n        Uri uri = Uri.parse(url);\n        String host = uri.getHost();\n        String path = uri.getPathSegments().get(0);\n        int resourceId = getResourceIdByName(context.getPackageName(), host, path);\n        if (resourceId != 0) {\n            Drawable drawable = ResourcesCompat.getDrawable(context.getResources(), resourceId, null);\n            if (drawable instanceof BitmapDrawable\n                    && width > 0 && height > 0\n                    && (((BitmapDrawable) drawable).getBitmap().getWidth() != width ||((BitmapDrawable) drawable).getBitmap().getHeight() != height)) {\n            Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();\n                    int imgWidth = bitmap.getWidth();\n                    int imgHeight = bitmap.getHeight();\n                    float scale = Math.max((float) height / imgHeight, (float) width / imgWidth);\n                    int newWidth = Math.round(imgWidth * scale);\n                    int newHeight = Math.round(imgHeight * scale);\n                    Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);\n                    int xCrop = (newWidth - width) / 2;\n                    int yCrop = (newHeight - height) / 2;\n                    bitmap = Bitmap.createBitmap(scaledBitmap, xCrop, yCrop, width, height);\n                return new BitmapDrawable(ContextHolder.getContext().getResources(), bitmap);\n            }\n            return drawable;\n        }\n        return null;\n    }\n    private static int getResourceIdByName(String packageName, String className, String name) {\n\n        Class<?> r;\n        int id = 0;\n        try {\n            r = Class.forName(packageName + \".R\");\n            Class<?>[] classes = r.getClasses();\n            Class<?> desireClass = null;\n            for (int i = 0; i < classes.length; i++) {\n                if (classes[i].getName().split(\"\\\\$\")[1].equals(className)) {\n                    desireClass = classes[i];\n                    break;\n                }\n            }\n            if (desireClass != null) id = desireClass.getField(name).getInt(desireClass);\n        } catch (ClassNotFoundException | IllegalAccessException | NoSuchFieldException | SecurityException | IllegalArgumentException e) {\n            e.printStackTrace();\n        }\n        return id;\n    }\n\n    @Override\n    public void loadImage(Context context, String url, int width, int height, Callback<Drawable> callback) {\n        if (url.startsWith(\"local://\")) {\n            Drawable drawable = loadDrawableResource(context, url, width, height);\n            if (drawable != null) {\n                callback.onSuccess(drawable);\n            }\n            return;\n        }\n        Glide.with(context).load(url).apply(new RequestOptions().override(width, height)).into(new SimpleTarget<Drawable>() {\n            @Override\n            public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {\n                callback.onSuccess(resource);\n            }\n        });\n    }\n\n    @Override\n    public Drawable loadImageSync(Context context, String url) {\n        if (url.startsWith(\"local://\")) {\n            return loadDrawableResource(context, url, 0, 0);\n        }\n        int defaultW = context.getResources().getDisplayMetrics().widthPixels - Utils.dpToPx(context, 24);\n        try {\n            return Glide.with(context).asDrawable().load(url).into(defaultW, defaultW).get();\n        } catch (Throwable e) {\n        }\n        return null;\n    }\n\n    @Override\n    public Drawable loadImageSync(Context context, String url, int width, int height) {\n        if (url.startsWith(\"local://\")) {\n            return loadDrawableResource(context, url, width, height);\n        }\n        try {\n            return Glide.with(context).asDrawable().load(url).into(width,  height).get();\n        } catch (Throwable e) {\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/java/com/fluid/markdown/demos/ListActivity.java",
    "content": "package com.fluid.markdown.demos;\n\nimport android.os.Bundle;\n\nimport androidx.annotation.Nullable;\nimport androidx.appcompat.app.AppCompatActivity;\nimport androidx.recyclerview.widget.LinearLayoutManager;\nimport androidx.recyclerview.widget.RecyclerView;\n\nimport com.fluid.afm.R;\n\n\npublic class ListActivity extends AppCompatActivity {\n\n\n    @Override\n    protected void onCreate(@Nullable Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_list);\n        String sampleString = getString(R.string.sample);\n        MarkwonListAdapter adapter = new MarkwonListAdapter();\n        findViewById(R.id.add).setOnClickListener(v -> {\n            adapter.addData(new MarkdownData(sampleString));\n        });\n        findViewById(R.id.back).setOnClickListener(v -> {\n            onBackPressed();\n        });\n        RecyclerView recyclerView = findViewById(R.id.recycler);\n        recyclerView.setLayoutManager(new LinearLayoutManager( this, LinearLayoutManager.VERTICAL, false){{setStackFromEnd(true);}});\n        recyclerView.setAdapter(adapter);\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/java/com/fluid/markdown/demos/MarkdownData.java",
    "content": "package com.fluid.markdown.demos;\n\nimport com.fluid.afm.markdown.widget.PrinterMarkDownTextView;\n\npublic class MarkdownData {\n    public String content;\n    public PrinterMarkDownTextView.MarkDownPrintData printData;\n\n    public MarkdownData(String content) {\n        this.content = content;\n        printData = new PrinterMarkDownTextView.MarkDownPrintData();\n    }\n\n}\n"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/java/com/fluid/markdown/demos/MarkdownHolder.java",
    "content": "package com.fluid.markdown.demos;\n\nimport android.view.View;\n\nimport androidx.annotation.NonNull;\nimport androidx.recyclerview.widget.RecyclerView;\n\nimport com.fluid.afm.R;\nimport com.fluid.afm.markdown.MarkdownParserFactory;\nimport com.fluid.afm.markdown.widget.PrinterMarkDownTextView;\nimport com.fluid.afm.styles.MarkdownStyles;\n\npublic class MarkdownHolder extends RecyclerView.ViewHolder {\n    private final PrinterMarkDownTextView mMarkdownTextView;\n\n    public MarkdownHolder(@NonNull View itemView) {\n        super(itemView);\n        mMarkdownTextView = itemView.findViewById(R.id.markdown);\n        MarkdownStyles styles =  MarkdownStyles.getDefaultStyles();\n        styles.linkStyle().icon(\"local://mipmap/link\");\n        mMarkdownTextView.init(styles, null);\n    }\n\n    public void bind(MarkdownData markdownData) {\n        if (!markdownData.printData.hasBoundView) {\n            mMarkdownTextView.setPrintData(markdownData.printData);\n            mMarkdownTextView.startPrinting(markdownData.content);\n        } else {\n            mMarkdownTextView.restore(markdownData.printData);\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/java/com/fluid/markdown/demos/MarkwonListAdapter.java",
    "content": "package com.fluid.markdown.demos;\n\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\n\nimport androidx.annotation.NonNull;\nimport androidx.recyclerview.widget.RecyclerView;\n\nimport com.fluid.afm.R;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class MarkwonListAdapter extends RecyclerView.Adapter<MarkdownHolder>{\n    private final List<MarkdownData> mData = new ArrayList<>();\n\n    @NonNull\n    @Override\n    public MarkdownHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {\n        View contentView = LayoutInflater.from(parent.getContext())\n                .inflate(R.layout.list_item, parent, false);\n        return new MarkdownHolder(contentView);\n    }\n\n    @Override\n    public int getItemCount() {\n        return mData.size();\n    }\n\n    @Override\n    public void onBindViewHolder(@NonNull MarkdownHolder holder, int position) {\n        holder.bind(mData.get(position));\n    }\n\n    public void addData(MarkdownData markdownData) {\n        mData.add(markdownData);\n        notifyItemInserted(mData.size() - 1);\n        notifyItemChanged(mData.size() - 1, mData.size());\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/java/com/fluid/markdown/demos/PrinterActivity.java",
    "content": "package com.fluid.markdown.demos;\n\nimport android.os.Bundle;\nimport android.view.ViewGroup;\nimport android.widget.EditText;\n\nimport androidx.annotation.NonNull;\nimport androidx.appcompat.app.AppCompatActivity;\nimport androidx.appcompat.widget.SwitchCompat;\nimport androidx.recyclerview.widget.LinearLayoutManager;\nimport androidx.recyclerview.widget.RecyclerView;\n\nimport com.fluid.afm.R;\nimport com.fluid.afm.markdown.MarkdownParser;\nimport com.fluid.afm.markdown.MarkdownParserFactory;\nimport com.fluid.afm.markdown.widget.PrinterMarkDownTextView;\nimport com.fluid.afm.styles.MarkdownStyles;\n\npublic class PrinterActivity extends AppCompatActivity {\n\n    private EditText mEditText;\n    private boolean isAppend;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_printer);\n        findViewById(R.id.back).setOnClickListener(v -> onBackPressed());\n        mEditText = findViewById(R.id.editor);\n        RecyclerView recyclerView = findViewById(R.id.recyclerView);\n        LinearLayoutManager linearLayoutManager = new LinearLayoutManager( this, LinearLayoutManager.VERTICAL, false);\n        recyclerView.setLayoutManager(linearLayoutManager);\n        PrinterMarkDownTextView markDownTextView = new PrinterMarkDownTextView(this);\n        linearLayoutManager.setStackFromEnd(true);\n        recyclerView.setAdapter(new RecyclerView.Adapter() {\n            @NonNull\n            @Override\n            public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {\n                return new RecyclerView.ViewHolder(markDownTextView) {};\n            }\n\n            @Override\n            public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {\n\n            }\n\n            @Override\n            public int getItemCount() {\n                return 1;\n            }\n        });\n\n        markDownTextView.init(MarkdownStyles.getDefaultStyles(), null);\n        markDownTextView.setPrintParams(25, 1);\n\n        findViewById(R.id.start).setOnClickListener(v -> {\n            String content = mEditText.getText().toString();\n            if (!content.isEmpty()) {\n                markDownTextView.startPrinting(content);\n            }\n        });\n        SwitchCompat appendSwitch = findViewById(R.id.appendSwitch);\n        isAppend = appendSwitch.isChecked();\n        appendSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {\n            isAppend = isChecked;\n        });\n        findViewById(R.id.append).setOnClickListener(v -> {\n            String content = mEditText.getText().toString();\n            if (!content.isEmpty()) {\n                markDownTextView.appendPrinting(content, isAppend);\n            }\n        });\n\n        findViewById(R.id.stop).setOnClickListener(v -> {\n            markDownTextView.stopPrinting(getResources().getString(R.string.stopped));\n        });\n        findViewById(R.id.clear).setOnClickListener(v -> {\n            mEditText.setText(\"\");\n        });\n\n        findViewById(R.id.pause).setOnClickListener(v -> {\n            markDownTextView.pause();\n        });\n\n        findViewById(R.id.resume).setOnClickListener(v -> {\n            markDownTextView.resume();\n        });\n\n    }\n}"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/res/drawable/baseline_arrow_back_24.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\" android:autoMirrored=\"true\" android:height=\"24dp\" android:tint=\"#FFFFFF\" android:viewportHeight=\"24\" android:viewportWidth=\"24\" android:width=\"24dp\">\n      \n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z\"/>\n    \n</vector>\n"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/res/drawable/circle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\" android:shape=\"oval\" >\n    <solid android:color=\"#1677FF\" />\n\n</shape>"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/res/drawable/editor_bg.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <stroke\n        android:width=\"1dp\"\n        android:color=\"#CCC\" />\n    <corners android:radius=\"18dp\"/>\n\n</shape>"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportWidth=\"108\"\n    android:viewportHeight=\"108\">\n    <path\n        android:fillColor=\"#3DDC84\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n</vector>\n"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/res/drawable/item_bg.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <solid android:color=\"#FFFFFF\" />\n    <corners android:radius=\"10dp\" />\n    <stroke\n        android:width=\"2dp\"\n        android:color=\"#E0E0E0\" />\n</shape>"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportWidth=\"108\"\n    android:viewportHeight=\"108\">\n    <path android:pathData=\"M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"85.84757\"\n                android:endY=\"92.4963\"\n                android:startX=\"42.9492\"\n                android:startY=\"49.59793\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        android:pathData=\"M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#00000000\" />\n</vector>"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/res/layout/activity_list.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:id=\"@+id/main\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\"\n    android:background=\"#F5F5F5\"\n    tools:context=\"com.fluid.markdown.demos.ListActivity\">\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"50dp\"\n        android:background=\"@color/colorPrimary\"\n        android:gravity=\"center_vertical\"\n        android:orientation=\"horizontal\">\n\n        <ImageView\n            android:id=\"@+id/back\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginStart=\"12dp\"\n            android:background=\"@drawable/baseline_arrow_back_24\"\n            android:importantForAccessibility=\"no\" />\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginStart=\"12dp\"\n            android:gravity=\"center_vertical\"\n            android:text=\"@string/list\"\n            android:textColor=\"@color/white\"\n            android:textSize=\"20sp\"\n            android:textStyle=\"bold\" />\n    </LinearLayout>\n\n    <Button\n        android:id=\"@+id/add\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:background=\"#1677FF\"\n        android:layout_margin=\"2dp\"\n        android:textColor=\"@color/white\"\n        android:text=\"@string/add\"/>\n    <androidx.recyclerview.widget.RecyclerView\n        android:id=\"@+id/recycler\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:clipToPadding=\"false\"\n        android:padding=\"12dp\"\n        android:stackFromBottom=\"true\" />\n\n</LinearLayout>"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/res/layout/activity_printer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:fitsSystemWindows=\"true\"\n    android:orientation=\"vertical\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"50dp\"\n        android:background=\"@color/colorPrimary\"\n        android:gravity=\"center_vertical\"\n        android:orientation=\"horizontal\">\n\n        <ImageView\n            android:id=\"@+id/back\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginStart=\"12dp\"\n            android:background=\"@drawable/baseline_arrow_back_24\"\n            android:importantForAccessibility=\"no\" />\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginStart=\"12dp\"\n            android:gravity=\"center_vertical\"\n            android:text=\"@string/printer\"\n            android:textColor=\"@color/white\"\n            android:textSize=\"20sp\"\n            android:textStyle=\"bold\" />\n\n    </LinearLayout>\n\n    <androidx.constraintlayout.widget.ConstraintLayout\n        android:id=\"@+id/main\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        tools:context=\"com.fluid.markdown.demos.PrinterActivity\">\n\n        <Button\n            android:id=\"@+id/clear\"\n            android:layout_width=\"25dp\"\n            android:layout_height=\"25dp\"\n            android:layout_margin=\"12dp\"\n            android:layout_marginTop=\"12dp\"\n            android:background=\"@drawable/circle\"\n            android:text=\"@string/delete\"\n            android:textColor=\"@color/white\"\n            android:textSize=\"16sp\"\n            app:layout_constraintBottom_toBottomOf=\"@+id/editorContainer\"\n            app:layout_constraintEnd_toEndOf=\"@+id/editorContainer\" />\n\n        <ScrollView\n            android:id=\"@+id/editorContainer\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"150dp\"\n            android:layout_margin=\"12dp\"\n            android:background=\"@drawable/editor_bg\"\n            android:clipToPadding=\"false\"\n            android:gravity=\"start|top\"\n            android:padding=\"12dp\"\n            android:textSize=\"15sp\"\n            app:layout_constraintEnd_toEndOf=\"parent\"\n            app:layout_constraintStart_toStartOf=\"parent\"\n            app:layout_constraintTop_toTopOf=\"parent\">\n\n            <EditText\n                android:id=\"@+id/editor\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:background=\"#0000\"\n                android:gravity=\"start|top\"\n                android:hint=\"@string/input_markdown_text\"\n                android:minHeight=\"126dp\"\n                android:textColorHint=\"#bbb\"\n                android:textSize=\"15sp\" />\n        </ScrollView>\n\n        <TextView\n            android:id=\"@+id/start\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginTop=\"12dp\"\n            android:background=\"#1677FF\"\n            android:gravity=\"center\"\n            android:minWidth=\"70dp\"\n            android:padding=\"12dp\"\n            android:text=\"@string/start\"\n            android:textColor=\"@color/white\"\n            app:layout_constraintStart_toStartOf=\"parent\"\n            app:layout_constraintTop_toBottomOf=\"@+id/editorContainer\"\n            app:layout_constraintEnd_toStartOf=\"@+id/stop\"/>\n        <TextView\n            android:id=\"@+id/stop\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:background=\"#1677FF\"\n            android:gravity=\"center\"\n            android:minWidth=\"70dp\"\n            android:padding=\"12dp\"\n            android:text=\"@string/stop\"\n            android:textColor=\"@color/white\"\n            app:layout_constraintStart_toEndOf=\"@+id/start\"\n            app:layout_constraintEnd_toStartOf=\"@+id/append\"\n            app:layout_constraintTop_toTopOf=\"@+id/start\" />\n\n\n        <TextView\n            android:id=\"@+id/append\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:background=\"#1677FF\"\n            android:padding=\"12dp\"\n            android:text=\"@string/appendText\"\n            android:textColor=\"@color/white\"\n            app:layout_constraintEnd_toStartOf=\"@+id/appendSwitch\"\n            app:layout_constraintStart_toEndOf=\"@+id/stop\"\n            app:layout_constraintTop_toTopOf=\"@+id/start\" />\n\n        <androidx.appcompat.widget.SwitchCompat\n            android:id=\"@+id/appendSwitch\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:text=\"@string/append\"\n            app:layout_constraintBottom_toBottomOf=\"@+id/stop\"\n            app:layout_constraintEnd_toEndOf=\"parent\"\n            app:layout_constraintStart_toEndOf=\"@+id/append\"\n            app:layout_constraintTop_toTopOf=\"@+id/append\" />\n\n        <TextView\n            android:id=\"@+id/pause\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:background=\"#1677FF\"\n            android:padding=\"12dp\"\n            android:minWidth=\"70dp\"\n            android:gravity=\"center\"\n            android:text=\"@string/pause\"\n            android:textColor=\"@color/white\"\n            android:layout_marginTop=\"12dp\"\n            app:layout_constraintStart_toStartOf=\"@+id/start\"\n            app:layout_constraintTop_toBottomOf=\"@id/start\" />\n\n        <TextView\n            android:id=\"@+id/resume\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:background=\"#1677FF\"\n            android:gravity=\"center\"\n            android:minWidth=\"70dp\"\n            android:padding=\"12dp\"\n            android:text=\"@string/resume\"\n            android:textColor=\"@color/white\"\n            app:layout_constraintStart_toStartOf=\"@+id/stop\"\n            app:layout_constraintTop_toTopOf=\"@id/pause\" />\n\n\n    </androidx.constraintlayout.widget.ConstraintLayout>\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:id=\"@+id/recyclerView\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:clipToPadding=\"false\"\n        android:padding=\"12dp\"\n        android:stackFromBottom=\"true\" />\n</LinearLayout>"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/res/layout/layout_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:fitsSystemWindows=\"true\"\n    android:orientation=\"vertical\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"50dp\"\n        android:background=\"@color/colorPrimary\"\n        android:orientation=\"vertical\">\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"0dp\"\n            android:gravity=\"center_vertical\"\n            android:layout_marginStart=\"12dp\"\n            android:layout_weight=\"1\"\n            android:text=\"@string/demo\"\n            android:textColor=\"@color/white\"\n            android:textSize=\"20sp\"\n            android:textStyle=\"bold\" />\n\n        <View\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"1dp\"\n            android:background=\"#ccc\" />\n    </LinearLayout>\n\n    <androidx.core.widget.NestedScrollView\n        android:id=\"@+id/scrollView\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:layout_weight=\"1\"\n        android:background=\"@color/white\">\n\n        <com.fluid.afm.markdown.widget.PrinterMarkDownTextView\n            android:id=\"@+id/textView\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_margin=\"12dp\" />\n\n    </androidx.core.widget.NestedScrollView>\n\n</LinearLayout>\n"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/res/layout/list_item.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:background=\"@drawable/item_bg\"\n    android:padding=\"12dp\"\n    android:layout_marginBottom=\"12dp\">\n\n    <com.fluid.afm.markdown.widget.PrinterMarkDownTextView\n        android:id=\"@+id/markdown\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"/>\n\n</FrameLayout>"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n    <monochrome android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n    <monochrome android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"purple_200\">#FFBB86FC</color>\n    <color name=\"purple_500\">#FF6200EE</color>\n    <color name=\"purple_700\">#FF3700B3</color>\n    <color name=\"teal_200\">#FF03DAC5</color>\n    <color name=\"teal_700\">#FF018786</color>\n    <color name=\"black\">#FF000000</color>\n    <color name=\"white\">#FFFFFFFF</color>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF018786</color>\n</resources>"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">AntFluidMarkdown</string>\n    <string name=\"printer\">Printer</string>\n    <string name=\"start\">start</string>\n    <string name=\"appendText\">append text</string>\n    <string name=\"stop\">stop</string>\n    <string name=\"delete\">×</string>\n    <string name=\"append\">append:</string>\n    <string name=\"demo\">Demo</string>\n    <string name=\"input_markdown_text\">input markdown text</string>\n    <string name=\"resume\">resume</string>\n    <string name=\"pause\">pause</string>\n    <string name=\"toPrinter\"><![CDATA[ <br/><iconlink link=\"open://printer\" src=\"local://mipmap/link\" style=\"color:#1296DB;font-size:26px\">Stream print demo</iconlink>\\n\\n ]]></string>\n    <string name=\"toList\"><![CDATA[ <iconlink link=\"open://list_printer\" src=\"local://mipmap/link\" style=\"color:#1296DB;font-size:26px\">List stream print demo</iconlink>\\n\\n ]]></string>\n\n    <string name=\"sample\"><![CDATA[# h1 Heading\\nThis is normal text. This is normal text. This is normal text. This is normal text. This is normal text. This is normal text. This is normal text. This is normal text. \\n\\n## h2 Heading\\n### h3 Heading\\n#### h4 Heading\\n##### h5 Heading\\n###### h6 Heading\\n**This is bold text**\\n*This is italic text*  \\n***This is bold and italic text***  \\n~~Strikethrough~~  \\n\\n---\\n\\n### Lists\\n- Unordered 1 level:0\\n- Unordered 2 level:0\\n\\t- Unordered 1 level:1\\n\\t- Unordered 2 level:1\\n1. Ordered 1 level:0\\n2. Ordered 2 level:0\\n\\t1. Ordered 1 level:1\\n\\t2. Ordered 2 level:1\\n    3. Ordered 2 level:1\\n\\n---\\n\\n### Blockquotes\\n> This is blockquotes\\n> Blockquotes can also be nested…\\n> **bold tex in blockquotes**\\n> Dorothy followed her through many of the beautiful rooms in her castle.\\n>> The Witch bade her clean the pots and kettles and sweep the floor and keep the fire fed with wood.\\n\\n---\\n\\n### Links & Images\\n[link text](https://www.example.com)  \\n\\n![image description1](https://gw.alipayobjects.com/zos/bmw-prod/4c49eb9a-88c1-4bd2-afa3-d3054331e983/kvgaht9k_w849_h375.png) \\n\\n![image description2](https://gw.alipayobjects.com/zos/bmw-prod/79ea98f0-303b-4816-ba27-5638a04ca353/kvgahl7g_w849_h375.png)\\n\\n---\\n\\n### Table\\n| header1 | header2 | header3 |\\n|-------|-------|-------|\\n| content1 | content2 | content3 |\\n| content4 | content5 | content6 |\\n\\n---\\n\\n### Code\\n`inline code`\\n\\n```python\\n# Code block\\ndef hello_world():\\n    print(\"Hello, World!\")\\n```\\n\\n---\\n\\n### Horizontal Rules\\n\\n---\\n\\n### Footnotes\\nthis is a footnote[^1][^2].\\n。\\n\\n---\\n\\n### HTML\\n<a href=\\\"https://www.example.com\\\" style=\\\"color: blue;text-decoration: underline;\\\"> This is a tag. </a><u>this is underline</u>\\n]]></string>\n    <string name=\"stopped\">(stopped)</string>\n    <string name=\"list\">List</string>\n    <string name=\"add\">add item</string>\n\n</resources>"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/res/values/themes.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <style name=\"Theme.AntFluidMarkdown\" parent=\"Theme.AppCompat.Light.NoActionBar\">\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/res/values-v35/themes.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <style name=\"Theme.AntFluidMarkdown\" parent=\"Theme.AppCompat.Light.NoActionBar\">\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n        <item name=\"android:windowOptOutEdgeToEdgeEnforcement\">true</item>\n    </style>\n\n</resources>"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/res/values-zh/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">AntFluidMarkdown</string>\n    <string name=\"printer\">Printer</string>\n    <string name=\"start\">开始</string>\n    <string name=\"appendText\">追加文字</string>\n    <string name=\"stop\">停止</string>\n    <string name=\"delete\">×</string>\n    <string name=\"append\">append:</string>\n    <string name=\"demo\">Demo</string>\n    <string name=\"input_markdown_text\">输入markdown原文</string>\n    <string name=\"resume\">继续</string>\n    <string name=\"pause\">暂停</string>\n    <string name=\"toPrinter\"><![CDATA[ <br/><iconlink link=\"open://printer\" src=\"local://mipmap/link\" style=\"color:#1296DB;font-size:26px\">流式打印Demo</iconlink>\\n\\n ]]></string>\n    <string name=\"toList\"><![CDATA[ <iconlink link=\"open://list_printer\" src=\"local://mipmap/link\" style=\"color:#1296DB;font-size:26px\">流式打印列表demo</iconlink>\\n\\n ]]></string>\n    <string name=\"sample\"><![CDATA[# 一级标题\\n我是正文我是正文我是正文我是正文我是正文我是正文我是正文我是正文我是正文我是正文我是正文我是正文我是正文我是正文我是正文我是正文我是正文我是正文我是正文我是正文\\n\\n## 二级标题\\n### 三级标题\\n#### 四级标题\\n##### 五级标题\\n###### 六级标题\\n**加粗文本**\\n*斜体文本*  \\n***加粗斜体文本***  \\n~~删除线文本~~  \\n\\n---\\n\\n### 列表\\n- 无序列表项1\\n- 无序列表项2\\n\\t- 子列表项1\\n\\t- 子列表项2\\n1. 有序列表项1\\n2. 有序列表项2\\n\\t1. 子列表项1\\n\\t2. 子列表项2\\n\\t3. 子列表项3\\n\\n---\\n\\n### 引用\\n> 引用内容\\n> 多行引用内容\\n> 引用中**加粗文本**\\n> Dorothy followed her through many of the beautiful rooms in her castle.\\n>> The Witch bade her clean the pots and kettles and sweep the floor and keep the fire fed with wood.\\n\\n---\\n\\n### 链接与图片\\n[这是一个链接](https://www.example.com)  \\n\\n![图片描述1](https://gw.alipayobjects.com/zos/bmw-prod/4c49eb9a-88c1-4bd2-afa3-d3054331e983/kvgaht9k_w849_h375.png) \\n\\n![图片描述2](https://gw.alipayobjects.com/zos/bmw-prod/79ea98f0-303b-4816-ba27-5638a04ca353/kvgahl7g_w849_h375.png)\\n\\n---\\n\\n### 表格\\n| 表头1 | 表头2 | 表头3 |\\n|-------|-------|-------|\\n| 内容1 | 内容2 | 内容3 |\\n| 内容4 | 内容5 | 内容6 |\\n\\n---\\n\\n### 代码\\n行内代码：`inline code`\\n\\n```python\\n# 代码块\\ndef hello_world():\\n    print(\\\"Hello, World!\\\")\\n```\\n\\n---\\n\\n### 分隔线\\n\\n---\\n\\n### 脚注\\n这是一个脚注示例[^1][^2].\\n。\\n\\n---\\n\\n### 内嵌HTML\\n<a href=\\\"https://www.example.com\\\" style=\\\"color: blue;text-decoration: underline;\\\"> 我是一个a标签。</a><u>我是下划线</u>]]></string>\n    <string name=\"stopped\">（已终止）</string>\n    <string name=\"list\">多markdown列表</string>\n    <string name=\"add\">添加数据</string>\n\n\n</resources>"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/res/xml/backup_rules.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n   Sample backup rules file; uncomment and customize as necessary.\n   See https://developer.android.com/guide/topics/data/autobackup\n   for details.\n   Note: This file is ignored for devices older than API 31\n   See https://developer.android.com/about/versions/12/backup-restore\n-->\n<full-backup-content>\n    <!--\n   <include domain=\"sharedpref\" path=\".\"/>\n   <exclude domain=\"sharedpref\" path=\"device.xml\"/>\n-->\n</full-backup-content>"
  },
  {
    "path": "Android/AntFluid/app-sample/src/main/res/xml/data_extraction_rules.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n   Sample data extraction rules file; uncomment and customize as necessary.\n   See https://developer.android.com/about/versions/12/backup-restore#xml-changes\n   for details.\n-->\n<data-extraction-rules>\n    <cloud-backup>\n    </cloud-backup>\n</data-extraction-rules>"
  },
  {
    "path": "Android/AntFluid/app-sample/src/test/java/com/fluid/markdown/ExampleUnitTest.kt",
    "content": "package com.fluid.markdown\n\nimport org.junit.Assert.assertEquals\nimport org.junit.Test\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * See [testing documentation](http://d.android.com/tools/testing).\n */\nclass ExampleUnitTest {\n    @Test\n    fun addition_isCorrect() {\n        assertEquals(4, 2 + 2)\n    }\n}"
  },
  {
    "path": "Android/AntFluid/build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\nplugins {\nalias(libs.plugins.android.application) apply false\n    alias(libs.plugins.kotlin.android) apply false\n    alias(libs.plugins.kotlin.compose) apply false\n    alias(libs.plugins.android.library) apply false\n}"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/.gitignore",
    "content": "/build"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/build.gradle",
    "content": "plugins {\n    alias(libs.plugins.android.library)\n}\n\nandroid {\n    namespace 'com.fluid.afm'\n    compileSdk 35\n\n    defaultConfig {\n        minSdk 21\n\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n        consumerProguardFiles \"consumer-rules.pro\"\n    }\n\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n        }\n    }\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_11\n        targetCompatibility JavaVersion.VERSION_11\n    }\n}\n\ndependencies {\n\n    implementation libs.androidx.appcompat\n    api project(':markwon-core')\n    api project(':markwon-ext-latex')\n    api project(':markwon-ext-strikethrough')\n    api project(':markwon-ext-tables')\n    api project(':markwon-ext-tasklist')\n    api project(':markwon-image')\n    api project(':markwon-html')\n    api project(':markwon-inline-parser')\n    api project(':markwon-syntax-highlight')\n    implementation libs.androidx.recyclerview\n    testImplementation libs.junit\n    androidTestImplementation libs.androidx.junit\n    androidTestImplementation libs.androidx.espresso.core\n    implementation 'com.vdurmont:emoji-java:5.1.1'\n}"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/consumer-rules.pro",
    "content": ""
  },
  {
    "path": "Android/AntFluid/fluid-markdown/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/androidTest/java/com/fluid/afm/ExampleInstrumentedTest.java",
    "content": "package com.fluid.afm;\n\nimport static org.junit.Assert.assertEquals;\n\nimport android.content.Context;\n\nimport androidx.test.ext.junit.runners.AndroidJUnit4;\nimport androidx.test.platform.app.InstrumentationRegistry;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();\n        assertEquals(\"com.fluid.afm\", appContext.getPackageName());\n    }\n}"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <application>\n        <activity\n            android:name=\".ui.MarkDownPreviewActivity\"\n            android:screenOrientation=\"landscape\"\n            android:theme=\"@style/Theme.Preview\">\n        </activity>\n    </application>\n</manifest>"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/AFMInitializer.java",
    "content": "package com.fluid.afm;\n\nimport android.content.Context;\n\nimport androidx.annotation.Nullable;\n\nimport com.fluid.afm.handler.BackgroundTaskHandler;\nimport com.fluid.afm.handler.EventHandlerManager;\nimport com.fluid.afm.handler.ImageHandler;\nimport com.fluid.afm.handler.LogHandler;\n\npublic class AFMInitializer {\n    public static void init(Context context,\n                            @Nullable BackgroundTaskHandler backgroundTaskHandler,\n                            @Nullable ImageHandler imageHandler,\n                            @Nullable LogHandler logHandler) {\n        ContextHolder.setContext(context);\n        EventHandlerManager.setLogHandler(logHandler);\n        EventHandlerManager.setBackgroundTaskHandler(backgroundTaskHandler);\n        EventHandlerManager.setImageHandler(imageHandler);\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/ElementClickEventCallback.java",
    "content": "package com.fluid.afm.markdown;\n\nimport android.view.View;\n\nimport com.fluid.afm.markdown.html.SpanTextClickableSpan;\nimport com.fluid.afm.markdown.model.EventModel;\n\nimport java.util.List;\nimport java.util.Map;\n\npublic interface ElementClickEventCallback {\n    String PARAM_KEY_LINK = \"link\";\n    String PARAM_KEY_SOURCE = \"source\";\n    String SOURCE_TYPE_LINK= \"link\";\n    String SOURCE_TYPE_ICON_LINK= \"iconlink\";\n\n    default boolean onLinkClicked(Map<String, Object> params) { return false;}\n    default void onFootnoteClicked(String index) { }\n\n    default void onImageClicked(String url, String description) {}\n    default boolean onTextClickableSpanClicked(View widget, String link, String entityID, SpanTextClickableSpan.ClickableTextType type)  { return false;}\n\n    default void exposureSpmBehavior(List<EventModel> models) {}\n}\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/MarkdownParser.java",
    "content": "package com.fluid.afm.markdown;\n\nimport android.content.Context;\nimport android.graphics.Paint;\nimport android.os.Build;\nimport android.os.SystemClock;\nimport android.util.TypedValue;\nimport android.widget.TextView;\n\nimport androidx.annotation.NonNull;\n\nimport com.fluid.afm.ContextHolder;\nimport com.fluid.afm.StreamOutStateObserver;\nimport com.fluid.afm.markdown.code.CodeBlockPlugin;\nimport com.fluid.afm.markdown.widget.PrinterMarkDownTextView;\nimport com.fluid.afm.styles.MarkdownStyles;\nimport com.fluid.afm.utils.MDLogger;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\nimport io.noties.markwon.AbstractMarkwonPlugin;\nimport io.noties.markwon.Markwon;\nimport io.noties.markwon.MarkwonPlugin;\nimport io.noties.markwon.core.CorePlugin;\nimport io.noties.markwon.core.MarkwonTheme;\nimport io.noties.markwon.inlineparser.MarkwonInlineParser;\nimport io.noties.markwon.inlineparser.MarkwonInlineParserPlugin;\n\npublic class MarkdownParser {\n\n    public static final String TAG = \"MarkdownParser\";\n    private Markwon.Builder mMarkwonBuilder;\n    private Markwon mMarkwon;\n    private final PrinterMarkDownTextView mTextView;\n    private final List<StreamOutStateObserver> mStreamOutStateObservers = new ArrayList<>();\n    private MarkdownStyles mProductStyles;\n    private MarkwonTheme mMarkwonTheme;\n\n    public MarkdownParser(Context context, List<AbstractMarkwonPlugin> plugins, PrinterMarkDownTextView textView, MarkdownStyles styles) {\n        this.mTextView = textView;\n        mProductStyles = styles;\n        init(context, plugins);\n    }\n\n    public void updateMarkdownStyles(MarkdownStyles styles) {\n        if (styles == null) {\n            return;\n        }\n        mProductStyles = styles;\n        if (mMarkwonTheme != null) {\n            mMarkwonTheme.updateStyles(styles);\n        }\n        if (mTextView == null) {\n            return;\n        }\n        updateTextViewStyle(styles);\n        mTextView.setText(mTextView.getText());\n    }\n\n    private void updateTextViewStyle(MarkdownStyles styles) {\n        if (styles == null) {\n            return;\n        }\n        if (styles.paragraphStyle().fontSize() > 0) {\n            mTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, styles.paragraphStyle().fontSize());\n        }\n        if (styles.paragraphStyle().lineHeight() > 0) {\n            mTextView.setLineSpacing(0, 1.f);\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {\n                mTextView.setFallbackLineSpacing(false);\n            }\n            Paint.FontMetrics fontMetrics = mTextView.getPaint().getFontMetrics();\n            mTextView.setLineSpacing(styles.paragraphStyle().lineHeight() - (fontMetrics.bottom- fontMetrics.top), 1f);\n        }\n        if (styles.paragraphStyle().fontColor() != 0) {\n            mTextView.setTextColor(styles.paragraphStyle().fontColor());\n        }\n    }\n\n    public void setPrintingState(boolean isPrinting) {\n        try {\n            for (StreamOutStateObserver observer : mStreamOutStateObservers) {\n                observer.onStreamOutStateChanged(isPrinting);\n            }\n        } catch (Exception e) {\n            MDLogger.e(TAG, \"delieverIsAnimationFinish error\", e);\n        }\n    }\n\n    private void init(final Context context, List<AbstractMarkwonPlugin> customPlugins) {\n        if(ContextHolder.getContext() == null) {\n            ContextHolder.setContext(context.getApplicationContext());\n        }\n        List<MarkwonPlugin> plugins = new ArrayList<>();\n        if (customPlugins != null) {\n            plugins.addAll(customPlugins);\n        }\n        for (Object obj : plugins) {\n            if (obj instanceof StreamOutStateObserver) {\n                mStreamOutStateObservers.add((StreamOutStateObserver) obj);\n            }\n        }\n        plugins.addAll(getDefaultPlugins(context));\n        mMarkwonBuilder = Markwon.builderWithPlugs(context, plugins);\n        mMarkwonTheme = MarkwonTheme.emptyBuilder().setStyles(mProductStyles).setTextView(mTextView).build(plugins);\n        mMarkwonBuilder.setMarkdownTheme(mMarkwonTheme);\n        mMarkwon = mMarkwonBuilder.build();\n        updateTextViewStyle(mProductStyles);\n    }\n\n    private ArrayList<AbstractMarkwonPlugin> getDefaultPlugins(final Context context) {\n        long startTime = SystemClock.elapsedRealtime();\n        ArrayList<AbstractMarkwonPlugin> plugins = new ArrayList<>(4);\n        plugins.add(CorePlugin.create(context));\n        plugins.add(CodeBlockPlugin.create(context, true));\n        plugins.add(new AbstractMarkwonPlugin() {\n\n            @NonNull\n            @Override\n            public String processMarkdown(@NonNull String markdown) {\n                String regex = \"\\\\${1,2}\\\\s*\\\\\\\\bm\\\\{([A-Za-z]{1,9})\\\\}\\\\s*\\\\${1,2}\";\n                Pattern pattern = Pattern.compile(regex);\n                Matcher matcher = pattern.matcher(markdown);\n                StringBuffer output = new StringBuffer();\n                while (matcher.find()) {\n                    String content = matcher.group(1);\n                    matcher.appendReplacement(output, \"***\" + content + \"***\");\n                }\n                matcher.appendTail(output);\n                return super.processMarkdown(output.toString());\n            }\n\n        });\n        plugins.add(MarkwonInlineParserPlugin.create(MarkwonInlineParser.factoryBuilder()));\n        MDLogger.d(TAG, \"addPlugin costTime=\" + (SystemClock.elapsedRealtime() - startTime));\n        return plugins;\n    }\n\n    public TextView getTextView() {\n        return mTextView;\n    }\n\n    public void setTextSetter(Markwon.TextSetter setter) {\n        mMarkwonBuilder.textSetter(setter);\n    }\n\n    public Markwon getMarkwon() {\n        return mMarkwon;\n    }\n}"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/MarkdownParserFactory.java",
    "content": "package com.fluid.afm.markdown;\n\nimport android.content.Context;\nimport android.graphics.drawable.Drawable;\nimport android.widget.TextView;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.appcompat.content.res.AppCompatResources;\n\nimport com.fluid.afm.MarkdownAwareMovementMethod;\nimport com.fluid.afm.R;\nimport com.fluid.afm.func.IImageClickCallback;\nimport com.fluid.afm.markdown.code.CodeBlockPlugin;\nimport com.fluid.afm.markdown.html.CustomHtmlPlugin;\nimport com.fluid.afm.markdown.html.HtmlMarkTagHandler;\nimport com.fluid.afm.markdown.html.HtmlParaTagHandler;\nimport com.fluid.afm.markdown.html.HtmlSpanTagHandler;\nimport com.fluid.afm.markdown.icon.IconSpanHandler;\nimport com.fluid.afm.markdown.iconlink.IconLinkSpanHandler;\nimport com.fluid.afm.markdown.list.DefinitionListPlugin;\nimport com.fluid.afm.markdown.span.LinkClickSpan;\nimport com.fluid.afm.markdown.text.AfmTextPlugin;\nimport com.fluid.afm.markdown.widget.PrinterMarkDownTextView;\nimport com.fluid.afm.network.ImageLoaderSchemeHandler;\nimport com.fluid.afm.styles.MarkdownStyles;\nimport com.fluid.afm.utils.MDLogger;\nimport com.fluid.afm.utils.Utils;\n\nimport org.commonmark.node.Link;\n\nimport java.util.ArrayList;\n\nimport io.noties.markwon.AbstractMarkwonPlugin;\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.MarkwonSpansFactory;\nimport io.noties.markwon.RenderProps;\nimport io.noties.markwon.SpanFactory;\nimport io.noties.markwon.core.CorePlugin;\nimport io.noties.markwon.core.CoreProps;\nimport io.noties.markwon.ext.latex.JLatexMathPlugin;\nimport io.noties.markwon.ext.strikethrough.StrikethroughPlugin;\nimport io.noties.markwon.ext.tables.TablePlugin;\nimport io.noties.markwon.ext.tasklist.TaskListPlugin;\nimport io.noties.markwon.image.AsyncDrawable;\nimport io.noties.markwon.image.DefaultDownScalingMediaDecoder;\nimport io.noties.markwon.image.ImagesPlugin;\nimport io.noties.markwon.inlineparser.MarkwonInlineParser;\nimport io.noties.markwon.inlineparser.MarkwonInlineParserPlugin;\nimport io.noties.markwon.movement.MovementMethodPlugin;\nimport io.noties.markwon.syntax.SyntaxHighlightPlugin;\n\npublic class MarkdownParserFactory {\n    public static final String TAG = \"MarkdownPluginsCreator\";\n\n    public static MarkdownParser create(Context context, PrinterMarkDownTextView textView) {\n        return create(context, textView, MarkdownStyles.getDefaultStyles(), null);\n    }\n\n    public static void bindMarkdownParser(Context context, PrinterMarkDownTextView textView, MarkdownStyles styles, ElementClickEventCallback callback) {\n        create(context, textView, styles, callback);\n    }\n\n    public static MarkdownParser create(Context context, PrinterMarkDownTextView textView, MarkdownStyles styles, ElementClickEventCallback callback) {\n        ArrayList<AbstractMarkwonPlugin> finalPlugins = getDefaultPlugins(context, textView, callback);\n        return new MarkdownParser(context, finalPlugins, textView, styles);\n    }\n\n    public static ArrayList<AbstractMarkwonPlugin> getPlugins(Context context, PrinterMarkDownTextView textView, TablePlugin tablePlugin) {\n        ArrayList<AbstractMarkwonPlugin> plugins = getDefaultPlugins(context, textView, null);\n        plugins.add(tablePlugin);\n        plugins.add(CorePlugin.create(context));\n        plugins.add(MarkwonInlineParserPlugin.create(MarkwonInlineParser.factoryBuilder()));\n        plugins.add(CodeBlockPlugin.create(context, false));\n        return plugins;\n    }\n\n    public static ArrayList<AbstractMarkwonPlugin> getDefaultPlugins(Context context, PrinterMarkDownTextView textView, ElementClickEventCallback callback) {\n        ArrayList<AbstractMarkwonPlugin> plugins = new ArrayList<>();\n        plugins.add(linkPlugin(callback));\n        plugins.add(imagePlugin(context, callback));\n        if (textView != null) {\n            plugins.add(htmlPlugin(context, textView, callback));\n        }\n        plugins.add(MovementMethodPlugin.create(MarkdownAwareMovementMethod.create()));\n        plugins.add(createJLatexMathPlugin(context));\n        plugins.add(createSyntaxHighlightPlugin());\n        plugins.add(createStrikethroughPlugin());\n        plugins.add(printStreamPlugin(context, callback));\n        plugins.add(createTaskListPlugin(context));\n        plugins.add(definitationPlugin());\n        plugins.add(TablePlugin.create(context));\n        return plugins;\n    }\n\n    public static AbstractMarkwonPlugin createJLatexMathPlugin(Context context) {\n        JLatexMathPlugin.init(context);\n        float size = Utils.dpToPx(context, 16f);\n        JLatexMathPlugin.BuilderConfigure jBuilder = builder -> {\n            builder.blocksEnabled(true);\n            builder.inlinesEnabled(true);\n            builder.blocksLegacy(true);\n            builder.errorHandler(new JLatexMathPlugin.ErrorHandler() {\n                @Nullable\n                @Override\n                public Drawable handleError(@NonNull String latex, @NonNull Throwable error) {\n                    MDLogger.e(\n                            TAG,\n                            \"latex error:\" + latex, error\n                    );\n                    return null;\n                }\n            });\n        };\n        return JLatexMathPlugin.create(size, jBuilder);\n    }\n\n    public static AbstractMarkwonPlugin createTaskListPlugin(Context context) {\n        return TaskListPlugin.create(context);\n    }\n\n    public static AbstractMarkwonPlugin createSyntaxHighlightPlugin() {\n        return SyntaxHighlightPlugin.createDefault();\n    }\n\n    public static AbstractMarkwonPlugin createStrikethroughPlugin() {\n        return StrikethroughPlugin.create();\n    }\n\n    public static AbstractMarkwonPlugin definitationPlugin() {\n        return DefinitionListPlugin.create();\n    }\n\n    public static AbstractMarkwonPlugin linkPlugin(ElementClickEventCallback callback) {\n        return new AbstractMarkwonPlugin() {\n            @Override\n            public void configureSpansFactory(@NonNull MarkwonSpansFactory.Builder builder) {\n                builder.setFactory(Link.class, new SpanFactory() {\n                    @Nullable\n                    @Override\n                    public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps props) {\n                        return new LinkClickSpan(CoreProps.LINK_DESTINATION.require(props), props, configuration.theme(), callback);\n                    }\n                });\n            }\n        };\n    }\n\n    public static ImagesPlugin imagePlugin(Context context, ElementClickEventCallback callback) {\n        IImageClickCallback imageClickCallback = (url, description) -> {\n            if (callback != null) {\n                callback.onImageClicked(url, description);\n            }\n        };\n         return ImagesPlugin.create(imageClickCallback).addSchemeHandler(ImageLoaderSchemeHandler.create(context))\n                .addMediaDecoder(DefaultDownScalingMediaDecoder.create(Utils.getScreenWidth(context) - 2 * Utils.dpToPx(context, 16f), 0))\n                .placeholderProvider(new ImagesPlugin.PlaceholderProvider() {\n                    @Nullable\n                    @Override\n                    public Drawable providePlaceholder(@NonNull AsyncDrawable drawable) {\n                        return AppCompatResources.getDrawable(context, R.drawable.default_placeholderdefault);\n                    }\n                });\n\n    }\n\n    public static AbstractMarkwonPlugin htmlPlugin(Context context, TextView textView, ElementClickEventCallback onClickCallback) {\n        return CustomHtmlPlugin.create()\n                .addHandler(new HtmlSpanTagHandler(context, onClickCallback))\n                .addHandler(new HtmlMarkTagHandler())\n                .addHandler(new HtmlParaTagHandler(context))\n                .addHandler(new IconLinkSpanHandler(textView, onClickCallback))\n                .addHandler(new IconSpanHandler(textView));\n    }\n\n    public static AbstractMarkwonPlugin printStreamPlugin(Context context, ElementClickEventCallback linkClickedCallback) {\n        return new AfmTextPlugin(context).setCustomClickListener(linkClickedCallback);\n    }\n\n}\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/code/CodeBlockPlugin.java",
    "content": "package com.fluid.afm.markdown.code;\n\nimport static io.noties.markwon.core.MarkwonTheme.CODE_BLOCK_HEADER_HEIGHT;\n\nimport android.content.Context;\n\nimport androidx.annotation.NonNull;\n\nimport com.fluid.afm.CodeBlockLineSpacingSpan;\nimport com.fluid.afm.CodeBlockTitleSpan;\nimport com.fluid.afm.markdown.text.RoundedBackgroundSpan;\n\nimport org.commonmark.node.Code;\nimport org.commonmark.node.FencedCodeBlock;\nimport org.commonmark.node.Node;\n\nimport io.noties.markwon.AbstractMarkwonPlugin;\nimport io.noties.markwon.MarkwonSpansFactory;\nimport io.noties.markwon.MarkwonVisitor;\nimport io.noties.markwon.core.MarkwonTheme;\n\npublic class CodeBlockPlugin extends AbstractMarkwonPlugin {\n\n    private static final String TAG = \"CodeBlockPlugin\";\n    private final Context context;\n    private final Boolean showCodeBlockHeader;\n\n    CodeBlockPlugin(@NonNull Context context, boolean showCodeBlockHeader) {\n        this.context = context;\n        this.showCodeBlockHeader = showCodeBlockHeader;\n    }\n    @NonNull\n    @Override\n    public String processMarkdown(@NonNull String markdown) {\n        return super.processMarkdown(markdown);\n    }\n\n    @Override\n    public void configureSpansFactory(@NonNull MarkwonSpansFactory.Builder builder) {\n        if (showCodeBlockHeader) {\n            builder.appendFactory(FencedCodeBlock.class, (configuration, props) -> new CodeBlockTitleSpan(context, configuration.theme(), CODE_BLOCK_HEADER_HEIGHT, configuration.theme().codeStyle().titleFontSize()));\n            builder.appendFactory(FencedCodeBlock.class, (configuration, props) -> new CodeBlockLineSpacingSpan(CODE_BLOCK_HEADER_HEIGHT, 0));\n            builder.appendFactory(Code.class, (configuration, props) -> {\n                MarkwonTheme markwonTheme = configuration.theme();\n                return new RoundedBackgroundSpan(markwonTheme,\n                        markwonTheme.getCodeBackgroundRadius());\n            });\n        }\n    }\n\n    @Override\n    public void configureVisitor(MarkwonVisitor.Builder builder) {\n        builder.blockHandler(new BlockHandlerNoAdditionalNewLines());\n    }\n\n    public static CodeBlockPlugin create(Context context, boolean showCodeBlockHeader) {\n        return new CodeBlockPlugin(context, showCodeBlockHeader);\n    }\n}\n\nclass BlockHandlerNoAdditionalNewLines implements MarkwonVisitor.BlockHandler {\n\n    public BlockHandlerNoAdditionalNewLines() {\n    }\n\n    @Override\n    public void blockStart(@NonNull MarkwonVisitor visitor, @NonNull Node node) {\n        // ensure that content rendered on a new line\n        visitor.ensureNewLine();\n    }\n\n    @Override\n    public void blockEnd(@NonNull MarkwonVisitor visitor, @NonNull Node node) {\n        /* no-op */\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/html/CustomHtmlPlugin.java",
    "content": "package com.fluid.afm.markdown.html;\n\nimport android.os.SystemClock;\nimport android.text.SpannableStringBuilder;\nimport android.text.Spanned;\nimport android.text.TextUtils;\nimport android.widget.TextView;\n\nimport androidx.annotation.NonNull;\n\nimport com.fluid.afm.utils.MDLogger;\n\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\nimport io.noties.markwon.html.HtmlPlugin;\n\npublic class CustomHtmlPlugin extends HtmlPlugin {\n    private static final String TAG = CustomHtmlPlugin.class.getSimpleName();\n\n    CustomHtmlPlugin() {\n        super();\n    }\n\n    public static CustomHtmlPlugin create() {\n        return new CustomHtmlPlugin();\n    }\n\n    @NonNull\n    @Override\n    public String processMarkdown(@NonNull String markdown) {\n        markdown = super.processMarkdown(markdown);\n        markdown = modifyHighlightData(markdown);\n        markdown = appendPoiAndRelatedEntityData(markdown);\n        markdown = handleFormulaCompat(markdown);\n        return markdown;\n    }\n\n    @Override\n    public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) {\n        super.beforeSetText(textView, markdown);\n\n        try {\n            if (markdown instanceof SpannableStringBuilder) {\n                int tableIndex = markdown.toString().indexOf(\"| |-\");\n                if (tableIndex == -1) {\n                    tableIndex = markdown.toString().indexOf(\"||-\");\n                }\n                if (tableIndex == -1) {\n                    tableIndex = markdown.toString().indexOf(\"| |:\");\n                }\n                if (tableIndex != -1) {\n                    ((SpannableStringBuilder) markdown).insert(tableIndex + 2, \"\\n\");\n                }\n            }\n        } catch (Throwable e) {\n            MDLogger.e(TAG, \"beforeSetText...e:\" + e);\n        }\n    }\n    private String modifyHighlightData(String markdown) {\n        long startTime = SystemClock.elapsedRealtime();\n        try {\n            // Regular expression to match <span> tags with class=\"highlight\" or class='highlight'\n            String regex = \"<span\\\\s+[^>]*class=[\\\"|']highlight[\\\"|'][^>]*>(.*?)</span>\";\n\n            // Compile the regex\n            Pattern pattern = Pattern.compile(regex);\n\n            // Create a matcher object\n            Matcher matcher = pattern.matcher(markdown);\n            // Find all matches\n            int groupIndex = 0;\n            while (matcher.find()) {\n                // Print the content inside the <span> tag\n                String span = matcher.group();\n                ++groupIndex;\n                if (TextUtils.isEmpty(span)) {\n                    MDLogger.d(TAG, \"span is null\");\n                    continue;\n                }\n\n                String spanContent = span.substring(span.indexOf('>') + 1, span.lastIndexOf('<'));\n                if (!TextUtils.isEmpty(spanContent) && spanContent.length() > 1) {\n                    StringBuilder afterSpan = new StringBuilder();\n                    char[] spanArray = spanContent.toCharArray();\n                    for (char c : spanArray) {\n                        String single = span.replace(spanContent, String.valueOf(c));\n                        afterSpan.append(single);\n                    }\n                    MDLogger.d(TAG, \"modifyHighlightData afterSpan=\" + afterSpan);\n                    markdown = markdown.replace(span, afterSpan);\n                }\n            }\n\n            final long costTime = (SystemClock.elapsedRealtime() - startTime);\n            if (costTime > 5) {\n                MDLogger.d(TAG, \"modifyHighlightData end cost:\" + costTime);\n            }\n        } catch (Throwable e) {\n            MDLogger.e(TAG, \"modifyHighlightData...e:\" + e);\n        }\n\n        return markdown;\n    }\n\n    private String appendPoiAndRelatedEntityData(String markdown) {\n        long startTime = SystemClock.elapsedRealtime();\n        try {\n            // Regular expression to match <span> tags with class=\"highlight\" or class='highlight'\n            String regex = \"<span\\\\s+[^>]*class=\\\"(poi|related-entity)\\\"[^>]*>(.*?)</span>\";\n\n            // Compile the regex\n            Pattern pattern = Pattern.compile(regex);\n\n            // Create a matcher object\n            Matcher matcher = pattern.matcher(markdown);\n            // Find all matches\n            int groupIndex = 0;\n            while (matcher.find()) {\n                // Print the content inside the <span> tag\n                String span = matcher.group();\n                ++groupIndex;\n                if (TextUtils.isEmpty(span)) {\n                    MDLogger.d(TAG, \"append span is null\");\n                    continue;\n                }\n\n                String spanContent = span.substring(span.indexOf('>') + 1, span.lastIndexOf('<'));\n                MDLogger.d(TAG, \"appendPoiAndRelatedEntityData spanContent=\" + spanContent + \", span=\" + span);\n                if (!TextUtils.isEmpty(spanContent)) {\n                    String afterSpan = span.replace(\"</span>\", \" </span>\");\n                    markdown = markdown.replace(span, afterSpan);\n                }\n            }\n\n            final long costTime = (SystemClock.elapsedRealtime() - startTime);\n            if (costTime > 5) {\n                MDLogger.d(TAG, \"appendPoiAndRelatedEntityData end cost:\" + costTime);\n            }\n        } catch (Throwable e) {\n            MDLogger.e(TAG, \"appendPoiAndRelatedEntityData...e:\" + e);\n        }\n\n        return markdown;\n    }\n\n    private String handleFormulaCompat(String markdown) {\n        try {\n            // Regular expression to match formula \\[a+b=c\\]\n            String formulaRegex = \"(\\\\\\\\\\\\(.*?\\\\\\\\\\\\)|\\\\\\\\\\\\[[\\\\s\\\\S]*?\\\\\\\\\\\\])\";\n\n            // Compile the regex\n            Pattern pattern = Pattern.compile(formulaRegex, Pattern.DOTALL);\n\n            // Create a matcher object\n            Matcher matcher = pattern.matcher(markdown);\n            // Find all matches\n            while (matcher.find()) {\n                // find [a + b =3]\n                String formula = matcher.group();\n                if (TextUtils.isEmpty(formula)) {\n                    MDLogger.d(TAG, \"formula is null\");\n                    continue;\n                }\n\n                try {\n                    String content = formula.substring(2, formula.length() - 2);\n                    if (TextUtils.isEmpty(content) || TextUtils.isEmpty(content.trim())) {\n                        MDLogger.d(TAG, \"handleFormulaCompat do not handle formula=\" + formula);\n                        continue;\n                    }\n                } catch (Throwable e) {\n                    MDLogger.e(TAG, \"handleFormulaCompat e=\" + e);\n                }\n\n                String afterFormula = formula;\n                if (formula.startsWith(\"\\\\[\")) {\n                    afterFormula = formula.replace(\"\\\\[\", \"$$\")\n                            .replace(\"\\\\]\", \"$$\");\n                    markdown = markdown.replace(formula, afterFormula);\n                } else {\n                    afterFormula = formula.replace(\"\\\\(\", \"$\")\n                            .replace(\"\\\\)\", \"$\");\n                    markdown = markdown.replace(formula, afterFormula);\n                }\n\n                MDLogger.d(TAG, \"handleFormulaCompat afterFormula:\" + afterFormula);\n            }\n        } catch (Throwable e) {\n            MDLogger.e(TAG, \"handleFormulaCompat...e:\" + e);\n        }\n        return markdown;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/html/CustomIndentSpan.java",
    "content": "package com.fluid.afm.markdown.html;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.text.Layout;\nimport android.text.style.LeadingMarginSpan;\n\npublic class CustomIndentSpan implements LeadingMarginSpan {\n    private final int indent;\n    private final int firstLineIndent;\n\n    public CustomIndentSpan(int indent) {\n        this.indent = indent;\n        this.firstLineIndent = indent;\n    }\n    public CustomIndentSpan(int indent, int firstLineIndent) {\n        this.indent = indent;\n        this.firstLineIndent = firstLineIndent;\n    }\n\n\n    @Override\n    public int getLeadingMargin(boolean first) {\n        return first ? firstLineIndent : indent;\n    }\n\n    @Override\n    public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline, int bottom, CharSequence text, int start, int end, boolean first, Layout layout) {\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/html/CustomUnderlineSpan.java",
    "content": "package com.fluid.afm.markdown.html;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.text.style.ReplacementSpan;\n\n/**\n * 自定义下划线\n */\npublic class CustomUnderlineSpan extends ReplacementSpan {\n\n    public static final String TAG = \"CustomUnderlineSpan\";\n    private final int color;\n    private final float thickness;\n\n    public CustomUnderlineSpan(int color, float thickness) {\n        this.color = color;\n        this.thickness = thickness;\n    }\n\n    @Override\n    public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {\n        return (int) paint.measureText(text, start, end);\n    }\n\n    @Override\n    public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {\n        int oldColor = paint.getColor();\n        paint.setColor(color);\n        paint.setStrokeWidth(thickness);\n\n        canvas.drawLine(x,\n                y,\n                x + paint.measureText(text, start, end),\n                y,\n                paint);\n        paint.setColor(oldColor);\n        canvas.drawText(text, start, end, x, y, paint);\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/html/HtmlMarkTagHandler.java",
    "content": "package com.fluid.afm.markdown.html;\n\nimport android.graphics.Color;\nimport android.graphics.Typeface;\nimport android.text.TextUtils;\nimport android.text.style.BackgroundColorSpan;\nimport android.text.style.ForegroundColorSpan;\nimport android.text.style.StyleSpan;\n\nimport androidx.annotation.NonNull;\n\nimport com.fluid.afm.utils.MDLogger;\nimport com.fluid.afm.utils.ParseUtil;\n\nimport org.json.JSONObject;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.List;\n\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.RenderProps;\nimport com.fluid.afm.span.AntUnderlineSupportMulLinesSpan;\nimport io.noties.markwon.html.CssInlineStyleParser;\nimport io.noties.markwon.html.CssProperty;\nimport io.noties.markwon.html.HtmlTag;\nimport io.noties.markwon.html.tag.SimpleTagHandler;\n\npublic class HtmlMarkTagHandler extends SimpleTagHandler {\n\n    private static final String TAG = \"HtmlMarkTagHandler\";\n    private int mBackgroundColor = 0xFFFFF2B3;\n    private int backgroundHeight = 30;\n    private String fontWeight = \"normal\";\n\n    public HtmlMarkTagHandler() {\n    }\n\n    @Override\n    public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps renderProps, @NonNull HtmlTag tag) {\n        final String style = tag.attributes().get(\"style\");\n        final String classAttr = tag.attributes().get(\"class\");\n        if (!TextUtils.isEmpty(style)) {\n            int color = 0;\n            int backgroundColor = 0;\n\n            for (CssProperty property : CssInlineStyleParser.create().parse(style)) {\n                switch (property.key()) {\n                    case \"color\":\n                        color = ParseUtil.parseColor(property.value());\n                        break;\n\n                    case \"background-color\":\n                        backgroundColor = ParseUtil.parseColor(property.value());\n                        break;\n\n                    default:\n                        MDLogger.i(\"unexpected CSS property: %s\", property.key());\n                }\n            }\n\n            final List<Object> spans = new ArrayList<>(3);\n            if (color != 0) {\n                spans.add(new ForegroundColorSpan(color));\n            }\n            if (backgroundColor != 0) {\n                spans.add(new BackgroundColorSpan(backgroundColor));\n            }\n\n            return spans.toArray();\n        } else if (!TextUtils.isEmpty(classAttr)) {\n            int color = 0;\n            switch (classAttr) {\n\n                case \"markdown-green-color\":\n                case \"down\":\n                    color = Color.parseColor(\"#0e9976\");\n                    break;\n\n                case \"markdown-red-color\":\n                case \"up\":\n                    color = Color.parseColor(\"#e62c3b\");\n                    break;\n\n                case \"highlight\":\n                    String markTagStyles = \"\";\n                    MDLogger.i(TAG, \"mark---markTagStyles: \" + markTagStyles);\n                    try {\n                        if (!TextUtils.isEmpty(markTagStyles)) {\n                            JSONObject markTagStylesJson = new JSONObject(markTagStyles);\n                            mBackgroundColor = ParseUtil.parseColor(markTagStylesJson.optString(\"backgroundColor\"), mBackgroundColor);\n                            backgroundHeight = ParseUtil.parseDp(markTagStylesJson.optString(\"backgroundHeight\"), backgroundHeight);\n                            String weight = markTagStylesJson.optString(\"fontWeight\");\n                            if (!TextUtils.isEmpty(weight)) {\n                                fontWeight = weight;\n                            }\n                        }\n                    } catch (Throwable e) {\n                        MDLogger.e(TAG, \"markTagStyles error: \" + e.getMessage());\n                    }\n                    final List<Object> spans = new ArrayList<>();\n                    if (\"bold\".equals(fontWeight)) {\n                        StyleSpan boldSpan = new StyleSpan(Typeface.BOLD); // 加粗样式\n                        spans.add(boldSpan);\n                    }\n                    spans.add(new AntUnderlineSupportMulLinesSpan(mBackgroundColor, backgroundHeight));\n                    return spans.toArray();\n            }\n            final List<Object> spans = new ArrayList<>();\n            if (color != 0) {\n                spans.add(new ForegroundColorSpan(color));\n                return spans.toArray();\n            }\n        } else {\n            // 针对<mark>默认文本高亮</mark>样式默认处理\n            final List<Object> spans = new ArrayList<>(1);\n            spans.add(new TextHeightBackgroundSpan(mBackgroundColor));\n            return spans.toArray();\n        }\n\n        return null;\n    }\n\n    @NonNull\n    @Override\n    public Collection<String> supportedTags() {\n        return Collections.singleton(\"mark\");\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/html/HtmlParaTagHandler.java",
    "content": "package com.fluid.afm.markdown.html;\n\nimport android.content.Context;\nimport android.text.TextUtils;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport com.fluid.afm.utils.MDLogger;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.List;\n\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.RenderProps;\nimport io.noties.markwon.html.CssInlineStyleParser;\nimport io.noties.markwon.html.CssProperty;\nimport io.noties.markwon.html.HtmlTag;\nimport io.noties.markwon.html.tag.SimpleTagHandler;\nimport com.fluid.afm.utils.Utils;\n\npublic class HtmlParaTagHandler extends SimpleTagHandler {\n    private static final String TAG = \"HtmlParaTagHandler\";\n\n    private static final String ATTRIBUTE_INDENT = \"indent\";\n    private static final String ATTRIBUTE_FIRST_LINE_INDENT = \"first-line-indent\";\n    private final Context context;\n\n    public HtmlParaTagHandler(Context context) {\n        this.context = context;\n    }\n\n    @Nullable\n    @Override\n    public Object getSpans(@androidx.annotation.NonNull MarkwonConfiguration configuration, @androidx.annotation.NonNull RenderProps renderProps, @androidx.annotation.NonNull HtmlTag tag) {\n        try {\n            final String style = tag.attributes().get(\"style\");\n\n            if (!TextUtils.isEmpty(style)) {\n                int indent = -1;\n                int firstLineIndent = -1;\n\n                for (CssProperty property : CssInlineStyleParser.create().parse(style)) {\n                    switch (property.key()) {\n                        case ATTRIBUTE_INDENT:\n                            String indentValue = property.value();\n                            if (indentValue.endsWith(\"rpx\")) {\n                                String rpxValue = indentValue.substring(0, indentValue.length() - 3);\n                                indent = (int) Utils.rpxToPx(Float.parseFloat(rpxValue), context);\n                            } else if (indentValue.endsWith(\"dp\")) {\n                                String dpValue = indentValue.substring(0, indentValue.length() - 2);\n                                indent = Utils.dpToPx(context, Float.parseFloat(dpValue));\n                            } else if (indentValue.endsWith(\"px\")) {\n                                String pxValue = indentValue.substring(0, indentValue.length() - 2);\n                                indent = Integer.parseInt(pxValue);\n                            } else {\n                                MDLogger.i(TAG, \"Unexpected unit: key=\" + property.key() + \", value=\" + indentValue);\n                            }\n                            break;\n                        case ATTRIBUTE_FIRST_LINE_INDENT:\n                            String firstLineValue = property.value();\n                            if (firstLineValue.endsWith(\"rpx\")) {\n                                String rpxValue = firstLineValue.substring(0, firstLineValue.length() - 3);\n                                firstLineIndent = (int) Utils.rpxToPx(Float.parseFloat(rpxValue), context);\n                            } else if (firstLineValue.endsWith(\"dp\")) {\n                                String dpValue = firstLineValue.substring(0, firstLineValue.length() - 2);\n                                firstLineIndent = Utils.dpToPx(context, Float.parseFloat(dpValue));\n                            } else if (firstLineValue.endsWith(\"px\")) {\n                                String pxValue = firstLineValue.substring(0, firstLineValue.length() - 2);\n                                firstLineIndent = Integer.parseInt(pxValue);\n                            } else {\n                                MDLogger.i(TAG, \"Unexpected unit: key=\" + property.key() + \", value=\" + firstLineValue);\n                            }\n                            break;\n                        default:\n                            MDLogger.i(TAG, \"Unexpected CSS property: key=\" + property.key());\n                    }\n                }\n\n                MDLogger.d(TAG, \"handleSpans: style=\" + style + \", indent=\" + indent);\n\n                final List<Object> spans = new ArrayList<>(3);\n                if (indent >= 0 && firstLineIndent >= 0) {\n                    spans.add(new CustomIndentSpan(indent, firstLineIndent));\n                } else if (indent >= 0) {\n                    spans.add(new CustomIndentSpan(indent));\n                }\n\n                return spans.toArray();\n            }\n        } catch (Exception e) {\n            MDLogger.e(TAG, \"handleSpans error: \" + e.getMessage());\n        }\n\n        return null;\n    }\n\n    @NonNull\n    @Override\n    public Collection<String> supportedTags() {\n        return Collections.singleton(\"para\");\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/html/HtmlSpanTagHandler.java",
    "content": "package com.fluid.afm.markdown.html;\n\nimport android.content.Context;\nimport android.graphics.Color;\nimport android.graphics.drawable.Drawable;\nimport android.text.TextUtils;\nimport android.text.style.BackgroundColorSpan;\nimport android.text.style.ForegroundColorSpan;\n\nimport androidx.annotation.NonNull;\nimport androidx.appcompat.content.res.AppCompatResources;\n\nimport com.fluid.afm.R;\nimport com.fluid.afm.markdown.ElementClickEventCallback;\nimport com.fluid.afm.markdown.image.SuperscriptImageSpan;\nimport com.fluid.afm.utils.MDLogger;\nimport com.fluid.afm.utils.ParseUtil;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.List;\n\nimport io.noties.markwon.MarkwonVisitor;\nimport io.noties.markwon.SpannableBuilder;\nimport io.noties.markwon.html.CssInlineStyleParser;\nimport io.noties.markwon.html.CssProperty;\nimport io.noties.markwon.html.HtmlTag;\nimport io.noties.markwon.html.MarkwonHtmlRenderer;\nimport io.noties.markwon.html.TagHandler;\nimport com.fluid.afm.utils.Utils;\n\npublic class HtmlSpanTagHandler extends TagHandler {\n    private static final String TAG = \"HtmlSpanTagHandler\";\n\n    private static final String DEFAULT_POI_COLOR = \"#0E489A\";\n    private static final String CLASS_POI = \"poi\";\n    private static final String CLASS_RELATED_ENTITY = \"related-entity\";\n    private static final String CLASS_VOICE_TEXT = \"voicetext\";\n    private static final String ATTRIBUTE_COLOR = \"color\";\n    private static final String ATTRIBUTE_BACKGROUND_COLOR = \"background-color\";\n    private static final String CLASS_HIGHLIGHT = \"highlight\";\n\n    private final Context context;\n    private final ElementClickEventCallback mElementClickEventCallback;\n\n    public HtmlSpanTagHandler(Context context, ElementClickEventCallback clickedInterface) {\n        this.context = context;\n        mElementClickEventCallback = clickedInterface;\n    }\n\n    private void handleInner(@NonNull MarkwonVisitor visitor,\n                             @NonNull MarkwonHtmlRenderer renderer,\n                             @NonNull HtmlTag tag) {\n        if (tag.isBlock()) {\n            visitChildren(visitor, renderer, tag.getAsBlock());\n        }\n\n        handleSpans(visitor, tag);\n    }\n\n    @Override\n    public void handle(@NonNull MarkwonVisitor visitor,\n                       @NonNull MarkwonHtmlRenderer renderer,\n                       @NonNull HtmlTag tag) {\n        handleInner(visitor, renderer, tag);\n    }\n\n    public void handleSpans(@NonNull MarkwonVisitor visitor,\n                            @NonNull HtmlTag tag) {\n        final String style = tag.attributes().get(\"style\");\n        final String classAttr = tag.attributes().get(\"class\");\n\n        if (!TextUtils.isEmpty(style)) {\n            int color = 0;\n            int backgroundColor = 0;\n\n            for (CssProperty property : CssInlineStyleParser.create().parse(style)) {\n                switch (property.key()) {\n                    case ATTRIBUTE_COLOR:\n                        color = ParseUtil.parseColor(property.value());\n                        break;\n\n                    case ATTRIBUTE_BACKGROUND_COLOR:\n                        backgroundColor = ParseUtil.parseColor(property.value());\n                        break;\n\n                    default:\n                        MDLogger.i(\"unexpected CSS property: %s\", property.key());\n                }\n            }\n\n            final List<Object> spans = new ArrayList<>(3);\n            if (color != 0) {\n                spans.add(new ForegroundColorSpan(color));\n            }\n            if (backgroundColor != 0) {\n                spans.add(new BackgroundColorSpan(backgroundColor));\n            }\n\n            SpannableBuilder.setSpans(visitor.builder(), spans.toArray(), tag.start(), tag.end());\n        } else if (!TextUtils.isEmpty(classAttr)) {\n            int color = 0;\n            switch (classAttr) {\n                case \"markdown-green-color\":\n                    color = ParseUtil.parseColor(\"#0e9976\");\n                    break;\n\n                case \"markdown-red-color\":\n                    color = ParseUtil.parseColor(\"#e62c3b\");\n                    break;\n\n                case CLASS_HIGHLIGHT:\n                    final List<Object> spans = new ArrayList<>(2);\n                    spans.add(new CustomUnderlineSpan(Color.parseColor(\"#521677FF\"),\n                            Utils.dpToPx(context, 11)));\n                    SpannableBuilder.setSpans(visitor.builder(), spans.toArray(), tag.start(), tag.end());\n                    return;\n                case CLASS_POI:\n                    setClassPoiSpans(visitor, tag);\n                    return;\n                case CLASS_RELATED_ENTITY:\n                    setClassRelatedEntitySpans(visitor, tag);\n                    return;\n\n                case CLASS_VOICE_TEXT:\n                    final List<Object> spansVoice = new ArrayList<>();\n                    spansVoice.add(new ForegroundColorSpan(0xFF1A65FF));\n                    spansVoice.add(new BackgroundColorSpan(0xFFF4F8FF));\n                    SpannableBuilder.setSpans(visitor.builder(), spansVoice.toArray(), tag.start(), tag.end());\n                    return;\n\n            }\n\n            final List<Object> spans = new ArrayList<>(2);\n            if (color != 0) {\n                spans.add(new ForegroundColorSpan(color));\n                SpannableBuilder.setSpans(visitor.builder(), spans.toArray(), tag.start(), tag.end());\n            }\n        }\n    }\n    @NonNull\n    @Override\n    public Collection<String> supportedTags() {\n        return Collections.singleton(\"span\");\n    }\n\n    /**\n     *  class=\"poi\" span\n     *\n     */\n    private void setClassPoiSpans(@NonNull MarkwonVisitor visitor, @NonNull HtmlTag tag) {\n        int color;\n        final List<Object> poiSpans = new ArrayList<>(3);\n        final String colorAttr = tag.attributes().get(ATTRIBUTE_COLOR);\n        if (TextUtils.isEmpty(colorAttr)) {\n            // 默认色\n            color = Color.parseColor(DEFAULT_POI_COLOR);\n        } else {\n            color = ParseUtil.parseColor(colorAttr);\n        }\n        poiSpans.add(new ForegroundColorSpan(color));\n\n        final String hrefAttr = tag.attributes().get(\"href\");\n        poiSpans.add(new SpanTextClickableSpan(SpanTextClickableSpan.ClickableTextType.TYPE_POI,\n                hrefAttr, null, mElementClickEventCallback));\n\n        MDLogger.d(TAG, \"poi color:\" + color\n                + \",start:\" + tag.start()\n                + \",end:\" + tag.end() + \",href=\" + hrefAttr);\n\n        SpannableBuilder.setSpans(visitor.builder(), poiSpans.toArray(), tag.start(), tag.end() - 1);\n\n        Drawable poiSuperscriptDrawable = getPoiSuperscriptDrawable();\n        if (poiSuperscriptDrawable != null) {\n            final int w = Utils.dpToPx(context, 12);\n            poiSuperscriptDrawable.setBounds(0, 0, w, w);\n            final List<Object> drawableSpans = new ArrayList<>(2);\n            drawableSpans.add(new SuperscriptImageSpan(poiSuperscriptDrawable));\n            drawableSpans.add(new SpanTextClickableSpan(SpanTextClickableSpan.ClickableTextType.TYPE_POI,\n                    hrefAttr, \"\", null));\n            SpannableBuilder.setSpans(visitor.builder(), drawableSpans.toArray(),\n                    tag.end() - 1, tag.end());\n        }\n    }\n\n    /**\n     * class=\"related-entity\" span\n     */\n    private void setClassRelatedEntitySpans(@NonNull MarkwonVisitor visitor, @NonNull HtmlTag tag) {\n        int color;\n        final List<Object> entitySpans = new ArrayList<>(3);\n\n        final String entityIdAttr = tag.attributes().get(\"data-entity-id\");\n\n        final String entityColorAttr = tag.attributes().get(ATTRIBUTE_COLOR);\n        if (TextUtils.isEmpty(entityColorAttr)) {\n            color = Color.parseColor(DEFAULT_POI_COLOR);\n        } else {\n            color = ParseUtil.parseColor(entityColorAttr);\n        }\n        entitySpans.add(new ForegroundColorSpan(color));\n        entitySpans.add(new SpanTextClickableSpan(SpanTextClickableSpan.ClickableTextType.TYPE_RELATED_ENTITY,\n                null, entityIdAttr, mElementClickEventCallback));\n\n        MDLogger.d(TAG, \"entity color:\" + color\n                + \",start:\" + tag.start()\n                + \",end:\" + tag.end() + \",entityIdAttr=\" + entityIdAttr);\n\n        SpannableBuilder.setSpans(visitor.builder(), entitySpans.toArray(), tag.start(), tag.end() - 1);\n\n        Drawable superscriptDrawable = getRelatedEntitySuperscriptDrawable();\n        if (superscriptDrawable != null) {\n            final int w = Utils.dpToPx(context, 12);\n            superscriptDrawable.setBounds(0, 0, w, w);\n            final List<Object> drawableSpans = new ArrayList<>(2);\n            drawableSpans.add(new SuperscriptImageSpan(superscriptDrawable));\n            drawableSpans.add(new SpanTextClickableSpan(SpanTextClickableSpan.ClickableTextType.TYPE_RELATED_ENTITY,\n                    null, entityIdAttr, mElementClickEventCallback));\n            SpannableBuilder.setSpans(visitor.builder(), drawableSpans.toArray(),\n                    tag.end() - 1, tag.end());\n        }\n    }\n\n    private Drawable getPoiSuperscriptDrawable() {\n        if (context == null) {\n            return null;\n        }\n        return AppCompatResources.getDrawable(context, R.drawable.chat_span_poi);\n    }\n\n    private Drawable getRelatedEntitySuperscriptDrawable() {\n        if (context == null) {\n            return null;\n        }\n\n        return AppCompatResources.getDrawable(context, R.drawable.chat_span_related_entity);\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/html/SpanTextClickableSpan.java",
    "content": "package com.fluid.afm.markdown.html;\n\nimport android.text.TextPaint;\nimport android.text.style.URLSpan;\nimport android.view.View;\n\nimport androidx.annotation.NonNull;\n\nimport com.fluid.afm.markdown.ElementClickEventCallback;\nimport com.fluid.afm.utils.MDLogger;\n\npublic class SpanTextClickableSpan extends URLSpan {\n    private static final String TAG = SpanTextClickableSpan.class.getSimpleName();\n\n    private final ClickableTextType clickableTextType;\n    private final String url;\n    private final String entityId;\n    private final ElementClickEventCallback mElementClickEventCallback;\n\n    public SpanTextClickableSpan(ClickableTextType type, String url, String entityId, ElementClickEventCallback clickedInterface) {\n        super(url);\n        this.clickableTextType = type;\n        this.url = url;\n        this.entityId = entityId;\n        mElementClickEventCallback = clickedInterface;\n    }\n\n    @Override\n    public void updateDrawState(TextPaint ds) {\n        ds.setColor(ds.linkColor);\n        ds.setUnderlineText(false);\n    }\n\n    @Override\n    public void onClick(@NonNull View widget) {\n        MDLogger.d(TAG, \"onClick...type:\" + clickableTextType\n                + \",entityId=\" + entityId\n                + \",url=\" + url);\n        if (mElementClickEventCallback != null && mElementClickEventCallback.onTextClickableSpanClicked(widget, url, entityId, clickableTextType)) {\n            return;\n        }\n        super.onClick(widget);\n    }\n\n    public enum ClickableTextType {\n\n        TYPE_POI,\n\n        TYPE_RELATED_ENTITY\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/html/TextHeightBackgroundSpan.java",
    "content": "package com.fluid.afm.markdown.html;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.graphics.RectF;\nimport android.text.style.ReplacementSpan;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\npublic class TextHeightBackgroundSpan extends ReplacementSpan {\n\n    private final int backgroundColor;\n\n    public TextHeightBackgroundSpan(int backgroundColor) {\n        this.backgroundColor = backgroundColor;\n    }\n\n    @Override\n    public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, @Nullable Paint.FontMetricsInt fm) {\n        return (int) paint.measureText(text, start, end);\n    }\n\n    @Override\n    public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {\n        final int oldColor = paint.getColor();\n        final Paint.Style oldStyle = paint.getStyle();\n\n        Paint.FontMetrics fontMetrics = paint.getFontMetrics();\n\n        float backgroundTop = y + fontMetrics.ascent;\n        float backgroundBottom = y + fontMetrics.descent;\n\n        paint.setColor(backgroundColor);\n        paint.setStyle(Paint.Style.FILL);\n        \n        RectF rect = new RectF(\n                x,\n                backgroundTop,\n                x + paint.measureText(text, start, end),\n                backgroundBottom\n        );\n        canvas.drawRect(rect, paint);\n\n        paint.setColor(oldColor);\n        paint.setStyle(oldStyle);\n        canvas.drawText(text, start, end, x, y, paint);\n    }\n} "
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/icon/IconSpan.java",
    "content": "package com.fluid.afm.markdown.icon;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.text.TextUtils;\nimport android.text.style.ReplacementSpan;\nimport android.view.View;\nimport android.widget.TextView;\n\nimport androidx.annotation.NonNull;\n\nimport com.fluid.afm.icon.DrawableWrapper;\nimport com.fluid.afm.icon.LoadIconUtil;\nimport com.fluid.afm.icon.LoadImageCallback;\n\nimport com.fluid.afm.utils.Utils;\n\npublic class IconSpan extends ReplacementSpan implements View.OnAttachStateChangeListener {\n    private DrawableWrapper mDrawableWrapper;\n    private final TextView mTextView;\n    private LoadImageCallback mLoadImageCallback;\n    private final String mSrc;\n    protected float iconOffset;\n\n    public IconSpan(TextView textView, String imageUrl) {\n        mTextView = textView;\n        mSrc = imageUrl;\n        textView.addOnAttachStateChangeListener(this);\n    }\n\n    @Override\n    public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {\n        if (TextUtils.isEmpty(mSrc)) {\n            return 0;\n        }\n        int textSize = (int) (paint.getFontMetrics().descent - paint.getFontMetrics().ascent + 0.5f);\n\n        iconOffset = textSize * Utils.FONT_HEIGHT_IN_LINE;\n        fetchImage(textSize);\n        if (mDrawableWrapper.getDrawable() != null) {\n            return mDrawableWrapper.getDrawable().getBounds().width();\n        }\n        return textSize;\n    }\n\n    private void fetchImage(int size) {\n        mDrawableWrapper = LoadIconUtil.getIcon(mSrc, size, size, false);\n        if (mDrawableWrapper.getDrawable() == null) {\n            if (mLoadImageCallback == null) {\n                mLoadImageCallback = new LoadImageCallback(mTextView);\n            }\n            mDrawableWrapper.load(mTextView.getContext(), mLoadImageCallback);\n        }\n    }\n\n    @Override\n    public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {\n        // draw icon\n        if (mDrawableWrapper.getDrawable() != null) {\n            canvas.save();\n            canvas.translate(x, y - Math.min(iconOffset, mDrawableWrapper.getDrawable().getBounds().height()));\n            mDrawableWrapper.getDrawable().draw(canvas);\n            canvas.restore();\n        }\n    }\n\n    @Override\n    public void onViewAttachedToWindow(View v) {\n        /* no-op */\n    }\n\n    @Override\n    public void onViewDetachedFromWindow(View v) {\n        if (mDrawableWrapper != null) {\n            mDrawableWrapper.cancel(mLoadImageCallback);\n        }\n        mTextView.removeOnAttachStateChangeListener(this);\n    }\n\n}\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/icon/IconSpanHandler.java",
    "content": "package com.fluid.afm.markdown.icon;\n\nimport android.widget.TextView;\n\nimport java.util.Collection;\nimport java.util.Collections;\n\nimport io.noties.markwon.MarkwonVisitor;\nimport io.noties.markwon.SpannableBuilder;\nimport io.noties.markwon.html.HtmlTag;\nimport io.noties.markwon.html.MarkwonHtmlRenderer;\nimport io.noties.markwon.html.TagHandler;\n\npublic class IconSpanHandler extends TagHandler {\n    private final TextView mTextView;\n\n    public IconSpanHandler(TextView textView) {\n        mTextView = textView;\n    }\n\n    @Override\n    public void handle(MarkwonVisitor visitor, MarkwonHtmlRenderer renderer, HtmlTag tag) {\n        final String src = tag.attributes().get(\"src\");\n        IconSpan iconSpan = new IconSpan(mTextView, src);\n        if (tag.end() > tag.start()) {\n            SpannableBuilder.setSpans(visitor.builder(), new Object[]{iconSpan}, tag.start(), tag.end());\n        } else {\n            visitor.builder().spannableStringBuilder().insert(tag.start(), String.valueOf('\\u00a0'));\n            SpannableBuilder.setSpans(visitor.builder(), new Object[]{iconSpan}, tag.start(), tag.start() + 1);\n        }\n    }\n\n    @Override\n    public Collection<String> supportedTags() {\n        return Collections.singleton(\"icon\");\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/iconlink/IconLinkSpan.java",
    "content": "package com.fluid.afm.markdown.iconlink;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.graphics.Path;\nimport android.graphics.Rect;\nimport android.text.TextPaint;\nimport android.text.style.LineHeightSpan;\nimport android.text.style.ReplacementSpan;\nimport android.view.View;\nimport android.widget.TextView;\n\nimport androidx.annotation.NonNull;\n\nimport com.fluid.afm.icon.DrawableWrapper;\nimport com.fluid.afm.icon.LoadIconUtil;\nimport com.fluid.afm.icon.LoadImageCallback;\nimport com.fluid.afm.span.IClickableSpan;\nimport com.fluid.afm.utils.Utils;\n\nimport io.noties.markwon.utils.SpanUtils;\npublic class IconLinkSpan extends ReplacementSpan implements LineHeightSpan, View.OnAttachStateChangeListener, IClickableSpan {\n\n    private static final int _10_6DP = Utils.dpToPx(10.67f);\n    private static final int _1_5DP = Utils.dpToPx(1.5f);\n    private static final int _3DP = Utils.dpToPx(3f);\n    private static final int RIGHT_PADDING = _3DP;\n    private static final int LEFT_PADDING = _1_5DP;\n    private static final int ICON_DISTANCE = _1_5DP;\n    private static final int CORNER_RADIUS = _10_6DP;\n    private static final int LEFT_RIGHT_MARGIN = _1_5DP;\n    private static final float VERTICAL_PADDING_RATIO = 0.2f;\n    private int mLineHeight = 0;\n    private DrawableWrapper mDrawableWrapper;\n    private final TextView mTextView;\n    private final Path mPath = new Path();\n    private boolean mFetched = false;\n    private final int mBackgroundColor;\n    private final int mTextColor;\n    private final float mFontSize;\n    private float mIconSize;\n    private final String mSrcUrl;\n    private int mInnerLineHeight;\n    private final Rect mBgRect = new Rect();\n    private LoadImageCallback mLoadImageCallback;\n    private final String mLink;\n    private int mTop;\n    private int mBottom;\n    public IconLinkSpan(TextView textView, String imageUrl, int backgroundColor, int textColor, float fontSize, String link) {\n        mTextView = textView;\n        mFontSize = fontSize;\n        mBackgroundColor = backgroundColor;\n        mTextColor = textColor;\n        mSrcUrl = imageUrl;\n        mLink = link;\n        textView.addOnAttachStateChangeListener(this);\n    }\n\n    @Override\n    public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {\n        if (mLineHeight == 0) {\n            mLineHeight = (int) (paint.getFontMetrics().descent - paint.getFontMetrics().ascent);\n        }\n        float oldSize = paint.getTextSize();\n\n        if (mFontSize > 0) {\n            paint.setTextSize(mFontSize);\n            mInnerLineHeight = (int) (paint.getFontMetrics().descent - paint.getFontMetrics().ascent);\n        } else {\n            mInnerLineHeight = mLineHeight;\n        }\n\n        mIconSize = mInnerLineHeight * 1.05f;\n        if (!mFetched) {\n            mFetched = true;\n            fetchImage((int) mIconSize);\n        } else if (mDrawableWrapper.getDrawable() != null) {\n            Rect imgBounds = mDrawableWrapper.getDrawable().getBounds();\n            mIconSize = imgBounds.width();\n        }\n        float textW = paint.measureText(text, start, end);\n        int size = (int) (textW + LEFT_RIGHT_MARGIN + mIconSize + LEFT_RIGHT_MARGIN + ICON_DISTANCE);\n        if (mBackgroundColor != 0) {\n            int paddingV = (int) (mInnerLineHeight * VERTICAL_PADDING_RATIO);\n            int bgW = (int) (LEFT_PADDING + RIGHT_PADDING + textW + mIconSize + ICON_DISTANCE);\n            size = bgW + LEFT_RIGHT_MARGIN + LEFT_RIGHT_MARGIN;\n            mBgRect.set(0, 0, bgW, mInnerLineHeight + paddingV + paddingV);\n        }\n        if (mFontSize > 0) {\n            paint.setTextSize(oldSize);\n        }\n\n        return size;\n    }\n\n    private void fetchImage(int size) {\n        mDrawableWrapper = LoadIconUtil.getIcon(mSrcUrl, size, size, true);\n        if (mDrawableWrapper.getDrawable() == null) {\n            if (mLoadImageCallback == null) {\n                mLoadImageCallback = new LoadImageCallback(mTextView);\n            }\n            mDrawableWrapper.load(mTextView.getContext(), mLoadImageCallback);\n        }\n    }\n\n    @Override\n    public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {\n        mTop = top;\n        mBottom = y;\n        int originalColor = paint.getColor();\n        float finalX = x + LEFT_RIGHT_MARGIN;\n        mPath.reset();\n        if (mFontSize > 0) {\n            paint.setTextSize(mFontSize);\n        }\n        Paint.Style oldStyle = paint.getStyle();\n        float rectTop = y + mInnerLineHeight * 1f / 9f - mIconSize;\n        // draw background\n        if (mBackgroundColor != 0) {\n            paint.setColor(mBackgroundColor);\n            paint.setStyle(Paint.Style.FILL);\n            int vp = (int) ((mBgRect.height() - mInnerLineHeight) / 2f);\n            mPath.addRoundRect(finalX, rectTop - vp,\n                    finalX + mBgRect.width(),\n                    rectTop  + mBgRect.height(),\n                    CORNER_RADIUS, CORNER_RADIUS, Path.Direction.CW);\n            canvas.drawPath(mPath, paint);\n            paint.setStyle(oldStyle);\n            finalX += LEFT_PADDING;\n        }\n        // draw icon\n        if (mDrawableWrapper.getDrawable() != null) {\n            canvas.save();\n            canvas.translate(finalX, rectTop);\n            mDrawableWrapper.getDrawable().draw(canvas);\n            canvas.restore();\n        }\n        paint.setStyle(oldStyle);\n        float oldSize = paint.getTextSize();\n        if (mTextColor != 0) {\n            paint.setColor(mTextColor);\n        } else {\n            paint.setColor(originalColor);\n        }\n        // draw text x: left-margin + left-padding + icon + spacing\n        canvas.drawText(text, start, end, finalX + mIconSize + ICON_DISTANCE, y, paint);\n\n        if (mTextColor != 0) {\n            paint.setColor(originalColor);\n        }\n        if (mFontSize > 0) {\n            paint.setTextSize(oldSize);\n        }\n    }\n\n    @Override\n    public void chooseHeight(CharSequence text, int start, int end, int spanstartv, int lineHeight, Paint.FontMetricsInt fm) {\n        if (mBgRect.height() <= mLineHeight) {\n            return;\n        }\n        if (fm == null) {\n            return;\n        }\n        if (SpanUtils.isSelf(start, end, text, this)) { // adjust line height that contains the span\n            if (mBgRect.height() > fm.bottom - fm.top) { // span height is higher than line height\n                int delta = ((mBgRect.height() - (fm.bottom - fm.top))) / 2;\n                fm.top -= delta;\n                fm.bottom += delta;\n                fm.ascent -= delta;\n                fm.descent += delta;\n            }\n        }\n    }\n\n    @Override\n    public void updateDrawState(TextPaint ds) {\n        super.updateDrawState(ds);\n    }\n\n    @Override\n    public void onViewAttachedToWindow(@NonNull View v) {\n        /* no-op */\n    }\n\n    @Override\n    public void onViewDetachedFromWindow(@NonNull View v) {\n        if (mDrawableWrapper != null) {\n            mDrawableWrapper.cancel(mLoadImageCallback);\n        }\n        mTextView.removeOnAttachStateChangeListener(this);\n    }\n\n    @Override\n    public String getUrl() {\n        return mLink;\n    }\n\n    @Override\n    public String getType() {\n        return \"iconlink\";\n    }\n\n    @Override\n    public int getTop() {\n        return mTop;\n    }\n\n    @Override\n    public int getBottom() {\n        return mBottom;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/iconlink/IconLinkSpanHandler.java",
    "content": "package com.fluid.afm.markdown.iconlink;\n\nimport android.graphics.Color;\nimport android.text.TextPaint;\nimport android.text.TextUtils;\nimport android.text.style.URLSpan;\nimport android.view.View;\nimport android.widget.TextView;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport com.fluid.afm.markdown.ElementClickEventCallback;\nimport com.fluid.afm.utils.MDLogger;\nimport com.fluid.afm.utils.ParseUtil;\n\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\n\nimport io.noties.markwon.MarkwonVisitor;\nimport io.noties.markwon.SpannableBuilder;\nimport io.noties.markwon.html.CssInlineStyleParser;\nimport io.noties.markwon.html.CssProperty;\nimport io.noties.markwon.html.HtmlTag;\nimport io.noties.markwon.html.MarkwonHtmlRenderer;\nimport io.noties.markwon.html.TagHandler;\n\npublic class IconLinkSpanHandler extends TagHandler {\n    private final TextView mTextView;\n    private final ElementClickEventCallback mnClickLCallback;\n\n    public IconLinkSpanHandler(TextView textView, @Nullable ElementClickEventCallback onClickLCallback2) {\n        mTextView = textView;\n        mnClickLCallback = onClickLCallback2;\n    }\n\n    @Override\n    public void handle(MarkwonVisitor visitor, MarkwonHtmlRenderer renderer, HtmlTag tag) {\n        final String style = tag.attributes().get(\"style\");\n        int textColor = 0;\n        int bgColor = 0;\n        float fontSize = 0;\n        if (!TextUtils.isEmpty(style)) {\n            for (CssProperty property : CssInlineStyleParser.create().parse(style)) {\n                switch (property.key()) {\n                    case \"color\":\n                        textColor = ParseUtil.parseColorWithRGBA(property.value());\n                        break;\n                    case \"font-size\":\n                        fontSize = ParseUtil.parseDp(mTextView.getContext(), property.value(), 0);\n                        break;\n                    case \"background-color\":\n                        bgColor = ParseUtil.parseColorWithRGBA(property.value());\n                        break;\n                    default:\n                        MDLogger.i(\"unexpected CSS property: %s\", property.key());\n                }\n            }\n        }\n\n        final String src = tag.attributes().get(\"src\");\n        final String link = tag.attributes().get(\"link\");\n        final String destination = visitor.configuration().imageDestinationProcessor().process(src);\n        IconLinkSpan iconSpan = new IconLinkSpan(mTextView, destination,\n                bgColor, textColor, fontSize, link);\n        if (!TextUtils.isEmpty(link)) {\n            URLSpan clickableSpan = new URLSpan(link) {\n                @Override\n                public void onClick(@NonNull View widget) {\n                    boolean result = false;\n                    if (mnClickLCallback != null) {\n                        HashMap<String, Object> param = new HashMap<>(2);\n                        param.put(ElementClickEventCallback.PARAM_KEY_LINK, link);\n                        param.put(ElementClickEventCallback.PARAM_KEY_SOURCE, ElementClickEventCallback.SOURCE_TYPE_ICON_LINK);\n                        result = mnClickLCallback.onLinkClicked(param);\n                    }\n                    if (!result) {\n                        super.onClick(widget);\n                    }\n                }\n                @Override\n                public void updateDrawState(TextPaint ds) {\n                    ds.bgColor = Color.TRANSPARENT;\n                    ds.setUnderlineText(false);\n                }\n            };\n            SpannableBuilder.setSpans(visitor.builder(), new Object[]{iconSpan, clickableSpan}, tag.start(), tag.end());\n        } else {\n            SpannableBuilder.setSpans(visitor.builder(), new Object[]{iconSpan}, tag.start(), tag.end());\n        }\n\n    }\n\n    @Override\n    public Collection<String> supportedTags() {\n        return Collections.singleton(\"iconlink\");\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/image/CustomImageSpan.java",
    "content": "package com.fluid.afm.markdown.image;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.graphics.drawable.Drawable;\nimport android.text.Spanned;\n\npublic class CustomImageSpan extends SuperscriptImageSpan {\n\n    public CustomImageSpan(Drawable drawable) {\n        super(drawable, ALIGN_CENTER);\n    }\n\n    @Override\n    public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {\n        if (!isSelf(start, end, text, this)) {\n            return;\n        }\n        super.draw(canvas, text, start, end, x, top, y, bottom, paint);\n    }\n    private static boolean isSelf(int start, int end, CharSequence text, Object span) {\n        final int spanStart = ((Spanned) text).getSpanStart(span);\n        final int spanEnd = ((Spanned) text).getSpanEnd(span);\n        return spanStart <= start && spanEnd >= end - 1;\n    }\n\n}\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/image/FootnoteClickSpan.java",
    "content": "package com.fluid.afm.markdown.image;\n\nimport android.annotation.SuppressLint;\nimport android.text.style.ClickableSpan;\nimport android.view.View;\n\nimport androidx.annotation.NonNull;\n\nimport com.fluid.afm.markdown.ElementClickEventCallback;\n\npublic class FootnoteClickSpan extends ClickableSpan {\n    private final ElementClickEventCallback mClickCallback;\n    private final String mIndexSequence;\n\n    public FootnoteClickSpan(String indexSequence, ElementClickEventCallback onClickCallback) {\n        mIndexSequence = indexSequence;\n        mClickCallback = onClickCallback;\n    }\n\n    @SuppressLint(\"ClickableViewAccessibility\")\n    @Override\n    public void onClick(@NonNull View widget) {\n      if (mClickCallback != null) {\n          mClickCallback.onFootnoteClicked(mIndexSequence);\n      }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/image/FootnoteSpan.java",
    "content": "package com.fluid.afm.markdown.image;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.text.style.ReplacementSpan;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport com.fluid.afm.styles.FootnoteStyle;\n\nimport io.noties.markwon.utils.SpanUtils;\nimport com.fluid.afm.utils.Utils;\n\npublic class FootnoteSpan extends ReplacementSpan {\n    private static final int SPACE = Utils.dpToPx(2);\n    private static final int SIZE = Utils.dpToPx(16);\n    private final String mIndexSequence;\n    private final FootnoteStyle mStyle;\n\n    public FootnoteSpan(String indexSequence, FootnoteStyle style) {\n        this.mIndexSequence = indexSequence;\n        mStyle = style;\n    }\n\n    @Override\n    public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, @Nullable Paint.FontMetricsInt fm) {\n        if (mStyle.style() == FootnoteStyle.STYLE_RECTANGLE) {\n            float oldSize = paint.getTextSize();\n            boolean oldBold = paint.isFakeBoldText();\n            paint.setTextSize(mStyle.fontSize());\n            paint.setFakeBoldText(mStyle.isBold());\n            float textW = paint.measureText(mIndexSequence);\n            float result = mStyle.size();\n            if (textW > SIZE) {\n                result = textW + SPACE + SPACE;\n            }\n            paint.setTextSize(oldSize);\n            paint.setFakeBoldText(oldBold);\n            return (int) (result + 0.5f);\n        }\n        if (mStyle.size() > 0) {\n            return (int) (mStyle.size() + SPACE + SPACE);\n        }\n        return SIZE + SPACE + SPACE;\n    }\n\n    @Override\n    public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {\n        if (!SpanUtils.isSelf(start, end, text, this)) {\n            return;\n        }\n        float oldSize = paint.getTextSize();\n        int oldColor = paint.getColor();\n        int saveCount = canvas.save();\n        boolean oldBold = paint.isFakeBoldText();\n\n        if (mStyle.backgroundColor() != 0) {\n            paint.setColor(mStyle.backgroundColor());\n        }\n        float shapeSize = mStyle.size() > 0 ? mStyle.size() : SIZE;\n        float lineHeight = paint.getFontMetrics().descent - paint.getFontMetrics().ascent;\n        float middleY = y - lineHeight / 2f + Utils.FONT_SPACING_IN_LINE * lineHeight;\n        float transY = middleY - shapeSize / 2f;\n        canvas.translate(x + SPACE, transY);\n        if (mStyle.fontSize() > 0) {\n            paint.setTextSize(mStyle.fontSize());\n        }\n        float textW = paint.measureText(mIndexSequence);\n        if (mStyle.style() == FootnoteStyle.STYLE_RECTANGLE) {\n            if (textW > shapeSize) {\n                shapeSize = textW + SPACE + SPACE;\n            }\n            canvas.drawRoundRect(0, 0, shapeSize, shapeSize, mStyle.radius(), mStyle.radius(), paint);\n        } else {\n            canvas.drawCircle(shapeSize / 2f, shapeSize / 2f, shapeSize / 2f, paint);\n        }\n        canvas.restoreToCount(saveCount);\n        if (mStyle.textColor() != 0) {\n            paint.setColor(mStyle.textColor());\n        } else {\n            paint.setColor(oldColor);\n        }\n        if (mStyle.isBold()) {\n             paint.setFakeBoldText(true);\n        }\n        float textHeight = paint.descent() - paint.ascent();\n        float offsetY = (lineHeight - textHeight) / 2;\n        float startX = SPACE + x + (shapeSize - textW) / 2;\n        canvas.drawText(mIndexSequence, startX, y - offsetY, paint);\n        paint.setTextSize(oldSize);\n        paint.setColor(oldColor);\n        paint.setFakeBoldText(oldBold);\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/image/SuperscriptImageSpan.java",
    "content": "package com.fluid.afm.markdown.image;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.graphics.drawable.Drawable;\nimport android.text.style.ImageSpan;\n\nimport androidx.annotation.NonNull;\n\nimport com.fluid.afm.utils.Utils;\n\npublic class SuperscriptImageSpan extends ImageSpan {\n    public static final int ALIGN_TOP = 0x10;\n    public static final int ALIGN_CENTER = 2;\n\n    public SuperscriptImageSpan(@NonNull Drawable drawable) {\n        super(drawable, ALIGN_TOP);\n    }\n\n    public SuperscriptImageSpan(Drawable drawable, int verticalAlignment) {\n        super(drawable, verticalAlignment);\n    }\n\n    @Override\n    public void draw(Canvas canvas, CharSequence text,\n                     int start, int end, float x,\n                     int top, int y, int bottom, Paint paint) {\n        Drawable b = getDrawable();\n        canvas.save();\n        float transY = bottom - b.getBounds().bottom;\n        if (mVerticalAlignment == ALIGN_BASELINE) {\n            transY -= paint.getFontMetricsInt().descent;\n        } else if (mVerticalAlignment == ALIGN_CENTER) {\n            float delta = (b.getBounds().height() - paint.getTextSize() ) / 2;\n            float textTop = y - paint.getTextSize() * Utils.FONT_HEIGHT_IN_LINE;\n            transY = textTop - delta;\n        } else if (mVerticalAlignment == ALIGN_BOTTOM) {\n            transY = bottom - b.getBounds().bottom;\n        } else {\n            transY = top;\n        }\n\n        canvas.translate(x, transY);\n        b.draw(canvas);\n        canvas.restore();\n    }\n}\n\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/list/DefinitionListPlugin.java",
    "content": "package com.fluid.afm.markdown.list;\n\nimport android.text.TextUtils;\n\nimport androidx.annotation.NonNull;\n\nimport com.fluid.afm.utils.MDLogger;\n\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\nimport io.noties.markwon.AbstractMarkwonPlugin;\n\npublic class DefinitionListPlugin extends AbstractMarkwonPlugin {\n    private static final String TAG = \"DefinitionListPlugin\";\n    private static final Pattern TABLE_PATTERN = Pattern.compile(\"\\\\|[ \\\\t]*:?-+:?[ \\\\t]*(\\\\|[ \\\\t]*:?-+:?[ \\\\t]*)*(\\\\|$)?\", Pattern.MULTILINE);\n\n    @Override\n    public String processMarkdown(@NonNull String markdown) {\n        long startTime = System.currentTimeMillis();\n        if (!markdown.contains(\":\")) {\n            return markdown;\n        }\n        \n        if (hasMarkdownTable(markdown)) {\n            return markdown;\n        }\n        \n        if (!hasDefinitionList(markdown)) {\n            return markdown;\n        }\n        return processDefinitionList(markdown, startTime);\n    }\n\n    private boolean hasDefinitionList(String markdown) {\n        int length = markdown.length();\n        boolean newLine = true;\n        boolean hasTerm = false;\n        \n        for (int i = 0; i < length; i++) {\n            char c = markdown.charAt(i);\n            \n            if (c == '\\n') {\n                newLine = true;\n                continue;\n            }\n            \n            if (newLine && (c == ' ' || c == '\\t')) {\n                continue;\n            }\n            \n            if (newLine && c == ':') {\n                if (hasTerm) {\n                    return true;\n                }\n            } else if (newLine) {\n                hasTerm = true;\n            }\n            \n            newLine = false;\n        }\n        \n        return false;\n    }\n\n    private String processDefinitionList(String markdown, long startTime) {\n        StringBuilder result = new StringBuilder(markdown.length() + 100);\n        String[] lines = markdown.split(\"\\n\");\n        \n        int i = 0;\n        boolean lastWasDefinitionList = false;\n        \n        while (i < lines.length) {\n            int start = findDefinitionListStart(lines, i);\n            if (start == -1) {\n                for (int j = i; j < lines.length; j++) {\n                    result.append(lines[j]).append('\\n');\n                }\n                break;\n            }\n            for (int j = i; j < start; j++) {\n                result.append(lines[j]).append('\\n');\n                lastWasDefinitionList = false;\n            }\n            int end = findDefinitionListEnd(lines, start);\n            if (lastWasDefinitionList && start > i) {\n                result.append('\\n');\n            }\n\n            processDefinitionListSection(lines, start, end, result);\n            lastWasDefinitionList = true;\n            \n            i = end + 1;\n            \n            if (i < lines.length && !lines[i].trim().isEmpty()) {\n                result.append('\\n');\n            }\n        }\n        MDLogger.i(TAG,\"processDefinitionList cost: \" + (System.currentTimeMillis() - startTime));\n        return result.toString();\n    }\n    private int findDefinitionListEnd(String[] lines, int startIndex) {\n        boolean inDefinitionList = false;\n        \n        for (int i = startIndex; i < lines.length; i++) {\n            String line = lines[i].trim();\n            \n            if (isOtherMarkdownFormat(line)) {\n                return i - 1;\n            }\n            \n            if (line.isEmpty()) {\n                if (inDefinitionList && (i + 1 >= lines.length || !isDefinitionListLine(lines[i+1]))) {\n                    return i - 1;\n                }\n                continue;\n            }\n            \n            if (!isDefinitionListLine(line) && inDefinitionList) {\n                return i - 1;\n            }\n            \n            if (!line.startsWith(\":\")) {\n                if (i + 1 >= lines.length || !lines[i + 1].trim().startsWith(\":\")) {\n                    if (inDefinitionList) {\n                        return i - 1;\n                    }\n                } else {\n                    inDefinitionList = true;\n                }\n            } else {\n                inDefinitionList = true;\n            }\n        }\n        \n        return lines.length - 1;\n    }\n\n    private boolean isDefinitionListLine(String line) {\n        line = line.trim();\n        if (line.startsWith(\":\")) {\n            return true;\n        }\n        return !isOtherMarkdownFormat(line);\n    }\n\n    private boolean isOtherMarkdownFormat(String line) {\n        return isMarkdownHeader(line) || isMarkdownList(line) || \n               isCodeBlock(line) || isHorizontalRule(line);\n    }\n\n    private int findDefinitionListStart(String[] lines, int startIndex) {\n        for (int i = startIndex; i < lines.length - 1; i++) {\n            String line = lines[i].trim();\n            String nextLine = lines[i + 1].trim();\n            \n            if (!line.isEmpty() && nextLine.startsWith(\":\") &&\n                !isOtherMarkdownFormat(line)) {\n                return i;\n            }\n        }\n        return -1;\n    }\n\n    private void processDefinitionListSection(String[] lines, int start, int end, StringBuilder result) {\n        result.append(\"<dl>\\n\");\n        \n        for (int i = start; i <= end; i++) {\n            String line = lines[i].trim();\n            \n            if (line.isEmpty()) {\n                continue;\n            }\n            \n            if (line.startsWith(\":\")) {\n                String definition = line.substring(1);\n                \n                String trimmedDefinition = definition.trim();\n                if (!trimmedDefinition.isEmpty()) {\n                    result.append(\"  <dd>\").append(trimmedDefinition).append(\"</dd>\\n\");\n                }\n            } else if (i + 1 <= end && lines[i + 1].trim().startsWith(\":\")) {\n                result.append(\"  <dt>\").append(line).append(\"</dt>\\n\");\n            } else {\n                result.append(lines[i]).append('\\n');\n            }\n        }\n        \n        result.append(\"</dl>\\n\");\n    }\n\n    private boolean isMarkdownHeader(String line) {\n        return line.startsWith(\"#\") || line.startsWith(\"=====\") || line.startsWith(\"-----\");\n    }\n\n    private boolean isMarkdownList(String line) {\n        return line.matches(\"^\\\\s*[-*+]\\\\s+.*\") || line.matches(\"^\\\\s*\\\\d+\\\\.\\\\s+.*\");\n    }\n\n    private boolean isCodeBlock(String line) {\n        return line.startsWith(\"```\") || line.startsWith(\"    \") || line.startsWith(\"\\t\");\n    }\n\n    private boolean isHorizontalRule(String line) {\n        return line.matches(\"^\\\\s*(\\\\*\\\\s*){3,}$\") || line.matches(\"^\\\\s*(-\\\\s*){3,}$\") || line.matches(\"^\\\\s*(_\\\\s*){3,}$\");\n    }\n\n    private boolean hasMarkdownTable(String markdown) {\n        if (TextUtils.isEmpty(markdown)) {\n            return false;\n        }\n\n        try {\n            Matcher matcher = TABLE_PATTERN.matcher(markdown);\n            return matcher.find();\n        } catch (Throwable e) {\n            MDLogger.e(TAG,  e);\n            return false;\n        }\n    }\n\n    public static DefinitionListPlugin create() {\n        return new DefinitionListPlugin();\n    }\n} "
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/model/EventModel.java",
    "content": "package com.fluid.afm.markdown.model;\n\nimport androidx.annotation.NonNull;\n\nimport java.util.Objects;\n\npublic class EventModel {\n    public String type;\n    public String url;\n    public String content;\n    public boolean visible;\n\n    public EventModel(String type, String url, String content, boolean visible) {\n        this.type = type;\n        this.url = url;\n        this.content = content;\n        this.visible = visible;\n    }\n\n    @NonNull\n    @Override\n    public String toString() {\n        return \"EventModel{\" +\n                \"type='\" + type + '\\'' +\n                \", url='\" + url + '\\'' +\n                \", content='\" + content + '\\'' +\n                \", visible=\" + visible +\n                '}';\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (!(o instanceof EventModel)) return false;\n        EventModel that = (EventModel) o;\n        return visible == that.visible && Objects.equals(type, that.type) && Objects.equals(url, that.url) && Objects.equals(content, that.content);\n    }\n\n}\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/span/LinkClickSpan.java",
    "content": "package com.fluid.afm.markdown.span;\n\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport android.graphics.Paint;\nimport android.text.TextPaint;\nimport android.text.TextUtils;\nimport android.text.style.LineBackgroundSpan;\nimport android.text.style.URLSpan;\nimport android.view.View;\n\nimport androidx.annotation.NonNull;\n\nimport com.fluid.afm.markdown.ElementClickEventCallback;\nimport com.fluid.afm.utils.ParseUtil;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport io.noties.markwon.RenderProps;\nimport io.noties.markwon.core.CoreProps;\nimport io.noties.markwon.core.MarkwonTheme;\nimport com.fluid.afm.span.IClickableSpan;\n\n\npublic class LinkClickSpan extends URLSpan implements IClickableSpan, LineBackgroundSpan {\n    private final MarkwonTheme theme;\n    private final String link;\n    private final ElementClickEventCallback linkClickCallback;\n    private int mTop = -1;\n    private int mBottom;\n    private final String decoration;\n    private final int color;\n    private final boolean isBold;\n\n\n\n    public LinkClickSpan(String url, RenderProps props, MarkwonTheme theme, ElementClickEventCallback linkClickCallback) {\n        super(url);\n        this.theme = theme;\n        this.link = url;\n        this.linkClickCallback = linkClickCallback;\n        String colorStr = CoreProps.COLOR.get(props);\n        color = ParseUtil.parseColor(colorStr, 0);\n        String fontWeight = CoreProps.FONT_WEIGHT.get(props);\n        isBold = TextUtils.equals(\"bold\", fontWeight);\n        decoration = CoreProps.LINK_TEXT_DECORATION.get(props);\n\n    }\n\n    @Override\n    public void onClick(View widget) {\n        if (linkClickCallback != null) {\n            Map<String, Object> param = new HashMap<>(2);\n            param.put(ElementClickEventCallback.PARAM_KEY_LINK, link);\n            param.put(ElementClickEventCallback.PARAM_KEY_SOURCE, ElementClickEventCallback.SOURCE_TYPE_LINK);\n            if (linkClickCallback.onLinkClicked(param)) {\n                return;\n            }\n        }\n        super.onClick(widget);\n    }\n\n    @Override\n    public void updateDrawState(@NonNull TextPaint ds) {\n        ds.bgColor = Color.TRANSPARENT;\n        theme.applyLinkStyle(ds, color, isBold, decoration);\n    }\n\n    @Override\n    public String getUrl() {\n        return link;\n    }\n\n    @Override\n    public String getType() {\n        return \"link\";\n    }\n\n    @Override\n    public int getTop() {\n        return mTop;\n    }\n\n    @Override\n    public int getBottom() {\n        return mBottom;\n    }\n\n    @Override\n    public void drawBackground(@NonNull Canvas canvas, @NonNull Paint paint, int left, int right, int top, int baseline, int bottom, @NonNull CharSequence text, int start, int end, int lineNumber) {\n        if (mTop == -1) {\n            mTop = top;\n        }\n        if (bottom > mBottom) {\n            mBottom = bottom;\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/span/OpacitySpan.java",
    "content": "package com.fluid.afm.markdown.span;\n\nimport android.text.TextPaint;\nimport android.text.style.CharacterStyle;\nimport android.text.style.UpdateAppearance;\n\npublic class OpacitySpan extends CharacterStyle\n        implements UpdateAppearance {\n\n    private final int opacity;\n\n    public OpacitySpan(int opacity) {\n        this.opacity = opacity;\n    }\n\n    @Override\n    public void updateDrawState(TextPaint tp) {\n        tp.setAlpha(opacity);\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/text/AfmTextPlugin.java",
    "content": "package com.fluid.afm.markdown.text;\n\nimport android.content.Context;\nimport android.graphics.drawable.Drawable;\nimport android.text.SpannableStringBuilder;\nimport android.text.Spanned;\n\nimport androidx.annotation.NonNull;\nimport androidx.appcompat.content.res.AppCompatResources;\n\nimport com.fluid.afm.R;\nimport com.fluid.afm.markdown.ElementClickEventCallback;\nimport com.fluid.afm.markdown.image.CustomImageSpan;\nimport com.fluid.afm.markdown.image.FootnoteClickSpan;\nimport com.fluid.afm.markdown.image.FootnoteSpan;\nimport com.fluid.afm.utils.MDLogger;\nimport com.fluid.afm.utils.Utils;\nimport com.vdurmont.emoji.Emoji;\nimport com.vdurmont.emoji.EmojiManager;\n\nimport org.commonmark.ext.gfm.tables.TableCell;\nimport org.commonmark.node.Text;\n\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\nimport io.noties.markwon.AbstractMarkwonPlugin;\nimport io.noties.markwon.MarkwonVisitor;\n\npublic class AfmTextPlugin extends AbstractMarkwonPlugin {\n    private static final String TAG = AfmTextPlugin.class.getSimpleName();\n    private final Context context;\n    private final int singleLineHeight;\n    private ElementClickEventCallback customClickListener;\n\n    public AfmTextPlugin(Context context) {\n        this.context = context;\n        singleLineHeight = Utils.dpToPx(context, 16);\n    }\n\n    public AfmTextPlugin setCustomClickListener(ElementClickEventCallback callback) {\n        customClickListener = callback;\n        return this;\n    }\n\n    public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) {\n        builder.on(Text.class, (visitor, textNode) -> {\n            String markdown = textNode.getLiteral();\n            Pattern EMOJI_PATTERN = Pattern.compile(\":(\\\\w+):\");\n            Matcher emojiMatch = EMOJI_PATTERN.matcher(markdown);\n            StringBuilder sb = new StringBuilder();\n            int lastIndex = 0;\n            while (emojiMatch.find()) {\n                sb.append(markdown, lastIndex, emojiMatch.start());\n                String emojiCode = emojiMatch.group(1);\n                String emoji = getEmoji(emojiCode);\n                sb.append(emoji);\n                lastIndex = emojiMatch.end();\n            }\n            sb.append(markdown, lastIndex, markdown.length());\n            String newMarkdown = sb.toString();\n            Pattern pattern = Pattern.compile(\"\\\\[\\\\^(.*?)]\");\n            Matcher matcher = pattern.matcher(newMarkdown);\n            SpannableStringBuilder spannable = new SpannableStringBuilder(newMarkdown);\n\n            while (matcher.find()) {\n                int start = matcher.start();\n                int end = matcher.end();\n                String index = matcher.group(1);\n                int leftMargin = Utils.dpToPx(context, 4);\n                MDLogger.d(TAG, \"index = \" + index);\n                if (\"\\\"\".equals(index) || \"”\".equals(index)) {\n                    MDLogger.d(TAG, \"get \\\" or ” \");\n                    Drawable drawable = AppCompatResources.getDrawable(context, R.drawable.quotes_pic);\n                    if (drawable != null) {\n                        drawable.setBounds(leftMargin, 0, singleLineHeight + leftMargin, singleLineHeight);\n                    }\n                    CustomImageSpan imageSpan = new CustomImageSpan(drawable);\n                    spannable.setSpan(imageSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);\n                } else if (textNode.getParent() instanceof TableCell) {\n                    FootnoteInTableSpan span = new FootnoteInTableSpan(index);\n                    spannable.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);\n                } else {\n                    FootnoteSpan footnoteSpan = new FootnoteSpan(index, visitor.configuration().theme().footnoteStyle());\n                    spannable.setSpan(footnoteSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);\n                }\n                end =  index == null ? end : Math.min(start + index.length(), end);\n                spannable.setSpan(new FootnoteClickSpan(index, customClickListener),\n                        start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);\n            }\n            MDLogger.d(TAG, \"spannable = \" + spannable);\n            // Set modified text\n            visitor.builder().append(spannable);\n\n        });\n    }\n\n    private String getEmoji(String emojiCode) {\n        Emoji emoji = EmojiManager.getForAlias(emojiCode);\n        if (emoji != null) {\n            return emoji.getUnicode();\n        }\n        return \":\" + emojiCode + \":\";\n    }\n\n    @androidx.annotation.NonNull\n    @Override\n    public String processMarkdown(@androidx.annotation.NonNull String markdown) {\n        return super.processMarkdown(markdown);\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/text/FootnoteInTableSpan.java",
    "content": "package com.fluid.afm.markdown.text;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.text.style.ReplacementSpan;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\npublic class FootnoteInTableSpan extends ReplacementSpan {\n    private final String footnote;\n\n    public FootnoteInTableSpan(String index) {\n        this.footnote = \"[\" + index + \"]\";\n    }\n\n    @Override\n    public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, @Nullable Paint.FontMetricsInt fm) {\n        return (int) (paint.measureText(footnote) + 0.5f);\n    }\n\n    @Override\n    public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {\n        canvas.drawText(footnote, x, y, paint);\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/text/RoundedBackgroundSpan.java",
    "content": "package com.fluid.afm.markdown.text;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.graphics.RectF;\nimport android.graphics.Typeface;\nimport android.text.Spanned;\nimport android.text.style.ReplacementSpan;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport io.noties.markwon.core.MarkwonTheme;\npublic class RoundedBackgroundSpan extends ReplacementSpan {\n\n    private final MarkwonTheme theme;\n    private float cornerRadius;\n    private final int paddingV;\n    private final int paddingH;\n    private final Typeface typeface;\n\n    public RoundedBackgroundSpan(MarkwonTheme theme, float cornerRadius) {\n        this.theme = theme;\n        this.cornerRadius = cornerRadius;\n        this.cornerRadius = theme.codeStyle().inlineBackgroundRadius();\n        this.paddingV = theme.codeStyle().inlinePaddingVertical();\n        this.paddingH = theme.codeStyle().inlinePaddingHorizontal();\n        typeface = theme.codeStyle().codeTypeface();\n    }\n\n    @Override\n    public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, @Nullable Paint.FontMetricsInt fm) {\n        return (int) (paint.measureText(text, start, end) + paddingH + paddingH);\n    }\n\n    @Override\n    public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {\n        if (!isSelf(start, end, text, this)) {\n            return;\n        }\n        final int oldColor = paint.getColor();\n        final float oldTextSize = paint.getTextSize();\n        final Typeface oldTypeface = paint.getTypeface();\n\n        theme.applyInlineCodeBackgroundColor(paint);\n        paint.setAntiAlias(true);\n\n        Paint.FontMetrics fm = paint.getFontMetrics();\n\n        float backgroundTop = y + fm.ascent - paddingV;\n        float backgroundBottom = y + fm.descent + paddingV;\n\n        RectF rect = new RectF(\n                x,\n                backgroundTop,\n                x + measureTextWidth(paint, text, start, end) + paddingH + paddingH,\n                backgroundBottom\n        );\n        canvas.drawRoundRect(rect, cornerRadius, cornerRadius, paint);\n\n        if (typeface != null) {\n            paint.setTypeface(typeface);\n        }\n        paint.setColor(theme.getInlineCodeTextColor());\n        canvas.drawText(text, start, end, x + paddingH, y, paint);\n\n        paint.setColor(oldColor);\n        paint.setTextSize(oldTextSize);\n        paint.setTypeface(oldTypeface);\n    }\n\n    private static boolean isSelf(int start, int end, CharSequence text, Object span) {\n        final int spanStart = ((Spanned) text).getSpanStart(span);\n        final int spanEnd = ((Spanned) text).getSpanEnd(span);\n        return spanStart <= start && spanEnd >= end - 1;\n    }\n\n    private float measureTextWidth(Paint paint, CharSequence text, int start, int end) {\n        return paint.measureText(text, start, end);\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/markdown/widget/PrinterMarkDownTextView.java",
    "content": "package com.fluid.afm.markdown.widget;\n\nimport android.content.Context;\nimport android.content.ContextWrapper;\nimport android.graphics.Color;\nimport android.graphics.Rect;\nimport android.os.Build;\nimport android.os.Handler;\nimport android.os.Looper;\nimport android.text.Editable;\nimport android.text.Spannable;\nimport android.text.SpannableStringBuilder;\nimport android.text.Spanned;\nimport android.text.TextUtils;\nimport android.text.TextWatcher;\nimport android.text.style.AbsoluteSizeSpan;\nimport android.text.style.CharacterStyle;\nimport android.text.style.ForegroundColorSpan;\nimport android.util.AttributeSet;\nimport android.view.View;\nimport android.view.ViewParent;\n\nimport androidx.annotation.NonNull;\nimport androidx.appcompat.widget.AppCompatTextView;\nimport androidx.lifecycle.DefaultLifecycleObserver;\nimport androidx.lifecycle.LifecycleOwner;\nimport androidx.recyclerview.widget.RecyclerView;\n\nimport com.fluid.afm.IMarkdownLayer;\nimport com.fluid.afm.icon.LoadIconUtil;\nimport com.fluid.afm.markdown.ElementClickEventCallback;\nimport com.fluid.afm.markdown.MarkdownParser;\nimport com.fluid.afm.markdown.MarkdownParserFactory;\nimport com.fluid.afm.markdown.model.EventModel;\nimport com.fluid.afm.markdown.span.OpacitySpan;\nimport com.fluid.afm.span.IClickableSpan;\nimport com.fluid.afm.styles.MarkdownStyles;\nimport com.fluid.afm.utils.MDLogger;\nimport com.fluid.afm.utils.Utils;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\n\nimport io.noties.markwon.image.AsyncDrawableSpan;\n\npublic class PrinterMarkDownTextView extends AppCompatTextView implements IMarkdownLayer, DefaultLifecycleObserver, TextWatcher {\n    private static final String TAG = \"PrinterMarkDownTextView\";\n    public static final String END_MESSAGE = \"(stopped）\";\n    private static final Handler MAIN_HANDLER = new Handler(Looper.getMainLooper());\n\n    private static final int GRADIANT_COUNT = 10;\n    protected MarkdownParser mMarkdownParser;\n    private MarkdownStyles mMarkdownStyles;\n    private ElementClickEventCallback mElementClickEventCallback;\n    protected String mOriginText;\n    private int mExposureNodeCount;\n    private boolean initialedScrollerWatcher = false;\n    private IClickableSpan[] mClickableSpans;\n    private List<EventModel> mEventModels = new ArrayList<>();\n\n    private int mInterval = 25;\n    private int mChunkSize = 1;\n    private SizeChangedListener mSizeChangedListener;\n    private PrintingEventListener mPrintingEventListener;\n    private boolean isPrinting;\n    private boolean isStopByUser;\n    private int mCurrentPrintIndex;\n    private SpannableStringBuilder mParsedContentText;\n    private final Runnable mPrintTask = () -> printing(mCurrentPrintIndex, mChunkSize);\n    private String mEndMessage = END_MESSAGE;\n    private boolean isDestroyed;\n    private OpacitySpan[] mGradiantSpans;\n    private int mHeight;\n    private int maxWidth = 0;\n    private boolean isStarted;\n    private MarkDownPrintData mPrintData;\n\n    public PrinterMarkDownTextView(Context context) {\n        this(context, null);\n    }\n\n    public PrinterMarkDownTextView(Context context, AttributeSet attrs) {\n        this(context, attrs, 0);\n    }\n\n    public PrinterMarkDownTextView(Context context, AttributeSet attrs, int defStyleAttr) {\n        super(context, attrs, defStyleAttr);\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {\n            setFallbackLineSpacing(false);\n        }\n        if (context instanceof LifecycleOwner) {\n            ((LifecycleOwner) context).getLifecycle().addObserver(this);\n        } else if (context instanceof ContextWrapper) {\n            Context realContext = ((ContextWrapper) context).getBaseContext();\n            if (realContext instanceof LifecycleOwner) {\n                ((LifecycleOwner) realContext).getLifecycle().addObserver(this);\n            }\n        }\n\n        setHighlightColor(Color.TRANSPARENT);\n        addTextChangedListener(this);\n        setOnLongClickListener(v -> true);\n    }\n\n    public void init(@NonNull MarkdownStyles styles, ElementClickEventCallback callback) {\n        mMarkdownStyles = styles;\n        mElementClickEventCallback = callback;\n        mMarkdownParser = MarkdownParserFactory.create(getContext(), this, styles, callback);\n    }\n\n    public void setPrintParams(int interval, int chunkSize) {\n        if (mInterval > 0) {\n            mInterval = interval;\n        }\n        if(chunkSize > 0) {\n            mChunkSize = chunkSize;\n        }\n    }\n\n    public void handleExposureSpm() {\n        handleSpm();\n    }\n\n    public void setMarkdownText(@NonNull String markdown) {\n        if (mMarkdownParser == null) {\n            MDLogger.e(TAG, \"PrinterMarkDownTextView is not initialized. Please call init() first.\");\n            return;\n        }\n        mOriginText = markdown;\n        setMinHeight(0);\n        mMarkdownParser.getMarkwon().setMarkdown(this, markdown);\n    }\n\n    public void startPrinting(String content) {\n        startPrinting(content, 0);\n    }\n\n    public boolean isStarted() {\n        return isStarted;\n    }\n\n    public void startPrinting(String content, int startIndex) {\n        if (mMarkdownParser == null) {\n            MDLogger.e(TAG, \"PrinterMarkDownTextView is not initialized. Please call init() first.\");\n            return;\n        }\n        if (isStarted) {\n            MDLogger.e(TAG, \"appendPrinting printing has started!\");\n            return;\n        }\n        setMinHeight(0);\n        mCurrentPrintIndex = 0;\n        isPrinting = true;\n        isStopByUser = false;\n        mOriginText = content;\n        isStarted = true;\n        if (startIndex <= 0) {\n            startIndex = 0;\n        }\n\n        mMarkdownParser.setPrintingState(true);\n        mParsedContentText = new SpannableStringBuilder(mMarkdownParser.getMarkwon().toMarkdown(mOriginText));\n        printing(startIndex, mChunkSize);\n        if (mPrintingEventListener != null) {\n            mPrintingEventListener.onPrintStart();\n        }\n        if (mPrintData != null) {\n            mPrintData.isStopByUser = false;\n            mPrintData.isPrinting = isPrinting;\n            mPrintData.originalText = mOriginText;\n            mPrintData.parsedMarkdownText = mParsedContentText;\n            mPrintData.interval = mInterval;\n            mPrintData.chunkSize = mChunkSize;\n        }\n\n    }\n    public void appendPrinting(String content) {\n        appendPrinting(content, true);\n    }\n\n    public void appendPrinting(String content, boolean append) {\n        if (!isStarted) {\n            MDLogger.e(TAG, \"appendPrinting printing has not started!\");\n            return;\n        }\n        if (append) {\n            mOriginText += content;\n        } else {\n            mOriginText = content;\n        }\n\n        mParsedContentText = new SpannableStringBuilder(mMarkdownParser.getMarkwon().toMarkdown(mOriginText));\n        isStopByUser = false;\n        isPrinting = true;\n        printing(mCurrentPrintIndex, mChunkSize);\n        if (mPrintData != null) {\n            mPrintData.isPrinting = isPrinting;\n            mPrintData.originalText = mOriginText;\n            mPrintData.parsedMarkdownText = mParsedContentText;\n        }\n    }\n    public void setPrintData(MarkDownPrintData printData) {\n        mPrintData = printData;\n    }\n\n    public MarkDownPrintData getPrintData() {\n        return mPrintData;\n    }\n\n    public void stopPrinting(String endMessage) {\n        if (!isStarted) {\n            MDLogger.e(TAG, \"appendPrinting printing has not started!\");\n            return;\n        }\n        isStarted = false;\n        if (!isPrinting) {\n            return;\n        }\n        mEndMessage = endMessage;\n        isStopByUser = true;\n        MAIN_HANDLER.removeCallbacks(mPrintTask);\n        isPrinting = false;\n        mMarkdownParser.setPrintingState(false);\n        if (!TextUtils.isEmpty(endMessage)) {\n            mEndMessage = endMessage;\n        }\n        clearGradient();\n        boolean printAll = mCurrentPrintIndex >= mParsedContentText.length() - 1;\n        SpannableStringBuilder span = handleSpan(mParsedContentText, mCurrentPrintIndex, printAll ? null : mEndMessage);\n        if (!printAll) {\n            setEndMessageStyle(span);\n        }\n        setTextSafely(span);\n        if (mPrintingEventListener != null) {\n            mPrintingEventListener.onPrintStop(printAll);\n        }\n        if (mPrintData != null) {\n            mPrintData.showingText = span;\n            mPrintData.isPrinting = isPrinting;\n            mPrintData.isStopByUser = isStopByUser;\n        }\n    }\n\n    public void restore(MarkDownPrintData markDownData) {\n        MDLogger.d(TAG, \"restore-markDownData:\" + markDownData);\n        if (markDownData == null || TextUtils.isEmpty(markDownData.showingText)) {\n            return;\n        }\n        if (mPrintData == markDownData) {\n            return;\n        }\n        mPrintData = markDownData;\n        setMinHeight(0);\n        mParsedContentText = mPrintData.parsedMarkdownText;\n        mCurrentPrintIndex = mPrintData.currentIndex;\n        mChunkSize = mPrintData.chunkSize;\n        mInterval = mPrintData.interval;\n        isPrinting = mPrintData.isPrinting;\n        isStopByUser = mPrintData.isStopByUser;\n        setTextSafely(mPrintData.showingText);\n        mOriginText = mPrintData.originalText;\n        if (isPrinting && !isStopByUser) {\n            printing(mCurrentPrintIndex, mChunkSize);\n        }\n        handleSpm();\n    }\n\n    public void setSizeChangedListener(SizeChangedListener listener) {\n        mSizeChangedListener = listener;\n    }\n\n    public void setPrintingEventListener(PrintingEventListener listener) {\n        mPrintingEventListener = listener;\n    }\n\n    public void pause() {\n        if (!isStarted) {\n            MDLogger.e(TAG, \"appendPrinting printing has not started!\");\n            return;\n        }\n        isPrinting = false;\n        mMarkdownParser.setPrintingState(false);\n        MAIN_HANDLER.removeCallbacks(mPrintTask);\n        if (mPrintingEventListener != null) {\n            mPrintingEventListener.onPrintPaused(mCurrentPrintIndex);\n        }\n    }\n\n    public void resume() {\n        resume(mCurrentPrintIndex);\n    }\n\n    public void resume(int index) {\n        if (!isStarted) {\n            MDLogger.e(TAG, \"appendPrinting printing has not started!\");\n            return;\n        }\n        if (isPrinting) {\n            return;\n        }\n        isStopByUser = false;\n        isPrinting = true;\n        if (index <= mParsedContentText.length()) {\n            mMarkdownParser.setPrintingState(true);\n            printing(mCurrentPrintIndex, mChunkSize);\n        }\n        if (mPrintingEventListener != null) {\n            mPrintingEventListener.onPrintResumed();\n        }\n    }\n\n    @Override\n    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {\n        super.onMeasure(widthMeasureSpec, heightMeasureSpec);\n        int newHeight = getMeasuredHeight();\n        if (newHeight != mHeight ) {\n            if (mSizeChangedListener != null) {\n                mSizeChangedListener.onSizeChanged(getMeasuredWidth(), newHeight);\n            }\n            if(newHeight > mHeight) {\n                setMinHeight(newHeight);\n            }\n            mHeight = newHeight;\n        }\n    }\n\n    private void printing(int start, int chunkSize) {\n        if (isDestroyed) {\n            return;\n        }\n        int end = start + chunkSize;\n        if (end >= mParsedContentText.length()) {\n            MDLogger.i(TAG, \"end >= spannablePrintText.length()\");\n            isPrinting = false;\n            mMarkdownParser.setPrintingState(false);\n            setTextSafely(mParsedContentText);\n            onStopPrinting();\n        } else {\n            SpannableStringBuilder newSpannable = handleSpan(mParsedContentText, end);\n            if (newSpannable == null) {\n                return;\n            }\n            mCurrentPrintIndex = end;\n            gradiantColorAnimateText(mCurrentPrintIndex, newSpannable);\n            setTextSafely(newSpannable);\n            if (!isStopByUser) {\n                MAIN_HANDLER.removeCallbacks(mPrintTask);\n                MAIN_HANDLER.postDelayed(mPrintTask, mInterval);\n            } else {\n                MAIN_HANDLER.removeCallbacks(mPrintTask);\n                MDLogger.i(TAG, \"printing---isStopByUser==true\");\n                isPrinting = false;\n                onStopPrinting();\n            }\n        }\n        if (mPrintData != null) {\n            mPrintData.currentIndex = mCurrentPrintIndex;\n        }\n\n    }\n\n    private void clearGradient() {\n        if (mGradiantSpans == null) {\n            return;\n        }\n        mParsedContentText.removeSpan(OpacitySpan.class);\n    }\n\n    /**\n     * 实现渐变打字的动画\n     */\n    private void gradiantColorAnimateText(int endIndex, SpannableStringBuilder spannableStringBuilder) {\n        if (endIndex == mParsedContentText.length()) {\n            return;\n        }\n        if (mGradiantSpans == null) {\n            mGradiantSpans = new OpacitySpan[GRADIANT_COUNT];\n            for (int i = 0; i < GRADIANT_COUNT; i++) {\n                int alpha = (int) (255f * i / GRADIANT_COUNT);\n                mGradiantSpans[GRADIANT_COUNT - i - 1] = new OpacitySpan(alpha);\n            }\n        }\n\n        for (int i = 0; i < GRADIANT_COUNT; i++) {\n            int textIndex = endIndex - i - 1;\n            if (textIndex < 0) {\n                break;\n            }\n            spannableStringBuilder.setSpan(mGradiantSpans[GRADIANT_COUNT - i - 1], textIndex, textIndex + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);\n        }\n    }\n\n    private SpannableStringBuilder handleSpan(SpannableStringBuilder source, int end) {\n        return handleSpan(source, end, \"\");\n    }\n\n    private SpannableStringBuilder handleSpan(SpannableStringBuilder source, int end, String endTag) {\n        SpannableStringBuilder newSpannable;\n        if (TextUtils.isEmpty(endTag)) {\n            newSpannable = new SpannableStringBuilder(source.subSequence(0, end));\n        } else {\n            newSpannable = new SpannableStringBuilder(source.subSequence(0, end)).append(endTag);\n        }\n        CharacterStyle[] spans = source.getSpans(0, end, CharacterStyle.class);\n        if (spans == null) {\n            return null;\n        }\n        for (CharacterStyle span : spans) {\n            if (span == null) {\n                continue;\n            }\n            int spanStart = source.getSpanStart(span);\n            int spanEnd = source.getSpanEnd(span);\n            int flags = source.getSpanFlags(span);\n\n            newSpannable.setSpan(span, spanStart, Math.min(spanEnd, end), flags);\n        }\n\n        return newSpannable;\n    }\n\n    private void onStopPrinting() {\n        if (mPrintingEventListener != null) {\n            mPrintingEventListener.onPrintStop(mParsedContentText == null || mCurrentPrintIndex == mParsedContentText.length());\n        }\n    }\n\n    private void setEndMessageStyle(SpannableStringBuilder span) {\n        if (TextUtils.isEmpty(mEndMessage)) {\n            return;\n        }\n        // 设置颜色\n        span.setSpan(\n                new ForegroundColorSpan(Color.parseColor(\"#999999\")),\n                span.length() - mEndMessage.length(),\n                span.length(),\n                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE\n        );\n        // 设置字体大小\n        span.setSpan(\n                new AbsoluteSizeSpan(Utils.dpToPx(getContext(), 13), false),\n                span.length() - mEndMessage.length(),\n                span.length(),\n                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE\n        );\n    }\n\n    public void onDestroy() {\n        LoadIconUtil.check();\n        isDestroyed = true;\n        mPrintData = null;\n    }\n\n    @Override\n    public void onDestroy(@NonNull LifecycleOwner l) {\n        onDestroy();\n    }\n\n\n    public void setMarkdownStyles(MarkdownStyles markdownStyles) {\n        if (mMarkdownParser != null) {\n            mMarkdownStyles = markdownStyles;\n            mMarkdownParser.updateMarkdownStyles(markdownStyles);\n        }\n    }\n\n    public void setTextSafely(SpannableStringBuilder spanned) {\n        if (mMarkdownParser != null) {\n            mMarkdownParser.getMarkwon().setParsedMarkdown(this, spanned);\n        }\n        if (mPrintData != null && spanned != null) {\n            mPrintData.showingText = spanned;\n        }\n    }\n\n    public void setMaxWidthForMeasure(int maxWidth) {\n        this.maxWidth = maxWidth;\n    }\n\n    @Override\n    public int getViewMaxWidth() {\n        return maxWidth;\n    }\n\n    @Override\n    public String getOriginText() {\n        return mOriginText;\n    }\n\n    @Override\n    public void beforeTextChanged(CharSequence s, int start, int count, int after) {\n        /* no-op */\n\n    }\n\n    @Override\n    public void onTextChanged(CharSequence s, int start, int before, int count) {\n        /* no-op */\n    }\n\n    @Override\n    public void afterTextChanged(Editable s) {\n        if (mElementClickEventCallback == null) {\n            return;\n        }\n        CharSequence str = getText();\n        if (!(str instanceof Spannable)) {\n            return;\n        }\n        Spanned spanned = (Spanned) str;\n        if (spanned.length() == 0) {\n            return;\n        }\n        IClickableSpan[] clickableSpans = spanned.getSpans(0, spanned.length(), IClickableSpan.class);\n        if (clickableSpans == null || clickableSpans.length == mExposureNodeCount) {\n            return;\n        }\n        mClickableSpans = clickableSpans;\n        handleScrollerSpm();\n        mExposureNodeCount = clickableSpans.length;\n        post(() -> handleSpm(clickableSpans));\n    }\n\n    private void handleScrollerSpm() {\n        if (initialedScrollerWatcher || mClickableSpans == null) {\n            return;\n        }\n        initialedScrollerWatcher = true;\n        View scroller = findScroller(getParent());\n        if (scroller instanceof RecyclerView) {\n            ((RecyclerView)scroller).addOnScrollListener(new RecyclerView.OnScrollListener() {\n                @Override\n                public void onScrollStateChanged(RecyclerView recyclerView, int state) {\n                    super.onScrollStateChanged(recyclerView, state);\n                    if (state == RecyclerView.SCROLL_STATE_IDLE) {\n                        handleSpm(mClickableSpans);\n                    }\n                }\n            });\n        } else if (scroller != null) {\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n                scroller.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> handleSpm(mClickableSpans));\n            }\n\n        }\n    }\n\n    private View findScroller(ViewParent child) {\n        ViewParent parent = child.getParent();\n        if (parent instanceof View && (parent instanceof RecyclerView || ((View)parent).isScrollContainer())) {\n            return (View) parent;\n        } else if (parent == null) {\n            return null;\n        }\n        return findScroller(parent);\n    }\n\n    private void handleSpm() {\n        if (mClickableSpans == null || mClickableSpans.length == 0) {\n            return;\n        }\n        handleSpm(mClickableSpans);\n    }\n    private void handleSpm(IClickableSpan[] spans) {\n        if (spans == null || spans.length == 0) {\n            return;\n        }\n        Rect rect = new Rect();\n        boolean isVisible = getGlobalVisibleRect(rect);\n        MDLogger.d(TAG, \"updateEventLogList:rect:\" + rect + \" rect isVisible:\" + isVisible);\n\n        int startY = 0;\n        int endY = 0;\n        if (isVisible) {\n            int[] pos = new int[2];\n            getLocationOnScreen(pos);\n            startY = rect.top - pos[1];\n            endY = startY + rect.height();\n            MDLogger.d(TAG, \"updateEventLogList:location:\" + Arrays.toString(pos) + \",startY:\" + startY + \",endY:\" + endY);\n        }\n        List<EventModel> models = new ArrayList<>();\n        for (IClickableSpan span : spans) {\n            if (span instanceof AsyncDrawableSpan && !((AsyncDrawableSpan) span).isClickable()) {\n                return;\n            }\n            boolean visible = (span.getTop() > startY && span.getTop() < endY) // visible Top\n                    || span.getBottom() > startY && span.getBottom() < endY; // visible Bottom\n            MDLogger.d(TAG, \"updateEventLogList:\" + span.getClass().getSimpleName() + \" span.getTop():\" + span.getTop() + \", span.getBottom()\" + span.getBottom() + \",visible:\" + visible);\n            models.add(new EventModel(span.getType(), span.getUrl(), span.getLiteral(), visible));\n        }\n        if (models.equals( mEventModels)) {\n            return;\n        }\n        this.mEventModels = models;\n        if (mElementClickEventCallback != null) {\n            mElementClickEventCallback.exposureSpmBehavior(models);\n        }\n    }\n\n    public int getPrintIndex() {\n        return mCurrentPrintIndex;\n    }\n\n    public interface SizeChangedListener {\n        void onSizeChanged(int width, int height);\n    }\n\n    public interface PrintingEventListener {\n        void onPrintStart();\n\n        void onPrintStop(boolean printAll);\n        void onPrintPaused(int index);\n\n        void onPrintResumed();\n    }\n    public static class MarkDownPrintData {\n        public int chunkSize;\n        public int interval;\n        public boolean isPrinting;\n        public boolean isStopByUser;\n        public String originalText;\n        public SpannableStringBuilder showingText; // showingData\n        public SpannableStringBuilder parsedMarkdownText; // fullData\n        public int currentIndex;\n        public boolean hasBoundView;\n\n        @Override\n        public String toString() {\n            return \"MarkDownPrintData{\" +\n                    \"chunkSize=\" + chunkSize +\n                    \", speed=\" + interval +\n                    \", isPrinting=\" + isPrinting +\n                    \", showingText='\" + showingText + '\\'' +\n                    \", printingText='\" + parsedMarkdownText + '\\'' +\n                    \", currentIndex=\" + currentIndex +\n                    \", createdView=\" + hasBoundView +\n                    '}';\n        }\n    }\n\n}\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/ui/MarkDownPreviewActivity.java",
    "content": "package com.fluid.afm.ui;\n\nimport android.annotation.SuppressLint;\nimport android.content.pm.ActivityInfo;\nimport android.graphics.Color;\nimport android.os.Build;\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.Looper;\nimport android.text.TextUtils;\nimport android.view.View;\nimport android.view.WindowManager;\n\nimport androidx.appcompat.app.AppCompatActivity;\nimport androidx.recyclerview.widget.LinearLayoutManager;\nimport androidx.recyclerview.widget.RecyclerView;\n\nimport com.fluid.afm.R;\nimport com.fluid.afm.TableBlockTitleBlockSpan;\nimport com.fluid.afm.markdown.MarkdownParserFactory;\nimport com.fluid.afm.markdown.widget.PrinterMarkDownTextView;\nimport com.fluid.afm.styles.CodeStyle;\nimport com.fluid.afm.styles.MarkdownStyles;\nimport com.fluid.afm.styles.TableStyle;\nimport com.fluid.afm.utils.MDLogger;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport io.noties.markwon.Markwon;\nimport io.noties.markwon.MarkwonPlugin;\nimport io.noties.markwon.core.MarkwonTheme;\nimport io.noties.markwon.ext.tables.TablePlugin;\n\npublic class MarkDownPreviewActivity extends AppCompatActivity {\n    public static final String TAG = \"MarkDownPreviewActivity\";\n    private String markdownContent;\n    private RecyclerView recyclerView;\n    private MarkdownContentAdapter adapter;\n    private Markwon markwon;\n    private final Handler mainHandler = new Handler(Looper.getMainLooper());\n    private TableStyle tableStyle;\n    private CodeStyle codeStyle;\n    private int columnCount = 0;\n    private boolean isTable = false;\n\n    @SuppressLint(\"SetTextI18n\")\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        initLayout();\n        initViews();\n        if (getIntentParams()) {\n            setContent(markdownContent);\n        }\n    }\n\n    private void initLayout() {\n        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,\n                WindowManager.LayoutParams.FLAG_FULLSCREEN);\n        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n            getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);\n        } else {\n            getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);\n        }\n        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);\n        getWindow().setStatusBarColor(Color.TRANSPARENT);\n        WindowManager.LayoutParams attributes = getWindow().getAttributes();\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {\n            attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;\n            getWindow().setAttributes(attributes);\n        }\n        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);\n        setContentView(R.layout.activity_magnify_table);\n    }\n\n    private void initViews() {\n        View back = findViewById(R.id.back);\n        recyclerView = findViewById(R.id.recyclerView);\n\n        // 设置RecyclerView\n        recyclerView.setLayoutManager(new LinearLayoutManager(this));\n        recyclerView.setHasFixedSize(true);\n        recyclerView.setItemViewCacheSize(1);\n        recyclerView.setNestedScrollingEnabled(false); // 禁用嵌套滚动，避免冲突\n\n        back.setOnClickListener(v -> onBackPressed());\n    }\n\n    private boolean getIntentParams() {\n        Bundle launchParam = getIntent().getExtras();\n        if (launchParam == null) {\n            MDLogger.e(TAG, \"Launch params is null\");\n            return false;\n        }\n        markdownContent = launchParam.getString(\"content\", \"\");\n        tableStyle = launchParam.getParcelable(\"tableStyle\");\n        codeStyle = launchParam.getParcelable(\"codeStyle\");\n        columnCount = launchParam.getInt(\"columnCount\", 0);\n        isTable = launchParam.getBoolean(\"isTable\", false);\n        if (TextUtils.isEmpty(markdownContent) && (!isTable || TableBlockTitleBlockSpan.getCurrentTableBlock() == null)) {\n            MDLogger.e(TAG, \"Both table_content and code_content are empty\");\n            return false;\n        }\n\n        MDLogger.d(TAG, \"markdownContent = \" + markdownContent +\" TableBlockTitleBlockSpan.getCurrentTableBlock()=\" + TableBlockTitleBlockSpan.getCurrentTableBlock());\n        return true;\n    }\n\n    private void setContent(String content) {\n        try {\n            PrinterMarkDownTextView textView = null;\n            if (markwon == null) {\n                textView = new PrinterMarkDownTextView(this);\n                MarkdownStyles style = MarkdownStyles.getDefaultStyles();\n                if (tableStyle == null) {\n                    tableStyle = style.tableStyle();\n                } else {\n                    style.tableStyle(tableStyle);\n                }\n                if (codeStyle != null) {\n                    codeStyle.drawBorder(false);\n                    style.codeStyle(codeStyle);\n                }\n                TablePlugin tablePlugin = TablePlugin.create(this, true);\n                List<MarkwonPlugin> plugins = new ArrayList<>(MarkdownParserFactory.getPlugins(this, textView, tablePlugin));\n                MarkwonTheme theme = MarkwonTheme.builderWithDefaults(this).setStyles(style).build(plugins);\n                markwon = Markwon.builderWithPlugs(this, plugins).setMarkdownTheme(theme).build();\n            }\n\n            if (adapter == null) {\n                adapter = new MarkdownContentAdapter(markwon, isTable, columnCount, textView);\n                recyclerView.setAdapter(adapter);\n            }\n            if (TableBlockTitleBlockSpan.getCurrentTableBlock() != null) {\n                adapter.setTableBlockNode(TableBlockTitleBlockSpan.getCurrentTableBlock());\n            } else {\n                adapter.setContent(content);\n            }\n        } catch (Throwable tr) {\n            MDLogger.e(TAG, \"Error initializing markwon: \" + tr.getMessage(), tr);\n        }\n    }\n\n    @Override\n    protected void onDestroy() {\n        super.onDestroy();\n        markwon = null;\n        adapter = null;\n        recyclerView.setAdapter(null);\n        mainHandler.removeCallbacksAndMessages(null);\n        TableBlockTitleBlockSpan.setCurrentTableBlock(null);\n    }\n}\n\n\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/ui/MarkdownContentAdapter.java",
    "content": "package com.fluid.afm.ui;\n\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.TextView;\n\nimport androidx.recyclerview.widget.LinearLayoutManager;\nimport androidx.recyclerview.widget.RecyclerView;\n\nimport com.fluid.afm.R;\n\nimport org.commonmark.ext.gfm.tables.TableBlock;\n\nimport io.noties.markwon.Markwon;\n\npublic class MarkdownContentAdapter extends RecyclerView.Adapter<MarkdownContentAdapter.ViewHolder> {\n    private final MarkdownTextAdapter textAdapter;\n\n\n    public MarkdownContentAdapter(Markwon markwon, boolean isTable, int columnCount, TextView textView) {\n        this.textAdapter = new MarkdownTextAdapter(markwon, isTable, columnCount, textView);\n    }\n\n    public void setContent(String content) {\n        textAdapter.setContent(content);\n        notifyDataSetChanged();\n    }\n    public void setTableBlockNode(TableBlock block) {\n        textAdapter.setTableBlockNode( block);\n        notifyDataSetChanged();\n    }\n\n\n    @Override\n    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {\n        View view = LayoutInflater.from(parent.getContext())\n                .inflate(R.layout.item_markdown_content, parent, false);\n        return new ViewHolder(view);\n    }\n\n    @Override\n    public void onBindViewHolder(ViewHolder holder, int position) {\n        holder.horizontalRecyclerView.setLayoutManager(new LinearLayoutManager(holder.itemView.getContext(), LinearLayoutManager.HORIZONTAL, false));\n        holder.horizontalRecyclerView.setHasFixedSize(true);\n        holder.horizontalRecyclerView.setItemViewCacheSize(1);\n        holder.horizontalRecyclerView.setAdapter(textAdapter);\n    }\n\n    @Override\n    public int getItemCount() {\n        return 1;\n    }\n\n    static class ViewHolder extends RecyclerView.ViewHolder {\n        final RecyclerView horizontalRecyclerView;\n\n        ViewHolder(View itemView) {\n            super(itemView);\n            horizontalRecyclerView = itemView.findViewById(R.id.horizontalRecyclerView);\n        }\n    }\n} "
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/java/com/fluid/afm/ui/MarkdownTextAdapter.java",
    "content": "package com.fluid.afm.ui;\n\nimport android.text.Spanned;\nimport android.util.TypedValue;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.TextView;\n\nimport androidx.recyclerview.widget.RecyclerView;\n\nimport com.fluid.afm.R;\nimport com.fluid.afm.markdown.widget.PrinterMarkDownTextView;\n\nimport org.commonmark.ext.gfm.tables.TableBlock;\n\nimport io.noties.markwon.Markwon;\nimport com.fluid.afm.utils.Utils;\n\npublic class MarkdownTextAdapter extends RecyclerView.Adapter<MarkdownTextAdapter.ViewHolder> {\n    private String content;\n    private final Markwon markwon;\n    private final boolean isTable;\n    private final int columnCount;\n    private int tableWidth;\n    private final TextView mTextView;\n    private Spanned spanned;\n\n    public MarkdownTextAdapter(Markwon markwon, boolean isTable, int columnCount, TextView textView) {\n        this.markwon = markwon;\n        this.isTable = isTable;\n        this.columnCount = columnCount;\n        mTextView = textView;\n        if (mTextView != null) {\n            mTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);\n            int padding = Utils.dpToPx(16);\n            mTextView.setPadding(padding, padding, padding, padding);\n        }\n    }\n\n    public void setContent(String content) {\n        this.content = content;\n        notifyDataSetChanged();\n    }\n\n    public void setTableBlockNode(TableBlock block) {\n        spanned = markwon.render(block);\n        notifyDataSetChanged();\n    }\n\n    @Override\n    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {\n\n        View view = mTextView == null ? LayoutInflater.from(parent.getContext())\n                .inflate(R.layout.item_markdown_text, parent, false) : mTextView;\n\n        ViewHolder viewHolder = new ViewHolder(view);\n        if (isTable) {\n            if (tableWidth == 0) {\n                if (columnCount >= 6) {\n                    int screenW = parent.getContext().getResources().getDisplayMetrics().widthPixels;\n                    tableWidth = (int) (screenW / 5.5f) * columnCount;\n                } else {\n                    tableWidth = ViewGroup.LayoutParams.MATCH_PARENT;\n                }\n            }\n            ViewGroup.LayoutParams params = viewHolder.textView.getLayoutParams();\n            if (params == null) {\n                params = new ViewGroup.LayoutParams(tableWidth, ViewGroup.LayoutParams.WRAP_CONTENT);\n            }\n            params.width = tableWidth;\n            viewHolder.textView.setMaxWidthForMeasure(tableWidth > 0 ? tableWidth : parent.getMeasuredWidth());\n            viewHolder.textView.setLayoutParams(params);\n        }\n        return viewHolder;\n    }\n\n    @Override\n    public void onBindViewHolder(ViewHolder holder, int position) {\n        if (spanned != null) {\n            markwon.setParsedMarkdown(holder.textView, spanned);\n        } else if (content != null) {\n            markwon.setMarkdown(holder.textView, content);\n        }\n    }\n\n    @Override\n    public int getItemCount() {\n        return 1;\n    }\n\n    static class ViewHolder extends RecyclerView.ViewHolder {\n        final PrinterMarkDownTextView textView;\n\n        ViewHolder(View itemView) {\n            super(itemView);\n            if (itemView instanceof TextView) {\n                textView = (PrinterMarkDownTextView) itemView;\n            } else {\n                textView = itemView.findViewById(R.id.mk_textView);\n            }\n        }\n    }\n} "
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/res/drawable/back.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\" android:autoMirrored=\"true\" android:height=\"24dp\" android:tint=\"#000000\" android:viewportHeight=\"24\" android:viewportWidth=\"24\" android:width=\"24dp\">\n      \n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z\"/>\n    \n</vector>\n"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/res/drawable/bg_shape_ffffffff_12.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <corners android:radius=\"12dp\" />\n    <solid android:color=\"#FFFFFF\" />\n</shape>"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/res/drawable/default_placeholderdefault.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <size\n        android:width=\"638px\"\n        android:height=\"360px\" />\n    <solid android:color=\"#ccc\" />\n    <corners android:radius=\"6dp\" />\n</shape>"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/res/drawable/ic_triangle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"100dp\"\n    android:height=\"50dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:pathData=\"M12,0 L0,24 L24,24 Z\" />\n</vector>"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/res/layout/activity_magnify_table.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:id=\"@+id/rl_root\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:fitsSystemWindows=\"true\"\n    android:background=\"@color/white\"\n    android:orientation=\"vertical\"\n    tools:ignore=\"ResAuto\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"horizontal\">\n\n        <ImageView\n            android:id=\"@+id/back\"\n            android:layout_width=\"24dp\"\n            android:layout_height=\"24dp\"\n            android:layout_marginLeft=\"16dp\"\n            android:layout_marginTop=\"12dp\"\n            android:layout_marginBottom=\"12dp\"\n            android:contentDescription=\"@string/back\"\n            android:src=\"@drawable/back\"/>\n    </LinearLayout>\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:id=\"@+id/recyclerView\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:layout_weight=\"1\"\n        android:scrollbars=\"vertical\"\n        android:overScrollMode=\"never\"\n        android:fadeScrollbars=\"true\"\n        android:hardwareAccelerated=\"true\" />\n\n</LinearLayout>"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/res/layout/item_markdown_content.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.recyclerview.widget.RecyclerView\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:id=\"@+id/horizontalRecyclerView\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:scrollbars=\"horizontal\"\n    android:overScrollMode=\"never\"\n    android:fadeScrollbars=\"true\"\n    android:hardwareAccelerated=\"true\" /> "
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/res/layout/item_markdown_text.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.fluid.afm.markdown.widget.MarkdownTextView\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:id=\"@+id/mk_textView\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"wrap_content\"\n    android:padding=\"16dp\"\n    android:textSize=\"14sp\"\n    android:hardwareAccelerated=\"true\" />"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"white\">#FFFFFF</color>\n</resources>"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/res/values/dimes.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <dimen name=\"chat_bubble_paddingH\">16dp</dimen>\n</resources>"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/res/values/ids.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <item type=\"id\" name=\"markdown_need_animation\"/>\n</resources>"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/res/values/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <string name=\"back\">返回</string>\n</resources>"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/main/res/values/themes.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n    <style name=\"Theme.Preview\" parent=\"Theme.AppCompat.Light.NoActionBar\">\n    </style>\n\n</resources>"
  },
  {
    "path": "Android/AntFluid/fluid-markdown/src/test/java/com/fluid/afm/ExampleUnitTest.java",
    "content": "package com.fluid.afm;\n\nimport static org.junit.Assert.assertEquals;\n\nimport org.junit.Test;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "Android/AntFluid/gradle/libs.versions.toml",
    "content": "[versions]\nagp = \"8.9.1\"\nkotlin = \"2.0.21\"\ncoreKtx = \"1.16.0\"\njunit = \"4.13.2\"\njunitVersion = \"1.2.1\"\nespressoCore = \"3.6.1\"\nlifecycleRuntimeKtx = \"2.9.1\"\nactivityCompose = \"1.10.1\"\ncomposeBom = \"2024.09.00\"\nappcompat = \"1.6.1\"\nmaterial = \"1.10.0\"\nrecyclerview = \"1.4.0\"\nactivity = \"1.10.1\"\nconstraintlayout = \"2.2.1\"\n\n[libraries]\nandroidx-core-ktx = { group = \"androidx.core\", name = \"core-ktx\", version.ref = \"coreKtx\" }\njunit = { group = \"junit\", name = \"junit\", version.ref = \"junit\" }\nandroidx-junit = { group = \"androidx.test.ext\", name = \"junit\", version.ref = \"junitVersion\" }\nandroidx-espresso-core = { group = \"androidx.test.espresso\", name = \"espresso-core\", version.ref = \"espressoCore\" }\nandroidx-lifecycle-runtime-ktx = { group = \"androidx.lifecycle\", name = \"lifecycle-runtime-ktx\", version.ref = \"lifecycleRuntimeKtx\" }\nandroidx-activity-compose = { group = \"androidx.activity\", name = \"activity-compose\", version.ref = \"activityCompose\" }\nandroidx-compose-bom = { group = \"androidx.compose\", name = \"compose-bom\", version.ref = \"composeBom\" }\nandroidx-ui = { group = \"androidx.compose.ui\", name = \"ui\" }\nandroidx-ui-graphics = { group = \"androidx.compose.ui\", name = \"ui-graphics\" }\nandroidx-ui-tooling = { group = \"androidx.compose.ui\", name = \"ui-tooling\" }\nandroidx-ui-tooling-preview = { group = \"androidx.compose.ui\", name = \"ui-tooling-preview\" }\nandroidx-ui-test-manifest = { group = \"androidx.compose.ui\", name = \"ui-test-manifest\" }\nandroidx-ui-test-junit4 = { group = \"androidx.compose.ui\", name = \"ui-test-junit4\" }\nandroidx-material3 = { group = \"androidx.compose.material3\", name = \"material3\" }\nandroidx-appcompat = { group = \"androidx.appcompat\", name = \"appcompat\", version.ref = \"appcompat\" }\nmaterial = { group = \"com.google.android.material\", name = \"material\", version.ref = \"material\" }\nandroidx-recyclerview = { group = \"androidx.recyclerview\", name = \"recyclerview\", version.ref = \"recyclerview\" }\nandroidx-activity = { group = \"androidx.activity\", name = \"activity\", version.ref = \"activity\" }\nandroidx-constraintlayout = { group = \"androidx.constraintlayout\", name = \"constraintlayout\", version.ref = \"constraintlayout\" }\n\n[plugins]\nandroid-application = { id = \"com.android.application\", version.ref = \"agp\" }\nkotlin-android = { id = \"org.jetbrains.kotlin.android\", version.ref = \"kotlin\" }\nkotlin-compose = { id = \"org.jetbrains.kotlin.plugin.compose\", version.ref = \"kotlin\" }\nandroid-library = { id = \"com.android.library\", version.ref = \"agp\" }\n\n"
  },
  {
    "path": "Android/AntFluid/gradle/wrapper/gradle-wrapper.properties",
    "content": "#Tue Aug 05 12:12:33 CST 2025\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://mirrors.aliyun.com/macports/distfiles/gradle/gradle-8.11.1-bin.zip\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "Android/AntFluid/gradle.properties",
    "content": "# Project-wide Gradle settings.\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\norg.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. For more details, visit\n# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects\n# org.gradle.parallel=true\n# AndroidX package structure to make it clearer which packages are bundled with the\n# Android operating system, and which are packaged with your app's APK\n# https://developer.android.com/topic/libraries/support-library/androidx-rn\nandroid.useAndroidX=true\n# Kotlin code style for this project: \"official\" or \"obsolete\":\nkotlin.code.style=official\n# Enables namespacing of each library's R class so that its R class includes only the\n# resources declared in the library itself and none from the library's dependencies,\n# thereby reducing the size of the R class for that library\nandroid.nonTransitiveRClass=true\n\n\n# License information\nPOM_LICENSE_NAME=Apache License 2.0\nPOM_LICENSE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt\nPOM_LICENSE_DIST=repo\n\n# Original library information\nORIGINAL_LIB_NAME=Markwon\nORIGINAL_LIB_URL=https://github.com/noties/Markwon\nORIGINAL_LIB_LICENSE=Apache License 2.0\nORIGINAL_OM_LICENSE_NAME=The Apache Software License, Version 2.0\nORIGINAL_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt\nORIGINAL_LICENCE_DIST=repo"
  },
  {
    "path": "Android/AntFluid/gradlew",
    "content": "#!/usr/bin/env sh\n\n#\n# Copyright 2015 the original author or authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif [ \"$cygwin\" = \"true\" -o \"$msys\" = \"true\" ] ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=`expr $i + 1`\n    done\n    case $i in\n        0) set -- ;;\n        1) set -- \"$args0\" ;;\n        2) set -- \"$args0\" \"$args1\" ;;\n        3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=`save \"$@\"`\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "Android/AntFluid/gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif \"%ERRORLEVEL%\" == \"0\" goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\nexit /b 1\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/.gitignore",
    "content": "/build"
  },
  {
    "path": "Android/AntFluid/markwon-core/build.gradle",
    "content": "plugins {\n    alias(libs.plugins.android.library)\n}\n\nandroid {\n    namespace 'io.noties.markwon'\n    compileSdk 35\n\n    defaultConfig {\n        minSdk 21\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n        consumerProguardFiles \"consumer-rules.pro\"\n    }\n\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n        }\n    }\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_11\n        targetCompatibility JavaVersion.VERSION_11\n    }\n}\n\ndependencies {\n    implementation libs.androidx.core.ktx\n    implementation libs.androidx.appcompat\n    api 'com.atlassian.commonmark:commonmark:0.13.0'\n}"
  },
  {
    "path": "Android/AntFluid/markwon-core/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/androidTest/java/io/noties/markwon/ExampleInstrumentedTest.kt",
    "content": "package io.noties.markwon\n\nimport androidx.test.ext.junit.runners.AndroidJUnit4\nimport androidx.test.platform.app.InstrumentationRegistry\nimport org.junit.Assert.*\nimport org.junit.Test\nimport org.junit.runner.RunWith\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * See [testing documentation](http://d.android.com/tools/testing).\n */\n@RunWith(AndroidJUnit4::class)\nclass ExampleInstrumentedTest {\n    @Test\n    fun useAppContext() {\n        // Context of the app under test.\n        val appContext = InstrumentationRegistry.getInstrumentation().targetContext\n        assertEquals(\"io.noties.markwon\", appContext.packageName)\n    }\n}"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest package=\"io.noties.markwon\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <!-- 添加 INTERNET 权限 -->\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <application>\n    </application>\n</manifest>\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/ContextHolder.java",
    "content": "package com.fluid.afm;\n\nimport android.annotation.SuppressLint;\nimport android.content.Context;\n\npublic class ContextHolder {\n\n    @SuppressLint(\"StaticFieldLeak\")\n    private static Context sContext;\n\n    public static void setContext(Context context) {\n        sContext = context.getApplicationContext();\n    }\n\n    public static Context getContext() {\n        return sContext;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/StreamOutStateObserver.java",
    "content": "package com.fluid.afm;\n\npublic interface StreamOutStateObserver {\n\n    void onStreamOutStateChanged(boolean isStreamingOutput);\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/func/Callback.java",
    "content": "package com.fluid.afm.func;\n\npublic interface Callback<T> {\n\n    /**\n     * 成功\n     *\n     * @param t result\n     */\n    void onSuccess(T t);\n\n    /**\n     * 失败\n     */\n    void onFail();\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/func/IImageClickCallback.java",
    "content": "package com.fluid.afm.func;\n\n\npublic interface IImageClickCallback {\n    void imageClicked(String url, String description);\n\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/handler/BackgroundTaskHandler.java",
    "content": "package com.fluid.afm.handler;\n\nimport java.util.concurrent.ThreadPoolExecutor;\n\npublic interface BackgroundTaskHandler {\n    void execute(Runnable runnable);\n    ThreadPoolExecutor acquireNormalThreadPoolExecutor();\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/handler/DefaultLogHandler.java",
    "content": "package com.fluid.afm.handler;\n\nimport android.util.Log;\n\npublic class DefaultLogHandler implements LogHandler {\n\n    public void i(String tag, String msg) {\n        Log.i(tag, msg);\n    }\n\n    public void e(String tag, String msg) {\n        Log.e(tag, msg);\n    }\n\n    public void e(String tag, Throwable tr) {\n        Log.e(tag, tr.toString());\n    }\n\n    public void e(String tag, String msg, Throwable tr) {\n        Log.e(tag, msg + \":\", tr);\n    }\n\n    public void d(String tag, String msg) {\n        Log.d(tag, msg);\n    }\n\n    public void v(String tag, String msg) {\n        Log.v(tag, msg);\n    }\n\n    public void w(String tag, String msg) {\n        Log.w(tag, msg);\n    }\n\n    public void w(String tag, Throwable tr) {\n        Log.w(tag, tr);\n    }\n\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/handler/DefaultTaskHandler.java",
    "content": "package com.fluid.afm.handler;\n\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.SynchronousQueue;\nimport java.util.concurrent.ThreadPoolExecutor;\nimport java.util.concurrent.TimeUnit;\n\npublic class DefaultTaskHandler implements BackgroundTaskHandler{\n    private final ExecutorService executor = Executors.newCachedThreadPool();\n\n    @Override\n    public void execute(Runnable runnable) {\n        executor.submit(runnable);\n    }\n\n    @Override\n    public ThreadPoolExecutor acquireNormalThreadPoolExecutor() {\n        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,\n                60L, TimeUnit.SECONDS,\n                new SynchronousQueue<>());\n    }\n\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/handler/DefualtImageHandler.java",
    "content": "package com.fluid.afm.handler;\n\nimport android.content.Context;\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapFactory;\nimport android.graphics.drawable.BitmapDrawable;\nimport android.graphics.drawable.Drawable;\n\nimport java.io.BufferedInputStream;\nimport java.io.InputStream;\nimport java.net.HttpURLConnection;\nimport java.net.URL;\n\nimport com.fluid.afm.ContextHolder;\nimport com.fluid.afm.func.Callback;\n\npublic class DefualtImageHandler implements ImageHandler {\n    @Override\n    public void loadImage(Context context, String url, final Callback<Drawable> callback) {\n        EventHandlerManager.getBackgroundTaskHandler().execute(() -> {\n            Drawable drawable = loadImageSync(context, url);\n            if (drawable != null) {\n                callback.onSuccess(drawable);\n            } else {\n                callback.onFail();\n            }\n        });\n    }\n\n    @Override\n    public void loadImage(Context context, String url, int width, int height, Callback<Drawable> callback) {\n        EventHandlerManager.getBackgroundTaskHandler().execute(() -> {\n            Drawable drawable;\n            if (width > 0 && height > 0) {\n                drawable = loadImageSync(context, url, width, height);\n            } else {\n                drawable = loadImageSync(context, url);\n            }\n            if (drawable != null) {\n                callback.onSuccess(drawable);\n            } else {\n                callback.onFail();\n            }\n        });\n    }\n\n    @Override\n    public Drawable loadImageSync(Context context, String raw) {\n        try {\n            final URL url = new URL(raw);\n            final HttpURLConnection connection = (HttpURLConnection) url.openConnection();\n            connection.connect();\n            final int responseCode = connection.getResponseCode();\n            if (responseCode >= 200 && responseCode < 300) {\n                final InputStream inputStream = new BufferedInputStream(connection.getInputStream());\n                final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);\n                return new BitmapDrawable(ContextHolder.getContext().getResources(), bitmap);\n            }\n        } catch (Throwable e) {\n            e.printStackTrace();\n        }\n        return null;\n    }\n\n    @Override\n    public Drawable loadImageSync(Context context, String raw, int width, int height) {\n        try {\n            final URL url = new URL(raw);\n            final HttpURLConnection connection = (HttpURLConnection) url.openConnection();\n            connection.connect();\n            final int responseCode = connection.getResponseCode();\n            if (responseCode >= 200 && responseCode < 300) {\n                final InputStream inputStream = new BufferedInputStream(connection.getInputStream());\n                Bitmap bitmap = BitmapFactory.decodeStream(inputStream);\n                if (width > 0 && height > 0 && (bitmap.getWidth() != width || bitmap.getHeight() != height)) {\n                    int imgWidth = bitmap.getWidth();\n                    int imgHeight = bitmap.getHeight();\n                    float scale = Math.max((float) height / imgHeight, (float) width / imgWidth);\n                    int newWidth = Math.round(imgWidth * scale);\n                    int newHeight = Math.round(imgHeight * scale);\n                    Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);\n                    int xCrop = (newWidth - width) / 2;\n                    int yCrop = (newHeight - height) / 2;\n                    bitmap = Bitmap.createBitmap(scaledBitmap, xCrop, yCrop, width, height);\n                }\n                return new BitmapDrawable(ContextHolder.getContext().getResources(), bitmap);\n            }\n        } catch (Throwable e) {\n            e.printStackTrace();\n        }\n        return null;\n    }\n\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/handler/EventHandlerManager.java",
    "content": "package com.fluid.afm.handler;\n\npublic class EventHandlerManager {\n    private static BackgroundTaskHandler sBackgroundTaskHandler;\n    private static LogHandler sLogHandler;\n    private static ImageHandler sImageHandler;\n\n    public static BackgroundTaskHandler getBackgroundTaskHandler() {\n        if (sBackgroundTaskHandler != null) {\n           return sBackgroundTaskHandler;\n        }\n        return TaskHandlerInstanceHolder.INSTANCE;\n    }\n\n    public static void setBackgroundTaskHandler(BackgroundTaskHandler backgroundTaskHandler) {\n        sBackgroundTaskHandler = backgroundTaskHandler;\n    }\n\n    public static LogHandler getLogHandler() {\n        if (sLogHandler != null) {\n            return sLogHandler;\n        }\n        return LogHandlerInstanceHolder.INSTANCE;\n    }\n\n    public static void setLogHandler(LogHandler logHandler) {\n        sLogHandler = logHandler;\n    }\n\n    public static ImageHandler getImageHandler() {\n        if (sImageHandler != null) {\n            return sImageHandler;\n        }\n        return ImageHandlerInstanceHolder.INSTANCE;\n    }\n\n    public static void setImageHandler(ImageHandler imageHandler) {\n        sImageHandler = imageHandler;\n    }\n\n\n    private static class TaskHandlerInstanceHolder {\n        private static final BackgroundTaskHandler INSTANCE = new DefaultTaskHandler();\n    }\n\n    private static class LogHandlerInstanceHolder {\n        private static final LogHandler INSTANCE = new DefaultLogHandler();\n    }\n\n    private static class ImageHandlerInstanceHolder {\n        private static final DefualtImageHandler INSTANCE = new DefualtImageHandler();\n    }\n\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/handler/ImageHandler.java",
    "content": "package com.fluid.afm.handler;\n\nimport android.content.Context;\nimport android.graphics.drawable.Drawable;\n\nimport com.fluid.afm.func.Callback;\n\npublic interface ImageHandler {\n    void loadImage(Context context, String url, final Callback<Drawable> callback);\n\n    void loadImage(Context context, String url, int width, int height, final Callback<Drawable> callback);\n\n    Drawable loadImageSync(Context context, String url);\n\n    public Drawable loadImageSync(Context context, String raw, int width, int height);\n\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/handler/LogHandler.java",
    "content": "package com.fluid.afm.handler;\n\npublic interface LogHandler {\n    void i(String tag, String msg);\n    void e(String tag, String msg);\n    void e(String tag, Throwable tr);\n    void e(String tag, String msg, Throwable tr);\n    void d(String tag, String msg);\n    void v(String tag, String msg);\n    void w(String tag, String msg);\n    void w(String tag, Throwable tr);\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/icon/DrawableWrapper.java",
    "content": "package com.fluid.afm.icon;\n\nimport android.content.Context;\nimport android.graphics.Bitmap;\nimport android.graphics.drawable.BitmapDrawable;\nimport android.graphics.drawable.Drawable;\n\nimport androidx.core.graphics.drawable.RoundedBitmapDrawable;\nimport androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;\n\nimport com.fluid.afm.utils.MDLogger;\n\nimport java.lang.ref.WeakReference;\nimport java.util.Objects;\nimport java.util.concurrent.ConcurrentHashMap;\n\nimport com.fluid.afm.utils.Utils;\nimport com.fluid.afm.func.Callback;\n\npublic class DrawableWrapper {\n    private static final String TAG = \"DrawableWrapper\";\n    public Data mData;\n    private boolean isLoaded;\n    private Drawable mDrawable;\n\n    private final ConcurrentHashMap<Integer, LoadImageCallback> mCallbackMaps = new ConcurrentHashMap<>();\n\n    public DrawableWrapper(Data data) {\n        mData = data;\n    }\n\n    public Drawable getDrawable() {\n        return mDrawable;\n    }\n\n    public void load(Context context, LoadImageCallback callback) {\n        if (isLoaded) {\n            if (mDrawable != null) {\n                callback.onSuccess(mDrawable);\n                return;\n            }\n            mCallbackMaps.put(callback.hashCode(), callback);\n            return;\n        }\n        mCallbackMaps.put(callback.hashCode(), callback);\n        isLoaded = true;\n        Utils.loadImageAsyn(context, mData.url, mData.width, mData.height, new IconCallback(this));\n    }\n\n    public void onLoadSuccess(Drawable drawable) {\n        if (drawable == null) {\n            onLoadFailed();\n            return;\n        }\n        MDLogger.i(TAG, \"load success. url=\" + mData.url);\n\n        try {\n            if (drawable instanceof BitmapDrawable && ((BitmapDrawable) drawable).getBitmap() != null) {\n                Bitmap bm = ((BitmapDrawable) drawable).getBitmap();\n                RoundedBitmapDrawable roundDrawable = RoundedBitmapDrawableFactory.create(null, bm);\n                roundDrawable.setCornerRadius(mData.round ? bm.getWidth() / 2f : 0);\n                roundDrawable.setBounds(0, 0, bm.getWidth(), bm.getHeight());\n                mDrawable = roundDrawable;\n            } else {\n                mDrawable = drawable;\n            }\n        } catch (Throwable e) { // 本地包： java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v4/graphics/drawable/RoundedBitmapDrawableFactory;兼容一下\n            MDLogger.e(TAG, e);\n            mDrawable = drawable;\n        }\n        for (LoadImageCallback callback : mCallbackMaps.values()) {\n            callback.onSuccess(drawable);\n        }\n    }\n\n    public void onLoadFailed() {\n        isLoaded = false;\n        MDLogger.e(\"DrawableWrapper\", \"load failed. url=\" + mData.url);\n    }\n\n    public void cancel(LoadImageCallback callback) {\n        if (callback != null) {\n            mCallbackMaps.remove(callback.hashCode());\n        }\n        LoadIconUtil.check();\n    }\n\n    public static class Data {\n        public String url;\n\n        public int width, height;\n        public boolean round;\n\n        public Data(String url, int width, int height, boolean round) {\n            this.url = url;\n            this.width = width;\n            this.height = height;\n            this.round = round;\n        }\n\n        @Override\n        public boolean equals(Object object) {\n            if (this == object) return true;\n            if (!(object instanceof Data)) return false;\n            Data data = (Data) object;\n            return width == data.width && height == data.height && Objects.equals(url, data.url) && round == data.round;\n        }\n\n        @Override\n        public int hashCode() {\n            return Objects.hash(url, width, height);\n        }\n    }\n\n    private static class IconCallback implements Callback<Drawable> {\n        WeakReference<DrawableWrapper> mReference;\n\n        public IconCallback(DrawableWrapper drawableWrapper) {\n            mReference = new WeakReference<>(drawableWrapper, LoadIconUtil.QUEUE);\n        }\n\n        @Override\n        public void onSuccess(Drawable drawable) {\n            if (mReference.get() != null) {\n                mReference.get().onLoadSuccess(drawable);\n            }\n        }\n\n        @Override\n        public void onFail() {\n            if (mReference.get() != null) {\n                mReference.get().onLoadFailed();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/icon/LoadIconUtil.java",
    "content": "package com.fluid.afm.icon;\n\nimport com.fluid.afm.utils.MDLogger;\n\nimport java.lang.ref.Reference;\nimport java.lang.ref.ReferenceQueue;\nimport java.lang.ref.WeakReference;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class LoadIconUtil {\n\n    public static final ConcurrentHashMap<DrawableWrapper.Data, WeakReference<DrawableWrapper>> CACHE = new ConcurrentHashMap<>();\n    public static final ReferenceQueue<DrawableWrapper> QUEUE = new ReferenceQueue<>();\n\n    public static DrawableWrapper getIcon(String url, int width, int height) {\n        DrawableWrapper.Data data = new DrawableWrapper.Data(url, width, height, false);\n        WeakReference<DrawableWrapper> cache = CACHE.get(data);\n        DrawableWrapper drawableWrapper = cache == null ? null : cache.get();\n        if (drawableWrapper == null) {\n            drawableWrapper = new DrawableWrapper(data);\n            cache = new WeakReference<>(drawableWrapper, QUEUE);\n            CACHE.put(data, cache);\n        }\n        check();\n        return drawableWrapper;\n    }\n\n    public static DrawableWrapper getIcon(String url, int width, int height, boolean round) {\n        DrawableWrapper.Data data = new DrawableWrapper.Data(url, width, height, round);\n        WeakReference<DrawableWrapper> cache = CACHE.get(data);\n        DrawableWrapper drawableWrapper = cache == null ? null : cache.get();\n        if (drawableWrapper == null) {\n            drawableWrapper = new DrawableWrapper(data);\n            cache = new WeakReference<>(drawableWrapper, QUEUE);\n            CACHE.put(data, cache);\n        }\n        check();\n        return drawableWrapper;\n    }\n\n    public static void check() {\n        MDLogger.d(\"IconLink\", \" CACHE check: size:\" + CACHE.size());\n        Reference<? extends DrawableWrapper> wrapper;\n        while ((wrapper = QUEUE.poll()) != null) {\n            if (wrapper.get() != null) {\n                MDLogger.d(\"IconLink\", \" CACHE released\");\n                CACHE.remove(wrapper.get().mData);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/icon/LoadImageCallback.java",
    "content": "package com.fluid.afm.icon;\n\nimport android.graphics.drawable.Drawable;\nimport android.os.Looper;\nimport android.widget.TextView;\n\nimport java.lang.ref.WeakReference;\n\nimport com.fluid.afm.func.Callback;\n\npublic class LoadImageCallback implements Callback<Drawable> {\n    private final WeakReference<TextView> mReference;\n\n    public LoadImageCallback(TextView textView) {\n        mReference = new WeakReference<>(textView);\n    }\n\n    @Override\n    public void onSuccess(Drawable drawable) {\n        if(mReference.get() != null) {\n            TextView textView = mReference.get();\n            if (Looper.myLooper() == Looper.getMainLooper()) {\n                // textView.invalidate() 不足以触发 Span 的重绘\n                textView.setText(textView.getText());\n            } else {\n                textView.postInvalidate();\n            }\n        }\n        LoadIconUtil.check();\n    }\n\n    @Override\n    public void onFail() {\n        LoadIconUtil.check();\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/span/AntUnderlineSupportMulLinesSpan.java",
    "content": "package com.fluid.afm.span;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.text.style.ReplacementSpan;\n\nimport com.fluid.afm.utils.Utils;\n\npublic class AntUnderlineSupportMulLinesSpan extends ReplacementSpan {\n    private final int color;\n    private final float thickness;\n\n    public AntUnderlineSupportMulLinesSpan(int color, float thickness) {\n        this.color = color;\n        this.thickness = thickness;\n    }\n\n    public int getColor() {\n        return color;\n    }\n\n    public float getThickness() {\n        return thickness;\n    }\n\n    @Override\n    public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {\n        return (int) paint.measureText(text, start, end);\n    }\n\n    @Override\n    public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {\n        int oldColor = paint.getColor();\n        paint.setColor(color);\n        paint.setStrokeWidth(thickness);\n        float lineY = y + paint.getTextSize() * Utils.FONT_SPACING_IN_LINE;\n\n        canvas.drawLine(x,\n                lineY,\n                x + paint.measureText(text, start, end),\n                lineY,\n                paint);\n        paint.setColor(oldColor);\n        canvas.drawText(text, start, end, x, y, paint);\n    }\n\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/span/BaseIconTextSpan.java",
    "content": "package com.fluid.afm.span;\n\nimport android.text.TextPaint;\nimport android.text.TextUtils;\nimport android.text.style.LeadingMarginSpan;\nimport android.text.style.MetricAffectingSpan;\nimport android.widget.TextView;\n\nimport androidx.annotation.NonNull;\n\nimport com.fluid.afm.icon.DrawableWrapper;\nimport com.fluid.afm.icon.LoadIconUtil;\nimport com.fluid.afm.icon.LoadImageCallback;\n\npublic abstract class BaseIconTextSpan extends MetricAffectingSpan implements LeadingMarginSpan {\n\n\n    protected TextView mTextView;\n\n    protected int realTextSize;\n    protected DrawableWrapper mDrawableWrapper;\n\n    private LoadImageCallback mLoadImageCallback;\n    protected float iconOffset;\n\n    public BaseIconTextSpan(TextView textView) {\n        mTextView = textView;\n    }\n\n    @Override\n    public void updateMeasureState(@NonNull TextPaint textPaint) {\n        handleStyle(textPaint);\n    }\n\n    @Override\n    public void updateDrawState(TextPaint tp) {\n        handleStyle(tp);\n    }\n\n    private void handleStyle(TextPaint paint) {\n        applyStyle(paint);\n        realTextSize = (int) (paint.getTextSize() + 0.5f);\n        if (!TextUtils.isEmpty(getImageUrl())) {\n            fetchImage();\n        }\n        iconOffset = getIconSize() * 8 / 9f;\n    }\n    private void fetchImage() {\n        if (mTextView == null) {\n            return;\n        }\n        if (mDrawableWrapper == null) {\n            int size = getIconSize();\n            mDrawableWrapper = LoadIconUtil.getIcon(getImageUrl(), size, size);\n        }\n        if (mDrawableWrapper.getDrawable() == null) {\n            if (mLoadImageCallback == null) {\n                mLoadImageCallback = new LoadImageCallback(mTextView);\n            }\n            mDrawableWrapper.load(mTextView.getContext(), mLoadImageCallback);\n        }\n    }\n\n\n    protected abstract String getImageUrl();\n    protected int getIconSize() {\n        return realTextSize;\n    }\n\n    protected abstract void applyStyle(TextPaint paint);\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/span/CodeLanguageSpan.java",
    "content": "package com.fluid.afm.span;\n\npublic class CodeLanguageSpan {\n    private final String language;\n\n    public CodeLanguageSpan(String language) {\n        this.language = language;\n    }\n\n    public String getLanguage() {\n        return language;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/span/HeadingTopOrBottomSpacingSpan.java",
    "content": "package com.fluid.afm.span;\n\nimport android.graphics.Paint;\nimport android.text.Spanned;\nimport android.text.style.LineHeightSpan;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Px;\n\n/**\n * @since 4.0.0\n */\npublic class HeadingTopOrBottomSpacingSpan implements LineHeightSpan {\n\n    @NonNull\n    public static HeadingTopOrBottomSpacingSpan create(@Px int spacing) {\n        return new HeadingTopOrBottomSpacingSpan(spacing);\n    }\n\n    private int spacing;\n\n    public HeadingTopOrBottomSpacingSpan(@Px int spacing) {\n        this.spacing = spacing;\n    }\n\n    @Override\n    public void chooseHeight(CharSequence text, int start, int end, int spanstartv, int v, Paint.FontMetricsInt fm) {\n        if (selfEnd(end, text, this)) {\n            // let's just add what we want\n\n            final int originHeight = fm.descent - fm.ascent;\n            // If original height is not positive, do nothing.\n            if (originHeight <= 0) {\n                return;\n            }\n            final float ratio = spacing * 1.0f / originHeight;\n            fm.descent = Math.round(fm.descent * ratio);\n            fm.ascent = fm.descent - spacing;\n        }\n    }\n\n    private static boolean selfEnd(int end, CharSequence text, Object span) {\n        // this is some kind of interesting magic here... only the last\n        // span will receive correct _end_ argument, but previous spans\n        // receive it tilted by one (1). Most likely it's just a new-line character... and\n        // if needed we could check for that\n        final int spanEnd = ((Spanned) text).getSpanEnd(span);\n        return spanEnd == end || spanEnd == end - 1;\n    }\n\n\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/span/IClickableSpan.java",
    "content": "package com.fluid.afm.span;\n\npublic interface IClickableSpan {\n    String getUrl();\n    String getType();\n\n    int getTop();\n    int getBottom();\n    default String getLiteral() {\n        return \"\";\n    }\n\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/span/LinkWithIconSpan.java",
    "content": "package com.fluid.afm.span;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.text.TextPaint;\nimport android.text.TextUtils;\nimport android.text.style.ReplacementSpan;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport com.fluid.afm.icon.DrawableWrapper;\nimport com.fluid.afm.icon.LoadIconUtil;\nimport com.fluid.afm.icon.LoadImageCallback;\nimport com.fluid.afm.styles.LinkStyle;\nimport com.fluid.afm.utils.Utils;\n\nimport io.noties.markwon.core.MarkwonTheme;\n\npublic class LinkWithIconSpan extends ReplacementSpan {\n\n    private LinkStyle mStyle;\n    private final MarkwonTheme mMarkwonTheme;\n    protected float mIconTop;\n    protected float mIconStart;\n    protected float mRealTextSize;\n\n    protected DrawableWrapper mDrawableWrapper;\n\n    private LoadImageCallback mLoadImageCallback;\n\n    public LinkWithIconSpan(@NonNull MarkwonTheme theme) {\n        mMarkwonTheme = theme;\n    }\n\n    @Override\n    public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, @Nullable Paint.FontMetricsInt fm) {\n        applyStyle(paint);\n        int size = (int) (paint.measureText(text, start, end) + .5F);\n        if (mStyle != null && !TextUtils.isEmpty(mStyle.icon())) {\n            mIconStart = size + mStyle.space();\n            return (int) (mIconStart + mRealTextSize);\n        }\n        return size;\n    }\n\n    private void applyStyle(Paint paint) {\n        mStyle = mMarkwonTheme.getLinkStyles();\n        if (paint instanceof TextPaint) {\n            mMarkwonTheme.applyLinkStyle((TextPaint) paint, 0, false, null);\n        } else {\n            mMarkwonTheme.applyLinkStyle(paint);\n        }\n        mRealTextSize = paint.getTextSize();\n        mIconTop = mRealTextSize * Utils.FONT_HEIGHT_IN_LINE;\n        fetchImage();\n    }\n\n    private void fetchImage() {\n        if (mMarkwonTheme.getTextView() == null) {\n            return;\n        }\n        if (mDrawableWrapper == null) {\n            int size = (int) mRealTextSize;\n            mDrawableWrapper = LoadIconUtil.getIcon(mStyle.icon(), size, size);\n        }\n        if (mDrawableWrapper.getDrawable() == null) {\n            if (mLoadImageCallback == null) {\n                mLoadImageCallback = new LoadImageCallback(mMarkwonTheme.getTextView());\n            }\n            mDrawableWrapper.load(mMarkwonTheme.getTextView().getContext(), mLoadImageCallback);\n        }\n    }\n\n    @Override\n    public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {\n        applyStyle(paint);\n        canvas.drawText(text, start, end, x, y, paint);\n        if (mDrawableWrapper != null && mDrawableWrapper.getDrawable() != null) {\n            canvas.save();\n            canvas.translate(x + mIconStart, y - mIconTop);\n            mDrawableWrapper.getDrawable().draw(canvas);\n            canvas.restore();\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/span/ParagraphSpacingSpan.java",
    "content": "package com.fluid.afm.span;\n\nimport android.graphics.Paint;\nimport android.text.Spanned;\nimport android.text.style.LineHeightSpan;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Px;\n\nimport com.fluid.afm.utils.Utils;\n\n/**\n * @since 4.0.0\n */\npublic class ParagraphSpacingSpan implements LineHeightSpan {\n\n    @NonNull\n    public static ParagraphSpacingSpan create(@Px int spacing) {\n        return new ParagraphSpacingSpan(spacing);\n    }\n\n    private int spacing;\n\n    public ParagraphSpacingSpan(@Px int spacing) {\n        this.spacing = spacing;\n    }\n\n    @Override\n    public void chooseHeight(CharSequence text, int start, int end, int spanstartv, int v, Paint.FontMetricsInt fm) {\n        if (selfEnd(end, text, this)) {\n            final int originHeight = fm.descent - fm.ascent;\n            // If original height is not positive, do nothing.\n            if (originHeight <= 0) {\n                return;\n            }\n            int realSpacing = (int) (0.5f + spacing - originHeight * Utils.FONT_SPACING_IN_LINE);\n            final float ratio = realSpacing * 1.0f / originHeight;\n            fm.descent = Math.round(fm.descent * ratio);\n            fm.ascent = fm.descent - spacing;\n        }\n    }\n\n    private static boolean selfEnd(int end, CharSequence text, Object span) {\n        // this is some kind of interesting magic here... only the last\n        // span will receive correct _end_ argument, but previous spans\n        // receive it tilted by one (1). Most likely it's just a new-line character... and\n        // if needed we could check for that\n        final int spanEnd = ((Spanned) text).getSpanEnd(span);\n        return spanEnd == end || spanEnd == end - 1;\n    }\n\n\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/styles/BlockQuoteStyle.java",
    "content": "package com.fluid.afm.styles;\n\nimport com.fluid.afm.utils.Utils;\n\n\npublic class BlockQuoteStyle {\n    private static final int LINE_WIDTH = Utils.dpToPx(4);\n    private static final int LINE_MARGIN = Utils.dpToPx(24);\n    private static final int BOTTOM_MARGIN = Utils.dpToPx(8);\n    private int lineWidth = LINE_WIDTH;\n    private int lineColor;\n    private int lineCornerRadius = -1;\n    private int lineMargin = LINE_MARGIN;\n    private int bottomMargin = BOTTOM_MARGIN;\n\n    private int leftMargin;\n    private final ParagraphStyle paragraph = new ParagraphStyle();\n\n    public static BlockQuoteStyle create() {\n        return new BlockQuoteStyle();\n    }\n\n    public static BlockQuoteStyle create(int lineWidth, int lineColor, int lineCornerRadius, int lineMargin, int bottomMargin, int leftMargin, float fontSize, int fontColor, int paragraphSpacing) {\n        return create().lineWidth(lineWidth).lineColor(lineColor).lineCornerRadius(lineCornerRadius).lineMargin(lineMargin).leftMargin(leftMargin).bottomMargin(bottomMargin).fontSize(fontSize).fontColor(fontColor).paragraphSpacing(paragraphSpacing);\n    }\n\n    public BlockQuoteStyle lineWidth(int lineWidth) {\n        this.lineWidth = Math.max(0, lineWidth);\n        return this;\n    }\n\n    public int lineWidth() {\n        return lineWidth;\n    }\n\n    public BlockQuoteStyle lineColor(int lineColor) {\n        this.lineColor = lineColor;\n        return this;\n    }\n\n    public int lineColor() {\n        return lineColor;\n    }\n\n    public BlockQuoteStyle lineCornerRadius(int lineCornerRadius) {\n        this.lineCornerRadius = Math.max(0, lineCornerRadius);\n        return this;\n    }\n\n    public int lineCornerRadius() {\n        return lineCornerRadius;\n    }\n\n    public BlockQuoteStyle lineMargin(int lineMargin) {\n        this.lineMargin = Math.max(0, lineMargin);\n        return this;\n    }\n\n    public int lineMargin() {\n        return lineMargin;\n    }\n\n    public BlockQuoteStyle bottomMargin(int bottomMargin) {\n        this.bottomMargin = Math.max(0, bottomMargin);\n        return this;\n    }\n\n    public int bottomMargin() {\n        return bottomMargin;\n    }\n\n    public BlockQuoteStyle leftMargin(int leftMargin) {\n        this.leftMargin = Math.max(0, leftMargin);\n        return this;\n    }\n\n    public int leftMargin() {\n        return leftMargin;\n    }\n\n    public BlockQuoteStyle fontSize(float fontSize) {\n        paragraph.fontSize(fontSize);\n        return this;\n    }\n\n    public float fontSize() {\n        return paragraph.fontSize();\n    }\n\n    public BlockQuoteStyle fontColor(int fontColor) {\n        paragraph.fontColor(fontColor);\n        return this;\n    }\n\n    public int fontColor() {\n        return paragraph.fontColor();\n    }\n\n    public BlockQuoteStyle paragraphSpacing(int paragraphSpacing) {\n        paragraph.paragraphSpacing(paragraphSpacing);\n        return this;\n    }\n\n    public int paragraphSpacing() {\n        return paragraph.paragraphSpacing();\n    }\n\n}\n\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/styles/BulletStyle.java",
    "content": "package com.fluid.afm.styles;\n\n\npublic class BulletStyle {\n    private Shape shape;\n    private int leadingSpacing = -1;\n    private int leading;\n    public static BulletStyle create() {\n        return new BulletStyle();\n    }\n\n    public BulletStyle setShape(Shape shape) {\n        this.shape = shape;\n        return this;\n    }\n\n    public BulletStyle leadingSpacing(int leadingSpacing) {\n        this.leadingSpacing = Math.max(0, leadingSpacing);\n        return this;\n    }\n\n    public BulletStyle leading(int leading) {\n        this.leading = Math.max(0, leading);\n        return this;\n    }\n\n    public Shape shape() {\n        return shape;\n    }\n\n    public int leadingSpacing() {\n        return leadingSpacing;\n    }\n\n    public int leading() {\n        return leading;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/styles/CodeStyle.java",
    "content": "package com.fluid.afm.styles;\n\nimport android.graphics.Color;\nimport android.graphics.Typeface;\nimport android.os.Parcel;\nimport android.os.Parcelable;\n\nimport androidx.annotation.NonNull;\n\nimport com.fluid.afm.utils.Utils;\n\npublic class CodeStyle implements Parcelable {\n\n    private int inlineFontColor = 0xFF333333;\n    private int inlineFontSize = Utils.dpToPx(15);\n    private int inlineBackgroundColor = 0x1E1F3B63;\n    private int inlineBackgroundRadius = Utils.dpToPx(4);\n    private int inlinePaddingVertical = Utils.dpToPx(1.5f);\n    private int inlinePaddingHorizontal = Utils.dpToPx(4);\n    private int codeFontColor = 0xFF333333;\n    private int codeFontSize = Utils.dpToPx(13);\n    private int codeBackgroundColor = Color.WHITE;\n    private int codeBackgroundRadius = Utils.dpToPx(12);\n    private int titleFontColor = 0xFF999999;\n    private int titleBackgroundColor = 0xFFEDEFF3;\n    private int titleFontSize = Utils.dpToPx(13);\n    private int borderColor = 0xFFDEDEDE;\n    private int borderWidth = Utils.dpToPx(0.5f);\n    private boolean lightIcon = true;\n    private boolean drawBorder = true;\n    private Typeface codeTypeface = Typeface.MONOSPACE;\n    private int blockLeading = Utils.dpToPx(8);\n    private boolean showTitle = true;\n\n    public CodeStyle() {\n\n    }\n\n    protected CodeStyle(Parcel in) {\n        inlineFontColor = in.readInt();\n        inlineFontSize = in.readInt();\n        inlineBackgroundColor = in.readInt();\n        inlineBackgroundRadius = in.readInt();\n        inlinePaddingVertical = in.readInt();\n        inlinePaddingHorizontal = in.readInt();\n        codeFontColor = in.readInt();\n        codeFontSize = in.readInt();\n        codeBackgroundColor = in.readInt();\n        codeBackgroundRadius = in.readInt();\n        titleFontColor = in.readInt();\n        titleBackgroundColor = in.readInt();\n        titleFontSize = in.readInt();\n        borderColor = in.readInt();\n        borderWidth = in.readInt();\n        lightIcon = in.readByte() != 0;\n        drawBorder = in.readByte() != 0;\n        blockLeading = in.readInt();\n    }\n\n    public static final Creator<CodeStyle> CREATOR = new Creator<>() {\n        @Override\n        public CodeStyle createFromParcel(Parcel in) {\n            return new CodeStyle(in);\n        }\n\n        @Override\n        public CodeStyle[] newArray(int size) {\n            return new CodeStyle[size];\n        }\n    };\n\n    public static CodeStyle create() {\n        return new CodeStyle();\n    }\n\n    public int inlineBackgroundColor() {\n        return inlineBackgroundColor;\n    }\n\n    public CodeStyle inlineCodeBackgroundColor(int inlineBackgroundColor) {\n        this.inlineBackgroundColor = inlineBackgroundColor;\n        return this;\n    }\n\n    public int inlineBackgroundRadius() {\n        return inlineBackgroundRadius;\n    }\n\n    public CodeStyle inlineCodeBackgroundRadius(int inlineBackgroundRadius) {\n        this.inlineBackgroundRadius = Math.max(0, inlineBackgroundRadius);\n        return this;\n    }\n\n    public boolean isLightIcon() {\n        return lightIcon;\n    }\n\n    public CodeStyle lightIcon(boolean lightIcon) {\n        this.lightIcon = lightIcon;\n        return this;\n    }\n\n    public CodeStyle inlineFontColor(int color) {\n        inlineFontColor = color;\n        return this;\n    }\n\n    public int inlineFontColor() {\n        return inlineFontColor;\n    }\n\n    public CodeStyle inlinePaddingVertical(int padding) {\n        inlinePaddingVertical = Math.max(0, padding);\n        return this;\n    }\n\n    public int inlinePaddingVertical() {\n        return inlinePaddingVertical;\n    }\n\n    public CodeStyle inlinePaddingHorizontal(int padding) {\n        inlinePaddingHorizontal = Math.max(0, padding);\n        return this;\n    }\n\n    public int inlinePaddingHorizontal() {\n        return inlinePaddingHorizontal;\n    }\n\n    public CodeStyle codeFontColor(int color) {\n        codeFontColor = color;\n        return this;\n    }\n\n    public int codeFontColor() {\n        return codeFontColor;\n    }\n\n    public CodeStyle codeFontSize(int size) {\n        codeFontSize = Math.max(0, size);\n        return this;\n    }\n\n    public int codeFontSize() {\n        return codeFontSize;\n    }\n\n    public CodeStyle codeBackgroundColor(int color) {\n        codeBackgroundColor = color;\n        return this;\n    }\n\n    public int codeBackgroundColor() {\n        return codeBackgroundColor;\n    }\n\n    public CodeStyle codeBackgroundRadius(int radius) {\n        codeBackgroundRadius = Math.max(0, radius);\n        return this;\n    }\n\n    public int codeBackgroundRadius() {\n        return codeBackgroundRadius;\n    }\n\n    public CodeStyle titleFontColor(int color) {\n        titleFontColor = color;\n        return this;\n    }\n\n    public int titleFontColor() {\n        return titleFontColor;\n    }\n\n    public CodeStyle titleFontSize(int size) {\n        titleFontSize = Math.max(0, size);\n        return this;\n    }\n\n    public int titleFontSize() {\n        return titleFontSize;\n    }\n\n    public CodeStyle drawBorder(boolean drawBorder) {\n        this.drawBorder = drawBorder;\n        return this;\n    }\n\n    public boolean isDrawBorder() {\n        return drawBorder;\n    }\n\n    public CodeStyle borderColor(int color) {\n        borderColor = color;\n        return this;\n    }\n\n    public int borderColor() {\n        return borderColor;\n    }\n\n    public CodeStyle borderWidth(int width) {\n        borderWidth = Math.max(0, width);\n        if (this.borderWidth == 1) {\n            this.borderWidth = 2;\n        }\n        return this;\n    }\n\n    public int borderWidth() {\n        return borderWidth;\n    }\n\n    public CodeStyle titleBackgroundColor(int color) {\n        titleBackgroundColor = color;\n        return this;\n    }\n\n    public int titleBackgroundColor() {\n        return titleBackgroundColor;\n    }\n\n    public CodeStyle codeTypeface(Typeface typeface) {\n        this.codeTypeface = typeface;\n        return this;\n    }\n\n    public Typeface codeTypeface() {\n        return codeTypeface;\n    }\n\n    public CodeStyle inlineFontSize(int size) {\n        inlineFontSize = Math.max(0, size);\n        return this;\n    }\n\n    public int inlineFontSize() {\n        return inlineFontSize;\n    }\n\n    public CodeStyle blockLeading(int leading) {\n        blockLeading = Math.max(0, leading);\n        return this;\n    }\n\n    public int blockLeading() {\n        return blockLeading;\n    }\n\n    public boolean isShowTitle() {\n        return showTitle;\n    }\n\n    public void setShowTitle(boolean showTitle) {\n        this.showTitle = showTitle;\n    }\n\n    @Override\n    public int describeContents() {\n        return 0;\n    }\n\n    @Override\n    public void writeToParcel(@NonNull Parcel dest, int flags) {\n        dest.writeInt(inlineFontColor);\n        dest.writeInt(inlineFontSize);\n        dest.writeInt(inlineBackgroundColor);\n        dest.writeInt(inlineBackgroundRadius);\n        dest.writeInt(inlinePaddingVertical);\n        dest.writeInt(inlinePaddingHorizontal);\n        dest.writeInt(codeFontColor);\n        dest.writeInt(codeFontSize);\n        dest.writeInt(codeBackgroundColor);\n        dest.writeInt(codeBackgroundRadius);\n        dest.writeInt(titleFontColor);\n        dest.writeInt(titleBackgroundColor);\n        dest.writeInt(titleFontSize);\n        dest.writeInt(borderColor);\n        dest.writeInt(borderWidth);\n        dest.writeByte((byte) (lightIcon ? 1 : 0));\n        dest.writeByte((byte) (drawBorder ? 1 : 0));\n        dest.writeInt(blockLeading);\n    }\n}\n\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/styles/FootnoteStyle.java",
    "content": "package com.fluid.afm.styles;\n\nimport static java.lang.annotation.RetentionPolicy.SOURCE;\n\nimport androidx.annotation.IntDef;\n\nimport java.lang.annotation.Retention;\n\npublic class FootnoteStyle {\n    public static final int STYLE_CIRCLE = 0;\n    public static final int STYLE_RECTANGLE = 1;\n    private int backgroundColor = 0x1E1677FF;\n    private int textColor = 0xFF0E489A;\n    private boolean bold = false;\n    private float fontSize = 20f;\n    private float size;\n    private int style;\n    private float radius;\n\n    public static FootnoteStyle create() {\n        return new FootnoteStyle();\n    }\n\n    public static FootnoteStyle create(int textColor, int backgroundColor) {\n        return new FootnoteStyle().textColor(textColor).backgroundColor(backgroundColor);\n    }\n\n    public FootnoteStyle backgroundColor(int backgroundColor) {\n        this.backgroundColor = backgroundColor;\n        return this;\n    }\n\n    public int backgroundColor() {\n        return backgroundColor;\n    }\n\n    public float fontSize() {\n        return fontSize;\n    }\n\n    public FootnoteStyle size(float size) {\n        this.size = Math.max(0, size);\n        return this;\n    }\n\n    public float size() {\n        return size;\n    }\n\n    public FootnoteStyle fontSize(float fontSize) {\n        this.fontSize = Math.max(0, fontSize);\n        return this;\n    }\n\n    public FootnoteStyle textColor(int textColor) {\n        this.textColor = textColor;\n        return this;\n    }\n\n    public int textColor() {\n        return textColor;\n    }\n\n    public FootnoteStyle isBold(boolean bold) {\n        this.bold = bold;\n        return this;\n    }\n\n    public boolean isBold() {\n        return bold;\n    }\n\n\n    public FootnoteStyle style(@Style int style) {\n        this.style = style;\n        return this;\n    }\n\n    @Style\n    public int style() {\n        return style;\n    }\n\n    public FootnoteStyle radius(float radius) {\n        this.radius = Math.max(0, radius);\n        return this;\n    }\n\n    public float radius() {\n        return radius;\n    }\n\n    @Retention(SOURCE)\n    @IntDef({STYLE_CIRCLE, STYLE_RECTANGLE})\n    public @interface Style {\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/styles/HorizonRuleStyle.java",
    "content": "package com.fluid.afm.styles;\n\nimport android.graphics.Paint;\n\npublic class HorizonRuleStyle {\n    /**\n     * return this;\n     * height : 4px\n     * color : #E2E5F3\n     */\n\n    private int height;\n    private int color = 0;\n    private final ParagraphStyle paragraph = new ParagraphStyle();\n    private int paragraphSpacingBefore;\n\n    public static HorizonRuleStyle create() {\n        return new HorizonRuleStyle();\n    }\n\n    public static HorizonRuleStyle create(int height, int color, int paragraphSpacing, int paragraphSpacingBefore) {\n        HorizonRuleStyle style = new HorizonRuleStyle();\n        style.height = height;\n        style.color = color;\n        style.paragraph.paragraphSpacing(paragraphSpacing);\n        style.paragraphSpacingBefore = paragraphSpacingBefore;\n        return style;\n    }\n\n    public HorizonRuleStyle setHeight(int height) {\n        this.height = Math.max(0, height);\n        return this;\n    }\n\n    public HorizonRuleStyle setColor(int color) {\n        this.color = color;\n        return this;\n    }\n\n    public HorizonRuleStyle paragraphSpacing(int paragraphSpacing) {\n        paragraph.paragraphSpacing(paragraphSpacing);\n        return this;\n    }\n\n    public HorizonRuleStyle paragraphSpacingBefore(int paragraphSpacingBefore) {\n        this.paragraphSpacingBefore = Math.max(0, paragraphSpacingBefore);\n        return this;\n    }\n\n    public int paragraphSpacingBefore() {\n        return paragraphSpacingBefore;\n    }\n\n    public int getHeight() {\n        return height;\n    }\n\n    public int getColor() {\n        return color;\n    }\n\n    public ParagraphStyle paragraph() {\n        return paragraph;\n    }\n\n    public void apply(Paint paint) {\n        if (color != 0) {\n            paint.setColor(color);\n        } else {\n            paint.setColor(0xFFEEEEEE);\n        }\n        paint.setStyle(Paint.Style.FILL);\n        if (height >= 0) {\n            //noinspection SuspiciousNameCombination\n            paint.setStrokeWidth(height);\n        }\n    }\n\n}"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/styles/LinkStyle.java",
    "content": "package com.fluid.afm.styles;\n\npublic class LinkStyle {\n\n    private int fontColor;\n    private int space;\n    private String icon;\n    private boolean underline = true;\n    private boolean isBold;\n\n    public static LinkStyle create() {\n        return new LinkStyle();\n    }\n\n    public static LinkStyle create(int fontColor, int space, String icon, boolean underline, boolean isBold) {\n        LinkStyle style = new LinkStyle();\n        style.fontColor = fontColor;\n        style.space = space;\n        style.icon = icon;\n        style.underline = underline;\n        style.isBold = isBold;\n        return style;\n    }\n\n    public LinkStyle fontColor(int fontColor) {\n        this.fontColor = fontColor;\n        return this;\n    }\n\n    public int fontColor() {\n        return fontColor;\n    }\n\n    public LinkStyle space(int space) {\n        this.space = Math.max(0, space);\n        return this;\n    }\n\n    public int space() {\n        return space;\n    }\n\n    public LinkStyle icon(String icon) {\n        this.icon = icon;\n        return this;\n    }\n\n    public String icon() {\n        return icon;\n    }\n\n    public LinkStyle underline(boolean underline) {\n        this.underline = underline;\n        return this;\n    }\n\n    public boolean underline( ) {\n        return underline;\n    }\n\n    public LinkStyle isBold(boolean bold) {\n        isBold = bold;\n        return this;\n    }\n\n    public boolean isBold() {\n        return isBold;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/styles/MarkdownStyles.java",
    "content": "package com.fluid.afm.styles;\n\nimport android.graphics.Color;\nimport android.graphics.Typeface;\n\nimport com.fluid.afm.utils.ParseUtil;\n\nimport java.util.Arrays;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class MarkdownStyles {\n    /**\n     * Paragraph style\n     * Paragraph spacing applies to normal paragraphs, ordered lists, unordered lists, and tables\n     */\n    private ParagraphStyle paragraph = ParagraphStyle.create();\n    /**\n     * Horizontial rule style\n     */\n    private HorizonRuleStyle horizonRule = HorizonRuleStyle.create();\n    /**\n     * Link style\n     */\n    private LinkStyle link = LinkStyle.create();\n    /**\n     * Table style\n     */\n    private TableStyle table = TableStyle.create();\n    /**\n     * 标题样式,数组大小是6\n     * TitleStyle.fontSize: 标题字体大小\n     * TitleStyle.sizeType: 标题字体大小类型，0:系数, 标题字体大小 = 正文字体大小*fontSize; 1:px\n     * 默认值： TitleStyle.fontSize = 1;TitleStyle.sizeType = 0\n     *\n     * Title style, array size is 6\n     * TitleStyle.fontSize: title font size\n     * TitleStyle.sizeType: title font size type, if sizeType is 0, title font size = paragraph font size*fontSize; if sizeType is 1  title font size = [fontSize]px\n     */\n    private TitleStyle[] titleStyles = TitleStyle.TITLE_DEFAULT_SIZES;\n    /**\n     * Ordered  style\n     * key: level, value: style\n     */\n    private Map<Integer, OrderStyle> orderStyles = new ConcurrentHashMap<>();\n    /**\n     * Basic ordered list style\n     * if Map<Integer, OrderBean> orderBeans has no corresponding level, use this style\n     */\n    private OrderStyle baseOrder = OrderStyle.create();\n    /**\n     * Bullet list style\n     * key: level, value: style\n     */\n    private Map<Integer, BulletStyle> bulletStyles = new ConcurrentHashMap<>();\n    /**\n     * Basic bullet style\n     * if Map<Integer, UnorderBean> unorderBeans has no corresponding level, use this style\n     */\n    private BulletStyle baseBullet = BulletStyle.create();\n\n    /**\n     * footnote style\n     */\n    private FootnoteStyle footnote = FootnoteStyle.create();\n    /**\n     * block quote style\n     */\n    private BlockQuoteStyle blockQuote = BlockQuoteStyle.create();\n\n    /**\n     * code style include code block and inline code\n     */\n    private CodeStyle code = CodeStyle.create();\n\n    /**\n     * underline style\n     */\n    private UnderlineStyle underline = UnderlineStyle.create(ParseUtil.parseDp(\"6rpx\"), 0x7A1677FF);\n\n    public MarkdownStyles() {\n    }\n\n    public MarkdownStyles paragraphStyle(ParagraphStyle paragraph) {\n        this.paragraph = paragraph;\n        return this;\n    }\n\n    public MarkdownStyles horizonRuleStyle(HorizonRuleStyle horizonRule) {\n        this.horizonRule = horizonRule;\n        return this;\n    }\n\n    public MarkdownStyles tableStyle(TableStyle table) {\n        this.table = table;\n        return this;\n    }\n\n    public MarkdownStyles setTitleStyles(TitleStyle[] titleStyles) {\n        this.titleStyles = titleStyles;\n        return this;\n    }\n    public MarkdownStyles setTitleStyle(int level, TitleStyle style) {\n        if (level < 0 || level >= titleStyles.length) {\n            return this;\n        }\n        if (this.titleStyles == TitleStyle.TITLE_DEFAULT_SIZES) {\n            this.titleStyles = new TitleStyle[6];\n            Arrays.fill(this.titleStyles, TitleStyle.TITLE_DEFAULT);\n        }\n        this.titleStyles[level] = style;\n        return this;\n    }\n\n    public Map<Integer, OrderStyle> getOrderStylesMap() {\n        return orderStyles;\n    }\n\n    public MarkdownStyles setOrderStyles(Map<Integer, OrderStyle> orderStyles) {\n        this.orderStyles = orderStyles;\n        return this;\n    }\n\n    public OrderStyle getBaseOrderStyle() {\n        return baseOrder;\n    }\n\n    public MarkdownStyles setBaseOrderStyle(OrderStyle baseOrder) {\n        this.baseOrder = baseOrder;\n        return this;\n    }\n\n    public MarkdownStyles setBulletStyles(Map<Integer, BulletStyle> bulletStyles) {\n        this.bulletStyles = bulletStyles;\n        return this;\n    }\n\n    public BulletStyle getBaseBulletStyle() {\n        return baseBullet;\n    }\n\n    public Map<Integer, BulletStyle> getBulletStylesMap() {\n        return bulletStyles;\n    }\n\n    public MarkdownStyles baseBulletStyle(BulletStyle base) {\n        this.baseBullet = base;\n        return this;\n    }\n\n    public FootnoteStyle getFootnoteStyle() {\n        return footnote;\n    }\n\n    public MarkdownStyles footnoteStyle(FootnoteStyle footnote) {\n        this.footnote = footnote;\n        return this;\n    }\n\n    public CodeStyle codeStyle() {\n        return code;\n    }\n    public MarkdownStyles codeStyle(CodeStyle style) {\n        this.code = style;\n        return this;\n    }\n    public UnderlineStyle underlineStyle() {\n        return underline;\n    }\n    public MarkdownStyles underlineStyle(UnderlineStyle style) {\n        this.underline = style;\n        return this;\n    }\n\n    public BlockQuoteStyle blockQuoteStyle() {\n        return blockQuote;\n    }\n\n    public MarkdownStyles blockQuoteStyle(BlockQuoteStyle blockQuote) {\n        this.blockQuote = blockQuote;\n        return this;\n    }\n\n    public TitleStyle[] titleStyles() {\n        return titleStyles;\n    }\n\n    public ParagraphStyle paragraphStyle() {\n        return paragraph;\n    }\n\n    public HorizonRuleStyle horizonRuleStyle() {\n        return horizonRule;\n    }\n\n    public LinkStyle linkStyle() {\n        return link;\n    }\n\n    public MarkdownStyles linkStyle(LinkStyle link) {\n        this.link = link;\n        return this;\n    }\n\n    public TableStyle tableStyle() {\n        return table;\n    }\n\n    public static MarkdownStyles getDefaultStyles() {\n        MarkdownStyles styles = new MarkdownStyles();\n        styles\n                // paragraph style\n                .paragraphStyle(ParagraphStyle.create()\n                        .fontSize(ParseUtil.parseDp(\"30rpx\"))\n                        .fontColor(0xFF333333)\n                        .lineHeight(ParseUtil.parseDp(\"48rpx\"))\n                        .paragraphSpacing(ParseUtil.parseDp(\"10px\"))\n                )\n                // horizon rule style\n                .horizonRuleStyle(HorizonRuleStyle.create(ParseUtil.parseDp(\"0.5px\"), 0xFFE2E5F3, ParseUtil.parseDp(\"16px\"), ParseUtil.parseDp(\"6px\")))\n                // link style\n                .linkStyle(LinkStyle.create()\n                        .underline(false)\n                        .fontColor(0xFF1296DB))\n                // ordered list style\n                .setBaseOrderStyle(OrderStyle.create()\n                        .leading(ParseUtil.parseDp(\"1px\"))\n                        .isBold(true)\n                        .leadingSpacing(ParseUtil.parseDp(\"5px\")))\n                // bullet list style\n                .baseBulletStyle(BulletStyle.create()\n                        .leading(ParseUtil.parseDp(\"1px\"))\n                        .leadingSpacing(ParseUtil.parseDp(\"8px\"))\n                        .setShape(new Shape().setColor(0xFF13113E).setType(Shape.SHAPE_CIRCLE).setSize(ParseUtil.parseDp(\"5px\"))))\n                // footnote style\n                .footnoteStyle(FootnoteStyle.create(0xFF999999, 0x141F3B63)\n                        .isBold(true)\n                        .size(ParseUtil.parseDp(\"32rpx\"))\n                        .fontSize(ParseUtil.parseDp(\"20rpx\")))\n                // blockquote style\n                .blockQuoteStyle(BlockQuoteStyle.create()\n                        .lineColor(0xFFEEEEEE)\n                        .fontColor(0xFF999999)\n                        .lineWidth(ParseUtil.parseDp(\"4px\"))\n                        .lineCornerRadius(ParseUtil.parseDp(\"2px\"))\n                        .lineMargin(ParseUtil.parseDp(\"40rpx\")))\n                // table style\n                .tableStyle(TableStyle.create()\n                        .tableBlockRadius(ParseUtil.parseDp(\"24rpx\"))\n                        .fontColor(0xFF333333)\n                        .titleFontColor(0xFF999999)\n                        .titleBackgroundColor(0xFFEDEFF3)\n                        .titleFontSize(ParseUtil.parseDp(\"30rpx\"))\n                        .headerBackgroundColor(0xFFF6F7F9)\n                        .headerFontSize(ParseUtil.parseDp(\"26rpx\"))\n                        .titleBackgroundRadius(ParseUtil.parseDp(\"24rpx\"))\n                        .bodyBackgroundColor(Color.WHITE)\n                        .cellTopBottomPadding(ParseUtil.parseDp(\"6px\"))\n                        .bodyFontSize(ParseUtil.parseDp(\"26rpx\"))\n                        .drawBorder(true).borderColor(0xFFDEDEDE).borderWidth(ParseUtil.parseDp(\"1rpx\")))\n                // code block + inline code style\n                .codeStyle(CodeStyle.create()\n                        .inlineFontColor(0xFF2980B9)\n                        .inlineFontSize(ParseUtil.parseDp(\"30rpx\"))\n                        .inlineCodeBackgroundColor(0x1E1F3B63)\n                        .inlineCodeBackgroundRadius(ParseUtil.parseDp(\"8rpx\"))\n                        .inlinePaddingHorizontal(ParseUtil.parseDp(\"4rpx\"))\n                        .inlinePaddingVertical(ParseUtil.parseDp(\"3rpx\"))\n                        .codeFontColor(0xFF333333)\n                        .codeFontSize(ParseUtil.parseDp(\"26rpx\"))\n                        .titleFontColor(0xFF999999)\n                        .titleFontSize(ParseUtil.parseDp(\"26rpx\"))\n                        .borderColor(0xFFDEDEDE)\n                        .borderWidth(ParseUtil.parseDp(\"1rpx\"))\n                        .lightIcon(true)\n                        .drawBorder(true)\n                        .codeTypeface(Typeface.MONOSPACE))\n                // underline style\n                .underlineStyle(UnderlineStyle.create(ParseUtil.parseDp(\"12rpx\"), 0x7A1677FF))\n                // title style\n                .setTitleStyle(0, TitleStyle.create(1.3f)\n                        .paragraphSpacing(ParseUtil.parseDp(\"10px\"))\n                        .paragraphSpacingBefore(ParseUtil.parseDp(\"4px\")))\n                .setTitleStyle(1, TitleStyle.create(1.2f).paragraphSpacing(ParseUtil.parseDp(\"10px\"))\n                        .paragraphSpacingBefore(ParseUtil.parseDp(\"4px\")))\n                .setTitleStyle(2, TitleStyle.create(1.1f).paragraphSpacing(ParseUtil.parseDp(\"10px\"))\n                        .paragraphSpacingBefore(ParseUtil.parseDp(\"4px\")))\n                .setTitleStyle(3, TitleStyle.create(1.f).paragraphSpacing(ParseUtil.parseDp(\"10px\"))\n                        .paragraphSpacingBefore(ParseUtil.parseDp(\"4px\")))\n                .setTitleStyle(4, TitleStyle.create(1.f).paragraphSpacing(ParseUtil.parseDp(\"10px\"))\n                        .paragraphSpacingBefore(ParseUtil.parseDp(\"4px\")))\n                .setTitleStyle(5, TitleStyle.create(1.f).paragraphSpacing(ParseUtil.parseDp(\"10px\"))\n                        .paragraphSpacingBefore(ParseUtil.parseDp(\"4px\")));\n        return styles;\n    }\n\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/styles/OrderStyle.java",
    "content": "package com.fluid.afm.styles;\n\nimport com.fluid.afm.utils.ParseUtil;\n\n/**\n * 有序列表\n * \"unorder\": {\n * \"item1\": {\n * \"shape\": {\n * \"type\": \"circle\",\n * \"shapeSize\": \"7px\",\n * \"shapeColor\": \"#4744da\"\n * },\n * \"leadingSpacing\": \"6px\"        * \t\t},\n * \"itemBase\": {\n * \"shape\": {\n * \"type\": \"circle\",\n * \"size\": \"1.5px\",\n * \"color\": \"#13113e\"\n * }\n * }\n */\n\npublic class OrderStyle {\n    private int fontColor;\n    private float fontSize;\n    // only support icon & rectangle\n    private Shape shape;\n    private int leading;\n    private int leadingSpacing;\n    private boolean bold = true;\n\n    public static OrderStyle create() {\n        return new OrderStyle()\n                .leading(ParseUtil.parseDp(\"12px\"))\n                .isBold(true)\n                .leadingSpacing(ParseUtil.parseDp(\"12px\"));\n    }\n\n    public OrderStyle orderFontColor(int fontColor) {\n        this.fontColor = fontColor;\n        return this;\n    }\n\n    public int orderFontColor() {\n        return fontColor;\n    }\n\n    public OrderStyle orderFontSize(float fontSize) {\n        this.fontSize = Math.max(0, fontSize);\n        return this;\n    }\n\n    public float orderFontSize() {\n        return fontSize;\n    }\n\n    public OrderStyle setShape(Shape shape) {\n        this.shape = shape;\n        return this;\n    }\n\n    public Shape shape() {\n        return shape;\n    }\n\n    public OrderStyle leading(int leading) {\n        this.leading = Math.max(0, leading);\n        return this;\n    }\n\n    public int leading() {\n        return leading;\n    }\n\n    public OrderStyle leadingSpacing(int leadingSpacing) {\n        this.leadingSpacing = Math.max(0, leadingSpacing);\n        return this;\n    }\n\n    public int leadingSpacing() {\n        return leadingSpacing;\n    }\n\n    public OrderStyle isBold(boolean bold) {\n        this.bold = bold;\n        return this;\n    }\n\n    public boolean isBold() {\n        return bold;\n    }\n}\n\n\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/styles/ParagraphStyle.java",
    "content": "package com.fluid.afm.styles;\n\n\npublic class ParagraphStyle {\n   private float fontSize;\n   private int fontColor;\n   private int lineHeight;\n   private int paragraphSpacing = -1;\n\n    public static ParagraphStyle create() {\n        return new ParagraphStyle();\n    }\n\n    public ParagraphStyle fontSize(float fontSize) {\n        this.fontSize = Math.max(0, fontSize);\n        return this;\n    }\n\n    public float fontSize() {\n        return fontSize;\n    }\n\n    public ParagraphStyle fontColor(int fontColor) {\n        this.fontColor = fontColor;\n        return this;\n    }\n\n    public int fontColor() {\n        return fontColor;\n    }\n\n    public ParagraphStyle lineHeight(int lineHeight) {\n        this.lineHeight = Math.max(0, lineHeight);\n        return this;\n    }\n\n    public int lineHeight() {\n        return lineHeight;\n    }\n\n    public ParagraphStyle paragraphSpacing(int paragraphSpacing) {\n        this.paragraphSpacing = Math.max(0, paragraphSpacing);\n        return this;\n    }\n\n    public int paragraphSpacing() {\n        return paragraphSpacing;\n    }\n\n\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/styles/Shape.java",
    "content": "package com.fluid.afm.styles;\n\n/**\n * \"shape\": {\n * \"type\": \"circle\",\n * \"size\": \"1.5px\",\n * \"color\": \"#13113e\"\n * }\n */\npublic class Shape {\n    public static final int SHAPE_CIRCLE = 0;\n    public static final int SHAPE_RECT = 1;\n    public static final int SHAPE_ICON = 2;\n    public static final int SHAPE_RING = 3;\n    public static final int SHAPE_RECT_OUTLINE = 4;\n    private int type = -1; // 0 circle 1 rect 3  icon\n    private int size = 15;\n    private int color;\n    private String icon;\n    private int radius;\n    private int lineWidth = 2;\n\n    public static Shape create(int type, int size, int color) {\n        Shape shape = new Shape();\n        shape.type = type;\n        shape.size = size;\n        shape.color = color;\n        return shape;\n    }\n\n    public static Shape create(int type, int size, String icon) {\n        Shape shape = new Shape();\n        shape.type = type;\n        shape.size = size;\n        shape.icon = icon;\n        return shape;\n    }\n\n    public Shape setType(int type) {\n        this.type = type;\n        return this;\n    }\n\n    public Shape setSize(int size) {\n        if (size >= 0) {\n            this.size = size;\n        }\n        return this;\n    }\n\n    public Shape setColor(int color) {\n        this.color = color;\n        return this;\n    }\n\n    public Shape setIcon(String icon) {\n        this.icon = icon;\n        return this;\n    }\n\n    public Shape setBorderRadius(int borderRadius) {\n        this.radius = borderRadius;\n        return this;\n    }\n    public Shape setLineWidth(int lineWidth) {\n        this.lineWidth = lineWidth;\n        return this;\n    }\n\n    public int type() {\n        return type;\n    }\n\n    public int size() {\n        return size;\n    }\n\n    public int color() {\n        return color;\n    }\n\n    public String icon() {\n        return icon;\n    }\n\n    public int radius() {\n        return radius;\n    }\n\n    public int lineWidth() {\n        return lineWidth;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/styles/TableStyle.java",
    "content": "package com.fluid.afm.styles;\n\nimport android.graphics.Color;\nimport android.graphics.Paint;\nimport android.os.Parcel;\nimport android.os.Parcelable;\nimport android.text.TextPaint;\n\nimport androidx.annotation.NonNull;\n\nimport com.fluid.afm.utils.ParseUtil;\n\nimport io.noties.markwon.utils.ColorUtils;\nimport com.fluid.afm.utils.Utils;\n\npublic class TableStyle implements Parcelable {\n    protected static final int TABLE_BORDER_DEF_ALPHA = 75;\n    public static final int DEFAULT_HEADER_TEXT_BACKGROUND_COLOR = 0xFFEDEFF2;\n\n    private int maxWidth;\n    private int maxHeight;\n    private TableCell title = new TableCell();\n    private TableCell header = new TableCell();\n    ;\n    private TableCell body = new TableCell();\n    ;\n    private int cellTopBottomPadding;\n    private int cellLeftRightPadding = Utils.dpToPx(12);\n    private float columnDefaultMaxWidth;\n    private float columnFirstMaxWidth;\n    private boolean drawBorder;\n    private int borderColor;\n    private int borderWidth = -1;\n    private int tableBlockRadius = -1;\n\n    private int textColor;\n    private int titleBackgroundRadius;\n\n    private int titleBarHeight = Utils.dpToPx(40);\n\n    public TableStyle() {\n        title.backgroundColor = Color.WHITE;\n        body.fontColor = 0xFF333333;\n        body.fontSize = 26;\n        header.fontColor = 0xFF999999;\n        header.fontSize = 26;\n    }\n\n    public static TableStyle create() {\n        return new TableStyle().tableBlockRadius(ParseUtil.parseDp(\"24rpx\"))\n                .fontColor(0xFF333333)\n                .titleFontColor(0xFF999999)\n                .titleBackgroundColor(0xFFEDEFF3)\n                .titleFontSize(ParseUtil.parseDp(\"30rpx\"))\n                .headerBackgroundColor(0xFFF6F7F9)\n                .headerFontSize(ParseUtil.parseDp(\"26rpx\"))\n                .titleBackgroundRadius(ParseUtil.parseDp(\"24rpx\"))\n                .bodyBackgroundColor(Color.WHITE)\n                .cellTopBottomPadding(ParseUtil.parseDp(\"6px\"))\n                .bodyFontSize(ParseUtil.parseDp(\"26rpx\"))\n                .drawBorder(true).borderColor(0xFFDEDEDE).borderWidth(ParseUtil.parseDp(\"1rpx\"));\n    }\n\n    public TableStyle maxWidth(int maxWidth) {\n        this.maxWidth = Math.max(0, maxWidth);\n        return this;\n    }\n\n    public TableStyle maxHeight(int maxHeight) {\n        this.maxHeight = Math.max(0, maxHeight);\n        return this;\n    }\n\n    public TableStyle titleFontSize(float size) {\n        this.title.fontSize = Math.max(0, size);\n        return this;\n    }\n\n    public TableStyle titleBackgroundColor(int color) {\n        this.title.backgroundColor = color;\n        return this;\n    }\n\n    public TableStyle headerFontSize(float size) {\n        this.header.fontSize = Math.max(0, size);\n        return this;\n    }\n\n    public TableStyle headerBackgroundColor(int color) {\n        this.header.backgroundColor = color;\n        return this;\n    }\n\n    public TableStyle bodyFontSize(float size) {\n        this.body.fontSize = Math.max(0, size);\n        return this;\n    }\n\n    public TableStyle bodyBackgroundColor(int color) {\n        this.body.backgroundColor = color;\n        return this;\n    }\n\n    public TableStyle cellTopBottomPadding(int rowTopBottomPadding) {\n        this.cellTopBottomPadding = Math.max(0, rowTopBottomPadding);\n        return this;\n    }\n\n    public TableStyle columnDefaultMaxWidth(float columnDefaultMaxWidth) {\n        this.columnDefaultMaxWidth = Math.max(0, columnDefaultMaxWidth);\n        return this;\n    }\n\n    public TableStyle columnFirstMaxWidth(float columnFirstMaxWidth) {\n        this.columnFirstMaxWidth = Math.max(0, columnFirstMaxWidth);\n        return this;\n    }\n\n    public TableStyle drawBorder(boolean drawBorder) {\n        this.drawBorder = drawBorder;\n        return this;\n    }\n\n    public TableStyle borderColor(int borderColor) {\n        this.borderColor = borderColor;\n        return this;\n    }\n\n    public TableStyle borderWidth(int borderWidth) {\n        this.borderWidth = Math.max(0, borderWidth);\n        if (this.borderWidth == 1) {\n            this.borderWidth = 2;\n        }\n        return this;\n    }\n\n    public TableStyle tableBlockRadius(int tableBlockRadius) {\n        this.tableBlockRadius = Math.max(0, tableBlockRadius);\n        return this;\n    }\n\n    public TableStyle fontColor(int color) {\n        this.textColor = color;\n        return this;\n    }\n\n    public TableStyle titleFontColor(int color) {\n        this.title.fontColor = color;\n        return this;\n    }\n\n    public int cellLeftRightPadding() {\n        return cellLeftRightPadding;\n    }\n\n    public TableStyle cellLeftRightPadding(int cellLeftRightPadding) {\n        this.cellLeftRightPadding = Math.max(0, cellLeftRightPadding);\n        return this;\n    }\n\n    public TableStyle titleBackgroundRadius(int headerBackgroundRadius) {\n        this.titleBackgroundRadius = Math.max(0, headerBackgroundRadius);\n        return this;\n    }\n\n    public int maxWidth() {\n        return maxWidth;\n    }\n\n    public int maxHeight() {\n        return maxHeight;\n    }\n\n    public TableCell title() {\n        return title;\n    }\n\n    public TableCell header() {\n        return header;\n    }\n\n    public TableCell body() {\n        return body;\n    }\n\n    public int cellTopBottomPadding() {\n        return cellTopBottomPadding;\n    }\n\n    public int rowLeftRightPadding() {\n        return cellLeftRightPadding;\n    }\n\n    public float columnDefaultMaxWidth() {\n        return columnDefaultMaxWidth;\n    }\n\n    public float columnFirstMaxWidth() {\n        return columnFirstMaxWidth;\n    }\n\n    public boolean drawBorder() {\n        return drawBorder;\n    }\n\n    public int borderColor() {\n        return borderColor;\n    }\n\n    public int borderWidth() {\n        return borderWidth;\n    }\n\n    public int tableBlockRadius() {\n        return tableBlockRadius;\n    }\n\n    public int getTextColor() {\n        return textColor;\n    }\n\n    public int titleBackgroundRadius() {\n        return titleBackgroundRadius;\n    }\n    public int titleBarHeight() {\n        return titleBarHeight;\n    }\n    public TableStyle titleBarHeight(int titleBarHeight) {\n        this.titleBarHeight = Math.max(0, titleBarHeight);\n        return this;\n    }\n\n    public void applyTableBorderStyle(@NonNull Paint paint) {\n        final int color;\n        if (borderColor() != 0) {\n            color = borderColor();\n        } else {\n            color = ColorUtils.applyAlpha(paint.getColor(), TABLE_BORDER_DEF_ALPHA);\n        }\n        if (borderWidth() > 0) {\n            paint.setStrokeWidth(borderWidth());\n        }\n        paint.setColor(color);\n        // @since 4.3.1 before it was STROKE... change to FILL as we draw border differently\n        paint.setStyle(Paint.Style.STROKE);\n    }\n\n\n    public void applyTableEvenRowStyle(@NonNull Paint paint) {\n        // by default to background to even row\n        handleBodyStyle(paint);\n    }\n\n\n    public void applyTableTextStyle(@NonNull TextPaint textPaint, boolean isHead) {\n        if (isHead) {\n            textPaint.setFakeBoldText(true);\n            textPaint.setTextSize(header().fontSize());\n            textPaint.setColor(getTextColor());\n        } else {\n            textPaint.setTextSize(body().fontSize());\n            textPaint.setColor(getTextColor());\n        }\n    }\n\n    public void applyTableHeaderRowStyle(@NonNull Paint paint) {\n        if (header().backgroundColor() != 0) {\n            paint.setColor(header().backgroundColor());\n        } else {\n            paint.setColor(DEFAULT_HEADER_TEXT_BACKGROUND_COLOR);\n        }\n        if (header().fontSize() > 0) {\n            paint.setTextSize(header().fontSize());\n        }\n        paint.setStyle(Paint.Style.FILL);\n    }\n\n    public void applyTableOddRowStyle(@NonNull Paint paint) {\n        handleBodyStyle(paint);\n    }\n\n    private void handleBodyStyle(@NonNull Paint paint) {\n        paint.setColor(body().backgroundColor());\n        if (borderWidth() >= 0) {\n            paint.setStrokeWidth(borderWidth());\n        }\n        if (body().fontSize() > 0) {\n            paint.setTextSize(body().fontSize());\n        }\n        paint.setStyle(Paint.Style.FILL);\n    }\n\n    @Override\n    public int describeContents() {\n        return 0;\n    }\n\n    @Override\n    public void writeToParcel(Parcel dest, int flags) {\n        dest.writeInt(maxWidth);\n        dest.writeInt(maxHeight);\n        dest.writeInt(cellTopBottomPadding);\n        dest.writeInt(cellLeftRightPadding);\n        dest.writeFloat(columnDefaultMaxWidth);\n        dest.writeFloat(columnFirstMaxWidth);\n        dest.writeInt(title.backgroundColor);\n        dest.writeFloat(title.fontSize);\n        dest.writeInt(header.backgroundColor);\n        dest.writeFloat(header.fontSize);\n        dest.writeInt(body.backgroundColor);\n        dest.writeFloat(body.fontSize);\n        dest.writeInt(drawBorder ? 1 : 0);\n        dest.writeInt(borderColor);\n        dest.writeInt(borderWidth);\n        dest.writeInt(tableBlockRadius);\n        dest.writeInt(textColor);\n        dest.writeInt(cellLeftRightPadding);\n    }\n\n    protected TableStyle(Parcel in) {\n        maxWidth = in.readInt();\n        maxHeight = in.readInt();\n        cellTopBottomPadding = in.readInt();\n        cellLeftRightPadding = in.readInt();\n        columnDefaultMaxWidth = in.readFloat();\n        columnFirstMaxWidth = in.readFloat();\n        title = new TableStyle.TableCell();\n        title.backgroundColor = in.readInt();\n        title.fontSize = in.readFloat();\n        header = new TableStyle.TableCell();\n        header.backgroundColor = in.readInt();\n        header.fontSize = in.readFloat();\n        body = new TableStyle.TableCell();\n        body.backgroundColor = in.readInt();\n        body.fontSize = in.readFloat();\n        drawBorder = in.readInt() == 1;\n        borderColor = in.readInt();\n        borderWidth = in.readInt();\n        tableBlockRadius = in.readInt();\n        textColor = in.readInt();\n        cellLeftRightPadding = in.readInt();\n    }\n\n    public static final Creator<TableStyle> CREATOR = new Creator<>() {\n        @Override\n        public TableStyle createFromParcel(Parcel in) {\n            return new TableStyle(in);\n        }\n\n        @Override\n        public TableStyle[] newArray(int size) {\n            return new TableStyle[size];\n        }\n    };\n\n    public static class TableCell {\n        private int backgroundColor;\n        private float fontSize;\n        private int fontColor;\n\n        public TableCell() {\n\n        }\n\n        public int backgroundColor() {\n            return backgroundColor;\n        }\n\n        public float fontSize() {\n            return fontSize;\n        }\n\n        public int fontColor() {\n            return fontColor;\n        }\n\n        public TableCell(int backgroundColor, float fontSize) {\n            this.backgroundColor = backgroundColor;\n            this.fontSize = fontSize;\n        }\n    }\n}"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/styles/TitleStyle.java",
    "content": "package com.fluid.afm.styles;\n\nimport android.graphics.Typeface;\nimport android.text.TextPaint;\n\npublic class TitleStyle {\n    public static final TitleStyle TITLE_DEFAULT = new TitleStyle(1f);\n    public static final TitleStyle[] TITLE_DEFAULT_SIZES = {\n            TitleStyle.create(1.3f), TitleStyle.create(1.2f), TitleStyle.create(1.1f),\n            TITLE_DEFAULT, TITLE_DEFAULT, TITLE_DEFAULT,\n    };\n    private String icon;\n    private int sizeType; // 0 scale, 1 px\n    private final ParagraphStyle paragraph = new ParagraphStyle();\n    private Typeface typeface;\n    private int paragraphSpacingBefore;\n\n    public static TitleStyle create(float fontSize) {\n        return new TitleStyle(fontSize);\n    }\n    public TitleStyle() {\n\n    }\n\n    public TitleStyle(float fontSize) {\n        this.paragraph.fontSize(fontSize);\n        sizeType = 0;\n    }\n\n    public TitleStyle fontSize(float fontSize) {\n        this.paragraph.fontSize(fontSize);\n        return this;\n    }\n\n    public TitleStyle icon(String icon) {\n        this.icon = icon;\n        return this;\n    }\n\n    public TitleStyle sizeType(int sizeType) {\n        this.sizeType = sizeType;\n        return this;\n    }\n    public TitleStyle paragraphSpacing(int paragraphSpacing) {\n        paragraph.paragraphSpacing(paragraphSpacing);\n        return this;\n    }\n\n    public TitleStyle paragraphSpacingBefore(int paragraphSpacingBefore) {\n        this.paragraphSpacingBefore = Math.max(0, paragraphSpacingBefore);\n        return this;\n    }\n\n    public int paragraphSpacingBefore() {\n        return paragraphSpacingBefore;\n    }\n    public TitleStyle setTypeface(Typeface typeface) {\n        this.typeface = typeface;\n        return this;\n    }\n\n    public String icon() {\n        return icon;\n    }\n\n    public ParagraphStyle paragraph() {\n        return paragraph;\n    }\n\n    public void apply(TextPaint paint) {\n        if (paragraph.fontColor() != 0) {\n            paint.setColor(paragraph.fontColor());\n        }\n        float size = paragraph.fontSize();\n        if (size > 0) {\n            if (sizeType == 0) {\n                paint.setTextSize(paint.getTextSize() * size);\n            } else {\n                paint.setTextSize(size);\n            }\n        }\n        if (typeface != null) {\n            paint.setTypeface(typeface);\n        } else {\n            paint.setFakeBoldText(true);\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/styles/UnderlineStyle.java",
    "content": "package com.fluid.afm.styles;\n\nimport com.fluid.afm.utils.Utils;\n\npublic class UnderlineStyle {\n    private int height = Utils.dpToPx(6);\n    private int color = 0x7A1677FF;\n\n    public static UnderlineStyle create(int height, int color) {\n        return new UnderlineStyle().setColor(color).setHeight(height);\n    }\n\n    public int getHeight() {\n        return height;\n    }\n\n    public int getColor() {\n        return color;\n    }\n\n    public UnderlineStyle setHeight(int height) {\n        this.height = Math.max(0, height);\n        return this;\n    }\n\n    public UnderlineStyle setColor(int color) {\n        this.color = color;\n        return this;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/utils/MDLogger.java",
    "content": "package com.fluid.afm.utils;\n\nimport com.fluid.afm.handler.EventHandlerManager;\n\npublic class MDLogger {\n    private static final String PREFIX_TAG = \"markdown\";\n\n    public static void i(String tag, String msg) {\n        EventHandlerManager.getLogHandler().i(PREFIX_TAG, tag + \":\" + msg);\n    }\n\n    public static void e(String tag, String msg) {\n        EventHandlerManager.getLogHandler().e(PREFIX_TAG, tag + \":\" + msg);\n    }\n\n    public static void e(String tag, Throwable tr) {\n        EventHandlerManager.getLogHandler().e(PREFIX_TAG, tag + \":\",  tr);\n    }\n\n    public static void e(String tag, String msg, Throwable tr) {\n        EventHandlerManager.getLogHandler().e(PREFIX_TAG, tag + \":\" + msg + \":\", tr);\n    }\n\n    public static void d(String tag, String msg) {\n        EventHandlerManager.getLogHandler().d(PREFIX_TAG, tag + \":\" + msg);\n    }\n\n    public static void v(String tag, String msg) {\n        EventHandlerManager.getLogHandler().v(PREFIX_TAG, tag + \":\" + msg);\n    }\n\n    public static void w(String tag, String msg) {\n        EventHandlerManager.getLogHandler().w(PREFIX_TAG, tag + \":\" + msg);\n    }\n\n    public static void w(String tag, Throwable tr) {\n        EventHandlerManager.getLogHandler().w(PREFIX_TAG, tag + \":\" + tr);\n    }\n\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/utils/ParseUtil.java",
    "content": "package com.fluid.afm.utils;\n\nimport android.content.Context;\nimport android.graphics.Color;\nimport android.text.TextUtils;\n\nimport com.fluid.afm.ContextHolder;\n\npublic class ParseUtil {\n\n    public static Integer parseColor(String color) {\n        return parseColor(color, 0);\n    }\n\n    public static Integer parseColor(String color, Integer defaultValue) {\n        try {\n            if (TextUtils.isEmpty(color)) {\n                return defaultValue;\n            }\n            return Color.parseColor(color);\n        } catch (Throwable e) {\n            MDLogger.e(\"ColorParseUtil\", \"parseColor failed:color=\" + color);\n        }\n        return defaultValue;\n    }\n\n    public static float parseFloat(String str, float def) {\n        try {\n            return Float.parseFloat(str);\n        } catch (Throwable e) {\n            MDLogger.e(\"ColorParseUtil\", \"parseFloat failed:str=\" + str);\n        }\n        return def;\n    }\n\n    public static int parseInt(String str, int def) {\n        try {\n            return Integer.parseInt(str);\n        } catch (Throwable e) {\n            MDLogger.e(\"ColorParseUtil\", \"parseInt failed:str=\" + str);\n        }\n        return def;\n    }\n\n    public static int parseDp(String str) {\n        return parseDp(ContextHolder.getContext(), str, 0);\n    }\n\n    public static int parseDp(String str, int def) {\n        return parseDp(ContextHolder.getContext(), str, def);\n    }\n\n    public static int parseDp(Context context, String str, int def) {\n        if (str == null) {\n            return def;\n        }\n        if (!TextUtils.isDigitsOnly(str)) {\n            if (str.endsWith(\"rpx\")) {\n                try {\n                    return (int) Utils.rpxToPx(Float.parseFloat(str.substring(0, str.length() - 3)), context);\n                } catch (Throwable e) {\n                    MDLogger.e(\"ColorParseUtil\", \"parseDp failed:str=\" + str);\n                }\n                return def;\n            } else if (str.endsWith(\"px\")) {\n                str = str.substring(0, str.length() - 2);\n            }\n        }\n        return Utils.dpToPx(context, parseFloat(str, def));\n    }\n\n    public static float parsePercent(String str, float def) {\n        try {\n            String percentStr = str.substring(0, str.length() - 1);\n            return parseFloat(percentStr, def) / 100;\n        } catch (Throwable throwable) {\n            MDLogger.e(\"ColorParseUtil\", \"parsePercent failed:str=\" + str);\n        }\n        return def;\n    }\n\n    public static int parseColorWithRGBA(String str) {\n        str = str.toLowerCase();\n        // #eee\n        if (!str.startsWith(\"#\")) {\n            return parseColor(str);\n        }\n\n        str = str.replace(\"#\", \"\");\n        if (!(str.length() == 3 || str.length() == 6 || str.length() == 8)) {\n            return 0;\n        }\n        String rString = \"\";\n        String gString = \"\";\n        String bString = \"\";\n        String aString = \"ff\";\n        if (str.length() == 3) {\n            rString += str.substring(0, 1);\n            rString += rString;\n            gString += str.substring(1, 2);\n            gString += gString;\n            bString += str.substring(2, 3);\n            bString += bString;\n        } else if (str.length() == 6) {\n            rString = str.substring(0, 2);\n            gString = str.substring(2, 4);\n            bString = str.substring(4, 6);\n        } else {\n            rString = str.substring(0, 2);\n            gString = str.substring(2, 4);\n            bString = str.substring(4, 6);\n            aString = str.substring(6, 8);\n        }\n\n        // Scan values\n        int r, g, b, a;\n        r = Integer.parseInt(rString, 16);\n        g = Integer.parseInt(gString, 16);\n        b = Integer.parseInt(bString, 16);\n        a = Integer.parseInt(aString, 16);\n        return Color.argb(a, r, g, b);\n    }\n\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/com/fluid/afm/utils/Utils.java",
    "content": "package com.fluid.afm.utils;\n\nimport android.content.Context;\nimport android.content.res.Resources;\nimport android.graphics.drawable.Drawable;\nimport android.os.Handler;\nimport android.os.Looper;\nimport android.util.DisplayMetrics;\nimport android.view.View;\n\nimport androidx.annotation.NonNull;\n\nimport com.fluid.afm.ContextHolder;\nimport com.fluid.afm.handler.EventHandlerManager;\n\nimport org.commonmark.node.Node;\n\nimport java.util.concurrent.ThreadPoolExecutor;\n\nimport com.fluid.afm.func.Callback;\n\npublic class Utils {\n\n    private static final String TAG = \"Utils\";\n    public static final float FONT_HEIGHT_IN_LINE = 8f / 9f;\n    public static final float FONT_SPACING_IN_LINE = 1f / 9f;\n\n    private static final Handler MAIN_HANDLER = new Handler(Looper.getMainLooper());\n\n    private static Integer screenWidth = null;\n    private static Integer screenHeight = null;\n\n    public static int dpToPx(float dp) {\n        return dpToPx(ContextHolder.getContext(), dp);\n    }\n\n    public static int dpToPx(Context context, float dp) {\n        if (context != null) {\n            float density = context.getResources().getDisplayMetrics().density;\n            return Math.round(dp * density);\n        }\n        MDLogger.i(TAG, \"dpToPx context == null, return dp*2\");\n        return Math.round(dp * 2);\n    }\n\n    public static float rpxToPx(float rpx) {\n        return rpxToPx(rpx, ContextHolder.getContext());\n    }\n\n    public static float rpxToPx(float rpx, Context context) {\n        DisplayMetrics metrics = context.getResources().getDisplayMetrics();\n        float screenWidth = metrics.widthPixels;\n        return rpx * (screenWidth / 750f);\n    }\n\n    public static boolean isNumeric(String str) {\n        return str != null && str.matches(\"[0-9]+\");\n    }\n\n    public static boolean runOnUiThread(View view, Runnable runnable) {\n        if (runnable == null) {\n            return false;\n        }\n\n        try {\n            if (Thread.currentThread().getId() == Looper.getMainLooper().getThread().getId()) {\n                runnable.run();\n            } else if (view != null) {\n                view.post(runnable);\n            } else {\n                MAIN_HANDLER.post(runnable);\n            }\n            return true;\n        } catch (Exception e) {\n            return false;\n        }\n    }\n    public static Drawable loadImageSync(Context context, String url, Drawable defaultDrawable) throws InterruptedException {\n        Drawable drawable = EventHandlerManager.getImageHandler().loadImageSync(context, url);\n        return drawable == null ? defaultDrawable : drawable;\n    }\n    public static Drawable loadImageSync(Context context, String url, int width, int height, Drawable defaultDrawable) throws InterruptedException {\n        Drawable drawable = EventHandlerManager.getImageHandler().loadImageSync(context, url, width, height);\n        return drawable == null ? defaultDrawable : drawable;\n    }\n\n    public static int getScreenWidth() {\n        return getScreenWidth(ContextHolder.getContext());\n    }\n\n    public static int getScreenWidth(Context context) {\n        if (screenWidth == null) {\n            screenWidth = context.getResources().getDisplayMetrics().widthPixels;\n        }\n        return screenWidth;\n    }\n\n    public static int getScreenHeight() {\n        return getScreenHeight(ContextHolder.getContext());\n    }\n\n    public static int getScreenHeight(Context context) {\n        if (screenHeight == null) {\n            screenHeight = context.getResources().getDisplayMetrics().heightPixels;\n        }\n        return screenHeight;\n    }\n\n    public static ThreadPoolExecutor acquireNormalThreadPoolExecutor() {\n        return EventHandlerManager.getBackgroundTaskHandler().acquireNormalThreadPoolExecutor();\n    }\n\n    public static float getDensity(Context context) {\n        if (context != null) {\n            return context.getResources().getDisplayMetrics().density;\n        }\n        return 3;\n    }\n\n    public static void loadImageAsyn(Context context, final String url, final Callback<Drawable> callback) {\n        EventHandlerManager.getImageHandler().loadImage(context, url, callback);\n    }\n\n    public static void loadImageAsyn(Context context, final String url, int width, int height, final Callback<Drawable> callback) {\n        EventHandlerManager.getImageHandler().loadImage(context, url, width, height, callback);\n    }\n\n    public static Resources getResources() {\n        return ContextHolder.getContext().getResources();\n    }\n\n    public static boolean isInTableNode(@NonNull Node node) {\n        return isInTableNode(node, 0);\n    }\n    private static boolean isInTableNode(@NonNull Node node, int depth) {\n        final Node parent = node.getParent();\n        if (parent != null && parent.getClass().getSimpleName().equals(\"TableCell\")) {\n            return true;\n        } else if (parent != null && depth < 5) {\n            return isInTableNode(parent, depth + 1);\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/AbstractMarkwonPlugin.java",
    "content": "package io.noties.markwon;\n\nimport android.text.Spanned;\nimport android.widget.TextView;\n\nimport androidx.annotation.NonNull;\n\nimport org.commonmark.node.Node;\nimport org.commonmark.parser.Parser;\n\nimport io.noties.markwon.core.MarkwonTheme;\n\n/**\n * Class that extends {@link MarkwonPlugin} with all methods implemented (empty body)\n * for easier plugin implementation. Only required methods can be overriden\n *\n * @see MarkwonPlugin\n * @since 3.0.0\n */\npublic abstract class AbstractMarkwonPlugin implements MarkwonPlugin {\n\n    @Override\n    public void configure(@NonNull Registry registry) {\n\n    }\n\n    @Override\n    public void configureParser(@NonNull Parser.Builder builder) {\n\n    }\n\n    @Override\n    public void configureTheme(@NonNull MarkwonTheme.Builder builder) {\n\n    }\n\n    @Override\n    public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) {\n\n    }\n\n    @Override\n    public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) {\n\n    }\n\n    @Override\n    public void configureSpansFactory(@NonNull MarkwonSpansFactory.Builder builder) {\n\n    }\n\n    @NonNull\n    @Override\n    public String processMarkdown(@NonNull String markdown) {\n        return markdown;\n    }\n\n    @Override\n    public void beforeRender(@NonNull Node node) {\n\n    }\n\n    @Override\n    public void afterRender(@NonNull Node node, @NonNull MarkwonVisitor visitor) {\n\n    }\n\n    @Override\n    public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) {\n\n    }\n\n    @Override\n    public void afterSetText(@NonNull TextView textView) {\n\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/BlockHandlerDef.java",
    "content": "package io.noties.markwon;\n\nimport androidx.annotation.NonNull;\n\nimport org.commonmark.node.Node;\n\n/**\n * @since 4.3.0\n */\npublic class BlockHandlerDef implements MarkwonVisitor.BlockHandler {\n    @Override\n    public void blockStart(@NonNull MarkwonVisitor visitor, @NonNull Node node) {\n        visitor.ensureNewLine();\n    }\n\n    @Override\n    public void blockEnd(@NonNull MarkwonVisitor visitor, @NonNull Node node) {\n        if (visitor.hasNext(node)) {\n            visitor.ensureNewLine();\n            visitor.forceNewLine();\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/LinkResolver.java",
    "content": "package io.noties.markwon;\n\nimport android.view.View;\n\nimport androidx.annotation.NonNull;\n\n/**\n * @see LinkResolverDef\n * @see MarkwonConfiguration.Builder#linkResolver(LinkResolver)\n * @since 4.0.0\n */\npublic interface LinkResolver {\n    void resolve(@NonNull View view, @NonNull String link);\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/LinkResolverDef.java",
    "content": "package io.noties.markwon;\n\nimport android.content.ActivityNotFoundException;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.net.Uri;\nimport android.provider.Browser;\nimport android.text.TextUtils;\nimport android.util.Log;\nimport android.view.View;\n\nimport androidx.annotation.NonNull;\n\npublic class LinkResolverDef implements LinkResolver {\n\n    // @since 4.3.0\n    private static final String DEFAULT_SCHEME = \"https\";\n\n    @Override\n    public void resolve(@NonNull View view, @NonNull String link) {\n        final Uri uri = parseLink(link);\n        final Context context = view.getContext();\n        final Intent intent = new Intent(Intent.ACTION_VIEW, uri);\n        intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());\n        try {\n            context.startActivity(intent);\n        } catch (ActivityNotFoundException e) {\n            Log.w(\"LinkResolverDef\", \"Actvity was not found for the link: '\" + link + \"'\");\n        }\n    }\n\n    /**\n     * @since 4.3.0\n     */\n    @NonNull\n    private static Uri parseLink(@NonNull String link) {\n        final Uri uri = Uri.parse(link);\n        if (TextUtils.isEmpty(uri.getScheme())) {\n            return uri.buildUpon()\n                    .scheme(DEFAULT_SCHEME)\n                    .build();\n        }\n        return uri;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/Markwon.java",
    "content": "package io.noties.markwon;\n\nimport android.content.Context;\nimport android.text.Spanned;\nimport android.widget.TextView;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport org.commonmark.node.Node;\n\nimport java.util.List;\n\nimport io.noties.markwon.core.CorePlugin;\nimport io.noties.markwon.core.MarkwonTheme;\n\n/**\n * Class to parse and render markdown. Since version 3.0.0 instance specific (previously consisted\n * of static stateless methods). An instance of builder can be obtained via {@link #builder(Context)}\n * method.\n *\n * @see #create(Context)\n * @see #builder(Context)\n * @see Builder\n */\npublic abstract class Markwon {\n\n    /**\n     * Factory method to create a <em>minimally</em> functional {@link Markwon} instance. This\n     * instance will have <strong>only</strong> {@link CorePlugin} registered. If you wish\n     * to configure this instance more consider using {@link #builder(Context)} method.\n     *\n     * @return {@link Markwon} instance with only CorePlugin registered\n     * @since 3.0.0\n     */\n    @NonNull\n    public static Markwon create(@NonNull Context context) {\n        return builder(context)\n                .usePlugin(CorePlugin.create(context))\n                .build();\n    }\n\n    /**\n     * Factory method to obtain an instance of {@link Builder} with {@link CorePlugin} added.\n     *\n     * @see Builder\n     * @see #builderNoCore(Context)\n     * @since 3.0.0\n     */\n    @NonNull\n    public static Builder builder(@NonNull Context context) {\n        return new MarkwonBuilderImpl(context)\n                // @since 4.0.0 add CorePlugin\n                .usePlugin(CorePlugin.create(context));\n    }\n    @NonNull\n    public static Builder builderWithPlugs(@NonNull Context context, List<MarkwonPlugin> plugins) {\n        return new MarkwonBuilderImpl(context, plugins);\n    }\n\n    /**\n     * Factory method to obtain an instance of {@link Builder} without {@link CorePlugin}.\n     *\n     * @since 4.0.0\n     */\n    @NonNull\n    public static Builder builderNoCore(@NonNull Context context) {\n        return new MarkwonBuilderImpl(context);\n    }\n\n    /**\n     * Method to parse markdown (without rendering)\n     *\n     * @param input markdown input to parse\n     * @return parsed via commonmark-java <code>org.commonmark.node.Node</code>\n     * @see #render(Node)\n     * @since 3.0.0\n     */\n    @NonNull\n    public abstract Node parse(@NonNull String input);\n\n    /**\n     * Create Spanned markdown from parsed Node (via {@link #parse(String)} call).\n     * <p>\n     * Please note that returned Spanned has few limitations. For example, images, tables\n     * and ordered lists require TextView to be properly displayed. This is why images and tables\n     * most likely won\\'t work in this case. Ordered lists might have mis-measurements. Whenever\n     * possible use {@link #setMarkdown(TextView, String)} or {@link #setParsedMarkdown(TextView, Spanned)}\n     * as these methods will additionally call specific {@link MarkwonPlugin} methods to <em>prepare</em>\n     * proper display.\n     *\n     * @since 3.0.0\n     */\n    @NonNull\n    public abstract Spanned render(@NonNull Node node);\n\n    /**\n     * This method will {@link #parse(String)} and {@link #render(Node)} supplied markdown. Returned\n     * Spanned has the same limitations as from {@link #render(Node)} method.\n     *\n     * @param input markdown input\n     * @see #parse(String)\n     * @see #render(Node)\n     * @since 3.0.0\n     */\n    @NonNull\n    public abstract Spanned toMarkdown(@NonNull String input);\n\n    public abstract void setMarkdown(@NonNull TextView textView, @NonNull String markdown);\n\n    public abstract void setParsedMarkdown(@NonNull TextView textView, @NonNull Spanned markdown);\n\n    /**\n     * Requests information if certain plugin has been registered. Please note that this\n     * method will check for super classes also, so if supplied with {@code markwon.hasPlugin(MarkwonPlugin.class)}\n     * this method (if has at least one plugin) will return true. If for example a custom\n     * (subclassed) version of a {@link CorePlugin} has been registered and given name\n     * {@code CorePlugin2}, then both {@code markwon.hasPlugin(CorePlugin2.class)} and\n     * {@code markwon.hasPlugin(CorePlugin.class)} will return true.\n     *\n     * @param plugin type to query\n     * @return true if a plugin is used when configuring this {@link Markwon} instance\n     */\n    public abstract boolean hasPlugin(@NonNull Class<? extends MarkwonPlugin> plugin);\n\n    @Nullable\n    public abstract <P extends MarkwonPlugin> P getPlugin(@NonNull Class<P> type);\n\n    /**\n     * @since 4.1.0\n     */\n    @NonNull\n    public abstract <P extends MarkwonPlugin> P requirePlugin(@NonNull Class<P> type);\n\n    /**\n     * @return a list of registered {@link MarkwonPlugin}\n     * @since 4.1.0\n     */\n    @NonNull\n    public abstract List<? extends MarkwonPlugin> getPlugins();\n\n    @NonNull\n    public abstract MarkwonConfiguration configuration();\n\n    /**\n     * Interface to set text on a TextView. Primary goal is to give a way to use PrecomputedText\n     * functionality\n     *\n     * @see PrecomputedTextSetterCompat\n     * @since 4.1.0\n     */\n    public interface TextSetter {\n        /**\n         * @param textView   TextView\n         * @param markdown   prepared markdown\n         * @param bufferType BufferType specified when building {@link Markwon} instance\n         *                   via {@link Builder#bufferType(TextView.BufferType)}\n         * @param onComplete action to run when set-text is finished (required to call in order\n         *                   to execute {@link MarkwonPlugin#afterSetText(TextView)})\n         */\n        void setText(\n                @NonNull TextView textView,\n                @NonNull Spanned markdown,\n                @NonNull TextView.BufferType bufferType,\n                @NonNull Runnable onComplete);\n    }\n\n    /**\n     * Builder for {@link Markwon}.\n     * <p>\n     * Please note that the order in which plugins are supplied is important as this order will be\n     * used through the whole usage of built Markwon instance\n     *\n     * @since 3.0.0\n     */\n    public interface Builder {\n\n        /**\n         * Specify bufferType when applying text to a TextView {@code textView.setText(CharSequence,BufferType)}.\n         * By default `BufferType.SPANNABLE` is used\n         *\n         * @param bufferType BufferType\n         */\n        @NonNull\n        Builder bufferType(@NonNull TextView.BufferType bufferType);\n\n        /**\n         * @param textSetter {@link TextSetter} to apply text to a TextView\n         * @since 4.1.0\n         */\n        @NonNull\n        Builder textSetter(@NonNull TextSetter textSetter);\n\n        @NonNull\n        Builder usePlugin(@NonNull MarkwonPlugin plugin);\n\n        @NonNull\n        Builder usePlugins(@NonNull Iterable<? extends MarkwonPlugin> plugins);\n\n        /**\n         * Control if small chunks of non-finished markdown sentences (for example, a single `*` character)\n         * should be displayed/rendered as raw input instead of an empty string.\n         * <p>\n         * Since 4.4.0 {@code true} by default, versions prior - {@code false}\n         *\n         * @since 4.4.0\n         */\n        @NonNull\n        Builder fallbackToRawInputWhenEmpty(boolean fallbackToRawInputWhenEmpty);\n\n        Builder setMarkdownTheme(MarkwonTheme theme);\n        @NonNull\n        Markwon build();\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/MarkwonBuilderImpl.java",
    "content": "package io.noties.markwon;\n\nimport android.content.Context;\nimport android.widget.TextView;\n\nimport androidx.annotation.NonNull;\n\nimport org.commonmark.parser.Parser;\n\nimport java.util.Collections;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.concurrent.CopyOnWriteArrayList;\n\nimport io.noties.markwon.core.MarkwonTheme;\n\n/**\n * @since 3.0.0\n */\nclass MarkwonBuilderImpl implements Markwon.Builder {\n\n    private final Context context;\n\n    private final CopyOnWriteArrayList<MarkwonPlugin> plugins;\n\n    private TextView.BufferType bufferType = TextView.BufferType.SPANNABLE;\n\n    private Markwon.TextSetter textSetter;\n\n    // @since 4.4.0\n    private boolean fallbackToRawInputWhenEmpty = true;\n    private MarkwonTheme theme;\n\n    MarkwonBuilderImpl(@NonNull Context context) {\n        this.context = context;\n        plugins = new CopyOnWriteArrayList<>();\n    }\n\n    MarkwonBuilderImpl(@NonNull Context context, List<MarkwonPlugin> plugins) {\n        this.context = context;\n        if (plugins != null) {\n            this.plugins = new CopyOnWriteArrayList<>(plugins);\n        } else {\n            this.plugins = new CopyOnWriteArrayList<>();\n        }\n    }\n\n    @NonNull\n    @Override\n    public Markwon.Builder bufferType(@NonNull TextView.BufferType bufferType) {\n        this.bufferType = bufferType;\n        return this;\n    }\n\n    @NonNull\n    @Override\n    public Markwon.Builder textSetter(@NonNull Markwon.TextSetter textSetter) {\n        this.textSetter = textSetter;\n        return this;\n    }\n\n    @NonNull\n    @Override\n    public Markwon.Builder usePlugin(@NonNull MarkwonPlugin plugin) {\n        plugins.add(plugin);\n        return this;\n    }\n\n    @NonNull\n    @Override\n    public Markwon.Builder usePlugins(@NonNull Iterable<? extends MarkwonPlugin> plugins) {\n\n        final Iterator<? extends MarkwonPlugin> iterator = plugins.iterator();\n\n        MarkwonPlugin plugin;\n\n        while (iterator.hasNext()) {\n            plugin = iterator.next();\n            if (plugin == null) {\n                throw new NullPointerException();\n            }\n            this.plugins.add(plugin);\n        }\n\n        return this;\n    }\n\n    @NonNull\n    @Override\n    public Markwon.Builder fallbackToRawInputWhenEmpty(boolean fallbackToRawInputWhenEmpty) {\n        this.fallbackToRawInputWhenEmpty = fallbackToRawInputWhenEmpty;\n        return this;\n    }\n\n    @Override\n    public Markwon.Builder setMarkdownTheme(MarkwonTheme theme) {\n        this.theme = theme;\n        return this;\n    }\n\n    @NonNull\n    @Override\n    public Markwon build() {\n\n        if (plugins.isEmpty()) {\n            throw new IllegalStateException(\"No plugins were added to this builder. Use #usePlugin \" +\n                    \"method to add them\");\n        }\n\n        // please note that this method must not modify supplied collection\n        // if nothing should be done -> the same collection can be returned\n        final List<MarkwonPlugin> plugins = preparePlugins(this.plugins);\n\n        final Parser.Builder parserBuilder = new Parser.Builder();\n\n        final MarkwonConfiguration.Builder configurationBuilder = new MarkwonConfiguration.Builder();\n        final MarkwonVisitor.Builder visitorBuilder = new MarkwonVisitorImpl.BuilderImpl();\n        final MarkwonSpansFactory.Builder spanFactoryBuilder = new MarkwonSpansFactoryImpl.BuilderImpl();\n\n        for (MarkwonPlugin plugin : plugins) {\n            plugin.configureParser(parserBuilder);\n            plugin.configureConfiguration(configurationBuilder);\n            plugin.configureVisitor(visitorBuilder);\n            plugin.configureSpansFactory(spanFactoryBuilder);\n        }\n\n        final MarkwonConfiguration configuration = configurationBuilder.build(theme, spanFactoryBuilder.build());\n\n        // @since 4.1.1\n        // @since 4.1.2 - do not reuse render-props (each render call should have own render-props)\n        final MarkwonVisitorFactory visitorFactory = MarkwonVisitorFactory.create(\n                visitorBuilder,\n                configuration);\n\n        return new MarkwonImpl(\n                bufferType,\n                textSetter,\n                parserBuilder.build(),\n                visitorFactory,\n                configuration,\n                Collections.unmodifiableList(plugins),\n                fallbackToRawInputWhenEmpty\n        );\n    }\n\n    @NonNull\n    private static List<MarkwonPlugin> preparePlugins(@NonNull List<MarkwonPlugin> plugins) {\n        return new RegistryImpl(plugins).process();\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/MarkwonConfiguration.java",
    "content": "package io.noties.markwon;\n\nimport androidx.annotation.NonNull;\n\nimport io.noties.markwon.core.MarkwonTheme;\nimport io.noties.markwon.image.AsyncDrawableLoader;\nimport io.noties.markwon.image.ImageSizeResolver;\nimport io.noties.markwon.image.ImageSizeResolverDef;\nimport io.noties.markwon.image.destination.ImageDestinationProcessor;\nimport io.noties.markwon.syntax.SyntaxHighlight;\nimport io.noties.markwon.syntax.SyntaxHighlightNoOp;\n\n/**\n * since 3.0.0 renamed `SpannableConfiguration` -&gt; `MarkwonConfiguration`\n */\npublic class MarkwonConfiguration {\n\n    @NonNull\n    public static Builder builder() {\n        return new Builder();\n    }\n\n    private final MarkwonTheme theme;\n    private final AsyncDrawableLoader asyncDrawableLoader;\n    private final SyntaxHighlight syntaxHighlight;\n    private final LinkResolver linkResolver;\n    // @since 4.4.0\n    private final ImageDestinationProcessor imageDestinationProcessor;\n    private final ImageSizeResolver imageSizeResolver;\n\n    // @since 3.0.0\n    private final MarkwonSpansFactory spansFactory;\n\n    private MarkwonConfiguration(@NonNull Builder builder) {\n        this.theme = builder.theme;\n        this.asyncDrawableLoader = builder.asyncDrawableLoader;\n        this.syntaxHighlight = builder.syntaxHighlight;\n        this.linkResolver = builder.linkResolver;\n        this.imageDestinationProcessor = builder.imageDestinationProcessor;\n        this.imageSizeResolver = builder.imageSizeResolver;\n        this.spansFactory = builder.spansFactory;\n    }\n\n    @NonNull\n    public MarkwonTheme theme() {\n        return theme;\n    }\n\n    @NonNull\n    public AsyncDrawableLoader asyncDrawableLoader() {\n        return asyncDrawableLoader;\n    }\n\n    @NonNull\n    public SyntaxHighlight syntaxHighlight() {\n        return syntaxHighlight;\n    }\n\n    @NonNull\n    public LinkResolver linkResolver() {\n        return linkResolver;\n    }\n\n    /**\n     * @since 4.4.0\n     */\n    @NonNull\n    public ImageDestinationProcessor imageDestinationProcessor() {\n        return imageDestinationProcessor;\n    }\n\n    @NonNull\n    public ImageSizeResolver imageSizeResolver() {\n        return imageSizeResolver;\n    }\n\n    /**\n     * @since 3.0.0\n     */\n    @NonNull\n    public MarkwonSpansFactory spansFactory() {\n        return spansFactory;\n    }\n\n    @SuppressWarnings({\"unused\", \"UnusedReturnValue\"})\n    public static class Builder {\n\n        private MarkwonTheme theme;\n        private AsyncDrawableLoader asyncDrawableLoader;\n        private SyntaxHighlight syntaxHighlight;\n        private LinkResolver linkResolver;\n        // @since 4.4.0\n        private ImageDestinationProcessor imageDestinationProcessor;\n        private ImageSizeResolver imageSizeResolver;\n        private MarkwonSpansFactory spansFactory;\n\n        Builder() {\n        }\n\n        /**\n         * @since 4.0.0\n         */\n        @NonNull\n        public Builder asyncDrawableLoader(@NonNull AsyncDrawableLoader asyncDrawableLoader) {\n            this.asyncDrawableLoader = asyncDrawableLoader;\n            return this;\n        }\n\n        @NonNull\n        public Builder syntaxHighlight(@NonNull SyntaxHighlight syntaxHighlight) {\n            this.syntaxHighlight = syntaxHighlight;\n            return this;\n        }\n\n        @NonNull\n        public Builder linkResolver(@NonNull LinkResolver linkResolver) {\n            this.linkResolver = linkResolver;\n            return this;\n        }\n\n        /**\n         * @since 4.4.0\n         */\n        @NonNull\n        public Builder imageDestinationProcessor(@NonNull ImageDestinationProcessor imageDestinationProcessor) {\n            this.imageDestinationProcessor = imageDestinationProcessor;\n            return this;\n        }\n\n        /**\n         * @since 1.0.1\n         */\n        @NonNull\n        public Builder imageSizeResolver(@NonNull ImageSizeResolver imageSizeResolver) {\n            this.imageSizeResolver = imageSizeResolver;\n            return this;\n        }\n\n        @NonNull\n        public MarkwonConfiguration build(\n                @NonNull MarkwonTheme theme,\n                @NonNull MarkwonSpansFactory spansFactory) {\n\n            this.theme = theme;\n            this.spansFactory = spansFactory;\n\n            // @since 4.0.0\n            if (asyncDrawableLoader == null) {\n                asyncDrawableLoader = AsyncDrawableLoader.noOp();\n            }\n\n            if (syntaxHighlight == null) {\n                syntaxHighlight = new SyntaxHighlightNoOp();\n            }\n\n            if (linkResolver == null) {\n                linkResolver = new LinkResolverDef();\n            }\n\n            // @since 4.4.0\n            if (imageDestinationProcessor == null) {\n                imageDestinationProcessor = ImageDestinationProcessor.noOp();\n            }\n\n            if (imageSizeResolver == null) {\n                imageSizeResolver = new ImageSizeResolverDef();\n            }\n\n            return new MarkwonConfiguration(this);\n        }\n    }\n\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/MarkwonImpl.java",
    "content": "package io.noties.markwon;\n\nimport android.text.SpannableStringBuilder;\nimport android.text.Spanned;\nimport android.text.TextUtils;\nimport android.widget.TextView;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport org.commonmark.node.Node;\nimport org.commonmark.parser.Parser;\n\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Locale;\n\n/**\n * @since 3.0.0\n */\nclass MarkwonImpl extends Markwon {\n\n    private final TextView.BufferType bufferType;\n    private final Parser parser;\n    private final MarkwonVisitorFactory visitorFactory; // @since 4.1.1\n    private final MarkwonConfiguration configuration;\n    private final List<MarkwonPlugin> plugins;\n\n    // @since 4.1.0\n    @Nullable\n    private final TextSetter textSetter;\n\n    // @since 4.4.0\n    private final boolean fallbackToRawInputWhenEmpty;\n\n    MarkwonImpl(\n            @NonNull TextView.BufferType bufferType,\n            @Nullable TextSetter textSetter,\n            @NonNull Parser parser,\n            @NonNull MarkwonVisitorFactory visitorFactory,\n            @NonNull MarkwonConfiguration configuration,\n            @NonNull List<MarkwonPlugin> plugins,\n            boolean fallbackToRawInputWhenEmpty\n    ) {\n        this.bufferType = bufferType;\n        this.textSetter = textSetter;\n        this.parser = parser;\n        this.visitorFactory = visitorFactory;\n        this.configuration = configuration;\n        this.plugins = plugins;\n        this.fallbackToRawInputWhenEmpty = fallbackToRawInputWhenEmpty;\n    }\n\n    @NonNull\n    @Override\n    public Node parse(@NonNull String input) {\n\n        // make sure that all plugins are called `processMarkdown` before parsing\n        for (MarkwonPlugin plugin : plugins) {\n            input = plugin.processMarkdown(input);\n        }\n\n        return parser.parse(input);\n    }\n\n    @NonNull\n    @Override\n    public Spanned render(@NonNull Node node) {\n\n        for (MarkwonPlugin plugin : plugins) {\n            plugin.beforeRender(node);\n        }\n\n        // @since 4.1.1 obtain visitor via factory\n        final MarkwonVisitor visitor = visitorFactory.create();\n\n        node.accept(visitor);\n\n        for (MarkwonPlugin plugin : plugins) {\n            plugin.afterRender(node, visitor);\n        }\n\n        //noinspection UnnecessaryLocalVariable\n        final Spanned spanned = visitor.builder().spannableStringBuilder();\n\n        // clear render props and builder after rendering\n        // @since 4.1.1 as we no longer reuse visitor - there is no need to clean it\n        //  we might still do it if we introduce a thread-local storage though\n//        visitor.clear();\n\n        return spanned;\n    }\n\n    @NonNull\n    @Override\n    public Spanned toMarkdown(@NonNull String input) {\n        final Spanned spanned = render(parse(input));\n\n        // @since 4.4.0\n        // if spanned is empty, we are configured to use raw input and input is not empty\n        if (TextUtils.isEmpty(spanned)\n                && fallbackToRawInputWhenEmpty\n                && !TextUtils.isEmpty(input)) {\n            // let's use SpannableStringBuilder in order to keep backward-compatibility\n            return new SpannableStringBuilder(input);\n        }\n\n        return spanned;\n    }\n\n    @Override\n    public void setMarkdown(@NonNull TextView textView, @NonNull String markdown) {\n        setParsedMarkdown(textView, toMarkdown(markdown));\n    }\n\n    @Override\n    public void setParsedMarkdown(@NonNull final TextView textView, @NonNull Spanned markdown) {\n\n        for (MarkwonPlugin plugin : plugins) {\n            plugin.beforeSetText(textView, markdown);\n        }\n\n        // @since 4.1.0\n        if (textSetter != null) {\n            textSetter.setText(textView, markdown, bufferType, new Runnable() {\n                @Override\n                public void run() {\n                    // on-complete we just must call `afterSetText` on all plugins\n                    for (MarkwonPlugin plugin : plugins) {\n                        plugin.afterSetText(textView);\n                    }\n                }\n            });\n        } else {\n\n            // if no text-setter is specified -> just a regular sync operation\n            textView.setText(markdown, bufferType);\n\n            for (MarkwonPlugin plugin : plugins) {\n                plugin.afterSetText(textView);\n            }\n        }\n    }\n\n    @Override\n    public boolean hasPlugin(@NonNull Class<? extends MarkwonPlugin> type) {\n        return getPlugin(type) != null;\n    }\n\n    @Nullable\n    @Override\n    public <P extends MarkwonPlugin> P getPlugin(@NonNull Class<P> type) {\n        MarkwonPlugin out = null;\n        for (MarkwonPlugin plugin : plugins) {\n            if (type.isAssignableFrom(plugin.getClass())) {\n                out = plugin;\n            }\n        }\n        //noinspection unchecked\n        return (P) out;\n    }\n\n    @NonNull\n    @Override\n    public <P extends MarkwonPlugin> P requirePlugin(@NonNull Class<P> type) {\n        final P plugin = getPlugin(type);\n        if (plugin == null) {\n            throw new IllegalStateException(String.format(Locale.US, \"Requested plugin `%s` is not \" +\n                    \"registered with this Markwon instance\", type.getName()));\n        }\n        return plugin;\n    }\n\n    @NonNull\n    @Override\n    public List<? extends MarkwonPlugin> getPlugins() {\n        return Collections.unmodifiableList(plugins);\n    }\n\n    @NonNull\n    @Override\n    public MarkwonConfiguration configuration() {\n        return configuration;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/MarkwonPlugin.java",
    "content": "package io.noties.markwon;\n\nimport android.text.Spanned;\nimport android.widget.TextView;\n\nimport androidx.annotation.NonNull;\n\nimport org.commonmark.node.Node;\nimport org.commonmark.parser.Parser;\n\nimport io.noties.markwon.core.CorePlugin;\nimport io.noties.markwon.core.MarkwonTheme;\nimport io.noties.markwon.image.AsyncDrawableSpan;\nimport io.noties.markwon.movement.MovementMethodPlugin;\n\n/**\n * Class represents a plugin (extension) to Markwon to configure how parsing and rendering\n * of markdown is carried on.\n *\n * @see AbstractMarkwonPlugin\n * @see CorePlugin\n * @see MovementMethodPlugin\n * @since 3.0.0\n */\npublic interface MarkwonPlugin {\n\n    /**\n     * @see Registry#require(Class, Action)\n     * @since 4.0.0\n     */\n    interface Action<P extends MarkwonPlugin> {\n        void apply(@NonNull P p);\n    }\n\n    /**\n     * @see #configure(Registry)\n     * @since 4.0.0\n     */\n    interface Registry {\n\n        @NonNull\n        <P extends MarkwonPlugin> P require(@NonNull Class<P> plugin);\n\n        <P extends MarkwonPlugin> void require(\n                @NonNull Class<P> plugin,\n                @NonNull Action<? super P> action);\n    }\n\n    /**\n     * This method will be called before any other during {@link Markwon} instance construction.\n     *\n     * @since 4.0.0\n     */\n    void configure(@NonNull Registry registry);\n\n    /**\n     * Method to configure <code>org.commonmark.parser.Parser</code> (for example register custom\n     * extension, etc).\n     */\n    void configureParser(@NonNull Parser.Builder builder);\n\n    /**\n     * Modify {@link MarkwonTheme} that is used for rendering of markdown.\n     *\n     * @see MarkwonTheme\n     * @see MarkwonTheme.Builder\n     */\n    void configureTheme(@NonNull MarkwonTheme.Builder builder);\n\n    /**\n     * Configure {@link MarkwonConfiguration}\n     *\n     * @see MarkwonConfiguration\n     * @see MarkwonConfiguration.Builder\n     */\n    void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder);\n\n    /**\n     * Configure {@link MarkwonVisitor} to accept new node types or override already registered nodes.\n     *\n     * @see MarkwonVisitor\n     * @see MarkwonVisitor.Builder\n     */\n    void configureVisitor(@NonNull MarkwonVisitor.Builder builder);\n\n    /**\n     * Configure {@link MarkwonSpansFactory} to change what spans are used for certain node types.\n     *\n     * @see MarkwonSpansFactory\n     * @see MarkwonSpansFactory.Builder\n     */\n    void configureSpansFactory(@NonNull MarkwonSpansFactory.Builder builder);\n\n    /**\n     * Process input markdown and return new string to be used in parsing stage further.\n     * Can be described as <code>pre-processing</code> of markdown String.\n     *\n     * @param markdown String to process\n     * @return processed markdown String\n     */\n    @NonNull\n    String processMarkdown(@NonNull String markdown);\n\n    /**\n     * This method will be called <strong>before</strong> rendering will occur thus making possible\n     * to <code>post-process</code> parsed node (make changes for example).\n     *\n     * @param node root parsed org.commonmark.node.Node\n     */\n    void beforeRender(@NonNull Node node);\n\n    /**\n     * This method will be called <strong>after</strong> rendering (but before applying markdown to a\n     * TextView, if such action will happen). It can be used to clean some\n     * internal state, or trigger certain action. Please note that modifying <code>node</code> won\\'t\n     * have any effect as it has been already <i>visited</i> at this stage.\n     *\n     * @param node    root parsed org.commonmark.node.Node\n     * @param visitor {@link MarkwonVisitor} instance used to render markdown\n     */\n    void afterRender(@NonNull Node node, @NonNull MarkwonVisitor visitor);\n\n    /**\n     * This method will be called <strong>before</strong> calling <code>TextView#setText</code>.\n     * <p>\n     * It can be useful to prepare a TextView for markdown. For example {@code ru.noties.markwon.image.ImagesPlugin}\n     * uses this method to unregister previously registered {@link AsyncDrawableSpan}\n     * (if there are such spans in this TextView at this point). Or {@link CorePlugin}\n     * which measures ordered list numbers\n     *\n     * @param textView TextView to which <code>markdown</code> will be applied\n     * @param markdown Parsed markdown\n     */\n    void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown);\n\n    /**\n     * This method will be called <strong>after</strong> markdown was applied.\n     * <p>\n     * It can be useful to trigger certain action on spans/textView. For example {@code ru.noties.markwon.image.ImagesPlugin}\n     * uses this method to register {@link AsyncDrawableSpan} and start\n     * asynchronously loading images.\n     * <p>\n     * Unlike {@link #beforeSetText(TextView, Spanned)} this method does not receive parsed markdown\n     * as at this point spans must be queried by calling <code>TextView#getText#getSpans</code>.\n     *\n     * @param textView TextView to which markdown was applied\n     */\n    void afterSetText(@NonNull TextView textView);\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/MarkwonReducer.java",
    "content": "package io.noties.markwon;\n\nimport androidx.annotation.NonNull;\n\nimport org.commonmark.node.LinkReferenceDefinition;\nimport org.commonmark.node.Node;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\n/**\n * @since 3.0.0\n */\npublic abstract class MarkwonReducer {\n\n    /**\n     * @return direct children of supplied Node. In the most usual case\n     * will return all BlockNodes of a Document\n     */\n    @NonNull\n    public static MarkwonReducer directChildren() {\n        return new DirectChildren();\n    }\n\n    @NonNull\n    public abstract List<Node> reduce(@NonNull Node node);\n\n\n    static class DirectChildren extends MarkwonReducer {\n\n        @NonNull\n        @Override\n        public List<Node> reduce(@NonNull Node root) {\n\n            final List<Node> list;\n\n            // we will extract all blocks that are direct children of Document\n            Node node = root.getFirstChild();\n\n            // please note, that if there are no children -> we will return a list with\n            // single element (which was supplied)\n            if (node == null) {\n                list = Collections.singletonList(root);\n            } else {\n\n                list = new ArrayList<>();\n\n                Node temp;\n\n                while (node != null) {\n                    // @since 4.5.0 do not include LinkReferenceDefinition node (would result\n                    //  in empty textView if rendered in recycler-view)\n                    if (!(node instanceof LinkReferenceDefinition)) {\n                        list.add(node);\n                    }\n                    temp = node.getNext();\n                    node.unlink();\n                    node = temp;\n                }\n            }\n\n            return list;\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/MarkwonSpansFactory.java",
    "content": "package io.noties.markwon;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport org.commonmark.node.Node;\n\n/**\n * Class that controls what spans are used for certain Nodes.\n *\n * @see SpanFactory\n * @since 3.0.0\n */\npublic interface MarkwonSpansFactory {\n\n    /**\n     * Returns registered {@link SpanFactory} or <code>null</code> if a factory for this node type\n     * is not registered. There is {@link #require(Class)} method that will throw an exception\n     * if required {@link SpanFactory} is not registered, thus making return type <code>non-null</code>\n     *\n     * @param node type of the node\n     * @return registered {@link SpanFactory} or null if it\\'s not registered\n     * @see #require(Class)\n     */\n    @Nullable\n    <N extends Node> SpanFactory get(@NonNull Class<N> node);\n\n    @NonNull\n    <N extends Node> SpanFactory require(@NonNull Class<N> node);\n\n\n    interface Builder {\n\n        @NonNull\n        <N extends Node> Builder setFactory(@NonNull Class<N> node, @Nullable SpanFactory factory);\n\n        /**\n         * Helper method to add a {@link SpanFactory} for a Node. This method will merge existing\n         * {@link SpanFactory} with the specified one.\n         *\n         * @since 3.0.1\n         * @deprecated 4.2.2 consider using {@link #appendFactory(Class, SpanFactory)} or\n         * {@link #prependFactory(Class, SpanFactory)} methods for more explicit factory ordering.\n         * `addFactory` behaved like {@link #prependFactory(Class, SpanFactory)}, so\n         * this method call can be replaced with it\n         */\n        @NonNull\n        @Deprecated\n        <N extends Node> Builder addFactory(@NonNull Class<N> node, @NonNull SpanFactory factory);\n\n        /**\n         * Append a factory to existing one (or make the first one for specified node). Specified factory\n         * will be called <strong>after</strong> original (if present) factory. Can be used to\n         * <em>change</em> behavior or original span factory.\n         *\n         * @since 4.2.2\n         */\n        @NonNull\n        <N extends Node> Builder appendFactory(@NonNull Class<N> node, @NonNull SpanFactory factory);\n\n        /**\n         * Prepend a factory to existing one (or make the first one for specified node). Specified factory\n         * will be called <string>before</string> original (if present) factory.\n         *\n         * @since 4.2.2\n         */\n        @NonNull\n        <N extends Node> Builder prependFactory(@NonNull Class<N> node, @NonNull SpanFactory factory);\n\n        /**\n         * Can be useful when <em>enhancing</em> an already defined SpanFactory with another one.\n         */\n        @Nullable\n        <N extends Node> SpanFactory getFactory(@NonNull Class<N> node);\n\n        /**\n         * To obtain current {@link SpanFactory} associated with specified node. Can be used\n         * when SpanFactory must be present for node. If it\\'s not added/registered a runtime\n         * exception will be thrown\n         *\n         * @see #getFactory(Class)\n         * @since 3.0.1\n         */\n        @NonNull\n        <N extends Node> SpanFactory requireFactory(@NonNull Class<N> node);\n\n        @NonNull\n        MarkwonSpansFactory build();\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/MarkwonSpansFactoryImpl.java",
    "content": "package io.noties.markwon;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport org.commonmark.node.Node;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * @since 3.0.0\n */\nclass MarkwonSpansFactoryImpl implements MarkwonSpansFactory {\n\n    private final Map<Class<? extends Node>, SpanFactory> factories;\n\n    MarkwonSpansFactoryImpl(@NonNull Map<Class<? extends Node>, SpanFactory> factories) {\n        this.factories = factories;\n    }\n\n    @Nullable\n    @Override\n    public <N extends Node> SpanFactory get(@NonNull Class<N> node) {\n        return factories.get(node);\n    }\n\n    @NonNull\n    @Override\n    public <N extends Node> SpanFactory require(@NonNull Class<N> node) {\n        final SpanFactory f = get(node);\n        if (f == null) {\n            throw new NullPointerException(node.getName());\n        }\n        return f;\n    }\n\n    static class BuilderImpl implements Builder {\n\n        private final Map<Class<? extends Node>, SpanFactory> factories =\n                new HashMap<>(3);\n\n        @NonNull\n        @Override\n        public <N extends Node> Builder setFactory(@NonNull Class<N> node, @Nullable SpanFactory factory) {\n            if (factory == null) {\n                factories.remove(node);\n            } else {\n                factories.put(node, factory);\n            }\n            return this;\n        }\n\n        @NonNull\n        @Override\n        @Deprecated\n        public <N extends Node> Builder addFactory(@NonNull Class<N> node, @NonNull SpanFactory factory) {\n            return prependFactory(node, factory);\n        }\n\n        @NonNull\n        @Override\n        public <N extends Node> Builder appendFactory(@NonNull Class<N> node, @NonNull SpanFactory factory) {\n            final SpanFactory existing = factories.get(node);\n            if (existing == null) {\n                factories.put(node, factory);\n            } else {\n                if (existing instanceof CompositeSpanFactory) {\n                    ((CompositeSpanFactory) existing).factories.add(0, factory);\n                } else {\n                    final CompositeSpanFactory compositeSpanFactory =\n                            new CompositeSpanFactory(factory, existing);\n                    factories.put(node, compositeSpanFactory);\n                }\n            }\n            return this;\n        }\n\n        @NonNull\n        @Override\n        public <N extends Node> Builder prependFactory(@NonNull Class<N> node, @NonNull SpanFactory factory) {\n            // if there is no factory registered for this node -> just add it\n            final SpanFactory existing = factories.get(node);\n            if (existing == null) {\n                factories.put(node, factory);\n            } else {\n                // existing span factory can be of CompositeSpanFactory at this point -> append to it\n                if (existing instanceof CompositeSpanFactory) {\n                    ((CompositeSpanFactory) existing).factories.add(factory);\n                } else {\n                    // if it's not composite at this point -> make it\n                    final CompositeSpanFactory compositeSpanFactory =\n                            new CompositeSpanFactory(existing, factory);\n                    factories.put(node, compositeSpanFactory);\n                }\n            }\n            return this;\n        }\n\n        @Nullable\n        @Override\n        public <N extends Node> SpanFactory getFactory(@NonNull Class<N> node) {\n            return factories.get(node);\n        }\n\n        @NonNull\n        @Override\n        public <N extends Node> SpanFactory requireFactory(@NonNull Class<N> node) {\n            final SpanFactory factory = getFactory(node);\n            if (factory == null) {\n                throw new NullPointerException(node.getName());\n            }\n            return factory;\n        }\n\n        @NonNull\n        @Override\n        public MarkwonSpansFactory build() {\n            return new MarkwonSpansFactoryImpl(Collections.unmodifiableMap(factories));\n        }\n    }\n\n    static class CompositeSpanFactory implements SpanFactory {\n\n        final List<SpanFactory> factories;\n\n        CompositeSpanFactory(@NonNull SpanFactory first, @NonNull SpanFactory second) {\n            this.factories = new ArrayList<>(3);\n            this.factories.add(first);\n            this.factories.add(second);\n        }\n\n        @Nullable\n        @Override\n        public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps props) {\n            // please note that we do not check it factory itself returns an array of spans,\n            // as this behaviour is supported now (previously we supported only a single-level array)\n            final int length = factories.size();\n            final Object[] out = new Object[length];\n            for (int i = 0; i < length; i++) {\n                out[i] = factories.get(i).getSpans(configuration, props);\n            }\n            return out;\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/MarkwonVisitor.java",
    "content": "package io.noties.markwon;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport org.commonmark.node.Node;\nimport org.commonmark.node.Visitor;\n\n/**\n * Configurable visitor of parsed markdown. Allows visiting certain (registered) nodes without\n * need to create own instance of this class.\n *\n * @see Builder#on(Class, NodeVisitor)\n * @see MarkwonPlugin#configureVisitor(Builder)\n * @since 3.0.0\n */\npublic interface MarkwonVisitor extends Visitor {\n\n    /**\n     * @see Builder#on(Class, NodeVisitor)\n     */\n    interface NodeVisitor<N extends Node> {\n        void visit(@NonNull MarkwonVisitor visitor, @NonNull N n);\n    }\n\n    /**\n     * Primary purpose is to control the spacing applied before/after certain blocks, which\n     * visitors are created elsewhere\n     *\n     * @since 4.3.0\n     */\n    interface BlockHandler {\n\n        void blockStart(@NonNull MarkwonVisitor visitor, @NonNull Node node);\n\n        void blockEnd(@NonNull MarkwonVisitor visitor, @NonNull Node node);\n    }\n\n    interface Builder {\n\n        /**\n         * @param node        to register\n         * @param nodeVisitor {@link NodeVisitor} to be used or null to ignore previously registered\n         *                    visitor for this node\n         */\n        @NonNull\n        <N extends Node> Builder on(@NonNull Class<N> node, @Nullable NodeVisitor<? super N> nodeVisitor);\n\n        /**\n         * @param blockHandler to handle block start/end\n         * @see BlockHandler\n         * @see BlockHandlerDef\n         * @since 4.3.0\n         */\n        @SuppressWarnings(\"UnusedReturnValue\")\n        @NonNull\n        Builder blockHandler(@NonNull BlockHandler blockHandler);\n\n        @NonNull\n        MarkwonVisitor build(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps renderProps);\n    }\n\n    @NonNull\n    MarkwonConfiguration configuration();\n\n    @NonNull\n    RenderProps renderProps();\n\n    @NonNull\n    SpannableBuilder builder();\n\n    /**\n     * Visits all children of supplied node.\n     *\n     * @param node to visit\n     */\n    void visitChildren(@NonNull Node node);\n\n    /**\n     * Executes a check if there is further content available.\n     *\n     * @param node to check\n     * @return boolean indicating if there are more nodes after supplied one\n     */\n    boolean hasNext(@NonNull Node node);\n\n    /**\n     * This method <strong>ensures</strong> that further content will start at a new line. If current\n     * last character is already a new line, then it won\\'t do anything.\n     */\n    void ensureNewLine();\n\n    /**\n     * This method inserts a new line without any condition checking (unlike {@link #ensureNewLine()}).\n     */\n    void forceNewLine();\n\n    /**\n     * Helper method to call <code>builder().length()</code>\n     *\n     * @return current length of underlying {@link SpannableBuilder}\n     */\n    int length();\n\n    /**\n     * Clears state of visitor (both {@link RenderProps} and {@link SpannableBuilder} will be cleared\n     */\n    void clear();\n\n    /**\n     * Sets <code>spans</code> to underlying {@link SpannableBuilder} from <em>start</em>\n     * to <em>{@link SpannableBuilder#length()}</em>.\n     *\n     * @param start start position of spans\n     * @param spans to apply\n     */\n    void setSpans(int start, @Nullable Object spans);\n\n    /**\n     * Helper method to obtain and apply spans for supplied Node. Internally queries {@link SpanFactory}\n     * for the node (via {@link MarkwonSpansFactory#require(Class)} thus throwing an exception\n     * if there is no {@link SpanFactory} registered for the node).\n     *\n     * @param node  to retrieve {@link SpanFactory} for\n     * @param start start position for further {@link #setSpans(int, Object)} call\n     * @see #setSpansForNodeOptional(Node, int)\n     */\n    <N extends Node> void setSpansForNode(@NonNull N node, int start);\n\n    /**\n     * The same as {@link #setSpansForNode(Node, int)} but can be used in situations when there is\n     * no access to a Node instance (for example in HTML rendering which doesn\\'t have markdown Nodes).\n     *\n     * @see #setSpansForNode(Node, int)\n     */\n    <N extends Node> void setSpansForNode(@NonNull Class<N> node, int start);\n\n    // does not throw if there is no SpanFactory registered for this node\n\n    /**\n     * Helper method to apply spans from a {@link SpanFactory} <b>if</b> it\\'s registered in\n     * {@link MarkwonSpansFactory} instance. Otherwise ignores this call (no spans will be applied).\n     * If there is a need to ensure that specified <code>node</code> has a {@link SpanFactory} registered,\n     * then {@link #setSpansForNode(Node, int)} can be used. {@link #setSpansForNode(Node, int)} internally\n     * uses {@link MarkwonSpansFactory#require(Class)}. This method uses {@link MarkwonSpansFactory#get(Class)}.\n     *\n     * @see #setSpansForNode(Node, int)\n     */\n    <N extends Node> void setSpansForNodeOptional(@NonNull N node, int start);\n\n    /**\n     * The same as {@link #setSpansForNodeOptional(Node, int)} but can be used in situations when\n     * there is no access to a Node instance (for example in HTML rendering).\n     *\n     * @see #setSpansForNodeOptional(Node, int)\n     */\n    @SuppressWarnings(\"unused\")\n    <N extends Node> void setSpansForNodeOptional(@NonNull Class<N> node, int start);\n\n    /**\n     * @since 4.3.0\n     */\n    void blockStart(@NonNull Node node);\n\n    /**\n     * @since 4.3.0\n     */\n    void blockEnd(@NonNull Node node);\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/MarkwonVisitorFactory.java",
    "content": "package io.noties.markwon;\n\nimport androidx.annotation.NonNull;\n\n/**\n * @since 4.1.1\n */\nabstract class MarkwonVisitorFactory {\n\n    @NonNull\n    abstract MarkwonVisitor create();\n\n    @NonNull\n    static MarkwonVisitorFactory create(\n            @NonNull final MarkwonVisitorImpl.Builder builder,\n            @NonNull final MarkwonConfiguration configuration) {\n        return new MarkwonVisitorFactory() {\n            @NonNull\n            @Override\n            MarkwonVisitor create() {\n                return builder.build(configuration, new RenderPropsImpl());\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/MarkwonVisitorImpl.java",
    "content": "package io.noties.markwon;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport org.commonmark.node.BlockQuote;\nimport org.commonmark.node.BulletList;\nimport org.commonmark.node.Code;\nimport org.commonmark.node.CustomBlock;\nimport org.commonmark.node.CustomNode;\nimport org.commonmark.node.Document;\nimport org.commonmark.node.Emphasis;\nimport org.commonmark.node.FencedCodeBlock;\nimport org.commonmark.node.HardLineBreak;\nimport org.commonmark.node.Heading;\nimport org.commonmark.node.HtmlBlock;\nimport org.commonmark.node.HtmlInline;\nimport org.commonmark.node.Image;\nimport org.commonmark.node.IndentedCodeBlock;\nimport org.commonmark.node.Link;\nimport org.commonmark.node.LinkReferenceDefinition;\nimport org.commonmark.node.ListItem;\nimport org.commonmark.node.Node;\nimport org.commonmark.node.OrderedList;\nimport org.commonmark.node.Paragraph;\nimport org.commonmark.node.SoftLineBreak;\nimport org.commonmark.node.StrongEmphasis;\nimport org.commonmark.node.Text;\nimport org.commonmark.node.ThematicBreak;\n\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * @since 3.0.0\n */\nclass MarkwonVisitorImpl implements MarkwonVisitor {\n\n    private final MarkwonConfiguration configuration;\n\n    private final RenderProps renderProps;\n\n    private final SpannableBuilder builder;\n\n    private final Map<Class<? extends Node>, NodeVisitor<? extends Node>> nodes;\n\n    // @since 4.3.0\n    private final BlockHandler blockHandler;\n\n    MarkwonVisitorImpl(\n            @NonNull MarkwonConfiguration configuration,\n            @NonNull RenderProps renderProps,\n            @NonNull SpannableBuilder builder,\n            @NonNull Map<Class<? extends Node>, NodeVisitor<? extends Node>> nodes,\n            @NonNull BlockHandler blockHandler) {\n        this.configuration = configuration;\n        this.renderProps = renderProps;\n        this.builder = builder;\n        this.nodes = nodes;\n        this.blockHandler = blockHandler;\n    }\n\n    @Override\n    public void visit(BlockQuote blockQuote) {\n        visit((Node) blockQuote);\n    }\n\n    @Override\n    public void visit(BulletList bulletList) {\n        visit((Node) bulletList);\n    }\n\n    @Override\n    public void visit(Code code) {\n        visit((Node) code);\n    }\n\n    @Override\n    public void visit(Document document) {\n        visit((Node) document);\n    }\n\n    @Override\n    public void visit(Emphasis emphasis) {\n        visit((Node) emphasis);\n    }\n\n    @Override\n    public void visit(FencedCodeBlock fencedCodeBlock) {\n        visit((Node) fencedCodeBlock);\n    }\n\n    @Override\n    public void visit(HardLineBreak hardLineBreak) {\n        visit((Node) hardLineBreak);\n    }\n\n    @Override\n    public void visit(Heading heading) {\n        visit((Node) heading);\n    }\n\n    @Override\n    public void visit(ThematicBreak thematicBreak) {\n        visit((Node) thematicBreak);\n    }\n\n    @Override\n    public void visit(HtmlInline htmlInline) {\n        visit((Node) htmlInline);\n    }\n\n    @Override\n    public void visit(HtmlBlock htmlBlock) {\n        visit((Node) htmlBlock);\n    }\n\n    @Override\n    public void visit(Image image) {\n        visit((Node) image);\n    }\n\n    @Override\n    public void visit(IndentedCodeBlock indentedCodeBlock) {\n        visit((Node) indentedCodeBlock);\n    }\n\n    @Override\n    public void visit(Link link) {\n        visit((Node) link);\n    }\n\n    @Override\n    public void visit(ListItem listItem) {\n        visit((Node) listItem);\n    }\n\n    @Override\n    public void visit(OrderedList orderedList) {\n        visit((Node) orderedList);\n    }\n\n    @Override\n    public void visit(Paragraph paragraph) {\n        visit((Node) paragraph);\n    }\n\n    @Override\n    public void visit(SoftLineBreak softLineBreak) {\n        visit((Node) softLineBreak);\n    }\n\n    @Override\n    public void visit(StrongEmphasis strongEmphasis) {\n        visit((Node) strongEmphasis);\n    }\n\n    @Override\n    public void visit(Text text) {\n        visit((Node) text);\n    }\n\n    @Override\n    public void visit(LinkReferenceDefinition linkReferenceDefinition) {\n        visit((Node) linkReferenceDefinition);\n    }\n\n    @Override\n    public void visit(CustomBlock customBlock) {\n        visit((Node) customBlock);\n    }\n\n    @Override\n    public void visit(CustomNode customNode) {\n        visit((Node) customNode);\n    }\n\n    private void visit(@NonNull Node node) {\n        //noinspection unchecked\n        final NodeVisitor<Node> nodeVisitor = (NodeVisitor<Node>) nodes.get(node.getClass());\n        if (nodeVisitor != null) {\n            nodeVisitor.visit(this, node);\n        } else {\n            visitChildren(node);\n        }\n    }\n\n    @NonNull\n    @Override\n    public MarkwonConfiguration configuration() {\n        return configuration;\n    }\n\n    @NonNull\n    @Override\n    public RenderProps renderProps() {\n        return renderProps;\n    }\n\n    @NonNull\n    @Override\n    public SpannableBuilder builder() {\n        return builder;\n    }\n\n    @Override\n    public void visitChildren(@NonNull Node parent) {\n        Node node = parent.getFirstChild();\n        while (node != null) {\n            // A subclass of this visitor might modify the node, resulting in getNext returning a different node or no\n            // node after visiting it. So get the next node before visiting.\n            Node next = node.getNext();\n            node.accept(this);\n            node = next;\n        }\n    }\n\n    @Override\n    public boolean hasNext(@NonNull Node node) {\n        return node.getNext() != null;\n    }\n\n    @Override\n    public void ensureNewLine() {\n        if (builder.length() > 0\n                && '\\n' != builder.lastChar()) {\n            builder.append('\\n');\n        }\n    }\n\n    @Override\n    public void forceNewLine() {\n        builder.append('\\n');\n    }\n\n    @Override\n    public int length() {\n        return builder.length();\n    }\n\n    @Override\n    public void setSpans(int start, @Nullable Object spans) {\n        SpannableBuilder.setSpans(builder, spans, start, builder.length());\n    }\n\n    @Override\n    public void clear() {\n        renderProps.clearAll();\n        builder.clear();\n    }\n\n    @Override\n    public <N extends Node> void setSpansForNode(@NonNull N node, int start) {\n        setSpansForNode(node.getClass(), start);\n    }\n\n    @Override\n    public <N extends Node> void setSpansForNode(@NonNull Class<N> node, int start) {\n        setSpans(start, configuration.spansFactory().require(node).getSpans(configuration, renderProps));\n    }\n\n    @Override\n    public <N extends Node> void setSpansForNodeOptional(@NonNull N node, int start) {\n        setSpansForNodeOptional(node.getClass(), start);\n    }\n\n    @Override\n    public <N extends Node> void setSpansForNodeOptional(@NonNull Class<N> node, int start) {\n        final SpanFactory factory = configuration.spansFactory().get(node);\n        if (factory != null) {\n            setSpans(start, factory.getSpans(configuration, renderProps));\n        }\n    }\n\n    @Override\n    public void blockStart(@NonNull Node node) {\n        blockHandler.blockStart(this, node);\n    }\n\n    @Override\n    public void blockEnd(@NonNull Node node) {\n        blockHandler.blockEnd(this, node);\n    }\n\n    static class BuilderImpl implements Builder {\n\n        private final Map<Class<? extends Node>, NodeVisitor<? extends Node>> nodes = new HashMap<>();\n        private BlockHandler blockHandler;\n\n        @NonNull\n        @Override\n        public <N extends Node> Builder on(@NonNull Class<N> node, @Nullable NodeVisitor<? super N> nodeVisitor) {\n\n            // @since 4.1.1 we might actually introduce a local flag to check if it's been built\n            //  and throw an exception here if some modification is requested\n            //  NB, as we might be built from different threads this flag must be synchronized\n\n            // we should allow `null` to exclude node from being visited (for example to disable\n            // some functionality)\n            if (nodeVisitor == null) {\n                nodes.remove(node);\n            } else {\n                nodes.put(node, nodeVisitor);\n            }\n            return this;\n        }\n\n        @NonNull\n        @Override\n        public Builder blockHandler(@NonNull BlockHandler blockHandler) {\n            this.blockHandler = blockHandler;\n            return this;\n        }\n\n        @NonNull\n        @Override\n        public MarkwonVisitor build(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps renderProps) {\n            // @since 4.3.0\n            BlockHandler blockHandler = this.blockHandler;\n            if (blockHandler == null) {\n                blockHandler = new BlockHandlerDef();\n            }\n\n            return new MarkwonVisitorImpl(\n                    configuration,\n                    renderProps,\n                    new SpannableBuilder(),\n                    Collections.unmodifiableMap(nodes),\n                    blockHandler);\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/PrecomputedFutureTextSetterCompat.java",
    "content": "package io.noties.markwon;\n\nimport android.text.Spanned;\nimport android.widget.TextView;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.appcompat.widget.AppCompatTextView;\nimport androidx.core.text.PrecomputedTextCompat;\n\nimport java.util.concurrent.Executor;\nimport java.util.concurrent.Future;\n\n/**\n * Please note this class requires `androidx.core:core` artifact being explicitly added to your dependencies.\n * This is intended to be used in a RecyclerView.\n *\n * @see Markwon.TextSetter\n * @since 4.3.1\n */\npublic class PrecomputedFutureTextSetterCompat implements Markwon.TextSetter {\n\n    /**\n     * @param executor for background execution of text pre-computation,\n     *                 if not provided the standard, single threaded one will be used.\n     */\n    @NonNull\n    public static PrecomputedFutureTextSetterCompat create(@Nullable Executor executor) {\n        return new PrecomputedFutureTextSetterCompat(executor);\n    }\n\n    @NonNull\n    public static PrecomputedFutureTextSetterCompat create() {\n        return new PrecomputedFutureTextSetterCompat(null);\n    }\n\n    @Nullable\n    private final Executor executor;\n\n    @SuppressWarnings(\"WeakerAccess\")\n    PrecomputedFutureTextSetterCompat(@Nullable Executor executor) {\n        this.executor = executor;\n    }\n\n    @Override\n    public void setText(\n            @NonNull TextView textView,\n            @NonNull Spanned markdown,\n            @NonNull TextView.BufferType bufferType,\n            @NonNull Runnable onComplete) {\n        if (textView instanceof AppCompatTextView) {\n            final AppCompatTextView appCompatTextView = (AppCompatTextView) textView;\n            final Future<PrecomputedTextCompat> future = PrecomputedTextCompat.getTextFuture(\n                    markdown,\n                    appCompatTextView.getTextMetricsParamsCompat(),\n                    executor);\n            appCompatTextView.setTextFuture(future);\n            // `setTextFuture` is actually a synchronous call, so we should call onComplete now\n            onComplete.run();\n        } else {\n            throw new IllegalStateException(\"TextView provided is not an instance of AppCompatTextView, \" +\n                    \"cannot call setTextFuture(), textView: \" + textView);\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/PrecomputedTextSetterCompat.java",
    "content": "package io.noties.markwon;\n\nimport android.os.Build;\nimport android.text.Spanned;\nimport android.util.Log;\nimport android.widget.TextView;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.core.text.PrecomputedTextCompat;\n\nimport java.lang.ref.WeakReference;\nimport java.util.concurrent.Executor;\n\n/**\n * Please note this class requires `androidx.core:core` artifact being explicitly added to your dependencies.\n * Please do not use with `markwon-recycler` as it will lead to bad item rendering (due to async nature)\n *\n * @see io.noties.markwon.Markwon.TextSetter\n * @since 4.1.0\n */\npublic class PrecomputedTextSetterCompat implements Markwon.TextSetter {\n\n    /**\n     * @param executor for background execution of text pre-computation\n     */\n    @NonNull\n    public static PrecomputedTextSetterCompat create(@NonNull Executor executor) {\n        return new PrecomputedTextSetterCompat(executor);\n    }\n\n    private final Executor executor;\n\n    @SuppressWarnings(\"WeakerAccess\")\n    PrecomputedTextSetterCompat(@NonNull Executor executor) {\n        this.executor = executor;\n    }\n\n    @Override\n    public void setText(\n            @NonNull TextView textView,\n            @NonNull final Spanned markdown,\n            @NonNull final TextView.BufferType bufferType,\n            @NonNull final Runnable onComplete) {\n\n        // insert version check and do not execute on a device < 21\n        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {\n            // it's still no-op, so there is no need to start background execution\n            applyText(textView, markdown, bufferType, onComplete);\n            return;\n        }\n\n        final WeakReference<TextView> reference = new WeakReference<>(textView);\n        executor.execute(new Runnable() {\n            @Override\n            public void run() {\n                try {\n                    final PrecomputedTextCompat precomputedTextCompat = precomputedText(reference.get(), markdown);\n                    if (precomputedTextCompat != null) {\n                        applyText(reference.get(), precomputedTextCompat, bufferType, onComplete);\n                    }\n                } catch (Throwable t) {\n                    Log.e(\"PrecomputdTxtSetterCmpt\", \"Exception during pre-computing text\", t);\n                    // apply initial markdown\n                    applyText(reference.get(), markdown, bufferType, onComplete);\n                }\n            }\n        });\n    }\n\n    @Nullable\n    private static PrecomputedTextCompat precomputedText(@Nullable TextView textView, @NonNull Spanned spanned) {\n\n        if (textView == null) {\n            return null;\n        }\n\n        final PrecomputedTextCompat.Params params;\n\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {\n            // use native parameters on P\n            params = new PrecomputedTextCompat.Params(textView.getTextMetricsParams());\n        } else {\n\n            final PrecomputedTextCompat.Params.Builder builder =\n                    new PrecomputedTextCompat.Params.Builder(textView.getPaint());\n\n            // please note that text-direction initialization is omitted\n            // by default it will be determined by the first locale-specific character\n\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {\n                // another miss on API surface, this can easily be done by the compat class itself\n                builder\n                        .setBreakStrategy(textView.getBreakStrategy())\n                        .setHyphenationFrequency(textView.getHyphenationFrequency());\n            }\n\n            params = builder.build();\n        }\n\n        return PrecomputedTextCompat.create(spanned, params);\n    }\n\n    private static void applyText(\n            @Nullable final TextView textView,\n            @NonNull final Spanned text,\n            @NonNull final TextView.BufferType bufferType,\n            @NonNull final Runnable onComplete) {\n        if (textView != null) {\n            textView.post(new Runnable() {\n                @Override\n                public void run() {\n                    textView.setText(text, bufferType);\n                    onComplete.run();\n                }\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/Prop.java",
    "content": "package io.noties.markwon;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\n/**\n * Class to hold data in {@link RenderProps}. Represents a certain <em>property</em>.\n *\n * @param <T> represents the type that this instance holds\n * @see #of(String)\n * @see #of(Class, String)\n * @since 3.0.0\n */\npublic class Prop<T> {\n\n    @SuppressWarnings(\"unused\")\n    @NonNull\n    public static <T> Prop<T> of(@NonNull Class<T> type, @NonNull String name) {\n        return new Prop<>(name);\n    }\n\n    @NonNull\n    public static <T> Prop<T> of(@NonNull String name) {\n        return new Prop<>(name);\n    }\n\n    private final String name;\n\n    Prop(@NonNull String name) {\n        this.name = name;\n    }\n\n    @NonNull\n    public String name() {\n        return name;\n    }\n\n    @Nullable\n    public T get(@NonNull RenderProps props) {\n        return props.get(this);\n    }\n\n    @NonNull\n    public T get(@NonNull RenderProps props, @NonNull T defValue) {\n        return props.get(this, defValue);\n    }\n\n    @NonNull\n    public T require(@NonNull RenderProps props) {\n        final T t = get(props);\n        if (t == null) {\n            throw new NullPointerException(name);\n        }\n        return t;\n    }\n\n    public void set(@NonNull RenderProps props, @Nullable T value) {\n        props.set(this, value);\n    }\n\n    public void clear(@NonNull RenderProps props) {\n        props.clear(this);\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        Prop<?> prop = (Prop<?>) o;\n\n        return name.equals(prop.name);\n    }\n\n    @Override\n    public int hashCode() {\n        return name.hashCode();\n    }\n\n    @Override\n    public String toString() {\n        return \"Prop{\" +\n                \"name='\" + name + '\\'' +\n                '}';\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/RegistryImpl.java",
    "content": "package io.noties.markwon;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\nimport io.noties.markwon.core.CorePlugin;\n\n// @since 4.0.0\nclass RegistryImpl implements MarkwonPlugin.Registry {\n\n    private final List<MarkwonPlugin> origin;\n    private final List<MarkwonPlugin> plugins;\n    private final Set<MarkwonPlugin> pending;\n\n    RegistryImpl(@NonNull List<MarkwonPlugin> origin) {\n        this.origin = origin;\n        this.plugins = new ArrayList<>(origin.size());\n        this.pending = new HashSet<>(3);\n    }\n\n    @NonNull\n    @Override\n    public <P extends MarkwonPlugin> P require(@NonNull Class<P> plugin) {\n        return get(plugin);\n    }\n\n    @Override\n    public <P extends MarkwonPlugin> void require(\n            @NonNull Class<P> plugin,\n            @NonNull MarkwonPlugin.Action<? super P> action) {\n        action.apply(get(plugin));\n    }\n\n    @NonNull\n    List<MarkwonPlugin> process() {\n        for (MarkwonPlugin plugin : origin) {\n            configure(plugin);\n        }\n        return plugins;\n    }\n\n    private void configure(@NonNull MarkwonPlugin plugin) {\n\n        // important -> check if it's in plugins\n        //  if it is -> no need to configure (already configured)\n\n        if (!plugins.contains(plugin)) {\n\n            if (pending.contains(plugin)) {\n                throw new IllegalStateException(\"Cyclic dependency chain found: \" + pending);\n            }\n\n            // start tracking plugins that are pending for configuration\n            pending.add(plugin);\n\n            plugin.configure(this);\n\n            // stop pending tracking\n            pending.remove(plugin);\n\n            // check again if it's included (a child might've configured it already)\n            // add to out-collection if not already present\n            // this is a bit different from `find` method as it does check for exact instance\n            // and not a sub-type\n            if (!plugins.contains(plugin)) {\n                // core-plugin must always be the first one (if it's present)\n                if (CorePlugin.class.isAssignableFrom(plugin.getClass())) {\n                    plugins.add(0, plugin);\n                } else {\n                    plugins.add(plugin);\n                }\n            }\n        }\n    }\n\n    @NonNull\n    private <P extends MarkwonPlugin> P get(@NonNull Class<P> type) {\n\n        // check if present already in plugins\n        // find in origin, if not found -> throw, else add to out-plugins\n\n        P plugin = find(plugins, type);\n\n        if (plugin == null) {\n\n            plugin = find(origin, type);\n\n            if (plugin == null) {\n                throw new IllegalStateException(\"Requested plugin is not added: \" +\n                        \"\" + type.getName() + \", plugins: \" + origin);\n            }\n\n            configure(plugin);\n        }\n\n        return plugin;\n    }\n\n    @Nullable\n    private static <P extends MarkwonPlugin> P find(\n            @NonNull List<MarkwonPlugin> plugins,\n            @NonNull Class<P> type) {\n        for (MarkwonPlugin plugin : plugins) {\n            if (type.isAssignableFrom(plugin.getClass())) {\n                //noinspection unchecked\n                return (P) plugin;\n            }\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/RenderProps.java",
    "content": "package io.noties.markwon;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\n/**\n * @since 3.0.0\n */\npublic interface RenderProps {\n\n    @Nullable\n    <T> T get(@NonNull Prop<T> prop);\n\n    @NonNull\n    <T> T get(@NonNull Prop<T> prop, @NonNull T defValue);\n\n    <T> void set(@NonNull Prop<T> prop, @Nullable T value);\n\n    <T> void clear(@NonNull Prop<T> prop);\n\n    void clearAll();\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/RenderPropsImpl.java",
    "content": "package io.noties.markwon;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * @since 3.0.0\n */\nclass RenderPropsImpl implements RenderProps {\n\n    private final Map<Prop, Object> values = new HashMap<>(3);\n\n    @Nullable\n    @Override\n    public <T> T get(@NonNull Prop<T> prop) {\n        //noinspection unchecked\n        return (T) values.get(prop);\n    }\n\n    @NonNull\n    @Override\n    public <T> T get(@NonNull Prop<T> prop, @NonNull T defValue) {\n        Object value = values.get(prop);\n        if (value != null) {\n            //noinspection unchecked\n            return (T) value;\n        }\n        return defValue;\n    }\n\n    @Override\n    public <T> void set(@NonNull Prop<T> prop, @Nullable T value) {\n        if (value == null) {\n            values.remove(prop);\n        } else {\n            values.put(prop, value);\n        }\n    }\n\n    @Override\n    public <T> void clear(@NonNull Prop<T> prop) {\n        values.remove(prop);\n    }\n\n    @Override\n    public void clearAll() {\n        values.clear();\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/SoftBreakAddsNewLinePlugin.java",
    "content": "package io.noties.markwon;\n\nimport androidx.annotation.NonNull;\n\nimport org.commonmark.node.SoftLineBreak;\n\n/**\n * @since 4.3.0\n */\npublic class SoftBreakAddsNewLinePlugin extends AbstractMarkwonPlugin {\n\n    @NonNull\n    public static SoftBreakAddsNewLinePlugin create() {\n        return new SoftBreakAddsNewLinePlugin();\n    }\n\n    @Override\n    public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) {\n        builder.on(SoftLineBreak.class, new MarkwonVisitor.NodeVisitor<SoftLineBreak>() {\n            @Override\n            public void visit(@NonNull MarkwonVisitor visitor, @NonNull SoftLineBreak softLineBreak) {\n                visitor.ensureNewLine();\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/SpanFactory.java",
    "content": "package io.noties.markwon;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\n/**\n * @since 3.0.0\n */\npublic interface SpanFactory {\n\n    @Nullable\n    Object getSpans(\n            @NonNull MarkwonConfiguration configuration,\n            @NonNull RenderProps props);\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/SpannableBuilder.java",
    "content": "package io.noties.markwon;\n\nimport android.text.SpannableStringBuilder;\nimport android.text.Spanned;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.VisibleForTesting;\n\nimport com.fluid.afm.utils.MDLogger;\n\nimport java.util.ArrayDeque;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Deque;\nimport java.util.Iterator;\nimport java.util.List;\n\nimport com.fluid.afm.span.AntUnderlineSupportMulLinesSpan;\n\n/**\n * This class is used to _revert_ order of applied spans. Original SpannableStringBuilder\n * is using an array to store all the information about spans. So, a span that is added first\n * will be drawn first, which leads to subtle bugs (spans receive wrong `x` values when\n * requested to draw itself)\n * <p>\n * since 2.0.0 implements Appendable and CharSequence\n *\n * @since 1.0.1\n */\n@SuppressWarnings({\"WeakerAccess\", \"unused\"})\npublic class SpannableBuilder implements Appendable, CharSequence {\n\n    /**\n     * @since 2.0.0\n     */\n    public static void setSpans(@NonNull SpannableBuilder builder, @Nullable Object spans, int start, int end) {\n        if (spans != null) {\n\n            // setting a span for an invalid position can lead to silent fail (no exception,\n            // but execution is stopped)\n            if (!isPositionValid(builder.length(), start, end)) {\n                return;\n            }\n\n            // @since 3.0.1 we introduce another method that recursively applies spans\n            // allowing array of arrays (and more)\n            setSpansInternal(builder, spans, start, end);\n        }\n    }\n\n    // @since 2.0.1 package-private visibility for testing\n    @VisibleForTesting\n    static boolean isPositionValid(int length, int start, int end) {\n        return end > start\n                && start >= 0\n                && end <= length;\n    }\n\n\n    private final StringBuilder builder;\n\n    // actually we might be just using ArrayList\n    private final Deque<Span> spans = new ArrayDeque<>(8);\n\n    public SpannableBuilder() {\n        this(\"\");\n    }\n\n    public SpannableBuilder(@NonNull CharSequence cs) {\n        this.builder = new StringBuilder(cs);\n        copySpans(0, cs);\n    }\n\n    /**\n     * Additional method that takes a String, which is proven to NOT contain any spans\n     *\n     * @param text String to append\n     * @return this instance\n     */\n    @NonNull\n    public SpannableBuilder append(@NonNull String text) {\n        builder.append(text);\n        return this;\n    }\n\n    @NonNull\n    @Override\n    public SpannableBuilder append(char c) {\n        builder.append(c);\n        return this;\n    }\n\n    @NonNull\n    @Override\n    public SpannableBuilder append(@NonNull CharSequence cs) {\n\n        copySpans(length(), cs);\n\n        builder.append(cs);\n\n        return this;\n    }\n\n    /**\n     * @since 2.0.0 to follow Appendable interface\n     */\n    @NonNull\n    @Override\n    public SpannableBuilder append(CharSequence csq, int start, int end) {\n\n        final CharSequence cs = csq.subSequence(start, end);\n        copySpans(length(), cs);\n\n        builder.append(cs);\n\n        return this;\n    }\n\n    @NonNull\n    public SpannableBuilder append(@NonNull CharSequence cs, @NonNull Object span) {\n        final int length = length();\n        append(cs);\n        setSpan(span, length);\n        return this;\n    }\n\n    @NonNull\n    public SpannableBuilder append(@NonNull CharSequence cs, @NonNull Object span, int flags) {\n        final int length = length();\n        append(cs);\n        setSpan(span, length, length(), flags);\n        return this;\n    }\n\n    @NonNull\n    public SpannableBuilder setSpan(@NonNull Object span, int start) {\n        return setSpan(span, start, length());\n    }\n\n    @NonNull\n    public SpannableBuilder setSpan(@NonNull Object span, int start, int end) {\n        return setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);\n    }\n\n    @NonNull\n    public SpannableBuilder setSpan(@NonNull Object span, int start, int end, int flags) {\n        spans.push(new Span(span, start, end, flags));\n        return this;\n    }\n\n    @Override\n    public int length() {\n        return builder.length();\n    }\n\n    @Override\n    public char charAt(int index) {\n        return builder.charAt(index);\n    }\n\n    /**\n     * @since 2.0.0 to follow CharSequence interface\n     */\n    @Override\n    public CharSequence subSequence(int start, int end) {\n\n        final CharSequence out;\n\n        // @since 2.0.1 we copy spans to resulting subSequence\n        final List<Span> spans = getSpans(start, end);\n        if (spans.isEmpty()) {\n            out = builder.subSequence(start, end);\n        } else {\n\n            // we should not be SpannableStringBuilderReversed here\n            final SpannableStringBuilder builder = new SpannableStringBuilder(this.builder.subSequence(start, end));\n\n            final int length = builder.length();\n\n            int s;\n            int e;\n\n            for (Span span : spans) {\n\n                // we should limit start/end to resulting subSequence length\n                //\n                // for example, originally it was 5-7 and range 5-7 requested\n                // span should have 0-2\n                //\n                // if a span was fully including resulting subSequence it's start and\n                // end must be within 0..length bounds\n                s = Math.max(0, span.start - start);\n                e = Math.min(length, s + (span.end - span.start));\n\n                builder.setSpan(\n                        span.what,\n                        s,\n                        e,\n                        span.flags\n                );\n            }\n            out = builder;\n        }\n\n        return out;\n    }\n\n    /**\n     * This method will return all {@link Span} spans that <em>overlap</em> specified range,\n     * so if for example a 1..9 range is specified some spans might have 0..6 or 0..10 start/end ranges.\n     * <<<<<<< HEAD:markwon-core/src/main/java/ru/noties/markwon/SpannableBuilder.java\n     * NB spans are returned in reversed order (not in order that we store them internally)\n     * =======\n     * NB spans are returned in reversed order (no in order that we store them internally)\n     * >>>>>>> master:markwon/src/main/java/ru/noties/markwon/SpannableBuilder.java\n     *\n     * @since 2.0.1\n     */\n    @NonNull\n    public List<Span> getSpans(int start, int end) {\n\n        final int length = length();\n\n        if (!isPositionValid(length, start, end)) {\n            // we might as well throw here\n            return Collections.emptyList();\n        }\n\n        // all requested\n        if (start == 0\n                && length == end) {\n            // but also copy (do not allow external modification)\n            final List<Span> list = new ArrayList<>(spans);\n            Collections.reverse(list);\n            return Collections.unmodifiableList(list);\n        }\n\n        final List<Span> list = new ArrayList<>(0);\n\n        final Iterator<Span> iterator = spans.descendingIterator();\n        Span span;\n\n        while (iterator.hasNext()) {\n            span = iterator.next();\n            // we must execute 2 checks: if overlap with specified range or fully include it\n            // if span.start is >= range.start -> check if it's before range.end\n            // if span.end is <= end -> check if it's after range.start\n            if (\n                    (span.start >= start && span.start < end)\n                            || (span.end <= end && span.end > start)\n                            || (span.start < start && span.end > end)) {\n                list.add(span);\n            }\n        }\n\n        return Collections.unmodifiableList(list);\n    }\n\n    public char lastChar() {\n        return builder.charAt(length() - 1);\n    }\n\n    @NonNull\n    public CharSequence removeFromEnd(int start) {\n\n        // this method is not intended to be used by clients\n        // it's a workaround to support tables\n\n        final int end = length();\n\n        // as we do not expose builder and do no apply spans to it, we are safe to NOT to convert to String\n        final SpannableStringBuilderReversed impl = new SpannableStringBuilderReversed(builder.subSequence(start, end));\n\n        final Iterator<Span> iterator = spans.iterator();\n\n        Span span;\n\n        while (iterator.hasNext() && ((span = iterator.next())) != null) {\n            if (span.start >= start && span.end <= end) {\n                impl.setSpan(span.what, span.start - start, span.end - start, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);\n                iterator.remove();\n            }\n        }\n\n        builder.replace(start, end, \"\");\n\n        return impl;\n    }\n\n    @Override\n    @NonNull\n    public String toString() {\n        return builder.toString();\n    }\n\n    @NonNull\n    public CharSequence text() {\n        // @since 2.0.0 redirects this call to `#spannableStringBuilder()`\n        return spannableStringBuilder();\n    }\n\n    /**\n     * Simple method to create a SpannableStringBuilder, which is created anyway. Unlike {@link #text()}\n     * method which returns the same SpannableStringBuilder there is no need to cast the resulting\n     * CharSequence and makes the thing more explicit\n     *\n     * @since 2.0.0\n     */\n    @NonNull\n    public SpannableStringBuilder spannableStringBuilder() {\n\n        // okay, in order to not allow external modification and keep our spans order\n        // we should not return our builder\n        //\n        // plus, if this method was called -> all spans would be applied, which potentially\n        // breaks the order that we intend to use\n        // so, we will defensively copy builder\n\n        // as we do not expose builder and do no apply spans to it, we are safe to NOT to convert to String\n\n        final SpannableStringBuilderReversed reversed = new SpannableStringBuilderReversed(builder);\n\n        // NB, as e are using Deque -> iteration will be started with last element\n        // so, spans will be appearing in the for loop in reverse order\n\n        for (Span span : spans) {\n            // 每个字设置span 为了增加span的换行能力\n            if (span.what instanceof AntUnderlineSupportMulLinesSpan) {\n                for (int i = span.start; i < span.end; i++) {\n                    try {\n                        if (reversed.charAt(i) == '[' && reversed.charAt(i + 1) == '^') {\n                            reversed.setSpan(span.what, i, i+4, span.flags);\n                            i = i + 3;\n                        } else {\n                            AntUnderlineSupportMulLinesSpan antUnderlineSupportMulLinesSpan = (AntUnderlineSupportMulLinesSpan) span.what;\n                            reversed.setSpan(new AntUnderlineSupportMulLinesSpan(antUnderlineSupportMulLinesSpan.getColor(),\n                                            antUnderlineSupportMulLinesSpan.getThickness()),\n                                    i, i + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);\n                        }\n                    } catch (Exception e) {\n                        MDLogger.e(\"SpannableBuilder\", \"setSpan error\", e);\n                    }\n                }\n            } else {\n                reversed.setSpan(span.what, span.start, span.end, span.flags);\n            }\n        }\n\n        return reversed;\n    }\n\n    /**\n     * @since 3.0.0\n     */\n    public void clear() {\n        builder.setLength(0);\n        spans.clear();\n    }\n\n    private void copySpans(final int index, @Nullable CharSequence cs) {\n\n        // we must identify already reversed Spanned...\n        // and (!) iterate backwards when adding (to preserve order)\n\n        if (cs instanceof Spanned) {\n\n            final Spanned spanned = (Spanned) cs;\n            final boolean reversed = spanned instanceof SpannableStringBuilderReversed;\n\n            final Object[] spans = spanned.getSpans(0, spanned.length(), Object.class);\n            final int length = spans != null\n                    ? spans.length\n                    : 0;\n\n            if (length > 0) {\n                if (reversed) {\n                    Object o;\n                    for (int i = length - 1; i >= 0; i--) {\n                        o = spans[i];\n                        setSpan(\n                                o,\n                                index + spanned.getSpanStart(o),\n                                index + spanned.getSpanEnd(o),\n                                spanned.getSpanFlags(o)\n                        );\n                    }\n                } else {\n                    Object o;\n                    for (int i = 0; i < length; i++) {\n                        o = spans[i];\n                        setSpan(\n                                o,\n                                index + spanned.getSpanStart(o),\n                                index + spanned.getSpanEnd(o),\n                                spanned.getSpanFlags(o)\n                        );\n                    }\n                }\n            }\n        }\n    }\n\n    /**\n     * @since 2.0.1 made public in order to be returned from `getSpans` method, initially added in 1.0.1\n     */\n    public static class Span {\n\n        public final Object what;\n        public int start;\n        public int end;\n        public final int flags;\n\n        Span(@NonNull Object what, int start, int end, int flags) {\n            this.what = what;\n            this.start = start;\n            this.end = end;\n            this.flags = flags;\n        }\n    }\n\n    /**\n     * @since 2.0.1 made inner class of {@link SpannableBuilder}, initially added in 1.0.1\n     */\n    static class SpannableStringBuilderReversed extends SpannableStringBuilder {\n        SpannableStringBuilderReversed(CharSequence text) {\n            super(text);\n        }\n    }\n\n    /**\n     * @since 3.0.1\n     */\n    private static void setSpansInternal(\n            @NonNull SpannableBuilder builder,\n            @Nullable Object spans,\n            int start,\n            int end) {\n        if (spans != null) {\n            if (spans.getClass().isArray()) {\n                for (Object o : ((Object[]) spans)) {\n                    // @since 3.0.1 recursively apply spans (allow array of arrays)\n                    setSpansInternal(builder, o, start, end);\n                }\n            } else {\n                builder.setSpan(spans, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/CorePlugin.java",
    "content": "package io.noties.markwon.core;\n\nimport android.content.Context;\nimport android.text.Spannable;\nimport android.text.Spanned;\nimport android.text.TextUtils;\nimport android.text.method.LinkMovementMethod;\nimport android.text.style.ForegroundColorSpan;\nimport android.widget.TextView;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.VisibleForTesting;\n\nimport com.fluid.afm.styles.TitleStyle;\nimport com.fluid.afm.utils.MDLogger;\n\nimport org.commonmark.node.Block;\nimport org.commonmark.node.BlockQuote;\nimport org.commonmark.node.BulletList;\nimport org.commonmark.node.Code;\nimport org.commonmark.node.Emphasis;\nimport org.commonmark.node.FencedCodeBlock;\nimport org.commonmark.node.HardLineBreak;\nimport org.commonmark.node.Heading;\nimport org.commonmark.node.HtmlBlock;\nimport org.commonmark.node.HtmlInline;\nimport org.commonmark.node.Image;\nimport org.commonmark.node.IndentedCodeBlock;\nimport org.commonmark.node.Link;\nimport org.commonmark.node.ListBlock;\nimport org.commonmark.node.ListItem;\nimport org.commonmark.node.Node;\nimport org.commonmark.node.OrderedList;\nimport org.commonmark.node.Paragraph;\nimport org.commonmark.node.SoftLineBreak;\nimport org.commonmark.node.StrongEmphasis;\nimport org.commonmark.node.Text;\nimport org.commonmark.node.ThematicBreak;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\nimport io.noties.markwon.AbstractMarkwonPlugin;\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.MarkwonSpansFactory;\nimport io.noties.markwon.MarkwonVisitor;\nimport io.noties.markwon.RenderProps;\nimport io.noties.markwon.SpanFactory;\nimport io.noties.markwon.SpannableBuilder;\nimport io.noties.markwon.core.factory.BlockQuoteSpanFactory;\nimport io.noties.markwon.core.factory.CodeBlockSpanFactory;\nimport io.noties.markwon.core.factory.CodeSpanFactory;\nimport io.noties.markwon.core.factory.EmphasisSpanFactory;\nimport io.noties.markwon.core.factory.HeadingSpanFactory;\nimport io.noties.markwon.core.factory.LinkSpanFactory;\nimport io.noties.markwon.core.factory.ListItemSpanFactory;\nimport io.noties.markwon.core.factory.StrongEmphasisSpanFactory;\nimport io.noties.markwon.core.factory.ThematicBreakSpanFactory;\nimport io.noties.markwon.core.spans.BulletListItemSpan;\nimport io.noties.markwon.core.spans.CodeBlockSpan;\nimport com.fluid.afm.span.CodeLanguageSpan;\nimport com.fluid.afm.span.HeadingTopOrBottomSpacingSpan;\nimport com.fluid.afm.span.LinkWithIconSpan;\nimport io.noties.markwon.core.spans.OrderedListItemSpan;\nimport com.fluid.afm.span.ParagraphSpacingSpan;\nimport io.noties.markwon.core.spans.TextViewSpan;\nimport io.noties.markwon.image.ImageProps;\nimport com.fluid.afm.utils.Utils;\n\n/**\n * @see CoreProps\n * @since 3.0.0\n */\npublic class CorePlugin extends AbstractMarkwonPlugin {\n\n    /**\n     * @see #addOnTextAddedListener(OnTextAddedListener)\n     * @since 4.0.0\n     */\n    public interface OnTextAddedListener {\n\n        /**\n         * Will be called when new text is added to resulting {@link SpannableBuilder}.\n         * Please note that only text represented by {@link Text} node will trigger this callback\n         * (text inside code and code-blocks won\\'t trigger it).\n         * <p>\n         * Please note that if you wish to add spans you must use {@code start} parameter\n         * in order to place spans correctly ({@code start} represents the index at which {@code text}\n         * was added). So, to set a span for the whole length of the text added one should use:\n         * <p>\n         * {@code\n         * visitor.builder().setSpan(new MySpan(), start, start + text.length(), 0);\n         * }\n         *\n         * @param visitor {@link MarkwonVisitor}\n         * @param text    literal that had been added\n         * @param start   index in {@code visitor} as which text had been added\n         * @see #addOnTextAddedListener(OnTextAddedListener)\n         */\n        void onTextAdded(@NonNull MarkwonVisitor visitor, @NonNull String text, int start);\n    }\n\n    @NonNull\n    public static CorePlugin create(Context context) {\n        return new CorePlugin(context);\n    }\n\n    /**\n     * @return a set with enabled by default block types\n     * @since 4.4.0\n     */\n    @NonNull\n    public static Set<Class<? extends Block>> enabledBlockTypes() {\n        return new HashSet<>(Arrays.asList(\n                BlockQuote.class,\n                Heading.class,\n                FencedCodeBlock.class,\n                HtmlBlock.class,\n                ThematicBreak.class,\n                ListBlock.class,\n                IndentedCodeBlock.class\n        ));\n    }\n\n    // @since 4.0.0\n    private final List<OnTextAddedListener> onTextAddedListeners = new ArrayList<>(0);\n\n    // @since 4.5.0\n    private boolean hasExplicitMovementMethod;\n    private final Context context;\n\n    protected CorePlugin(Context context) {\n        this.context = context;\n    }\n\n    /**\n     * @since 4.5.0\n     */\n    @SuppressWarnings(\"UnusedReturnValue\")\n    @NonNull\n    public CorePlugin hasExplicitMovementMethod(boolean hasExplicitMovementMethod) {\n        this.hasExplicitMovementMethod = hasExplicitMovementMethod;\n        return this;\n    }\n\n    /**\n     * Can be useful to post-process text added. For example for auto-linking capabilities.\n     *\n     * @see OnTextAddedListener\n     * @since 4.0.0\n     */\n    @SuppressWarnings(\"UnusedReturnValue\")\n    @NonNull\n    public CorePlugin addOnTextAddedListener(@NonNull OnTextAddedListener onTextAddedListener) {\n        onTextAddedListeners.add(onTextAddedListener);\n        return this;\n    }\n\n    @Override\n    public void configureTheme(@NonNull MarkwonTheme.Builder builder) {\n\n    }\n\n    @Override\n    public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) {\n        text(builder);\n        strongEmphasis(builder);\n        emphasis(builder);\n        blockQuote(builder);\n        code(builder);\n        fencedCodeBlock(builder);\n        indentedCodeBlock(builder);\n        image(builder);\n        bulletList(builder);\n        orderedList(builder);\n        listItem(builder);\n        thematicBreak(builder);\n        heading(builder);\n        softLineBreak(builder);\n        hardLineBreak(builder);\n        paragraph(context, builder);\n        link(builder);\n    }\n\n    @Override\n    public void configureSpansFactory(@NonNull MarkwonSpansFactory.Builder builder) {\n\n        // reuse this one for both code-blocks (indent & fenced)\n        final CodeBlockSpanFactory codeBlockSpanFactory = new CodeBlockSpanFactory();\n\n        builder\n                .setFactory(StrongEmphasis.class, new StrongEmphasisSpanFactory())\n                .setFactory(Emphasis.class, new EmphasisSpanFactory())\n                .setFactory(BlockQuote.class, new BlockQuoteSpanFactory())\n                .setFactory(Code.class, new CodeSpanFactory())\n                .setFactory(FencedCodeBlock.class, codeBlockSpanFactory)\n                .setFactory(IndentedCodeBlock.class, codeBlockSpanFactory)\n                .setFactory(ListItem.class, new ListItemSpanFactory())\n                .setFactory(Heading.class, new HeadingSpanFactory())\n                .setFactory(Link.class, new LinkSpanFactory())\n                .setFactory(ThematicBreak.class, new ThematicBreakSpanFactory());\n    }\n\n    @Override\n    public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) {\n        OrderedListItemSpan.measure(textView, markdown);\n\n        // @since 4.4.0\n        // we do not break API compatibility, instead we introduce the `instance of` check\n        if (markdown instanceof Spannable) {\n            final Spannable spannable = (Spannable) markdown;\n            TextViewSpan.applyTo(spannable, textView);\n        }\n    }\n\n    @Override\n    public void afterSetText(@NonNull TextView textView) {\n        // let's ensure that there is a movement method applied\n        // we do it `afterSetText` so any user-defined movement method won't be\n        // replaced (it should be done in `beforeSetText` or manually on a TextView)\n        // @since 4.5.0 we additionally check if we should apply _implicit_ movement method\n        if (!hasExplicitMovementMethod && textView.getMovementMethod() == null) {\n            textView.setMovementMethod(LinkMovementMethod.getInstance());\n        }\n    }\n\n    private void text(@NonNull MarkwonVisitor.Builder builder) {\n        builder.on(Text.class, new MarkwonVisitor.NodeVisitor<Text>() {\n            @Override\n            public void visit(@NonNull MarkwonVisitor visitor, @NonNull Text text) {\n\n                final String literal = text.getLiteral();\n\n                visitor.builder().append(literal);\n\n                // @since 4.0.0\n                if (!onTextAddedListeners.isEmpty()) {\n                    // calculate the start position\n                    final int length = visitor.length() - literal.length();\n                    for (OnTextAddedListener onTextAddedListener : onTextAddedListeners) {\n                        onTextAddedListener.onTextAdded(visitor, literal, length);\n                    }\n                }\n            }\n        });\n    }\n\n    private static void strongEmphasis(@NonNull MarkwonVisitor.Builder builder) {\n        builder.on(StrongEmphasis.class, new MarkwonVisitor.NodeVisitor<StrongEmphasis>() {\n            @Override\n            public void visit(@NonNull MarkwonVisitor visitor, @NonNull StrongEmphasis strongEmphasis) {\n                final int length = visitor.length();\n                visitor.visitChildren(strongEmphasis);\n                visitor.setSpansForNodeOptional(strongEmphasis, length);\n            }\n        });\n    }\n\n    private static void emphasis(@NonNull MarkwonVisitor.Builder builder) {\n        builder.on(Emphasis.class, new MarkwonVisitor.NodeVisitor<Emphasis>() {\n            @Override\n            public void visit(@NonNull MarkwonVisitor visitor, @NonNull Emphasis emphasis) {\n                final int length = visitor.length();\n                visitor.visitChildren(emphasis);\n                visitor.setSpansForNodeOptional(emphasis, length);\n            }\n        });\n    }\n\n    private static void blockQuote(@NonNull MarkwonVisitor.Builder builder) {\n        builder.on(BlockQuote.class, new MarkwonVisitor.NodeVisitor<BlockQuote>() {\n            @Override\n            public void visit(@NonNull MarkwonVisitor visitor, @NonNull BlockQuote blockQuote) {\n\n                visitor.blockStart(blockQuote);\n\n                final int length = visitor.length();\n\n                visitor.visitChildren(blockQuote);\n                visitor.setSpansForNodeOptional(blockQuote, length);\n\n                visitor.blockEnd(blockQuote);\n                int space = visitor.configuration().theme().blockQuoteStyle().paragraphSpacing() + visitor.configuration().theme().blockQuoteStyle().bottomMargin() - visitor.configuration().theme().getParagraphBreakHeight();\n                int start = visitor.length();\n                visitor.builder().append('\\n').append('\\u00a0');\n                if (space > 0) {\n                    visitor.setSpans(start, ParagraphSpacingSpan.create(space));\n                } else {\n                    visitor.setSpans(start, ParagraphSpacingSpan.create(Utils.dpToPx(8f)));\n                }\n            }\n        });\n    }\n\n    private static void code(@NonNull MarkwonVisitor.Builder builder) {\n        builder.on(Code.class, new MarkwonVisitor.NodeVisitor<Code>() {\n            @Override\n            public void visit(@NonNull MarkwonVisitor visitor, @NonNull Code code) {\n                final int length = visitor.length();\n                // NB, in order to provide a _padding_ feeling code is wrapped inside two unbreakable spaces\n                // unfortunately we cannot use this for multiline code as we cannot control where a new line break will be inserted\n                SpannableBuilder builder = visitor.builder();\n                builder.append(code.getLiteral());\n                visitor.setSpansForNodeOptional(code, length);\n             }\n        });\n    }\n\n    private static void fencedCodeBlock(@NonNull MarkwonVisitor.Builder builder) {\n        builder.on(FencedCodeBlock.class, new MarkwonVisitor.NodeVisitor<FencedCodeBlock>() {\n            @Override\n            public void visit(@NonNull MarkwonVisitor visitor, @NonNull FencedCodeBlock fencedCodeBlock) {\n                final int length = visitor.length();\n\n                visitCodeBlock(visitor, fencedCodeBlock.getInfo(), fencedCodeBlock.getLiteral(), fencedCodeBlock);\n\n                handleCodeBlockLeftMargin(length, visitor);\n                int start = visitor.length();\n                visitor.builder()\n                        .append('\\n')\n                        .append('\\u00a0');\n                visitor.setSpans(start + 1, ParagraphSpacingSpan.create(visitor.configuration().theme().getParagraphBreakHeight()));\n            }\n        });\n    }\n\n    private static void handleCodeBlockLeftMargin(int length, MarkwonVisitor visitor) {\n        if (bulletListItemSpan != null || orderedListItemSpan != null) {\n            List<SpannableBuilder.Span> itemSpans = visitor.builder().getSpans(length + 1, length + 2);\n            if (itemSpans == null) {\n                return;\n            }\n\n            for (SpannableBuilder.Span itemSpan : itemSpans) {\n                Object object = itemSpan.what;\n                if (object instanceof CodeBlockSpan) {\n                    MDLogger.d(\"MYA_CorePlugin\", \"handleCodeBlockLeftMargin bulletListItemSpan=\"\n                            + bulletListItemSpan + \", orderedListItemSpan=\" + orderedListItemSpan);\n                    ((CodeBlockSpan) object).setListItemSpan(bulletListItemSpan, orderedListItemSpan);\n                }\n            }\n\n            clear();\n        } else {\n            codeBlockStartIndex = length;\n        }\n    }\n\n    private static void indentedCodeBlock(@NonNull MarkwonVisitor.Builder builder) {\n        builder.on(IndentedCodeBlock.class, new MarkwonVisitor.NodeVisitor<IndentedCodeBlock>() {\n            @Override\n            public void visit(@NonNull MarkwonVisitor visitor, @NonNull IndentedCodeBlock indentedCodeBlock) {\n                visitCodeBlock(visitor, null, indentedCodeBlock.getLiteral(), indentedCodeBlock);\n            }\n        });\n    }\n\n    // @since 4.0.0\n    // his method is moved from ImagesPlugin. Alternative implementations must set SpanFactory\n    // for Image node in order for this visitor to function\n    private static void image(MarkwonVisitor.Builder builder) {\n        builder.on(Image.class, new MarkwonVisitor.NodeVisitor<Image>() {\n            @Override\n            public void visit(@NonNull MarkwonVisitor visitor, @NonNull Image image) {\n\n                // if there is no image spanFactory, ignore\n                final SpanFactory spanFactory = visitor.configuration().spansFactory().get(Image.class);\n                if (spanFactory == null) {\n                    visitor.visitChildren(image);\n                    return;\n                }\n\n                final int length = visitor.length();\n\n                visitor.visitChildren(image);\n\n                // we must check if anything _was_ added, as we need at least one char to render\n                if (length == visitor.length()) {\n                    visitor.builder().append('\\uFFFC');\n                }\n\n                final MarkwonConfiguration configuration = visitor.configuration();\n\n                final Node parent = image.getParent();\n                final boolean link = parent instanceof Link;\n\n                final String destination = configuration\n                        .imageDestinationProcessor()\n                        .process(image.getDestination());\n\n                final RenderProps props = visitor.renderProps();\n\n                // apply image properties\n                // Please note that we explicitly set IMAGE_SIZE to null as we do not clear\n                // properties after we applied span (we could though)\n                ImageProps.DESTINATION.set(props, destination);\n                ImageProps.REPLACEMENT_TEXT_IS_LINK.set(props, link);\n                ImageProps.IMAGE_SIZE.set(props, null);\n\n                visitor.setSpans(length, spanFactory.getSpans(configuration, props));\n            }\n        });\n    }\n    private static BulletListItemSpan bulletListItemSpan;\n    private static OrderedListItemSpan orderedListItemSpan;\n    private static Integer codeBlockStartIndex = null;\n\n    private static void clear() {\n        bulletListItemSpan = null;\n        orderedListItemSpan = null;\n    }\n\n    @VisibleForTesting\n    static void visitCodeBlock(\n            @NonNull MarkwonVisitor visitor,\n            @Nullable String info,\n            @NonNull String code,\n            @NonNull Node node) {\n\n        visitor.blockStart(node);\n\n        final int length = visitor.length();\n\n        StringBuilder language = new StringBuilder();\n        visitor.builder()\n                .append('\\u00a0').append('\\n')\n                .append(visitor.configuration().syntaxHighlight().highlight(info, code, language));\n\n        visitor.ensureNewLine();\n\n        visitor.builder().append('\\u00a0');\n\n        // @since 4.1.1\n        CoreProps.CODE_BLOCK_INFO.set(visitor.renderProps(), info);\n\n        visitor.setSpansForNodeOptional(node, length);\n\n        // store language\n        visitor.setSpans(length + 2, new CodeLanguageSpan(language.toString()));\n        visitor.blockEnd(node);\n    }\n\n    private static void bulletList(@NonNull MarkwonVisitor.Builder builder) {\n        builder.on(BulletList.class, new SimpleBlockNodeVisitor());\n    }\n\n    private static void orderedList(@NonNull MarkwonVisitor.Builder builder) {\n        builder.on(OrderedList.class, new SimpleBlockNodeVisitor());\n    }\n\n    private static void listItem(@NonNull MarkwonVisitor.Builder builder) {\n        builder.on(ListItem.class, (visitor, listItem) -> {\n\n            final int length = visitor.length();\n\n            codeBlockStartIndex = null;\n            // it's important to visit children before applying render props (\n            // we can have nested children, who are list items also, thus they will\n            // override out props (if we set them before visiting children)\n            visitor.visitChildren(listItem);\n\n            final Node parent = listItem.getParent();\n            if (parent instanceof OrderedList) {\n                final int start = ((OrderedList) parent).getStartNumber();\n\n                CoreProps.LIST_ITEM_TYPE.set(visitor.renderProps(), CoreProps.ListItemType.ORDERED);\n                CoreProps.ORDERED_LIST_ITEM_NUMBER.set(visitor.renderProps(), start);\n                CoreProps.BULLET_LIST_ITEM_LEVEL.set(visitor.renderProps(), listLevel(listItem));\n\n                // after we have visited the children increment start number\n                final OrderedList orderedList = (OrderedList) parent;\n                orderedList.setStartNumber(orderedList.getStartNumber() + 1);\n\n            } else {\n                CoreProps.LIST_ITEM_TYPE.set(visitor.renderProps(), CoreProps.ListItemType.BULLET);\n                CoreProps.BULLET_LIST_ITEM_LEVEL.set(visitor.renderProps(), listLevel(listItem));\n            }\n\n            visitor.setSpansForNodeOptional(listItem, length);\n\n            getListItemSpanAndResetCodeBlockLeftMargin(length, visitor);\n            if (visitor.hasNext(listItem)) {\n                visitor.ensureNewLine();\n            }\n        });\n    }\n    private static void getListItemSpanAndResetCodeBlockLeftMargin(int length, MarkwonVisitor visitor) {\n        clear();\n\n        List<SpannableBuilder.Span> itemSpans = visitor.builder().getSpans(length, length + 1);\n\n        for (SpannableBuilder.Span itemSpan : itemSpans) {\n            Object object = itemSpan.what;\n            if (object instanceof BulletListItemSpan) {\n                bulletListItemSpan = (BulletListItemSpan) object;\n            } else if (object instanceof OrderedListItemSpan) {\n                orderedListItemSpan = (OrderedListItemSpan) object;\n            }\n        }\n        if (codeBlockStartIndex != null) {\n            handleCodeBlockLeftMargin(codeBlockStartIndex, visitor);\n            codeBlockStartIndex = null;\n        }\n        clear();\n    }\n\n    private static int listLevel(@NonNull Node node) {\n        int level = 0;\n        Node parent = node.getParent();\n        while (parent != null) {\n            if (parent instanceof ListItem) {\n                level += 1;\n            }\n            parent = parent.getParent();\n        }\n        if (level < 0) {\n            level = 0;\n        }\n        return level;\n    }\n\n    private static void thematicBreak(@NonNull MarkwonVisitor.Builder builder) {\n        builder.on(ThematicBreak.class, (visitor, thematicBreak) -> {\n            visitor.blockStart(thematicBreak);\n\n            final int length = visitor.length();\n\n            // without space it won't render\n            visitor.builder().append('\\u00a0');\n\n            visitor.setSpansForNodeOptional(thematicBreak, length);\n\n            visitor.blockEnd(thematicBreak);\n        });\n    }\n\n    private static void heading(@NonNull MarkwonVisitor.Builder builder) {\n        builder.on(Heading.class, (visitor, heading) -> {\n            TitleStyle titleStyle = visitor.configuration().theme().getTitleStyle(heading.getLevel());\n            if (heading.getPrevious() != null\n                    && !(heading.getPrevious() instanceof Heading)\n                    && !(heading.getPrevious() instanceof ThematicBreak)\n                    && titleStyle != null && titleStyle.paragraphSpacingBefore() > 0) {\n                int paragraphBreakHeight = titleStyle.paragraphSpacingBefore();\n                final int start = visitor.length();\n                visitor.builder().append(\"\\n\\u00a0\");\n                visitor.setSpans(start + 1, new HeadingTopOrBottomSpacingSpan(paragraphBreakHeight));\n            }\n\n            visitor.blockStart(heading);\n\n            final int length = visitor.length();\n            visitor.visitChildren(heading);\n\n            CoreProps.HEADING_LEVEL.set(visitor.renderProps(), heading.getLevel());\n\n            visitor.setSpansForNodeOptional(heading, length);\n            if (titleStyle != null && titleStyle.paragraph().paragraphSpacing() > 0) {\n                int paragraphBreakHeight = titleStyle.paragraph().paragraphSpacing();\n                final int start = visitor.length();\n                visitor.builder().append(\"\\n\\u00a0\");\n                visitor.setSpans(start + 1, new HeadingTopOrBottomSpacingSpan(paragraphBreakHeight));\n            } else if (titleStyle == null) {\n                final int start = visitor.length();\n                visitor.builder().append(\"\\n\\u00a0\");\n                visitor.setSpans(start + 1, new HeadingTopOrBottomSpacingSpan(visitor.configuration().theme().getParagraphBreakHeight() + Utils.dpToPx(2)));\n            }\n            visitor.blockEnd(heading);\n        });\n    }\n\n    private static void softLineBreak(@NonNull MarkwonVisitor.Builder builder) {\n        builder.on(SoftLineBreak.class, (visitor, softLineBreak) -> visitor.builder().append(' '));\n    }\n\n    private static void hardLineBreak(@NonNull MarkwonVisitor.Builder builder) {\n        builder.on(HardLineBreak.class, (visitor, hardLineBreak) -> visitor.ensureNewLine());\n    }\n\n    private static void paragraph(Context context, @NonNull MarkwonVisitor.Builder builder) {\n        builder.on(Paragraph.class, (visitor, paragraph) -> {\n            if (paragraph.getParent() instanceof BlockQuote) {\n                visitor.ensureNewLine();\n                final int start = visitor.length();\n                visitor.builder().append('\\u00a0').append('\\n');\n                visitor.setSpans(start, ParagraphSpacingSpan.create(Utils.dpToPx(3)));\n            }\n            int paragraphStart = visitor.length();\n            final boolean inTightList = isInTightList(paragraph);\n\n            if (!inTightList) {\n                visitor.blockStart(paragraph);\n            }\n\n            final int length = visitor.length();\n            visitor.visitChildren(paragraph);\n\n            CoreProps.PARAGRAPH_IS_IN_TIGHT_LIST.set(visitor.renderProps(), inTightList);\n\n            // @since 1.1.1 apply paragraph span\n            visitor.setSpansForNodeOptional(paragraph, length);\n\n            int paragraphBreakHeight = ensureParagraphBreakHeight(context, visitor, paragraph);\n            boolean addParagraphBreak;\n            if (paragraphBreakHeight <= 0 || paragraph.getParent() == null) {\n                addParagraphBreak = false;\n            } else {\n                addParagraphBreak = paragraph.getParent().getParent() != null || paragraph.getParent().getLastChild() != paragraph;\n            }\n\n            if (addParagraphBreak) {\n                visitor.ensureNewLine();\n                final int start = visitor.length();\n                visitor.builder().append('\\u00a0');\n                visitor.setSpans(start, ParagraphSpacingSpan.create(paragraphBreakHeight));\n            }\n            if (!inTightList) {\n                visitor.blockEnd(paragraph);\n            }\n            if (paragraph.getParent() instanceof BlockQuote && visitor.configuration().theme().blockQuoteStyle().fontColor() != 0) {\n                visitor.setSpans(paragraphStart, new ForegroundColorSpan(visitor.configuration().theme().blockQuoteStyle().fontColor()));\n            }\n        });\n    }\n\n    private static int ensureParagraphBreakHeight(Context context, @NonNull MarkwonVisitor visitor, @NonNull Paragraph paragraph) {\n        int height = visitor.configuration().theme().getParagraphBreakHeight();\n        try {\n            Node next = paragraph.getNext();\n            if (next != null && next.getFirstChild() instanceof HtmlInline) {\n                HtmlInline htmlInline = (HtmlInline) next.getFirstChild();\n                Pattern pattern = Pattern.compile(\"para-space-before\\\\s*:\\\\s*(\\\\d+)rpx\");\n                Matcher matcher = pattern.matcher(htmlInline.getLiteral());\n                if (matcher.find()) {\n                    String mg = matcher.group(1);\n                    if (!TextUtils.isEmpty(mg) && TextUtils.isDigitsOnly(mg)) {\n                        height = (int) Utils.rpxToPx(Float.parseFloat(mg), context);\n                    }\n                }\n            }\n        } catch (Exception e) {\n            MDLogger.e(\"Paragraph\", \"Parse custom space error: \" + e.getMessage());\n        }\n        return height;\n    }\n\n    private static boolean isInTightList(@NonNull Paragraph paragraph) {\n        final Node parent = paragraph.getParent();\n        if (parent != null) {\n            final Node gramps = parent.getParent();\n            if (gramps instanceof ListBlock) {\n                ListBlock list = (ListBlock) gramps;\n                return list.isTight();\n            }\n        }\n        return false;\n    }\n\n    private static void link(@NonNull MarkwonVisitor.Builder builder) {\n        builder.on(Link.class, (visitor, link) -> {\n            final int length = visitor.length();\n            visitor.visitChildren(link);\n            if (Utils.isInTableNode(link)) {\n                return;\n            }\n            final String destination = link.getDestination();\n            CoreProps.LINK_DESTINATION.set(visitor.renderProps(), destination);\n            CoreProps.LINK_TEXT_DESCRIPTION.set(visitor.renderProps(), link.getTitle());\n            visitor.setSpansForNodeOptional(link, length);\n            int lengthAfter = visitor.length();\n            if (length < lengthAfter && !TextUtils.isEmpty(visitor.configuration().theme().linkStyle().icon())) {\n                SpannableBuilder.setSpans(visitor.builder(), new LinkWithIconSpan(visitor.configuration().theme()), lengthAfter - 1, lengthAfter);\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/CoreProps.java",
    "content": "package io.noties.markwon.core;\n\nimport io.noties.markwon.Prop;\n\n/**\n * @since 3.0.0\n */\npublic abstract class CoreProps {\n\n    public static final Prop<ListItemType> LIST_ITEM_TYPE = Prop.of(\"list-item-type\");\n\n    public static final Prop<Integer> BULLET_LIST_ITEM_LEVEL = Prop.of(\"bullet-list-item-level\");\n\n    public static final Prop<Integer> ORDERED_LIST_ITEM_NUMBER = Prop.of(\"ordered-list-item-number\");\n\n    public static final Prop<Integer> HEADING_LEVEL = Prop.of(\"heading-level\");\n\n    public static final Prop<String> LINK_DESTINATION = Prop.of(\"link-destination\");\n\n    public static final Prop<Boolean> PARAGRAPH_IS_IN_TIGHT_LIST = Prop.of(\"paragraph-is-in-tight-list\");\n    public static final Prop<String> LINK_TEXT_DESCRIPTION = Prop.of(\"link-text-description\");\n    public static final Prop<String> COLOR = Prop.of(\"style-color\");\n    public static final Prop<String> LINK_TEXT_DECORATION = Prop.of(\"link-text-decoration\");\n    public static final Prop<String> FONT_WEIGHT = Prop.of(\"font-weight\");\n    public static final Prop<String> SOURCE = Prop.of(\"click-source\");\n\n\n    /**\n     * @since 4.1.1\n     */\n    public static final Prop<String> CODE_BLOCK_INFO = Prop.of(\"code-block-info\");\n\n    public enum ListItemType {\n        BULLET,\n        ORDERED\n    }\n\n    private CoreProps() {\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/MarkwonTheme.java",
    "content": "\npackage io.noties.markwon.core;\n\nimport android.content.Context;\nimport android.graphics.Paint;\nimport android.graphics.Typeface;\nimport android.text.TextPaint;\nimport android.text.TextUtils;\nimport android.widget.TextView;\n\nimport androidx.annotation.NonNull;\n\nimport com.fluid.afm.styles.BlockQuoteStyle;\nimport com.fluid.afm.styles.BulletStyle;\nimport com.fluid.afm.styles.CodeStyle;\nimport com.fluid.afm.styles.FootnoteStyle;\nimport com.fluid.afm.styles.HorizonRuleStyle;\nimport com.fluid.afm.styles.LinkStyle;\nimport com.fluid.afm.styles.MarkdownStyles;\nimport com.fluid.afm.styles.OrderStyle;\nimport com.fluid.afm.styles.ParagraphStyle;\nimport com.fluid.afm.styles.TableStyle;\nimport com.fluid.afm.styles.TitleStyle;\nimport com.fluid.afm.styles.UnderlineStyle;\nimport com.fluid.afm.utils.Utils;\n\nimport java.util.List;\nimport java.util.Map;\n\nimport io.noties.markwon.MarkwonPlugin;\nimport io.noties.markwon.utils.ColorUtils;\n\n/**\n * Class to hold <i>theming</i> information for rending of markdown.\n * <p>\n * Since version 3.0.0 this class should be considered as <em>CoreTheme</em> as its\n * information holds data for core features only. But based on this other components can still use it\n * to display markdown consistently.\n * <p>\n * Since version 3.0.0 this class should not be instantiated manually. Instead a {@link MarkwonPlugin}\n * should be used: {@link MarkwonPlugin#configureTheme(Builder)}\n * <p>\n * Since version 3.0.0 properties related to <em>strike-through</em>, <em>tables</em> and <em>HTML</em>\n * are moved to specific plugins in independent artifacts\n *\n * @see CorePlugin\n * @see MarkwonPlugin#configureTheme(Builder)\n */\n@SuppressWarnings(\"WeakerAccess\")\npublic class MarkwonTheme {\n\n    private static final float THEMATIC_BREAK_DEF_WIDTH = 5f;\n    protected static final int BLOCK_QUOTE_DEF_COLOR_ALPHA = 25;\n    protected static final float CODE_DEF_TEXT_SIZE_RATIO = .87F;\n    public static final int CODE_BLOCK_HEADER_HEIGHT =  Utils.dpToPx(40);\n\n\n    public static final int THEMATIC_BREAK_DEF_ALPHA = 25;\n    private ParagraphStyle paragraph;\n    private HorizonRuleStyle horizonRule;\n    private LinkStyle link;\n    private TableStyle table;\n    private TitleStyle[] titleStyles;\n    private Map<Integer, OrderStyle> orderStyles;\n    private OrderStyle baseOrder;\n    private Map<Integer, BulletStyle> bulletStyles;\n    private BulletStyle baseBullet;\n    private FootnoteStyle footnote;\n    private BlockQuoteStyle blockQuote;\n    private CodeStyle code;\n    private UnderlineStyle underline;\n    private final TextView textView;\n\n    /**\n     * Create an <strong>empty</strong> instance of {@link Builder} with no default values applied\n     * <p>\n     * Since version 3.0.0 manual construction of {@link MarkwonTheme} is not required, instead a\n     * {@link MarkwonPlugin#configureTheme(Builder)} should be used in order\n     * to change certain theme properties\n     *\n     * @since 3.0.0\n     */\n    @SuppressWarnings(\"unused\")\n    @NonNull\n    public static Builder emptyBuilder() {\n        return new Builder();\n    }\n\n    /**\n     * Factory method to create a {@link Builder} instance and initialize it with values\n     * from supplied {@link MarkwonTheme}\n     *\n     * @param copyFrom {@link MarkwonTheme} to copy values from\n     * @return {@link Builder} instance\n     * @see #builderWithDefaults(Context)\n     * @since 1.0.0\n     */\n    @NonNull\n    public static Builder builder(@NonNull MarkwonTheme copyFrom) {\n        return new Builder(copyFrom);\n    }\n\n    /**\n     * Factory method to obtain a {@link Builder} instance initialized with default values taken\n     * from current application theme.\n     *\n     * @param context Context to obtain default styling values (colors, etc)\n     * @return {@link Builder} instance\n     * @since 1.0.0\n     */\n    @NonNull\n    public static Builder builderWithDefaults(@NonNull Context context) {\n        return new Builder();\n    }\n\n    protected MarkwonTheme(@NonNull Builder builder) {\n        this.textView = builder.textView;\n        updateStyles(builder.mProductStyles);\n    }\n\n    public void updateStyles(MarkdownStyles styles) {\n        this.paragraph = styles.paragraphStyle();\n        this.horizonRule = styles.horizonRuleStyle();\n        this.link = styles.linkStyle();\n        this.table = styles.tableStyle();\n        this.titleStyles = styles.titleStyles();\n        this.orderStyles = styles.getOrderStylesMap();\n        this.baseOrder = styles.getBaseOrderStyle();\n        this.bulletStyles = styles.getBulletStylesMap();\n        this.baseBullet = styles.getBaseBulletStyle();\n        this.footnote = styles.getFootnoteStyle();\n        this.blockQuote = styles.blockQuoteStyle();\n        this.code = styles.codeStyle();\n        this.underline = styles.underlineStyle();\n    }\n\n    public UnderlineStyle underlineStyle() {\n        return underline;\n    }\n\n    public BlockQuoteStyle blockQuoteStyle() {\n        return blockQuote;\n    }\n\n    public LinkStyle linkStyle() {\n        return link;\n    }\n\n    public FootnoteStyle footnoteStyle() {\n        return footnote;\n    }\n\n    public CodeStyle codeStyle() {\n        return code;\n    }\n\n    public TextView getTextView() {\n        return textView;\n    }\n\n    public void applyLinkStyle(@NonNull TextPaint paint, int textColor, boolean isBold, String decoration) {\n        paint.setUnderlineText(link.underline());\n        if (textColor!= 0) {\n            paint.setColor(textColor);\n        } else if (link.fontColor() != 0) {\n            paint.setColor(link.fontColor());\n        } else {\n            paint.setColor(paint.linkColor);\n        }\n        if (isBold || link.isBold()) {\n            paint.setFakeBoldText(true);\n        }\n        if (TextUtils.equals(\"none\", decoration)) {\n            paint.setUnderlineText(false);\n        } else if (TextUtils.equals(\"line-through\", decoration)) {\n            paint.setUnderlineText(false);\n            paint.setStrikeThruText(true);\n        } else if (TextUtils.equals(\"underline\", decoration)) {\n            paint.setUnderlineText(true);\n        } else {\n            paint.setUnderlineText(link.underline());\n        }\n    }\n    /**\n     * @since 1.0.5\n     */\n    public void applyLinkStyle(@NonNull TextPaint paint) {\n        paint.setUnderlineText(link.underline());\n        if (link.fontColor() != 0) {\n            paint.setColor(link.fontColor());\n        }\n        if (link.isBold()) {\n            paint.setFakeBoldText(true);\n        }\n    }\n\n    public void applyLinkStyle(@NonNull Paint paint) {\n        paint.setUnderlineText(link.underline());\n        if (link.fontColor() != 0) {\n            // by default we will be using text color\n            paint.setColor(link.fontColor());\n        } else {\n            // @since 1.0.5, if link color is specified during configuration, _try_ to use the\n            // default one (if provided paint is an instance of TextPaint)\n            if (paint instanceof TextPaint) {\n                paint.setColor(((TextPaint) paint).linkColor);\n            }\n        }\n    }\n\n    public void applyBlockQuoteStyle(@NonNull Paint paint) {\n        int color = blockQuote.lineColor();\n        if (color == 0) {\n            color = ColorUtils.applyAlpha(paint.getColor(), BLOCK_QUOTE_DEF_COLOR_ALPHA);\n        }\n        paint.setStyle(Paint.Style.FILL);\n        paint.setColor(color);\n    }\n\n    public int getCodeBlockMargin() {\n        return code.blockLeading();\n    }\n\n    public int getInlineCodeTextColor() {\n        return code.inlineFontColor();\n    }\n\n    /**\n     * @since 3.0.0\n     */\n    public void applyInlineCodeTextStyle(@NonNull Paint paint) {\n        paint.setTextSize(code.inlineFontSize());\n        paint.setColor(code.inlineFontColor());\n        paint.setTypeface(code.codeTypeface());\n\n    }\n\n    /**\n     * @since 3.0.0\n     */\n    public void applyCodeBlockTextStyle(@NonNull Paint paint) {\n\n        // apply text color, first check for block specific value,\n        // then check for code (inline), else do nothing (keep original color of text)\n\n        int textColor;\n\n        Typeface typeface;\n        int textSize;\n        textColor = code.codeFontColor();\n        typeface = code.codeTypeface();\n        textSize = code.codeFontSize();\n        if (textColor != 0) {\n            paint.setColor(textColor);\n        }\n        if (typeface != null) {\n            paint.setTypeface(typeface);\n\n            // please note that we won't be calculating textSize\n            // (like we do when no Typeface is provided), if it's some specific typeface\n            // we would confuse users about textSize\n\n            if (textSize > 0) {\n                paint.setTextSize(textSize);\n            }\n        } else {\n\n            // by default use monospace\n            paint.setTypeface(Typeface.MONOSPACE);\n            if (textSize > 0) {\n                paint.setTextSize(textSize);\n            } else {\n                // calculate default value\n                paint.setTextSize(paint.getTextSize() * CODE_DEF_TEXT_SIZE_RATIO);\n            }\n        }\n    }\n\n    /**\n     * @since 3.0.0\n     */\n    public void applyCodeBackgroundColor(@NonNull Paint paint) {\n        paint.setColor(code.codeBackgroundColor());\n    }\n\n    public void applyInlineCodeBackgroundColor(@NonNull Paint paint) {\n        paint.setColor(code.inlineBackgroundColor());\n    }\n\n    public int getCodeBackgroundRadius() {\n        return code.codeBackgroundRadius();\n    }\n\n    /**\n     * @since 3.0.0\n     */\n    public int getCodeBlockBackgroundColor(@NonNull Paint paint) {\n        return code.codeBackgroundColor();\n    }\n\n    public void applyThematicBreakStyle(@NonNull Paint paint) {\n        final int color = horizonRule.getColor() == 0 ? ColorUtils.applyAlpha(paint.getColor(), THEMATIC_BREAK_DEF_ALPHA) : horizonRule.getColor();\n        paint.setColor(color);\n        paint.setStyle(Paint.Style.FILL);\n        if (horizonRule.getHeight() >= 0) {\n            paint.setStrokeWidth((float) horizonRule.getHeight());\n        } else {\n            paint.setStrokeWidth(THEMATIC_BREAK_DEF_WIDTH);\n        }\n    }\n\n    public int getParagraphBreakHeight() {\n        return paragraph.paragraphSpacing();\n    }\n\n    public TitleStyle getTitleStyle(int level) {\n        return titleStyles[level - 1];\n    }\n\n    public TitleStyle getTitleStyles(int level) {\n        return titleStyles[level];\n    }\n\n    public BulletStyle getBulletStyle(int level) {\n        BulletStyle bulletStyle = bulletStyles.get(level);\n        if (bulletStyle == null) {\n            if (baseBullet == null) {\n                baseBullet = BulletStyle.create();\n            }\n            bulletStyle = baseBullet;\n        }\n        return bulletStyle;\n    }\n\n    public TableStyle getTableStyle() {\n        return table;\n    }\n\n    public OrderStyle orderBean(int level) {\n        OrderStyle orderBean = orderStyles.get(level);\n        if (orderBean == null) {\n            if (baseOrder == null) {\n                baseOrder = OrderStyle.create();\n            }\n            orderBean = baseOrder;\n        }\n        return orderBean;\n    }\n\n    public LinkStyle getLinkStyles() {\n        return link;\n    }\n\n    public HorizonRuleStyle getHorizonRule() {\n        return horizonRule;\n    }\n\n    @SuppressWarnings(\"unused\")\n    public static class Builder {\n\n        private TextView textView;\n        private MarkdownStyles mProductStyles;\n\n        Builder() {\n        }\n\n        Builder(@NonNull MarkwonTheme theme) {\n            this.textView = theme.getTextView();\n            mProductStyles = new MarkdownStyles()\n                    .paragraphStyle(theme.paragraph)\n                    .codeStyle(theme.code)\n                    .linkStyle(theme.link)\n                    .blockQuoteStyle(theme.blockQuote)\n                    .horizonRuleStyle(theme.horizonRule)\n                    .tableStyle(theme.table)\n                    .setTitleStyles(theme.titleStyles)\n                    .setOrderStyles(theme.orderStyles)\n                    .setBaseOrderStyle(theme.baseOrder)\n                    .setBulletStyles(theme.bulletStyles)\n                    .baseBulletStyle(theme.baseBullet)\n                    .footnoteStyle(theme.footnote)\n                    .underlineStyle(theme.underline);\n\n        }\n\n        public Builder setTextView(TextView textView) {\n            this.textView = textView;\n            return this;\n        }\n\n        public Builder setStyles(MarkdownStyles productStyles) {\n            this.mProductStyles = productStyles;\n            return this;\n        }\n\n        @NonNull\n        public MarkwonTheme build(List<MarkwonPlugin> plugins) {\n            if (plugins != null) {\n                for (MarkwonPlugin plugin : plugins) {\n                    plugin.configureTheme(this);\n                }\n            }\n            return new MarkwonTheme(this);\n        }\n    }\n\n}"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/SimpleBlockNodeVisitor.java",
    "content": "package io.noties.markwon.core;\n\nimport androidx.annotation.NonNull;\n\nimport org.commonmark.node.Node;\n\nimport io.noties.markwon.MarkwonVisitor;\n\n/**\n * A {@link MarkwonVisitor.NodeVisitor} that ensures that a markdown\n * block starts with a new line, all children are visited and if further content available\n * ensures a new line after self. Does not render any spans\n *\n * @since 3.0.0\n */\npublic class SimpleBlockNodeVisitor implements MarkwonVisitor.NodeVisitor<Node> {\n    @Override\n    public void visit(@NonNull MarkwonVisitor visitor, @NonNull Node node) {\n\n        visitor.blockStart(node);\n\n        // @since 3.0.1 we keep track of start in order to apply spans (optionally)\n        final int length = visitor.length();\n\n        visitor.visitChildren(node);\n\n        // @since 3.0.1 we apply optional spans\n        visitor.setSpansForNodeOptional(node, length);\n\n        visitor.blockEnd(node);\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/factory/BlockQuoteSpanFactory.java",
    "content": "package io.noties.markwon.core.factory;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.RenderProps;\nimport io.noties.markwon.SpanFactory;\nimport io.noties.markwon.core.spans.BlockQuoteSpan;\n\npublic class BlockQuoteSpanFactory implements SpanFactory {\n    @Nullable\n    @Override\n    public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps props) {\n        return new BlockQuoteSpan(configuration.theme());\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/factory/CodeBlockSpanFactory.java",
    "content": "package io.noties.markwon.core.factory;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.RenderProps;\nimport io.noties.markwon.SpanFactory;\nimport io.noties.markwon.core.spans.CodeBlockSpan;\n\npublic class CodeBlockSpanFactory implements SpanFactory {\n    @Nullable\n    @Override\n    public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps props) {\n        return new CodeBlockSpan(configuration.theme());\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/factory/CodeSpanFactory.java",
    "content": "package io.noties.markwon.core.factory;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.RenderProps;\nimport io.noties.markwon.SpanFactory;\nimport io.noties.markwon.core.spans.CodeSpan;\n\npublic class CodeSpanFactory implements SpanFactory {\n    @Nullable\n    @Override\n    public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps props) {\n        return new CodeSpan(configuration.theme());\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/factory/EmphasisSpanFactory.java",
    "content": "package io.noties.markwon.core.factory;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.RenderProps;\nimport io.noties.markwon.SpanFactory;\nimport io.noties.markwon.core.spans.EmphasisSpan;\n\npublic class EmphasisSpanFactory implements SpanFactory {\n    @Nullable\n    @Override\n    public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps props) {\n        return new EmphasisSpan();\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/factory/HeadingSpanFactory.java",
    "content": "package io.noties.markwon.core.factory;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.RenderProps;\nimport io.noties.markwon.SpanFactory;\nimport io.noties.markwon.core.CoreProps;\nimport io.noties.markwon.core.spans.HeadingSpan;\n\npublic class HeadingSpanFactory implements SpanFactory {\n    @Nullable\n    @Override\n    public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps props) {\n        return new HeadingSpan(\n                configuration.theme(),\n                CoreProps.HEADING_LEVEL.require(props)\n        );\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/factory/LinkSpanFactory.java",
    "content": "package io.noties.markwon.core.factory;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.RenderProps;\nimport io.noties.markwon.SpanFactory;\nimport io.noties.markwon.core.CoreProps;\nimport io.noties.markwon.core.spans.LinkSpan;\n\npublic class LinkSpanFactory implements SpanFactory {\n    @Nullable\n    @Override\n    public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps props) {\n        return new LinkSpan(\n                configuration.theme(),\n                CoreProps.LINK_DESTINATION.require(props),\n                configuration.linkResolver()\n        );\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/factory/ListItemSpanFactory.java",
    "content": "package io.noties.markwon.core.factory;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.RenderProps;\nimport io.noties.markwon.SpanFactory;\nimport io.noties.markwon.core.CoreProps;\nimport io.noties.markwon.core.spans.BulletListItemSpan;\nimport io.noties.markwon.core.spans.OrderedListItemSpan;\n\npublic class ListItemSpanFactory implements SpanFactory {\n\n    @Nullable\n    @Override\n    public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps props) {\n\n        // type of list item\n        // bullet : level\n        // ordered: number\n        final Object spans;\n\n        if (CoreProps.ListItemType.BULLET == CoreProps.LIST_ITEM_TYPE.require(props)) {\n            spans = new BulletListItemSpan(\n                    configuration.theme(),\n                    CoreProps.BULLET_LIST_ITEM_LEVEL.require(props)\n            );\n        } else {\n\n            spans = new OrderedListItemSpan(\n                    configuration.theme(),\n                    CoreProps.ORDERED_LIST_ITEM_NUMBER.require(props),\n                    CoreProps.BULLET_LIST_ITEM_LEVEL.require(props)\n            );\n        }\n\n        return spans;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/factory/StrongEmphasisSpanFactory.java",
    "content": "package io.noties.markwon.core.factory;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.RenderProps;\nimport io.noties.markwon.SpanFactory;\nimport io.noties.markwon.core.spans.StrongEmphasisSpan;\n\npublic class StrongEmphasisSpanFactory implements SpanFactory {\n    @Nullable\n    @Override\n    public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps props) {\n        return new StrongEmphasisSpan();\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/factory/ThematicBreakSpanFactory.java",
    "content": "package io.noties.markwon.core.factory;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.RenderProps;\nimport io.noties.markwon.SpanFactory;\nimport io.noties.markwon.core.spans.ThematicBreakSpan;\n\npublic class ThematicBreakSpanFactory implements SpanFactory {\n    @Nullable\n    @Override\n    public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps props) {\n        return new ThematicBreakSpan(configuration.theme());\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/spans/BlockQuoteSpan.java",
    "content": "package io.noties.markwon.core.spans;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.graphics.Rect;\nimport android.graphics.RectF;\nimport android.text.Layout;\nimport android.text.Spanned;\nimport android.text.style.LeadingMarginSpan;\n\nimport androidx.annotation.NonNull;\n\nimport com.fluid.afm.styles.BlockQuoteStyle;\n\nimport io.noties.markwon.core.MarkwonTheme;\n\npublic class BlockQuoteSpan implements LeadingMarginSpan {\n\n    private final MarkwonTheme theme;\n    private final Rect rect = ObjectsPool.rect();\n    private final Paint paint = ObjectsPool.paint();\n\n    private int mLineWidth;\n    private int mSpace;\n    private int mLineCornerRadius;\n    private int mLineColor;\n    private int mBottomDistance;\n\n    public BlockQuoteSpan(@NonNull MarkwonTheme theme) {\n        this.theme = theme;\n        applyStyles();\n    }\n\n    private void applyStyles() {\n        BlockQuoteStyle blockQuoteStyle = theme.blockQuoteStyle();\n        mLineWidth = blockQuoteStyle.lineWidth();\n        mSpace = blockQuoteStyle.lineMargin() + blockQuoteStyle.lineWidth() + blockQuoteStyle.leftMargin();\n        mLineCornerRadius = blockQuoteStyle.lineCornerRadius();\n        mLineColor = blockQuoteStyle.lineColor();\n        mBottomDistance = blockQuoteStyle.bottomMargin();\n    }\n\n    @Override\n    public int getLeadingMargin(boolean first) {\n        return mSpace;\n    }\n\n    @Override\n    public void drawLeadingMargin(\n            Canvas c,\n            Paint p,\n            int x,\n            int dir,\n            int top,\n            int baseline,\n            int bottom,\n            CharSequence text,\n            int start,\n            int end,\n            boolean first,\n            Layout layout) {\n\n        final int width = mLineWidth;\n        paint.set(p);\n        if (mLineColor != 0) {\n            paint.setColor(mLineColor);\n        } else {\n            theme.applyBlockQuoteStyle(paint);\n        }\n\n        final int l = x + theme.blockQuoteStyle().leftMargin();\n        final int r = l + (dir * width);\n        final int left = Math.min(l, r);\n        final int right = Math.max(l, r);\n\n        if (selfEnd(end, text, this)) {\n            rect.set(left, top, right, Math.max(bottom - theme.getParagraphBreakHeight() + mBottomDistance, top));\n        } else if (bottom > top){\n            rect.set(left, top, right, bottom);\n        }\n\n        // get span start/end\n        final Spanned spanned = (Spanned) text;\n        final int spanStart = spanned.getSpanStart(this);\n        final int spanEnd = spanned.getSpanEnd(this);\n\n        // is first/last line\n        boolean isFirstLine = layout.getLineForOffset(start) == layout.getLineForOffset(spanStart);\n        boolean isLastLine = layout.getLineForOffset(end) == layout.getLineForOffset(spanEnd);\n\n        RectF rectF = new android.graphics.RectF(\n                rect.left, rect.top, rect.right, rect.bottom\n        );\n        paint.setAlpha((int) (0.6f * 255));\n        if (mLineCornerRadius > 0 && (isFirstLine || isLastLine)) {\n            int save = c.save();\n            if (isFirstLine) {\n                c.clipRect(rectF);\n                c.drawRoundRect(rectF.left, rectF.top, rectF.right, rectF.bottom + mLineCornerRadius, mLineCornerRadius, mLineCornerRadius, paint);\n            } else { // last line\n                if (rectF.bottom < rectF.top) {\n                    rectF.set(rectF.left, rectF.top, rectF.right, rectF.top + mLineCornerRadius);\n                }\n                c.clipRect(rectF);\n                c.drawRoundRect(rectF.left, rectF.top - mLineCornerRadius, rectF.right, rectF.bottom, mLineCornerRadius, mLineCornerRadius, paint);\n            }\n            c.restoreToCount(save);\n        } else {\n            c.drawRect(rectF, paint);\n        }\n    }\n\n    private static boolean selfEnd(int end, CharSequence text, Object span) {\n        final int spanEnd = ((Spanned) text).getSpanEnd(span);\n        return spanEnd == end || spanEnd == end - 1;\n    }\n\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/spans/BulletListItemSpan.java",
    "content": "package io.noties.markwon.core.spans;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.graphics.Rect;\nimport android.graphics.RectF;\nimport android.os.Build;\nimport android.text.Layout;\nimport android.text.TextPaint;\nimport android.text.TextUtils;\n\nimport androidx.annotation.IntRange;\nimport androidx.annotation.NonNull;\n\nimport com.fluid.afm.span.BaseIconTextSpan;\nimport com.fluid.afm.styles.BulletStyle;\nimport com.fluid.afm.styles.Shape;\nimport com.fluid.afm.utils.Utils;\n\nimport io.noties.markwon.core.MarkwonTheme;\nimport io.noties.markwon.utils.LeadingMarginUtils;\n\n/**\n * 无序列表项\n */\npublic class BulletListItemSpan extends BaseIconTextSpan {\n\n    private static final boolean IS_NOUGAT;\n    private static final int DEFAULT_STROKE_WIDTH = Utils.dpToPx(1);\n    private static final int DEFAULT_LEADING_MARGIN = Utils.dpToPx(24);\n    private Integer leadingMargin = null;\n\n    static {\n        final int sdk = Build.VERSION.SDK_INT;\n        IS_NOUGAT = Build.VERSION_CODES.N == sdk || Build.VERSION_CODES.N_MR1 == sdk;\n    }\n\n    private final MarkwonTheme theme;\n\n    private final Paint paint = ObjectsPool.paint();\n    private final RectF circle = ObjectsPool.rectF();\n    private final Rect rectangle = ObjectsPool.rect();\n\n    private final int level;\n\n    private BulletStyle style;\n\n    public BulletListItemSpan(\n            @NonNull MarkwonTheme theme,\n            @IntRange(from = 0) int level) {\n        super(theme.getTextView());\n        this.theme = theme;\n        this.level = level;\n        style = theme.getBulletStyle(level);\n    }\n\n    @Override\n    protected String getImageUrl() {\n        if (style != null && style.shape() != null) {\n            return style.shape().icon();\n        }\n        return \"\";\n    }\n\n    @Override\n    protected void applyStyle(TextPaint paint) {\n        applyStyleInner(paint);\n    }\n\n    private void applyStyleInner(Paint p) {\n        style = theme.getBulletStyle(level);\n        if (TextUtils.isEmpty(getImageUrl())) {\n            paint.setStrokeWidth(DEFAULT_STROKE_WIDTH);\n        }\n        if (validShape() && style.shape().color() != 0) {\n            paint.setColor(style.shape().color());\n        } else {\n            paint.setColor(p.getColor());\n        }\n    }\n\n    public int getLeadingMarginIfUsed() {\n        return leadingMargin == null ? 0 : leadingMargin;\n    }\n\n    @Override\n    public int getLeadingMargin(boolean first) {\n        if (style.leadingSpacing() >= 0) {\n            leadingMargin = style.leadingSpacing();\n        } else {\n            leadingMargin = (int) (realTextSize + 0.5) / 2;\n        }\n        if (style.leading() > 0) {\n            leadingMargin += style.leading();\n        } else {\n            leadingMargin += (int) (realTextSize + 0.5) / 2;\n        }\n        if (style.shape() != null && style.shape().size() > 0) {\n            leadingMargin += style.shape().size();\n        } else {\n            final int textLineHeight = (int) (paint.descent() - paint.ascent() + .5F);\n\n            final int side = getSpotSize(textLineHeight);\n            leadingMargin += getSpotSize(side) + DEFAULT_LEADING_MARGIN;\n        }\n        return leadingMargin;\n    }\n\n    private boolean validShape() {\n        if (style.shape() == null) {\n            return false;\n        }\n        if (style.shape().type() == Shape.SHAPE_CIRCLE || style.shape().type() == Shape.SHAPE_RECT || style.shape().type() == Shape.SHAPE_RING || style.shape().type() == Shape.SHAPE_RECT_OUTLINE) {\n            return style.shape().size() > 0;\n        } else {\n            return style.shape().type() == Shape.SHAPE_ICON;\n        }\n    }\n\n    @Override\n    public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline, int bottom, CharSequence text, int start, int end, boolean first, Layout layout) {\n\n        // if there was a line break, we don't need to draw anything\n        if (!first\n                || !LeadingMarginUtils.selfStart(start, text, this)) {\n            return;\n        }\n\n        paint.set(p);\n\n        applyStyleInner(paint);\n        boolean validShape = validShape();\n        if (validShape && style.shape().type() == Shape.SHAPE_ICON) {\n            if (mDrawableWrapper != null && mDrawableWrapper.getDrawable() != null) {\n                c.save();\n                c.translate(x, baseline - iconOffset);\n                mDrawableWrapper.getDrawable().draw(c);\n                c.restore();\n            }\n            return;\n        }\n        final int save = c.save();\n        try {\n            final int width = leadingMargin;\n\n            // @since 1.0.6 we no longer rely on (bottom-top) calculation in order to detect line height\n            // it lead to bad rendering as first & last lines received different results even\n            // if text size is the same (first line received greater amount and bottom line -> less)\n            final int textLineHeight = (int) (paint.descent() - paint.ascent() + .5F);\n\n            final int side = getSpotSize(textLineHeight);\n\n            final int marginLeft = validShape ? style.leading() : (width - side) / 2;\n\n            // in order to support RTL\n            final int l;\n            final int r;\n            {\n                // @since 4.2.1 to correctly position bullet\n                // when nested inside other LeadingMarginSpans (sorry, Nougat)\n                if (IS_NOUGAT) {\n\n                    // @since 2.0.2\n                    // There is a bug in Android Nougat, when this span receives an `x` that\n                    // doesn't correspond to what it should be (text is placed correctly though).\n                    // Let's make this a general rule -> manually calculate difference between expected/actual\n                    // and add this difference to resulting left/right values. If everything goes well\n                    // we do not encounter a bug -> this `diff` value will be 0\n                    final int diff;\n                    if (dir < 0) {\n                        // rtl\n                        diff = x - (layout.getWidth() - (width * level));\n                    } else {\n                        diff = (width * level) - x;\n                    }\n\n                    final int left = x + (dir * marginLeft);\n                    final int right = left + (dir * side);\n                    l = Math.min(left, right) + (dir * diff);\n                    r = Math.max(left, right) + (dir * diff);\n\n                } else {\n                    if (dir > 0) {\n                        l = x + marginLeft;\n                    } else {\n                        l = x - width + marginLeft;\n                    }\n                    r = l + side;\n                }\n            }\n\n            final int t = baseline + (int) (((paint.descent() + paint.ascent()) / 2.F + .5F) * (1 + Utils.FONT_SPACING_IN_LINE)) - (side / 2);\n            final int b = t + side;\n            boolean drawn = false;\n            if (validShape) {\n                if (style.shape().type() == Shape.SHAPE_CIRCLE || style.shape().type() == Shape.SHAPE_RING) {\n                    circle.set(l, t, r, b);\n                    Paint.Style paintStyle =  Paint.Style.FILL;\n                    if (style.shape().type() == Shape.SHAPE_RING || (!validShape && level == 0)) {\n                        paintStyle = Paint.Style.STROKE;\n                    }\n                    paint.setStyle(paintStyle);\n                    c.drawOval(circle, paint);\n                    drawn = true;\n                } else if (style.shape().type() == Shape.SHAPE_RECT || style.shape().type() == Shape.SHAPE_RECT_OUTLINE) {\n                    rectangle.set(l, t, r, b);\n                    if (style.shape().type() == Shape.SHAPE_RECT) {\n                        paint.setStyle(Paint.Style.FILL);\n                    } else {\n                        paint.setStyle(Paint.Style.STROKE);\n                        paint.setStrokeWidth(style.shape().lineWidth());\n                    }\n                    c.drawRect(rectangle, paint);\n                    drawn = true;\n                }\n            }\n            if (!drawn) {\n                if (level == 0 || level == 1) {\n                    circle.set(l, t, r, b);\n\n                    final Paint.Style style = level == 0\n                            ? Paint.Style.FILL\n                            : Paint.Style.STROKE;\n                    paint.setStyle(style);\n\n                    c.drawOval(circle, paint);\n                } else {\n                    rectangle.set(l, t, r, b);\n                    paint.setStyle(Paint.Style.FILL);\n                    c.drawRect(rectangle, paint);\n                }\n            }\n\n        } finally {\n            c.restoreToCount(save);\n        }\n    }\n\n    private int getSpotSize(int textLineHeight) {\n        if (validShape() && style.shape().size() > 0) {\n            return style.shape().size();\n        }\n        return textLineHeight / 3;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/spans/CodeBlockSpan.java",
    "content": "package io.noties.markwon.core.spans;\n\nimport static io.noties.markwon.core.MarkwonTheme.CODE_BLOCK_HEADER_HEIGHT;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.graphics.Rect;\nimport android.text.Layout;\nimport android.text.Spanned;\nimport android.text.TextPaint;\nimport android.text.style.LeadingMarginSpan;\nimport android.text.style.MetricAffectingSpan;\n\nimport androidx.annotation.NonNull;\n\nimport com.fluid.afm.utils.MDLogger;\n\nimport io.noties.markwon.core.MarkwonTheme;\nimport io.noties.markwon.utils.LeadingMarginUtils;\nimport io.noties.markwon.utils.SpanUtils;\n\n/**\n * @since 3.0.0 split inline and block spans\n */\npublic class CodeBlockSpan extends MetricAffectingSpan implements LeadingMarginSpan {\n    private static final String TAG = \"MYA_CodeBlockSpan\";\n\n    private final MarkwonTheme theme;\n    private final Rect rect = ObjectsPool.rect();\n    private final Paint paint = ObjectsPool.paint();\n    private final int radius;\n    private int leftOffset;\n    private BulletListItemSpan bulletListItemSpan;\n    private OrderedListItemSpan orderedListItemSpan;\n\n    public CodeBlockSpan(@NonNull MarkwonTheme theme) {\n        this.theme = theme;\n        this.radius = theme.getCodeBackgroundRadius();\n        this.leftOffset = 0;\n    }\n\n    public void setListItemSpan(BulletListItemSpan bulletListItemSpan,\n                                      OrderedListItemSpan orderedListItemSpan) {\n        this.bulletListItemSpan = bulletListItemSpan;\n        this.orderedListItemSpan = orderedListItemSpan;\n    }\n\n    @Override\n    public void updateMeasureState(TextPaint p) {\n        apply(p);\n    }\n\n    @Override\n    public void updateDrawState(TextPaint ds) {\n        apply(ds);\n    }\n\n    private void apply(TextPaint p) {\n        theme.applyCodeBlockTextStyle(p);\n    }\n\n    @Override\n    public int getLeadingMargin(boolean first) {\n        if (bulletListItemSpan != null) {\n            leftOffset = bulletListItemSpan.getLeadingMarginIfUsed();\n        } else if (orderedListItemSpan != null) {\n            leftOffset = orderedListItemSpan.getLeadingMarginIfUsed();\n        }\n        if (leftOffset != 0) {\n            MDLogger.d(TAG, \"getLeadingMargin leftOffset=\" + leftOffset\n                    + \",bulletListItemSpan=\" + bulletListItemSpan\n                    + \",orderedListItemSpan=\" + orderedListItemSpan);\n        }\n        return theme.codeStyle().blockLeading() - leftOffset;\n    }\n\n    @Override\n    public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline, int bottom, CharSequence text, int start, int end, boolean first, Layout layout) {\n        if (!SpanUtils.isSelf(start, end, text, this)) {\n            return;\n        }\n        paint.setStyle(Paint.Style.FILL);\n        paint.setColor(theme.getCodeBlockBackgroundColor(p));\n\n        int left;\n        final int right;\n        if (dir > 0) {\n            left = 0;\n            right = layout.getWidth();\n        } else {\n            left = x - layout.getWidth();\n            right = x;\n        }\n        left -= leftOffset;\n        left = Math.max(0, left);\n\n        final boolean lastLine = selfEnd(end, text, this);\n\n        final boolean firstLine = LeadingMarginUtils.selfStart(start, text, this);\n        if (lastLine) {\n            // draw bottom\n            Paint.FontMetricsInt fontMetrics = p.getFontMetricsInt();\n            final int fontHeight = fontMetrics.bottom - fontMetrics.top;\n            final int lineHeight = bottom - top;\n            if (lineHeight < fontHeight) {\n                bottom += (fontHeight - lineHeight / 2 );\n                MDLogger.d(TAG, \"drawLeadingMargin bottom=\" + bottom\n                        + \", fontHeight=\" + fontHeight\n                        + \", lineHeight=\" + lineHeight);\n            }\n            // reduce last line height\n            bottom -= lineHeight / 2;\n            drawRectWithBottomRound(c, paint, left, top, right, bottom, radius);\n        } else if (firstLine) {\n            // draw top\n            if(theme.codeStyle().isShowTitle()) {\n                rect.set(left, top + CODE_BLOCK_HEADER_HEIGHT, right, bottom);\n                c.drawRect(rect, paint);\n            } else {\n                drawRectWithTopRound(c, paint, left, top, right, bottom, radius);\n            }\n        } else {\n            // draw middle left and right line\n            rect.set(left, top, right, bottom);\n            c.drawRect(rect, paint);\n        }\n        if (theme.codeStyle().isDrawBorder()) {\n            paint.setStyle(Paint.Style.STROKE);\n            paint.setColor(theme.codeStyle().borderColor());\n            paint.setStrokeWidth(theme.codeStyle().borderWidth());\n            float halfStrokeWidth = paint.getStrokeWidth() / 2;\n            int saveCount = c.save();\n            if (firstLine) {\n                if(theme.codeStyle().isShowTitle()) {\n                    c.clipRect(left, top + CODE_BLOCK_HEADER_HEIGHT + halfStrokeWidth, right, bottom);\n                } else {\n                    c.clipRect(left, top + radius + halfStrokeWidth, right, bottom);\n                }\n            } else {\n                c.clipRect(left, top, right, bottom);\n            }\n            if (lastLine) {\n                c.drawRoundRect(left + halfStrokeWidth, top - paint.getStrokeWidth() - radius, right - halfStrokeWidth, bottom - paint.getStrokeWidth(), radius, radius, paint);\n            } else {\n                c.drawRect(left + halfStrokeWidth, top - paint.getStrokeWidth(), right - halfStrokeWidth, bottom + paint.getStrokeWidth(), paint);\n            }\n            c.restoreToCount(saveCount);\n            paint.setStyle(Paint.Style.FILL);\n        }\n    }\n\n    private void drawRectWithTopRound(Canvas canvas, Paint paint,\n                      float left, float top, float right, float bottom,\n                      float radius) {\n        int count = canvas.save();\n        canvas.clipRect(left, top, right, bottom);\n        canvas.drawRoundRect(left, top, right, bottom + radius, radius, radius, paint);\n        canvas.restoreToCount(count);\n    }\n\n    private void drawRectWithBottomRound(Canvas canvas, Paint paint,\n                                         float left, float top, float right, float bottom,\n                                         float radius) {\n        int count = canvas.save();\n        canvas.clipRect(left, top, right, bottom);\n        canvas.drawRoundRect(left, top - radius, right, bottom, radius, radius, paint);\n        canvas.restoreToCount(count);\n    }\n\n    private boolean selfEnd(int end, CharSequence text, Object span) {\n        final int spanEnd = ((Spanned) text).getSpanEnd(span);\n        return spanEnd == end || spanEnd == end - 1;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/spans/CodeSpan.java",
    "content": "package io.noties.markwon.core.spans;\n\nimport android.text.TextPaint;\nimport android.text.style.MetricAffectingSpan;\n\nimport androidx.annotation.NonNull;\n\nimport io.noties.markwon.core.MarkwonTheme;\n\n/**\n * @since 3.0.0 split inline and block spans\n */\npublic class CodeSpan extends MetricAffectingSpan {\n\n    private final MarkwonTheme theme;\n\n    public CodeSpan(@NonNull MarkwonTheme theme) {\n        this.theme = theme;\n    }\n\n    @Override\n    public void updateMeasureState(TextPaint p) {\n        apply(p);\n    }\n\n    @Override\n    public void updateDrawState(TextPaint ds) {\n        apply(ds);\n        theme.applyCodeBackgroundColor(ds);\n    }\n\n    private void apply(TextPaint p) {\n        theme.applyInlineCodeTextStyle(p);\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/spans/CustomTypefaceSpan.java",
    "content": "package io.noties.markwon.core.spans;\n\nimport android.annotation.SuppressLint;\nimport android.graphics.Typeface;\nimport android.text.TextPaint;\nimport android.text.style.MetricAffectingSpan;\n\nimport androidx.annotation.NonNull;\n\n/**\n * A span implementation that allow applying custom Typeface. Although it is\n * not used directly by the library, it\\'s helpful for customizations.\n * <p>\n * Please note that this implementation does not validate current paint state\n * and won\\'t be updating/modifying supplied Typeface unless {@code mergeStyles} is specified\n *\n * @since 3.0.0\n */\npublic class CustomTypefaceSpan extends MetricAffectingSpan {\n\n    @NonNull\n    public static CustomTypefaceSpan create(@NonNull Typeface typeface) {\n        return create(typeface, false);\n    }\n\n    /**\n     * <strong>NB!</strong> in order to <em>merge</em> typeface styles, supplied typeface must be\n     * able to be created via {@code Typeface.create(Typeface, int)} method. This would mean that bundled fonts\n     * inside {@code assets} folder would be able to display styles properly.\n     *\n     * @param mergeStyles control if typeface styles must be merged, for example, if\n     *                    this span (bold) is contained by other span (italic),\n     *                    {@code mergeStyles=true} would result in bold-italic\n     * @since 4.6.1\n     */\n    @NonNull\n    public static CustomTypefaceSpan create(@NonNull Typeface typeface, boolean mergeStyles) {\n        return new CustomTypefaceSpan(typeface, mergeStyles);\n    }\n\n    private final Typeface typeface;\n\n    private final boolean mergeStyles;\n\n    /**\n     * @deprecated 4.6.1 use {{@link #create(Typeface)}}\n     * or {@link #create(Typeface, boolean)} factory method\n     */\n    @Deprecated\n    public CustomTypefaceSpan(@NonNull Typeface typeface) {\n        this(typeface, false);\n    }\n\n    // @since 4.6.1\n    CustomTypefaceSpan(@NonNull Typeface typeface, boolean mergeStyles) {\n        this.typeface = typeface;\n        this.mergeStyles = mergeStyles;\n    }\n\n\n    @Override\n    public void updateMeasureState(@NonNull TextPaint paint) {\n        updatePaint(paint);\n    }\n\n    @Override\n    public void updateDrawState(@NonNull TextPaint paint) {\n        updatePaint(paint);\n    }\n\n    private void updatePaint(@NonNull TextPaint paint) {\n        final Typeface oldTypeface = paint.getTypeface();\n        if (!mergeStyles ||\n                oldTypeface == null ||\n                oldTypeface.getStyle() == Typeface.NORMAL) {\n            paint.setTypeface(typeface);\n        } else {\n            final int oldStyle = oldTypeface.getStyle();\n\n            @SuppressLint(\"WrongConstant\") final int want = oldStyle | typeface.getStyle();\n            final Typeface styledTypeface = Typeface.create(typeface, want);\n\n            paint.setTypeface(styledTypeface);\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/spans/EmphasisSpan.java",
    "content": "package io.noties.markwon.core.spans;\n\nimport android.text.TextPaint;\nimport android.text.style.MetricAffectingSpan;\n\npublic class EmphasisSpan extends MetricAffectingSpan {\n\n    @Override\n    public void updateMeasureState(TextPaint p) {\n        p.setTextSkewX(-0.25F);\n    }\n\n    @Override\n    public void updateDrawState(TextPaint tp) {\n        tp.setTextSkewX(-0.25F);\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/spans/HeadingSpan.java",
    "content": "package io.noties.markwon.core.spans;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.text.Layout;\nimport android.text.TextPaint;\nimport android.text.TextUtils;\n\nimport androidx.annotation.IntRange;\nimport androidx.annotation.NonNull;\n\nimport com.fluid.afm.span.BaseIconTextSpan;\nimport com.fluid.afm.styles.TitleStyle;\n\nimport io.noties.markwon.core.MarkwonTheme;\n\n/**\n * 标题\n */\npublic class HeadingSpan extends BaseIconTextSpan {\n\n    private final MarkwonTheme theme;\n    private final int level;\n    private TitleStyle style;\n\n    public HeadingSpan(@NonNull MarkwonTheme theme, @IntRange(from = 1, to = 6) int level) {\n        super(theme.getTextView());\n        this.theme = theme;\n        this.level = level;\n        style = theme.getTitleStyles(level - 1);\n    }\n\n    @Override\n    protected String getImageUrl() {\n        if (style != null) {\n            return style.icon();\n        }\n        return \"\";\n    }\n\n    @Override\n    protected void applyStyle(TextPaint paint) {\n        style = theme.getTitleStyles(level - 1);\n        style.apply(paint);\n    }\n\n    @Override\n    public int getLeadingMargin(boolean first) {\n        // no margin actually, but we need to access Canvas to draw break\n        if (style != null && first && !TextUtils.isEmpty(style.icon())) {\n            return realTextSize;\n        }\n        return 0;\n    }\n\n    @Override\n    public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline, int bottom, CharSequence text, int start, int end, boolean first, Layout layout) {\n        if (first && mDrawableWrapper != null && mDrawableWrapper.getDrawable() != null) {\n            c.save();\n            c.translate(x, baseline - iconOffset);\n            mDrawableWrapper.getDrawable().draw(c);\n            c.restore();\n        }\n    }\n\n    /**\n     * @since 4.2.0\n     */\n    public int getLevel() {\n        return level;\n    }\n\n\n\n\n\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/spans/LastLineSpacingSpan.java",
    "content": "package io.noties.markwon.core.spans;\n\nimport android.graphics.Paint;\nimport android.text.Spanned;\nimport android.text.style.LineHeightSpan;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Px;\n\n/**\n * @since 4.0.0\n */\npublic class LastLineSpacingSpan implements LineHeightSpan {\n\n    @NonNull\n    public static LastLineSpacingSpan create(@Px int spacing) {\n        return new LastLineSpacingSpan(spacing);\n    }\n\n    private final int spacing;\n\n    public LastLineSpacingSpan(@Px int spacing) {\n        this.spacing = spacing;\n    }\n\n    @Override\n    public void chooseHeight(CharSequence text, int start, int end, int spanstartv, int v, Paint.FontMetricsInt fm) {\n        if (selfEnd(end, text, this)) {\n            // let's just add what we want\n            fm.descent += spacing;\n            fm.bottom += spacing;\n        }\n    }\n\n    private static boolean selfEnd(int end, CharSequence text, Object span) {\n        // this is some kind of interesting magic here... only the last\n        // span will receive correct _end_ argument, but previous spans\n        // receive it tilted by one (1). Most likely it's just a new-line character... and\n        // if needed we could check for that\n        final int spanEnd = ((Spanned) text).getSpanEnd(span);\n        return spanEnd == end || spanEnd == end - 1;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/spans/LinkSpan.java",
    "content": "package io.noties.markwon.core.spans;\n\nimport android.text.TextPaint;\nimport android.text.style.URLSpan;\nimport android.view.View;\n\nimport androidx.annotation.NonNull;\n\nimport io.noties.markwon.LinkResolver;\nimport io.noties.markwon.core.MarkwonTheme;\n\npublic class LinkSpan extends URLSpan {\n\n    private final MarkwonTheme theme;\n    private final String link;\n    private final LinkResolver resolver;\n\n    public LinkSpan(\n            @NonNull MarkwonTheme theme,\n            @NonNull String link,\n            @NonNull LinkResolver resolver) {\n        super(link);\n        this.theme = theme;\n        this.link = link;\n        this.resolver = resolver;\n    }\n\n    @Override\n    public void onClick(View widget) {\n        resolver.resolve(widget, link);\n    }\n\n    @Override\n    public void updateDrawState(@NonNull TextPaint ds) {\n        theme.applyLinkStyle(ds);\n    }\n\n    /**\n     * @since 4.2.0\n     */\n    @NonNull\n    public String getLink() {\n        return link;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/spans/ObjectsPool.java",
    "content": "package io.noties.markwon.core.spans;\n\nimport android.graphics.Paint;\nimport android.graphics.Rect;\nimport android.graphics.RectF;\n\nabstract class ObjectsPool {\n\n    // maybe it's premature optimization, but as all the drawing is done in one thread\n    // and we apply needed values before actual drawing it's (I assume) safe to reuse some frequently used objects\n\n    // if one of the spans need some really specific handling for Paint object (like colorFilters, masks, etc)\n    // it should instantiate own instance of it\n\n    private static final Rect RECT = new Rect();\n    private static final RectF RECT_F = new RectF();\n    private static final Paint PAINT = new Paint(Paint.ANTI_ALIAS_FLAG);\n\n    static Rect rect() {\n        return RECT;\n    }\n\n    static RectF rectF() {\n        return RECT_F;\n    }\n\n    static Paint paint() {\n        return PAINT;\n    }\n\n    private ObjectsPool() {\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/spans/OrderedListItemSpan.java",
    "content": "package io.noties.markwon.core.spans;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.text.Layout;\nimport android.text.Spanned;\nimport android.text.TextPaint;\nimport android.text.style.LeadingMarginSpan;\nimport android.widget.TextView;\n\nimport androidx.annotation.IntRange;\nimport androidx.annotation.NonNull;\n\nimport com.fluid.afm.span.BaseIconTextSpan;\nimport com.fluid.afm.styles.OrderStyle;\nimport com.fluid.afm.styles.Shape;\n\nimport io.noties.markwon.core.MarkwonTheme;\nimport io.noties.markwon.utils.LeadingMarginUtils;\nimport com.fluid.afm.utils.Utils;\n\npublic class OrderedListItemSpan extends BaseIconTextSpan implements LeadingMarginSpan {\n\n    private static final int DEFAULT_STROKE_WIDTH = Utils.dpToPx(1);\n    private static final int ICON_SPACING = Utils.dpToPx(5);\n    private static final int DEFAULT_LEADING_MARGIN = Utils.dpToPx(24);\n\n\n    /**\n     * Process supplied `text` argument and supply TextView paint to all OrderedListItemSpans\n     * in order for them to measure number.\n     * <p>\n     * NB, this method must be called <em>before</em> setting text to a TextView (`TextView#setText`\n     * internally can trigger new Layout creation which will ask for leading margins right away)\n     *\n     * @param textView to which markdown will be applied\n     * @param text     parsed markdown to process\n     * @since 2.0.1\n     */\n\n    private static final int BASE_CHAR_WIDTH = Utils.dpToPx(9f);\n    private static final int SPACE = Utils.dpToPx(5f);\n\n    public static void measure(@NonNull TextView textView, @NonNull CharSequence text) {\n\n        if (!(text instanceof Spanned)) {\n            // nothing to do here\n            return;\n        }\n\n        final OrderedListItemSpan[] spans = ((Spanned) text).getSpans(\n                0,\n                text.length(),\n                OrderedListItemSpan.class);\n\n        if (spans != null) {\n            final TextPaint paint = textView.getPaint();\n            for (OrderedListItemSpan span : spans) {\n                span.margin = (int) (paint.measureText(span.number) + .5F);\n            }\n        }\n    }\n\n    private final MarkwonTheme theme;\n    private final String number;\n    private final Paint paint = ObjectsPool.paint();\n\n    private Integer leadingMargin = null;\n\n    // we will use this variable to check if our order number text exceeds block margin,\n    // so we will use it instead of block margin\n    // @since 1.0.3\n    private float margin;\n    private final int level;\n    private int numberLength;\n    private OrderStyle style;\n\n    public OrderedListItemSpan(\n            @NonNull MarkwonTheme theme,\n            @IntRange(from = 0) int number,\n            @IntRange(from = 0) int level\n    ) {\n        super(theme.getTextView());\n\n        style = theme.orderBean(level);\n        this.theme = theme;\n        this.level = level;\n        if (style != null && style.shape() != null) {\n            this.number = String.valueOf(number);\n        } else {\n            this.number = number + \".\" + '\\u00a0';\n        }\n        numberLength = String.valueOf(number).length();\n    }\n\n    public int getLeadingMarginIfUsed() {\n        return getProductLeading();\n    }\n\n    public int getProductLeading() {\n        if (style != null) {\n            if (style.shape() != null) {\n                if (style.shape().type() == Shape.SHAPE_ICON) {\n                    return getIconSize() + style.leading() + style.leadingSpacing();\n                } else if (style.shape().type() == Shape.SHAPE_RECT) {\n                    return style.shape().size() + style.leading() + style.leadingSpacing();\n                }\n            } else {\n                if (style.orderFontSize() > 0) {\n                    paint.setTextSize(style.orderFontSize());\n                }\n                float baseW = paint.measureText(\"4\"); // 4 is the widest number\n                return (int) (style.leading() + numberLength * baseW + style.leadingSpacing());\n            }\n        }\n        return (int) margin + DEFAULT_LEADING_MARGIN;\n    }\n\n\n    @Override\n    public int getLeadingMargin(boolean first) {\n        leadingMargin = getProductLeading();\n        return leadingMargin;\n    }\n\n    private void applyListItemStyle(@NonNull Paint paint) {\n        paint.setStrokeWidth(DEFAULT_STROKE_WIDTH);\n        paint.setLetterSpacing(0);\n        if (style.orderFontSize() > 0) {\n            paint.setTextSize(style.orderFontSize());\n        }\n    }\n\n    @Override\n    public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline, int bottom, CharSequence text, int start, int end, boolean first, Layout layout) {\n\n        // if there was a line break, we don't need to draw anything\n        if (!first\n                || !LeadingMarginUtils.selfStart(start, text, this)) {\n            return;\n        }\n\n        paint.set(p);\n        boolean drawIcon = mDrawableWrapper != null && mDrawableWrapper.getDrawable() != null;\n        float oldSize = paint.getTextSize();\n\n        float baselineOffset = 0;\n        boolean isBold = paint.isFakeBoldText();\n        if (drawIcon || (style != null && style.shape() != null)) {\n            float textsize;\n            if (style != null && style.orderFontSize() > 0) {\n                textsize = style.orderFontSize();\n            } else {\n                float numberRatio = 0.62f;\n                textsize = oldSize * numberRatio;\n            }\n            paint.setTextSize(textsize);\n            if (style != null && style.isBold()) {\n                paint.setFakeBoldText(true);\n            }\n            baselineOffset = (oldSize - textsize) / 2f * Utils.FONT_HEIGHT_IN_LINE;\n        }\n\n        applyListItemStyle(paint);\n\n        // if we could force usage of #measure method then we might want skip this measuring here\n        // but this won't hold against new values that a TextView can receive (new text size for\n        // example...)\n        String drawText = number;\n        float numberWidth = paint.measureText(number);\n\n        // @since 1.0.3\n        float width = leadingMargin == null ? 0 : leadingMargin;\n        if (style != null && style.shape() != null) {\n            width = style.shape().size();\n        }\n        boolean isNumber = true;\n        if (numberWidth > width) {\n            // let's keep this logic here in case a user decided not to call #measure and is fine\n            // with current implementation\n            if (style == null || style.shape() == null) {\n                width = numberWidth;\n                margin = numberWidth;\n            } else {\n                isNumber = false;\n                drawText = \"...\";\n                numberWidth = (int) (paint.measureText(drawText) + .5F);\n            }\n        } else {\n            margin = 0;\n        }\n\n        float left;\n        if (style != null) {\n            left = x;\n        } else if (dir > 0) {\n            left = x + (width * dir);\n        } else {\n            left = x + (width * dir) + width;\n        }\n        if (drawIcon) {\n            left -= getIconSize() + ICON_SPACING;\n            c.save();\n            c.translate(left, baseline - iconOffset);\n            mDrawableWrapper.getDrawable().draw(c);\n            c.restore();\n            float numberOffset = (getIconSize() - numberWidth) / 2f;\n            left += numberOffset;\n        } else if (style != null && style.shape() != null && style.shape().type() == Shape.SHAPE_RECT) {\n            float fontTop = baseline - iconOffset;\n            float rectTop = fontTop + (getIconSize() - style.shape().size()) / 2f;\n            int oldColor = paint.getColor();\n            Paint.Style oldStyle = paint.getStyle();\n            paint.setStyle(Paint.Style.FILL);\n            paint.setColor(style.shape().color());\n            left += style.leading();\n            c.drawRoundRect(left, rectTop, left + style.shape().size(), rectTop + style.shape().size(), style.shape().radius(), style.shape().radius(), paint);\n            paint.setStyle(oldStyle);\n            paint.setColor(oldColor);\n            float numberOffset = (style.shape().size() - numberWidth) / 2f;\n            if (isNumber) {\n                numberOffset -= 1;\n            }\n            left += numberOffset;\n        } else if (style == null) {\n            left -= numberWidth;\n        } else if (style.isBold()) {\n            left += style.leading();\n            paint.setFakeBoldText(true);\n        }\n\n        int oldColor = paint.getColor();\n        if (style != null && style.orderFontColor() != 0) {\n            paint.setColor(style.orderFontColor());\n        }\n        // @since 1.1.1 we are using `baseline` argument to position text\n\n        c.drawText(drawText, left, baseline - baselineOffset, paint);\n        paint.setColor(oldColor);\n        paint.setTextSize(oldSize);\n        paint.setFakeBoldText(isBold);\n    }\n\n    @Override\n    protected String getImageUrl() {\n        if (style != null && style.shape() != null && style.shape().type() == Shape.SHAPE_ICON) {\n            return style.shape().icon();\n        }\n        return \"\";\n    }\n\n    @Override\n    protected void applyStyle(TextPaint paint) {\n        if (style == null || style.orderFontSize() == 0) {\n            this.paint.setTextSize(paint.getTextSize());\n        } else {\n            this.paint.setTextSize(style.orderFontSize());\n        }\n        if (style == null || style.orderFontColor() == 0) {\n            this.paint.setColor(paint.getColor());\n        } else {\n            this.paint.setColor(style.orderFontColor());\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/spans/StrongEmphasisSpan.java",
    "content": "package io.noties.markwon.core.spans;\n\nimport android.text.TextPaint;\nimport android.text.style.MetricAffectingSpan;\n\npublic class StrongEmphasisSpan extends MetricAffectingSpan {\n\n    @Override\n    public void updateMeasureState(TextPaint p) {\n        p.setFakeBoldText(true);\n    }\n\n    @Override\n    public void updateDrawState(TextPaint tp) {\n        tp.setFakeBoldText(true);\n    }\n}"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/spans/TextLayoutSpan.java",
    "content": "package io.noties.markwon.core.spans;\n\nimport android.text.Layout;\nimport android.text.Spannable;\nimport android.text.Spanned;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport java.lang.ref.WeakReference;\n\n/**\n * @since 4.4.0\n */\npublic class TextLayoutSpan {\n\n    /**\n     * @see #applyTo(Spannable, Layout)\n     */\n    @Nullable\n    public static Layout layoutOf(@NonNull CharSequence cs) {\n        if (cs instanceof Spanned) {\n            return layoutOf((Spanned) cs);\n        }\n        return null;\n    }\n\n    @Nullable\n    public static Layout layoutOf(@NonNull Spanned spanned) {\n        final TextLayoutSpan[] spans = spanned.getSpans(\n                0,\n                spanned.length(),\n                TextLayoutSpan.class\n        );\n        return spans != null && spans.length > 0\n                ? spans[0].layout()\n                : null;\n    }\n\n    public static void applyTo(@NonNull Spannable spannable, @NonNull Layout layout) {\n\n        // remove all current ones (only one should be present)\n        final TextLayoutSpan[] spans = spannable.getSpans(0, spannable.length(), TextLayoutSpan.class);\n        if (spans != null) {\n            for (TextLayoutSpan span : spans) {\n                spannable.removeSpan(span);\n            }\n        }\n\n        final TextLayoutSpan span = new TextLayoutSpan(layout);\n        spannable.setSpan(\n                span,\n                0,\n                spannable.length(),\n                Spanned.SPAN_INCLUSIVE_INCLUSIVE\n        );\n    }\n\n    private final WeakReference<Layout> reference;\n\n    @SuppressWarnings(\"WeakerAccess\")\n    TextLayoutSpan(@NonNull Layout layout) {\n        this.reference = new WeakReference<>(layout);\n    }\n\n    @Nullable\n    public Layout layout() {\n        return reference.get();\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/spans/TextViewSpan.java",
    "content": "package io.noties.markwon.core.spans;\n\nimport android.text.Spannable;\nimport android.text.Spanned;\nimport android.widget.TextView;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport java.lang.ref.WeakReference;\n\n/**\n * A special span that allows to obtain {@code TextView} in which spans are displayed\n *\n * @since 4.4.0\n */\npublic class TextViewSpan {\n\n    @Nullable\n    public static TextView textViewOf(@NonNull CharSequence cs) {\n        if (cs instanceof Spanned) {\n            return textViewOf((Spanned) cs);\n        }\n        return null;\n    }\n\n    @Nullable\n    public static TextView textViewOf(@NonNull Spanned spanned) {\n        final TextViewSpan[] spans = spanned.getSpans(0, spanned.length(), TextViewSpan.class);\n        return spans != null && spans.length > 0\n                ? spans[0].textView()\n                : null;\n    }\n\n    public static void applyTo(@NonNull Spannable spannable, @NonNull TextView textView) {\n\n        final TextViewSpan[] spans = spannable.getSpans(0, spannable.length(), TextViewSpan.class);\n        if (spans != null) {\n            for (TextViewSpan span : spans) {\n                spannable.removeSpan(span);\n            }\n        }\n\n        final TextViewSpan span = new TextViewSpan(textView);\n        // `SPAN_INCLUSIVE_INCLUSIVE` to persist in case of possible text change (deletion, etc)\n        spannable.setSpan(\n                span,\n                0,\n                spannable.length(),\n                Spanned.SPAN_INCLUSIVE_INCLUSIVE\n        );\n    }\n\n    private final WeakReference<TextView> reference;\n\n    public TextViewSpan(@NonNull TextView textView) {\n        this.reference = new WeakReference<>(textView);\n    }\n\n    @Nullable\n    public TextView textView() {\n        return reference.get();\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/core/spans/ThematicBreakSpan.java",
    "content": "package io.noties.markwon.core.spans;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.graphics.Rect;\nimport android.text.Layout;\nimport android.text.Spanned;\nimport android.text.style.LeadingMarginSpan;\nimport android.text.style.LineHeightSpan;\nimport android.widget.TextView;\n\nimport androidx.annotation.NonNull;\n\nimport com.fluid.afm.styles.HorizonRuleStyle;\n\nimport io.noties.markwon.core.MarkwonTheme;\n\npublic class ThematicBreakSpan implements LeadingMarginSpan, LineHeightSpan {\n\n    private final MarkwonTheme theme;\n    private final Rect rect = ObjectsPool.rect();\n    private final Paint paint = ObjectsPool.paint();\n    private HorizonRuleStyle mStyle;\n    private  float textViewMultiplier = 1.0f;\n\n    public ThematicBreakSpan(@NonNull MarkwonTheme theme) {\n        this.theme = theme;\n        mStyle = theme.getHorizonRule();\n    }\n\n    @Override\n    public int getLeadingMargin(boolean first) {\n        return 0;\n    }\n\n    @Override\n    public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline, int bottom, CharSequence text, int start, int end, boolean first, Layout layout) {\n        int lineTop;\n        if (mStyle.paragraph().paragraphSpacing() <= 0 && mStyle.paragraphSpacingBefore() <= 0) {\n            lineTop = top + ((bottom - top) / 2) - mStyle.getHeight() / 2;\n        } else if (mStyle.paragraphSpacingBefore() > 0) {\n            lineTop = (int) (top + mStyle.paragraphSpacingBefore() / textViewMultiplier);\n        } else {\n            lineTop = bottom - mStyle.paragraph().paragraphSpacing();\n        }\n\n        paint.set(p);\n        if (mStyle.getColor() == 0 || mStyle.getHeight() < 0) {\n            theme.applyThematicBreakStyle(paint);\n        } else {\n            mStyle.apply(paint);\n        }\n\n        final int height = (int) (paint.getStrokeWidth() + .5F);\n\n        final int left;\n        final int right;\n        if (dir > 0) {\n            left = x;\n            right = c.getWidth();\n        } else {\n            left = x - c.getWidth();\n            right = x;\n        }\n\n        rect.set(left, lineTop, right, lineTop + height);\n        c.drawRect(rect, paint);\n    }\n\n    @Override\n    public void chooseHeight(CharSequence text, int start, int end, int spanstartv, int lh, Paint.FontMetricsInt fm) {\n        if (mStyle != null && (mStyle.paragraph().paragraphSpacing() > 0 || mStyle.paragraphSpacingBefore() > 0 || mStyle.getHeight() > 3) && selfStart(start, text, this)) {\n            int lineHeight = (fm.descent - fm.ascent);\n            int targetHeight = mStyle.paragraph().paragraphSpacing() + mStyle.paragraphSpacingBefore() + mStyle.getHeight();\n            if (text instanceof Spanned) {\n                final Spanned spanned = (Spanned) text;\n                final TextView textView = TextViewSpan.textViewOf(spanned);\n                if (textView != null) {\n                    float multiplier = textView.getLineSpacingMultiplier();\n                    if (multiplier > 0) {\n                        targetHeight = (int) (targetHeight / multiplier);\n                        textViewMultiplier = multiplier;\n                    }\n                }\n            }\n            final float ratio = targetHeight * 1.0f / lineHeight;\n            fm.descent = Math.round(fm.descent * ratio);\n            fm.ascent = fm.descent - targetHeight;\n        }\n    }\n\n    private static boolean selfStart(int start, CharSequence text, Object span) {\n        final int spanStart = ((Spanned) text).getSpanStart(span);\n        return spanStart == start;\n    }\n\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/image/AsyncDrawable.java",
    "content": "package io.noties.markwon.image;\n\nimport android.graphics.Canvas;\nimport android.graphics.ColorFilter;\nimport android.graphics.PixelFormat;\nimport android.graphics.Rect;\nimport android.graphics.drawable.Animatable;\nimport android.graphics.drawable.Drawable;\nimport android.text.TextUtils;\nimport android.util.Log;\n\nimport androidx.annotation.IntRange;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\npublic class AsyncDrawable extends Drawable {\n\n    public static final String TAG = \"MD_AsyncDrawable\";\n    private final String destination;\n    private final AsyncDrawableLoader loader;\n    private final ImageSize imageSize;\n    private final ImageSizeResolver imageSizeResolver;\n\n    // @since 4.5.0\n    private final Drawable placeholder;\n\n    private Drawable result;\n    private Callback callback;\n\n    public static int lastCanvasWidth;\n    private int canvasWidth;\n    private float textSize;\n\n    // @since 2.0.1 for use-cases when image is loaded faster than span is drawn and knows canvas width\n    private boolean waitingForDimensions;\n\n    // @since 4.5.0 in case if result is Animatable and this drawable was detached, we\n    //  keep the state to resume when we are going to be attached again (when used in RecyclerView)\n    private boolean wasPlayingBefore = false;\n\n    /**\n     * @since 1.0.1\n     */\n    public AsyncDrawable(\n                         @NonNull String destination,\n                         @NonNull AsyncDrawableLoader loader,\n                         @NonNull ImageSizeResolver imageSizeResolver,\n                         @Nullable ImageSize imageSize\n    ) {\n\n        this.destination = destination;\n        this.loader = loader;\n        this.imageSizeResolver = imageSizeResolver;\n        this.imageSize = imageSize;\n\n        Log.d(TAG,\"AsyncDrawable destination = \" + destination);\n        final Drawable placeholder = this.placeholder = loader.placeholder(this);\n        if (placeholder != null) {\n            Log.d(TAG,\"setPlaceholderResult\");\n            setPlaceholderResult(placeholder);\n        }\n    }\n\n    @NonNull\n    public String getDestination() {\n        return destination;\n    }\n\n    public Drawable getPlaceholder(){\n        return placeholder;\n    }\n\n    /**\n     * @since 4.0.0\n     */\n    @SuppressWarnings(\"WeakerAccess\")\n    @Nullable\n    public ImageSize getImageSize() {\n        return imageSize;\n    }\n\n    /**\n     * @since 4.0.0\n     */\n    @SuppressWarnings(\"unused\")\n    @NonNull\n    public ImageSizeResolver getImageSizeResolver() {\n        return imageSizeResolver;\n    }\n\n    /**\n     * @since 4.2.1\n     */\n    @SuppressWarnings({\"unused\", \"WeakerAccess\"})\n    public boolean hasKnownDimensions() {\n        return canvasWidth > 0;\n    }\n\n    /**\n     * @see #hasKnownDimensions()\n     * @since 4.0.0\n     */\n    public int getLastKnownCanvasWidth() {\n        return canvasWidth;\n    }\n\n    /**\n     * @see #hasKnownDimensions()\n     * @since 4.0.0\n     */\n    @SuppressWarnings(\"WeakerAccess\")\n    public float getLastKnowTextSize() {\n        return textSize;\n    }\n\n    public Drawable getResult() {\n        return result;\n    }\n\n    public boolean hasResult() {\n        return result != null;\n    }\n\n    public boolean isAttached() {\n        return getCallback() != null;\n    }\n\n    public void setCallback2(@Nullable Callback cb) {\n\n        Log.d(TAG,\"setCallback2 cb = \" + cb);\n\n        if(cb == null){\n            return;\n        }\n        // @since 4.2.1\n        //  wrap callback so invalidation happens to this AsyncDrawable instance\n        //  and not for wrapped result/placeholder\n        this.callback = cb == null\n                ? null\n                : new WrappedCallback(cb);\n\n        super.setCallback(cb);\n\n        // if not null -> means we are attached\n        if (callback != null) {\n\n            // as we have a placeholder now, it's important to check it our placeholder\n            // has a proper callback at this point. This is not required in most cases,\n            // as placeholder should be static, but if it's not -> it can operate as usual\n            if (result != null\n                    && result.getCallback() == null) {\n                result.setCallback(callback);\n            }\n\n            // @since 4.5.0 we trigger loading only if we have no result (and result is not placeholder)\n            final boolean shouldLoad = result == null || result == placeholder || TextUtils.isEmpty(destination);\n\n            Log.d(TAG,\"shouldLoad = \" + shouldLoad);\n            if (result != null) {\n                result.setCallback(callback);\n\n                // @since 4.5.0\n                if (result instanceof Animatable && wasPlayingBefore) {\n                    ((Animatable) result).start();\n                }\n            }\n\n            if (shouldLoad) {\n                Log.d(TAG,\"load here\");\n                loader.load(this);\n            }else {\n                Log.d(TAG,\"has loaded\");\n            }\n        } else {\n            Log.d(TAG,\"loader.cancel(this);\");\n\n            return;\n//            if (result != null) {\n//\n//                result.setCallback(null);\n//\n//                // let's additionally stop if it Animatable\n//                if (result instanceof Animatable) {\n//                    final Animatable animatable = (Animatable) result;\n//                    final boolean isPlaying = wasPlayingBefore = animatable.isRunning();\n//                    if (isPlaying) {\n//                        animatable.stop();\n//                    }\n//                }\n//            }\n//            loader.cancel(this);\n        }\n    }\n\n    /**\n     * @since 3.0.1\n     */\n    @SuppressWarnings(\"WeakerAccess\")\n    protected void setPlaceholderResult(@NonNull Drawable placeholder) {\n        Log.d(TAG,\"setPlaceholderResult waitingForDimensions = \" + waitingForDimensions);\n        // okay, if placeholder has bounds -> use it, otherwise use original imageSize\n        // it's important to NOT pass to imageSizeResolver when placeholder has bounds\n        // this is done, so actual result and placeholder can have _different_\n        // bounds. Assume image is loaded with HTML and has ImageSize width=100%,\n        // so, even if placeholder has exact bounds, it will still be scaled up.\n\n        // this condition should not be true for placeholder (at least for now)\n        // (right now this method is always called from constructor)\n        if (result != null) {\n            // but it is, unregister current result\n            result.setCallback(null);\n        }\n\n        final Rect rect = placeholder.getBounds();\n\n        if (rect.isEmpty()) {\n            // check for intrinsic bounds\n            final Rect intrinsic = DrawableUtils.intrinsicBounds(placeholder);\n            if (intrinsic.isEmpty()) {\n                // @since 4.2.2\n                // if intrinsic bounds are empty, use _any_ non-empty bounds,\n                // they must be non-empty so when result is obtained - proper invalidation will occur\n                // (0, 0, 1, 0) is still considered empty\n                placeholder.setBounds(0, 0, 1, 1);\n            } else {\n                // use them\n                placeholder.setBounds(intrinsic);\n            }\n\n            // it is very important (if we have a placeholder) to set own bounds to it (and they must not be empty\n            // otherwise result won't be rendered)\n            // @since 4.2.2\n            setBounds(placeholder.getBounds());\n            setResult(placeholder);\n\n        } else {\n\n            Log.d(TAG,\"set result as placeholder\");\n            // this method is not the same as above, as we do not want to trigger image-size-resolver\n            // in case when placeholder has exact bounds\n\n            // placeholder has bounds specified -> use them until we have real result\n            this.result = placeholder;\n            this.result.setCallback(callback);\n\n            // use bounds directly\n            setBounds(rect);\n\n            // just in case -> so we do not update placeholder when we have canvas dimensions\n            waitingForDimensions = false;\n        }\n    }\n\n    public void setResult(@NonNull Drawable result) {\n\n        Log.d(TAG,\"set setResult\");\n        // @since 4.5.0 revert this flag when we have new source\n        wasPlayingBefore = false;\n\n        // if we have previous one, detach it\n        if (this.result != null) {\n            this.result.setCallback(null);\n        }\n\n        this.result = result;\n//        this.result.setCallback(callback);\n\n        initBounds();\n    }\n\n    /**\n     * Remove result from this drawable (for example, in case of cancellation)\n     *\n     * @since 3.0.1\n     */\n    public void clearResult() {\n\n        final Drawable result = this.result;\n\n        if (result != null) {\n            result.setCallback(null);\n            this.result = null;\n\n            // clear bounds\n            setBounds(0, 0, 0, 0);\n        }\n    }\n\n    private void initBounds() {\n\n        Log.d(TAG,\"initBounds canvasWidth = \" + canvasWidth);\n        if (canvasWidth == 0 && lastCanvasWidth == 0) {\n            Log.d(TAG,\"initBounds canvasWidth 0\");\n            // we still have no bounds - wait for them\n            waitingForDimensions = true;\n            // we cannot have empty bounds - otherwise in case if text contains\n            //  a single AsyncDrawableSpan, it won't be displayed\n            setBounds(noDimensionsBounds(result));\n            return;\n        }\n\n        if(canvasWidth == 0 && lastCanvasWidth != 0){\n            canvasWidth = lastCanvasWidth;\n        }\n\n        waitingForDimensions = false;\n\n        final Rect bounds = resolveBounds();\n        Log.d(TAG,\"initBounds bounds = \" + bounds);\n        result.setBounds(bounds);\n        // @since 4.2.1, we set callback after bounds are resolved\n        //  to reduce number of invalidations\n        result.setCallback(callback);\n\n        // so, this method will check if there is previous bounds and call invalidate _BEFORE_\n        //  applying new bounds. This is why it is important to have initial bounds empty.\n        setBounds(bounds);\n\n        invalidateSelf();\n        lastCanvasWidth = canvasWidth;\n    }\n\n    /**\n     * @since 4.3.0\n     */\n    @NonNull\n    private static Rect noDimensionsBounds(@Nullable Drawable result) {\n        Log.d(TAG,\"noDimensionsBounds\");\n        if (result != null) {\n            Log.d(TAG,\"result exist\");\n            final Rect bounds = result.getBounds();\n            if (!bounds.isEmpty()) {\n                Log.d(TAG,\"bounds exist \");\n                return bounds;\n            }\n            final Rect intrinsicBounds = DrawableUtils.intrinsicBounds(result);\n            if (!intrinsicBounds.isEmpty()) {\n                Log.d(TAG,\"intrinsicBounds exist\");\n                return intrinsicBounds;\n            }\n        }\n        Log.d(TAG,\"return 0 0 1 1\");\n        return new Rect(0, 0, 1, 1);\n    }\n\n    /**\n     * @since 1.0.1\n     */\n    @SuppressWarnings(\"WeakerAccess\")\n    public void initWithKnownDimensions(int width, float textSize) {\n        Log.d(TAG,\"initWithKnownDimensions\");\n        this.canvasWidth = width;\n        this.textSize = textSize;\n\n        if (waitingForDimensions) {\n            initBounds();\n        }\n    }\n\n    @Override\n    public void draw(@NonNull Canvas canvas) {\n        if (hasResult()) {\n            result.draw(canvas);\n        }\n    }\n\n    @Override\n    public void setAlpha(@IntRange(from = 0, to = 255) int alpha) {\n\n    }\n\n    @Override\n    public void setColorFilter(@Nullable ColorFilter colorFilter) {\n\n    }\n\n    @Override\n    public int getOpacity() {\n        final int opacity;\n        if (hasResult()) {\n            opacity = result.getOpacity();\n        } else {\n            opacity = PixelFormat.TRANSPARENT;\n        }\n        return opacity;\n    }\n\n    @Override\n    public int getIntrinsicWidth() {\n        final int out;\n        if (hasResult()) {\n            out = result.getIntrinsicWidth();\n        } else {\n            // @since 4.0.0, must not be zero in order to receive canvas dimensions\n            out = 1;\n        }\n        return out;\n    }\n\n    @Override\n    public int getIntrinsicHeight() {\n        final int out;\n        if (hasResult()) {\n            out = result.getIntrinsicHeight();\n        } else {\n            // @since 4.0.0, must not be zero in order to receive canvas dimensions\n            out = 1;\n        }\n        return out;\n    }\n\n    /**\n     * @since 1.0.1\n     */\n    @NonNull\n    private Rect resolveBounds() {\n        Log.d(TAG,\"resolveBounds \");\n        // @since 2.0.0 previously we were checking if image is greater than canvas width here\n        //          but as imageSizeResolver won't be null anymore, we should transfer this logic\n        //          there\n        return imageSizeResolver.resolveImageSize(this);\n    }\n\n    @NonNull\n    @Override\n    public String toString() {\n        return \"AsyncDrawable{\" +\n                \"destination='\" + destination + '\\'' +\n                \", imageSize=\" + imageSize +\n                \", result=\" + result +\n                \", canvasWidth=\" + canvasWidth +\n                \", textSize=\" + textSize +\n                \", waitingForDimensions=\" + waitingForDimensions +\n                '}';\n    }\n\n    // @since 4.2.1\n    //  Wrapped callback to trigger invalidation for this AsyncDrawable instance (and not result/placeholder)\n    private class WrappedCallback implements Callback {\n\n        private final Callback callback;\n\n        WrappedCallback(@NonNull Callback callback) {\n            this.callback = callback;\n        }\n\n        @Override\n        public void invalidateDrawable(@NonNull Drawable who) {\n            callback.invalidateDrawable(AsyncDrawable.this);\n        }\n\n        @Override\n        public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) {\n            callback.scheduleDrawable(AsyncDrawable.this, what, when);\n        }\n\n        @Override\n        public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) {\n            callback.unscheduleDrawable(AsyncDrawable.this, what);\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/image/AsyncDrawableLoader.java",
    "content": "package io.noties.markwon.image;\n\nimport android.graphics.drawable.Drawable;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\npublic abstract class AsyncDrawableLoader {\n\n    /**\n     * @since 3.0.0\n     */\n    @NonNull\n    public static AsyncDrawableLoader noOp() {\n        return new AsyncDrawableLoaderNoOp();\n    }\n\n    /**\n     * @since 4.0.0\n     */\n    public abstract void load(@NonNull AsyncDrawable drawable);\n\n    /**\n     * @since 4.0.0\n     */\n    public abstract void cancel(@NonNull AsyncDrawable drawable);\n\n    @Nullable\n    public abstract Drawable placeholder(@NonNull AsyncDrawable drawable);\n\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/image/AsyncDrawableLoaderNoOp.java",
    "content": "package io.noties.markwon.image;\n\nimport android.graphics.drawable.Drawable;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nclass AsyncDrawableLoaderNoOp extends AsyncDrawableLoader {\n    @Override\n    public void load(@NonNull AsyncDrawable drawable) {\n\n    }\n\n    @Override\n    public void cancel(@NonNull AsyncDrawable drawable) {\n\n    }\n\n    @Nullable\n    @Override\n    public Drawable placeholder(@NonNull AsyncDrawable drawable) {\n        return null;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/image/AsyncDrawableScheduler.java",
    "content": "package io.noties.markwon.image;\n\nimport android.graphics.Rect;\nimport android.graphics.drawable.Drawable;\nimport android.os.Looper;\nimport android.os.SystemClock;\nimport android.text.Spanned;\nimport android.view.View;\nimport android.widget.TextView;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport io.noties.markwon.R;\n\npublic abstract class AsyncDrawableScheduler {\n\n    public static void schedule(@NonNull final TextView textView) {\n\n        // we need a simple check if current text has already scheduled drawables\n        // we need this in order to allow multiple calls to schedule (different plugins\n        // might use AsyncDrawable), but we do not want to repeat the task\n        //\n        // hm... we need the same thing for unschedule then... we can check if last hash is !null,\n        // if it's not -> unschedule, else ignore\n\n        // @since 4.0.0\n        final Integer lastTextHashCode =\n                (Integer) textView.getTag(R.id.markwon_drawables_scheduler_last_text_hashcode);\n        final int textHashCode = textView.getText().hashCode();\n        if (lastTextHashCode != null\n                && lastTextHashCode == textHashCode) {\n            return;\n        }\n        textView.setTag(R.id.markwon_drawables_scheduler_last_text_hashcode, textHashCode);\n\n\n        final AsyncDrawableSpan[] spans = extractSpans(textView);\n        if (spans != null\n                && spans.length > 0) {\n\n            if (textView.getTag(R.id.markwon_drawables_scheduler) == null) {\n                final View.OnAttachStateChangeListener listener = new View.OnAttachStateChangeListener() {\n                    @Override\n                    public void onViewAttachedToWindow(View v) {\n\n                    }\n\n                    @Override\n                    public void onViewDetachedFromWindow(View v) {\n                        unschedule(textView);\n                        v.removeOnAttachStateChangeListener(this);\n                        v.setTag(R.id.markwon_drawables_scheduler, null);\n                    }\n                };\n                textView.addOnAttachStateChangeListener(listener);\n                textView.setTag(R.id.markwon_drawables_scheduler, listener);\n            }\n\n            // @since 4.1.0\n            final DrawableCallbackImpl.Invalidator invalidator = new TextViewInvalidator(textView);\n\n            AsyncDrawable drawable;\n\n            for (AsyncDrawableSpan span : spans) {\n                drawable = span.getDrawable();\n                drawable.setCallback2(new DrawableCallbackImpl(textView, invalidator, drawable.getBounds()));\n            }\n        }\n    }\n\n    // must be called when text manually changed in TextView\n    public static void unschedule(@NonNull TextView view) {\n\n        // @since 4.0.0\n        if (view.getTag(R.id.markwon_drawables_scheduler_last_text_hashcode) == null) {\n            return;\n        }\n        view.setTag(R.id.markwon_drawables_scheduler_last_text_hashcode, null);\n\n\n        final AsyncDrawableSpan[] spans = extractSpans(view);\n        if (spans != null\n                && spans.length > 0) {\n            for (AsyncDrawableSpan span : spans) {\n                span.getDrawable().setCallback2(null);\n            }\n        }\n    }\n\n    @Nullable\n    private static AsyncDrawableSpan[] extractSpans(@NonNull TextView textView) {\n\n        final CharSequence cs = textView.getText();\n        final int length = cs != null\n                ? cs.length()\n                : 0;\n\n        if (length == 0\n                || !(cs instanceof Spanned)) {\n            return null;\n        }\n\n        // we also could've tried the `nextSpanTransition`, but strangely it leads to worse performance\n        // than direct getSpans\n\n        return ((Spanned) cs).getSpans(0, length, AsyncDrawableSpan.class);\n    }\n\n    private AsyncDrawableScheduler() {\n    }\n\n    private static class DrawableCallbackImpl implements Drawable.Callback {\n\n        // @since 4.1.0\n        // interface to be used when bounds change and view must be invalidated\n        interface Invalidator {\n            void invalidate();\n        }\n\n        private final TextView view;\n        private final Invalidator invalidator; // @since 4.1.0\n\n        private Rect previousBounds;\n\n        DrawableCallbackImpl(\n                @NonNull TextView view,\n                @NonNull Invalidator invalidator,\n                Rect initialBounds) {\n            this.view = view;\n            this.invalidator = invalidator;\n            this.previousBounds = new Rect(initialBounds);\n        }\n\n        @Override\n        public void invalidateDrawable(@NonNull final Drawable who) {\n\n            if (Looper.myLooper() != Looper.getMainLooper()) {\n                view.post(new Runnable() {\n                    @Override\n                    public void run() {\n                        invalidateDrawable(who);\n                    }\n                });\n                return;\n            }\n\n            final Rect rect = who.getBounds();\n\n            // okay... the thing is IF we do not change bounds size, normal invalidate would do\n            // but if the size has changed, then we need to update the whole layout...\n\n            if (!previousBounds.equals(rect)) {\n                // @since 4.1.0\n                // invalidation moved to upper level (so invalidation can be deferred,\n                // and multiple calls combined)\n                invalidator.invalidate();\n                previousBounds = new Rect(rect);\n            } else {\n\n                view.postInvalidate();\n            }\n        }\n\n        @Override\n        public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) {\n            final long delay = when - SystemClock.uptimeMillis();\n            view.postDelayed(what, delay);\n        }\n\n        @Override\n        public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) {\n            view.removeCallbacks(what);\n        }\n    }\n\n    private static class TextViewInvalidator implements DrawableCallbackImpl.Invalidator, Runnable {\n\n        private final TextView textView;\n\n        TextViewInvalidator(@NonNull TextView textView) {\n            this.textView = textView;\n        }\n\n        @Override\n        public void invalidate() {\n            textView.removeCallbacks(this);\n            textView.post(this);\n        }\n\n        @Override\n        public void run() {\n            textView.setText(textView.getText());\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/image/AsyncDrawableSpan.java",
    "content": "\npackage io.noties.markwon.image;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.graphics.Rect;\nimport android.text.Spanned;\nimport android.text.style.LineHeightSpan;\nimport android.text.style.ReplacementSpan;\nimport android.util.Log;\nimport android.widget.TextView;\n\nimport androidx.annotation.IntDef;\nimport androidx.annotation.IntRange;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\n\nimport io.noties.markwon.core.MarkwonTheme;\n\nimport com.fluid.afm.func.IImageClickCallback;\nimport com.fluid.afm.span.IClickableSpan;\nimport io.noties.markwon.core.spans.TextViewSpan;\nimport io.noties.markwon.utils.SpanUtils;\n\n@SuppressWarnings(\"WeakerAccess\")\npublic class AsyncDrawableSpan extends ReplacementSpan implements LineHeightSpan, IClickableSpan {\n\n    @Override\n    public String getLiteral() {\n        return IClickableSpan.super.getLiteral();\n    }\n\n    @IntDef({ALIGN_BOTTOM, ALIGN_BASELINE, ALIGN_CENTER, ALIGN_TEXT_BOTTOM})\n    @Retention(RetentionPolicy.SOURCE)\n    @interface Alignment {\n    }\n\n    public static final String TAG = \"AsyncDrawableSpan\";\n    public static final int ALIGN_BOTTOM = 0;\n    public static final int ALIGN_BASELINE = 1;\n    public static final int ALIGN_CENTER = 2; // will only center if drawable height is less than text line height\n    public static final int ALIGN_TEXT_BOTTOM = 3;\n\n    private final MarkwonTheme theme;\n    private final AsyncDrawable drawable;\n    private final int alignment;\n    private final boolean replacementTextIsLink;\n    private int mTop;\n    private int mBottom;\n    private boolean clickable = true;\n    private IImageClickCallback mClickCallback;\n    private String imageDescription;\n    public AsyncDrawableSpan(\n            @NonNull MarkwonTheme theme,\n            @NonNull AsyncDrawable drawable,\n            @Alignment int alignment,\n            boolean replacementTextIsLink,\n            IImageClickCallback clickCallback) {\n        this.theme = theme;\n        this.drawable = drawable;\n        this.alignment = alignment;\n        this.replacementTextIsLink = replacementTextIsLink;\n        mClickCallback = clickCallback;\n        Log.d(TAG, \"this.replacementTextIsLink = \" + this.replacementTextIsLink);\n        // @since 4.2.1 we do not set intrinsic bounds\n        //  at this point they will always be 0,0-1,1, but this\n        //  will trigger another invalidation when we will have bounds\n    }\n\n    public AsyncDrawableSpan(\n            @NonNull MarkwonTheme theme,\n            @NonNull AsyncDrawable drawable,\n            @Alignment int alignment,\n            boolean replacementTextIsLink, boolean clickable) {\n        this.theme = theme;\n        this.drawable = drawable;\n        this.alignment = alignment;\n        this.replacementTextIsLink = replacementTextIsLink;\n        this.clickable = clickable;\n        Log.d(TAG, \"this.replacementTextIsLink = \" + this.replacementTextIsLink);\n        // @since 4.2.1 we do not set intrinsic bounds\n        //  at this point they will always be 0,0-1,1, but this\n        //  will trigger another invalidation when we will have bounds\n    }\n\n    @Override\n    public String getUrl() {\n        return clickable && drawable != null ? drawable.getDestination() : \"\";\n    }\n\n    @Override\n    public String getType() {\n        return clickable ? \"image\" : \"\";\n    }\n\n    @Override\n    public int getTop() {\n        return mTop;\n    }\n\n    @Override\n    public int getBottom() {\n        return mBottom;\n    }\n\n    public void click() {\n        if (clickable && mClickCallback != null) {\n            mClickCallback.imageClicked(drawable.getDestination(), imageDescription);\n        }\n    }\n\n    public boolean isClickable() {\n        return clickable;\n    }\n\n    @Override\n    public int getSize(\n            @NonNull Paint paint,\n            CharSequence text,\n            @IntRange(from = 0) int start,\n            @IntRange(from = 0) int end,\n            @Nullable Paint.FontMetricsInt fm) {\n\n        // if we have no async drawable result - we will just render text\n        final int size;\n        if (drawable.hasResult()) {\n\n            final Rect rect = drawable.getBounds();\n\n            if (fm != null) {\n                fm.ascent = -rect.bottom;\n                fm.descent = 0;\n\n                fm.top = fm.ascent;\n                fm.bottom = 0;\n            }\n\n            size = rect.right;\n\n        } else {\n\n            // we will apply style here in case if theme modifies textSize or style (affects metrics)\n            if (replacementTextIsLink) {\n                theme.applyLinkStyle(paint);\n            }\n\n            // NB, no specific text handling (no new lines, etc)\n            size = (int) (paint.measureText(text, start, end) + .5F);\n        }\n\n        return size;\n    }\n\n    @Override\n    public void chooseHeight(CharSequence text, int start, int end, int spanstartv, int lineHeight, Paint.FontMetricsInt fm) {\n        if (fm == null) {\n            return;\n        }\n        if (!drawable.hasResult()) {\n            return;\n        }\n        if (!SpanUtils.isSelf(start, end, text, this)) {\n            return;\n        }\n        int drawableLineHeight = drawable.getBounds().height() + theme.getParagraphBreakHeight();\n        if (text instanceof Spanned) {\n            final Spanned spanned = (Spanned) text;\n            final TextView textView = TextViewSpan.textViewOf(spanned);\n            if (textView != null) {\n                float multiplier = textView.getLineSpacingMultiplier();\n                if (multiplier > 0) {\n                    drawableLineHeight = (int) (drawableLineHeight / multiplier);\n                }\n            }\n        }\n        final int originHeight = fm.descent - fm.ascent;\n        if (originHeight <= 0) {\n            return;\n        }\n        final float ratio = drawableLineHeight * 1.0f / originHeight;\n        fm.descent = Math.round(fm.descent * ratio);\n        fm.ascent = fm.descent - drawableLineHeight;\n    }\n\n    @Override\n    public void draw(\n            @NonNull Canvas canvas,\n            CharSequence text,\n            @IntRange(from = 0) int start,\n            @IntRange(from = 0) int end,\n            float x,\n            int top,\n            int y,\n            int bottom,\n            @NonNull Paint paint) {\n\n        // @since 4.4.0 use SpanUtils instead of `canvas.getWidth`\n        drawable.initWithKnownDimensions(\n                SpanUtils.width(canvas, text),\n                paint.getTextSize()\n        );\n\n        final AsyncDrawable drawable = this.drawable;\n\n        if (drawable.hasResult()) {\n\n            final int b = bottom - drawable.getBounds().bottom;\n            final int save = canvas.save();\n            try {\n                int translationY;\n                if (ALIGN_CENTER == alignment) {\n                    translationY = (top - paint.getFontMetricsInt().bottom * 2) + ((paint.getFontMetricsInt().bottom * 4 + bottom - top - drawable.getBounds().height()) / 2);\n                } else if (ALIGN_BASELINE == alignment) {\n                    translationY = b - paint.getFontMetricsInt().bottom;\n                } else if (ALIGN_TEXT_BOTTOM == alignment) {\n                    final int textHeight = paint.getFontMetricsInt().bottom - paint.getFontMetricsInt().top;\n                    final int lineHeight = bottom - top;\n                    final int paddingBottom = lineHeight - textHeight;\n                    final int calibrate = 5;\n                    translationY = b - paddingBottom + calibrate;\n                } else {\n                    translationY = b;\n                }\n                canvas.translate(x, translationY);\n                drawable.draw(canvas);\n                mTop = translationY;\n                mBottom = translationY + drawable.getBounds().height();\n            } finally {\n                canvas.restoreToCount(save);\n            }\n        } else {\n            // will it make sense to have additional background/borders for an image replacement?\n            // let's focus on main functionality and then think of it\n\n            final float textY = textCenterY(top, bottom, paint);\n            if (replacementTextIsLink) {\n                theme.applyLinkStyle(paint);\n            }\n\n            // NB, no specific text handling (no new lines, etc)\n            canvas.drawText(text, start, end, x, textY, paint);\n        }\n        imageDescription = text.subSequence(start, end).toString();\n    }\n\n    @NonNull\n    public AsyncDrawable getDrawable() {\n        return drawable;\n    }\n\n    private static float textCenterY(int top, int bottom, @NonNull Paint paint) {\n        // @since 1.1.1 it's `top +` and not `bottom -`\n        return (int) (top + ((bottom - top) / 2) - ((paint.descent() + paint.ascent()) / 2.F + .5F));\n    }\n}"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/image/DrawableUtils.java",
    "content": "package io.noties.markwon.image;\n\nimport android.graphics.Rect;\nimport android.graphics.drawable.Drawable;\n\nimport androidx.annotation.CheckResult;\nimport androidx.annotation.NonNull;\n\n/**\n * @since 3.0.1\n */\npublic abstract class DrawableUtils {\n\n    @NonNull\n    @CheckResult\n    public static Rect intrinsicBounds(@NonNull Drawable drawable) {\n        return new Rect(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());\n    }\n\n    public static void applyIntrinsicBounds(@NonNull Drawable drawable) {\n        drawable.setBounds(intrinsicBounds(drawable));\n    }\n\n    public static void applyIntrinsicBoundsIfEmpty(@NonNull Drawable drawable) {\n        if (drawable.getBounds().isEmpty()) {\n            drawable.setBounds(intrinsicBounds(drawable));\n        }\n    }\n\n    private DrawableUtils() {\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/image/ImageProps.java",
    "content": "package io.noties.markwon.image;\n\nimport io.noties.markwon.Prop;\n\n/**\n * @since 3.0.0\n */\npublic abstract class ImageProps {\n\n    public static final Prop<String> DESTINATION = Prop.of(\"image-destination\");\n\n    public static final Prop<Boolean> REPLACEMENT_TEXT_IS_LINK =\n            Prop.of(\"image-replacement-text-is-link\");\n\n    public static final Prop<ImageSize> IMAGE_SIZE = Prop.of(\"image-size\");\n\n\n    private ImageProps() {\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/image/ImageSize.java",
    "content": "package io.noties.markwon.image;\n\nimport androidx.annotation.Nullable;\n\n/**\n * @since 1.0.1\n */\n@SuppressWarnings(\"WeakerAccess\")\npublic class ImageSize {\n\n    public static class Dimension {\n\n        public final float value;\n        public final String unit;\n\n        public Dimension(float value, @Nullable String unit) {\n            this.value = value;\n            this.unit = unit;\n        }\n\n        @Override\n        public String toString() {\n            return \"Dimension{\" +\n                    \"value=\" + value +\n                    \", unit='\" + unit + '\\'' +\n                    '}';\n        }\n    }\n\n    public final Dimension width;\n    public final Dimension height;\n\n    public ImageSize(@Nullable Dimension width, @Nullable Dimension height) {\n        this.width = width;\n        this.height = height;\n    }\n\n    @Override\n    public String toString() {\n        return \"ImageSize{\" +\n                \"width=\" + width +\n                \", height=\" + height +\n                '}';\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/image/ImageSizeResolver.java",
    "content": "package io.noties.markwon.image;\n\nimport android.graphics.Rect;\n\nimport androidx.annotation.NonNull;\n\n/**\n * @see ImageSizeResolverDef\n * @see io.noties.markwon.MarkwonConfiguration.Builder#imageSizeResolver(ImageSizeResolver)\n * @since 1.0.1\n */\npublic abstract class ImageSizeResolver {\n\n    /**\n     * @since 4.0.0\n     */\n    @NonNull\n    public abstract Rect resolveImageSize(@NonNull AsyncDrawable drawable);\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/image/ImageSizeResolverDef.java",
    "content": "package io.noties.markwon.image;\n\nimport android.content.Context;\nimport android.graphics.Rect;\nimport android.util.Log;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\n/**\n * @since 1.0.1\n */\n@SuppressWarnings({\"WeakerAccess\", \"unused\"})\npublic class ImageSizeResolverDef extends ImageSizeResolver {\n\n    public static final String TAG = \"MD_ImageSizeResolverDef\";\n\n    // we track these two, others are considered to be pixels\n    protected static final String UNIT_PERCENT = \"%\";\n    protected static final String UNIT_EM = \"em\";\n    public static final String UNIT_RPX = \"rpx\";\n    public static final String UNIT_PX = \"px\";\n\n    @NonNull\n    @Override\n    public Rect resolveImageSize(@NonNull AsyncDrawable drawable) {\n        Log.d(TAG,\"resolveImageSize \");\n        return resolveImageSize(drawable,\n                drawable.getImageSize(),\n                drawable.getResult().getBounds(),\n                drawable.getLastKnownCanvasWidth(),\n                drawable.getLastKnowTextSize());\n    }\n\n    @NonNull\n    protected Rect resolveImageSize(\n            @NonNull AsyncDrawable drawable,\n            @Nullable ImageSize imageSize,\n            @NonNull Rect imageBounds,\n            int canvasWidth,\n            float textSize\n    ) {\n\n        if (imageSize == null) {\n            // @since 2.0.0 post process bounds to fit canvasWidth (previously was inside AsyncDrawable)\n            //      must be applied only if imageSize is null\n            final Rect rect;\n            int w = imageBounds.width();\n            int h = imageBounds.height();\n            int designedWidth = 638;\n            int designedHeight = 360;\n            float dpRatio = ((float)canvasWidth * 2)/designedWidth;\n            if((h < w)  && (canvasWidth > 0)) {\n                float widthRatio = ((float) canvasWidth)/w;\n                w = canvasWidth;\n                h = (int)(widthRatio*h);\n                int standardHeight = (int) ((designedHeight/2)*dpRatio);\n                if(h>standardHeight){\n                    h = standardHeight;\n                }\n            }else if((w <= h) && (canvasWidth > 0)){\n                h = (int) ((designedHeight / 2 ) * dpRatio);\n                w = (int) ((((float)h) /(imageBounds.height())) * w);\n            }\n            imageBounds = new Rect(0,0,w,h);\n            if (w > canvasWidth) {\n                final float reduceRatio = (float) w / canvasWidth;\n                rect = new Rect(\n                        0,\n                        0,\n                        canvasWidth,\n                        (int) (imageBounds.height() / reduceRatio + .5F)\n                );\n            } else {\n                rect = imageBounds;\n            }\n            return rect;\n        }\n\n        final Rect rect;\n\n        final ImageSize.Dimension width = imageSize.width;\n        final ImageSize.Dimension height = imageSize.height;\n\n        final int imageWidth = imageBounds.width();\n        final int imageHeight = imageBounds.height();\n\n        final float ratio = (float) imageWidth / imageHeight;\n\n        if (width != null) {\n\n            final int w;\n            final int h;\n\n            if (UNIT_PERCENT.equals(width.unit)) {\n                w = (int) (canvasWidth * (width.value / 100.F) + .5F);\n            } else {\n                w = resolveAbsolute(width, imageWidth, textSize);\n            }\n\n            if (height == null\n                    || UNIT_PERCENT.equals(height.unit)) {\n                h = (int) (w / ratio + .5F);\n            } else {\n                h = resolveAbsolute(height, imageHeight, textSize);\n            }\n\n            rect = new Rect(0, 0, w, h);\n\n        } else if (height != null) {\n\n            if (!UNIT_PERCENT.equals(height.unit)) {\n                final int h = resolveAbsolute(height, imageHeight, textSize);\n                final int w = (int) (h * ratio + .5F);\n                rect = new Rect(0, 0, w, h);\n            } else {\n                rect = imageBounds;\n            }\n        } else {\n            rect = imageBounds;\n        }\n\n        return rect;\n    }\n\n    private int dpToPx(Context context, float dp){\n        if (context != null) {\n            float density = context.getResources().getDisplayMetrics().density;\n            return Math.round(dp * density);\n        }\n        return Math.round(dp * 2);\n    }\n\n    protected int resolveAbsolute(@NonNull ImageSize.Dimension dimension, int original, float textSize) {\n        final int out;\n        if (UNIT_EM.equals(dimension.unit)) {\n            out = (int) (dimension.value * textSize + .5F);\n        } else {\n            out = (int) (dimension.value + .5F);\n        }\n        return out;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/image/ImageSpanFactory.java",
    "content": "package io.noties.markwon.image;\n\nimport android.util.Log;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport com.fluid.afm.func.IImageClickCallback;\n\nimport java.util.concurrent.ConcurrentHashMap;\n\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.RenderProps;\nimport io.noties.markwon.SpanFactory;\n\npublic class ImageSpanFactory implements SpanFactory {\n\n    public static final String TAG = \"MD_ImageSpanFactory\";\n    public ConcurrentHashMap<String,AsyncDrawableSpan> cacheAsyncDrawableSpan = new ConcurrentHashMap<>();\n    private boolean mIsStreamOutput;\n\n    private IImageClickCallback mClickCallback ;\n\n    public ImageSpanFactory(){\n    }\n    @Nullable\n    @Override\n    public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps props) {\n        String destination = ImageProps.DESTINATION.require(props);\n        ConcurrentHashMap<String,AsyncDrawableSpan> cache = cacheAsyncDrawableSpan;\n        AsyncDrawableSpan cacheSpan = cache.get(destination);\n        Log.d(TAG,\" destination = \" + destination + \" cacheSpan = \" + cacheSpan + \"isStreamOutput = \" + mIsStreamOutput);\n        if(isIsStreamOutput() && cacheSpan != null){\n            Log.d(TAG,\"ready to set cacheSpan\");\n            return cacheSpan;\n        }else {\n            Log.d(TAG,\"set new AsyncDrawableSpan\");\n            AsyncDrawableSpan asyncDrawableSpan =  new AsyncDrawableSpan(\n                    configuration.theme(),\n                    new AsyncDrawable(\n                            ImageProps.DESTINATION.require(props),\n                            configuration.asyncDrawableLoader(),\n                            configuration.imageSizeResolver(),\n                            ImageProps.IMAGE_SIZE.get(props)\n                    ),\n                    AsyncDrawableSpan.ALIGN_CENTER,\n                    ImageProps.REPLACEMENT_TEXT_IS_LINK.get(props, false),\n                    mClickCallback\n            );\n            cache.put(destination,asyncDrawableSpan);\n            return asyncDrawableSpan;\n        }\n    }\n    public void setImageCallback(IImageClickCallback clickCallback) {\n        mClickCallback = clickCallback;\n    }\n\n    private boolean isIsStreamOutput() {\n        return mIsStreamOutput;\n    }\n\n    public void onStreamOutStateChanged(boolean isStreamingOutput) {\n        mIsStreamOutput = isStreamingOutput;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/image/destination/ImageDestinationProcessor.java",
    "content": "package io.noties.markwon.image.destination;\n\nimport androidx.annotation.NonNull;\n\n/**\n * Process destination of image nodes\n *\n * @since 4.4.0\n */\npublic abstract class ImageDestinationProcessor {\n    @NonNull\n    public abstract String process(@NonNull String destination);\n\n    @NonNull\n    public static ImageDestinationProcessor noOp() {\n        return new NoOp();\n    }\n\n    private static class NoOp extends ImageDestinationProcessor {\n\n        @NonNull\n        @Override\n        public String process(@NonNull String destination) {\n            return destination;\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/image/destination/ImageDestinationProcessorAssets.java",
    "content": "package io.noties.markwon.image.destination;\n\nimport android.net.Uri;\nimport android.text.TextUtils;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\n/**\n * {@link ImageDestinationProcessor} that treats all destinations <strong>without scheme</strong>\n * information as pointing to the {@code assets} folder of an application. Please note that this\n * processor only adds required {@code file:///android_asset/} prefix to destinations and\n * actual image loading must take that into account (implement this functionality).\n * <p>\n * {@code FileSchemeHandler} from the {@code image} module supports asset images when created with\n * {@code createWithAssets} factory method\n *\n * @since 4.4.0\n */\npublic class ImageDestinationProcessorAssets extends ImageDestinationProcessor {\n\n    @NonNull\n    public static ImageDestinationProcessorAssets create(@Nullable ImageDestinationProcessor parent) {\n        return new ImageDestinationProcessorAssets(parent);\n    }\n\n    static final String MOCK = \"https://android.asset/\";\n    static final String BASE = \"file:///android_asset/\";\n\n    private final ImageDestinationProcessorRelativeToAbsolute assetsProcessor\n            = new ImageDestinationProcessorRelativeToAbsolute(MOCK);\n\n    private final ImageDestinationProcessor processor;\n\n    public ImageDestinationProcessorAssets() {\n        this(null);\n    }\n\n    public ImageDestinationProcessorAssets(@Nullable ImageDestinationProcessor parent) {\n        this.processor = parent;\n    }\n\n    @NonNull\n    @Override\n    public String process(@NonNull String destination) {\n        final String out;\n        final Uri uri = Uri.parse(destination);\n        if (TextUtils.isEmpty(uri.getScheme())) {\n            out = assetsProcessor.process(destination).replace(MOCK, BASE);\n        } else {\n            if (processor != null) {\n                out = processor.process(destination);\n            } else {\n                out = destination;\n            }\n        }\n        return out;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/image/destination/ImageDestinationProcessorRelativeToAbsolute.java",
    "content": "package io.noties.markwon.image.destination;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport java.net.MalformedURLException;\nimport java.net.URL;\n\n/**\n * @since 4.4.0\n */\npublic class ImageDestinationProcessorRelativeToAbsolute extends ImageDestinationProcessor {\n\n    @NonNull\n    public static ImageDestinationProcessorRelativeToAbsolute create(@NonNull String base) {\n        return new ImageDestinationProcessorRelativeToAbsolute(base);\n    }\n\n    public static ImageDestinationProcessorRelativeToAbsolute create(@NonNull URL base) {\n        return new ImageDestinationProcessorRelativeToAbsolute(base);\n    }\n\n    private final URL base;\n\n    public ImageDestinationProcessorRelativeToAbsolute(@NonNull String base) {\n        this.base = obtain(base);\n    }\n\n    public ImageDestinationProcessorRelativeToAbsolute(@NonNull URL base) {\n        this.base = base;\n    }\n\n    @NonNull\n    @Override\n    public String process(@NonNull String destination) {\n\n        String out = destination;\n\n        if (base != null) {\n            try {\n                final URL u = new URL(base, destination);\n                out = u.toString();\n            } catch (MalformedURLException e) {\n                e.printStackTrace();\n            }\n        }\n        return out;\n    }\n\n    @Nullable\n    private static URL obtain(String base) {\n        try {\n            return new URL(base);\n        } catch (MalformedURLException e) {\n            e.printStackTrace();\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/movement/MovementMethodPlugin.java",
    "content": "package io.noties.markwon.movement;\n\nimport android.text.Spanned;\nimport android.text.method.LinkMovementMethod;\nimport android.text.method.MovementMethod;\nimport android.widget.TextView;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport io.noties.markwon.AbstractMarkwonPlugin;\nimport io.noties.markwon.core.CorePlugin;\n\n/**\n * @since 3.0.0\n */\npublic class MovementMethodPlugin extends AbstractMarkwonPlugin {\n\n    /**\n     * Creates plugin that will ensure that there is movement method registered on a TextView.\n     * Uses Android system LinkMovementMethod as default\n     *\n     * @see #create(MovementMethod)\n     * @see #link()\n     * @deprecated 4.5.0 use {@link #link()}\n     */\n    @NonNull\n    @Deprecated\n    public static MovementMethodPlugin create() {\n        return create(LinkMovementMethod.getInstance());\n    }\n\n    /**\n     * @since 4.5.0\n     */\n    @NonNull\n    public static MovementMethodPlugin link() {\n        return create(LinkMovementMethod.getInstance());\n    }\n\n    /**\n     * Special {@link MovementMethodPlugin} that is <strong>not</strong> applying a MovementMethod on a TextView\n     * implicitly\n     *\n     * @since 4.5.0\n     */\n    @NonNull\n    public static MovementMethodPlugin none() {\n        return new MovementMethodPlugin(null);\n    }\n\n    @NonNull\n    public static MovementMethodPlugin create(@NonNull MovementMethod movementMethod) {\n        return new MovementMethodPlugin(movementMethod);\n    }\n\n    @Nullable\n    private final MovementMethod movementMethod;\n\n    /**\n     * Since 4.5.0 change to be <em>nullable</em>\n     */\n    @SuppressWarnings(\"WeakerAccess\")\n    MovementMethodPlugin(@Nullable MovementMethod movementMethod) {\n        this.movementMethod = movementMethod;\n    }\n\n    @Override\n    public void configure(@NonNull Registry registry) {\n        registry.require(CorePlugin.class)\n                .hasExplicitMovementMethod(true);\n    }\n\n    @Override\n    public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) {\n        // @since 4.5.0 check for equality\n        final MovementMethod current = textView.getMovementMethod();\n        if (current != movementMethod) {\n            textView.setMovementMethod(movementMethod);\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/node/OiintNode.java",
    "content": "package io.noties.markwon.node;\nimport org.commonmark.node.CustomNode;\n\npublic class OiintNode extends CustomNode {\n    private String integrationLimit;\n    public void setIntegrationLimit(String limit) {\n        this.integrationLimit = limit;\n    }\n    public String getIntegrationLimit() {\n        return integrationLimit;\n    }\n}"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/syntax/SyntaxHighlight.java",
    "content": "package io.noties.markwon.syntax;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\n@SuppressWarnings(\"WeakerAccess\")\npublic interface SyntaxHighlight {\n\n    @NonNull\n    CharSequence highlight(@Nullable String info, @NonNull String code, StringBuilder language);\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/syntax/SyntaxHighlightNoOp.java",
    "content": "package io.noties.markwon.syntax;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\npublic class SyntaxHighlightNoOp implements SyntaxHighlight {\n    @NonNull\n    @Override\n    public CharSequence highlight(@Nullable String info, @NonNull String code, StringBuilder language) {\n        return code;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/utils/ColorUtils.java",
    "content": "package io.noties.markwon.utils;\n\nimport android.graphics.Color;\n\nimport androidx.annotation.ColorInt;\nimport androidx.annotation.FloatRange;\nimport androidx.annotation.IntRange;\n\npublic abstract class ColorUtils {\n\n    @ColorInt\n    public static int applyAlpha(\n            @ColorInt int color,\n            @IntRange(from = 0, to = 255) int alpha) {\n        return (color & 0x00FFFFFF) | (alpha << 24);\n    }\n\n    // blend two colors w/ specified ratio, resulting color won't have alpha channel\n    @ColorInt\n    public static int blend(\n            @ColorInt int foreground,\n            @ColorInt int background,\n            @FloatRange(from = 0.0F, to = 1.0F) float ratio) {\n        return Color.rgb(\n                (int) (((1F - ratio) * Color.red(foreground)) + (ratio * Color.red(background))),\n                (int) (((1F - ratio) * Color.green(foreground)) + (ratio * Color.green(background))),\n                (int) (((1F - ratio) * Color.blue(foreground)) + (ratio * Color.blue(background)))\n        );\n    }\n\n    private ColorUtils() {\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/utils/Dip.java",
    "content": "package io.noties.markwon.utils;\n\nimport android.content.Context;\n\nimport androidx.annotation.NonNull;\n\npublic class Dip {\n\n    @NonNull\n    public static Dip create(@NonNull Context context) {\n        return new Dip(context.getResources().getDisplayMetrics().density);\n    }\n\n    @NonNull\n    public static Dip create(float density) {\n        return new Dip(density);\n    }\n\n    private final float density;\n\n    @SuppressWarnings(\"WeakerAccess\")\n    public Dip(float density) {\n        this.density = density;\n    }\n\n    public int toPx(int dp) {\n        return (int) (dp * density + .5F);\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/utils/DrawableUtils.java",
    "content": "package io.noties.markwon.utils;\n\nimport android.graphics.drawable.Drawable;\n\nimport androidx.annotation.NonNull;\n\n/**\n * @deprecated Please use {@link io.noties.markwon.image.DrawableUtils}\n */\n@Deprecated\npublic abstract class DrawableUtils {\n\n    public static void intrinsicBounds(@NonNull Drawable drawable) {\n        drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());\n    }\n\n    private DrawableUtils() {\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/utils/DumpNodes.java",
    "content": "package io.noties.markwon.utils;\n\nimport androidx.annotation.CheckResult;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport org.commonmark.node.Node;\nimport org.commonmark.node.Visitor;\n\nimport java.lang.reflect.InvocationHandler;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Proxy;\n\n// utility class to print parsed Nodes hierarchy\n@SuppressWarnings({\"unused\", \"WeakerAccess\"})\npublic abstract class DumpNodes {\n\n    /**\n     * Creates String representation of a node which will be used in output\n     */\n    public interface NodeProcessor {\n        @NonNull\n        String process(@NonNull Node node);\n    }\n\n    @NonNull\n    @CheckResult\n    public static String dump(@NonNull Node node) {\n        return dump(node, null);\n    }\n\n    @NonNull\n    @CheckResult\n    public static String dump(@NonNull Node node, @Nullable NodeProcessor nodeProcessor) {\n\n        final NodeProcessor processor = nodeProcessor != null\n                ? nodeProcessor\n                : new NodeProcessorToString();\n\n        final Indent indent = new Indent();\n        final StringBuilder builder = new StringBuilder();\n        final Visitor visitor = (Visitor) Proxy.newProxyInstance(\n                Visitor.class.getClassLoader(),\n                new Class[]{Visitor.class},\n                new InvocationHandler() {\n                    @Override\n                    public Object invoke(Object proxy, Method method, Object[] args) {\n\n                        final Node argument = (Node) args[0];\n\n                        // initial indent\n                        indent.appendTo(builder);\n\n                        // node info\n                        builder.append(processor.process(argument));\n\n                        // @since 4.6.0 check for first child instead of casting to Block\n                        //  (regular nodes can contain other nodes, for example Text)\n                        if (argument.getFirstChild() != null) {\n                            builder.append(\" [\\n\");\n                            indent.increment();\n                            visitChildren((Visitor) proxy, argument);\n                            indent.decrement();\n                            indent.appendTo(builder);\n                            builder.append(\"]\\n\");\n                        } else {\n                            builder.append(\"\\n\");\n                        }\n\n                        return null;\n                    }\n                });\n        node.accept(visitor);\n        return builder.toString();\n    }\n\n    private DumpNodes() {\n    }\n\n    private static class Indent {\n\n        private int count;\n\n        void increment() {\n            count += 1;\n        }\n\n        void decrement() {\n            count -= 1;\n        }\n\n        void appendTo(@NonNull StringBuilder builder) {\n            for (int i = 0; i < count; i++) {\n                builder\n                        .append(' ')\n                        .append(' ');\n            }\n        }\n    }\n\n    private static void visitChildren(@NonNull Visitor visitor, @NonNull Node parent) {\n        Node node = parent.getFirstChild();\n        while (node != null) {\n            // A subclass of this visitor might modify the node, resulting in getNext returning a different node or no\n            // node after visiting it. So get the next node before visiting.\n            Node next = node.getNext();\n            node.accept(visitor);\n            node = next;\n        }\n    }\n\n    private static class NodeProcessorToString implements NodeProcessor {\n        @NonNull\n        @Override\n        public String process(@NonNull Node node) {\n            return node.toString();\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/utils/LayoutUtils.java",
    "content": "package io.noties.markwon.utils;\n\nimport android.os.Build;\nimport android.text.Layout;\n\nimport androidx.annotation.NonNull;\n\n/**\n * @since 4.4.0\n */\npublic abstract class LayoutUtils {\n\n    private static final float DEFAULT_EXTRA = 0F;\n    private static final float DEFAULT_MULTIPLIER = 1F;\n\n    public static int getLineBottomWithoutPaddingAndSpacing(\n            @NonNull Layout layout,\n            int line\n    ) {\n\n        final int bottom = layout.getLineBottom(line);\n        final boolean lastLineSpacingNotAdded = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;\n        final boolean isSpanLastLine = line == (layout.getLineCount() - 1);\n\n        final int lineBottom;\n        final float lineSpacingExtra = layout.getSpacingAdd();\n        final float lineSpacingMultiplier = layout.getSpacingMultiplier();\n\n        // simplified check\n        final boolean hasLineSpacing = lineSpacingExtra != DEFAULT_EXTRA\n                || lineSpacingMultiplier != DEFAULT_MULTIPLIER;\n\n        if (!hasLineSpacing\n                || (isSpanLastLine && lastLineSpacingNotAdded)) {\n            lineBottom = bottom;\n        } else {\n            final float extra;\n            if (Float.compare(DEFAULT_MULTIPLIER, lineSpacingMultiplier) != 0) {\n                final int lineHeight = getLineHeight(layout, line);\n                extra = lineHeight -\n                        ((lineHeight - lineSpacingExtra) / lineSpacingMultiplier);\n            } else {\n                extra = lineSpacingExtra;\n            }\n            lineBottom = (int) (bottom - extra + .5F);\n        }\n\n        // check if it is the last line that span is occupying **and** that this line is the last\n        //  one in TextView\n        if (isSpanLastLine\n                && (line == layout.getLineCount() - 1)) {\n            return lineBottom - layout.getBottomPadding();\n        }\n\n        return lineBottom;\n    }\n\n    public static int getLineTopWithoutPadding(@NonNull Layout layout, int line) {\n        final int top = layout.getLineTop(line);\n        if (line == 0) {\n            return top - layout.getTopPadding();\n        }\n        return top;\n    }\n\n    public static int getLineHeight(@NonNull Layout layout, int line) {\n        return layout.getLineTop(line + 1) - layout.getLineTop(line);\n    }\n\n    private LayoutUtils() {\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/utils/LeadingMarginUtils.java",
    "content": "package io.noties.markwon.utils;\n\nimport android.text.Spanned;\n\npublic abstract class LeadingMarginUtils {\n\n    public static boolean selfStart(int start, CharSequence text, Object span) {\n        return text instanceof Spanned && ((Spanned) text).getSpanStart(span) == start;\n    }\n\n    public static boolean selfEnd(int end, CharSequence text, Object span) {\n        return text instanceof Spanned && ((Spanned) text).getSpanEnd(span) == end;\n    }\n\n    private LeadingMarginUtils() {\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/utils/NoCopySpannableFactory.java",
    "content": "package io.noties.markwon.utils;\n\nimport android.text.Spannable;\nimport android.text.SpannableString;\n\nimport androidx.annotation.NonNull;\n\n/**\n * Utility SpannableFactory that re-uses Spannable instance between multiple\n * `TextView#setText` calls.\n *\n * @since 3.0.0\n */\npublic class NoCopySpannableFactory extends Spannable.Factory {\n\n    @NonNull\n    public static NoCopySpannableFactory getInstance() {\n        return Holder.INSTANCE;\n    }\n\n    @Override\n    public Spannable newSpannable(CharSequence source) {\n        return source instanceof Spannable\n                ? (Spannable) source\n                : new SpannableString(source);\n    }\n\n    static class Holder {\n        private static final NoCopySpannableFactory INSTANCE = new NoCopySpannableFactory();\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/utils/ParserUtils.java",
    "content": "package io.noties.markwon.utils;\n\nimport androidx.annotation.NonNull;\n\nimport org.commonmark.node.Node;\n\n/**\n * @since 4.6.0\n */\npublic abstract class ParserUtils {\n\n    public static void moveChildren(@NonNull Node to, @NonNull Node from) {\n        Node next = from.getNext();\n        Node temp;\n        while (next != null) {\n            // appendChild would unlink passed node (thus making next info un-available)\n            temp = next.getNext();\n            to.appendChild(next);\n            next = temp;\n        }\n    }\n\n    private ParserUtils() {\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/java/io/noties/markwon/utils/SpanUtils.java",
    "content": "package io.noties.markwon.utils;\n\nimport android.graphics.Canvas;\nimport android.text.Layout;\nimport android.text.Spanned;\nimport android.widget.TextView;\n\nimport androidx.annotation.NonNull;\n\nimport io.noties.markwon.core.spans.TextLayoutSpan;\nimport io.noties.markwon.core.spans.TextViewSpan;\n\n/**\n * @since 4.4.0\n */\npublic abstract class SpanUtils {\n\n    public static int width(Canvas canvas, @NonNull CharSequence cs) {\n        // Layout\n        // TextView\n        // canvas\n        if (cs instanceof Spanned) {\n            final Spanned spanned = (Spanned) cs;\n\n            // if we are displayed with layout information -> use it\n            final Layout layout = TextLayoutSpan.layoutOf(spanned);\n            if (layout != null) {\n                return layout.getWidth();\n            }\n\n            // if we have TextView -> obtain width from it (exclude padding)\n            final TextView textView = TextViewSpan.textViewOf(spanned);\n            if (textView != null) {\n                return textView.getWidth() - textView.getPaddingLeft() - textView.getPaddingRight();\n            }\n        }\n        // else just use canvas width\n        if (canvas != null) {\n            return canvas.getWidth();\n        }\n        return 0;\n    }\n\n    public static boolean isSelfEnd(int end, CharSequence text, Object span) {\n        final int spanEnd = ((Spanned) text).getSpanEnd(span);\n        return spanEnd == end || spanEnd == end - 1;\n    }\n\n    public static boolean isSelfStart(int start, CharSequence text, Object span) {\n        final int spanStart = ((Spanned) text).getSpanStart(span);\n        return spanStart == start;\n    }\n\n    public static boolean isSelf(int start, int end, CharSequence text, Object span) {\n        final int spanStart = ((Spanned) text).getSpanStart(span);\n        final int spanEnd = ((Spanned) text).getSpanEnd(span);\n        return spanStart <= start && spanEnd >= end - 1;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/main/res/values/ids.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n    <item name=\"markwon_drawables_scheduler\" type=\"id\" />\n    <item name=\"markwon_drawables_scheduler_last_text_hashcode\" type=\"id\" />\n\n</resources>"
  },
  {
    "path": "Android/AntFluid/markwon-core/src/test/java/io/noties/markwon/ExampleUnitTest.kt",
    "content": "package io.noties.markwon\n\nimport org.junit.Assert.*\nimport org.junit.Test\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * See [testing documentation](http://d.android.com/tools/testing).\n */\nclass ExampleUnitTest {\n    @Test\n    fun addition_isCorrect() {\n        assertEquals(4, 2 + 2)\n    }\n}"
  },
  {
    "path": "Android/AntFluid/markwon-ext-latex/.gitignore",
    "content": "/build"
  },
  {
    "path": "Android/AntFluid/markwon-ext-latex/build.gradle",
    "content": "plugins {\n    alias(libs.plugins.android.library)\n}\n\nandroid {\n    namespace 'io.noties.markwon.ext.latex'\n    compileSdk 35\n\n    defaultConfig {\n        minSdk 21\n\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n        consumerProguardFiles \"consumer-rules.pro\"\n    }\n\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n        }\n    }\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_11\n        targetCompatibility JavaVersion.VERSION_11\n    }\n}\n\ndependencies {\n\n    implementation libs.androidx.appcompat\n    compileOnly project(':markwon-core')\n    compileOnly project(':markwon-inline-parser')\n    implementation 'ru.noties:jlatexmath-android:0.2.0'\n    implementation 'ru.noties:jlatexmath-android-font-cyrillic:0.2.0'\n    implementation 'ru.noties:jlatexmath-android-font-greek:0.2.0'\n    testImplementation libs.junit\n    androidTestImplementation libs.androidx.junit\n    androidTestImplementation libs.androidx.espresso.core\n}"
  },
  {
    "path": "Android/AntFluid/markwon-ext-latex/consumer-rules.pro",
    "content": ""
  },
  {
    "path": "Android/AntFluid/markwon-ext-latex/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile"
  },
  {
    "path": "Android/AntFluid/markwon-ext-latex/src/androidTest/java/io/noties/markwon/ext/latex/ExampleInstrumentedTest.java",
    "content": "package io.noties.markwon.ext.latex;\n\nimport static org.junit.Assert.assertEquals;\n\nimport android.content.Context;\n\nimport androidx.test.ext.junit.runners.AndroidJUnit4;\nimport androidx.test.platform.app.InstrumentationRegistry;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();\n        assertEquals(\"io.noties.markwon.ext.latex.test\", appContext.getPackageName());\n    }\n}"
  },
  {
    "path": "Android/AntFluid/markwon-ext-latex/src/main/AndroidManifest.xml",
    "content": "<manifest package=\"io.noties.markwon.ext.latex\" />"
  },
  {
    "path": "Android/AntFluid/markwon-ext-latex/src/main/java/io/noties/markwon/ext/latex/JLatexAsyncDrawableSpan.java",
    "content": "package io.noties.markwon.ext.latex;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.graphics.drawable.Drawable;\n\nimport androidx.annotation.ColorInt;\nimport androidx.annotation.NonNull;\n\nimport org.scilab.forge.jlatexmath.TeXIcon;\n\nimport io.noties.markwon.core.MarkwonTheme;\nimport io.noties.markwon.image.AsyncDrawableSpan;\nimport ru.noties.jlatexmath.JLatexMathDrawable;\nimport ru.noties.jlatexmath.awt.Color;\n\n/**\n * @since 4.3.0\n */\npublic class JLatexAsyncDrawableSpan extends AsyncDrawableSpan {\n\n    private final JLatextAsyncDrawable drawable;\n    private final int color;\n    private boolean appliedTextColor;\n\n    public JLatexAsyncDrawableSpan(\n            @NonNull MarkwonTheme theme,\n            @NonNull JLatextAsyncDrawable drawable,\n            @ColorInt int color) {\n        super(theme, drawable, ALIGN_CENTER, false, false);\n        this.drawable = drawable;\n        this.color = color;\n        // if color is not 0 -> then no need to apply text color\n        this.appliedTextColor = color != 0;\n    }\n\n    @Override\n    public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {\n        if (!appliedTextColor && drawable.hasResult()) {\n            // it is important to check for type (in case of an error, or custom placeholder or whatever\n            //  this result can be of other type)\n            final Drawable drawableResult = drawable.getResult();\n            if (drawableResult instanceof JLatexMathDrawable) {\n                final JLatexMathDrawable result = (JLatexMathDrawable) drawableResult;\n                final TeXIcon icon = result.icon();\n                icon.setForeground(new Color(paint.getColor()));\n                appliedTextColor = true;\n            }\n        }\n        super.draw(canvas, text, start, end, x, top, y, bottom, paint);\n    }\n\n    @NonNull\n    public JLatextAsyncDrawable drawable() {\n        return drawable;\n    }\n\n    @ColorInt\n    public int color() {\n        return color;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-latex/src/main/java/io/noties/markwon/ext/latex/JLatexBlockImageSizeResolver.java",
    "content": "package io.noties.markwon.ext.latex;\n\nimport android.graphics.Rect;\n\nimport androidx.annotation.NonNull;\n\nimport io.noties.markwon.image.AsyncDrawable;\nimport io.noties.markwon.image.ImageSizeResolver;\n\n// we must make drawable fit canvas (if specified), but do not keep the ratio whilst scaling up\n// @since 4.0.0\nclass JLatexBlockImageSizeResolver extends ImageSizeResolver {\n\n    private final boolean fitCanvas;\n\n    JLatexBlockImageSizeResolver(boolean fitCanvas) {\n        this.fitCanvas = fitCanvas;\n    }\n\n    @NonNull\n    @Override\n    public Rect resolveImageSize(@NonNull AsyncDrawable drawable) {\n\n        final Rect imageBounds = drawable.getResult().getBounds();\n        final int canvasWidth = drawable.getLastKnownCanvasWidth();\n\n        if (fitCanvas) {\n\n            // we modify bounds only if `fitCanvas` is true\n            final int w = imageBounds.width();\n\n            if (w < canvasWidth) {\n                // increase width and center formula (keep height as-is)\n                return new Rect(0, 0, canvasWidth, imageBounds.height());\n            }\n\n            // @since 4.0.2 we additionally scale down the resulting formula (keeping the ratio)\n            // the thing is - JLatexMathDrawable will do it anyway, but it will modify its own\n            // bounds (which AsyncDrawable won't catch), thus leading to an empty space after the formula\n            if (w > canvasWidth) {\n                // here we must scale it down (keeping the ratio)\n                final float ratio = (float) w / imageBounds.height();\n                final int h = (int) (canvasWidth / ratio + .5F);\n                return new Rect(0, 0, canvasWidth, h);\n            }\n        }\n\n        return imageBounds;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-latex/src/main/java/io/noties/markwon/ext/latex/JLatexInlineAsyncDrawableSpan.java",
    "content": "package io.noties.markwon.ext.latex;\n\nimport android.graphics.Paint;\nimport android.graphics.Rect;\n\nimport androidx.annotation.ColorInt;\nimport androidx.annotation.IntRange;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport io.noties.markwon.core.MarkwonTheme;\nimport io.noties.markwon.image.AsyncDrawable;\n\n/**\n * @since 4.3.0\n */\nclass JLatexInlineAsyncDrawableSpan extends JLatexAsyncDrawableSpan {\n\n    private final AsyncDrawable drawable;\n\n    JLatexInlineAsyncDrawableSpan(@NonNull MarkwonTheme theme, @NonNull JLatextAsyncDrawable drawable, @ColorInt int color) {\n        super(theme, drawable, color);\n        this.drawable = drawable;\n    }\n\n    @Override\n    public int getSize(\n            @NonNull Paint paint,\n            CharSequence text,\n            @IntRange(from = 0) int start,\n            @IntRange(from = 0) int end,\n            @Nullable Paint.FontMetricsInt fm) {\n\n        // if we have no async drawable result - we will just render text\n\n        final int size;\n\n        if (drawable.hasResult()) {\n\n            final Rect rect = drawable.getBounds();\n\n            if (fm != null) {\n                final int half = rect.bottom / 2;\n                fm.ascent = -half;\n                fm.descent = half;\n\n                fm.top = fm.ascent;\n                fm.bottom = 0;\n            }\n\n            size = rect.right;\n\n        } else {\n\n            // NB, no specific text handling (no new lines, etc)\n            size = (int) (paint.measureText(text, start, end) + .5F);\n        }\n\n        return size;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-latex/src/main/java/io/noties/markwon/ext/latex/JLatexMathBlock.java",
    "content": "package io.noties.markwon.ext.latex;\n\nimport org.commonmark.node.CustomBlock;\n\npublic class JLatexMathBlock extends CustomBlock {\n\n    private String latex;\n\n    public String latex() {\n        return latex;\n    }\n\n    public void latex(String latex) {\n        this.latex = latex;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-latex/src/main/java/io/noties/markwon/ext/latex/JLatexMathBlockParser.java",
    "content": "package io.noties.markwon.ext.latex;\n\nimport androidx.annotation.NonNull;\n\nimport org.commonmark.internal.util.Parsing;\nimport org.commonmark.node.Block;\nimport org.commonmark.parser.block.AbstractBlockParser;\nimport org.commonmark.parser.block.AbstractBlockParserFactory;\nimport org.commonmark.parser.block.BlockContinue;\nimport org.commonmark.parser.block.BlockStart;\nimport org.commonmark.parser.block.MatchedBlockParser;\nimport org.commonmark.parser.block.ParserState;\n\n/**\n * @since 4.3.0 (although there was a class with the same name,\n * which is renamed now to {@link JLatexMathBlockParserLegacy})\n */\nclass JLatexMathBlockParser extends AbstractBlockParser {\n\n    private static final char DOLLAR = '$';\n    private static final char SPACE = ' ';\n\n    private final JLatexMathBlock block = new JLatexMathBlock();\n\n    private final StringBuilder builder = new StringBuilder();\n\n    private final int signs;\n\n    JLatexMathBlockParser(int signs) {\n        this.signs = signs;\n    }\n\n    @Override\n    public Block getBlock() {\n        return block;\n    }\n\n    @Override\n    public BlockContinue tryContinue(ParserState parserState) {\n        final int nextNonSpaceIndex = parserState.getNextNonSpaceIndex();\n        final CharSequence line = parserState.getLine();\n        final int length = line.length();\n\n        // check for closing\n        if (parserState.getIndent() < Parsing.CODE_BLOCK_INDENT) {\n            if (consume(DOLLAR, line, nextNonSpaceIndex, length) == signs) {\n                // okay, we have our number of signs\n                // let's consume spaces until the end\n                if (Parsing.skip(SPACE, line, nextNonSpaceIndex + signs, length) == length) {\n                    return BlockContinue.finished();\n                }\n            }\n        }\n\n        return BlockContinue.atIndex(parserState.getIndex());\n    }\n\n    @Override\n    public void addLine(CharSequence line) {\n        builder.append(line);\n        builder.append('\\n');\n    }\n\n    @Override\n    public void closeBlock() {\n        block.latex(builder.toString());\n    }\n\n    public static class Factory extends AbstractBlockParserFactory {\n\n        @Override\n        public BlockStart tryStart(ParserState state, MatchedBlockParser matchedBlockParser) {\n\n            // let's define the spec:\n            //  * 0-3 spaces before are allowed (Parsing.CODE_BLOCK_INDENT = 4)\n            //  * 2+ subsequent `$` signs\n            //  * any optional amount of spaces\n            //  * new line\n            //  * block is closed when the same amount of opening signs is met\n\n            final int indent = state.getIndent();\n\n            // check if it's an indented code block\n            if (indent >= Parsing.CODE_BLOCK_INDENT) {\n                return BlockStart.none();\n            }\n\n            final int nextNonSpaceIndex = state.getNextNonSpaceIndex();\n            final CharSequence line = state.getLine();\n            final int length = line.length();\n\n            final int signs = consume(DOLLAR, line, nextNonSpaceIndex, length);\n\n            // 2 is minimum\n            if (signs < 2) {\n                return BlockStart.none();\n            }\n\n            // consume spaces until the end of the line, if any other content is found -> NONE\n            if (Parsing.skip(SPACE, line, nextNonSpaceIndex + signs, length) != length) {\n                return BlockStart.none();\n            }\n\n            return BlockStart.of(new JLatexMathBlockParser(signs))\n                    .atIndex(length + 1);\n        }\n    }\n\n    @SuppressWarnings(\"SameParameterValue\")\n    private static int consume(char c, @NonNull CharSequence line, int start, int end) {\n        for (int i = start; i < end; i++) {\n            if (c != line.charAt(i)) {\n                return i - start;\n            }\n        }\n        // all consumed\n        return end - start;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-latex/src/main/java/io/noties/markwon/ext/latex/JLatexMathBlockParserLegacy.java",
    "content": "package io.noties.markwon.ext.latex;\n\nimport org.commonmark.node.Block;\nimport org.commonmark.parser.block.AbstractBlockParser;\nimport org.commonmark.parser.block.AbstractBlockParserFactory;\nimport org.commonmark.parser.block.BlockContinue;\nimport org.commonmark.parser.block.BlockStart;\nimport org.commonmark.parser.block.MatchedBlockParser;\nimport org.commonmark.parser.block.ParserState;\n\n/**\n * @since 4.3.0 (although it is just renamed parser from previous versions)\n */\nclass JLatexMathBlockParserLegacy extends AbstractBlockParser {\n\n    private final JLatexMathBlock block = new JLatexMathBlock();\n\n    private final StringBuilder builder = new StringBuilder();\n\n    private boolean isClosed;\n\n    @Override\n    public Block getBlock() {\n        return block;\n    }\n\n    @Override\n    public BlockContinue tryContinue(ParserState parserState) {\n\n        if (isClosed) {\n            return BlockContinue.finished();\n        }\n\n        return BlockContinue.atIndex(parserState.getIndex());\n    }\n\n    @Override\n    public void addLine(CharSequence line) {\n\n        if (builder.length() > 0) {\n            builder.append('\\n');\n        }\n\n        builder.append(line);\n\n        final int length = builder.length();\n        if (length > 1) {\n            isClosed = '$' == builder.charAt(length - 1)\n                    && '$' == builder.charAt(length - 2);\n            if (isClosed) {\n                builder.replace(length - 2, length, \"\");\n            }\n        }\n    }\n\n    @Override\n    public void closeBlock() {\n        if(isClosed){\n            block.latex(builder.toString());\n        }else {\n            block.latex(\"\");\n        }\n    }\n\n    public static class Factory extends AbstractBlockParserFactory {\n        public static CharSequence lastLine = \"\";\n        @Override\n        public BlockStart tryStart(ParserState state, MatchedBlockParser matchedBlockParser) {\n\n            final CharSequence line = state.getLine();\n            final int length = line != null\n                    ? line.length()\n                    : 0;\n\n            if (length > 1) {\n                if ('$' == line.charAt(0)\n                        && '$' == line.charAt(1)) {\n                    if(line.equals(lastLine)){\n                        return BlockStart.none();\n                    }\n                    lastLine = line;\n                    return BlockStart.of(new JLatexMathBlockParserLegacy())\n                            .atIndex(state.getIndex() + 2);\n                }\n            }\n\n            return BlockStart.none();\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-latex/src/main/java/io/noties/markwon/ext/latex/JLatexMathInlineProcessor.java",
    "content": "package io.noties.markwon.ext.latex;\n\nimport androidx.annotation.Nullable;\n\nimport org.commonmark.node.Node;\n\nimport java.util.regex.Pattern;\n\nimport io.noties.markwon.inlineparser.InlineProcessor;\n\n/**\n * @since 4.3.0\n */\nclass JLatexMathInlineProcessor extends InlineProcessor {\n\n    // support single $ character\n    private static final Pattern RE = Pattern.compile(\"(\\\\${2}|\\\\${1})([\\\\s\\\\S]+?)\\\\1\");\n\n    @Override\n    public char specialCharacter() {\n        return '$';\n    }\n\n    @Nullable\n    @Override\n    protected Node parse() {\n        final String latex = match(RE);\n        if (latex == null) {\n            return null;\n        }\n\n        // support single $ character\n        int dollarCount = latex.startsWith(\"$$\") ? 2 : 1;\n        final JLatexMathNode node = new JLatexMathNode();\n        node.latex(latex.substring(dollarCount, latex.length() - dollarCount));\n\n        return node;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-latex/src/main/java/io/noties/markwon/ext/latex/JLatexMathNode.java",
    "content": "package io.noties.markwon.ext.latex;\n\nimport org.commonmark.node.CustomNode;\n\n/**\n * @since 4.3.0\n */\npublic class JLatexMathNode extends CustomNode {\n\n    private String latex;\n\n    public String latex() {\n        return latex;\n    }\n\n    public void latex(String latex) {\n        this.latex = latex;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-latex/src/main/java/io/noties/markwon/ext/latex/JLatexMathPlugin.java",
    "content": "package io.noties.markwon.ext.latex;\n\nimport android.content.Context;\nimport android.graphics.Rect;\nimport android.graphics.drawable.Drawable;\nimport android.os.Handler;\nimport android.os.Looper;\nimport android.os.SystemClock;\nimport android.text.Spanned;\nimport android.text.TextUtils;\nimport android.widget.TextView;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.Px;\nimport androidx.annotation.VisibleForTesting;\n\nimport com.fluid.afm.StreamOutStateObserver;\nimport com.fluid.afm.utils.MDLogger;\n\nimport org.commonmark.parser.Parser;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.Future;\n\nimport io.noties.markwon.AbstractMarkwonPlugin;\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.MarkwonVisitor;\nimport io.noties.markwon.image.AsyncDrawable;\nimport io.noties.markwon.image.AsyncDrawableLoader;\nimport io.noties.markwon.image.AsyncDrawableScheduler;\nimport io.noties.markwon.image.AsyncDrawableSpan;\nimport io.noties.markwon.image.DrawableUtils;\nimport io.noties.markwon.image.ImageSizeResolver;\nimport io.noties.markwon.inlineparser.MarkwonInlineParserPlugin;\nimport ru.noties.jlatexmath.JLatexMathAndroid;\nimport ru.noties.jlatexmath.JLatexMathDrawable;\n\n/**\n * @since 3.0.0\n */\npublic class JLatexMathPlugin extends AbstractMarkwonPlugin implements StreamOutStateObserver {\n\n    private boolean mIsStreamingOutput = false;\n    public ConcurrentHashMap<String,AsyncDrawableSpan> mLatexDesCache = new ConcurrentHashMap<>();\n\n    public static void init(Context context) {\n        JLatexMathAndroid.init(context);\n    }\n\n    @Override\n    public void onStreamOutStateChanged(boolean isStreamingOutput) {\n        mIsStreamingOutput = isStreamingOutput;\n        if (!isStreamingOutput) {\n            mLatexDesCache.clear();\n        }\n    }\n\n    /**\n     * @since 4.3.0\n     */\n    public interface ErrorHandler {\n\n        /**\n         * @param latex that caused the error\n         * @param error occurred\n         * @return (optional) error drawable that will be used instead (if drawable will have bounds\n         * it will be used, if not intrinsic bounds will be set)\n         */\n        @Nullable\n        Drawable handleError(@NonNull String latex, @NonNull Throwable error);\n    }\n\n    public interface BuilderConfigure {\n        void configureBuilder(@NonNull Builder builder);\n    }\n\n    @NonNull\n    public static JLatexMathPlugin create(float textSize) {\n        return new JLatexMathPlugin(builder(textSize).build());\n    }\n\n    /**\n     * @since 4.3.0\n     */\n    @NonNull\n    public static JLatexMathPlugin create(@Px float inlineTextSize, @Px float blockTextSize) {\n        return new JLatexMathPlugin(builder(inlineTextSize, blockTextSize).build());\n    }\n\n    @NonNull\n    public static JLatexMathPlugin create(@NonNull Config config) {\n        return new JLatexMathPlugin(config);\n    }\n\n    @NonNull\n    public static JLatexMathPlugin create(@Px float textSize, @NonNull BuilderConfigure builderConfigure) {\n        final Builder builder = builder(textSize);\n        builderConfigure.configureBuilder(builder);\n        return new JLatexMathPlugin(builder.build());\n    }\n\n    /**\n     * @since 4.3.0\n     */\n    @NonNull\n    public static JLatexMathPlugin create(\n            @Px float inlineTextSize,\n            @Px float blockTextSize,\n            @NonNull BuilderConfigure builderConfigure) {\n        final Builder builder = builder(inlineTextSize, blockTextSize);\n        builderConfigure.configureBuilder(builder);\n        return new JLatexMathPlugin(builder.build());\n    }\n\n    @NonNull\n    public static Builder builder(@Px float textSize) {\n        return new Builder(JLatexMathTheme.builder(textSize));\n    }\n\n    /**\n     * @since 4.3.0\n     */\n    @NonNull\n    public static Builder builder(@Px float inlineTextSize, @Px float blockTextSize) {\n        return new Builder(JLatexMathTheme.builder(inlineTextSize, blockTextSize));\n    }\n\n    @VisibleForTesting\n    static class Config {\n\n        // @since 4.3.0\n        final JLatexMathTheme theme;\n\n        // @since 4.3.0\n        final boolean blocksEnabled;\n        final boolean blocksLegacy;\n        final boolean inlinesEnabled;\n\n        // @since 4.3.0\n        final ErrorHandler errorHandler;\n\n        final ExecutorService executorService;\n\n        Config(@NonNull Builder builder) {\n            this.theme = builder.theme.build();\n            this.blocksEnabled = builder.blocksEnabled;\n            this.blocksLegacy = builder.blocksLegacy;\n            this.inlinesEnabled = builder.inlinesEnabled;\n            this.errorHandler = builder.errorHandler;\n            // @since 4.0.0\n            ExecutorService executorService = builder.executorService;\n            if (executorService == null) {\n                executorService = Executors.newCachedThreadPool();\n            }\n            this.executorService = executorService;\n        }\n    }\n\n    @VisibleForTesting\n    final Config config;\n\n    private final JLatextAsyncDrawableLoader jLatextAsyncDrawableLoader;\n    private final JLatexBlockImageSizeResolver jLatexBlockImageSizeResolver;\n    private final ImageSizeResolver inlineImageSizeResolver;\n\n    @SuppressWarnings(\"WeakerAccess\")\n    JLatexMathPlugin(@NonNull Config config) {\n        this.config = config;\n        this.jLatextAsyncDrawableLoader = new JLatextAsyncDrawableLoader(config);\n        this.jLatexBlockImageSizeResolver = new JLatexBlockImageSizeResolver(false);\n        this.inlineImageSizeResolver = new InlineImageSizeResolver();\n    }\n\n    @Override\n    public void configure(@NonNull Registry registry) {\n        if (config.inlinesEnabled) {\n            registry.require(MarkwonInlineParserPlugin.class)\n                    .factoryBuilder()\n                    .addInlineProcessor(new JLatexMathInlineProcessor());\n        }\n    }\n\n    @Override\n    public void configureParser(@NonNull Parser.Builder builder) {\n        // @since 4.3.0\n        if (config.blocksEnabled) {\n            if (config.blocksLegacy) {\n                builder.customBlockParserFactory(new JLatexMathBlockParserLegacy.Factory());\n            } else {\n                builder.customBlockParserFactory(new JLatexMathBlockParser.Factory());\n            }\n        }\n    }\n\n    @Override\n    public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) {\n        addBlockVisitor(builder);\n        addInlineVisitor(builder);\n    }\n\n    private void addBlockVisitor(@NonNull MarkwonVisitor.Builder builder) {\n        if (!config.blocksEnabled) {\n            return;\n        }\n\n        builder.on(JLatexMathBlock.class, new MarkwonVisitor.NodeVisitor<JLatexMathBlock>() {\n            @Override\n            public void visit(@NonNull MarkwonVisitor visitor, @NonNull JLatexMathBlock jLatexMathBlock) {\n\n                visitor.blockStart(jLatexMathBlock);\n\n                final String latex = jLatexMathBlock.latex();\n                final int length = visitor.length();\n                // @since 4.0.2 we cannot append _raw_ latex as a placeholder-text,\n                // because Android will draw formula for each line of text, thus\n                // leading to formula duplicated (drawn on each line of text)\n                visitor.builder().append(prepareLatexTextPlaceholder(latex));\n                handleVisitorAndJLatex(visitor,latex,length,\"BlockVisitor\");\n                visitor.blockEnd(jLatexMathBlock);\n            }\n        });\n    }\n\n    private void handleVisitorAndJLatex(MarkwonVisitor visitor,String latex,int length,String tag){\n\n        if(TextUtils.isEmpty(latex)){\n            return;\n        }\n\n        AsyncDrawableSpan span = mLatexDesCache.get(latex);\n        if (isStreamingOutput() && span != null) {\n//            if (span.getDrawable().hasResult()) {\n//                Drawable drawable = span.getDrawable().getResult();\n//                ImageSpan imageSpan = new ImageSpan(drawable);\n//                visitor.setSpans(length, imageSpan);\n//            } else {\n                visitor.setSpans(length, span);\n//            }\n        } else {\n            final MarkwonConfiguration configuration = visitor.configuration();\n            span = new JLatexAsyncDrawableSpan(\n                    configuration.theme(),\n                    new JLatextAsyncDrawable(\n                            latex,\n                            jLatextAsyncDrawableLoader,\n                            \"BlockVisitor\".equals(tag)?jLatexBlockImageSizeResolver:inlineImageSizeResolver,\n                            null,\n                            true),\n                    config.theme.blockTextColor()\n            );\n            visitor.setSpans(length, span);\n            mLatexDesCache.put(latex,span);\n        }\n    }\n\n    private boolean isStreamingOutput() {\n        return mIsStreamingOutput;\n    }\n\n    private void addInlineVisitor(@NonNull MarkwonVisitor.Builder builder) {\n\n        if (!config.inlinesEnabled) {\n            return;\n        }\n\n        builder.on(JLatexMathNode.class, new MarkwonVisitor.NodeVisitor<JLatexMathNode>() {\n            @Override\n            public void visit(@NonNull MarkwonVisitor visitor, @NonNull JLatexMathNode jLatexMathNode) {\n                final String latex = jLatexMathNode.latex();\n                final int length = visitor.length();\n                // @since 4.0.2 we cannot append _raw_ latex as a placeholder-text,\n                // because Android will draw formula for each line of text, thus\n                // leading to formula duplicated (drawn on each line of text)\n                visitor.builder().append(prepareLatexTextPlaceholder(latex));\n                handleVisitorAndJLatex(visitor,latex,length,\"InlineVisitor\");\n            }\n        });\n    }\n\n    @Override\n    public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) {\n        AsyncDrawableScheduler.unschedule(textView);\n    }\n\n    @Override\n    public void afterSetText(@NonNull TextView textView) {\n        AsyncDrawableScheduler.schedule(textView);\n    }\n\n\n    // @since 4.0.2\n    @VisibleForTesting\n    @NonNull\n    static String prepareLatexTextPlaceholder(@NonNull String latex) {\n        return latex.replace('\\n', ' ').trim();\n    }\n\n    @SuppressWarnings({\"unused\", \"UnusedReturnValue\"})\n    public static class Builder {\n\n        // @since 4.3.0\n        private final JLatexMathTheme.Builder theme;\n\n        // @since 4.3.0\n        private boolean blocksEnabled = true;\n        private boolean blocksLegacy;\n        private boolean inlinesEnabled;\n\n        // @since 4.3.0\n        private ErrorHandler errorHandler;\n\n        // @since 4.0.0\n        private ExecutorService executorService;\n\n        Builder(@NonNull JLatexMathTheme.Builder builder) {\n            this.theme = builder;\n        }\n\n        @NonNull\n        public JLatexMathTheme.Builder theme() {\n            return theme;\n        }\n\n        /**\n         * @since 4.3.0\n         */\n        @NonNull\n        public Builder blocksEnabled(boolean blocksEnabled) {\n            this.blocksEnabled = blocksEnabled;\n            return this;\n        }\n\n        /**\n         * @param blocksLegacy indicates if blocks should be handled in legacy mode ({@code pre 4.3.0})\n         * @since 4.3.0\n         */\n        @NonNull\n        public Builder blocksLegacy(boolean blocksLegacy) {\n            this.blocksLegacy = blocksLegacy;\n            return this;\n        }\n\n        /**\n         * @param inlinesEnabled indicates if inline parsing should be enabled.\n         *                       NB, this requires `MarkwonInlineParserPlugin` to be used when creating `MarkwonInstance`\n         * @since 4.3.0\n         */\n        @NonNull\n        public Builder inlinesEnabled(boolean inlinesEnabled) {\n            this.inlinesEnabled = inlinesEnabled;\n            return this;\n        }\n\n        @NonNull\n        public Builder errorHandler(@Nullable ErrorHandler errorHandler) {\n            this.errorHandler = errorHandler;\n            return this;\n        }\n\n        /**\n         * @since 4.0.0\n         */\n        @SuppressWarnings(\"WeakerAccess\")\n        @NonNull\n        public Builder executorService(@NonNull ExecutorService executorService) {\n            this.executorService = executorService;\n            return this;\n        }\n        @NonNull\n        public Config build() {\n            return new Config(this);\n        }\n    }\n\n    // @since 4.0.0\n    static class JLatextAsyncDrawableLoader extends AsyncDrawableLoader {\n\n        private final Config config;\n        private final Handler handler = new Handler(Looper.getMainLooper());\n        private final Map<AsyncDrawable, Future<?>> cache = new HashMap<>(3);\n\n        JLatextAsyncDrawableLoader(@NonNull Config config) {\n            this.config = config;\n        }\n\n        @Override\n        public void load(@NonNull final AsyncDrawable drawable) {\n\n            // this method must be called from main-thread only (thus synchronization can be skipped)\n\n            // check for currently running tasks associated with provided drawable\n            final Future<?> future = cache.get(drawable);\n\n            // if it's present -> proceed with new execution\n            // as asyncDrawable is immutable, it won't have destination changed (so there is no need\n            // to cancel any started tasks)\n            if (future == null) {\n\n                cache.put(drawable, config.executorService.submit(new Runnable() {\n                    @Override\n                    public void run() {\n                        // @since 4.0.1 wrap in try-catch block and add error logging\n                        try {\n                            execute();\n                        } catch (Throwable t) {\n                            // @since 4.3.0 add error handling\n                            final ErrorHandler errorHandler = config.errorHandler;\n                            if (errorHandler == null) {\n                                // as before\n                                MDLogger.e(\n                                        \"JLatexMathPlugin\",\n                                        \"Error displaying latex: `\" + drawable.getDestination() + \"`\",\n                                        t);\n                            } else {\n                                // just call `getDestination` without casts and checks\n                                final Drawable errorDrawable = errorHandler.handleError(\n                                        drawable.getDestination(),\n                                        t\n                                );\n                                if (errorDrawable != null) {\n                                    DrawableUtils.applyIntrinsicBoundsIfEmpty(errorDrawable);\n                                    setResult(drawable, errorDrawable);\n                                }\n                            }\n                        }\n                    }\n\n                    private void execute() {\n\n                        final JLatexMathDrawable jLatexMathDrawable;\n\n                        final JLatextAsyncDrawable jLatextAsyncDrawable = (JLatextAsyncDrawable) drawable;\n\n                        if (jLatextAsyncDrawable.isBlock()) {\n                            jLatexMathDrawable = createBlockDrawable(jLatextAsyncDrawable);\n                        } else {\n                            jLatexMathDrawable = createInlineDrawable(jLatextAsyncDrawable);\n                        }\n\n                        setResult(drawable, jLatexMathDrawable);\n                    }\n                }));\n            }\n        }\n\n        @Override\n        public void cancel(@NonNull AsyncDrawable drawable) {\n\n            // this method also must be called from main thread only\n\n            final Future<?> future = cache.remove(drawable);\n            if (future != null) {\n                future.cancel(true);\n            }\n\n            // remove all callbacks (via runnable) and messages posted for this drawable\n            handler.removeCallbacksAndMessages(drawable);\n        }\n\n        @Nullable\n        @Override\n        public Drawable placeholder(@NonNull AsyncDrawable drawable) {\n            return null;\n        }\n\n        // @since 4.3.0\n        @NonNull\n        private JLatexMathDrawable createBlockDrawable(@NonNull JLatextAsyncDrawable drawable) {\n\n            final String latex = drawable.getDestination();\n\n            final JLatexMathTheme theme = config.theme;\n\n            final JLatexMathTheme.BackgroundProvider backgroundProvider = theme.blockBackgroundProvider();\n            final JLatexMathTheme.Padding padding = theme.blockPadding();\n            final int color = theme.blockTextColor();\n\n            final JLatexMathDrawable.Builder builder = JLatexMathDrawable.builder(latex)\n                    .textSize(theme.blockTextSize())\n                    .align(theme.blockHorizontalAlignment());\n\n            if (backgroundProvider != null) {\n                builder.background(backgroundProvider.provide());\n            }\n\n            if (padding != null) {\n                builder.padding(padding.left, padding.top, padding.right, padding.bottom);\n            }\n\n            if (color != 0) {\n                builder.color(color);\n            }\n\n            return builder.build();\n        }\n\n        // @since 4.3.0\n        @NonNull\n        private JLatexMathDrawable createInlineDrawable(@NonNull JLatextAsyncDrawable drawable) {\n\n            final String latex = drawable.getDestination();\n\n            final JLatexMathTheme theme = config.theme;\n\n            final JLatexMathTheme.BackgroundProvider backgroundProvider = theme.inlineBackgroundProvider();\n            final JLatexMathTheme.Padding padding = theme.inlinePadding();\n            final int color = theme.inlineTextColor();\n\n            final JLatexMathDrawable.Builder builder = JLatexMathDrawable.builder(latex)\n                    .textSize(theme.inlineTextSize());\n\n            if (backgroundProvider != null) {\n                builder.background(backgroundProvider.provide());\n            }\n\n            if (padding != null) {\n                builder.padding(padding.left, padding.top, padding.right, padding.bottom);\n            }\n\n            if (color != 0) {\n                builder.color(color);\n            }\n\n            return builder.build();\n        }\n\n        // @since 4.3.0\n        private void setResult(@NonNull final AsyncDrawable drawable, @NonNull final Drawable result) {\n            // we must post to handler, but also have a way to identify the drawable\n            // for which we are posting (in case of cancellation)\n            handler.postAtTime(new Runnable() {\n                @Override\n                public void run() {\n                    // remove entry from cache (it will be present if task is not cancelled)\n                    if (cache.remove(drawable) != null\n                            && drawable.isAttached()) {\n                        drawable.setResult(result);\n                    }\n\n                }\n            }, drawable, SystemClock.uptimeMillis());\n        }\n    }\n\n    private static class InlineImageSizeResolver extends ImageSizeResolver {\n\n        @NonNull\n        @Override\n        public Rect resolveImageSize(@NonNull AsyncDrawable drawable) {\n\n            // @since 4.4.0 resolve inline size (scale down if exceed available width)\n            final Rect imageBounds = drawable.getResult().getBounds();\n            final int canvasWidth = drawable.getLastKnownCanvasWidth();\n            final int w = imageBounds.width();\n\n            if (w > canvasWidth) {\n                // here we must scale it down (keeping the ratio)\n                final float ratio = (float) w / imageBounds.height();\n                final int h = (int) (canvasWidth / ratio + .5F);\n                return new Rect(0, 0, canvasWidth, h);\n            }\n\n            return imageBounds;\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-latex/src/main/java/io/noties/markwon/ext/latex/JLatexMathTheme.java",
    "content": "package io.noties.markwon.ext.latex;\n\nimport android.graphics.drawable.Drawable;\n\nimport androidx.annotation.ColorInt;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.Px;\n\nimport ru.noties.jlatexmath.JLatexMathDrawable;\n\n/**\n * @since 4.3.0\n */\npublic abstract class JLatexMathTheme {\n\n    @NonNull\n    public static JLatexMathTheme create(@Px float textSize) {\n        return builder(textSize).build();\n    }\n\n    @NonNull\n    public static JLatexMathTheme create(@Px float inlineTextSize, @Px float blockTextSize) {\n        return builder(inlineTextSize, blockTextSize).build();\n    }\n\n    @NonNull\n    public static Builder builder(@Px float textSize) {\n        return new Builder(textSize, 0F, 0F);\n    }\n\n    @NonNull\n    public static Builder builder(@Px float inlineTextSize, @Px float blockTextSize) {\n        return new Builder(0F, inlineTextSize, blockTextSize);\n    }\n\n    /**\n     * Moved from {@link JLatexMathPlugin} in {@code 4.3.0} version\n     *\n     * @since 4.0.0\n     */\n    public interface BackgroundProvider {\n        @NonNull\n        Drawable provide();\n    }\n\n    /**\n     * Special immutable class to hold padding information\n     */\n    @SuppressWarnings(\"WeakerAccess\")\n    public static class Padding {\n        public final int left;\n        public final int top;\n        public final int right;\n        public final int bottom;\n\n        public Padding(int left, int top, int right, int bottom) {\n            this.left = left;\n            this.top = top;\n            this.right = right;\n            this.bottom = bottom;\n        }\n\n        @NonNull\n        @Override\n        public String toString() {\n            return \"Padding{\" +\n                    \"left=\" + left +\n                    \", top=\" + top +\n                    \", right=\" + right +\n                    \", bottom=\" + bottom +\n                    '}';\n        }\n\n        @NonNull\n        public static Padding all(int value) {\n            return new Padding(value, value, value, value);\n        }\n\n        @NonNull\n        public static Padding symmetric(int vertical, int horizontal) {\n            return new Padding(horizontal, vertical, horizontal, vertical);\n        }\n\n        /**\n         * @since 4.5.0\n         */\n        @NonNull\n        public static Padding of(int left, int top, int right, int bottom) {\n            return new Padding(left, top, right, bottom);\n        }\n    }\n\n    /**\n     * @return text size in pixels for <strong>inline LaTeX</strong>\n     * @see #blockTextSize()\n     */\n    @Px\n    public abstract float inlineTextSize();\n\n    /**\n     * @return text size in pixels for <strong>block LaTeX</strong>\n     * @see #inlineTextSize()\n     */\n    @Px\n    public abstract float blockTextSize();\n\n    @Nullable\n    public abstract BackgroundProvider inlineBackgroundProvider();\n\n    @Nullable\n    public abstract BackgroundProvider blockBackgroundProvider();\n\n    /**\n     * @return boolean if <strong>block LaTeX</strong> must fit the width of canvas\n     */\n    public abstract boolean blockFitCanvas();\n\n    /**\n     * @return horizontal alignment of <strong>block LaTeX</strong> if {@link #blockFitCanvas()}\n     * is enabled (thus space for alignment is available)\n     */\n    @JLatexMathDrawable.Align\n    public abstract int blockHorizontalAlignment();\n\n    @Nullable\n    public abstract Padding inlinePadding();\n\n    @Nullable\n    public abstract Padding blockPadding();\n\n    @ColorInt\n    public abstract int inlineTextColor();\n\n    @ColorInt\n    public abstract int blockTextColor();\n\n    @SuppressWarnings({\"unused\", \"UnusedReturnValue\"})\n    public static class Builder {\n        private final float textSize;\n        private final float inlineTextSize;\n        private final float blockTextSize;\n\n        private BackgroundProvider backgroundProvider;\n        private BackgroundProvider inlineBackgroundProvider;\n        private BackgroundProvider blockBackgroundProvider;\n\n        private boolean blockFitCanvas = true;\n        // horizontal alignment (when there is additional horizontal space)\n        private int blockHorizontalAlignment = JLatexMathDrawable.ALIGN_CENTER;\n\n        private Padding padding;\n        private Padding inlinePadding;\n        private Padding blockPadding;\n\n        private int textColor;\n        private int inlineTextColor;\n        private int blockTextColor;\n\n        Builder(float textSize, float inlineTextSize, float blockTextSize) {\n            this.textSize = textSize;\n            this.inlineTextSize = inlineTextSize;\n            this.blockTextSize = blockTextSize;\n        }\n\n        @NonNull\n        public Builder backgroundProvider(@Nullable BackgroundProvider backgroundProvider) {\n            this.backgroundProvider = backgroundProvider;\n            this.inlineBackgroundProvider = backgroundProvider;\n            this.blockBackgroundProvider = backgroundProvider;\n            return this;\n        }\n\n        @NonNull\n        public Builder inlineBackgroundProvider(@Nullable BackgroundProvider inlineBackgroundProvider) {\n            this.inlineBackgroundProvider = inlineBackgroundProvider;\n            return this;\n        }\n\n        @NonNull\n        public Builder blockBackgroundProvider(@Nullable BackgroundProvider blockBackgroundProvider) {\n            this.blockBackgroundProvider = blockBackgroundProvider;\n            return this;\n        }\n\n        /**\n         * Configure if `LaTeX` formula should take all available widget width.\n         * By default - `true`\n         */\n        @NonNull\n        public Builder blockFitCanvas(boolean blockFitCanvas) {\n            this.blockFitCanvas = blockFitCanvas;\n            return this;\n        }\n\n        @NonNull\n        public Builder blockHorizontalAlignment(@JLatexMathDrawable.Align int blockHorizontalAlignment) {\n            this.blockHorizontalAlignment = blockHorizontalAlignment;\n            return this;\n        }\n\n        @NonNull\n        public Builder padding(@Nullable Padding padding) {\n            this.padding = padding;\n            this.inlinePadding = padding;\n            this.blockPadding = padding;\n            return this;\n        }\n\n        @NonNull\n        public Builder inlinePadding(@Nullable Padding inlinePadding) {\n            this.inlinePadding = inlinePadding;\n            return this;\n        }\n\n        @NonNull\n        public Builder blockPadding(@Nullable Padding blockPadding) {\n            this.blockPadding = blockPadding;\n            return this;\n        }\n\n        @NonNull\n        public Builder textColor(@ColorInt int textColor) {\n            this.textColor = textColor;\n            return this;\n        }\n\n        @NonNull\n        public Builder inlineTextColor(@ColorInt int inlineTextColor) {\n            this.inlineTextColor = inlineTextColor;\n            return this;\n        }\n\n        @NonNull\n        public Builder blockTextColor(@ColorInt int blockTextColor) {\n            this.blockTextColor = blockTextColor;\n            return this;\n        }\n\n        @NonNull\n        public JLatexMathTheme build() {\n            return new Impl(this);\n        }\n    }\n\n    static class Impl extends JLatexMathTheme {\n\n        private final float textSize;\n        private final float inlineTextSize;\n        private final float blockTextSize;\n\n        private final BackgroundProvider backgroundProvider;\n        private final BackgroundProvider inlineBackgroundProvider;\n        private final BackgroundProvider blockBackgroundProvider;\n\n        private final boolean blockFitCanvas;\n        // horizontal alignment (when there is additional horizontal space)\n        private int blockHorizontalAlignment;\n\n        private final Padding padding;\n        private final Padding inlinePadding;\n        private final Padding blockPadding;\n\n        private final int textColor;\n        private final int inlineTextColor;\n        private final int blockTextColor;\n\n        Impl(@NonNull Builder builder) {\n            this.textSize = builder.textSize;\n            this.inlineTextSize = builder.inlineTextSize;\n            this.blockTextSize = builder.blockTextSize;\n            this.backgroundProvider = builder.backgroundProvider;\n            this.inlineBackgroundProvider = builder.inlineBackgroundProvider;\n            this.blockBackgroundProvider = builder.blockBackgroundProvider;\n            this.blockFitCanvas = builder.blockFitCanvas;\n            this.blockHorizontalAlignment = builder.blockHorizontalAlignment;\n            this.padding = builder.padding;\n            this.inlinePadding = builder.inlinePadding;\n            this.blockPadding = builder.blockPadding;\n            this.textColor = builder.textColor;\n            this.inlineTextColor = builder.inlineTextColor;\n            this.blockTextColor = builder.blockTextColor;\n        }\n\n        @Override\n        public float inlineTextSize() {\n            if (inlineTextSize > 0F) {\n                return inlineTextSize;\n            }\n            return textSize;\n        }\n\n        @Override\n        public float blockTextSize() {\n            if (blockTextSize > 0F) {\n                return blockTextSize;\n            }\n            return textSize;\n        }\n\n        @Nullable\n        @Override\n        public BackgroundProvider inlineBackgroundProvider() {\n            if (inlineBackgroundProvider != null) {\n                return inlineBackgroundProvider;\n            }\n            return backgroundProvider;\n        }\n\n        @Nullable\n        @Override\n        public BackgroundProvider blockBackgroundProvider() {\n            if (blockBackgroundProvider != null) {\n                return blockBackgroundProvider;\n            }\n            return backgroundProvider;\n        }\n\n        @Override\n        public boolean blockFitCanvas() {\n            return blockFitCanvas;\n        }\n\n        @Override\n        public int blockHorizontalAlignment() {\n            return blockHorizontalAlignment;\n        }\n\n        @Nullable\n        @Override\n        public Padding inlinePadding() {\n            if (inlinePadding != null) {\n                return inlinePadding;\n            }\n            return padding;\n        }\n\n        @Nullable\n        @Override\n        public Padding blockPadding() {\n            if (blockPadding != null) {\n                return blockPadding;\n            }\n            return padding;\n        }\n\n        @Override\n        public int inlineTextColor() {\n            if (inlineTextColor != 0) {\n                return inlineTextColor;\n            }\n            return textColor;\n        }\n\n        @Override\n        public int blockTextColor() {\n            if (blockTextColor != 0) {\n                return blockTextColor;\n            }\n            return textColor;\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-latex/src/main/java/io/noties/markwon/ext/latex/JLatextAsyncDrawable.java",
    "content": "package io.noties.markwon.ext.latex;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport io.noties.markwon.image.AsyncDrawable;\nimport io.noties.markwon.image.AsyncDrawableLoader;\nimport io.noties.markwon.image.ImageSize;\nimport io.noties.markwon.image.ImageSizeResolver;\n\n/**\n * @since 4.3.0\n */\nclass JLatextAsyncDrawable extends AsyncDrawable {\n\n    private final boolean isBlock;\n\n    JLatextAsyncDrawable(\n            @NonNull String destination,\n            @NonNull AsyncDrawableLoader loader,\n            @NonNull ImageSizeResolver imageSizeResolver,\n            @Nullable ImageSize imageSize,\n            boolean isBlock\n    ) {\n        super(destination, loader, imageSizeResolver, imageSize);\n        this.isBlock = isBlock;\n    }\n\n    public boolean isBlock() {\n        return isBlock;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-latex/src/test/java/io/noties/markwon/ext/latex/ExampleUnitTest.java",
    "content": "package io.noties.markwon.ext.latex;\n\nimport static org.junit.Assert.assertEquals;\n\nimport org.junit.Test;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "Android/AntFluid/markwon-ext-strikethrough/.gitignore",
    "content": "/build"
  },
  {
    "path": "Android/AntFluid/markwon-ext-strikethrough/build.gradle",
    "content": "plugins {\n    alias(libs.plugins.android.library)\n}\n\nandroid {\n    namespace 'io.noties.markwon.ext.strikethrough'\n    compileSdk 35\n\n    defaultConfig {\n        minSdk 21\n\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n        consumerProguardFiles \"consumer-rules.pro\"\n    }\n\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n        }\n    }\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_11\n        targetCompatibility JavaVersion.VERSION_11\n    }\n}\n\ndependencies {\n\n    implementation libs.androidx.appcompat\n    api fileTree(dir: 'libs', include: ['*.jar'])\n    compileOnly project(':markwon-core')\n    androidTestImplementation libs.androidx.junit\n    androidTestImplementation libs.androidx.espresso.core\n}"
  },
  {
    "path": "Android/AntFluid/markwon-ext-strikethrough/consumer-rules.pro",
    "content": ""
  },
  {
    "path": "Android/AntFluid/markwon-ext-strikethrough/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile"
  },
  {
    "path": "Android/AntFluid/markwon-ext-strikethrough/src/androidTest/java/io/noties/markwon/ext/strikethrough/ExampleInstrumentedTest.java",
    "content": "package io.noties.markwon.ext.strikethrough;\n\nimport static org.junit.Assert.assertEquals;\n\nimport android.content.Context;\n\nimport androidx.test.ext.junit.runners.AndroidJUnit4;\nimport androidx.test.platform.app.InstrumentationRegistry;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();\n        assertEquals(\"io.noties.markwon.ext.strikethrough.test\", appContext.getPackageName());\n    }\n}"
  },
  {
    "path": "Android/AntFluid/markwon-ext-strikethrough/src/main/AndroidManifest.xml",
    "content": "<manifest package=\"io.noties.markwon.ext.strikethrough\" />"
  },
  {
    "path": "Android/AntFluid/markwon-ext-strikethrough/src/main/java/io/noties/markwon/ext/strikethrough/StrikethroughPlugin.java",
    "content": "package io.noties.markwon.ext.strikethrough;\n\nimport android.text.style.StrikethroughSpan;\n\nimport androidx.annotation.NonNull;\n\nimport org.commonmark.ext.gfm.strikethrough.Strikethrough;\nimport org.commonmark.ext.gfm.strikethrough.StrikethroughExtension;\nimport org.commonmark.parser.Parser;\n\nimport java.util.Collections;\n\nimport io.noties.markwon.AbstractMarkwonPlugin;\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.MarkwonSpansFactory;\nimport io.noties.markwon.MarkwonVisitor;\nimport io.noties.markwon.RenderProps;\nimport io.noties.markwon.SpanFactory;\n\n/**\n * Plugin to add strikethrough markdown feature. This plugin will extend commonmark-java.Parser\n * with strikethrough extension, add SpanFactory and register commonmark-java.Strikethrough node\n * visitor\n *\n * @see #create()\n * @since 3.0.0\n */\npublic class StrikethroughPlugin extends AbstractMarkwonPlugin {\n\n    @NonNull\n    public static StrikethroughPlugin create() {\n        return new StrikethroughPlugin();\n    }\n\n    @Override\n    public void configureParser(@NonNull Parser.Builder builder) {\n        builder.extensions(Collections.singleton(StrikethroughExtension.create()));\n    }\n\n    @Override\n    public void configureSpansFactory(@NonNull MarkwonSpansFactory.Builder builder) {\n        builder.setFactory(Strikethrough.class, new SpanFactory() {\n            @Override\n            public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps props) {\n                return new StrikethroughSpan();\n            }\n        });\n    }\n\n    @Override\n    public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) {\n        builder.on(Strikethrough.class, new MarkwonVisitor.NodeVisitor<Strikethrough>() {\n            @Override\n            public void visit(@NonNull MarkwonVisitor visitor, @NonNull Strikethrough strikethrough) {\n                final int length = visitor.length();\n                visitor.visitChildren(strikethrough);\n                visitor.setSpansForNodeOptional(strikethrough, length);\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-strikethrough/src/test/java/io/noties/markwon/ext/strikethrough/ExampleUnitTest.java",
    "content": "package io.noties.markwon.ext.strikethrough;\n\nimport static org.junit.Assert.*;\n\nimport org.junit.Test;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tables/.gitignore",
    "content": "/build"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tables/build.gradle",
    "content": "plugins {\n    alias(libs.plugins.android.library)\n}\n\nandroid {\n    namespace 'io.noties.markwon.ext.tables'\n    compileSdk 35\n\n    defaultConfig {\n        minSdk 21\n\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n        consumerProguardFiles \"consumer-rules.pro\"\n    }\n\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n        }\n    }\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_11\n        targetCompatibility JavaVersion.VERSION_11\n    }\n}\n\ndependencies {\n\n    implementation libs.androidx.appcompat\n    api 'com.atlassian.commonmark:commonmark-ext-gfm-tables:0.13.0'\n    compileOnly project(':markwon-core')\n\n    testImplementation libs.junit\n    androidTestImplementation libs.androidx.junit\n    androidTestImplementation libs.androidx.espresso.core\n}"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tables/consumer-rules.pro",
    "content": ""
  },
  {
    "path": "Android/AntFluid/markwon-ext-tables/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tables/src/androidTest/java/io/noties/markwon/ext/tables/ExampleInstrumentedTest.java",
    "content": "package io.noties.markwon.ext.tables;\n\nimport static org.junit.Assert.assertEquals;\n\nimport android.content.Context;\n\nimport androidx.test.ext.junit.runners.AndroidJUnit4;\nimport androidx.test.platform.app.InstrumentationRegistry;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();\n        assertEquals(\"io.noties.markwon.ext.tables.test\", appContext.getPackageName());\n    }\n}"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tables/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest>\n\n</manifest>"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tables/src/main/java/com/fluid/afm/BaseBlockTitleSpan.java",
    "content": "package com.fluid.afm;\n\nimport android.content.ClipData;\nimport android.content.ClipboardManager;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport android.graphics.Paint;\nimport android.graphics.Path;\nimport android.graphics.Rect;\nimport android.graphics.RectF;\nimport android.graphics.drawable.Drawable;\nimport android.os.Bundle;\nimport android.text.Layout;\nimport android.text.Spanned;\nimport android.text.TextUtils;\nimport android.text.style.LeadingMarginSpan;\nimport android.view.View;\nimport android.widget.Toast;\n\nimport com.fluid.afm.utils.MDLogger;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport com.fluid.afm.span.CodeLanguageSpan;\nimport io.noties.markwon.ext.tables.R;\nimport io.noties.markwon.utils.SpanUtils;\n\npublic class BaseBlockTitleSpan implements LeadingMarginSpan {\n\n    protected static final String TAG = BaseBlockTitleSpan.class.getSimpleName();\n\n    protected final Rect rect = new Rect();\n    protected Drawable copyIcon;\n    protected Drawable magnifyIcon;\n\n    protected final HashMap<Rect, CodeSpanModel> copyRectMap;\n    protected final int parentHeight;\n    protected final int textSize;\n    protected int tableIndex;\n    protected String blockTitle = \"\";\n\n    public BaseBlockTitleSpan(Context context, int height, int textSize) {\n        this.copyRectMap = new HashMap<>();\n        this.parentHeight = height;\n        this.textSize = textSize;\n    }\n\n    public BaseBlockTitleSpan(Context context, int height, int textSize, int tableIndex) {\n        this.copyRectMap = new HashMap<>();\n        this.parentHeight = height;\n        this.textSize = textSize;\n        this.tableIndex = tableIndex;\n    }\n\n    @Override\n    public int getLeadingMargin(boolean b) {\n        return 0;\n    }\n\n    @Override\n    public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline, int bottom, CharSequence text, int start, int end, boolean first, Layout layout) {\n        if (!SpanUtils.isSelfStart(start, text, this)) return;\n\n        int save = c.save();\n        try {\n            final float oldStrokeWidth = p.getStrokeWidth();\n            final int oldColor = p.getColor();\n            final Paint.Style oldStyle = p.getStyle();\n            final float oldTextSize = p.getTextSize();\n\n            drawBackground(c, p, top, layout.getWidth());\n            drawBorder(c, p, top, layout.getWidth());\n            drawHeaderText(c, p, text, start, top, x);\n\n            drawCopyIcon(c, p, start, end, top, layout.getWidth(), magnifyIcon != null);\n            drawMagnifyIcon(c, p, start, end, top, layout.getWidth());\n\n            p.setStrokeWidth(oldStrokeWidth);\n            p.setColor(oldColor);\n            p.setStyle(oldStyle);\n            p.setTextSize(oldTextSize);\n        } finally {\n            c.restoreToCount(save);\n        }\n    }\n\n    private void drawBorder(Canvas c, Paint p, int top, int layoutWidth) {\n        if (!drawBorder()) {\n            return;\n        }\n        applyBorderStyle(p);\n        int saveCount = c.save();\n        float radius = getBackgroundRadius();\n        c.clipRect(0, 0, layoutWidth, top + rect.height());\n        if (p.getStrokeWidth() > 0 && p.getStrokeWidth() <= 1) {\n            p.setStrokeWidth(2);\n        }\n        float halfWidth = p.getStrokeWidth() / 2;\n        c.drawRoundRect(rect.left + halfWidth , rect.top + halfWidth, rect.right - halfWidth, rect.bottom + radius +  p.getStrokeWidth(), radius, radius, p);\n        c.restoreToCount(saveCount);\n        p.setStyle(Paint.Style.FILL);\n        p.setStrokeWidth(1);\n    }\n\n    protected boolean drawBorder() {\n        return false;\n    }\n    protected void applyBorderStyle(Paint paint) {\n\n    }\n    protected int getBackgroundColor() {\n        return Color.parseColor(\"#E7E7EC\");\n    }\n\n    /**\n     * draw background and border\n     *\n     * @param c\n     * @param p\n     * @param top\n     * @param layoutWidth\n     */\n    protected void drawBackground(Canvas c, Paint p, int top, int layoutWidth) {\n        float startX = 0;\n        float startY = top + parentHeight;\n        float stopX = startX + layoutWidth;\n        // background\n        p.setAlpha(1);\n        p.setStyle(Paint.Style.FILL);\n        rect.set(0, top, (int) stopX, (int) startY);\n        p.setColor(getBackgroundColor());\n        drawRectWithTopRound(c, p, rect.left, rect.top, rect.right, rect.bottom, getBackgroundRadius());\n        // 画分割线\n        if(drawLine()) {\n            p.setStrokeWidth(getBorderWidth());\n            p.setColor(getBorderColor());\n            c.drawLine(startX, startY, stopX, startY, p);\n        }\n    }\n\n    protected int getBorderColor() {\n        return 0xFFD3D8E1;\n    }\n    protected int getBorderWidth() {\n        return 3;\n    }\n\n    protected boolean drawLine() {\n        return true;\n    }\n\n    protected int getBackgroundRadius() {\n        return 24;\n    }\n\n    /**\n     * draw text (Code title)\n     *\n     * @param c\n     * @param p\n     * @param text\n     * @param start\n     * @param top\n     * @param x\n     */\n    private void drawHeaderText(Canvas c, Paint p, CharSequence text, int start, int top, int x) {\n        blockTitle = getBlockTitle(text, start);\n        Paint.FontMetricsInt fm = p.getFontMetricsInt();\n        int textHeight = fm.bottom - fm.top;\n        float centerY = (parentHeight - textHeight) / 2f - fm.top;\n        p.setColor(getTextColor());\n        boolean isbold = p.isFakeBoldText();\n        p.setFakeBoldText(true);\n        p.setTextSize(getTextSize());\n        c.drawText(blockTitle, x + getHeaderTextLeftPadding(), top + centerY, p);\n        p.setFakeBoldText(isbold);\n    }\n\n    protected float getTextSize() {\n        return textSize;\n    }\n    protected int getTextColor() {\n        return 0xFF13113E;\n    }\n\n    protected int getHeaderTextLeftPadding() {\n        return 0;\n    }\n\n    private void drawCopyIcon(Canvas c, Paint p, int start, int end, int top, int layoutWidth, boolean isDrawMagnifyIcon) {\n        if (copyIcon == null) return;\n\n        float w = (float) copyIcon.getBounds().width();\n        float left = isDrawMagnifyIcon ? layoutWidth - (w + (w / 4F)) * 2 : layoutWidth - (w + (w / 4F));\n\n        CodeBlockTitleSpan.CodeSpanModel copyModel = new CodeBlockTitleSpan.CodeSpanModel();\n        copyModel.spanStart = start;\n        copyModel.spanEnd = end;\n        copyModel.clickRectType = CodeBlockTitleSpan.ClickRectType.TYPE_COPY;\n        Rect copyRect = new Rect((int) left, top, (int) (left + w), top + parentHeight);\n        copyRectMap.put(copyRect, copyModel);\n\n        final int iconTopPadding = (parentHeight - copyIcon.getBounds().height()) / 2;\n        c.save();\n        c.translate(left, top + iconTopPadding);\n        copyIcon.draw(c);\n        c.restore();\n    }\n\n    private void drawMagnifyIcon(Canvas c, Paint p, int start, int end, int top, int layoutWidth) {\n        if (magnifyIcon == null) return;\n\n        int rightPadding = getIconRightMargin();\n        float w = (float) magnifyIcon.getBounds().width();\n        float left = layoutWidth - w - (w / 4F) - rightPadding;\n\n        // 保存copy icon的坐标\n        CodeBlockTitleSpan.CodeSpanModel magnifyModel = new CodeBlockTitleSpan.CodeSpanModel();\n        magnifyModel.spanStart = start;\n        magnifyModel.spanEnd = end;\n        magnifyModel.clickRectType = CodeBlockTitleSpan.ClickRectType.TYPE_MAGNIFY;\n        Rect magnifyRect = new Rect((int) left, top, (int) (left + w), top + parentHeight);\n        copyRectMap.put(magnifyRect, magnifyModel);\n\n        // 画magnify icon\n        final int iconTopPadding = (parentHeight - magnifyIcon.getBounds().height()) / 2;\n        c.save();\n        c.translate(left, top + iconTopPadding);\n        magnifyIcon.draw(c);\n        c.restore();\n    }\n\n    protected int getIconRightMargin() {\n        return 0;\n    }\n\n    private void drawRectWithTopRound(Canvas canvas, Paint paint,\n                                      float left, float top, float right, float bottom,\n                                      float radius) {\n        Path path = new Path();\n        path.moveTo(left, top + radius);\n        path.arcTo(new RectF(left, top, left + 2 * radius, top + 2 * radius), 180, 90);\n        path.lineTo(right - radius, top);\n        path.arcTo(new RectF(right - 2 * radius, top, right, top + 2 * radius), 270, 90);\n        path.lineTo(right, bottom);\n        path.lineTo(left, bottom);\n        path.lineTo(left, top + radius);\n        path.close();\n\n        canvas.drawPath(path, paint);\n    }\n\n    protected String getBlockTitle(CharSequence text, int start) {\n        if (text instanceof Spanned) {\n            CodeLanguageSpan[] codeLanguageSpans = ((Spanned) text).getSpans(start, text.length(), CodeLanguageSpan.class);\n            if (codeLanguageSpans == null || codeLanguageSpans.length == 0) {\n                return \"Code\";\n            }\n            return codeLanguageSpans[codeLanguageSpans.length - 1].getLanguage();\n        }\n        return \"Code\";\n    }\n\n\n    protected CodeBlockTitleSpan.CodeSpanModel whoClicked(int x, int y) {\n        for (Map.Entry<Rect, CodeBlockTitleSpan.CodeSpanModel> entry : copyRectMap.entrySet()) {\n            Rect key = entry.getKey();\n            CodeBlockTitleSpan.CodeSpanModel value = entry.getValue();\n            if (x >= key.left && x <= key.right && y >= key.top && y <= key.bottom) {\n                return value;\n            }\n        }\n\n        return null;\n    }\n\n    public boolean handleClickEvent(View widget, Spanned spanned, int x, int y) {\n        return false;\n    }\n\n    /**\n     * copy\n     *\n     * @param widget\n     * @param codeContent\n     */\n    public void onCopyClicked(final View widget, final String codeContent) {\n        if (TextUtils.isEmpty(codeContent)) {\n            MDLogger.e(TAG, \"onCopyClicked...code is null\");\n            Toast.makeText(widget.getContext(), R.string.copy_failed, Toast.LENGTH_SHORT).show();\n            return;\n        }\n\n        MDLogger.d(TAG, \"onCopyClicked...\");\n        ClipboardManager clipboard = (ClipboardManager)\n                widget.getContext().getSystemService(Context.CLIPBOARD_SERVICE);\n        ClipData clip = ClipData.newPlainText(\"\", codeContent);\n        clipboard.setPrimaryClip(clip);\n        Toast.makeText(widget.getContext(), R.string.copied, Toast.LENGTH_SHORT).show();\n    }\n\n\n    public void onMagnifyClicked(View widget, String content) {\n        try {\n            Intent intent = new Intent(widget.getContext(), Class.forName(\"com.fluid.afm.ui.MarkDownPreviewActivity\"));\n            intent.putExtras(getPreviewBundle(content));\n            widget.getContext().startActivity(intent);\n        } catch (ClassNotFoundException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    protected Bundle getPreviewBundle( String content) {\n        Bundle bundle = new Bundle();\n        bundle.putString(\"content\", content);\n        return bundle;\n    }\n\n\n    public static class CodeSpanModel {\n        public int spanStart;\n        public int spanEnd;\n        public ClickRectType clickRectType;\n\n        @Override\n        public String toString() {\n            return spanStart + \",\" + spanEnd + \",clickRectType:\" + clickRectType;\n        }\n    }\n\n    public enum ClickRectType {\n        /**\n         * copy\n         */\n        TYPE_COPY,\n        /**\n         * magnify\n         */\n        TYPE_MAGNIFY\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tables/src/main/java/com/fluid/afm/CodeBlockLineSpacingSpan.java",
    "content": "package com.fluid.afm;\n\nimport android.graphics.Paint;\nimport android.text.Spanned;\n\npublic class CodeBlockLineSpacingSpan extends TopSpacingSpan {\n    private final int reducedLineHeight;\n    private final int firstLastLineReducedHeight;\n\n    public CodeBlockLineSpacingSpan(int topLineSpacingHeight, int reducedLineHeight) {\n        super(topLineSpacingHeight);\n        this.reducedLineHeight = reducedLineHeight;\n        this.firstLastLineReducedHeight = (int) ((reducedLineHeight - 0.5f) * 6);\n    }\n\n    @Override\n    public void chooseHeight(CharSequence text, int start, int end,\n                             int spanstartv,\n                             int v, Paint.FontMetricsInt fm) {\n        super.chooseHeight(text, start, end, spanstartv, v, fm);\n        fm.ascent += (reducedLineHeight / 2);\n        fm.descent -= (reducedLineHeight / 2);\n\n        if (selfStart(start, text, this)) {\n            fm.top += firstLastLineReducedHeight;\n            fm.ascent += firstLastLineReducedHeight;\n        } else if (selfEnd(start, text, this)) {\n            fm.bottom -= firstLastLineReducedHeight;\n            fm.descent -= firstLastLineReducedHeight;\n        }\n    }\n\n    private boolean selfEnd(int end, CharSequence text, Object span) {\n        final int spanEnd = ((Spanned) text).getSpanEnd(span);\n        return spanEnd == end || spanEnd == end - 1;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tables/src/main/java/com/fluid/afm/CodeBlockTitleSpan.java",
    "content": "package com.fluid.afm;\n\nimport android.content.Context;\nimport android.graphics.Paint;\nimport android.os.Bundle;\nimport android.text.Spanned;\nimport android.view.View;\n\nimport androidx.annotation.Keep;\nimport androidx.appcompat.content.res.AppCompatResources;\n\nimport com.fluid.afm.utils.MDLogger;\n\nimport io.noties.markwon.core.MarkwonTheme;\nimport com.fluid.afm.span.CodeLanguageSpan;\nimport io.noties.markwon.ext.tables.R;\nimport com.fluid.afm.utils.Utils;\n\n@Keep\npublic class CodeBlockTitleSpan extends BaseBlockTitleSpan {\n    protected static final String TAG = CodeBlockTitleSpan.class.getSimpleName();\n\n    private MarkwonTheme mMarkwonTheme;\n\n    public CodeBlockTitleSpan(Context context, MarkwonTheme theme, int height, int textSize) {\n        super(context, height, textSize);\n        try {\n            this.mMarkwonTheme = theme;\n            magnifyIcon = AppCompatResources.getDrawable(context, R.drawable.icon_table_magnify_light);\n            copyIcon = AppCompatResources.getDrawable(context, R.drawable.icon_table_copy_light);\n            final int size = Utils.dpToPx(context, 22);\n            copyIcon.setBounds(0, 0, size, size);\n            magnifyIcon.setBounds(0, 0, size, size);\n        } catch (Throwable e) {\n            MDLogger.d(TAG, \"CodeBlockHeaderSpan e:\" + e);\n        }\n    }\n\n    protected int getBackgroundRadius() {\n        if (mMarkwonTheme != null && mMarkwonTheme.getCodeBackgroundRadius() >= 0) {\n            return mMarkwonTheme.getCodeBackgroundRadius();\n        }\n        return 24;\n    }\n\n    public CodeBlockTitleSpan(Context context, int height, int textSize, int tableIndex) {\n        super(context, height, textSize, tableIndex);\n        try {\n            copyIcon = AppCompatResources.getDrawable(context, R.drawable.icon_table_copy_light);\n            if (copyIcon != null) {\n                final int width = Utils.dpToPx(context, 22);\n                copyIcon.setBounds(0, 0, width, width);\n            }\n        } catch (Throwable e) {\n            MDLogger.e(TAG, e);\n        }\n    }\n\n    @Override\n    protected boolean drawBorder() {\n        return mMarkwonTheme.codeStyle().isDrawBorder();\n    }\n\n    @Override\n    protected void applyBorderStyle(Paint paint) {\n        paint.setStyle(Paint.Style.STROKE);\n        paint.setColor(mMarkwonTheme.codeStyle().borderColor());\n        paint.setStrokeWidth(mMarkwonTheme.codeStyle().borderWidth());\n    }\n\n    protected String getBlockContent(ClickRectType clickRectType, Spanned spanned, int start) {\n        StringBuilder stringBuilder = new StringBuilder();\n        try {\n            String code = spanned.subSequence(start, spanned.getSpanEnd(this)).toString().trim();\n            if (clickRectType == ClickRectType.TYPE_MAGNIFY) {\n                stringBuilder.append(\"```\").append(blockTitle).append(code.replace(\"\\u00A0\", \"\")).append(\"```\");\n            } else if (clickRectType == ClickRectType.TYPE_COPY) {\n                stringBuilder.append(code.replace(\"\\u00A0\", \"\"));\n            }\n        } catch (Exception e) {\n            MDLogger.e(TAG, \"getBlockContent\", e);\n        }\n        return stringBuilder.toString();\n    }\n\n    @Override\n    public boolean handleClickEvent(View widget, Spanned spanned, int x, int y) {\n        CodeSpanModel spanModel = whoClicked(x, y);\n        if (spanModel == null) {\n            MDLogger.d(TAG, \"handleClickEvent nobody clicked\");\n            return false;\n        }\n        MDLogger.d(TAG, \"handleClickEvent:\" + spanModel);\n        String code = getBlockContent(spanModel.clickRectType, spanned, spanModel.spanStart);\n        if (spanModel.clickRectType == ClickRectType.TYPE_COPY) {\n            // copy clicked\n            onCopyClicked(widget, code);\n        } else if (spanModel.clickRectType == ClickRectType.TYPE_MAGNIFY) {\n            // magnify clicked\n            onMagnifyClicked(widget, code);\n        }\n        return true;\n    }\n\n\n    protected String getBlockTitle(CharSequence text, int start) {\n        if (text instanceof Spanned) {\n            CodeLanguageSpan[] codeLanguageSpans = ((Spanned) text).getSpans(start, text.length(), CodeLanguageSpan.class);\n            if (codeLanguageSpans == null || codeLanguageSpans.length == 0) {\n                return \"\";\n            }\n            return codeLanguageSpans[codeLanguageSpans.length - 1].getLanguage();\n        }\n        return \"\";\n    }\n\n    @Override\n    protected int getTextColor() {\n        if (mMarkwonTheme.codeStyle().titleFontColor() != 0) {\n            return mMarkwonTheme.codeStyle().titleFontColor();\n        }\n        return super.getTextColor();\n    }\n\n    @Override\n    protected float getTextSize() {\n        if (mMarkwonTheme.codeStyle().titleFontSize() > 0) {\n            return mMarkwonTheme.codeStyle().titleFontSize();\n        }\n        return super.getTextSize();\n    }\n\n    @Override\n    protected int getBackgroundColor() {\n        if (mMarkwonTheme.codeStyle().titleBackgroundColor() != 0) {\n            return mMarkwonTheme.codeStyle().titleBackgroundColor();\n        }\n        return super.getBackgroundColor();\n    }\n\n    @Override\n    protected int getBorderColor() {\n        if (mMarkwonTheme.codeStyle().borderColor() != 0) {\n            return mMarkwonTheme.codeStyle().borderColor();\n        }\n        return super.getBorderColor();\n    }\n\n    @Override\n    protected int getBorderWidth() {\n        return mMarkwonTheme.codeStyle().borderWidth();\n    }\n\n    protected Bundle getPreviewBundle(String content) {\n        Bundle bundle = super.getPreviewBundle(content);\n        bundle.putParcelable(\"codeStyle\", mMarkwonTheme.codeStyle());\n        bundle.putBoolean(\"isCode\", true);\n        return bundle;\n    }\n\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tables/src/main/java/com/fluid/afm/IMarkdownLayer.java",
    "content": "package com.fluid.afm;\n\npublic interface IMarkdownLayer {\n    int getViewMaxWidth();\n\n    String getOriginText();\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tables/src/main/java/com/fluid/afm/MarkdownAwareMovementMethod.java",
    "content": "package com.fluid.afm;\n\nimport android.text.Layout;\nimport android.text.Spannable;\nimport android.text.method.LinkMovementMethod;\nimport android.text.method.MovementMethod;\nimport android.view.KeyEvent;\nimport android.view.MotionEvent;\nimport android.widget.TextView;\n\nimport androidx.annotation.NonNull;\n\nimport com.fluid.afm.utils.MDLogger;\n\nimport io.noties.markwon.image.AsyncDrawableSpan;\n\n/**\n * @since 4.6.0\n */\npublic class MarkdownAwareMovementMethod implements MovementMethod {\n    private static final String TAG = MarkdownAwareMovementMethod.class.getSimpleName();\n\n    @NonNull\n    public static MarkdownAwareMovementMethod wrap(@NonNull MovementMethod movementMethod) {\n        return new MarkdownAwareMovementMethod(movementMethod);\n    }\n\n    /**\n     * Wraps LinkMovementMethod\n     */\n    @NonNull\n    public static MarkdownAwareMovementMethod create() {\n        return new MarkdownAwareMovementMethod(LinkMovementMethod.getInstance());\n    }\n\n    public static boolean handleCodeBlockTouchEvent(\n            @NonNull TextView widget,\n            @NonNull Spannable buffer,\n            @NonNull MotionEvent event) {\n        // handle only action up (originally action down is used in order to handle selection,\n        //  which tables do no have)\n        if (event.getAction() != MotionEvent.ACTION_UP) {\n            return false;\n        }\n\n        int x = (int) event.getX();\n        int y = (int) event.getY();\n        x -= widget.getTotalPaddingLeft();\n        y -= widget.getTotalPaddingTop();\n        x += widget.getScrollX();\n        y += widget.getScrollY();\n\n        final Layout layout = widget.getLayout();\n        final int line = layout.getLineForVertical(y);\n        final int off = layout.getOffsetForHorizontal(line, x);\n\n        final CodeBlockTitleSpan[] spans = buffer.getSpans(off, off, CodeBlockTitleSpan.class);\n        if (spans.length == 0) {\n            return false;\n        }\n\n        return spans[0].handleClickEvent(widget, buffer, x, y);\n    }\n\n    public static boolean handleTableRowTouchEvent(\n            @NonNull TextView widget,\n            @NonNull Spannable buffer,\n            @NonNull MotionEvent event) {\n        // handle only action up (originally action down is used in order to handle selection,\n        //  which tables do no have)\n        if (event.getAction() != MotionEvent.ACTION_UP) {\n            return false;\n        }\n\n        int x = (int) event.getX();\n        int y = (int) event.getY();\n        x -= widget.getTotalPaddingLeft();\n        y -= widget.getTotalPaddingTop();\n        x += widget.getScrollX();\n        y += widget.getScrollY();\n\n        final Layout layout = widget.getLayout();\n        final int line = layout.getLineForVertical(y);\n        final int off = layout.getOffsetForHorizontal(line, x);\n\n        final TableBlockTitleBlockSpan[] spans = buffer.getSpans(off, off, TableBlockTitleBlockSpan.class);\n        if (spans.length == 0) {\n            return false;\n        }\n\n        MDLogger.d(TAG, \"handleTableRowTouchEvent length:\" + spans.length\n                + \",line:\" + line\n                + \",off:\" + off\n                + \",x:\" + x + \",y:\" + y);\n\n        return spans[0].handleClickEvent(widget, buffer, x, y);\n    }\n\n    private final MovementMethod wrapped;\n\n    public MarkdownAwareMovementMethod(@NonNull MovementMethod wrapped) {\n        this.wrapped = wrapped;\n    }\n\n    @Override\n    public void initialize(TextView widget, Spannable text) {\n        wrapped.initialize(widget, text);\n    }\n\n    @Override\n    public boolean onKeyDown(TextView widget, Spannable text, int keyCode, KeyEvent event) {\n        return wrapped.onKeyDown(widget, text, keyCode, event);\n    }\n\n    @Override\n    public boolean onKeyUp(TextView widget, Spannable text, int keyCode, KeyEvent event) {\n        return wrapped.onKeyUp(widget, text, keyCode, event);\n    }\n\n    @Override\n    public boolean onKeyOther(TextView view, Spannable text, KeyEvent event) {\n        return wrapped.onKeyOther(view, text, event);\n    }\n\n    @Override\n    public void onTakeFocus(TextView widget, Spannable text, int direction) {\n        wrapped.onTakeFocus(widget, text, direction);\n    }\n\n    @Override\n    public boolean onTrackballEvent(TextView widget, Spannable text, MotionEvent event) {\n        return wrapped.onTrackballEvent(widget, text, event);\n    }\n\n    @Override\n    public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {\n        // let wrapped handle first, then if super handles nothing, search for table row spans\n        return wrapped.onTouchEvent(widget, buffer, event)\n                || handleTableRowTouchEvent(widget, buffer, event)\n                || handleCodeBlockTouchEvent(widget, buffer, event)\n                || handleImageTouchEvent(widget, buffer, event);\n    }\n\n    private boolean handleImageTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {\n        if (event.getAction() != MotionEvent.ACTION_UP) {\n            return false;\n        }\n\n        int x = (int) event.getX();\n        int y = (int) event.getY();\n        x -= widget.getTotalPaddingLeft();\n        y -= widget.getTotalPaddingTop();\n        x += widget.getScrollX();\n        y += widget.getScrollY();\n\n        final Layout layout = widget.getLayout();\n        final int line = layout.getLineForVertical(y);\n        final int off = layout.getOffsetForHorizontal(line, x);\n\n        final AsyncDrawableSpan[] spans = buffer.getSpans(off, off, AsyncDrawableSpan.class);\n        if (spans.length == 0) {\n            return false;\n        }\n        for (AsyncDrawableSpan span : spans) {\n            if (span.getTop() <= y && span.getBottom() >= y) {\n                span.click();\n            }\n        }\n\n        return false;\n    }\n\n    @Override\n    public boolean onGenericMotionEvent(TextView widget, Spannable text, MotionEvent event) {\n        return wrapped.onGenericMotionEvent(widget, text, event);\n    }\n\n    @Override\n    public boolean canSelectArbitrarily() {\n        return wrapped.canSelectArbitrarily();\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tables/src/main/java/com/fluid/afm/TableBlockTitleBlockSpan.java",
    "content": "package com.fluid.afm;\n\nimport android.content.Context;\nimport android.content.Intent;\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.os.Bundle;\nimport android.text.Spanned;\nimport android.text.TextUtils;\nimport android.view.View;\nimport android.widget.TextView;\n\nimport androidx.appcompat.content.res.AppCompatResources;\n\nimport com.fluid.afm.styles.TableStyle;\nimport com.fluid.afm.utils.MDLogger;\nimport com.fluid.afm.utils.Utils;\n\nimport org.commonmark.ext.gfm.tables.TableBlock;\n\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\nimport io.noties.markwon.ext.tables.R;\n\npublic class TableBlockTitleBlockSpan extends BaseBlockTitleSpan {\n    private static final String TAG = \"TableBlockTitleBlockSpan\";\n    private final int textLeftPadding;\n    private final TableStyle mStyle;\n    private int columnCount;\n    private boolean countIndex = false;\n    private TableBlock mTableBlock;\n    private static TableBlock sCurrentTableBlock;\n\n    public static void setCurrentTableBlock(TableBlock currentTableBlock) {\n        sCurrentTableBlock = currentTableBlock;\n    }\n\n    public static TableBlock getCurrentTableBlock() {\n        return sCurrentTableBlock;\n    }\n\n    public TableBlockTitleBlockSpan(Context context, int height, TableStyle style, int tableIndex, int columnCount, boolean countIndex, TableBlock tableBlock) {\n        super(context, height, (int) style.title().fontSize(), tableIndex);\n        this.countIndex = countIndex;\n        try {\n            magnifyIcon = AppCompatResources.getDrawable(context, R.drawable.icon_table_magnify_light);\n            final int width = Utils.dpToPx(context, 20);\n            magnifyIcon.setBounds(0, 0, width, width);\n            this.columnCount = columnCount;\n        } catch (Throwable e) {\n            MDLogger.e(TAG, e);\n        }\n        mStyle = style;\n        textLeftPadding = mStyle.cellLeftRightPadding();\n        mTableBlock = tableBlock;\n    }\n\n    public void setTableBlock(TableBlock tableBlock) {\n        mTableBlock = tableBlock;\n    }\n\n    @Override\n    protected int getBackgroundColor() {\n        return mStyle.title().backgroundColor();\n    }\n\n    protected boolean drawLine() {\n        return false;\n    }\n\n    @Override\n    protected float getTextSize() {\n        return mStyle.title().fontSize();\n    }\n\n    @Override\n    protected void drawBackground(Canvas c, Paint p, int top, int layoutWidth) {\n        super.drawBackground(c, p, top, layoutWidth);\n        if (!mStyle.drawBorder()) {\n            return;\n        }\n        mStyle.applyTableBorderStyle(p);\n        // 绘制圆角矩形的描边\n        int saveCount = c.save();\n        float radius = getBackgroundRadius(); // 圆角半径，应与 drawRectWithTopRound 中使用的值一致\n        c.clipRect(0, 0, layoutWidth, top + rect.height());\n        if (p.getStrokeWidth() > 0 && p.getStrokeWidth() <= 1) {\n            p.setStrokeWidth(2);\n        }\n        float halfWidth = p.getStrokeWidth() / 2;\n        c.drawRoundRect(rect.left + halfWidth, rect.top + halfWidth, rect.right - halfWidth, rect.bottom + radius + p.getStrokeWidth(), radius, radius, p);\n        c.restoreToCount(saveCount);\n        // 恢复Paint状态\n        p.setStyle(Paint.Style.FILL); // 恢复为填充模式\n        p.setStrokeWidth(1); // 恢复默认线宽\n    }\n\n    @Override\n    protected boolean drawBorder() {\n        return mStyle.drawBorder();\n    }\n\n    @Override\n    protected void applyBorderStyle(Paint paint) {\n        mStyle.applyTableBorderStyle(paint);\n    }\n\n    @Override\n    protected int getBorderColor() {\n        return mStyle.borderColor();\n    }\n\n    protected int getBackgroundRadius() {\n        return mStyle.titleBackgroundRadius();\n    }\n\n    protected int getIconRightMargin() {\n        return 16;\n    }\n\n    protected int getHeaderTextLeftPadding() {\n        return textLeftPadding;\n    }\n\n    /**\n     * 获取当前table block的语音类型\n     *\n     * @param text\n     * @param start\n     * @return\n     */\n    protected String getBlockTitle(CharSequence text, int start) {\n        if (ContextHolder.getContext() != null) {\n            return ContextHolder.getContext().getResources().getString(R.string.table);\n        }\n        return \"Table\";\n    }\n\n    @Override\n    protected int getTextColor() {\n        return mStyle.title().fontColor();\n    }\n\n    protected String getBlockContent(View view) {\n        return getTableMarkdown(view);\n    }\n\n    @Override\n    public boolean handleClickEvent(View widget, Spanned spanned, int x, int y) {\n        CodeSpanModel spanModel = whoClicked(x, y);\n        if (spanModel == null) {\n            MDLogger.d(TAG, \"handleClickEvent nobody clicked\");\n            return false;\n        } else {\n            MDLogger.d(TAG, \"handleClickEvent:\" + spanModel);\n            String code = getBlockContent(widget);\n            if (spanModel.clickRectType == CodeBlockTitleSpan.ClickRectType.TYPE_COPY) {\n                onCopyClicked(widget, code);\n            } else if (spanModel.clickRectType == CodeBlockTitleSpan.ClickRectType.TYPE_MAGNIFY) {\n                onMagnifyClicked(widget, \"\");\n            }\n            return true;\n        }\n    }\n\n    @Override\n    public void onMagnifyClicked(View widget, String content) {\n        try {\n            Intent intent = new Intent(widget.getContext(), Class.forName(\"com.fluid.afm.ui.MarkDownPreviewActivity\"));\n            Bundle bundle = new Bundle();\n            if (mTableBlock != null) {\n                sCurrentTableBlock = mTableBlock;\n            }\n            if (mStyle != null) {\n                bundle.putBoolean(\"hasTableStyle\",true);\n                bundle.putParcelable(\"tableStyle\", mStyle);\n            } else {\n                bundle.putBoolean(\"hasTableStyle\", false);\n            }\n            bundle.putInt(\"columnCount\", columnCount);\n            bundle.putBoolean(\"isTable\", true);\n            intent.putExtras(bundle);\n            widget.getContext().startActivity(intent);\n        } catch (ClassNotFoundException e) {\n            throw new RuntimeException(e);\n        }\n    }\n    protected Bundle getPreviewBundle(String content) {\n        Bundle bundle = super.getPreviewBundle(content);\n        bundle.putParcelable(\"tableStyle\", mStyle);\n        bundle.putInt(\"columnCount\", columnCount);\n        bundle.putBoolean(\"isTable\", true);\n        return bundle;\n    }\n\n    protected String getTableMarkdown(View view) {\n        if (!(view instanceof TextView)) {\n            return null;\n        } else {\n            String markdown = null;\n            if (view instanceof IMarkdownLayer) {\n                markdown = ((IMarkdownLayer) view).getOriginText();\n            }\n            if (TextUtils.isEmpty(markdown)) {\n                return \"\";\n            } else {\n                String regex = \"\\\\|[^\\\\n]*\\\\|(\\\\n\\\\|[:\\\\s\\\\-\\\\|]*\\\\|)+\\\\n(\\\\|[^\\\\n]*\\\\|\\\\n?)*\";\n                Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);\n                Matcher matcher = pattern.matcher(markdown);\n                int index = tableIndex;\n                String table = null;\n                if (countIndex) {\n                    while (index >= 0 && matcher.find()) {\n                        table = matcher.group();\n                        index--;\n                    }\n                } else if (matcher.find()) {\n                    table = matcher.group();\n                }\n                MDLogger.d(TAG, \"getTableMarkdown get table markdown: \" + table);\n                return table;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tables/src/main/java/com/fluid/afm/TableLineSpacingSpan.java",
    "content": "package com.fluid.afm;\n\nimport android.graphics.Paint;\nimport android.text.style.LineHeightSpan;\n\npublic class TableLineSpacingSpan implements LineHeightSpan {\n    private final int reducedLineHeight;\n\n    private final boolean header;\n\n    public TableLineSpacingSpan(boolean header, int reducedLineHeight) {\n        this.header = header;\n        this.reducedLineHeight = reducedLineHeight;\n    }\n\n    @Override\n    public void chooseHeight(CharSequence text, int start, int end,\n                             int spanstartv,\n                             int v, Paint.FontMetricsInt fm) {\n\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tables/src/main/java/com/fluid/afm/TopSpacingSpan.java",
    "content": "package com.fluid.afm;\n\nimport android.graphics.Paint;\nimport android.text.Spanned;\nimport android.text.style.LineHeightSpan;\n\npublic class TopSpacingSpan implements LineHeightSpan {\n\n    private final int height;\n\n    public TopSpacingSpan(int height) {\n        this.height = height;\n    }\n\n    @Override\n    public void chooseHeight(CharSequence text, int start, int end,\n                             int spanstartv,\n                             int v, Paint.FontMetricsInt fm) {\n        if (selfStart(start, text, this)) {\n            fm.top -= height;\n            fm.ascent -= height;\n        }\n    }\n\n    protected boolean selfStart(int start, CharSequence text, Object span) {\n        // this is some kind of interesting magic here... only the last\n        // span will receive correct _end_ argument, but previous spans\n        // receive it tilted by one (1). Most likely it's just a new-line character... and\n        // if needed we could check for that\n        final int spanStart = ((Spanned) text).getSpanStart(span);\n        return spanStart == start;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tables/src/main/java/io/noties/markwon/ext/tables/Table.java",
    "content": "package io.noties.markwon.ext.tables;\n\nimport android.text.Spanned;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport org.commonmark.ext.gfm.tables.TableBlock;\nimport org.commonmark.ext.gfm.tables.TableCell;\nimport org.commonmark.ext.gfm.tables.TableHead;\nimport org.commonmark.ext.gfm.tables.TableRow;\nimport org.commonmark.node.AbstractVisitor;\nimport org.commonmark.node.CustomNode;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport io.noties.markwon.Markwon;\n\n/**\n * A class to parse <code>TableBlock</code> and return a data-structure that is not dependent\n * on commonmark-java table extension. Can be useful when rendering tables require special\n * handling (multiple views, specific table view) for example when used with `markwon-recycler` artifact\n *\n * @see #parse(Markwon, TableBlock)\n * @since 3.0.0\n */\npublic class Table {\n\n    /**\n     * Factory method to obtain an instance of {@link Table}\n     *\n     * @param markwon    Markwon\n     * @param tableBlock TableBlock to parse\n     * @return parsed {@link Table} or null\n     */\n    @Nullable\n    public static Table parse(@NonNull Markwon markwon, @NonNull TableBlock tableBlock) {\n\n        final Table table;\n\n        final ParseVisitor visitor = new ParseVisitor(markwon);\n        tableBlock.accept(visitor);\n        final List<Row> rows = visitor.rows();\n\n        if (rows == null) {\n            table = null;\n        } else {\n            table = new Table(rows);\n        }\n\n        return table;\n    }\n\n    public static class Row {\n\n        private final boolean isHeader;\n        private final List<Column> columns;\n\n        public Row(\n                boolean isHeader,\n                @NonNull List<Column> columns) {\n            this.isHeader = isHeader;\n            this.columns = columns;\n        }\n\n        public boolean header() {\n            return isHeader;\n        }\n\n        @NonNull\n        public List<Column> columns() {\n            return columns;\n        }\n\n        @Override\n        public String toString() {\n            return \"Row{\" +\n                    \"isHeader=\" + isHeader +\n                    \", columns=\" + columns +\n                    '}';\n        }\n    }\n\n    public static class Column {\n\n        private final Alignment alignment;\n        private final Spanned content;\n\n        public Column(@NonNull Alignment alignment, @NonNull Spanned content) {\n            this.alignment = alignment;\n            this.content = content;\n        }\n\n        @NonNull\n        public Alignment alignment() {\n            return alignment;\n        }\n\n        @NonNull\n        public Spanned content() {\n            return content;\n        }\n\n        @Override\n        public String toString() {\n            return \"Column{\" +\n                    \"alignment=\" + alignment +\n                    \", content=\" + content +\n                    '}';\n        }\n    }\n\n    public enum Alignment {\n        LEFT,\n        CENTER,\n        RIGHT\n    }\n\n    private final List<Row> rows;\n\n    public Table(@NonNull List<Row> rows) {\n        this.rows = rows;\n    }\n\n    @NonNull\n    public List<Row> rows() {\n        return rows;\n    }\n\n    @Override\n    public String toString() {\n        return \"Table{\" +\n                \"rows=\" + rows +\n                '}';\n    }\n\n    static class ParseVisitor extends AbstractVisitor {\n\n        private final Markwon markwon;\n\n        private List<Row> rows;\n\n        private List<Column> pendingRow;\n        private boolean pendingRowIsHeader;\n\n        ParseVisitor(@NonNull Markwon markwon) {\n            this.markwon = markwon;\n        }\n\n        @Nullable\n        public List<Row> rows() {\n            return rows;\n        }\n\n        @Override\n        public void visit(CustomNode customNode) {\n\n            if (customNode instanceof TableCell) {\n\n                final TableCell cell = (TableCell) customNode;\n\n                if (pendingRow == null) {\n                    pendingRow = new ArrayList<>(2);\n                }\n\n                pendingRow.add(new Table.Column(alignment(cell.getAlignment()), markwon.render(cell)));\n                pendingRowIsHeader = cell.isHeader();\n\n                return;\n            }\n\n            if (customNode instanceof TableHead\n                    || customNode instanceof TableRow) {\n\n                visitChildren(customNode);\n\n                // this can happen, ignore such row\n                if (pendingRow != null && pendingRow.size() > 0) {\n\n                    if (rows == null) {\n                        rows = new ArrayList<>(2);\n                    }\n\n                    rows.add(new Table.Row(pendingRowIsHeader, pendingRow));\n                }\n\n                pendingRow = null;\n                pendingRowIsHeader = false;\n\n                return;\n            }\n\n            visitChildren(customNode);\n        }\n\n        @NonNull\n        private static Table.Alignment alignment(@NonNull TableCell.Alignment alignment) {\n            final Table.Alignment out;\n            if (TableCell.Alignment.RIGHT == alignment) {\n                out = Table.Alignment.RIGHT;\n            } else if (TableCell.Alignment.CENTER == alignment) {\n                out = Table.Alignment.CENTER;\n            } else {\n                out = Table.Alignment.LEFT;\n            }\n            return out;\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tables/src/main/java/io/noties/markwon/ext/tables/TablePlugin.java",
    "content": "package io.noties.markwon.ext.tables;\n\nimport android.content.Context;\nimport android.text.Spanned;\nimport android.text.TextUtils;\nimport android.widget.TextView;\n\nimport androidx.annotation.NonNull;\n\nimport com.fluid.afm.StreamOutStateObserver;\nimport com.fluid.afm.TableBlockTitleBlockSpan;\nimport com.fluid.afm.TableLineSpacingSpan;\nimport com.fluid.afm.TopSpacingSpan;\nimport com.fluid.afm.span.ParagraphSpacingSpan;\nimport com.fluid.afm.styles.TableStyle;\nimport com.fluid.afm.utils.MDLogger;\nimport com.fluid.afm.utils.Utils;\n\nimport org.commonmark.Extension;\nimport org.commonmark.ext.gfm.tables.TableBlock;\nimport org.commonmark.ext.gfm.tables.TableBody;\nimport org.commonmark.ext.gfm.tables.TableCell;\nimport org.commonmark.ext.gfm.tables.TableHead;\nimport org.commonmark.ext.gfm.tables.TableRow;\nimport org.commonmark.ext.gfm.tables.internal.TableHtmlNodeRenderer;\nimport org.commonmark.ext.gfm.tables.internal.TableTextContentNodeRenderer;\nimport org.commonmark.node.Block;\nimport org.commonmark.node.Document;\nimport org.commonmark.node.Node;\nimport org.commonmark.parser.InlineParser;\nimport org.commonmark.parser.Parser;\nimport org.commonmark.parser.block.AbstractBlockParser;\nimport org.commonmark.parser.block.AbstractBlockParserFactory;\nimport org.commonmark.parser.block.BlockContinue;\nimport org.commonmark.parser.block.BlockStart;\nimport org.commonmark.parser.block.MatchedBlockParser;\nimport org.commonmark.parser.block.ParserState;\nimport org.commonmark.renderer.html.HtmlRenderer;\nimport org.commonmark.renderer.text.TextContentRenderer;\n\nimport java.lang.ref.WeakReference;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.ConcurrentHashMap;\n\nimport io.noties.markwon.AbstractMarkwonPlugin;\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.MarkwonSpansFactory;\nimport io.noties.markwon.MarkwonVisitor;\nimport io.noties.markwon.SpannableBuilder;\nimport io.noties.markwon.core.MarkwonTheme;\n\n/**\n * @since 3.0.0\n */\npublic class TablePlugin extends AbstractMarkwonPlugin implements StreamOutStateObserver {\n    private static final String TAG = \"MD_TablePlugin\";\n\n    private final TableVisitor visitor;\n\n    @NonNull\n    public static TablePlugin create(@NonNull Context context, boolean isHideHeader) {\n        return new TablePlugin(context, isHideHeader);\n    }\n\n    @NonNull\n    public static TablePlugin create(Context context) {\n        return new TablePlugin(context);\n    }\n\n    @SuppressWarnings(\"WeakerAccess\")\n    TablePlugin( Context context) {\n        this.visitor = new TableVisitor(context);\n    }\n\n    TablePlugin(Context context, boolean isHideHeader) {\n        this.visitor = new TableVisitor(context, isHideHeader);\n    }\n\n    @Override\n    public void onStreamOutStateChanged(boolean isStreamingOutput) {\n        visitor.setStreamingOutput(isStreamingOutput);\n        if (!isStreamingOutput) {\n            visitor.mTableSpanCache.clear();\n        }\n    }\n    @Override\n    public void configure(@NonNull Registry registry) {\n        super.configure(registry);\n    }\n\n    @Override\n    public void configureTheme(@NonNull MarkwonTheme.Builder builder) {\n        super.configureTheme(builder);\n    }\n\n    @Override\n    public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) {\n        super.configureConfiguration(builder);\n    }\n\n    @Override\n    public void configureSpansFactory(@NonNull MarkwonSpansFactory.Builder builder) {\n        super.configureSpansFactory(builder);\n    }\n\n    @NonNull\n    @Override\n    public String processMarkdown(@NonNull String markdown) {\n        visitor.originMarkdown = markdown;\n        return super.processMarkdown(markdown);\n    }\n\n    @Override\n    public void afterRender(@NonNull Node node, @NonNull MarkwonVisitor visitor) {\n        super.afterRender(node, visitor);\n        MDLogger.d(TAG, \"afterRender node.getNext = \" + node.getNext());\n\n    }\n\n    @Override\n    public void configureParser(@NonNull Parser.Builder builder) {\n        builder.extensions(Collections.singleton(MyTablesExtension.create()));\n    }\n\n    @Override\n    public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) {\n        visitor.configure(builder);\n    }\n\n    @Override\n    public void beforeRender(@NonNull Node node) {\n        // clear before rendering (as visitor has some internal mutable state)\n        visitor.clear();\n    }\n\n    @Override\n    public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) {\n        TableRowsScheduler.unschedule(textView);\n    }\n\n    @Override\n    public void afterSetText(@NonNull TextView textView) {\n        TableRowsScheduler.schedule(textView);\n    }\n\n    private static class TableVisitor {\n        public ConcurrentHashMap<Integer, Integer> mTableIndexMap = new ConcurrentHashMap<>(); // key: all content String index, value: table index\n\n        public ConcurrentHashMap<Integer, List<TableRowSpan.Cell>> mPendingTableRow = new ConcurrentHashMap<>(); // key: table index, value: blockLength\n\n        public ConcurrentHashMap<Integer, Integer> mTableblockLength = new ConcurrentHashMap<>(); // key: table index, value: blockLength\n\n        public ConcurrentHashMap<Integer, Boolean> mTableIsHeader = new ConcurrentHashMap<>(); // key: table index\n\n        public ConcurrentHashMap<Integer, Integer> mTableRows = new ConcurrentHashMap<>(); // key: table index\n        public ConcurrentHashMap<Integer, List<TableRowSpan>> mPendingTableRowSpanList = new ConcurrentHashMap<>(); // key: table index\n\n        private final int tableReducedLineHeight = Utils.dpToPx(2);\n\n        private final WeakReference<Context> contextRef;\n        public ConcurrentHashMap<Integer, Integer> mTableStartIndex = new ConcurrentHashMap<>(); // key: table index\n        private boolean isHideTitle;\n\n        public ConcurrentHashMap<Integer, ConcurrentHashMap<String, TableRowSpan>> mTableSpanCache = new ConcurrentHashMap<>(); // key: table index\n\n        private boolean mIsStreamingOutput = false;\n        private int tableCount = 0;\n        private int maxContentIndex = -1;\n        private String originMarkdown;\n        private final ConcurrentHashMap<Integer, TableBlockTitleBlockSpan> mTitleBlockSpans = new ConcurrentHashMap<>();\n\n        TableVisitor(Context context) {\n            this.contextRef = new WeakReference<>(context);\n        }\n\n        TableVisitor(Context context, boolean isHideTitle) {\n            this.isHideTitle = isHideTitle;\n            this.contextRef = new WeakReference<>(context);\n        }\n\n        public boolean isStreamingOutput() {\n            return mIsStreamingOutput;\n        }\n\n        public void setStreamingOutput(boolean streamingOutput) {\n            mIsStreamingOutput = streamingOutput;\n        }\n\n        void clear() {\n            mTableblockLength.clear();\n            mTableIsHeader.clear();\n            mTableRows.clear();\n            mPendingTableRow.clear();\n        }\n\n        void configure(@NonNull MarkwonVisitor.Builder builder) {\n            builder\n                    // @since 4.1.1 we use TableBlock instead of TableBody to add new lines\n                    .on(TableBlock.class, (visitor, tableBlock) -> {\n                        visitor.blockStart(tableBlock);\n                        final int length = visitor.length();\n                        if (!mTableIndexMap.containsKey(visitor.length())) {\n                            mTableblockLength.put(tableCount, length);\n                            mTableStartIndex.put(tableCount, length);\n                            mTableIndexMap.put(length, tableCount++);\n                        }\n                        visitor.visitChildren(tableBlock);\n\n                        // @since 4.3.1 apply table span for the full table\n                        visitor.setSpans(length, new TableSpan());\n\n                        visitor.blockEnd(tableBlock);\n                        boolean isDocumentLast = tableBlock.getNext() == null && tableBlock.getParent() instanceof Document;\n                        if (!isDocumentLast) {\n                            int index = visitor.length();\n                            visitor.builder().append('\\n').append('\\u00a0');\n                            visitor.setSpans(index + 1, new ParagraphSpacingSpan((int) (visitor.configuration().theme().getParagraphBreakHeight() * 1.6f)));\n                        }\n                    }).on(TableBody.class, (visitor, tableBody) -> {\n\n                        final int length = visitor.length();\n                        int tableIndex = getTableIndex(length);\n                        visitor.visitChildren(tableBody);\n                        mTableRows.put(tableIndex, 0);\n                    }).on(TableRow.class, this::visitRow).on(TableHead.class, this::visitRow).on(TableCell.class, (visitor, tableCell) -> {\n                        final int length = visitor.length();\n                        int tableIndex = getTableIndex(length);\n                        visitor.visitChildren(tableCell);\n                        List<TableRowSpan.Cell> pendingTableRow = mPendingTableRow.get(tableIndex);\n                        if (pendingTableRow == null) {\n                            pendingTableRow = new ArrayList<>(2);\n                            mPendingTableRow.put(tableIndex, pendingTableRow);\n                        }\n\n                        pendingTableRow.add(new TableRowSpan.Cell(tableCellAlignment(tableCell.getAlignment()), visitor.builder().removeFromEnd(length)));\n                        mTableIsHeader.put(tableIndex, tableCell.isHeader());\n                    });\n        }\n\n        private int getTableIndex(int contentIndex) {\n            if (mTableIndexMap.size() <= 1) {\n                return 0;\n            }\n            int max = 0;\n            Set<Map.Entry<Integer, Integer>> entrySet = mTableIndexMap.entrySet();\n            for (Map.Entry<Integer, Integer> entry : entrySet) {\n                if (entry.getKey() <= contentIndex && max < entry.getValue()) {\n                    max = entry.getValue();\n                }\n            }\n            return max;\n        }\n\n        private void visitRow(@NonNull MarkwonVisitor visitor, @NonNull Node node) {\n            final int length = visitor.length();\n            visitor.visitChildren(node);\n            TableStyle style = visitor.configuration().theme().getTableStyle();\n\n            final SpannableBuilder builder = visitor.builder();\n            // @since 2.0.0\n            // we cannot rely on hasNext(TableHead) as it's not reliable\n            // we must apply new line manually and then exclude it from tableRow span\n            int tableIndex = getTableIndex(length);\n            List<TableRowSpan.Cell> pendingTableRow = mPendingTableRow.get(tableIndex);\n            Boolean tableRowIsHeader = mTableIsHeader.get(tableIndex);\n            if (tableRowIsHeader == null) {\n                tableRowIsHeader = false;\n            }\n            Integer tableRows = mTableRows.get(tableIndex);\n            if (tableRows == null) {\n                tableRows = 0;\n            }\n            if (pendingTableRow != null) {\n                final boolean addNewLine;\n                {\n                    final int builderLength = builder.length();\n                    addNewLine = builderLength > 0 && '\\n' != builder.charAt(builderLength - 1);\n                }\n                if (addNewLine) {\n                    visitor.forceNewLine();\n                }\n                boolean useCachedSpan = false;\n                MDLogger.d(TAG, \"===== maxIndex is=\" + maxContentIndex);\n                if (maxContentIndex == -1) {\n                    maxContentIndex = length;\n                }\n                if (length <= maxContentIndex) {\n                    useCachedSpan = true;\n                } else {\n                    maxContentIndex = length;\n                    MDLogger.d(TAG, \"===== update maxIndex=\" + length);\n                }\n\n                // @since 1.0.4 Replace table char with non-breakable space\n                // we need this because if table is at the end of the text, then it will be\n                // trimmed from the final result\n                builder.append('\\u00a0');\n                for (TableRowSpan.Cell cell : pendingTableRow) {\n                    MDLogger.d(TAG, \"cell.text =\" + cell.text + \" TextUtils.isEmpty(cell.text) = \" + TextUtils.isEmpty(cell.text));\n                }\n                TableRowSpan cachedSpan = getCachedSpan(tableIndex, length);\n                MDLogger.d(TAG, \" isStreamingOutput = \" + isStreamingOutput() + \" useCachedSpan = \" + useCachedSpan + \" length = \" + length + \" tableIndex=\" + tableIndex);\n                final int start = addNewLine ? length + 1 : length;\n                if (useCachedSpan && cachedSpan != null && !isHideTitle) {\n                    MDLogger.d(TAG, \"get rowSpanCache span = \" + cachedSpan);\n                    final TableRowSpan span = getCachedSpan(tableIndex, length);\n\n                    cacheAndUpdateTableCurrentMaxNumber(tableIndex, span);\n                    updateCachedTableCurrentMaxNumber(tableIndex);\n\n                    tableRows = tableRowIsHeader ? 0 : tableRows + 1;\n                    mTableRows.put(tableIndex, tableRows);\n                    if (tableRowIsHeader) {\n                        final int headerHeight = style.titleBarHeight();\n                        visitor.setSpans(start, new TopSpacingSpan(headerHeight));\n                        if (!isHideTitle) {\n                            final TableBlockTitleBlockSpan titleSpan = mTitleBlockSpans.get(tableIndex);\n                            if (titleSpan != null) {\n                                visitor.setSpans(start, titleSpan);\n                                TableBlock tableBlock = getTableBlock(node);\n                                if (tableBlock != null) {\n                                    titleSpan.setTableBlock(tableBlock);\n                                }\n                            }\n                        }\n                    }\n                    visitor.setSpans(start, new TableLineSpacingSpan(tableRowIsHeader, tableReducedLineHeight));\n                    visitor.setSpans(start, span);\n                } else {\n                    boolean isCreateNewSpan;\n                    int value = maxContentIndex;\n                    isCreateNewSpan = !isStreamingOutput() || (length < value || ((length == value) && findCurrentTableEnd(tableIndex)));\n                    if (isCreateNewSpan) {\n                        Integer blockLength = mTableblockLength.get(tableIndex);\n                        if (blockLength == null) {\n                            blockLength = length;\n                        }\n                        if (blockLength != length) {\n                            tableRowIsHeader = false;\n                            mTableIsHeader.put(tableIndex, false);\n                        }\n                        final TableRowSpan span = new TableRowSpan(style, pendingTableRow, tableRowIsHeader, isHideTitle, tableRows % 2 == 1, tableRows);\n                        MDLogger.d(TAG, \"new span\");\n\n                        cacheAndUpdateTableCurrentMaxNumber(tableIndex, span);\n                        if (!isStreamingOutput()) {\n                            updateCachedTableCurrentMaxNumber(tableIndex);\n                        }\n\n                        tableRows = tableRowIsHeader ? 0 : tableRows + 1;\n                        mTableRows.put(tableIndex, tableRows);\n                        if (tableRowIsHeader) {\n                            final int headerHeight = style.titleBarHeight();\n                            visitor.setSpans(start, new TopSpacingSpan(headerHeight));\n                            if (!isHideTitle) {\n                                MDLogger.d(TAG, \" tableIndex = \" + tableIndex);\n                                TableBlock tableBlock =  getTableBlock(node);\n\n                                TableBlockTitleBlockSpan titleBlockSpan = new TableBlockTitleBlockSpan(contextRef.get(), headerHeight, style, tableIndex, pendingTableRow.size(), true, tableBlock);\n                                mTitleBlockSpans.put(tableIndex, titleBlockSpan);\n                                visitor.setSpans(start, titleBlockSpan);\n                            }\n                        }\n\n                        visitor.setSpans(start, new TableLineSpacingSpan(tableRowIsHeader, tableReducedLineHeight));\n                        visitor.setSpans(start, span);\n                        boolean cacheSpan = isStreamingOutput();\n                        if (cacheSpan) {\n                            MDLogger.d(TAG, \"rowSpanCache put \" + \"length = \" + length + \" span = \" + span);\n                            cacheSpan(tableIndex, length, span);\n                        }\n                    }\n                }\n                mPendingTableRow.remove(tableIndex);\n            }\n        }\n        private TableBlock getTableBlock(Node node) {\n            if (node instanceof TableBlock) {\n                return (TableBlock) node;\n            } else if (node == null) {\n                return null;\n            }\n            return getTableBlock(node.getParent());\n        }\n\n\n        private void cacheAndUpdateTableCurrentMaxNumber(int tableIndex, TableRowSpan span) {\n            List<TableRowSpan> pendingTableRowList = mPendingTableRowSpanList.get(tableIndex);\n            if (pendingTableRowList == null) {\n                pendingTableRowList = new ArrayList<>();\n                mPendingTableRowSpanList.put(tableIndex, pendingTableRowList);\n            }\n            pendingTableRowList.add(span);\n            Integer tableRows = mTableRows.get(tableIndex);\n            if (tableRows == null) {\n                tableRows = 0;\n            }\n            for (TableRowSpan rowSpan : pendingTableRowList) {\n                if (rowSpan == null) continue;\n                rowSpan.updateCurrentMaxRows(tableRows);\n            }\n        }\n\n        private void updateCachedTableCurrentMaxNumber(int tableIndex) {\n            if (getSpanCache(tableIndex).isEmpty()) {\n                return;\n            }\n            Integer tableRows = mTableRows.get(tableIndex);\n            if (tableRows == null) {\n                tableRows = 0;\n            }\n            ConcurrentHashMap<String, TableRowSpan> spanCache = getSpanCache(tableIndex);\n            Integer tableStartIndex = mTableStartIndex.get(tableIndex);\n            if (tableStartIndex == null) {\n                tableStartIndex = 0;\n            }\n            for (Map.Entry<String, TableRowSpan> entry : spanCache.entrySet()) {\n                String key = entry.getKey();\n                if (TextUtils.isEmpty(key)) {\n                    continue;\n                }\n                try {\n                    final int keyLength = Integer.parseInt(key);\n                    if (keyLength < tableStartIndex) {\n                        MDLogger.d(TAG, \"has render keyLength = \" + keyLength + \" tableStartIndex = \" + tableStartIndex);\n                    } else {\n                        TableRowSpan rowSpan = entry.getValue();\n                        rowSpan.updateCurrentMaxRows(tableRows);\n                    }\n                } catch (Throwable e) {\n                    MDLogger.e(TAG, \"updateCachedTableCurrentMaxNumber..e:\", e);\n                }\n            }\n        }\n\n        @TableRowSpan.Alignment\n        private static int tableCellAlignment(TableCell.Alignment alignment) {\n            final int out;\n            if (alignment != null) {\n                switch (alignment) {\n                    case CENTER:\n                        out = TableRowSpan.ALIGN_CENTER;\n                        break;\n                    case RIGHT:\n                        out = TableRowSpan.ALIGN_RIGHT;\n                        break;\n                    default:\n                        out = TableRowSpan.ALIGN_LEFT;\n                        break;\n                }\n            } else {\n                out = TableRowSpan.ALIGN_LEFT;\n            }\n            return out;\n        }\n\n        /**\n         * 找到当前originMarkdown的字符串最后一行\n         */\n        private boolean findCurrentTableEnd(int tableIndex) {\n            try {\n                List<TableRowSpan.Cell> pendingTableRow = mPendingTableRow.get(tableIndex);\n                if (pendingTableRow == null || pendingTableRow.isEmpty()) {\n                    return false;\n                }\n\n                final int lastIndex = originMarkdown.lastIndexOf(\"|\\n|\");\n                if (lastIndex == -1) {\n                    return false;\n                }\n\n                String lastColumn = originMarkdown.substring(lastIndex + 3);\n                if (TextUtils.isEmpty(lastColumn)) {\n                    return false;\n                }\n\n                final int lastSeparatorIndex = lastColumn.lastIndexOf(\"|\");\n                if (lastSeparatorIndex == -1) {\n                    return false;\n                }\n\n                String columnContent = lastColumn.substring(0, lastSeparatorIndex);\n                String[] columns = columnContent.split(\"\\\\|\");\n                return pendingTableRow.size() <= columns.length;\n            } catch (Throwable e) {\n                MDLogger.e(TAG, \"findCurrentTableEnd..e:\", e);\n            }\n            return false;\n        }\n\n        private TableRowSpan getCachedSpan(int tableIndex, int length) {\n            return getSpanCache(tableIndex).get(String.valueOf(length));\n        }\n\n        private void cacheSpan(int tableIndex, int length, TableRowSpan span) {\n            getSpanCache(tableIndex).put(String.valueOf(length), span);\n        }\n\n        private ConcurrentHashMap<String, TableRowSpan> getSpanCache(int tableIndex) {\n            ConcurrentHashMap<String, TableRowSpan> cache = mTableSpanCache.get(tableIndex);\n            if (cache == null) {\n                cache = new ConcurrentHashMap<>();\n                mTableSpanCache.put(tableIndex, cache);\n            }\n            return cache;\n        }\n    }\n\n    public static class MyTablesExtension implements Parser.ParserExtension, HtmlRenderer.HtmlRendererExtension, TextContentRenderer.TextContentRendererExtension {\n        private MyTablesExtension() {\n        }\n\n        public static Extension create() {\n            return new MyTablesExtension();\n        }\n\n        public void extend(Parser.Builder parserBuilder) {\n            parserBuilder.customBlockParserFactory(new MyTableBlockParser.Factory());\n        }\n\n        public void extend(HtmlRenderer.Builder rendererBuilder) {\n            rendererBuilder.nodeRendererFactory(TableHtmlNodeRenderer::new);\n        }\n\n        public void extend(TextContentRenderer.Builder rendererBuilder) {\n            rendererBuilder.nodeRendererFactory(TableTextContentNodeRenderer::new);\n        }\n\n        public static class MyTableBlockParser extends AbstractBlockParser {\n            private final TableBlock block;\n            private final List<CharSequence> bodyLines;\n            private List<TableCell.Alignment> columns;\n            private List<String> headerCells;\n            private boolean nextIsSeparatorLine;\n            private final boolean isInParagraph;\n            private int lineCount = 0;\n\n            private MyTableBlockParser(List<TableCell.Alignment> columns, List<String> headerCells, boolean isInParagraph) {\n                this.block = new TableBlock();\n                this.bodyLines = new ArrayList<>();\n                this.nextIsSeparatorLine = true;\n                this.columns = columns != null ? columns : (new ArrayList<>());\n                this.headerCells = headerCells != null ? headerCells : (new ArrayList<>());\n                this.isInParagraph = isInParagraph;\n            }\n\n            public boolean canHaveLazyContinuationLines() {\n                return true;\n            }\n\n            public Block getBlock() {\n                return this.block;\n            }\n\n            public BlockContinue tryContinue(ParserState state) {\n                if (invalidData) {\n                    return BlockContinue.none();\n                }\n                return state.getLine().toString().contains(\"|\") ? BlockContinue.atIndex(state.getIndex()) : BlockContinue.none();\n            }\n\n            boolean invalidData = false;\n\n            public void addLine(CharSequence line) {\n                lineCount++;\n                if (isInParagraph) {\n                    if (lineCount == 1) {\n                        headerCells = MyTableBlockParser.split(line);\n                        if (headerCells.isEmpty()) {\n                            invalidData = true;\n                            MDLogger.e(TAG, \"no header cells:\" + line);\n                        }\n                    } else if (lineCount == 2) {\n                        columns = MyTableBlockParser.parseSeparator(line);\n                        if (columns == null) {\n                            columns = new ArrayList<>();\n                        }\n                        int headCellSize = headerCells == null ? 0 : headerCells.size();\n                        if (columns.isEmpty() || columns.size() < headCellSize) {\n                            invalidData = true;\n                            MDLogger.e(TAG, \"no colum:\" + line);\n                        }\n\n                    } else {\n                        this.bodyLines.add(line);\n                    }\n                    return;\n                }\n\n                if (this.nextIsSeparatorLine) {\n                    this.nextIsSeparatorLine = false;\n                } else {\n                    if (columns == null || columns.isEmpty()) {\n                        columns = MyTableBlockParser.parseSeparator(line);\n                        return;\n                    }\n                    this.bodyLines.add(line);\n                }\n\n            }\n\n            public void parseInlines(InlineParser inlineParser) {\n                try {\n                    int headerColumns = this.headerCells.size();\n                    Node head = new TableHead();\n                    this.block.appendChild(head);\n                    TableRow headerRow = new TableRow();\n                    head.appendChild(headerRow);\n\n                    for (int i = 0; i < headerColumns; ++i) {\n                        String cell = this.headerCells.get(i);\n                        TableCell tableCell = this.parseCell(cell, i, inlineParser);\n                        tableCell.setHeader(true);\n                        headerRow.appendChild(tableCell);\n                    }\n\n                    Node body = null;\n\n                    TableRow row;\n                    for (Iterator<CharSequence> var14 = this.bodyLines.iterator(); var14.hasNext(); body.appendChild(row)) {\n                        CharSequence rowLine = var14.next();\n                        List<String> cells = split(rowLine);\n                        row = new TableRow();\n\n                        for (int i = 0; i < headerColumns; ++i) {\n                            String cell = i < cells.size() ? cells.get(i) : \"\";\n                            TableCell tableCell = this.parseCell(cell, i, inlineParser);\n                            row.appendChild(tableCell);\n                        }\n\n                        if (body == null) {\n                            body = new TableBody();\n                            this.block.appendChild(body);\n                        }\n                    }\n                } catch (Exception e) {\n                    MDLogger.e(TAG, e);\n                }\n            }\n\n            private TableCell parseCell(String cell, int column, InlineParser inlineParser) {\n                TableCell tableCell = new TableCell();\n                if (column < this.columns.size()) {\n                    tableCell.setAlignment(this.columns.get(column));\n                }\n\n                inlineParser.parse(cell.trim(), tableCell);\n                return tableCell;\n            }\n\n            private static List<String> split(CharSequence input) {\n                String line = input.toString().trim();\n                if (line.startsWith(\"|\")) {\n                    line = line.substring(1);\n                }\n\n                List<String> cells = new ArrayList<>();\n                StringBuilder sb = new StringBuilder();\n\n                for (int i = 0; i < line.length(); ++i) {\n                    char c = line.charAt(i);\n                    switch (c) {\n                        case '\\\\':\n                            if (i + 1 < line.length() && line.charAt(i + 1) == '|') {\n                                sb.append('|');\n                                ++i;\n                                break;\n                            }\n\n                            sb.append('\\\\');\n                            break;\n                        case '|':\n                            cells.add(sb.toString());\n                            sb.setLength(0);\n                            break;\n                        default:\n                            sb.append(c);\n                    }\n                }\n\n                if (sb.length() > 0) {\n                    cells.add(sb.toString());\n                }\n\n                return cells;\n            }\n\n            private static List<TableCell.Alignment> parseSeparator(CharSequence s) {\n                List<TableCell.Alignment> columns = new ArrayList<>();\n                int pipes = 0;\n                boolean valid = false;\n                int i = 0;\n\n                while (i < s.length()) {\n                    char c = s.charAt(i);\n                    switch (c) {\n                        case '\\t':\n                        case ' ':\n                            ++i;\n                            break;\n                        case '-':\n                        case ':':\n                            if (pipes == 0 && !columns.isEmpty()) {\n                                return null;\n                            }\n\n                            boolean left = false;\n                            boolean right = false;\n                            if (c == ':') {\n                                left = true;\n                                ++i;\n                            }\n\n                            boolean haveDash;\n                            for (haveDash = false; i < s.length() && s.charAt(i) == '-'; haveDash = true) {\n                                ++i;\n                            }\n\n                            if (!haveDash) {\n                                return null;\n                            }\n\n                            if (i < s.length() && s.charAt(i) == ':') {\n                                right = true;\n                                ++i;\n                            }\n\n                            columns.add(getAlignment(left, right));\n                            pipes = 0;\n                            break;\n                        case '|':\n                            ++i;\n                            ++pipes;\n                            if (pipes > 1) {\n                                return null;\n                            }\n\n                            valid = true;\n                            break;\n                        default:\n                            return null;\n                    }\n                }\n\n                if (!valid) {\n                    return null;\n                } else {\n                    return columns;\n                }\n            }\n\n            private static TableCell.Alignment getAlignment(boolean left, boolean right) {\n                if (left && right) {\n                    return TableCell.Alignment.CENTER;\n                } else if (left) {\n                    return TableCell.Alignment.LEFT;\n                } else {\n                    return right ? TableCell.Alignment.RIGHT : null;\n                }\n            }\n\n            @Override\n            public boolean isContainer() {\n                return super.isContainer();\n            }\n\n            @Override\n            public boolean canContain(Block childBlock) {\n                return super.canContain(childBlock);\n            }\n\n            public static class Factory extends AbstractBlockParserFactory {\n                public Factory() {\n                }\n\n                public BlockStart tryStart(ParserState state, MatchedBlockParser matchedBlockParser) {\n                    CharSequence line = state.getLine();\n                    CharSequence paragraph = matchedBlockParser.getParagraphContent();\n                    if (paragraph != null && paragraph.toString().contains(\"|\") && !paragraph.toString().contains(\"\\n\")) {\n                        CharSequence separatorLine = line.subSequence(state.getIndex(), line.length());\n                        List<TableCell.Alignment> columns = MyTableBlockParser.parseSeparator(separatorLine);\n                        if (columns != null && !columns.isEmpty()) {\n                            List<String> headerCells = MyTableBlockParser.split(paragraph);\n                            if (columns.size() >= headerCells.size()) {\n                                return BlockStart.of(new MyTableBlockParser(columns, headerCells, false)).atIndex(state.getIndex()).replaceActiveBlockParser();\n                            }\n                        }\n                    } else if (paragraph != null) {\n                        if (line.toString().stripLeading().startsWith(\"|\")) {\n                            List<String> headerCells = MyTableBlockParser.split(line);\n                            if (!headerCells.isEmpty()) {\n                                return BlockStart.of(new MyTableBlockParser(null, null, true)).atIndex(state.getIndex());\n                            }\n                        }\n                    } else if (line != null && line.toString().stripLeading().startsWith(\"|\") && line.toString().endsWith(\"|\")) {\n                        List<String> headerCells = MyTableBlockParser.split(line);\n                        if (headerCells.size() > 1) {\n                            return BlockStart.of(new MyTableBlockParser(null, null, true)).atIndex(state.getIndex());\n                        }\n                    }\n\n                    return BlockStart.none();\n                }\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tables/src/main/java/io/noties/markwon/ext/tables/TableRowSpan.java",
    "content": "package io.noties.markwon.ext.tables;\n\nimport android.annotation.SuppressLint;\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.graphics.Path;\nimport android.graphics.RectF;\nimport android.graphics.drawable.Drawable;\nimport android.text.Layout;\nimport android.text.Spannable;\nimport android.text.SpannableString;\nimport android.text.Spanned;\nimport android.text.StaticLayout;\nimport android.text.TextPaint;\nimport android.text.style.ReplacementSpan;\nimport android.widget.TextView;\n\nimport androidx.annotation.IntDef;\nimport androidx.annotation.IntRange;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport com.fluid.afm.IMarkdownLayer;\nimport com.fluid.afm.styles.TableStyle;\nimport com.fluid.afm.utils.MDLogger;\n\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport io.noties.markwon.core.spans.TextLayoutSpan;\nimport io.noties.markwon.core.spans.TextViewSpan;\nimport io.noties.markwon.image.AsyncDrawable;\nimport io.noties.markwon.image.AsyncDrawableSpan;\nimport io.noties.markwon.utils.LeadingMarginUtils;\nimport io.noties.markwon.utils.SpanUtils;\n\npublic class TableRowSpan extends ReplacementSpan {\n\n    public static final int ALIGN_LEFT = 0;\n    public static final int ALIGN_CENTER = 1;\n    public static final int ALIGN_RIGHT = 2;\n\n    @IntDef(value = {ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT})\n    @Retention(RetentionPolicy.SOURCE)\n    public @interface Alignment {\n    }\n\n    public interface Invalidator {\n        void invalidate();\n    }\n\n    public static class Cell {\n\n        final int alignment;\n        final CharSequence text;\n\n        public Cell(@Alignment int alignment, CharSequence text) {\n            this.alignment = alignment;\n            this.text = text;\n        }\n\n        @Alignment\n        public int alignment() {\n            return alignment;\n        }\n\n        public CharSequence text() {\n            return text;\n        }\n\n        @NonNull\n        @Override\n        public String toString() {\n            return \"Cell{\" +\n                    \"alignment=\" + alignment +\n                    \", text=\" + text +\n                    '}';\n        }\n    }\n\n    private final TableStyle mStyle;\n    private final List<Cell> cells;\n    private final List<Layout> layouts;\n    private final TextPaint textPaint;\n    public final boolean header;\n    private final boolean isHideHeader;\n    private final boolean odd;\n\n    private final RectF rect = new RectF();\n    private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);\n\n    private int width;\n    private int height;\n    private Invalidator invalidator;\n    private final int rowsNumber;\n    private int currentMaxRows;\n    private final int radius;\n    private float leading;\n\n    public TableRowSpan(\n            @NonNull TableStyle tableStyle,\n            @NonNull List<Cell> cells,\n            boolean header,\n            boolean odd,\n            int rows) {\n        this.mStyle = tableStyle;\n        this.cells = cells;\n        this.layouts = new ArrayList<>(cells.size());\n        this.textPaint = new TextPaint();\n        this.header = header;\n        this.isHideHeader = false;\n        this.odd = odd;\n        this.rowsNumber = rows;\n        this.radius = tableStyle.tableBlockRadius();\n    }\n\n    public TableRowSpan(\n            @NonNull TableStyle tableStyle,\n            @NonNull List<Cell> cells,\n            boolean header,\n            boolean isHideHeader,\n            boolean odd,\n            int rows) {\n        this.mStyle = tableStyle;\n        this.cells = cells;\n        this.layouts = new ArrayList<>(cells.size());\n        this.textPaint = new TextPaint();\n        this.header = header;\n        this.isHideHeader = isHideHeader;\n        this.odd = odd;\n        this.rowsNumber = rows;\n        this.radius = tableStyle.tableBlockRadius();\n    }\n\n\n    /**\n     * 更新当前最大行号\n     * @param currentMaxRows\n     */\n    public void updateCurrentMaxRows(int currentMaxRows) {\n        this.currentMaxRows = currentMaxRows;\n    }\n\n    @Override\n    public int getSize(\n            @NonNull Paint paint,\n            CharSequence text,\n            @IntRange(from = 0) int start,\n            @IntRange(from = 0) int end,\n            @Nullable Paint.FontMetricsInt fm) {\n        // it's our absolute requirement to have width of the canvas here... because, well, it changes\n        // the way we draw text. So, if we do not know the width of canvas we cannot correctly measure our text\n\n        int maxWTmp = 0;\n        if (text instanceof Spanned){\n            final Spanned spanned = (Spanned) text;\n            final TextView textView = TextViewSpan.textViewOf(spanned);\n            if (textView != null){\n                if (textView instanceof IMarkdownLayer){\n                    maxWTmp = ((IMarkdownLayer) textView).getViewMaxWidth() - 1;\n                }\n            }\n        }\n        if (layouts.size() == 0 && paint != null){\n\n            final int spanWidth = SpanUtils.width(null, text);\n\n            //MDLogger.d(\"gavin-test\", \"===xxx=== getSize  targetW=\"+spanWidth +\"_\" +maxWTmp + \"  view=\" + stringTmp);\n            int oldW = width;\n            width = spanWidth;\n            if (width <=0){\n                width = maxWTmp;\n            }\n            // @since 4.3.1 it's important to cast to TextPaint in order to display links, etc\n            if (paint instanceof TextPaint) {\n                // there must be a reason why this method receives Paint instead of TextPaint...\n                textPaint.set((TextPaint) paint);\n            } else {\n                textPaint.set(paint);\n            }\n            mStyle.applyTableTextStyle(textPaint, header);\n            makeNewLayouts();\n            width = oldW;\n        }\n\n        if (layouts.size() > 0) {\n\n            if (fm != null) {\n\n                int max = 0;\n                for (Layout layout : layouts) {\n                    final int height = layout.getHeight();\n                    if (height > max) {\n                        max = height;\n                    }\n                }\n\n                // we store actual height\n                height = max;\n\n                // but apply height with padding\n                int padding = mStyle.cellTopBottomPadding() * 2;\n                if (isHideHeader && header) {\n                    padding = 0;\n                }\n                fm.ascent = -(max + padding);\n                fm.descent = 0;\n\n                fm.top = fm.ascent;\n                fm.bottom = 0;\n            }\n        }\n\n        final int spanWidth = SpanUtils.width(null, text);\n        int ret = width;\n        if (maxWTmp > 0) {\n            ret = Math.min(width, maxWTmp);\n        } else if (spanWidth > 0) {\n            ret = Math.min(width, spanWidth);\n        }\n        return  Math.min(1, (int) (ret - leading));\n    }\n\n    @Override\n    public void draw(\n            @NonNull Canvas canvas,\n            CharSequence text,\n            @IntRange(from = 0) int start,\n            @IntRange(from = 0) int end,\n            float x,\n            int top,\n            int y,\n            int bottom,\n            @NonNull Paint p) {\n\n        final boolean isCurrentLastLine = (rowsNumber == currentMaxRows);\n        final int spanWidth = SpanUtils.width(canvas, text);\n        boolean invalidate = false;\n        if (recreateLayouts(spanWidth, x)) {\n            width = spanWidth;\n            // @since 4.3.1 it's important to cast to TextPaint in order to display links, etc\n            if (p instanceof TextPaint) {\n                // there must be a reason why this method receives Paint instead of TextPaint...\n                textPaint.set((TextPaint) p);\n            } else {\n                textPaint.set(p);\n            }\n            leading = x;\n            mStyle.applyTableTextStyle(textPaint, header);\n            makeNewLayouts();\n            invalidate = true;\n        }\n        x = 0;\n\n        int maxHeight = 0;\n\n        final int padding = mStyle.cellTopBottomPadding();\n        final int leftRightPadding = mStyle.cellLeftRightPadding();\n\n        final int size = layouts.size();\n\n        final float w = cellWidth(size);\n\n        // @since 4.6.0 roundingDiff to offset last vertical border\n        final float roundingDiff =(w - width / size) * size;\n\n        // 如果是头，向下移动height空白区域给表头的顶部区块绘制使用\n        if (header && !isHideHeader) {\n            top += mStyle.titleBarHeight();\n        }\n        // @since 1.1.1\n        // draw backgrounds\n        {\n            if (header) {\n                mStyle.applyTableHeaderRowStyle(paint);\n            } else if (odd) {\n                mStyle.applyTableOddRowStyle(paint);\n            } else {\n                // even\n                mStyle.applyTableEvenRowStyle(paint);\n            }\n\n            // if present (0 is transparent)\n            if (paint.getColor() != 0) {\n                final int save = canvas.save();\n                try {\n                    rect.set(0, 0, width, bottom - top);\n                    canvas.translate(x, top);\n                    if (isCurrentLastLine && !isHideHeader) {\n                        drawRectWithBottomRound(canvas, paint, rect, radius);\n                    } else if (isHideHeader && header && mStyle.drawBorder()) {\n                        canvas.save();\n                        canvas.clipRect(rect);\n                        canvas.drawRoundRect(rect.left, rect.top, rect.right, rect.bottom + radius, radius, radius, paint);\n                        canvas.restore();\n                    } else {\n                        canvas.drawRect(rect, paint);\n                    }\n                } finally {\n                    canvas.restoreToCount(save);\n                }\n            }\n        }\n\n        // @since 1.1.1 reset after applying background color\n        // as background changes color attribute and if not specific tableBorderColor\n        // is specified then after this row all borders will have color of this row (plus alpha)\n        paint.set(p);\n        mStyle.applyTableBorderStyle(paint);\n\n        final int borderWidth = mStyle.borderWidth();\n        final boolean drawBorder = borderWidth > 0;\n\n        // why divided by 4 gives a more or less good result is still not clear (shouldn't it be 2?)\n        final int heightDiff = (bottom - top - height) / 3;\n\n        // required for borderTop calculation\n        final boolean isFirstTableRow;\n\n        // @since 4.3.1\n        if (drawBorder) {\n            boolean first = false;\n            // only if first draw the line\n            {\n                final Spanned spanned = (Spanned) text;\n                final TableSpan[] spans = spanned.getSpans(start, end, TableSpan.class);\n                if (spans != null && spans.length > 0) {\n                    final TableSpan span = spans[0];\n                    if (LeadingMarginUtils.selfStart(start, text, span)) {\n                        first = true;\n                        rect.set((int) x, top + borderWidth / 2, width, top + borderWidth + borderWidth / 2);\n                        if (header && isHideHeader && mStyle.drawBorder() && radius > 0) {\n                            final int save = canvas.save();\n                            rect.set((int) x, top, width, bottom + radius);\n                            canvas.clipRect(rect);\n                            if (paint.getStrokeWidth() == 1) {\n                                paint.setStrokeWidth(2);\n                            }\n                            canvas.drawRoundRect(rect.left, rect.top, rect.right, rect.bottom, radius, radius, paint);\n                            canvas.restoreToCount(save);\n                        } else {\n                            canvas.drawLine(rect.left, rect.top, rect.right, rect.top, paint);\n                        }\n                    }\n                }\n            }\n            // draw the line at the bottom\n             if (!isCurrentLastLine) {\n                rect.set((int) x, bottom - borderWidth / 2f, width, bottom);\n                canvas.drawRect(rect, paint);\n            } else if (isCurrentLastLine && mStyle.drawBorder()) {\n                drawLineWithBottomRound(canvas, paint, x, top, width, bottom, radius);\n            } else if (isCurrentLastLine && isHideHeader) {\n                rect.set((int) x, bottom - borderWidth, width, bottom);\n                canvas.drawRect(rect, paint);\n            }\n            isFirstTableRow = first;\n        } else {\n            isFirstTableRow = false;\n        }\n\n\n        // to NOT overlap borders inset top and bottom\n        final int borderTop = isFirstTableRow ? borderWidth : 0;\n        final int borderBottom = bottom - top - borderWidth;\n\n        Layout layout;\n        for (int i = 0; i < size; i++) {\n            layout = layouts.get(i);\n            final int save = canvas.save();\n            try {\n\n                canvas.translate(x + (i * w), top);\n\n                // @since 4.3.1\n                if (drawBorder) {\n                    // first vertical border will have full width (it cannot exceed canvas)\n                    if (i == 0) {\n                        rect.set(0, borderTop, borderWidth, isCurrentLastLine ? borderBottom - radius + borderWidth : borderBottom);\n                        if (header && isHideHeader && mStyle.drawBorder() && radius > 0) {\n                            rect.set(rect.left, rect.top + radius, rect.right, rect.bottom + radius);\n                        }\n                    } else {\n                        rect.set(0, borderTop, borderWidth, borderBottom);\n                    }\n\n                    if (mStyle.drawBorder() || i != 0) {\n                        canvas.drawLine(rect.left + borderWidth / 2f, rect.top, rect.left + borderWidth / 2f, rect.bottom, paint);\n                    }\n\n                    if (i == (size - 1)) {\n                        // @since 4.6.0 subtract rounding offset for the last vertical divider\n                        rect.set(\n                                w - borderWidth,\n                                borderTop,\n                                w - roundingDiff,\n                                isCurrentLastLine ? borderBottom - radius + borderWidth : borderBottom\n                        );\n                        if (header && isHideHeader && mStyle.drawBorder() && radius > 0) {\n                            rect.set(rect.left, rect.top + radius, rect.right, rect.bottom + radius);\n                        }\n                        // draw right line\n                        if (mStyle.drawBorder()) {\n                            canvas.drawLine(rect.right - borderWidth / 2f, rect.top, rect.right -  borderWidth / 2f, rect.bottom, paint);\n                        }\n                    }\n                }\n\n                canvas.translate(leftRightPadding, padding + heightDiff);\n                layout.draw(canvas);\n\n                if (layout.getHeight() > maxHeight) {\n                    maxHeight = layout.getHeight();\n                }\n\n            } finally {\n                canvas.restoreToCount(save);\n            }\n        }\n\n        if (height != maxHeight) {\n            invalidate = true;\n        }\n        if (invalidate && invalidator != null) {\n            invalidator.invalidate();\n        }\n    }\n\n    private void drawLineWithBottomRound(Canvas canvas, Paint paint,\n                                         float left, float top, float right, float bottom,\n                                         float radius) {\n        final int save = canvas.save();\n        final float oldStrokeWidth = paint.getStrokeWidth();\n        final int oldColor = paint.getColor();\n        final Paint.Style oldStyle = paint.getStyle();\n        mStyle.applyTableBorderStyle(paint);\n        if (paint.getStrokeWidth() == 1) {\n            paint.setStrokeWidth(2);\n        }\n        float halfWidth = paint.getStrokeWidth() / 2;\n        canvas.clipRect(left, bottom -  radius, right, bottom + halfWidth);\n        canvas.drawRoundRect(left + halfWidth, bottom -  radius - radius, right - halfWidth, bottom, radius, radius, paint);\n\n        paint.setStrokeWidth(oldStrokeWidth);\n        paint.setColor(oldColor);\n        paint.setStyle(oldStyle);\n\n        canvas.restoreToCount(save);\n    }\n\n    private void drawRectWithBottomRound(Canvas canvas, Paint paint, RectF rect, float radius) {\n        drawRectWithBottomRound(canvas, paint, rect.left, rect.top, rect.right, rect.bottom, radius);\n    }\n\n    private void drawRectWithBottomRound(Canvas canvas, Paint paint,\n                                         float left, float top, float right, float bottom,\n                                         float radius) {\n        final int save = canvas.save();\n        final float oldStrokeWidth = paint.getStrokeWidth();\n        final int oldColor = paint.getColor();\n        final Paint.Style oldStyle = paint.getStyle();\n\n        paint.setStrokeWidth(2);\n        paint.setStyle(Paint.Style.FILL);\n\n        Path path = new Path();\n        RectF rect = new RectF(left, top, right, bottom);\n\n        // Move to the top-left corner\n        path.moveTo(rect.left, rect.top);\n\n        // Top line\n        path.lineTo(rect.right, rect.top);\n\n        // Right line\n        path.lineTo(rect.right, rect.bottom - radius);\n\n        // Bottom-right corner\n        path.arcTo(new RectF(rect.right - 2*radius, rect.bottom - 2*radius, rect.right, rect.bottom), 0, 90, false);\n\n        // Bottom line\n        path.lineTo(rect.left + radius, rect.bottom);\n\n        // Bottom-left corner\n        path.arcTo(new RectF(rect.left, rect.bottom - 2*radius, rect.left + 2*radius, rect.bottom), 90, 90, false);\n\n        // Left line\n        path.lineTo(rect.left, rect.top);\n\n        // Close the path\n        path.close();\n\n        canvas.drawPath(path, paint);\n\n        paint.setStrokeWidth(oldStrokeWidth);\n        paint.setColor(oldColor);\n        paint.setStyle(oldStyle);\n\n        canvas.restoreToCount(save);\n    }\n\n    private boolean recreateLayouts(int newWidth, float x) {\n        return width != newWidth || x != leading;\n    }\n\n    private void makeNewLayouts() {\n\n        final int columns = cells.size();\n        final int padding = mStyle.cellLeftRightPadding() * 2;\n        float w = cellWidth(columns) - padding + mStyle.cellTopBottomPadding();\n        if (w < 0) {\n            w = padding;\n            MDLogger.d(\"MYA_TableRowSpan\", \"w:\" + w + \",padding:\" + padding);\n        }\n\n        this.layouts.clear();\n\n        for (int i = 0, size = cells.size(); i < size; i++) {\n            makeLayout(i, (int) w, cells.get(i));\n        }\n    }\n\n    private void makeLayout(final int index, final int width, @NonNull final Cell cell) {\n\n        final Runnable recreate = () -> {\n            final Invalidator invalidator = TableRowSpan.this.invalidator;\n            if (invalidator != null) {\n                layouts.remove(index);\n                makeLayout(index, width, cell);\n                invalidator.invalidate();\n            }\n        };\n\n        final Spannable spannable;\n\n        if (cell.text instanceof Spannable) {\n            spannable = (Spannable) cell.text;\n        } else {\n            spannable = new SpannableString(cell.text);\n        }\n\n        final Layout layout = new StaticLayout(\n                spannable,\n                textPaint,\n                width,\n                alignment(cell.alignment),\n                1.0F,\n                0.0F,\n                false\n        );\n\n        // @since 4.4.0\n        TextLayoutSpan.applyTo(spannable, layout);\n\n        // @since 4.4.0\n        scheduleAsyncDrawables(spannable, recreate);\n\n        layouts.add(index, layout);\n    }\n\n    private void scheduleAsyncDrawables(@NonNull Spannable spannable, @NonNull final Runnable recreate) {\n\n        final AsyncDrawableSpan[] spans = spannable.getSpans(0, spannable.length(), AsyncDrawableSpan.class);\n        if (spans != null\n                && spans.length > 0) {\n\n            for (AsyncDrawableSpan span : spans) {\n\n                final AsyncDrawable drawable = span.getDrawable();\n\n                // it is absolutely crucial to check if drawable is already attached,\n                //  otherwise we would end up with a loop\n                if (drawable.isAttached()) {\n                    continue;\n                }\n\n                drawable.setCallback2(new CallbackAdapter() {\n                    @Override\n                    public void invalidateDrawable(@NonNull Drawable who) {\n                        recreate.run();\n                    }\n                });\n            }\n        }\n    }\n\n    /**\n     * Obtain Layout given horizontal offset. Primary usage target - MovementMethod\n     *\n     * @since 4.6.0\n     */\n    @Nullable\n    public Layout findLayoutForHorizontalOffset(int x) {\n        final int size = layouts.size();\n        final float w = cellWidth(size);\n        final int i = (int) (x / w);\n        if (i >= size) {\n            return null;\n        }\n        return layouts.get(i);\n    }\n\n    /**\n     * @since 4.6.0\n     */\n    public int cellWidth() {\n        return (int) cellWidth(layouts.size());\n    }\n\n    // @since 4.6.0\n    protected float cellWidth(int size) {\n        return 1F * width / size;\n    }\n\n    @SuppressLint(\"SwitchIntDef\")\n    private static Layout.Alignment alignment(@Alignment int alignment) {\n        final Layout.Alignment out;\n        switch (alignment) {\n            case ALIGN_CENTER:\n                out = Layout.Alignment.ALIGN_CENTER;\n                break;\n            case ALIGN_RIGHT:\n                out = Layout.Alignment.ALIGN_OPPOSITE;\n                break;\n            default:\n                out = Layout.Alignment.ALIGN_NORMAL;\n                break;\n        }\n        return out;\n    }\n\n    public void invalidator(@Nullable Invalidator invalidator) {\n        this.invalidator = invalidator;\n    }\n\n    private static abstract class CallbackAdapter implements Drawable.Callback {\n        @Override\n        public void invalidateDrawable(@NonNull Drawable who) {\n\n        }\n\n        @Override\n        public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) {\n\n        }\n\n        @Override\n        public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) {\n\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tables/src/main/java/io/noties/markwon/ext/tables/TableRowsScheduler.java",
    "content": "package io.noties.markwon.ext.tables;\n\nimport android.text.Spanned;\nimport android.text.TextUtils;\nimport android.view.View;\nimport android.widget.TextView;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nabstract class TableRowsScheduler {\n\n    static void schedule(@NonNull final TextView view) {\n        final Object[] spans = extract(view);\n        if (spans != null\n                && spans.length > 0) {\n\n            if (view.getTag(R.id.markwon_tables_scheduler) == null) {\n                final View.OnAttachStateChangeListener listener = new View.OnAttachStateChangeListener() {\n                    @Override\n                    public void onViewAttachedToWindow(View v) {\n\n                    }\n\n                    @Override\n                    public void onViewDetachedFromWindow(View v) {\n                        unschedule(view);\n                        view.removeOnAttachStateChangeListener(this);\n                        view.setTag(R.id.markwon_tables_scheduler, null);\n                    }\n                };\n                view.addOnAttachStateChangeListener(listener);\n                view.setTag(R.id.markwon_tables_scheduler, listener);\n            }\n\n            final TableRowSpan.Invalidator invalidator = new TableRowSpan.Invalidator() {\n\n                // @since 4.1.0\n                // let's stack-up invalidation calls (so invalidation happens,\n                // but not with each table-row-span draw call)\n                final Runnable runnable = new Runnable() {\n                    @Override\n                    public void run() {\n                        view.setText(view.getText());\n                    }\n                };\n\n                @Override\n                public void invalidate() {\n                    // @since 4.1.0 post invalidation (combine multiple calls)\n                    view.removeCallbacks(runnable);\n                    view.post(runnable);\n                }\n            };\n\n            for (Object span : spans) {\n                ((TableRowSpan) span).invalidator(invalidator);\n            }\n        }\n    }\n\n    static void unschedule(@NonNull TextView view) {\n        final Object[] spans = extract(view);\n        if (spans != null\n                && spans.length > 0) {\n            for (Object span : spans) {\n                ((TableRowSpan) span).invalidator(null);\n            }\n        }\n    }\n\n    @Nullable\n    private static Object[] extract(@NonNull TextView view) {\n        final Object[] out;\n        final CharSequence text = view.getText();\n        if (!TextUtils.isEmpty(text) && text instanceof Spanned) {\n            out = ((Spanned) text).getSpans(0, text.length(), TableRowSpan.class);\n        } else {\n            out = null;\n        }\n        return out;\n    }\n\n    private TableRowsScheduler() {\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tables/src/main/java/io/noties/markwon/ext/tables/TableSpan.java",
    "content": "package io.noties.markwon.ext.tables;\n\n/**\n * @since 4.3.1\n */\npublic class TableSpan {\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tables/src/main/res/values/ids.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n    <item name=\"markwon_tables_scheduler\" type=\"id\" />\n    <item type=\"id\" name=\"markdown_original_text\"/>\n</resources>"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tables/src/main/res/values/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <string name=\"copy_failed\">Copy failed</string>\n    <string name=\"copied\">Copied</string>\n    <string name=\"table\">Table</string>\n</resources>"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tables/src/main/res/values-zh/strings.xml",
    "content": "<resources>\n    <string name=\"copy_failed\">复制失败</string>\n    <string name=\"copied\">复制成功</string>\n    <string name=\"table\">表格</string>\n</resources>"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tables/src/test/java/io/noties/markwon/ext/tables/ExampleUnitTest.java",
    "content": "package io.noties.markwon.ext.tables;\n\nimport static org.junit.Assert.assertEquals;\n\nimport org.junit.Test;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tasklist/.gitignore",
    "content": "/build"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tasklist/build.gradle",
    "content": "plugins {\n    alias(libs.plugins.android.library)\n}\n\nandroid {\n    namespace 'io.noties.markwon.ext.tasklist'\n    compileSdk 35\n\n    defaultConfig {\n        minSdk 21\n\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n        consumerProguardFiles \"consumer-rules.pro\"\n    }\n\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n        }\n    }\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_11\n        targetCompatibility JavaVersion.VERSION_11\n    }\n}\n\ndependencies {\n\n    implementation libs.androidx.appcompat\n    compileOnly project(':markwon-core')\n    testImplementation libs.junit\n    androidTestImplementation libs.androidx.junit\n    androidTestImplementation libs.androidx.espresso.core\n}"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tasklist/consumer-rules.pro",
    "content": ""
  },
  {
    "path": "Android/AntFluid/markwon-ext-tasklist/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tasklist/src/androidTest/java/io/noties/markwon/ext/tasklist/ExampleInstrumentedTest.java",
    "content": "package io.noties.markwon.ext.tasklist;\n\nimport static org.junit.Assert.assertEquals;\n\nimport android.content.Context;\n\nimport androidx.test.ext.junit.runners.AndroidJUnit4;\nimport androidx.test.platform.app.InstrumentationRegistry;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();\n        assertEquals(\"io.noties.markwon.ext.tasklist.test\", appContext.getPackageName());\n    }\n}"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tasklist/src/main/AndroidManifest.xml",
    "content": "<manifest package=\"io.noties.markwon.ext.tasklist\" />\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tasklist/src/main/java/io/noties/markwon/ext/tasklist/TaskListDrawable.java",
    "content": "package io.noties.markwon.ext.tasklist;\n\nimport android.graphics.Canvas;\nimport android.graphics.ColorFilter;\nimport android.graphics.Paint;\nimport android.graphics.Path;\nimport android.graphics.PixelFormat;\nimport android.graphics.Rect;\nimport android.graphics.RectF;\nimport android.graphics.drawable.Drawable;\n\nimport androidx.annotation.ColorInt;\nimport androidx.annotation.IntRange;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\n/**\n * @since 1.0.1\n */\n@SuppressWarnings(\"WeakerAccess\")\npublic class TaskListDrawable extends Drawable {\n\n    // represent ratios (not exact coordinates)\n    private static final Point POINT_0 = new Point(2.75F / 18, 8.25F / 18);\n    private static final Point POINT_1 = new Point(7.F / 18, 12.5F / 18);\n    private static final Point POINT_2 = new Point(15.25F / 18, 4.75F / 18);\n\n    private final int checkedFillColor;\n    private final int normalOutlineColor;\n\n    private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);\n    private final RectF rectF = new RectF();\n\n    private final Paint checkMarkPaint = new Paint(Paint.ANTI_ALIAS_FLAG);\n    private final Path checkMarkPath = new Path();\n\n    private boolean isChecked;\n\n    // unfortunately we cannot rely on TextView to be LAYER_TYPE_SOFTWARE\n    // if we could we would draw our checkMarkPath with PorterDuff.CLEAR\n    public TaskListDrawable(\n            @ColorInt int checkedFillColor,\n            @ColorInt int normalOutlineColor,\n            @ColorInt int checkMarkColor) {\n        this.checkedFillColor = checkedFillColor;\n        this.normalOutlineColor = normalOutlineColor;\n\n        checkMarkPaint.setColor(checkMarkColor);\n        checkMarkPaint.setStyle(Paint.Style.STROKE);\n    }\n\n    @Override\n    protected void onBoundsChange(Rect bounds) {\n        super.onBoundsChange(bounds);\n\n        // we should exclude stroke with from final bounds (half of the strokeWidth from all sides)\n\n        // we should have square shape\n        final float min = Math.min(bounds.width(), bounds.height());\n        final float stroke = min / 8;\n\n        final float side = min - stroke;\n        rectF.set(0, 0, side, side);\n\n        paint.setStrokeWidth(stroke);\n        checkMarkPaint.setStrokeWidth(stroke);\n\n        checkMarkPath.reset();\n\n        POINT_0.moveTo(checkMarkPath, side);\n        POINT_1.lineTo(checkMarkPath, side);\n        POINT_2.lineTo(checkMarkPath, side);\n    }\n\n    @Override\n    public void draw(@NonNull Canvas canvas) {\n\n        final Paint.Style style;\n        final int color;\n\n        if (isChecked) {\n            style = Paint.Style.FILL_AND_STROKE;\n            color = checkedFillColor;\n        } else {\n            style = Paint.Style.STROKE;\n            color = normalOutlineColor;\n        }\n        paint.setStyle(style);\n        paint.setColor(color);\n\n        final Rect bounds = getBounds();\n\n        final float left = (bounds.width() - rectF.width()) / 2;\n        final float top = (bounds.height() - rectF.height()) / 2;\n\n        final float radius = rectF.width() / 8;\n\n        final int save = canvas.save();\n        try {\n\n            canvas.translate(left, top);\n\n            canvas.drawRoundRect(rectF, radius, radius, paint);\n\n            if (isChecked) {\n                canvas.drawPath(checkMarkPath, checkMarkPaint);\n            }\n        } finally {\n            canvas.restoreToCount(save);\n        }\n    }\n\n    @Override\n    public void setAlpha(@IntRange(from = 0, to = 255) int alpha) {\n        paint.setAlpha(alpha);\n    }\n\n    @Override\n    public void setColorFilter(@Nullable ColorFilter colorFilter) {\n        paint.setColorFilter(colorFilter);\n    }\n\n    @Override\n    public int getOpacity() {\n        return PixelFormat.OPAQUE;\n    }\n\n    @Override\n    public boolean isStateful() {\n        return true;\n    }\n\n    @Override\n    protected boolean onStateChange(int[] state) {\n\n        final boolean checked;\n\n        final int length = state != null\n                ? state.length\n                : 0;\n\n        if (length > 0) {\n\n            boolean inner = false;\n\n            for (int i = 0; i < length; i++) {\n                if (android.R.attr.state_checked == state[i]) {\n                    inner = true;\n                    break;\n                }\n            }\n            checked = inner;\n        } else {\n            checked = false;\n        }\n\n        final boolean result = checked != isChecked;\n        if (result) {\n            invalidateSelf();\n            isChecked = checked;\n        }\n\n        return result;\n    }\n\n    private static class Point {\n\n        final float x;\n        final float y;\n\n        Point(float x, float y) {\n            this.x = x;\n            this.y = y;\n        }\n\n        void moveTo(@NonNull Path path, float side) {\n            path.moveTo(side * x, side * y);\n        }\n\n        void lineTo(@NonNull Path path, float side) {\n            path.lineTo(side * x, side * y);\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tasklist/src/main/java/io/noties/markwon/ext/tasklist/TaskListItem.java",
    "content": "package io.noties.markwon.ext.tasklist;\n\nimport androidx.annotation.NonNull;\n\nimport org.commonmark.node.CustomBlock;\n\n/**\n * @since 1.0.1\n */\n@SuppressWarnings(\"WeakerAccess\")\npublic class TaskListItem extends CustomBlock {\n\n    private final boolean isDone;\n\n    public TaskListItem(boolean isDone) {\n        this.isDone = isDone;\n    }\n\n    public boolean isDone() {\n        return isDone;\n    }\n\n    @Override\n    @NonNull\n    public String toString() {\n        return \"TaskListItem{\" +\n                \"isDone=\" + isDone +\n                '}';\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tasklist/src/main/java/io/noties/markwon/ext/tasklist/TaskListPlugin.java",
    "content": "package io.noties.markwon.ext.tasklist;\n\nimport android.content.Context;\nimport android.content.res.TypedArray;\nimport android.graphics.drawable.Drawable;\nimport android.util.TypedValue;\n\nimport androidx.annotation.AttrRes;\nimport androidx.annotation.ColorInt;\nimport androidx.annotation.NonNull;\n\nimport org.commonmark.parser.Parser;\n\nimport io.noties.markwon.AbstractMarkwonPlugin;\nimport io.noties.markwon.MarkwonSpansFactory;\nimport io.noties.markwon.MarkwonVisitor;\nimport io.noties.markwon.core.SimpleBlockNodeVisitor;\n\n/**\n * @since 3.0.0\n */\npublic class TaskListPlugin extends AbstractMarkwonPlugin {\n\n    /**\n     * Supplied Drawable must be stateful ({@link Drawable#isStateful()} returns true). If a task\n     * is marked as done, then this drawable will be updated with an {@code int[] { android.R.attr.state_checked }}\n     * as the state, otherwise an empty array will be used. This library provides a ready to be\n     * used Drawable: {@link TaskListDrawable}\n     *\n     * @see TaskListDrawable\n     */\n    @NonNull\n    public static TaskListPlugin create(@NonNull Drawable drawable) {\n        return new TaskListPlugin(drawable);\n    }\n\n    @NonNull\n    public static TaskListPlugin create(@NonNull Context context) {\n\n        // by default we will be using link color for the checkbox color\n        // & window background as a checkMark color\n        final int linkColor = resolve(context, android.R.attr.textColorLink);\n        final int backgroundColor = resolve(context, android.R.attr.colorBackground);\n\n        return new TaskListPlugin(new TaskListDrawable(linkColor, linkColor, backgroundColor));\n    }\n\n    @NonNull\n    public static TaskListPlugin create(\n            @ColorInt int checkedFillColor,\n            @ColorInt int normalOutlineColor,\n            @ColorInt int checkMarkColor) {\n        return new TaskListPlugin(new TaskListDrawable(\n                checkedFillColor,\n                normalOutlineColor,\n                checkMarkColor));\n    }\n\n    private final Drawable drawable;\n\n    private TaskListPlugin(@NonNull Drawable drawable) {\n        this.drawable = drawable;\n    }\n\n    @Override\n    public void configureParser(@NonNull Parser.Builder builder) {\n        builder.postProcessor(new TaskListPostProcessor());\n    }\n\n    @Override\n    public void configureSpansFactory(@NonNull MarkwonSpansFactory.Builder builder) {\n        builder.setFactory(TaskListItem.class, new TaskListSpanFactory(drawable));\n    }\n\n    @Override\n    public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) {\n        builder\n                .on(TaskListItem.class, new MarkwonVisitor.NodeVisitor<TaskListItem>() {\n                    @Override\n                    public void visit(@NonNull MarkwonVisitor visitor, @NonNull TaskListItem taskListItem) {\n\n                        final int length = visitor.length();\n\n                        visitor.visitChildren(taskListItem);\n\n                        TaskListProps.DONE.set(visitor.renderProps(), taskListItem.isDone());\n\n                        visitor.setSpansForNode(taskListItem, length);\n\n                        if (visitor.hasNext(taskListItem)) {\n                            visitor.ensureNewLine();\n                        }\n                    }\n                });\n    }\n\n    private static int resolve(@NonNull Context context, @AttrRes int attr) {\n        final TypedValue typedValue = new TypedValue();\n        final int[] attrs = new int[]{attr};\n        final TypedArray typedArray = context.obtainStyledAttributes(typedValue.data, attrs);\n        try {\n            return typedArray.getColor(0, 0);\n        } finally {\n            typedArray.recycle();\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tasklist/src/main/java/io/noties/markwon/ext/tasklist/TaskListPostProcessor.java",
    "content": "package io.noties.markwon.ext.tasklist;\n\nimport android.text.TextUtils;\n\nimport org.commonmark.node.AbstractVisitor;\nimport org.commonmark.node.ListItem;\nimport org.commonmark.node.Node;\nimport org.commonmark.node.Paragraph;\nimport org.commonmark.node.Text;\nimport org.commonmark.parser.PostProcessor;\n\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\nimport io.noties.markwon.utils.ParserUtils;\n\n// @since 4.6.0\n// Hint taken from commonmark-ext-task-list-items artifact\nclass TaskListPostProcessor implements PostProcessor {\n\n    @Override\n    public Node process(Node node) {\n        final TaskListVisitor visitor = new TaskListVisitor();\n        node.accept(visitor);\n        return node;\n    }\n\n    private static class TaskListVisitor extends AbstractVisitor {\n\n        private static final Pattern REGEX_TASK_LIST_ITEM = Pattern.compile(\"^\\\\[([xX\\\\s])]\\\\s+(.*)\");\n\n        @Override\n        public void visit(ListItem listItem) {\n            // Takes first child and checks if it is Text (we are looking for exact `[xX\\s]` without any formatting)\n            final Node child = listItem.getFirstChild();\n            // check if it is paragraph (can contain text)\n            if (child instanceof Paragraph) {\n                final Node node = child.getFirstChild();\n                if (node instanceof Text) {\n\n                    final Text textNode = (Text) node;\n                    final Matcher matcher = REGEX_TASK_LIST_ITEM.matcher(textNode.getLiteral());\n\n                    if (matcher.matches()) {\n                        final String checked = matcher.group(1);\n                        final boolean isChecked = \"x\".equals(checked) || \"X\".equals(checked);\n\n                        final TaskListItem taskListItem = new TaskListItem(isChecked);\n\n                        final Paragraph paragraph = new Paragraph();\n\n                        // insert before list item (directly before inside parent)\n                        listItem.insertBefore(taskListItem);\n\n                        // append the rest of matched text (can be empty)\n                        final String restMatchedText = matcher.group(2);\n                        if (!TextUtils.isEmpty(restMatchedText)) {\n                            paragraph.appendChild(new Text(restMatchedText));\n                        }\n\n                        // move all the rest children (from the first paragraph)\n                        ParserUtils.moveChildren(paragraph, node);\n\n                        // append our created paragraph\n                        taskListItem.appendChild(paragraph);\n\n                        // move all the rest children from the listItem (further nested lists, etc)\n                        ParserUtils.moveChildren(taskListItem, child);\n\n                        // remove list item from node\n                        listItem.unlink();\n\n                        // visit taskListItem children\n                        visitChildren(taskListItem);\n                        return;\n                    }\n                }\n            }\n            visitChildren(listItem);\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tasklist/src/main/java/io/noties/markwon/ext/tasklist/TaskListProps.java",
    "content": "package io.noties.markwon.ext.tasklist;\n\nimport io.noties.markwon.Prop;\n\n/**\n * @since 3.0.0\n */\npublic abstract class TaskListProps {\n\n    public static final Prop<Boolean> DONE = Prop.of(\"task-list-done\");\n\n    private TaskListProps() {\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tasklist/src/main/java/io/noties/markwon/ext/tasklist/TaskListSpan.java",
    "content": "package io.noties.markwon.ext.tasklist;\n\nimport android.graphics.Canvas;\nimport android.graphics.Paint;\nimport android.graphics.drawable.Drawable;\nimport android.text.Layout;\nimport android.text.style.LeadingMarginSpan;\n\nimport androidx.annotation.NonNull;\n\nimport io.noties.markwon.core.MarkwonTheme;\nimport io.noties.markwon.utils.LeadingMarginUtils;\nimport com.fluid.afm.utils.Utils;\n\n/**\n * @since 1.0.1\n */\npublic class TaskListSpan implements LeadingMarginSpan {\n\n    private static final int[] STATE_CHECKED = new int[]{android.R.attr.state_checked};\n\n    private static final int[] STATE_NONE = new int[0];\n    private static final int LEADING = Utils.dpToPx(8);\n\n\n    private final MarkwonTheme theme;\n    private final Drawable drawable;\n\n    // @since 2.0.1 field is NOT final (to allow mutation)\n    private boolean isDone;\n\n    public TaskListSpan(@NonNull MarkwonTheme theme, @NonNull Drawable drawable, boolean isDone) {\n        this.theme = theme;\n        this.drawable = drawable;\n        this.isDone = isDone;\n    }\n\n    /**\n     * @since 2.0.1\n     */\n    public boolean isDone() {\n        return isDone;\n    }\n\n    /**\n     * Update {@link #isDone} property of this span. Please note that this is merely a visual change\n     * which is not changing underlying text in any means.\n     *\n     * @since 2.0.1\n     */\n    public void setDone(boolean isDone) {\n        this.isDone = isDone;\n    }\n\n    @Override\n    public int getLeadingMargin(boolean first) {\n        return LEADING;\n    }\n\n    @Override\n    public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline, int bottom, CharSequence text, int start, int end, boolean first, Layout layout) {\n\n        if (!first\n                || !LeadingMarginUtils.selfStart(start, text, this)) {\n            return;\n        }\n\n        final float descent = p.descent();\n        final float ascent = p.ascent();\n\n        final int save = c.save();\n        try {\n\n            final int width = LEADING;\n            final int height = (int) (descent - ascent + 0.5F);\n\n            final int w = (int) (width * .75F + .5F);\n            final int h = (int) (height * .75F + .5F);\n\n            drawable.setBounds(0, 0, w, h);\n\n            if (drawable.isStateful()) {\n                final int[] state;\n                if (isDone) {\n                    state = STATE_CHECKED;\n                } else {\n                    state = STATE_NONE;\n                }\n                drawable.setState(state);\n            }\n\n            final int l;\n            if (dir > 0) {\n                l = x + ((width - w) / 2);\n            } else {\n                l = x - ((width - w) / 2) - w;\n            }\n\n            final int t = (int) (baseline + ascent + 0.5F) + ((height - h) / 2);\n\n            c.translate(l, t);\n            drawable.draw(c);\n\n        } finally {\n            c.restoreToCount(save);\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tasklist/src/main/java/io/noties/markwon/ext/tasklist/TaskListSpanFactory.java",
    "content": "package io.noties.markwon.ext.tasklist;\n\nimport android.graphics.drawable.Drawable;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.RenderProps;\nimport io.noties.markwon.SpanFactory;\n\npublic class TaskListSpanFactory implements SpanFactory {\n\n    private final Drawable drawable;\n\n    public TaskListSpanFactory(@NonNull Drawable drawable) {\n        this.drawable = drawable;\n    }\n\n    @Nullable\n    @Override\n    public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps props) {\n        return new TaskListSpan(\n                configuration.theme(),\n                drawable,\n                TaskListProps.DONE.get(props, false)\n        );\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-ext-tasklist/src/test/java/io/noties/markwon/ext/tasklist/ExampleUnitTest.java",
    "content": "package io.noties.markwon.ext.tasklist;\n\nimport static org.junit.Assert.assertEquals;\n\nimport org.junit.Test;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "Android/AntFluid/markwon-html/.gitignore",
    "content": "/build"
  },
  {
    "path": "Android/AntFluid/markwon-html/build.gradle",
    "content": "plugins {\n    alias(libs.plugins.android.library)\n}\n\nandroid {\n    namespace 'io.noties.markwon.html'\n    compileSdk 35\n\n    defaultConfig {\n        minSdk 21\n\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n        consumerProguardFiles \"consumer-rules.pro\"\n    }\n\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n        }\n    }\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_11\n        targetCompatibility JavaVersion.VERSION_11\n    }\n}\n\ndependencies {\n    implementation libs.androidx.appcompat\n    compileOnly project(':markwon-core')\n\n    testImplementation libs.junit\n    androidTestImplementation libs.androidx.junit\n    androidTestImplementation libs.androidx.espresso.core\n}"
  },
  {
    "path": "Android/AntFluid/markwon-html/consumer-rules.pro",
    "content": ""
  },
  {
    "path": "Android/AntFluid/markwon-html/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/androidTest/java/io/noties/markwon/html/ExampleInstrumentedTest.java",
    "content": "package io.noties.markwon.html;\n\nimport static org.junit.Assert.assertEquals;\n\nimport android.content.Context;\n\nimport androidx.test.ext.junit.runners.AndroidJUnit4;\nimport androidx.test.platform.app.InstrumentationRegistry;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();\n        assertEquals(\"io.noties.markwon.html.test\", appContext.getPackageName());\n    }\n}"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/AndroidManifest.xml",
    "content": "<manifest package=\"io.noties.markwon.html\" />\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/com/fluid/afm/spans/DefinitionListSpan.java",
    "content": "package com.fluid.afm.spans;\n\nimport android.graphics.Typeface;\nimport android.text.Layout;\nimport android.text.style.LeadingMarginSpan;\nimport android.text.style.StyleSpan;\n\n\npublic class DefinitionListSpan implements LeadingMarginSpan {\n    private static final int MARGIN = 24; // dp\n\n    @Override\n    public int getLeadingMargin(boolean first) {\n        return MARGIN;\n    }\n\n    @Override\n    public void drawLeadingMargin(android.graphics.Canvas canvas, android.graphics.Paint paint,\n                                 int x, int dir, int top, int baseline, int bottom,\n                                 CharSequence text, int start, int end, boolean first,\n                                 Layout layout) {\n    }\n\n    public static class TermSpan extends StyleSpan {\n        public TermSpan() {\n            super(Typeface.BOLD);\n        }\n    }\n\n\n    public static class DescriptionSpan implements LeadingMarginSpan {\n        private static final int DESCRIPTION_MARGIN = 48; // dp\n\n        @Override\n        public int getLeadingMargin(boolean first) {\n            return DESCRIPTION_MARGIN;\n        }\n\n        @Override\n        public void drawLeadingMargin(android.graphics.Canvas canvas, android.graphics.Paint paint,\n                                     int x, int dir, int top, int baseline, int bottom,\n                                     CharSequence text, int start, int end, boolean first,\n                                     Layout layout) {\n        }\n    }\n} "
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/com/fluid/afm/tag/DefinitionListTagHandler.java",
    "content": "package com.fluid.afm.tag;\n\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport java.util.Arrays;\nimport java.util.Collection;\n\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.RenderProps;\nimport io.noties.markwon.html.HtmlTag;\nimport com.fluid.afm.spans.DefinitionListSpan;\nimport io.noties.markwon.html.tag.SimpleTagHandler;\n\npublic class DefinitionListTagHandler extends SimpleTagHandler {\n\n    @Nullable\n    @Override\n    public Object getSpans(\n            @NonNull MarkwonConfiguration configuration,\n            @NonNull RenderProps renderProps,\n            @NonNull HtmlTag tag) {\n        final String tagName = tag.name();\n        \n        if (\"dl\".equals(tagName)) {\n            return new DefinitionListSpan();\n        } else if (\"dt\".equals(tagName)) {\n            return new DefinitionListSpan.TermSpan();\n        } else if (\"dd\".equals(tagName)) {\n            return new DefinitionListSpan.DescriptionSpan();\n        }\n        \n        return null;\n    }\n\n    @NonNull\n    @Override\n    public Collection<String> supportedTags() {\n        return Arrays.asList(\"dl\", \"dt\", \"dd\");\n    }\n\n    public static DefinitionListTagHandler create() {\n        return new DefinitionListTagHandler();\n    }\n}"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/AppendableUtils.java",
    "content": "package io.noties.markwon.html;\n\nimport androidx.annotation.NonNull;\n\nimport java.io.IOException;\n\nabstract class AppendableUtils {\n\n    static void appendQuietly(@NonNull Appendable appendable, char c) {\n        try {\n            appendable.append(c);\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    static void appendQuietly(@NonNull Appendable appendable, @NonNull CharSequence cs) {\n        try {\n            appendable.append(cs);\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    static void appendQuietly(@NonNull Appendable appendable, @NonNull CharSequence cs, int start, int end) {\n        try {\n            appendable.append(cs, start, end);\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    private AppendableUtils() {\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/CssInlineStyleParser.java",
    "content": "package io.noties.markwon.html;\n\nimport android.text.TextUtils;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport java.util.Iterator;\nimport java.util.NoSuchElementException;\n\npublic abstract class CssInlineStyleParser {\n\n    @NonNull\n    public abstract Iterable<CssProperty> parse(@NonNull String inlineStyle);\n\n    @NonNull\n    public static CssInlineStyleParser create() {\n        return new Impl();\n    }\n\n    static class Impl extends CssInlineStyleParser {\n\n        @NonNull\n        @Override\n        public Iterable<CssProperty> parse(@NonNull String inlineStyle) {\n            return new CssIterable(inlineStyle);\n        }\n\n        private static class CssIterable implements Iterable<CssProperty> {\n\n            private final String input;\n\n            CssIterable(@NonNull String input) {\n                this.input = input;\n            }\n\n            @NonNull\n            @Override\n            public Iterator<CssProperty> iterator() {\n                return new CssIterator();\n            }\n\n            private class CssIterator implements Iterator<CssProperty> {\n\n                private final CssProperty cssProperty = new CssProperty();\n\n                private final StringBuilder builder = new StringBuilder();\n\n                private final int length = input.length();\n\n                private int index;\n\n                @Override\n                public boolean hasNext() {\n\n                    prepareNext();\n\n                    return hasNextPrepared();\n                }\n\n                @Override\n                public CssProperty next() {\n                    if (!hasNextPrepared()) {\n                        throw new NoSuchElementException();\n                    }\n                    return cssProperty;\n                }\n\n                private void prepareNext() {\n\n                    // clear first\n                    cssProperty.set(\"\", \"\");\n\n                    builder.setLength(0);\n\n                    String key = null;\n                    String value = null;\n\n                    char c;\n\n                    boolean keyHasWhiteSpace = false;\n\n                    for (int i = index; i < length; i++) {\n\n                        c = input.charAt(i);\n\n                        // if we are building KEY, then when we encounter WS (white-space) we finish\n                        // KEY and wait for the ':', if we do not find it and we find EOF or ';'\n                        // we start creating KEY again after the ';'\n\n                        if (key == null) {\n\n                            if (':' == c) {\n\n                                // we have no key yet, but we might have started creating it already\n                                if (builder.length() > 0) {\n                                    key = builder.toString().trim();\n                                }\n\n                                builder.setLength(0);\n\n                            } else {\n                                // if by any chance we have here the ';' -> reset key and try to match next\n                                if (';' == c) {\n                                    builder.setLength(0);\n                                } else {\n\n                                    // key cannot have WS gaps (but leading and trailing are OK)\n                                    if (Character.isWhitespace(c)) {\n                                        if (builder.length() > 0) {\n                                            keyHasWhiteSpace = true;\n                                        }\n                                    } else {\n                                        // if not a WS and we have found WS before, start a-new\n                                        // else append\n                                        if (keyHasWhiteSpace) {\n                                            // start new filling\n                                            builder.setLength(0);\n                                            builder.append(c);\n                                            // clear this flag\n                                            keyHasWhiteSpace = false;\n                                        } else {\n                                            builder.append(c);\n                                        }\n                                    }\n                                }\n                            }\n                        } else if (value == null) {\n\n                            if (Character.isWhitespace(c)) {\n                                if (builder.length() > 0) {\n                                    builder.append(c);\n                                }\n                            } else if (';' == c) {\n\n                                value = builder.toString().trim();\n                                builder.setLength(0);\n\n                                // check if we have valid values -> if yes -> return it\n                                if (hasValues(key, value)) {\n                                    index = i + 1;\n                                    cssProperty.set(key, value);\n                                    return;\n                                }\n\n                            } else {\n                                builder.append(c);\n                            }\n                        }\n                    }\n\n                    // here we must additionally check for EOF (we might be tracking value here)\n                    if (key != null\n                            && builder.length() > 0) {\n                        value = builder.toString().trim();\n                        cssProperty.set(key, value);\n                        index = length;\n                    }\n                }\n\n                private boolean hasNextPrepared() {\n                    return hasValues(cssProperty.key(), cssProperty.value());\n                }\n\n                private boolean hasValues(@Nullable String key, @Nullable String value) {\n                    return !TextUtils.isEmpty(key)\n                            && !TextUtils.isEmpty(value);\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/CssProperty.java",
    "content": "package io.noties.markwon.html;\n\nimport androidx.annotation.NonNull;\n\npublic class CssProperty {\n\n    private String key;\n    private String value;\n\n    CssProperty() {\n    }\n\n    void set(@NonNull String key, @NonNull String value) {\n        this.key = key;\n        this.value = value;\n    }\n\n    @NonNull\n    public String key() {\n        return key;\n    }\n\n    @NonNull\n    public String value() {\n        return value;\n    }\n\n    @NonNull\n    public CssProperty mutate() {\n        final CssProperty cssProperty = new CssProperty();\n        cssProperty.set(this.key, this.value);\n        return cssProperty;\n    }\n\n    @Override\n    public String toString() {\n        return \"CssProperty{\" +\n                \"key='\" + key + '\\'' +\n                \", value='\" + value + '\\'' +\n                '}';\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/HtmlEmptyTagReplacement.java",
    "content": "package io.noties.markwon.html;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\n/**\n * This class will be used to append some text to output in order to\n * apply a Span for this tag. Please note that this class will be used for\n * _void_ tags and tags that are self-closed (even if HTML spec doesn\\'t specify\n * a tag as self-closed). This is due to the fact that underlying parser does not\n * validate context and does not check if a tag is correctly used. Plus it will be\n * used for tags without content, for example: {@code <my-custom-element></my-custom-element>}\n *\n * @since 2.0.0\n */\npublic class HtmlEmptyTagReplacement {\n\n    @NonNull\n    public static HtmlEmptyTagReplacement create() {\n        return new HtmlEmptyTagReplacement();\n    }\n\n    private static final String IMG_REPLACEMENT = \"\\uFFFC\";\n    private static final String IFRAME_REPLACEMENT = \"\\u00a0\"; // non-breakable space\n\n    /**\n     * @return replacement for supplied startTag or null if no replacement should occur (which will\n     * lead to `Inline` tag have start &amp; end the same value, thus not applicable for applying a Span)\n     */\n    @Nullable\n    public String replace(@NonNull HtmlTag tag) {\n\n        final String replacement;\n\n        final String name = tag.name();\n\n        if (\"br\".equals(name)) {\n            replacement = \"\\n\";\n        } else if (\"img\".equals(name)) {\n            final String alt = tag.attributes().get(\"alt\");\n            if (alt == null\n                    || alt.length() == 0) {\n                // no alt is provided\n                replacement = IMG_REPLACEMENT;\n            } else {\n                replacement = alt;\n            }\n        } else if (\"iframe\".equals(name)) {\n            // @since 4.4.0 make iframe non-empty\n            replacement = IFRAME_REPLACEMENT;\n        } else {\n            replacement = null;\n        }\n\n        return replacement;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/HtmlPlugin.java",
    "content": "package io.noties.markwon.html;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport org.commonmark.node.HtmlBlock;\nimport org.commonmark.node.HtmlInline;\nimport org.commonmark.node.Node;\n\nimport io.noties.markwon.AbstractMarkwonPlugin;\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.MarkwonVisitor;\nimport io.noties.markwon.html.tag.BlockquoteHandler;\nimport com.fluid.afm.tag.DefinitionListTagHandler;\nimport io.noties.markwon.html.tag.EmphasisHandler;\nimport io.noties.markwon.html.tag.HeadingHandler;\nimport io.noties.markwon.html.tag.ImageHandler;\nimport io.noties.markwon.html.tag.LinkHandler;\nimport io.noties.markwon.html.tag.ListHandler;\nimport io.noties.markwon.html.tag.StrikeHandler;\nimport io.noties.markwon.html.tag.StrongEmphasisHandler;\nimport io.noties.markwon.html.tag.SubScriptHandler;\nimport io.noties.markwon.html.tag.SuperScriptHandler;\nimport io.noties.markwon.html.tag.UnderlineHandler;\nimport com.fluid.afm.utils.Utils;\n\n/**\n * @since 3.0.0\n */\npublic class HtmlPlugin extends AbstractMarkwonPlugin {\n\n    /**\n     * @see #create(HtmlConfigure)\n     * @since 4.0.0\n     */\n    public interface HtmlConfigure {\n        void configureHtml(@NonNull HtmlPlugin plugin);\n    }\n\n    @NonNull\n    public static HtmlPlugin create() {\n        return new HtmlPlugin();\n    }\n\n    /**\n     * @since 4.0.0\n     */\n    @NonNull\n    public static HtmlPlugin create(@NonNull HtmlConfigure configure) {\n        final HtmlPlugin plugin = create();\n        configure.configureHtml(plugin);\n        return plugin;\n    }\n\n    public static final float SCRIPT_DEF_TEXT_SIZE_RATIO = .75F;\n\n    private final MarkwonHtmlRendererImpl.Builder builder;\n\n    private MarkwonHtmlParser htmlParser;\n    private MarkwonHtmlRenderer htmlRenderer;\n\n    // @since 4.4.0\n    private HtmlEmptyTagReplacement emptyTagReplacement = new HtmlEmptyTagReplacement();\n\n    @SuppressWarnings(\"WeakerAccess\")\n    public HtmlPlugin() {\n        this.builder = new MarkwonHtmlRendererImpl.Builder();\n    }\n\n    /**\n     * @param allowNonClosedTags whether or not non-closed tags should be closed\n     *                           at the document end. By default `false`\n     * @since 4.0.0\n     */\n    @NonNull\n    public HtmlPlugin allowNonClosedTags(boolean allowNonClosedTags) {\n        builder.allowNonClosedTags(allowNonClosedTags);\n        return this;\n    }\n\n    /**\n     * @since 4.0.0\n     */\n    @NonNull\n    public HtmlPlugin addHandler(@NonNull TagHandler tagHandler) {\n        builder.addHandler(tagHandler);\n        return this;\n    }\n\n    /**\n     * @since 4.0.0\n     */\n    @Nullable\n    public TagHandler getHandler(@NonNull String tagName) {\n        return builder.getHandler(tagName);\n    }\n\n    /**\n     * Indicate if HtmlPlugin should register default HTML tag handlers. Pass `true` to <strong>not</strong>\n     * include default handlers. By default default handlers are included. You can use\n     * {@link TagHandlerNoOp} to no-op certain default tags.\n     *\n     * @see TagHandlerNoOp\n     * @since 4.0.0\n     */\n    @NonNull\n    public HtmlPlugin excludeDefaults(boolean excludeDefaults) {\n        builder.excludeDefaults(excludeDefaults);\n        return this;\n    }\n\n    /**\n     * @param emptyTagReplacement {@link HtmlEmptyTagReplacement}\n     * @since 4.4.0\n     */\n    @NonNull\n    public HtmlPlugin emptyTagReplacement(@NonNull HtmlEmptyTagReplacement emptyTagReplacement) {\n        this.emptyTagReplacement = emptyTagReplacement;\n        return this;\n    }\n\n    @Override\n    public void configureConfiguration(@NonNull MarkwonConfiguration.Builder configurationBuilder) {\n\n        // @since 4.0.0 we init internal html-renderer here (marks the end of configuration)\n\n        final MarkwonHtmlRendererImpl.Builder builder = this.builder;\n\n        if (!builder.excludeDefaults()) {\n            // please note that it's better to not checkState for\n            // this method call (minor optimization), final `build` method call\n            // will check for the state and throw an exception if applicable\n            builder.addDefaultTagHandler(ImageHandler.create());\n            builder.addDefaultTagHandler(new LinkHandler());\n            builder.addDefaultTagHandler(new BlockquoteHandler());\n            builder.addDefaultTagHandler(new SubScriptHandler());\n            builder.addDefaultTagHandler(new SuperScriptHandler());\n            builder.addDefaultTagHandler(new StrongEmphasisHandler());\n            builder.addDefaultTagHandler(new StrikeHandler());\n            builder.addDefaultTagHandler(new UnderlineHandler());\n            builder.addDefaultTagHandler(new ListHandler());\n            builder.addDefaultTagHandler(new EmphasisHandler());\n            builder.addDefaultTagHandler(new HeadingHandler());\n            builder.addDefaultTagHandler(new DefinitionListTagHandler());\n        }\n\n        htmlParser = MarkwonHtmlParserImpl.create(emptyTagReplacement);\n        htmlRenderer = builder.build();\n    }\n\n    @Override\n    public void afterRender(@NonNull Node node, @NonNull MarkwonVisitor visitor) {\n        final MarkwonHtmlRenderer htmlRenderer = this.htmlRenderer;\n        if (htmlRenderer != null) {\n            htmlRenderer.render(visitor, htmlParser);\n        } else {\n            throw new IllegalStateException(\"Unexpected state, html-renderer is not defined\");\n        }\n    }\n\n    @Override\n    public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) {\n        builder\n                .on(HtmlBlock.class, new MarkwonVisitor.NodeVisitor<HtmlBlock>() {\n                    @Override\n                    public void visit(@NonNull MarkwonVisitor visitor, @NonNull HtmlBlock htmlBlock) {\n                        visitHtml(visitor, htmlBlock.getLiteral());\n                    }\n                })\n                .on(HtmlInline.class, new MarkwonVisitor.NodeVisitor<HtmlInline>() {\n                    @Override\n                    public void visit(@NonNull MarkwonVisitor visitor, @NonNull HtmlInline htmlInline) {\n                        if (Utils.isInTableNode(htmlInline)) {\n                            return;\n                        }\n                        visitHtml(visitor, htmlInline.getLiteral());\n                    }\n                });\n    }\n\n    private void visitHtml(@NonNull MarkwonVisitor visitor, @Nullable String html) {\n        if (html != null) {\n            htmlParser.processFragment(visitor.builder(), html);\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/HtmlTag.java",
    "content": "package io.noties.markwon.html;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * @see Inline\n * @see Block\n * @since 2.0.0\n */\npublic interface HtmlTag {\n\n    int NO_END = -1;\n\n    /**\n     * @return normalized tag name (lower-case)\n     */\n    @NonNull\n    String name();\n\n    /**\n     * @return index at which this tag starts\n     */\n    int start();\n\n    /**\n     * @return index at which this tag ends\n     */\n    int end();\n\n    /**\n     * @return flag indicating if this tag has no content (when start == end)\n     */\n    boolean isEmpty();\n\n    /**\n     * @return flag indicating if this tag is closed (has valid start and end)\n     * @see #NO_END\n     */\n    boolean isClosed();\n\n    @NonNull\n    Map<String, String> attributes();\n\n    /**\n     * @see Inline\n     */\n    boolean isInline();\n\n    /**\n     * @see Block\n     */\n    boolean isBlock();\n\n    @NonNull\n    Inline getAsInline();\n\n    @NonNull\n    Block getAsBlock();\n\n    /**\n     * Represents <em>really</em> inline HTML tags (unlile commonmark definitions)\n     */\n    interface Inline extends HtmlTag {\n    }\n\n    /**\n     * Represents HTML block tags. Please note that all tags that are not inline should be\n     * considered as block tags\n     */\n    interface Block extends HtmlTag {\n\n        /**\n         * @return parent {@link Block} or null if there is no parent (this block is at root level)\n         */\n        @Nullable\n        Block parent();\n\n        /**\n         * @return list of children\n         */\n        @NonNull\n        List<Block> children();\n\n        /**\n         * @return a flag indicating if this {@link Block} is at the root level (shortcut to calling:\n         * {@code parent() == null}\n         */\n        boolean isRoot();\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/HtmlTagImpl.java",
    "content": "package io.noties.markwon.html;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Map;\n\nabstract class HtmlTagImpl implements HtmlTag {\n\n    final String name;\n    final int start;\n    final Map<String, String> attributes;\n    int end = NO_END;\n\n    protected HtmlTagImpl(@NonNull String name, int start, @NonNull Map<String, String> attributes) {\n        this.name = name;\n        this.start = start;\n        this.attributes = attributes;\n    }\n\n    @NonNull\n    @Override\n    public String name() {\n        return name;\n    }\n\n    @Override\n    public int start() {\n        return start;\n    }\n\n    @Override\n    public int end() {\n        return end;\n    }\n\n    @Override\n    public boolean isEmpty() {\n        return start == end;\n    }\n\n    @NonNull\n    @Override\n    public Map<String, String> attributes() {\n        return attributes;\n    }\n\n    @Override\n    public boolean isClosed() {\n        return end > NO_END;\n    }\n\n    abstract void closeAt(int end);\n\n\n    static class InlineImpl extends HtmlTagImpl implements Inline {\n\n        InlineImpl(@NonNull String name, int start, @NonNull Map<String, String> attributes) {\n            super(name, start, attributes);\n        }\n\n        @Override\n        void closeAt(int end) {\n            if (!isClosed()) {\n                super.end = end;\n            }\n        }\n\n        @Override\n        public String toString() {\n            return \"InlineImpl{\" +\n                    \"name='\" + name + '\\'' +\n                    \", start=\" + start +\n                    \", end=\" + end +\n                    \", attributes=\" + attributes +\n                    '}';\n        }\n\n        @Override\n        public boolean isInline() {\n            return true;\n        }\n\n        @Override\n        public boolean isBlock() {\n            return false;\n        }\n\n        @NonNull\n        @Override\n        public Inline getAsInline() {\n            return this;\n        }\n\n        @NonNull\n        @Override\n        public Block getAsBlock() {\n            throw new ClassCastException(\"Cannot cast Inline instance to Block\");\n        }\n    }\n\n    static class BlockImpl extends HtmlTagImpl implements Block {\n\n        @NonNull\n        static BlockImpl root() {\n            return new BlockImpl(\"\", 0, Collections.<String, String>emptyMap(), null);\n        }\n\n        @NonNull\n        static BlockImpl create(\n                @NonNull String name,\n                int start,\n                @NonNull Map<String, String> attributes,\n                @Nullable BlockImpl parent) {\n            return new BlockImpl(name, start, attributes, parent);\n        }\n\n        final BlockImpl parent;\n        List<BlockImpl> children;\n\n        @SuppressWarnings(\"NullableProblems\")\n        BlockImpl(\n                @NonNull String name,\n                int start,\n                @NonNull Map<String, String> attributes,\n                @Nullable BlockImpl parent) {\n            super(name, start, attributes);\n            this.parent = parent;\n        }\n\n        @Override\n        void closeAt(int end) {\n            if (!isClosed()) {\n                super.end = end;\n                if (children != null) {\n                    for (BlockImpl child : children) {\n                        child.closeAt(end);\n                    }\n                }\n            }\n        }\n\n        @Override\n        public boolean isRoot() {\n            return parent == null;\n        }\n\n        @Nullable\n        @Override\n        public Block parent() {\n            return parent;\n        }\n\n        @NonNull\n        @Override\n        public List<Block> children() {\n            final List<Block> list;\n            if (children == null) {\n                list = Collections.emptyList();\n            } else {\n                list = Collections.unmodifiableList((List<? extends Block>) children);\n            }\n            return list;\n        }\n\n        @NonNull\n        @Override\n        public Map<String, String> attributes() {\n            return attributes;\n        }\n\n        @Override\n        public boolean isInline() {\n            return false;\n        }\n\n        @Override\n        public boolean isBlock() {\n            return true;\n        }\n\n        @NonNull\n        @Override\n        public Inline getAsInline() {\n            throw new ClassCastException(\"Cannot cast Block instance to Inline\");\n        }\n\n        @NonNull\n        @Override\n        public Block getAsBlock() {\n            return this;\n        }\n\n        @Override\n        public String toString() {\n            return \"BlockImpl{\" +\n                    \"name='\" + name + '\\'' +\n                    \", start=\" + start +\n                    \", end=\" + end +\n                    \", attributes=\" + attributes +\n                    \", parent=\" + (parent != null ? parent.name : null) +\n                    \", children=\" + children +\n                    '}';\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/MarkwonHtmlParser.java",
    "content": "package io.noties.markwon.html;\n\nimport androidx.annotation.NonNull;\n\nimport java.util.List;\n\n/**\n * @since 2.0.0\n */\npublic abstract class MarkwonHtmlParser {\n\n    public interface FlushAction<T> {\n        void apply(@NonNull List<T> tags);\n    }\n\n    public abstract <T extends Appendable & CharSequence> void processFragment(\n            @NonNull T output,\n            @NonNull String htmlFragment);\n\n    /**\n     * After this method exists a {@link MarkwonHtmlParser} will clear internal state for stored tags.\n     * If you wish to process them further after this method exists create own copy of supplied\n     * collection.\n     *\n     * @param documentLength known document length. This value is used to close all non-closed tags.\n     *                       If you wish to keep them open (do not force close at the end of a\n     *                       document pass here {@link HtmlTag#NO_END}. Later non-closed tags\n     *                       can be detected by calling {@link HtmlTag#isClosed()}\n     * @param action         {@link FlushAction} to be called with resulting tags ({@link HtmlTag.Inline})\n     */\n    public abstract void flushInlineTags(\n            int documentLength,\n            @NonNull FlushAction<HtmlTag.Inline> action);\n\n    /**\n     * After this method exists a {@link MarkwonHtmlParser} will clear internal state for stored tags.\n     * If you wish to process them further after this method exists create own copy of supplied\n     * collection.\n     *\n     * @param documentLength known document length. This value is used to close all non-closed tags.\n     *                       If you wish to keep them open (do not force close at the end of a\n     *                       document pass here {@link HtmlTag#NO_END}. Later non-closed tags\n     *                       can be detected by calling {@link HtmlTag#isClosed()}\n     * @param action         {@link FlushAction} to be called with resulting tags ({@link HtmlTag.Block})\n     */\n    public abstract void flushBlockTags(\n            int documentLength,\n            @NonNull FlushAction<HtmlTag.Block> action);\n\n    public abstract void reset();\n\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/MarkwonHtmlParserImpl.java",
    "content": "package io.noties.markwon.html;\n\nimport static io.noties.markwon.html.AppendableUtils.appendQuietly;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.VisibleForTesting;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Locale;\nimport java.util.Map;\nimport java.util.Set;\n\nimport io.noties.markwon.html.jsoup.nodes.Attribute;\nimport io.noties.markwon.html.jsoup.nodes.Attributes;\nimport io.noties.markwon.html.jsoup.parser.CharacterReader;\nimport io.noties.markwon.html.jsoup.parser.ParseErrorList;\nimport io.noties.markwon.html.jsoup.parser.Token;\nimport io.noties.markwon.html.jsoup.parser.Tokeniser;\n\n/**\n * @since 2.0.0\n */\npublic class MarkwonHtmlParserImpl extends MarkwonHtmlParser {\n\n    @NonNull\n    public static MarkwonHtmlParserImpl create() {\n        return create(HtmlEmptyTagReplacement.create());\n    }\n\n    @NonNull\n    public static MarkwonHtmlParserImpl create(@NonNull HtmlEmptyTagReplacement inlineTagReplacement) {\n        return new MarkwonHtmlParserImpl(inlineTagReplacement, TrimmingAppender.create());\n    }\n\n    // https://developer.mozilla.org/en-US/docs/Web/HTML/Inline_elements\n    @VisibleForTesting\n    static final Set<String> INLINE_TAGS;\n\n    private static final Set<String> VOID_TAGS;\n\n    // these are the tags that are considered _block_ ones\n    // this parser will ensure that these blocks are started on a new line\n    // other tags that are NOT inline are considered as block tags, but won't have new line\n    // inserted before them\n    // https://developer.mozilla.org/en-US/docs/Web/HTML/Block-level_elements\n    private static final Set<String> BLOCK_TAGS;\n\n    private static final String TAG_PARAGRAPH = \"p\";\n    private static final String TAG_LIST_ITEM = \"li\";\n\n    static {\n        INLINE_TAGS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(\n                \"a\", \"abbr\", \"acronym\",\n                \"b\", \"bdo\", \"big\", \"br\", \"button\",\n                \"cite\", \"code\",\n                \"dfn\",\n                \"em\",\n                \"i\", \"img\", \"input\",\n                \"kbd\",\n                \"label\",\n                \"map\",\n                \"object\",\n                \"q\",\n                \"samp\", \"script\", \"select\", \"small\", \"span\", \"strong\", \"sub\", \"sup\",\"iconlink\",\n                \"textarea\", \"time\", \"tt\",\n                \"var\"\n        )));\n        VOID_TAGS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(\n                \"area\",\n                \"base\", \"br\",\n                \"col\",\n                \"embed\",\n                \"hr\",\n                \"img\", \"input\",\n                \"keygen\",\n                \"link\",\n                \"meta\",\n                \"param\",\n                \"source\",\n                \"track\",\n                \"wbr\"\n        )));\n        BLOCK_TAGS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(\n                \"address\", \"article\", \"aside\",\n                \"blockquote\",\n                \"canvas\",\n                \"dd\", \"div\", \"dl\", \"dt\",\n                \"fieldset\", \"figcaption\", \"figure\", \"footer\", \"form\",\n                \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\", \"header\", \"hgroup\", \"hr\",\n                \"li\",\n                \"main\",\n                \"nav\", \"noscript\",\n                \"ol\", \"output\",\n                \"p\", \"pre\",\n                \"section\",\n                \"table\", \"tfoot\",\n                \"ul\",\n                \"video\"\n        )));\n    }\n\n    private final HtmlEmptyTagReplacement emptyTagReplacement;\n\n    private final TrimmingAppender trimmingAppender;\n\n    private final List<HtmlTagImpl.InlineImpl> inlineTags = new ArrayList<>(0);\n\n    private HtmlTagImpl.BlockImpl currentBlock = HtmlTagImpl.BlockImpl.root();\n\n    private boolean isInsidePreTag;\n\n    // the thing is: we ensure a new line BEFORE block tag\n    // but not after, so another tag will be placed on the same line (which is wrong)\n    private boolean previousIsBlock;\n\n\n    MarkwonHtmlParserImpl(\n            @NonNull HtmlEmptyTagReplacement replacement,\n            @NonNull TrimmingAppender trimmingAppender) {\n        this.emptyTagReplacement = replacement;\n        this.trimmingAppender = trimmingAppender;\n    }\n\n    @Override\n    public <T extends Appendable & CharSequence> void processFragment(\n            @NonNull T output,\n            @NonNull String htmlFragment) {\n\n        // we might want to reuse tokeniser (at least when the same output is involved)\n        // as CharacterReader does a bit of initialization (cache etc) as it's\n        // primary usage is parsing a document in one run (not parsing _fragments_)\n        final Tokeniser tokeniser = new Tokeniser(new CharacterReader(htmlFragment), ParseErrorList.noTracking());\n\n        while (true) {\n\n            final Token token = tokeniser.read();\n            final Token.TokenType tokenType = token.type;\n\n            if (Token.TokenType.EOF == tokenType) {\n                break;\n            }\n\n            switch (tokenType) {\n\n                case StartTag: {\n\n                    final Token.StartTag startTag = (Token.StartTag) token;\n\n                    if (isInlineTag(startTag.normalName)) {\n                        processInlineTagStart(output, startTag);\n                    } else {\n                        processBlockTagStart(output, startTag);\n                    }\n                }\n                break;\n\n                case EndTag: {\n\n                    final Token.EndTag endTag = (Token.EndTag) token;\n\n                    if (isInlineTag(endTag.normalName)) {\n                        processInlineTagEnd(output, endTag);\n                    } else {\n                        processBlockTagEnd(output, endTag);\n                    }\n                }\n                break;\n\n                case Character: {\n                    processCharacter(output, ((Token.Character) token));\n                }\n                break;\n            }\n\n            // do not forget to reset processed token (even if it's not processed)\n            token.reset();\n        }\n    }\n\n    @Override\n    public void flushInlineTags(int documentLength, @NonNull FlushAction<HtmlTag.Inline> action) {\n        if (inlineTags.size() > 0) {\n\n            if (documentLength > HtmlTag.NO_END) {\n                for (HtmlTagImpl.InlineImpl inline : inlineTags) {\n                    inline.closeAt(documentLength);\n                }\n            }\n\n            action.apply(Collections.unmodifiableList((List<? extends HtmlTag.Inline>) inlineTags));\n            inlineTags.clear();\n        } else {\n            action.apply(Collections.<HtmlTag.Inline>emptyList());\n        }\n    }\n\n    @Override\n    public void flushBlockTags(int documentLength, @NonNull FlushAction<HtmlTag.Block> action) {\n\n        HtmlTagImpl.BlockImpl block = currentBlock;\n        while (block.parent != null) {\n            block = block.parent;\n        }\n\n        if (documentLength > HtmlTag.NO_END) {\n            block.closeAt(documentLength);\n        }\n\n        final List<HtmlTag.Block> children = block.children();\n        if (children.size() > 0) {\n            action.apply(children);\n        } else {\n            action.apply(Collections.<HtmlTag.Block>emptyList());\n        }\n\n        currentBlock = HtmlTagImpl.BlockImpl.root();\n    }\n\n    @Override\n    public void reset() {\n        inlineTags.clear();\n        currentBlock = HtmlTagImpl.BlockImpl.root();\n    }\n\n\n    protected <T extends Appendable & CharSequence> void processInlineTagStart(\n            @NonNull T output,\n            @NonNull Token.StartTag startTag) {\n\n        final String name = startTag.normalName;\n\n        final HtmlTagImpl.InlineImpl inline = new HtmlTagImpl.InlineImpl(name, output.length(), extractAttributes(startTag));\n\n        ensureNewLineIfPreviousWasBlock(output);\n\n        if (isVoidTag(name)\n                || startTag.selfClosing) {\n\n            final String replacement = emptyTagReplacement.replace(inline);\n            if (replacement != null\n                    && replacement.length() > 0) {\n                AppendableUtils.appendQuietly(output, replacement);\n            }\n\n            // the thing is: we will keep this inline tag in the list,\n            // but in case of void-tag that has no replacement, there will be no\n            // possibility to set a span (requires at least one char)\n            inline.closeAt(output.length());\n        }\n\n        inlineTags.add(inline);\n    }\n\n    protected <T extends Appendable & CharSequence> void processInlineTagEnd(\n            @NonNull T output,\n            @NonNull Token.EndTag endTag) {\n\n        // try to find it, if none found -> ignore\n        final HtmlTagImpl.InlineImpl openInline = findOpenInlineTag(endTag.normalName);\n        if (openInline != null) {\n\n            // okay, if this tag is empty -> call replacement\n            if (isEmpty(output, openInline)) {\n                appendEmptyTagReplacement(output, openInline);\n            }\n\n            // close open inline tag\n            openInline.closeAt(output.length());\n        }\n    }\n\n\n    protected <T extends Appendable & CharSequence> void processBlockTagStart(\n            @NonNull T output,\n            @NonNull Token.StartTag startTag) {\n\n        final String name = startTag.normalName;\n\n        // block tags (all that are NOT inline -> blocks\n        // there is only one strong rule -> paragraph cannot contain anything\n        // except inline tags\n\n        if (TAG_PARAGRAPH.equals(currentBlock.name)) {\n            // it must be closed here not matter what we are as here we _assume_\n            // that it's a block tag\n            currentBlock.closeAt(output.length());\n            AppendableUtils.appendQuietly(output, '\\n');\n            currentBlock = currentBlock.parent;\n        } else if (TAG_LIST_ITEM.equals(name)\n                && TAG_LIST_ITEM.equals(currentBlock.name)) {\n            // close previous list item if in the same parent\n            currentBlock.closeAt(output.length());\n            currentBlock = currentBlock.parent;\n        }\n\n        if (isBlockTag(name)) {\n            isInsidePreTag = \"pre\".equals(name);\n            ensureNewLine(output);\n        } else {\n            ensureNewLineIfPreviousWasBlock(output);\n        }\n\n        final int start = output.length();\n\n        final HtmlTagImpl.BlockImpl block = HtmlTagImpl.BlockImpl.create(name, start, extractAttributes(startTag), currentBlock);\n\n        final boolean isVoid = isVoidTag(name) || startTag.selfClosing;\n        if (isVoid) {\n            final String replacement = emptyTagReplacement.replace(block);\n            if (replacement != null\n                    && replacement.length() > 0) {\n                AppendableUtils.appendQuietly(output, replacement);\n            }\n            block.closeAt(output.length());\n        }\n\n        //noinspection ConstantConditions\n        appendBlockChild(block.parent, block);\n\n        // if not void start filling-in children\n        if (!isVoid) {\n            this.currentBlock = block;\n        }\n    }\n\n    protected <T extends Appendable & CharSequence> void processBlockTagEnd(\n            @NonNull T output,\n            @NonNull Token.EndTag endTag) {\n\n        final String name = endTag.normalName;\n\n        final HtmlTagImpl.BlockImpl block = findOpenBlockTag(endTag.normalName);\n        if (block != null) {\n\n            if (\"pre\".equals(name)) {\n                isInsidePreTag = false;\n            }\n\n            // okay, if this tag is empty -> call replacement\n            if (isEmpty(output, block)) {\n                appendEmptyTagReplacement(output, block);\n            }\n\n            block.closeAt(output.length());\n\n            // if it's empty -> we do no care about if it's block or not\n            if (!block.isEmpty()) {\n                previousIsBlock = isBlockTag(block.name);\n            }\n\n            if (TAG_PARAGRAPH.equals(name)) {\n                AppendableUtils.appendQuietly(output, '\\n');\n            }\n\n            this.currentBlock = block.parent;\n        }\n    }\n\n    protected <T extends Appendable & CharSequence> void processCharacter(\n            @NonNull T output,\n            @NonNull Token.Character character) {\n\n        // there are tags: BUTTON, INPUT, SELECT, SCRIPT, TEXTAREA, STYLE\n        // that might have character data that we do not want to display\n\n        if (isInsidePreTag) {\n            appendQuietly(output, character.getData());\n        } else {\n            ensureNewLineIfPreviousWasBlock(output);\n            trimmingAppender.append(output, character.getData());\n        }\n    }\n\n    protected void appendBlockChild(@NonNull HtmlTagImpl.BlockImpl parent, @NonNull HtmlTagImpl.BlockImpl child) {\n        List<HtmlTagImpl.BlockImpl> children = parent.children;\n        if (children == null) {\n            children = new ArrayList<>(2);\n            parent.children = children;\n        }\n        children.add(child);\n    }\n\n    @Nullable\n    protected HtmlTagImpl.InlineImpl findOpenInlineTag(@NonNull String name) {\n\n        HtmlTagImpl.InlineImpl inline;\n\n        for (int i = inlineTags.size() - 1; i > -1; i--) {\n            inline = inlineTags.get(i);\n            if (name.equals(inline.name)\n                    && inline.end < 0) {\n                return inline;\n            }\n        }\n\n        return null;\n    }\n\n    @Nullable\n    protected HtmlTagImpl.BlockImpl findOpenBlockTag(@NonNull String name) {\n\n        HtmlTagImpl.BlockImpl blockTag = currentBlock;\n\n        while (blockTag != null\n                && !name.equals(blockTag.name) && !blockTag.isClosed()) {\n            blockTag = blockTag.parent;\n        }\n\n        return blockTag;\n    }\n\n    protected <T extends Appendable & CharSequence> void ensureNewLineIfPreviousWasBlock(@NonNull T output) {\n        if (previousIsBlock) {\n            ensureNewLine(output);\n            previousIsBlock = false;\n        }\n    }\n\n    // name here must lower case\n    protected static boolean isInlineTag(@NonNull String name) {\n        return INLINE_TAGS.contains(name);\n    }\n\n    protected static boolean isVoidTag(@NonNull String name) {\n        return VOID_TAGS.contains(name);\n    }\n\n    protected static boolean isBlockTag(@NonNull String name) {\n        return BLOCK_TAGS.contains(name);\n    }\n\n    protected static <T extends Appendable & CharSequence> void ensureNewLine(@NonNull T output) {\n        final int length = output.length();\n        if (length > 0\n                && '\\n' != output.charAt(length - 1)) {\n            AppendableUtils.appendQuietly(output, '\\n');\n        }\n    }\n\n    @NonNull\n    protected static Map<String, String> extractAttributes(@NonNull Token.StartTag startTag) {\n\n        Map<String, String> map;\n\n        final Attributes attributes = startTag.attributes;\n        final int size = attributes.size();\n\n        if (size > 0) {\n            map = new HashMap<>(size);\n            for (Attribute attribute : attributes) {\n                map.put(attribute.getKey().toLowerCase(Locale.US), attribute.getValue());\n            }\n            map = Collections.unmodifiableMap(map);\n        } else {\n            map = Collections.emptyMap();\n        }\n\n        return map;\n    }\n\n    protected static <T extends Appendable & CharSequence> boolean isEmpty(\n            @NonNull T output,\n            @NonNull HtmlTagImpl tag) {\n        return tag.start == output.length();\n    }\n\n    protected <T extends Appendable & CharSequence> void appendEmptyTagReplacement(\n            @NonNull T output,\n            @NonNull HtmlTagImpl tag) {\n        final String replacement = emptyTagReplacement.replace(tag);\n        if (replacement != null) {\n            AppendableUtils.appendQuietly(output, replacement);\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/MarkwonHtmlRenderer.java",
    "content": "package io.noties.markwon.html;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport io.noties.markwon.MarkwonVisitor;\n\n/**\n * @since 2.0.0\n */\npublic abstract class MarkwonHtmlRenderer {\n\n    public abstract void render(\n            @NonNull MarkwonVisitor visitor,\n            @NonNull MarkwonHtmlParser parser\n    );\n\n    @Nullable\n    public abstract TagHandler tagHandler(@NonNull String tagName);\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/MarkwonHtmlRendererImpl.java",
    "content": "package io.noties.markwon.html;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport io.noties.markwon.MarkwonVisitor;\n\nclass MarkwonHtmlRendererImpl extends MarkwonHtmlRenderer {\n\n    private final boolean allowNonClosedTags;\n    private final Map<String, TagHandler> tagHandlers;\n\n    @SuppressWarnings(\"WeakerAccess\")\n    MarkwonHtmlRendererImpl(boolean allowNonClosedTags, @NonNull Map<String, TagHandler> tagHandlers) {\n        this.allowNonClosedTags = allowNonClosedTags;\n        this.tagHandlers = tagHandlers;\n    }\n\n    @Override\n    public void render(\n            @NonNull final MarkwonVisitor visitor,\n            @NonNull MarkwonHtmlParser parser) {\n\n        final int end;\n        if (!allowNonClosedTags) {\n            end = HtmlTag.NO_END;\n        } else {\n            end = visitor.length();\n        }\n\n        parser.flushInlineTags(end, new MarkwonHtmlParser.FlushAction<HtmlTag.Inline>() {\n            @Override\n            public void apply(@NonNull List<HtmlTag.Inline> tags) {\n\n                TagHandler handler;\n\n                for (HtmlTag.Inline inline : tags) {\n\n                    // if tag is not closed -> do not render\n                    if (!inline.isClosed()) {\n                        continue;\n                    }\n\n                    handler = tagHandler(inline.name());\n                    if (handler != null) {\n                        handler.handle(visitor, MarkwonHtmlRendererImpl.this, inline);\n                    }\n                }\n            }\n        });\n\n        parser.flushBlockTags(end, new MarkwonHtmlParser.FlushAction<HtmlTag.Block>() {\n            @Override\n            public void apply(@NonNull List<HtmlTag.Block> tags) {\n\n                TagHandler handler;\n\n                for (HtmlTag.Block block : tags) {\n\n                    if (!block.isClosed()) {\n                        continue;\n                    }\n\n                    handler = tagHandler(block.name());\n                    if (handler != null) {\n                        handler.handle(visitor, MarkwonHtmlRendererImpl.this, block);\n                    } else {\n                        // see if any of children can be handled\n                        apply(block.children());\n                    }\n                }\n            }\n        });\n\n        parser.reset();\n    }\n\n    @Nullable\n    @Override\n    public TagHandler tagHandler(@NonNull String tagName) {\n        return tagHandlers.get(tagName);\n    }\n\n    static class Builder {\n\n        private final Map<String, TagHandler> tagHandlers = new HashMap<>(2);\n        private boolean allowNonClosedTags;\n        private boolean excludeDefaults;\n\n        private boolean isBuilt;\n\n        void allowNonClosedTags(boolean allowNonClosedTags) {\n            checkState();\n            this.allowNonClosedTags = allowNonClosedTags;\n        }\n\n        void addHandler(@NonNull TagHandler tagHandler) {\n            checkState();\n            for (String tag : tagHandler.supportedTags()) {\n                tagHandlers.put(tag, tagHandler);\n            }\n        }\n\n        @Nullable\n        TagHandler getHandler(@NonNull String tagName) {\n            checkState();\n            return tagHandlers.get(tagName);\n        }\n\n        public void excludeDefaults(boolean excludeDefaults) {\n            checkState();\n            this.excludeDefaults = excludeDefaults;\n        }\n\n        boolean excludeDefaults() {\n            return excludeDefaults;\n        }\n\n        @NonNull\n        public MarkwonHtmlRenderer build() {\n\n            checkState();\n\n            isBuilt = true;\n\n            // okay, let's validate that we have at least one tagHandler registered\n            // if we have none -> return no-op implementation\n            return tagHandlers.size() > 0\n                    ? new MarkwonHtmlRendererImpl(allowNonClosedTags, Collections.unmodifiableMap(tagHandlers))\n                    : new MarkwonHtmlRendererNoOp();\n        }\n\n        private void checkState() {\n//            if (isBuilt) {\n//                throw new IllegalStateException(\"Builder has been already built\");\n//            }\n        }\n\n        void addDefaultTagHandler(@NonNull TagHandler tagHandler) {\n            for (String tag : tagHandler.supportedTags()) {\n                if (!tagHandlers.containsKey(tag)) {\n                    tagHandlers.put(tag, tagHandler);\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/MarkwonHtmlRendererNoOp.java",
    "content": "package io.noties.markwon.html;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport io.noties.markwon.MarkwonVisitor;\n\nclass MarkwonHtmlRendererNoOp extends MarkwonHtmlRenderer {\n\n    @Override\n    public void render(@NonNull MarkwonVisitor visitor, @NonNull MarkwonHtmlParser parser) {\n        parser.reset();\n    }\n\n    @Nullable\n    @Override\n    public TagHandler tagHandler(@NonNull String tagName) {\n        return null;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/TagHandler.java",
    "content": "package io.noties.markwon.html;\n\nimport androidx.annotation.NonNull;\n\nimport java.util.Collection;\n\nimport io.noties.markwon.MarkwonVisitor;\n\npublic abstract class TagHandler {\n\n    public abstract void handle(\n            @NonNull MarkwonVisitor visitor,\n            @NonNull MarkwonHtmlRenderer renderer,\n            @NonNull HtmlTag tag\n    );\n\n    /**\n     * @since 4.0.0\n     */\n    @NonNull\n    public abstract Collection<String> supportedTags();\n\n\n    protected static void visitChildren(\n            @NonNull MarkwonVisitor visitor,\n            @NonNull MarkwonHtmlRenderer renderer,\n            @NonNull HtmlTag.Block block) {\n\n        TagHandler handler;\n\n        for (HtmlTag.Block child : block.children()) {\n\n            if (!child.isClosed()) {\n                continue;\n            }\n\n            handler = renderer.tagHandler(child.name());\n            if (handler != null) {\n                handler.handle(visitor, renderer, child);\n            } else {\n                visitChildren(visitor, renderer, child);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/TagHandlerNoOp.java",
    "content": "package io.noties.markwon.html;\n\nimport androidx.annotation.NonNull;\n\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.Collections;\n\nimport io.noties.markwon.MarkwonVisitor;\n\n/**\n * @since 4.0.0\n */\npublic class TagHandlerNoOp extends TagHandler {\n\n    @NonNull\n    public static TagHandlerNoOp create(@NonNull String tag) {\n        return new TagHandlerNoOp(Collections.singleton(tag));\n    }\n\n    @NonNull\n    public static TagHandlerNoOp create(@NonNull String... tags) {\n        return new TagHandlerNoOp(Arrays.asList(tags));\n    }\n\n    private final Collection<String> tags;\n\n    @SuppressWarnings(\"WeakerAccess\")\n    TagHandlerNoOp(Collection<String> tags) {\n        this.tags = tags;\n    }\n\n    @Override\n    public void handle(@NonNull MarkwonVisitor visitor, @NonNull MarkwonHtmlRenderer renderer, @NonNull HtmlTag tag) {\n        // no op\n    }\n\n    @NonNull\n    @Override\n    public Collection<String> supportedTags() {\n        return tags;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/TrimmingAppender.java",
    "content": "package io.noties.markwon.html;\n\nimport androidx.annotation.NonNull;\n\nimport static io.noties.markwon.html.AppendableUtils.appendQuietly;\n\nabstract class TrimmingAppender {\n\n    abstract <T extends Appendable & CharSequence> void append(\n            @NonNull T output,\n            @NonNull String data\n    );\n\n    @NonNull\n    static TrimmingAppender create() {\n        return new Impl();\n    }\n\n    static class Impl extends TrimmingAppender {\n\n        // if data is fully empty (consists of white spaces) -> do not add anything\n        // leading ws:\n        //  - trim to one space (if at all present) append to output only if previous is ws\n        // trailing ws:\n        //  - if present trim to single space\n\n        @Override\n        <T extends Appendable & CharSequence> void append(\n                @NonNull T output,\n                @NonNull String data\n        ) {\n\n            final int startLength = output.length();\n\n            char c;\n\n            boolean previousIsWhiteSpace = false;\n\n            for (int i = 0, length = data.length(); i < length; i++) {\n\n                c = data.charAt(i);\n\n                if (Character.isWhitespace(c)) {\n                    previousIsWhiteSpace = true;\n                    continue;\n                }\n\n                if (previousIsWhiteSpace) {\n                    // validate that output has ws as last char\n                    final int outputLength = output.length();\n                    if (outputLength > 0\n                            && !Character.isWhitespace(output.charAt(outputLength - 1))) {\n                        appendQuietly(output, ' ');\n                    }\n                }\n\n                previousIsWhiteSpace = false;\n                appendQuietly(output, c);\n            }\n\n            // additionally check if previousIsWhiteSpace is true (if data ended with ws)\n            // BUT only if we have added something (otherwise the whole data is empty (white))\n            if (previousIsWhiteSpace && (startLength < output.length())) {\n                appendQuietly(output, ' ');\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/jsoup/UncheckedIOException.java",
    "content": "package io.noties.markwon.html.jsoup;\n\nimport java.io.IOException;\n\npublic class UncheckedIOException extends RuntimeException {\n    public UncheckedIOException(IOException cause) {\n        super(cause);\n    }\n\n    public IOException ioException() {\n        return (IOException) getCause();\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/jsoup/helper/Normalizer.java",
    "content": "package io.noties.markwon.html.jsoup.helper;\n\nimport java.util.Locale;\n\n/**\n * Util methods for normalizing strings. Jsoup internal use only, please don't depend on this API.\n */\npublic final class Normalizer {\n\n    public static String lowerCase(final String input) {\n        return input != null ? input.toLowerCase(Locale.ENGLISH) : \"\";\n    }\n\n    public static String normalize(final String input) {\n        return lowerCase(input).trim();\n    }\n}\n\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/jsoup/helper/Validate.java",
    "content": "package io.noties.markwon.html.jsoup.helper;\n\n/**\n * Simple validation methods. Designed for jsoup internal use\n */\npublic final class Validate {\n\n    private Validate() {}\n\n    /**\n     * Validates that the object is not null\n     * @param obj object to test\n     */\n    public static void notNull(Object obj) {\n        if (obj == null)\n            throw new IllegalArgumentException(\"Object must not be null\");\n    }\n\n    /**\n     * Validates that the object is not null\n     * @param obj object to test\n     * @param msg message to output if validation fails\n     */\n    public static void notNull(Object obj, String msg) {\n        if (obj == null)\n            throw new IllegalArgumentException(msg);\n    }\n\n    /**\n     * Validates that the value is true\n     * @param val object to test\n     */\n    public static void isTrue(boolean val) {\n        if (!val)\n            throw new IllegalArgumentException(\"Must be true\");\n    }\n\n    /**\n     * Validates that the value is true\n     * @param val object to test\n     * @param msg message to output if validation fails\n     */\n    public static void isTrue(boolean val, String msg) {\n        if (!val)\n            throw new IllegalArgumentException(msg);\n    }\n\n    /**\n     * Validates that the value is false\n     * @param val object to test\n     */\n    public static void isFalse(boolean val) {\n        if (val)\n            throw new IllegalArgumentException(\"Must be false\");\n    }\n\n    /**\n     * Validates that the value is false\n     * @param val object to test\n     * @param msg message to output if validation fails\n     */\n    public static void isFalse(boolean val, String msg) {\n        if (val)\n            throw new IllegalArgumentException(msg);\n    }\n\n    /**\n     * Validates that the array contains no null elements\n     * @param objects the array to test\n     */\n    public static void noNullElements(Object[] objects) {\n        noNullElements(objects, \"Array must not contain any null objects\");\n    }\n\n    /**\n     * Validates that the array contains no null elements\n     * @param objects the array to test\n     * @param msg message to output if validation fails\n     */\n    public static void noNullElements(Object[] objects, String msg) {\n        for (Object obj : objects)\n            if (obj == null)\n                throw new IllegalArgumentException(msg);\n    }\n\n    /**\n     * Validates that the string is not empty\n     * @param string the string to test\n     */\n    public static void notEmpty(String string) {\n        if (string == null || string.length() == 0)\n            throw new IllegalArgumentException(\"String must not be empty\");\n    }\n\n    /**\n     * Validates that the string is not empty\n     * @param string the string to test\n     * @param msg message to output if validation fails\n     */\n    public static void notEmpty(String string, String msg) {\n        if (string == null || string.length() == 0)\n            throw new IllegalArgumentException(msg);\n    }\n\n    /**\n     Cause a failure.\n     @param msg message to output.\n     */\n    public static void fail(String msg) {\n        throw new IllegalArgumentException(msg);\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/jsoup/nodes/Attribute.java",
    "content": "package io.noties.markwon.html.jsoup.nodes;\n\nimport java.util.Map;\n\nimport io.noties.markwon.html.jsoup.helper.Validate;\n\n/**\n A single key + value attribute. (Only used for presentation.)\n */\npublic class Attribute implements Map.Entry<String, String>, Cloneable  {\n//    private static final String[] booleanAttributes = {\n//            \"allowfullscreen\", \"async\", \"autofocus\", \"checked\", \"compact\", \"declare\", \"default\", \"defer\", \"disabled\",\n//            \"formnovalidate\", \"hidden\", \"inert\", \"ismap\", \"itemscope\", \"multiple\", \"muted\", \"nohref\", \"noresize\",\n//            \"noshade\", \"novalidate\", \"nowrap\", \"open\", \"readonly\", \"required\", \"reversed\", \"seamless\", \"selected\",\n//            \"sortable\", \"truespeed\", \"typemustmatch\"\n//    };\n\n    private String key;\n    private String val;\n    Attributes parent; // used to update the holding Attributes when the key / value is changed via this interface\n\n    /**\n     * Create a new attribute from unencoded (raw) key and value.\n     * @param key attribute key; case is preserved.\n     * @param value attribute value\n     */\n    public Attribute(String key, String value) {\n        this(key, value, null);\n    }\n\n    /**\n     * Create a new attribute from unencoded (raw) key and value.\n     * @param key attribute key; case is preserved.\n     * @param val attribute value\n     * @param parent the containing Attributes (this Attribute is not automatically added to said Attributes)\n     */\n    public Attribute(String key, String val, Attributes parent) {\n        Validate.notNull(key);\n        this.key = key.trim();\n        Validate.notEmpty(key); // trimming could potentially make empty, so validate here\n        this.val = val;\n        this.parent = parent;\n    }\n\n    /**\n     Get the attribute key.\n     @return the attribute key\n     */\n    public String getKey() {\n        return key;\n    }\n\n    /**\n     Set the attribute key; case is preserved.\n     @param key the new key; must not be null\n     */\n    public void setKey(String key) {\n        Validate.notNull(key);\n        key = key.trim();\n        Validate.notEmpty(key); // trimming could potentially make empty, so validate here\n        if (parent != null) {\n            int i = parent.indexOfKey(this.key);\n            if (i != Attributes.NotFound)\n                parent.keys[i] = key;\n        }\n        this.key = key;\n    }\n\n    /**\n     Get the attribute value.\n     @return the attribute value\n     */\n    public String getValue() {\n        return val;\n    }\n\n    /**\n     Set the attribute value.\n     @param val the new attribute value; must not be null\n     */\n    public String setValue(String val) {\n        String oldVal = parent.get(this.key);\n        if (parent != null) {\n            int i = parent.indexOfKey(this.key);\n            if (i != Attributes.NotFound)\n                parent.vals[i] = val;\n        }\n        this.val = val;\n        return oldVal;\n    }\n\n//    /**\n//     Get the HTML representation of this attribute; e.g. {@code href=\"index.html\"}.\n//     @return HTML\n//     */\n//    public String html() {\n//        StringBuilder accum = new StringBuilder();\n//\n//        try {\n//            html(accum, (new Document(\"\")).outputSettings());\n//        } catch(IOException exception) {\n//            throw new SerializationException(exception);\n//        }\n//        return accum.toString();\n//    }\n//\n//    protected static void html(String key, String val, Appendable accum, Document.OutputSettings out) throws IOException {\n//        accum.append(key);\n//        if (!shouldCollapseAttribute(key, val, out)) {\n//            accum.append(\"=\\\"\");\n//            Entities.escape(accum, Attributes.checkNotNull(val) , out, true, false, false);\n//            accum.append('\"');\n//        }\n//    }\n//\n//    protected void html(Appendable accum, Document.OutputSettings out) throws IOException {\n//        html(key, val, accum, out);\n//    }\n\n//    /**\n//     Get the string representation of this attribute, implemented as {@link #html()}.\n//     @return string\n//     */\n//    @Override\n//    public String toString() {\n//        return html();\n//    }\n\n//    /**\n//     * Create a new Attribute from an unencoded key and a HTML attribute encoded value.\n//     * @param unencodedKey assumes the key is not encoded, as can be only run of simple \\w chars.\n//     * @param encodedValue HTML attribute encoded value\n//     * @return attribute\n//     */\n//    public static Attribute createFromEncoded(String unencodedKey, String encodedValue) {\n//        String value = Entities.unescape(encodedValue, true);\n//        return new Attribute(unencodedKey, value, null); // parent will get set when Put\n//    }\n\n//    protected boolean isDataAttribute() {\n//        return isDataAttribute(key);\n//    }\n//\n//    protected static boolean isDataAttribute(String key) {\n//        return key.startsWith(Attributes.dataPrefix) && key.length() > Attributes.dataPrefix.length();\n//    }\n\n//    /**\n//     * Collapsible if it's a boolean attribute and value is empty or same as name\n//     *\n//     * @param out output settings\n//     * @return  Returns whether collapsible or not\n//     */\n//    protected final boolean shouldCollapseAttribute(Document.OutputSettings out) {\n//        return shouldCollapseAttribute(key, val, out);\n//    }\n\n//    protected static boolean shouldCollapseAttribute(final String key, final String val, final Document.OutputSettings out) {\n//        return (\n//                out.syntax() == Document.OutputSettings.Syntax.html &&\n//                        (val == null || (\"\".equals(val) || val.equalsIgnoreCase(key)) && Attribute.isBooleanAttribute(key)));\n//    }\n\n//    /**\n//     * @deprecated\n//     */\n//    protected boolean isBooleanAttribute() {\n//        return Arrays.binarySearch(booleanAttributes, key) >= 0 || val == null;\n//    }\n//\n//    /**\n//     * Checks if this attribute name is defined as a boolean attribute in HTML5\n//     */\n//    protected static boolean isBooleanAttribute(final String key) {\n//        return Arrays.binarySearch(booleanAttributes, key) >= 0;\n//    }\n\n    @Override\n    public boolean equals(Object o) { // note parent not considered\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n        Attribute attribute = (Attribute) o;\n        if (key != null ? !key.equals(attribute.key) : attribute.key != null) return false;\n        return val != null ? val.equals(attribute.val) : attribute.val == null;\n    }\n\n    @Override\n    public int hashCode() { // note parent not considered\n        int result = key != null ? key.hashCode() : 0;\n        result = 31 * result + (val != null ? val.hashCode() : 0);\n        return result;\n    }\n\n    @Override\n    public Attribute clone() {\n        try {\n            return (Attribute) super.clone();\n        } catch (CloneNotSupportedException e) {\n            throw new RuntimeException(e);\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/jsoup/nodes/Attributes.java",
    "content": "package io.noties.markwon.html.jsoup.nodes;\n\nimport java.util.Arrays;\nimport java.util.Iterator;\n\nimport io.noties.markwon.html.jsoup.helper.Validate;\n\nimport static io.noties.markwon.html.jsoup.helper.Normalizer.lowerCase;\n\n/**\n * The attributes of an Element.\n * <p>\n * Attributes are treated as a map: there can be only one value associated with an attribute key/name.\n * </p>\n * <p>\n * Attribute name and value comparisons are  generally <b>case sensitive</b>. By default for HTML, attribute names are\n * normalized to lower-case on parsing. That means you should use lower-case strings when referring to attributes by\n * name.\n * </p>\n *\n * @author Jonathan Hedley, jonathan@hedley.net\n */\npublic class Attributes implements Iterable<Attribute>, Cloneable {\n//    protected static final String dataPrefix = \"data-\";\n    private static final int InitialCapacity = 4; // todo - analyze Alexa 1MM sites, determine best setting\n\n    // manages the key/val arrays\n    private static final int GrowthFactor = 2;\n    private static final String[] Empty = {};\n    static final int NotFound = -1;\n    private static final String EmptyString = \"\";\n\n    private int size = 0; // number of slots used (not capacity, which is keys.length\n    String[] keys = Empty;\n    String[] vals = Empty;\n\n    // check there's room for more\n    private void checkCapacity(int minNewSize) {\n        Validate.isTrue(minNewSize >= size);\n        int curSize = keys.length;\n        if (curSize >= minNewSize)\n            return;\n\n        int newSize = curSize >= InitialCapacity ? size * GrowthFactor : InitialCapacity;\n        if (minNewSize > newSize)\n            newSize = minNewSize;\n\n        keys = copyOf(keys, newSize);\n        vals = copyOf(vals, newSize);\n    }\n\n    // simple implementation of Arrays.copy, for support of Android API 8.\n    private static String[] copyOf(String[] orig, int size) {\n        final String[] copy = new String[size];\n        System.arraycopy(orig, 0, copy, 0,\n                Math.min(orig.length, size));\n        return copy;\n    }\n\n    int indexOfKey(String key) {\n        Validate.notNull(key);\n        for (int i = 0; i < size; i++) {\n            if (key.equals(keys[i]))\n                return i;\n        }\n        return NotFound;\n    }\n\n    private int indexOfKeyIgnoreCase(String key) {\n        Validate.notNull(key);\n        for (int i = 0; i < size; i++) {\n            if (key.equalsIgnoreCase(keys[i]))\n                return i;\n        }\n        return NotFound;\n    }\n\n    // we track boolean attributes as null in values - they're just keys. so returns empty for consumers\n    static String checkNotNull(String val) {\n        return val == null ? EmptyString : val;\n    }\n\n    /**\n     Get an attribute value by key.\n     @param key the (case-sensitive) attribute key\n     @return the attribute value if set; or empty string if not set (or a boolean attribute).\n     @see #hasKey(String)\n     */\n    public String get(String key) {\n        int i = indexOfKey(key);\n        return i == NotFound ? EmptyString : checkNotNull(vals[i]);\n    }\n\n    /**\n     * Get an attribute's value by case-insensitive key\n     * @param key the attribute name\n     * @return the first matching attribute value if set; or empty string if not set (ora boolean attribute).\n     */\n    public String getIgnoreCase(String key) {\n        int i = indexOfKeyIgnoreCase(key);\n        return i == NotFound ? EmptyString : checkNotNull(vals[i]);\n    }\n\n    // adds without checking if this key exists\n    private void add(String key, String value) {\n        checkCapacity(size + 1);\n        keys[size] = key;\n        vals[size] = value;\n        size++;\n    }\n\n    /**\n     * Set a new attribute, or replace an existing one by key.\n     * @param key case sensitive attribute key\n     * @param value attribute value\n     * @return these attributes, for chaining\n     */\n    public Attributes put(String key, String value) {\n        int i = indexOfKey(key);\n        if (i != NotFound)\n            vals[i] = value;\n        else\n            add(key, value);\n        return this;\n    }\n\n    void putIgnoreCase(String key, String value) {\n        int i = indexOfKeyIgnoreCase(key);\n        if (i != NotFound) {\n            vals[i] = value;\n            if (!keys[i].equals(key)) // case changed, update\n                keys[i] = key;\n        }\n        else\n            add(key, value);\n    }\n\n    /**\n     * Set a new boolean attribute, remove attribute if value is false.\n     * @param key case <b>insensitive</b> attribute key\n     * @param value attribute value\n     * @return these attributes, for chaining\n     */\n    public Attributes put(String key, boolean value) {\n        if (value)\n            putIgnoreCase(key, null);\n        else\n            remove(key);\n        return this;\n    }\n\n    /**\n     Set a new attribute, or replace an existing one by key.\n     @param attribute attribute with case sensitive key\n     @return these attributes, for chaining\n     */\n    public Attributes put(Attribute attribute) {\n        Validate.notNull(attribute);\n        put(attribute.getKey(), attribute.getValue());\n        attribute.parent = this;\n        return this;\n    }\n\n    // removes and shifts up\n    private void remove(int index) {\n        Validate.isFalse(index >= size);\n        int shifted = size - index - 1;\n        if (shifted > 0) {\n            System.arraycopy(keys, index + 1, keys, index, shifted);\n            System.arraycopy(vals, index + 1, vals, index, shifted);\n        }\n        size--;\n        keys[size] = null; // release hold\n        vals[size] = null;\n    }\n\n    /**\n     Remove an attribute by key. <b>Case sensitive.</b>\n     @param key attribute key to remove\n     */\n    public void remove(String key) {\n        int i = indexOfKey(key);\n        if (i != NotFound)\n            remove(i);\n    }\n\n    /**\n     Remove an attribute by key. <b>Case insensitive.</b>\n     @param key attribute key to remove\n     */\n    public void removeIgnoreCase(String key) {\n        int i = indexOfKeyIgnoreCase(key);\n        if (i != NotFound)\n            remove(i);\n    }\n\n    /**\n     Tests if these attributes contain an attribute with this key.\n     @param key case-sensitive key to check for\n     @return true if key exists, false otherwise\n     */\n    public boolean hasKey(String key) {\n        return indexOfKey(key) != NotFound;\n    }\n\n    /**\n     Tests if these attributes contain an attribute with this key.\n     @param key key to check for\n     @return true if key exists, false otherwise\n     */\n    public boolean hasKeyIgnoreCase(String key) {\n        return indexOfKeyIgnoreCase(key) != NotFound;\n    }\n\n    /**\n     Get the number of attributes in this set.\n     @return size\n     */\n    public int size() {\n        return size;\n    }\n\n    /**\n     Add all the attributes from the incoming set to this set.\n     @param incoming attributes to add to these attributes.\n     */\n    public void addAll(Attributes incoming) {\n        if (incoming.size() == 0)\n            return;\n        checkCapacity(size + incoming.size);\n\n        for (Attribute attr : incoming) {\n            // todo - should this be case insensitive?\n            put(attr);\n        }\n\n    }\n\n    public Iterator<Attribute> iterator() {\n        return new Iterator<Attribute>() {\n            int i = 0;\n\n            @Override\n            public boolean hasNext() {\n                return i < size;\n            }\n\n            @Override\n            public Attribute next() {\n                final String val = vals[i];\n                final Attribute attr = new Attribute(keys[i], val == null ? \"\" : val, Attributes.this);\n                i++;\n                return attr;\n            }\n\n            @Override\n            public void remove() {\n                Attributes.this.remove(--i); // next() advanced, so rewind\n            }\n        };\n    }\n\n//    /**\n//     Get the attributes as a List, for iteration.\n//     @return an view of the attributes as an unmodifialbe List.\n//     */\n//    public List<Attribute> asList() {\n//        ArrayList<Attribute> list = new ArrayList<>(size);\n//        for (int i = 0; i < size; i++) {\n////            Attribute attr = vals[i] == null ?\n////                    new BooleanAttribute(keys[i]) : // deprecated class, but maybe someone still wants it\n////                    new Attribute(keys[i], vals[i], Attributes.this);\n////            list.add(attr);\n//            list.add(new Attribute(keys[i], vals[i], Attributes.this));\n//        }\n//        return Collections.unmodifiableList(list);\n//    }\n\n//    /**\n//     * Retrieves a filtered view of attributes that are HTML5 custom data attributes; that is, attributes with keys\n//     * starting with {@code data-}.\n//     * @return map of custom data attributes.\n//     */\n//    public Map<String, String> dataset() {\n//        return new Dataset(this);\n//    }\n\n//    /**\n//     Get the HTML representation of these attributes.\n//     @return HTML\n//     @throws SerializationException if the HTML representation of the attributes cannot be constructed.\n//     */\n//    public String html() {\n//        StringBuilder accum = new StringBuilder();\n//        try {\n//            html(accum, (new Document(\"\")).outputSettings()); // output settings a bit funky, but this html() seldom used\n//        } catch (IOException e) { // ought never happen\n//            throw new SerializationException(e);\n//        }\n//        return accum.toString();\n//    }\n//\n//    final void html(final Appendable accum, final Document.OutputSettings out) throws IOException {\n//        final int sz = size;\n//        for (int i = 0; i < sz; i++) {\n//            // inlined from Attribute.html()\n//            final String key = keys[i];\n//            final String val = vals[i];\n//            accum.append(' ').append(key);\n//\n//            // collapse checked=null, checked=\"\", checked=checked; write out others\n//            if (!Attribute.shouldCollapseAttribute(key, val, out)) {\n//                accum.append(\"=\\\"\");\n//                Entities.escape(accum, val == null ? EmptyString : val, out, true, false, false);\n//                accum.append('\"');\n//            }\n//        }\n//    }\n//\n//    @Override\n//    public String toString() {\n//        return html();\n//    }\n\n    /**\n     * Checks if these attributes are equal to another set of attributes, by comparing the two sets\n     * @param o attributes to compare with\n     * @return if both sets of attributes have the same content\n     */\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        Attributes that = (Attributes) o;\n\n        if (size != that.size) return false;\n        if (!Arrays.equals(keys, that.keys)) return false;\n        return Arrays.equals(vals, that.vals);\n    }\n\n    /**\n     * Calculates the hashcode of these attributes, by iterating all attributes and summing their hashcodes.\n     * @return calculated hashcode\n     */\n    @Override\n    public int hashCode() {\n        int result = size;\n        result = 31 * result + Arrays.hashCode(keys);\n        result = 31 * result + Arrays.hashCode(vals);\n        return result;\n    }\n\n    @Override\n    public Attributes clone() {\n        Attributes clone;\n        try {\n            clone = (Attributes) super.clone();\n        } catch (CloneNotSupportedException e) {\n            throw new RuntimeException(e);\n        }\n        clone.size = size;\n        keys = copyOf(keys, size);\n        vals = copyOf(vals, size);\n        return clone;\n    }\n\n    /**\n     * Internal method. Lowercases all keys.\n     */\n    public void normalize() {\n        for (int i = 0; i < size; i++) {\n            keys[i] = lowerCase(keys[i]);\n        }\n    }\n\n//    private static class Dataset extends AbstractMap<String, String> {\n//        private final Attributes attributes;\n//\n//        private Dataset(Attributes attributes) {\n//            this.attributes = attributes;\n//        }\n//\n//        @Override\n//        public Set<Entry<String, String>> entrySet() {\n//            return new EntrySet();\n//        }\n//\n//        @Override\n//        public String put(String key, String value) {\n//            String dataKey = dataKey(key);\n//            String oldValue = attributes.hasKey(dataKey) ? attributes.get(dataKey) : null;\n//            attributes.put(dataKey, value);\n//            return oldValue;\n//        }\n//\n//        private class EntrySet extends AbstractSet<Map.Entry<String, String>> {\n//\n//            @Override\n//            public Iterator<Map.Entry<String, String>> iterator() {\n//                return new DatasetIterator();\n//            }\n//\n//            @Override\n//            public int size() {\n//                int count = 0;\n//                Iterator iter = new DatasetIterator();\n//                while (iter.hasNext())\n//                    count++;\n//                return count;\n//            }\n//        }\n//\n//        private class DatasetIterator implements Iterator<Map.Entry<String, String>> {\n//            private Iterator<Attribute> attrIter = attributes.iterator();\n//            private Attribute attr;\n//            public boolean hasNext() {\n//                while (attrIter.hasNext()) {\n//                    attr = attrIter.next();\n//                    if (attr.isDataAttribute()) return true;\n//                }\n//                return false;\n//            }\n//\n//            public Entry<String, String> next() {\n//                return new Attribute(attr.getKey().substring(dataPrefix.length()), attr.getValue());\n//            }\n//\n//            public void remove() {\n//                attributes.remove(attr.getKey());\n//            }\n//        }\n//    }\n\n//    private static String dataKey(String key) {\n//        return dataPrefix + key;\n//    }\n}"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/jsoup/nodes/CommonMarkEntities.java",
    "content": "package io.noties.markwon.html.jsoup.nodes;\n\nimport androidx.annotation.NonNull;\n\nimport org.commonmark.internal.util.Html5Entities;\n\nimport java.lang.reflect.Field;\nimport java.util.Collections;\nimport java.util.Map;\n\npublic abstract class CommonMarkEntities {\n\n    public static boolean isNamedEntity(@NonNull String name) {\n        return COMMONMARK_NAMED_ENTITIES.containsKey(name);\n    }\n\n    public static int codepointsForName(@NonNull String name, @NonNull int[] codepoints) {\n        final String value = COMMONMARK_NAMED_ENTITIES.get(name);\n        if (value != null) {\n            final int length = value.length();\n            if (length == 1) {\n                codepoints[0] = value.charAt(0);\n            } else {\n                codepoints[0] = value.charAt(0);\n                codepoints[1] = value.charAt(1);\n            }\n            return length;\n        }\n        return 0;\n    }\n\n    private static final Map<String, String> COMMONMARK_NAMED_ENTITIES;\n\n    static {\n        Map<String, String> map;\n        try {\n            final Field field = Html5Entities.class.getDeclaredField(\"NAMED_CHARACTER_REFERENCES\");\n            field.setAccessible(true);\n            //noinspection unchecked\n            map = (Map<String, String>) field.get(null);\n        } catch (Throwable t) {\n            map = Collections.emptyMap();\n            t.printStackTrace();\n        }\n        COMMONMARK_NAMED_ENTITIES = map;\n    }\n\n    private CommonMarkEntities() {\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/jsoup/nodes/DocumentType.java",
    "content": "package io.noties.markwon.html.jsoup.nodes;\n\n/**\n * A {@code <!DOCTYPE>} node.\n */\npublic class DocumentType /*extends LeafNode*/ {\n    // todo needs a bit of a chunky cleanup. this level of detail isn't needed\n    public static final String PUBLIC_KEY = \"PUBLIC\";\n    public static final String SYSTEM_KEY = \"SYSTEM\";\n//    private static final String NAME = \"name\";\n//    private static final String PUB_SYS_KEY = \"pubSysKey\"; // PUBLIC or SYSTEM\n//    private static final String PUBLIC_ID = \"publicId\";\n//    private static final String SYSTEM_ID = \"systemId\";\n    // todo: quirk mode from publicId and systemId\n\n//    /**\n//     * Create a new doctype element.\n//     * @param name the doctype's name\n//     * @param publicId the doctype's public ID\n//     * @param systemId the doctype's system ID\n//     */\n//    public DocumentType(String name, String publicId, String systemId) {\n//        Validate.notNull(name);\n//        Validate.notNull(publicId);\n//        Validate.notNull(systemId);\n//        attr(NAME, name);\n//        attr(PUBLIC_ID, publicId);\n//        if (has(PUBLIC_ID)) {\n//            attr(PUB_SYS_KEY, PUBLIC_KEY);\n//        }\n//        attr(SYSTEM_ID, systemId);\n//    }\n//\n//    /**\n//     * Create a new doctype element.\n//     * @param name the doctype's name\n//     * @param publicId the doctype's public ID\n//     * @param systemId the doctype's system ID\n//     * @param baseUri unused\n//     * @deprecated\n//     */\n//    public DocumentType(String name, String publicId, String systemId, String baseUri) {\n//        attr(NAME, name);\n//        attr(PUBLIC_ID, publicId);\n//        if (has(PUBLIC_ID)) {\n//            attr(PUB_SYS_KEY, PUBLIC_KEY);\n//        }\n//        attr(SYSTEM_ID, systemId);\n//    }\n//\n//    /**\n//     * Create a new doctype element.\n//     * @param name the doctype's name\n//     * @param publicId the doctype's public ID\n//     * @param systemId the doctype's system ID\n//     * @param baseUri unused\n//     * @deprecated\n//     */\n//    public DocumentType(String name, String pubSysKey, String publicId, String systemId, String baseUri) {\n//        attr(NAME, name);\n//        if (pubSysKey != null) {\n//            attr(PUB_SYS_KEY, pubSysKey);\n//        }\n//        attr(PUBLIC_ID, publicId);\n//        attr(SYSTEM_ID, systemId);\n//    }\n//    public void setPubSysKey(String value) {\n//        if (value != null)\n//            attr(PUB_SYS_KEY, value);\n//    }\n//\n//    @Override\n//    public String nodeName() {\n//        return \"#doctype\";\n//    }\n//\n//    @Override\n//    void outerHtmlHead(Appendable accum, int depth, Document.OutputSettings out) throws IOException {\n//        if (out.syntax() == Syntax.html && !has(PUBLIC_ID) && !has(SYSTEM_ID)) {\n//            // looks like a html5 doctype, go lowercase for aesthetics\n//            accum.append(\"<!doctype\");\n//        } else {\n//            accum.append(\"<!DOCTYPE\");\n//        }\n//        if (has(NAME))\n//            accum.append(\" \").append(attr(NAME));\n//        if (has(PUB_SYS_KEY))\n//            accum.append(\" \").append(attr(PUB_SYS_KEY));\n//        if (has(PUBLIC_ID))\n//            accum.append(\" \\\"\").append(attr(PUBLIC_ID)).append('\"');\n//        if (has(SYSTEM_ID))\n//            accum.append(\" \\\"\").append(attr(SYSTEM_ID)).append('\"');\n//        accum.append('>');\n//    }\n//\n//    @Override\n//    void outerHtmlTail(Appendable accum, int depth, Document.OutputSettings out) {\n//    }\n//\n//    private boolean has(final String attribute) {\n//        return !StringUtil.isBlank(attr(attribute));\n//    }\n}\n\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/jsoup/parser/CharacterReader.java",
    "content": "package io.noties.markwon.html.jsoup.parser;\n\nimport java.io.IOException;\nimport java.io.Reader;\nimport java.io.StringReader;\nimport java.util.Arrays;\nimport java.util.Locale;\n\nimport io.noties.markwon.html.jsoup.UncheckedIOException;\nimport io.noties.markwon.html.jsoup.helper.Validate;\n\n/**\n * CharacterReader consumes tokens off a string. Used internally by jsoup. API subject to changes.\n */\npublic final class CharacterReader {\n    static final char EOF = (char) -1;\n    private static final int maxStringCacheLen = 12;\n    static final int maxBufferLen = 1024 * 4; // visible for testing\n    private static final int readAheadLimit = (int) (maxBufferLen * 0.75);\n\n    private final char[] charBuf;\n    private final Reader reader;\n    private int bufLength;\n    private int bufSplitPoint;\n    private int bufPos;\n    private int readerPos;\n    private int bufMark;\n    private final String[] stringCache = new String[128]; // holds reused strings in this doc, to lessen garbage\n\n    public CharacterReader(Reader input, int sz) {\n        Validate.notNull(input);\n        Validate.isTrue(input.markSupported());\n        reader = input;\n        charBuf = new char[maxBufferLen];\n        bufferUp();\n    }\n\n    public CharacterReader(Reader input) {\n        this(input, maxBufferLen);\n    }\n\n    public CharacterReader(String input) {\n        this(new StringReader(input), input.length());\n    }\n\n//    public void swapInput(@NonNull String input) {\n//        reader = new StringReader(input);\n//        bufLength = 0;\n//        bufSplitPoint = 0;\n//        bufPos = 0;\n//        readerPos = 0;\n//        bufferUp();\n//    }\n\n    private void bufferUp() {\n        if (bufPos < bufSplitPoint)\n            return;\n\n        try {\n            reader.skip(bufPos);\n            reader.mark(maxBufferLen);\n            final int read = reader.read(charBuf);\n            reader.reset();\n            if (read != -1) {\n                bufLength = read;\n                readerPos += bufPos;\n                bufPos = 0;\n                bufMark = 0;\n                bufSplitPoint = bufLength > readAheadLimit ? readAheadLimit : bufLength;\n            }\n        } catch (IOException e) {\n            throw new UncheckedIOException(e);\n        }\n    }\n\n    /**\n     * Gets the current cursor position in the content.\n     *\n     * @return current position\n     */\n    public int pos() {\n        return readerPos + bufPos;\n    }\n\n    /**\n     * Tests if all the content has been read.\n     *\n     * @return true if nothing left to read.\n     */\n    public boolean isEmpty() {\n        bufferUp();\n        return bufPos >= bufLength;\n    }\n\n    private boolean isEmptyNoBufferUp() {\n        return bufPos >= bufLength;\n    }\n\n    /**\n     * Get the char at the current position.\n     *\n     * @return char\n     */\n    public char current() {\n        bufferUp();\n        return isEmptyNoBufferUp() ? EOF : charBuf[bufPos];\n    }\n\n    char consume() {\n        bufferUp();\n        char val = isEmptyNoBufferUp() ? EOF : charBuf[bufPos];\n        bufPos++;\n        return val;\n    }\n\n    void unconsume() {\n        bufPos--;\n    }\n\n    /**\n     * Moves the current position by one.\n     */\n    public void advance() {\n        bufPos++;\n    }\n\n    void mark() {\n        bufMark = bufPos;\n    }\n\n    void rewindToMark() {\n        bufPos = bufMark;\n    }\n\n    /**\n     * Returns the number of characters between the current position and the next instance of the input char\n     *\n     * @param c scan target\n     * @return offset between current position and next instance of target. -1 if not found.\n     */\n    int nextIndexOf(char c) {\n        // doesn't handle scanning for surrogates\n        bufferUp();\n        for (int i = bufPos; i < bufLength; i++) {\n            if (c == charBuf[i])\n                return i - bufPos;\n        }\n        return -1;\n    }\n\n    /**\n     * Returns the number of characters between the current position and the next instance of the input sequence\n     *\n     * @param seq scan target\n     * @return offset between current position and next instance of target. -1 if not found.\n     */\n    int nextIndexOf(CharSequence seq) {\n        bufferUp();\n        // doesn't handle scanning for surrogates\n        char startChar = seq.charAt(0);\n        for (int offset = bufPos; offset < bufLength; offset++) {\n            // scan to first instance of startchar:\n            if (startChar != charBuf[offset])\n                while (++offset < bufLength && startChar != charBuf[offset]) { /* empty */ }\n            int i = offset + 1;\n            int last = i + seq.length() - 1;\n            if (offset < bufLength && last <= bufLength) {\n                for (int j = 1; i < last && seq.charAt(j) == charBuf[i]; i++, j++) { /* empty */ }\n                if (i == last) // found full sequence\n                    return offset - bufPos;\n            }\n        }\n        return -1;\n    }\n\n    /**\n     * Reads characters up to the specific char.\n     *\n     * @param c the delimiter\n     * @return the chars read\n     */\n    public String consumeTo(char c) {\n        int offset = nextIndexOf(c);\n        if (offset != -1) {\n            String consumed = cacheString(charBuf, stringCache, bufPos, offset);\n            bufPos += offset;\n            return consumed;\n        } else {\n            return consumeToEnd();\n        }\n    }\n\n    String consumeTo(String seq) {\n        int offset = nextIndexOf(seq);\n        if (offset != -1) {\n            String consumed = cacheString(charBuf, stringCache, bufPos, offset);\n            bufPos += offset;\n            return consumed;\n        } else {\n            return consumeToEnd();\n        }\n    }\n\n    /**\n     * Read characters until the first of any delimiters is found.\n     *\n     * @param chars delimiters to scan for\n     * @return characters read up to the matched delimiter.\n     */\n    public String consumeToAny(final char... chars) {\n        bufferUp();\n        final int start = bufPos;\n        final int remaining = bufLength;\n        final char[] val = charBuf;\n\n        OUTER:\n        while (bufPos < remaining) {\n            for (char c : chars) {\n                if (val[bufPos] == c)\n                    break OUTER;\n            }\n            bufPos++;\n        }\n\n        return bufPos > start ? cacheString(charBuf, stringCache, start, bufPos - start) : \"\";\n    }\n\n    String consumeToAnySorted(final char... chars) {\n        bufferUp();\n        final int start = bufPos;\n        final int remaining = bufLength;\n        final char[] val = charBuf;\n\n        while (bufPos < remaining) {\n            if (Arrays.binarySearch(chars, val[bufPos]) >= 0)\n                break;\n            bufPos++;\n        }\n\n        return bufPos > start ? cacheString(charBuf, stringCache, start, bufPos - start) : \"\";\n    }\n\n    String consumeData() {\n        // &, <, null\n        bufferUp();\n        final int start = bufPos;\n        final int remaining = bufLength;\n        final char[] val = charBuf;\n\n        while (bufPos < remaining) {\n            final char c = val[bufPos];\n            if (c == '&' || c == '<' || c == TokeniserState.nullChar)\n                break;\n            bufPos++;\n        }\n\n        return bufPos > start ? cacheString(charBuf, stringCache, start, bufPos - start) : \"\";\n    }\n\n    String consumeTagName() {\n        // '\\t', '\\n', '\\r', '\\f', ' ', '/', '>', nullChar\n        bufferUp();\n        final int start = bufPos;\n        final int remaining = bufLength;\n        final char[] val = charBuf;\n\n        while (bufPos < remaining) {\n            final char c = val[bufPos];\n            if (c == '\\t' || c == '\\n' || c == '\\r' || c == '\\f' || c == ' ' || c == '/' || c == '>' || c == TokeniserState.nullChar)\n                break;\n            bufPos++;\n        }\n\n        return bufPos > start ? cacheString(charBuf, stringCache, start, bufPos - start) : \"\";\n    }\n\n    String consumeToEnd() {\n        bufferUp();\n        String data = cacheString(charBuf, stringCache, bufPos, bufLength - bufPos);\n        bufPos = bufLength;\n        return data;\n    }\n\n    String consumeLetterSequence() {\n        bufferUp();\n        int start = bufPos;\n        while (bufPos < bufLength) {\n            char c = charBuf[bufPos];\n            if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || Character.isLetter(c))\n                bufPos++;\n            else\n                break;\n        }\n\n        return cacheString(charBuf, stringCache, start, bufPos - start);\n    }\n\n    String consumeLetterThenDigitSequence() {\n        bufferUp();\n        int start = bufPos;\n        while (bufPos < bufLength) {\n            char c = charBuf[bufPos];\n            if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || Character.isLetter(c))\n                bufPos++;\n            else\n                break;\n        }\n        while (!isEmptyNoBufferUp()) {\n            char c = charBuf[bufPos];\n            if (c >= '0' && c <= '9')\n                bufPos++;\n            else\n                break;\n        }\n\n        return cacheString(charBuf, stringCache, start, bufPos - start);\n    }\n\n    String consumeHexSequence() {\n        bufferUp();\n        int start = bufPos;\n        while (bufPos < bufLength) {\n            char c = charBuf[bufPos];\n            if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))\n                bufPos++;\n            else\n                break;\n        }\n        return cacheString(charBuf, stringCache, start, bufPos - start);\n    }\n\n    String consumeDigitSequence() {\n        bufferUp();\n        int start = bufPos;\n        while (bufPos < bufLength) {\n            char c = charBuf[bufPos];\n            if (c >= '0' && c <= '9')\n                bufPos++;\n            else\n                break;\n        }\n        return cacheString(charBuf, stringCache, start, bufPos - start);\n    }\n\n    boolean matches(char c) {\n        return !isEmpty() && charBuf[bufPos] == c;\n\n    }\n\n    boolean matches(String seq) {\n        bufferUp();\n        int scanLength = seq.length();\n        if (scanLength > bufLength - bufPos)\n            return false;\n\n        for (int offset = 0; offset < scanLength; offset++)\n            if (seq.charAt(offset) != charBuf[bufPos + offset])\n                return false;\n        return true;\n    }\n\n    boolean matchesIgnoreCase(String seq) {\n        bufferUp();\n        int scanLength = seq.length();\n        if (scanLength > bufLength - bufPos)\n            return false;\n\n        for (int offset = 0; offset < scanLength; offset++) {\n            char upScan = Character.toUpperCase(seq.charAt(offset));\n            char upTarget = Character.toUpperCase(charBuf[bufPos + offset]);\n            if (upScan != upTarget)\n                return false;\n        }\n        return true;\n    }\n\n    boolean matchesAny(char... seq) {\n        if (isEmpty())\n            return false;\n\n        bufferUp();\n        char c = charBuf[bufPos];\n        for (char seek : seq) {\n            if (seek == c)\n                return true;\n        }\n        return false;\n    }\n\n    boolean matchesAnySorted(char[] seq) {\n        bufferUp();\n        return !isEmpty() && Arrays.binarySearch(seq, charBuf[bufPos]) >= 0;\n    }\n\n    boolean matchesLetter() {\n        if (isEmpty())\n            return false;\n        char c = charBuf[bufPos];\n        return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || Character.isLetter(c);\n    }\n\n    boolean matchesDigit() {\n        if (isEmpty())\n            return false;\n        char c = charBuf[bufPos];\n        return (c >= '0' && c <= '9');\n    }\n\n    boolean matchConsume(String seq) {\n        bufferUp();\n        if (matches(seq)) {\n            bufPos += seq.length();\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    boolean matchConsumeIgnoreCase(String seq) {\n        if (matchesIgnoreCase(seq)) {\n            bufPos += seq.length();\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    boolean containsIgnoreCase(String seq) {\n        // used to check presence of </title>, </style>. only finds consistent case.\n        String loScan = seq.toLowerCase(Locale.ENGLISH);\n        String hiScan = seq.toUpperCase(Locale.ENGLISH);\n        return (nextIndexOf(loScan) > -1) || (nextIndexOf(hiScan) > -1);\n    }\n\n    @Override\n    public String toString() {\n        return new String(charBuf, bufPos, bufLength - bufPos);\n    }\n\n    /**\n     * Caches short strings, as a flywheel pattern, to reduce GC load. Just for this doc, to prevent leaks.\n     * <p/>\n     * Simplistic, and on hash collisions just falls back to creating a new string, vs a full HashMap with Entry list.\n     * That saves both having to create objects as hash keys, and running through the entry list, at the expense of\n     * some more duplicates.\n     */\n    private static String cacheString(final char[] charBuf, final String[] stringCache, final int start, final int count) {\n        // limit (no cache):\n        if (count > maxStringCacheLen)\n            return new String(charBuf, start, count);\n        if (count < 1)\n            return \"\";\n\n        // calculate hash:\n        int hash = 0;\n        int offset = start;\n        for (int i = 0; i < count; i++) {\n            hash = 31 * hash + charBuf[offset++];\n        }\n\n        // get from cache\n        final int index = hash & stringCache.length - 1;\n        String cached = stringCache[index];\n\n        if (cached == null) { // miss, add\n            cached = new String(charBuf, start, count);\n            stringCache[index] = cached;\n        } else { // hashcode hit, check equality\n            if (rangeEquals(charBuf, start, count, cached)) { // hit\n                return cached;\n            } else { // hashcode conflict\n                cached = new String(charBuf, start, count);\n                stringCache[index] = cached; // update the cache, as recently used strings are more likely to show up again\n            }\n        }\n        return cached;\n    }\n\n    /**\n     * Check if the value of the provided range equals the string.\n     */\n    static boolean rangeEquals(final char[] charBuf, final int start, int count, final String cached) {\n        if (count == cached.length()) {\n            int i = start;\n            int j = 0;\n            while (count-- != 0) {\n                if (charBuf[i++] != cached.charAt(j++))\n                    return false;\n            }\n            return true;\n        }\n        return false;\n    }\n\n    // just used for testing\n    boolean rangeEquals(final int start, final int count, final String cached) {\n        return rangeEquals(charBuf, start, count, cached);\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/jsoup/parser/ParseError.java",
    "content": "package io.noties.markwon.html.jsoup.parser;\n\n/**\n * A Parse Error records an error in the input HTML that occurs in either the tokenisation or the tree building phase.\n */\npublic class ParseError {\n    private int pos;\n    private String errorMsg;\n\n    ParseError(int pos, String errorMsg) {\n        this.pos = pos;\n        this.errorMsg = errorMsg;\n    }\n\n    ParseError(int pos, String errorFormat, Object... args) {\n        this.errorMsg = String.format(errorFormat, args);\n        this.pos = pos;\n    }\n\n    /**\n     * Retrieve the error message.\n     * @return the error message.\n     */\n    public String getErrorMessage() {\n        return errorMsg;\n    }\n\n    /**\n     * Retrieves the offset of the error.\n     * @return error offset within input\n     */\n    public int getPosition() {\n        return pos;\n    }\n\n    @Override\n    public String toString() {\n        return pos + \": \" + errorMsg;\n    }\n}\n\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/jsoup/parser/ParseErrorList.java",
    "content": "package io.noties.markwon.html.jsoup.parser;\n\nimport java.util.ArrayList;\n\n/**\n * A container for ParseErrors.\n *\n * @author Jonathan Hedley\n */\npublic class ParseErrorList extends ArrayList<ParseError>{\n    private static final int INITIAL_CAPACITY = 16;\n    private final int maxSize;\n\n    ParseErrorList(int initialCapacity, int maxSize) {\n        super(initialCapacity);\n        this.maxSize = maxSize;\n    }\n\n    boolean canAddError() {\n        return size() < maxSize;\n    }\n\n    int getMaxSize() {\n        return maxSize;\n    }\n\n    public static ParseErrorList noTracking() {\n        return new ParseErrorList(0, 0);\n    }\n\n    public static ParseErrorList tracking(int maxSize) {\n        return new ParseErrorList(INITIAL_CAPACITY, maxSize);\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/jsoup/parser/Token.java",
    "content": "package io.noties.markwon.html.jsoup.parser;\n\nimport androidx.annotation.NonNull;\n\nimport io.noties.markwon.html.jsoup.helper.Validate;\nimport io.noties.markwon.html.jsoup.nodes.Attributes;\n\nimport static io.noties.markwon.html.jsoup.helper.Normalizer.lowerCase;\n\n/**\n * Parse tokens for the Tokeniser.\n */\npublic abstract class Token {\n\n    public final TokenType type;\n\n    protected Token(@NonNull TokenType tokenType) {\n        this.type = tokenType;\n    }\n\n//    String tokenType() {\n//        return this.getClass().getSimpleName();\n//    }\n\n    /**\n     * Reset the data represent by this token, for reuse. Prevents the need to create transfer objects for every\n     * piece of data, which immediately get GCed.\n     */\n    public abstract Token reset();\n\n    static void reset(StringBuilder sb) {\n        if (sb != null) {\n            sb.delete(0, sb.length());\n        }\n    }\n\n    public static final class Doctype extends Token {\n        final StringBuilder name = new StringBuilder();\n        String pubSysKey = null;\n        final StringBuilder publicIdentifier = new StringBuilder();\n        final StringBuilder systemIdentifier = new StringBuilder();\n        boolean forceQuirks = false;\n\n        Doctype() {\n            super(TokenType.Doctype);\n        }\n\n        @Override\n        public Token reset() {\n            reset(name);\n            pubSysKey = null;\n            reset(publicIdentifier);\n            reset(systemIdentifier);\n            forceQuirks = false;\n            return this;\n        }\n\n        String getName() {\n            return name.toString();\n        }\n\n        String getPubSysKey() {\n            return pubSysKey;\n        }\n\n        String getPublicIdentifier() {\n            return publicIdentifier.toString();\n        }\n\n        public String getSystemIdentifier() {\n            return systemIdentifier.toString();\n        }\n\n        public boolean isForceQuirks() {\n            return forceQuirks;\n        }\n    }\n\n    public static abstract class Tag extends Token {\n\n        public String tagName;\n        public String normalName; // lc version of tag name, for case insensitive tree build\n        private String pendingAttributeName; // attribute names are generally caught in one hop, not accumulated\n        private StringBuilder pendingAttributeValue = new StringBuilder(); // but values are accumulated, from e.g. & in hrefs\n        private String pendingAttributeValueS; // try to get attr vals in one shot, vs Builder\n        private boolean hasEmptyAttributeValue = false; // distinguish boolean attribute from empty string value\n        private boolean hasPendingAttributeValue = false;\n        public boolean selfClosing = false;\n        public Attributes attributes; // start tags get attributes on construction. End tags get attributes on first new attribute (but only for parser convenience, not used).\n\n        protected Tag(@NonNull TokenType tokenType) {\n            super(tokenType);\n        }\n\n        @Override\n        public Tag reset() {\n            tagName = null;\n            normalName = null;\n            pendingAttributeName = null;\n            reset(pendingAttributeValue);\n            pendingAttributeValueS = null;\n            hasEmptyAttributeValue = false;\n            hasPendingAttributeValue = false;\n            selfClosing = false;\n            attributes = null;\n            return this;\n        }\n\n        final void newAttribute() {\n            if (attributes == null)\n                attributes = new Attributes();\n\n            if (pendingAttributeName != null) {\n                // the tokeniser has skipped whitespace control chars, but trimming could collapse to empty for other control codes, so verify here\n                pendingAttributeName = pendingAttributeName.trim();\n                if (pendingAttributeName.length() > 0) {\n                    String value;\n                    if (hasPendingAttributeValue)\n                        value = pendingAttributeValue.length() > 0 ? pendingAttributeValue.toString() : pendingAttributeValueS;\n                    else if (hasEmptyAttributeValue)\n                        value = \"\";\n                    else\n                        value = null;\n                    attributes.put(pendingAttributeName, value);\n                }\n            }\n            pendingAttributeName = null;\n            hasEmptyAttributeValue = false;\n            hasPendingAttributeValue = false;\n            reset(pendingAttributeValue);\n            pendingAttributeValueS = null;\n        }\n\n        final void finaliseTag() {\n            // finalises for emit\n            if (pendingAttributeName != null) {\n                // todo: check if attribute name exists; if so, drop and error\n                newAttribute();\n            }\n        }\n\n        final String name() { // preserves case, for input into Tag.valueOf (which may drop case)\n            Validate.isFalse(tagName == null || tagName.length() == 0);\n            return tagName;\n        }\n\n        final String normalName() { // loses case, used in tree building for working out where in tree it should go\n            return normalName;\n        }\n\n        final Tag name(String name) {\n            tagName = name;\n            normalName = lowerCase(name);\n            return this;\n        }\n\n        final boolean isSelfClosing() {\n            return selfClosing;\n        }\n\n        @SuppressWarnings({\"TypeMayBeWeakened\"})\n        final Attributes getAttributes() {\n            return attributes;\n        }\n\n        // these appenders are rarely hit in not null state-- caused by null chars.\n        final void appendTagName(String append) {\n            tagName = tagName == null ? append : tagName.concat(append);\n            normalName = lowerCase(tagName);\n        }\n\n        final void appendTagName(char append) {\n            appendTagName(String.valueOf(append));\n        }\n\n        final void appendAttributeName(String append) {\n            pendingAttributeName = pendingAttributeName == null ? append : pendingAttributeName.concat(append);\n        }\n\n        final void appendAttributeName(char append) {\n            appendAttributeName(String.valueOf(append));\n        }\n\n        final void appendAttributeValue(String append) {\n            ensureAttributeValue();\n            if (pendingAttributeValue.length() == 0) {\n                pendingAttributeValueS = append;\n            } else {\n                pendingAttributeValue.append(append);\n            }\n        }\n\n        final void appendAttributeValue(char append) {\n            ensureAttributeValue();\n            pendingAttributeValue.append(append);\n        }\n\n        final void appendAttributeValue(char[] append) {\n            ensureAttributeValue();\n            pendingAttributeValue.append(append);\n        }\n\n        final void appendAttributeValue(int[] appendCodepoints) {\n            ensureAttributeValue();\n            for (int codepoint : appendCodepoints) {\n                pendingAttributeValue.appendCodePoint(codepoint);\n            }\n        }\n\n        final void setEmptyAttributeValue() {\n            hasEmptyAttributeValue = true;\n        }\n\n        private void ensureAttributeValue() {\n            hasPendingAttributeValue = true;\n            // if on second hit, we'll need to move to the builder\n            if (pendingAttributeValueS != null) {\n                pendingAttributeValue.append(pendingAttributeValueS);\n                pendingAttributeValueS = null;\n            }\n        }\n    }\n\n    public final static class StartTag extends Tag {\n        public StartTag() {\n            super(TokenType.StartTag);\n            attributes = new Attributes();\n        }\n\n        @Override\n        public Tag reset() {\n            super.reset();\n            attributes = new Attributes();\n            // todo - would prefer these to be null, but need to check Element assertions\n            return this;\n        }\n\n        StartTag nameAttr(String name, Attributes attributes) {\n            this.tagName = name;\n            this.attributes = attributes;\n            normalName = lowerCase(tagName);\n            return this;\n        }\n\n        @Override\n        public String toString() {\n            if (attributes != null && attributes.size() > 0)\n                return \"<\" + name() + \" \" + attributes.toString() + \">\";\n            else\n                return \"<\" + name() + \">\";\n        }\n    }\n\n    public final static class EndTag extends Tag {\n        EndTag() {\n            super(TokenType.EndTag);\n        }\n\n        @Override\n        public String toString() {\n            return \"</\" + name() + \">\";\n        }\n    }\n\n    public final static class Comment extends Token {\n        final StringBuilder data = new StringBuilder();\n        boolean bogus = false;\n\n        @Override\n        public Token reset() {\n            reset(data);\n            bogus = false;\n            return this;\n        }\n\n        Comment() {\n            super(TokenType.Comment);\n        }\n\n        String getData() {\n            return data.toString();\n        }\n\n        @Override\n        public String toString() {\n            return \"<!--\" + getData() + \"-->\";\n        }\n    }\n\n    public static class Character extends Token {\n        private String data;\n\n        Character() {\n            super(TokenType.Character);\n        }\n\n        @Override\n        public Token reset() {\n            data = null;\n            return this;\n        }\n\n        Character data(String data) {\n            this.data = data;\n            return this;\n        }\n\n        public String getData() {\n            return data;\n        }\n\n        @Override\n        public String toString() {\n            return getData();\n        }\n    }\n\n    public final static class CData extends Character {\n        CData(String data) {\n            super();\n            this.data(data);\n        }\n\n        @Override\n        public String toString() {\n            return \"<![CDATA[\" + getData() + \"]]>\";\n        }\n\n    }\n\n    public final static class EOF extends Token {\n        EOF() {\n            super(Token.TokenType.EOF);\n        }\n\n        @Override\n        public Token reset() {\n            return this;\n        }\n    }\n\n//    final boolean isDoctype() {\n//        return type == TokenType.Doctype;\n//    }\n//\n//    final Doctype asDoctype() {\n//        return (Doctype) this;\n//    }\n//\n//    final boolean isStartTag() {\n//        return type == TokenType.StartTag;\n//    }\n//\n//    final StartTag asStartTag() {\n//        return (StartTag) this;\n//    }\n//\n//    final boolean isEndTag() {\n//        return type == TokenType.EndTag;\n//    }\n//\n//    final EndTag asEndTag() {\n//        return (EndTag) this;\n//    }\n//\n//    final boolean isComment() {\n//        return type == TokenType.Comment;\n//    }\n//\n//    final Comment asComment() {\n//        return (Comment) this;\n//    }\n//\n//    final boolean isCharacter() {\n//        return type == TokenType.Character;\n//    }\n//\n//    final boolean isCData() {\n//        return this instanceof CData;\n//    }\n//\n//    final Character asCharacter() {\n//        return (Character) this;\n//    }\n//\n//    final boolean isEOF() {\n//        return type == TokenType.EOF;\n//    }\n\n    public enum TokenType {\n        Doctype,\n        StartTag,\n        EndTag,\n        Comment,\n        Character, // note no CData - treated in builder as an extension of Character\n        EOF\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/jsoup/parser/Tokeniser.java",
    "content": "package io.noties.markwon.html.jsoup.parser;\n\nimport java.util.Arrays;\n\nimport io.noties.markwon.html.jsoup.helper.Validate;\nimport io.noties.markwon.html.jsoup.nodes.CommonMarkEntities;\n\n/**\n * Readers the input stream into tokens.\n */\npublic final class Tokeniser {\n    static final char replacementChar = '\\uFFFD'; // replaces null character\n    private static final char[] notCharRefCharsSorted = new char[]{'\\t', '\\n', '\\r', '\\f', ' ', '<', '&'};\n\n    // Some illegal character escapes are parsed by browsers as windows-1252 instead. See issue #1034\n    // https://html.spec.whatwg.org/multipage/parsing.html#numeric-character-reference-end-state\n    static final int win1252ExtensionsStart = 0x80;\n    static final int[] win1252Extensions = new int[] {\n            // we could build this manually, but Windows-1252 is not a standard java charset so that could break on\n            // some platforms - this table is verified with a test\n            0x20AC, 0x0081, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,\n            0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x008D, 0x017D, 0x008F,\n            0x0090, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,\n            0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x009D, 0x017E, 0x0178,\n    };\n\n    static {\n        Arrays.sort(notCharRefCharsSorted);\n    }\n\n    private final CharacterReader reader; // html input\n    private final ParseErrorList errors; // errors found while tokenising\n\n    private TokeniserState state = TokeniserState.Data; // current tokenisation state\n    private Token emitPending; // the token we are about to emit on next read\n    private boolean isEmitPending = false;\n    private String charsString = null; // characters pending an emit. Will fall to charsBuilder if more than one\n    private StringBuilder charsBuilder = new StringBuilder(1024); // buffers characters to output as one token, if more than one emit per read\n    StringBuilder dataBuffer = new StringBuilder(1024); // buffers data looking for </script>\n\n    Token.Tag tagPending; // tag we are building up\n    Token.StartTag startPending = new Token.StartTag();\n    Token.EndTag endPending = new Token.EndTag();\n    Token.Character charPending = new Token.Character();\n    Token.Doctype doctypePending = new Token.Doctype(); // doctype building up\n    Token.Comment commentPending = new Token.Comment(); // comment building up\n    private String lastStartTag; // the last start tag emitted, to test appropriate end tag\n\n    public Tokeniser(CharacterReader reader, ParseErrorList errors) {\n        this.reader = reader;\n        this.errors = errors;\n    }\n\n    public Token read() {\n        while (!isEmitPending)\n            state.read(this, reader);\n\n        // if emit is pending, a non-character token was found: return any chars in buffer, and leave token for next read:\n        if (charsBuilder.length() > 0) {\n            String str = charsBuilder.toString();\n            charsBuilder.delete(0, charsBuilder.length());\n            charsString = null;\n            return charPending.data(str);\n        } else if (charsString != null) {\n            Token token = charPending.data(charsString);\n            charsString = null;\n            return token;\n        } else {\n            isEmitPending = false;\n            return emitPending;\n        }\n    }\n\n    void emit(Token token) {\n        Validate.isFalse(isEmitPending, \"There is an unread token pending!\");\n\n        emitPending = token;\n        isEmitPending = true;\n\n        if (token.type == Token.TokenType.StartTag) {\n            Token.StartTag startTag = (Token.StartTag) token;\n            lastStartTag = startTag.tagName;\n        } else if (token.type == Token.TokenType.EndTag) {\n            Token.EndTag endTag = (Token.EndTag) token;\n            if (endTag.attributes != null)\n                error(\"Attributes incorrectly present on end tag\");\n        }\n    }\n\n    void emit(final String str) {\n        // buffer strings up until last string token found, to emit only one token for a run of character refs etc.\n        // does not set isEmitPending; read checks that\n        if (charsString == null) {\n            charsString = str;\n        }\n        else {\n            if (charsBuilder.length() == 0) { // switching to string builder as more than one emit before read\n                charsBuilder.append(charsString);\n            }\n            charsBuilder.append(str);\n        }\n    }\n\n    void emit(char[] chars) {\n        emit(String.valueOf(chars));\n    }\n\n    void emit(int[] codepoints) {\n        emit(new String(codepoints, 0, codepoints.length));\n    }\n\n    void emit(char c) {\n        emit(String.valueOf(c));\n    }\n\n    TokeniserState getState() {\n        return state;\n    }\n\n    void transition(TokeniserState state) {\n        this.state = state;\n    }\n\n    void advanceTransition(TokeniserState state) {\n        reader.advance();\n        this.state = state;\n    }\n\n    final private int[] codepointHolder = new int[1]; // holder to not have to keep creating arrays\n    final private int[] multipointHolder = new int[2];\n    int[] consumeCharacterReference(Character additionalAllowedCharacter, boolean inAttribute) {\n        if (reader.isEmpty())\n            return null;\n        if (additionalAllowedCharacter != null && additionalAllowedCharacter == reader.current())\n            return null;\n        if (reader.matchesAnySorted(notCharRefCharsSorted))\n            return null;\n\n        final int[] codeRef = codepointHolder;\n        reader.mark();\n        if (reader.matchConsume(\"#\")) { // numbered\n            boolean isHexMode = reader.matchConsumeIgnoreCase(\"X\");\n            String numRef = isHexMode ? reader.consumeHexSequence() : reader.consumeDigitSequence();\n            if (numRef.length() == 0) { // didn't match anything\n                characterReferenceError(\"numeric reference with no numerals\");\n                reader.rewindToMark();\n                return null;\n            }\n            if (!reader.matchConsume(\";\"))\n                characterReferenceError(\"missing semicolon\"); // missing semi\n            int charval = -1;\n            try {\n                int base = isHexMode ? 16 : 10;\n                charval = Integer.valueOf(numRef, base);\n            } catch (NumberFormatException ignored) {\n                error(ignored.getMessage());\n            } // skip\n            if (charval == -1 || (charval >= 0xD800 && charval <= 0xDFFF) || charval > 0x10FFFF) {\n                characterReferenceError(\"character outside of valid range\");\n                codeRef[0] = replacementChar;\n                return codeRef;\n            } else {\n                // fix illegal unicode characters to match browser behavior\n                if (charval >= win1252ExtensionsStart && charval < win1252ExtensionsStart + win1252Extensions.length) {\n                    characterReferenceError(\"character is not a valid unicode code point\");\n                    charval = win1252Extensions[charval - win1252ExtensionsStart];\n                }\n\n                // todo: implement number replacement table\n                // todo: check for extra illegal unicode points as parse errors\n                codeRef[0] = charval;\n                return codeRef;\n            }\n        } else { // named\n            // get as many letters as possible, and look for matching entities.\n            String nameRef = reader.consumeLetterThenDigitSequence();\n            boolean looksLegit = reader.matches(';');\n            // found if a base named entity without a ;, or an extended entity with the ;.\n            boolean found = (CommonMarkEntities.isNamedEntity(nameRef) && looksLegit);\n\n            if (!found) {\n                reader.rewindToMark();\n                if (looksLegit) // named with semicolon\n                    characterReferenceError(String.format(\"invalid named referenece '%s'\", nameRef));\n                return null;\n            }\n            if (inAttribute && (reader.matchesLetter() || reader.matchesDigit() || reader.matchesAny('=', '-', '_'))) {\n                // don't want that to match\n                reader.rewindToMark();\n                return null;\n            }\n            if (!reader.matchConsume(\";\"))\n                characterReferenceError(\"missing semicolon\"); // missing semi\n            int numChars = CommonMarkEntities.codepointsForName(nameRef, multipointHolder);\n            if (numChars == 1) {\n                codeRef[0] = multipointHolder[0];\n                return codeRef;\n            } else if (numChars ==2) {\n                return multipointHolder;\n            } else {\n                Validate.fail(\"Unexpected characters returned for \" + nameRef);\n                return multipointHolder;\n            }\n        }\n    }\n\n    Token.Tag createTagPending(boolean start) {\n        tagPending = start ? startPending.reset() : endPending.reset();\n        return tagPending;\n    }\n\n    void emitTagPending() {\n        tagPending.finaliseTag();\n        emit(tagPending);\n    }\n\n    void createCommentPending() {\n        commentPending.reset();\n    }\n\n    void emitCommentPending() {\n        emit(commentPending);\n    }\n\n    void createDoctypePending() {\n        doctypePending.reset();\n    }\n\n    void emitDoctypePending() {\n        emit(doctypePending);\n    }\n\n    void createTempBuffer() {\n        Token.reset(dataBuffer);\n    }\n\n    boolean isAppropriateEndTagToken() {\n        return lastStartTag != null && tagPending.name().equalsIgnoreCase(lastStartTag);\n    }\n\n    String appropriateEndTagName() {\n        return lastStartTag; // could be null\n    }\n\n    void error(TokeniserState state) {\n        if (errors.canAddError())\n            errors.add(new ParseError(reader.pos(), \"Unexpected character '%s' in input state [%s]\", reader.current(), state));\n    }\n\n    void eofError(TokeniserState state) {\n        if (errors.canAddError())\n            errors.add(new ParseError(reader.pos(), \"Unexpectedly reached end of file (EOF) in input state [%s]\", state));\n    }\n\n    private void characterReferenceError(String message) {\n        if (errors.canAddError())\n            errors.add(new ParseError(reader.pos(), \"Invalid character reference: %s\", message));\n    }\n\n    void error(String errorMsg) {\n        if (errors.canAddError())\n            errors.add(new ParseError(reader.pos(), errorMsg));\n    }\n\n    boolean currentNodeInHtmlNS() {\n        // todo: implement namespaces correctly\n        return true;\n        // Element currentNode = currentNode();\n        // return currentNode != null && currentNode.namespace().equals(\"HTML\");\n    }\n\n//    /**\n//     * Utility method to consume reader and unescape entities found within.\n//     * @param inAttribute if the text to be unescaped is in an attribute\n//     * @return unescaped string from reader\n//     */\n//    String unescapeEntities(boolean inAttribute) {\n//        StringBuilder builder = StringUtil.stringBuilder();\n//        while (!reader.isEmpty()) {\n//            builder.append(reader.consumeTo('&'));\n//            if (reader.matches('&')) {\n//                reader.consume();\n//                int[] c = consumeCharacterReference(null, inAttribute);\n//                if (c == null || c.length==0)\n//                    builder.append('&');\n//                else {\n//                    builder.appendCodePoint(c[0]);\n//                    if (c.length == 2)\n//                        builder.appendCodePoint(c[1]);\n//                }\n//\n//            }\n//        }\n//        return builder.toString();\n//    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/jsoup/parser/TokeniserState.java",
    "content": "package io.noties.markwon.html.jsoup.parser;\n\nimport io.noties.markwon.html.jsoup.nodes.DocumentType;\n\n/**\n * States and transition activations for the Tokeniser.\n */\nenum TokeniserState {\n    Data {\n        // in data state, gather characters until a character reference or tag is found\n        void read(Tokeniser t, CharacterReader r) {\n            switch (r.current()) {\n                case '&':\n                    t.advanceTransition(CharacterReferenceInData);\n                    break;\n                case '<':\n                    t.advanceTransition(TagOpen);\n                    break;\n                case nullChar:\n                    t.error(this); // NOT replacement character (oddly?)\n                    t.emit(r.consume());\n                    break;\n                case eof:\n                    t.emit(new Token.EOF());\n                    break;\n                default:\n                    String data = r.consumeData();\n                    t.emit(data);\n                    break;\n            }\n        }\n    },\n    CharacterReferenceInData {\n        // from & in data\n        void read(Tokeniser t, CharacterReader r) {\n            readCharRef(t, Data);\n        }\n    },\n    Rcdata {\n        /// handles data in title, textarea etc\n        void read(Tokeniser t, CharacterReader r) {\n            switch (r.current()) {\n                case '&':\n                    t.advanceTransition(CharacterReferenceInRcdata);\n                    break;\n                case '<':\n                    t.advanceTransition(RcdataLessthanSign);\n                    break;\n                case nullChar:\n                    t.error(this);\n                    r.advance();\n                    t.emit(replacementChar);\n                    break;\n                case eof:\n                    t.emit(new Token.EOF());\n                    break;\n                default:\n                    String data = r.consumeToAny('&', '<', nullChar);\n                    t.emit(data);\n                    break;\n            }\n        }\n    },\n    CharacterReferenceInRcdata {\n        void read(Tokeniser t, CharacterReader r) {\n            readCharRef(t, Rcdata);\n        }\n    },\n    Rawtext {\n        void read(Tokeniser t, CharacterReader r) {\n            readData(t, r, this, RawtextLessthanSign);\n        }\n    },\n    ScriptData {\n        void read(Tokeniser t, CharacterReader r) {\n            readData(t, r, this, ScriptDataLessthanSign);\n        }\n    },\n    PLAINTEXT {\n        void read(Tokeniser t, CharacterReader r) {\n            switch (r.current()) {\n                case nullChar:\n                    t.error(this);\n                    r.advance();\n                    t.emit(replacementChar);\n                    break;\n                case eof:\n                    t.emit(new Token.EOF());\n                    break;\n                default:\n                    String data = r.consumeTo(nullChar);\n                    t.emit(data);\n                    break;\n            }\n        }\n    },\n    TagOpen {\n        // from < in data\n        void read(Tokeniser t, CharacterReader r) {\n            switch (r.current()) {\n                case '!':\n                    t.advanceTransition(MarkupDeclarationOpen);\n                    break;\n                case '/':\n                    t.advanceTransition(EndTagOpen);\n                    break;\n                case '?':\n                    t.advanceTransition(BogusComment);\n                    break;\n                default:\n                    if (r.matchesLetter()) {\n                        t.createTagPending(true);\n                        t.transition(TagName);\n                    } else {\n                        t.error(this);\n                        t.emit('<'); // char that got us here\n                        t.transition(Data);\n                    }\n                    break;\n            }\n        }\n    },\n    EndTagOpen {\n        void read(Tokeniser t, CharacterReader r) {\n            if (r.isEmpty()) {\n                t.eofError(this);\n                t.emit(\"</\");\n                t.transition(Data);\n            } else if (r.matchesLetter()) {\n                t.createTagPending(false);\n                t.transition(TagName);\n            } else if (r.matches('>')) {\n                t.error(this);\n                t.advanceTransition(Data);\n            } else {\n                t.error(this);\n                t.advanceTransition(BogusComment);\n            }\n        }\n    },\n    TagName {\n        // from < or </ in data, will have start or end tag pending\n        void read(Tokeniser t, CharacterReader r) {\n            // previous TagOpen state did NOT consume, will have a letter char in current\n            //String tagName = r.consumeToAnySorted(tagCharsSorted).toLowerCase();\n            String tagName = r.consumeTagName();\n            t.tagPending.appendTagName(tagName);\n\n            char c = r.consume();\n            switch (c) {\n                case '\\t':\n                case '\\n':\n                case '\\r':\n                case '\\f':\n                case ' ':\n                    t.transition(BeforeAttributeName);\n                    break;\n                case '/':\n                    t.transition(SelfClosingStartTag);\n                    break;\n                case '>':\n                    t.emitTagPending();\n                    t.transition(Data);\n                    break;\n                case nullChar: // replacement\n                    t.tagPending.appendTagName(replacementStr);\n                    break;\n                case eof: // should emit pending tag?\n                    t.eofError(this);\n                    t.transition(Data);\n                    break;\n                default: // buffer underrun\n                    t.tagPending.appendTagName(c);\n            }\n        }\n    },\n    RcdataLessthanSign {\n        // from < in rcdata\n        void read(Tokeniser t, CharacterReader r) {\n            if (r.matches('/')) {\n                t.createTempBuffer();\n                t.advanceTransition(RCDATAEndTagOpen);\n            } else if (r.matchesLetter() && t.appropriateEndTagName() != null && !r.containsIgnoreCase(\"</\" + t.appropriateEndTagName())) {\n                // diverge from spec: got a start tag, but there's no appropriate end tag (</title>), so rather than\n                // consuming to EOF; break out here\n                t.tagPending = t.createTagPending(false).name(t.appropriateEndTagName());\n                t.emitTagPending();\n                r.unconsume(); // undo \"<\"\n                t.transition(Data);\n            } else {\n                t.emit(\"<\");\n                t.transition(Rcdata);\n            }\n        }\n    },\n    RCDATAEndTagOpen {\n        void read(Tokeniser t, CharacterReader r) {\n            if (r.matchesLetter()) {\n                t.createTagPending(false);\n                t.tagPending.appendTagName(r.current());\n                t.dataBuffer.append(r.current());\n                t.advanceTransition(RCDATAEndTagName);\n            } else {\n                t.emit(\"</\");\n                t.transition(Rcdata);\n            }\n        }\n    },\n    RCDATAEndTagName {\n        void read(Tokeniser t, CharacterReader r) {\n            if (r.matchesLetter()) {\n                String name = r.consumeLetterSequence();\n                t.tagPending.appendTagName(name);\n                t.dataBuffer.append(name);\n                return;\n            }\n\n            char c = r.consume();\n            switch (c) {\n                case '\\t':\n                case '\\n':\n                case '\\r':\n                case '\\f':\n                case ' ':\n                    if (t.isAppropriateEndTagToken())\n                        t.transition(BeforeAttributeName);\n                    else\n                        anythingElse(t, r);\n                    break;\n                case '/':\n                    if (t.isAppropriateEndTagToken())\n                        t.transition(SelfClosingStartTag);\n                    else\n                        anythingElse(t, r);\n                    break;\n                case '>':\n                    if (t.isAppropriateEndTagToken()) {\n                        t.emitTagPending();\n                        t.transition(Data);\n                    }\n                    else\n                        anythingElse(t, r);\n                    break;\n                default:\n                    anythingElse(t, r);\n            }\n        }\n\n        private void anythingElse(Tokeniser t, CharacterReader r) {\n            t.emit(\"</\" + t.dataBuffer.toString());\n            r.unconsume();\n            t.transition(Rcdata);\n        }\n    },\n    RawtextLessthanSign {\n        void read(Tokeniser t, CharacterReader r) {\n            if (r.matches('/')) {\n                t.createTempBuffer();\n                t.advanceTransition(RawtextEndTagOpen);\n            } else {\n                t.emit('<');\n                t.transition(Rawtext);\n            }\n        }\n    },\n    RawtextEndTagOpen {\n        void read(Tokeniser t, CharacterReader r) {\n            readEndTag(t, r, RawtextEndTagName, Rawtext);\n        }\n    },\n    RawtextEndTagName {\n        void read(Tokeniser t, CharacterReader r) {\n            handleDataEndTag(t, r, Rawtext);\n        }\n    },\n    ScriptDataLessthanSign {\n        void read(Tokeniser t, CharacterReader r) {\n            switch (r.consume()) {\n                case '/':\n                    t.createTempBuffer();\n                    t.transition(ScriptDataEndTagOpen);\n                    break;\n                case '!':\n                    t.emit(\"<!\");\n                    t.transition(ScriptDataEscapeStart);\n                    break;\n                default:\n                    t.emit(\"<\");\n                    r.unconsume();\n                    t.transition(ScriptData);\n            }\n        }\n    },\n    ScriptDataEndTagOpen {\n        void read(Tokeniser t, CharacterReader r) {\n            readEndTag(t, r, ScriptDataEndTagName, ScriptData);\n        }\n    },\n    ScriptDataEndTagName {\n        void read(Tokeniser t, CharacterReader r) {\n            handleDataEndTag(t, r, ScriptData);\n        }\n    },\n    ScriptDataEscapeStart {\n        void read(Tokeniser t, CharacterReader r) {\n            if (r.matches('-')) {\n                t.emit('-');\n                t.advanceTransition(ScriptDataEscapeStartDash);\n            } else {\n                t.transition(ScriptData);\n            }\n        }\n    },\n    ScriptDataEscapeStartDash {\n        void read(Tokeniser t, CharacterReader r) {\n            if (r.matches('-')) {\n                t.emit('-');\n                t.advanceTransition(ScriptDataEscapedDashDash);\n            } else {\n                t.transition(ScriptData);\n            }\n        }\n    },\n    ScriptDataEscaped {\n        void read(Tokeniser t, CharacterReader r) {\n            if (r.isEmpty()) {\n                t.eofError(this);\n                t.transition(Data);\n                return;\n            }\n\n            switch (r.current()) {\n                case '-':\n                    t.emit('-');\n                    t.advanceTransition(ScriptDataEscapedDash);\n                    break;\n                case '<':\n                    t.advanceTransition(ScriptDataEscapedLessthanSign);\n                    break;\n                case nullChar:\n                    t.error(this);\n                    r.advance();\n                    t.emit(replacementChar);\n                    break;\n                default:\n                    String data = r.consumeToAny('-', '<', nullChar);\n                    t.emit(data);\n            }\n        }\n    },\n    ScriptDataEscapedDash {\n        void read(Tokeniser t, CharacterReader r) {\n            if (r.isEmpty()) {\n                t.eofError(this);\n                t.transition(Data);\n                return;\n            }\n\n            char c = r.consume();\n            switch (c) {\n                case '-':\n                    t.emit(c);\n                    t.transition(ScriptDataEscapedDashDash);\n                    break;\n                case '<':\n                    t.transition(ScriptDataEscapedLessthanSign);\n                    break;\n                case nullChar:\n                    t.error(this);\n                    t.emit(replacementChar);\n                    t.transition(ScriptDataEscaped);\n                    break;\n                default:\n                    t.emit(c);\n                    t.transition(ScriptDataEscaped);\n            }\n        }\n    },\n    ScriptDataEscapedDashDash {\n        void read(Tokeniser t, CharacterReader r) {\n            if (r.isEmpty()) {\n                t.eofError(this);\n                t.transition(Data);\n                return;\n            }\n\n            char c = r.consume();\n            switch (c) {\n                case '-':\n                    t.emit(c);\n                    break;\n                case '<':\n                    t.transition(ScriptDataEscapedLessthanSign);\n                    break;\n                case '>':\n                    t.emit(c);\n                    t.transition(ScriptData);\n                    break;\n                case nullChar:\n                    t.error(this);\n                    t.emit(replacementChar);\n                    t.transition(ScriptDataEscaped);\n                    break;\n                default:\n                    t.emit(c);\n                    t.transition(ScriptDataEscaped);\n            }\n        }\n    },\n    ScriptDataEscapedLessthanSign {\n        void read(Tokeniser t, CharacterReader r) {\n            if (r.matchesLetter()) {\n                t.createTempBuffer();\n                t.dataBuffer.append(r.current());\n                t.emit(\"<\" + r.current());\n                t.advanceTransition(ScriptDataDoubleEscapeStart);\n            } else if (r.matches('/')) {\n                t.createTempBuffer();\n                t.advanceTransition(ScriptDataEscapedEndTagOpen);\n            } else {\n                t.emit('<');\n                t.transition(ScriptDataEscaped);\n            }\n        }\n    },\n    ScriptDataEscapedEndTagOpen {\n        void read(Tokeniser t, CharacterReader r) {\n            if (r.matchesLetter()) {\n                t.createTagPending(false);\n                t.tagPending.appendTagName(r.current());\n                t.dataBuffer.append(r.current());\n                t.advanceTransition(ScriptDataEscapedEndTagName);\n            } else {\n                t.emit(\"</\");\n                t.transition(ScriptDataEscaped);\n            }\n        }\n    },\n    ScriptDataEscapedEndTagName {\n        void read(Tokeniser t, CharacterReader r) {\n            handleDataEndTag(t, r, ScriptDataEscaped);\n        }\n    },\n    ScriptDataDoubleEscapeStart {\n        void read(Tokeniser t, CharacterReader r) {\n            handleDataDoubleEscapeTag(t, r, ScriptDataDoubleEscaped, ScriptDataEscaped);\n        }\n    },\n    ScriptDataDoubleEscaped {\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.current();\n            switch (c) {\n                case '-':\n                    t.emit(c);\n                    t.advanceTransition(ScriptDataDoubleEscapedDash);\n                    break;\n                case '<':\n                    t.emit(c);\n                    t.advanceTransition(ScriptDataDoubleEscapedLessthanSign);\n                    break;\n                case nullChar:\n                    t.error(this);\n                    r.advance();\n                    t.emit(replacementChar);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.transition(Data);\n                    break;\n                default:\n                    String data = r.consumeToAny('-', '<', nullChar);\n                    t.emit(data);\n            }\n        }\n    },\n    ScriptDataDoubleEscapedDash {\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.consume();\n            switch (c) {\n                case '-':\n                    t.emit(c);\n                    t.transition(ScriptDataDoubleEscapedDashDash);\n                    break;\n                case '<':\n                    t.emit(c);\n                    t.transition(ScriptDataDoubleEscapedLessthanSign);\n                    break;\n                case nullChar:\n                    t.error(this);\n                    t.emit(replacementChar);\n                    t.transition(ScriptDataDoubleEscaped);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.transition(Data);\n                    break;\n                default:\n                    t.emit(c);\n                    t.transition(ScriptDataDoubleEscaped);\n            }\n        }\n    },\n    ScriptDataDoubleEscapedDashDash {\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.consume();\n            switch (c) {\n                case '-':\n                    t.emit(c);\n                    break;\n                case '<':\n                    t.emit(c);\n                    t.transition(ScriptDataDoubleEscapedLessthanSign);\n                    break;\n                case '>':\n                    t.emit(c);\n                    t.transition(ScriptData);\n                    break;\n                case nullChar:\n                    t.error(this);\n                    t.emit(replacementChar);\n                    t.transition(ScriptDataDoubleEscaped);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.transition(Data);\n                    break;\n                default:\n                    t.emit(c);\n                    t.transition(ScriptDataDoubleEscaped);\n            }\n        }\n    },\n    ScriptDataDoubleEscapedLessthanSign {\n        void read(Tokeniser t, CharacterReader r) {\n            if (r.matches('/')) {\n                t.emit('/');\n                t.createTempBuffer();\n                t.advanceTransition(ScriptDataDoubleEscapeEnd);\n            } else {\n                t.transition(ScriptDataDoubleEscaped);\n            }\n        }\n    },\n    ScriptDataDoubleEscapeEnd {\n        void read(Tokeniser t, CharacterReader r) {\n            handleDataDoubleEscapeTag(t,r, ScriptDataEscaped, ScriptDataDoubleEscaped);\n        }\n    },\n    BeforeAttributeName {\n        // from tagname <xxx\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.consume();\n            switch (c) {\n                case '\\t':\n                case '\\n':\n                case '\\r':\n                case '\\f':\n                case ' ':\n                    break; // ignore whitespace\n                case '/':\n                    t.transition(SelfClosingStartTag);\n                    break;\n                case '>':\n                    t.emitTagPending();\n                    t.transition(Data);\n                    break;\n                case nullChar:\n                    t.error(this);\n                    t.tagPending.newAttribute();\n                    r.unconsume();\n                    t.transition(AttributeName);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.transition(Data);\n                    break;\n                case '\"':\n                case '\\'':\n                case '<':\n                case '=':\n                    t.error(this);\n                    t.tagPending.newAttribute();\n                    t.tagPending.appendAttributeName(c);\n                    t.transition(AttributeName);\n                    break;\n                default: // A-Z, anything else\n                    t.tagPending.newAttribute();\n                    r.unconsume();\n                    t.transition(AttributeName);\n            }\n        }\n    },\n    AttributeName {\n        // from before attribute name\n        void read(Tokeniser t, CharacterReader r) {\n            String name = r.consumeToAnySorted(attributeNameCharsSorted);\n            t.tagPending.appendAttributeName(name);\n\n            char c = r.consume();\n            switch (c) {\n                case '\\t':\n                case '\\n':\n                case '\\r':\n                case '\\f':\n                case ' ':\n                    t.transition(AfterAttributeName);\n                    break;\n                case '/':\n                    t.transition(SelfClosingStartTag);\n                    break;\n                case '=':\n                    t.transition(BeforeAttributeValue);\n                    break;\n                case '>':\n                    t.emitTagPending();\n                    t.transition(Data);\n                    break;\n                case nullChar:\n                    t.error(this);\n                    t.tagPending.appendAttributeName(replacementChar);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.transition(Data);\n                    break;\n                case '\"':\n                case '\\'':\n                case '<':\n                    t.error(this);\n                    t.tagPending.appendAttributeName(c);\n                    break;\n                default: // buffer underrun\n                    t.tagPending.appendAttributeName(c);\n            }\n        }\n    },\n    AfterAttributeName {\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.consume();\n            switch (c) {\n                case '\\t':\n                case '\\n':\n                case '\\r':\n                case '\\f':\n                case ' ':\n                    // ignore\n                    break;\n                case '/':\n                    t.transition(SelfClosingStartTag);\n                    break;\n                case '=':\n                    t.transition(BeforeAttributeValue);\n                    break;\n                case '>':\n                    t.emitTagPending();\n                    t.transition(Data);\n                    break;\n                case nullChar:\n                    t.error(this);\n                    t.tagPending.appendAttributeName(replacementChar);\n                    t.transition(AttributeName);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.transition(Data);\n                    break;\n                case '\"':\n                case '\\'':\n                case '<':\n                    t.error(this);\n                    t.tagPending.newAttribute();\n                    t.tagPending.appendAttributeName(c);\n                    t.transition(AttributeName);\n                    break;\n                default: // A-Z, anything else\n                    t.tagPending.newAttribute();\n                    r.unconsume();\n                    t.transition(AttributeName);\n            }\n        }\n    },\n    BeforeAttributeValue {\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.consume();\n            switch (c) {\n                case '\\t':\n                case '\\n':\n                case '\\r':\n                case '\\f':\n                case ' ':\n                    // ignore\n                    break;\n                case '\"':\n                    t.transition(AttributeValue_doubleQuoted);\n                    break;\n                case '&':\n                    r.unconsume();\n                    t.transition(AttributeValue_unquoted);\n                    break;\n                case '\\'':\n                    t.transition(AttributeValue_singleQuoted);\n                    break;\n                case nullChar:\n                    t.error(this);\n                    t.tagPending.appendAttributeValue(replacementChar);\n                    t.transition(AttributeValue_unquoted);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.emitTagPending();\n                    t.transition(Data);\n                    break;\n                case '>':\n                    t.error(this);\n                    t.emitTagPending();\n                    t.transition(Data);\n                    break;\n                case '<':\n                case '=':\n                case '`':\n                    t.error(this);\n                    t.tagPending.appendAttributeValue(c);\n                    t.transition(AttributeValue_unquoted);\n                    break;\n                default:\n                    r.unconsume();\n                    t.transition(AttributeValue_unquoted);\n            }\n        }\n    },\n    AttributeValue_doubleQuoted {\n        void read(Tokeniser t, CharacterReader r) {\n            String value = r.consumeToAny(attributeDoubleValueCharsSorted);\n            if (value.length() > 0)\n                t.tagPending.appendAttributeValue(value);\n            else\n                t.tagPending.setEmptyAttributeValue();\n\n            char c = r.consume();\n            switch (c) {\n                case '\"':\n                    t.transition(AfterAttributeValue_quoted);\n                    break;\n                case '&':\n                    int[] ref = t.consumeCharacterReference('\"', true);\n                    if (ref != null)\n                        t.tagPending.appendAttributeValue(ref);\n                    else\n                        t.tagPending.appendAttributeValue('&');\n                    break;\n                case nullChar:\n                    t.error(this);\n                    t.tagPending.appendAttributeValue(replacementChar);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.transition(Data);\n                    break;\n                default: // hit end of buffer in first read, still in attribute\n                    t.tagPending.appendAttributeValue(c);\n            }\n        }\n    },\n    AttributeValue_singleQuoted {\n        void read(Tokeniser t, CharacterReader r) {\n            String value = r.consumeToAny(attributeSingleValueCharsSorted);\n            if (value.length() > 0)\n                t.tagPending.appendAttributeValue(value);\n            else\n                t.tagPending.setEmptyAttributeValue();\n\n            char c = r.consume();\n            switch (c) {\n                case '\\'':\n                    t.transition(AfterAttributeValue_quoted);\n                    break;\n                case '&':\n                    int[] ref = t.consumeCharacterReference('\\'', true);\n                    if (ref != null)\n                        t.tagPending.appendAttributeValue(ref);\n                    else\n                        t.tagPending.appendAttributeValue('&');\n                    break;\n                case nullChar:\n                    t.error(this);\n                    t.tagPending.appendAttributeValue(replacementChar);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.transition(Data);\n                    break;\n                default: // hit end of buffer in first read, still in attribute\n                    t.tagPending.appendAttributeValue(c);\n            }\n        }\n    },\n    AttributeValue_unquoted {\n        void read(Tokeniser t, CharacterReader r) {\n            String value = r.consumeToAnySorted(attributeValueUnquoted);\n            if (value.length() > 0)\n                t.tagPending.appendAttributeValue(value);\n\n            char c = r.consume();\n            switch (c) {\n                case '\\t':\n                case '\\n':\n                case '\\r':\n                case '\\f':\n                case ' ':\n                    t.transition(BeforeAttributeName);\n                    break;\n                case '&':\n                    int[] ref = t.consumeCharacterReference('>', true);\n                    if (ref != null)\n                        t.tagPending.appendAttributeValue(ref);\n                    else\n                        t.tagPending.appendAttributeValue('&');\n                    break;\n                case '>':\n                    t.emitTagPending();\n                    t.transition(Data);\n                    break;\n                case nullChar:\n                    t.error(this);\n                    t.tagPending.appendAttributeValue(replacementChar);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.transition(Data);\n                    break;\n                case '\"':\n                case '\\'':\n                case '<':\n                case '=':\n                case '`':\n                    t.error(this);\n                    t.tagPending.appendAttributeValue(c);\n                    break;\n                default: // hit end of buffer in first read, still in attribute\n                    t.tagPending.appendAttributeValue(c);\n            }\n\n        }\n    },\n    // CharacterReferenceInAttributeValue state handled inline\n    AfterAttributeValue_quoted {\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.consume();\n            switch (c) {\n                case '\\t':\n                case '\\n':\n                case '\\r':\n                case '\\f':\n                case ' ':\n                    t.transition(BeforeAttributeName);\n                    break;\n                case '/':\n                    t.transition(SelfClosingStartTag);\n                    break;\n                case '>':\n                    t.emitTagPending();\n                    t.transition(Data);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.transition(Data);\n                    break;\n                default:\n                    t.error(this);\n                    r.unconsume();\n                    t.transition(BeforeAttributeName);\n            }\n\n        }\n    },\n    SelfClosingStartTag {\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.consume();\n            switch (c) {\n                case '>':\n                    t.tagPending.selfClosing = true;\n                    t.emitTagPending();\n                    t.transition(Data);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.transition(Data);\n                    break;\n                default:\n                    t.error(this);\n                    r.unconsume();\n                    t.transition(BeforeAttributeName);\n            }\n        }\n    },\n    BogusComment {\n        void read(Tokeniser t, CharacterReader r) {\n            // todo: handle bogus comment starting from eof. when does that trigger?\n            // rewind to capture character that lead us here\n            r.unconsume();\n            Token.Comment comment = new Token.Comment();\n            comment.bogus = true;\n            comment.data.append(r.consumeTo('>'));\n            // todo: replace nullChar with replaceChar\n            t.emit(comment);\n            t.advanceTransition(Data);\n        }\n    },\n    MarkupDeclarationOpen {\n        void read(Tokeniser t, CharacterReader r) {\n            if (r.matchConsume(\"--\")) {\n                t.createCommentPending();\n                t.transition(CommentStart);\n            } else if (r.matchConsumeIgnoreCase(\"DOCTYPE\")) {\n                t.transition(Doctype);\n            } else if (r.matchConsume(\"[CDATA[\")) {\n                // todo: should actually check current namepspace, and only non-html allows cdata. until namespace\n                // is implemented properly, keep handling as cdata\n                //} else if (!t.currentNodeInHtmlNS() && r.matchConsume(\"[CDATA[\")) {\n                t.createTempBuffer();\n                t.transition(CdataSection);\n            } else {\n                t.error(this);\n                t.advanceTransition(BogusComment); // advance so this character gets in bogus comment data's rewind\n            }\n        }\n    },\n    CommentStart {\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.consume();\n            switch (c) {\n                case '-':\n                    t.transition(CommentStartDash);\n                    break;\n                case nullChar:\n                    t.error(this);\n                    t.commentPending.data.append(replacementChar);\n                    t.transition(Comment);\n                    break;\n                case '>':\n                    t.error(this);\n                    t.emitCommentPending();\n                    t.transition(Data);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.emitCommentPending();\n                    t.transition(Data);\n                    break;\n                default:\n                    t.commentPending.data.append(c);\n                    t.transition(Comment);\n            }\n        }\n    },\n    CommentStartDash {\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.consume();\n            switch (c) {\n                case '-':\n                    t.transition(CommentStartDash);\n                    break;\n                case nullChar:\n                    t.error(this);\n                    t.commentPending.data.append(replacementChar);\n                    t.transition(Comment);\n                    break;\n                case '>':\n                    t.error(this);\n                    t.emitCommentPending();\n                    t.transition(Data);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.emitCommentPending();\n                    t.transition(Data);\n                    break;\n                default:\n                    t.commentPending.data.append(c);\n                    t.transition(Comment);\n            }\n        }\n    },\n    Comment {\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.current();\n            switch (c) {\n                case '-':\n                    t.advanceTransition(CommentEndDash);\n                    break;\n                case nullChar:\n                    t.error(this);\n                    r.advance();\n                    t.commentPending.data.append(replacementChar);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.emitCommentPending();\n                    t.transition(Data);\n                    break;\n                default:\n                    t.commentPending.data.append(r.consumeToAny('-', nullChar));\n            }\n        }\n    },\n    CommentEndDash {\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.consume();\n            switch (c) {\n                case '-':\n                    t.transition(CommentEnd);\n                    break;\n                case nullChar:\n                    t.error(this);\n                    t.commentPending.data.append('-').append(replacementChar);\n                    t.transition(Comment);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.emitCommentPending();\n                    t.transition(Data);\n                    break;\n                default:\n                    t.commentPending.data.append('-').append(c);\n                    t.transition(Comment);\n            }\n        }\n    },\n    CommentEnd {\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.consume();\n            switch (c) {\n                case '>':\n                    t.emitCommentPending();\n                    t.transition(Data);\n                    break;\n                case nullChar:\n                    t.error(this);\n                    t.commentPending.data.append(\"--\").append(replacementChar);\n                    t.transition(Comment);\n                    break;\n                case '!':\n                    t.error(this);\n                    t.transition(CommentEndBang);\n                    break;\n                case '-':\n                    t.error(this);\n                    t.commentPending.data.append('-');\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.emitCommentPending();\n                    t.transition(Data);\n                    break;\n                default:\n                    t.error(this);\n                    t.commentPending.data.append(\"--\").append(c);\n                    t.transition(Comment);\n            }\n        }\n    },\n    CommentEndBang {\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.consume();\n            switch (c) {\n                case '-':\n                    t.commentPending.data.append(\"--!\");\n                    t.transition(CommentEndDash);\n                    break;\n                case '>':\n                    t.emitCommentPending();\n                    t.transition(Data);\n                    break;\n                case nullChar:\n                    t.error(this);\n                    t.commentPending.data.append(\"--!\").append(replacementChar);\n                    t.transition(Comment);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.emitCommentPending();\n                    t.transition(Data);\n                    break;\n                default:\n                    t.commentPending.data.append(\"--!\").append(c);\n                    t.transition(Comment);\n            }\n        }\n    },\n    Doctype {\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.consume();\n            switch (c) {\n                case '\\t':\n                case '\\n':\n                case '\\r':\n                case '\\f':\n                case ' ':\n                    t.transition(BeforeDoctypeName);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    // note: fall through to > case\n                case '>': // catch invalid <!DOCTYPE>\n                    t.error(this);\n                    t.createDoctypePending();\n                    t.doctypePending.forceQuirks = true;\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                default:\n                    t.error(this);\n                    t.transition(BeforeDoctypeName);\n            }\n        }\n    },\n    BeforeDoctypeName {\n        void read(Tokeniser t, CharacterReader r) {\n            if (r.matchesLetter()) {\n                t.createDoctypePending();\n                t.transition(DoctypeName);\n                return;\n            }\n            char c = r.consume();\n            switch (c) {\n                case '\\t':\n                case '\\n':\n                case '\\r':\n                case '\\f':\n                case ' ':\n                    break; // ignore whitespace\n                case nullChar:\n                    t.error(this);\n                    t.createDoctypePending();\n                    t.doctypePending.name.append(replacementChar);\n                    t.transition(DoctypeName);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.createDoctypePending();\n                    t.doctypePending.forceQuirks = true;\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                default:\n                    t.createDoctypePending();\n                    t.doctypePending.name.append(c);\n                    t.transition(DoctypeName);\n            }\n        }\n    },\n    DoctypeName {\n        void read(Tokeniser t, CharacterReader r) {\n            if (r.matchesLetter()) {\n                String name = r.consumeLetterSequence();\n                t.doctypePending.name.append(name);\n                return;\n            }\n            char c = r.consume();\n            switch (c) {\n                case '>':\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                case '\\t':\n                case '\\n':\n                case '\\r':\n                case '\\f':\n                case ' ':\n                    t.transition(AfterDoctypeName);\n                    break;\n                case nullChar:\n                    t.error(this);\n                    t.doctypePending.name.append(replacementChar);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.doctypePending.forceQuirks = true;\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                default:\n                    t.doctypePending.name.append(c);\n            }\n        }\n    },\n    AfterDoctypeName {\n        void read(Tokeniser t, CharacterReader r) {\n            if (r.isEmpty()) {\n                t.eofError(this);\n                t.doctypePending.forceQuirks = true;\n                t.emitDoctypePending();\n                t.transition(Data);\n                return;\n            }\n            if (r.matchesAny('\\t', '\\n', '\\r', '\\f', ' '))\n                r.advance(); // ignore whitespace\n            else if (r.matches('>')) {\n                t.emitDoctypePending();\n                t.advanceTransition(Data);\n            } else if (r.matchConsumeIgnoreCase(DocumentType.PUBLIC_KEY)) {\n                t.doctypePending.pubSysKey = DocumentType.PUBLIC_KEY;\n                t.transition(AfterDoctypePublicKeyword);\n            } else if (r.matchConsumeIgnoreCase(DocumentType.SYSTEM_KEY)) {\n                t.doctypePending.pubSysKey = DocumentType.SYSTEM_KEY;\n                t.transition(AfterDoctypeSystemKeyword);\n            } else {\n                t.error(this);\n                t.doctypePending.forceQuirks = true;\n                t.advanceTransition(BogusDoctype);\n            }\n\n        }\n    },\n    AfterDoctypePublicKeyword {\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.consume();\n            switch (c) {\n                case '\\t':\n                case '\\n':\n                case '\\r':\n                case '\\f':\n                case ' ':\n                    t.transition(BeforeDoctypePublicIdentifier);\n                    break;\n                case '\"':\n                    t.error(this);\n                    // set public id to empty string\n                    t.transition(DoctypePublicIdentifier_doubleQuoted);\n                    break;\n                case '\\'':\n                    t.error(this);\n                    // set public id to empty string\n                    t.transition(DoctypePublicIdentifier_singleQuoted);\n                    break;\n                case '>':\n                    t.error(this);\n                    t.doctypePending.forceQuirks = true;\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.doctypePending.forceQuirks = true;\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                default:\n                    t.error(this);\n                    t.doctypePending.forceQuirks = true;\n                    t.transition(BogusDoctype);\n            }\n        }\n    },\n    BeforeDoctypePublicIdentifier {\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.consume();\n            switch (c) {\n                case '\\t':\n                case '\\n':\n                case '\\r':\n                case '\\f':\n                case ' ':\n                    break;\n                case '\"':\n                    // set public id to empty string\n                    t.transition(DoctypePublicIdentifier_doubleQuoted);\n                    break;\n                case '\\'':\n                    // set public id to empty string\n                    t.transition(DoctypePublicIdentifier_singleQuoted);\n                    break;\n                case '>':\n                    t.error(this);\n                    t.doctypePending.forceQuirks = true;\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.doctypePending.forceQuirks = true;\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                default:\n                    t.error(this);\n                    t.doctypePending.forceQuirks = true;\n                    t.transition(BogusDoctype);\n            }\n        }\n    },\n    DoctypePublicIdentifier_doubleQuoted {\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.consume();\n            switch (c) {\n                case '\"':\n                    t.transition(AfterDoctypePublicIdentifier);\n                    break;\n                case nullChar:\n                    t.error(this);\n                    t.doctypePending.publicIdentifier.append(replacementChar);\n                    break;\n                case '>':\n                    t.error(this);\n                    t.doctypePending.forceQuirks = true;\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.doctypePending.forceQuirks = true;\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                default:\n                    t.doctypePending.publicIdentifier.append(c);\n            }\n        }\n    },\n    DoctypePublicIdentifier_singleQuoted {\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.consume();\n            switch (c) {\n                case '\\'':\n                    t.transition(AfterDoctypePublicIdentifier);\n                    break;\n                case nullChar:\n                    t.error(this);\n                    t.doctypePending.publicIdentifier.append(replacementChar);\n                    break;\n                case '>':\n                    t.error(this);\n                    t.doctypePending.forceQuirks = true;\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.doctypePending.forceQuirks = true;\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                default:\n                    t.doctypePending.publicIdentifier.append(c);\n            }\n        }\n    },\n    AfterDoctypePublicIdentifier {\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.consume();\n            switch (c) {\n                case '\\t':\n                case '\\n':\n                case '\\r':\n                case '\\f':\n                case ' ':\n                    t.transition(BetweenDoctypePublicAndSystemIdentifiers);\n                    break;\n                case '>':\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                case '\"':\n                    t.error(this);\n                    // system id empty\n                    t.transition(DoctypeSystemIdentifier_doubleQuoted);\n                    break;\n                case '\\'':\n                    t.error(this);\n                    // system id empty\n                    t.transition(DoctypeSystemIdentifier_singleQuoted);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.doctypePending.forceQuirks = true;\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                default:\n                    t.error(this);\n                    t.doctypePending.forceQuirks = true;\n                    t.transition(BogusDoctype);\n            }\n        }\n    },\n    BetweenDoctypePublicAndSystemIdentifiers {\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.consume();\n            switch (c) {\n                case '\\t':\n                case '\\n':\n                case '\\r':\n                case '\\f':\n                case ' ':\n                    break;\n                case '>':\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                case '\"':\n                    t.error(this);\n                    // system id empty\n                    t.transition(DoctypeSystemIdentifier_doubleQuoted);\n                    break;\n                case '\\'':\n                    t.error(this);\n                    // system id empty\n                    t.transition(DoctypeSystemIdentifier_singleQuoted);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.doctypePending.forceQuirks = true;\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                default:\n                    t.error(this);\n                    t.doctypePending.forceQuirks = true;\n                    t.transition(BogusDoctype);\n            }\n        }\n    },\n    AfterDoctypeSystemKeyword {\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.consume();\n            switch (c) {\n                case '\\t':\n                case '\\n':\n                case '\\r':\n                case '\\f':\n                case ' ':\n                    t.transition(BeforeDoctypeSystemIdentifier);\n                    break;\n                case '>':\n                    t.error(this);\n                    t.doctypePending.forceQuirks = true;\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                case '\"':\n                    t.error(this);\n                    // system id empty\n                    t.transition(DoctypeSystemIdentifier_doubleQuoted);\n                    break;\n                case '\\'':\n                    t.error(this);\n                    // system id empty\n                    t.transition(DoctypeSystemIdentifier_singleQuoted);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.doctypePending.forceQuirks = true;\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                default:\n                    t.error(this);\n                    t.doctypePending.forceQuirks = true;\n                    t.emitDoctypePending();\n            }\n        }\n    },\n    BeforeDoctypeSystemIdentifier {\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.consume();\n            switch (c) {\n                case '\\t':\n                case '\\n':\n                case '\\r':\n                case '\\f':\n                case ' ':\n                    break;\n                case '\"':\n                    // set system id to empty string\n                    t.transition(DoctypeSystemIdentifier_doubleQuoted);\n                    break;\n                case '\\'':\n                    // set public id to empty string\n                    t.transition(DoctypeSystemIdentifier_singleQuoted);\n                    break;\n                case '>':\n                    t.error(this);\n                    t.doctypePending.forceQuirks = true;\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.doctypePending.forceQuirks = true;\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                default:\n                    t.error(this);\n                    t.doctypePending.forceQuirks = true;\n                    t.transition(BogusDoctype);\n            }\n        }\n    },\n    DoctypeSystemIdentifier_doubleQuoted {\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.consume();\n            switch (c) {\n                case '\"':\n                    t.transition(AfterDoctypeSystemIdentifier);\n                    break;\n                case nullChar:\n                    t.error(this);\n                    t.doctypePending.systemIdentifier.append(replacementChar);\n                    break;\n                case '>':\n                    t.error(this);\n                    t.doctypePending.forceQuirks = true;\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.doctypePending.forceQuirks = true;\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                default:\n                    t.doctypePending.systemIdentifier.append(c);\n            }\n        }\n    },\n    DoctypeSystemIdentifier_singleQuoted {\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.consume();\n            switch (c) {\n                case '\\'':\n                    t.transition(AfterDoctypeSystemIdentifier);\n                    break;\n                case nullChar:\n                    t.error(this);\n                    t.doctypePending.systemIdentifier.append(replacementChar);\n                    break;\n                case '>':\n                    t.error(this);\n                    t.doctypePending.forceQuirks = true;\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.doctypePending.forceQuirks = true;\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                default:\n                    t.doctypePending.systemIdentifier.append(c);\n            }\n        }\n    },\n    AfterDoctypeSystemIdentifier {\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.consume();\n            switch (c) {\n                case '\\t':\n                case '\\n':\n                case '\\r':\n                case '\\f':\n                case ' ':\n                    break;\n                case '>':\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                case eof:\n                    t.eofError(this);\n                    t.doctypePending.forceQuirks = true;\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                default:\n                    t.error(this);\n                    t.transition(BogusDoctype);\n                    // NOT force quirks\n            }\n        }\n    },\n    BogusDoctype {\n        void read(Tokeniser t, CharacterReader r) {\n            char c = r.consume();\n            switch (c) {\n                case '>':\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                case eof:\n                    t.emitDoctypePending();\n                    t.transition(Data);\n                    break;\n                default:\n                    // ignore char\n                    break;\n            }\n        }\n    },\n    CdataSection {\n        void read(Tokeniser t, CharacterReader r) {\n            String data = r.consumeTo(\"]]>\");\n            t.dataBuffer.append(data);\n            if (r.matchConsume(\"]]>\") || r.isEmpty()) {\n                t.emit(new Token.CData(t.dataBuffer.toString()));\n                t.transition(Data);\n            }// otherwise, buffer underrun, stay in data section\n        }\n    };\n\n\n    abstract void read(Tokeniser t, CharacterReader r);\n\n    static final char nullChar = '\\u0000';\n    // char searches. must be sorted, used in inSorted. MUST update TokenisetStateTest if more arrays are added.\n    static final char[] attributeSingleValueCharsSorted = new char[]{nullChar, '&', '\\''};\n    static final char[] attributeDoubleValueCharsSorted = new char[]{nullChar, '\"', '&'};\n    static final char[] attributeNameCharsSorted = new char[]{nullChar, '\\t', '\\n', '\\f', '\\r', ' ', '\"', '\\'', '/', '<', '=', '>'};\n    static final char[] attributeValueUnquoted = new char[]{nullChar, '\\t', '\\n', '\\f', '\\r', ' ', '\"', '&', '\\'', '<', '=', '>', '`'};\n\n    private static final char replacementChar = Tokeniser.replacementChar;\n    private static final String replacementStr = String.valueOf(Tokeniser.replacementChar);\n    private static final char eof = CharacterReader.EOF;\n\n    /**\n     * Handles RawtextEndTagName, ScriptDataEndTagName, and ScriptDataEscapedEndTagName. Same body impl, just\n     * different else exit transitions.\n     */\n    private static void handleDataEndTag(Tokeniser t, CharacterReader r, TokeniserState elseTransition) {\n        if (r.matchesLetter()) {\n            String name = r.consumeLetterSequence();\n            t.tagPending.appendTagName(name);\n            t.dataBuffer.append(name);\n            return;\n        }\n\n        boolean needsExitTransition = false;\n        if (t.isAppropriateEndTagToken() && !r.isEmpty()) {\n            char c = r.consume();\n            switch (c) {\n                case '\\t':\n                case '\\n':\n                case '\\r':\n                case '\\f':\n                case ' ':\n                    t.transition(BeforeAttributeName);\n                    break;\n                case '/':\n                    t.transition(SelfClosingStartTag);\n                    break;\n                case '>':\n                    t.emitTagPending();\n                    t.transition(Data);\n                    break;\n                default:\n                    t.dataBuffer.append(c);\n                    needsExitTransition = true;\n            }\n        } else {\n            needsExitTransition = true;\n        }\n\n        if (needsExitTransition) {\n            t.emit(\"</\" + t.dataBuffer.toString());\n            t.transition(elseTransition);\n        }\n    }\n\n    private static void readData(Tokeniser t, CharacterReader r, TokeniserState current, TokeniserState advance) {\n        switch (r.current()) {\n            case '<':\n                t.advanceTransition(advance);\n                break;\n            case nullChar:\n                t.error(current);\n                r.advance();\n                t.emit(replacementChar);\n                break;\n            case eof:\n                t.emit(new Token.EOF());\n                break;\n            default:\n                String data = r.consumeToAny('<', nullChar); // todo - why hunt for null here? Just consumeTo'<'?\n                t.emit(data);\n                break;\n        }\n    }\n\n    private static void readCharRef(Tokeniser t, TokeniserState advance) {\n        int[] c = t.consumeCharacterReference(null, false);\n        if (c == null)\n            t.emit('&');\n        else\n            t.emit(c);\n        t.transition(advance);\n    }\n\n    private static void readEndTag(Tokeniser t, CharacterReader r, TokeniserState a, TokeniserState b) {\n        if (r.matchesLetter()) {\n            t.createTagPending(false);\n            t.transition(a);\n        } else {\n            t.emit(\"</\");\n            t.transition(b);\n        }\n    }\n\n    private static void handleDataDoubleEscapeTag(Tokeniser t, CharacterReader r, TokeniserState primary, TokeniserState fallback) {\n        if (r.matchesLetter()) {\n            String name = r.consumeLetterSequence();\n            t.dataBuffer.append(name);\n            t.emit(name);\n            return;\n        }\n\n        char c = r.consume();\n        switch (c) {\n            case '\\t':\n            case '\\n':\n            case '\\r':\n            case '\\f':\n            case ' ':\n            case '/':\n            case '>':\n                if (t.dataBuffer.toString().equals(\"script\"))\n                    t.transition(primary);\n                else\n                    t.transition(fallback);\n                t.emit(c);\n                break;\n            default:\n                r.unconsume();\n                t.transition(fallback);\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/span/SubScriptSpan.java",
    "content": "package io.noties.markwon.html.span;\n\nimport android.text.TextPaint;\nimport android.text.style.MetricAffectingSpan;\n\nimport androidx.annotation.NonNull;\n\nimport io.noties.markwon.html.HtmlPlugin;\n\npublic class SubScriptSpan extends MetricAffectingSpan {\n\n    @Override\n    public void updateDrawState(TextPaint tp) {\n        apply(tp);\n    }\n\n    @Override\n    public void updateMeasureState(@NonNull TextPaint tp) {\n        apply(tp);\n    }\n\n    private void apply(TextPaint paint) {\n        paint.setTextSize(paint.getTextSize() * HtmlPlugin.SCRIPT_DEF_TEXT_SIZE_RATIO);\n        paint.baselineShift -= (int) (paint.ascent() / 2);\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/span/SuperScriptSpan.java",
    "content": "package io.noties.markwon.html.span;\n\nimport android.text.TextPaint;\nimport android.text.style.MetricAffectingSpan;\n\nimport androidx.annotation.NonNull;\n\nimport io.noties.markwon.html.HtmlPlugin;\n\npublic class SuperScriptSpan extends MetricAffectingSpan {\n\n    @Override\n    public void updateDrawState(TextPaint tp) {\n        apply(tp);\n    }\n\n    @Override\n    public void updateMeasureState(@NonNull TextPaint tp) {\n        apply(tp);\n    }\n\n    private void apply(TextPaint paint) {\n        paint.setTextSize(paint.getTextSize() * HtmlPlugin.SCRIPT_DEF_TEXT_SIZE_RATIO);\n        paint.baselineShift += (int) (paint.ascent() / 2);\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/tag/BlockquoteHandler.java",
    "content": "package io.noties.markwon.html.tag;\n\nimport androidx.annotation.NonNull;\n\nimport org.commonmark.node.BlockQuote;\n\nimport java.util.Collection;\nimport java.util.Collections;\n\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.MarkwonVisitor;\nimport io.noties.markwon.SpanFactory;\nimport io.noties.markwon.SpannableBuilder;\nimport io.noties.markwon.html.HtmlTag;\nimport io.noties.markwon.html.MarkwonHtmlRenderer;\nimport io.noties.markwon.html.TagHandler;\n\npublic class BlockquoteHandler extends TagHandler {\n\n    @Override\n    public void handle(\n            @NonNull MarkwonVisitor visitor,\n            @NonNull MarkwonHtmlRenderer renderer,\n            @NonNull HtmlTag tag) {\n\n        if (tag.isBlock()) {\n            visitChildren(visitor, renderer, tag.getAsBlock());\n        }\n\n        final MarkwonConfiguration configuration = visitor.configuration();\n        final SpanFactory factory = configuration.spansFactory().get(BlockQuote.class);\n        if (factory != null) {\n            SpannableBuilder.setSpans(\n                    visitor.builder(),\n                    factory.getSpans(configuration, visitor.renderProps()),\n                    tag.start(),\n                    tag.end()\n            );\n        }\n    }\n\n    @NonNull\n    @Override\n    public Collection<String> supportedTags() {\n        return Collections.singleton(\"blockquote\");\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/tag/EmphasisHandler.java",
    "content": "package io.noties.markwon.html.tag;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport org.commonmark.node.Emphasis;\n\nimport java.util.Arrays;\nimport java.util.Collection;\n\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.RenderProps;\nimport io.noties.markwon.SpanFactory;\nimport io.noties.markwon.html.HtmlTag;\n\npublic class EmphasisHandler extends SimpleTagHandler {\n    @Nullable\n    @Override\n    public Object getSpans(\n            @NonNull MarkwonConfiguration configuration,\n            @NonNull RenderProps renderProps,\n            @NonNull HtmlTag tag) {\n        final SpanFactory spanFactory = configuration.spansFactory().get(Emphasis.class);\n        if (spanFactory == null) {\n            return null;\n        }\n        return spanFactory.getSpans(configuration, renderProps);\n    }\n\n    @NonNull\n    @Override\n    public Collection<String> supportedTags() {\n        return Arrays.asList(\"i\", \"em\", \"cite\", \"dfn\");\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/tag/HeadingHandler.java",
    "content": "package io.noties.markwon.html.tag;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport org.commonmark.node.Heading;\n\nimport java.util.Arrays;\nimport java.util.Collection;\n\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.RenderProps;\nimport io.noties.markwon.SpanFactory;\nimport io.noties.markwon.core.CoreProps;\nimport io.noties.markwon.html.HtmlTag;\n\npublic class HeadingHandler extends SimpleTagHandler {\n\n    @Nullable\n    @Override\n    public Object getSpans(\n            @NonNull MarkwonConfiguration configuration,\n            @NonNull RenderProps renderProps,\n            @NonNull HtmlTag tag) {\n\n        final SpanFactory factory = configuration.spansFactory().get(Heading.class);\n        if (factory == null) {\n            return null;\n        }\n\n        int level;\n        try {\n            level = Integer.parseInt(tag.name().substring(1));\n        } catch (NumberFormatException e) {\n            e.printStackTrace();\n            level = 0;\n        }\n\n        if (level < 1 || level > 6) {\n            return null;\n        }\n\n        CoreProps.HEADING_LEVEL.set(renderProps, level);\n\n        return factory.getSpans(configuration, renderProps);\n    }\n\n    @NonNull\n    @Override\n    public Collection<String> supportedTags() {\n        return Arrays.asList(\"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\");\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/tag/ImageHandler.java",
    "content": "package io.noties.markwon.html.tag;\n\nimport android.text.TextUtils;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport org.commonmark.node.Image;\n\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.Map;\n\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.RenderProps;\nimport io.noties.markwon.SpanFactory;\nimport io.noties.markwon.html.CssInlineStyleParser;\nimport io.noties.markwon.html.HtmlTag;\nimport io.noties.markwon.image.ImageProps;\nimport io.noties.markwon.image.ImageSize;\n\npublic class ImageHandler extends SimpleTagHandler {\n\n    @NonNull\n    @Override\n    public Collection<String> supportedTags() {\n        return Collections.singleton(\"img\");\n    }\n\n    interface ImageSizeParser {\n        @Nullable\n        ImageSize parse(@NonNull Map<String, String> attributes);\n    }\n\n    @NonNull\n    public static ImageHandler create() {\n        return new ImageHandler(new ImageSizeParserImpl(CssInlineStyleParser.create()));\n    }\n\n    private final ImageSizeParser imageSizeParser;\n\n    @SuppressWarnings(\"WeakerAccess\")\n    ImageHandler(@NonNull ImageSizeParser imageSizeParser) {\n        this.imageSizeParser = imageSizeParser;\n    }\n\n    @Nullable\n    @Override\n    public Object getSpans(\n            @NonNull MarkwonConfiguration configuration,\n            @NonNull RenderProps renderProps,\n            @NonNull HtmlTag tag) {\n\n        final Map<String, String> attributes = tag.attributes();\n        final String src = attributes.get(\"src\");\n        if (TextUtils.isEmpty(src)) {\n            return null;\n        }\n\n        final SpanFactory spanFactory = configuration.spansFactory().get(Image.class);\n        if (spanFactory == null) {\n            return null;\n        }\n\n        final String destination = configuration.imageDestinationProcessor().process(src);\n        final ImageSize imageSize = imageSizeParser.parse(tag.attributes());\n\n        // todo: replacement text is link... as we are not at block level\n        // and cannot inspect the parent of this node... (img and a are both inlines)\n        //\n        // but we can look and see if we are inside a LinkSpan (will have to extend TagHandler\n        // to obtain an instance SpannableBuilder for inspection)\n\n        ImageProps.DESTINATION.set(renderProps, destination);\n        ImageProps.IMAGE_SIZE.set(renderProps, imageSize);\n        ImageProps.REPLACEMENT_TEXT_IS_LINK.set(renderProps, false);\n\n        return spanFactory.getSpans(configuration, renderProps);\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/tag/ImageSizeParserImpl.java",
    "content": "package io.noties.markwon.html.tag;\n\nimport android.text.TextUtils;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.VisibleForTesting;\n\nimport com.fluid.afm.utils.MDLogger;\n\nimport java.util.Map;\n\nimport io.noties.markwon.html.CssInlineStyleParser;\nimport io.noties.markwon.html.CssProperty;\nimport io.noties.markwon.image.ImageSize;\nimport io.noties.markwon.image.ImageSizeResolverDef;\nimport com.fluid.afm.utils.Utils;\n\nclass ImageSizeParserImpl implements ImageHandler.ImageSizeParser {\n\n    private final CssInlineStyleParser inlineStyleParser;\n\n    ImageSizeParserImpl(@NonNull CssInlineStyleParser inlineStyleParser) {\n        this.inlineStyleParser = inlineStyleParser;\n    }\n\n    @Override\n    public ImageSize parse(@NonNull Map<String, String> attributes) {\n\n        // strictly speaking percents when specified directly on an attribute\n        // are not part of the HTML spec (I couldn't find any reference)\n\n        ImageSize.Dimension width = null;\n        ImageSize.Dimension height = null;\n\n        // okay, let's first check styles\n        final String style = attributes.get(\"style\");\n        if (!TextUtils.isEmpty(style)) {\n            String key;\n            for (CssProperty cssProperty : inlineStyleParser.parse(style)) {\n                key = cssProperty.key();\n                if (\"width\".equals(key)) {\n                    width = dimension(cssProperty.value());\n                } else if (\"height\".equals(key)) {\n                    height = dimension(cssProperty.value());\n                }\n                if (width != null && height != null) {\n                    break;\n                }\n            }\n        }\n\n        if (width != null\n                && height != null) {\n            width = rpxToPx(width);\n            height = rpxToPx(height);\n            return new ImageSize(width, height);\n        }\n\n        // check tag attributes\n        if (width == null) {\n            width = dimension(attributes.get(\"width\"));\n        }\n\n        if (height == null) {\n            height = dimension(attributes.get(\"height\"));\n        }\n\n        if (width == null\n                && height == null) {\n            return null;\n        }\n        width = rpxToPx(width);\n        height = rpxToPx(height);\n        return new ImageSize(width, height);\n    }\n\n    private ImageSize.Dimension rpxToPx(@Nullable ImageSize.Dimension side) {\n        MDLogger.d(\"ImageSizeParserImpl\", \"parse before convert: \" + side);\n        ImageSize.Dimension result = side;\n        try {\n            if (side != null && side.value != 0 && ImageSizeResolverDef.UNIT_RPX.equalsIgnoreCase(side.unit)) {\n                result = new ImageSize.Dimension(Utils.rpxToPx(side.value), ImageSizeResolverDef.UNIT_PX);\n            }\n        } catch (Exception e) {\n            MDLogger.e(\"ImageSizeParserImpl\", \"throwable e = \" + e.getMessage());\n        }\n        MDLogger.d(\"ImageSizeParserImpl\", \"after convert parse: \" + result);\n        return result;\n    }\n\n\n    @Nullable\n    @VisibleForTesting\n    ImageSize.Dimension dimension(@Nullable String value) {\n\n        if (TextUtils.isEmpty(value)) {\n            return null;\n        }\n\n        final int length = value.length();\n\n        for (int i = length - 1; i > -1; i--) {\n\n            if (Character.isDigit(value.charAt(i))) {\n\n                try {\n                    final float val = Float.parseFloat(value.substring(0, i + 1));\n                    final String unit;\n                    if (i == length - 1) {\n                        // no unit info\n                        unit = null;\n                    } else {\n                        unit = value.substring(i + 1, length);\n                    }\n                    return new ImageSize.Dimension(val, unit);\n                } catch (NumberFormatException e) {\n                    // value cannot not be represented as a float\n                    return null;\n                }\n            }\n        }\n\n        return null;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/tag/LinkHandler.java",
    "content": "package io.noties.markwon.html.tag;\n\nimport android.text.TextUtils;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport com.fluid.afm.utils.MDLogger;\n\nimport org.commonmark.node.Link;\n\nimport java.util.Collection;\nimport java.util.Collections;\n\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.RenderProps;\nimport io.noties.markwon.SpanFactory;\nimport io.noties.markwon.core.CoreProps;\nimport io.noties.markwon.html.CssInlineStyleParser;\nimport io.noties.markwon.html.CssProperty;\nimport io.noties.markwon.html.HtmlTag;\n\npublic class LinkHandler extends SimpleTagHandler {\n    @Nullable\n    @Override\n    public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps renderProps, @NonNull HtmlTag tag) {\n        final SpanFactory spanFactory = configuration.spansFactory().get(Link.class);\n        if (spanFactory == null) {\n            return null;\n        }\n        final String destination = tag.attributes().get(\"href\");\n        if (!TextUtils.isEmpty(destination)) {\n            CoreProps.LINK_DESTINATION.set(\n                    renderProps,\n                    destination\n            );\n        }\n        final String style = tag.attributes().get(\"style\");\n        if (!TextUtils.isEmpty(style)) {\n            Iterable<CssProperty> styleProp = CssInlineStyleParser.create().parse(style);\n            for (CssProperty property : styleProp) {\n                switch (property.key()) {\n                    case \"color\":\n                        CoreProps.COLOR.set(\n                                renderProps,\n                                property.value()\n                        );\n                        break;\n                    case \"text-decoration\":\n                        CoreProps.LINK_TEXT_DECORATION.set(\n                                renderProps,\n                                property.value()\n                        );\n                        break;\n                    case \"font-weight\":\n                        CoreProps.FONT_WEIGHT.set(\n                                renderProps,\n                                property.value()\n                        );\n                        break;\n                    default:\n                        MDLogger.i(\"unexpected CSS property: %s\", property.key());\n                }\n            }\n        }\n        CoreProps.SOURCE.set(\n                renderProps,\n                tag.name()\n        );\n        return spanFactory.getSpans(configuration, renderProps);\n    }\n\n    @NonNull\n    @Override\n    public Collection<String> supportedTags() {\n        return Collections.singleton(\"a\");\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/tag/ListHandler.java",
    "content": "package io.noties.markwon.html.tag;\n\nimport androidx.annotation.NonNull;\n\nimport org.commonmark.node.ListItem;\n\nimport java.util.Arrays;\nimport java.util.Collection;\n\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.MarkwonVisitor;\nimport io.noties.markwon.RenderProps;\nimport io.noties.markwon.SpanFactory;\nimport io.noties.markwon.SpannableBuilder;\nimport io.noties.markwon.core.CoreProps;\nimport io.noties.markwon.html.HtmlTag;\nimport io.noties.markwon.html.MarkwonHtmlRenderer;\nimport io.noties.markwon.html.TagHandler;\n\npublic class ListHandler extends TagHandler {\n\n    @Override\n    public void handle(\n            @NonNull MarkwonVisitor visitor,\n            @NonNull MarkwonHtmlRenderer renderer,\n            @NonNull HtmlTag tag) {\n\n        if (!tag.isBlock()) {\n            return;\n        }\n\n        final HtmlTag.Block block = tag.getAsBlock();\n        final boolean ol = \"ol\".equals(block.name());\n        final boolean ul = \"ul\".equals(block.name());\n\n        if (!ol && !ul) {\n            return;\n        }\n\n        final MarkwonConfiguration configuration = visitor.configuration();\n        final RenderProps renderProps = visitor.renderProps();\n        final SpanFactory spanFactory = configuration.spansFactory().get(ListItem.class);\n\n        int number = 1;\n        final int bulletLevel = currentBulletListLevel(block);\n\n        for (HtmlTag.Block child : block.children()) {\n\n            visitChildren(visitor, renderer, child);\n\n            if (spanFactory != null && \"li\".equals(child.name())) {\n\n                // insert list item here\n                if (ol) {\n                    CoreProps.LIST_ITEM_TYPE.set(renderProps, CoreProps.ListItemType.ORDERED);\n                    CoreProps.ORDERED_LIST_ITEM_NUMBER.set(renderProps, number++);\n                    CoreProps.BULLET_LIST_ITEM_LEVEL.set(renderProps, bulletLevel);\n                } else {\n                    CoreProps.LIST_ITEM_TYPE.set(renderProps, CoreProps.ListItemType.BULLET);\n                    CoreProps.BULLET_LIST_ITEM_LEVEL.set(renderProps, bulletLevel);\n                }\n\n                SpannableBuilder.setSpans(\n                        visitor.builder(),\n                        spanFactory.getSpans(configuration, renderProps),\n                        child.start(),\n                        child.end());\n            }\n        }\n    }\n\n    @NonNull\n    @Override\n    public Collection<String> supportedTags() {\n        return Arrays.asList(\"ol\", \"ul\");\n    }\n\n    private static int currentBulletListLevel(@NonNull HtmlTag.Block block) {\n        int level = 0;\n        while ((block = block.parent()) != null) {\n            if (\"ul\".equals(block.name())\n                    || \"ol\".equals(block.name())) {\n                level += 1;\n            }\n        }\n        return level;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/tag/SimpleTagHandler.java",
    "content": "package io.noties.markwon.html.tag;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport java.util.Collection;\n\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.MarkwonVisitor;\nimport io.noties.markwon.RenderProps;\nimport io.noties.markwon.SpannableBuilder;\nimport io.noties.markwon.html.HtmlTag;\nimport io.noties.markwon.html.MarkwonHtmlRenderer;\nimport io.noties.markwon.html.TagHandler;\n\npublic abstract class SimpleTagHandler extends TagHandler {\n    private String tagContent = \"\";\n\n    @Nullable\n    public abstract Object getSpans(\n            @NonNull MarkwonConfiguration configuration,\n            @NonNull RenderProps renderProps,\n            @NonNull HtmlTag tag);\n\n    @NonNull\n    @Override\n    public abstract Collection<String> supportedTags();\n\n\n    @Override\n    public void handle(@NonNull MarkwonVisitor visitor, @NonNull MarkwonHtmlRenderer renderer, @NonNull HtmlTag tag) {\n        // @since 4.5.0 check if tag is block one and visit children\n        if (tag.isBlock()) {\n            visitChildren(visitor, renderer, tag.getAsBlock());\n        }\n        if (tag.end() > tag.start() && tag.start() >= 0 && tag.end() <= visitor.builder().length()) {\n            tagContent = visitor.builder().subSequence(tag.start(), tag.end()).toString();\n        }\n        final Object spans = getSpans(visitor.configuration(), visitor.renderProps(), tag);\n        if (spans != null) {\n            SpannableBuilder.setSpans(visitor.builder(), spans, tag.start(), tag.end());\n        }\n    }\n\n    protected String getTagContent() {\n        return tagContent;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/tag/StrikeHandler.java",
    "content": "package io.noties.markwon.html.tag;\n\nimport android.text.style.StrikethroughSpan;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport java.util.Arrays;\nimport java.util.Collection;\n\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.MarkwonVisitor;\nimport io.noties.markwon.SpanFactory;\nimport io.noties.markwon.SpannableBuilder;\nimport io.noties.markwon.html.HtmlTag;\nimport io.noties.markwon.html.MarkwonHtmlRenderer;\nimport io.noties.markwon.html.TagHandler;\n\npublic class StrikeHandler extends TagHandler {\n\n    // flag to detect if commonmark-java-strikethrough is in classpath, so we use SpanFactory\n    // to obtain strikethrough span\n    private static final boolean HAS_MARKDOWN_IMPLEMENTATION;\n\n    static {\n        boolean hasMarkdownImplementation;\n        try {\n            // @since 4.3.1 we class Class.forName instead of trying\n            //  to access the class by full qualified name (which caused issues with DexGuard)\n            Class.forName(\"org.commonmark.ext.gfm.strikethrough.Strikethrough\");\n            hasMarkdownImplementation = true;\n        } catch (Throwable t) {\n            hasMarkdownImplementation = false;\n        }\n        HAS_MARKDOWN_IMPLEMENTATION = hasMarkdownImplementation;\n    }\n\n    @Override\n    public void handle(\n            @NonNull MarkwonVisitor visitor,\n            @NonNull MarkwonHtmlRenderer renderer,\n            @NonNull HtmlTag tag) {\n\n        if (tag.isBlock()) {\n            visitChildren(visitor, renderer, tag.getAsBlock());\n        }\n\n        SpannableBuilder.setSpans(\n                visitor.builder(),\n                HAS_MARKDOWN_IMPLEMENTATION ? getMarkdownSpans(visitor) : new StrikethroughSpan(),\n                tag.start(),\n                tag.end()\n        );\n    }\n\n    @NonNull\n    @Override\n    public Collection<String> supportedTags() {\n        return Arrays.asList(\"s\", \"del\");\n    }\n\n    @Nullable\n    private static Object getMarkdownSpans(@NonNull MarkwonVisitor visitor) {\n        Class strikethroughClass = null;\n        try {\n            strikethroughClass = Class.forName(\"org.commonmark.ext.gfm.strikethrough.Strikethrough\");\n        } catch (ClassNotFoundException e) {\n            return null;\n        }\n\n        if (strikethroughClass == null) {\n            return null;\n        }\n\n        final MarkwonConfiguration configuration = visitor.configuration();\n        final SpanFactory spanFactory = configuration.spansFactory().get(strikethroughClass);\n        if (spanFactory == null) {\n            return null;\n        }\n        return spanFactory.getSpans(configuration, visitor.renderProps());\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/tag/StrongEmphasisHandler.java",
    "content": "package io.noties.markwon.html.tag;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport org.commonmark.node.StrongEmphasis;\n\nimport java.util.Arrays;\nimport java.util.Collection;\n\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.RenderProps;\nimport io.noties.markwon.SpanFactory;\nimport io.noties.markwon.html.HtmlTag;\n\npublic class StrongEmphasisHandler extends SimpleTagHandler {\n    @Nullable\n    @Override\n    public Object getSpans(\n            @NonNull MarkwonConfiguration configuration,\n            @NonNull RenderProps renderProps,\n            @NonNull HtmlTag tag) {\n        final SpanFactory spanFactory = configuration.spansFactory().get(StrongEmphasis.class);\n        if (spanFactory == null) {\n            return null;\n        }\n        return spanFactory.getSpans(configuration, renderProps);\n    }\n\n    @NonNull\n    @Override\n    public Collection<String> supportedTags() {\n        return Arrays.asList(\"b\", \"strong\");\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/tag/SubScriptHandler.java",
    "content": "package io.noties.markwon.html.tag;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport java.util.Collection;\nimport java.util.Collections;\n\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.RenderProps;\nimport io.noties.markwon.html.HtmlTag;\nimport io.noties.markwon.html.span.SubScriptSpan;\n\npublic class SubScriptHandler extends SimpleTagHandler {\n    @Nullable\n    @Override\n    public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps renderProps, @NonNull HtmlTag tag) {\n        return new SubScriptSpan();\n    }\n\n    @NonNull\n    @Override\n    public Collection<String> supportedTags() {\n        return Collections.singleton(\"sub\");\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/tag/SuperScriptHandler.java",
    "content": "package io.noties.markwon.html.tag;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport java.util.Collection;\nimport java.util.Collections;\n\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.RenderProps;\nimport io.noties.markwon.html.HtmlTag;\nimport io.noties.markwon.html.span.SuperScriptSpan;\n\npublic class SuperScriptHandler extends SimpleTagHandler {\n    @Nullable\n    @Override\n    public Object getSpans(@NonNull MarkwonConfiguration configuration, @NonNull RenderProps renderProps, @NonNull HtmlTag tag) {\n        return new SuperScriptSpan();\n    }\n\n    @NonNull\n    @Override\n    public Collection<String> supportedTags() {\n        return Collections.singleton(\"sup\");\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/main/java/io/noties/markwon/html/tag/UnderlineHandler.java",
    "content": "package io.noties.markwon.html.tag;\n\nimport android.text.style.UnderlineSpan;\n\nimport androidx.annotation.NonNull;\n\nimport com.fluid.afm.styles.UnderlineStyle;\n\nimport java.util.Arrays;\nimport java.util.Collection;\n\nimport io.noties.markwon.MarkwonVisitor;\nimport io.noties.markwon.SpannableBuilder;\nimport com.fluid.afm.span.AntUnderlineSupportMulLinesSpan;\nimport io.noties.markwon.html.HtmlTag;\nimport io.noties.markwon.html.MarkwonHtmlRenderer;\nimport io.noties.markwon.html.TagHandler;\n\npublic class UnderlineHandler extends TagHandler {\n\n    @Override\n    public void handle(\n            @NonNull MarkwonVisitor visitor,\n            @NonNull MarkwonHtmlRenderer renderer,\n            @NonNull HtmlTag tag) {\n\n        // as parser doesn't treat U tag as an inline one,\n        // thus doesn't allow children, we must visit them first\n\n        if (tag.isBlock()) {\n            visitChildren(visitor, renderer, tag.getAsBlock());\n        }\n        UnderlineStyle style = visitor.configuration().theme().underlineStyle();\n        if (style != null && style.getColor() != 0 && style.getHeight() > 0) {\n            SpannableBuilder.setSpans(\n                    visitor.builder(),\n                    new AntUnderlineSupportMulLinesSpan(style.getColor(), style.getHeight()),\n                    tag.start(),\n                    tag.end()\n            );\n        } else {\n            SpannableBuilder.setSpans(\n                    visitor.builder(),\n                    new UnderlineSpan(),\n                    tag.start(),\n                    tag.end()\n            );\n        }\n    }\n\n    @NonNull\n    @Override\n    public Collection<String> supportedTags() {\n        return Arrays.asList(\"u\", \"ins\");\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-html/src/test/java/io/noties/markwon/html/ExampleUnitTest.java",
    "content": "package io.noties.markwon.html;\n\nimport static org.junit.Assert.assertEquals;\n\nimport org.junit.Test;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "Android/AntFluid/markwon-image/.gitignore",
    "content": "/build"
  },
  {
    "path": "Android/AntFluid/markwon-image/build.gradle",
    "content": "plugins {\n    alias(libs.plugins.android.library)\n}\n\nandroid {\n    namespace 'io.noties.markwon.image'\n    compileSdk 35\n\n    defaultConfig {\n        minSdk 21\n\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n        consumerProguardFiles \"consumer-rules.pro\"\n    }\n\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n        }\n    }\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_11\n        targetCompatibility JavaVersion.VERSION_11\n    }\n}\n\ndependencies {\n\n    implementation libs.androidx.appcompat\n    compileOnly project(':markwon-core')\n    testImplementation libs.junit\n    androidTestImplementation libs.androidx.junit\n    androidTestImplementation libs.androidx.espresso.core\n}"
  },
  {
    "path": "Android/AntFluid/markwon-image/consumer-rules.pro",
    "content": ""
  },
  {
    "path": "Android/AntFluid/markwon-image/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile"
  },
  {
    "path": "Android/AntFluid/markwon-image/src/androidTest/java/io/noties/markwon/image/ExampleInstrumentedTest.java",
    "content": "package io.noties.markwon.image;\n\nimport static org.junit.Assert.assertEquals;\n\nimport android.content.Context;\n\nimport androidx.test.ext.junit.runners.AndroidJUnit4;\nimport androidx.test.platform.app.InstrumentationRegistry;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();\n        assertEquals(\"io.noties.markwon.image.test\", appContext.getPackageName());\n    }\n}"
  },
  {
    "path": "Android/AntFluid/markwon-image/src/main/AndroidManifest.xml",
    "content": "<manifest package=\"io.noties.markwon.image\">\n</manifest>\n"
  },
  {
    "path": "Android/AntFluid/markwon-image/src/main/java/com/fluid/afm/network/CircleDrawable.java",
    "content": "package com.fluid.afm.network;\n\nimport android.content.Context;\nimport android.graphics.Bitmap;\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport android.graphics.Paint;\nimport android.graphics.drawable.BitmapDrawable;\nimport android.graphics.drawable.Drawable;\n\npublic class CircleDrawable {\n\n    public static Drawable createCircleDrawable(Context context, int diameter) {\n        // Create a Bitmap with the specified diameter\n        Bitmap bitmap = Bitmap.createBitmap(diameter, diameter, Bitmap.Config.ARGB_8888);\n        Canvas canvas = new Canvas(bitmap);\n\n        // Create a Paint object to draw the circle\n        Paint paint = new Paint();\n        paint.setAntiAlias(true);\n        paint.setColor(Color.BLUE);\n\n        // Draw the circle\n        float radius = diameter / 2f;\n        canvas.drawCircle(radius, radius, radius, paint);\n\n        // Set up the Paint for the text\n        Paint textPaint = new Paint();\n        textPaint.setAntiAlias(true);\n        textPaint.setColor(Color.WHITE);\n        textPaint.setTextSize(radius); // Adjust text size as needed\n        textPaint.setTextAlign(Paint.Align.CENTER);\n\n        // Draw the \"1\" in the center of the circle\n        // Calculate Y position to center text vertically\n        float textY = radius - ((textPaint.descent() + textPaint.ascent()) / 2);\n        canvas.drawText(\"1\", radius, textY, textPaint);\n\n        // Return a Drawable from the Bitmap\n        return new BitmapDrawable(context.getResources(), bitmap);\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-image/src/main/java/com/fluid/afm/network/ImageLoaderSchemeHandler.java",
    "content": "package com.fluid.afm.network;\n\nimport android.content.Context;\nimport android.graphics.drawable.Drawable;\nimport android.net.Uri;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport java.io.IOException;\nimport java.lang.ref.WeakReference;\nimport java.util.Arrays;\nimport java.util.Collection;\n\nimport io.noties.markwon.image.ImageItem;\nimport io.noties.markwon.image.SchemeHandler;\nimport com.fluid.afm.utils.Utils;\n\npublic class ImageLoaderSchemeHandler extends SchemeHandler {\n    public static final String SCHEME_HTTP = \"http\";\n    public static final String SCHEME_HTTPS = \"https\";\n    private WeakReference<Context> mContextRef;\n\n    @NonNull\n    public static ImageLoaderSchemeHandler create(Context context) {\n        return new ImageLoaderSchemeHandler(context);\n    }\n\n    @SuppressWarnings(\"WeakerAccess\")\n    ImageLoaderSchemeHandler(Context context) {\n        mContextRef = new WeakReference<>(context);\n    }\n\n    @NonNull\n    @Override\n    public ImageItem handle(@NonNull String raw, @NonNull Uri uri, int width, int height) {\n\n        final ImageItem imageItem;\n        try {\n            Context context = mContextRef.get();\n            Drawable drawable = context == null ? null : Utils.loadImageSync(context, raw, width, height, null);\n            if (drawable != null){\n                imageItem = ImageItem.withResult(drawable);\n            }else {\n                throw new IOException(\"loadImageSync: null\" + \", url: \" + raw);\n            }\n\n        } catch (IOException | InterruptedException e) {\n            throw new IllegalStateException(\"Exception obtaining network resource: \" + raw, e);\n        }\n\n        return imageItem;\n    }\n\n    @NonNull\n    @Override\n    public Collection<String> supportedSchemes() {\n        return Arrays.asList(SCHEME_HTTP, SCHEME_HTTPS);\n    }\n\n    @Nullable\n    static String contentType(@Nullable String contentType) {\n\n        if (contentType == null) {\n            return null;\n        }\n\n        final int index = contentType.indexOf(';');\n        if (index > -1) {\n            return contentType.substring(0, index);\n        }\n\n        return contentType;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-image/src/main/java/io/noties/markwon/image/AsyncDrawableLoaderBuilder.java",
    "content": "package io.noties.markwon.image;\n\nimport android.util.Log;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.concurrent.ExecutorService;\n\nimport io.noties.markwon.image.data.DataUriSchemeHandler;\nimport io.noties.markwon.image.network.NetworkSchemeHandler;\nimport com.fluid.afm.utils.Utils;\n\nclass AsyncDrawableLoaderBuilder {\n\n    ExecutorService executorService;\n    final Map<String, SchemeHandler> schemeHandlers = new HashMap<>(3);\n    final Map<String, MediaDecoder> mediaDecoders = new HashMap<>(3);\n    MediaDecoder defaultMediaDecoder;\n    ImagesPlugin.PlaceholderProvider placeholderProvider;\n    ImagesPlugin.ErrorHandler errorHandler;\n\n    public static final String TAG = \"AsyncDrawableLoader\";\n\n    boolean isBuilt;\n\n    AsyncDrawableLoaderBuilder() {\n        Log.d(TAG,\"AsyncDrawableLoaderBuilder construct\");\n\n        // @since 4.0.0\n        // okay, let's add supported schemes at the start, this would be : data-uri and default network\n        // we should not use file-scheme as it's a bit complicated to assume file usage (lack of permissions)\n        addSchemeHandler(DataUriSchemeHandler.create());\n        addSchemeHandler(NetworkSchemeHandler.create());\n\n        // add SVG and GIF, but only if they are present in the class-path\n        // not support yet\n\n        defaultMediaDecoder = DefaultMediaDecoder.create();\n    }\n\n    void executorService(@NonNull ExecutorService executorService) {\n        checkState();\n        this.executorService = executorService;\n    }\n\n    void addSchemeHandler(@NonNull SchemeHandler schemeHandler) {\n        checkState();\n        for (String scheme : schemeHandler.supportedSchemes()) {\n            schemeHandlers.put(scheme, schemeHandler);\n        }\n    }\n\n    void addMediaDecoder(@NonNull MediaDecoder mediaDecoder) {\n        checkState();\n        for (String type : mediaDecoder.supportedTypes()) {\n            mediaDecoders.put(type, mediaDecoder);\n        }\n    }\n\n    void defaultMediaDecoder(@Nullable MediaDecoder mediaDecoder) {\n        checkState();\n        this.defaultMediaDecoder = mediaDecoder;\n    }\n\n    void removeSchemeHandler(@NonNull String scheme) {\n        checkState();\n        schemeHandlers.remove(scheme);\n    }\n\n    void removeMediaDecoder(@NonNull String contentType) {\n        checkState();\n        mediaDecoders.remove(contentType);\n    }\n\n    /**\n     * @since 3.0.0\n     */\n    void placeholderProvider(@NonNull ImagesPlugin.PlaceholderProvider placeholderDrawableProvider) {\n        checkState();\n        this.placeholderProvider = placeholderDrawableProvider;\n    }\n\n    /**\n     * @since 3.0.0\n     */\n    void errorHandler(@NonNull ImagesPlugin.ErrorHandler errorHandler) {\n        checkState();\n        this.errorHandler = errorHandler;\n    }\n\n    @NonNull\n    AsyncDrawableLoader build() {\n\n        Log.d(TAG,\"build\");\n        checkState();\n\n        isBuilt = true;\n\n        if (executorService == null) {\n            executorService = Utils.acquireNormalThreadPoolExecutor();\n        }\n\n        return new AsyncDrawableLoaderImpl(this);\n    }\n\n    private void checkState() {\n//        if (isBuilt) {\n//            throw new IllegalStateException(\"ImagesPlugin has already been configured \" +\n//                    \"and cannot be modified any further\");\n//        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-image/src/main/java/io/noties/markwon/image/AsyncDrawableLoaderImpl.java",
    "content": "package io.noties.markwon.image;\n\nimport android.graphics.Bitmap;\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport android.graphics.Paint;\nimport android.graphics.PorterDuff;\nimport android.graphics.PorterDuffXfermode;\nimport android.graphics.Rect;\nimport android.graphics.RectF;\nimport android.graphics.drawable.BitmapDrawable;\nimport android.graphics.drawable.Drawable;\nimport android.net.Uri;\nimport android.os.Handler;\nimport android.os.Looper;\nimport android.os.SystemClock;\nimport android.text.TextUtils;\nimport android.util.Log;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.VisibleForTesting;\n\nimport java.io.IOException;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Future;\n\nimport com.fluid.afm.utils.Utils;\n\nclass AsyncDrawableLoaderImpl extends AsyncDrawableLoader {\n\n    public static final String TAG = \"MD_AsyncDrawLoaderImpl\";\n    private final ExecutorService executorService;\n    private final Map<String, SchemeHandler> schemeHandlers;\n    private final Map<String, MediaDecoder> mediaDecoders;\n    private final MediaDecoder defaultMediaDecoder;\n    private final ImagesPlugin.PlaceholderProvider placeholderProvider;\n    private final ImagesPlugin.ErrorHandler errorHandler;\n\n    private final Handler handler;\n\n    // @since 4.0.0 use a hash-map with a AsyncDrawable as key for multiple requests\n    //  for the same destination\n    private final Map<AsyncDrawable, Future<?>> requests = new HashMap<>(2);\n\n    AsyncDrawableLoaderImpl(@NonNull AsyncDrawableLoaderBuilder builder) {\n        this(builder, new Handler(Looper.getMainLooper()));\n        Log.d(TAG, \"AsyncDrawableLoaderImpl construct\");\n    }\n\n    // @since 4.0.0\n    @VisibleForTesting\n    AsyncDrawableLoaderImpl(@NonNull AsyncDrawableLoaderBuilder builder, @NonNull Handler handler) {\n        this.executorService = builder.executorService;\n        this.schemeHandlers = builder.schemeHandlers;\n        this.mediaDecoders = builder.mediaDecoders;\n        this.defaultMediaDecoder = builder.defaultMediaDecoder;\n        this.placeholderProvider = builder.placeholderProvider;\n        this.errorHandler = builder.errorHandler;\n        this.handler = handler;\n    }\n\n    @Override\n    public void load(@NonNull final AsyncDrawable drawable) {\n        Log.d(TAG, \"load drawable = \" + drawable);\n        final Future<?> future = requests.get(drawable);\n        if (future == null) {\n            requests.put(drawable, execute(drawable));\n        }\n    }\n\n    @Override\n    public void cancel(@NonNull final AsyncDrawable drawable) {\n\n        Log.d(TAG, \"cancel future\");\n        final Future<?> future = requests.remove(drawable);\n        if (future != null) {\n            future.cancel(true);\n        }\n\n        handler.removeCallbacksAndMessages(drawable);\n    }\n\n    @Nullable\n    @Override\n    public Drawable placeholder(@NonNull AsyncDrawable drawable) {\n        return placeholderProvider != null\n                ? placeholderProvider.providePlaceholder(drawable)\n                : null;\n    }\n\n    public Bitmap drawableToBitmap(Drawable drawable) {\n        if (drawable instanceof BitmapDrawable) {\n            return ((BitmapDrawable) drawable).getBitmap();\n        }\n\n        int width = drawable.getIntrinsicWidth();\n        int height = drawable.getIntrinsicHeight();\n        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);\n\n        Canvas canvas = new Canvas(bitmap);\n        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());\n        drawable.draw(canvas);\n\n        return bitmap;\n    }\n\n    @NonNull\n    private Future<?> execute(@NonNull final AsyncDrawable asyncDrawable) {\n        Log.d(TAG, \"execute\");\n        return executorService.submit(() -> {\n            String destination = asyncDrawable.getDestination();\n            Log.d(TAG, \"run destination = \" + destination);\n            final Uri uri = Uri.parse(destination);\n\n            Drawable drawable = null;\n            int canvasWidth = asyncDrawable.getLastKnownCanvasWidth();\n            if (canvasWidth == 0) {\n                canvasWidth = Utils.getScreenWidth();\n            }\n            int designedWidth = 638;\n            int designedHeight = 360;\n            float dpRatio = (float) canvasWidth / designedWidth;\n            int standardHeight = (int) (designedHeight * dpRatio);\n            try {\n                final String scheme = uri.getScheme();\n                if (TextUtils.isEmpty(scheme)) {\n                    throw new IllegalStateException(\"No scheme is found: \" + destination);\n                }\n\n                // obtain scheme handler\n                final SchemeHandler schemeHandler = schemeHandlers.get(scheme);\n                if (schemeHandler != null) {\n\n                    Log.d(TAG, \"schemeHandler.handle start \");\n                    // handle scheme\n                    final ImageItem imageItem = schemeHandler.handle(destination, uri, canvasWidth, standardHeight);\n\n                    Log.d(TAG, \"schemeHandler.handle finish \");\n                    // if resulting imageItem needs further decoding -> proceed\n                    if (imageItem.hasDecodingNeeded()) {\n\n                        final ImageItem.WithDecodingNeeded withDecodingNeeded = imageItem.getAsWithDecodingNeeded();\n\n                        // @since 4.6.2 close input stream\n                        try {\n                            MediaDecoder mediaDecoder = mediaDecoders.get(withDecodingNeeded.contentType());\n                            Log.d(TAG, \"mediaDecoder = \" + mediaDecoder + \" withDecodingNeeded.contentType() = \" + withDecodingNeeded.contentType());\n\n                            if (mediaDecoder == null) {\n                                mediaDecoder = defaultMediaDecoder;\n                            }\n\n                            if (mediaDecoder != null) {\n                                drawable = mediaDecoder.decode(withDecodingNeeded.contentType(), withDecodingNeeded.inputStream());\n                            } else {\n                                // throw that no media decoder is found\n                                throw new IllegalStateException(\"No media-decoder is found: \" + destination);\n                            }\n                        } finally {\n                            try {\n                                withDecodingNeeded.inputStream().close();\n                            } catch (IOException e) {\n                                Log.e(\"MARKWON-IMAGE\", \"Error closing inputStream\", e);\n                            }\n                        }\n                    } else {\n                        Log.d(TAG, \"getAsWithResult result\");\n                        drawable = imageItem.getAsWithResult().result();\n                    }\n                } else {\n                    // throw no scheme handler is available\n                    throw new IllegalStateException(\"No scheme-handler is found: \" + destination);\n                }\n\n            } catch (Throwable t) {\n                if (errorHandler != null) {\n                    drawable = errorHandler.handleError(destination, t);\n                } else {\n                    // else simply log the error\n                    Log.e(\"MARKWON-IMAGE\", \"Error loading image: \" + destination, t);\n                }\n            }\n\n            Log.d(TAG, \"asyncDrawable.getLastKnownCanvasWidth() = \" + asyncDrawable.getLastKnownCanvasWidth());\n\n            int designedMinWidthForHeightOverWidth = 270;\n            int rawWidth = drawable.getIntrinsicWidth();\n            int rawHeight = drawable.getIntrinsicHeight();\n            int minWidthForHeightOverWidth = (int) ((designedMinWidthForHeightOverWidth / 2) * dpRatio);\n            Bitmap bitmap = drawableToBitmap(drawable);\n            Bitmap corpedBgBitmap = scaleAndCropCenter(bitmap, canvasWidth, standardHeight);\n            if (rawWidth < rawHeight) {\n                Bitmap transparentBitmap = setBitmapTransparency(corpedBgBitmap, 128);\n                Bitmap fgBitmap = scaleAndCropHeightOverWidthBitmap(bitmap, standardHeight, minWidthForHeightOverWidth);\n                Bitmap combineBitmap = overlayBitmaps(transparentBitmap, fgBitmap);\n                Bitmap output = getRoundedCornerBitmap(combineBitmap, 24);\n                drawable = new BitmapDrawable(null, output);\n            } else {\n                Bitmap output = getRoundedCornerBitmap(corpedBgBitmap, 24);\n                drawable = new BitmapDrawable(null, output);\n            }\n\n            final Drawable out = drawable;\n\n            // @since 4.0.0 apply intrinsic bounds (but only if they are empty)\n            if (out != null) {\n                final Rect bounds = out.getBounds();\n                //noinspection ConstantConditions\n                if (bounds == null\n                        || bounds.isEmpty()) {\n                    DrawableUtils.applyIntrinsicBounds(out);\n                }\n            }\n\n            Log.d(TAG, \"SystemClock.uptimeMillis() = \" + SystemClock.uptimeMillis());\n            handler.postAtTime(new Runnable() {\n                @Override\n                public void run() {\n                    Log.d(TAG, \"postAtTime asyncDrawable Destination = \" + asyncDrawable.getDestination());\n                    // validate that\n                    // * request was not cancelled\n                    // * out-result is present\n                    // * async-drawable is attached\n                    final Future<?> future = requests.remove(asyncDrawable);\n                    Log.d(TAG, \"future = \" + future + \" out = \" + out + \" asyncDrawable.isAttached() =\" + asyncDrawable.isAttached());\n\n                    if (future != null\n                            && out != null\n                            && asyncDrawable.isAttached()) {\n                        Log.d(TAG, \"asyncDrawable.setResult(out)\");\n                        asyncDrawable.setResult(out);\n                    }\n                }\n            }, asyncDrawable, SystemClock.uptimeMillis());\n        });\n    }\n\n    public Bitmap setBitmapTransparency(Bitmap bitmap, int alpha) {\n        Bitmap transparentBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);\n        Canvas canvas = new Canvas(transparentBitmap);\n        Paint paint = new Paint();\n        paint.setAlpha(alpha);\n        canvas.drawBitmap(bitmap, 0, 0, paint);\n        return transparentBitmap;\n    }\n\n    public Bitmap overlayBitmaps(Bitmap background, Bitmap overlay) {\n        Bitmap overlayBitmap = Bitmap.createBitmap(background.getWidth(), background.getHeight(), background.getConfig());\n        Canvas canvas = new Canvas(overlayBitmap);\n        canvas.drawBitmap(background, 0, 0, null);\n\n        // 计算叠加图片的左上角坐标，使其居中\n        int left = (background.getWidth() - overlay.getWidth()) / 2;\n        int top = (background.getHeight() - overlay.getHeight()) / 2;\n\n        // 绘制叠加图片\n        canvas.drawBitmap(overlay, left, top, null);\n        return overlayBitmap;\n    }\n\n    public Bitmap scaleAndCropCenter(Bitmap srcBitmap, int targetWidth, int targetHeight) {\n        if (srcBitmap == null) return null;\n\n        // 计算宽高比例\n        float srcWidth = srcBitmap.getWidth();\n        float srcHeight = srcBitmap.getHeight();\n\n        float widthRatio = targetWidth / srcWidth;\n        float heightRatio = targetHeight / srcHeight;\n\n        // 选择较大的缩放比例\n        float scale = Math.max(widthRatio, heightRatio);\n\n        // 计算缩放后的宽高\n        int scaledWidth = Math.round(srcWidth * scale);\n        int scaledHeight = Math.round(srcHeight * scale);\n\n        // 缩放图片\n        Bitmap scaledBitmap = Bitmap.createScaledBitmap(srcBitmap, scaledWidth, scaledHeight, true);\n\n        // 计算图片居中裁剪的起始点\n        int xOffset = (scaledWidth - targetWidth) / 2;\n        int yOffset = (scaledHeight - targetHeight) / 2;\n\n        // 裁剪出目标区域\n        Bitmap croppedBitmap = Bitmap.createBitmap(scaledBitmap, xOffset, yOffset, targetWidth, targetHeight);\n\n        // 如果缩放图片与原图不同，则回收中间产生的 Bitmap\n        if (scaledBitmap != srcBitmap) {\n            scaledBitmap.recycle();\n        }\n\n        return croppedBitmap;\n    }\n\n    public Bitmap scaleAndCropHeightOverWidthBitmap(Bitmap bitmap, int fixedHeight, int minWidth) {\n        int imgWidth = bitmap.getWidth();\n        int imgHeight = bitmap.getHeight();\n\n        // 计算缩放比例\n        float scale = Math.max((float) fixedHeight / imgHeight, (float) minWidth / imgWidth);\n\n        // 新的宽高\n        int newWidth = Math.round(imgWidth * scale);\n        int newHeight = Math.round(imgHeight * scale);\n\n        // 缩放图片\n        Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);\n\n        // 居中裁剪图片\n        int xCrop = (newWidth - minWidth) / 2;\n        int yCrop = (newHeight - fixedHeight) / 2;\n\n        return Bitmap.createBitmap(scaledBitmap, xCrop, yCrop, minWidth, fixedHeight);\n    }\n\n    public Bitmap getRoundedCornerBitmap(Bitmap bitmap, int cornerRadius) {\n        // 保持原始位图大小\n        int width = bitmap.getWidth();\n        int height = bitmap.getHeight();\n\n        // 创建一个输出Bitmap\n        Bitmap output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);\n        // 创建一个画布，这样我们就可以在其上绘制形状\n        Canvas canvas = new Canvas(output);\n        // 设置抗锯齿\n        final Paint paint = new Paint();\n        paint.setAntiAlias(true);\n        paint.setFilterBitmap(true);\n        paint.setDither(true);\n\n        // 绘制一个圆角矩形作为底层\n        Rect rect = new Rect(0, 0, width, height);\n        RectF rectF = new RectF(rect);\n\n        // 填充圆角矩形并剪裁画布\n        paint.setColor(Color.BLACK);\n        canvas.drawRoundRect(rectF, cornerRadius, cornerRadius, paint);\n\n        // 使用 \"SRC_IN\" 模式，绘制原始位图到画布上，这样只会显示在圆角区域的部分\n        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));\n        canvas.drawBitmap(bitmap, rect, rect, paint);\n\n        return output;\n    }\n\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-image/src/main/java/io/noties/markwon/image/DefaultDownScalingMediaDecoder.java",
    "content": "package io.noties.markwon.image;\n\nimport android.content.res.Resources;\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapFactory;\nimport android.graphics.drawable.BitmapDrawable;\nimport android.graphics.drawable.Drawable;\nimport android.util.Log;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport java.io.BufferedInputStream;\nimport java.io.BufferedOutputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport java.io.FileOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.util.Collection;\nimport java.util.Collections;\n\n/**\n * A {@link MediaDecoder} that additionally process media resource to optionally\n * scale it down to fit specified maximum values. Should be used to ensure that no exception is raised\n * whilst rendering ({@code Canvas: trying to draw too large(Xbytes) bitmap}) or {@code OutOfMemoryException} is thrown.\n *\n * <strong>NB</strong> this media decoder will create a temporary file for each incoming media resource,\n * which can have a performance penalty (IO)\n *\n * @since 4.6.2\n */\npublic class DefaultDownScalingMediaDecoder extends MediaDecoder {\n\n    public static final String TAG = \"DownScalingMediaDecoder\";\n\n    /**\n     * Values {@code <= 0} are ignored, a dimension is considered to be not restrained any limit in such case\n     */\n    @NonNull\n    public static DefaultDownScalingMediaDecoder create(int maxWidth, int maxHeight) {\n        return create(Resources.getSystem(), maxWidth, maxHeight);\n    }\n\n    @NonNull\n    public static DefaultDownScalingMediaDecoder create(\n            @NonNull Resources resources,\n            int maxWidth,\n            int maxHeight\n    ) {\n        return new DefaultDownScalingMediaDecoder(resources, maxWidth, maxHeight);\n    }\n\n    private final Resources resources;\n    private final int maxWidth;\n    private final int maxHeight;\n\n    private DefaultDownScalingMediaDecoder(@NonNull Resources resources, int maxWidth, int maxHeight) {\n        this.resources = resources;\n        this.maxWidth = maxWidth;\n        this.maxHeight = maxHeight;\n    }\n\n    // https://android.jlelse.eu/loading-large-bitmaps-efficiently-in-android-66826cd4ad53\n    @NonNull\n    @Override\n    public Drawable decode(@Nullable String contentType, @NonNull InputStream inputStream) {\n\n        Log.d(TAG,\"DefaultDownScalingMediaDecoder decode \");\n        final File file = writeToTempFile(inputStream);\n        try {\n\n            final BitmapFactory.Options options = new BitmapFactory.Options();\n            options.inJustDecodeBounds = true;\n\n            // initial result when obtaining bounds is discarded\n            decode(file, options);\n\n            options.inSampleSize = calculateInSampleSize(options, maxWidth, maxHeight);\n            options.inJustDecodeBounds = false;\n\n            final Bitmap bitmap = decode(file, options);\n            return new BitmapDrawable(resources, bitmap);\n        } finally {\n            // we no longer need the temporary file\n            //noinspection ResultOfMethodCallIgnored\n            file.delete();\n        }\n    }\n\n    @NonNull\n    private static File writeToTempFile(@NonNull InputStream inputStream) {\n        final File file;\n        try {\n            file = File.createTempFile(\"markwon\", null);\n        } catch (IOException e) {\n            throw new IllegalStateException(e);\n        }\n\n        final OutputStream outputStream;\n        try {\n            outputStream = new BufferedOutputStream(new FileOutputStream(file, false));\n        } catch (FileNotFoundException e) {\n            throw new IllegalStateException(e);\n        }\n\n        final byte[] buffer = new byte[1024 * 8];\n        int length;\n        try {\n            while ((length = inputStream.read(buffer)) > 0) {\n                outputStream.write(buffer, 0, length);\n            }\n        } catch (IOException e) {\n            throw new IllegalStateException(e);\n        } finally {\n            try {\n                outputStream.close();\n            } catch (IOException e) {\n                // ignored\n            }\n        }\n\n        return file;\n    }\n\n    @Nullable\n    private static Bitmap decode(@NonNull File file, @NonNull BitmapFactory.Options options) {\n        final InputStream is = readFile(file);\n        // not yet, still min SDK is 16\n        try {\n            return BitmapFactory.decodeStream(is, null, options);\n        } finally {\n            try {\n                is.close();\n            } catch (IOException e) {\n                // ignored\n            }\n        }\n    }\n\n\n    @NonNull\n    private static InputStream readFile(@NonNull File file) {\n        try {\n            return new BufferedInputStream(new FileInputStream(file));\n        } catch (FileNotFoundException e) {\n            throw new IllegalStateException(e);\n        }\n    }\n\n    // see: https://developer.android.com/topic/performance/graphics/load-bitmap.html#load-bitmap\n    private static int calculateInSampleSize(@NonNull BitmapFactory.Options options, int maxWidth, int maxHeight) {\n        final int w = options.outWidth;\n        final int h = options.outHeight;\n\n        final boolean hasMaxWidth = maxWidth > 0;\n        final boolean hasMaxHeight = maxHeight > 0;\n\n        final int inSampleSize;\n        if (hasMaxWidth && hasMaxHeight) {\n            // minimum of both\n            inSampleSize = Math.min(calculateInSampleSize(w, maxWidth), calculateInSampleSize(h, maxHeight));\n        } else if (hasMaxWidth) {\n            inSampleSize = calculateInSampleSize(w, maxWidth);\n        } else if (hasMaxHeight) {\n            inSampleSize = calculateInSampleSize(h, maxHeight);\n        } else {\n            // else no sampling, as we have no dimensions to base our calculations on\n            inSampleSize = 1;\n        }\n\n        return inSampleSize;\n    }\n\n    private static int calculateInSampleSize(int actual, int max) {\n        int inSampleSize = 1;\n        final int half = actual / 2;\n        while ((half / inSampleSize) > max) {\n            inSampleSize *= 2;\n        }\n        return inSampleSize;\n    }\n\n    @NonNull\n    @Override\n    public Collection<String> supportedTypes() {\n        return Collections.emptySet();\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-image/src/main/java/io/noties/markwon/image/DefaultMediaDecoder.java",
    "content": "package io.noties.markwon.image;\n\nimport android.content.res.Resources;\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapFactory;\nimport android.graphics.drawable.BitmapDrawable;\nimport android.graphics.drawable.Drawable;\nimport android.util.Log;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport java.io.InputStream;\nimport java.util.Collection;\nimport java.util.Collections;\n\n/**\n * This class can be used as the last {@link MediaDecoder} to _try_ to handle all rest cases.\n * Here we just assume that supplied InputStream is of image type and try to decode it.\n *\n * <strong>NB</strong> if you are dealing with big images that require down scaling see {@link DefaultDownScalingMediaDecoder}\n * which additionally down scales displayed images.\n *\n * @see DefaultDownScalingMediaDecoder\n * @since 1.1.0\n */\npublic class DefaultMediaDecoder extends MediaDecoder {\n\n    public static final String TAG = \"DefaultMediaDecoder\";\n\n    @NonNull\n    public static DefaultMediaDecoder create() {\n        return new DefaultMediaDecoder(Resources.getSystem());\n    }\n\n    @NonNull\n    public static DefaultMediaDecoder create(@NonNull Resources resources) {\n        return new DefaultMediaDecoder(resources);\n    }\n\n    private final Resources resources;\n\n    @SuppressWarnings(\"WeakerAccess\")\n    DefaultMediaDecoder(Resources resources) {\n        this.resources = resources;\n    }\n\n    @NonNull\n    @Override\n    public Drawable decode(@Nullable String contentType, @NonNull InputStream inputStream) {\n        Log.d(TAG,\"DefaultMediaDecoder decode\");\n\n        final Bitmap bitmap;\n        try {\n            // absolutely not optimal... thing\n            bitmap = BitmapFactory.decodeStream(inputStream);\n        } catch (Throwable t) {\n            throw new IllegalStateException(\"Exception decoding input-stream\", t);\n        }\n\n        return new BitmapDrawable(resources, bitmap);\n    }\n\n    @NonNull\n    @Override\n    public Collection<String> supportedTypes() {\n        return Collections.emptySet();\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-image/src/main/java/io/noties/markwon/image/ImageItem.java",
    "content": "package io.noties.markwon.image;\n\nimport android.graphics.drawable.Drawable;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport java.io.InputStream;\n\n/**\n * @since 2.0.0\n */\npublic abstract class ImageItem {\n\n    /**\n     * Create an {@link ImageItem} with result, so no further decoding is required.\n     *\n     * @see #withDecodingNeeded(String, InputStream)\n     * @see WithResult\n     * @since 4.0.0\n     */\n    @NonNull\n    public static ImageItem withResult(@NonNull Drawable drawable) {\n        return new WithResult(drawable);\n    }\n\n    /**\n     * Create an {@link ImageItem} that requires further decoding of InputStream.\n     *\n     * @see #withResult(Drawable)\n     * @see WithDecodingNeeded\n     * @since 4.0.0\n     */\n    @NonNull\n    public static ImageItem withDecodingNeeded(\n            @Nullable String contentType,\n            @NonNull InputStream inputStream) {\n        return new WithDecodingNeeded(contentType, inputStream);\n    }\n\n\n    private ImageItem() {\n    }\n\n    /**\n     * @since 4.0.0\n     */\n    public abstract boolean hasResult();\n\n    /**\n     * @since 4.0.0\n     */\n    public abstract boolean hasDecodingNeeded();\n\n    /**\n     * @see #hasResult()\n     * @since 4.0.0\n     */\n    @NonNull\n    public abstract WithResult getAsWithResult();\n\n    /**\n     * @see #hasDecodingNeeded()\n     * @since 4.0.0\n     */\n    @NonNull\n    public abstract WithDecodingNeeded getAsWithDecodingNeeded();\n\n    /**\n     * @since 4.0.0\n     */\n    public static class WithResult extends ImageItem {\n\n        private final Drawable result;\n\n        private WithResult(@NonNull Drawable drawable) {\n            result = drawable;\n        }\n\n        @NonNull\n        public Drawable result() {\n            return result;\n        }\n\n        @Override\n        public boolean hasResult() {\n            return true;\n        }\n\n        @Override\n        public boolean hasDecodingNeeded() {\n            return false;\n        }\n\n        @NonNull\n        @Override\n        public WithResult getAsWithResult() {\n            return this;\n        }\n\n        @NonNull\n        @Override\n        public WithDecodingNeeded getAsWithDecodingNeeded() {\n            throw new IllegalStateException();\n        }\n    }\n\n    /**\n     * @since 4.0.0\n     */\n    public static class WithDecodingNeeded extends ImageItem {\n\n        private final String contentType;\n        private final InputStream inputStream;\n\n        private WithDecodingNeeded(\n                @Nullable String contentType,\n                @NonNull InputStream inputStream) {\n            this.contentType = contentType;\n            this.inputStream = inputStream;\n        }\n\n        @Nullable\n        public String contentType() {\n            return contentType;\n        }\n\n        @NonNull\n        public InputStream inputStream() {\n            return inputStream;\n        }\n\n        @Override\n        public boolean hasResult() {\n            return false;\n        }\n\n        @Override\n        public boolean hasDecodingNeeded() {\n            return true;\n        }\n\n        @NonNull\n        @Override\n        public WithResult getAsWithResult() {\n            throw new IllegalStateException();\n        }\n\n        @NonNull\n        @Override\n        public WithDecodingNeeded getAsWithDecodingNeeded() {\n            return this;\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-image/src/main/java/io/noties/markwon/image/ImagesPlugin.java",
    "content": "package io.noties.markwon.image;\n\nimport android.graphics.drawable.Drawable;\nimport android.text.Spanned;\nimport android.util.Log;\nimport android.widget.TextView;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.annotation.VisibleForTesting;\n\nimport org.commonmark.node.Image;\n\nimport java.util.concurrent.ExecutorService;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\nimport io.noties.markwon.AbstractMarkwonPlugin;\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.markwon.MarkwonPlugin;\nimport io.noties.markwon.MarkwonSpansFactory;\nimport com.fluid.afm.StreamOutStateObserver;\nimport com.fluid.afm.func.IImageClickCallback;\n\nimport io.noties.markwon.image.data.DataUriSchemeHandler;\nimport io.noties.markwon.image.file.FileSchemeHandler;\nimport io.noties.markwon.image.network.NetworkSchemeHandler;\n\n@SuppressWarnings({\"UnusedReturnValue\", \"WeakerAccess\"})\npublic class ImagesPlugin extends AbstractMarkwonPlugin implements StreamOutStateObserver {\n\n    public static final String TAG = \"MD_ImagesPlugin\";\n    public ImageSpanFactory imageSpanFactory;\n\n    @Override\n    public void onStreamOutStateChanged(boolean isStreamingOutput) {\n        imageSpanFactory.onStreamOutStateChanged(isStreamingOutput);\n    }\n\n    /**\n     * @since 4.0.0\n     */\n    public interface ImagesConfigure {\n        void configureImages(@NonNull ImagesPlugin plugin);\n    }\n\n    /**\n     * @since 4.0.0\n     */\n    public interface PlaceholderProvider {\n        @Nullable\n        Drawable providePlaceholder(@NonNull AsyncDrawable drawable);\n    }\n\n    /**\n     * @since 4.0.0\n     */\n    public interface ErrorHandler {\n\n        /**\n         * Can optionally return a Drawable that will be displayed in case of an error\n         */\n        @Nullable\n        Drawable handleError(@NonNull String url, @NonNull Throwable throwable);\n    }\n\n    /**\n     * Factory method to create an empty {@link ImagesPlugin} instance with no {@link SchemeHandler}s\n     * nor {@link MediaDecoder}s registered. Can be used to further configure via instance methods or\n     * via {@link MarkwonPlugin#configure(Registry)}\n     *\n     */\n    @NonNull\n    public static ImagesPlugin create() {\n        return new ImagesPlugin();\n    }  @NonNull\n    public static ImagesPlugin create(IImageClickCallback clickCallback) {\n        return new ImagesPlugin(clickCallback);\n    }\n\n\n    @NonNull\n    public static ImagesPlugin create(@NonNull ImagesConfigure configure) {\n        final ImagesPlugin plugin = new ImagesPlugin();\n        configure.configureImages(plugin);\n        return plugin;\n    }\n\n    private final AsyncDrawableLoaderBuilder builder;\n\n    // @since 4.0.0\n    ImagesPlugin() {\n        this(new AsyncDrawableLoaderBuilder());\n        imageSpanFactory = new ImageSpanFactory();\n    }\n    ImagesPlugin(IImageClickCallback callback) {\n        this(new AsyncDrawableLoaderBuilder());\n        imageSpanFactory = new ImageSpanFactory();\n        imageSpanFactory.setImageCallback(callback);\n    }\n\n    // @since 4.0.0\n    @VisibleForTesting\n    ImagesPlugin(@NonNull AsyncDrawableLoaderBuilder builder) {\n        this.builder = builder;\n    }\n\n    /**\n     * Optional (by default new cached thread executor will be used)\n     *\n     * @since 4.0.0\n     */\n    @NonNull\n    public ImagesPlugin executorService(@NonNull ExecutorService executorService) {\n        builder.executorService(executorService);\n        return this;\n    }\n\n    /**\n     * @see SchemeHandler\n     * @see DataUriSchemeHandler\n     * @see FileSchemeHandler\n     * @see NetworkSchemeHandler\n     * @since 4.0.0\n     */\n    @NonNull\n    public ImagesPlugin addSchemeHandler(@NonNull SchemeHandler schemeHandler) {\n        builder.addSchemeHandler(schemeHandler);\n        return this;\n    }\n\n    /**\n     * @see DefaultMediaDecoder\n     * @since 4.0.0\n     */\n    @NonNull\n    public ImagesPlugin addMediaDecoder(@NonNull MediaDecoder mediaDecoder) {\n        builder.addMediaDecoder(mediaDecoder);\n        return this;\n    }\n\n    /**\n     * Please note that if not specified a {@link DefaultMediaDecoder} will be used. So\n     * if you need to disable default-image-media-decoder specify here own no-op implementation or null.\n     *\n     * @see DefaultMediaDecoder\n     * @since 4.0.0\n     */\n    @NonNull\n    public ImagesPlugin defaultMediaDecoder(@Nullable MediaDecoder mediaDecoder) {\n        builder.defaultMediaDecoder(mediaDecoder);\n        return this;\n    }\n\n    /**\n     * @since 4.0.0\n     */\n    @NonNull\n    public ImagesPlugin removeSchemeHandler(@NonNull String scheme) {\n        builder.removeSchemeHandler(scheme);\n        return this;\n    }\n\n\n    @NonNull\n    @Override\n    public String processMarkdown(@NonNull String markdown) {\n        //正则识别未闭合的图片标签![\n        Pattern pattern = Pattern.compile(\"!\\\\[.*?\\\\]\\\\([^)]*$|!\\\\[[^\\\\]]*$|!\\\\[[^\\\\]]*\\\\]$\");\n        Matcher matcher = pattern.matcher(markdown);\n        // 替换为空的图片，此时展示占位\n        String result = matcher.replaceAll(\"![]()\");\n        return result;\n    }\n\n    /**\n     * @since 4.0.0\n     */\n    @NonNull\n    public ImagesPlugin removeMediaDecoder(@NonNull String contentType) {\n        builder.removeMediaDecoder(contentType);\n        return this;\n    }\n\n    /**\n     * @since 4.0.0\n     */\n    @NonNull\n    public ImagesPlugin placeholderProvider(@NonNull PlaceholderProvider placeholderProvider) {\n        builder.placeholderProvider(placeholderProvider);\n        return this;\n    }\n\n    /**\n     * @see ErrorHandler\n     * @since 4.0.0\n     */\n    @NonNull\n    public ImagesPlugin errorHandler(@NonNull ErrorHandler errorHandler) {\n        builder.errorHandler(errorHandler);\n        return this;\n    }\n\n    @Override\n    public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) {\n        Log.d(TAG,\"configureConfiguration\");\n        builder.asyncDrawableLoader(this.builder.build());\n    }\n\n    @Override\n    public void configureSpansFactory(@NonNull MarkwonSpansFactory.Builder builder) {\n        Log.d(TAG,\"configureSpansFactory\");\n        builder.setFactory(Image.class, imageSpanFactory);\n    }\n\n    @Override\n    public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) {\n        AsyncDrawableScheduler.unschedule(textView);\n    }\n\n    @Override\n    public void afterSetText(@NonNull TextView textView) {\n        AsyncDrawableScheduler.schedule(textView);\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-image/src/main/java/io/noties/markwon/image/MediaDecoder.java",
    "content": "package io.noties.markwon.image;\n\nimport android.graphics.drawable.Drawable;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport java.io.InputStream;\nimport java.util.Collection;\n\n/**\n * @since 3.0.0\n */\npublic abstract class MediaDecoder {\n\n    /**\n     * Changes since 4.0.0:\n     * <ul>\n     * <li>Returns `non-null` drawable</li>\n     * <li>Added `contentType` method parameter</li>\n     * </ul>\n     */\n    @NonNull\n    public abstract Drawable decode(\n            @Nullable String contentType,\n            @NonNull InputStream inputStream\n    );\n\n    /**\n     * @since 4.0.0\n     */\n    @NonNull\n    public abstract Collection<String> supportedTypes();\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-image/src/main/java/io/noties/markwon/image/SchemeHandler.java",
    "content": "package io.noties.markwon.image;\n\nimport android.net.Uri;\n\nimport androidx.annotation.NonNull;\n\nimport java.util.Collection;\n\n/**\n * @since 3.0.0\n */\npublic abstract class SchemeHandler {\n\n    /**\n     * Changes since 4.0.0:\n     * <ul>\n     * <li>Returns `non-null` image-item</li>\n     * </ul>\n     *\n     * @see ImageItem#withResult(android.graphics.drawable.Drawable)\n     * @see ImageItem#withDecodingNeeded(String, java.io.InputStream)\n     */\n    @NonNull\n    public abstract ImageItem handle(@NonNull String raw, @NonNull Uri uri, int width, int height);\n\n    /**\n     * @since 4.0.0\n     */\n    @NonNull\n    public abstract Collection<String> supportedSchemes();\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-image/src/main/java/io/noties/markwon/image/data/DataUri.java",
    "content": "package io.noties.markwon.image.data;\n\nimport androidx.annotation.Nullable;\n\npublic class DataUri {\n\n    private final String contentType;\n    private final boolean base64;\n    private final String data;\n\n    public DataUri(@Nullable String contentType, boolean base64, @Nullable String data) {\n        this.contentType = contentType;\n        this.base64 = base64;\n        this.data = data;\n    }\n\n    @Nullable\n    public String contentType() {\n        return contentType;\n    }\n\n    public boolean base64() {\n        return base64;\n    }\n\n    @Nullable\n    public String data() {\n        return data;\n    }\n\n    @Override\n    public String toString() {\n        return \"DataUri{\" +\n                \"contentType='\" + contentType + '\\'' +\n                \", base64=\" + base64 +\n                \", data='\" + data + '\\'' +\n                '}';\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        DataUri dataUri = (DataUri) o;\n\n        if (base64 != dataUri.base64) return false;\n        if (contentType != null ? !contentType.equals(dataUri.contentType) : dataUri.contentType != null)\n            return false;\n        return data != null ? data.equals(dataUri.data) : dataUri.data == null;\n    }\n\n    @Override\n    public int hashCode() {\n        int result = contentType != null ? contentType.hashCode() : 0;\n        result = 31 * result + (base64 ? 1 : 0);\n        result = 31 * result + (data != null ? data.hashCode() : 0);\n        return result;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-image/src/main/java/io/noties/markwon/image/data/DataUriDecoder.java",
    "content": "package io.noties.markwon.image.data;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport android.text.TextUtils;\nimport android.util.Base64;\n\npublic abstract class DataUriDecoder {\n\n    @Nullable\n    public abstract byte[] decode(@NonNull DataUri dataUri) throws Throwable;\n\n    @NonNull\n    public static DataUriDecoder create() {\n        return new Impl();\n    }\n\n    static class Impl extends DataUriDecoder {\n\n        private static final String CHARSET = \"UTF-8\";\n\n        @Nullable\n        @Override\n        public byte[] decode(@NonNull DataUri dataUri) throws Throwable {\n\n            final String data = dataUri.data();\n\n            if (!TextUtils.isEmpty(data)) {\n                if (dataUri.base64()) {\n                    return Base64.decode(data.getBytes(CHARSET), Base64.DEFAULT);\n                } else {\n                    return data.getBytes(CHARSET);\n                }\n            } else {\n                return null;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-image/src/main/java/io/noties/markwon/image/data/DataUriParser.java",
    "content": "package io.noties.markwon.image.data;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\npublic abstract class DataUriParser {\n\n    @Nullable\n    public abstract DataUri parse(@NonNull String input);\n\n\n    @NonNull\n    public static DataUriParser create() {\n        return new Impl();\n    }\n\n    static class Impl extends DataUriParser {\n\n        @Nullable\n        @Override\n        public DataUri parse(@NonNull String input) {\n\n            final int index = input.indexOf(',');\n            // we expect exactly one comma\n            if (index < 0) {\n                return null;\n            }\n\n            final String contentType;\n            final boolean base64;\n\n            if (index > 0) {\n                final String part = input.substring(0, index);\n                final String[] parts = part.split(\";\");\n                final int length = parts.length;\n                if (length > 0) {\n                    // if one: either content-type or base64\n                    if (length == 1) {\n                        final String value = parts[0];\n                        if (\"base64\".equals(value)) {\n                            contentType = null;\n                            base64 = true;\n                        } else {\n                            contentType = value.indexOf('/') > -1\n                                    ? value\n                                    : null;\n                            base64 = false;\n                        }\n                    } else {\n                        contentType = parts[0].indexOf('/') > -1\n                                ? parts[0]\n                                : null;\n                        base64 = \"base64\".equals(parts[length - 1]);\n                    }\n                } else {\n                    contentType = null;\n                    base64 = false;\n                }\n            } else {\n                contentType = null;\n                base64 = false;\n            }\n\n            final String data;\n            if (index < input.length()) {\n                final String value = input.substring(index + 1, input.length()).replaceAll(\"\\n\", \"\");\n                if (value.length() == 0) {\n                    data = null;\n                } else {\n                    data = value;\n                }\n            } else {\n                data = null;\n            }\n\n            return new DataUri(contentType, base64, data);\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-image/src/main/java/io/noties/markwon/image/data/DataUriSchemeHandler.java",
    "content": "package io.noties.markwon.image.data;\n\nimport android.net.Uri;\nimport androidx.annotation.NonNull;\n\nimport java.io.ByteArrayInputStream;\nimport java.util.Collection;\nimport java.util.Collections;\n\nimport io.noties.markwon.image.ImageItem;\nimport io.noties.markwon.image.SchemeHandler;\n\n/**\n * @since 2.0.0\n */\npublic class DataUriSchemeHandler extends SchemeHandler {\n\n    public static final String SCHEME = \"data\";\n\n    @NonNull\n    public static DataUriSchemeHandler create() {\n        return new DataUriSchemeHandler(DataUriParser.create(), DataUriDecoder.create());\n    }\n\n    private static final String START = \"data:\";\n\n    private final DataUriParser uriParser;\n    private final DataUriDecoder uriDecoder;\n\n    @SuppressWarnings(\"WeakerAccess\")\n    DataUriSchemeHandler(@NonNull DataUriParser uriParser, @NonNull DataUriDecoder uriDecoder) {\n        this.uriParser = uriParser;\n        this.uriDecoder = uriDecoder;\n    }\n\n    @NonNull\n    @Override\n    public ImageItem handle(@NonNull String raw, @NonNull Uri uri, int width, int height) {\n\n        if (!raw.startsWith(START)) {\n            throw new IllegalStateException(\"Invalid data-uri: \" + raw);\n        }\n\n        final String part = raw.substring(START.length());\n\n        final DataUri dataUri = uriParser.parse(part);\n        if (dataUri == null) {\n            throw new IllegalStateException(\"Invalid data-uri: \" + raw);\n        }\n\n        final byte[] bytes;\n        try {\n            bytes = uriDecoder.decode(dataUri);\n        } catch (Throwable t) {\n            throw new IllegalStateException(\"Cannot decode data-uri: \" + raw, t);\n        }\n\n        if (bytes == null) {\n            throw new IllegalStateException(\"Decoding data-uri failed: \" + raw);\n        }\n\n        return ImageItem.withDecodingNeeded(\n                dataUri.contentType(),\n                new ByteArrayInputStream(bytes));\n    }\n\n    @NonNull\n    @Override\n    public Collection<String> supportedSchemes() {\n        return Collections.singleton(SCHEME);\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-image/src/main/java/io/noties/markwon/image/file/FileSchemeHandler.java",
    "content": "package io.noties.markwon.image.file;\n\nimport android.content.Context;\nimport android.content.res.AssetManager;\nimport android.net.Uri;\nimport android.text.TextUtils;\nimport android.webkit.MimeTypeMap;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport java.io.BufferedInputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.List;\n\nimport io.noties.markwon.image.ImageItem;\nimport io.noties.markwon.image.SchemeHandler;\n\n/**\n * @since 3.0.0\n */\npublic class FileSchemeHandler extends SchemeHandler {\n\n    public static final String SCHEME = \"file\";\n\n    /**\n     * @see io.noties.markwon.image.destination.ImageDestinationProcessorAssets\n     */\n    @NonNull\n    public static FileSchemeHandler createWithAssets(@NonNull AssetManager assetManager) {\n        return new FileSchemeHandler(assetManager);\n    }\n\n    /**\n     * @see #createWithAssets(AssetManager)\n     * @see io.noties.markwon.image.destination.ImageDestinationProcessorAssets\n     * @since 4.0.0\n     */\n    @NonNull\n    public static FileSchemeHandler createWithAssets(@NonNull Context context) {\n        return new FileSchemeHandler(context.getAssets());\n    }\n\n    @NonNull\n    public static FileSchemeHandler create() {\n        return new FileSchemeHandler(null);\n    }\n\n    private static final String FILE_ANDROID_ASSETS = \"android_asset\";\n\n    @Nullable\n    private final AssetManager assetManager;\n\n    @SuppressWarnings(\"WeakerAccess\")\n    FileSchemeHandler(@Nullable AssetManager assetManager) {\n        this.assetManager = assetManager;\n    }\n\n    @NonNull\n    @Override\n    public ImageItem handle(@NonNull String raw, @NonNull Uri uri, int width, int height) {\n\n        final List<String> segments = uri.getPathSegments();\n        if (segments == null\n                || segments.size() == 0) {\n            // pointing to file & having no path segments is no use\n            throw new IllegalStateException(\"Invalid file path: \" + raw);\n        }\n\n        final InputStream inputStream;\n\n        final boolean assets = FILE_ANDROID_ASSETS.equals(segments.get(0));\n        final String fileName = uri.getLastPathSegment();\n\n        if (assets) {\n\n            // no handling of assets here if we have no assetsManager\n            if (assetManager != null) {\n\n                final StringBuilder path = new StringBuilder();\n                for (int i = 1, size = segments.size(); i < size; i++) {\n                    if (i != 1) {\n                        path.append('/');\n                    }\n                    path.append(segments.get(i));\n                }\n                // load assets\n\n                try {\n                    inputStream = assetManager.open(path.toString());\n                } catch (IOException e) {\n                    throw new IllegalStateException(\"Exception obtaining asset file: \" +\n                            \"\" + raw + \", path: \" + path.toString(), e);\n                }\n            } else {\n                throw new IllegalStateException(\"Supplied file path points to assets, \" +\n                        \"but FileSchemeHandler was not supplied with AssetsManager. \" +\n                        \"Use `#createWithAssets` factory method to create FileSchemeHandler \" +\n                        \"that can handle android assets\");\n            }\n\n        } else {\n\n            final String path = uri.getPath();\n            if (TextUtils.isEmpty(path)) {\n                throw new IllegalStateException(\"Invalid file path: \" + raw + \", \" + path);\n            }\n\n            try {\n                inputStream = new BufferedInputStream(new FileInputStream(new File(path)));\n            } catch (FileNotFoundException e) {\n                throw new IllegalStateException(\"Exception reading file: \" + raw, e);\n            }\n        }\n\n        final String contentType = MimeTypeMap\n                .getSingleton()\n                .getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(fileName));\n\n        return ImageItem.withDecodingNeeded(contentType, inputStream);\n    }\n\n    @NonNull\n    @Override\n    public Collection<String> supportedSchemes() {\n        return Collections.singleton(SCHEME);\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-image/src/main/java/io/noties/markwon/image/network/NetworkSchemeHandler.java",
    "content": "package io.noties.markwon.image.network;\n\nimport android.net.Uri;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport java.io.BufferedInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.net.HttpURLConnection;\nimport java.net.URL;\nimport java.util.Arrays;\nimport java.util.Collection;\n\nimport io.noties.markwon.image.ImageItem;\nimport io.noties.markwon.image.SchemeHandler;\n\n/**\n * A simple network scheme handler that is not dependent on any external libraries.\n *\n * @see #create()\n * @since 3.0.0\n */\npublic class NetworkSchemeHandler extends SchemeHandler {\n\n    public static final String SCHEME_HTTP = \"http\";\n    public static final String SCHEME_HTTPS = \"https\";\n\n    @NonNull\n    public static NetworkSchemeHandler create() {\n        return new NetworkSchemeHandler();\n    }\n\n    @SuppressWarnings(\"WeakerAccess\")\n    NetworkSchemeHandler() {\n\n    }\n\n    @NonNull\n    @Override\n    public ImageItem handle(@NonNull String raw, @NonNull Uri uri, int width, int height) {\n\n        final ImageItem imageItem;\n        try {\n\n            final URL url = new URL(raw);\n            final HttpURLConnection connection = (HttpURLConnection) url.openConnection();\n            connection.connect();\n\n            final int responseCode = connection.getResponseCode();\n            if (responseCode >= 200 && responseCode < 300) {\n                final String contentType = contentType(connection.getHeaderField(\"Content-Type\"));\n                final InputStream inputStream = new BufferedInputStream(connection.getInputStream());\n                imageItem = ImageItem.withDecodingNeeded(contentType, inputStream);\n            } else {\n                throw new IOException(\"Bad response code: \" + responseCode + \", url: \" + raw);\n            }\n\n        } catch (IOException e) {\n            throw new IllegalStateException(\"Exception obtaining network resource: \" + raw, e);\n        }\n\n        return imageItem;\n    }\n\n    @NonNull\n    @Override\n    public Collection<String> supportedSchemes() {\n        return Arrays.asList(SCHEME_HTTP, SCHEME_HTTPS);\n    }\n\n    @Nullable\n    static String contentType(@Nullable String contentType) {\n\n        if (contentType == null) {\n            return null;\n        }\n\n        final int index = contentType.indexOf(';');\n        if (index > -1) {\n            return contentType.substring(0, index);\n        }\n\n        return contentType;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-image/src/test/java/io/noties/markwon/image/ExampleUnitTest.java",
    "content": "package io.noties.markwon.image;\n\nimport static org.junit.Assert.assertEquals;\n\nimport org.junit.Test;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "Android/AntFluid/markwon-inline-parser/.gitignore",
    "content": "/build"
  },
  {
    "path": "Android/AntFluid/markwon-inline-parser/build.gradle",
    "content": "plugins {\n    alias(libs.plugins.android.library)\n}\n\nandroid {\n    namespace 'io.noties.markwon.inlineparser'\n    compileSdk 35\n\n    defaultConfig {\n        minSdk 21\n\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n        consumerProguardFiles \"consumer-rules.pro\"\n    }\n\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n        }\n    }\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_11\n        targetCompatibility JavaVersion.VERSION_11\n    }\n}\n\ndependencies {\n\n    implementation libs.androidx.appcompat\n    compileOnly project(':markwon-core')\n    testImplementation libs.junit\n    androidTestImplementation libs.androidx.junit\n    androidTestImplementation libs.androidx.espresso.core\n}"
  },
  {
    "path": "Android/AntFluid/markwon-inline-parser/consumer-rules.pro",
    "content": ""
  },
  {
    "path": "Android/AntFluid/markwon-inline-parser/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile"
  },
  {
    "path": "Android/AntFluid/markwon-inline-parser/src/androidTest/java/io/noties/markwon/inlineparser/ExampleInstrumentedTest.java",
    "content": "package io.noties.markwon.inlineparser;\n\nimport static org.junit.Assert.assertEquals;\n\nimport android.content.Context;\n\nimport androidx.test.ext.junit.runners.AndroidJUnit4;\nimport androidx.test.platform.app.InstrumentationRegistry;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();\n        assertEquals(\"io.noties.markwon.inlineparser.test\", appContext.getPackageName());\n    }\n}"
  },
  {
    "path": "Android/AntFluid/markwon-inline-parser/src/main/AndroidManifest.xml",
    "content": "<manifest package=\"io.noties.markwon.inlineparser\" />"
  },
  {
    "path": "Android/AntFluid/markwon-inline-parser/src/main/java/com/fluid/afm/inline/OiintInlineProcessor.java",
    "content": "package com.fluid.afm.inline;\n\nimport org.commonmark.node.Node;\nimport org.commonmark.node.Text;\n\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\nimport io.noties.markwon.inlineparser.InlineProcessor;\nimport io.noties.markwon.node.OiintNode;\npublic class OiintInlineProcessor extends InlineProcessor {\n    private static final Pattern PATTERN = Pattern.compile(\"^\\\\$\\\\\\\\oiint\\\\$\");\n    @Override\n    public char specialCharacter() {\n        return '$';\n    }\n    @Override\n    protected Node parse() {\n        final String matched = match(PATTERN);\n        if (matched == null) return null;\n        final Matcher matcher = PATTERN.matcher(matched);\n        if (!matcher.find()) return null;\n        final OiintNode parent = new OiintNode();\n        parent.appendChild(new Text(\"\\u222F\")); // character ∯\n        return parent;\n    }\n}"
  },
  {
    "path": "Android/AntFluid/markwon-inline-parser/src/main/java/io/noties/markwon/inlineparser/AutolinkInlineProcessor.java",
    "content": "package io.noties.markwon.inlineparser;\n\nimport org.commonmark.node.Link;\nimport org.commonmark.node.Node;\nimport org.commonmark.node.Text;\n\nimport java.util.regex.Pattern;\n\n/**\n * Parses autolinks, for example {@code <me@mydoma.in>}\n *\n * @since 4.2.0\n */\npublic class AutolinkInlineProcessor extends InlineProcessor {\n\n    private static final Pattern EMAIL_AUTOLINK = Pattern\n            .compile(\"^<([a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)>\");\n\n    private static final Pattern AUTOLINK = Pattern\n            .compile(\"^<[a-zA-Z][a-zA-Z0-9.+-]{1,31}:[^<>\\u0000-\\u0020]*>\");\n\n    @Override\n    public char specialCharacter() {\n        return '<';\n    }\n\n    @Override\n    protected Node parse() {\n        String m;\n        if ((m = match(EMAIL_AUTOLINK)) != null) {\n            String dest = m.substring(1, m.length() - 1);\n            Link node = new Link(\"mailto:\" + dest, null);\n            node.appendChild(new Text(dest));\n            return node;\n        } else if ((m = match(AUTOLINK)) != null) {\n            String dest = m.substring(1, m.length() - 1);\n            Link node = new Link(dest, null);\n            node.appendChild(new Text(dest));\n            return node;\n        } else {\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-inline-parser/src/main/java/io/noties/markwon/inlineparser/BackslashInlineProcessor.java",
    "content": "package io.noties.markwon.inlineparser;\n\nimport org.commonmark.node.HardLineBreak;\nimport org.commonmark.node.Node;\n\nimport java.util.regex.Pattern;\n\n/**\n * @since 4.2.0\n */\npublic class BackslashInlineProcessor extends InlineProcessor {\n\n    private static final Pattern ESCAPABLE = MarkwonInlineParser.ESCAPABLE;\n\n    @Override\n    public char specialCharacter() {\n        return '\\\\';\n    }\n\n    @Override\n    protected Node parse() {\n        index++;\n        Node node;\n        if (peek() == '\\n') {\n            node = new HardLineBreak();\n            index++;\n        } else if (index < input.length() && ESCAPABLE.matcher(input.substring(index, index + 1)).matches()) {\n            node = text(input, index, index + 1);\n            index++;\n        } else {\n            node = text(\"\\\\\");\n        }\n        return node;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-inline-parser/src/main/java/io/noties/markwon/inlineparser/BackticksInlineProcessor.java",
    "content": "package io.noties.markwon.inlineparser;\n\nimport org.commonmark.internal.util.Parsing;\nimport org.commonmark.node.Code;\nimport org.commonmark.node.Node;\n\nimport java.util.regex.Pattern;\n\n/**\n * Parses inline code surrounded with {@code `} chars {@code `code`}\n *\n * @since 4.2.0\n */\npublic class BackticksInlineProcessor extends InlineProcessor {\n\n    private static final Pattern TICKS = Pattern.compile(\"`+\");\n\n    private static final Pattern TICKS_HERE = Pattern.compile(\"^`+\");\n\n    @Override\n    public char specialCharacter() {\n        return '`';\n    }\n\n    @Override\n    protected Node parse() {\n        String ticks = match(TICKS_HERE);\n        if (ticks == null) {\n            return null;\n        }\n        int afterOpenTicks = index;\n        String matched;\n        while ((matched = match(TICKS)) != null) {\n            if (matched.equals(ticks)) {\n                Code node = new Code();\n                String content = input.substring(afterOpenTicks, index - ticks.length());\n                content = content.replace('\\n', ' ');\n\n                // spec: If the resulting string both begins and ends with a space character, but does not consist\n                // entirely of space characters, a single space character is removed from the front and back.\n                if (content.length() >= 3 &&\n                        content.charAt(0) == ' ' &&\n                        content.charAt(content.length() - 1) == ' ' &&\n                        Parsing.hasNonSpace(content)) {\n                    content = content.substring(1, content.length() - 1);\n                }\n\n                node.setLiteral(content);\n                return node;\n            }\n        }\n        // If we got here, we didn't match a closing backtick sequence.\n        index = afterOpenTicks;\n        return text(ticks);\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-inline-parser/src/main/java/io/noties/markwon/inlineparser/BangInlineProcessor.java",
    "content": "package io.noties.markwon.inlineparser;\n\nimport org.commonmark.internal.Bracket;\nimport org.commonmark.node.Node;\nimport org.commonmark.node.Text;\n\n/**\n * Parses markdown images {@code ![alt](#href)}\n *\n * @since 4.2.0\n */\npublic class BangInlineProcessor extends InlineProcessor {\n    @Override\n    public char specialCharacter() {\n        return '!';\n    }\n\n    @Override\n    protected Node parse() {\n        int startIndex = index;\n        index++;\n        if (peek() == '[') {\n            index++;\n\n            Text node = text(\"![\");\n\n            // Add entry to stack for this opener\n            addBracket(Bracket.image(node, startIndex + 1, lastBracket(), lastDelimiter()));\n\n            return node;\n        } else {\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-inline-parser/src/main/java/io/noties/markwon/inlineparser/CloseBracketInlineProcessor.java",
    "content": "package io.noties.markwon.inlineparser;\n\nimport org.commonmark.internal.Bracket;\nimport org.commonmark.internal.util.Escaping;\nimport org.commonmark.node.Image;\nimport org.commonmark.node.Link;\nimport org.commonmark.node.LinkReferenceDefinition;\nimport org.commonmark.node.Node;\n\nimport java.util.regex.Pattern;\n\nimport static io.noties.markwon.inlineparser.InlineParserUtils.mergeChildTextNodes;\n\n/**\n * Parses markdown link or image, relies on {@link OpenBracketInlineProcessor}\n * to handle start of these elements\n *\n * @since 4.2.0\n */\npublic class CloseBracketInlineProcessor extends InlineProcessor {\n\n    private static final Pattern WHITESPACE = MarkwonInlineParser.WHITESPACE;\n\n    @Override\n    public char specialCharacter() {\n        return ']';\n    }\n\n    @Override\n    protected Node parse() {\n        index++;\n        int startIndex = index;\n\n        // Get previous `[` or `![`\n        Bracket opener = lastBracket();\n        if (opener == null) {\n            // No matching opener, just return a literal.\n            return text(\"]\");\n        }\n\n        if (!opener.allowed) {\n            // Matching opener but it's not allowed, just return a literal.\n            removeLastBracket();\n            return text(\"]\");\n        }\n\n        // Check to see if we have a link/image\n\n        String dest = null;\n        String title = null;\n        boolean isLinkOrImage = false;\n\n        // Maybe a inline link like `[foo](/uri \"title\")`\n        if (peek() == '(') {\n            index++;\n            spnl();\n            if ((dest = parseLinkDestination()) != null) {\n                spnl();\n                // title needs a whitespace before\n                if (WHITESPACE.matcher(input.substring(index - 1, index)).matches()) {\n                    title = parseLinkTitle();\n                    spnl();\n                }\n                if (peek() == ')') {\n                    index++;\n                    isLinkOrImage = true;\n                } else {\n                    index = startIndex;\n                }\n            }\n        }\n\n        // Maybe a reference link like `[foo][bar]`, `[foo][]` or `[foo]`\n        if (!isLinkOrImage) {\n\n            // See if there's a link label like `[bar]` or `[]`\n            int beforeLabel = index;\n            parseLinkLabel();\n            int labelLength = index - beforeLabel;\n            String ref = null;\n            if (labelLength > 2) {\n                ref = input.substring(beforeLabel, beforeLabel + labelLength);\n            } else if (!opener.bracketAfter) {\n                // If the second label is empty `[foo][]` or missing `[foo]`, then the first label is the reference.\n                // But it can only be a reference when there's no (unescaped) bracket in it.\n                // If there is, we don't even need to try to look up the reference. This is an optimization.\n                ref = input.substring(opener.index, startIndex);\n            }\n\n            if (ref != null) {\n                String label = Escaping.normalizeReference(ref);\n                LinkReferenceDefinition definition = context.getLinkReferenceDefinition(label);\n                if (definition != null) {\n                    dest = definition.getDestination();\n                    title = definition.getTitle();\n                    isLinkOrImage = true;\n                }\n            }\n        }\n\n        if (isLinkOrImage) {\n            // If we got here, open is a potential opener\n            Node linkOrImage = opener.image ? new Image(dest, title) : new Link(dest, title);\n\n            Node node = opener.node.getNext();\n            while (node != null) {\n                Node next = node.getNext();\n                linkOrImage.appendChild(node);\n                node = next;\n            }\n\n            // Process delimiters such as emphasis inside link/image\n            processDelimiters(opener.previousDelimiter);\n            mergeChildTextNodes(linkOrImage);\n            // We don't need the corresponding text node anymore, we turned it into a link/image node\n            opener.node.unlink();\n            removeLastBracket();\n\n            // Links within links are not allowed. We found this link, so there can be no other link around it.\n            if (!opener.image) {\n                Bracket bracket = lastBracket();\n                while (bracket != null) {\n                    if (!bracket.image) {\n                        // Disallow link opener. It will still get matched, but will not result in a link.\n                        bracket.allowed = false;\n                    }\n                    bracket = bracket.previous;\n                }\n            }\n\n            return linkOrImage;\n\n        } else { // no link or image\n            index = startIndex;\n            removeLastBracket();\n\n            return text(\"]\");\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-inline-parser/src/main/java/io/noties/markwon/inlineparser/EntityInlineProcessor.java",
    "content": "package io.noties.markwon.inlineparser;\n\nimport com.fluid.afm.utils.MDLogger;\n\nimport org.commonmark.internal.util.Escaping;\nimport org.commonmark.internal.util.Html5Entities;\nimport org.commonmark.node.Node;\n\nimport java.util.regex.Pattern;\n\n/**\n * Parses HTML entities {@code &amp;}\n *\n * @since 4.2.0\n */\npublic class EntityInlineProcessor extends InlineProcessor {\n\n    private static final Pattern ENTITY_HERE = Pattern.compile('^' + Escaping.ENTITY, Pattern.CASE_INSENSITIVE);\n\n    @Override\n    public char specialCharacter() {\n        return '&';\n    }\n\n    @Override\n    protected Node parse() {\n        String m;\n        if ((m = match(ENTITY_HERE)) != null) {\n            try {\n                return text(Html5Entities.entityToString(m));\n            } catch (Throwable t) {\n                MDLogger.e(\"EntityInlineProcessor\", \"Failed to parse entity: \", t);\n\n            }\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-inline-parser/src/main/java/io/noties/markwon/inlineparser/HtmlInlineProcessor.java",
    "content": "package io.noties.markwon.inlineparser;\n\nimport org.commonmark.internal.util.Parsing;\nimport org.commonmark.node.HtmlInline;\nimport org.commonmark.node.Node;\n\nimport java.util.regex.Pattern;\n\n/**\n * Parses inline HTML tags\n *\n * @since 4.2.0\n */\npublic class HtmlInlineProcessor extends InlineProcessor {\n\n    private static final String HTMLCOMMENT = \"<!---->|<!--(?:-?[^>-])(?:-?[^-])*-->\";\n    private static final String PROCESSINGINSTRUCTION = \"[<][?].*?[?][>]\";\n    private static final String DECLARATION = \"<![A-Z]+\\\\s+[^>]*>\";\n    private static final String CDATA = \"<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?\\\\]\\\\]>\";\n    private static final String HTMLTAG = \"(?:\" + Parsing.OPENTAG + \"|\" + Parsing.CLOSETAG + \"|\" + HTMLCOMMENT\n            + \"|\" + PROCESSINGINSTRUCTION + \"|\" + DECLARATION + \"|\" + CDATA + \")\";\n    private static final Pattern HTML_TAG = Pattern.compile('^' + HTMLTAG, Pattern.CASE_INSENSITIVE);\n\n    @Override\n    public char specialCharacter() {\n        return '<';\n    }\n\n    @Override\n    protected Node parse() {\n        String m = match(HTML_TAG);\n        if (m != null) {\n            HtmlInline node = new HtmlInline();\n            node.setLiteral(m);\n            return node;\n        } else {\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-inline-parser/src/main/java/io/noties/markwon/inlineparser/InlineParserUtils.java",
    "content": "package io.noties.markwon.inlineparser;\n\nimport org.commonmark.node.Node;\nimport org.commonmark.node.Text;\n\n/**\n * @since 4.2.0\n */\npublic abstract class InlineParserUtils {\n\n    public static void mergeTextNodesBetweenExclusive(Node fromNode, Node toNode) {\n        // No nodes between them\n        if (fromNode == toNode || fromNode.getNext() == toNode) {\n            return;\n        }\n\n        mergeTextNodesInclusive(fromNode.getNext(), toNode.getPrevious());\n    }\n\n    public static void mergeChildTextNodes(Node node) {\n        // No children or just one child node, no need for merging\n        if (node.getFirstChild() == node.getLastChild()) {\n            return;\n        }\n\n        mergeTextNodesInclusive(node.getFirstChild(), node.getLastChild());\n    }\n\n    public static void mergeTextNodesInclusive(Node fromNode, Node toNode) {\n        Text first = null;\n        Text last = null;\n        int length = 0;\n\n        Node node = fromNode;\n        while (node != null) {\n            if (node instanceof Text) {\n                Text text = (Text) node;\n                if (first == null) {\n                    first = text;\n                }\n                length += text.getLiteral().length();\n                last = text;\n            } else {\n                mergeIfNeeded(first, last, length);\n                first = null;\n                last = null;\n                length = 0;\n            }\n            if (node == toNode) {\n                break;\n            }\n            node = node.getNext();\n        }\n\n        mergeIfNeeded(first, last, length);\n    }\n\n    public static void mergeIfNeeded(Text first, Text last, int textLength) {\n        if (first != null && last != null && first != last) {\n            StringBuilder sb = new StringBuilder(textLength);\n            sb.append(first.getLiteral());\n            Node node = first.getNext();\n            Node stop = last.getNext();\n            while (node != stop) {\n                sb.append(((Text) node).getLiteral());\n                Node unlink = node;\n                node = node.getNext();\n                unlink.unlink();\n            }\n            String literal = sb.toString();\n            first.setLiteral(literal);\n        }\n    }\n\n    private InlineParserUtils() {\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-inline-parser/src/main/java/io/noties/markwon/inlineparser/InlineProcessor.java",
    "content": "package io.noties.markwon.inlineparser;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport org.commonmark.internal.Bracket;\nimport org.commonmark.internal.Delimiter;\nimport org.commonmark.node.Link;\nimport org.commonmark.node.Node;\nimport org.commonmark.node.Text;\n\nimport java.util.Map;\nimport java.util.regex.Pattern;\n\n/**\n * @see AutolinkInlineProcessor\n * @see BackslashInlineProcessor\n * @see BackticksInlineProcessor\n * @see BangInlineProcessor\n * @see CloseBracketInlineProcessor\n * @see EntityInlineProcessor\n * @see HtmlInlineProcessor\n * @see NewLineInlineProcessor\n * @see OpenBracketInlineProcessor\n * @see MarkwonInlineParser.FactoryBuilder#addInlineProcessor(InlineProcessor)\n * @see MarkwonInlineParser.FactoryBuilder#excludeInlineProcessor(Class)\n * @since 4.2.0\n */\npublic abstract class InlineProcessor {\n\n    /**\n     * Special character that triggers parsing attempt\n     */\n    public abstract char specialCharacter();\n\n    /**\n     * @return boolean indicating if parsing succeeded\n     */\n    @Nullable\n    protected abstract Node parse();\n\n\n    protected MarkwonInlineParserContext context;\n    protected Node block;\n    protected String input;\n    protected int index;\n\n    @Nullable\n    public Node parse(@NonNull MarkwonInlineParserContext context) {\n        this.context = context;\n        this.block = context.block();\n        this.input = context.input();\n        this.index = context.index();\n\n        final Node result = parse();\n\n        // synchronize index\n        context.setIndex(index);\n\n        return result;\n    }\n\n    protected Bracket lastBracket() {\n        return context.lastBracket();\n    }\n\n    protected Delimiter lastDelimiter() {\n        return context.lastDelimiter();\n    }\n\n    protected void addBracket(Bracket bracket) {\n        context.addBracket(bracket);\n    }\n\n    protected void removeLastBracket() {\n        context.removeLastBracket();\n    }\n\n    protected void spnl() {\n        context.setIndex(index);\n        context.spnl();\n        index = context.index();\n    }\n\n    @Nullable\n    protected String match(@NonNull Pattern re) {\n        // before trying to match, we must notify context about our index (which we store additionally here)\n        context.setIndex(index);\n\n        final String result = context.match(re);\n\n        // after match we must reflect index change here\n        this.index = context.index();\n\n        return result;\n    }\n\n    @Nullable\n    protected String parseLinkDestination() {\n        context.setIndex(index);\n        final String result = context.parseLinkDestination();\n        this.index = context.index();\n        return result;\n    }\n\n    @Nullable\n    protected String parseLinkTitle() {\n        context.setIndex(index);\n        final String result = context.parseLinkTitle();\n        this.index = context.index();\n        return result;\n    }\n\n    protected int parseLinkLabel() {\n        context.setIndex(index);\n        final int result = context.parseLinkLabel();\n        this.index = context.index();\n        return result;\n    }\n\n    protected void processDelimiters(Delimiter stackBottom) {\n        context.setIndex(index);\n        context.processDelimiters(stackBottom);\n        this.index = context.index();\n    }\n\n    @NonNull\n    protected Text text(@NonNull String text) {\n        return context.text(text);\n    }\n\n    @NonNull\n    protected Text text(@NonNull String text, int start, int end) {\n        return context.text(text, start, end);\n    }\n\n    protected char peek() {\n        context.setIndex(index);\n        return context.peek();\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-inline-parser/src/main/java/io/noties/markwon/inlineparser/MarkwonInlineParser.java",
    "content": "package io.noties.markwon.inlineparser;\n\nimport static io.noties.markwon.inlineparser.InlineParserUtils.mergeChildTextNodes;\nimport static io.noties.markwon.inlineparser.InlineParserUtils.mergeTextNodesBetweenExclusive;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport com.fluid.afm.inline.OiintInlineProcessor;\n\nimport org.commonmark.internal.Bracket;\nimport org.commonmark.internal.Delimiter;\nimport org.commonmark.internal.inline.AsteriskDelimiterProcessor;\nimport org.commonmark.internal.inline.UnderscoreDelimiterProcessor;\nimport org.commonmark.internal.util.Escaping;\nimport org.commonmark.internal.util.LinkScanner;\nimport org.commonmark.node.LinkReferenceDefinition;\nimport org.commonmark.node.Node;\nimport org.commonmark.node.Text;\nimport org.commonmark.parser.InlineParser;\nimport org.commonmark.parser.InlineParserContext;\nimport org.commonmark.parser.InlineParserFactory;\nimport org.commonmark.parser.delimiter.DelimiterProcessor;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.BitSet;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n/**\n * @see #factoryBuilder()\n * @see #factoryBuilderNoDefaults()\n * @see FactoryBuilder\n * @since 4.2.0\n */\npublic class MarkwonInlineParser implements InlineParser, MarkwonInlineParserContext {\n\n    @SuppressWarnings(\"unused\")\n    public interface FactoryBuilder {\n\n        /**\n         * @see InlineProcessor\n         */\n        @NonNull\n        FactoryBuilder addInlineProcessor(@NonNull InlineProcessor processor);\n\n        /**\n         * @see AsteriskDelimiterProcessor\n         * @see UnderscoreDelimiterProcessor\n         */\n        @NonNull\n        FactoryBuilder addDelimiterProcessor(@NonNull DelimiterProcessor processor);\n\n        /**\n         * Indicate if markdown references are enabled. By default = `true`\n         */\n        @NonNull\n        FactoryBuilder referencesEnabled(boolean referencesEnabled);\n\n        @NonNull\n        FactoryBuilder excludeInlineProcessor(@NonNull Class<? extends InlineProcessor> processor);\n\n        @NonNull\n        FactoryBuilder excludeDelimiterProcessor(@NonNull Class<? extends DelimiterProcessor> processor);\n\n        @NonNull\n        InlineParserFactory build();\n    }\n\n    public interface FactoryBuilderNoDefaults extends FactoryBuilder {\n        /**\n         * Includes all default delimiter and inline processors, and sets {@code referencesEnabled=true}.\n         * Useful with subsequent calls to {@link #excludeInlineProcessor(Class)} or {@link #excludeDelimiterProcessor(Class)}\n         */\n        @NonNull\n        FactoryBuilder includeDefaults();\n    }\n\n    /**\n     * Creates an instance of {@link FactoryBuilder} and includes all defaults.\n     *\n     * @see #factoryBuilderNoDefaults()\n     */\n    @NonNull\n    public static FactoryBuilder factoryBuilder() {\n        return new FactoryBuilderImpl().includeDefaults();\n    }\n\n    /**\n     * NB, this return an <em>empty</em> builder, so if no {@link FactoryBuilderNoDefaults#includeDefaults()}\n     * is called, it means effectively <strong>no inline parsing</strong> (unless further calls\n     * to {@link FactoryBuilder#addInlineProcessor(InlineProcessor)} or {@link FactoryBuilder#addDelimiterProcessor(DelimiterProcessor)}).\n     */\n    @NonNull\n    public static FactoryBuilderNoDefaults factoryBuilderNoDefaults() {\n        return new FactoryBuilderImpl();\n    }\n\n    private static final String ASCII_PUNCTUATION = \"!\\\"#\\\\$%&'\\\\(\\\\)\\\\*\\\\+,\\\\-\\\\./:;<=>\\\\?@\\\\[\\\\\\\\\\\\]\\\\^_`\\\\{\\\\|\\\\}~\";\n    private static final Pattern PUNCTUATION = Pattern\n            .compile(\"^[\" + ASCII_PUNCTUATION + \"\\\\p{Pc}\\\\p{Pd}\\\\p{Pe}\\\\p{Pf}\\\\p{Pi}\\\\p{Po}\\\\p{Ps}]\");\n\n    private static final Pattern SPNL = Pattern.compile(\"^ *(?:\\n *)?\");\n\n    private static final Pattern UNICODE_WHITESPACE_CHAR = Pattern.compile(\"^[\\\\p{Zs}\\t\\r\\n\\f]\");\n\n    static final Pattern ESCAPABLE = Pattern.compile('^' + Escaping.ESCAPABLE);\n    static final Pattern WHITESPACE = Pattern.compile(\"\\\\s+\");\n\n    private final InlineParserContext inlineParserContext;\n\n    private final boolean referencesEnabled;\n\n    private final BitSet specialCharacters;\n    private final Map<Character, List<InlineProcessor>> inlineProcessors;\n    private final Map<Character, DelimiterProcessor> delimiterProcessors;\n\n    // currently we still hold a reference to it because we decided not to\n    //  pass previous node argument to inline-processors (current usage is limited with NewLineInlineProcessor)\n    private Node block;\n    private String input;\n    private int index;\n\n    /**\n     * Top delimiter (emphasis, strong emphasis or custom emphasis). (Brackets are on a separate stack, different\n     * from the algorithm described in the spec.)\n     */\n    private Delimiter lastDelimiter;\n\n    /**\n     * Top opening bracket (<code>[</code> or <code>![)</code>).\n     */\n    private Bracket lastBracket;\n\n    // might we construct these in factory?\n    public MarkwonInlineParser(\n            @NonNull InlineParserContext inlineParserContext,\n            boolean referencesEnabled,\n            @NonNull List<InlineProcessor> inlineProcessors,\n            @NonNull List<DelimiterProcessor> delimiterProcessors) {\n        this.inlineParserContext = inlineParserContext;\n        this.referencesEnabled = referencesEnabled;\n        this.inlineProcessors = calculateInlines(inlineProcessors);\n        this.delimiterProcessors = calculateDelimiterProcessors(delimiterProcessors);\n        this.specialCharacters = calculateSpecialCharacters(\n                this.inlineProcessors.keySet(),\n                this.delimiterProcessors.keySet());\n    }\n\n    @NonNull\n    private static Map<Character, List<InlineProcessor>> calculateInlines(@NonNull List<InlineProcessor> inlines) {\n        final Map<Character, List<InlineProcessor>> map = new HashMap<>(inlines.size());\n        List<InlineProcessor> list;\n        for (InlineProcessor inlineProcessor : inlines) {\n            final char character = inlineProcessor.specialCharacter();\n            list = map.get(character);\n            if (list == null) {\n                list = new ArrayList<>(1);\n                map.put(character, list);\n            }\n            list.add(inlineProcessor);\n        }\n        return map;\n    }\n\n    @NonNull\n    private static BitSet calculateSpecialCharacters(Set<Character> inlineCharacters, Set<Character> delimiterCharacters) {\n        final BitSet bitSet = new BitSet();\n        for (Character c : inlineCharacters) {\n            bitSet.set(c);\n        }\n        for (Character c : delimiterCharacters) {\n            bitSet.set(c);\n        }\n        return bitSet;\n    }\n\n    private static Map<Character, DelimiterProcessor> calculateDelimiterProcessors(List<DelimiterProcessor> delimiterProcessors) {\n        Map<Character, DelimiterProcessor> map = new HashMap<>();\n        addDelimiterProcessors(delimiterProcessors, map);\n        return map;\n    }\n\n    private static void addDelimiterProcessors(Iterable<DelimiterProcessor> delimiterProcessors, Map<Character, DelimiterProcessor> map) {\n        for (DelimiterProcessor delimiterProcessor : delimiterProcessors) {\n            char opening = delimiterProcessor.getOpeningCharacter();\n            char closing = delimiterProcessor.getClosingCharacter();\n            if (opening == closing) {\n                DelimiterProcessor old = map.get(opening);\n                if (old != null && old.getOpeningCharacter() == old.getClosingCharacter()) {\n                    StaggeredDelimiterProcessor s;\n                    if (old instanceof StaggeredDelimiterProcessor) {\n                        s = (StaggeredDelimiterProcessor) old;\n                    } else {\n                        s = new StaggeredDelimiterProcessor(opening);\n                        s.add(old);\n                    }\n                    s.add(delimiterProcessor);\n                    map.put(opening, s);\n                } else {\n                    addDelimiterProcessorForChar(opening, delimiterProcessor, map);\n                }\n            } else {\n                addDelimiterProcessorForChar(opening, delimiterProcessor, map);\n                addDelimiterProcessorForChar(closing, delimiterProcessor, map);\n            }\n        }\n    }\n\n    private static void addDelimiterProcessorForChar(char delimiterChar, DelimiterProcessor toAdd, Map<Character, DelimiterProcessor> delimiterProcessors) {\n        DelimiterProcessor existing = delimiterProcessors.put(delimiterChar, toAdd);\n        if (existing != null) {\n            throw new IllegalArgumentException(\"Delimiter processor conflict with delimiter char '\" + delimiterChar + \"'\");\n        }\n    }\n\n    /**\n     * Parse content in block into inline children, using reference map to resolve references.\n     */\n    @Override\n    public void parse(String content, Node block) {\n        reset(content.trim());\n\n        // we still reference it\n        this.block = block;\n\n        while (true) {\n            Node node = parseInline();\n            if (node != null) {\n                block.appendChild(node);\n            } else {\n                break;\n            }\n        }\n\n        processDelimiters(null);\n        mergeChildTextNodes(block);\n    }\n\n    private void reset(String content) {\n        this.input = content;\n        this.index = 0;\n        this.lastDelimiter = null;\n        this.lastBracket = null;\n    }\n\n    /**\n     * Parse the next inline element in subject, advancing input index.\n     * On success, add the result to block's children and return true.\n     * On failure, return false.\n     */\n    @Nullable\n    private Node parseInline() {\n\n        final char c = peek();\n\n        if (c == '\\0') {\n            return null;\n        }\n\n        Node node = null;\n\n        final List<InlineProcessor> inlines = this.inlineProcessors.get(c);\n\n        if (inlines != null) {\n            // @since 4.6.0 index must not be advanced if inline-processor returned null\n            //  so, further processors can be called at the _same_ position (and thus char)\n            final int startIndex = index;\n\n            for (InlineProcessor inline : inlines) {\n                node = inline.parse(this);\n                if (node != null) {\n                    break;\n                }\n\n                // reset after each iteration (happens only when node is null)\n                index = startIndex;\n            }\n        } else {\n            final DelimiterProcessor delimiterProcessor = delimiterProcessors.get(c);\n            if (delimiterProcessor != null) {\n                node = parseDelimiters(delimiterProcessor, c);\n            } else {\n                node = parseString();\n            }\n        }\n\n        if (node != null) {\n            return node;\n        } else {\n            index++;\n            // When we get here, it's only for a single special character that turned out to not have a special meaning.\n            // So we shouldn't have a single surrogate here, hence it should be ok to turn it into a String.\n            String literal = String.valueOf(c);\n            return text(literal);\n        }\n    }\n\n    /**\n     * If RE matches at current index in the input, advance index and return the match; otherwise return null.\n     */\n    @Override\n    @Nullable\n    public String match(@NonNull Pattern re) {\n        if (index >= input.length()) {\n            return null;\n        }\n        Matcher matcher = re.matcher(input);\n        matcher.region(index, input.length());\n        boolean m = matcher.find();\n        if (m) {\n            index = matcher.end();\n            return matcher.group();\n        } else {\n            return null;\n        }\n    }\n\n    @NonNull\n    @Override\n    public Text text(@NonNull String text) {\n        return new Text(text);\n    }\n\n    @NonNull\n    @Override\n    public Text text(@NonNull String text, int beginIndex, int endIndex) {\n        return new Text(text.substring(beginIndex, endIndex));\n    }\n\n    @Nullable\n    @Override\n    public LinkReferenceDefinition getLinkReferenceDefinition(String label) {\n        return referencesEnabled\n                ? inlineParserContext.getLinkReferenceDefinition(label)\n                : null;\n    }\n\n    /**\n     * Returns the char at the current input index, or {@code '\\0'} in case there are no more characters.\n     */\n    @Override\n    public char peek() {\n        if (index < input.length()) {\n            return input.charAt(index);\n        } else {\n            return '\\0';\n        }\n    }\n\n    @NonNull\n    @Override\n    public Node block() {\n        return block;\n    }\n\n    @NonNull\n    @Override\n    public String input() {\n        return input;\n    }\n\n    @Override\n    public int index() {\n        return index;\n    }\n\n    @Override\n    public void setIndex(int index) {\n        this.index = index;\n    }\n\n    @Override\n    public Bracket lastBracket() {\n        return lastBracket;\n    }\n\n    @Override\n    public Delimiter lastDelimiter() {\n        return lastDelimiter;\n    }\n\n    @Override\n    public void addBracket(Bracket bracket) {\n        if (lastBracket != null) {\n            lastBracket.bracketAfter = true;\n        }\n        lastBracket = bracket;\n    }\n\n    @Override\n    public void removeLastBracket() {\n        lastBracket = lastBracket.previous;\n    }\n\n    /**\n     * Parse zero or more space characters, including at most one newline.\n     */\n    @Override\n    public void spnl() {\n        match(SPNL);\n    }\n\n    /**\n     * Attempt to parse delimiters like emphasis, strong emphasis or custom delimiters.\n     */\n    @Nullable\n    private Node parseDelimiters(DelimiterProcessor delimiterProcessor, char delimiterChar) {\n        DelimiterData res = scanDelimiters(delimiterProcessor, delimiterChar);\n        if (res == null) {\n            return null;\n        }\n        int length = res.count;\n        int startIndex = index;\n\n        index += length;\n        Text node = text(input, startIndex, index);\n\n        // Add entry to stack for this opener\n        lastDelimiter = new Delimiter(node, delimiterChar, res.canOpen, res.canClose, lastDelimiter);\n        lastDelimiter.length = length;\n        lastDelimiter.originalLength = length;\n        if (lastDelimiter.previous != null) {\n            lastDelimiter.previous.next = lastDelimiter;\n        }\n\n        return node;\n    }\n\n    /**\n     * Attempt to parse link destination, returning the string or null if no match.\n     */\n    @Override\n    @Nullable\n    public String parseLinkDestination() {\n        int afterDest = LinkScanner.scanLinkDestination(input, index);\n        if (afterDest == -1) {\n            return null;\n        }\n\n        String dest;\n        if (peek() == '<') {\n            // chop off surrounding <..>:\n            dest = input.substring(index + 1, afterDest - 1);\n        } else {\n            dest = input.substring(index, afterDest);\n        }\n\n        index = afterDest;\n        return Escaping.unescapeString(dest);\n    }\n\n    /**\n     * Attempt to parse link title (sans quotes), returning the string or null if no match.\n     */\n    @Override\n    @Nullable\n    public String parseLinkTitle() {\n        int afterTitle = LinkScanner.scanLinkTitle(input, index);\n        if (afterTitle == -1) {\n            return null;\n        }\n\n        // chop off ', \" or parens\n        String title = input.substring(index + 1, afterTitle - 1);\n        index = afterTitle;\n        return Escaping.unescapeString(title);\n    }\n\n    /**\n     * Attempt to parse a link label, returning number of characters parsed.\n     */\n    @Override\n    public int parseLinkLabel() {\n        if (index >= input.length() || input.charAt(index) != '[') {\n            return 0;\n        }\n\n        int startContent = index + 1;\n        int endContent = LinkScanner.scanLinkLabelContent(input, startContent);\n        // spec: A link label can have at most 999 characters inside the square brackets.\n        int contentLength = endContent - startContent;\n        if (endContent == -1 || contentLength > 999) {\n            return 0;\n        }\n        if (endContent >= input.length() || input.charAt(endContent) != ']') {\n            return 0;\n        }\n        index = endContent + 1;\n        return contentLength + 2;\n    }\n\n    /**\n     * Parse a run of ordinary characters, or a single character with a special meaning in markdown, as a plain string.\n     */\n    private Node parseString() {\n        int begin = index;\n        int length = input.length();\n        while (index != length) {\n            if (specialCharacters.get(input.charAt(index))) {\n                break;\n            }\n            index++;\n        }\n        if (begin != index) {\n            return text(input, begin, index);\n        } else {\n            return null;\n        }\n    }\n\n    /**\n     * Scan a sequence of characters with code delimiterChar, and return information about the number of delimiters\n     * and whether they are positioned such that they can open and/or close emphasis or strong emphasis.\n     *\n     * @return information about delimiter run, or {@code null}\n     */\n    private DelimiterData scanDelimiters(DelimiterProcessor delimiterProcessor, char delimiterChar) {\n        int startIndex = index;\n\n        int delimiterCount = 0;\n        while (peek() == delimiterChar) {\n            delimiterCount++;\n            index++;\n        }\n\n        if (delimiterCount < delimiterProcessor.getMinLength()) {\n            index = startIndex;\n            return null;\n        }\n\n        String before = startIndex == 0 ? \"\\n\" :\n                input.substring(startIndex - 1, startIndex);\n\n        char charAfter = peek();\n        String after = charAfter == '\\0' ? \"\\n\" :\n                String.valueOf(charAfter);\n\n        // We could be more lazy here, in most cases we don't need to do every match case.\n        boolean beforeIsPunctuation = PUNCTUATION.matcher(before).matches();\n        boolean beforeIsWhitespace = UNICODE_WHITESPACE_CHAR.matcher(before).matches();\n        boolean afterIsPunctuation = PUNCTUATION.matcher(after).matches();\n        boolean afterIsWhitespace = UNICODE_WHITESPACE_CHAR.matcher(after).matches();\n\n        boolean leftFlanking = !afterIsWhitespace &&\n                (!afterIsPunctuation || beforeIsWhitespace || beforeIsPunctuation);\n        boolean rightFlanking = !beforeIsWhitespace &&\n                (!beforeIsPunctuation || afterIsWhitespace || afterIsPunctuation);\n        boolean canOpen;\n        boolean canClose;\n        if (delimiterChar == '_') {\n            canOpen = leftFlanking && (!rightFlanking || beforeIsPunctuation);\n            canClose = rightFlanking && (!leftFlanking || afterIsPunctuation);\n        } else {\n            canOpen = leftFlanking && delimiterChar == delimiterProcessor.getOpeningCharacter();\n            canClose = rightFlanking && delimiterChar == delimiterProcessor.getClosingCharacter();\n        }\n\n        index = startIndex;\n        return new DelimiterData(delimiterCount, canOpen, canClose);\n    }\n\n    @Override\n    public void processDelimiters(Delimiter stackBottom) {\n\n        Map<Character, Delimiter> openersBottom = new HashMap<>();\n\n        // find first closer above stackBottom:\n        Delimiter closer = lastDelimiter;\n        while (closer != null && closer.previous != stackBottom) {\n            closer = closer.previous;\n        }\n        // move forward, looking for closers, and handling each\n        while (closer != null) {\n            char delimiterChar = closer.delimiterChar;\n\n            DelimiterProcessor delimiterProcessor = delimiterProcessors.get(delimiterChar);\n            if (!closer.canClose || delimiterProcessor == null) {\n                closer = closer.next;\n                continue;\n            }\n\n            char openingDelimiterChar = delimiterProcessor.getOpeningCharacter();\n\n            // Found delimiter closer. Now look back for first matching opener.\n            int useDelims = 0;\n            boolean openerFound = false;\n            boolean potentialOpenerFound = false;\n            Delimiter opener = closer.previous;\n            while (opener != null && opener != stackBottom && opener != openersBottom.get(delimiterChar)) {\n                if (opener.canOpen && opener.delimiterChar == openingDelimiterChar) {\n                    potentialOpenerFound = true;\n                    useDelims = delimiterProcessor.getDelimiterUse(opener, closer);\n                    if (useDelims > 0) {\n                        openerFound = true;\n                        break;\n                    }\n                }\n                opener = opener.previous;\n            }\n\n            if (!openerFound) {\n                if (!potentialOpenerFound) {\n                    // Set lower bound for future searches for openers.\n                    // Only do this when we didn't even have a potential\n                    // opener (one that matches the character and can open).\n                    // If an opener was rejected because of the number of\n                    // delimiters (e.g. because of the \"multiple of 3\" rule),\n                    // we want to consider it next time because the number\n                    // of delimiters can change as we continue processing.\n                    openersBottom.put(delimiterChar, closer.previous);\n                    if (!closer.canOpen) {\n                        // We can remove a closer that can't be an opener,\n                        // once we've seen there's no matching opener:\n                        removeDelimiterKeepNode(closer);\n                    }\n                }\n                closer = closer.next;\n                continue;\n            }\n\n            Text openerNode = opener.node;\n            Text closerNode = closer.node;\n\n            // Remove number of used delimiters from stack and inline nodes.\n            opener.length -= useDelims;\n            closer.length -= useDelims;\n            openerNode.setLiteral(\n                    openerNode.getLiteral().substring(0,\n                            openerNode.getLiteral().length() - useDelims));\n            closerNode.setLiteral(\n                    closerNode.getLiteral().substring(0,\n                            closerNode.getLiteral().length() - useDelims));\n\n            removeDelimitersBetween(opener, closer);\n            // The delimiter processor can re-parent the nodes between opener and closer,\n            // so make sure they're contiguous already. Exclusive because we want to keep opener/closer themselves.\n            mergeTextNodesBetweenExclusive(openerNode, closerNode);\n            delimiterProcessor.process(openerNode, closerNode, useDelims);\n\n            // No delimiter characters left to process, so we can remove delimiter and the now empty node.\n            if (opener.length == 0) {\n                removeDelimiterAndNode(opener);\n            }\n\n            if (closer.length == 0) {\n                Delimiter next = closer.next;\n                removeDelimiterAndNode(closer);\n                closer = next;\n            }\n        }\n\n        // remove all delimiters\n        while (lastDelimiter != null && lastDelimiter != stackBottom) {\n            removeDelimiterKeepNode(lastDelimiter);\n        }\n    }\n\n    private void removeDelimitersBetween(Delimiter opener, Delimiter closer) {\n        Delimiter delimiter = closer.previous;\n        while (delimiter != null && delimiter != opener) {\n            Delimiter previousDelimiter = delimiter.previous;\n            removeDelimiterKeepNode(delimiter);\n            delimiter = previousDelimiter;\n        }\n    }\n\n    /**\n     * Remove the delimiter and the corresponding text node. For used delimiters, e.g. `*` in `*foo*`.\n     */\n    private void removeDelimiterAndNode(Delimiter delim) {\n        Text node = delim.node;\n        node.unlink();\n        removeDelimiter(delim);\n    }\n\n    /**\n     * Remove the delimiter but keep the corresponding node as text. For unused delimiters such as `_` in `foo_bar`.\n     */\n    private void removeDelimiterKeepNode(Delimiter delim) {\n        removeDelimiter(delim);\n    }\n\n    private void removeDelimiter(Delimiter delim) {\n        if (delim.previous != null) {\n            delim.previous.next = delim.next;\n        }\n        if (delim.next == null) {\n            // top of stack\n            lastDelimiter = delim.previous;\n        } else {\n            delim.next.previous = delim.previous;\n        }\n    }\n\n    private static class DelimiterData {\n\n        final int count;\n        final boolean canClose;\n        final boolean canOpen;\n\n        DelimiterData(int count, boolean canOpen, boolean canClose) {\n            this.count = count;\n            this.canOpen = canOpen;\n            this.canClose = canClose;\n        }\n    }\n\n    static class FactoryBuilderImpl implements FactoryBuilder, FactoryBuilderNoDefaults {\n\n        private final List<InlineProcessor> inlineProcessors = new ArrayList<>(3);\n        private final List<DelimiterProcessor> delimiterProcessors = new ArrayList<>(3);\n        private boolean referencesEnabled;\n\n        @NonNull\n        @Override\n        public FactoryBuilder addInlineProcessor(@NonNull InlineProcessor processor) {\n            this.inlineProcessors.add(processor);\n            return this;\n        }\n\n        @NonNull\n        @Override\n        public FactoryBuilder addDelimiterProcessor(@NonNull DelimiterProcessor processor) {\n            this.delimiterProcessors.add(processor);\n            return this;\n        }\n\n        @NonNull\n        @Override\n        public FactoryBuilder referencesEnabled(boolean referencesEnabled) {\n            this.referencesEnabled = referencesEnabled;\n            return this;\n        }\n\n        @NonNull\n        @Override\n        public FactoryBuilder includeDefaults() {\n\n            // by default enabled\n            this.referencesEnabled = true;\n\n            this.inlineProcessors.addAll(Arrays.asList(\n                    new AutolinkInlineProcessor(),\n                    new BackslashInlineProcessor(),\n                    new BackticksInlineProcessor(),\n                    new BangInlineProcessor(),\n                    new CloseBracketInlineProcessor(),\n                    new EntityInlineProcessor(),\n                    new HtmlInlineProcessor(),\n                    new NewLineInlineProcessor(),\n                    new OiintInlineProcessor(),\n                    new OpenBracketInlineProcessor()));\n\n            this.delimiterProcessors.addAll(Arrays.asList(\n                    new AsteriskDelimiterProcessor(),\n                    new UnderscoreDelimiterProcessor()));\n\n            return this;\n        }\n\n        @NonNull\n        @Override\n        public FactoryBuilder excludeInlineProcessor(@NonNull Class<? extends InlineProcessor> type) {\n            for (int i = 0, size = inlineProcessors.size(); i < size; i++) {\n                if (type.equals(inlineProcessors.get(i).getClass())) {\n                    inlineProcessors.remove(i);\n                    break;\n                }\n            }\n            return this;\n        }\n\n        @NonNull\n        @Override\n        public FactoryBuilder excludeDelimiterProcessor(@NonNull Class<? extends DelimiterProcessor> type) {\n            for (int i = 0, size = delimiterProcessors.size(); i < size; i++) {\n                if (type.equals(delimiterProcessors.get(i).getClass())) {\n                    delimiterProcessors.remove(i);\n                    break;\n                }\n            }\n            return this;\n        }\n\n        @NonNull\n        @Override\n        public InlineParserFactory build() {\n            return new InlineParserFactoryImpl(referencesEnabled, inlineProcessors, delimiterProcessors);\n        }\n    }\n\n    static class InlineParserFactoryImpl implements InlineParserFactory {\n\n        private final boolean referencesEnabled;\n        private final List<InlineProcessor> inlineProcessors;\n        private final List<DelimiterProcessor> delimiterProcessors;\n\n        InlineParserFactoryImpl(\n                boolean referencesEnabled,\n                @NonNull List<InlineProcessor> inlineProcessors,\n                @NonNull List<DelimiterProcessor> delimiterProcessors) {\n            this.referencesEnabled = referencesEnabled;\n            this.inlineProcessors = inlineProcessors;\n            this.delimiterProcessors = delimiterProcessors;\n        }\n\n        @Override\n        public InlineParser create(InlineParserContext inlineParserContext) {\n            final List<DelimiterProcessor> delimiterProcessors;\n            final List<DelimiterProcessor> customDelimiterProcessors = inlineParserContext.getCustomDelimiterProcessors();\n            final int size = customDelimiterProcessors != null\n                    ? customDelimiterProcessors.size()\n                    : 0;\n            if (size > 0) {\n                delimiterProcessors = new ArrayList<>(size + this.delimiterProcessors.size());\n                delimiterProcessors.addAll(this.delimiterProcessors);\n                delimiterProcessors.addAll(customDelimiterProcessors);\n            } else {\n                delimiterProcessors = this.delimiterProcessors;\n            }\n            return new MarkwonInlineParser(\n                    inlineParserContext,\n                    referencesEnabled,\n                    inlineProcessors,\n                    delimiterProcessors);\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-inline-parser/src/main/java/io/noties/markwon/inlineparser/MarkwonInlineParserContext.java",
    "content": "package io.noties.markwon.inlineparser;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport org.commonmark.internal.Bracket;\nimport org.commonmark.internal.Delimiter;\nimport org.commonmark.node.Link;\nimport org.commonmark.node.LinkReferenceDefinition;\nimport org.commonmark.node.Node;\nimport org.commonmark.node.Text;\n\nimport java.util.Map;\nimport java.util.regex.Pattern;\n\npublic interface MarkwonInlineParserContext {\n\n    @NonNull\n    Node block();\n\n    @NonNull\n    String input();\n\n    int index();\n\n    void setIndex(int index);\n\n    Bracket lastBracket();\n\n    Delimiter lastDelimiter();\n\n    void addBracket(Bracket bracket);\n\n    void removeLastBracket();\n\n    void spnl();\n\n    /**\n     * Returns the char at the current input index, or {@code '\\0'} in case there are no more characters.\n     */\n    char peek();\n\n    @Nullable\n    String match(@NonNull Pattern re);\n\n    @NonNull\n    Text text(@NonNull String text);\n\n    @NonNull\n    Text text(@NonNull String text, int beginIndex, int endIndex);\n\n    @Nullable\n    LinkReferenceDefinition getLinkReferenceDefinition(String label);\n\n    @Nullable\n    String parseLinkDestination();\n\n    @Nullable\n    String parseLinkTitle();\n\n    int parseLinkLabel();\n\n    void processDelimiters(Delimiter stackBottom);\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-inline-parser/src/main/java/io/noties/markwon/inlineparser/MarkwonInlineParserPlugin.java",
    "content": "package io.noties.markwon.inlineparser;\n\nimport androidx.annotation.NonNull;\n\nimport org.commonmark.parser.Parser;\n\nimport io.noties.markwon.AbstractMarkwonPlugin;\n\n/**\n * @since 4.3.0\n */\npublic class MarkwonInlineParserPlugin extends AbstractMarkwonPlugin {\n\n    public interface BuilderConfigure<B extends MarkwonInlineParser.FactoryBuilder> {\n        void configureBuilder(@NonNull B factoryBuilder);\n    }\n\n    @NonNull\n    public static MarkwonInlineParserPlugin create() {\n        return create(MarkwonInlineParser.factoryBuilder());\n    }\n\n    @NonNull\n    public static MarkwonInlineParserPlugin create(@NonNull BuilderConfigure<MarkwonInlineParser.FactoryBuilder> configure) {\n        final MarkwonInlineParser.FactoryBuilder factoryBuilder = MarkwonInlineParser.factoryBuilder();\n        configure.configureBuilder(factoryBuilder);\n        return new MarkwonInlineParserPlugin(factoryBuilder);\n    }\n\n    @NonNull\n    public static MarkwonInlineParserPlugin create(@NonNull MarkwonInlineParser.FactoryBuilder factoryBuilder) {\n        return new MarkwonInlineParserPlugin(factoryBuilder);\n    }\n\n    @NonNull\n    public static <B extends MarkwonInlineParser.FactoryBuilder> MarkwonInlineParserPlugin create(\n            @NonNull B factoryBuilder,\n            @NonNull BuilderConfigure<B> configure) {\n        configure.configureBuilder(factoryBuilder);\n        return new MarkwonInlineParserPlugin(factoryBuilder);\n    }\n\n    private final MarkwonInlineParser.FactoryBuilder factoryBuilder;\n\n    @SuppressWarnings(\"WeakerAccess\")\n    MarkwonInlineParserPlugin(@NonNull MarkwonInlineParser.FactoryBuilder factoryBuilder) {\n        this.factoryBuilder = factoryBuilder;\n    }\n\n    @Override\n    public void configureParser(@NonNull Parser.Builder builder) {\n        builder.inlineParserFactory(factoryBuilder.build());\n    }\n\n    @NonNull\n    public MarkwonInlineParser.FactoryBuilder factoryBuilder() {\n        return factoryBuilder;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-inline-parser/src/main/java/io/noties/markwon/inlineparser/NewLineInlineProcessor.java",
    "content": "package io.noties.markwon.inlineparser;\n\nimport org.commonmark.node.HardLineBreak;\nimport org.commonmark.node.Node;\nimport org.commonmark.node.SoftLineBreak;\nimport org.commonmark.node.Text;\n\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n/**\n * @since 4.2.0\n */\npublic class NewLineInlineProcessor extends InlineProcessor {\n\n    private static final Pattern FINAL_SPACE = Pattern.compile(\" *$\");\n\n    @Override\n    public char specialCharacter() {\n        return '\\n';\n    }\n\n    @Override\n    protected Node parse() {\n        index++; // assume we're at a \\n\n\n        final Node previous = block.getLastChild();\n\n        // Check previous text for trailing spaces.\n        // The \"endsWith\" is an optimization to avoid an RE match in the common case.\n        if (previous instanceof Text && ((Text) previous).getLiteral().endsWith(\" \")) {\n            Text text = (Text) previous;\n            String literal = text.getLiteral();\n            Matcher matcher = FINAL_SPACE.matcher(literal);\n            int spaces = matcher.find() ? matcher.end() - matcher.start() : 0;\n            if (spaces > 0) {\n                text.setLiteral(literal.substring(0, literal.length() - spaces));\n            }\n            if (spaces >= 2) {\n                return new HardLineBreak();\n            } else {\n                return new SoftLineBreak();\n            }\n        } else {\n            return new SoftLineBreak();\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-inline-parser/src/main/java/io/noties/markwon/inlineparser/OpenBracketInlineProcessor.java",
    "content": "package io.noties.markwon.inlineparser;\n\nimport org.commonmark.internal.Bracket;\nimport org.commonmark.node.Node;\nimport org.commonmark.node.Text;\n\n/**\n * Parses markdown links {@code [link](#href)}\n *\n * @since 4.2.0\n */\npublic class OpenBracketInlineProcessor extends InlineProcessor {\n    @Override\n    public char specialCharacter() {\n        return '[';\n    }\n\n    @Override\n    protected Node parse() {\n        int startIndex = index;\n        index++;\n\n        Text node = text(\"[\");\n\n        // Add entry to stack for this opener\n        addBracket(Bracket.link(node, startIndex, lastBracket(), lastDelimiter()));\n\n        return node;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-inline-parser/src/main/java/io/noties/markwon/inlineparser/StaggeredDelimiterProcessor.java",
    "content": "package io.noties.markwon.inlineparser;\n\nimport org.commonmark.node.Text;\nimport org.commonmark.parser.delimiter.DelimiterProcessor;\nimport org.commonmark.parser.delimiter.DelimiterRun;\n\nimport java.util.LinkedList;\nimport java.util.ListIterator;\n\nclass StaggeredDelimiterProcessor implements DelimiterProcessor {\n\n    private final char delim;\n    private int minLength = 0;\n    private LinkedList<DelimiterProcessor> processors = new LinkedList<>(); // in reverse getMinLength order\n\n    StaggeredDelimiterProcessor(char delim) {\n        this.delim = delim;\n    }\n\n    @Override\n    public char getOpeningCharacter() {\n        return delim;\n    }\n\n    @Override\n    public char getClosingCharacter() {\n        return delim;\n    }\n\n    @Override\n    public int getMinLength() {\n        return minLength;\n    }\n\n    void add(DelimiterProcessor dp) {\n        final int len = dp.getMinLength();\n        ListIterator<DelimiterProcessor> it = processors.listIterator();\n        boolean added = false;\n        while (it.hasNext()) {\n            DelimiterProcessor p = it.next();\n            int pLen = p.getMinLength();\n            if (len > pLen) {\n                it.previous();\n                it.add(dp);\n                added = true;\n                break;\n            } else if (len == pLen) {\n                throw new IllegalArgumentException(\"Cannot add two delimiter processors for char '\" + delim + \"' and minimum length \" + len);\n            }\n        }\n        if (!added) {\n            processors.add(dp);\n            this.minLength = len;\n        }\n    }\n\n    private DelimiterProcessor findProcessor(int len) {\n        for (DelimiterProcessor p : processors) {\n            if (p.getMinLength() <= len) {\n                return p;\n            }\n        }\n        return processors.getFirst();\n    }\n\n    @Override\n    public int getDelimiterUse(DelimiterRun opener, DelimiterRun closer) {\n        return findProcessor(opener.length()).getDelimiterUse(opener, closer);\n    }\n\n    @Override\n    public void process(Text opener, Text closer, int delimiterUse) {\n        findProcessor(delimiterUse).process(opener, closer, delimiterUse);\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-inline-parser/src/test/java/io/noties/markwon/inlineparser/ExampleUnitTest.java",
    "content": "package io.noties.markwon.inlineparser;\n\nimport static org.junit.Assert.assertEquals;\n\nimport org.junit.Test;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "Android/AntFluid/markwon-syntax-highlight/.gitignore",
    "content": "/build"
  },
  {
    "path": "Android/AntFluid/markwon-syntax-highlight/build.gradle",
    "content": "plugins {\n    alias(libs.plugins.android.library)\n}\n\nandroid {\n    namespace 'io.noties.markwon.syntax'\n    compileSdk 35\n\n    defaultConfig {\n        minSdk 21\n\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n        consumerProguardFiles \"consumer-rules.pro\"\n    }\n\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n        }\n    }\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_11\n        targetCompatibility JavaVersion.VERSION_11\n    }\n}\n\ndependencies {\n\n    api fileTree(dir: 'libs', include: ['*.jar'])\n    compileOnly project(':markwon-core')\n    implementation libs.androidx.appcompat\n    testImplementation libs.junit\n    androidTestImplementation libs.androidx.junit\n    androidTestImplementation libs.androidx.espresso.core\n\n}"
  },
  {
    "path": "Android/AntFluid/markwon-syntax-highlight/consumer-rules.pro",
    "content": ""
  },
  {
    "path": "Android/AntFluid/markwon-syntax-highlight/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile"
  },
  {
    "path": "Android/AntFluid/markwon-syntax-highlight/src/androidTest/java/io/noties/markwon/syntax/ExampleInstrumentedTest.java",
    "content": "package io.noties.markwon.syntax;\n\nimport static org.junit.Assert.assertEquals;\n\nimport android.content.Context;\n\nimport androidx.test.ext.junit.runners.AndroidJUnit4;\nimport androidx.test.platform.app.InstrumentationRegistry;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();\n        assertEquals(\"io.noties.markwon.syntax.test\", appContext.getPackageName());\n    }\n}"
  },
  {
    "path": "Android/AntFluid/markwon-syntax-highlight/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest>\n\n</manifest>"
  },
  {
    "path": "Android/AntFluid/markwon-syntax-highlight/src/main/java/io/noties/markwon/syntax/BaseCodeGrammar.java",
    "content": "package io.noties.markwon.syntax;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\n\nimport io.noties.prism4j.GrammarLocator;\nimport io.noties.prism4j.Prism4j;\nimport io.noties.prism4j.languages.Prism_brainfuck;\nimport io.noties.prism4j.languages.Prism_c;\nimport io.noties.prism4j.languages.Prism_clike;\nimport io.noties.prism4j.languages.Prism_clojure;\nimport io.noties.prism4j.languages.Prism_cpp;\nimport io.noties.prism4j.languages.Prism_csharp;\nimport io.noties.prism4j.languages.Prism_css;\nimport io.noties.prism4j.languages.Prism_css_extras;\nimport io.noties.prism4j.languages.Prism_dart;\nimport io.noties.prism4j.languages.Prism_git;\nimport io.noties.prism4j.languages.Prism_go;\nimport io.noties.prism4j.languages.Prism_groovy;\nimport io.noties.prism4j.languages.Prism_java;\nimport io.noties.prism4j.languages.Prism_javascript;\nimport io.noties.prism4j.languages.Prism_json;\nimport io.noties.prism4j.languages.Prism_kotlin;\nimport io.noties.prism4j.languages.Prism_latex;\nimport io.noties.prism4j.languages.Prism_makefile;\nimport io.noties.prism4j.languages.Prism_markdown;\nimport io.noties.prism4j.languages.Prism_markup;\nimport io.noties.prism4j.languages.Prism_python;\nimport io.noties.prism4j.languages.Prism_scala;\nimport io.noties.prism4j.languages.Prism_sql;\nimport io.noties.prism4j.languages.Prism_swift;\nimport io.noties.prism4j.languages.Prism_yaml;\n\npublic class BaseCodeGrammar implements GrammarLocator {\n\n    @SuppressWarnings(\"ConstantConditions\")\n    private static final Prism4j.Grammar NULL =\n            new Prism4j.Grammar() {\n                @NonNull\n                @Override\n                public String name() {\n                    return null;\n                }\n                @NonNull\n                @Override\n                public List<Prism4j.Token> tokens() {\n                    return null;\n                }\n            };\n    private final Map<String, Prism4j.Grammar> cache = new HashMap<>(3);\n    @Nullable\n    @Override\n    public Prism4j.Grammar grammar(@NonNull Prism4j prism4j, @NonNull String language) {\n        final String name = realLanguageName(language);\n        Prism4j.Grammar grammar = cache.get(name);\n        if (grammar != null) {\n            if (NULL == grammar) {\n                grammar = null;\n            }\n            return grammar;\n        }\n        grammar = obtainGrammar(prism4j, name);\n        if (grammar == null) {\n            cache.put(name, NULL);\n        } else {\n            cache.put(name, grammar);\n            triggerModify(prism4j, name);\n        }\n        return grammar;\n    }\n    @NonNull\n    protected String realLanguageName(@NonNull String name) {\n        final String out;\n        switch (name) {\n            case \"js\":\n                out = \"javascript\";\n                break;\n            case \"xml\":\n            case \"html\":\n            case \"mathml\":\n            case \"svg\":\n                out = \"markup\";\n                break;\n            case \"dotnet\":\n                out = \"csharp\";\n                break;\n            case \"jsonp\":\n                out = \"json\";\n                break;\n            default:\n                out = name;\n        }\n        return out;\n    }\n    @Nullable\n    protected Prism4j.Grammar obtainGrammar(@NonNull Prism4j prism4j, @NonNull String name) {\n        final Prism4j.Grammar grammar;\n        switch (name) {\n            case \"brainfuck\":\n                grammar = Prism_brainfuck.create(prism4j);\n                break;\n            case \"c\":\n                grammar = Prism_c.create(prism4j);\n                break;\n            case \"clike\":\n                grammar = Prism_clike.create(prism4j);\n                break;\n            case \"clojure\":\n                grammar = Prism_clojure.create(prism4j);\n                break;\n            case \"cpp\":\n                grammar = Prism_cpp.create(prism4j);\n                break;\n            case \"csharp\":\n                grammar = Prism_csharp.create(prism4j);\n                break;\n            case \"css\":\n                grammar = Prism_css.create(prism4j);\n                break;\n            case \"css-extras\":\n                grammar = Prism_css_extras.create(prism4j);\n                break;\n            case \"dart\":\n                grammar = Prism_dart.create(prism4j);\n                break;\n            case \"git\":\n                grammar = Prism_git.create(prism4j);\n                break;\n            case \"go\":\n                grammar = Prism_go.create(prism4j);\n                break;\n            case \"groovy\":\n                grammar = Prism_groovy.create(prism4j);\n                break;\n            case \"java\":\n                grammar = Prism_java.create(prism4j);\n                break;\n            case \"javascript\":\n                grammar = Prism_javascript.create(prism4j);\n                break;\n            case \"json\":\n                grammar = Prism_json.create(prism4j);\n                break;\n            case \"kotlin\":\n                grammar = Prism_kotlin.create(prism4j);\n                break;\n            case \"latex\":\n                grammar = Prism_latex.create(prism4j);\n                break;\n            case \"makefile\":\n                grammar = Prism_makefile.create(prism4j);\n                break;\n            case \"markdown\":\n                grammar = Prism_markdown.create(prism4j);\n                break;\n            case \"markup\":\n                grammar = Prism_markup.create(prism4j);\n                break;\n            case \"python\":\n                grammar = Prism_python.create(prism4j);\n                break;\n            case \"scala\":\n                grammar = Prism_scala.create(prism4j);\n                break;\n            case \"sql\":\n                grammar = Prism_sql.create(prism4j);\n                break;\n            case \"swift\":\n                grammar = Prism_swift.create(prism4j);\n                break;\n            case \"yaml\":\n                grammar = Prism_yaml.create(prism4j);\n                break;\n            default:\n                grammar = null;\n        }\n        return grammar;\n    }\n    protected void triggerModify(@NonNull Prism4j prism4j, @NonNull String name) {\n        switch (name) {\n            case \"markup\":\n                prism4j.grammar(\"css\");\n                prism4j.grammar(\"javascript\");\n                break;\n            case \"css\":\n                prism4j.grammar(\"css-extras\");\n                break;\n        }\n    }\n    @Override\n    @NonNull\n    public Set<String> languages() {\n        final Set<String> set = new HashSet<String>(25);\n        set.add(\"brainfuck\");\n        set.add(\"c\");\n        set.add(\"clike\");\n        set.add(\"clojure\");\n        set.add(\"cpp\");\n        set.add(\"csharp\");\n        set.add(\"css\");\n        set.add(\"css-extras\");\n        set.add(\"dart\");\n        set.add(\"git\");\n        set.add(\"go\");\n        set.add(\"groovy\");\n        set.add(\"java\");\n        set.add(\"javascript\");\n        set.add(\"json\");\n        set.add(\"kotlin\");\n        set.add(\"latex\");\n        set.add(\"makefile\");\n        set.add(\"markdown\");\n        set.add(\"markup\");\n        set.add(\"python\");\n        set.add(\"scala\");\n        set.add(\"sql\");\n        set.add(\"swift\");\n        set.add(\"yaml\");\n        return set;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-syntax-highlight/src/main/java/io/noties/markwon/syntax/FixPrism4j.java",
    "content": "package io.noties.markwon.syntax;\n\nimport androidx.annotation.NonNull;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport io.noties.prism4j.GrammarLocator;\nimport io.noties.prism4j.Prism4j;\nimport io.noties.prism4j.TextImpl;\n\npublic class FixPrism4j extends Prism4j {\n    public FixPrism4j(GrammarLocator grammarLocator) {\n        super(grammarLocator);\n    }\n\n    @NonNull\n    @Override\n    public List<Node> tokenize(@NonNull String text, @NonNull Grammar grammar) {\n        try {\n            return super.tokenize(text, grammar);\n        } catch (Throwable e) {\n            List<Node> entries = new ArrayList<>();\n            entries.add(new TextImpl(text));\n            return entries;\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-syntax-highlight/src/main/java/io/noties/markwon/syntax/Prism4jSyntaxHighlight.java",
    "content": "package io.noties.markwon.syntax;\n\nimport android.text.SpannableStringBuilder;\nimport android.text.TextUtils;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport io.noties.prism4j.Prism4j;\n\npublic class Prism4jSyntaxHighlight implements SyntaxHighlight {\n\n    @NonNull\n    public static Prism4jSyntaxHighlight create(\n            @NonNull Prism4j prism4j,\n            @NonNull Prism4jTheme theme) {\n        return new Prism4jSyntaxHighlight(prism4j, theme, null);\n    }\n\n    @NonNull\n    public static Prism4jSyntaxHighlight create(\n            @NonNull Prism4j prism4j,\n            @NonNull Prism4jTheme theme,\n            @Nullable String fallback) {\n        return new Prism4jSyntaxHighlight(prism4j, theme, fallback);\n    }\n\n    private final Prism4j prism4j;\n    private final Prism4jTheme theme;\n    private final String fallback;\n\n    protected Prism4jSyntaxHighlight(\n            @NonNull Prism4j prism4j,\n            @NonNull Prism4jTheme theme,\n            @Nullable String fallback) {\n        this.prism4j = prism4j;\n        this.theme = theme;\n        this.fallback = fallback;\n    }\n\n    @NonNull\n    @Override\n    public CharSequence highlight(@Nullable String info, @NonNull String code, StringBuilder language) {\n\n        // @since 4.2.2\n        // although not null, but still is empty\n        if (code.isEmpty()) {\n            return code;\n        }\n\n        // if info is null, do not highlight -> LICENCE footer very commonly wrapped inside code\n        // block without syntax name specified (so, do not highlight)\n        return info == null\n                ? highlightNoLanguageInfo(code)\n                : highlightWithLanguageInfo(info, code, language);\n    }\n\n    @NonNull\n    protected CharSequence highlightNoLanguageInfo(@NonNull String code) {\n        return code;\n    }\n\n    @NonNull\n    protected CharSequence highlightWithLanguageInfo(@NonNull String info, @NonNull String code,\n                                                     StringBuilder languageBuilder) {\n\n        final CharSequence out;\n\n        final String language;\n        final Prism4j.Grammar grammar;\n        {\n            String _language = info;\n            Prism4j.Grammar _grammar = prism4j.grammar(info);\n            if (_grammar == null && !TextUtils.isEmpty(fallback)) {\n                _language = fallback;\n                _grammar = prism4j.grammar(fallback);\n            }\n            language = _language;\n            grammar = _grammar;\n        }\n\n        if (grammar != null) {\n            out = highlight(language, grammar, code);\n        } else {\n            out = code;\n        }\n\n        languageBuilder.append(language);\n        return out;\n    }\n\n    @NonNull\n    protected CharSequence highlight(@NonNull String language, @NonNull Prism4j.Grammar grammar, @NonNull String code) {\n        final SpannableStringBuilder builder = new SpannableStringBuilder();\n        final Prism4jSyntaxVisitor visitor = new Prism4jSyntaxVisitor(language, theme, builder);\n        visitor.visit(prism4j.tokenize(code, grammar));\n        return builder;\n    }\n\n    @NonNull\n    protected Prism4j prism4j() {\n        return prism4j;\n    }\n\n    @NonNull\n    protected Prism4jTheme theme() {\n        return theme;\n    }\n\n    @Nullable\n    protected String fallback() {\n        return fallback;\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-syntax-highlight/src/main/java/io/noties/markwon/syntax/Prism4jSyntaxVisitor.java",
    "content": "package io.noties.markwon.syntax;\n\nimport android.text.SpannableStringBuilder;\n\nimport androidx.annotation.NonNull;\n\nimport io.noties.prism4j.AbsVisitor;\nimport io.noties.prism4j.Prism4j;\n\nclass Prism4jSyntaxVisitor extends AbsVisitor {\n\n    private final String language;\n    private final Prism4jTheme theme;\n    private final SpannableStringBuilder builder;\n\n    Prism4jSyntaxVisitor(\n            @NonNull String language,\n            @NonNull Prism4jTheme theme,\n            @NonNull SpannableStringBuilder builder) {\n        this.language = language;\n        this.theme = theme;\n        this.builder = builder;\n    }\n\n    @Override\n    protected void visitText(@NonNull Prism4j.Text text) {\n        builder.append(text.literal());\n    }\n\n    @Override\n    protected void visitSyntax(@NonNull Prism4j.Syntax syntax) {\n\n        final int start = builder.length();\n        visit(syntax.children());\n        final int end = builder.length();\n\n        if (end != start) {\n            theme.apply(language, syntax, builder, start, end);\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-syntax-highlight/src/main/java/io/noties/markwon/syntax/Prism4jTheme.java",
    "content": "package io.noties.markwon.syntax;\n\nimport android.text.SpannableStringBuilder;\n\nimport androidx.annotation.ColorInt;\nimport androidx.annotation.NonNull;\n\nimport io.noties.prism4j.Prism4j;\n\npublic interface Prism4jTheme {\n\n    @ColorInt\n    int background();\n\n    @ColorInt\n    int textColor();\n\n    void apply(\n            @NonNull String language,\n            @NonNull Prism4j.Syntax syntax,\n            @NonNull SpannableStringBuilder builder,\n            int start,\n            int end\n    );\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-syntax-highlight/src/main/java/io/noties/markwon/syntax/Prism4jThemeBase.java",
    "content": "package io.noties.markwon.syntax;\n\nimport android.text.SpannableStringBuilder;\nimport android.text.Spanned;\nimport android.text.style.ForegroundColorSpan;\n\nimport androidx.annotation.ColorInt;\nimport androidx.annotation.FloatRange;\nimport androidx.annotation.IntRange;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport java.util.HashMap;\n\nimport io.noties.prism4j.Prism4j;\n\npublic abstract class Prism4jThemeBase implements Prism4jTheme {\n\n    @ColorInt\n    protected static int applyAlpha(@IntRange(from = 0, to = 255) int alpha, @ColorInt int color) {\n        return (color & 0x00FFFFFF) | (alpha << 24);\n    }\n\n    @ColorInt\n    protected static int applyAlpha(@FloatRange(from = .0F, to = 1.F) float alpha, @ColorInt int color) {\n        return applyAlpha((int) (255 * alpha + .5F), color);\n    }\n\n    protected static boolean isOfType(@NonNull String expected, @NonNull String type, @Nullable String alias) {\n        return expected.equals(type) || expected.equals(alias);\n    }\n\n    private final ColorHashMap colorHashMap;\n\n    protected Prism4jThemeBase() {\n        this.colorHashMap = init();\n    }\n\n    @NonNull\n    protected abstract ColorHashMap init();\n\n    @ColorInt\n    protected int color(@NonNull String language, @NonNull String type, @Nullable String alias) {\n\n        Color color = colorHashMap.get(type);\n        if (color == null\n                && alias != null) {\n            color = colorHashMap.get(alias);\n        }\n\n        return color != null\n                ? color.color\n                : 0;\n    }\n\n    @Override\n    public void apply(\n            @NonNull String language,\n            @NonNull Prism4j.Syntax syntax,\n            @NonNull SpannableStringBuilder builder,\n            int start,\n            int end) {\n\n        final String type = syntax.type();\n        final String alias = syntax.alias();\n\n        final int color = color(language, type, alias);\n        if (color != 0) {\n            applyColor(language, type, alias, color, builder, start, end);\n        }\n    }\n\n    @SuppressWarnings(\"unused\")\n    protected void applyColor(\n            @NonNull String language,\n            @NonNull String type,\n            @Nullable String alias,\n            @ColorInt int color,\n            @NonNull SpannableStringBuilder builder,\n            int start,\n            int end) {\n        builder.setSpan(new ForegroundColorSpan(color), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);\n    }\n\n    protected static class Color {\n\n        @NonNull\n        public static Color of(@ColorInt int color) {\n            return new Color(color);\n        }\n\n        @ColorInt\n        protected final int color;\n\n        protected Color(@ColorInt int color) {\n            this.color = color;\n        }\n    }\n\n    protected static class ColorHashMap extends HashMap<String, Color> {\n\n        @NonNull\n        protected ColorHashMap add(@ColorInt int color, String name) {\n            put(name, Color.of(color));\n            return this;\n        }\n\n        @NonNull\n        protected ColorHashMap add(\n                @ColorInt int color,\n                @NonNull String name1,\n                @NonNull String name2) {\n            final Color c = Color.of(color);\n            put(name1, c);\n            put(name2, c);\n            return this;\n        }\n\n        @NonNull\n        protected ColorHashMap add(\n                @ColorInt int color,\n                @NonNull String name1,\n                @NonNull String name2,\n                @NonNull String name3) {\n            final Color c = Color.of(color);\n            put(name1, c);\n            put(name2, c);\n            put(name3, c);\n            return this;\n        }\n\n        @NonNull\n        protected ColorHashMap add(@ColorInt int color, String... names) {\n            final Color c = Color.of(color);\n            for (String name : names) {\n                put(name, c);\n            }\n            return this;\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-syntax-highlight/src/main/java/io/noties/markwon/syntax/Prism4jThemeDarkula.java",
    "content": "package io.noties.markwon.syntax;\n\nimport android.text.SpannableStringBuilder;\nimport android.text.Spanned;\n\nimport androidx.annotation.ColorInt;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport io.noties.markwon.core.spans.EmphasisSpan;\nimport io.noties.markwon.core.spans.StrongEmphasisSpan;\n\npublic class Prism4jThemeDarkula extends Prism4jThemeBase {\n\n    @NonNull\n    public static Prism4jThemeDarkula create() {\n        return new Prism4jThemeDarkula(0xFF2d2d2d);\n    }\n\n    /**\n     * @param background color\n     * @since 3.0.0\n     */\n    @NonNull\n    public static Prism4jThemeDarkula create(@ColorInt int background) {\n        return new Prism4jThemeDarkula(background);\n    }\n\n    private final int background;\n\n    public Prism4jThemeDarkula(@ColorInt int background) {\n        this.background = background;\n    }\n\n    @Override\n    public int background() {\n        return background;\n    }\n\n    @Override\n    public int textColor() {\n        return 0xFFa9b7c6;\n    }\n\n    @NonNull\n    @Override\n    protected ColorHashMap init() {\n        return new ColorHashMap()\n                .add(0xFF808080, \"comment\", \"prolog\", \"cdata\")\n                .add(0xFFcc7832, \"delimiter\", \"boolean\", \"keyword\", \"selector\", \"important\", \"atrule\")\n                .add(0xFFa9b7c6, \"operator\", \"punctuation\", \"attr-name\")\n                .add(0xFFe8bf6a, \"tag\", \"doctype\", \"builtin\")\n                .add(0xFF6897bb, \"entity\", \"number\", \"symbol\")\n                .add(0xFF9876aa, \"property\", \"constant\", \"variable\")\n                .add(0xFF6a8759, \"string\", \"char\")\n                .add(0xFFbbb438, \"annotation\")\n                .add(0xFFa5c261, \"attr-value\")\n                .add(0xFF287bde, \"url\")\n                .add(0xFFffc66d, \"function\")\n                .add(0xFF364135, \"regex\")\n                .add(0xFF294436, \"inserted\")\n                .add(0xFF484a4a, \"deleted\");\n    }\n\n    @Override\n    protected void applyColor(@NonNull String language, @NonNull String type, @Nullable String alias, int color, @NonNull SpannableStringBuilder builder, int start, int end) {\n        super.applyColor(language, type, alias, color, builder, start, end);\n\n        if (isOfType(\"important\", type, alias)\n                || isOfType(\"bold\", type, alias)) {\n            builder.setSpan(new StrongEmphasisSpan(), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);\n        }\n\n        if (isOfType(\"italic\", type, alias)) {\n            builder.setSpan(new EmphasisSpan(), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-syntax-highlight/src/main/java/io/noties/markwon/syntax/Prism4jThemeDefault.java",
    "content": "package io.noties.markwon.syntax;\n\nimport android.text.SpannableStringBuilder;\nimport android.text.Spanned;\nimport android.text.style.BackgroundColorSpan;\n\nimport androidx.annotation.ColorInt;\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport io.noties.markwon.core.spans.EmphasisSpan;\nimport io.noties.markwon.core.spans.StrongEmphasisSpan;\n\npublic class Prism4jThemeDefault extends Prism4jThemeBase {\n\n    @NonNull\n    public static Prism4jThemeDefault create() {\n        return new Prism4jThemeDefault(0xFFf5f2f0);\n    }\n\n    /**\n     * @since 3.0.0\n     */\n    @NonNull\n    public static Prism4jThemeDefault create(@ColorInt int background) {\n        return new Prism4jThemeDefault(background);\n    }\n\n    private final int background;\n\n    public Prism4jThemeDefault(@ColorInt int background) {\n        this.background = background;\n    }\n\n    @Override\n    public int background() {\n        return background;\n    }\n\n    @Override\n    public int textColor() {\n        return 0xdd000000;\n    }\n\n    @NonNull\n    @Override\n    protected ColorHashMap init() {\n        return new ColorHashMap()\n                .add(0xFF708090, \"comment\", \"prolog\", \"doctype\", \"cdata\")\n                .add(0xFF999999, \"punctuation\")\n                .add(0xFF990055, \"property\", \"tag\", \"boolean\", \"number\", \"constant\", \"symbol\", \"deleted\")\n                .add(0xFF669900, \"selector\", \"attr-name\", \"string\", \"char\", \"builtin\", \"inserted\")\n                .add(0xFF9a6e3a, \"operator\", \"entity\", \"url\")\n                .add(0xFF0077aa, \"atrule\", \"attr-value\", \"keyword\")\n                .add(0xFFDD4A68, \"function\", \"class-name\")\n                .add(0xFFee9900, \"regex\", \"important\", \"variable\");\n    }\n\n    @Override\n    protected void applyColor(\n            @NonNull String language,\n            @NonNull String type,\n            @Nullable String alias,\n            @ColorInt int color,\n            @NonNull SpannableStringBuilder builder,\n            int start,\n            int end) {\n\n        if (\"css\".equals(language) && isOfType(\"string\", type, alias)) {\n            super.applyColor(language, type, alias, 0xFF9a6e3a, builder, start, end);\n            builder.setSpan(new BackgroundColorSpan(0x80ffffff), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);\n            return;\n        }\n\n        if (isOfType(\"namespace\", type, alias)) {\n            color = applyAlpha(.7F, color);\n        }\n\n        super.applyColor(language, type, alias, color, builder, start, end);\n\n        if (isOfType(\"important\", type, alias)\n                || isOfType(\"bold\", type, alias)) {\n            builder.setSpan(new StrongEmphasisSpan(), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);\n        }\n\n        if (isOfType(\"italic\", type, alias)) {\n            builder.setSpan(new EmphasisSpan(), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);\n        }\n    }\n}\n"
  },
  {
    "path": "Android/AntFluid/markwon-syntax-highlight/src/main/java/io/noties/markwon/syntax/SyntaxHighlightPlugin.java",
    "content": "package io.noties.markwon.syntax;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\n\nimport io.noties.markwon.AbstractMarkwonPlugin;\nimport io.noties.markwon.MarkwonConfiguration;\nimport io.noties.prism4j.Prism4j;\n\npublic class SyntaxHighlightPlugin extends AbstractMarkwonPlugin {\n\n    @NonNull\n    public static SyntaxHighlightPlugin create(\n            @NonNull Prism4j prism4j,\n            @NonNull Prism4jTheme theme) {\n        return create(prism4j, theme, null);\n    }\n\n    @NonNull\n    public static SyntaxHighlightPlugin create(\n            @NonNull Prism4j prism4j,\n            @NonNull Prism4jTheme theme,\n            @Nullable String fallbackLanguage) {\n        return new SyntaxHighlightPlugin(prism4j, theme, fallbackLanguage);\n    }\n\n    private final Prism4j prism4j;\n    private final Prism4jTheme theme;\n    private final String fallbackLanguage;\n\n    public SyntaxHighlightPlugin(\n            @NonNull Prism4j prism4j,\n            @NonNull Prism4jTheme theme,\n            @Nullable String fallbackLanguage) {\n        this.prism4j = prism4j;\n        this.theme = theme;\n        this.fallbackLanguage = fallbackLanguage;\n    }\n    public static SyntaxHighlightPlugin createDefault() {\n        return SyntaxHighlightPlugin.create(new FixPrism4j(new BaseCodeGrammar()), Prism4jThemeDefault.create(0));\n    }\n\n    @Override\n    public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) {\n        builder.syntaxHighlight(Prism4jSyntaxHighlight.create(prism4j, theme, fallbackLanguage));\n    }\n}"
  },
  {
    "path": "Android/AntFluid/markwon-syntax-highlight/src/test/java/io/noties/markwon/syntax/ExampleUnitTest.java",
    "content": "package io.noties.markwon.syntax;\n\nimport static org.junit.Assert.assertEquals;\n\nimport org.junit.Test;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "Android/AntFluid/settings.gradle",
    "content": "pluginManagement {\n    repositories {\n        google {\n            content {\n                includeGroupByRegex(\"com\\\\.android.*\")\n                includeGroupByRegex(\"com\\\\.google.*\")\n                includeGroupByRegex(\"androidx.*\")\n            }\n        }\n        mavenCentral()\n        gradlePluginPortal()\n    }\n}\ndependencyResolutionManagement {\n    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)\n    repositories {\n        google()\n        mavenCentral()\n    }\n}\n\nrootProject.name = \"AntFluidMarkdown\"\ninclude ':app-sample'\ninclude ':markwon-core'\ninclude ':markwon-syntax-highlight'\ninclude ':markwon-inline-parser'\ninclude ':markwon-image'\ninclude ':markwon-html'\ninclude ':markwon-ext-tasklist'\ninclude ':markwon-ext-tables'\ninclude ':markwon-ext-strikethrough'\ninclude ':markwon-ext-latex'\ninclude ':fluid-markdown'\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "## v1.0.11 (2026-01-30)\n### Added\n\n- `ohos` ohpm supports build artifacts for the x86_64 architecture on emulator.\n\n\n## v1.0.10 (2026-01-30)\n### Added\n\n- `ohos` Added `LaTeX` math formula support, leveraging `formula_hybrid` to generate formula images.\n- `ohos` Added `click event` to the Image node.\n\n### Fixed\n\n- `ohos` Fixed an issue where Unicode surrogate pairs were not rendered correctly during streaming output.\n\n\n## v1.0.9 (2026-01-15)\n### Added\n\n- `ohos` AST Service: introduced toHtml() to convert a Node into HTML format.\n- `ohos` EHtmlTag: enum type to declare built-in HTML tag names.\n- `ohos` HtmlTag: built-in tag list extended with the div tag.\n\n\n## v1.0.8 (2026-01-14)\n### Fixed\n\n- `ohos` Resolved the incorrect callback order in AST parsing tasks caused by StyledString.styledFromHtml.\n\n\n## v1.0.7 (2026-01-13)\n### Changed\n\n- `ohos` AST Parser: Introduced a queue mechanism to guarantee ordered callbacks.\n- `ohos` Fragment: Switched to an append-only update strategy during single-shot streaming, improving rendering performance.\n\n\n## v1.0.6 (2026-01-08)\n### Fixed\n\n- `ohos` Fixed an issue where Fragment can not refresh while @Param Node changed on Normal mode.\n\n\n## v1.0.5 (2026-01-08)\n### Fixed\n\n- `ohos` Fixed an issue where Fragment can not render on Normal mode.\n\n\n## v1.0.4 (2026-01-07)\n### Fixed\n\n- `ohos` Use the synchronous API of the uuid library to generate the AST Node model's hash, preventing timing issues caused by the async built-in crypto library.  \n- `ohos` Fixed an issue where the typing-finish event might not be emitted when deduplicating fragments.\n\n### Added\n- `ohos` Introduced a built-in plugin for the Markdown AST parser module.\n\n## v1.0.3 (2026-01-05)\n### Fixed\n\n- `ohos` Resolved an issue where `embed` components were not cleaned up promptly during streaming output, causing overlapping display.\n- `ohos` Fixed a problem where the `stop` interface for streaming output was not correctly bound.\n\n### Changed\n\n- `ohos` Refined the assembly and update strategy for the `likelyKey` of embed nodes to reduce rendering flicker during streaming output.\n- `ohos` Adjusted the parsing strategy for custom `icon` tags to comply with HTML void-element specifications.\n- `ohos` Updated the validation rules for the `Stopped` state in the streaming output control flow to prevent content that has already been stopped from being re-activated by the `resume` interface.\n\n### Added\n\n- `ohos` Introduced `hook-level` plugin customization capabilities in the rendering pipeline.\n- `ohos` Added built-in content deduplication during streaming output.\n- `ohos` Added a global scroll-state listener for main list scenarios; combined with safe `pause/resume` APIs for streaming output, it improves scrolling smoothness while streaming is active.\n- `ohos` Implemented a syntax-parsing queue control mechanism that guarantees asynchronous parse results are delivered in the order they were submitted.\n- `ohos` Introduced `Fragment-based` segmented rendering to mitigate slowdowns when streaming long-form content.\n\n\n## v1.0.2 (2025-12-19)\n### Changed\n- `ohos` Improved scrolling performance for multiple Markdown components on the list page.\n- `ohos` Adjusted the reuse-matching mechanism for embed nodes in streaming mode, allowing prior node types to change dynamically.\n\n### Added\n- `ohos` Added hook-level plugin support to the Styled model rendering module.\n\n\n## v1.0.1 (2025-12-16)\n### Fixed\n- `ohos` Fixed issue where the `pause` interface could not stop streaming output in typing mode.\n- `ohos` Fixed issue where table nodes could not be rendered correctly in typing mode.\n- `ohos` Fixed layout issue where table cells containing asynchronously rendered elements (e.g., images) failed to expand properly.\n- `ohos` Improved scrolling performance of tables within list views to eliminate stuttering and frame drops.\n- `ohos` Fixed paragraph indentation issue when a code block is nested inside a list.\n\n### Changed\n- `ohos` Default streaming output interval adjusted to `25 ms`.\n- `ohos` Console logs now output in `plain text` by default to simplify debugging.\n- `ohos` Ordered-list label now sourced from the node’s `info` field instead of the `index` field.\n\n### Added\n- `ohos` ImageService now supports `hook-level plugin`.\n- `ohos` Code blocks now expose a `copy code` action.\n- `ohos` Log now provides a `global interception configuration` API.\n- `ohos` New `landscape-detail component` for table views in horizontal screen scenarios.\n\n\n## v1.0.0 (2025-12-01)\n### Added\n- Support for HarmonyOS\n- Full Markdown syntax parsing using the markdown-it open-source library\n- Native layout and rendering based on HarmonyOS StyledString\n- Customizable themes, plugins, and events\n- Streaming output mode optimized for AI conversation scenarios\n\n\n## v0.1.1 (2025-10-28)\n### Fixed\n+ Fix Android platform bug: unordered list rendering crashes under certain custom styles.\n+ Fix Android platform bug: table parsing fails when text starts with leading spaces.\n+ Fix iOS platform bug: During streaming output, a section of markdown-formatted content fails to be correctly parsed and rendered when added incrementally via addStreamContent.\n+ Fix iOS platform bug: The list cell in the demo page AIChatViewController does not respond to gesture events.\n\n\n## v0.1.0 (2025-09-08)\n### Added\n+ Support for markdown syntax: titles, paragraphs, ordered lists, unordered lists, tables, code blocks, mathematical formulas, inline code blocks, quotes, dividing lines, footnotes, links, and images.\n+ Support for HTML tags:`<s>` `<sup>` `<sub>` `<mark>` `<a>` `<span>` `<cite>` `<del>` `<font>` `<img>` `<u>`, etc.\n+ Streaming rendering and one-time full rendering modes.\n+ Customizable rendering styles for Markdown syntax.\n+ Adjustable streaming speed via custom parameters.\n+ Event support for clickable elements, including click handling, visibility callbacks, and rendering status updates<font style=\"color:rgb(38, 38, 38);\">, etc.\n+ Added some new extended HTML tags such as `<iconlink>` `<icon>`in `AMHTMLTransformer` class.\n\n\n\n\n\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "## Contributing to FluidMarkdown\n\nThank you for your interest in contributing to FluidMarkdown!\n\n## Clone the code repository\n\n```plain\ngit clone git@github.com:antgroup/FluidMarkdown.git\n\ncd FluidMarkdown\n```\n\n## Make a change\n\n1. Create a new branch for your feature or fix\n\n```plain\ngit checkout -b feature/your-feature-name\n```\n\n2. Make changes and ensure\n    1. All tests pass\n    2. Code is properly formatted\n    3. Necessary comments are included<\n3. Write test cases for your changes\n\n## Submission guidelines\n\nPlease follow the commit log specification to get a clear historical commit record\n\n+ feat: New features\n+ fix: Bug fixes\n+ docs: Documentation changes\n+ style: Code style changes (formatting, etc.)\n+ refactor: Code changes neither fix bugs nor add functionality\n+ test: Add or update a test\n+ chore: Maintenance tasks\nFor example:\n\n```plain\nfeat: add support for custom code block themes\nfix: resolve markdown parsing issue with nested lists\ndocs: update README with new API examples\n```\n\n## Pull request review process\n\n1. Make sure your PR:\n    1. Has a clear, descriptive title\n    2. Contains a changeset (run `pnpm changeset` if one hasn’t been added)\n    3. Passes all CI checks. Including new feature testing\n    4. Updates documentation if necessary\n2. The PR description should include:\n    1. What changes have been made\n    2. Why these changes are necessary\n    3. Any major changes Screenshots/Demos of UI changes\n3. Uses keywords to link any related questions, e.g.Fixes #123 or Closes #456\n   \n## Coding style\n\n+ Follows the existing coding style in the project\n+ Uses meaningful variable and function names\n+ Adds comments to complex logic\n+ Keeps features small and focused\n\n## License\n\nBy contributing to FluidMarkdown, you agree that your contributions will be licensed under the Apache-2.0.\n\n  \n\n\n\n"
  },
  {
    "path": "HarmonyOS/.gitignore",
    "content": "/node_modules\n/oh_modules\n/local.properties\n/.idea\n**/build\n/.hvigor\n.cxx\n/.clangd\n/.clang-format\n/.clang-tidy\n**/.test\n/.appanalyzer\n.js.js\noh-package-lock.json5\n.idea/"
  },
  {
    "path": "HarmonyOS/AppScope/app.json5",
    "content": "{\n  \"app\": {\n    \"bundleName\": \"com.alipay.antmark\",\n    \"vendor\": \"example\",\n    \"versionCode\": 1000000,\n    \"versionName\": \"1.0.0\",\n    \"icon\": \"$media:layered_image\",\n    \"label\": \"$string:app_name\"\n  }\n}\n"
  },
  {
    "path": "HarmonyOS/AppScope/resources/base/element/string.json",
    "content": "{\n  \"string\": [\n    {\n      \"name\": \"app_name\",\n      \"value\": \"antmark\"\n    }\n  ]\n}\n"
  },
  {
    "path": "HarmonyOS/AppScope/resources/base/media/layered_image.json",
    "content": "{\n  \"layered-image\":\n  {\n    \"background\" : \"$media:background\",\n    \"foreground\" : \"$media:foreground\"\n  }\n}"
  },
  {
    "path": "HarmonyOS/build-profile.json5",
    "content": "{\n  \"app\": {\n    \"signingConfigs\": [\n      {\n        \"name\": \"default\",\n        \"type\": \"HarmonyOS\",\n        \"material\": {\n          \"certpath\": \"/Users/jiayou/.ohos/config/default_antmark_MVvdUkRSpNiaEZip4e-Mqm4nQPxwsd2Fq5cLIuNCgME=.cer\",\n          \"keyAlias\": \"debugKey\",\n          \"keyPassword\": \"0000001926108C826E4C8E37C30493BD181810976826C28D4C14912CD69EDA884602BD435E35588593\",\n          \"profile\": \"/Users/jiayou/.ohos/config/default_antmark_MVvdUkRSpNiaEZip4e-Mqm4nQPxwsd2Fq5cLIuNCgME=.p7b\",\n          \"signAlg\": \"SHA256withECDSA\",\n          \"storeFile\": \"/Users/jiayou/.ohos/config/default_antmark_MVvdUkRSpNiaEZip4e-Mqm4nQPxwsd2Fq5cLIuNCgME=.p12\",\n          \"storePassword\": \"0000001937A3895731CBEC45FF27E79F3E9D0AEAF029F167C70D6E67384207C86CAE36543785D4D028\"\n        }\n      }\n    ],\n    \"products\": [\n      {\n        \"name\": \"default\",\n        \"signingConfig\": \"default\",\n        \"targetSdkVersion\": \"6.0.0(20)\",\n        \"compatibleSdkVersion\": \"5.0.3(15)\",\n        \"runtimeOS\": \"HarmonyOS\",\n        \"buildOption\": {\n          \"strictMode\": {\n            \"caseSensitiveCheck\": true,\n            \"useNormalizedOHMUrl\": true\n          }\n        }\n      }\n    ],\n    \"buildModeSet\": [\n      {\n        \"name\": \"debug\",\n      },\n      {\n        \"name\": \"release\"\n      }\n    ]\n  },\n  \"modules\": [\n    {\n      \"name\": \"playground\",\n      \"srcPath\": \"./playground\",\n      \"targets\": [\n        {\n          \"name\": \"default\",\n          \"applyToProducts\": [\n            \"default\"\n          ]\n        }\n      ]\n    },\n    {\n      \"name\": \"markdown\",\n      \"srcPath\": \"./markdown\",\n      \"targets\": [\n        {\n          \"name\": \"default\",\n          \"applyToProducts\": [\n            \"default\"\n          ]\n        }\n      ]\n    }\n  ]\n}"
  },
  {
    "path": "HarmonyOS/code-linter.json5",
    "content": "{\n  \"files\": [\n    \"**/*.ets\"\n  ],\n  \"ignore\": [\n    \"**/src/ohosTest/**/*\",\n    \"**/src/test/**/*\",\n    \"**/src/mock/**/*\",\n    \"**/node_modules/**/*\",\n    \"**/oh_modules/**/*\",\n    \"**/build/**/*\",\n    \"**/.preview/**/*\"\n  ],\n  \"ruleSet\": [\n    \"plugin:@performance/recommended\",\n    \"plugin:@typescript-eslint/recommended\"\n  ],\n  \"rules\": {\n    \"@security/no-unsafe-aes\": \"error\",\n    \"@security/no-unsafe-hash\": \"error\",\n    \"@security/no-unsafe-mac\": \"warn\",\n    \"@security/no-unsafe-dh\": \"error\",\n    \"@security/no-unsafe-dsa\": \"error\",\n    \"@security/no-unsafe-ecdsa\": \"error\",\n    \"@security/no-unsafe-rsa-encrypt\": \"error\",\n    \"@security/no-unsafe-rsa-sign\": \"error\",\n    \"@security/no-unsafe-rsa-key\": \"error\",\n    \"@security/no-unsafe-dsa-key\": \"error\",\n    \"@security/no-unsafe-dh-key\": \"error\",\n    \"@security/no-unsafe-3des\": \"error\"\n  }\n}"
  },
  {
    "path": "HarmonyOS/hvigor/hvigor-config.json5",
    "content": "{\n  \"modelVersion\": \"5.1.1\",\n  \"dependencies\": {\n  },\n  \"execution\": {\n    // \"analyze\": \"normal\",                     /* Define the build analyze mode. Value: [ \"normal\" | \"advanced\" | false ]. Default: \"normal\" */\n    // \"daemon\": true,                          /* Enable daemon compilation. Value: [ true | false ]. Default: true */\n    // \"incremental\": true,                     /* Enable incremental compilation. Value: [ true | false ]. Default: true */\n    // \"parallel\": true,                        /* Enable parallel compilation. Value: [ true | false ]. Default: true */\n    // \"typeCheck\": false,                      /* Enable typeCheck. Value: [ true | false ]. Default: false */\n    // \"optimizationStrategy\": \"memory\"         /* Define the optimization strategy. Value: [ \"memory\" | \"performance\" ]. Default: \"memory\" */\n  },\n  \"logging\": {\n    // \"level\": \"info\"                          /* Define the log level. Value: [ \"debug\" | \"info\" | \"warn\" | \"error\" ]. Default: \"info\" */\n  },\n  \"debugging\": {\n    // \"stacktrace\": false                      /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */\n  },\n  \"nodeOptions\": {\n    // \"maxOldSpaceSize\": 8192                  /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/\n    // \"exposeGC\": true                         /* Enable to trigger garbage collection explicitly. Default: true*/\n  }\n}\n"
  },
  {
    "path": "HarmonyOS/hvigorfile.ts",
    "content": "import { appTasks } from '@ohos/hvigor-ohos-plugin';\n\nexport default {\n  system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */\n  plugins: []       /* Custom plugin to extend the functionality of Hvigor. */\n}"
  },
  {
    "path": "HarmonyOS/markdown/.gitignore",
    "content": ".cxx\n/build/\n/oh_modules\noh-package-lock.json5\n.DS_Store"
  },
  {
    "path": "HarmonyOS/markdown/BuildProfile.ets",
    "content": "/**\n * Use these variables when you tailor your ArkTS code. They must be of the const type.\n */\nexport const HAR_VERSION = '1.0.0';\nexport const BUILD_MODE_NAME = 'debug';\nexport const DEBUG = true;\nexport const TARGET_NAME = 'default';\n\n/**\n * BuildProfile Class is used only for compatibility purposes.\n */\nexport default class BuildProfile { \n\tstatic readonly HAR_VERSION = HAR_VERSION;\n\tstatic readonly BUILD_MODE_NAME = BUILD_MODE_NAME;\n\tstatic readonly DEBUG = DEBUG;\n\tstatic readonly TARGET_NAME = TARGET_NAME;\n}"
  },
  {
    "path": "HarmonyOS/markdown/CHANGELOG.md",
    "content": "## v1.0.11 (2026-01-30)\n### Added\n\n- `ohos` ohpm supports build artifacts for the x86_64 architecture on emulator.\n\n\n## v1.0.10 (2026-01-30)\n### Added\n\n- `ohos` Added `LaTeX` math formula support, leveraging `formula_hybrid` to generate formula images.\n- `ohos` Added `click event` to the Image node.\n\n### Fixed\n\n- `ohos` Fixed an issue where Unicode surrogate pairs were not rendered correctly during streaming output.\n\n\n## v1.0.9 (2026-01-15)\n### Added\n\n- `ohos` AST Service: introduced toHtml() to convert a Node into HTML format.\n- `ohos` EHtmlTag: enum type to declare built-in HTML tag names.\n- `ohos` HtmlTag: built-in tag list extended with the div tag.\n\n\n## v1.0.8 (2026-01-14)\n### Fixed\n\n- `ohos` Resolved the incorrect callback order in AST parsing tasks caused by StyledString.styledFromHtml.\n\n\n## v1.0.7 (2026-01-13)\n### Changed\n\n- `ohos` AST Parser: Introduced a queue mechanism to guarantee ordered callbacks.\n- `ohos` Fragment: Switched to an append-only update strategy during single-shot streaming, improving rendering performance.\n\n\n## v1.0.6 (2026-01-08)\n### Fixed\n\n- `ohos` Fixed an issue where Fragment can not refresh while @Param Node changed on Normal mode.\n\n\n## v1.0.5 (2026-01-08)\n### Fixed\n\n- `ohos` Fixed an issue where Fragment can not render on Normal mode.\n\n\n## v1.0.4 (2026-01-07)\n### Fixed\n\n- `ohos` Use the synchronous API of the uuid library to generate the AST Node model's hash, preventing timing issues caused by the async built-in crypto library.  \n- `ohos` Fixed an issue where the typing-finish event might not be emitted when deduplicating fragments.\n\n### Added\n- `ohos` Introduced a built-in plugin for the Markdown AST parser module.\n\n## v1.0.3 (2026-01-05)\n### Fixed\n\n- `ohos` Resolved an issue where `embed` components were not cleaned up promptly during streaming output, causing overlapping display.\n- `ohos` Fixed a problem where the `stop` interface for streaming output was not correctly bound.\n\n### Changed\n\n- `ohos` Refined the assembly and update strategy for the `likelyKey` of embed nodes to reduce rendering flicker during streaming output.\n- `ohos` Adjusted the parsing strategy for custom `icon` tags to comply with HTML void-element specifications.\n- `ohos` Updated the validation rules for the `Stopped` state in the streaming output control flow to prevent content that has already been stopped from being re-activated by the `resume` interface.\n\n### Added\n\n- `ohos` Introduced `hook-level` plugin customization capabilities in the rendering pipeline.\n- `ohos` Added built-in content deduplication during streaming output.\n- `ohos` Added a global scroll-state listener for main list scenarios; combined with safe `pause/resume` APIs for streaming output, it improves scrolling smoothness while streaming is active.\n- `ohos` Implemented a syntax-parsing queue control mechanism that guarantees asynchronous parse results are delivered in the order they were submitted.\n- `ohos` Introduced `Fragment-based` segmented rendering to mitigate slowdowns when streaming long-form content.\n\n\n## v1.0.2 (2025-12-19)\n### Changed\n- `ohos` Improved scrolling performance for multiple Markdown components on the list page.\n- `ohos` Adjusted the reuse-matching mechanism for embed nodes in streaming mode, allowing prior node types to change dynamically.\n\n### Added\n- `ohos` Added hook-level plugin support to the Styled model rendering module.\n\n\n## v1.0.1 (2025-12-16)\n### Fixed\n- `ohos` Fixed issue where the `pause` interface could not stop streaming output in typing mode.\n- `ohos` Fixed issue where table nodes could not be rendered correctly in typing mode.\n- `ohos` Fixed layout issue where table cells containing asynchronously rendered elements (e.g., images) failed to expand properly.\n- `ohos` Improved scrolling performance of tables within list views to eliminate stuttering and frame drops.\n- `ohos` Fixed paragraph indentation issue when a code block is nested inside a list.\n\n### Changed\n- `ohos` Default streaming output interval adjusted to `25 ms`.\n- `ohos` Console logs now output in `plain text` by default to simplify debugging.\n- `ohos` Ordered-list label now sourced from the node’s `info` field instead of the `index` field.\n\n### Added\n- `ohos` ImageService now supports `hook-level plugin`.\n- `ohos` Code blocks now expose a `copy code` action.\n- `ohos` Log now provides a `global interception configuration` API.\n- `ohos` New `landscape-detail component` for table views in horizontal screen scenarios.\n\n\n## v1.0.0 (2025-12-01)\n### Added\n- Support for HarmonyOS\n- Full Markdown syntax parsing using the markdown-it open-source library\n- Native layout and rendering based on HarmonyOS StyledString\n- Customizable themes, plugins, and events\n- Streaming output mode optimized for AI conversation scenarios\n\n\n## v0.1.1 (2025-10-28)\n### Fixed\n+ Fix Android platform bug: unordered list rendering crashes under certain custom styles.\n+ Fix Android platform bug: table parsing fails when text starts with leading spaces.\n+ Fix iOS platform bug: During streaming output, a section of markdown-formatted content fails to be correctly parsed and rendered when added incrementally via addStreamContent.\n+ Fix iOS platform bug: The list cell in the demo page AIChatViewController does not respond to gesture events.\n\n\n## v0.1.0 (2025-09-08)\n### Added\n+ Support for markdown syntax: titles, paragraphs, ordered lists, unordered lists, tables, code blocks, mathematical formulas, inline code blocks, quotes, dividing lines, footnotes, links, and images.\n+ Support for HTML tags:`<s>` `<sup>` `<sub>` `<mark>` `<a>` `<span>` `<cite>` `<del>` `<font>` `<img>` `<u>`, etc.\n+ Streaming rendering and one-time full rendering modes.\n+ Customizable rendering styles for Markdown syntax.\n+ Adjustable streaming speed via custom parameters.\n+ Event support for clickable elements, including click handling, visibility callbacks, and rendering status updates<font style=\"color:rgb(38, 38, 38);\">, etc.\n+ Added some new extended HTML tags such as `<iconlink>` `<icon>`in `AMHTMLTransformer` class.\n\n\n\n\n\n"
  },
  {
    "path": "HarmonyOS/markdown/Index.ets",
    "content": "export * from './src/main/ets/index';\n"
  },
  {
    "path": "HarmonyOS/markdown/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "HarmonyOS/markdown/README.md",
    "content": "# FluidMarkdown\nWe are committed to enabling the streaming rendering of Markdown content generated by large language models on the client side within AI-driven business applications.\n\n# Overview\nThis library is designed for native Android, iOS and HarmonyOS developers. Built on the open-source CommonMark parsing library, it supports core Markdown syntax and selected HTML tags, rendering them progressively within UI components. It exposes Markdown styling as a structured model, enabling customization and integration into your specific application contexts. For faster integration, refer to the sample code to preview the rendering effect based on input text.\n\n# Features\n+ Support for markdown syntax: titles, paragraphs, ordered lists, unordered lists, tables, code blocks, mathematical formulas, inline code blocks, quotes, dividing lines, footnotes, links, and images.\n+ Support for HTML tags:`<s>` `<sup>` `<sub>` `<mark>` `<a>` `<span>` `<cite>` `<del>` `<font>` `<img>` `<u>`, etc.\n+ Streaming rendering and one-time full rendering modes.\n+ Customizable rendering styles for Markdown syntax.\n+ Adjustable streaming speed via custom parameters.\n+ Event support for clickable elements, including click handling, visibility callbacks, and rendering status updates<font style=\"color:rgb(38, 38, 38);\">, etc.\n+ Added some new extended HTML tags such as `<iconlink>` `<icon>`in `AMHTMLTransformer` class.\n\n# Install\nThe source code of this project is open-source. For information on how to download and run the project, please refer to the file [INSTALL](https://github.com/antgroup/FluidMarkdown/blob/main/INSTALL.md).\n\n# Directory structure\n## iOS\n+ AntMarkdown —— a standard markdown parser and rendering module based on commonMark.\n+ FluidMarkdown —— Component for streaming output.\n\n## Android\n+ fluid-markdown —— Component for streaming output.\n+ markwon-xxx —— Syntax parsing and style rendering implementation based on the open-source markwon library.\n\n## HarmonyOS\n+ markdown —— the folder contains all the source code for the markdown component, such as syntax parsing, layout rendering, theme configuration, runtime services, etc.\n+ playground —— a demo to show markdown component feature list.\n\n``` shell\nyour/project/markdown/src/main/ets\n├── engine\t\t\t\t\t//\t[folder] engine manages all services and plugins at runtime.\n├── index.ets       //  [file]   default exports.\n├── markdown.ets\t\t//\t[file]   markdown component compliant with the @ComponentV2 specification.\n├── render\t\t\t\t\t//\t[folder] rendering-related logic based on the StyledString mechanism.\n├── service\t\t\t\t\t//\t[folder] runtime service modules, such as syntax parsing, code highlighting, etc.\n├── theme\t\t\t\t\t\t//\t[folder] style and theme-related logic based on the StyledString mechanism.\n└── util\t\t\t\t\t\t//\t[folder] built-in utility api.\n```\n\n# Usage\n## iOS\n+ Native API： `AMXMarkdownWidget.h` is summary header file of the open API. The following is the general calling process of streaming rendering components.\n    1. Create a TextView instance.\n    2. Generate default styles and set custom styles ( if needed )\n    3. Begin streaming the Markdown content.\n    4. Append data dynamically during rendering.\n    5. Adjust list scrolling in response to content size changes in the TextView.\n    6. Handle completion when rendering is finished.\n\n```objectivec\nAMXMarkdownTextView* contentTextView = [[AMXMarkdownTextView alloc] initWithFrame_ant_mark:CGRectMake(0, 0, screenWidht - 20 * 2, 1)];\n\n// get default style config\nAMXMarkdownStyleConfig* config = [AMXMarkdownStyleConfig defaultConfig];\n\n// modify code block style for example\nconfig.codeBlockConfig.backgroundColor = [UIColor greenColor];\n\n// set the style with unique Id\n[[AMXRenderService shared] setMarkdownStyleWithId:config styleId:@\"demo\"];\n\n// begin print\n[self.contentTextView startStreamingWithContent:@\"testing data\"];\n\n// append content during printing\n[self.contentTextView addStreamContent:@\"**append test data**\"];\n\n// stop print when you need\n[self.contentTextView stop];\n```\n\n```objectivec\n@interface StreamPreviewViewController ()<AMXMarkdownTextViewDelegate>\n-(void)initUI\n{\n    // set delegate\n    self.contentTextView.textViewDelegate = self;\n}\n// size change delegate\n-(void)onSizeChange:(CGSize)size\n{\n    // adjust size of AMXMarkdownTextView and container view\n    [self.contentTextView setFrame:CGRectMake(0, 0, self.contentTextView.frame.size.width, size.height)];\n    [self.containerView setContentSize:size];\n    CGPoint bottomOffset = CGPointMake(0, self.containerView.contentSize.height - self.containerView.bounds.size.height);\n    if (bottomOffset.y > 0) {\n        // scroll the container view to bottom\n        [self.containerView setContentOffset:bottomOffset animated:NO];\n    }\n}\n```\n\n\n\n+ Sample Description \n    1. The `StreamPreviewViewController` class is a sample page for previewing streaming output.\n    2. The `AIChatViewController` class demonstrates FluidMarkdown usage in simulated AI conversation scenarios. Note that the conversation data is statically defined and intended solely for rendering demonstration purposes.\n\n![StreamingPreview](https://github.com/antgroup/FluidMarkdown/blob/main/media/StreamViewController.gif)![AIChat](https://github.com/antgroup/FluidMarkdown/blob/main/media/AIChatViewController.gif)\n\n## Android\n1. Initialize by calling AFMInitializer.init(context, backgroundTaskHandler, imageHandler, logHandler) once globally. Except for context, all other parameters can be null.\n2. Create PrinterMarkDownTextView to display markdown content.\n3. Create MarkdownStyles to set render styles.\n4. **Call PrinterMarkDownTextView.init()** to bind MarkdownStyles and ElementClickEventCallback.  Must be called, MarkdownStyles cannot be null.\n5. Set markdown content or call the print start method.\n\n```java\nAFMInitializer.init(context, null, null, null);\n// Create PrinterMarkDownTextView\nPrinterMarkDownTextView markdownTextView = findViewById(R.id.markdown_view);\n\n// Create MarkdownStyles，or you can also create custom styles with new MarkdownStyles()\nMarkdownStyles styles = MarkdownStyles.getDefaultStyles();\n// set style sample\nstyles.linkStyle().icon(\"https://you_image_url\");\nstyles.setTitleStyle(0, TitleStyle.create(1.5f).icon(https://you_image_url));// Set title level 1 style\n\n// bind MarkdownStyles and ElementClickEventCallback. \nmarkdownTextView.init(styles, elementClickEventCallback);\n// Set markdown content or you can call the startPrinting(content) to starting printing.\nmarkdownTextView.setMarkdownText(markdown);\n```\n\n+ Sample Description \n    - MainActivity - Markdown normal mode sample.\n    - PrinterActivity - Streaming print sample.\n    - ListActivity - Streaming print list sample.\n\n![print](https://github.com/antgroup/FluidMarkdown/blob/main/media/android-print.gif)![list](https://github.com/antgroup/FluidMarkdown/blob/main/media/android-list.gif)\n\n## HarmonyOS\n### Combine Markdown\n+ Import and combine the Markdown component in your page `build()` method.\n+ Bind markdown-formatted content text via the `@Param content` parameter.\n+ Handle various callback events inside the Markdown component to enhance the business interaction flow, such as `@Event onMarkdownAreaChange`, `@Event onMarkdownNodeClick`, etc.\n\n> Install dependency via ohpm: ohpm install fluid-markdown\n\n``` ts\nimport { Markdown, EMarkdownMode } from 'fluid-markdown';\n\n@ComponentV2\nexport struct MyComponent {\n  @Param content: string;\n  private scroller: Scroller = new Scroller();\n\n  build() {\n      Scroll(this.scroller) {\n        Markdown({\n          content: this.content,\n          mode: EMarkdownMode.Normal,\n          onMarkdownAreaChange: () => {},\n          onMarkdownNodeClick: data => {},\n        })\n          .margin(12)\n      }\n      .width('100%')\n      .height('100%')\n      .scrollable(ScrollDirection.Vertical)\n      .margin(12)\n  }\n}\n```\n\n### Streaming Output\n+ Enable streaming output mode by setting the `@Param` mode parameter to `EMarkdownMode.Typing`.\n+ Create a `MarkdownController` instance and bind it to the `@Param controller` parameter to manage the streaming output process, such as `update()`, `pause()`, `resume()`, etc.\n+ Note: Control methods of `MarkdownController`, such as `update()`, can only be reliably executed within the `@Event onMarkdownTypingReady` callback event.\n+ Note: The `@Param content` parameter will be ignored in streaming output mode.\n\n``` ts\nimport { \n  Markdown, EMarkdownMode, MarkdownController, ETypingMode,\n} from 'fluid-markdown';\n\n@ComponentV2\nexport struct MyComponent {\n  private scroller: Scroller = new Scroller();\n  private markdownController: MarkdownController = new MarkdownController();\n\n  build() {\n      Scroll(this.scroller) {\n        Markdown({\n          controller: this.markdownController,\n          mode: EMarkdownMode.Typing,\n          onMarkdownTypingReady: () => {\n            this.markdownController.typing.update('Hello FluidMarkdown', ETypingMode.Begin);\n          },\n        })\n          .margin(12)\n      }\n      .width('100%')\n      .height('100%')\n      .scrollable(ScrollDirection.Vertical)\n      .margin(12)\n  }\n}\n```\n\n### Theme Config\n+ Create a new Engine instance and bind it to the `@Param engine` parameter.\n+ Set `ITheme` properties for theme styling through the `theme service` within the Engine.\n\n``` ts\nimport { Markdown, EMarkdownMode, BaseEngine } from 'fluid-markdown';\n\n@ComponentV2\nexport struct MyComponent {\n  @Param content: string;\n  private scroller: Scroller = new Scroller();\n  private engine: BaseEngine = new BaseEngine();\n\n  aboutToAppear() {\n    this.engine.theme!.theme!.document!.font!.fontColor = Color.Red;\n  }\n  \n  build() {\n      Scroll(this.scroller) {\n        Markdown({\n          engine: this.engine,\n          content: this.content,\n          mode: EMarkdownMode.Normal,\n          onMarkdownAreaChange: () => {},\n          onMarkdownNodeClick: data => {},\n        })\n          .margin(12)\n      }\n      .width('100%')\n      .height('100%')\n      .scrollable(ScrollDirection.Vertical)\n      .margin(12)\n  }\n}\n```\n\n### Playground\nBuild and run the Playground app to try out FluidMarkdown—have fun!\n![fluid-markdown-ohos-playground](https://mdn.alipayobjects.com/huamei_iobbj9/afts/img/A*uca1RLdcS90AAAAAgEAAAAgAetF-AQ/original)\n\n# Known Issues\n+ Clickable elements within tables appear as plain text and are not interactive.\n+ Nested HTML tags within table cells are not supported.\n+ Tables on Android may overflow their container and do not support horizontal scrolling.\n+ LaTex capability on the HarmonyOS platform is under development and not yet available.\n+ The minimum required HarmonyOS API version is 15 or higher.\n\n# Contribute\nThe FluidMarkdown team welcomes individual or team contributions. For more informations, please refer to the file [CONTRIBUTING](https://github.com/antgroup/FluidMarkdown/blob/main/CONTRIBUTING.md).\n\n# Licensing\nAll source code is licensed under the Apache 2.0 license. For details, please refer to [LICENSE](https://github.com/antgroup/FluidMarkdown/blob/main/LICENSE).\n\nWe acknowledge the following open-source projects:\n\n+ [noties/Markwon](https://github.com/noties/Markwon)\n    - license: Apache-2.0\n+ [indragiek/CocoaMarkdown](https://github.com/indragiek/CocoaMarkdown)\n    - license: <font style=\"color:rgb(31, 35, 40);\">MIT License</font>\n+ [commonmark/commonmark-spec](https://commonmark.org/)\n    - license: <font style=\"color:rgb(31, 35, 40);\">MIT License</font>\n+ [https://github.com/max-lfeng/iosMath/](https://github.com/max-lfeng/iosMath/)\n    - license: <font style=\"color:rgb(31, 35, 40);\">MIT License</font>\n+ [https://github.com/mattt/Ono/](https://github.com/mattt/Ono/)\n    - license: <font style=\"color:rgb(31, 35, 40);\">MIT License</font>\n+ [markdown-it](https://github.com/markdown-it/markdown-it/blob/master/LICENSE)\n    - license: <font style=\"color:rgb(31, 35, 40);\">MIT License</font>\n+ [highlight.js](https://github.com/highlightjs/highlight.js/blob/main/LICENSE)\n    - license: <font style=\"color:rgb(31, 35, 40);\">BSD 3-Clause License</font>\n+ [csstree](https://github.com/csstree/csstree/blob/master/LICENSE)\n    - license: <font style=\"color:rgb(31, 35, 40);\">MIT License</font>\n+ [htmlparser2](https://github.com/fb55/htmlparser2/blob/master/LICENSE)\n    - license: <font style=\"color:rgb(31, 35, 40);\">MIT License</font>\n\n# Acknowledgements and References\n+ All developers who have contributed code to the Ant Markdown component\n+ Thanks to the following open source projects：\n    - [noties/Markwon](https://github.com/noties/Markwon)\n    - [indragiek/CocoaMarkdown](https://github.com/indragiek/CocoaMarkdown)\n    - [commonmark/commonmark-spec](https://commonmark.org/)\n    - [https://github.com/max-lfeng/iosMath/](https://github.com/max-lfeng/iosMath/)\n    - [https://github.com/mattt/Ono/](https://github.com/mattt/Ono/)\n    - [markdown-it](https://github.com/markdown-it/markdown-it/)\n    - [highlight.js](https://github.com/highlightjs/highlight.js/)\n    - [csstree](https://github.com/csstree/csstree/)\n    - [htmlparser2](https://github.com/fb55/htmlparser2/)\n\n\n"
  },
  {
    "path": "HarmonyOS/markdown/build-profile.json5",
    "content": "{\n  \"apiType\": \"stageMode\",\n  \"buildOption\": {\n    \"externalNativeOptions\": {\n      \"path\": \"./src/main/cpp/CMakeLists.txt\",\n      \"arguments\": \"\",\n      \"cppFlags\": \"\",\n      \"abiFilters\": [ \"arm64-v8a\", \"x86_64\" ]\n    },\n    \"resOptions\": {\n      \"copyCodeResource\": {\n        \"enable\": false\n      }\n    }\n  },\n  \"buildOptionSet\": [\n    {\n      \"name\": \"release\",\n      //配置筛选har依赖.so资源文件的过滤规则\n      \"napiLibFilterOption\": {\n        //允许当.so重名冲突时，使用高优先级的.so文件覆盖低优先级的.so文件\n        \"enableOverride\": true\n      },\n      \"arkOptions\": {\n        \"obfuscation\": {\n          \"ruleOptions\": {\n            \"enable\": true,\n            \"files\": [\n              \"./obfuscation-rules.txt\"\n            ]\n          },\n          \"consumerFiles\": [\n            \"./consumer-rules.txt\"\n          ]\n        }\n      }\n    },\n    {\n      \"name\": \"debug\",\n      //配置筛选har依赖.so资源文件的过滤规则\n      \"napiLibFilterOption\": {\n        //允许当.so重名冲突时，使用高优先级的.so文件覆盖低优先级的.so文件\n        \"enableOverride\": true\n      },\n      \"arkOptions\": {\n        \"obfuscation\": {\n          \"ruleOptions\": {\n            \"enable\": true,\n            \"files\": [\n              \"./obfuscation-rules.txt\"\n            ]\n          },\n          \"consumerFiles\": [\n            \"./consumer-rules.txt\"\n          ]\n        }\n      }\n    }\n  ],\n  \"targets\": [\n    {\n      \"name\": \"default\"\n    }\n  ]\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/consumer-rules.txt",
    "content": ""
  },
  {
    "path": "HarmonyOS/markdown/hvigorfile.ts",
    "content": "import { harTasks } from '@ohos/hvigor-ohos-plugin';\n\nexport default {\n  system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */\n  plugins: []       /* Custom plugin to extend the functionality of Hvigor. */\n}"
  },
  {
    "path": "HarmonyOS/markdown/obfuscation-rules.txt",
    "content": "# Define project specific obfuscation rules here.\n# You can include the obfuscation configuration files in the current module's build-profile.json5.\n#\n# For more details, see\n#   https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5\n\n# Obfuscation options:\n# -disable-obfuscation: disable all obfuscations\n# -enable-property-obfuscation: obfuscate the property names\n# -enable-toplevel-obfuscation: obfuscate the names in the global scope\n# -compact: remove unnecessary blank spaces and all line feeds\n# -remove-log: remove all console.* statements\n# -print-namecache: print the name cache that contains the mapping from the old names to new names\n# -apply-namecache: reuse the given cache file\n\n# Keep options:\n# -keep-property-name: specifies property names that you want to keep\n# -keep-global-name: specifies names that you want to keep in the global scope\n\n-enable-property-obfuscation\n-enable-toplevel-obfuscation\n-enable-filename-obfuscation\n-enable-export-obfuscation"
  },
  {
    "path": "HarmonyOS/markdown/oh-package.json5",
    "content": "{\n  \"name\": \"fluid-markdown\",\n  \"version\": \"1.0.11\",\n  \"description\": \"Streaming Markdown engine for AI chat on mobile.\",\n  \"keywords\": [ \"markdown\", \"chat\", \"native\", \"stream-output\", \"ai\", \"ios\", \"android\", \"harmonyos\" ],\n  \"homepage\": \"https://github.com/antgroup/FluidMarkdown\",\n  \"compatibleSdkVersion\": \"15\",\n  \"main\": \"Index.ets\",\n  \"author\": \"jiayou-tss\",\n  \"license\": \"Apache-2.0\",\n  \"dependencies\": {\n    \"liblatexentry.so\": \"file:./src/main/cpp/types/liblatexentry\"\n  }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/CMakeLists.txt",
    "content": "# the minimum version of CMake.\ncmake_minimum_required(VERSION 3.5.0)\nproject(latex)\n\nset(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})\n\nadd_subdirectory(formula-ffi/ffi)\n\nif(DEFINED PACKAGE_FIND_FILE)\n    include(${PACKAGE_FIND_FILE})\nendif()\n\ninclude_directories(${NATIVERENDER_ROOT_PATH}\n                    ${NATIVERENDER_ROOT_PATH}/include\n                    \"formula-ffi/ffi/latex/src\"\n                    \"formula-ffi/ffi/latex\"\n                    \"formula-ffi/ffi/latex/src/xml\"\n                    \"formula-ffi/ffi/ffi\"\n                    \"formula-ffi/ffi/third_party_bounds_checking_function/include\"\n                    )\n\nadd_library(latexentry SHARED napi_init.cpp)\ntarget_link_libraries(latexentry PUBLIC latex libace_napi.z.so libhilog_ndk.z.so)\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/.gitcode/ISSUE_TEMPLATE/bug.md",
    "content": "---\nname: 缺陷\nabout: 报告一个问题帮助我们改进\ntitle: 【缺陷】请输入您的标题\nlabels: [\"bug\"]\nassignees:\n---\n\n### 系统环境\n\n<!-- \n请在这里描述您的开发环境\n-->\n\n### 版本信息\n\n<!-- \n请在这里描述您的版本信息\n-->\n\n### 关联工具链 （可选项：Linux/Windows/Runtime/VM/VScode 插件/Terminal 工具链/其他）：\n\n<!-- \n请在这里描述您的关联工具链\n-->\n\n### 问题描述\n\n<!-- \n请在这里描述您遇到的问题\n-->\n\n### 复现步骤\n\n<!-- \n请在这里描述复现您所提出问题的步骤\n-->\n\n### 期望效果\n\n<!-- \n请在这里描述您认为无误的效果\n-->\n\n### 源码/附件\n\n<!-- \n请在这里输入可复现该问题的代码，或贴上可复现该问题的项目链接，或在附件上传可复现该问题的项目\n-->\n\n```cj\nmain() {\n    println(\"感谢您的关注！\")\n}\n```"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/.gitcode/ISSUE_TEMPLATE/question.md",
    "content": "---\nname: 咨询\nabout: 提出一个您对我们的问题\ntitle: 【咨询】请输入您的标题\nlabels: [\"question\"]\nassignees:\n---\n\n### 咨询问题\n\n<!-- \n请在这里描述您对我们的疑问\n-->\n\n### 咨询关键词\n\n<!-- \n请在这里描述您的问题的关键词\n-->"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/.gitcode/ISSUE_TEMPLATE/request.md",
    "content": "---\nname: 需求\nabout: 提出一个您对我们的需求\ntitle: 【需求】请输入您的标题\nlabels: [\"enhancement\"]\nassignees:\n---\n\n### 需求描述\n\n<!-- \n请在这里描述您对我们的需求\n-->\n\n### 需求价值\n\n<!-- \n请在这里描述您的需求的价值\n-->\n\n### 需求分析\n\n<!-- \n请在这里描述您的需求在业界相关领域实现情况\n-->\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/.gitcode/PULL_REQUEST_TEMPLATE.md",
    "content": "### 相关的Issue\n\n### 原因（目的、解决的问题等）\n\n### 描述（做了什么，变更了什么）\n\n### 测试用例（新增、改动、可能影响的功能）"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/.gitignore",
    "content": ".git/\r\n.gitee/\r\n.vscode/\r\n*.macrocall\r\n*.cj.macrocall\r\n.cache\r\nlib\r\ntarget\r\ncjpm.lock\r\nci_test\r\ntest_temp\r\ntest/log\r\ntest/tmp\r\ntest/report\r\nffi/build\r\nlog.txt"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/.gitmodules",
    "content": "[submodule \"ffi/latex\"]\n\tpath = ffi/latex\n\turl = https://gitcode.com/Cangjie-TPC/formula-ffi.git\n\tbranch = microtex-v0.0.1-fix\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/CHANGELOG.md",
    "content": "# v1.0.1\n\n1. 升级适配1.0.0\n2. 修复V显示不全\n3. 修复部分闪退bug\n\n# v0.0.1\n\n1. 提供生成解析数学公式接口\n2. 提供生成bitmap接口\n3. 提供生成图片资源接口\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/LICENSE",
    "content": " The MIT License (MIT)\r\n\r\n Copyright (c) 2020 Nano Michael\r\n\r\n Permission is hereby granted, free of charge, to any person obtaining a copy\r\n of this software and associated documentation files (the \"Software\"), to deal\r\n in the Software without restriction, including without limitation the rights\r\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n copies of the Software, and to permit persons to whom the Software is\r\n furnished to do so, subject to the following conditions:\r\n\r\n The above copyright notice and this permission notice shall be included in all\r\n copies or substantial portions of the Software.\r\n\r\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n SOFTWARE."
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/README.OpenSource",
    "content": "[\r\n    {\r\n        \"Name\": \"MicroTeX\",\r\n        \"License\": \"MIT License\",\r\n        \"License File\": \"LICENSE\",\r\n        \"Owner\": \"NanoMichael\"\r\n        \"Upstream URL\": \"https://github.com/NanoMichael/MicroTeX\",\r\n        \"Version Number\": \"v0.0.1\",\r\n        \"Description\": \" A dynamic, cross-platform, and embeddable LaTeX rendering library.\"\r\n    }\r\n]"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/README.md",
    "content": "<div align=\"center\">\n<h1>formula-ffi</h1>\n</div>\n\n<p align=\"center\">\n<img alt=\"\" src=\"https://img.shields.io/badge/release-v1.0.1-brightgreen\" style=\"display: inline-block;\" />\n<img alt=\"\" src=\"https://img.shields.io/badge/build-pass-brightgreen\" style=\"display: inline-block;\" />\n<img alt=\"\" src=\"https://img.shields.io/badge/cjc-v1.0.0-brightgreen\" style=\"display: inline-block;\" />\n<img alt=\"\" src=\"https://img.shields.io/badge/cjcov-NA-red\" style=\"display: inline-block;\" />\n<img alt=\"\" src=\"https://img.shields.io/badge/project-open-brightgreen\" style=\"display: inline-block;\" />\n</p>\n\n## 介绍\n\nformula 主要目的是显示用 LaTeX 编写的数学公式。\n\n### 特性\n\n- 🚀 特性1\n\n  提供生成解析数学公式接口\n\n- 🚀 特性2\n\n  提供生成bitmap接口\n\n- 💪 特性3\n\n  提供生成图片资源接口\n\n## 软件架构\n\n### 源码目录\n\n```shell\nformula\n├─ doc\n│  ├─ assets\n│  ├─ design.md\n│  └─ feature_api.md\n├─ ffi\n│  ├─ CMakeLists.txt\n│  ├─ ffi\n│  │  ├─ graphic_ohos.cpp\n│  │  ├─ graphic_ohos.h\n│  │  ├─ graphic_ohos_ffi.cpp\n│  │  ├─ latex_ffi.cpp\n│  │  ├─ render_ffi.cpp\n│  │  └─ utils.h\n│  └─ latex\n├─ README.md\n├─ src\n│  ├─ ffi.cj\n│  ├─ graphic2D.cj\n│  ├─ LaTex.cj\n│  └─ render.cj\n└─ test\n   ├─ HLT\n   └─ LLT\n\n```\n\n- `doc`  文档目录，用于存放设计、API接口等文档\n- `ffi` `ffi`接口\n- `src`  源码目录\n- `test` 测试目录\n\n### 接口说明\n\n主要类和函数接口说明详见 [API](./doc/feature_api.md)\n\n## 使用说明\n\n### 编译构建\n\n1. 代码下载：\n\n   ```shell\n   git clone --recursive https://gitcode.com/Cangjie-TPC/formula-ffi.git\n   ```\n\n2. 编译\n\n   1. 下载安装msys2和mingw64\n\n      msys2：https://github.com/msys2/msys2-installer/releases/download/2023-03-18/msys2-x86_64-20230318.exe\n\n      mingw64：https://github.com/niXman/mingw-builds-binaries/releases/download/8.5.0-rt_v10-rev0/x86_64-8.5.0-release-posix-seh-rt_v10-rev0.7z\n\n      将`x86_64-8.5.0-release-posix-seh-rt_v10-rev0.7z`解压到msys2的根目录\n\n   2. 下载cmake：https://github.com/Kitware/CMake/releases/download/v3.26.3/cmake-3.26.3-windows-x86_64.zip\n\n      将`cmake-3.26.3-windows-x86_64.zip`解压，将`cmake-3.26.3-windows-x86_64`目录下的所有文件夹拷贝到`msys2/usr/`目录\n\n      将 msys2\\mingw64\\bin目录下的 mingw32-make.exe 复制一份改成 make.exe\n\n   3. 下载安装DevecoStuido\n\n      DevecoStuido：https://developer.huawei.com/consumer/cn/download/\n\n      修改build-ohos.sh中的路径。ohos环境在DevEco Studio安装目录下sdk -> HarmonyOS-NEXT-DB3（有可能是DB2其他内容） -> openharmony下面\n\n   4. 仓颉交叉编译环境\n\n      修改cjpm.toml中${DEVECO_CANGJIE_HOME}变量。一般DevecoStuido安装仓颉插件之后仓颉SDK在C盘用户目录.cangjie-sdk下面。\n\n   5. 用mingw64进入项目根目录，执行`build-ohos.sh`\n\n      ```shell\n      ./build-ohos.sh\n      ```\n\n### 功能示例\n\n#### 生成bitmap功能示例\n\n功能示例描述:\n\n示例代码如下：\n\n```cangjie\nimport formula.*\nimport std.fs.*\n\nmain(): Int64 {\n\n    var latex = LaTeX(\"res\")\n    var str = ###\"\n\\sideset{^\\backprime}{'}\\sum_{x=1}^{\\infty} x\\sideset{a_1^2}{}\\sum_{x=1}^\\infty x_0\n\\\\\n\\sideset{_\\text{left bottom}'''}{_{\\text{right bottom}}'''}\\sum_{\\text{quite long text}}^\\infty x\n\\\\\n\\sideset{}{'}\n\\sum_{n<k,\\;\\text{$n$ odd}} nE_n\n\\\\\n\\sideset{}{'}\n\\sum^{n<k,\\;\\text{$n$ odd}} nE_n\n\\\\\nM_x''' M'''_x M^{'''}_x M_x{'''} M^{\\prime\\backprime}\n\"###\n    var r = latex.parse(str, 2000, 40.0, 10.0, 0xFF000000)\n    var w = r.getWidth()\n    var h = r.getHeight()\n    var g2 = Graphic2D(r, COLOR_FORMAT_RGB_565)\n    r.draw(g2, 0xFFFFFFFF)\n\n    var arr = r.toBitmap(g2)\n\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n    file.write(arr)\n    file.close()\n\n    return 0\n}\n```\n\n执行结果如下：\n\n![test](./doc/assets/test.bmp)\n\n## 约束与限制\n\n只适用ohos环境\n\n## 开源协议\n\n本项目基于 [MIT License](./LICENSE)，请自由的享受和参与开源。\n\n## 参与贡献\n\n欢迎给我们提交PR，欢迎给我们提交Issue，欢迎参与任何形式的贡献。\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/build-ohos.sh",
    "content": "#! /bin/bash\n\nmkdir -p ffi/build\nmkdir -p lib\ncd ffi/build\n\ncd ffi/build\n\n# -DCMAKE_CXX_COMPILER 和 -DCMAKE_CXX_FLAGS 路径自行设置\ncmake .. -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=\"D:/DevecoStudio_SDK/sdk/default/openharmony/native/llvm/bin/clang++.exe\" -DCMAKE_CXX_FLAGS=\"--sysroot=D:/DevecoStudio_SDK/sdk/default/openharmony/native/sysroot --target=x86_64-linux-ohos\" -DCMAKE_SYSTEM_NAME=linux -DCMAKE_SYSTEM_PROCESSOR=x86_64  -G \"MinGW Makefiles\" -DCMAKE_STRIP=\"D:/DevecoStudio_SDK/sdk/default/openharmony/native/llvm/bin/llvm-strip.exe\"\n\n# cmake .. -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=\"D:/DevecoStudio_SDK/sdk/default/openharmony/native/llvm/bin/clang++.exe\" -DCMAKE_CXX_FLAGS=\"--sysroot=D:/DevecoStudio_SDK/sdk/default/openharmony/native/sysroot --target=aarch64-linux-ohos\" -DCMAKE_SYSTEM_NAME=linux -DCMAKE_SYSTEM_PROCESSOR=aarch64  -G \"MinGW Makefiles\" -DCMAKE_STRIP=\"D:/DevecoStudio_SDK/sdk/default/openharmony/native/llvm/bin/llvm-strip.exe\"\nmake -j20\n\ncp liblatex.so ../../lib/\ncd ../../\ncjpm build --target aarch64-linux-ohos"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/cjpm.toml",
    "content": "[target]\n  [target.aarch64-linux-ohos]\n    compile-option = \"-B \\\"${DEVECO_CANGJIE_HOME}/compiler/third_party/llvm/bin\\\" -B \\\"${DEVECO_OH_NATIVE_HOME}/sysroot/usr/lib/aarch64-linux-ohos\\\" -L \\\"${DEVECO_OH_NATIVE_HOME}/sysroot/usr/lib/aarch64-linux-ohos\\\" -L \\\"${DEVECO_OH_NATIVE_HOME}/llvm/lib/clang/15.0.4/lib/aarch64-linux-ohos\\\" -L \\\"${DEVECO_OH_NATIVE_HOME}/llvm/lib/aarch64-linux-ohos\\\" -L \\\"${DEVECO_CANGJIE_HOME}/build/linux_ohos_aarch64_llvm/openssl\\\" --sysroot \\\"${DEVECO_OH_NATIVE_HOME}/sysroot\\\"\"\n    [target.aarch64-linux-ohos.bin-dependencies]\n      path-option = [ \"${AARCH64_LIBS}\", \"${AARCH64_MACRO_LIBS}\", \"${AARCH64_KIT_LIBS}\" ]\n      [target.aarch64-linux-ohos.bin-dependencies.package-option]\n  [target.x86_64-linux-ohos]\n    compile-option = \"-B \\\"${DEVECO_CANGJIE_HOME}/compiler/third_party/llvm/bin\\\" -B \\\"${DEVECO_OH_NATIVE_HOME}/sysroot/usr/lib/x86_64-linux-ohos\\\" -L \\\"${DEVECO_OH_NATIVE_HOME}/sysroot/usr/lib/x86_64-linux-ohos\\\" -L \\\"${DEVECO_OH_NATIVE_HOME}/llvm/lib/clang/15.0.4/lib/x86_64-linux-ohos\\\" -L \\\"${DEVECO_OH_NATIVE_HOME}/llvm/lib/x86_64-linux-ohos\\\" -L \\\"${DEVECO_CANGJIE_HOME}/build/linux_ohos_x86_64_llvm/openssl\\\" --sysroot \\\"${DEVECO_OH_NATIVE_HOME}/sysroot\\\"\"\n    [target.x86_64-linux-ohos.bin-dependencies]\n      path-option = [ \"${X86_64_OHOS_LIBS}\", \"${X86_64_OHOS_MACRO_LIBS}\", \"${X86_64_OHOS_KIT_LIBS}\" ]\n  [target.x86_64-unknown-windows-gnu]\n    [target.x86_64-unknown-windows-gnu.bin-dependencies]\n      path-option = [ \"${X86_64_LIBS}\", \"${X86_64_MACRO_LIBS}\" ]\n      [target.x86_64-unknown-windows-gnu.bin-dependencies.package-option]\n\n[dependencies]\n\n[ffi.c]\n  latex = {path = \"./libs/${ABI}/\"}\n\n[package]\n  cjc-version = \"1.0.1\"\n  compile-option = \"\"\n  description = \"nothing here\"\n  link-option = \"\"\n  name = \"formula\"\n  output-type = \"dynamic\"\n  src-dir = \"src\"\n  target-dir = \"\"\n  version = \"1.0.1\"\n  package-configuration = {}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/doc/feature_api.md",
    "content": "# formula库\n\n## 介绍\n\nformula 主要目的是显示用 LaTeX 编写的数学公式。参考地址：https://github.com/NanoMichael/MicroTeX\n\n## formula\n\n前置条件：NA\n\n场景：\n\n约束：\n\n### 1. Graphic2D\n\n#### 1.1 主要接口\n\n```\npublic class Graphic2D {\n    /*\n    * 初始化画布\n    *\n    * 参数 - render Render\n    * 参数 - colorFormat 位图像素存储格式\n    *\n    * 返回值 - Unit\n    */\n    public init(render: Render, colorFormat: ColorFormat)\n\n    /*\n    * 获取画布ffi指针\n    *\n    * 返回值 - CPointer<UInt8>\n    */\n    public func getG2(): CPointer<UInt8>\n\n    /*\n    * 获取位图像素存储格式(Int32格式)\n    *\n    * 返回值 - CPointer<UInt8>\n    */\n    public func getColorFormat(): Int32\n\n    /*\n    * 画布宽度\n    */\n    public prop width: UInt32\n\n    /*\n    * 画布高度\n    */\n    public prop height: UInt32\n}\n```\n\n### 2. LaTeX\n\n#### 2.1 主要接口\n\n```\npublic class LaTeX {\n    /*\n    * 初始化LaTex\n    *\n    * 参数 - rootDir 字体资源路径\n    *\n    * 返回值 - Unit\n    */\n    public init(rootDir: String)\n    \n    /*\n    * 销毁LaTeX\n    *\n    * 返回值 - Unit\n    */\n    public func release(): Unit\n    \n    /*\n    * 解析数学公式\n    *\n    * 参数 - ltx 数学公式字符串\n    * 参数 - width 画布宽度（预设宽度）\n    * 参数 - textSize 字体大小\n    * 参数 - lineSpace 行距\n    * 参数 - foreground 前景色（画笔颜色），ARGB格式，透明度A不能设置为0，不然颜色可能是随机的\n    *\n    * 返回值 - Render\n    */\n    public func parse(ltx: String, width: Int32, textSize: Float32, lineSpace: Float32, foreground: UInt32): Render\n}\n```\n\n### 3. Render\n\n#### 3.1 主要接口\n\n```\npublic class Render {\n    /*\n    * 初始化\n    *\n    * 参数 - ptr ffi指针\n    *\n    * 返回值 - Unit\n    */\n    public init(ptr: CPointer<UInt8>)\n    \n    /*\n    * 绘制图片\n    *\n    * 参数 - g2 Graphic2D\n    * 参数 - background 背景色，ARGB格式\n    *\n    * 返回值 - Unit\n    */\n    public func draw(g2: Graphic2D, background: UInt32): Unit\n\n    /*\n    * 获取字体大小\n    *\n    * 返回值 - Int32\n    */\n    public func getTextSize(): Float32\n    \n    /*\n    * 获取绘制的实际高度（非画布高度）\n    *\n    * 返回值 - Int32\n    */\n    public func getHeight(): UInt32\n    \n    /*\n    * 获取绘制的实际宽度（非画布宽度）\n    *\n    * 返回值 - Int32\n    */\n    public func getWidth(): UInt32\n    \n    /*\n    * 销毁Render\n    *\n    * 返回值 - Unit\n    */\n    public func finalize(): Unit\n        \n    /*\n    * 生成bitmap图片资源\n    *\n    * 参数 - g2 Graphic2D\n    *\n    * 返回值 - Array<UInt8>\n    */\n    public func toBitmap(g2: Graphic2D): Array<UInt8> \n    \n    /*\n    * 获取生成图片资源\n    *\n    * 参数 - g2 Graphic2D\n    *\n    * 返回值 - Array<UInt8>\n    */\n    public func getMapData(g2: Graphic2D): Array<UInt8>\n}\n```\n\n### 示例\n\ntest.cj\n\n```\nimport formula.*\nimport std.fs.*\n\nmain(): Int64 {\n\n    var latex = LaTeX(\"res\")\n    var str = ###\"\n\\sideset{^\\backprime}{'}\\sum_{x=1}^{\\infty} x\\sideset{a_1^2}{}\\sum_{x=1}^\\infty x_0\n\\\\\n\\sideset{_\\text{left bottom}'''}{_{\\text{right bottom}}'''}\\sum_{\\text{quite long text}}^\\infty x\n\\\\\n\\sideset{}{'}\n\\sum_{n<k,\\;\\text{$n$ odd}} nE_n\n\\\\\n\\sideset{}{'}\n\\sum^{n<k,\\;\\text{$n$ odd}} nE_n\n\\\\\nM_x''' M'''_x M^{'''}_x M_x{'''} M^{\\prime\\backprime}\n\"###\n    var r = latex.parse(str, 2000, 40.0, 10.0, 0xFF000000)\n    var w = r.getWidth()\n    var h = r.getHeight()\n    var g2 = Graphic2D(r, COLOR_FORMAT_RGB_565)\n    r.draw(g2, 0xFFFFFFFF)\n\n    var arr = r.toBitmap(g2)\n\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n    file.write(arr)\n    file.close()\n\n    return 0\n}\n```\n\n编译运行：\n\n```\ncjc --import-path target/aarch64-linux-ohos/release -Ltarget/aarch64-linux-ohos/release/formula -Llib -lnative_drawing  -llatex -lformula_formula test.cj -o main\n```\n\n运行结果如下：\n\n![test](./assets/test.bmp)\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.5)\nproject(latex)\n\n\ninclude(CheckCXXCompilerFlag)\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -std=c++11 -w\")\n\n\nadd_subdirectory(\"third_party_bounds_checking_function\")\n\n# copy res dir\n\nfile(COPY latex/res DESTINATION .)\n\n# file(WRITE \"latex/src/config.h\" \"#ifndef CONFIG_H_INCLUDED\\n#define CONFIG_H_INCLUDED\\n\\n// Flag for debug\\n#if defined(_DEBUG) || defined(DEBUG) || defined(__DEBUG__) || !defined(NDEBUG)\\n#   ifndef __DEBUG\\n#       define __DEBUG\\n#   endif\\n#endif\\n\\n// Check platforms\\n#if defined(__linux__)\\n#   ifdef __ANDROID__\\n#       define __OS_Android__\\n#   elif defined __OHOS__\\n#       define __OS_ohos__\\n#   else\\n#       define __OS_Linux__\\n#   endif\\n#elif defined(_WIN32)\\n#   ifdef __OHOS__\\n#       define __OS_ohos__\\n#   else\\n#       define __OS_Windows__\\n#   endif\\n#endif\\n// Other platforms...\\n\\n// Flag for if compile samples\\n#if defined(__OS_Linux__) || defined(__OS_Windows__) || defined(MEM_CHECK)\\n#   define __USE_SAMPLES\\n#endif\\n\\n// Disable log if not in debug mode\\n#ifndef __DEBUG\\n#   undef HAVE_LOG\\n#endif\\n\\n#endif  // CONFIG_H_INCLUDED\\n\")\n\n# modify formula.cpp\n# set(COMMANDFILE \"modify.sh\")\n# file(WRITE ${COMMANDFILE} \"sed -n -i '1h;1!H;\\${g;s/for (size_t j = 0; j < _row; j++).*auto it = _array\\\\[j\\\\].begin();/for (size_t j = 0; j < _row; j++) {\\\\n        size_t n_row_columns = _array[j].size();\\\\n        if (n_row_columns < col) {\\\\n        for (unsigned int i = 0; i < col - n_row_columns; i++)\\\\n            _array[j].push_back(nullptr);\\\\n        }\\\\n        auto it = _array[j].begin();/;p}' latex/src/core/formula.cpp\")\n# execute_process(COMMAND sh ${COMMANDFILE} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})\n# file(REMOVE ${COMMANDFILE})\n\n# source files\n\nfile(GLOB_RECURSE SRC \"latex/src/*.cpp\" \"ffi/*.cpp\")\n\n# check operating system\n\nmessage(STATUS \"We are working on ohos\")\ninclude_directories(\"latex/src\" \"latex\" \"latex/src/xml\" \"third_party_bounds_checking_function/include\")\n\n# compile options\n\nadd_compile_definitions(__OHOS__)\nadd_link_options(-static-libstdc++ -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/export.map)\n\nadd_library(latex SHARED ${SRC})\ntarget_link_libraries(latex native_drawing securec)\n\n#only in Release type use strip\nif(CMAKE_BUILD_TYPE)\n    if(${CMAKE_BUILD_TYPE} STREQUAL \"Release\")\n        add_custom_command(TARGET ${PROJECT_NAME}\n                    POST_BUILD\n                    COMMAND ${CMAKE_STRIP} -s \"$<TARGET_FILE:${PROJECT_NAME}>\"\n                )\n    endif()\nendif()"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/ffi/graphic_ohos.cpp",
    "content": "/*\r\n * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.\r\n */\r\n\r\n#include \"config.h\"\r\n\r\n#if defined(__OS_ohos__) && !defined(MEM_CHECK)\r\n\r\n#include \"graphic_ohos.h\"\r\n#include \"utils.h\"\r\n\r\nusing namespace tex;\r\nusing namespace std;\r\n\r\n/******************************************* ohos Font *****************************************/\r\n\r\nmap<string, string> Font_ohos::_file_name_map;\r\n\r\nFont_ohos::Font_ohos(const string& family, int style, float size)\r\n    : _family(family), _style(style), _size(size), _file(\"\"){\r\n    }\r\n\r\nFont_ohos::Font_ohos(const string& file, float size) : Font_ohos(\"\", PLAIN, size) {\r\n    loadFont(file);\r\n    _file = file;\r\n}\r\n\r\nvoid Font_ohos::loadFont(const string& file) {\r\n    auto it = _file_name_map.find(file);\r\n    if (it != _file_name_map.end()) {\r\n        // already loaded\r\n        _family = _file_name_map[file];\r\n        return;\r\n    }\r\n\r\n    int index = file.rfind(\"/\");\r\n    string name = file.substr(index + 1, file.rfind(\".\") - index - 1);\r\n    _family = name;\r\n    _file_name_map[file] = _family;\r\n}\r\n\r\nstring Font_ohos::getFile() const {\r\n    return _file;\r\n}\r\n\r\nstring Font_ohos::getFamily() const {\r\n    return _family;\r\n}\r\n\r\nint Font_ohos::getStyle() const {\r\n    return _style;\r\n}\r\n\r\nfloat Font_ohos::getSize() const {\r\n    return _size;\r\n}\r\n\r\nsptr<Font> Font_ohos::deriveFont(int style) const {\r\n    return sptr<Font>(new Font_ohos(_family, style, _size));\r\n}\r\n\r\nbool Font_ohos::operator==(const Font& ft) const {\r\n    const Font_ohos& f = static_cast<const Font_ohos&>(ft);\r\n    return _size == f._size && _style == f._style && _family == f._family;\r\n}\r\n\r\nbool Font_ohos::operator!=(const Font& f) const {\r\n    return !(*this == f);\r\n}\r\n\r\nFont* Font::create(const string& file, float size) {\r\n    return new Font_ohos(file, size);\r\n}\r\n\r\nsptr<Font> Font::_create(const string& name, int style, float size) {\r\n    return sptr<Font>(new Font_ohos(name, style, size));\r\n}\r\n\r\n/******************************************* Text layout ******************************************/\r\n\r\nTextLayout_ohos::TextLayout_ohos(const wstring& src, const sptr<Font_ohos>& font): _txt(src), _font(font) {}\r\n\r\nvoid TextLayout_ohos::getBounds(_out_ Rect& r) {\r\n    OH_Drawing_TypographyStyle* typoStyle = OH_Drawing_CreateTypographyStyle();\r\n    OH_Drawing_TextStyle* txtStyle = OH_Drawing_CreateTextStyle();\r\n    OH_Drawing_TypographyCreate* handler = OH_Drawing_CreateTypographyHandler(typoStyle, OH_Drawing_CreateFontCollection());\r\n    double fontSize = _font->getSize();\r\n    OH_Drawing_SetTextStyleFontSize(txtStyle, fontSize);\r\n    OH_Drawing_SetTextStyleFontWeight(txtStyle, FONT_WEIGHT_400);\r\n    bool halfLeading = true;\r\n    OH_Drawing_SetTextStyleHalfLeading(txtStyle, halfLeading);\r\n    const char *fontFamilies[] = {_font->getFamily().c_str()};\r\n    OH_Drawing_SetTextStyleFontFamilies(txtStyle, 1, fontFamilies);\r\n    OH_Drawing_TypographyHandlerPushTextStyle(handler, txtStyle);\r\n    OH_Drawing_TypographyHandlerAddText(handler, wide2utf8(_txt.c_str()).c_str());\r\n    OH_Drawing_PlaceholderSpan placeholderSpan = {(double)1000, (double)1000, ALIGNMENT_OFFSET_AT_BASELINE, TEXT_BASELINE_ALPHABETIC, 10};\r\n    OH_Drawing_TypographyHandlerAddPlaceholder(handler, &placeholderSpan);\r\n    OH_Drawing_TypographyHandlerPopTextStyle(handler);\r\n    OH_Drawing_Typography* typography = OH_Drawing_CreateTypography(handler);\r\n    OH_Drawing_TypographyLayout(typography, 1000);\r\n    OH_Drawing_RectHeightStyle heightStyle = RECT_HEIGHT_STYLE_TIGHT;\r\n    OH_Drawing_RectWidthStyle widthStyle = RECT_WIDTH_STYLE_TIGHT;\r\n    OH_Drawing_TextBox *textbox = OH_Drawing_TypographyGetRectsForRange(typography, 0, _txt.length(), heightStyle, widthStyle);\r\n    float right =  OH_Drawing_GetRightFromTextBox (textbox, 0);\r\n    float bottom = OH_Drawing_GetBottomFromTextBox(textbox, 0);\r\n\r\n    r.x = 0;\r\n    r.y = -9;\r\n    r.w = right;\r\n    r.h = bottom;\r\n\r\n    OH_Drawing_DestroyTypography(typography);\r\n    OH_Drawing_DestroyTypographyHandler(handler);\r\n    OH_Drawing_DestroyTextStyle(txtStyle);\r\n    OH_Drawing_DestroyTypographyStyle(typoStyle);\r\n}\r\n\r\nvoid TextLayout_ohos::draw(Graphics2D& g2, float x, float y) {\r\n    const Font* oldFont = g2.getFont();\r\n    g2.setFont(_font.get());\r\n    g2.drawText(_txt, x, y);\r\n    g2.setFont(oldFont);\r\n}\r\n\r\nsptr<TextLayout> TextLayout::create(const wstring& txt, const sptr<Font>& font) {\r\n    sptr<Font_ohos> f = static_pointer_cast<Font_ohos>(font);\r\n    return sptr<TextLayout>(new TextLayout_ohos(txt, f));\r\n}\r\n\r\n/******************************************* Graphics 2D ******************************************/\r\n\r\nGraphics2D_ohos::Graphics2D_ohos(OH_Drawing_Bitmap *bitmap, uint32_t background): _stroke() {\r\n    _color = black;\r\n    _bitmap = bitmap;\r\n    _font = new Font_ohos(\"sans-serif\", PLAIN, 14.f);\r\n\r\n    _canvas = OH_Drawing_CanvasCreate();\r\n    OH_Drawing_CanvasBind(_canvas, _bitmap);\r\n    OH_Drawing_CanvasClear(_canvas, background);\r\n\r\n    _pen = OH_Drawing_PenCreate();\r\n    OH_Drawing_PenSetAntiAlias(_pen, true);\r\n\r\n    _brush = OH_Drawing_BrushCreate();\r\n\r\n    _txtStyle = OH_Drawing_CreateTextStyle();\r\n\r\n    // 选择从左到右/左对齐等排版属性\r\n    _typoStyle = OH_Drawing_CreateTypographyStyle();\r\n    OH_Drawing_SetTypographyTextDirection(_typoStyle, TEXT_DIRECTION_LTR);\r\n    OH_Drawing_SetTypographyTextAlign(_typoStyle, TEXT_ALIGN_LEFT);\r\n}\r\n\r\nGraphics2D_ohos::~Graphics2D_ohos() {\r\n    OH_Drawing_PenDestroy(_pen);\r\n    OH_Drawing_BrushDestroy(_brush);\r\n    OH_Drawing_DestroyTextStyle(_txtStyle);\r\n    OH_Drawing_DestroyTypographyStyle(_typoStyle);\r\n    OH_Drawing_CanvasDestroy(_canvas);\r\n}\r\n\r\nvoid Graphics2D_ohos::setColor(color c) {\r\n    _color = c;\r\n    OH_Drawing_PenSetColor(_pen, _color);\r\n    OH_Drawing_BrushSetColor(_brush, _color);\r\n    OH_Drawing_SetTextStyleColor(_txtStyle, c);\r\n}\r\n\r\ncolor Graphics2D_ohos::getColor() const {\r\n    return _color;\r\n}\r\n\r\nvoid Graphics2D_ohos::setStroke(const Stroke& s) {\r\n    _stroke = s;\r\n    OH_Drawing_PenSetWidth(_pen, s.lineWidth);\r\n    OH_Drawing_PenSetMiterLimit(_pen, s.miterLimit);\r\n    OH_Drawing_PenLineCapStyle c;\r\n    switch (s.cap) {\r\n    case CAP_BUTT:\r\n        c = LINE_FLAT_CAP;\r\n        break;\r\n    case CAP_ROUND:\r\n        c = LINE_ROUND_CAP;\r\n        break;\r\n    case CAP_SQUARE:\r\n        c = LINE_SQUARE_CAP;\r\n        break;\r\n    }\r\n    OH_Drawing_PenSetCap(_pen, c);\r\n    OH_Drawing_PenLineJoinStyle j;\r\n    switch (s.join) {\r\n    case JOIN_BEVEL:\r\n        j = LINE_BEVEL_JOIN;\r\n        break;\r\n    case JOIN_ROUND:\r\n        j = LINE_ROUND_JOIN;\r\n        break;\r\n    case JOIN_MITER:\r\n        j = LINE_MITER_JOIN;\r\n        break;\r\n    }\r\n    OH_Drawing_PenSetJoin(_pen, j);\r\n}\r\n\r\nconst Stroke& Graphics2D_ohos::getStroke() const {\r\n    return _stroke;\r\n}\r\n\r\nvoid Graphics2D_ohos::setStrokeWidth(float w) {\r\n    _stroke.lineWidth = w;\r\n   OH_Drawing_PenSetWidth(_pen, w);\r\n}\r\n\r\nconst Font* Graphics2D_ohos::getFont() const {\r\n    return _font;\r\n}\r\n\r\n// 修改\r\nvoid Graphics2D_ohos::setFont(const Font* font) {\r\n    _font = static_cast<const Font_ohos*>(font);\r\n}\r\n\r\nvoid Graphics2D_ohos::translate(float dx, float dy) {\r\n    OH_Drawing_CanvasTranslate(_canvas, dx, dy);\r\n}\r\n\r\nvoid Graphics2D_ohos::scale(float sx, float sy) {\r\n    T[SX] *= sx;\r\n    T[SY] *= sy;\r\n    OH_Drawing_CanvasScale(_canvas, sx, sy);\r\n}\r\n\r\nvoid Graphics2D_ohos::rotate(float angle) {\r\n    rotate(angle, 0, 0);\r\n}\r\n\r\nvoid Graphics2D_ohos::rotate(float angle, float px, float py) {\r\n    float r = angle / PI * 180;\r\n    T[R] += r;\r\n    T[PX] = px;\r\n    T[PY] = py;\r\n    OH_Drawing_CanvasRotate(_canvas, r, px, py);\r\n}\r\n\r\nvoid Graphics2D_ohos::reset() {\r\n    OH_Drawing_CanvasRotate(_canvas, -T[R], T[PX], T[PY]);\r\n    memset_s(T, sizeof(T), 0, sizeof(T));\r\n    \r\n    T[SX] = T[SY] = 1.f;\r\n}\r\n\r\nfloat Graphics2D_ohos::sx() const {\r\n    return T[SX];\r\n}\r\n\r\nfloat Graphics2D_ohos::sy() const {\r\n    return T[SY];\r\n}\r\n\r\nvoid Graphics2D_ohos::drawChar(wchar_t c, float x, float y) {\r\n    wstring str = {c, L'\\0'};\r\n    drawText(str, x, y);\r\n}\r\n\r\nvoid Graphics2D_ohos::setTextStyle(int style) {\r\n    switch (style) {\r\n    case PLAIN:\r\n        OH_Drawing_SetTextStyleFontWeight(_txtStyle, FONT_WEIGHT_400);\r\n        break;\r\n    case BOLD:\r\n        OH_Drawing_SetTextStyleFontWeight(_txtStyle, FONT_WEIGHT_700);\r\n        break;\r\n    case ITALIC:\r\n        OH_Drawing_SetTextStyleFontStyle(_txtStyle, FONT_STYLE_ITALIC);\r\n        break;\r\n    case BOLDITALIC:\r\n        OH_Drawing_SetTextStyleFontWeight(_txtStyle, FONT_WEIGHT_700);\r\n        OH_Drawing_SetTextStyleFontStyle(_txtStyle, FONT_STYLE_ITALIC);\r\n        break;\r\n    default:\r\n        OH_Drawing_SetTextStyleFontWeight(_txtStyle, FONT_WEIGHT_400);\r\n        break;\r\n    }\r\n}\r\n\r\nvoid Graphics2D_ohos::drawText(const wstring& t, float x, float y) {\r\n    string tmp = wide2utf8(t.c_str());\r\n    int len = tmp.length();\r\n    char *str = (char *)malloc(len + 1);\r\n    tmp.copy(str, len, 0);\r\n    str[len] = '\\0';\r\n    tmp = _font->getFile();\r\n    len = tmp.length();\r\n    char *file = (char *)malloc(len + 1);\r\n    tmp.copy(file, len, 0);\r\n    file[len] = '\\0';\r\n    tmp = _font->getFamily();\r\n    len = tmp.length();\r\n    char *family = (char *)malloc(len + 1);\r\n    tmp.copy(family, len, 0);\r\n    family[len] = '\\0';\r\n    const char *fontFamilies[] = {family};\r\n    float s = _font->getSize();\r\n    OH_Drawing_SetTextStyleFontSize(_txtStyle, s);\r\n    OH_Drawing_SetTextStyleBaseLine(_txtStyle, TEXT_BASELINE_ALPHABETIC);\r\n    OH_Drawing_SetTextStyleFontHeight(_txtStyle, 0.1);\r\n    setTextStyle(_font->getStyle());\r\n    OH_Drawing_FontCollection *fontCollection = OH_Drawing_CreateFontCollection();\r\n    if (file[0] != '\\0') {\r\n        OH_Drawing_RegisterFont(fontCollection, fontFamilies[0], file);\r\n    }\r\n    OH_Drawing_SetTextStyleFontFamilies(_txtStyle, 1, fontFamilies);\r\n    OH_Drawing_SetTextStyleLocale(_txtStyle, \"en\");\r\n\r\n    OH_Drawing_TypographyCreate *handler = OH_Drawing_CreateTypographyHandler(_typoStyle, fontCollection);\r\n    OH_Drawing_TypographyHandlerPushTextStyle(handler, _txtStyle);\r\n    OH_Drawing_TypographyHandlerAddText(handler, str);\r\n    OH_Drawing_TypographyHandlerPopTextStyle(handler);\r\n    OH_Drawing_Typography *typography = OH_Drawing_CreateTypography(handler);\r\n    double maxWidth = (double)OH_Drawing_BitmapGetWidth(_bitmap);\r\n    OH_Drawing_TypographyLayout(typography, maxWidth);\r\n\r\n    OH_Drawing_TypographyPaint(typography, _canvas, (double)x, (double)y);\r\n\r\n    OH_Drawing_DestroyTypography(typography);\r\n    OH_Drawing_DestroyTypographyHandler(handler);\r\n    OH_Drawing_DestroyFontCollection(fontCollection);\r\n\r\n    free(str);\r\n    free(file);\r\n    free(family);\r\n}\r\n\r\nvoid Graphics2D_ohos::drawLine(float x1, float y1, float x2, float y2) {\r\n    OH_Drawing_CanvasAttachPen(_canvas, _pen);\r\n    OH_Drawing_CanvasDrawLine(_canvas, x1, y1, x2, y2);\r\n    OH_Drawing_CanvasDetachPen(_canvas);\r\n}\r\n\r\nvoid Graphics2D_ohos::renderRect(float x, float y, float w, float h) {\r\n    OH_Drawing_CanvasAttachPen(_canvas, _pen);\r\n    OH_Drawing_Rect *rect = OH_Drawing_RectCreate(x, y, x + w, y + h);\r\n    OH_Drawing_CanvasDrawRect(_canvas, rect);\r\n    OH_Drawing_RectDestroy(rect);\r\n    OH_Drawing_CanvasDetachPen(_canvas);\r\n}\r\n\r\nvoid Graphics2D_ohos::drawRect(float x, float y, float w, float h) {\r\n    renderRect(x, y, w, h);\r\n}\r\n\r\nvoid Graphics2D_ohos::fillRect(float x, float y, float w, float h) {\r\n    float th = _stroke.lineWidth;\r\n    setStrokeWidth(0.f);\r\n    OH_Drawing_CanvasAttachBrush(_canvas, _brush);\r\n    renderRect(x, y, w, h);\r\n    OH_Drawing_CanvasDetachBrush(_canvas);\r\n    setStrokeWidth(th);\r\n}\r\n\r\nvoid Graphics2D_ohos::renderRoundRect(float x, float y, float w, float h, float rx, float ry) {\r\n    OH_Drawing_Rect *rect = OH_Drawing_RectCreate(x, y, x + w, y + h);\r\n    OH_Drawing_RoundRect *roundRect = OH_Drawing_RoundRectCreate(rect, rx, ry);\r\n    OH_Drawing_CanvasDrawRoundRect(_canvas, roundRect);\r\n    OH_Drawing_RoundRectDestroy(roundRect);\r\n    OH_Drawing_RectDestroy(rect);\r\n}\r\n\r\nvoid Graphics2D_ohos::drawRoundRect(float x, float y, float w, float h, float rx, float ry) {\r\n    renderRoundRect(x, y, w, h, rx, ry);\r\n}\r\n\r\nvoid Graphics2D_ohos::fillRoundRect(float x, float y, float w, float h, float rx, float ry) {\r\n    float th = _stroke.lineWidth;\r\n    setStrokeWidth(0.f);\r\n    OH_Drawing_CanvasAttachBrush(_canvas, _brush);\r\n    renderRoundRect(x, y, w, h, rx, ry);\r\n    OH_Drawing_CanvasDetachBrush(_canvas);\r\n    setStrokeWidth(th);\r\n}\r\n\r\n#endif  // __OS_OHOS__\r\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/ffi/graphic_ohos.h",
    "content": "/*\r\n * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.\r\n */\r\n\r\n#include \"config.h\"\r\n\r\n#if defined(__OS_ohos__) && !defined(MEM_CHECK)\r\n\r\n#ifndef GRAPHIC_OHOS_H_INCLUDED\r\n#define GRAPHIC_OHOS_H_INCLUDED\r\n\r\n#include \"graphic/graphic.h\"\r\n#include <native_drawing/drawing_bitmap.h>\r\n#include <native_drawing/drawing_text_typography.h>\r\n#include <native_drawing/drawing_pen.h>\r\n#include <native_drawing/drawing_brush.h>\r\n#include <native_drawing/drawing_canvas.h>\r\n#include <native_drawing/drawing_font_collection.h>\r\n#include <native_drawing/drawing_rect.h>\r\n#include <native_drawing/drawing_round_rect.h>\r\n#include <native_drawing/drawing_register_font.h>\r\n#include <native_drawing/drawing_text_typography.h>\r\n\r\nusing namespace std;\r\n\r\nnamespace tex {\r\n\r\nclass Font_ohos : public Font {\r\nprivate:\r\n    static map<string, string> _file_name_map;\r\n\r\n    int _style;\r\n    float _size;\r\n    string _family;\r\n    string _file;\r\n\r\n    void loadFont(const string &file);\r\n\r\npublic:\r\n    Font_ohos(const string& family = \"\", int style = PLAIN, float size = 1.f);\r\n\r\n    Font_ohos(const string& file, float size);\r\n\r\n    string getFile() const;\r\n\r\n    string getFamily() const;\r\n\r\n    int getStyle() const;\r\n\r\n    virtual float getSize() const override;\r\n\r\n    virtual sptr<Font> deriveFont(int style) const override;\r\n\r\n    virtual bool operator==(const Font& f) const override;\r\n\r\n    virtual bool operator!=(const Font& f) const override;\r\n};\r\n\r\n/**************************************************************************************************/\r\n\r\nclass TextLayout_ohos : public TextLayout {\r\nprivate:\r\n    sptr<Font_ohos> _font;\r\n    const wstring _txt;\r\n\r\npublic:\r\n    TextLayout_ohos(const wstring& src, const sptr<Font_ohos>& font);\r\n\r\n    virtual void getBounds(_out_ Rect& r) override;\r\n\r\n    virtual void draw(Graphics2D& g2, float x, float y) override;\r\n};\r\n\r\n/**************************************************************************************************/\r\n\r\nclass Graphics2D_ohos : public Graphics2D {\r\nprivate:\r\n    color _color;\r\n    Stroke _stroke;\r\n    const Font_ohos* _font;\r\n    float T[9] = {1, 0, 0, 0, 1, 0, 0, 0, 0};\r\n    int SX = 0;\r\n    int SY = 4;\r\n    int TX = 2;\r\n    int TY = 5;\r\n    int R = 6;\r\n    int PX = 7;\r\n    int PY = 8;\r\n\r\n    OH_Drawing_Bitmap *_bitmap;\r\n    OH_Drawing_Canvas *_canvas;\r\n    OH_Drawing_Pen *_pen;\r\n    OH_Drawing_Brush *_brush;\r\n    OH_Drawing_TextStyle *_txtStyle;\r\n    OH_Drawing_TypographyStyle *_typoStyle;\r\n\r\n    void renderRect(float x, float y, float w, float h);\r\n    void renderRoundRect(float x, float y, float w, float h, float rx, float ry);\r\n    void setTextStyle(int style);\r\n\r\npublic:\r\n    Graphics2D_ohos(OH_Drawing_Bitmap *bitmap, uint32_t foreground);\r\n\r\n    ~Graphics2D_ohos();\r\n\r\n    virtual void setColor(color c) override;\r\n\r\n    virtual color getColor() const override;\r\n\r\n    virtual void setStroke(const Stroke& s) override;\r\n\r\n    virtual const Stroke& getStroke() const override;\r\n\r\n    virtual void setStrokeWidth(float w) override;\r\n\r\n    virtual const Font* getFont() const override;\r\n\r\n    virtual void setFont(const Font* font) override;\r\n\r\n    virtual void translate(float dx, float dy) override;\r\n\r\n    virtual void scale(float sx, float sy) override;\r\n\r\n    virtual void rotate(float angle) override;\r\n\r\n    virtual void rotate(float angle, float px, float py) override;\r\n\r\n    virtual void reset() override;\r\n\r\n    virtual float sx() const override;\r\n\r\n    virtual float sy() const override;\r\n\r\n    virtual void drawChar(wchar_t c, float x, float y) override;\r\n\r\n    virtual void drawText(const wstring& t, float x, float y) override;\r\n\r\n    virtual void drawLine(float x, float y1, float x2, float y2) override;\r\n\r\n    virtual void drawRect(float x, float y, float w, float h) override;\r\n\r\n    virtual void fillRect(float x, float y, float w, float h) override;\r\n\r\n    virtual void drawRoundRect(float x, float y, float w, float h, float rx, float ry) override;\r\n\r\n    virtual void fillRoundRect(float x, float y, float w, float h, float rx, float ry) override;\r\n};\r\n\r\n}  // namespace tex\r\n\r\n#endif  // GRAPHIC_OHOS_H_INCLUDED\r\n#endif  // __OS_ohos__ && !MEM_CHECK\r\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/ffi/graphic_ohos_ffi.cpp",
    "content": "/*\r\n * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.\r\n */\r\n\r\n#include \"config.h\"\r\n\r\n#ifdef __OS_ohos__\r\n\r\n#include <native_drawing/drawing_bitmap.h>\r\n#include <iostream>\r\n\r\nusing namespace std;\r\n\r\n#ifdef __cplusplus\r\nextern \"C\" {\r\n#endif\r\n\r\nOH_Drawing_Bitmap *initGraphics2D_ffi(uint32_t w, uint32_t h, OH_Drawing_ColorFormat colorFormat) {\r\n    OH_Drawing_Bitmap *bitmap = OH_Drawing_BitmapCreate();\r\n    // 定义bitmap的像素格式\r\n    OH_Drawing_BitmapFormat cFormat{colorFormat, ALPHA_FORMAT_OPAQUE};\r\n    // 构造对应格式的bitmap\r\n    OH_Drawing_BitmapBuild(bitmap, w, h, &cFormat);\r\n    return bitmap;\r\n}\r\n\r\n#ifdef __cplusplus\r\n}\r\n#endif\r\n\r\n#endif  // __OS_ohos__\r\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/ffi/graphic_ohos_ffi.h",
    "content": "//\n// Created on 2025/12/17.\n//\n// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,\n// please include \"napi/native_api.h\".\n\n#ifndef LATEX_GRAPHIC_OHOS_FFI_H\n#define LATEX_GRAPHIC_OHOS_FFI_H\n\n#include <native_drawing/drawing_bitmap.h>\n#include <iostream>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nOH_Drawing_Bitmap *initGraphics2D_ffi(uint32_t w, uint32_t h, OH_Drawing_ColorFormat colorFormat);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif //LATEX_GRAPHIC_OHOS_FFI_H\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/ffi/latex_ffi.cpp",
    "content": "/*\r\n * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.\r\n */\r\n\r\n#include \"latex.h\"\r\n\r\n#ifdef __OS_ohos__\r\n\r\n#include <ctype.h>\r\n#include <string>\r\n\r\nusing namespace std;\r\nusing namespace tex;\r\n\r\n#ifdef __cplusplus\r\nextern \"C\" {\r\n#endif\r\n\r\nbool LaTeX_init(char *rootDir) {\r\n    try {\r\n        LaTeX::init(rootDir);\r\n        return true;\r\n    } catch (ex_tex& e) {\r\n        return false;\r\n    }\r\n}\r\n\r\nvoid LaTeX_release() {\r\n    LaTeX::release();\r\n}\r\n\r\nTeXRender *LaTeX_parse(char *ltx, int width, float textSize, float lineSpace, uint32_t foreground) {\r\n    wstring value;\r\n    value = utf82wide(ltx);\r\n    const wchar_t *wstr = value.c_str();\r\n    try {\r\n        TeXRender *r = LaTeX::parse(value, width, textSize, lineSpace, foreground);\r\n        return r;\r\n    } catch (exception& e) {\r\n        return nullptr;\r\n    }\r\n}\r\n\r\nvoid LaTeX_setDebug(bool debug) {\r\n    LaTeX::setDebug(debug);\r\n}\r\n\r\n#ifdef __cplusplus\r\n}\r\n#endif\r\n\r\n#endif  // __OS_ohos__\r\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/ffi/latex_ffi.h",
    "content": "//\n// Created on 2025/12/17.\n//\n// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,\n// please include \"napi/native_api.h\".\n\n#ifndef LATEX_LATEX_FFI_H\n#define LATEX_LATEX_FFI_H\n\n#include \"latex.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nbool LaTeX_init(char *rootDir);\n\nvoid LaTeX_release();\n\nTeXRender *LaTeX_parse(char *ltx, int width, float textSize, float lineSpace, uint32_t foreground);\n\nvoid LaTeX_setDebug(bool debug);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif //LATEX_LATEX_FFI_H\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/ffi/render_ffi.cpp",
    "content": "/*\r\n * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.\r\n */\r\n\r\n#include \"config.h\"\r\n\r\n#ifdef __OS_ohos__\r\n\r\n#include \"graphic_ohos.h\"\r\n#include \"latex.h\"\r\n#include \"utils.h\"\r\n\r\nusing namespace tex;\r\n\r\n#ifdef __cplusplus,\r\nextern \"C\" {\r\n#endif\r\n\r\ntypedef struct {\r\n    uint8_t *data;\r\n    int64_t len;\r\n} UInt8Data;\r\n\r\nvoid TeXRender_draw(TeXRender *r, OH_Drawing_Bitmap *bitmap, int x, int y, uint32_t background) {\r\n    Graphics2D_ohos g2(bitmap, background);\r\n    r->draw(g2, x, y);\r\n}\r\n\r\nfloat TeXRender_getTextSize(TeXRender *r) {\r\n    return r->getTextSize();\r\n}\r\n\r\nint TeXRender_getHeight(TeXRender *r) {\r\n    return r->getHeight();\r\n}\r\n\r\nint TeXRender_getDepth(TeXRender *r) {\r\n    return r->getDepth();\r\n}\r\n\r\nint TeXRender_getWidth(TeXRender *r) {\r\n    return r->getWidth();\r\n}\r\n\r\nfloat TeXRender_getBaseline(TeXRender *r) {\r\n    return r->getBaseline();\r\n}\r\n\r\nvoid TeXRender_setTextSize(TeXRender *r, float size) {\r\n    r->setTextSize(size);\r\n}\r\n\r\nvoid TeXRender_setForeground(TeXRender *r, int c) {\r\n    r->setForeground((color)c);\r\n}\r\n\r\nvoid TeXRender_setWidth(TeXRender *r, int width, int align) {\r\n    r->setWidth(width, align);\r\n}\r\n\r\nvoid TeXRender_setHeight(TeXRender *r, int height, int align) {\r\n    r->setHeight(height, align);\r\n}\r\n\r\nvoid TeXRender_finalize(TeXRender *r) {\r\n    delete r;\r\n}\r\n\r\nstatic UInt8Data toBitmapRGB_565(TeXRender *r, OH_Drawing_Bitmap *bitmap) {\r\n    BitMapFileHeader bmfHdr; // 定义文件头\r\n    BitMapInfoHeader bmiHdr; // 定义信息头\r\n    RgbQuad bmiClr[3]; // 定义调色板\r\n\r\n    uint32_t w = OH_Drawing_BitmapGetWidth(bitmap);\r\n    uint32_t h = OH_Drawing_BitmapGetHeight(bitmap);\r\n    uint8_t *bitmapAddr = (uint8_t *)OH_Drawing_BitmapGetPixels(bitmap);\r\n\r\n    bmiHdr.biSize = sizeof(BitMapInfoHeader);\r\n    bmiHdr.biWidth = w; // 指定图像的宽度，单位是像素\r\n    bmiHdr.biHeight = h; // 指定图像的高度，单位是像素\r\n    bmiHdr.biPlanes = 1; // 目标设备的级别，必须是1\r\n    bmiHdr.biBitCount = 16; // 表示用到颜色时用到的位数 16位表示高彩色图\r\n    bmiHdr.biCompression = BI_BITFIELDS; // RGB565格式\r\n    bmiHdr.biSizeImage = (w + w % 2) * h * 2; // 指定实际位图所占字节数\r\n    bmiHdr.biXPelsPerMeter = 0; // 水平分辨率，单位长度内的像素数\r\n    bmiHdr.biYPelsPerMeter = 0; // 垂直分辨率，单位长度内的像素数\r\n    bmiHdr.biClrUsed = 0; // 位图实际使用的彩色表中的颜色索引数（设为0的话，则说明使用所有调色板项）\r\n    bmiHdr.biClrImportant = 0; // 说明对图象显示有重要影响的颜色索引的数目，0表示所有颜色都重要\r\n\r\n    // RGB565格式掩码\r\n    bmiClr[0].rgbBlue = 0;\r\n    bmiClr[0].rgbGreen = 0xF8;\r\n    bmiClr[0].rgbRed = 0;\r\n    bmiClr[0].rgbReserved = 0;\r\n\r\n    bmiClr[1].rgbBlue = 0xE0;\r\n    bmiClr[1].rgbGreen = 0x07;\r\n    bmiClr[1].rgbRed = 0;\r\n    bmiClr[1].rgbReserved = 0;\r\n\r\n    bmiClr[2].rgbBlue = 0x1F;\r\n    bmiClr[2].rgbGreen = 0;\r\n    bmiClr[2].rgbRed = 0;\r\n    bmiClr[2].rgbReserved = 0;\r\n\r\n    bmfHdr.bfType = (WORD)0x4D42; // 文件类型，0x4D42也就是字符'BM'\r\n    bmfHdr.bfSize = (DWORD)(sizeof(BitMapFileHeader) + sizeof(BitMapInfoHeader) + sizeof(bmiClr) + bmiHdr.biSizeImage); // 文件大小\r\n    bmfHdr.bfReserved1 = 0; // 保留，必须为0\r\n    bmfHdr.bfReserved2 = 0; // 保留，必须为0\r\n    bmfHdr.bfOffBits = (DWORD)(sizeof(BitMapFileHeader) + sizeof(BitMapInfoHeader)+ sizeof(bmiClr)); // 实际图像数据偏移量\r\n\r\n    uint8_t *data = (uint8_t *)malloc(bmfHdr.bfSize);\r\n    memset_s(data, bmfHdr.bfSize, 0, bmfHdr.bfOffBits);\r\n    uint8_t *start = data;\r\n    int32_t destsz = bmfHdr.bfSize;\r\n    memcpy_s(start, destsz, &bmfHdr, sizeof(BitMapFileHeader));\r\n    start += sizeof(BitMapFileHeader);\r\n    destsz -= sizeof(BitMapFileHeader);\r\n    memcpy_s(start, destsz, &bmiHdr, sizeof(BitMapInfoHeader));\r\n    start += sizeof(BitMapInfoHeader);\r\n    destsz -= sizeof(BitMapInfoHeader);\r\n    memcpy_s(start, destsz, &bmiClr, sizeof(bmiClr));\r\n    start += sizeof(bmiClr);\r\n    destsz -= sizeof(bmiClr);\r\n    for (int i = 0; i < h; i++) {\r\n        memcpy_s(start, destsz, bitmapAddr + (w * (h - i - 1) * 2), w * 2);\r\n        start += (w + w % 2) * 2;\r\n        destsz -= (w + w % 2) * 2;\r\n    }\r\n\r\n    UInt8Data u8data;\r\n    u8data.data = data;\r\n    u8data.len = bmfHdr.bfSize;\r\n    return u8data;\r\n}\r\n\r\n\r\n// 手动定义必要的结构体\r\ntypedef struct {\r\n    LONG fx;\r\n    LONG fy;\r\n    LONG fz;\r\n} CIEXYZ1;\r\n\r\ntypedef struct {\r\n    CIEXYZ1 ciexyzRed;\r\n    CIEXYZ1 ciexyzGreen;\r\n    CIEXYZ1 ciexyzBlue;\r\n} CIEXYZTRIPLE1;\r\n\r\ntypedef struct {\r\n    DWORD bV4Size;\r\n    LONG  bV4Width;\r\n    LONG  bV4Height;\r\n    WORD  bV4Planes;\r\n    WORD  bV4BitCount;\r\n    DWORD bV4Compression;\r\n    DWORD bV4SizeImage;\r\n    LONG  bV4XPelsPerMeter;\r\n    LONG  bV4YPelsPerMeter;\r\n    DWORD bV4ClrUsed;\r\n    DWORD bV4ClrImportant;\r\n    DWORD bV4RedMask;\r\n    DWORD bV4GreenMask;\r\n    DWORD bV4BlueMask;\r\n    DWORD bV4AlphaMask;\r\n    DWORD bV4CSType;\r\n    CIEXYZTRIPLE1 bV4Endpoints;\r\n    DWORD bV4GammaRed;\r\n    DWORD bV4GammaGreen;\r\n    DWORD bV4GammaBlue;\r\n} BitMapV4Header1;\r\n\r\nstatic UInt8Data toBitmapBGRA_8888(TeXRender *r, OH_Drawing_Bitmap *bitmap) {\r\n    BitMapFileHeader bmfHdr;\r\n    BitMapV4Header1 bmiHdr;\r\n\r\n    uint32_t w = OH_Drawing_BitmapGetWidth(bitmap);\r\n    uint32_t h = OH_Drawing_BitmapGetHeight(bitmap);\r\n    uint8_t *bitmapAddr = (uint8_t *)OH_Drawing_BitmapGetPixels(bitmap);\r\n\r\n    // 初始化BITMAPV4HEADER\r\n    memset(&bmiHdr, 0, sizeof(BitMapV4Header1));\r\n    bmiHdr.bV4Size = sizeof(BitMapV4Header1);\r\n    bmiHdr.bV4Width = w;\r\n    bmiHdr.bV4Height = h;\r\n    bmiHdr.bV4Planes = 1;\r\n    bmiHdr.bV4BitCount = 32;\r\n    bmiHdr.bV4Compression = BI_BITFIELDS; // 使用BITFIELDS表示有自定义颜色掩码\r\n    bmiHdr.bV4SizeImage = w * h * 4;\r\n    bmiHdr.bV4XPelsPerMeter = 0;\r\n    bmiHdr.bV4YPelsPerMeter = 0;\r\n    bmiHdr.bV4ClrUsed = 0;\r\n    bmiHdr.bV4ClrImportant = 0;\r\n    \r\n    // 设置颜色掩码 - BGRA顺序\r\n    bmiHdr.bV4RedMask = 0x00FF0000;   // 红色掩码\r\n    bmiHdr.bV4GreenMask = 0x0000FF00; // 绿色掩码\r\n    bmiHdr.bV4BlueMask = 0x000000FF;  // 蓝色掩码\r\n    bmiHdr.bV4AlphaMask = 0xFF000000; // Alpha通道掩码\r\n    \r\n    // 设置颜色空间为sRGB\r\n    bmiHdr.bV4CSType = 0x73524742; // 'sRGB'\r\n\r\n    // 设置文件头\r\n    bmfHdr.bfType = (WORD)0x4D42; // \"BM\"\r\n    bmfHdr.bfSize = (DWORD)(sizeof(BitMapFileHeader) + sizeof(BitMapV4Header1) + bmiHdr.bV4SizeImage);\r\n    bmfHdr.bfReserved1 = 0;\r\n    bmfHdr.bfReserved2 = 0;\r\n    bmfHdr.bfOffBits = (DWORD)(sizeof(BitMapFileHeader) + sizeof(BitMapV4Header1));\r\n\r\n    // 分配内存\r\n    uint8_t *data = (uint8_t *)malloc(bmfHdr.bfSize);\r\n    if (!data) {\r\n        UInt8Data empty = {NULL, 0};\r\n        return empty;\r\n    }\r\n    \r\n    uint8_t *start = data;\r\n    int32_t destsz = bmfHdr.bfSize;\r\n    \r\n    // 复制文件头\r\n    memcpy_s(start, destsz, &bmfHdr, sizeof(BitMapFileHeader));\r\n    start += sizeof(BitMapFileHeader);\r\n    destsz -= sizeof(BitMapFileHeader);\r\n    \r\n    // 复制信息头\r\n    memcpy_s(start, destsz, &bmiHdr, sizeof(BitMapV4Header1));\r\n    start += sizeof(BitMapV4Header1);\r\n    destsz -= sizeof(BitMapV4Header1);\r\n    \r\n    // 复制像素数据（注意BMP是从下到上存储的）\r\n    for (int i = 0; i < h; i++) {\r\n        // 从源位图的最后一行开始复制（BMP是从下到上存储的）\r\n        uint8_t *srcLine = bitmapAddr + (w * (h - i - 1) * 4);\r\n        memcpy_s(start, destsz, srcLine, w * 4);\r\n        start += w * 4;\r\n        destsz -= w * 4;\r\n    }\r\n    \r\n    UInt8Data u8data;\r\n    u8data.data = data;\r\n    u8data.len = bmfHdr.bfSize;\r\n    return u8data;\r\n}\r\n\r\nUInt8Data TeXRender_toBitmap(TeXRender *r, OH_Drawing_Bitmap *bitmap, OH_Drawing_ColorFormat colorFormat) {\r\n    if (colorFormat == COLOR_FORMAT_RGB_565) {\r\n        return toBitmapRGB_565(r, bitmap);\r\n    } else if (colorFormat == COLOR_FORMAT_BGRA_8888) {\r\n        return toBitmapBGRA_8888(r, bitmap);\r\n    }\r\n}\r\n\r\nUInt8Data TeXRender_getMapData(TeXRender *r, OH_Drawing_Bitmap *bitmap, OH_Drawing_ColorFormat colorFormat) {\r\n    if (colorFormat == COLOR_FORMAT_RGB_565) {\r\n        return toBitmapRGB_565(r, bitmap);\r\n    } else if (colorFormat == COLOR_FORMAT_BGRA_8888) {\r\n        uint32_t w = OH_Drawing_BitmapGetWidth(bitmap);\r\n        uint32_t h = OH_Drawing_BitmapGetHeight(bitmap);\r\n        int size = h * w * 4;\r\n        uint8_t *bitmapAddr = (uint8_t *)OH_Drawing_BitmapGetPixels(bitmap);\r\n        UInt8Data u8data;\r\n        u8data.data = bitmapAddr;\r\n        u8data.len = size;\r\n        return u8data;\r\n    }\r\n}\r\n\r\n#ifdef __cplusplus\r\n}\r\n#endif\r\n\r\n#endif  // __OS_ohos__"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/ffi/render_ffi.h",
    "content": "//\n// Created on 2025/12/17.\n//\n// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,\n// please include \"napi/native_api.h\".\n\n#ifndef LATEX_RENDER_FFI_H\n#define LATEX_RENDER_FFI_H\n\n#include \"graphic_ohos.h\"\n#include \"latex.h\"\n#include \"utils.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\ntypedef struct {\n    uint8_t *data;\n    int64_t len;\n} UInt8Data;\n\nvoid TeXRender_draw(TeXRender *r, OH_Drawing_Bitmap *bitmap, int x, int y, uint32_t background);\n\nfloat TeXRender_getTextSize(TeXRender *r);\n\nint TeXRender_getHeight(TeXRender *r);\n\nint TeXRender_getDepth(TeXRender *r);\n\nint TeXRender_getWidth(TeXRender *r);\n\nfloat TeXRender_getBaseline(TeXRender *r);\n\nvoid TeXRender_setTextSize(TeXRender *r, float size);\n\nvoid TeXRender_setForeground(TeXRender *r, int c);\n\nvoid TeXRender_setWidth(TeXRender *r, int width, int align);\n\nvoid TeXRender_setHeight(TeXRender *r, int height, int align);\n\nvoid TeXRender_finalize(TeXRender *r);\n\nUInt8Data TeXRender_toBitmap(TeXRender *r, OH_Drawing_Bitmap *bitmap, OH_Drawing_ColorFormat colorFormat);\n\nUInt8Data TeXRender_getMapData(TeXRender *r, OH_Drawing_Bitmap *bitmap, OH_Drawing_ColorFormat colorFormat);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif //LATEX_RENDER_FFI_H\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/ffi/utils.h",
    "content": "/*\r\n * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.\r\n */\r\n\r\n#ifndef UTIL_H\r\n#define UTIL_H\r\n\r\n#include <stdint.h>\r\n#include <securec.h>\r\n\r\n#ifdef __cplusplus\r\nextern \"C\" {\r\n#endif\r\n\r\n// int memset_s(void *dest, uint32_t destsz, int ch, uint32_t count);\r\n// int memcpy_s(void *dest, uint32_t destsz, void *src, uint32_t count);\r\n\r\n\r\n#define BI_RGB 0x0\r\n#define BI_BITFIELDS 0x3\r\n\r\ntypedef char BYTE;\r\ntypedef short WORD;\r\ntypedef int DWORD;\r\ntypedef int LONG;\r\n\r\ntypedef struct tagBITMAPFILEHEADER {\r\n    WORD bfType;                            // 位图文件的类型, 在Windows中, 此字段的值总为‘BM’(1-2字节)\r\n    DWORD bfSize;                           // 位图文件的大小, 以字节为单位(3-6字节, 低位在前)\r\n    WORD bfReserved1;                       // 位图文件保留字, 必须为0(7-8字节)\r\n    WORD bfReserved2;                       // 位图文件保留字, 必须为0(9-10字节)\r\n    DWORD bfOffBits;                        // 位图数据的起始位置, 以相对于位图(11-14字节, 低位在前)\r\n} __attribute__((packed)) BitMapFileHeader; // BITMAPFILEHEADER;\r\n\r\ntypedef struct tagBITMAPINFOHEADER {\r\n    DWORD biSize;                           // 本结构所占用字节数(15-18字节)\r\n    LONG biWidth;                           // 位图的宽度, 以像素为单位(19-22字节)\r\n    LONG biHeight;                          // 位图的高度, 以像素为单位(23-26字节)\r\n    WORD biPlanes;                          // 目标设备的级别, 必须为1(27-28字节)\r\n    WORD biBitCount;                        // 每个像素所需的位数, 1(双色), 4(16色), 8(256色), 16(高彩色), 24(真彩色),\r\n                                            // 32位图(增强真彩色), (29-30字节)\r\n    DWORD biCompression;                    // 位图压缩类型, 0(BI_RGB不压缩), 1(BI_RLE8压缩类型), 2(BI_RLE4压缩类型),\r\n                                            // 3(BI_BITFIELDS), 4(BI_JPEG), 5(BI_PNG), (31-34字节)\r\n    DWORD biSizeImage;                      // 位图的大小(其中包含了为了补齐行数是4的倍数而添加的空字节), 以字节为单位(35-38字节)\r\n    LONG biXPelsPerMeter;                   // 位图水平分辨率, 像素数(39-42字节)\r\n    LONG biYPelsPerMeter;                   // 位图垂直分辨率, 像素数(43-46字节)\r\n    DWORD biClrUsed;                        // 位图实际使用的颜色表中的颜色数(47-50字节)\r\n    DWORD biClrImportant;                   // 位图显示过程中重要的颜色数(51-54字节)\r\n} __attribute__((packed)) BitMapInfoHeader; // BITMAPINFOHEADER;\r\n\r\ntypedef struct tagRGBQUAD {\r\n    BYTE rgbBlue;                     // 蓝色的亮度(值范围为0-255)\r\n    BYTE rgbGreen;                    // 绿色的亮度(值范围为0-255)\r\n    BYTE rgbRed;                      // 红色的亮度(值范围为0-255)\r\n    BYTE rgbReserved;                 // 保留, 必须为0\r\n} __attribute__((packed)) RgbQuad;    //RGBQUAD;\r\n\r\n#ifdef __cplusplus\r\n}\r\n#endif\r\n\r\n#endif"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/.gitignore",
    "content": "#ignore obj\nobj/\n#ignore bin\nbin/\n*.cbp\n*.depend\n*.layout\n/CppCheckResults.xml\n.DS_Store\ndocs/\ndoxyfile\nbuild/\nsrc/doc\nsrc/Doxyfile\n.vscode/\nprebuilt-scripts/\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.5)\nproject(LaTeX)\n\n\n# check if compiler has c++11 support\n\ninclude(CheckCXXCompilerFlag)\nCHECK_CXX_COMPILER_FLAG(\"-std=c++11\" COMPILER_SUPPORTS_CXX11)\nCHECK_CXX_COMPILER_FLAG(\"-std=c++0x\" COMPILER_SUPPORTS_CXX0X)\nif(COMPILER_SUPPORTS_CXX11)\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -std=c++11\")\nelseif(COMPILER_SUPPORTS_CXX0X)\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -std=c++0x\")\nelse()\n    message(STATUS \"The compiler ${CMAKE_CXX_COMPILER} has no c++11 support. Please use a different one that supports c++11.\")\nendif()\n\n# copy res dir\n\nfile(COPY res DESTINATION .)\n\n# source files\n\nfile(GLOB_RECURSE SRC \"src/*.cpp\")\n\n\n# check operating system\n\nif(WIN32)\n    message(STATUS \"We are working on Windows\")\n    include_directories(\"src\")\n    set(LINK_LIBS gdiplus)\nelseif(UNIX AND NOT APPLE)\n    message(STATUS \"We are working on Linux\")\n    find_package(PkgConfig)\n    # include gtkmm module\n    pkg_check_modules(GTKMM gtkmm-3.0)\n    # include gtksourceview\n    pkg_check_modules(GSVMM gtksourceviewmm-3.0)\n    # inlcudes and libraries\n    link_directories(${GTKMM_LIBRARY_DIRS} ${GSVMM_LIBRARY_DIRS})\n    include_directories(${GTKMM_INCLUDE_DIRS} ${GSVMM_INCLUDE_DIRS} \"src\")\n    set(LINK_LIBS ${GTKMM_LIBRARIES} ${GSVMM_LIBRARIES} fontconfig)\nelse()\n    message(STATUS \"We are working on a unknown platform\")\n    # other platforms...\nendif()\n\n\n# compile options\n\noption(HAVE_LOG \"If enable log\" ON)\nif(HAVE_LOG)\n    add_definitions(-DHAVE_LOG)\nendif()\n\noption(GRAPHICS_DEBUG \"If enable graphics debug\" ON)\nif(GRAPHICS_DEBUG)\n    add_definitions(-DGRAPHICS_DEBUG)\nendif()\n\noption(MEM_CHECK \"If compile for memory check only\" OFF)\nif(MEM_CHECK)\n    add_definitions(-DMEM_CHECK)\nendif()\n\nadd_executable(LaTeX ${SRC})\ntarget_link_libraries(LaTeX ${LINK_LIBS})"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/README.md",
    "content": "# ![logo](readme/tex_logo.svg)\n\nIt is a dynamic, cross-platform, and embeddable LaTeX rendering library. Its main purpose is to display mathematical formulas written in LaTeX. It can be embedded in applications on various platforms (Android, iOS, Windows, Linux...). The following pictures demonstrate the application run in Ubuntu and Windows.\n\n![demo ubuntu](readme/example_ubuntu.png)\n\n![demo windows](readme/example_windows.png)\n\n[Here](readme/samples.md) contains more demos you may want to take a look.\n\n# Build demo\n\nFirst make sure you have a C++ compiler that supports `C++ 11` or `C++ 0x` standard. It uses CMake to build the demo, make sure you have it installed. Currently support Windows and Linux on PC, the version on Mac OS is in the plan, and you can find the Android version in [here](https://github.com/NanoMichael/AndroidLaTeXMath).\n\n- `CygWin` or `MinGW` is recommended to be installed on Windows, and `Gdiplus` is required.\n- `GTKMM` and `GSVMM` must be installed on Linux.\n\nAfter all the dependencies have been satisfied, run the following commands to build:\n\n```sh\ncd your/project/dir\nmkdir build\ncd build\ncmake ..\nmake -j32\n```\n\nAfter all the works have done, run the executable file `LaTeX` in the directory `build` to check the demo.\n\n## Headless mode\n\nIt supports to run with headless mode (no GUI) on Linux OS, check the scripts below to learn how to do this.\n\nBatch mode:\n\n```sh\n./LaTeX -headless \\\n    -samples=res/SAMPLES.tex \\\n    -outputdir=samples \\\n    -prefix=sample_ \\\n    # common options\n    -textsize=14 \\\n    -foreground=black \\\n    -background=white \\\n    -padding=0 \\\n    -maxwidth=720\n```\n\nSingle mode:\n\n```sh\n./LaTeX -headless \\\n    \"-input=\\sqrt[3]{(x-y)^3}=x-y\" \\\n    -output=an_example.svg\n    # other options...\n```\n\n**COMMON OPTIONS**\n\n- `-h`: show usages and exit\n\n- `-headless`: tells the application to run with the headless mode, that converts the input LaTeX codes into SVG images\n\n- `-textsize`: config the font size (in point) to display formulas, the default is 20\n\n- `-foreground`: config the foreground color to display formulas; the value can be a color name or in the form of #AARRGGBB; default is black\n\n- `-background`: config the background color to display formulas; the value can be a color name or in the form of #AARRGGBB; default is transparent\n\n- `-padding`: config spaces to add to the SVG images, the default is 10\n\n- `-maxwidth`: config the max width of the graphics context, the default is 720 pixels; this option has weak limits on the SVG images, thus the width of the SVG image may be wider than the value defined by this option\n\n**BATCH MODE OPTIONS**\n\nThe program will save the SVG images produced by the LaTeX codes that parsed from the given file (specified by the option '-samples') into the directory specified by the option '-outputdir'.\n\n- `-outputdir`: indicates the directory to save the SVG images\n\n- `-samples`: specifies the file that contains several LaTeX codes split by a line that consists of the character '%' only, the default is './res/SAMPLES.tex'; check [this file](res/SAMPLES.tex) to get more details\n\n- `-prefix`: specifies the prefix of the filename of the SVG images, the default is ''; for example if 2 pieces of code have given with the option '-prefix=a_', the filename of the SVG images will be 'a_0.svg' and 'a_1.svg'\n\n**SINGLE MODE OPTIONS**\n\n- `-input`: the source code that is written in LaTeX\n\n- `-output`: indicates where to save the produced SVG image, only works if the option '-input' has given\n\n> **NOTICE**\n>\n> If both '-outputdir' and '-input' are specified, the '-input' option wins. Run the command `./LaTeX -h` to get helps.\n\nPlease read [this section](#Display-mathmatical-formulas) to learn more.\n\n## Compile-time options\n\nThe program can be built just fine using the default compilation options. However, if required, the options documented below can be used to omit some features (that can reduce the library size) and to check memory only.\n\n### HAVE_LOG\n\nIf HAVE_LOG is defined, the program will output some logs (e.g.: the symbols parse result, generated box tree and so on) during runtime to help us to find out if there're issues or bugs, the default is **ON**. The option will be disabled when building with release mode, you can set it to **OFF** manually to make double insurance. For example, when parsing the following LaTeX code with the option is defined:\n\n```tex\n\\sqrt[3]{(x-y)^3}=x-y\n```\n\n![example have log](readme/example_have_log.svg)\n\nwill produce the following box tree:\n\n```\n0    HorizontalBox\n1    ├── HorizontalBox\n2    │   ├── StrutBox\n2    │   ├── CharBox\n2    │   ├── StrutBox\n2    │   └── HorizontalBox\n3    │       ├── CharBox\n3    │       └── OverBar\n4    │           ├── StrutBox\n4    │           ├── HorizontalRule\n4    │           ├── StrutBox\n4    │           └── HorizontalBox\n5    │               ├── HorizontalBox\n6    │               │   ├── CharBox\n6    │               │   ├── GlueBox\n6    │               │   ├── CharBox\n6    │               │   ├── GlueBox\n6    │               │   ├── CharBox\n6    │               │   ├── GlueBox\n6    │               │   ├── CharBox\n6    │               │   ├── GlueBox\n6    │               │   └── HorizontalBox\n7    │               │       ├── CharBox\n7    │               │       ├── HorizontalBox\n8    │               │       │   ├── CharBox\n8    │               │       │   └── StrutBox\n7    │               │       └── StrutBox\n5    │               └── StrutBox\n1    ├── GlueBox\n1    ├── CharBox\n1    ├── GlueBox\n1    ├── CharBox\n1    ├── GlueBox\n1    ├── CharBox\n1    ├── GlueBox\n1    └── CharBox\n```\n\nThe number represents the depth of the tree node.\n\n### GRAPHICS_DEBUG\n\nIf this macro is defined, then the custom command `\\debug` and `\\undebug` will be compiled, the default is **ON**. The program will draw some assisted information to help us to check if there're issues when draw formulas after run `\\debug`, and `\\undebug` will close this feature. For example, parse the LaTeX code below:\n\n```tex\n\\debug\n\\newcolumntype{s}{>{\\color{#1234B6}}c}\n\\begin{array}{|c|c|c|s|}\n  \\hline\n  \\rowcolor{Tan}\\multicolumn{4}{|c|}{\\textcolor{white}{\\bold{\\text{Table Head}}}}\\\\\n  \\hline\n  \\text{Matrix}&\\multicolumn{2}{|c|}{\\text{Multicolumns}}&\\text{Font size commands}\\\\\n  \\hline\n  \\begin{pmatrix}\n      \\alpha_{11}&\\cdots&\\alpha_{1n}\\\\\n      \\hdotsfor{3}\\\\\n      \\alpha_{n1}&\\cdots&\\alpha_{nn}\n  \\end{pmatrix}\n  &\\large \\text{Left}&\\cellcolor{#00bde5}\\small \\textcolor{white}{\\text{\\bold{Right}}}\n  &\\small \\text{small Small}\\\\\n  \\hline\n  \\multicolumn{4}{|c|}{\\text{Table Foot}}\\\\\n  \\hline\n\\end{array}\n```\n\nwill produce:\n\n![example debug](readme/example_debug.svg)\n\nThe red blocks represent the depth of the boxes, and these rectangles represent the boxes' bounds.\n\n### MEM_CHECK\n\nBasically, the program implemented an empty graphics interface (check [this file](src/samples/mem_check_main.cpp)), all the other implementations will be ignored if the `MEM_CHECK` option is defined, the default is **OFF**. It is useful when using `valgrind` to detect memory leaks and memory misuse, make sure you have compiled it with the option `-DCMAKE_BUILD_TYPE=Debug` before using `valgrind`. The following script shows how to do memory check using `valgrind`.\n\n```sh\ncmake \n    -DCMAKE_BUILD_TYPE=Debug \\\n    -DGRAPHICS_DEBUG=ON \\\n    -DMEM_CHECK=ON \\\n    -DHAVE_LOG=OFF ..\nmake -j32\nvalgrind --leak-check=full -v ./LaTeX\n```\n\nwill produce:\n\n```\n==26443== HEAP SUMMARY:\n==26443==     in use at exit: 72,704 bytes in 1 blocks\n==26443==   total heap usage: 84,520 allocs, 84,519 frees, 12,515,092 bytes allocated\n==26443== \n==26443== Searching for pointers to 1 not-freed blocks\n==26443== Checked 111,952 bytes\n==26443== \n==26443== LEAK SUMMARY:\n==26443==    definitely lost: 0 bytes in 0 blocks\n==26443==    indirectly lost: 0 bytes in 0 blocks\n==26443==      possibly lost: 0 bytes in 0 blocks\n==26443==    still reachable: 72,704 bytes in 1 blocks\n==26443==         suppressed: 0 bytes in 0 blocks\n==26443== Reachable blocks (those to which a pointer was found) are not shown.\n==26443== To see them, rerun with: --leak-check=full --show-leak-kinds=all\n==26443== \n==26443== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)\n```\n\n# How to use\n\nThis section shows how to use this library to display mathematical formulas.\n\nFirst, load the required resources at the very beginning:\n\n```c++\n#include \"latex.h\"\n\nusing namespace tex;\n\n/**\n * Initialize the program with the default parameter (directory\n * path of the resources) value \"res\" to load required resources,\n * that may take a long time, you may call it from a background\n * thread.\n *\n * Also, you can use the code below to specifies your custom\n * resources directory:\n * \n *      LaTex::init(\"your/resources/root/directory\");\n */\nLaTeX::init();\n\n// After initialization, you could display your formulas now\n```\n\nYou could set the point size (pixels per point) use the code below:\n\n```c++\n/** \n * Set the point size; the default value is 1 that means\n * use 1 pixel to represent 1 point.\n */\nTeXFormula::PIXELS_PER_POINT = 2;\n```\n\nAlso, you could set the DPI (dots per inch) use the code below:\n\n```c++\n/**\n * For example, set the DPI-target to 74, the point size\n * will be 74/72\n */\nTeXFormula::setDPITarget(74);\n```\n\nWrite the code below to release resources before application exit, it is not necessary but is a good habit.\n\n```c++\n// ... some other code ...\n// before application exit\n\nLaTeX::release();\n```\n\n## Display mathematical formulas\n\nGeneral mode:\n\n```c++\n// ... initialization ...\n\n/**\n * The LaTeX code to parse.\n * \n * The program uses wide string to represent UTF characters, you\n * could use the code below to convert a string with UTF-8 encoding\n * to a wide string:\n * \n *      wstring wstr = utf82wide(\"A string with UTF-8 encoding.\");\n */\nwstring code = L\"\\\\int_{now}^{+\\\\infty} \\\\text{Keep trying}\";\n// Convert the code to a paintable object (TeXRender)\nauto r = LaTeX::parse(\n    code,   // LaTeX code to parse\n    720,    // logical width of the graphics context (in pixel)\n    20,     // font size (in point)\n    10,     // space between 2 lines (in pixel)\n    BLACK   // foreground color\n);\n```\n\nBuilder mode:\n\n```c++\nwstring code = L\"\\\\int_{now}^{+\\\\infty} \\\\text{Keep trying}\";\nTeXFormula formula;\nTeXRenderBuilder builder;\nformula.setLaTeX(code);\n\nauto r = builder\n    // environment style, see TeXConstants (defined in common.h) to\n    // get more details\n    .setStyle(STYLE_DISPLAY)\n    // text size (in point)\n    .setSize(20)\n    // the logical width and the alignment of the graphics context\n    .setWidth(UNIT_PIXEL, 720, ALIGN_LEFT)\n    // set if the logical width of the graphics context specified\n    // above is the max width to display the formula, the formula\n    // will be centered if set to true; you must call this method\n    // after 'setWidth' has called, otherwise an ex_invalid_state \n    // exception will be thrown\n    .setIsMaxWidth(false)\n    // space between 2 lines\n    .setLineSpace(UNIT_PIXEL, 10)\n    .setForground(tex::BLACK)\n    // convert the formula to a paintable object (TeXRender)\n    .build(formula);\n```\n\n> **NOTICE**\n>\n> A style and text size are required to build a TeXRender, in another word, you must call method `setStyle` and `setSize` before method `build` has been called, otherwise an `ex_invalid_state` exception will be thrown. If the logical width has not set, the generated TeXRender may be wide enough to overflow into the graphics context.\n\nNow you can draw the generated `TeXRender` (take `Graphics2D_cairo` that uses `cairomm` to implement the graphics (2D) context that run in Linux as an example):\n\n```c++\n// cairomm implementation\nGraphics2D_cairo g2;\n// draw the formula on the coordinate (10, 10) of the graphics context\nr->draw(10, 10);\n// IMPORTANT: remember to delete the generated TeXRender after there\n// is no use on it.\ndelete r;\n```\n\nThe code above will produce:\n\n![example keep trying](readme/example_keep_trying.svg)\n\n## Implement the graphical interfaces\n\nBasically, you need to implement all the interfaces declared in [this file](src/graphic/graphic.h). There're 4 implementations list below, check it out before the start.\n\n- `graphic_cairo`: that uses `cairomm` and `gtkmm` to implement these interfaces that run in Linux, declared in [here](src/platform/cairo/graphic_cairo.h), and implemented [here](src/platform/cairo/graphic_cairo.cpp).\n\n- `graphic_win32`: is a Windows implementation that uses `gdiplus` to implement these interfaces, please check [here](src/platform/gdi_win/graphic_win32.h) and [here](src/platform/gdi_win/graphic_win32.cpp).\n\n- And implementations on Android OS can be found at [here](https://github.com/NanoMichael/AndroidLaTeXMath).\n\n- And the empty implementations to perform memory check are defined in [here](src/samples/mem_check_main.cpp).\n\nThe following sections illustrate these interfaces.\n\n### tex::Font\n\nThis interface represents a font (typeface). The program uses it to draw characters and layout boxes. The code below shows how to implement this interface with the name `Font_impl`.\n\n```c++\n#include \"graphic/graphic.h\"\n\nnamespace tex {\n\nclass Font_impl : public tex::Font {\npublic:\n\n    Font_impl(const string& file, float size) {\n        // load platform-specific font from given file and size\n    }\n\n    Font_impl(const string& name, int style, float size) {\n        // create platform-specific font with given name, style\n        // and size\n    }\n\n    // ... implementations of the other methods ...\n};\n\n/**\n * IMPORTANT: do not forget to implement the 2 static methods below,\n * it is the factory methods to create a new font.\n */\n\nFont* Font::create(const string& file, float size) {\n    return new Font_impl(file, size);\n}\n\nsptr<Font> Font::_create(const string& name, int style, float size) {\n    return sptr<Font>(new Font_impl(name, style, size));\n}\n\n} // namespace tex\n```\n\n### tex::TextLayout\n\nAn alphabet contains several Unicode-blocks on a **Basic Multilingual Plane** (BMP), check [here](https://en.wikipedia.org/wiki/Plane_(Unicode)) for more information.\n\nFor these characters in unregistered alphabets, the library uses `tex::TextLayout` to layout it. For example, parse the following LaTeX code:\n\n```tex\n\\int_{now}^{\\infty} \\text{努力}\n```\n\nThe character \"努\" and \"力\" are under the Unicode-block [CJK Unified Ideographs](https://en.wikipedia.org/wiki/CJK_Unified_Ideographs_(Unicode_block)) belongs to the alphabet CJK that has not registered with the program, it will use the implementation of the class `tex::TextLayout` to layout the text \"努力\" and calculate the layout bounds. The `tex::TextLayout_cairo` implementation (declared in [here](src/platform/cairo/graphic_cairo.h)) demonstrates how to do this.\n\nThe LaTeX code above will produce:\n\n![example cjk trying](readme/example_cjk_trying.svg)\n\nThe predefined Unicode-blocks are list below, check [this file](src/fonts/alphabet.cpp) for more details.\n\n```\nname               code range\n-----------------  ---------------\nBASIC_LATIN        0x0020 ~ 0x007F\nLATIN1_SUPPLEMENT  0x0080 ~ 0x00FF\nCYRILLIC           0x0400 ~ 0x04FF\nGREEK              0x0370 ~ 0x03FF\nGREEK_EXTENDED     0x1f00 ~ 0x1FFF\nUNKNOWN            0xFFFF ~ 0xFFFF\n```\n\nWrite the code below to register a new alphabet with the program:\n\n```c++\nclass NewAlphabetRegistration : public AlphabetRegistration {\nprivate:\n    vector<UnicodeBlock> _blocks;\n\npublic:\n    NewAlphabetRegistration(const vector<UnicodeBlock>& blocks)\n        :_blocks(blocks) {}\n\n    const vector<UnicodeBlock>& getUnicodeBlock() const override {\n        return _blocks;\n    }\n\n    const string getPackage() const override {\n        // the root directory path of the font-mapping and\n        // symbols-mapping for this alphabet\n    }\n\n    const string getTeXFontFile() const override {\n        // language settings (a xml file) for this alphabet\n    }\n};\n\n// ... some other code ...\n\n// Define a new Unicode-block\nauto newBlock = UnicodeBlock::define(\n    newAlphabetCodePointStart, \n    newAlphabetCodePointEnd);\n\n// Register the new alphabet\nDefaultTeXFont::registerAlphabet(new NewAlphabetRegistration({newBlock});\n```\n\n### tex::Graphics2D\n\nThis interface defines a 2D graphics context, all the TeX drawing operations will on it. It declares various basic 2D graphics operations, including affine transformations and meta graphical operations. The class `Graphics2D_cairo` (defined in [this file](src/platform/cairo/graphic_cairo.cpp)) uses `cariomm` to implement this interface, take it a look to learn how to achieve it. It is the most important part of the graphical environment, and also very simple, all you need to do is wrap these functions on a specific platform into the form of this interface declared. [This file](src/graphic/graphic_basic.h) declares some built-in colors and various entity classes to support the graphical environment.\n\n# Custom commands and symbols\n\n## \\debug and \\undebug\n\nAs mentioned [above](#GRAPHICS_DEBUG), the command `\\debug` and `\\undebug` is used to switch graphical debug mode on/off, please check it out.\n\n## \\fatalIfCmdConflict\n\nThis command takes a boolean argument to determine whether to raise an error that when defining a new command but it has defined already or redefining a command but it has not defined. The default value is true. The script below shows how to use it.\n\n```tex\n\\fatalIfCmdConflict{true}\n% define a new command with the name R\n\\newcommand{\\R}{\\mathbb{R}}\n\\R\n% here will cause the program throws an error\n% use \\fatalIfCmdConflict{false} to disable it\n\\newcommand{\\R}{\\mathcal{R}}\n```\n\n## \\breakEverywhere\n\nThis command takes a boolean argument, the predefined value is false. Its functionality is hard to describe, an example worths thousands of words, the examples below show the difference between when it set to true and false.\n\n```tex\n\\text{What is real? How do you define ‘real’? If you're talking about what you can feel, what you can smell, what you can taste and see, then ‘real’ is simply electrical signals interpreted by your brain. \\bold{\\text{― Morpheus The Matrix}}}\n```\n\nWhen with `\\breakEverywhere{false}`, the result will be:\n\n![bw false](readme/example_bw_false.svg)\n\nAnd with `\\breakEverywhere{true}`, the result will be:\n\n![bw true](readme/example_bw_true.svg)\n\n> **NOTICE**\n>\n> The program has a weak ability to handle line feeds when laying out texts, you should try to avoid using it to lay out large amounts of text, delegate these tasks to the text-layout system, and use this program to display formulas is a good choice.\n\n## \\TeX and \\AndroidTeX\n\nThe logo and the logo of the Android version are produced by the command `\\TeX` and `\\AndroidTeX`, take a quick look:\n\n```tex\n\\TeX \\\\\n\\AndroidTeX\n```\n\n![logos](readme/example_logos.svg)\n\n## Custom symbols\n\nThere're 4 custom symbols in the script below:\n\n```tex\nAB \\varparallel CD\nAB \\nvarparallel CD\nAB \\varparalleleq CD\n\\parallelogram ABCD\n```\n\nthat will produce:\n\n![custom symbols](readme/example_custom_symbols.svg)\n\n# Plans to do next\n\n- make the use of XML configurable\n- make the built-in resources a loadable/unloadable dynamic plugin\n- eliminate the use of 'dynamic_cast'\n- rewrite the parsing algorithm, make it more efficient\n- support for dynamic parsing\n- implement the `\\def` command\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/githooks/pre-commit",
    "content": "#!/bin/bash\n#\n# Check compiling before commit\n#\n\nCYAN='\\033[0;36m'\nRESET='\\033[0m'\n\necho -e \"${CYAN}############################### START BUILD ##############################${RESET}\"\n\nworkingDir=$(pwd)\n\ncd build\ncmake -DCMAKE_BUILD_TYPE=Debug -DGRAPHICS_DEBUG=ON -DMEM_CHECK=OFF -DHAVE_LOG=ON ..\nmake -j32\n\ncd $workingDir\n\necho -e \"${CYAN}################################## DONE ##################################${RESET}\"\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/githooks/pre-push",
    "content": "#!/bin/bash\n#\n# Update samples before push\n#\n\nGREEN='\\033[0;32m'\nRED='\\033[0;31m'\nCYAN='\\033[0;36m'\nRESET='\\033[0m'\n\necho -e \"${CYAN}############################# UPDATE SAMPLES #############################${RESET}\"\n\nworkingDir=$(pwd)\n\ncd build\n\nwrite_sample() {\n    echo -e \"\\`\\`\\`tex\" >> samples.md\n    cat __tmp >> samples.md\n    echo -e \"\\`\\`\\`\" >> samples.md\n    cp /dev/null __tmp\n    echo -e \"\\n![sample_$1](samples/sample_$1.svg)\\n\\n\" >> samples.md\n}\n\nupdate_samples() {\n    # regenerate sample_*.svg\n    if [ -d samples ]; then\n        rm -r samples\n    fi\n    mkdir samples\n    ./LaTeX -headless \\\n        -outputdir=./samples \\\n        -prefix=sample_ \\\n        -textsize=14 \\\n        -foreground=black \\\n        -background=white\n    # regenerate samples.md\n    if [ -e samples.md ]; then\n        rm samples.md\n    fi\n    touch samples.md\n    echo -e \"# SAMPLES\\n\" >> samples.md\n    touch __tmp\n    cp /dev/null __tmp\n    j=0\n    while IFS='' read -r i || [[ -n \"$i\" ]]; do\n        if [[ $i == +(['%']) ]]; then\n            write_sample $j\n            j=`expr $j + 1`\n        elif [ -n \"$i\" ]; then\n            echo \"$i\" >> __tmp\n        fi\n    done < res/SAMPLES.tex\n    # the last sample\n    write_sample $j\n\n    rm __tmp\n}\n\nupdate_change() {\n    if [ ! -d ../readme/samples ]; then\n        mkdir ../readme/samples\n    fi\n    # compress svg files\n    for svg in `ls samples`; do\n        scour -i `pwd`/samples/$svg -o ../readme/samples/$svg \\\n            --enable-viewboxing --enable-id-stripping \\\n            --enable-comment-stripping --shorten-ids --indent=none\n    done\n    cp samples.md ../readme\n    # check if samples changed\n    git add ../readme/samples.md\n    git add ../readme/samples\n    git diff --cached --exit-code ../readme/samples > /dev/null\n    samplesChanged=$?\n    git diff --cached --exit-code ../readme/samples.md > /dev/null\n    mdChanged=$?\n    if [ $samplesChanged != 0 -o $mdChanged != 0 ]; then\n        echo -e \"${RED}Samples changed, commit changes...${RESET}\"\n        git commit -m \"update samples\"\n    else\n        echo -e \"${GREEN}No changes need to commit.${RESET}\"\n    fi\n}\n\n# Allows us to read user input below, assigns stdin to keyboard,\n# since git hooks not run in an interactive environment\nexec < /dev/tty\n\nwhile true; do\n    read -p \"Do you wish to update samples (Y/N)?\" yn\n    case $yn in\n        [Yy]* ) update_samples; update_change; break;;\n        * ) echo -e \"${RED}Samples updating canceled.${RESET}\"; break;;\n    esac\ndone\n\n# Close STDIN\nexec <&-\n\ncd $workingDir\n\necho -e \"${CYAN}################################## DONE ##################################${RESET}\"\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/readme/samples.md",
    "content": "# SAMPLES\n\n```tex\n%Side sets test\n\\sideset{^\\backprime}{'}\n\\sum_{x=1}^{\\infty} x\n\\sideset{a_1^2}{}\\sum_{x=1}^\\infty x_0\n\\\\\n\\sideset{_\\text{left bottom}'''}{_{\\text{right bottom}}'''}\n\\sum_{\\text{quite long text}}^\\infty x\n\\\\\n\\sideset{}{'}\n\\sum_{n<k,\\;\\text{$n$ odd}} nE_n\n\\\\\n\\sideset{}{'}\n\\sum^{n<k,\\;\\text{$n$ odd}} nE_n\n\\\\\nM_x''' M'''_x M^{'''}_x M_x{'''} M^{\\prime\\backprime}\n```\n\n![sample_0](samples/sample_0.svg)\n\n\n```tex\n%Cyrillic and Greek alphabet\n\\begin{array}{lr}\n  \\mbox{\\textcolor{Blue}{Russian}}&\\mbox{\\textcolor{Melon}{Greek}}\\\\\n  \\mbox{привет мир}&\\mbox{γειά κόσμο}\\\\\n  \\mbox{привет мир}&\\mbox{γειά κόσμο}\\\\\n  \\mathbf{\\mbox{привет мир}}&\\mathbf{\\mbox{γειά κόσμο}}\\\\\n  \\mathit{\\mbox{привет мир}}&\\mathit{\\mbox{γειά κόσμο}}\\\\\n  \\mathsf{\\mbox{привет мир}}&\\mathsf{\\mbox{γειά κόσμο}}\\\\\n  \\mathtt{\\mbox{привет мир}}&\\mathtt{\\mbox{γειά κόσμο}}\\\\\n  \\mathbf{\\mathit{\\mbox{привет мир}}}&\\mathbf{\\mathit{\\mbox{γειά κόσμο}}}\\\\\n  \\mathbf{\\mathsf{\\mbox{привет мир}}}&\\mathbf{\\mathsf{\\mbox{γειά κόσμο}}}\\\\\n  \\mathsf{\\mathit{\\mbox{привет мир}}}&\\mathsf{\\mathit{\\mbox{γειά κόσμο}}}\\\\\n  &\\\\\n  \\mbox{\\textcolor{Salmon}{Bulgarian}}&\\mbox{\\textcolor{Tan}{Serbian}}\\\\\n  \\mbox{здравей свят}&\\mbox{Хелло уорлд}\\\\\n  &\\\\\n  \\mbox{\\textcolor{Turquoise}{Bielorussian}}&\\mbox{\\textcolor{LimeGreen}{Ukrainian}}\\\\\n  \\mbox{прывітаньне Свет}&\\mbox{привіт світ}\\\\\n\\end{array}\n```\n\n![sample_1](samples/sample_1.svg)\n\n\n```tex\n%Complex formula test\n\\begin{array}{l}\n  \\forall\\varepsilon\\in\\mathbb{R}_+^*\\ \\exists\\eta>0\\ |x-x_0|\\leq\\eta\\Longrightarrow|f(x)-f(x_0)|\\leq\\varepsilon\\\\\n  \\det\n  \\begin{bmatrix}\n      a_{11}&a_{12}&\\cdots&a_{1n}\\\\\n      a_{21}&\\ddots&&\\vdots\\\\\n      \\vdots&&\\ddots&\\vdots\\\\\n      a_{n1}&\\cdots&\\cdots&a_{nn}\n  \\end{bmatrix}\n  \\overset{\\mathrm{def}}{=}\\sum_{\\sigma\\in\\mathfrak{S}_n}\\varepsilon(\\sigma)\\prod_{k=1}^n a_{k\\sigma(k)}\\\\\n  \\sideset{_\\alpha^\\beta}{_\\gamma^\\delta}{\\begin{pmatrix}a&b\\\\c&d\\end{pmatrix}}\\\\\n  \\int_0^\\infty{x^{2n} e^{-a x^2}\\,dx} = \\frac{2n-1}{2a} \n      \\int_0^\\infty{x^{2(n-1)} e^{-a x^2}\\,dx} = \\frac{(2n-1)!!}{2^{n+1}} \\sqrt{\\frac{\\pi}{a^{2n+1}}}\\\\\n  \\int_a^b{f(x)\\,dx} = (b - a) \\sum\\limits_{n = 1}^\\infty  \n      {\\sum\\limits_{m = 1}^{2^n  - 1} {\\left( { - 1} \\right)^{m + 1} } } 2^{ - n} f(a + m\\left( {b - a} \\right)2^{-n} )\\\\\n  \\int_{-\\pi}^{\\pi} \\sin(\\alpha x) \\sin^n(\\beta x) dx = \\textstyle{\\left \\{\n      \\begin{array}{cc}\n          (-1)^{(n+1)/2} (-1)^m \\frac{2 \\pi}{2^n} \\binom{n}{m} & n \\mbox{ odd},\\ \\alpha = \\beta (2m-n) \\\\\n          0 & \\mbox{otherwise} \\\\ \\end{array} \\right .}\\\\\n  L = \\int_a^b \\sqrt{ \\left|\\sum_{i,j=1}^ng_{ij}(\\gamma(t))\\left(\\frac{d}{dt}x^i\\circ\\gamma(t)\\right)\n      \\left(\\frac{d}{dt}x^j\\circ\\gamma(t)\\right)\\right|}\\,dt\\\\\n  \\begin{array}{rl}\n      s &= \\int_a^b\\left\\|\\frac{d}{dt}\\vec{r}\\,(u(t),v(t))\\right\\|\\,dt \\\\\n      &= \\int_a^b \\sqrt{u'(t)^2\\,\\vec{r}_u\\cdot\\vec{r}_u + 2u'(t)v'(t)\\, \\vec{r}_u\\cdot\n          \\vec{r}_v+ v'(t)^2\\,\\vec{r}_v\\cdot\\vec{r}_v}\\,\\,\\, dt. \n  \\end{array}\\\\\n\\end{array}\n```\n\n![sample_2](samples/sample_2.svg)\n\n\n```tex\n\\definecolor{gris}{gray}{0.9}\n\\definecolor{noir}{rgb}{0,0,0}\n\\definecolor{bleu}{rgb}{0,0,1}\n\\fatalIfCmdConflict{false}\n\\newcommand{\\pa}{\\left|}\n\\begin{array}{c}\n  \\LaTeX\\\\\n  \\begin{split}\n      &Тепловой\\ поток\\ \\mathrm{Тепловой\\ поток}\\ \\mathtt{Тепловой\\ поток}\\\\\n      &\\boldsymbol{\\mathrm{Тепловой\\ поток}}\\ \\mathsf{Тепловой\\ поток}\\\\\n      |I_2| &= \\pa\\int_0^T\\psi(t)\\left\\{ u(a,t)-\\int_{\\gamma(t)}^a \\frac{d\\theta}{k} (\\theta,t) \\int_a^\\theta c(\\xi) \n          u_t (\\xi,t)\\,d\\xi\\right\\}dt\\right|\\\\\n      &\\le C_6 \\Bigg|\\pa f \\int_\\Omega \\pa\\widetilde{S}^{-1,0}_{a,-}\n          W_2(\\Omega, \\Gamma_1)\\right|\\ \\right|\\left| |u|\\overset{\\circ}{\\to} W_2^{\\widetilde{A}}(\\Omega\\Gamma_r,T)\\right|\\Bigg|\\\\\n      &\\\\\n      &\\begin{pmatrix}\n          \\alpha&\\beta&\\gamma&\\delta\\\\\n          \\aleph&\\beth&\\gimel&\\daleth\\\\\n          \\mathfrak{A}&\\mathfrak{B}&\\mathfrak{C}&\\mathfrak{D}\\\\\n          \\boldsymbol{\\mathfrak{a}}&\\boldsymbol{\\mathfrak{b}}&\\boldsymbol{\\mathfrak{c}}&\\boldsymbol{\\mathfrak{d}}\n      \\end{pmatrix}\n      \\quad{(a+b)}^{\\frac{n}{2}}=\\sqrt{\\sum_{k=0}^n\\tbinom{n}{k}a^kb^{n-k}}\\quad \n          \\Biggl(\\biggl(\\Bigl(\\bigl(()\\bigr)\\Bigr)\\biggr)\\Biggr)\\\\\n      &\\forall\\varepsilon\\in\\mathbb{R}_+^*\\ \\exists\\eta>0\\ |x-x_0|\\leq\\eta\\Longrightarrow|f(x)-f(x_0)|\\leq\\varepsilon\\\\\n      &\\det\n      \\begin{bmatrix}\n          a_{11}&a_{12}&\\cdots&a_{1n}\\\\\n          a_{21}&\\ddots&&\\vdots\\\\\n          \\vdots&&\\ddots&\\vdots\\\\\n          a_{n1}&\\cdots&\\cdots&a_{nn}\n      \\end{bmatrix}\n      \\overset{\\mathrm{def}}{=}\\sum_{\\sigma\\in\\mathfrak{S}_n}\\varepsilon(\\sigma)\\prod_{k=1}^n a_{k\\sigma(k)}\\\\\n      &\\Delta f(x,y)=\\frac{\\partial^2f}{\\partial x^2}+\\frac{\\partial^2f}{\\partial y^2}\\qquad\\qquad \\fcolorbox{noir}{gris}\n          {n!\\underset{n\\rightarrow+\\infty}{\\sim} {\\left(\\frac{n}{e}\\right)}^n\\sqrt{2\\pi n}}\\\\\n      &\\sideset{_\\alpha^\\beta}{_\\gamma^\\delta}{\n      \\begin{pmatrix}\n          a&b\\\\\n          c&d\n      \\end{pmatrix}}\n      \\xrightarrow[T]{n\\pm i-j}\\sideset{^t}{}A\\xleftarrow{\\overrightarrow{u}\\wedge\\overrightarrow{v}}\n          \\underleftrightarrow{\\iint_{\\mathds{R}^2}e^{-\\left(x^2+y^2\\right)}\\,\\mathrm{d}x\\mathrm{d}y}\n  \\end{split}\\\\\n  \\rotatebox{30}{\\sum_{n=1}^{+\\infty}}\\quad\\mbox{Mirror rorriM}\\reflectbox{\\mbox{Mirror rorriM}}\n\\end{array}\n```\n\n![sample_3](samples/sample_3.svg)\n\n\n```tex\n\\begin{array}{|c|l|||r|c|}\n  \\hline\n  \\text{Matrix}&\\multicolumn{2}{|c|}{\\text{Multicolumns}}&\\text{Font sizes commands}\\cr\n  \\hline\n  \\begin{pmatrix}\n      \\alpha_{11}&\\cdots&\\alpha_{1n}\\cr\n      \\hdotsfor{3}\\cr\n      \\alpha_{n1}&\\cdots&\\alpha_{nn}\n  \\end{pmatrix}\n  &\\Large \\text{Large Right}&\\small \\text{small Left}&\\tiny \\text{tiny Tiny}\\cr\n  \\hline\n  \\multicolumn{4}{|c|}{\\Huge \\text{Huge Multicolumns}}\\cr\n  \\hline\n\\end{array}\n```\n\n![sample_4](samples/sample_4.svg)\n\n\n```tex\n\\cornersize{0.2}\n\\begin{array}{cc}\n  \\fbox{\\text{A framed box with \\textdbend}}&\\shadowbox{\\text{A shadowed box}}\\cr\n  \\doublebox{\\text{A double framed box}}&\\ovalbox{\\text{An oval framed box}}\\cr\n\\end{array}\n```\n\n![sample_5](samples/sample_5.svg)\n\n\n```tex\n%ASCII character\n\\text{!\"#'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]\n^_`abcdefghijklmnopqrstuvwxyz{|}~\n     ¡¢£¤¥¦§¨©ª«¬­\n®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ}\n```\n\n![sample_6](samples/sample_6.svg)\n\n\n```tex\n%Table test\n\\newcolumntype{s}{>{\\color{#1234B6}}c}\n\\begin{array}{|c|c|c|s|}\n  \\hline\n  \\rowcolor{Tan}\\multicolumn{4}{|c|}{\\textcolor{white}{\\bold{\\text{Table Head}}}}\\\\\n  \\hline\n  \\text{Matrix}&\\multicolumn{2}{|c|}{\\text{Multicolumns}}&\\text{Font size commands}\\\\\n  \\hline\n  \\begin{pmatrix}\n      \\alpha_{11}&\\cdots&\\alpha_{1n}\\\\\n      \\hdotsfor{3}\\\\\n      \\alpha_{n1}&\\cdots&\\alpha_{nn}\n  \\end{pmatrix}\n  &\\large \\text{Left}&\\cellcolor{#00bde5}\\small \\textcolor{white}{\\text{\\bold{Right}}}\n  &\\small \\text{small Small}\\\\\n  \\hline\n  \\multicolumn{4}{|c|}{\\text{Table Foot}}\\\\\n  \\hline\n\\end{array}\n```\n\n![sample_7](samples/sample_7.svg)\n\n\n```tex\n\\rlap{\\overbrace{\\phantom{1 + a + b + \\cdots + z}}^{\\text{total + 1}}}\n1 + \\underbrace{a + b + \\cdots + z}_{\\text{total}}\n\\\\\n\\frac{a\\cancel{b}}{\\cancel{b}} = a;\n\\frac{a\\bcancel{b}}{\\bcancel{b}} = a;\n\\frac{a\\xcancel{b}}{\\xcancel{b}} = a;\n\\\\\n\\text{A long division: }\\longdiv{12345}{13}\n```\n\n![sample_8](samples/sample_8.svg)\n\n\n```tex\n\\left\\{\n    \\begin{array}{l}\n    2a < -1,\\\\\n    a + 8 \\ge 5,\n    \\end{array}\n\\right.\n\\\\\nP_{r-j}=\\begin{cases}\n0& \\text{if $r-j$ is odd},\\\\\nr!\\,(-1)^{(r-j)/2}& \\text{if $r-j$ is even}.\n\\end{cases}\\text{Cases}\n\\\\\nP_{r-j}=\\left\\{\\begin{array}{@{}ll@{\\,}}\n0& \\text{if $r-j$ is odd},\\\\\nr!\\,(-1)^{(r-j)/2}& \\text{if $r-j$ is even}.\n\\end{array}\\right.\\text{Cases}\n\\\\\nP_{r-j}=\\begin{cases}\n4-x\\geq 0 \\\\\n3-x\\geq 1\n\\end{cases}\\text{Cases}\n\\\\\n\\left\\{\\begin{array}{@{}ll}\n1 & 2\\\\\n3 & 4\n\\end{array}\\right.\\text{Equation}\n\\\\\n\\left\\{\\begin{array}{l@{}l}\n1 & 2\\\\\n3 & 4\n\\end{array}\\right.\\text{Equation}\n\\\\\n\\left\\{\\begin{array}{ll@{}}\n1 & 2\\\\\n3 & 4\n\\end{array}\\right.\\text{Equation}\n\\\\\n\\begin{split}\nH_c&=\\frac{1}{2n} \\sum^n_{l=0}(-1)^{l}(n-{l})^{p-2}\n\\sum_{l _1+\\dots+ l _p=l}\\prod^p_{i=1} \\binom{n_i}{l _i}\\\\\n&\\quad\\cdot[(n-l )-(n_i-l _i)]^{n_i-l _i}\\cdot\n\\Bigl[(n-l )^2-\\sum^p_{j=1}(n_i-l _i)^2\\Bigr].\n\\end{split}\n\\\\\n\\begin{align}\nA_1&=N_0(\\lambda;\\Omega’)-\\phi(\\lambda;\\Omega’),\\\\\nA_2&=\\phi(\\lambda;\\Omega’)-\\phi(\\lambda;\\Omega),\\\\\n\\intertext{and}\nA_3&=\\mathcal{N}(\\lambda;\\omega).\n\\end{align}\n```\n\n![sample_9](samples/sample_9.svg)\n\n\n```tex\n\\frac{\\sum_{n > 0} z^n}\n{\\prod_{1\\leq k\\leq n} (1-q^k)}\n\\\\\n\\frac{{\\displaystyle\\sum_{n > 0} z^n}}\n{{\\displaystyle\\prod_{1\\leq k\\leq n} (1-q^k)}}\n\\\\\n\\frac{{\\displaystyle\\sum\\nolimits_{n> 0} z^n}}\n{{\\displaystyle\\prod\\nolimits_{1\\leq k\\leq n} (1-q^k)}}\n```\n\n![sample_10](samples/sample_10.svg)\n\n\n```tex\n\\cfrac{1}{\\sqrt{2}+\n\\cfrac{1}{\\sqrt{2}+\n\\cfrac{1}{\\sqrt{2}+\\dotsb\n}}}\n\\\\\n\\biggl[\n\\sum_i a_i\\biggl\\lvert\\sum_j x_{ij}\n\\biggr\\rvert^p\\biggr]^{1/p}\n\\\\\n\\biggl[\n\\sum_i a_i\\Bigl\\lvert\\sum_j x_{ij}\n\\Bigr\\rvert^p\\biggr]^{1/p}\n```\n\n![sample_11](samples/sample_11.svg)\n\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/RES_README",
    "content": "fonts/licences/OFL.txt\nfonts/licences/License_for_dsrom.txt\nfonts/licences/Knuth_License.txt\nfonts/euler/eufb10.ttf\nfonts/euler/eufm10.ttf\nfonts/base/cmmi10.ttf\nfonts/base/cmmib10.ttf\nfonts/base/cmex10.ttf\nfonts/latin/sb10.ttf\nfonts/latin/optional/cmss10.ttf\nfonts/latin/optional/cmtt10.ttf\nfonts/latin/optional/cmbxti10.ttf\nfonts/latin/optional/cmssbx10.ttf\nfonts/latin/optional/cmbx10.ttf\nfonts/latin/optional/cmti10.ttf\nfonts/latin/optional/cmssi10.ttf\nfonts/latin/i10.ttf\nfonts/latin/bi10.ttf\nfonts/latin/ss10.ttf\nfonts/latin/cmr10.ttf\nfonts/latin/tt10.ttf\nfonts/latin/si10.ttf\nfonts/latin/bx10.ttf\nfonts/latin/r10.ttf\nfonts/latin/sbi10.ttf\nfonts/maths/cmsy10.ttf\nfonts/maths/optional/dsrom10.ttf\nfonts/maths/rsfs10.ttf\nfonts/maths/special.ttf\nfonts/maths/msam10.ttf\nfonts/maths/stmary10.ttf\nfonts/maths/cmbsy10.ttf\nfonts/maths/msbm10.ttf\ngreek/fcmrpg.ttf\ngreek/fcsrpg.ttf\ngreek/fcmbipg.ttf\ngreek/fctrpg.ttf\ngreek/fctrpg.xml\ngreek/fcmbpg.xml\ngreek/fcsbpg.ttf\ngreek/fcmrpg.xml\ngreek/language_greek.xml\ngreek/fcmripg.ttf\ngreek/fcsropg.ttf\ngreek/fcsrpg.xml\ngreek/fcsbpg.xml\ngreek/greek.map.xml\ngreek/mappings_greek.xml\ngreek/fcsropg.xml\ngreek/fcmbpg.ttf\ngreek/symbols_greek.xml\ngreek/fcmripg.xml\ngreek/fcmbipg.xml\ncyrillic/wnbx10.xml\ncyrillic/cyrillic.map.xml\ncyrillic/wnssi10.ttf\ncyrillic/wntt10.ttf\ncyrillic/wnss10.xml\ncyrillic/wnssbx10.xml\ncyrillic/wntt10.xml\ncyrillic/wnti10.xml\ncyrillic/wnbxti10.xml\ncyrillic/wnbxti10.ttf\ncyrillic/symbols_cyrillic.xml\ncyrillic/wnssbx10.ttf\ncyrillic/wnbx10.ttf\ncyrillic/wnr10.xml\ncyrillic/wnti10.ttf\ncyrillic/language_cyrillic.xml\ncyrillic/wnr10.ttf\ncyrillic/wnssi10.xml\ncyrillic/mappings_cyrillic.xml\ncyrillic/wnss10.ttf\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/SAMPLES.tex",
    "content": "%Side sets test\n\\sideset{^\\backprime}{'}\n\\sum_{x=1}^{\\infty} x\n\\sideset{a_1^2}{}\\sum_{x=1}^\\infty x_0\n\\\\\n\\sideset{_\\text{left bottom}'''}{_{\\text{right bottom}}'''}\n\\sum_{\\text{quite long text}}^\\infty x\n\\\\\n\\sideset{}{'}\n\\sum_{n<k,\\;\\text{$n$ odd}} nE_n\n\\\\\n\\sideset{}{'}\n\\sum^{n<k,\\;\\text{$n$ odd}} nE_n\n\\\\\nM_x''' M'''_x M^{'''}_x M_x{'''} M^{\\prime\\backprime}\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n%Cyrillic and Greek alphabet\n\\begin{array}{lr}\n  \\mbox{\\textcolor{Blue}{Russian}}&\\mbox{\\textcolor{Melon}{Greek}}\\\\\n  \\mbox{привет мир}&\\mbox{γειά κόσμο}\\\\\n  \\mbox{привет мир}&\\mbox{γειά κόσμο}\\\\\n  \\mathbf{\\mbox{привет мир}}&\\mathbf{\\mbox{γειά κόσμο}}\\\\\n  \\mathit{\\mbox{привет мир}}&\\mathit{\\mbox{γειά κόσμο}}\\\\\n  \\mathsf{\\mbox{привет мир}}&\\mathsf{\\mbox{γειά κόσμο}}\\\\\n  \\mathtt{\\mbox{привет мир}}&\\mathtt{\\mbox{γειά κόσμο}}\\\\\n  \\mathbf{\\mathit{\\mbox{привет мир}}}&\\mathbf{\\mathit{\\mbox{γειά κόσμο}}}\\\\\n  \\mathbf{\\mathsf{\\mbox{привет мир}}}&\\mathbf{\\mathsf{\\mbox{γειά κόσμο}}}\\\\\n  \\mathsf{\\mathit{\\mbox{привет мир}}}&\\mathsf{\\mathit{\\mbox{γειά κόσμο}}}\\\\\n  &\\\\\n  \\mbox{\\textcolor{Salmon}{Bulgarian}}&\\mbox{\\textcolor{Tan}{Serbian}}\\\\\n  \\mbox{здравей свят}&\\mbox{Хелло уорлд}\\\\\n  &\\\\\n  \\mbox{\\textcolor{Turquoise}{Bielorussian}}&\\mbox{\\textcolor{LimeGreen}{Ukrainian}}\\\\\n  \\mbox{прывітаньне Свет}&\\mbox{привіт світ}\\\\\n\\end{array}\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n%Complex formula test\n\\begin{array}{l}\n  \\forall\\varepsilon\\in\\mathbb{R}_+^*\\ \\exists\\eta>0\\ |x-x_0|\\leq\\eta\\Longrightarrow|f(x)-f(x_0)|\\leq\\varepsilon\\\\\n  \\det\n  \\begin{bmatrix}\n      a_{11}&a_{12}&\\cdots&a_{1n}\\\\\n      a_{21}&\\ddots&&\\vdots\\\\\n      \\vdots&&\\ddots&\\vdots\\\\\n      a_{n1}&\\cdots&\\cdots&a_{nn}\n  \\end{bmatrix}\n  \\overset{\\mathrm{def}}{=}\\sum_{\\sigma\\in\\mathfrak{S}_n}\\varepsilon(\\sigma)\\prod_{k=1}^n a_{k\\sigma(k)}\\\\\n  \\sideset{_\\alpha^\\beta}{_\\gamma^\\delta}{\\begin{pmatrix}a&b\\\\c&d\\end{pmatrix}}\\\\\n  \\int_0^\\infty{x^{2n} e^{-a x^2}\\,dx} = \\frac{2n-1}{2a} \n      \\int_0^\\infty{x^{2(n-1)} e^{-a x^2}\\,dx} = \\frac{(2n-1)!!}{2^{n+1}} \\sqrt{\\frac{\\pi}{a^{2n+1}}}\\\\\n  \\int_a^b{f(x)\\,dx} = (b - a) \\sum\\limits_{n = 1}^\\infty  \n      {\\sum\\limits_{m = 1}^{2^n  - 1} {\\left( { - 1} \\right)^{m + 1} } } 2^{ - n} f(a + m\\left( {b - a} \\right)2^{-n} )\\\\\n  \\int_{-\\pi}^{\\pi} \\sin(\\alpha x) \\sin^n(\\beta x) dx = \\textstyle{\\left \\{\n      \\begin{array}{cc}\n          (-1)^{(n+1)/2} (-1)^m \\frac{2 \\pi}{2^n} \\binom{n}{m} & n \\mbox{ odd},\\ \\alpha = \\beta (2m-n) \\\\\n          0 & \\mbox{otherwise} \\\\ \\end{array} \\right .}\\\\\n  L = \\int_a^b \\sqrt{ \\left|\\sum_{i,j=1}^ng_{ij}(\\gamma(t))\\left(\\frac{d}{dt}x^i\\circ\\gamma(t)\\right)\n      \\left(\\frac{d}{dt}x^j\\circ\\gamma(t)\\right)\\right|}\\,dt\\\\\n  \\begin{array}{rl}\n      s &= \\int_a^b\\left\\|\\frac{d}{dt}\\vec{r}\\,(u(t),v(t))\\right\\|\\,dt \\\\\n      &= \\int_a^b \\sqrt{u'(t)^2\\,\\vec{r}_u\\cdot\\vec{r}_u + 2u'(t)v'(t)\\, \\vec{r}_u\\cdot\n          \\vec{r}_v+ v'(t)^2\\,\\vec{r}_v\\cdot\\vec{r}_v}\\,\\,\\, dt. \n  \\end{array}\\\\\n\\end{array}\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n\\definecolor{gris}{gray}{0.9}\n\\definecolor{noir}{rgb}{0,0,0}\n\\definecolor{bleu}{rgb}{0,0,1}\n\\fatalIfCmdConflict{false}\n\\newcommand{\\pa}{\\left|}\n\\begin{array}{c}\n  \\LaTeX\\\\\n  \\begin{split}\n      &Тепловой\\ поток\\ \\mathrm{Тепловой\\ поток}\\ \\mathtt{Тепловой\\ поток}\\\\\n      &\\boldsymbol{\\mathrm{Тепловой\\ поток}}\\ \\mathsf{Тепловой\\ поток}\\\\\n      |I_2| &= \\pa\\int_0^T\\psi(t)\\left\\{ u(a,t)-\\int_{\\gamma(t)}^a \\frac{d\\theta}{k} (\\theta,t) \\int_a^\\theta c(\\xi) \n          u_t (\\xi,t)\\,d\\xi\\right\\}dt\\right|\\\\\n      &\\le C_6 \\Bigg|\\pa f \\int_\\Omega \\pa\\widetilde{S}^{-1,0}_{a,-}\n          W_2(\\Omega, \\Gamma_1)\\right|\\ \\right|\\left| |u|\\overset{\\circ}{\\to} W_2^{\\widetilde{A}}(\\Omega\\Gamma_r,T)\\right|\\Bigg|\\\\\n      &\\\\\n      &\\begin{pmatrix}\n          \\alpha&\\beta&\\gamma&\\delta\\\\\n          \\aleph&\\beth&\\gimel&\\daleth\\\\\n          \\mathfrak{A}&\\mathfrak{B}&\\mathfrak{C}&\\mathfrak{D}\\\\\n          \\boldsymbol{\\mathfrak{a}}&\\boldsymbol{\\mathfrak{b}}&\\boldsymbol{\\mathfrak{c}}&\\boldsymbol{\\mathfrak{d}}\n      \\end{pmatrix}\n      \\quad{(a+b)}^{\\frac{n}{2}}=\\sqrt{\\sum_{k=0}^n\\tbinom{n}{k}a^kb^{n-k}}\\quad \n          \\Biggl(\\biggl(\\Bigl(\\bigl(()\\bigr)\\Bigr)\\biggr)\\Biggr)\\\\\n      &\\forall\\varepsilon\\in\\mathbb{R}_+^*\\ \\exists\\eta>0\\ |x-x_0|\\leq\\eta\\Longrightarrow|f(x)-f(x_0)|\\leq\\varepsilon\\\\\n      &\\det\n      \\begin{bmatrix}\n          a_{11}&a_{12}&\\cdots&a_{1n}\\\\\n          a_{21}&\\ddots&&\\vdots\\\\\n          \\vdots&&\\ddots&\\vdots\\\\\n          a_{n1}&\\cdots&\\cdots&a_{nn}\n      \\end{bmatrix}\n      \\overset{\\mathrm{def}}{=}\\sum_{\\sigma\\in\\mathfrak{S}_n}\\varepsilon(\\sigma)\\prod_{k=1}^n a_{k\\sigma(k)}\\\\\n      &\\Delta f(x,y)=\\frac{\\partial^2f}{\\partial x^2}+\\frac{\\partial^2f}{\\partial y^2}\\qquad\\qquad \\fcolorbox{noir}{gris}\n          {n!\\underset{n\\rightarrow+\\infty}{\\sim} {\\left(\\frac{n}{e}\\right)}^n\\sqrt{2\\pi n}}\\\\\n      &\\sideset{_\\alpha^\\beta}{_\\gamma^\\delta}{\n      \\begin{pmatrix}\n          a&b\\\\\n          c&d\n      \\end{pmatrix}}\n      \\xrightarrow[T]{n\\pm i-j}\\sideset{^t}{}A\\xleftarrow{\\overrightarrow{u}\\wedge\\overrightarrow{v}}\n          \\underleftrightarrow{\\iint_{\\mathds{R}^2}e^{-\\left(x^2+y^2\\right)}\\,\\mathrm{d}x\\mathrm{d}y}\n  \\end{split}\\\\\n  \\rotatebox{30}{\\sum_{n=1}^{+\\infty}}\\quad\\mbox{Mirror rorriM}\\reflectbox{\\mbox{Mirror rorriM}}\n\\end{array}\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n\\begin{array}{|c|l|||r|c|}\n  \\hline\n  \\text{Matrix}&\\multicolumn{2}{|c|}{\\text{Multicolumns}}&\\text{Font sizes commands}\\cr\n  \\hline\n  \\begin{pmatrix}\n      \\alpha_{11}&\\cdots&\\alpha_{1n}\\cr\n      \\hdotsfor{3}\\cr\n      \\alpha_{n1}&\\cdots&\\alpha_{nn}\n  \\end{pmatrix}\n  &\\Large \\text{Large Right}&\\small \\text{small Left}&\\tiny \\text{tiny Tiny}\\cr\n  \\hline\n  \\multicolumn{4}{|c|}{\\Huge \\text{Huge Multicolumns}}\\cr\n  \\hline\n\\end{array}\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n\\cornersize{0.2}\n\\begin{array}{cc}\n  \\fbox{\\text{A framed box with \\textdbend}}&\\shadowbox{\\text{A shadowed box}}\\cr\n  \\doublebox{\\text{A double framed box}}&\\ovalbox{\\text{An oval framed box}}\\cr\n\\end{array}\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n%ASCII character\n\\text{!\"#'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]\n^_`abcdefghijklmnopqrstuvwxyz{|}~\n\n     ¡¢£¤¥¦§¨©ª«¬­\n®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ}\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n%Table test\n\\newcolumntype{s}{>{\\color{#1234B6}}c}\n\\begin{array}{|c|c|c|s|}\n  \\hline\n  \\rowcolor{Tan}\\multicolumn{4}{|c|}{\\textcolor{white}{\\bold{\\text{Table Head}}}}\\\\\n  \\hline\n  \\text{Matrix}&\\multicolumn{2}{|c|}{\\text{Multicolumns}}&\\text{Font size commands}\\\\\n  \\hline\n  \\begin{pmatrix}\n      \\alpha_{11}&\\cdots&\\alpha_{1n}\\\\\n      \\hdotsfor{3}\\\\\n      \\alpha_{n1}&\\cdots&\\alpha_{nn}\n  \\end{pmatrix}\n  &\\large \\text{Left}&\\cellcolor{#00bde5}\\small \\textcolor{white}{\\text{\\bold{Right}}}\n  &\\small \\text{small Small}\\\\\n  \\hline\n  \\multicolumn{4}{|c|}{\\text{Table Foot}}\\\\\n  \\hline\n\\end{array}\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n\\rlap{\\overbrace{\\phantom{1 + a + b + \\cdots + z}}^{\\text{total + 1}}}\n1 + \\underbrace{a + b + \\cdots + z}_{\\text{total}}\n\\\\\n\\frac{a\\cancel{b}}{\\cancel{b}} = a;\n\\frac{a\\bcancel{b}}{\\bcancel{b}} = a;\n\\frac{a\\xcancel{b}}{\\xcancel{b}} = a;\n\\\\\n\\text{A long division: }\\longdiv{12345}{13}\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n\\left\\{\n    \\begin{array}{l}\n    2a < -1,\\\\\n    a + 8 \\ge 5,\n    \\end{array}\n\\right.\n\\\\\nP_{r-j}=\\begin{cases}\n0& \\text{if $r-j$ is odd},\\\\\nr!\\,(-1)^{(r-j)/2}& \\text{if $r-j$ is even}.\n\\end{cases}\\text{Cases}\n\\\\\nP_{r-j}=\\left\\{\\begin{array}{@{}ll@{\\,}}\n0& \\text{if $r-j$ is odd},\\\\\nr!\\,(-1)^{(r-j)/2}& \\text{if $r-j$ is even}.\n\\end{array}\\right.\\text{Cases}\n\\\\\nP_{r-j}=\\begin{cases}\n4-x\\geq 0 \\\\\n3-x\\geq 1\n\\end{cases}\\text{Cases}\n\\\\\n\\left\\{\\begin{array}{@{}ll}\n1 & 2\\\\\n3 & 4\n\\end{array}\\right.\\text{Equation}\n\\\\\n\\left\\{\\begin{array}{l@{}l}\n1 & 2\\\\\n3 & 4\n\\end{array}\\right.\\text{Equation}\n\\\\\n\\left\\{\\begin{array}{ll@{}}\n1 & 2\\\\\n3 & 4\n\\end{array}\\right.\\text{Equation}\n\\\\\n\\begin{split}\nH_c&=\\frac{1}{2n} \\sum^n_{l=0}(-1)^{l}(n-{l})^{p-2}\n\\sum_{l _1+\\dots+ l _p=l}\\prod^p_{i=1} \\binom{n_i}{l _i}\\\\\n&\\quad\\cdot[(n-l )-(n_i-l _i)]^{n_i-l _i}\\cdot\n\\Bigl[(n-l )^2-\\sum^p_{j=1}(n_i-l _i)^2\\Bigr].\n\\end{split}\n\\\\\n\\begin{align}\nA_1&=N_0(\\lambda;\\Omega’)-\\phi(\\lambda;\\Omega’),\\\\\nA_2&=\\phi(\\lambda;\\Omega’)-\\phi(\\lambda;\\Omega),\\\\\n\\intertext{and}\nA_3&=\\mathcal{N}(\\lambda;\\omega).\n\\end{align}\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n\\frac{\\sum_{n > 0} z^n}\n{\\prod_{1\\leq k\\leq n} (1-q^k)}\n\\\\\n\\frac{{\\displaystyle\\sum_{n > 0} z^n}}\n{{\\displaystyle\\prod_{1\\leq k\\leq n} (1-q^k)}}\n\\\\\n\\frac{{\\displaystyle\\sum\\nolimits_{n> 0} z^n}}\n{{\\displaystyle\\prod\\nolimits_{1\\leq k\\leq n} (1-q^k)}}\n\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n\\cfrac{1}{\\sqrt{2}+\n\\cfrac{1}{\\sqrt{2}+\n\\cfrac{1}{\\sqrt{2}+\\dotsb\n}}}\n\\\\\n\\biggl[\n\\sum_i a_i\\biggl\\lvert\\sum_j x_{ij}\n\\biggr\\rvert^p\\biggr]^{1/p}\n\\\\\n\\biggl[\n\\sum_i a_i\\Bigl\\lvert\\sum_j x_{ij}\n\\Bigr\\rvert^p\\biggr]^{1/p}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/cyrillic/cyrillic.map.xml",
    "content": "<?xml version='1.0'?>\n<SymbolMappings>\n  <SymbolMapping name=\"dotlessi\" ch=\"305\" fontId=\"wnr10\"/>\n<!-- Modern Russian -->\n  <SymbolMapping name=\"CYRA\" ch=\"1040\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRB\" ch=\"1041\" fontId=\"wnr10\"/> \n  <SymbolMapping name=\"CYRV\" ch=\"1042\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRG\" ch=\"1043\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRD\" ch=\"1044\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRE\" ch=\"1045\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRYO\" ch=\"1025\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRZH\" ch=\"1046\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRZ\" ch=\"1047\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRI\" ch=\"1048\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRIO\" ch=\"1049\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRK\" ch=\"1050\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRL\" ch=\"1051\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRM\" ch=\"1052\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRN\" ch=\"1053\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRO\" ch=\"1054\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRP\" ch=\"1055\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRR\" ch=\"1056\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRS\" ch=\"1057\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRT\" ch=\"1058\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRU\" ch=\"1059\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRF\" ch=\"1060\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRH\" ch=\"1061\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRC\" ch=\"1062\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRCH\" ch=\"1063\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRSH\" ch=\"1064\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRSHCH\" ch=\"1065\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRHRDSN\" ch=\"1066\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRY\" ch=\"1067\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRSFTSN\" ch=\"1068\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYREREV\" ch=\"1069\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRYU\" ch=\"1070\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRYA\" ch=\"1071\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyra\" ch=\"1072\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrb\" ch=\"1073\" fontId=\"wnr10\"/> \n  <SymbolMapping name=\"cyrv\" ch=\"1074\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrg\" ch=\"1075\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrd\" ch=\"1076\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyre\" ch=\"1077\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyryo\" ch=\"1105\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrzh\" ch=\"1078\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrz\" ch=\"1079\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyri\" ch=\"1080\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrio\" ch=\"1081\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrk\" ch=\"1082\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrl\" ch=\"1083\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrm\" ch=\"1084\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrn\" ch=\"1085\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyro\" ch=\"1086\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrp\" ch=\"1087\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrr\" ch=\"1088\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrs\" ch=\"1089\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrt\" ch=\"1090\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyru\" ch=\"1091\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrf\" ch=\"1092\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrh\" ch=\"1093\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrc\" ch=\"1094\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrch\" ch=\"1095\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrsh\" ch=\"1096\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrshch\" ch=\"1097\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrhrdsn\" ch=\"1098\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyry\" ch=\"1099\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrsftsn\" ch=\"1100\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrerev\" ch=\"1101\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyryu\" ch=\"1102\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrya\" ch=\"1103\" fontId=\"wnr10\"/>\n<!-- Ukrainian -->\n  <SymbolMapping name=\"CYRIE\" ch=\"1028\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRII\" ch=\"1030\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrie\" ch=\"1108\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrii\" ch=\"1110\" fontId=\"wnr10\"/>\n<!-- Other slavic languages and Old Russian -->\n  <SymbolMapping name=\"CYRDJE\" ch=\"1026\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRDZE\" ch=\"1029\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRJE\" ch=\"1032\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRLJE\" ch=\"1033\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRNJE\" ch=\"1034\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRTSHE\" ch=\"1035\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRDZHE\" ch=\"1039\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRIZH\" ch=\"1140\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRYAT\" ch=\"1122\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRFITA\" ch=\"1138\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrdje\" ch=\"1106\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrdze\" ch=\"1109\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrje\" ch=\"1112\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrlje\" ch=\"1113\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrnje\" ch=\"1114\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrtshe\" ch=\"1115\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrdzhe\" ch=\"1119\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrizh\" ch=\"1141\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyryat\" ch=\"1123\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrfita\" ch=\"1139\" fontId=\"wnr10\"/>\n<!-- Accent -->\n  <SymbolMapping name=\"cyrbreve\" ch=\"774\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrddot\" ch=\"776\" fontId=\"wnr10\"/>\n</SymbolMappings>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/cyrillic/language_cyrillic.xml",
    "content": "<?xml version='1.0'?>\n<!--\n  language_cyrillic.xml\n-->\n\n<TeXFont>\n\n<SymbolMappings>\n  <Mapping include=\"cyrillic.map.xml\" />\n</SymbolMappings>\n\n<FontDescriptions>\n  <Metrics include=\"wnr10.xml\" />\n  <Metrics include=\"wnti10.xml\" />\n  <Metrics include=\"wntt10.xml\" />\n  <Metrics include=\"wnss10.xml\" />\n  <Metrics include=\"wnssi10.xml\" />\n  <Metrics include=\"wnssbx10.xml\" />\n  <Metrics include=\"wnbx10.xml\" />\n  <Metrics include=\"wnbxti10.xml\" />\n</FontDescriptions>\n\n<TeXSymbols include=\"symbols_cyrillic.xml\" />\n\n<FormulaSettings include=\"mappings_cyrillic.xml\" />\n\n</TeXFont>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/cyrillic/mappings_cyrillic.xml",
    "content": "<?xml version='1.0'?>\n<!--\n  mappings_cyrillic.xml\n-->\n\n<FormulaSettings>\n  <CharacterToSymbolMappings>\n    <Map char=\"&#305;\" symbol=\"dotlessi\"/>\n    <Map char=\"&#1040;\" symbol=\"CYRA\"/>\n    <Map char=\"&#1041;\" symbol=\"CYRB\"/>\n    <Map char=\"&#1042;\" symbol=\"CYRV\"/>\n    <Map char=\"&#1043;\" symbol=\"CYRG\"/>\n    <Map char=\"&#1044;\" symbol=\"CYRD\"/>\n    <Map char=\"&#1045;\" symbol=\"CYRE\"/>\n    <Map char=\"&#1025;\" symbol=\"CYRYO\"/>\n    <Map char=\"&#1046;\" symbol=\"CYRZH\"/>\n    <Map char=\"&#1047;\" symbol=\"CYRZ\"/>\n    <Map char=\"&#1048;\" symbol=\"CYRI\"/>\n    <Map char=\"&#1049;\" symbol=\"CYRIO\"/>\n    <Map char=\"&#1050;\" symbol=\"CYRK\"/>\n    <Map char=\"&#1051;\" symbol=\"CYRL\"/>\n    <Map char=\"&#1052;\" symbol=\"CYRM\"/>\n    <Map char=\"&#1053;\" symbol=\"CYRN\"/>\n    <Map char=\"&#1054;\" symbol=\"CYRO\"/>\n    <Map char=\"&#1055;\" symbol=\"CYRP\"/>\n    <Map char=\"&#1056;\" symbol=\"CYRR\"/>\n    <Map char=\"&#1057;\" symbol=\"CYRS\"/>\n    <Map char=\"&#1058;\" symbol=\"CYRT\"/>\n    <Map char=\"&#1059;\" symbol=\"CYRU\"/>\n    <Map char=\"&#1060;\" symbol=\"CYRF\"/>\n    <Map char=\"&#1061;\" symbol=\"CYRH\"/>\n    <Map char=\"&#1062;\" symbol=\"CYRC\"/>\n    <Map char=\"&#1063;\" symbol=\"CYRCH\"/>\n    <Map char=\"&#1064;\" symbol=\"CYRSH\"/>\n    <Map char=\"&#1065;\" symbol=\"CYRSHCH\"/>\n    <Map char=\"&#1066;\" symbol=\"CYRHRDSN\"/>\n    <Map char=\"&#1067;\" symbol=\"CYRY\"/>\n    <Map char=\"&#1068;\" symbol=\"CYRSFTSN\"/>\n    <Map char=\"&#1069;\" symbol=\"CYREREV\"/>\n    <Map char=\"&#1070;\" symbol=\"CYRYU\"/>\n    <Map char=\"&#1071;\" symbol=\"CYRYA\"/>\n    <Map char=\"&#1072;\" symbol=\"cyra\"/>\n    <Map char=\"&#1073;\" symbol=\"cyrb\"/>\n    <Map char=\"&#1074;\" symbol=\"cyrv\"/>\n    <Map char=\"&#1075;\" symbol=\"cyrg\"/>\n    <Map char=\"&#1076;\" symbol=\"cyrd\"/>\n    <Map char=\"&#1077;\" symbol=\"cyre\"/>\n    <Map char=\"&#1105;\" symbol=\"cyryo\"/>\n    <Map char=\"&#1078;\" symbol=\"cyrzh\"/>\n    <Map char=\"&#1079;\" symbol=\"cyrz\"/>\n    <Map char=\"&#1080;\" symbol=\"cyri\"/>\n    <Map char=\"&#1081;\" symbol=\"cyrio\"/>\n    <Map char=\"&#1082;\" symbol=\"cyrk\"/>\n    <Map char=\"&#1083;\" symbol=\"cyrl\"/>\n    <Map char=\"&#1084;\" symbol=\"cyrm\"/>\n    <Map char=\"&#1085;\" symbol=\"cyrn\"/>\n    <Map char=\"&#1086;\" symbol=\"cyro\"/>\n    <Map char=\"&#1087;\" symbol=\"cyrp\"/>\n    <Map char=\"&#1088;\" symbol=\"cyrr\"/>\n    <Map char=\"&#1089;\" symbol=\"cyrs\"/>\n    <Map char=\"&#1090;\" symbol=\"cyrt\"/>\n    <Map char=\"&#1091;\" symbol=\"cyru\"/>\n    <Map char=\"&#1092;\" symbol=\"cyrf\"/>\n    <Map char=\"&#1093;\" symbol=\"cyrh\"/>\n    <Map char=\"&#1094;\" symbol=\"cyrc\"/>\n    <Map char=\"&#1095;\" symbol=\"cyrch\"/>\n    <Map char=\"&#1096;\" symbol=\"cyrsh\"/>\n    <Map char=\"&#1097;\" symbol=\"cyrshch\"/>\n    <Map char=\"&#1098;\" symbol=\"cyrhrdsn\"/>\n    <Map char=\"&#1099;\" symbol=\"cyry\"/>\n    <Map char=\"&#1100;\" symbol=\"cyrsftsn\"/>\n    <Map char=\"&#1101;\" symbol=\"cyrerev\"/>\n    <Map char=\"&#1102;\" symbol=\"cyryu\"/>\n    <Map char=\"&#1103;\" symbol=\"cyrya\"/>\n    <Map char=\"&#1028;\" symbol=\"CYRIE\"/>\n    <Map char=\"&#1030;\" symbol=\"CYRII\"/>\n    <Map char=\"&#1108;\" symbol=\"cyrie\"/>\n    <Map char=\"&#1110;\" symbol=\"cyrii\"/>\n    <Map char=\"&#1026;\" symbol=\"CYRDJE\"/>\n    <Map char=\"&#1029;\" symbol=\"CYRDZE\"/>\n    <Map char=\"&#1032;\" symbol=\"CYRJE\"/>\n    <Map char=\"&#1033;\" symbol=\"CYRLJE\"/>\n    <Map char=\"&#1034;\" symbol=\"CYRNJE\"/>\n    <Map char=\"&#1035;\" symbol=\"CYRTSHE\"/>\n    <Map char=\"&#1039;\" symbol=\"CYRDZHE\"/>\n    <Map char=\"&#1140;\" symbol=\"CYRIZH\"/>\n    <Map char=\"&#1122;\" symbol=\"CYRYAT\"/>\n    <Map char=\"&#1138;\" symbol=\"CYRFITA\"/>\n    <Map char=\"&#1106;\" symbol=\"cyrdje\"/>\n    <Map char=\"&#1109;\" symbol=\"cyrdze\"/>\n    <Map char=\"&#1112;\" symbol=\"cyrje\"/>\n    <Map char=\"&#1113;\" symbol=\"cyrlje\"/>\n    <Map char=\"&#1114;\" symbol=\"cyrnje\"/>\n    <Map char=\"&#1115;\" symbol=\"cyrtshe\"/>\n    <Map char=\"&#1119;\" symbol=\"cyrdzhe\"/>\n    <Map char=\"&#1141;\" symbol=\"cyrizh\"/>\n    <Map char=\"&#1123;\" symbol=\"cyryat\"/>\n    <Map char=\"&#1139;\" symbol=\"cyrfita\"/>\n  </CharacterToSymbolMappings>\n  \n  <CharacterToFormulaMappings>\n    <Map char=\"&#1024;\" formula=\"\\`\\CYRE\"/>\n    <Map char=\"&#1027;\" formula=\"\\'\\CYRG\"/>\n    <Map char=\"&#1031;\" formula=\"\\cyrddot\\CYRII\"/>\n    <Map char=\"&#1111;\" formula=\"\\cyrddot\\dotlessi\"/>\n    <Map char=\"&#1027;\" formula=\"\\'\\CYRG\"/>\n    <Map char=\"&#1027;\" formula=\"\\'\\CYRK\"/>\n    <Map char=\"&#1037;\" formula=\"\\`\\CYRI\"/>\n    <Map char=\"&#1038;\" formula=\"\\cyrbreve\\CYRU\"/>\n    <Map char=\"&#1104;\" formula=\"\\`\\cyre\"/>\n    <Map char=\"&#1107;\" formula=\"\\'\\cyrg\"/>\n    <Map char=\"&#1116;\" formula=\"\\'\\cyrk\"/>\n    <Map char=\"&#1117;\" formula=\"\\`\\cyri\"/>\n    <Map char=\"&#1118;\" formula=\"\\cyrbreve\\cyru\"/>\n  </CharacterToFormulaMappings>\n</FormulaSettings>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/cyrillic/symbols_cyrillic.xml",
    "content": "<?xml version='1.0'?>\n<!--\n  symbols_cyrillic.xml\n-->\n\n<TeXSymbols>\n  <Symbol name=\"dotlessi\" type=\"ord\"/>\n  <Symbol name=\"cyrbreve\" type=\"acc\"/>\n  <Symbol name=\"cyrddot\" type=\"acc\"/>\n  <Symbol name=\"CYRA\" type=\"ord\"/>\n  <Symbol name=\"CYRB\" type=\"ord\"/> \n  <Symbol name=\"CYRV\" type=\"ord\"/>\n  <Symbol name=\"CYRG\" type=\"ord\"/>\n  <Symbol name=\"CYRD\" type=\"ord\"/>\n  <Symbol name=\"CYRE\" type=\"ord\"/>\n  <Symbol name=\"CYRYO\" type=\"ord\"/>\n  <Symbol name=\"CYRZH\" type=\"ord\"/>\n  <Symbol name=\"CYRZ\" type=\"ord\"/>\n  <Symbol name=\"CYRE\" type=\"ord\"/>\n  <Symbol name=\"CYRI\" type=\"ord\"/>\n  <Symbol name=\"CYRIO\" type=\"ord\"/>\n  <Symbol name=\"CYRK\" type=\"ord\"/>\n  <Symbol name=\"CYRL\" type=\"ord\"/>\n  <Symbol name=\"CYRM\" type=\"ord\"/>\n  <Symbol name=\"CYRN\" type=\"ord\"/>\n  <Symbol name=\"CYRO\" type=\"ord\"/>\n  <Symbol name=\"CYRP\" type=\"ord\"/>\n  <Symbol name=\"CYRR\" type=\"ord\"/>\n  <Symbol name=\"CYRS\" type=\"ord\"/>\n  <Symbol name=\"CYRT\" type=\"ord\"/>\n  <Symbol name=\"CYRU\" type=\"ord\"/>\n  <Symbol name=\"CYRF\" type=\"ord\"/>\n  <Symbol name=\"CYRH\" type=\"ord\"/>\n  <Symbol name=\"CYRC\" type=\"ord\"/>\n  <Symbol name=\"CYRCH\" type=\"ord\"/>\n  <Symbol name=\"CYRSH\" type=\"ord\"/>\n  <Symbol name=\"CYRSHCH\" type=\"ord\"/>\n  <Symbol name=\"CYRHRDSN\" type=\"ord\"/>\n  <Symbol name=\"CYRY\" type=\"ord\"/>\n  <Symbol name=\"CYRSFTSN\" type=\"ord\"/>\n  <Symbol name=\"CYREREV\" type=\"ord\"/>\n  <Symbol name=\"CYRYU\" type=\"ord\"/>\n  <Symbol name=\"CYRYA\" type=\"ord\"/>\n  <Symbol name=\"cyra\" type=\"ord\"/>\n  <Symbol name=\"cyrb\" type=\"ord\"/> \n  <Symbol name=\"cyrv\" type=\"ord\"/>\n  <Symbol name=\"cyrg\" type=\"ord\"/>\n  <Symbol name=\"cyrd\" type=\"ord\"/>\n  <Symbol name=\"cyre\" type=\"ord\"/>\n  <Symbol name=\"cyryo\" type=\"ord\"/>\n  <Symbol name=\"cyrzh\" type=\"ord\"/>\n  <Symbol name=\"cyrz\" type=\"ord\"/>\n  <Symbol name=\"cyre\" type=\"ord\"/>\n  <Symbol name=\"cyri\" type=\"ord\"/>\n  <Symbol name=\"cyrio\" type=\"ord\"/>\n  <Symbol name=\"cyrk\" type=\"ord\"/>\n  <Symbol name=\"cyrl\" type=\"ord\"/>\n  <Symbol name=\"cyrm\" type=\"ord\"/>\n  <Symbol name=\"cyrn\" type=\"ord\"/>\n  <Symbol name=\"cyro\" type=\"ord\"/>\n  <Symbol name=\"cyrp\" type=\"ord\"/>\n  <Symbol name=\"cyrr\" type=\"ord\"/>\n  <Symbol name=\"cyrs\" type=\"ord\"/>\n  <Symbol name=\"cyrt\" type=\"ord\"/>\n  <Symbol name=\"cyru\" type=\"ord\"/>\n  <Symbol name=\"cyrf\" type=\"ord\"/>\n  <Symbol name=\"cyrh\" type=\"ord\"/>\n  <Symbol name=\"cyrc\" type=\"ord\"/>\n  <Symbol name=\"cyrch\" type=\"ord\"/>\n  <Symbol name=\"cyrsh\" type=\"ord\"/>\n  <Symbol name=\"cyrshch\" type=\"ord\"/>\n  <Symbol name=\"cyrhrdsn\" type=\"ord\"/>\n  <Symbol name=\"cyry\" type=\"ord\"/>\n  <Symbol name=\"cyrsftsn\" type=\"ord\"/>\n  <Symbol name=\"cyrerev\" type=\"ord\"/>\n  <Symbol name=\"cyryu\" type=\"ord\"/>\n  <Symbol name=\"cyrya\" type=\"ord\"/>\n<!-- Ukrainian -->\n  <Symbol name=\"CYRIE\" type=\"ord\"/>\n  <Symbol name=\"CYRII\" type=\"ord\"/>\n  <Symbol name=\"cyrie\" type=\"ord\"/>\n  <Symbol name=\"cyrii\" type=\"ord\"/>\n<!-- Other slavic languages and Old Russian -->\n  <Symbol name=\"CYRDJE\" type=\"ord\"/>\n  <Symbol name=\"CYRDZE\" type=\"ord\"/>\n  <Symbol name=\"CYRJE\" type=\"ord\"/>\n  <Symbol name=\"CYRLJE\" type=\"ord\"/>\n  <Symbol name=\"CYRNJE\" type=\"ord\"/>\n  <Symbol name=\"CYRTSHE\" type=\"ord\"/>\n  <Symbol name=\"CYRDZHE\" type=\"ord\"/>\n  <Symbol name=\"CYRIZH\" type=\"ord\"/>\n  <Symbol name=\"CYRYAT\" type=\"ord\"/>\n  <Symbol name=\"CYRFITA\" type=\"ord\"/>\n  <Symbol name=\"cyrdje\" type=\"ord\"/>\n  <Symbol name=\"cyrdze\" type=\"ord\"/>\n  <Symbol name=\"cyrje\" type=\"ord\"/>\n  <Symbol name=\"cyrlje\" type=\"ord\"/>\n  <Symbol name=\"cyrnje\" type=\"ord\"/>\n  <Symbol name=\"cyrtshe\" type=\"ord\"/>\n  <Symbol name=\"cyrdzhe\" type=\"ord\"/>\n  <Symbol name=\"cyrizh\" type=\"ord\"/>\n  <Symbol name=\"cyryat\" type=\"ord\"/>\n  <Symbol name=\"cyrfita\" type=\"ord\"/>\n</TeXSymbols>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/cyrillic/wnbx10.xml",
    "content": "<Font name=\"wnbx10.ttf\" id=\"wnbx10\" space=\"0.383331\" xHeight=\"0.444445\" quad=\"1.149994\" unicode=\"95\" itVersion=\"wnbxti10\" ssVersion=\"wnssbx10\" ttVersion=\"wntt10\">\n   <Char code=\"1034\" width=\"1.234021\" height=\"0.686111\" >\n      <Kern code=\"1046\" val=\"-0.031944\"/>\n      <Kern code=\"1061\" val=\"-0.031944\"/>\n      <Kern code=\"1054\" val=\"-0.031944\"/>\n      <Kern code=\"1060\" val=\"-0.031944\"/>\n      <Kern code=\"1138\" val=\"-0.031944\"/>\n      <Kern code=\"1057\" val=\"-0.031944\"/>\n      <Kern code=\"1028\" val=\"-0.031944\"/>\n      <Kern code=\"1058\" val=\"-0.095833\"/>\n      <Kern code=\"1066\" val=\"-0.095833\"/>\n      <Kern code=\"1026\" val=\"-0.095833\"/>\n      <Kern code=\"1035\" val=\"-0.095833\"/>\n      <Kern code=\"1122\" val=\"-0.095833\"/>\n      <Kern code=\"1063\" val=\"-0.095833\"/>\n      <Kern code=\"1059\" val=\"-0.095833\"/>\n      <Kern code=\"1140\" val=\"-0.127777\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.095833\"/>\n   </Char>\n   <Char code=\"1033\" width=\"1.234021\" height=\"0.686111\" >\n      <Kern code=\"1046\" val=\"-0.031944\"/>\n      <Kern code=\"1061\" val=\"-0.031944\"/>\n      <Kern code=\"1054\" val=\"-0.031944\"/>\n      <Kern code=\"1060\" val=\"-0.031944\"/>\n      <Kern code=\"1138\" val=\"-0.031944\"/>\n      <Kern code=\"1057\" val=\"-0.031944\"/>\n      <Kern code=\"1028\" val=\"-0.031944\"/>\n      <Kern code=\"1058\" val=\"-0.095833\"/>\n      <Kern code=\"1066\" val=\"-0.095833\"/>\n      <Kern code=\"1026\" val=\"-0.095833\"/>\n      <Kern code=\"1035\" val=\"-0.095833\"/>\n      <Kern code=\"1122\" val=\"-0.095833\"/>\n      <Kern code=\"1063\" val=\"-0.095833\"/>\n      <Kern code=\"1059\" val=\"-0.095833\"/>\n      <Kern code=\"1140\" val=\"-0.127777\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.095833\"/>\n   </Char>\n   <Char code=\"1039\" width=\"0.901384\" height=\"0.686111\" depth=\"0.194445\" />\n   <Char code=\"1069\" width=\"0.830551\" height=\"0.686111\" >\n      <Kern code=\"1040\" val=\"-0.031944\"/>\n      <Kern code=\"1044\" val=\"-0.031944\"/>\n      <Kern code=\"1046\" val=\"-0.031944\"/>\n      <Kern code=\"1061\" val=\"-0.031944\"/>\n      <Kern code=\"1059\" val=\"-0.031944\"/>\n      <Kern code=\"1140\" val=\"-0.031944\"/>\n      <Kern code=\"1071\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1030\" width=\"0.43611\" height=\"0.686111\" >\n      <Kern code=\"1030\" val=\"0.031944\"/>\n   </Char>\n   <Char code=\"1028\" width=\"0.830551\" height=\"0.686111\" />\n   <Char code=\"1026\" width=\"0.959717\" height=\"0.686111\" >\n      <Kern code=\"1046\" val=\"-0.031944\"/>\n      <Kern code=\"1061\" val=\"-0.031944\"/>\n      <Kern code=\"1054\" val=\"-0.031944\"/>\n      <Kern code=\"1060\" val=\"-0.031944\"/>\n      <Kern code=\"1138\" val=\"-0.031944\"/>\n      <Kern code=\"1057\" val=\"-0.031944\"/>\n      <Kern code=\"1028\" val=\"-0.031944\"/>\n      <Kern code=\"1058\" val=\"-0.095833\"/>\n      <Kern code=\"1066\" val=\"-0.095833\"/>\n      <Kern code=\"1026\" val=\"-0.095833\"/>\n      <Kern code=\"1035\" val=\"-0.095833\"/>\n      <Kern code=\"1122\" val=\"-0.095833\"/>\n      <Kern code=\"1063\" val=\"-0.095833\"/>\n      <Kern code=\"1059\" val=\"-0.095833\"/>\n      <Kern code=\"1140\" val=\"-0.127777\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.095833\"/>\n   </Char>\n   <Char code=\"1035\" width=\"0.8784685\" height=\"0.686111\" />\n   <Char code=\"1114\" width=\"0.86319\" height=\"0.444445\" >\n      <Kern code=\"1091\" val=\"-0.063889\"/>\n      <Kern code=\"1141\" val=\"-0.063889\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.095833\"/>\n      <Kern code=\"1086\" val=\"-0.031944\"/>\n      <Kern code=\"1139\" val=\"-0.031944\"/>\n      <Kern code=\"1092\" val=\"-0.031944\"/>\n      <Kern code=\"1108\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1113\" width=\"0.86319\" height=\"0.444445\" >\n      <Kern code=\"1091\" val=\"-0.063889\"/>\n      <Kern code=\"1141\" val=\"-0.063889\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.095833\"/>\n      <Kern code=\"1086\" val=\"-0.031944\"/>\n      <Kern code=\"1139\" val=\"-0.031944\"/>\n      <Kern code=\"1092\" val=\"-0.031944\"/>\n      <Kern code=\"1108\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1119\" width=\"0.6388855\" height=\"0.444445\" depth=\"0.162038\" />\n   <Char code=\"1101\" width=\"0.511108\" height=\"0.444445\" >\n      <Kern code=\"1076\" val=\"-0.031944\"/>\n      <Kern code=\"1078\" val=\"-0.031944\"/>\n      <Kern code=\"1093\" val=\"-0.031944\"/>\n      <Kern code=\"1103\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1110\" width=\"0.319443\" height=\"0.694445\" />\n   <Char code=\"1108\" width=\"0.50472\" height=\"0.444445\" />\n   <Char code=\"1106\" width=\"0.606941\" height=\"0.694445\" depth=\"0.194445\" />\n   <Char code=\"1115\" width=\"0.6388855\" height=\"0.694445\" />\n   <Char code=\"1070\" width=\"1.273605\" height=\"0.686111\" >\n      <Kern code=\"1040\" val=\"-0.031944\"/>\n      <Kern code=\"1044\" val=\"-0.031944\"/>\n      <Kern code=\"1046\" val=\"-0.031944\"/>\n      <Kern code=\"1061\" val=\"-0.031944\"/>\n      <Kern code=\"1059\" val=\"-0.031944\"/>\n      <Kern code=\"1140\" val=\"-0.031944\"/>\n      <Kern code=\"1071\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1046\" width=\"1.366656\" height=\"0.686111\" >\n      <Kern code=\"1054\" val=\"-0.031944\"/>\n      <Kern code=\"1060\" val=\"-0.031944\"/>\n      <Kern code=\"1138\" val=\"-0.031944\"/>\n      <Kern code=\"1057\" val=\"-0.031944\"/>\n      <Kern code=\"1028\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.031944\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1049\" width=\"0.901384\" height=\"0.894394\" />\n   <Char code=\"1025\" width=\"0.755551\" height=\"0.894394\" />\n   <Char code=\"1140\" width=\"0.945828\" height=\"0.686111\" italic=\"0.015973\" >\n      <Kern code=\"1040\" val=\"-0.127777\"/>\n      <Kern code=\"1071\" val=\"-0.127777\"/>\n      <Kern code=\"1054\" val=\"-0.031944\"/>\n      <Kern code=\"1060\" val=\"-0.031944\"/>\n      <Kern code=\"1138\" val=\"-0.031944\"/>\n      <Kern code=\"1057\" val=\"-0.031944\"/>\n      <Kern code=\"1028\" val=\"-0.031944\"/>\n      <Kern code=\"1072\" val=\"-0.095833\"/>\n      <Kern code=\"1086\" val=\"-0.095833\"/>\n      <Kern code=\"1139\" val=\"-0.095833\"/>\n      <Kern code=\"1077\" val=\"-0.095833\"/>\n      <Kern code=\"1105\" val=\"-0.095833\"/>\n      <Kern code=\"1076\" val=\"-0.127777\"/>\n      <Kern code=\"1083\" val=\"-0.127777\"/>\n      <Kern code=\"1113\" val=\"-0.127777\"/>\n      <Kern code=\"1103\" val=\"-0.127777\"/>\n   </Char>\n   <Char code=\"1138\" width=\"0.89444\" height=\"0.686111\" >\n      <Kern code=\"1040\" val=\"-0.031944\"/>\n      <Kern code=\"1044\" val=\"-0.031944\"/>\n      <Kern code=\"1046\" val=\"-0.031944\"/>\n      <Kern code=\"1061\" val=\"-0.031944\"/>\n      <Kern code=\"1059\" val=\"-0.031944\"/>\n      <Kern code=\"1140\" val=\"-0.031944\"/>\n      <Kern code=\"1071\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1029\" width=\"0.6388855\" height=\"0.686111\" />\n   <Char code=\"1071\" width=\"0.901384\" height=\"0.686111\" />\n   <Char code=\"1102\" width=\"0.862495\" height=\"0.444445\" >\n      <Kern code=\"1076\" val=\"-0.031944\"/>\n      <Kern code=\"1078\" val=\"-0.031944\"/>\n      <Kern code=\"1093\" val=\"-0.031944\"/>\n      <Kern code=\"1103\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1078\" width=\"0.958328\" height=\"0.444445\" >\n      <Kern code=\"1072\" val=\"-0.031944\"/>\n      <Kern code=\"1086\" val=\"-0.031944\"/>\n      <Kern code=\"1139\" val=\"-0.031944\"/>\n      <Kern code=\"1089\" val=\"-0.031944\"/>\n      <Kern code=\"1108\" val=\"-0.031944\"/>\n      <Kern code=\"1077\" val=\"-0.031944\"/>\n      <Kern code=\"1105\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1081\" width=\"0.6388855\" height=\"0.652727\" />\n   <Char code=\"1105\" width=\"0.5270815\" height=\"0.686111\" />\n   <Char code=\"1141\" width=\"0.685414\" height=\"0.444445\" italic=\"0.015973\" >\n      <Kern code=\"1072\" val=\"-0.031944\"/>\n      <Kern code=\"1086\" val=\"-0.031944\"/>\n      <Kern code=\"1139\" val=\"-0.031944\"/>\n      <Kern code=\"1089\" val=\"-0.031944\"/>\n      <Kern code=\"1108\" val=\"-0.031944\"/>\n      <Kern code=\"1077\" val=\"-0.031944\"/>\n      <Kern code=\"1105\" val=\"-0.031944\"/>\n      <Kern code=\"1103\" val=\"-0.031944\"/>\n      <Kern code=\"1076\" val=\"-0.063889\"/>\n      <Kern code=\"1083\" val=\"-0.063889\"/>\n      <Kern code=\"1113\" val=\"-0.063889\"/>\n   </Char>\n   <Char code=\"1139\" width=\"0.511108\" height=\"0.444445\" >\n      <Kern code=\"1076\" val=\"-0.031944\"/>\n      <Kern code=\"1078\" val=\"-0.031944\"/>\n      <Kern code=\"1093\" val=\"-0.031944\"/>\n      <Kern code=\"1103\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1109\" width=\"0.4536085\" height=\"0.444445\" />\n   <Char code=\"1103\" width=\"0.6076355\" height=\"0.444445\" />\n   <Char code=\"776\" width=\"0.574997\" height=\"0.686111\" />\n   <Char code=\"1122\" width=\"0.945828\" height=\"0.75\" >\n      <Kern code=\"1046\" val=\"-0.031944\"/>\n      <Kern code=\"1061\" val=\"-0.031944\"/>\n      <Kern code=\"1054\" val=\"-0.031944\"/>\n      <Kern code=\"1060\" val=\"-0.031944\"/>\n      <Kern code=\"1138\" val=\"-0.031944\"/>\n      <Kern code=\"1057\" val=\"-0.031944\"/>\n      <Kern code=\"1028\" val=\"-0.031944\"/>\n      <Kern code=\"1058\" val=\"-0.095833\"/>\n      <Kern code=\"1066\" val=\"-0.095833\"/>\n      <Kern code=\"1026\" val=\"-0.095833\"/>\n      <Kern code=\"1035\" val=\"-0.095833\"/>\n      <Kern code=\"1122\" val=\"-0.095833\"/>\n      <Kern code=\"1063\" val=\"-0.095833\"/>\n      <Kern code=\"1059\" val=\"-0.095833\"/>\n      <Kern code=\"1140\" val=\"-0.127777\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.095833\"/>\n   </Char>\n   <Char code=\"774\" width=\"0.574997\" height=\"0.652727\" />\n   <Char code=\"1123\" width=\"0.574997\" height=\"0.652727\" >\n      <Kern code=\"1091\" val=\"-0.063889\"/>\n      <Kern code=\"1141\" val=\"-0.063889\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.095833\"/>\n      <Kern code=\"1086\" val=\"-0.031944\"/>\n      <Kern code=\"1139\" val=\"-0.031944\"/>\n      <Kern code=\"1092\" val=\"-0.031944\"/>\n      <Kern code=\"1108\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"171\" width=\"0.6388855\" height=\"0.472223\" />\n   <Char code=\"305\" width=\"0.319443\" height=\"0.444445\" />\n   <Char code=\"187\" width=\"0.6388855\" height=\"0.472223\" />\n   <Char code=\"1040\" width=\"0.86944\" height=\"0.686111\" >\n      <Kern code=\"1054\" val=\"-0.031944\"/>\n      <Kern code=\"1060\" val=\"-0.031944\"/>\n      <Kern code=\"1138\" val=\"-0.031944\"/>\n      <Kern code=\"1057\" val=\"-0.031944\"/>\n      <Kern code=\"1028\" val=\"-0.031944\"/>\n      <Kern code=\"1058\" val=\"-0.095833\"/>\n      <Kern code=\"1066\" val=\"-0.095833\"/>\n      <Kern code=\"1026\" val=\"-0.095833\"/>\n      <Kern code=\"1035\" val=\"-0.095833\"/>\n      <Kern code=\"1122\" val=\"-0.095833\"/>\n      <Kern code=\"1063\" val=\"-0.095833\"/>\n      <Kern code=\"1059\" val=\"-0.095833\"/>\n      <Kern code=\"1140\" val=\"-0.127777\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.095833\"/>\n   </Char>\n   <Char code=\"1041\" width=\"0.818051\" height=\"0.686111\" />\n   <Char code=\"1062\" width=\"0.901384\" height=\"0.686111\" depth=\"0.194445\" >\n      <Lig code=\"1061\" ligCode=\"1063\"/>\n      <Lig code=\"1093\" ligCode=\"1063\"/>\n   </Char>\n   <Char code=\"1044\" width=\"0.901384\" height=\"0.686111\" depth=\"0.194445\" >\n      <Lig code=\"1032\" ligCode=\"1026\"/>\n      <Lig code=\"1112\" ligCode=\"1026\"/>\n   </Char>\n   <Char code=\"1045\" width=\"0.755551\" height=\"0.686111\" >\n   </Char>\n   <Char code=\"1060\" width=\"0.958328\" height=\"0.686111\" >\n      <Kern code=\"1040\" val=\"-0.031944\"/>\n      <Kern code=\"1044\" val=\"-0.031944\"/>\n      <Kern code=\"1046\" val=\"-0.031944\"/>\n      <Kern code=\"1061\" val=\"-0.031944\"/>\n      <Kern code=\"1059\" val=\"-0.031944\"/>\n      <Kern code=\"1140\" val=\"-0.031944\"/>\n      <Kern code=\"1071\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1043\" width=\"0.691663\" height=\"0.686111\" >\n      <Kern code=\"1040\" val=\"-0.095833\"/>\n      <Kern code=\"1044\" val=\"-0.095833\"/>\n      <Kern code=\"1071\" val=\"-0.095833\"/>\n      <Kern code=\"1051\" val=\"-0.031944\"/>\n      <Kern code=\"1033\" val=\"-0.031944\"/>\n      <Kern code=\"1072\" val=\"-0.095833\"/>\n      <Kern code=\"1086\" val=\"-0.095833\"/>\n      <Kern code=\"1139\" val=\"-0.095833\"/>\n      <Kern code=\"1077\" val=\"-0.095833\"/>\n      <Kern code=\"1105\" val=\"-0.095833\"/>\n      <Kern code=\"1089\" val=\"-0.095833\"/>\n      <Kern code=\"1108\" val=\"-0.095833\"/>\n      <Kern code=\"1092\" val=\"-0.095833\"/>\n      <Kern code=\"1076\" val=\"-0.095833\"/>\n      <Kern code=\"1083\" val=\"-0.095833\"/>\n      <Kern code=\"1113\" val=\"-0.095833\"/>\n      <Kern code=\"1103\" val=\"-0.095833\"/>\n   </Char>\n   <Char code=\"1061\" width=\"0.86944\" height=\"0.686111\" >\n      <Kern code=\"1054\" val=\"-0.031944\"/>\n      <Kern code=\"1060\" val=\"-0.031944\"/>\n      <Kern code=\"1138\" val=\"-0.031944\"/>\n      <Kern code=\"1057\" val=\"-0.031944\"/>\n      <Kern code=\"1028\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.031944\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1048\" width=\"0.901384\" height=\"0.686111\" >\n   </Char>\n   <Char code=\"1032\" width=\"0.594441\" height=\"0.686111\" >\n   </Char>\n   <Char code=\"1050\" width=\"0.901384\" height=\"0.686111\" >\n      <Lig code=\"1061\" ligCode=\"1061\"/>\n      <Lig code=\"1093\" ligCode=\"1061\"/>\n      <Kern code=\"1054\" val=\"-0.031944\"/>\n      <Kern code=\"1060\" val=\"-0.031944\"/>\n      <Kern code=\"1138\" val=\"-0.031944\"/>\n      <Kern code=\"1057\" val=\"-0.031944\"/>\n      <Kern code=\"1028\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.031944\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1051\" width=\"0.901384\" height=\"0.686111\" >\n      <Lig code=\"1032\" ligCode=\"1033\"/>\n      <Lig code=\"1112\" ligCode=\"1033\"/>\n   </Char>\n   <Char code=\"1052\" width=\"1.091661\" height=\"0.686111\" />\n   <Char code=\"1053\" width=\"0.901384\" height=\"0.686111\" >\n      <Lig code=\"1032\" ligCode=\"1034\"/>\n      <Lig code=\"1112\" ligCode=\"1034\"/>\n   </Char>\n   <Char code=\"1054\" width=\"0.863884\" height=\"0.686111\" >\n      <Kern code=\"1040\" val=\"-0.031944\"/>\n      <Kern code=\"1044\" val=\"-0.031944\"/>\n      <Kern code=\"1046\" val=\"-0.031944\"/>\n      <Kern code=\"1061\" val=\"-0.031944\"/>\n      <Kern code=\"1059\" val=\"-0.031944\"/>\n      <Kern code=\"1140\" val=\"-0.031944\"/>\n      <Kern code=\"1071\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1055\" width=\"0.901384\" height=\"0.686111\" >\n   </Char>\n   <Char code=\"1063\" width=\"0.901384\" height=\"0.686111\" />\n   <Char code=\"1056\" width=\"0.786107\" height=\"0.686111\" >\n      <Kern code=\"1040\" val=\"-0.095833\"/>\n      <Kern code=\"1044\" val=\"-0.095833\"/>\n      <Kern code=\"1051\" val=\"-0.095833\"/>\n      <Kern code=\"1033\" val=\"-0.095833\"/>\n      <Kern code=\"1071\" val=\"-0.095833\"/>\n      <Kern code=\"1072\" val=\"-0.031944\"/>\n      <Kern code=\"1086\" val=\"-0.031944\"/>\n      <Kern code=\"1139\" val=\"-0.031944\"/>\n      <Kern code=\"1077\" val=\"-0.031944\"/>\n      <Kern code=\"1105\" val=\"-0.031944\"/>\n      <Kern code=\"1076\" val=\"-0.095833\"/>\n      <Kern code=\"1083\" val=\"-0.095833\"/>\n      <Kern code=\"1113\" val=\"-0.095833\"/>\n   </Char>\n   <Char code=\"1057\" width=\"0.830551\" height=\"0.686111\" >\n      <Lig code=\"1061\" ligCode=\"1064\"/>\n      <Lig code=\"1093\" ligCode=\"1064\"/>\n   </Char>\n   <Char code=\"1058\" width=\"0.799995\" height=\"0.686111\" >\n      <Lig code=\"1057\" ligCode=\"1062\"/>\n      <Lig code=\"1089\" ligCode=\"1062\"/>\n      <Kern code=\"1040\" val=\"-0.095833\"/>\n      <Kern code=\"1044\" val=\"-0.095833\"/>\n      <Kern code=\"1071\" val=\"-0.095833\"/>\n      <Kern code=\"1051\" val=\"-0.031944\"/>\n      <Kern code=\"1033\" val=\"-0.031944\"/>\n      <Kern code=\"1072\" val=\"-0.095833\"/>\n      <Kern code=\"1086\" val=\"-0.095833\"/>\n      <Kern code=\"1139\" val=\"-0.095833\"/>\n      <Kern code=\"1077\" val=\"-0.095833\"/>\n      <Kern code=\"1105\" val=\"-0.095833\"/>\n      <Kern code=\"1089\" val=\"-0.095833\"/>\n      <Kern code=\"1108\" val=\"-0.095833\"/>\n      <Kern code=\"1092\" val=\"-0.095833\"/>\n      <Kern code=\"1076\" val=\"-0.095833\"/>\n      <Kern code=\"1083\" val=\"-0.095833\"/>\n      <Kern code=\"1113\" val=\"-0.095833\"/>\n      <Kern code=\"1103\" val=\"-0.095833\"/>\n   </Char>\n   <Char code=\"1059\" width=\"0.86944\" height=\"0.686111\" italic=\"0.015973\" >\n      <Kern code=\"1040\" val=\"-0.095833\"/>\n      <Kern code=\"1071\" val=\"-0.095833\"/>\n      <Kern code=\"1044\" val=\"-0.063889\"/>\n      <Kern code=\"1051\" val=\"-0.063889\"/>\n      <Kern code=\"1033\" val=\"-0.063889\"/>\n      <Kern code=\"1054\" val=\"-0.031944\"/>\n      <Kern code=\"1060\" val=\"-0.031944\"/>\n      <Kern code=\"1138\" val=\"-0.031944\"/>\n      <Kern code=\"1057\" val=\"-0.031944\"/>\n      <Kern code=\"1028\" val=\"-0.031944\"/>\n      <Kern code=\"1072\" val=\"-0.095833\"/>\n      <Kern code=\"1086\" val=\"-0.095833\"/>\n      <Kern code=\"1139\" val=\"-0.095833\"/>\n      <Kern code=\"1077\" val=\"-0.095833\"/>\n      <Kern code=\"1105\" val=\"-0.095833\"/>\n      <Kern code=\"1089\" val=\"-0.095833\"/>\n      <Kern code=\"1108\" val=\"-0.095833\"/>\n      <Kern code=\"1076\" val=\"-0.095833\"/>\n      <Kern code=\"1083\" val=\"-0.095833\"/>\n      <Kern code=\"1113\" val=\"-0.095833\"/>\n      <Kern code=\"1103\" val=\"-0.095833\"/>\n   </Char>\n   <Char code=\"1042\" width=\"0.818051\" height=\"0.686111\" />\n   <Char code=\"1065\" width=\"1.3312435\" height=\"0.686111\" depth=\"0.194445\" />\n   <Char code=\"1064\" width=\"1.3312435\" height=\"0.686111\" >\n      <Lig code=\"1063\" ligCode=\"1065\"/>\n      <Lig code=\"1095\" ligCode=\"1065\"/>\n      <Lig code=\"1062\" ligCode=\"0\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1067\" width=\"1.124994\" height=\"0.686111\" >\n      <Lig code=\"1040\" ligCode=\"1071\"/>\n      <Lig code=\"1072\" ligCode=\"1071\"/>\n      <Lig code=\"1059\" ligCode=\"1070\"/>\n      <Lig code=\"1091\" ligCode=\"1070\"/>\n   </Char>\n   <Char code=\"1047\" width=\"0.702774\" height=\"0.686111\" >\n      <Lig code=\"1061\" ligCode=\"1046\"/>\n      <Lig code=\"1093\" ligCode=\"1046\"/>\n   </Char>\n   <Char code=\"1068\" width=\"0.818051\" height=\"0.686111\" >\n      <Kern code=\"1046\" val=\"-0.031944\"/>\n      <Kern code=\"1061\" val=\"-0.031944\"/>\n      <Kern code=\"1054\" val=\"-0.031944\"/>\n      <Kern code=\"1060\" val=\"-0.031944\"/>\n      <Kern code=\"1138\" val=\"-0.031944\"/>\n      <Kern code=\"1057\" val=\"-0.031944\"/>\n      <Kern code=\"1028\" val=\"-0.031944\"/>\n      <Kern code=\"1058\" val=\"-0.095833\"/>\n      <Kern code=\"1066\" val=\"-0.095833\"/>\n      <Kern code=\"1026\" val=\"-0.095833\"/>\n      <Kern code=\"1035\" val=\"-0.095833\"/>\n      <Kern code=\"1122\" val=\"-0.095833\"/>\n      <Kern code=\"1063\" val=\"-0.095833\"/>\n      <Kern code=\"1059\" val=\"-0.095833\"/>\n      <Kern code=\"1140\" val=\"-0.127777\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.095833\"/>\n   </Char>\n   <Char code=\"1066\" width=\"1.006938\" height=\"0.686111\" >\n      <Kern code=\"1046\" val=\"-0.031944\"/>\n      <Kern code=\"1061\" val=\"-0.031944\"/>\n      <Kern code=\"1054\" val=\"-0.031944\"/>\n      <Kern code=\"1060\" val=\"-0.031944\"/>\n      <Kern code=\"1138\" val=\"-0.031944\"/>\n      <Kern code=\"1057\" val=\"-0.031944\"/>\n      <Kern code=\"1028\" val=\"-0.031944\"/>\n      <Kern code=\"1058\" val=\"-0.095833\"/>\n      <Kern code=\"1066\" val=\"-0.095833\"/>\n      <Kern code=\"1026\" val=\"-0.095833\"/>\n      <Kern code=\"1035\" val=\"-0.095833\"/>\n      <Kern code=\"1122\" val=\"-0.095833\"/>\n      <Kern code=\"1063\" val=\"-0.095833\"/>\n      <Kern code=\"1059\" val=\"-0.095833\"/>\n      <Kern code=\"1140\" val=\"-0.127777\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.095833\"/>\n   </Char>\n   <Char code=\"1072\" width=\"0.559024\" height=\"0.444445\" >\n      <Kern code=\"1095\" val=\"-0.031944\"/>\n      <Kern code=\"1091\" val=\"-0.031944\"/>\n      <Kern code=\"1141\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1073\" width=\"0.574997\" height=\"0.694445\" >\n      <Kern code=\"1076\" val=\"-0.031944\"/>\n      <Kern code=\"1078\" val=\"-0.031944\"/>\n      <Kern code=\"1093\" val=\"-0.031944\"/>\n      <Kern code=\"1103\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1094\" width=\"0.6388855\" height=\"0.444445\" depth=\"0.162038\" >\n      <Lig code=\"1093\" ligCode=\"1095\"/>\n   </Char>\n   <Char code=\"1076\" width=\"0.6388855\" height=\"0.444445\" depth=\"0.162038\" >\n      <Lig code=\"1112\" ligCode=\"1106\"/>\n   </Char>\n   <Char code=\"1077\" width=\"0.5270815\" height=\"0.444445\" >\n   </Char>\n   <Char code=\"1092\" width=\"0.89444\" height=\"0.694445\" depth=\"0.194445\" >\n      <Kern code=\"1076\" val=\"-0.031944\"/>\n      <Kern code=\"1078\" val=\"-0.031944\"/>\n      <Kern code=\"1093\" val=\"-0.031944\"/>\n      <Kern code=\"1103\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1075\" width=\"0.49583\" height=\"0.444445\" >\n      <Kern code=\"1072\" val=\"-0.031944\"/>\n      <Kern code=\"1076\" val=\"-0.031944\"/>\n      <Kern code=\"1083\" val=\"-0.031944\"/>\n      <Kern code=\"1113\" val=\"-0.031944\"/>\n      <Kern code=\"1103\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1093\" width=\"0.606941\" height=\"0.444445\" >\n      <Kern code=\"1072\" val=\"-0.031944\"/>\n      <Kern code=\"1086\" val=\"-0.031944\"/>\n      <Kern code=\"1139\" val=\"-0.031944\"/>\n      <Kern code=\"1089\" val=\"-0.031944\"/>\n      <Kern code=\"1108\" val=\"-0.031944\"/>\n      <Kern code=\"1077\" val=\"-0.031944\"/>\n      <Kern code=\"1105\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1080\" width=\"0.6388855\" height=\"0.444445\" >\n   </Char>\n   <Char code=\"1112\" width=\"0.351387\" height=\"0.694445\" depth=\"0.194445\" >\n   </Char>\n   <Char code=\"1082\" width=\"0.6388855\" height=\"0.444445\" >\n      <Lig code=\"1093\" ligCode=\"1093\"/>\n      <Kern code=\"1072\" val=\"-0.031944\"/>\n      <Kern code=\"1086\" val=\"-0.031944\"/>\n      <Kern code=\"1139\" val=\"-0.031944\"/>\n      <Kern code=\"1089\" val=\"-0.031944\"/>\n      <Kern code=\"1108\" val=\"-0.031944\"/>\n      <Kern code=\"1077\" val=\"-0.031944\"/>\n      <Kern code=\"1105\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1083\" width=\"0.6388855\" height=\"0.444445\" >\n      <Lig code=\"1112\" ligCode=\"1113\"/>\n   </Char>\n   <Char code=\"1084\" width=\"0.766663\" height=\"0.444445\" />\n   <Char code=\"1085\" width=\"0.6388855\" height=\"0.444445\" >\n      <Lig code=\"1112\" ligCode=\"1114\"/>\n   </Char>\n   <Char code=\"1086\" width=\"0.574997\" height=\"0.444445\" >\n      <Kern code=\"1076\" val=\"-0.031944\"/>\n      <Kern code=\"1078\" val=\"-0.031944\"/>\n      <Kern code=\"1093\" val=\"-0.031944\"/>\n      <Kern code=\"1103\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1087\" width=\"0.6388855\" height=\"0.444445\" >\n   </Char>\n   <Char code=\"1095\" width=\"0.6388855\" height=\"0.444445\" />\n   <Char code=\"1088\" width=\"0.6388855\" height=\"0.444445\" depth=\"0.194445\" >\n      <Kern code=\"1076\" val=\"-0.031944\"/>\n      <Kern code=\"1078\" val=\"-0.031944\"/>\n      <Kern code=\"1093\" val=\"-0.031944\"/>\n      <Kern code=\"1103\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1089\" width=\"0.511108\" height=\"0.444445\" >\n      <Lig code=\"1093\" ligCode=\"1096\"/>\n      <Kern code=\"1076\" val=\"-0.031944\"/>\n      <Kern code=\"1078\" val=\"-0.031944\"/>\n      <Kern code=\"1093\" val=\"-0.031944\"/>\n      <Kern code=\"1103\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1090\" width=\"0.544441\" height=\"0.444445\" >\n      <Lig code=\"1089\" ligCode=\"1094\"/>\n      <Kern code=\"1072\" val=\"-0.031944\"/>\n      <Kern code=\"1076\" val=\"-0.031944\"/>\n      <Kern code=\"1083\" val=\"-0.031944\"/>\n      <Kern code=\"1113\" val=\"-0.031944\"/>\n      <Kern code=\"1103\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1091\" width=\"0.606941\" height=\"0.444445\" depth=\"0.194445\" italic=\"0.015973\" >\n      <Kern code=\"1072\" val=\"-0.031944\"/>\n      <Kern code=\"1086\" val=\"-0.031944\"/>\n      <Kern code=\"1139\" val=\"-0.031944\"/>\n      <Kern code=\"1089\" val=\"-0.031944\"/>\n      <Kern code=\"1108\" val=\"-0.031944\"/>\n      <Kern code=\"1077\" val=\"-0.031944\"/>\n      <Kern code=\"1105\" val=\"-0.031944\"/>\n      <Kern code=\"1103\" val=\"-0.031944\"/>\n      <Kern code=\"1076\" val=\"-0.063889\"/>\n      <Kern code=\"1083\" val=\"-0.063889\"/>\n      <Kern code=\"1113\" val=\"-0.063889\"/>\n   </Char>\n   <Char code=\"1074\" width=\"0.574997\" height=\"0.444445\" />\n   <Char code=\"1097\" width=\"0.941663\" height=\"0.444445\" depth=\"0.162038\" />\n   <Char code=\"1096\" width=\"0.941663\" height=\"0.444445\" >\n      <Lig code=\"1095\" ligCode=\"1097\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1099\" width=\"0.830551\" height=\"0.444445\" >\n      <Lig code=\"1072\" ligCode=\"1103\"/>\n      <Lig code=\"1091\" ligCode=\"1102\"/>\n   </Char>\n   <Char code=\"1079\" width=\"0.511108\" height=\"0.444445\" italic=\"0.006389\" >\n      <Lig code=\"1093\" ligCode=\"1078\"/>\n   </Char>\n   <Char code=\"1100\" width=\"0.574997\" height=\"0.444445\" >\n      <Kern code=\"1091\" val=\"-0.063889\"/>\n      <Kern code=\"1141\" val=\"-0.063889\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.095833\"/>\n      <Kern code=\"1086\" val=\"-0.031944\"/>\n      <Kern code=\"1139\" val=\"-0.031944\"/>\n      <Kern code=\"1092\" val=\"-0.031944\"/>\n      <Kern code=\"1108\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1098\" width=\"0.687495\" height=\"0.444445\" >\n      <Kern code=\"1091\" val=\"-0.063889\"/>\n      <Kern code=\"1141\" val=\"-0.063889\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.095833\"/>\n      <Kern code=\"1086\" val=\"-0.031944\"/>\n      <Kern code=\"1139\" val=\"-0.031944\"/>\n      <Kern code=\"1092\" val=\"-0.031944\"/>\n      <Kern code=\"1108\" val=\"-0.031944\"/>\n   </Char>\n</Font>\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/cyrillic/wnbxti10.xml",
    "content": "<Font name=\"wnbxti10.ttf\" id=\"wnbxti10\" space=\"0.414441\" xHeight=\"0.444445\" quad=\"1.182211\" unicode=\"95\" romanVersion=\"wnbx10\" ttVersion=\"wntt10\" ssVersion=\"wnssbx10\">\n   <Char code=\"1034\" width=\"1.198877\" height=\"0.686111\" italic=\"0.032991\" >\n      <Kern code=\"1046\" val=\"-0.029445\"/>\n      <Kern code=\"1061\" val=\"-0.029445\"/>\n      <Kern code=\"1054\" val=\"-0.029445\"/>\n      <Kern code=\"1060\" val=\"-0.029445\"/>\n      <Kern code=\"1138\" val=\"-0.029445\"/>\n      <Kern code=\"1057\" val=\"-0.029445\"/>\n      <Kern code=\"1028\" val=\"-0.029445\"/>\n      <Kern code=\"1058\" val=\"-0.088333\"/>\n      <Kern code=\"1066\" val=\"-0.088333\"/>\n      <Kern code=\"1026\" val=\"-0.088333\"/>\n      <Kern code=\"1035\" val=\"-0.088333\"/>\n      <Kern code=\"1122\" val=\"-0.088333\"/>\n      <Kern code=\"1063\" val=\"-0.088333\"/>\n      <Kern code=\"1059\" val=\"-0.088333\"/>\n      <Kern code=\"1140\" val=\"-0.117777\"/>\n      <Kern code=\"1098\" val=\"-0.029445\"/>\n      <Kern code=\"1141\" val=\"-0.029445\"/>\n      <Kern code=\"1082\" val=\"-0.029445\"/>\n      <Kern code=\"1085\" val=\"-0.029445\"/>\n      <Kern code=\"1114\" val=\"-0.029445\"/>\n      <Kern code=\"1087\" val=\"-0.029445\"/>\n      <Kern code=\"1090\" val=\"-0.029445\"/>\n      <Kern code=\"1102\" val=\"-0.029445\"/>\n      <Kern code=\"1123\" val=\"-0.029445\"/>\n      <Kern code=\"1110\" val=\"-0.029445\"/>\n      <Kern code=\"1080\" val=\"-0.029445\"/>\n      <Kern code=\"1081\" val=\"-0.029445\"/>\n      <Kern code=\"1094\" val=\"-0.029445\"/>\n      <Kern code=\"1096\" val=\"-0.029445\"/>\n      <Kern code=\"1097\" val=\"-0.029445\"/>\n      <Kern code=\"1100\" val=\"-0.029445\"/>\n      <Kern code=\"1099\" val=\"-0.029445\"/>\n      <Kern code=\"1091\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1033\" width=\"1.198877\" height=\"0.686111\" italic=\"0.032991\" >\n      <Kern code=\"1046\" val=\"-0.029445\"/>\n      <Kern code=\"1061\" val=\"-0.029445\"/>\n      <Kern code=\"1054\" val=\"-0.029445\"/>\n      <Kern code=\"1060\" val=\"-0.029445\"/>\n      <Kern code=\"1138\" val=\"-0.029445\"/>\n      <Kern code=\"1057\" val=\"-0.029445\"/>\n      <Kern code=\"1028\" val=\"-0.029445\"/>\n      <Kern code=\"1058\" val=\"-0.088333\"/>\n      <Kern code=\"1066\" val=\"-0.088333\"/>\n      <Kern code=\"1026\" val=\"-0.088333\"/>\n      <Kern code=\"1035\" val=\"-0.088333\"/>\n      <Kern code=\"1122\" val=\"-0.088333\"/>\n      <Kern code=\"1063\" val=\"-0.088333\"/>\n      <Kern code=\"1059\" val=\"-0.088333\"/>\n      <Kern code=\"1140\" val=\"-0.117777\"/>\n      <Kern code=\"1098\" val=\"-0.029445\"/>\n      <Kern code=\"1141\" val=\"-0.029445\"/>\n      <Kern code=\"1082\" val=\"-0.029445\"/>\n      <Kern code=\"1085\" val=\"-0.029445\"/>\n      <Kern code=\"1114\" val=\"-0.029445\"/>\n      <Kern code=\"1087\" val=\"-0.029445\"/>\n      <Kern code=\"1090\" val=\"-0.029445\"/>\n      <Kern code=\"1102\" val=\"-0.029445\"/>\n      <Kern code=\"1123\" val=\"-0.029445\"/>\n      <Kern code=\"1110\" val=\"-0.029445\"/>\n      <Kern code=\"1080\" val=\"-0.029445\"/>\n      <Kern code=\"1081\" val=\"-0.029445\"/>\n      <Kern code=\"1094\" val=\"-0.029445\"/>\n      <Kern code=\"1096\" val=\"-0.029445\"/>\n      <Kern code=\"1097\" val=\"-0.029445\"/>\n      <Kern code=\"1100\" val=\"-0.029445\"/>\n      <Kern code=\"1099\" val=\"-0.029445\"/>\n      <Kern code=\"1091\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1039\" width=\"0.894992\" height=\"0.686111\" depth=\"0.194445\" italic=\"0.172084\" />\n   <Char code=\"1069\" width=\"0.826658\" height=\"0.686111\" italic=\"0.090625\" >\n      <Kern code=\"1040\" val=\"-0.029445\"/>\n      <Kern code=\"1044\" val=\"-0.029445\"/>\n      <Kern code=\"1046\" val=\"-0.029445\"/>\n      <Kern code=\"1061\" val=\"-0.029445\"/>\n      <Kern code=\"1059\" val=\"-0.029445\"/>\n      <Kern code=\"1140\" val=\"-0.029445\"/>\n      <Kern code=\"1071\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1030\" width=\"0.471664\" height=\"0.686111\" italic=\"0.156807\" >\n      <Kern code=\"1030\" val=\"0.029445\"/>\n   </Char>\n   <Char code=\"1028\" width=\"0.826658\" height=\"0.686111\" italic=\"0.142084\" />\n   <Char code=\"1026\" width=\"0.943324\" height=\"0.686111\" italic=\"0.12903\" >\n      <Kern code=\"1046\" val=\"-0.029445\"/>\n      <Kern code=\"1061\" val=\"-0.029445\"/>\n      <Kern code=\"1054\" val=\"-0.029445\"/>\n      <Kern code=\"1060\" val=\"-0.029445\"/>\n      <Kern code=\"1138\" val=\"-0.029445\"/>\n      <Kern code=\"1057\" val=\"-0.029445\"/>\n      <Kern code=\"1028\" val=\"-0.029445\"/>\n      <Kern code=\"1058\" val=\"-0.088333\"/>\n      <Kern code=\"1066\" val=\"-0.088333\"/>\n      <Kern code=\"1026\" val=\"-0.088333\"/>\n      <Kern code=\"1035\" val=\"-0.088333\"/>\n      <Kern code=\"1122\" val=\"-0.088333\"/>\n      <Kern code=\"1063\" val=\"-0.088333\"/>\n      <Kern code=\"1059\" val=\"-0.088333\"/>\n      <Kern code=\"1140\" val=\"-0.117777\"/>\n      <Kern code=\"1098\" val=\"-0.029445\"/>\n      <Kern code=\"1141\" val=\"-0.029445\"/>\n      <Kern code=\"1082\" val=\"-0.029445\"/>\n      <Kern code=\"1085\" val=\"-0.029445\"/>\n      <Kern code=\"1114\" val=\"-0.029445\"/>\n      <Kern code=\"1087\" val=\"-0.029445\"/>\n      <Kern code=\"1090\" val=\"-0.029445\"/>\n      <Kern code=\"1102\" val=\"-0.029445\"/>\n      <Kern code=\"1123\" val=\"-0.029445\"/>\n      <Kern code=\"1110\" val=\"-0.029445\"/>\n      <Kern code=\"1080\" val=\"-0.029445\"/>\n      <Kern code=\"1081\" val=\"-0.029445\"/>\n      <Kern code=\"1094\" val=\"-0.029445\"/>\n      <Kern code=\"1096\" val=\"-0.029445\"/>\n      <Kern code=\"1097\" val=\"-0.029445\"/>\n      <Kern code=\"1100\" val=\"-0.029445\"/>\n      <Kern code=\"1099\" val=\"-0.029445\"/>\n      <Kern code=\"1091\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1035\" width=\"0.870825\" height=\"0.686111\" italic=\"0.084864\" />\n   <Char code=\"1114\" width=\"0.82666\" height=\"0.444445\" italic=\"0.078611\" >\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n      <Kern code=\"1141\" val=\"-0.029445\"/>\n      <Kern code=\"1098\" val=\"-0.029445\"/>\n      <Kern code=\"1095\" val=\"-0.088333\"/>\n      <Kern code=\"1086\" val=\"-0.029445\"/>\n      <Kern code=\"1139\" val=\"-0.029445\"/>\n      <Kern code=\"1092\" val=\"-0.029445\"/>\n      <Kern code=\"1108\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1113\" width=\"0.797215\" height=\"0.444445\" italic=\"0.078611\" >\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n      <Kern code=\"1141\" val=\"-0.029445\"/>\n      <Kern code=\"1098\" val=\"-0.029445\"/>\n      <Kern code=\"1095\" val=\"-0.088333\"/>\n      <Kern code=\"1086\" val=\"-0.029445\"/>\n      <Kern code=\"1139\" val=\"-0.029445\"/>\n      <Kern code=\"1092\" val=\"-0.029445\"/>\n      <Kern code=\"1108\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1119\" width=\"0.62055\" height=\"0.444445\" depth=\"0.194445\" italic=\"0.094261\" />\n   <Char code=\"1101\" width=\"0.511606\" height=\"0.444445\" italic=\"0.078611\" >\n      <Kern code=\"1092\" val=\"-0.058888\"/>\n      <Kern code=\"1072\" val=\"-0.058888\"/>\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1110\" width=\"0.355553\" height=\"0.693255\" italic=\"0.113872\" />\n   <Char code=\"1108\" width=\"0.511606\" height=\"0.444445\" italic=\"0.081667\" />\n   <Char code=\"1106\" width=\"0.532217\" height=\"0.694445\" depth=\"0.194445\" italic=\"0.077777\" />\n   <Char code=\"1115\" width=\"0.591105\" height=\"0.694445\" italic=\"0.094261\" />\n   <Char code=\"1070\" width=\"1.236933\" height=\"0.686111\" italic=\"0.090625\" >\n      <Kern code=\"1040\" val=\"-0.029445\"/>\n      <Kern code=\"1044\" val=\"-0.029445\"/>\n      <Kern code=\"1046\" val=\"-0.029445\"/>\n      <Kern code=\"1061\" val=\"-0.029445\"/>\n      <Kern code=\"1059\" val=\"-0.029445\"/>\n      <Kern code=\"1140\" val=\"-0.029445\"/>\n      <Kern code=\"1071\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1046\" width=\"1.318319\" height=\"0.686111\" italic=\"0.142084\" >\n      <Kern code=\"1054\" val=\"-0.029445\"/>\n      <Kern code=\"1060\" val=\"-0.029445\"/>\n      <Kern code=\"1138\" val=\"-0.029445\"/>\n      <Kern code=\"1057\" val=\"-0.029445\"/>\n      <Kern code=\"1028\" val=\"-0.029445\"/>\n      <Kern code=\"1095\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1049\" width=\"0.894992\" height=\"0.894394\" italic=\"0.172084\" />\n   <Char code=\"1025\" width=\"0.756659\" height=\"0.894394\" italic=\"0.114306\" />\n   <Char code=\"1140\" width=\"0.934436\" height=\"0.686111\" italic=\"0.186251\" >\n      <Kern code=\"1040\" val=\"-0.117777\"/>\n      <Kern code=\"1071\" val=\"-0.117777\"/>\n      <Kern code=\"1054\" val=\"-0.029445\"/>\n      <Kern code=\"1060\" val=\"-0.029445\"/>\n      <Kern code=\"1138\" val=\"-0.029445\"/>\n      <Kern code=\"1057\" val=\"-0.029445\"/>\n      <Kern code=\"1028\" val=\"-0.029445\"/>\n      <Kern code=\"1072\" val=\"-0.088333\"/>\n      <Kern code=\"1086\" val=\"-0.088333\"/>\n      <Kern code=\"1139\" val=\"-0.088333\"/>\n      <Kern code=\"1077\" val=\"-0.088333\"/>\n      <Kern code=\"1105\" val=\"-0.088333\"/>\n      <Kern code=\"1080\" val=\"-0.117777\"/>\n      <Kern code=\"1081\" val=\"-0.117777\"/>\n      <Kern code=\"1094\" val=\"-0.117777\"/>\n      <Kern code=\"1096\" val=\"-0.117777\"/>\n      <Kern code=\"1097\" val=\"-0.117777\"/>\n      <Kern code=\"1100\" val=\"-0.117777\"/>\n      <Kern code=\"1099\" val=\"-0.117777\"/>\n      <Kern code=\"1091\" val=\"-0.117777\"/>\n      <Kern code=\"1141\" val=\"-0.117777\"/>\n      <Kern code=\"1098\" val=\"-0.117777\"/>\n      <Kern code=\"1083\" val=\"-0.117777\"/>\n      <Kern code=\"1084\" val=\"-0.117777\"/>\n      <Kern code=\"1113\" val=\"-0.117777\"/>\n   </Char>\n   <Char code=\"1138\" width=\"0.885547\" height=\"0.686111\" italic=\"0.090625\" >\n      <Kern code=\"1040\" val=\"-0.029445\"/>\n      <Kern code=\"1044\" val=\"-0.029445\"/>\n      <Kern code=\"1046\" val=\"-0.029445\"/>\n      <Kern code=\"1061\" val=\"-0.029445\"/>\n      <Kern code=\"1059\" val=\"-0.029445\"/>\n      <Kern code=\"1140\" val=\"-0.029445\"/>\n      <Kern code=\"1071\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1029\" width=\"0.649994\" height=\"0.686111\" italic=\"0.11264\" />\n   <Char code=\"1071\" width=\"0.894992\" height=\"0.686111\" italic=\"0.172084\" />\n   <Char code=\"1102\" width=\"0.835492\" height=\"0.444445\" italic=\"0.078611\" >\n      <Kern code=\"1092\" val=\"-0.058888\"/>\n      <Kern code=\"1072\" val=\"-0.058888\"/>\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1078\" width=\"1.209432\" height=\"0.444445\" italic=\"0.052223\" />\n   <Char code=\"1081\" width=\"0.649994\" height=\"0.652727\" italic=\"0.094261\" />\n   <Char code=\"1105\" width=\"0.511606\" height=\"0.686111\" italic=\"0.085002\" >\n      <Kern code=\"1092\" val=\"-0.058888\"/>\n      <Kern code=\"1072\" val=\"-0.058888\"/>\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1141\" width=\"0.723051\" height=\"0.444445\" italic=\"0.1258335\" >\n      <Kern code=\"1083\" val=\"-0.088333\"/>\n      <Kern code=\"1084\" val=\"-0.088333\"/>\n      <Kern code=\"1113\" val=\"-0.088333\"/>\n   </Char>\n   <Char code=\"1139\" width=\"0.532217\" height=\"0.444445\" italic=\"0.078611\" >\n      <Kern code=\"1092\" val=\"-0.058888\"/>\n      <Kern code=\"1072\" val=\"-0.058888\"/>\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1109\" width=\"0.486941\" height=\"0.444445\" italic=\"0.081667\" />\n   <Char code=\"1103\" width=\"0.62055\" height=\"0.444445\" italic=\"0.094261\" />\n   <Char code=\"776\" width=\"0.591105\" height=\"0.686111\" italic=\"0.112642\" />\n   <Char code=\"1122\" width=\"0.934436\" height=\"0.75\" italic=\"0.099202\" >\n      <Kern code=\"1046\" val=\"-0.029445\"/>\n      <Kern code=\"1061\" val=\"-0.029445\"/>\n      <Kern code=\"1054\" val=\"-0.029445\"/>\n      <Kern code=\"1060\" val=\"-0.029445\"/>\n      <Kern code=\"1138\" val=\"-0.029445\"/>\n      <Kern code=\"1057\" val=\"-0.029445\"/>\n      <Kern code=\"1028\" val=\"-0.029445\"/>\n      <Kern code=\"1058\" val=\"-0.088333\"/>\n      <Kern code=\"1066\" val=\"-0.088333\"/>\n      <Kern code=\"1026\" val=\"-0.088333\"/>\n      <Kern code=\"1035\" val=\"-0.088333\"/>\n      <Kern code=\"1122\" val=\"-0.088333\"/>\n      <Kern code=\"1063\" val=\"-0.088333\"/>\n      <Kern code=\"1059\" val=\"-0.088333\"/>\n      <Kern code=\"1140\" val=\"-0.117777\"/>\n      <Kern code=\"1098\" val=\"-0.029445\"/>\n      <Kern code=\"1141\" val=\"-0.029445\"/>\n      <Kern code=\"1082\" val=\"-0.029445\"/>\n      <Kern code=\"1085\" val=\"-0.029445\"/>\n      <Kern code=\"1114\" val=\"-0.029445\"/>\n      <Kern code=\"1087\" val=\"-0.029445\"/>\n      <Kern code=\"1090\" val=\"-0.029445\"/>\n      <Kern code=\"1102\" val=\"-0.029445\"/>\n      <Kern code=\"1123\" val=\"-0.029445\"/>\n      <Kern code=\"1110\" val=\"-0.029445\"/>\n      <Kern code=\"1080\" val=\"-0.029445\"/>\n      <Kern code=\"1081\" val=\"-0.029445\"/>\n      <Kern code=\"1094\" val=\"-0.029445\"/>\n      <Kern code=\"1096\" val=\"-0.029445\"/>\n      <Kern code=\"1097\" val=\"-0.029445\"/>\n      <Kern code=\"1100\" val=\"-0.029445\"/>\n      <Kern code=\"1099\" val=\"-0.029445\"/>\n      <Kern code=\"1091\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"774\" width=\"0.591105\" height=\"0.652727\" italic=\"0.092905\" />\n   <Char code=\"1123\" width=\"0.826658\" height=\"0.444445\" italic=\"0.078611\" >\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n      <Kern code=\"1141\" val=\"-0.029445\"/>\n      <Kern code=\"1098\" val=\"-0.029445\"/>\n      <Kern code=\"1095\" val=\"-0.088333\"/>\n      <Kern code=\"1086\" val=\"-0.029445\"/>\n      <Kern code=\"1139\" val=\"-0.029445\"/>\n      <Kern code=\"1092\" val=\"-0.029445\"/>\n      <Kern code=\"1108\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"171\" width=\"0.649994\" height=\"0.472223\" italic=\"0.008611\" />\n   <Char code=\"305\" width=\"0.355553\" height=\"0.444445\" italic=\"0.094261\" />\n   <Char code=\"187\" width=\"0.649994\" height=\"0.472223\" />\n   <Char code=\"1040\" width=\"0.865547\" height=\"0.686111\" >\n      <Kern code=\"1054\" val=\"-0.029445\"/>\n      <Kern code=\"1060\" val=\"-0.029445\"/>\n      <Kern code=\"1138\" val=\"-0.029445\"/>\n      <Kern code=\"1057\" val=\"-0.029445\"/>\n      <Kern code=\"1028\" val=\"-0.029445\"/>\n      <Kern code=\"1058\" val=\"-0.088333\"/>\n      <Kern code=\"1066\" val=\"-0.088333\"/>\n      <Kern code=\"1026\" val=\"-0.088333\"/>\n      <Kern code=\"1035\" val=\"-0.088333\"/>\n      <Kern code=\"1122\" val=\"-0.088333\"/>\n      <Kern code=\"1063\" val=\"-0.088333\"/>\n      <Kern code=\"1059\" val=\"-0.088333\"/>\n      <Kern code=\"1140\" val=\"-0.117777\"/>\n      <Kern code=\"1098\" val=\"-0.029445\"/>\n      <Kern code=\"1141\" val=\"-0.029445\"/>\n      <Kern code=\"1082\" val=\"-0.029445\"/>\n      <Kern code=\"1085\" val=\"-0.029445\"/>\n      <Kern code=\"1114\" val=\"-0.029445\"/>\n      <Kern code=\"1087\" val=\"-0.029445\"/>\n      <Kern code=\"1090\" val=\"-0.029445\"/>\n      <Kern code=\"1102\" val=\"-0.029445\"/>\n      <Kern code=\"1123\" val=\"-0.029445\"/>\n      <Kern code=\"1110\" val=\"-0.029445\"/>\n      <Kern code=\"1080\" val=\"-0.029445\"/>\n      <Kern code=\"1081\" val=\"-0.029445\"/>\n      <Kern code=\"1094\" val=\"-0.029445\"/>\n      <Kern code=\"1096\" val=\"-0.029445\"/>\n      <Kern code=\"1097\" val=\"-0.029445\"/>\n      <Kern code=\"1100\" val=\"-0.029445\"/>\n      <Kern code=\"1099\" val=\"-0.029445\"/>\n      <Kern code=\"1091\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1041\" width=\"0.81666\" height=\"0.686111\" italic=\"0.055418\" />\n   <Char code=\"1062\" width=\"0.894992\" height=\"0.686111\" depth=\"0.194445\" italic=\"0.172084\" >\n      <Lig code=\"1061\" ligCode=\"1063\"/>\n      <Lig code=\"1093\" ligCode=\"1063\"/>\n   </Char>\n   <Char code=\"1044\" width=\"0.894992\" height=\"0.686111\" depth=\"0.194445\" italic=\"0.172084\" >\n      <Lig code=\"1032\" ligCode=\"1026\"/>\n      <Lig code=\"1112\" ligCode=\"1026\"/>\n   </Char>\n   <Char code=\"1045\" width=\"0.756659\" height=\"0.686111\" italic=\"0.114306\" >\n   </Char>\n   <Char code=\"1060\" width=\"0.944435\" height=\"0.686111\" italic=\"0.090625\" >\n      <Kern code=\"1040\" val=\"-0.029445\"/>\n      <Kern code=\"1044\" val=\"-0.029445\"/>\n      <Kern code=\"1046\" val=\"-0.029445\"/>\n      <Kern code=\"1061\" val=\"-0.029445\"/>\n      <Kern code=\"1059\" val=\"-0.029445\"/>\n      <Kern code=\"1140\" val=\"-0.029445\"/>\n      <Kern code=\"1071\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1043\" width=\"0.697771\" height=\"0.686111\" italic=\"0.12903\" >\n      <Kern code=\"1040\" val=\"-0.088333\"/>\n      <Kern code=\"1044\" val=\"-0.088333\"/>\n      <Kern code=\"1071\" val=\"-0.088333\"/>\n      <Kern code=\"1051\" val=\"-0.029445\"/>\n      <Kern code=\"1033\" val=\"-0.029445\"/>\n      <Kern code=\"1072\" val=\"-0.088333\"/>\n      <Kern code=\"1086\" val=\"-0.088333\"/>\n      <Kern code=\"1139\" val=\"-0.088333\"/>\n      <Kern code=\"1077\" val=\"-0.088333\"/>\n      <Kern code=\"1105\" val=\"-0.088333\"/>\n      <Kern code=\"1089\" val=\"-0.088333\"/>\n      <Kern code=\"1108\" val=\"-0.088333\"/>\n      <Kern code=\"1092\" val=\"-0.088333\"/>\n      <Kern code=\"1080\" val=\"-0.088333\"/>\n      <Kern code=\"1081\" val=\"-0.088333\"/>\n      <Kern code=\"1094\" val=\"-0.088333\"/>\n      <Kern code=\"1096\" val=\"-0.088333\"/>\n      <Kern code=\"1097\" val=\"-0.088333\"/>\n      <Kern code=\"1100\" val=\"-0.088333\"/>\n      <Kern code=\"1099\" val=\"-0.088333\"/>\n      <Kern code=\"1091\" val=\"-0.088333\"/>\n      <Kern code=\"1141\" val=\"-0.088333\"/>\n      <Kern code=\"1098\" val=\"-0.088333\"/>\n      <Kern code=\"1083\" val=\"-0.088333\"/>\n      <Kern code=\"1084\" val=\"-0.088333\"/>\n      <Kern code=\"1113\" val=\"-0.088333\"/>\n   </Char>\n   <Char code=\"1061\" width=\"0.865547\" height=\"0.686111\" italic=\"0.156807\" >\n      <Kern code=\"1054\" val=\"-0.029445\"/>\n      <Kern code=\"1060\" val=\"-0.029445\"/>\n      <Kern code=\"1138\" val=\"-0.029445\"/>\n      <Kern code=\"1057\" val=\"-0.029445\"/>\n      <Kern code=\"1028\" val=\"-0.029445\"/>\n      <Kern code=\"1095\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1048\" width=\"0.894992\" height=\"0.686111\" italic=\"0.172084\" >\n   </Char>\n   <Char code=\"1032\" width=\"0.61055\" height=\"0.686111\" italic=\"0.145001\" >\n   </Char>\n   <Char code=\"1050\" width=\"0.894992\" height=\"0.686111\" italic=\"0.142084\" >\n      <Lig code=\"1061\" ligCode=\"1061\"/>\n      <Lig code=\"1093\" ligCode=\"1061\"/>\n      <Kern code=\"1054\" val=\"-0.029445\"/>\n      <Kern code=\"1060\" val=\"-0.029445\"/>\n      <Kern code=\"1138\" val=\"-0.029445\"/>\n      <Kern code=\"1057\" val=\"-0.029445\"/>\n      <Kern code=\"1028\" val=\"-0.029445\"/>\n      <Kern code=\"1095\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1051\" width=\"0.894992\" height=\"0.686111\" italic=\"0.172084\" >\n      <Lig code=\"1032\" ligCode=\"1033\"/>\n      <Lig code=\"1112\" ligCode=\"1033\"/>\n   </Char>\n   <Char code=\"1052\" width=\"1.072767\" height=\"0.686111\" italic=\"0.172084\" />\n   <Char code=\"1053\" width=\"0.894992\" height=\"0.686111\" italic=\"0.172084\" >\n      <Lig code=\"1032\" ligCode=\"1034\"/>\n      <Lig code=\"1112\" ligCode=\"1034\"/>\n   </Char>\n   <Char code=\"1054\" width=\"0.854991\" height=\"0.686111\" italic=\"0.090625\" >\n      <Kern code=\"1040\" val=\"-0.029445\"/>\n      <Kern code=\"1044\" val=\"-0.029445\"/>\n      <Kern code=\"1046\" val=\"-0.029445\"/>\n      <Kern code=\"1061\" val=\"-0.029445\"/>\n      <Kern code=\"1059\" val=\"-0.029445\"/>\n      <Kern code=\"1140\" val=\"-0.029445\"/>\n      <Kern code=\"1071\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1055\" width=\"0.894992\" height=\"0.686111\" italic=\"0.172084\" >\n   </Char>\n   <Char code=\"1063\" width=\"0.894992\" height=\"0.686111\" italic=\"0.172084\" />\n   <Char code=\"1056\" width=\"0.787214\" height=\"0.686111\" italic=\"0.099202\" >\n      <Kern code=\"1040\" val=\"-0.088333\"/>\n      <Kern code=\"1044\" val=\"-0.088333\"/>\n      <Kern code=\"1051\" val=\"-0.088333\"/>\n      <Kern code=\"1033\" val=\"-0.088333\"/>\n      <Kern code=\"1071\" val=\"-0.088333\"/>\n      <Kern code=\"1072\" val=\"-0.029445\"/>\n      <Kern code=\"1086\" val=\"-0.029445\"/>\n      <Kern code=\"1139\" val=\"-0.029445\"/>\n      <Kern code=\"1077\" val=\"-0.029445\"/>\n      <Kern code=\"1105\" val=\"-0.029445\"/>\n      <Kern code=\"1076\" val=\"-0.088333\"/>\n      <Kern code=\"1083\" val=\"-0.088333\"/>\n      <Kern code=\"1113\" val=\"-0.088333\"/>\n   </Char>\n   <Char code=\"1057\" width=\"0.826658\" height=\"0.686111\" italic=\"0.142084\" >\n      <Lig code=\"1061\" ligCode=\"1064\"/>\n      <Lig code=\"1093\" ligCode=\"1064\"/>\n   </Char>\n   <Char code=\"1058\" width=\"0.796103\" height=\"0.686111\" italic=\"0.12903\" >\n      <Lig code=\"1057\" ligCode=\"1062\"/>\n      <Lig code=\"1089\" ligCode=\"1062\"/>\n      <Kern code=\"1040\" val=\"-0.088333\"/>\n      <Kern code=\"1044\" val=\"-0.088333\"/>\n      <Kern code=\"1071\" val=\"-0.088333\"/>\n      <Kern code=\"1051\" val=\"-0.029445\"/>\n      <Kern code=\"1033\" val=\"-0.029445\"/>\n      <Kern code=\"1072\" val=\"-0.088333\"/>\n      <Kern code=\"1086\" val=\"-0.088333\"/>\n      <Kern code=\"1139\" val=\"-0.088333\"/>\n      <Kern code=\"1077\" val=\"-0.088333\"/>\n      <Kern code=\"1105\" val=\"-0.088333\"/>\n      <Kern code=\"1089\" val=\"-0.088333\"/>\n      <Kern code=\"1108\" val=\"-0.088333\"/>\n      <Kern code=\"1092\" val=\"-0.088333\"/>\n      <Kern code=\"1080\" val=\"-0.088333\"/>\n      <Kern code=\"1081\" val=\"-0.088333\"/>\n      <Kern code=\"1094\" val=\"-0.088333\"/>\n      <Kern code=\"1096\" val=\"-0.088333\"/>\n      <Kern code=\"1097\" val=\"-0.088333\"/>\n      <Kern code=\"1100\" val=\"-0.088333\"/>\n      <Kern code=\"1099\" val=\"-0.088333\"/>\n      <Kern code=\"1091\" val=\"-0.088333\"/>\n      <Kern code=\"1141\" val=\"-0.088333\"/>\n      <Kern code=\"1098\" val=\"-0.088333\"/>\n      <Kern code=\"1083\" val=\"-0.088333\"/>\n      <Kern code=\"1084\" val=\"-0.088333\"/>\n      <Kern code=\"1113\" val=\"-0.088333\"/>\n   </Char>\n   <Char code=\"1059\" width=\"0.865547\" height=\"0.686111\" italic=\"0.186251\" >\n      <Kern code=\"1040\" val=\"-0.088333\"/>\n      <Kern code=\"1071\" val=\"-0.088333\"/>\n      <Kern code=\"1044\" val=\"-0.058888\"/>\n      <Kern code=\"1051\" val=\"-0.058888\"/>\n      <Kern code=\"1033\" val=\"-0.058888\"/>\n      <Kern code=\"1054\" val=\"-0.029445\"/>\n      <Kern code=\"1060\" val=\"-0.029445\"/>\n      <Kern code=\"1138\" val=\"-0.029445\"/>\n      <Kern code=\"1057\" val=\"-0.029445\"/>\n      <Kern code=\"1028\" val=\"-0.029445\"/>\n      <Kern code=\"1072\" val=\"-0.088333\"/>\n      <Kern code=\"1086\" val=\"-0.088333\"/>\n      <Kern code=\"1139\" val=\"-0.088333\"/>\n      <Kern code=\"1077\" val=\"-0.088333\"/>\n      <Kern code=\"1105\" val=\"-0.088333\"/>\n      <Kern code=\"1089\" val=\"-0.088333\"/>\n      <Kern code=\"1108\" val=\"-0.088333\"/>\n      <Kern code=\"1080\" val=\"-0.117777\"/>\n      <Kern code=\"1081\" val=\"-0.117777\"/>\n      <Kern code=\"1094\" val=\"-0.117777\"/>\n      <Kern code=\"1096\" val=\"-0.117777\"/>\n      <Kern code=\"1097\" val=\"-0.117777\"/>\n      <Kern code=\"1100\" val=\"-0.117777\"/>\n      <Kern code=\"1099\" val=\"-0.117777\"/>\n      <Kern code=\"1091\" val=\"-0.117777\"/>\n      <Kern code=\"1141\" val=\"-0.117777\"/>\n      <Kern code=\"1098\" val=\"-0.117777\"/>\n      <Kern code=\"1083\" val=\"-0.117777\"/>\n      <Kern code=\"1084\" val=\"-0.117777\"/>\n      <Kern code=\"1113\" val=\"-0.117777\"/>\n   </Char>\n   <Char code=\"1042\" width=\"0.81666\" height=\"0.686111\" italic=\"0.069758\" />\n   <Char code=\"1065\" width=\"1.293599\" height=\"0.686111\" depth=\"0.194445\" italic=\"0.172084\" />\n   <Char code=\"1064\" width=\"1.293599\" height=\"0.686111\" italic=\"0.172084\" >\n      <Lig code=\"1063\" ligCode=\"1065\"/>\n      <Lig code=\"1095\" ligCode=\"1065\"/>\n      <Lig code=\"1062\" ligCode=\"0\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1067\" width=\"1.101102\" height=\"0.686111\" italic=\"0.172084\" >\n      <Lig code=\"1040\" ligCode=\"1071\"/>\n      <Lig code=\"1072\" ligCode=\"1071\"/>\n      <Lig code=\"1059\" ligCode=\"1070\"/>\n      <Lig code=\"1091\" ligCode=\"1070\"/>\n   </Char>\n   <Char code=\"1047\" width=\"0.708882\" height=\"0.686111\" italic=\"0.099202\" >\n      <Lig code=\"1061\" ligCode=\"1046\"/>\n      <Lig code=\"1093\" ligCode=\"1046\"/>\n   </Char>\n   <Char code=\"1068\" width=\"0.81666\" height=\"0.686111\" italic=\"0.032991\" >\n      <Kern code=\"1046\" val=\"-0.029445\"/>\n      <Kern code=\"1061\" val=\"-0.029445\"/>\n      <Kern code=\"1054\" val=\"-0.029445\"/>\n      <Kern code=\"1060\" val=\"-0.029445\"/>\n      <Kern code=\"1138\" val=\"-0.029445\"/>\n      <Kern code=\"1057\" val=\"-0.029445\"/>\n      <Kern code=\"1028\" val=\"-0.029445\"/>\n      <Kern code=\"1058\" val=\"-0.088333\"/>\n      <Kern code=\"1066\" val=\"-0.088333\"/>\n      <Kern code=\"1026\" val=\"-0.088333\"/>\n      <Kern code=\"1035\" val=\"-0.088333\"/>\n      <Kern code=\"1122\" val=\"-0.088333\"/>\n      <Kern code=\"1063\" val=\"-0.088333\"/>\n      <Kern code=\"1059\" val=\"-0.088333\"/>\n      <Kern code=\"1140\" val=\"-0.117777\"/>\n      <Kern code=\"1098\" val=\"-0.029445\"/>\n      <Kern code=\"1141\" val=\"-0.029445\"/>\n      <Kern code=\"1082\" val=\"-0.029445\"/>\n      <Kern code=\"1085\" val=\"-0.029445\"/>\n      <Kern code=\"1114\" val=\"-0.029445\"/>\n      <Kern code=\"1087\" val=\"-0.029445\"/>\n      <Kern code=\"1090\" val=\"-0.029445\"/>\n      <Kern code=\"1102\" val=\"-0.029445\"/>\n      <Kern code=\"1123\" val=\"-0.029445\"/>\n      <Kern code=\"1110\" val=\"-0.029445\"/>\n      <Kern code=\"1080\" val=\"-0.029445\"/>\n      <Kern code=\"1081\" val=\"-0.029445\"/>\n      <Kern code=\"1094\" val=\"-0.029445\"/>\n      <Kern code=\"1096\" val=\"-0.029445\"/>\n      <Kern code=\"1097\" val=\"-0.029445\"/>\n      <Kern code=\"1100\" val=\"-0.029445\"/>\n      <Kern code=\"1099\" val=\"-0.029445\"/>\n      <Kern code=\"1091\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1066\" width=\"0.988047\" height=\"0.686111\" italic=\"0.032991\" >\n      <Kern code=\"1046\" val=\"-0.029445\"/>\n      <Kern code=\"1061\" val=\"-0.029445\"/>\n      <Kern code=\"1054\" val=\"-0.029445\"/>\n      <Kern code=\"1060\" val=\"-0.029445\"/>\n      <Kern code=\"1138\" val=\"-0.029445\"/>\n      <Kern code=\"1057\" val=\"-0.029445\"/>\n      <Kern code=\"1028\" val=\"-0.029445\"/>\n      <Kern code=\"1058\" val=\"-0.088333\"/>\n      <Kern code=\"1066\" val=\"-0.088333\"/>\n      <Kern code=\"1026\" val=\"-0.088333\"/>\n      <Kern code=\"1035\" val=\"-0.088333\"/>\n      <Kern code=\"1122\" val=\"-0.088333\"/>\n      <Kern code=\"1063\" val=\"-0.088333\"/>\n      <Kern code=\"1059\" val=\"-0.088333\"/>\n      <Kern code=\"1140\" val=\"-0.117777\"/>\n      <Kern code=\"1098\" val=\"-0.029445\"/>\n      <Kern code=\"1141\" val=\"-0.029445\"/>\n      <Kern code=\"1082\" val=\"-0.029445\"/>\n      <Kern code=\"1085\" val=\"-0.029445\"/>\n      <Kern code=\"1114\" val=\"-0.029445\"/>\n      <Kern code=\"1087\" val=\"-0.029445\"/>\n      <Kern code=\"1090\" val=\"-0.029445\"/>\n      <Kern code=\"1102\" val=\"-0.029445\"/>\n      <Kern code=\"1123\" val=\"-0.029445\"/>\n      <Kern code=\"1110\" val=\"-0.029445\"/>\n      <Kern code=\"1080\" val=\"-0.029445\"/>\n      <Kern code=\"1081\" val=\"-0.029445\"/>\n      <Kern code=\"1094\" val=\"-0.029445\"/>\n      <Kern code=\"1096\" val=\"-0.029445\"/>\n      <Kern code=\"1097\" val=\"-0.029445\"/>\n      <Kern code=\"1100\" val=\"-0.029445\"/>\n      <Kern code=\"1099\" val=\"-0.029445\"/>\n      <Kern code=\"1091\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1072\" width=\"0.570494\" height=\"0.444445\" italic=\"0.094261\" />\n   <Char code=\"1073\" width=\"0.549883\" height=\"0.694445\" italic=\"0.167501\" >\n      <Kern code=\"1092\" val=\"-0.058888\"/>\n      <Kern code=\"1072\" val=\"-0.058888\"/>\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1094\" width=\"0.655884\" height=\"0.444445\" depth=\"0.194445\" italic=\"0.094261\" >\n      <Lig code=\"1093\" ligCode=\"1095\"/>\n   </Char>\n   <Char code=\"1076\" width=\"0.549883\" height=\"0.694445\" italic=\"0.112694\" >\n      <Lig code=\"1112\" ligCode=\"1106\"/>\n   </Char>\n   <Char code=\"1077\" width=\"0.511606\" height=\"0.444445\" italic=\"0.085002\" >\n      <Kern code=\"1092\" val=\"-0.058888\"/>\n      <Kern code=\"1072\" val=\"-0.058888\"/>\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1092\" width=\"0.785437\" height=\"0.694445\" depth=\"0.194445\" italic=\"0.078611\" >\n      <Kern code=\"1092\" val=\"-0.058888\"/>\n      <Kern code=\"1072\" val=\"-0.058888\"/>\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1075\" width=\"0.488052\" height=\"0.444445\" italic=\"0.085002\" />\n   <Char code=\"1093\" width=\"0.648885\" height=\"0.444445\" italic=\"0.1258335\" />\n   <Char code=\"1080\" width=\"0.649994\" height=\"0.444445\" italic=\"0.094261\" >\n   </Char>\n   <Char code=\"1112\" width=\"0.355553\" height=\"0.693255\" depth=\"0.194445\" italic=\"0.167204\" >\n   </Char>\n   <Char code=\"1082\" width=\"0.591105\" height=\"0.444445\" italic=\"0.111112\" >\n      <Lig code=\"1093\" ligCode=\"1093\"/>\n   </Char>\n   <Char code=\"1083\" width=\"0.62055\" height=\"0.444445\" italic=\"0.094261\" >\n      <Lig code=\"1112\" ligCode=\"1113\"/>\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n      <Kern code=\"1141\" val=\"-0.029445\"/>\n      <Kern code=\"1098\" val=\"-0.029445\"/>\n      <Kern code=\"1095\" val=\"-0.088333\"/>\n   </Char>\n   <Char code=\"1084\" width=\"0.856104\" height=\"0.444445\" italic=\"0.094261\" />\n   <Char code=\"1085\" width=\"0.649994\" height=\"0.444445\" italic=\"0.094261\" >\n      <Lig code=\"1112\" ligCode=\"1114\"/>\n   </Char>\n   <Char code=\"1086\" width=\"0.549883\" height=\"0.444445\" italic=\"0.078611\" >\n      <Kern code=\"1092\" val=\"-0.058888\"/>\n      <Kern code=\"1072\" val=\"-0.058888\"/>\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1087\" width=\"0.649994\" height=\"0.444445\" italic=\"0.094261\" >\n   </Char>\n   <Char code=\"1095\" width=\"0.62055\" height=\"0.444445\" italic=\"0.094261\" />\n   <Char code=\"1088\" width=\"0.585216\" height=\"0.444445\" depth=\"0.194445\" italic=\"0.078611\" >\n      <Kern code=\"1092\" val=\"-0.058888\"/>\n      <Kern code=\"1072\" val=\"-0.058888\"/>\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1089\" width=\"0.511606\" height=\"0.444445\" italic=\"0.052223\" >\n      <Lig code=\"1093\" ligCode=\"1096\"/>\n      <Kern code=\"1092\" val=\"-0.058888\"/>\n      <Kern code=\"1072\" val=\"-0.058888\"/>\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1090\" width=\"0.944435\" height=\"0.444445\" italic=\"0.094261\" >\n      <Lig code=\"1089\" ligCode=\"1094\"/>\n   </Char>\n   <Char code=\"1091\" width=\"0.591105\" height=\"0.444445\" depth=\"0.194445\" italic=\"0.105001\" />\n   <Char code=\"1074\" width=\"0.570494\" height=\"0.444445\" italic=\"0.085002\" />\n   <Char code=\"1097\" width=\"0.950325\" height=\"0.444445\" depth=\"0.194445\" italic=\"0.094261\" />\n   <Char code=\"1096\" width=\"0.944435\" height=\"0.444445\" italic=\"0.094261\" >\n      <Lig code=\"1095\" ligCode=\"1097\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1099\" width=\"0.767771\" height=\"0.444445\" italic=\"0.094261\" >\n      <Lig code=\"1072\" ligCode=\"1103\"/>\n      <Lig code=\"1091\" ligCode=\"1102\"/>\n   </Char>\n   <Char code=\"1079\" width=\"0.532217\" height=\"0.444445\" italic=\"0.052223\" >\n      <Lig code=\"1093\" ligCode=\"1078\"/>\n   </Char>\n   <Char code=\"1100\" width=\"0.591105\" height=\"0.444445\" italic=\"0.078611\" >\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n      <Kern code=\"1141\" val=\"-0.029445\"/>\n      <Kern code=\"1098\" val=\"-0.029445\"/>\n      <Kern code=\"1095\" val=\"-0.088333\"/>\n      <Kern code=\"1086\" val=\"-0.029445\"/>\n      <Kern code=\"1139\" val=\"-0.029445\"/>\n      <Kern code=\"1092\" val=\"-0.029445\"/>\n      <Kern code=\"1108\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1098\" width=\"0.561663\" height=\"0.444445\" italic=\"0.078611\" >\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n      <Kern code=\"1141\" val=\"-0.029445\"/>\n      <Kern code=\"1098\" val=\"-0.029445\"/>\n      <Kern code=\"1095\" val=\"-0.088333\"/>\n      <Kern code=\"1086\" val=\"-0.029445\"/>\n      <Kern code=\"1139\" val=\"-0.029445\"/>\n      <Kern code=\"1092\" val=\"-0.029445\"/>\n      <Kern code=\"1108\" val=\"-0.029445\"/>\n   </Char>\n</Font>\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/cyrillic/wnr10.xml",
    "content": "<Font name=\"wnr10.ttf\" id=\"wnr10\" space=\"0.333334\" xHeight=\"0.430555\" quad=\"1.000003\" unicode=\"95\" boldVersion=\"wnbx10\" ssVersion=\"wnss10\" ttVersion=\"wntt10\" itVersion=\"wnti10\">\n   <Char code=\"1034\" width=\"1.083338\" height=\"0.683332\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.083334\"/>\n      <Kern code=\"1140\" val=\"-0.111112\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1033\" width=\"1.083338\" height=\"0.683332\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.083334\"/>\n      <Kern code=\"1140\" val=\"-0.111112\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1039\" width=\"0.777781\" height=\"0.683332\" depth=\"0.194445\" />\n   <Char code=\"1069\" width=\"0.722224\" height=\"0.683332\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n      <Kern code=\"1071\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1030\" width=\"0.361112\" height=\"0.683332\" >\n      <Kern code=\"1030\" val=\"0.027779\"/>\n   </Char>\n   <Char code=\"1028\" width=\"0.722224\" height=\"0.683332\" />\n   <Char code=\"1026\" width=\"0.8611145\" height=\"0.683332\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.083334\"/>\n      <Kern code=\"1140\" val=\"-0.111112\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1035\" width=\"0.763891\" height=\"0.683332\" />\n   <Char code=\"1114\" width=\"0.763891\" height=\"0.430555\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1113\" width=\"0.763891\" height=\"0.430555\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1119\" width=\"0.555557\" height=\"0.430555\" depth=\"0.162038\" italic=\"0.001389\" />\n   <Char code=\"1101\" width=\"0.444446\" height=\"0.430555\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1110\" width=\"0.277779\" height=\"0.667859\" />\n   <Char code=\"1108\" width=\"0.43889\" height=\"0.430555\" />\n   <Char code=\"1106\" width=\"0.527781\" height=\"0.694445\" depth=\"0.194445\" />\n   <Char code=\"1115\" width=\"0.555557\" height=\"0.694445\" />\n   <Char code=\"1070\" width=\"1.125003\" height=\"0.683332\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n      <Kern code=\"1071\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1046\" width=\"1.194448\" height=\"0.683332\" >\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.027779\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1049\" width=\"0.777781\" height=\"0.891615\" />\n   <Char code=\"1025\" width=\"0.680557\" height=\"0.891615\" />\n   <Char code=\"1140\" width=\"0.8194475\" height=\"0.683332\" italic=\"0.013888\" >\n      <Kern code=\"1040\" val=\"-0.111112\"/>\n      <Kern code=\"1071\" val=\"-0.111112\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1072\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.083334\"/>\n      <Kern code=\"1139\" val=\"-0.083334\"/>\n      <Kern code=\"1077\" val=\"-0.083334\"/>\n      <Kern code=\"1105\" val=\"-0.083334\"/>\n      <Kern code=\"1076\" val=\"-0.111112\"/>\n      <Kern code=\"1083\" val=\"-0.111112\"/>\n      <Kern code=\"1113\" val=\"-0.111112\"/>\n      <Kern code=\"1103\" val=\"-0.111112\"/>\n   </Char>\n   <Char code=\"1138\" width=\"0.777781\" height=\"0.683332\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n      <Kern code=\"1071\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1029\" width=\"0.555557\" height=\"0.683332\" />\n   <Char code=\"1071\" width=\"0.777781\" height=\"0.683332\" />\n   <Char code=\"1102\" width=\"0.750003\" height=\"0.430555\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1078\" width=\"0.833336\" height=\"0.430555\" >\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1081\" width=\"0.555557\" height=\"0.638838\" italic=\"0.001389\" />\n   <Char code=\"1105\" width=\"0.444446\" height=\"0.659131\" />\n   <Char code=\"1141\" width=\"0.587503\" height=\"0.430555\" italic=\"0.013888\" >\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.055555\"/>\n      <Kern code=\"1083\" val=\"-0.055555\"/>\n      <Kern code=\"1113\" val=\"-0.055555\"/>\n   </Char>\n   <Char code=\"1139\" width=\"0.444446\" height=\"0.430555\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1109\" width=\"0.394445\" height=\"0.430555\" />\n   <Char code=\"1103\" width=\"0.541669\" height=\"0.430555\" italic=\"0.001389\" />\n   <Char code=\"776\" width=\"0.500002\" height=\"0.659131\" />\n   <Char code=\"1122\" width=\"0.8194475\" height=\"0.75\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.083334\"/>\n      <Kern code=\"1140\" val=\"-0.111112\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"774\" width=\"0.500002\" height=\"0.638838\" />\n   <Char code=\"1123\" width=\"0.500002\" height=\"0.638838\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"171\" width=\"0.555557\" height=\"0.483335\" />\n   <Char code=\"305\" width=\"0.277779\" height=\"0.430555\" />\n   <Char code=\"187\" width=\"0.555557\" height=\"0.483335\" />\n   <Char code=\"1040\" width=\"0.750002\" height=\"0.683332\" >\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.083334\"/>\n      <Kern code=\"1140\" val=\"-0.111112\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1041\" width=\"0.708336\" height=\"0.683332\" />\n   <Char code=\"1062\" width=\"0.777781\" height=\"0.683332\" depth=\"0.194445\" >\n      <Lig code=\"1061\" ligCode=\"1063\"/>\n      <Lig code=\"1093\" ligCode=\"1063\"/>\n   </Char>\n   <Char code=\"1044\" width=\"0.777781\" height=\"0.683332\" depth=\"0.194445\" >\n      <Lig code=\"1032\" ligCode=\"1026\"/>\n      <Lig code=\"1112\" ligCode=\"1026\"/>\n   </Char>\n   <Char code=\"1045\" width=\"0.680557\" height=\"0.683332\" >\n   </Char>\n   <Char code=\"1060\" width=\"0.833336\" height=\"0.683332\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n      <Kern code=\"1071\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1043\" width=\"0.625002\" height=\"0.683332\" >\n      <Kern code=\"1040\" val=\"-0.083334\"/>\n      <Kern code=\"1044\" val=\"-0.083334\"/>\n      <Kern code=\"1071\" val=\"-0.083334\"/>\n      <Kern code=\"1051\" val=\"-0.027779\"/>\n      <Kern code=\"1033\" val=\"-0.027779\"/>\n      <Kern code=\"1072\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.083334\"/>\n      <Kern code=\"1139\" val=\"-0.083334\"/>\n      <Kern code=\"1077\" val=\"-0.083334\"/>\n      <Kern code=\"1105\" val=\"-0.083334\"/>\n      <Kern code=\"1089\" val=\"-0.083334\"/>\n      <Kern code=\"1108\" val=\"-0.083334\"/>\n      <Kern code=\"1092\" val=\"-0.083334\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n      <Kern code=\"1103\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1061\" width=\"0.750002\" height=\"0.683332\" >\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.027779\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1048\" width=\"0.777781\" height=\"0.683332\" >\n   </Char>\n   <Char code=\"1032\" width=\"0.51389\" height=\"0.683332\" >\n   </Char>\n   <Char code=\"1050\" width=\"0.777781\" height=\"0.683332\" >\n      <Lig code=\"1061\" ligCode=\"1061\"/>\n      <Lig code=\"1093\" ligCode=\"1061\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.027779\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1051\" width=\"0.777781\" height=\"0.683332\" >\n      <Lig code=\"1032\" ligCode=\"1033\"/>\n      <Lig code=\"1112\" ligCode=\"1033\"/>\n   </Char>\n   <Char code=\"1052\" width=\"0.916669\" height=\"0.683332\" />\n   <Char code=\"1053\" width=\"0.777781\" height=\"0.683332\" >\n      <Lig code=\"1032\" ligCode=\"1034\"/>\n      <Lig code=\"1112\" ligCode=\"1034\"/>\n   </Char>\n   <Char code=\"1054\" width=\"0.777781\" height=\"0.683332\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n      <Kern code=\"1071\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1055\" width=\"0.777781\" height=\"0.683332\" >\n   </Char>\n   <Char code=\"1063\" width=\"0.777781\" height=\"0.683332\" />\n   <Char code=\"1056\" width=\"0.680557\" height=\"0.683332\" >\n      <Kern code=\"1040\" val=\"-0.083334\"/>\n      <Kern code=\"1044\" val=\"-0.083334\"/>\n      <Kern code=\"1051\" val=\"-0.083334\"/>\n      <Kern code=\"1033\" val=\"-0.083334\"/>\n      <Kern code=\"1071\" val=\"-0.083334\"/>\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1057\" width=\"0.722224\" height=\"0.683332\" >\n      <Lig code=\"1061\" ligCode=\"1064\"/>\n      <Lig code=\"1093\" ligCode=\"1064\"/>\n   </Char>\n   <Char code=\"1058\" width=\"0.722224\" height=\"0.683332\" >\n      <Lig code=\"1057\" ligCode=\"1062\"/>\n      <Lig code=\"1089\" ligCode=\"1062\"/>\n      <Kern code=\"1040\" val=\"-0.083334\"/>\n      <Kern code=\"1044\" val=\"-0.083334\"/>\n      <Kern code=\"1071\" val=\"-0.083334\"/>\n      <Kern code=\"1051\" val=\"-0.027779\"/>\n      <Kern code=\"1033\" val=\"-0.027779\"/>\n      <Kern code=\"1072\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.083334\"/>\n      <Kern code=\"1139\" val=\"-0.083334\"/>\n      <Kern code=\"1077\" val=\"-0.083334\"/>\n      <Kern code=\"1105\" val=\"-0.083334\"/>\n      <Kern code=\"1089\" val=\"-0.083334\"/>\n      <Kern code=\"1108\" val=\"-0.083334\"/>\n      <Kern code=\"1092\" val=\"-0.083334\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n      <Kern code=\"1103\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1059\" width=\"0.750002\" height=\"0.683332\" italic=\"0.013888\" >\n      <Kern code=\"1040\" val=\"-0.083334\"/>\n      <Kern code=\"1071\" val=\"-0.083334\"/>\n      <Kern code=\"1044\" val=\"-0.055555\"/>\n      <Kern code=\"1051\" val=\"-0.055555\"/>\n      <Kern code=\"1033\" val=\"-0.055555\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1072\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.083334\"/>\n      <Kern code=\"1139\" val=\"-0.083334\"/>\n      <Kern code=\"1077\" val=\"-0.083334\"/>\n      <Kern code=\"1105\" val=\"-0.083334\"/>\n      <Kern code=\"1089\" val=\"-0.083334\"/>\n      <Kern code=\"1108\" val=\"-0.083334\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n      <Kern code=\"1103\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1042\" width=\"0.708336\" height=\"0.683332\" />\n   <Char code=\"1065\" width=\"1.125003\" height=\"0.683332\" depth=\"0.194445\" />\n   <Char code=\"1064\" width=\"1.125003\" height=\"0.683332\" >\n      <Lig code=\"1063\" ligCode=\"1065\"/>\n      <Lig code=\"1095\" ligCode=\"1065\"/>\n      <Lig code=\"1062\" ligCode=\"0\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1067\" width=\"0.972226\" height=\"0.683332\" >\n      <Lig code=\"1040\" ligCode=\"1071\"/>\n      <Lig code=\"1072\" ligCode=\"1071\"/>\n      <Lig code=\"1059\" ligCode=\"1070\"/>\n      <Lig code=\"1091\" ligCode=\"1070\"/>\n   </Char>\n   <Char code=\"1047\" width=\"0.611113\" height=\"0.683332\" >\n      <Lig code=\"1061\" ligCode=\"1046\"/>\n      <Lig code=\"1093\" ligCode=\"1046\"/>\n   </Char>\n   <Char code=\"1068\" width=\"0.708336\" height=\"0.683332\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.083334\"/>\n      <Kern code=\"1140\" val=\"-0.111112\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1066\" width=\"0.888893\" height=\"0.683332\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.083334\"/>\n      <Kern code=\"1140\" val=\"-0.111112\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1072\" width=\"0.500002\" height=\"0.430555\" >\n      <Kern code=\"1095\" val=\"-0.027779\"/>\n      <Kern code=\"1091\" val=\"-0.027779\"/>\n      <Kern code=\"1141\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1073\" width=\"0.500002\" height=\"0.694445\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1094\" width=\"0.555557\" height=\"0.430555\" depth=\"0.162038\" italic=\"0.001389\" >\n      <Lig code=\"1093\" ligCode=\"1095\"/>\n   </Char>\n   <Char code=\"1076\" width=\"0.555557\" height=\"0.430555\" depth=\"0.162038\" italic=\"0.001389\" >\n      <Lig code=\"1112\" ligCode=\"1106\"/>\n   </Char>\n   <Char code=\"1077\" width=\"0.444446\" height=\"0.430555\" >\n   </Char>\n   <Char code=\"1092\" width=\"0.7777815\" height=\"0.694445\" depth=\"0.194445\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1075\" width=\"0.444446\" height=\"0.430555\" >\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1083\" val=\"-0.027779\"/>\n      <Kern code=\"1113\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1093\" width=\"0.527781\" height=\"0.430555\" >\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1080\" width=\"0.555557\" height=\"0.430555\" italic=\"0.001389\" >\n   </Char>\n   <Char code=\"1112\" width=\"0.305557\" height=\"0.667859\" depth=\"0.194445\" >\n   </Char>\n   <Char code=\"1082\" width=\"0.555557\" height=\"0.430555\" >\n      <Lig code=\"1093\" ligCode=\"1093\"/>\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1083\" width=\"0.555557\" height=\"0.430555\" italic=\"0.001389\" >\n      <Lig code=\"1112\" ligCode=\"1113\"/>\n   </Char>\n   <Char code=\"1084\" width=\"0.666669\" height=\"0.430555\" italic=\"0.001389\" />\n   <Char code=\"1085\" width=\"0.555557\" height=\"0.430555\" italic=\"0.001389\" >\n      <Lig code=\"1112\" ligCode=\"1114\"/>\n   </Char>\n   <Char code=\"1086\" width=\"0.500002\" height=\"0.430555\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1087\" width=\"0.555557\" height=\"0.430555\" italic=\"0.001389\" >\n   </Char>\n   <Char code=\"1095\" width=\"0.555557\" height=\"0.430555\" italic=\"0.001389\" />\n   <Char code=\"1088\" width=\"0.555557\" height=\"0.430555\" depth=\"0.194445\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1089\" width=\"0.444446\" height=\"0.430555\" >\n      <Lig code=\"1093\" ligCode=\"1096\"/>\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1090\" width=\"0.500002\" height=\"0.430555\" >\n      <Lig code=\"1089\" ligCode=\"1094\"/>\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1083\" val=\"-0.027779\"/>\n      <Kern code=\"1113\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1091\" width=\"0.527781\" height=\"0.430555\" depth=\"0.194445\" italic=\"0.013888\" >\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.055555\"/>\n      <Kern code=\"1083\" val=\"-0.055555\"/>\n      <Kern code=\"1113\" val=\"-0.055555\"/>\n   </Char>\n   <Char code=\"1074\" width=\"0.500002\" height=\"0.430555\" />\n   <Char code=\"1097\" width=\"0.805559\" height=\"0.430555\" depth=\"0.162038\" italic=\"0.001389\" />\n   <Char code=\"1096\" width=\"0.805559\" height=\"0.430555\" italic=\"0.001389\" >\n      <Lig code=\"1095\" ligCode=\"1097\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1099\" width=\"0.722224\" height=\"0.430555\" italic=\"0.001389\" >\n      <Lig code=\"1072\" ligCode=\"1103\"/>\n      <Lig code=\"1091\" ligCode=\"1102\"/>\n   </Char>\n   <Char code=\"1079\" width=\"0.444446\" height=\"0.430555\" italic=\"0.005556\" >\n      <Lig code=\"1093\" ligCode=\"1078\"/>\n   </Char>\n   <Char code=\"1100\" width=\"0.500002\" height=\"0.430555\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1098\" width=\"0.611113\" height=\"0.430555\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n</Font>\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/cyrillic/wnss10.xml",
    "content": "<Font name=\"wnss10.ttf\" id=\"wnss10\" space=\"0.333334\" xHeight=\"0.444445\" quad=\"1.000003\" unicode=\"95\" romanVersion=\"wnr10\" ttVersion=\"wntt10\" boldVersion=\"wnssbx10\" itVersion=\"wnssi10\">\n   <Char code=\"1034\" width=\"1.020838\" height=\"0.694445\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1033\" width=\"1.037504\" height=\"0.694445\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1039\" width=\"0.694448\" height=\"0.694445\" depth=\"0.194445\" />\n   <Char code=\"1069\" width=\"0.638891\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1030\" width=\"0.277781\" height=\"0.694445\" >\n      <Kern code=\"1030\" val=\"0.027779\"/>\n   </Char>\n   <Char code=\"1028\" width=\"0.638891\" height=\"0.694445\" />\n   <Char code=\"1026\" width=\"0.8194475\" height=\"0.694445\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1035\" width=\"0.763891\" height=\"0.694445\" />\n   <Char code=\"1114\" width=\"0.765282\" height=\"0.444445\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1113\" width=\"0.755559\" height=\"0.444445\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1119\" width=\"0.537503\" height=\"0.444445\" depth=\"0.162038\" />\n   <Char code=\"1101\" width=\"0.444446\" height=\"0.444445\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1110\" width=\"0.23889\" height=\"0.679365\" />\n   <Char code=\"1108\" width=\"0.43889\" height=\"0.444445\" />\n   <Char code=\"1106\" width=\"0.488892\" height=\"0.694445\" depth=\"0.194445\" />\n   <Char code=\"1115\" width=\"0.516668\" height=\"0.694445\" />\n   <Char code=\"1070\" width=\"1.04167\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1046\" width=\"1.111117\" height=\"0.694445\" >\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.027779\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1049\" width=\"0.694448\" height=\"0.902727\" />\n   <Char code=\"1025\" width=\"0.597224\" height=\"0.902727\" />\n   <Char code=\"1140\" width=\"0.722226\" height=\"0.694445\" italic=\"0.013888\" >\n      <Kern code=\"1040\" val=\"-0.083334\"/>\n      <Kern code=\"1044\" val=\"-0.055555\"/>\n      <Kern code=\"1051\" val=\"-0.055555\"/>\n      <Kern code=\"1033\" val=\"-0.055555\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n      <Kern code=\"1103\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1138\" width=\"0.777781\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1029\" width=\"0.555557\" height=\"0.694445\" />\n   <Char code=\"1071\" width=\"0.645836\" height=\"0.694445\" />\n   <Char code=\"1102\" width=\"0.730558\" height=\"0.444445\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1078\" width=\"0.7388935\" height=\"0.444445\" >\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1081\" width=\"0.537503\" height=\"0.652727\" />\n   <Char code=\"1105\" width=\"0.444446\" height=\"0.660319\" />\n   <Char code=\"1141\" width=\"0.491667\" height=\"0.444445\" italic=\"0.013888\" >\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.055555\"/>\n      <Kern code=\"1083\" val=\"-0.055555\"/>\n      <Kern code=\"1113\" val=\"-0.055555\"/>\n   </Char>\n   <Char code=\"1139\" width=\"0.500002\" height=\"0.444445\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1109\" width=\"0.383334\" height=\"0.444445\" />\n   <Char code=\"1103\" width=\"0.515279\" height=\"0.444445\" />\n   <Char code=\"776\" width=\"0.500002\" height=\"0.660319\" />\n   <Char code=\"1122\" width=\"0.7777815\" height=\"0.75\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"774\" width=\"0.500002\" height=\"0.652727\" />\n   <Char code=\"1123\" width=\"0.500002\" height=\"0.652727\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"171\" width=\"0.666669\" height=\"0.438889\" />\n   <Char code=\"305\" width=\"0.23889\" height=\"0.444445\" />\n   <Char code=\"187\" width=\"0.666669\" height=\"0.438889\" />\n   <Char code=\"1040\" width=\"0.66667\" height=\"0.694445\" >\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1041\" width=\"0.66667\" height=\"0.694445\" />\n   <Char code=\"1062\" width=\"0.711116\" height=\"0.694445\" depth=\"0.194445\" >\n      <Lig code=\"1061\" ligCode=\"1063\"/>\n      <Lig code=\"1093\" ligCode=\"1063\"/>\n   </Char>\n   <Char code=\"1044\" width=\"0.727783\" height=\"0.694445\" depth=\"0.194445\" >\n      <Lig code=\"1032\" ligCode=\"1026\"/>\n      <Lig code=\"1112\" ligCode=\"1026\"/>\n   </Char>\n   <Char code=\"1045\" width=\"0.597224\" height=\"0.694445\" >\n   </Char>\n   <Char code=\"1060\" width=\"0.833336\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1043\" width=\"0.541669\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.083334\"/>\n      <Kern code=\"1044\" val=\"-0.083334\"/>\n      <Kern code=\"1051\" val=\"-0.055555\"/>\n      <Kern code=\"1033\" val=\"-0.055555\"/>\n      <Kern code=\"1072\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.083334\"/>\n      <Kern code=\"1139\" val=\"-0.083334\"/>\n      <Kern code=\"1077\" val=\"-0.083334\"/>\n      <Kern code=\"1105\" val=\"-0.083334\"/>\n      <Kern code=\"1089\" val=\"-0.083334\"/>\n      <Kern code=\"1108\" val=\"-0.083334\"/>\n      <Kern code=\"1092\" val=\"-0.083334\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n      <Kern code=\"1103\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1061\" width=\"0.66667\" height=\"0.694445\" >\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.027779\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1048\" width=\"0.694448\" height=\"0.694445\" >\n   </Char>\n   <Char code=\"1032\" width=\"0.472224\" height=\"0.694445\" >\n   </Char>\n   <Char code=\"1050\" width=\"0.694448\" height=\"0.694445\" >\n      <Lig code=\"1061\" ligCode=\"1061\"/>\n      <Lig code=\"1093\" ligCode=\"1061\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.027779\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1051\" width=\"0.711116\" height=\"0.694445\" >\n      <Lig code=\"1032\" ligCode=\"1033\"/>\n      <Lig code=\"1112\" ligCode=\"1033\"/>\n   </Char>\n   <Char code=\"1052\" width=\"0.875005\" height=\"0.694445\" />\n   <Char code=\"1053\" width=\"0.694448\" height=\"0.694445\" >\n      <Lig code=\"1032\" ligCode=\"1034\"/>\n      <Lig code=\"1112\" ligCode=\"1034\"/>\n   </Char>\n   <Char code=\"1054\" width=\"0.736113\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1055\" width=\"0.694448\" height=\"0.694445\" >\n   </Char>\n   <Char code=\"1063\" width=\"0.694448\" height=\"0.694445\" />\n   <Char code=\"1056\" width=\"0.638891\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.083334\"/>\n      <Kern code=\"1044\" val=\"-0.083334\"/>\n      <Kern code=\"1051\" val=\"-0.083334\"/>\n      <Kern code=\"1033\" val=\"-0.083334\"/>\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1057\" width=\"0.638891\" height=\"0.694445\" >\n      <Lig code=\"1061\" ligCode=\"1064\"/>\n      <Lig code=\"1093\" ligCode=\"1064\"/>\n   </Char>\n   <Char code=\"1058\" width=\"0.680557\" height=\"0.694445\" >\n      <Lig code=\"1057\" ligCode=\"1062\"/>\n      <Lig code=\"1089\" ligCode=\"1062\"/>\n      <Kern code=\"1040\" val=\"-0.083334\"/>\n      <Kern code=\"1044\" val=\"-0.083334\"/>\n      <Kern code=\"1051\" val=\"-0.055555\"/>\n      <Kern code=\"1033\" val=\"-0.055555\"/>\n      <Kern code=\"1072\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.083334\"/>\n      <Kern code=\"1139\" val=\"-0.083334\"/>\n      <Kern code=\"1077\" val=\"-0.083334\"/>\n      <Kern code=\"1105\" val=\"-0.083334\"/>\n      <Kern code=\"1089\" val=\"-0.083334\"/>\n      <Kern code=\"1108\" val=\"-0.083334\"/>\n      <Kern code=\"1092\" val=\"-0.083334\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n      <Kern code=\"1103\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1059\" width=\"0.66667\" height=\"0.694445\" italic=\"0.013888\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.055555\"/>\n      <Kern code=\"1051\" val=\"-0.055555\"/>\n      <Kern code=\"1033\" val=\"-0.055555\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n      <Kern code=\"1103\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1042\" width=\"0.66667\" height=\"0.694445\" />\n   <Char code=\"1065\" width=\"1.100006\" height=\"0.694445\" depth=\"0.194445\" />\n   <Char code=\"1064\" width=\"1.083339\" height=\"0.694445\" >\n      <Lig code=\"1063\" ligCode=\"1065\"/>\n      <Lig code=\"1095\" ligCode=\"1065\"/>\n      <Lig code=\"1062\" ligCode=\"0\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1067\" width=\"0.888895\" height=\"0.694445\" >\n      <Lig code=\"1040\" ligCode=\"1071\"/>\n      <Lig code=\"1072\" ligCode=\"1071\"/>\n      <Lig code=\"1059\" ligCode=\"1070\"/>\n      <Lig code=\"1091\" ligCode=\"1070\"/>\n   </Char>\n   <Char code=\"1047\" width=\"0.611113\" height=\"0.694445\" >\n      <Lig code=\"1061\" ligCode=\"1046\"/>\n      <Lig code=\"1093\" ligCode=\"1046\"/>\n   </Char>\n   <Char code=\"1068\" width=\"0.66667\" height=\"0.694445\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1066\" width=\"0.868059\" height=\"0.694445\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1072\" width=\"0.480557\" height=\"0.444445\" >\n      <Kern code=\"1095\" val=\"-0.027779\"/>\n      <Kern code=\"1091\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1073\" width=\"0.500002\" height=\"0.694445\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1094\" width=\"0.5486145\" height=\"0.444445\" depth=\"0.162038\" >\n      <Lig code=\"1093\" ligCode=\"1095\"/>\n   </Char>\n   <Char code=\"1076\" width=\"0.538892\" height=\"0.444445\" depth=\"0.162038\" >\n      <Lig code=\"1112\" ligCode=\"1106\"/>\n   </Char>\n   <Char code=\"1077\" width=\"0.444446\" height=\"0.444445\" >\n   </Char>\n   <Char code=\"1092\" width=\"0.76667\" height=\"0.694445\" depth=\"0.194445\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1075\" width=\"0.404167\" height=\"0.444445\" italic=\"0.013888\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1083\" val=\"-0.027779\"/>\n      <Kern code=\"1113\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1093\" width=\"0.461113\" height=\"0.444445\" >\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1080\" width=\"0.537503\" height=\"0.444445\" >\n   </Char>\n   <Char code=\"1112\" width=\"0.266668\" height=\"0.679365\" depth=\"0.194445\" >\n   </Char>\n   <Char code=\"1082\" width=\"0.488892\" height=\"0.444445\" >\n      <Lig code=\"1093\" ligCode=\"1093\"/>\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1083\" width=\"0.527781\" height=\"0.444445\" >\n      <Lig code=\"1112\" ligCode=\"1113\"/>\n   </Char>\n   <Char code=\"1084\" width=\"0.669447\" height=\"0.444445\" />\n   <Char code=\"1085\" width=\"0.516668\" height=\"0.444445\" >\n      <Lig code=\"1112\" ligCode=\"1114\"/>\n   </Char>\n   <Char code=\"1086\" width=\"0.500002\" height=\"0.444445\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1087\" width=\"0.516668\" height=\"0.444445\" >\n   </Char>\n   <Char code=\"1095\" width=\"0.537503\" height=\"0.444445\" />\n   <Char code=\"1088\" width=\"0.516668\" height=\"0.444445\" depth=\"0.194445\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1089\" width=\"0.444446\" height=\"0.444445\" >\n      <Lig code=\"1093\" ligCode=\"1096\"/>\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1090\" width=\"0.458334\" height=\"0.444445\" italic=\"0.019444\" >\n      <Lig code=\"1089\" ligCode=\"1094\"/>\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1083\" val=\"-0.027779\"/>\n      <Kern code=\"1113\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1091\" width=\"0.461113\" height=\"0.444445\" depth=\"0.194445\" italic=\"0.013888\" >\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.055555\"/>\n      <Kern code=\"1083\" val=\"-0.055555\"/>\n      <Kern code=\"1113\" val=\"-0.055555\"/>\n   </Char>\n   <Char code=\"1074\" width=\"0.480557\" height=\"0.444445\" />\n   <Char code=\"1097\" width=\"0.7777815\" height=\"0.444445\" depth=\"0.162038\" />\n   <Char code=\"1096\" width=\"0.76667\" height=\"0.444445\" >\n      <Lig code=\"1095\" ligCode=\"1097\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1099\" width=\"0.683336\" height=\"0.444445\" >\n      <Lig code=\"1072\" ligCode=\"1103\"/>\n      <Lig code=\"1091\" ligCode=\"1102\"/>\n   </Char>\n   <Char code=\"1079\" width=\"0.444446\" height=\"0.444445\" italic=\"0.002777\" >\n      <Lig code=\"1093\" ligCode=\"1078\"/>\n   </Char>\n   <Char code=\"1100\" width=\"0.480557\" height=\"0.444445\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1098\" width=\"0.590279\" height=\"0.444445\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n</Font>\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/cyrillic/wnssbx10.xml",
    "content": "<Font name=\"wnssbx10.ttf\" id=\"wnssbx10\" space=\"0.366669\" xHeight=\"0.458333\" quad=\"1.100006\" unicode=\"95\" romanVersion=\"wnbx10\" ttVersion=\"wntt10\">\n   <Char code=\"1034\" width=\"1.115285\" height=\"0.694445\" >\n      <Kern code=\"1046\" val=\"-0.030556\"/>\n      <Kern code=\"1061\" val=\"-0.030556\"/>\n      <Kern code=\"1054\" val=\"-0.030556\"/>\n      <Kern code=\"1060\" val=\"-0.030556\"/>\n      <Kern code=\"1138\" val=\"-0.030556\"/>\n      <Kern code=\"1057\" val=\"-0.030556\"/>\n      <Kern code=\"1028\" val=\"-0.030556\"/>\n      <Kern code=\"1058\" val=\"-0.091667\"/>\n      <Kern code=\"1066\" val=\"-0.091667\"/>\n      <Kern code=\"1026\" val=\"-0.091667\"/>\n      <Kern code=\"1035\" val=\"-0.091667\"/>\n      <Kern code=\"1122\" val=\"-0.091667\"/>\n      <Kern code=\"1063\" val=\"-0.091667\"/>\n      <Kern code=\"1059\" val=\"-0.030556\"/>\n      <Kern code=\"1140\" val=\"-0.091667\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.091667\"/>\n   </Char>\n   <Char code=\"1033\" width=\"1.15834\" height=\"0.694445\" >\n      <Kern code=\"1046\" val=\"-0.030556\"/>\n      <Kern code=\"1061\" val=\"-0.030556\"/>\n      <Kern code=\"1054\" val=\"-0.030556\"/>\n      <Kern code=\"1060\" val=\"-0.030556\"/>\n      <Kern code=\"1138\" val=\"-0.030556\"/>\n      <Kern code=\"1057\" val=\"-0.030556\"/>\n      <Kern code=\"1028\" val=\"-0.030556\"/>\n      <Kern code=\"1058\" val=\"-0.091667\"/>\n      <Kern code=\"1066\" val=\"-0.091667\"/>\n      <Kern code=\"1026\" val=\"-0.091667\"/>\n      <Kern code=\"1035\" val=\"-0.091667\"/>\n      <Kern code=\"1122\" val=\"-0.091667\"/>\n      <Kern code=\"1063\" val=\"-0.091667\"/>\n      <Kern code=\"1059\" val=\"-0.030556\"/>\n      <Kern code=\"1140\" val=\"-0.091667\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.091667\"/>\n   </Char>\n   <Char code=\"1039\" width=\"0.763893\" height=\"0.694445\" depth=\"0.194445\" />\n   <Char code=\"1069\" width=\"0.702782\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.030556\"/>\n      <Kern code=\"1044\" val=\"-0.030556\"/>\n      <Kern code=\"1046\" val=\"-0.030556\"/>\n      <Kern code=\"1061\" val=\"-0.030556\"/>\n      <Kern code=\"1059\" val=\"-0.030556\"/>\n      <Kern code=\"1140\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1030\" width=\"0.330557\" height=\"0.694445\" >\n      <Kern code=\"1030\" val=\"0.030556\"/>\n   </Char>\n   <Char code=\"1028\" width=\"0.702782\" height=\"0.694445\" />\n   <Char code=\"1026\" width=\"0.886116\" height=\"0.694445\" >\n      <Kern code=\"1046\" val=\"-0.030556\"/>\n      <Kern code=\"1061\" val=\"-0.030556\"/>\n      <Kern code=\"1054\" val=\"-0.030556\"/>\n      <Kern code=\"1060\" val=\"-0.030556\"/>\n      <Kern code=\"1138\" val=\"-0.030556\"/>\n      <Kern code=\"1057\" val=\"-0.030556\"/>\n      <Kern code=\"1028\" val=\"-0.030556\"/>\n      <Kern code=\"1058\" val=\"-0.091667\"/>\n      <Kern code=\"1066\" val=\"-0.091667\"/>\n      <Kern code=\"1026\" val=\"-0.091667\"/>\n      <Kern code=\"1035\" val=\"-0.091667\"/>\n      <Kern code=\"1122\" val=\"-0.091667\"/>\n      <Kern code=\"1063\" val=\"-0.091667\"/>\n      <Kern code=\"1059\" val=\"-0.030556\"/>\n      <Kern code=\"1140\" val=\"-0.091667\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.091667\"/>\n   </Char>\n   <Char code=\"1035\" width=\"0.840283\" height=\"0.694445\" />\n   <Char code=\"1114\" width=\"0.845839\" height=\"0.458333\" >\n      <Kern code=\"1091\" val=\"-0.061111\"/>\n      <Kern code=\"1141\" val=\"-0.061111\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.091667\"/>\n      <Kern code=\"1086\" val=\"-0.030556\"/>\n      <Kern code=\"1139\" val=\"-0.030556\"/>\n      <Kern code=\"1092\" val=\"-0.030556\"/>\n      <Kern code=\"1108\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1113\" width=\"0.852783\" height=\"0.458333\" >\n      <Kern code=\"1091\" val=\"-0.061111\"/>\n      <Kern code=\"1141\" val=\"-0.061111\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.091667\"/>\n      <Kern code=\"1086\" val=\"-0.030556\"/>\n      <Kern code=\"1139\" val=\"-0.030556\"/>\n      <Kern code=\"1092\" val=\"-0.030556\"/>\n      <Kern code=\"1108\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1119\" width=\"0.59167\" height=\"0.458333\" depth=\"0.162038\" />\n   <Char code=\"1101\" width=\"0.488892\" height=\"0.458333\" >\n      <Kern code=\"1076\" val=\"-0.030556\"/>\n      <Kern code=\"1078\" val=\"-0.030556\"/>\n      <Kern code=\"1093\" val=\"-0.030556\"/>\n      <Kern code=\"1103\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1110\" width=\"0.255557\" height=\"0.694445\" />\n   <Char code=\"1108\" width=\"0.48278\" height=\"0.458333\" />\n   <Char code=\"1106\" width=\"0.530559\" height=\"0.694445\" depth=\"0.194445\" />\n   <Char code=\"1115\" width=\"0.561114\" height=\"0.694445\" />\n   <Char code=\"1070\" width=\"1.143062\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.030556\"/>\n      <Kern code=\"1044\" val=\"-0.030556\"/>\n      <Kern code=\"1046\" val=\"-0.030556\"/>\n      <Kern code=\"1061\" val=\"-0.030556\"/>\n      <Kern code=\"1059\" val=\"-0.030556\"/>\n      <Kern code=\"1140\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1046\" width=\"1.214895\" height=\"0.694445\" >\n      <Kern code=\"1054\" val=\"-0.030556\"/>\n      <Kern code=\"1060\" val=\"-0.030556\"/>\n      <Kern code=\"1138\" val=\"-0.030556\"/>\n      <Kern code=\"1057\" val=\"-0.030556\"/>\n      <Kern code=\"1028\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.030556\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1049\" width=\"0.763893\" height=\"0.902727\" />\n   <Char code=\"1025\" width=\"0.64167\" height=\"0.902727\" />\n   <Char code=\"1140\" width=\"0.794449\" height=\"0.694445\" italic=\"0.015279\" >\n      <Kern code=\"1040\" val=\"-0.091667\"/>\n      <Kern code=\"1044\" val=\"-0.061111\"/>\n      <Kern code=\"1051\" val=\"-0.061111\"/>\n      <Kern code=\"1033\" val=\"-0.061111\"/>\n      <Kern code=\"1054\" val=\"-0.030556\"/>\n      <Kern code=\"1060\" val=\"-0.030556\"/>\n      <Kern code=\"1138\" val=\"-0.030556\"/>\n      <Kern code=\"1057\" val=\"-0.030556\"/>\n      <Kern code=\"1028\" val=\"-0.030556\"/>\n      <Kern code=\"1072\" val=\"-0.030556\"/>\n      <Kern code=\"1086\" val=\"-0.030556\"/>\n      <Kern code=\"1139\" val=\"-0.030556\"/>\n      <Kern code=\"1077\" val=\"-0.030556\"/>\n      <Kern code=\"1105\" val=\"-0.030556\"/>\n      <Kern code=\"1076\" val=\"-0.091667\"/>\n      <Kern code=\"1083\" val=\"-0.091667\"/>\n      <Kern code=\"1113\" val=\"-0.091667\"/>\n      <Kern code=\"1103\" val=\"-0.091667\"/>\n   </Char>\n   <Char code=\"1138\" width=\"0.85556\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.030556\"/>\n      <Kern code=\"1044\" val=\"-0.030556\"/>\n      <Kern code=\"1046\" val=\"-0.030556\"/>\n      <Kern code=\"1061\" val=\"-0.030556\"/>\n      <Kern code=\"1059\" val=\"-0.030556\"/>\n      <Kern code=\"1140\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1029\" width=\"0.6111145\" height=\"0.694445\" />\n   <Char code=\"1071\" width=\"0.702782\" height=\"0.694445\" />\n   <Char code=\"1102\" width=\"0.800005\" height=\"0.458333\" >\n      <Kern code=\"1076\" val=\"-0.030556\"/>\n      <Kern code=\"1078\" val=\"-0.030556\"/>\n      <Kern code=\"1093\" val=\"-0.030556\"/>\n      <Kern code=\"1103\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1078\" width=\"0.80556\" height=\"0.458333\" >\n      <Kern code=\"1072\" val=\"-0.030556\"/>\n      <Kern code=\"1086\" val=\"-0.030556\"/>\n      <Kern code=\"1139\" val=\"-0.030556\"/>\n      <Kern code=\"1089\" val=\"-0.030556\"/>\n      <Kern code=\"1108\" val=\"-0.030556\"/>\n      <Kern code=\"1077\" val=\"-0.030556\"/>\n      <Kern code=\"1105\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1081\" width=\"0.59167\" height=\"0.6666155\" />\n   <Char code=\"1105\" width=\"0.511114\" height=\"0.694445\" />\n   <Char code=\"1141\" width=\"0.562503\" height=\"0.458333\" italic=\"0.015279\" >\n      <Kern code=\"1072\" val=\"-0.030556\"/>\n      <Kern code=\"1086\" val=\"-0.030556\"/>\n      <Kern code=\"1139\" val=\"-0.030556\"/>\n      <Kern code=\"1089\" val=\"-0.030556\"/>\n      <Kern code=\"1108\" val=\"-0.030556\"/>\n      <Kern code=\"1077\" val=\"-0.030556\"/>\n      <Kern code=\"1105\" val=\"-0.030556\"/>\n      <Kern code=\"1103\" val=\"-0.030556\"/>\n      <Kern code=\"1076\" val=\"-0.061111\"/>\n      <Kern code=\"1083\" val=\"-0.061111\"/>\n      <Kern code=\"1113\" val=\"-0.061111\"/>\n   </Char>\n   <Char code=\"1139\" width=\"0.550003\" height=\"0.458333\" >\n      <Kern code=\"1076\" val=\"-0.030556\"/>\n      <Kern code=\"1078\" val=\"-0.030556\"/>\n      <Kern code=\"1093\" val=\"-0.030556\"/>\n      <Kern code=\"1103\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1109\" width=\"0.421669\" height=\"0.458333\" />\n   <Char code=\"1103\" width=\"0.555559\" height=\"0.458333\" />\n   <Char code=\"776\" width=\"0.550003\" height=\"0.694445\" />\n   <Char code=\"1122\" width=\"0.85556\" height=\"0.75\" >\n      <Kern code=\"1046\" val=\"-0.030556\"/>\n      <Kern code=\"1061\" val=\"-0.030556\"/>\n      <Kern code=\"1054\" val=\"-0.030556\"/>\n      <Kern code=\"1060\" val=\"-0.030556\"/>\n      <Kern code=\"1138\" val=\"-0.030556\"/>\n      <Kern code=\"1057\" val=\"-0.030556\"/>\n      <Kern code=\"1028\" val=\"-0.030556\"/>\n      <Kern code=\"1058\" val=\"-0.091667\"/>\n      <Kern code=\"1066\" val=\"-0.091667\"/>\n      <Kern code=\"1026\" val=\"-0.091667\"/>\n      <Kern code=\"1035\" val=\"-0.091667\"/>\n      <Kern code=\"1122\" val=\"-0.091667\"/>\n      <Kern code=\"1063\" val=\"-0.091667\"/>\n      <Kern code=\"1059\" val=\"-0.030556\"/>\n      <Kern code=\"1140\" val=\"-0.091667\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.091667\"/>\n   </Char>\n   <Char code=\"774\" width=\"0.550003\" height=\"0.6666155\" />\n   <Char code=\"1123\" width=\"0.550003\" height=\"0.6666155\" >\n      <Kern code=\"1091\" val=\"-0.061111\"/>\n      <Kern code=\"1141\" val=\"-0.061111\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.091667\"/>\n      <Kern code=\"1086\" val=\"-0.030556\"/>\n      <Kern code=\"1139\" val=\"-0.030556\"/>\n      <Kern code=\"1092\" val=\"-0.030556\"/>\n      <Kern code=\"1108\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"171\" width=\"0.733337\" height=\"0.5\" />\n   <Char code=\"305\" width=\"0.255557\" height=\"0.458333\" />\n   <Char code=\"187\" width=\"0.733337\" height=\"0.5\" />\n   <Char code=\"1040\" width=\"0.733337\" height=\"0.694445\" >\n      <Kern code=\"1054\" val=\"-0.030556\"/>\n      <Kern code=\"1060\" val=\"-0.030556\"/>\n      <Kern code=\"1138\" val=\"-0.030556\"/>\n      <Kern code=\"1057\" val=\"-0.030556\"/>\n      <Kern code=\"1028\" val=\"-0.030556\"/>\n      <Kern code=\"1058\" val=\"-0.091667\"/>\n      <Kern code=\"1066\" val=\"-0.091667\"/>\n      <Kern code=\"1026\" val=\"-0.091667\"/>\n      <Kern code=\"1035\" val=\"-0.091667\"/>\n      <Kern code=\"1122\" val=\"-0.091667\"/>\n      <Kern code=\"1063\" val=\"-0.091667\"/>\n      <Kern code=\"1059\" val=\"-0.030556\"/>\n      <Kern code=\"1140\" val=\"-0.091667\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.091667\"/>\n   </Char>\n   <Char code=\"1041\" width=\"0.733337\" height=\"0.694445\" />\n   <Char code=\"1062\" width=\"0.806949\" height=\"0.694445\" depth=\"0.194445\" >\n      <Lig code=\"1061\" ligCode=\"1063\"/>\n      <Lig code=\"1093\" ligCode=\"1063\"/>\n   </Char>\n   <Char code=\"1044\" width=\"0.850004\" height=\"0.694445\" depth=\"0.194445\" >\n      <Lig code=\"1032\" ligCode=\"1026\"/>\n      <Lig code=\"1112\" ligCode=\"1026\"/>\n   </Char>\n   <Char code=\"1045\" width=\"0.64167\" height=\"0.694445\" >\n   </Char>\n   <Char code=\"1060\" width=\"0.916672\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.030556\"/>\n      <Kern code=\"1044\" val=\"-0.030556\"/>\n      <Kern code=\"1046\" val=\"-0.030556\"/>\n      <Kern code=\"1061\" val=\"-0.030556\"/>\n      <Kern code=\"1059\" val=\"-0.030556\"/>\n      <Kern code=\"1140\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1043\" width=\"0.580559\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.091667\"/>\n      <Kern code=\"1044\" val=\"-0.091667\"/>\n      <Kern code=\"1051\" val=\"-0.061111\"/>\n      <Kern code=\"1033\" val=\"-0.061111\"/>\n      <Kern code=\"1072\" val=\"-0.091667\"/>\n      <Kern code=\"1086\" val=\"-0.091667\"/>\n      <Kern code=\"1139\" val=\"-0.091667\"/>\n      <Kern code=\"1077\" val=\"-0.091667\"/>\n      <Kern code=\"1105\" val=\"-0.091667\"/>\n      <Kern code=\"1089\" val=\"-0.091667\"/>\n      <Kern code=\"1108\" val=\"-0.091667\"/>\n      <Kern code=\"1092\" val=\"-0.091667\"/>\n      <Kern code=\"1076\" val=\"-0.091667\"/>\n      <Kern code=\"1083\" val=\"-0.091667\"/>\n      <Kern code=\"1113\" val=\"-0.091667\"/>\n      <Kern code=\"1103\" val=\"-0.091667\"/>\n   </Char>\n   <Char code=\"1061\" width=\"0.733337\" height=\"0.694445\" >\n      <Kern code=\"1054\" val=\"-0.030556\"/>\n      <Kern code=\"1060\" val=\"-0.030556\"/>\n      <Kern code=\"1138\" val=\"-0.030556\"/>\n      <Kern code=\"1057\" val=\"-0.030556\"/>\n      <Kern code=\"1028\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.030556\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1048\" width=\"0.763893\" height=\"0.694445\" >\n   </Char>\n   <Char code=\"1032\" width=\"0.519447\" height=\"0.694445\" >\n   </Char>\n   <Char code=\"1050\" width=\"0.763893\" height=\"0.694445\" >\n      <Lig code=\"1061\" ligCode=\"1061\"/>\n      <Lig code=\"1093\" ligCode=\"1061\"/>\n      <Kern code=\"1054\" val=\"-0.030556\"/>\n      <Kern code=\"1060\" val=\"-0.030556\"/>\n      <Kern code=\"1138\" val=\"-0.030556\"/>\n      <Kern code=\"1057\" val=\"-0.030556\"/>\n      <Kern code=\"1028\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.030556\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1051\" width=\"0.806949\" height=\"0.694445\" >\n      <Lig code=\"1032\" ligCode=\"1033\"/>\n      <Lig code=\"1112\" ligCode=\"1033\"/>\n   </Char>\n   <Char code=\"1052\" width=\"0.977783\" height=\"0.694445\" />\n   <Char code=\"1053\" width=\"0.763893\" height=\"0.694445\" >\n      <Lig code=\"1032\" ligCode=\"1034\"/>\n      <Lig code=\"1112\" ligCode=\"1034\"/>\n   </Char>\n   <Char code=\"1054\" width=\"0.794449\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.030556\"/>\n      <Kern code=\"1044\" val=\"-0.030556\"/>\n      <Kern code=\"1046\" val=\"-0.030556\"/>\n      <Kern code=\"1061\" val=\"-0.030556\"/>\n      <Kern code=\"1059\" val=\"-0.030556\"/>\n      <Kern code=\"1140\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1055\" width=\"0.763893\" height=\"0.694445\" >\n   </Char>\n   <Char code=\"1063\" width=\"0.763893\" height=\"0.694445\" />\n   <Char code=\"1056\" width=\"0.702782\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.091667\"/>\n      <Kern code=\"1044\" val=\"-0.091667\"/>\n      <Kern code=\"1051\" val=\"-0.091667\"/>\n      <Kern code=\"1033\" val=\"-0.091667\"/>\n      <Kern code=\"1072\" val=\"-0.030556\"/>\n      <Kern code=\"1086\" val=\"-0.030556\"/>\n      <Kern code=\"1139\" val=\"-0.030556\"/>\n      <Kern code=\"1077\" val=\"-0.030556\"/>\n      <Kern code=\"1105\" val=\"-0.030556\"/>\n      <Kern code=\"1076\" val=\"-0.091667\"/>\n      <Kern code=\"1083\" val=\"-0.091667\"/>\n      <Kern code=\"1113\" val=\"-0.091667\"/>\n   </Char>\n   <Char code=\"1057\" width=\"0.702782\" height=\"0.694445\" >\n      <Lig code=\"1061\" ligCode=\"1064\"/>\n      <Lig code=\"1093\" ligCode=\"1064\"/>\n   </Char>\n   <Char code=\"1058\" width=\"0.733337\" height=\"0.694445\" >\n      <Lig code=\"1057\" ligCode=\"1062\"/>\n      <Lig code=\"1089\" ligCode=\"1062\"/>\n      <Kern code=\"1040\" val=\"-0.091667\"/>\n      <Kern code=\"1044\" val=\"-0.091667\"/>\n      <Kern code=\"1051\" val=\"-0.061111\"/>\n      <Kern code=\"1033\" val=\"-0.061111\"/>\n      <Kern code=\"1072\" val=\"-0.091667\"/>\n      <Kern code=\"1086\" val=\"-0.091667\"/>\n      <Kern code=\"1139\" val=\"-0.091667\"/>\n      <Kern code=\"1077\" val=\"-0.091667\"/>\n      <Kern code=\"1105\" val=\"-0.091667\"/>\n      <Kern code=\"1089\" val=\"-0.091667\"/>\n      <Kern code=\"1108\" val=\"-0.091667\"/>\n      <Kern code=\"1092\" val=\"-0.091667\"/>\n      <Kern code=\"1076\" val=\"-0.091667\"/>\n      <Kern code=\"1083\" val=\"-0.091667\"/>\n      <Kern code=\"1113\" val=\"-0.091667\"/>\n      <Kern code=\"1103\" val=\"-0.091667\"/>\n   </Char>\n   <Char code=\"1059\" width=\"0.733337\" height=\"0.694445\" italic=\"0.015279\" >\n      <Kern code=\"1040\" val=\"-0.030556\"/>\n      <Kern code=\"1044\" val=\"-0.061111\"/>\n      <Kern code=\"1051\" val=\"-0.061111\"/>\n      <Kern code=\"1033\" val=\"-0.061111\"/>\n      <Kern code=\"1054\" val=\"-0.030556\"/>\n      <Kern code=\"1060\" val=\"-0.030556\"/>\n      <Kern code=\"1138\" val=\"-0.030556\"/>\n      <Kern code=\"1057\" val=\"-0.030556\"/>\n      <Kern code=\"1028\" val=\"-0.030556\"/>\n      <Kern code=\"1072\" val=\"-0.030556\"/>\n      <Kern code=\"1086\" val=\"-0.030556\"/>\n      <Kern code=\"1139\" val=\"-0.030556\"/>\n      <Kern code=\"1077\" val=\"-0.030556\"/>\n      <Kern code=\"1105\" val=\"-0.030556\"/>\n      <Kern code=\"1089\" val=\"-0.030556\"/>\n      <Kern code=\"1108\" val=\"-0.030556\"/>\n      <Kern code=\"1076\" val=\"-0.091667\"/>\n      <Kern code=\"1083\" val=\"-0.091667\"/>\n      <Kern code=\"1113\" val=\"-0.091667\"/>\n      <Kern code=\"1103\" val=\"-0.091667\"/>\n   </Char>\n   <Char code=\"1042\" width=\"0.733337\" height=\"0.694445\" />\n   <Char code=\"1065\" width=\"1.250008\" height=\"0.694445\" depth=\"0.194445\" />\n   <Char code=\"1064\" width=\"1.206952\" height=\"0.694445\" >\n      <Lig code=\"1063\" ligCode=\"1065\"/>\n      <Lig code=\"1095\" ligCode=\"1065\"/>\n      <Lig code=\"1062\" ligCode=\"0\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1067\" width=\"0.977783\" height=\"0.694445\" >\n      <Lig code=\"1040\" ligCode=\"1071\"/>\n      <Lig code=\"1072\" ligCode=\"1071\"/>\n      <Lig code=\"1059\" ligCode=\"1070\"/>\n      <Lig code=\"1091\" ligCode=\"1070\"/>\n   </Char>\n   <Char code=\"1047\" width=\"0.672226\" height=\"0.694445\" >\n      <Lig code=\"1061\" ligCode=\"1046\"/>\n      <Lig code=\"1093\" ligCode=\"1046\"/>\n   </Char>\n   <Char code=\"1068\" width=\"0.733337\" height=\"0.694445\" >\n      <Kern code=\"1046\" val=\"-0.030556\"/>\n      <Kern code=\"1061\" val=\"-0.030556\"/>\n      <Kern code=\"1054\" val=\"-0.030556\"/>\n      <Kern code=\"1060\" val=\"-0.030556\"/>\n      <Kern code=\"1138\" val=\"-0.030556\"/>\n      <Kern code=\"1057\" val=\"-0.030556\"/>\n      <Kern code=\"1028\" val=\"-0.030556\"/>\n      <Kern code=\"1058\" val=\"-0.091667\"/>\n      <Kern code=\"1066\" val=\"-0.091667\"/>\n      <Kern code=\"1026\" val=\"-0.091667\"/>\n      <Kern code=\"1035\" val=\"-0.091667\"/>\n      <Kern code=\"1122\" val=\"-0.091667\"/>\n      <Kern code=\"1063\" val=\"-0.091667\"/>\n      <Kern code=\"1059\" val=\"-0.030556\"/>\n      <Kern code=\"1140\" val=\"-0.091667\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.091667\"/>\n   </Char>\n   <Char code=\"1066\" width=\"0.940283\" height=\"0.694445\" >\n      <Kern code=\"1046\" val=\"-0.030556\"/>\n      <Kern code=\"1061\" val=\"-0.030556\"/>\n      <Kern code=\"1054\" val=\"-0.030556\"/>\n      <Kern code=\"1060\" val=\"-0.030556\"/>\n      <Kern code=\"1138\" val=\"-0.030556\"/>\n      <Kern code=\"1057\" val=\"-0.030556\"/>\n      <Kern code=\"1028\" val=\"-0.030556\"/>\n      <Kern code=\"1058\" val=\"-0.091667\"/>\n      <Kern code=\"1066\" val=\"-0.091667\"/>\n      <Kern code=\"1026\" val=\"-0.091667\"/>\n      <Kern code=\"1035\" val=\"-0.091667\"/>\n      <Kern code=\"1122\" val=\"-0.091667\"/>\n      <Kern code=\"1063\" val=\"-0.091667\"/>\n      <Kern code=\"1059\" val=\"-0.030556\"/>\n      <Kern code=\"1140\" val=\"-0.091667\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.091667\"/>\n   </Char>\n   <Char code=\"1072\" width=\"0.525003\" height=\"0.458333\" >\n      <Kern code=\"1095\" val=\"-0.030556\"/>\n      <Kern code=\"1091\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1073\" width=\"0.550003\" height=\"0.694445\" >\n      <Kern code=\"1076\" val=\"-0.030556\"/>\n      <Kern code=\"1078\" val=\"-0.030556\"/>\n      <Kern code=\"1093\" val=\"-0.030556\"/>\n      <Kern code=\"1103\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1094\" width=\"0.62917\" height=\"0.458333\" depth=\"0.162038\" >\n      <Lig code=\"1093\" ligCode=\"1095\"/>\n   </Char>\n   <Char code=\"1076\" width=\"0.636114\" height=\"0.458333\" depth=\"0.162038\" >\n      <Lig code=\"1112\" ligCode=\"1106\"/>\n   </Char>\n   <Char code=\"1077\" width=\"0.511114\" height=\"0.458333\" >\n   </Char>\n   <Char code=\"1092\" width=\"0.836118\" height=\"0.694445\" depth=\"0.194445\" >\n      <Kern code=\"1076\" val=\"-0.030556\"/>\n      <Kern code=\"1078\" val=\"-0.030556\"/>\n      <Kern code=\"1093\" val=\"-0.030556\"/>\n      <Kern code=\"1103\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1075\" width=\"0.433336\" height=\"0.458333\" italic=\"0.015279\" >\n      <Kern code=\"1076\" val=\"-0.030556\"/>\n      <Kern code=\"1083\" val=\"-0.030556\"/>\n      <Kern code=\"1113\" val=\"-0.030556\"/>\n      <Kern code=\"1103\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1093\" width=\"0.500003\" height=\"0.458333\" >\n      <Kern code=\"1072\" val=\"-0.030556\"/>\n      <Kern code=\"1086\" val=\"-0.030556\"/>\n      <Kern code=\"1139\" val=\"-0.030556\"/>\n      <Kern code=\"1089\" val=\"-0.030556\"/>\n      <Kern code=\"1108\" val=\"-0.030556\"/>\n      <Kern code=\"1077\" val=\"-0.030556\"/>\n      <Kern code=\"1105\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1080\" width=\"0.59167\" height=\"0.458333\" >\n   </Char>\n   <Char code=\"1112\" width=\"0.286113\" height=\"0.694445\" depth=\"0.194445\" >\n   </Char>\n   <Char code=\"1082\" width=\"0.530559\" height=\"0.458333\" >\n      <Lig code=\"1093\" ligCode=\"1093\"/>\n      <Kern code=\"1072\" val=\"-0.030556\"/>\n      <Kern code=\"1086\" val=\"-0.030556\"/>\n      <Kern code=\"1139\" val=\"-0.030556\"/>\n      <Kern code=\"1089\" val=\"-0.030556\"/>\n      <Kern code=\"1108\" val=\"-0.030556\"/>\n      <Kern code=\"1077\" val=\"-0.030556\"/>\n      <Kern code=\"1105\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1083\" width=\"0.598615\" height=\"0.458333\" >\n      <Lig code=\"1112\" ligCode=\"1113\"/>\n   </Char>\n   <Char code=\"1084\" width=\"0.744449\" height=\"0.458333\" />\n   <Char code=\"1085\" width=\"0.561114\" height=\"0.458333\" >\n      <Lig code=\"1112\" ligCode=\"1114\"/>\n   </Char>\n   <Char code=\"1086\" width=\"0.550003\" height=\"0.458333\" >\n      <Kern code=\"1076\" val=\"-0.030556\"/>\n      <Kern code=\"1078\" val=\"-0.030556\"/>\n      <Kern code=\"1093\" val=\"-0.030556\"/>\n      <Kern code=\"1103\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1087\" width=\"0.561114\" height=\"0.458333\" >\n   </Char>\n   <Char code=\"1095\" width=\"0.59167\" height=\"0.458333\" />\n   <Char code=\"1088\" width=\"0.561114\" height=\"0.458333\" depth=\"0.194445\" >\n      <Kern code=\"1076\" val=\"-0.030556\"/>\n      <Kern code=\"1078\" val=\"-0.030556\"/>\n      <Kern code=\"1093\" val=\"-0.030556\"/>\n      <Kern code=\"1103\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1089\" width=\"0.488892\" height=\"0.458333\" >\n      <Lig code=\"1093\" ligCode=\"1096\"/>\n      <Kern code=\"1076\" val=\"-0.030556\"/>\n      <Kern code=\"1078\" val=\"-0.030556\"/>\n      <Kern code=\"1093\" val=\"-0.030556\"/>\n      <Kern code=\"1103\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1090\" width=\"0.488892\" height=\"0.458333\" italic=\"0.02139\" >\n      <Lig code=\"1089\" ligCode=\"1094\"/>\n      <Kern code=\"1076\" val=\"-0.030556\"/>\n      <Kern code=\"1083\" val=\"-0.030556\"/>\n      <Kern code=\"1113\" val=\"-0.030556\"/>\n      <Kern code=\"1103\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1091\" width=\"0.500003\" height=\"0.458333\" depth=\"0.194445\" italic=\"0.015279\" >\n      <Kern code=\"1072\" val=\"-0.030556\"/>\n      <Kern code=\"1086\" val=\"-0.030556\"/>\n      <Kern code=\"1139\" val=\"-0.030556\"/>\n      <Kern code=\"1089\" val=\"-0.030556\"/>\n      <Kern code=\"1108\" val=\"-0.030556\"/>\n      <Kern code=\"1077\" val=\"-0.030556\"/>\n      <Kern code=\"1105\" val=\"-0.030556\"/>\n      <Kern code=\"1103\" val=\"-0.030556\"/>\n      <Kern code=\"1076\" val=\"-0.061111\"/>\n      <Kern code=\"1083\" val=\"-0.061111\"/>\n      <Kern code=\"1113\" val=\"-0.061111\"/>\n   </Char>\n   <Char code=\"1074\" width=\"0.525003\" height=\"0.458333\" />\n   <Char code=\"1097\" width=\"0.873616\" height=\"0.458333\" depth=\"0.162038\" />\n   <Char code=\"1096\" width=\"0.836116\" height=\"0.458333\" >\n      <Lig code=\"1095\" ligCode=\"1097\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1099\" width=\"0.744449\" height=\"0.458333\" >\n      <Lig code=\"1072\" ligCode=\"1103\"/>\n      <Lig code=\"1091\" ligCode=\"1102\"/>\n   </Char>\n   <Char code=\"1079\" width=\"0.488892\" height=\"0.458333\" italic=\"0.006111\" >\n      <Lig code=\"1093\" ligCode=\"1078\"/>\n   </Char>\n   <Char code=\"1100\" width=\"0.525003\" height=\"0.458333\" >\n      <Kern code=\"1091\" val=\"-0.061111\"/>\n      <Kern code=\"1141\" val=\"-0.061111\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.091667\"/>\n      <Kern code=\"1086\" val=\"-0.030556\"/>\n      <Kern code=\"1139\" val=\"-0.030556\"/>\n      <Kern code=\"1092\" val=\"-0.030556\"/>\n      <Kern code=\"1108\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1098\" width=\"0.64167\" height=\"0.458333\" >\n      <Kern code=\"1091\" val=\"-0.061111\"/>\n      <Kern code=\"1141\" val=\"-0.061111\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.091667\"/>\n      <Kern code=\"1086\" val=\"-0.030556\"/>\n      <Kern code=\"1139\" val=\"-0.030556\"/>\n      <Kern code=\"1092\" val=\"-0.030556\"/>\n      <Kern code=\"1108\" val=\"-0.030556\"/>\n   </Char>\n</Font>\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/cyrillic/wnssi10.xml",
    "content": "<Font name=\"wnssi10.ttf\" id=\"wnssi10\" space=\"0.333334\" xHeight=\"0.444445\" quad=\"1.000003\" unicode=\"95\" romanVersion=\"wnti10\" ttVersion=\"wntt10\" boldVersion=\"wnssbx10\">\n   <Char code=\"1034\" width=\"1.020838\" height=\"0.694445\" italic=\"0.02595\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1033\" width=\"1.037504\" height=\"0.694445\" italic=\"0.02595\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1039\" width=\"0.694448\" height=\"0.694445\" depth=\"0.194445\" italic=\"0.080938\" />\n   <Char code=\"1069\" width=\"0.638891\" height=\"0.694445\" italic=\"0.075546\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1030\" width=\"0.277781\" height=\"0.694445\" italic=\"0.1337185\" >\n      <Kern code=\"1030\" val=\"0.027779\"/>\n   </Char>\n   <Char code=\"1028\" width=\"0.638891\" height=\"0.694445\" italic=\"0.119829\" />\n   <Char code=\"1026\" width=\"0.8194475\" height=\"0.694445\" italic=\"0.1337185\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1035\" width=\"0.763891\" height=\"0.694445\" italic=\"0.0920515\" />\n   <Char code=\"1114\" width=\"0.765282\" height=\"0.444445\" italic=\"0.0389\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1113\" width=\"0.755559\" height=\"0.444445\" italic=\"0.0389\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1119\" width=\"0.537503\" height=\"0.444445\" depth=\"0.162038\" italic=\"0.04169\" />\n   <Char code=\"1101\" width=\"0.444446\" height=\"0.444445\" italic=\"0.060573\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1110\" width=\"0.23889\" height=\"0.679365\" italic=\"0.09718\" />\n   <Char code=\"1108\" width=\"0.43889\" height=\"0.444445\" italic=\"0.083357\" />\n   <Char code=\"1106\" width=\"0.488892\" height=\"0.694445\" depth=\"0.194445\" italic=\"0.066129\" />\n   <Char code=\"1115\" width=\"0.516668\" height=\"0.694445\" italic=\"0.017778\" />\n   <Char code=\"1070\" width=\"1.04167\" height=\"0.694445\" italic=\"0.075546\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1046\" width=\"1.111117\" height=\"0.694445\" italic=\"0.119829\" >\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.027779\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1049\" width=\"0.694448\" height=\"0.902727\" italic=\"0.080938\" />\n   <Char code=\"1025\" width=\"0.597224\" height=\"0.902727\" italic=\"0.119829\" />\n   <Char code=\"1140\" width=\"0.722226\" height=\"0.694445\" italic=\"0.161496\" >\n      <Kern code=\"1040\" val=\"-0.083334\"/>\n      <Kern code=\"1044\" val=\"-0.055555\"/>\n      <Kern code=\"1051\" val=\"-0.055555\"/>\n      <Kern code=\"1033\" val=\"-0.055555\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n      <Kern code=\"1103\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1138\" width=\"0.777781\" height=\"0.694445\" italic=\"0.075546\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1029\" width=\"0.555557\" height=\"0.694445\" italic=\"0.0920515\" />\n   <Char code=\"1071\" width=\"0.645836\" height=\"0.694445\" italic=\"0.080938\" />\n   <Char code=\"1102\" width=\"0.730558\" height=\"0.444445\" italic=\"0.066129\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1078\" width=\"0.7388935\" height=\"0.444445\" italic=\"0.083357\" >\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1081\" width=\"0.537503\" height=\"0.652727\" italic=\"0.04169\" />\n   <Char code=\"1105\" width=\"0.444446\" height=\"0.660319\" italic=\"0.067778\" />\n   <Char code=\"1141\" width=\"0.491667\" height=\"0.444445\" italic=\"0.108357\" >\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.055555\"/>\n      <Kern code=\"1083\" val=\"-0.055555\"/>\n      <Kern code=\"1113\" val=\"-0.055555\"/>\n   </Char>\n   <Char code=\"1139\" width=\"0.500002\" height=\"0.444445\" italic=\"0.03835\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1109\" width=\"0.383334\" height=\"0.444445\" italic=\"0.077802\" />\n   <Char code=\"1103\" width=\"0.515279\" height=\"0.444445\" italic=\"0.04169\" />\n   <Char code=\"776\" width=\"0.500002\" height=\"0.660319\" italic=\"0.059799\" />\n   <Char code=\"1122\" width=\"0.7777815\" height=\"0.75\" italic=\"0.082927\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"774\" width=\"0.500002\" height=\"0.652727\" italic=\"0.085962\" />\n   <Char code=\"1123\" width=\"0.500002\" height=\"0.652727\" italic=\"0.030568\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"171\" width=\"0.666669\" height=\"0.438889\" italic=\"0.02018\" />\n   <Char code=\"305\" width=\"0.23889\" height=\"0.444445\" italic=\"0.04169\" />\n   <Char code=\"187\" width=\"0.666669\" height=\"0.438889\" />\n   <Char code=\"1040\" width=\"0.66667\" height=\"0.694445\" >\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1041\" width=\"0.66667\" height=\"0.694445\" italic=\"0.064273\" />\n   <Char code=\"1062\" width=\"0.711116\" height=\"0.694445\" depth=\"0.194445\" italic=\"0.080938\" >\n      <Lig code=\"1061\" ligCode=\"1063\"/>\n      <Lig code=\"1093\" ligCode=\"1063\"/>\n   </Char>\n   <Char code=\"1044\" width=\"0.727783\" height=\"0.694445\" depth=\"0.194445\" italic=\"0.080938\" >\n      <Lig code=\"1032\" ligCode=\"1026\"/>\n      <Lig code=\"1112\" ligCode=\"1026\"/>\n   </Char>\n   <Char code=\"1045\" width=\"0.597224\" height=\"0.694445\" italic=\"0.119829\" >\n   </Char>\n   <Char code=\"1060\" width=\"0.833336\" height=\"0.694445\" italic=\"0.075546\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1043\" width=\"0.541669\" height=\"0.694445\" italic=\"0.1337185\" >\n      <Kern code=\"1040\" val=\"-0.083334\"/>\n      <Kern code=\"1044\" val=\"-0.083334\"/>\n      <Kern code=\"1051\" val=\"-0.055555\"/>\n      <Kern code=\"1033\" val=\"-0.055555\"/>\n      <Kern code=\"1072\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.083334\"/>\n      <Kern code=\"1139\" val=\"-0.083334\"/>\n      <Kern code=\"1077\" val=\"-0.083334\"/>\n      <Kern code=\"1105\" val=\"-0.083334\"/>\n      <Kern code=\"1089\" val=\"-0.083334\"/>\n      <Kern code=\"1108\" val=\"-0.083334\"/>\n      <Kern code=\"1092\" val=\"-0.083334\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n      <Kern code=\"1103\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1061\" width=\"0.66667\" height=\"0.694445\" italic=\"0.1337185\" >\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.027779\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1048\" width=\"0.694448\" height=\"0.694445\" italic=\"0.080938\" >\n   </Char>\n   <Char code=\"1032\" width=\"0.472224\" height=\"0.694445\" italic=\"0.080938\" >\n   </Char>\n   <Char code=\"1050\" width=\"0.694448\" height=\"0.694445\" italic=\"0.119829\" >\n      <Lig code=\"1061\" ligCode=\"1061\"/>\n      <Lig code=\"1093\" ligCode=\"1061\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.027779\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1051\" width=\"0.711116\" height=\"0.694445\" italic=\"0.080938\" >\n      <Lig code=\"1032\" ligCode=\"1033\"/>\n      <Lig code=\"1112\" ligCode=\"1033\"/>\n   </Char>\n   <Char code=\"1052\" width=\"0.875005\" height=\"0.694445\" italic=\"0.080938\" />\n   <Char code=\"1053\" width=\"0.694448\" height=\"0.694445\" italic=\"0.080938\" >\n      <Lig code=\"1032\" ligCode=\"1034\"/>\n      <Lig code=\"1112\" ligCode=\"1034\"/>\n   </Char>\n   <Char code=\"1054\" width=\"0.736113\" height=\"0.694445\" italic=\"0.075546\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1055\" width=\"0.694448\" height=\"0.694445\" italic=\"0.080938\" >\n   </Char>\n   <Char code=\"1063\" width=\"0.694448\" height=\"0.694445\" italic=\"0.080938\" />\n   <Char code=\"1056\" width=\"0.638891\" height=\"0.694445\" italic=\"0.082927\" >\n      <Kern code=\"1040\" val=\"-0.083334\"/>\n      <Kern code=\"1044\" val=\"-0.083334\"/>\n      <Kern code=\"1051\" val=\"-0.083334\"/>\n      <Kern code=\"1033\" val=\"-0.083334\"/>\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1057\" width=\"0.638891\" height=\"0.694445\" italic=\"0.119829\" >\n      <Lig code=\"1061\" ligCode=\"1064\"/>\n      <Lig code=\"1093\" ligCode=\"1064\"/>\n   </Char>\n   <Char code=\"1058\" width=\"0.680557\" height=\"0.694445\" italic=\"0.1337185\" >\n      <Lig code=\"1057\" ligCode=\"1062\"/>\n      <Lig code=\"1089\" ligCode=\"1062\"/>\n      <Kern code=\"1040\" val=\"-0.083334\"/>\n      <Kern code=\"1044\" val=\"-0.083334\"/>\n      <Kern code=\"1051\" val=\"-0.055555\"/>\n      <Kern code=\"1033\" val=\"-0.055555\"/>\n      <Kern code=\"1072\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.083334\"/>\n      <Kern code=\"1139\" val=\"-0.083334\"/>\n      <Kern code=\"1077\" val=\"-0.083334\"/>\n      <Kern code=\"1105\" val=\"-0.083334\"/>\n      <Kern code=\"1089\" val=\"-0.083334\"/>\n      <Kern code=\"1108\" val=\"-0.083334\"/>\n      <Kern code=\"1092\" val=\"-0.083334\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n      <Kern code=\"1103\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1059\" width=\"0.66667\" height=\"0.694445\" italic=\"0.161496\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.055555\"/>\n      <Kern code=\"1051\" val=\"-0.055555\"/>\n      <Kern code=\"1033\" val=\"-0.055555\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n      <Kern code=\"1103\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1042\" width=\"0.66667\" height=\"0.694445\" italic=\"0.05515\" />\n   <Char code=\"1065\" width=\"1.100006\" height=\"0.694445\" depth=\"0.194445\" italic=\"0.080938\" />\n   <Char code=\"1064\" width=\"1.083339\" height=\"0.694445\" italic=\"0.080938\" >\n      <Lig code=\"1063\" ligCode=\"1065\"/>\n      <Lig code=\"1095\" ligCode=\"1065\"/>\n      <Lig code=\"1062\" ligCode=\"0\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1067\" width=\"0.888895\" height=\"0.694445\" italic=\"0.080938\" >\n      <Lig code=\"1040\" ligCode=\"1071\"/>\n      <Lig code=\"1072\" ligCode=\"1071\"/>\n      <Lig code=\"1059\" ligCode=\"1070\"/>\n      <Lig code=\"1091\" ligCode=\"1070\"/>\n   </Char>\n   <Char code=\"1047\" width=\"0.611113\" height=\"0.694445\" italic=\"0.082927\" >\n      <Lig code=\"1061\" ligCode=\"1046\"/>\n      <Lig code=\"1093\" ligCode=\"1046\"/>\n   </Char>\n   <Char code=\"1068\" width=\"0.66667\" height=\"0.694445\" italic=\"0.02595\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1066\" width=\"0.868059\" height=\"0.694445\" italic=\"0.02595\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1072\" width=\"0.480557\" height=\"0.444445\" italic=\"0.009807\" >\n      <Kern code=\"1095\" val=\"-0.027779\"/>\n      <Kern code=\"1091\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1073\" width=\"0.500002\" height=\"0.694445\" italic=\"0.094829\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1094\" width=\"0.5486145\" height=\"0.444445\" depth=\"0.162038\" italic=\"0.04169\" >\n      <Lig code=\"1093\" ligCode=\"1095\"/>\n   </Char>\n   <Char code=\"1076\" width=\"0.538892\" height=\"0.444445\" depth=\"0.162038\" italic=\"0.04169\" >\n      <Lig code=\"1112\" ligCode=\"1106\"/>\n   </Char>\n   <Char code=\"1077\" width=\"0.444446\" height=\"0.444445\" italic=\"0.067778\" >\n   </Char>\n   <Char code=\"1092\" width=\"0.76667\" height=\"0.694445\" depth=\"0.194445\" italic=\"0.0389\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1075\" width=\"0.404167\" height=\"0.444445\" italic=\"0.108357\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1083\" val=\"-0.027779\"/>\n      <Kern code=\"1113\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1093\" width=\"0.461113\" height=\"0.444445\" italic=\"0.09169\" >\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1080\" width=\"0.537503\" height=\"0.444445\" italic=\"0.04169\" >\n   </Char>\n   <Char code=\"1112\" width=\"0.266668\" height=\"0.679365\" depth=\"0.194445\" italic=\"0.091624\" >\n   </Char>\n   <Char code=\"1082\" width=\"0.488892\" height=\"0.444445\" italic=\"0.083357\" >\n      <Lig code=\"1093\" ligCode=\"1093\"/>\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1083\" width=\"0.527781\" height=\"0.444445\" italic=\"0.04169\" >\n      <Lig code=\"1112\" ligCode=\"1113\"/>\n   </Char>\n   <Char code=\"1084\" width=\"0.669447\" height=\"0.444445\" italic=\"0.04169\" />\n   <Char code=\"1085\" width=\"0.516668\" height=\"0.444445\" italic=\"0.04169\" >\n      <Lig code=\"1112\" ligCode=\"1114\"/>\n   </Char>\n   <Char code=\"1086\" width=\"0.500002\" height=\"0.444445\" italic=\"0.066129\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1087\" width=\"0.516668\" height=\"0.444445\" italic=\"0.04169\" >\n   </Char>\n   <Char code=\"1095\" width=\"0.537503\" height=\"0.444445\" italic=\"0.04169\" />\n   <Char code=\"1088\" width=\"0.516668\" height=\"0.444445\" depth=\"0.194445\" italic=\"0.0389\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1089\" width=\"0.444446\" height=\"0.444445\" italic=\"0.083357\" >\n      <Lig code=\"1093\" ligCode=\"1096\"/>\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1090\" width=\"0.458334\" height=\"0.444445\" italic=\"0.113913\" >\n      <Lig code=\"1089\" ligCode=\"1094\"/>\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1083\" val=\"-0.027779\"/>\n      <Kern code=\"1113\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1091\" width=\"0.461113\" height=\"0.444445\" depth=\"0.194445\" italic=\"0.108357\" >\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.055555\"/>\n      <Kern code=\"1083\" val=\"-0.055555\"/>\n      <Kern code=\"1113\" val=\"-0.055555\"/>\n   </Char>\n   <Char code=\"1074\" width=\"0.480557\" height=\"0.444445\" italic=\"0.0389\" />\n   <Char code=\"1097\" width=\"0.7777815\" height=\"0.444445\" depth=\"0.162038\" italic=\"0.04169\" />\n   <Char code=\"1096\" width=\"0.76667\" height=\"0.444445\" italic=\"0.04169\" >\n      <Lig code=\"1095\" ligCode=\"1097\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1099\" width=\"0.683336\" height=\"0.444445\" italic=\"0.04169\" >\n      <Lig code=\"1072\" ligCode=\"1103\"/>\n      <Lig code=\"1091\" ligCode=\"1102\"/>\n   </Char>\n   <Char code=\"1079\" width=\"0.444446\" height=\"0.444445\" italic=\"0.050013\" >\n      <Lig code=\"1093\" ligCode=\"1078\"/>\n   </Char>\n   <Char code=\"1100\" width=\"0.480557\" height=\"0.444445\" italic=\"0.0389\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1098\" width=\"0.590279\" height=\"0.444445\" italic=\"0.0389\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n</Font>\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/cyrillic/wnti10.xml",
    "content": "<Font name=\"wnti10.ttf\" id=\"wnti10\" space=\"0.357776\" xHeight=\"0.430555\" quad=\"1.022217\" unicode=\"95\" romanVersion=\"wnr10\" boldVersion=\"wnbxti10\" ssVersion=\"wnssi10\" ttVersion=\"wntt10\">\n   <Char code=\"1034\" width=\"1.048883\" height=\"0.683332\" italic=\"0.036629\" >\n      <Kern code=\"1046\" val=\"-0.025556\"/>\n      <Kern code=\"1061\" val=\"-0.025556\"/>\n      <Kern code=\"1054\" val=\"-0.025556\"/>\n      <Kern code=\"1060\" val=\"-0.025556\"/>\n      <Kern code=\"1138\" val=\"-0.025556\"/>\n      <Kern code=\"1057\" val=\"-0.025556\"/>\n      <Kern code=\"1028\" val=\"-0.025556\"/>\n      <Kern code=\"1058\" val=\"-0.076666\"/>\n      <Kern code=\"1066\" val=\"-0.076666\"/>\n      <Kern code=\"1026\" val=\"-0.076666\"/>\n      <Kern code=\"1035\" val=\"-0.076666\"/>\n      <Kern code=\"1122\" val=\"-0.076666\"/>\n      <Kern code=\"1063\" val=\"-0.076666\"/>\n      <Kern code=\"1059\" val=\"-0.076666\"/>\n      <Kern code=\"1140\" val=\"-0.1022215\"/>\n      <Kern code=\"1098\" val=\"-0.025556\"/>\n      <Kern code=\"1141\" val=\"-0.025556\"/>\n      <Kern code=\"1082\" val=\"-0.025556\"/>\n      <Kern code=\"1085\" val=\"-0.025556\"/>\n      <Kern code=\"1114\" val=\"-0.025556\"/>\n      <Kern code=\"1087\" val=\"-0.025556\"/>\n      <Kern code=\"1090\" val=\"-0.025556\"/>\n      <Kern code=\"1102\" val=\"-0.025556\"/>\n      <Kern code=\"1123\" val=\"-0.025556\"/>\n      <Kern code=\"1110\" val=\"-0.025556\"/>\n      <Kern code=\"1080\" val=\"-0.025556\"/>\n      <Kern code=\"1081\" val=\"-0.025556\"/>\n      <Kern code=\"1094\" val=\"-0.025556\"/>\n      <Kern code=\"1096\" val=\"-0.025556\"/>\n      <Kern code=\"1097\" val=\"-0.025556\"/>\n      <Kern code=\"1100\" val=\"-0.025556\"/>\n      <Kern code=\"1099\" val=\"-0.025556\"/>\n      <Kern code=\"1091\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1033\" width=\"1.048883\" height=\"0.683332\" italic=\"0.036629\" >\n      <Kern code=\"1046\" val=\"-0.025556\"/>\n      <Kern code=\"1061\" val=\"-0.025556\"/>\n      <Kern code=\"1054\" val=\"-0.025556\"/>\n      <Kern code=\"1060\" val=\"-0.025556\"/>\n      <Kern code=\"1138\" val=\"-0.025556\"/>\n      <Kern code=\"1057\" val=\"-0.025556\"/>\n      <Kern code=\"1028\" val=\"-0.025556\"/>\n      <Kern code=\"1058\" val=\"-0.076666\"/>\n      <Kern code=\"1066\" val=\"-0.076666\"/>\n      <Kern code=\"1026\" val=\"-0.076666\"/>\n      <Kern code=\"1035\" val=\"-0.076666\"/>\n      <Kern code=\"1122\" val=\"-0.076666\"/>\n      <Kern code=\"1063\" val=\"-0.076666\"/>\n      <Kern code=\"1059\" val=\"-0.076666\"/>\n      <Kern code=\"1140\" val=\"-0.1022215\"/>\n      <Kern code=\"1098\" val=\"-0.025556\"/>\n      <Kern code=\"1141\" val=\"-0.025556\"/>\n      <Kern code=\"1082\" val=\"-0.025556\"/>\n      <Kern code=\"1085\" val=\"-0.025556\"/>\n      <Kern code=\"1114\" val=\"-0.025556\"/>\n      <Kern code=\"1087\" val=\"-0.025556\"/>\n      <Kern code=\"1090\" val=\"-0.025556\"/>\n      <Kern code=\"1102\" val=\"-0.025556\"/>\n      <Kern code=\"1123\" val=\"-0.025556\"/>\n      <Kern code=\"1110\" val=\"-0.025556\"/>\n      <Kern code=\"1080\" val=\"-0.025556\"/>\n      <Kern code=\"1081\" val=\"-0.025556\"/>\n      <Kern code=\"1094\" val=\"-0.025556\"/>\n      <Kern code=\"1096\" val=\"-0.025556\"/>\n      <Kern code=\"1097\" val=\"-0.025556\"/>\n      <Kern code=\"1100\" val=\"-0.025556\"/>\n      <Kern code=\"1099\" val=\"-0.025556\"/>\n      <Kern code=\"1091\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1039\" width=\"0.768885\" height=\"0.683332\" depth=\"0.194445\" italic=\"0.16389\" />\n   <Char code=\"1069\" width=\"0.715551\" height=\"0.683332\" italic=\"0.0940275\" >\n      <Kern code=\"1040\" val=\"-0.025556\"/>\n      <Kern code=\"1044\" val=\"-0.025556\"/>\n      <Kern code=\"1046\" val=\"-0.025556\"/>\n      <Kern code=\"1061\" val=\"-0.025556\"/>\n      <Kern code=\"1059\" val=\"-0.025556\"/>\n      <Kern code=\"1140\" val=\"-0.025556\"/>\n      <Kern code=\"1071\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1030\" width=\"0.385553\" height=\"0.683332\" italic=\"0.158055\" >\n      <Kern code=\"1030\" val=\"0.025556\"/>\n   </Char>\n   <Char code=\"1028\" width=\"0.715551\" height=\"0.683332\" italic=\"0.145277\" />\n   <Char code=\"1026\" width=\"0.843328\" height=\"0.683332\" italic=\"0.133055\" >\n      <Kern code=\"1046\" val=\"-0.025556\"/>\n      <Kern code=\"1061\" val=\"-0.025556\"/>\n      <Kern code=\"1054\" val=\"-0.025556\"/>\n      <Kern code=\"1060\" val=\"-0.025556\"/>\n      <Kern code=\"1138\" val=\"-0.025556\"/>\n      <Kern code=\"1057\" val=\"-0.025556\"/>\n      <Kern code=\"1028\" val=\"-0.025556\"/>\n      <Kern code=\"1058\" val=\"-0.076666\"/>\n      <Kern code=\"1066\" val=\"-0.076666\"/>\n      <Kern code=\"1026\" val=\"-0.076666\"/>\n      <Kern code=\"1035\" val=\"-0.076666\"/>\n      <Kern code=\"1122\" val=\"-0.076666\"/>\n      <Kern code=\"1063\" val=\"-0.076666\"/>\n      <Kern code=\"1059\" val=\"-0.076666\"/>\n      <Kern code=\"1140\" val=\"-0.1022215\"/>\n      <Kern code=\"1098\" val=\"-0.025556\"/>\n      <Kern code=\"1141\" val=\"-0.025556\"/>\n      <Kern code=\"1082\" val=\"-0.025556\"/>\n      <Kern code=\"1085\" val=\"-0.025556\"/>\n      <Kern code=\"1114\" val=\"-0.025556\"/>\n      <Kern code=\"1087\" val=\"-0.025556\"/>\n      <Kern code=\"1090\" val=\"-0.025556\"/>\n      <Kern code=\"1102\" val=\"-0.025556\"/>\n      <Kern code=\"1123\" val=\"-0.025556\"/>\n      <Kern code=\"1110\" val=\"-0.025556\"/>\n      <Kern code=\"1080\" val=\"-0.025556\"/>\n      <Kern code=\"1081\" val=\"-0.025556\"/>\n      <Kern code=\"1094\" val=\"-0.025556\"/>\n      <Kern code=\"1096\" val=\"-0.025556\"/>\n      <Kern code=\"1097\" val=\"-0.025556\"/>\n      <Kern code=\"1100\" val=\"-0.025556\"/>\n      <Kern code=\"1099\" val=\"-0.025556\"/>\n      <Kern code=\"1091\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1035\" width=\"0.753885\" height=\"0.683332\" italic=\"0.094722\" />\n   <Char code=\"1114\" width=\"0.715551\" height=\"0.430555\" italic=\"0.063124\" >\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n      <Kern code=\"1141\" val=\"-0.025556\"/>\n      <Kern code=\"1098\" val=\"-0.025556\"/>\n      <Kern code=\"1095\" val=\"-0.076666\"/>\n      <Kern code=\"1086\" val=\"-0.025556\"/>\n      <Kern code=\"1139\" val=\"-0.025556\"/>\n      <Kern code=\"1092\" val=\"-0.025556\"/>\n      <Kern code=\"1108\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1113\" width=\"0.689997\" height=\"0.430555\" italic=\"0.063124\" >\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n      <Kern code=\"1141\" val=\"-0.025556\"/>\n      <Kern code=\"1098\" val=\"-0.025556\"/>\n      <Kern code=\"1095\" val=\"-0.076666\"/>\n      <Kern code=\"1086\" val=\"-0.025556\"/>\n      <Kern code=\"1139\" val=\"-0.025556\"/>\n      <Kern code=\"1092\" val=\"-0.025556\"/>\n      <Kern code=\"1108\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1119\" width=\"0.536664\" height=\"0.430555\" depth=\"0.194445\" italic=\"0.076714\" />\n   <Char code=\"1101\" width=\"0.442108\" height=\"0.430555\" italic=\"0.063124\" >\n      <Kern code=\"1092\" val=\"-0.051111\"/>\n      <Kern code=\"1072\" val=\"-0.051111\"/>\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1110\" width=\"0.306665\" height=\"0.655359\" italic=\"0.101896\" />\n   <Char code=\"1108\" width=\"0.442108\" height=\"0.430555\" italic=\"0.082083\" />\n   <Char code=\"1106\" width=\"0.459997\" height=\"0.694445\" depth=\"0.194445\" italic=\"0.075346\" />\n   <Char code=\"1115\" width=\"0.511108\" height=\"0.694445\" italic=\"0.076714\" />\n   <Char code=\"1070\" width=\"1.087216\" height=\"0.683332\" italic=\"0.0940275\" >\n      <Kern code=\"1040\" val=\"-0.025556\"/>\n      <Kern code=\"1044\" val=\"-0.025556\"/>\n      <Kern code=\"1046\" val=\"-0.025556\"/>\n      <Kern code=\"1061\" val=\"-0.025556\"/>\n      <Kern code=\"1059\" val=\"-0.025556\"/>\n      <Kern code=\"1140\" val=\"-0.025556\"/>\n      <Kern code=\"1071\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1046\" width=\"1.152216\" height=\"0.683332\" italic=\"0.145277\" >\n      <Kern code=\"1054\" val=\"-0.025556\"/>\n      <Kern code=\"1060\" val=\"-0.025556\"/>\n      <Kern code=\"1138\" val=\"-0.025556\"/>\n      <Kern code=\"1057\" val=\"-0.025556\"/>\n      <Kern code=\"1028\" val=\"-0.025556\"/>\n      <Kern code=\"1095\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1049\" width=\"0.768885\" height=\"0.891615\" italic=\"0.16389\" />\n   <Char code=\"1025\" width=\"0.678329\" height=\"0.891615\" italic=\"0.120277\" />\n   <Char code=\"1140\" width=\"0.806107\" height=\"0.683332\" italic=\"0.183611\" >\n      <Kern code=\"1040\" val=\"-0.1022215\"/>\n      <Kern code=\"1071\" val=\"-0.1022215\"/>\n      <Kern code=\"1054\" val=\"-0.025556\"/>\n      <Kern code=\"1060\" val=\"-0.025556\"/>\n      <Kern code=\"1138\" val=\"-0.025556\"/>\n      <Kern code=\"1057\" val=\"-0.025556\"/>\n      <Kern code=\"1028\" val=\"-0.025556\"/>\n      <Kern code=\"1072\" val=\"-0.076666\"/>\n      <Kern code=\"1086\" val=\"-0.076666\"/>\n      <Kern code=\"1139\" val=\"-0.076666\"/>\n      <Kern code=\"1077\" val=\"-0.076666\"/>\n      <Kern code=\"1105\" val=\"-0.076666\"/>\n      <Kern code=\"1080\" val=\"-0.1022215\"/>\n      <Kern code=\"1081\" val=\"-0.1022215\"/>\n      <Kern code=\"1094\" val=\"-0.1022215\"/>\n      <Kern code=\"1096\" val=\"-0.1022215\"/>\n      <Kern code=\"1097\" val=\"-0.1022215\"/>\n      <Kern code=\"1100\" val=\"-0.1022215\"/>\n      <Kern code=\"1099\" val=\"-0.1022215\"/>\n      <Kern code=\"1091\" val=\"-0.1022215\"/>\n      <Kern code=\"1141\" val=\"-0.1022215\"/>\n      <Kern code=\"1098\" val=\"-0.1022215\"/>\n      <Kern code=\"1083\" val=\"-0.1022215\"/>\n      <Kern code=\"1084\" val=\"-0.1022215\"/>\n      <Kern code=\"1113\" val=\"-0.1022215\"/>\n   </Char>\n   <Char code=\"1138\" width=\"0.766663\" height=\"0.683332\" italic=\"0.0940275\" >\n      <Kern code=\"1040\" val=\"-0.025556\"/>\n      <Kern code=\"1044\" val=\"-0.025556\"/>\n      <Kern code=\"1046\" val=\"-0.025556\"/>\n      <Kern code=\"1061\" val=\"-0.025556\"/>\n      <Kern code=\"1059\" val=\"-0.025556\"/>\n      <Kern code=\"1140\" val=\"-0.025556\"/>\n      <Kern code=\"1071\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1029\" width=\"0.56222\" height=\"0.683332\" italic=\"0.119722\" />\n   <Char code=\"1071\" width=\"0.768885\" height=\"0.683332\" italic=\"0.16389\" />\n   <Char code=\"1102\" width=\"0.723218\" height=\"0.430555\" italic=\"0.063124\" >\n      <Kern code=\"1092\" val=\"-0.051111\"/>\n      <Kern code=\"1072\" val=\"-0.051111\"/>\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1078\" width=\"1.047772\" height=\"0.430555\" italic=\"0.056528\" />\n   <Char code=\"1081\" width=\"0.56222\" height=\"0.638838\" italic=\"0.076714\" />\n   <Char code=\"1105\" width=\"0.442108\" height=\"0.659131\" italic=\"0.075139\" >\n      <Kern code=\"1092\" val=\"-0.051111\"/>\n      <Kern code=\"1072\" val=\"-0.051111\"/>\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1141\" width=\"0.615275\" height=\"0.430555\" italic=\"0.120417\" >\n      <Kern code=\"1083\" val=\"-0.076666\"/>\n      <Kern code=\"1084\" val=\"-0.076666\"/>\n      <Kern code=\"1113\" val=\"-0.076666\"/>\n   </Char>\n   <Char code=\"1139\" width=\"0.459997\" height=\"0.430555\" italic=\"0.063124\" >\n      <Kern code=\"1092\" val=\"-0.051111\"/>\n      <Kern code=\"1072\" val=\"-0.051111\"/>\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1109\" width=\"0.408887\" height=\"0.430555\" italic=\"0.082083\" />\n   <Char code=\"1103\" width=\"0.536664\" height=\"0.430555\" italic=\"0.076714\" />\n   <Char code=\"776\" width=\"0.511108\" height=\"0.659131\" italic=\"0.102562\" />\n   <Char code=\"1122\" width=\"0.806107\" height=\"0.75\" italic=\"0.10257\" >\n      <Kern code=\"1046\" val=\"-0.025556\"/>\n      <Kern code=\"1061\" val=\"-0.025556\"/>\n      <Kern code=\"1054\" val=\"-0.025556\"/>\n      <Kern code=\"1060\" val=\"-0.025556\"/>\n      <Kern code=\"1138\" val=\"-0.025556\"/>\n      <Kern code=\"1057\" val=\"-0.025556\"/>\n      <Kern code=\"1028\" val=\"-0.025556\"/>\n      <Kern code=\"1058\" val=\"-0.076666\"/>\n      <Kern code=\"1066\" val=\"-0.076666\"/>\n      <Kern code=\"1026\" val=\"-0.076666\"/>\n      <Kern code=\"1035\" val=\"-0.076666\"/>\n      <Kern code=\"1122\" val=\"-0.076666\"/>\n      <Kern code=\"1063\" val=\"-0.076666\"/>\n      <Kern code=\"1059\" val=\"-0.076666\"/>\n      <Kern code=\"1140\" val=\"-0.1022215\"/>\n      <Kern code=\"1098\" val=\"-0.025556\"/>\n      <Kern code=\"1141\" val=\"-0.025556\"/>\n      <Kern code=\"1082\" val=\"-0.025556\"/>\n      <Kern code=\"1085\" val=\"-0.025556\"/>\n      <Kern code=\"1114\" val=\"-0.025556\"/>\n      <Kern code=\"1087\" val=\"-0.025556\"/>\n      <Kern code=\"1090\" val=\"-0.025556\"/>\n      <Kern code=\"1102\" val=\"-0.025556\"/>\n      <Kern code=\"1123\" val=\"-0.025556\"/>\n      <Kern code=\"1110\" val=\"-0.025556\"/>\n      <Kern code=\"1080\" val=\"-0.025556\"/>\n      <Kern code=\"1081\" val=\"-0.025556\"/>\n      <Kern code=\"1094\" val=\"-0.025556\"/>\n      <Kern code=\"1096\" val=\"-0.025556\"/>\n      <Kern code=\"1097\" val=\"-0.025556\"/>\n      <Kern code=\"1100\" val=\"-0.025556\"/>\n      <Kern code=\"1099\" val=\"-0.025556\"/>\n      <Kern code=\"1091\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"774\" width=\"0.511108\" height=\"0.638838\" italic=\"0.094154\" />\n   <Char code=\"1123\" width=\"0.715551\" height=\"0.430555\" italic=\"0.063124\" >\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n      <Kern code=\"1141\" val=\"-0.025556\"/>\n      <Kern code=\"1098\" val=\"-0.025556\"/>\n      <Kern code=\"1095\" val=\"-0.076666\"/>\n      <Kern code=\"1086\" val=\"-0.025556\"/>\n      <Kern code=\"1139\" val=\"-0.025556\"/>\n      <Kern code=\"1092\" val=\"-0.025556\"/>\n      <Kern code=\"1108\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"171\" width=\"0.56222\" height=\"0.483335\" italic=\"0.022985\"  />\n   <Char code=\"305\" width=\"0.306665\" height=\"0.430555\" italic=\"0.076714\" />\n   <Char code=\"187\" width=\"0.56222\" height=\"0.483335\" />\n   <Char code=\"1040\" width=\"0.743329\" height=\"0.683332\" >\n      <Kern code=\"1054\" val=\"-0.025556\"/>\n      <Kern code=\"1060\" val=\"-0.025556\"/>\n      <Kern code=\"1138\" val=\"-0.025556\"/>\n      <Kern code=\"1057\" val=\"-0.025556\"/>\n      <Kern code=\"1028\" val=\"-0.025556\"/>\n      <Kern code=\"1058\" val=\"-0.076666\"/>\n      <Kern code=\"1066\" val=\"-0.076666\"/>\n      <Kern code=\"1026\" val=\"-0.076666\"/>\n      <Kern code=\"1035\" val=\"-0.076666\"/>\n      <Kern code=\"1122\" val=\"-0.076666\"/>\n      <Kern code=\"1063\" val=\"-0.076666\"/>\n      <Kern code=\"1059\" val=\"-0.076666\"/>\n      <Kern code=\"1140\" val=\"-0.1022215\"/>\n      <Kern code=\"1098\" val=\"-0.025556\"/>\n      <Kern code=\"1141\" val=\"-0.025556\"/>\n      <Kern code=\"1082\" val=\"-0.025556\"/>\n      <Kern code=\"1085\" val=\"-0.025556\"/>\n      <Kern code=\"1114\" val=\"-0.025556\"/>\n      <Kern code=\"1087\" val=\"-0.025556\"/>\n      <Kern code=\"1090\" val=\"-0.025556\"/>\n      <Kern code=\"1102\" val=\"-0.025556\"/>\n      <Kern code=\"1123\" val=\"-0.025556\"/>\n      <Kern code=\"1110\" val=\"-0.025556\"/>\n      <Kern code=\"1080\" val=\"-0.025556\"/>\n      <Kern code=\"1081\" val=\"-0.025556\"/>\n      <Kern code=\"1094\" val=\"-0.025556\"/>\n      <Kern code=\"1096\" val=\"-0.025556\"/>\n      <Kern code=\"1097\" val=\"-0.025556\"/>\n      <Kern code=\"1100\" val=\"-0.025556\"/>\n      <Kern code=\"1099\" val=\"-0.025556\"/>\n      <Kern code=\"1091\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1041\" width=\"0.703885\" height=\"0.683332\" italic=\"0.069166\" />\n   <Char code=\"1062\" width=\"0.768885\" height=\"0.683332\" depth=\"0.194445\" italic=\"0.16389\" >\n      <Lig code=\"1061\" ligCode=\"1063\"/>\n      <Lig code=\"1093\" ligCode=\"1063\"/>\n   </Char>\n   <Char code=\"1044\" width=\"0.768885\" height=\"0.683332\" depth=\"0.194445\" italic=\"0.16389\" >\n      <Lig code=\"1032\" ligCode=\"1026\"/>\n      <Lig code=\"1112\" ligCode=\"1026\"/>\n   </Char>\n   <Char code=\"1045\" width=\"0.678329\" height=\"0.683332\" italic=\"0.120277\" >\n   </Char>\n   <Char code=\"1060\" width=\"0.817774\" height=\"0.683332\" italic=\"0.0940275\" >\n      <Kern code=\"1040\" val=\"-0.025556\"/>\n      <Kern code=\"1044\" val=\"-0.025556\"/>\n      <Kern code=\"1046\" val=\"-0.025556\"/>\n      <Kern code=\"1061\" val=\"-0.025556\"/>\n      <Kern code=\"1059\" val=\"-0.025556\"/>\n      <Kern code=\"1140\" val=\"-0.025556\"/>\n      <Kern code=\"1071\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1043\" width=\"0.627218\" height=\"0.683332\" italic=\"0.133055\" >\n      <Kern code=\"1040\" val=\"-0.076666\"/>\n      <Kern code=\"1044\" val=\"-0.076666\"/>\n      <Kern code=\"1071\" val=\"-0.076666\"/>\n      <Kern code=\"1051\" val=\"-0.025556\"/>\n      <Kern code=\"1033\" val=\"-0.025556\"/>\n      <Kern code=\"1072\" val=\"-0.076666\"/>\n      <Kern code=\"1086\" val=\"-0.076666\"/>\n      <Kern code=\"1139\" val=\"-0.076666\"/>\n      <Kern code=\"1077\" val=\"-0.076666\"/>\n      <Kern code=\"1105\" val=\"-0.076666\"/>\n      <Kern code=\"1089\" val=\"-0.076666\"/>\n      <Kern code=\"1108\" val=\"-0.076666\"/>\n      <Kern code=\"1092\" val=\"-0.076666\"/>\n      <Kern code=\"1080\" val=\"-0.076666\"/>\n      <Kern code=\"1081\" val=\"-0.076666\"/>\n      <Kern code=\"1094\" val=\"-0.076666\"/>\n      <Kern code=\"1096\" val=\"-0.076666\"/>\n      <Kern code=\"1097\" val=\"-0.076666\"/>\n      <Kern code=\"1100\" val=\"-0.076666\"/>\n      <Kern code=\"1099\" val=\"-0.076666\"/>\n      <Kern code=\"1091\" val=\"-0.076666\"/>\n      <Kern code=\"1141\" val=\"-0.076666\"/>\n      <Kern code=\"1098\" val=\"-0.076666\"/>\n      <Kern code=\"1083\" val=\"-0.076666\"/>\n      <Kern code=\"1084\" val=\"-0.076666\"/>\n      <Kern code=\"1113\" val=\"-0.076666\"/>\n   </Char>\n   <Char code=\"1061\" width=\"0.743329\" height=\"0.683332\" italic=\"0.158055\" >\n      <Kern code=\"1054\" val=\"-0.025556\"/>\n      <Kern code=\"1060\" val=\"-0.025556\"/>\n      <Kern code=\"1138\" val=\"-0.025556\"/>\n      <Kern code=\"1057\" val=\"-0.025556\"/>\n      <Kern code=\"1028\" val=\"-0.025556\"/>\n      <Kern code=\"1095\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1048\" width=\"0.768885\" height=\"0.683332\" italic=\"0.16389\" >\n   </Char>\n   <Char code=\"1032\" width=\"0.524997\" height=\"0.683332\" italic=\"0.140279\" >\n   </Char>\n   <Char code=\"1050\" width=\"0.768885\" height=\"0.683332\" italic=\"0.145277\" >\n      <Lig code=\"1061\" ligCode=\"1061\"/>\n      <Lig code=\"1093\" ligCode=\"1061\"/>\n      <Kern code=\"1054\" val=\"-0.025556\"/>\n      <Kern code=\"1060\" val=\"-0.025556\"/>\n      <Kern code=\"1138\" val=\"-0.025556\"/>\n      <Kern code=\"1057\" val=\"-0.025556\"/>\n      <Kern code=\"1028\" val=\"-0.025556\"/>\n      <Kern code=\"1095\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1051\" width=\"0.768885\" height=\"0.683332\" italic=\"0.16389\" >\n      <Lig code=\"1032\" ligCode=\"1033\"/>\n      <Lig code=\"1112\" ligCode=\"1033\"/>\n   </Char>\n   <Char code=\"1052\" width=\"0.896662\" height=\"0.683332\" italic=\"0.16389\" />\n   <Char code=\"1053\" width=\"0.768885\" height=\"0.683332\" italic=\"0.16389\" >\n      <Lig code=\"1032\" ligCode=\"1034\"/>\n      <Lig code=\"1112\" ligCode=\"1034\"/>\n   </Char>\n   <Char code=\"1054\" width=\"0.766663\" height=\"0.683332\" italic=\"0.0940275\" >\n      <Kern code=\"1040\" val=\"-0.025556\"/>\n      <Kern code=\"1044\" val=\"-0.025556\"/>\n      <Kern code=\"1046\" val=\"-0.025556\"/>\n      <Kern code=\"1061\" val=\"-0.025556\"/>\n      <Kern code=\"1059\" val=\"-0.025556\"/>\n      <Kern code=\"1140\" val=\"-0.025556\"/>\n      <Kern code=\"1071\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1055\" width=\"0.768885\" height=\"0.683332\" italic=\"0.16389\" >\n   </Char>\n   <Char code=\"1063\" width=\"0.768885\" height=\"0.683332\" italic=\"0.16389\" />\n   <Char code=\"1056\" width=\"0.678329\" height=\"0.683332\" italic=\"0.10257\" >\n      <Kern code=\"1040\" val=\"-0.076666\"/>\n      <Kern code=\"1044\" val=\"-0.076666\"/>\n      <Kern code=\"1051\" val=\"-0.076666\"/>\n      <Kern code=\"1033\" val=\"-0.076666\"/>\n      <Kern code=\"1071\" val=\"-0.076666\"/>\n      <Kern code=\"1072\" val=\"-0.025556\"/>\n      <Kern code=\"1086\" val=\"-0.025556\"/>\n      <Kern code=\"1139\" val=\"-0.025556\"/>\n      <Kern code=\"1077\" val=\"-0.025556\"/>\n      <Kern code=\"1105\" val=\"-0.025556\"/>\n      <Kern code=\"1076\" val=\"-0.076666\"/>\n      <Kern code=\"1083\" val=\"-0.076666\"/>\n      <Kern code=\"1113\" val=\"-0.076666\"/>\n   </Char>\n   <Char code=\"1057\" width=\"0.715551\" height=\"0.683332\" italic=\"0.145277\" >\n      <Lig code=\"1061\" ligCode=\"1064\"/>\n      <Lig code=\"1093\" ligCode=\"1064\"/>\n   </Char>\n   <Char code=\"1058\" width=\"0.715551\" height=\"0.683332\" italic=\"0.133055\" >\n      <Lig code=\"1057\" ligCode=\"1062\"/>\n      <Lig code=\"1089\" ligCode=\"1062\"/>\n      <Kern code=\"1040\" val=\"-0.076666\"/>\n      <Kern code=\"1044\" val=\"-0.076666\"/>\n      <Kern code=\"1071\" val=\"-0.076666\"/>\n      <Kern code=\"1051\" val=\"-0.025556\"/>\n      <Kern code=\"1033\" val=\"-0.025556\"/>\n      <Kern code=\"1072\" val=\"-0.076666\"/>\n      <Kern code=\"1086\" val=\"-0.076666\"/>\n      <Kern code=\"1139\" val=\"-0.076666\"/>\n      <Kern code=\"1077\" val=\"-0.076666\"/>\n      <Kern code=\"1105\" val=\"-0.076666\"/>\n      <Kern code=\"1089\" val=\"-0.076666\"/>\n      <Kern code=\"1108\" val=\"-0.076666\"/>\n      <Kern code=\"1092\" val=\"-0.076666\"/>\n      <Kern code=\"1080\" val=\"-0.076666\"/>\n      <Kern code=\"1081\" val=\"-0.076666\"/>\n      <Kern code=\"1094\" val=\"-0.076666\"/>\n      <Kern code=\"1096\" val=\"-0.076666\"/>\n      <Kern code=\"1097\" val=\"-0.076666\"/>\n      <Kern code=\"1100\" val=\"-0.076666\"/>\n      <Kern code=\"1099\" val=\"-0.076666\"/>\n      <Kern code=\"1091\" val=\"-0.076666\"/>\n      <Kern code=\"1141\" val=\"-0.076666\"/>\n      <Kern code=\"1098\" val=\"-0.076666\"/>\n      <Kern code=\"1083\" val=\"-0.076666\"/>\n      <Kern code=\"1084\" val=\"-0.076666\"/>\n      <Kern code=\"1113\" val=\"-0.076666\"/>\n   </Char>\n   <Char code=\"1059\" width=\"0.743329\" height=\"0.683332\" italic=\"0.183611\" >\n      <Kern code=\"1040\" val=\"-0.076666\"/>\n      <Kern code=\"1071\" val=\"-0.076666\"/>\n      <Kern code=\"1044\" val=\"-0.051111\"/>\n      <Kern code=\"1051\" val=\"-0.051111\"/>\n      <Kern code=\"1033\" val=\"-0.051111\"/>\n      <Kern code=\"1054\" val=\"-0.025556\"/>\n      <Kern code=\"1060\" val=\"-0.025556\"/>\n      <Kern code=\"1138\" val=\"-0.025556\"/>\n      <Kern code=\"1057\" val=\"-0.025556\"/>\n      <Kern code=\"1028\" val=\"-0.025556\"/>\n      <Kern code=\"1072\" val=\"-0.076666\"/>\n      <Kern code=\"1086\" val=\"-0.076666\"/>\n      <Kern code=\"1139\" val=\"-0.076666\"/>\n      <Kern code=\"1077\" val=\"-0.076666\"/>\n      <Kern code=\"1105\" val=\"-0.076666\"/>\n      <Kern code=\"1089\" val=\"-0.076666\"/>\n      <Kern code=\"1108\" val=\"-0.076666\"/>\n      <Kern code=\"1080\" val=\"-0.1022215\"/>\n      <Kern code=\"1081\" val=\"-0.1022215\"/>\n      <Kern code=\"1094\" val=\"-0.1022215\"/>\n      <Kern code=\"1096\" val=\"-0.1022215\"/>\n      <Kern code=\"1097\" val=\"-0.1022215\"/>\n      <Kern code=\"1100\" val=\"-0.1022215\"/>\n      <Kern code=\"1099\" val=\"-0.1022215\"/>\n      <Kern code=\"1091\" val=\"-0.1022215\"/>\n      <Kern code=\"1141\" val=\"-0.1022215\"/>\n      <Kern code=\"1098\" val=\"-0.1022215\"/>\n      <Kern code=\"1083\" val=\"-0.1022215\"/>\n      <Kern code=\"1084\" val=\"-0.1022215\"/>\n      <Kern code=\"1113\" val=\"-0.1022215\"/>\n   </Char>\n   <Char code=\"1042\" width=\"0.703885\" height=\"0.683332\" italic=\"0.077014\" />\n   <Char code=\"1065\" width=\"1.088327\" height=\"0.683332\" depth=\"0.194445\" italic=\"0.16389\" />\n   <Char code=\"1064\" width=\"1.088327\" height=\"0.683332\" italic=\"0.16389\" >\n      <Lig code=\"1063\" ligCode=\"1065\"/>\n      <Lig code=\"1095\" ligCode=\"1065\"/>\n      <Lig code=\"1062\" ligCode=\"0\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1067\" width=\"0.947772\" height=\"0.683332\" italic=\"0.16389\" >\n      <Lig code=\"1040\" ligCode=\"1071\"/>\n      <Lig code=\"1072\" ligCode=\"1071\"/>\n      <Lig code=\"1059\" ligCode=\"1070\"/>\n      <Lig code=\"1091\" ligCode=\"1070\"/>\n   </Char>\n   <Char code=\"1047\" width=\"0.61333\" height=\"0.683332\" italic=\"0.10257\" >\n      <Lig code=\"1061\" ligCode=\"1046\"/>\n      <Lig code=\"1093\" ligCode=\"1046\"/>\n   </Char>\n   <Char code=\"1068\" width=\"0.703885\" height=\"0.683332\" italic=\"0.036629\" >\n      <Kern code=\"1046\" val=\"-0.025556\"/>\n      <Kern code=\"1061\" val=\"-0.025556\"/>\n      <Kern code=\"1054\" val=\"-0.025556\"/>\n      <Kern code=\"1060\" val=\"-0.025556\"/>\n      <Kern code=\"1138\" val=\"-0.025556\"/>\n      <Kern code=\"1057\" val=\"-0.025556\"/>\n      <Kern code=\"1028\" val=\"-0.025556\"/>\n      <Kern code=\"1058\" val=\"-0.076666\"/>\n      <Kern code=\"1066\" val=\"-0.076666\"/>\n      <Kern code=\"1026\" val=\"-0.076666\"/>\n      <Kern code=\"1035\" val=\"-0.076666\"/>\n      <Kern code=\"1122\" val=\"-0.076666\"/>\n      <Kern code=\"1063\" val=\"-0.076666\"/>\n      <Kern code=\"1059\" val=\"-0.076666\"/>\n      <Kern code=\"1140\" val=\"-0.1022215\"/>\n      <Kern code=\"1098\" val=\"-0.025556\"/>\n      <Kern code=\"1141\" val=\"-0.025556\"/>\n      <Kern code=\"1082\" val=\"-0.025556\"/>\n      <Kern code=\"1085\" val=\"-0.025556\"/>\n      <Kern code=\"1114\" val=\"-0.025556\"/>\n      <Kern code=\"1087\" val=\"-0.025556\"/>\n      <Kern code=\"1090\" val=\"-0.025556\"/>\n      <Kern code=\"1102\" val=\"-0.025556\"/>\n      <Kern code=\"1123\" val=\"-0.025556\"/>\n      <Kern code=\"1110\" val=\"-0.025556\"/>\n      <Kern code=\"1080\" val=\"-0.025556\"/>\n      <Kern code=\"1081\" val=\"-0.025556\"/>\n      <Kern code=\"1094\" val=\"-0.025556\"/>\n      <Kern code=\"1096\" val=\"-0.025556\"/>\n      <Kern code=\"1097\" val=\"-0.025556\"/>\n      <Kern code=\"1100\" val=\"-0.025556\"/>\n      <Kern code=\"1099\" val=\"-0.025556\"/>\n      <Kern code=\"1091\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1066\" width=\"0.868884\" height=\"0.683332\" italic=\"0.036629\" >\n      <Kern code=\"1046\" val=\"-0.025556\"/>\n      <Kern code=\"1061\" val=\"-0.025556\"/>\n      <Kern code=\"1054\" val=\"-0.025556\"/>\n      <Kern code=\"1060\" val=\"-0.025556\"/>\n      <Kern code=\"1138\" val=\"-0.025556\"/>\n      <Kern code=\"1057\" val=\"-0.025556\"/>\n      <Kern code=\"1028\" val=\"-0.025556\"/>\n      <Kern code=\"1058\" val=\"-0.076666\"/>\n      <Kern code=\"1066\" val=\"-0.076666\"/>\n      <Kern code=\"1026\" val=\"-0.076666\"/>\n      <Kern code=\"1035\" val=\"-0.076666\"/>\n      <Kern code=\"1122\" val=\"-0.076666\"/>\n      <Kern code=\"1063\" val=\"-0.076666\"/>\n      <Kern code=\"1059\" val=\"-0.076666\"/>\n      <Kern code=\"1140\" val=\"-0.1022215\"/>\n      <Kern code=\"1098\" val=\"-0.025556\"/>\n      <Kern code=\"1141\" val=\"-0.025556\"/>\n      <Kern code=\"1082\" val=\"-0.025556\"/>\n      <Kern code=\"1085\" val=\"-0.025556\"/>\n      <Kern code=\"1114\" val=\"-0.025556\"/>\n      <Kern code=\"1087\" val=\"-0.025556\"/>\n      <Kern code=\"1090\" val=\"-0.025556\"/>\n      <Kern code=\"1102\" val=\"-0.025556\"/>\n      <Kern code=\"1123\" val=\"-0.025556\"/>\n      <Kern code=\"1110\" val=\"-0.025556\"/>\n      <Kern code=\"1080\" val=\"-0.025556\"/>\n      <Kern code=\"1081\" val=\"-0.025556\"/>\n      <Kern code=\"1094\" val=\"-0.025556\"/>\n      <Kern code=\"1096\" val=\"-0.025556\"/>\n      <Kern code=\"1097\" val=\"-0.025556\"/>\n      <Kern code=\"1100\" val=\"-0.025556\"/>\n      <Kern code=\"1099\" val=\"-0.025556\"/>\n      <Kern code=\"1091\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1072\" width=\"0.493219\" height=\"0.430555\" italic=\"0.076714\" />\n   <Char code=\"1073\" width=\"0.475329\" height=\"0.694445\" italic=\"0.154445\" >\n      <Kern code=\"1092\" val=\"-0.051111\"/>\n      <Kern code=\"1072\" val=\"-0.051111\"/>\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1094\" width=\"0.567331\" height=\"0.430555\" depth=\"0.194445\" italic=\"0.076714\" >\n      <Lig code=\"1093\" ligCode=\"1095\"/>\n   </Char>\n   <Char code=\"1076\" width=\"0.475329\" height=\"0.694445\" italic=\"0.113861\" >\n      <Lig code=\"1112\" ligCode=\"1106\"/>\n   </Char>\n   <Char code=\"1077\" width=\"0.442108\" height=\"0.430555\" italic=\"0.075139\" >\n      <Kern code=\"1092\" val=\"-0.051111\"/>\n      <Kern code=\"1072\" val=\"-0.051111\"/>\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1092\" width=\"0.679773\" height=\"0.694445\" depth=\"0.194445\" italic=\"0.063124\" >\n      <Kern code=\"1092\" val=\"-0.051111\"/>\n      <Kern code=\"1072\" val=\"-0.051111\"/>\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1075\" width=\"0.421664\" height=\"0.430555\" italic=\"0.075139\" />\n   <Char code=\"1093\" width=\"0.540553\" height=\"0.430555\" italic=\"0.120417\" />\n   <Char code=\"1080\" width=\"0.56222\" height=\"0.430555\" italic=\"0.076714\" >\n   </Char>\n   <Char code=\"1112\" width=\"0.306665\" height=\"0.655359\" depth=\"0.194445\" italic=\"0.144673\" >\n   </Char>\n   <Char code=\"1082\" width=\"0.511108\" height=\"0.430555\" italic=\"0.107638\" >\n      <Lig code=\"1093\" ligCode=\"1093\"/>\n   </Char>\n   <Char code=\"1083\" width=\"0.536664\" height=\"0.430555\" italic=\"0.076714\" >\n      <Lig code=\"1112\" ligCode=\"1113\"/>\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n      <Kern code=\"1141\" val=\"-0.025556\"/>\n      <Kern code=\"1098\" val=\"-0.025556\"/>\n      <Kern code=\"1095\" val=\"-0.076666\"/>\n   </Char>\n   <Char code=\"1084\" width=\"0.741107\" height=\"0.430555\" italic=\"0.076714\" />\n   <Char code=\"1085\" width=\"0.56222\" height=\"0.430555\" italic=\"0.076714\" >\n      <Lig code=\"1112\" ligCode=\"1114\"/>\n   </Char>\n   <Char code=\"1086\" width=\"0.475329\" height=\"0.430555\" italic=\"0.063124\" >\n      <Kern code=\"1092\" val=\"-0.051111\"/>\n      <Kern code=\"1072\" val=\"-0.051111\"/>\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1087\" width=\"0.56222\" height=\"0.430555\" italic=\"0.076714\" >\n   </Char>\n   <Char code=\"1095\" width=\"0.536664\" height=\"0.430555\" italic=\"0.076714\" />\n   <Char code=\"1088\" width=\"0.505997\" height=\"0.430555\" depth=\"0.194445\" italic=\"0.063124\" >\n      <Kern code=\"1092\" val=\"-0.051111\"/>\n      <Kern code=\"1072\" val=\"-0.051111\"/>\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1089\" width=\"0.442108\" height=\"0.430555\" italic=\"0.056528\" >\n      <Lig code=\"1093\" ligCode=\"1096\"/>\n      <Kern code=\"1092\" val=\"-0.051111\"/>\n      <Kern code=\"1072\" val=\"-0.051111\"/>\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1090\" width=\"0.817774\" height=\"0.430555\" italic=\"0.076714\" >\n      <Lig code=\"1089\" ligCode=\"1094\"/>\n   </Char>\n   <Char code=\"1091\" width=\"0.511108\" height=\"0.430555\" depth=\"0.194445\" italic=\"0.088472\" />\n   <Char code=\"1074\" width=\"0.493219\" height=\"0.430555\" italic=\"0.075139\" />\n   <Char code=\"1097\" width=\"0.8228855\" height=\"0.430555\" depth=\"0.194445\" italic=\"0.076714\" />\n   <Char code=\"1096\" width=\"0.817774\" height=\"0.430555\" italic=\"0.076714\" >\n      <Lig code=\"1095\" ligCode=\"1097\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1099\" width=\"0.664441\" height=\"0.430555\" italic=\"0.076714\" >\n      <Lig code=\"1072\" ligCode=\"1103\"/>\n      <Lig code=\"1091\" ligCode=\"1102\"/>\n   </Char>\n   <Char code=\"1079\" width=\"0.459997\" height=\"0.430555\" italic=\"0.056528\" >\n      <Lig code=\"1093\" ligCode=\"1078\"/>\n   </Char>\n   <Char code=\"1100\" width=\"0.511108\" height=\"0.430555\" italic=\"0.063124\" >\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n      <Kern code=\"1141\" val=\"-0.025556\"/>\n      <Kern code=\"1098\" val=\"-0.025556\"/>\n      <Kern code=\"1095\" val=\"-0.076666\"/>\n      <Kern code=\"1086\" val=\"-0.025556\"/>\n      <Kern code=\"1139\" val=\"-0.025556\"/>\n      <Kern code=\"1092\" val=\"-0.025556\"/>\n      <Kern code=\"1108\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1098\" width=\"0.485553\" height=\"0.430555\" italic=\"0.063124\" >\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n      <Kern code=\"1141\" val=\"-0.025556\"/>\n      <Kern code=\"1098\" val=\"-0.025556\"/>\n      <Kern code=\"1095\" val=\"-0.076666\"/>\n      <Kern code=\"1086\" val=\"-0.025556\"/>\n      <Kern code=\"1139\" val=\"-0.025556\"/>\n      <Kern code=\"1092\" val=\"-0.025556\"/>\n      <Kern code=\"1108\" val=\"-0.025556\"/>\n   </Char>\n</Font>\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/cyrillic/wntt10.xml",
    "content": "<Font name=\"wntt10.ttf\" id=\"wntt10\" space=\"0.524996\" xHeight=\"0.430555\" quad=\"1.049991\" unicode=\"95\" romanVersion=\"wnr10\" ssVersion=\"wnss10\">\n   <Char code=\"1034\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1033\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1039\" width=\"0.524996\" height=\"0.611112\" depth=\"0.166667\" />\n   <Char code=\"1069\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1030\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1028\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1026\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1035\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1114\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1113\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1119\" width=\"0.524996\" height=\"0.430555\" depth=\"0.13889\" />\n   <Char code=\"1101\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1110\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1108\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1106\" width=\"0.524996\" height=\"0.611112\" depth=\"0.222223\" />\n   <Char code=\"1115\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1070\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1046\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1049\" width=\"0.524996\" height=\"0.819394\" />\n   <Char code=\"1025\" width=\"0.524996\" height=\"0.819394\" />\n   <Char code=\"1140\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1138\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1029\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1071\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1102\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1078\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1081\" width=\"0.524996\" height=\"0.638838\" />\n   <Char code=\"1105\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1141\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1139\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1109\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1103\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"776\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1122\" width=\"0.524996\" height=\"0.694445\" />\n   <Char code=\"774\" width=\"0.524996\" height=\"0.638838\" />\n   <Char code=\"1123\" width=\"0.524996\" height=\"0.638838\" />\n   <Char code=\"171\" width=\"0.524996\" height=\"0.438889\" />\n   <Char code=\"305\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"187\" width=\"0.524996\" height=\"0.438889\" />\n   <Char code=\"1040\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1041\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1062\" width=\"0.524996\" height=\"0.611112\" depth=\"0.166667\" >\n      <Lig code=\"1061\" ligCode=\"1063\"/>\n      <Lig code=\"1093\" ligCode=\"1063\"/>\n   </Char>\n   <Char code=\"1044\" width=\"0.524996\" height=\"0.611112\" depth=\"0.166667\" >\n      <Lig code=\"1032\" ligCode=\"1026\"/>\n      <Lig code=\"1112\" ligCode=\"1026\"/>\n   </Char>\n   <Char code=\"1045\" width=\"0.524996\" height=\"0.611112\" >\n   </Char>\n   <Char code=\"1060\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1043\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1061\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1048\" width=\"0.524996\" height=\"0.611112\" >\n   </Char>\n   <Char code=\"1032\" width=\"0.524996\" height=\"0.611112\" >\n   </Char>\n   <Char code=\"1050\" width=\"0.524996\" height=\"0.611112\" >\n      <Lig code=\"1061\" ligCode=\"1061\"/>\n      <Lig code=\"1093\" ligCode=\"1061\"/>\n   </Char>\n   <Char code=\"1051\" width=\"0.524996\" height=\"0.611112\" >\n      <Lig code=\"1032\" ligCode=\"1033\"/>\n      <Lig code=\"1112\" ligCode=\"1033\"/>\n   </Char>\n   <Char code=\"1052\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1053\" width=\"0.524996\" height=\"0.611112\" >\n      <Lig code=\"1032\" ligCode=\"1034\"/>\n      <Lig code=\"1112\" ligCode=\"1034\"/>\n   </Char>\n   <Char code=\"1054\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1055\" width=\"0.524996\" height=\"0.611112\" >\n   </Char>\n   <Char code=\"1063\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1056\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1057\" width=\"0.524996\" height=\"0.611112\" >\n      <Lig code=\"1061\" ligCode=\"1064\"/>\n      <Lig code=\"1093\" ligCode=\"1064\"/>\n   </Char>\n   <Char code=\"1058\" width=\"0.524996\" height=\"0.611112\" >\n      <Lig code=\"1057\" ligCode=\"1062\"/>\n      <Lig code=\"1089\" ligCode=\"1062\"/>\n   </Char>\n   <Char code=\"1059\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1042\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1065\" width=\"0.524996\" height=\"0.611112\" depth=\"0.166667\" />\n   <Char code=\"1064\" width=\"0.524996\" height=\"0.611112\" >\n      <Lig code=\"1063\" ligCode=\"1065\"/>\n      <Lig code=\"1095\" ligCode=\"1065\"/>\n      <Lig code=\"1062\" ligCode=\"0\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1067\" width=\"0.524996\" height=\"0.611112\" >\n      <Lig code=\"1040\" ligCode=\"1071\"/>\n      <Lig code=\"1072\" ligCode=\"1071\"/>\n      <Lig code=\"1059\" ligCode=\"1070\"/>\n      <Lig code=\"1091\" ligCode=\"1070\"/>\n   </Char>\n   <Char code=\"1047\" width=\"0.524996\" height=\"0.611112\" >\n      <Lig code=\"1061\" ligCode=\"1046\"/>\n      <Lig code=\"1093\" ligCode=\"1046\"/>\n   </Char>\n   <Char code=\"1068\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1066\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1072\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1073\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1094\" width=\"0.524996\" height=\"0.430555\" depth=\"0.13889\" >\n      <Lig code=\"1093\" ligCode=\"1095\"/>\n   </Char>\n   <Char code=\"1076\" width=\"0.524996\" height=\"0.430555\" depth=\"0.13889\" >\n      <Lig code=\"1112\" ligCode=\"1106\"/>\n   </Char>\n   <Char code=\"1077\" width=\"0.524996\" height=\"0.430555\" >\n   </Char>\n   <Char code=\"1092\" width=\"0.524996\" height=\"0.611112\" depth=\"0.222223\" />\n   <Char code=\"1075\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1093\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1080\" width=\"0.524996\" height=\"0.430555\" >\n   </Char>\n   <Char code=\"1112\" width=\"0.524996\" height=\"0.611112\" depth=\"0.222223\" >\n   </Char>\n   <Char code=\"1082\" width=\"0.524996\" height=\"0.430555\" >\n      <Lig code=\"1093\" ligCode=\"1093\"/>\n   </Char>\n   <Char code=\"1083\" width=\"0.524996\" height=\"0.430555\" >\n      <Lig code=\"1112\" ligCode=\"1113\"/>\n   </Char>\n   <Char code=\"1084\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1085\" width=\"0.524996\" height=\"0.430555\" >\n      <Lig code=\"1112\" ligCode=\"1114\"/>\n   </Char>\n   <Char code=\"1086\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1087\" width=\"0.524996\" height=\"0.430555\" >\n   </Char>\n   <Char code=\"1095\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1088\" width=\"0.524996\" height=\"0.430555\" depth=\"0.222223\" />\n   <Char code=\"1089\" width=\"0.524996\" height=\"0.430555\" >\n      <Lig code=\"1093\" ligCode=\"1096\"/>\n   </Char>\n   <Char code=\"1090\" width=\"0.524996\" height=\"0.430555\" >\n      <Lig code=\"1089\" ligCode=\"1094\"/>\n   </Char>\n   <Char code=\"1091\" width=\"0.524996\" height=\"0.430555\" depth=\"0.222223\" />\n   <Char code=\"1074\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1097\" width=\"0.524996\" height=\"0.430555\" depth=\"0.13889\" />\n   <Char code=\"1096\" width=\"0.524996\" height=\"0.430555\" >\n      <Lig code=\"1095\" ligCode=\"1097\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1099\" width=\"0.524996\" height=\"0.430555\" >\n      <Lig code=\"1072\" ligCode=\"1103\"/>\n      <Lig code=\"1091\" ligCode=\"1102\"/>\n   </Char>\n   <Char code=\"1079\" width=\"0.524996\" height=\"0.430555\" >\n      <Lig code=\"1093\" ligCode=\"1078\"/>\n   </Char>\n   <Char code=\"1100\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1098\" width=\"0.524996\" height=\"0.430555\" />\n</Font>\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/fonts/licences/Knuth_License.txt",
    "content": "Knuth License\n\nThis software is copyright and you are explicitly granted a license which gives you, the \"user\" of the software, legal permission to copy, distribute and/or modify the software, so long as if you modify the software then it carry a different name from the original software.\n\nAll the same, please check the specific details of the software's license before making modifications. \n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/fonts/licences/License_for_dsrom.txt",
    "content": "License\n-------\n\nYou may use and distribute these fonts as you like.\nYou may modify these fonts as long as you do not\nrename the files to one of those names that \nDonald E. Knuth chose for the Computer Modern fonts.\n(And seriously, who would want to do that?)\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/fonts/licences/OFL.txt",
    "content": "Copyright (c) 1997, 2009, American Mathematical Society (http://www.ams.org).\nAll Rights Reserved.\n\n\"eufb10\" is a Reserved Font Name for this Font Software.\n\"eufm10\" is a Reserved Font Name for this Font Software.\n\"msam10\" is a Reserved Font Name for this Font Software.\n\"msbm10\" is a Reserved Font Name for this Font Software.\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttp://scripts.sil.org/OFL\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/greek/fcmbipg.xml",
    "content": "<?xml version='1.0'?>\n<Font name=\"fcmbipg.ttf\" id=\"fcmbipg\" space=\"0.355\" xHeight=\"0.451\" quad=\"1\" unicode=\"204\" ssVersion=\"fcsbpg\" ttVersion=\"fctrpg\">\n  <Char code=\"32\" width=\"0.355\" height=\"0.0\" />\n  <Char code=\"168\" width=\"0.255\" height=\"0.644\" italic=\"0.216\" />\n  <Char code=\"884\" width=\"0.224\" height=\"0.714\" italic=\"0.144\" />\n  <Char code=\"885\" width=\"0.224\" height=\"0.005\" depth=\"0.215\" />\n  <Char code=\"890\" width=\"0.128\" height=\"-0.032\" depth=\"0.211\" italic=\"0.064\" />\n  <Char code=\"900\" width=\"0.192\" height=\"0.714\" italic=\"0.15\" >\n    <Kern code=\"913\" val=\"-0.128\"/>\n    <Kern code=\"927\" val=\"-0.064\"/>\n    <Kern code=\"937\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.128\"/>\n    <Kern code=\"8188\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"901\" width=\"0.319\" height=\"0.714\" italic=\"0.206\" />\n  <Char code=\"903\" width=\"0.319\" height=\"0.446\" italic=\"0.021\" />\n  <Char code=\"912\" width=\"0.287\" height=\"0.714\" depth=\"0.006\" italic=\"0.188\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"913\" width=\"0.869\" height=\"0.7\" >\n    <Kern code=\"920\" val=\"-0.096\"/>\n    <Kern code=\"927\" val=\"-0.096\"/>\n    <Kern code=\"932\" val=\"-0.096\"/>\n    <Kern code=\"933\" val=\"-0.16\"/>\n    <Kern code=\"934\" val=\"-0.096\"/>\n    <Kern code=\"936\" val=\"-0.141\"/>\n    <Kern code=\"939\" val=\"-0.16\"/>\n    <Kern code=\"957\" val=\"-0.112\"/>\n  </Char>\n  <Char code=\"914\" width=\"0.818\" height=\"0.689\" italic=\"0.046\" />\n  <Char code=\"915\" width=\"0.691\" height=\"0.681\" italic=\"0.102\" >\n    <Kern code=\"913\" val=\"-0.153\"/>\n    <Kern code=\"916\" val=\"-0.128\"/>\n    <Kern code=\"923\" val=\"-0.141\"/>\n    <Kern code=\"8124\" val=\"-0.153\"/>\n  </Char>\n  <Char code=\"916\" width=\"0.958\" height=\"0.699\" >\n    <Kern code=\"927\" val=\"-0.038\"/>\n    <Kern code=\"933\" val=\"-0.16\"/>\n    <Kern code=\"939\" val=\"-0.16\"/>\n  </Char>\n  <Char code=\"917\" width=\"0.755\" height=\"0.681\" italic=\"0.086\" />\n  <Char code=\"918\" width=\"0.703\" height=\"0.688\" italic=\"0.115\" />\n  <Char code=\"919\" width=\"0.9\" height=\"0.687\" italic=\"0.144\" />\n  <Char code=\"920\" width=\"0.894\" height=\"0.699\" depth=\"0.011\" italic=\"0.04\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"933\" val=\"-0.096\"/>\n    <Kern code=\"939\" val=\"-0.096\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"921\" width=\"0.436\" height=\"0.687\" italic=\"0.15\" />\n  <Char code=\"922\" width=\"0.901\" height=\"0.687\" italic=\"0.119\" >\n    <Kern code=\"927\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"923\" width=\"0.805\" height=\"0.699\" >\n    <Kern code=\"927\" val=\"-0.038\"/>\n    <Kern code=\"933\" val=\"-0.115\"/>\n    <Kern code=\"939\" val=\"-0.115\"/>\n  </Char>\n  <Char code=\"924\" width=\"1.091\" height=\"0.688\" italic=\"0.143\" />\n  <Char code=\"925\" width=\"0.9\" height=\"0.687\" italic=\"0.144\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"926\" width=\"0.766\" height=\"0.676\" italic=\"0.117\" />\n  <Char code=\"927\" width=\"0.864\" height=\"0.699\" depth=\"0.011\" italic=\"0.041\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"931\" val=\"-0.064\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"928\" width=\"0.9\" height=\"0.681\" italic=\"0.142\" />\n  <Char code=\"929\" width=\"0.786\" height=\"0.687\" italic=\"0.073\" >\n    <Kern code=\"913\" val=\"-0.192\"/>\n    <Kern code=\"8124\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"931\" width=\"0.83\" height=\"0.688\" italic=\"0.089\" >\n    <Kern code=\"913\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"932\" width=\"0.8\" height=\"0.676\" italic=\"0.118\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"933\" width=\"0.805\" height=\"0.687\" italic=\"0.166\" >\n    <Kern code=\"913\" val=\"-0.16\"/>\n    <Kern code=\"916\" val=\"-0.16\"/>\n    <Kern code=\"923\" val=\"-0.16\"/>\n    <Kern code=\"8124\" val=\"-0.16\"/>\n  </Char>\n  <Char code=\"934\" width=\"0.83\" height=\"0.687\" italic=\"0.031\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"935\" width=\"0.869\" height=\"0.687\" italic=\"0.101\" />\n  <Char code=\"936\" width=\"0.894\" height=\"0.687\" italic=\"0.077\" >\n    <Kern code=\"913\" val=\"-0.141\"/>\n    <Kern code=\"8124\" val=\"-0.141\"/>\n  </Char>\n  <Char code=\"937\" width=\"0.83\" height=\"0.698\" italic=\"0.065\" />\n  <Char code=\"938\" width=\"0.436\" height=\"0.893\" italic=\"0.219\" />\n  <Char code=\"939\" width=\"0.805\" height=\"0.893\" italic=\"0.166\" >\n    <Kern code=\"913\" val=\"-0.16\"/>\n    <Kern code=\"916\" val=\"-0.16\"/>\n    <Kern code=\"923\" val=\"-0.16\"/>\n    <Kern code=\"8124\" val=\"-0.16\"/>\n  </Char>\n  <Char code=\"940\" width=\"0.639\" height=\"0.714\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"941\" width=\"0.447\" height=\"0.714\" depth=\"0.006\" italic=\"0.055\" >\n    <Kern code=\"940\" val=\"-0.032\"/>\n    <Kern code=\"945\" val=\"-0.032\"/>\n    <Kern code=\"948\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.01\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.032\"/>\n    <Kern code=\"8115\" val=\"-0.032\"/>\n    <Kern code=\"8116\" val=\"-0.032\"/>\n    <Kern code=\"8118\" val=\"-0.032\"/>\n    <Kern code=\"8119\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"942\" width=\"0.594\" height=\"0.713\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"943\" width=\"0.287\" height=\"0.714\" depth=\"0.006\" italic=\"0.101\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"944\" width=\"0.575\" height=\"0.738\" depth=\"0.005\" italic=\"0.07\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"945\" width=\"0.639\" height=\"0.452\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.109\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"993\" val=\"-0.255\"/>\n    <Kern code=\"8016\" val=\"-0.096\"/>\n    <Kern code=\"8018\" val=\"-0.096\"/>\n    <Kern code=\"8020\" val=\"-0.096\"/>\n    <Kern code=\"8021\" val=\"-0.096\"/>\n    <Kern code=\"8022\" val=\"-0.096\"/>\n    <Kern code=\"8023\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n    <Kern code=\"8166\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"946\" width=\"0.511\" height=\"0.702\" depth=\"0.212\" italic=\"0.082\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"943\" val=\"0.032\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"953\" val=\"0.032\"/>\n    <Kern code=\"959\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"0.032\"/>\n    <Kern code=\"966\" val=\"0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.064\"/>\n    <Kern code=\"972\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.064\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8054\" val=\"0.032\"/>\n    <Kern code=\"8056\" val=\"0.032\"/>\n    <Kern code=\"8150\" val=\"0.032\"/>\n  </Char>\n  <Char code=\"947\" width=\"0.575\" height=\"0.46\" depth=\"0.224\" italic=\"0.058\" >\n    <Kern code=\"967\" val=\"0.019\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"948\" width=\"0.537\" height=\"0.702\" depth=\"0.005\" italic=\"0.029\" >\n    <Kern code=\"940\" val=\"-0.032\"/>\n    <Kern code=\"945\" val=\"-0.032\"/>\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"956\" val=\"-0.051\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"960\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.019\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.032\"/>\n    <Kern code=\"8115\" val=\"-0.032\"/>\n    <Kern code=\"8116\" val=\"-0.032\"/>\n    <Kern code=\"8118\" val=\"-0.032\"/>\n    <Kern code=\"8119\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"949\" width=\"0.447\" height=\"0.451\" depth=\"0.006\" italic=\"0.051\" >\n    <Kern code=\"940\" val=\"-0.032\"/>\n    <Kern code=\"945\" val=\"-0.032\"/>\n    <Kern code=\"948\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.01\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.032\"/>\n    <Kern code=\"8115\" val=\"-0.032\"/>\n    <Kern code=\"8116\" val=\"-0.032\"/>\n    <Kern code=\"8118\" val=\"-0.032\"/>\n    <Kern code=\"8119\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"950\" width=\"0.479\" height=\"0.696\" depth=\"0.188\" italic=\"0.06\" >\n    <Kern code=\"940\" val=\"-0.096\"/>\n    <Kern code=\"941\" val=\"-0.096\"/>\n    <Kern code=\"942\" val=\"-0.096\"/>\n    <Kern code=\"945\" val=\"-0.096\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"948\" val=\"-0.064\"/>\n    <Kern code=\"949\" val=\"-0.096\"/>\n    <Kern code=\"951\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.064\"/>\n    <Kern code=\"956\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.102\"/>\n    <Kern code=\"959\" val=\"-0.096\"/>\n    <Kern code=\"960\" val=\"-0.096\"/>\n    <Kern code=\"963\" val=\"-0.096\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"966\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"969\" val=\"-0.096\"/>\n    <Kern code=\"972\" val=\"-0.096\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"974\" val=\"-0.096\"/>\n    <Kern code=\"993\" val=\"-0.064\"/>\n    <Kern code=\"8048\" val=\"-0.096\"/>\n    <Kern code=\"8050\" val=\"-0.096\"/>\n    <Kern code=\"8052\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.096\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n    <Kern code=\"8060\" val=\"-0.096\"/>\n    <Kern code=\"8114\" val=\"-0.096\"/>\n    <Kern code=\"8115\" val=\"-0.096\"/>\n    <Kern code=\"8116\" val=\"-0.096\"/>\n    <Kern code=\"8118\" val=\"-0.096\"/>\n    <Kern code=\"8119\" val=\"-0.096\"/>\n    <Kern code=\"8130\" val=\"-0.096\"/>\n    <Kern code=\"8131\" val=\"-0.096\"/>\n    <Kern code=\"8132\" val=\"-0.096\"/>\n    <Kern code=\"8134\" val=\"-0.096\"/>\n    <Kern code=\"8135\" val=\"-0.096\"/>\n    <Kern code=\"8166\" val=\"-0.096\"/>\n    <Kern code=\"8178\" val=\"-0.096\"/>\n    <Kern code=\"8179\" val=\"-0.096\"/>\n    <Kern code=\"8180\" val=\"-0.096\"/>\n    <Kern code=\"8182\" val=\"-0.096\"/>\n    <Kern code=\"8183\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"951\" width=\"0.594\" height=\"0.452\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"952\" width=\"0.591\" height=\"0.702\" depth=\"0.006\" italic=\"0.075\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"943\" val=\"0.032\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"953\" val=\"0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.064\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8054\" val=\"0.032\"/>\n    <Kern code=\"8150\" val=\"0.032\"/>\n  </Char>\n  <Char code=\"953\" width=\"0.287\" height=\"0.445\" depth=\"0.006\" italic=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"954\" width=\"0.607\" height=\"0.458\" depth=\"0.006\" italic=\"0.063\" >\n    <Kern code=\"946\" val=\"0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"955\" width=\"0.517\" height=\"0.701\" depth=\"0.006\" italic=\"0.014\" >\n    <Kern code=\"940\" val=\"-0.016\"/>\n    <Kern code=\"945\" val=\"-0.016\"/>\n    <Kern code=\"947\" val=\"-0.16\"/>\n    <Kern code=\"952\" val=\"-0.051\"/>\n    <Kern code=\"956\" val=\"0.016\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.064\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"973\" val=\"-0.064\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.016\"/>\n    <Kern code=\"8058\" val=\"-0.064\"/>\n    <Kern code=\"8114\" val=\"-0.016\"/>\n    <Kern code=\"8115\" val=\"-0.016\"/>\n    <Kern code=\"8116\" val=\"-0.016\"/>\n    <Kern code=\"8118\" val=\"-0.016\"/>\n    <Kern code=\"8119\" val=\"-0.016\"/>\n    <Kern code=\"8166\" val=\"-0.064\"/>\n  </Char>\n  <Char code=\"956\" width=\"0.575\" height=\"0.445\" depth=\"0.235\" italic=\"0.001\" >\n    <Kern code=\"940\" val=\"-0.064\"/>\n    <Kern code=\"945\" val=\"-0.064\"/>\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"950\" val=\"-0.032\"/>\n    <Kern code=\"952\" val=\"-0.07\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.064\"/>\n    <Kern code=\"966\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.067\"/>\n    <Kern code=\"969\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.064\"/>\n    <Kern code=\"974\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.255\"/>\n    <Kern code=\"8048\" val=\"-0.064\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.064\"/>\n    <Kern code=\"8060\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.064\"/>\n    <Kern code=\"8115\" val=\"-0.064\"/>\n    <Kern code=\"8116\" val=\"-0.064\"/>\n    <Kern code=\"8118\" val=\"-0.064\"/>\n    <Kern code=\"8119\" val=\"-0.064\"/>\n    <Kern code=\"8166\" val=\"-0.064\"/>\n    <Kern code=\"8178\" val=\"-0.032\"/>\n    <Kern code=\"8179\" val=\"-0.032\"/>\n    <Kern code=\"8180\" val=\"-0.032\"/>\n    <Kern code=\"8182\" val=\"-0.032\"/>\n    <Kern code=\"8183\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"957\" width=\"0.479\" height=\"0.451\" depth=\"0.01\" italic=\"0.06\" >\n    <Kern code=\"940\" val=\"-0.026\"/>\n    <Kern code=\"945\" val=\"-0.026\"/>\n    <Kern code=\"955\" val=\"-0.051\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"961\" val=\"-0.006\"/>\n    <Kern code=\"969\" val=\"0.01\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"974\" val=\"0.01\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.026\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8060\" val=\"0.01\"/>\n    <Kern code=\"8114\" val=\"-0.026\"/>\n    <Kern code=\"8115\" val=\"-0.026\"/>\n    <Kern code=\"8116\" val=\"-0.026\"/>\n    <Kern code=\"8118\" val=\"-0.026\"/>\n    <Kern code=\"8119\" val=\"-0.026\"/>\n    <Kern code=\"8178\" val=\"0.01\"/>\n    <Kern code=\"8179\" val=\"0.01\"/>\n    <Kern code=\"8180\" val=\"0.01\"/>\n    <Kern code=\"8182\" val=\"0.01\"/>\n    <Kern code=\"8183\" val=\"0.01\"/>\n  </Char>\n  <Char code=\"958\" width=\"0.479\" height=\"0.696\" depth=\"0.188\" italic=\"0.031\" >\n    <Kern code=\"940\" val=\"-0.032\"/>\n    <Kern code=\"941\" val=\"-0.064\"/>\n    <Kern code=\"945\" val=\"-0.032\"/>\n    <Kern code=\"947\" val=\"-0.045\"/>\n    <Kern code=\"949\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.064\"/>\n    <Kern code=\"963\" val=\"-0.064\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"966\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.064\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.064\"/>\n    <Kern code=\"8048\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"-0.064\"/>\n    <Kern code=\"8056\" val=\"-0.064\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.032\"/>\n    <Kern code=\"8115\" val=\"-0.032\"/>\n    <Kern code=\"8116\" val=\"-0.032\"/>\n    <Kern code=\"8118\" val=\"-0.032\"/>\n    <Kern code=\"8119\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"959\" width=\"0.543\" height=\"0.452\" depth=\"0.006\" italic=\"0.019\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"964\" val=\"-0.038\"/>\n    <Kern code=\"965\" val=\"-0.064\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.064\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8058\" val=\"-0.064\"/>\n    <Kern code=\"8166\" val=\"-0.064\"/>\n  </Char>\n  <Char code=\"960\" width=\"0.655\" height=\"0.452\" depth=\"0.006\" italic=\"0.076\" >\n    <Kern code=\"943\" val=\"0.032\"/>\n    <Kern code=\"953\" val=\"0.032\"/>\n    <Kern code=\"954\" val=\"0.032\"/>\n    <Kern code=\"959\" val=\"-0.064\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"972\" val=\"-0.064\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8054\" val=\"0.032\"/>\n    <Kern code=\"8056\" val=\"-0.064\"/>\n    <Kern code=\"8150\" val=\"0.032\"/>\n  </Char>\n  <Char code=\"961\" width=\"0.543\" height=\"0.451\" depth=\"0.212\" italic=\"0.022\" >\n    <Kern code=\"943\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.064\"/>\n    <Kern code=\"950\" val=\"0.032\"/>\n    <Kern code=\"953\" val=\"0.032\"/>\n    <Kern code=\"957\" val=\"-0.057\"/>\n    <Kern code=\"959\" val=\"0.032\"/>\n    <Kern code=\"963\" val=\"0.032\"/>\n    <Kern code=\"967\" val=\"-0.013\"/>\n    <Kern code=\"968\" val=\"0.019\"/>\n    <Kern code=\"972\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8054\" val=\"0.032\"/>\n    <Kern code=\"8056\" val=\"0.032\"/>\n    <Kern code=\"8150\" val=\"0.032\"/>\n  </Char>\n  <Char code=\"962\" width=\"0.479\" height=\"0.452\" depth=\"0.159\" italic=\"0.034\" />\n  <Char code=\"963\" width=\"0.575\" height=\"0.476\" depth=\"0.005\" italic=\"0.076\" >\n    <Kern code=\"940\" val=\"-0.051\"/>\n    <Kern code=\"945\" val=\"-0.051\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"961\" val=\"-0.032\"/>\n    <Kern code=\"969\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"974\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.051\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8060\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.051\"/>\n    <Kern code=\"8115\" val=\"-0.051\"/>\n    <Kern code=\"8116\" val=\"-0.051\"/>\n    <Kern code=\"8118\" val=\"-0.051\"/>\n    <Kern code=\"8119\" val=\"-0.051\"/>\n    <Kern code=\"8164\" val=\"-0.032\"/>\n    <Kern code=\"8165\" val=\"-0.032\"/>\n    <Kern code=\"8178\" val=\"-0.032\"/>\n    <Kern code=\"8179\" val=\"-0.032\"/>\n    <Kern code=\"8180\" val=\"-0.032\"/>\n    <Kern code=\"8182\" val=\"-0.032\"/>\n    <Kern code=\"8183\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"964\" width=\"0.527\" height=\"0.484\" depth=\"0.005\" italic=\"0.074\" >\n    <Kern code=\"940\" val=\"-0.032\"/>\n    <Kern code=\"941\" val=\"-0.032\"/>\n    <Kern code=\"945\" val=\"-0.032\"/>\n    <Kern code=\"949\" val=\"-0.032\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"969\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"974\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8060\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.032\"/>\n    <Kern code=\"8115\" val=\"-0.032\"/>\n    <Kern code=\"8116\" val=\"-0.032\"/>\n    <Kern code=\"8118\" val=\"-0.032\"/>\n    <Kern code=\"8119\" val=\"-0.032\"/>\n    <Kern code=\"8178\" val=\"-0.032\"/>\n    <Kern code=\"8179\" val=\"-0.032\"/>\n    <Kern code=\"8180\" val=\"-0.032\"/>\n    <Kern code=\"8182\" val=\"-0.032\"/>\n    <Kern code=\"8183\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"965\" width=\"0.594\" height=\"0.462\" depth=\"0.005\" italic=\"0.018\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"966\" width=\"0.671\" height=\"0.452\" depth=\"0.218\" italic=\"0.031\" >\n    <Kern code=\"942\" val=\"-0.032\"/>\n    <Kern code=\"947\" val=\"-0.064\"/>\n    <Kern code=\"951\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.045\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.064\"/>\n    <Kern code=\"967\" val=\"-0.013\"/>\n    <Kern code=\"973\" val=\"-0.064\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8052\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.064\"/>\n    <Kern code=\"8130\" val=\"-0.032\"/>\n    <Kern code=\"8131\" val=\"-0.032\"/>\n    <Kern code=\"8132\" val=\"-0.032\"/>\n    <Kern code=\"8134\" val=\"-0.064\"/>\n    <Kern code=\"8135\" val=\"-0.064\"/>\n    <Kern code=\"8166\" val=\"-0.064\"/>\n  </Char>\n  <Char code=\"967\" width=\"0.543\" height=\"0.452\" depth=\"0.217\" italic=\"0.022\" >\n    <Kern code=\"940\" val=\"-0.077\"/>\n    <Kern code=\"941\" val=\"-0.032\"/>\n    <Kern code=\"942\" val=\"-0.067\"/>\n    <Kern code=\"943\" val=\"-0.032\"/>\n    <Kern code=\"945\" val=\"-0.077\"/>\n    <Kern code=\"947\" val=\"-0.051\"/>\n    <Kern code=\"948\" val=\"-0.077\"/>\n    <Kern code=\"949\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.067\"/>\n    <Kern code=\"952\" val=\"-0.064\"/>\n    <Kern code=\"953\" val=\"-0.032\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"955\" val=\"-0.077\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"958\" val=\"-0.051\"/>\n    <Kern code=\"959\" val=\"-0.096\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"961\" val=\"-0.051\"/>\n    <Kern code=\"963\" val=\"-0.045\"/>\n    <Kern code=\"964\" val=\"-0.051\"/>\n    <Kern code=\"965\" val=\"-0.051\"/>\n    <Kern code=\"966\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"969\" val=\"-0.077\"/>\n    <Kern code=\"972\" val=\"-0.096\"/>\n    <Kern code=\"973\" val=\"-0.051\"/>\n    <Kern code=\"974\" val=\"-0.077\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.077\"/>\n    <Kern code=\"8050\" val=\"-0.032\"/>\n    <Kern code=\"8052\" val=\"-0.067\"/>\n    <Kern code=\"8054\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.096\"/>\n    <Kern code=\"8058\" val=\"-0.051\"/>\n    <Kern code=\"8060\" val=\"-0.077\"/>\n    <Kern code=\"8114\" val=\"-0.077\"/>\n    <Kern code=\"8115\" val=\"-0.077\"/>\n    <Kern code=\"8116\" val=\"-0.077\"/>\n    <Kern code=\"8118\" val=\"-0.077\"/>\n    <Kern code=\"8119\" val=\"-0.077\"/>\n    <Kern code=\"8130\" val=\"-0.067\"/>\n    <Kern code=\"8131\" val=\"-0.067\"/>\n    <Kern code=\"8132\" val=\"-0.067\"/>\n    <Kern code=\"8134\" val=\"-0.067\"/>\n    <Kern code=\"8135\" val=\"-0.067\"/>\n    <Kern code=\"8150\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.051\"/>\n    <Kern code=\"8178\" val=\"-0.077\"/>\n    <Kern code=\"8179\" val=\"-0.077\"/>\n    <Kern code=\"8180\" val=\"-0.077\"/>\n    <Kern code=\"8182\" val=\"-0.077\"/>\n    <Kern code=\"8183\" val=\"-0.077\"/>\n  </Char>\n  <Char code=\"968\" width=\"0.639\" height=\"0.454\" depth=\"0.213\" italic=\"0.042\" >\n    <Kern code=\"947\" val=\"-0.045\"/>\n    <Kern code=\"965\" val=\"-0.064\"/>\n    <Kern code=\"967\" val=\"-0.006\"/>\n    <Kern code=\"973\" val=\"-0.064\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8058\" val=\"-0.064\"/>\n    <Kern code=\"8166\" val=\"-0.064\"/>\n  </Char>\n  <Char code=\"969\" width=\"0.766\" height=\"0.446\" depth=\"0.006\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"970\" width=\"0.287\" height=\"0.638\" depth=\"0.006\" italic=\"0.192\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"971\" width=\"0.575\" height=\"0.638\" depth=\"0.005\" italic=\"0.071\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"972\" width=\"0.543\" height=\"0.714\" depth=\"0.006\" italic=\"0.019\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"964\" val=\"-0.038\"/>\n    <Kern code=\"965\" val=\"-0.064\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.064\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8058\" val=\"-0.064\"/>\n    <Kern code=\"8166\" val=\"-0.064\"/>\n  </Char>\n  <Char code=\"973\" width=\"0.575\" height=\"0.713\" depth=\"0.005\" italic=\"0.037\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"974\" width=\"0.766\" height=\"0.713\" depth=\"0.006\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"984\" width=\"0.575\" height=\"0.694\" depth=\"0.003\" italic=\"0.096\" />\n  <Char code=\"985\" width=\"0.575\" height=\"0.451\" depth=\"0.222\" italic=\"0.003\" >\n    <Kern code=\"993\" val=\"-0.255\"/>\n  </Char>\n  <Char code=\"986\" width=\"0.894\" height=\"0.677\" italic=\"0.118\" />\n  <Char code=\"987\" width=\"0.575\" height=\"0.504\" depth=\"0.106\" italic=\"0.08\" >\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"988\" width=\"0.723\" height=\"0.681\" italic=\"0.102\" />\n  <Char code=\"989\" width=\"0.575\" height=\"0.696\" italic=\"0.14\" />\n  <Char code=\"991\" width=\"0.447\" height=\"0.696\" depth=\"0.211\" italic=\"0.047\" >\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"992\" width=\"0.881\" height=\"0.705\" />\n  <Char code=\"993\" width=\"0.83\" height=\"0.701\" depth=\"0.028\" >\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"7936\" width=\"0.639\" height=\"0.695\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"7937\" width=\"0.639\" height=\"0.696\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"7938\" width=\"0.639\" height=\"0.713\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"7939\" width=\"0.639\" height=\"0.713\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"7940\" width=\"0.639\" height=\"0.713\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"7941\" width=\"0.639\" height=\"0.714\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.051\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"7942\" width=\"0.639\" height=\"0.724\" depth=\"0.006\" italic=\"0.037\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"7943\" width=\"0.639\" height=\"0.724\" depth=\"0.006\" italic=\"0.037\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"7952\" width=\"0.447\" height=\"0.695\" depth=\"0.006\" italic=\"0.051\" >\n    <Kern code=\"940\" val=\"-0.032\"/>\n    <Kern code=\"945\" val=\"-0.032\"/>\n    <Kern code=\"948\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.01\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.032\"/>\n    <Kern code=\"8115\" val=\"-0.032\"/>\n    <Kern code=\"8116\" val=\"-0.032\"/>\n    <Kern code=\"8118\" val=\"-0.032\"/>\n    <Kern code=\"8119\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7953\" width=\"0.447\" height=\"0.696\" depth=\"0.006\" italic=\"0.051\" >\n    <Kern code=\"940\" val=\"-0.032\"/>\n    <Kern code=\"945\" val=\"-0.032\"/>\n    <Kern code=\"948\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.01\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.032\"/>\n    <Kern code=\"8115\" val=\"-0.032\"/>\n    <Kern code=\"8116\" val=\"-0.032\"/>\n    <Kern code=\"8118\" val=\"-0.032\"/>\n    <Kern code=\"8119\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7954\" width=\"0.447\" height=\"0.713\" depth=\"0.006\" italic=\"0.061\" >\n    <Kern code=\"940\" val=\"-0.032\"/>\n    <Kern code=\"945\" val=\"-0.032\"/>\n    <Kern code=\"948\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.01\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.032\"/>\n    <Kern code=\"8115\" val=\"-0.032\"/>\n    <Kern code=\"8116\" val=\"-0.032\"/>\n    <Kern code=\"8118\" val=\"-0.032\"/>\n    <Kern code=\"8119\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7955\" width=\"0.447\" height=\"0.714\" depth=\"0.006\" italic=\"0.061\" >\n    <Kern code=\"940\" val=\"-0.032\"/>\n    <Kern code=\"945\" val=\"-0.032\"/>\n    <Kern code=\"948\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.01\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.032\"/>\n    <Kern code=\"8115\" val=\"-0.032\"/>\n    <Kern code=\"8116\" val=\"-0.032\"/>\n    <Kern code=\"8118\" val=\"-0.032\"/>\n    <Kern code=\"8119\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7956\" width=\"0.447\" height=\"0.714\" depth=\"0.006\" italic=\"0.102\" >\n    <Kern code=\"940\" val=\"-0.032\"/>\n    <Kern code=\"945\" val=\"-0.032\"/>\n    <Kern code=\"948\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.01\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.032\"/>\n    <Kern code=\"8115\" val=\"-0.032\"/>\n    <Kern code=\"8116\" val=\"-0.032\"/>\n    <Kern code=\"8118\" val=\"-0.032\"/>\n    <Kern code=\"8119\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7957\" width=\"0.447\" height=\"0.713\" depth=\"0.006\" italic=\"0.102\" >\n    <Kern code=\"940\" val=\"-0.032\"/>\n    <Kern code=\"945\" val=\"-0.032\"/>\n    <Kern code=\"948\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.01\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.032\"/>\n    <Kern code=\"8115\" val=\"-0.032\"/>\n    <Kern code=\"8116\" val=\"-0.032\"/>\n    <Kern code=\"8118\" val=\"-0.032\"/>\n    <Kern code=\"8119\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7968\" width=\"0.594\" height=\"0.695\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7969\" width=\"0.594\" height=\"0.696\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7970\" width=\"0.594\" height=\"0.713\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7971\" width=\"0.594\" height=\"0.714\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7972\" width=\"0.594\" height=\"0.714\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7973\" width=\"0.594\" height=\"0.713\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7974\" width=\"0.594\" height=\"0.723\" depth=\"0.214\" italic=\"0.066\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7975\" width=\"0.594\" height=\"0.723\" depth=\"0.214\" italic=\"0.066\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7984\" width=\"0.287\" height=\"0.695\" depth=\"0.006\" italic=\"0.102\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7985\" width=\"0.287\" height=\"0.696\" depth=\"0.006\" italic=\"0.072\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7986\" width=\"0.287\" height=\"0.713\" depth=\"0.006\" italic=\"0.108\" />\n  <Char code=\"7987\" width=\"0.287\" height=\"0.714\" depth=\"0.006\" italic=\"0.108\" />\n  <Char code=\"7988\" width=\"0.287\" height=\"0.714\" depth=\"0.006\" italic=\"0.149\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7989\" width=\"0.287\" height=\"0.713\" depth=\"0.006\" italic=\"0.149\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7990\" width=\"0.287\" height=\"0.724\" depth=\"0.006\" italic=\"0.2\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7991\" width=\"0.287\" height=\"0.724\" depth=\"0.006\" italic=\"0.2\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8000\" width=\"0.543\" height=\"0.695\" depth=\"0.006\" italic=\"0.024\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"964\" val=\"-0.038\"/>\n    <Kern code=\"965\" val=\"-0.064\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.064\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8058\" val=\"-0.064\"/>\n    <Kern code=\"8166\" val=\"-0.064\"/>\n  </Char>\n  <Char code=\"8001\" width=\"0.543\" height=\"0.696\" depth=\"0.006\" italic=\"0.019\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"964\" val=\"-0.038\"/>\n    <Kern code=\"965\" val=\"-0.064\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.064\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8058\" val=\"-0.064\"/>\n    <Kern code=\"8166\" val=\"-0.064\"/>\n  </Char>\n  <Char code=\"8002\" width=\"0.543\" height=\"0.713\" depth=\"0.006\" italic=\"0.019\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"964\" val=\"-0.038\"/>\n    <Kern code=\"965\" val=\"-0.064\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.064\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8058\" val=\"-0.064\"/>\n    <Kern code=\"8166\" val=\"-0.064\"/>\n  </Char>\n  <Char code=\"8003\" width=\"0.543\" height=\"0.714\" depth=\"0.006\" italic=\"0.019\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"964\" val=\"-0.038\"/>\n    <Kern code=\"965\" val=\"-0.064\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.064\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8058\" val=\"-0.064\"/>\n    <Kern code=\"8166\" val=\"-0.064\"/>\n  </Char>\n  <Char code=\"8004\" width=\"0.543\" height=\"0.714\" depth=\"0.006\" italic=\"0.054\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"964\" val=\"-0.038\"/>\n    <Kern code=\"965\" val=\"-0.064\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.064\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8058\" val=\"-0.064\"/>\n    <Kern code=\"8166\" val=\"-0.064\"/>\n  </Char>\n  <Char code=\"8005\" width=\"0.543\" height=\"0.713\" depth=\"0.006\" italic=\"0.054\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"964\" val=\"-0.038\"/>\n    <Kern code=\"965\" val=\"-0.064\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.064\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8058\" val=\"-0.064\"/>\n    <Kern code=\"8166\" val=\"-0.064\"/>\n  </Char>\n  <Char code=\"8016\" width=\"0.575\" height=\"0.695\" depth=\"0.005\" italic=\"0.037\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"8017\" width=\"0.575\" height=\"0.696\" depth=\"0.005\" italic=\"0.037\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"8018\" width=\"0.575\" height=\"0.714\" depth=\"0.005\" italic=\"0.037\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"8019\" width=\"0.575\" height=\"0.714\" depth=\"0.005\" italic=\"0.037\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"8020\" width=\"0.575\" height=\"0.713\" depth=\"0.005\" italic=\"0.037\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"8021\" width=\"0.575\" height=\"0.714\" depth=\"0.005\" italic=\"0.037\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"8022\" width=\"0.575\" height=\"0.724\" depth=\"0.005\" italic=\"0.081\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"8023\" width=\"0.575\" height=\"0.724\" depth=\"0.005\" italic=\"0.081\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"8032\" width=\"0.766\" height=\"0.695\" depth=\"0.006\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8033\" width=\"0.766\" height=\"0.696\" depth=\"0.006\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8034\" width=\"0.766\" height=\"0.713\" depth=\"0.006\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8035\" width=\"0.766\" height=\"0.714\" depth=\"0.006\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8036\" width=\"0.766\" height=\"0.714\" depth=\"0.006\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8037\" width=\"0.766\" height=\"0.714\" depth=\"0.006\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8038\" width=\"0.766\" height=\"0.724\" depth=\"0.006\" italic=\"0.027\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8039\" width=\"0.766\" height=\"0.724\" depth=\"0.006\" italic=\"0.027\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8048\" width=\"0.639\" height=\"0.713\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8050\" width=\"0.447\" height=\"0.714\" depth=\"0.006\" italic=\"0.051\" >\n    <Kern code=\"940\" val=\"-0.032\"/>\n    <Kern code=\"945\" val=\"-0.032\"/>\n    <Kern code=\"948\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.01\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.032\"/>\n    <Kern code=\"8115\" val=\"-0.032\"/>\n    <Kern code=\"8116\" val=\"-0.032\"/>\n    <Kern code=\"8118\" val=\"-0.032\"/>\n    <Kern code=\"8119\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8052\" width=\"0.594\" height=\"0.714\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8054\" width=\"0.287\" height=\"0.714\" depth=\"0.006\" italic=\"0.018\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8056\" width=\"0.543\" height=\"0.714\" depth=\"0.006\" italic=\"0.019\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"964\" val=\"-0.038\"/>\n    <Kern code=\"965\" val=\"-0.064\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.064\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8058\" val=\"-0.064\"/>\n    <Kern code=\"8166\" val=\"-0.064\"/>\n  </Char>\n  <Char code=\"8058\" width=\"0.575\" height=\"0.714\" depth=\"0.005\" italic=\"0.037\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"8060\" width=\"0.766\" height=\"0.714\" depth=\"0.006\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8064\" width=\"0.639\" height=\"0.695\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8065\" width=\"0.639\" height=\"0.696\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8066\" width=\"0.639\" height=\"0.713\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8067\" width=\"0.639\" height=\"0.713\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8068\" width=\"0.639\" height=\"0.713\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8069\" width=\"0.639\" height=\"0.714\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.051\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8070\" width=\"0.639\" height=\"0.724\" depth=\"0.211\" italic=\"0.037\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8071\" width=\"0.639\" height=\"0.724\" depth=\"0.211\" italic=\"0.037\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8080\" width=\"0.594\" height=\"0.695\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8081\" width=\"0.594\" height=\"0.696\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8082\" width=\"0.594\" height=\"0.713\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8083\" width=\"0.594\" height=\"0.714\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8084\" width=\"0.594\" height=\"0.714\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8085\" width=\"0.594\" height=\"0.713\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8086\" width=\"0.594\" height=\"0.723\" depth=\"0.214\" italic=\"0.066\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8087\" width=\"0.594\" height=\"0.723\" depth=\"0.214\" italic=\"0.066\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8096\" width=\"0.766\" height=\"0.695\" depth=\"0.211\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8097\" width=\"0.766\" height=\"0.696\" depth=\"0.211\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8098\" width=\"0.766\" height=\"0.713\" depth=\"0.211\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8099\" width=\"0.766\" height=\"0.714\" depth=\"0.211\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8100\" width=\"0.766\" height=\"0.714\" depth=\"0.211\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8101\" width=\"0.766\" height=\"0.714\" depth=\"0.211\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8102\" width=\"0.766\" height=\"0.724\" depth=\"0.211\" italic=\"0.027\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8103\" width=\"0.766\" height=\"0.724\" depth=\"0.211\" italic=\"0.027\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8114\" width=\"0.639\" height=\"0.713\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8115\" width=\"0.639\" height=\"0.452\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.109\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"993\" val=\"-0.255\"/>\n    <Kern code=\"8016\" val=\"-0.096\"/>\n    <Kern code=\"8018\" val=\"-0.096\"/>\n    <Kern code=\"8020\" val=\"-0.096\"/>\n    <Kern code=\"8021\" val=\"-0.096\"/>\n    <Kern code=\"8022\" val=\"-0.096\"/>\n    <Kern code=\"8023\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n    <Kern code=\"8166\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8116\" width=\"0.639\" height=\"0.714\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8118\" width=\"0.639\" height=\"0.636\" depth=\"0.006\" italic=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8119\" width=\"0.639\" height=\"0.636\" depth=\"0.211\" italic=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8124\" width=\"0.869\" height=\"0.7\" depth=\"0.211\" >\n    <Kern code=\"920\" val=\"-0.096\"/>\n    <Kern code=\"927\" val=\"-0.096\"/>\n    <Kern code=\"932\" val=\"-0.096\"/>\n    <Kern code=\"933\" val=\"-0.16\"/>\n    <Kern code=\"934\" val=\"-0.096\"/>\n    <Kern code=\"936\" val=\"-0.141\"/>\n    <Kern code=\"939\" val=\"-0.16\"/>\n    <Kern code=\"957\" val=\"-0.112\"/>\n  </Char>\n  <Char code=\"8126\" width=\"0.255\" height=\"0.157\" depth=\"0.155\" italic=\"0.006\" />\n  <Char code=\"8127\" width=\"0.255\" height=\"0.695\" italic=\"0.168\" >\n    <Kern code=\"913\" val=\"-0.16\"/>\n    <Kern code=\"927\" val=\"-0.064\"/>\n    <Kern code=\"937\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.16\"/>\n    <Kern code=\"8188\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8128\" width=\"0.383\" height=\"0.635\" italic=\"0.16\" >\n    <Kern code=\"913\" val=\"-0.128\"/>\n    <Kern code=\"8124\" val=\"-0.128\"/>\n  </Char>\n  <Char code=\"8129\" width=\"0.511\" height=\"0.723\" italic=\"0.122\" />\n  <Char code=\"8130\" width=\"0.594\" height=\"0.714\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8131\" width=\"0.594\" height=\"0.452\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8132\" width=\"0.594\" height=\"0.713\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8134\" width=\"0.594\" height=\"0.636\" depth=\"0.214\" italic=\"0.04\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8135\" width=\"0.594\" height=\"0.636\" depth=\"0.214\" italic=\"0.04\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8140\" width=\"0.9\" height=\"0.687\" depth=\"0.211\" italic=\"0.144\" />\n  <Char code=\"8141\" width=\"0.319\" height=\"0.713\" italic=\"0.125\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"927\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8142\" width=\"0.319\" height=\"0.714\" italic=\"0.166\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"927\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8143\" width=\"0.383\" height=\"0.724\" italic=\"0.186\" >\n    <Kern code=\"913\" val=\"-0.128\"/>\n    <Kern code=\"8124\" val=\"-0.128\"/>\n  </Char>\n  <Char code=\"8146\" width=\"0.287\" height=\"0.714\" depth=\"0.006\" italic=\"0.188\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8150\" width=\"0.287\" height=\"0.636\" depth=\"0.006\" italic=\"0.174\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8151\" width=\"0.287\" height=\"0.724\" depth=\"0.006\" italic=\"0.2\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8157\" width=\"0.319\" height=\"0.714\" italic=\"0.125\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"927\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8158\" width=\"0.319\" height=\"0.713\" italic=\"0.166\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"927\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8159\" width=\"0.383\" height=\"0.724\" italic=\"0.186\" >\n    <Kern code=\"913\" val=\"-0.128\"/>\n    <Kern code=\"8124\" val=\"-0.128\"/>\n  </Char>\n  <Char code=\"8162\" width=\"0.575\" height=\"0.739\" depth=\"0.005\" italic=\"0.07\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"8164\" width=\"0.543\" height=\"0.695\" depth=\"0.212\" italic=\"0.024\" >\n    <Kern code=\"943\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.064\"/>\n    <Kern code=\"950\" val=\"0.032\"/>\n    <Kern code=\"953\" val=\"0.032\"/>\n    <Kern code=\"957\" val=\"-0.057\"/>\n    <Kern code=\"959\" val=\"0.032\"/>\n    <Kern code=\"963\" val=\"0.032\"/>\n    <Kern code=\"967\" val=\"-0.013\"/>\n    <Kern code=\"968\" val=\"0.019\"/>\n    <Kern code=\"972\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8054\" val=\"0.032\"/>\n    <Kern code=\"8056\" val=\"0.032\"/>\n    <Kern code=\"8150\" val=\"0.032\"/>\n  </Char>\n  <Char code=\"8165\" width=\"0.543\" height=\"0.696\" depth=\"0.212\" italic=\"0.022\" >\n    <Kern code=\"943\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.064\"/>\n    <Kern code=\"950\" val=\"0.032\"/>\n    <Kern code=\"953\" val=\"0.032\"/>\n    <Kern code=\"957\" val=\"-0.057\"/>\n    <Kern code=\"959\" val=\"0.032\"/>\n    <Kern code=\"963\" val=\"0.032\"/>\n    <Kern code=\"967\" val=\"-0.013\"/>\n    <Kern code=\"968\" val=\"0.019\"/>\n    <Kern code=\"972\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8054\" val=\"0.032\"/>\n    <Kern code=\"8056\" val=\"0.032\"/>\n    <Kern code=\"8150\" val=\"0.032\"/>\n  </Char>\n  <Char code=\"8166\" width=\"0.575\" height=\"0.636\" depth=\"0.005\" italic=\"0.055\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"8167\" width=\"0.575\" height=\"0.724\" depth=\"0.005\" italic=\"0.081\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"8173\" width=\"0.319\" height=\"0.714\" italic=\"0.206\" />\n  <Char code=\"8175\" width=\"0.192\" height=\"0.714\" italic=\"0.131\" >\n    <Kern code=\"913\" val=\"-0.128\"/>\n    <Kern code=\"927\" val=\"-0.064\"/>\n    <Kern code=\"937\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.128\"/>\n    <Kern code=\"8188\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8178\" width=\"0.766\" height=\"0.714\" depth=\"0.211\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8179\" width=\"0.766\" height=\"0.446\" depth=\"0.211\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8180\" width=\"0.766\" height=\"0.713\" depth=\"0.211\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8182\" width=\"0.766\" height=\"0.635\" depth=\"0.006\" italic=\"0.001\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8183\" width=\"0.766\" height=\"0.635\" depth=\"0.211\" italic=\"0.001\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8188\" width=\"0.83\" height=\"0.698\" depth=\"0.211\" italic=\"0.065\" />\n  <Char code=\"8190\" width=\"0.255\" height=\"0.696\" italic=\"0.106\" >\n    <Kern code=\"913\" val=\"-0.192\"/>\n    <Kern code=\"927\" val=\"-0.064\"/>\n    <Kern code=\"937\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.192\"/>\n    <Kern code=\"8188\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8217\" width=\"0.319\" height=\"0.696\" italic=\"0.095\" >\n  </Char>\n  <Char code=\"9001\" width=\"0.473\" height=\"0.751\" depth=\"0.25\" italic=\"0.091\" />\n  <Char code=\"9002\" width=\"0.473\" height=\"0.751\" depth=\"0.25\" />\n</Font>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/greek/fcmbpg.xml",
    "content": "<?xml version='1.0'?>\n<Font name=\"fcmbpg.ttf\" id=\"fcmbpg\" space=\"0.319\" xHeight=\"0.451\" quad=\"1\" unicode=\"205\" itVersion=\"fcmbipg\" ssVersion=\"fcsbpg\" ttVersion=\"fctrpg\">\n  <Char code=\"32\" width=\"0.319\" height=\"0.0\" />\n  <Char code=\"168\" width=\"0.255\" height=\"0.645\" italic=\"0.061\" />\n  <Char code=\"884\" width=\"0.224\" height=\"0.712\" />\n  <Char code=\"885\" width=\"0.224\" height=\"0.007\" depth=\"0.216\" />\n  <Char code=\"890\" width=\"0.128\" height=\"-0.053\" depth=\"0.241\" />\n  <Char code=\"900\" width=\"0.192\" height=\"0.712\" >\n    <Kern code=\"913\" val=\"-0.128\"/>\n    <Kern code=\"927\" val=\"-0.064\"/>\n    <Kern code=\"937\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.128\"/>\n    <Kern code=\"8188\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"901\" width=\"0.319\" height=\"0.711\" italic=\"0.031\" />\n  <Char code=\"903\" width=\"0.319\" height=\"0.445\" />\n  <Char code=\"912\" width=\"0.287\" height=\"0.711\" depth=\"0.007\" italic=\"0.028\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.019\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"913\" width=\"0.869\" height=\"0.7\" >\n    <Kern code=\"920\" val=\"-0.096\"/>\n    <Kern code=\"927\" val=\"-0.096\"/>\n    <Kern code=\"932\" val=\"-0.096\"/>\n    <Kern code=\"933\" val=\"-0.16\"/>\n    <Kern code=\"934\" val=\"-0.096\"/>\n    <Kern code=\"936\" val=\"-0.141\"/>\n    <Kern code=\"939\" val=\"-0.16\"/>\n  </Char>\n  <Char code=\"914\" width=\"0.818\" height=\"0.688\" />\n  <Char code=\"915\" width=\"0.691\" height=\"0.681\" >\n    <Kern code=\"913\" val=\"-0.153\"/>\n    <Kern code=\"916\" val=\"-0.128\"/>\n    <Kern code=\"923\" val=\"-0.141\"/>\n    <Kern code=\"8124\" val=\"-0.153\"/>\n  </Char>\n  <Char code=\"916\" width=\"0.958\" height=\"0.699\" >\n    <Kern code=\"927\" val=\"-0.038\"/>\n    <Kern code=\"933\" val=\"-0.16\"/>\n    <Kern code=\"939\" val=\"-0.16\"/>\n  </Char>\n  <Char code=\"917\" width=\"0.755\" height=\"0.681\" />\n  <Char code=\"918\" width=\"0.703\" height=\"0.687\" />\n  <Char code=\"919\" width=\"0.9\" height=\"0.687\" />\n  <Char code=\"920\" width=\"0.894\" height=\"0.699\" depth=\"0.011\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"921\" width=\"0.436\" height=\"0.687\" />\n  <Char code=\"922\" width=\"0.901\" height=\"0.687\" >\n    <Kern code=\"927\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"923\" width=\"0.805\" height=\"0.7\" >\n    <Kern code=\"927\" val=\"-0.038\"/>\n    <Kern code=\"933\" val=\"-0.115\"/>\n    <Kern code=\"939\" val=\"-0.115\"/>\n  </Char>\n  <Char code=\"924\" width=\"1.091\" height=\"0.688\" />\n  <Char code=\"925\" width=\"0.9\" height=\"0.687\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"926\" width=\"0.766\" height=\"0.676\" />\n  <Char code=\"927\" width=\"0.864\" height=\"0.699\" depth=\"0.011\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"931\" val=\"-0.064\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"928\" width=\"0.9\" height=\"0.681\" />\n  <Char code=\"929\" width=\"0.786\" height=\"0.688\" >\n    <Kern code=\"913\" val=\"-0.192\"/>\n    <Kern code=\"8124\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"931\" width=\"0.83\" height=\"0.687\" >\n    <Kern code=\"913\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"932\" width=\"0.8\" height=\"0.676\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"933\" width=\"0.894\" height=\"0.699\" >\n    <Kern code=\"913\" val=\"-0.16\"/>\n    <Kern code=\"916\" val=\"-0.16\"/>\n    <Kern code=\"923\" val=\"-0.16\"/>\n    <Kern code=\"8124\" val=\"-0.16\"/>\n  </Char>\n  <Char code=\"934\" width=\"0.83\" height=\"0.687\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"935\" width=\"0.869\" height=\"0.687\" />\n  <Char code=\"936\" width=\"0.894\" height=\"0.687\" >\n    <Kern code=\"913\" val=\"-0.141\"/>\n    <Kern code=\"8124\" val=\"-0.141\"/>\n  </Char>\n  <Char code=\"937\" width=\"0.83\" height=\"0.698\" />\n  <Char code=\"938\" width=\"0.436\" height=\"0.893\" />\n  <Char code=\"939\" width=\"0.894\" height=\"0.892\" >\n    <Kern code=\"913\" val=\"-0.16\"/>\n    <Kern code=\"916\" val=\"-0.16\"/>\n    <Kern code=\"923\" val=\"-0.16\"/>\n    <Kern code=\"8124\" val=\"-0.16\"/>\n  </Char>\n  <Char code=\"940\" width=\"0.575\" height=\"0.711\" depth=\"0.006\" italic=\"0.029\" />\n  <Char code=\"941\" width=\"0.495\" height=\"0.711\" depth=\"0.01\" />\n  <Char code=\"942\" width=\"0.575\" height=\"0.712\" depth=\"0.26\" />\n  <Char code=\"943\" width=\"0.287\" height=\"0.711\" depth=\"0.007\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.031\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"944\" width=\"0.575\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"945\" width=\"0.575\" height=\"0.452\" depth=\"0.006\" italic=\"0.029\" />\n  <Char code=\"946\" width=\"0.575\" height=\"0.701\" depth=\"0.269\" />\n  <Char code=\"947\" width=\"0.639\" height=\"0.452\" depth=\"0.2\" />\n  <Char code=\"948\" width=\"0.543\" height=\"0.704\" depth=\"0.006\" />\n  <Char code=\"949\" width=\"0.495\" height=\"0.456\" depth=\"0.01\" />\n  <Char code=\"950\" width=\"0.543\" height=\"0.707\" depth=\"0.207\" />\n  <Char code=\"951\" width=\"0.575\" height=\"0.456\" depth=\"0.26\" />\n  <Char code=\"952\" width=\"0.519\" height=\"0.706\" depth=\"0.012\" />\n  <Char code=\"953\" width=\"0.287\" height=\"0.452\" depth=\"0.007\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.031\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"954\" width=\"0.607\" height=\"0.457\" depth=\"0.011\" />\n  <Char code=\"955\" width=\"0.575\" height=\"0.698\" depth=\"0.005\" />\n  <Char code=\"956\" width=\"0.622\" height=\"0.457\" depth=\"0.257\" />\n  <Char code=\"957\" width=\"0.543\" height=\"0.452\" depth=\"0.005\" />\n  <Char code=\"958\" width=\"0.543\" height=\"0.707\" depth=\"0.206\" />\n  <Char code=\"959\" width=\"0.607\" height=\"0.452\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.026\"/>\n    <Kern code=\"964\" val=\"-0.026\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"960\" width=\"0.591\" height=\"0.446\" depth=\"0.021\" />\n  <Char code=\"961\" width=\"0.543\" height=\"0.452\" depth=\"0.256\" />\n  <Char code=\"962\" width=\"0.511\" height=\"0.451\" depth=\"0.125\" />\n  <Char code=\"963\" width=\"0.655\" height=\"0.446\" depth=\"0.006\" />\n  <Char code=\"964\" width=\"0.527\" height=\"0.446\" depth=\"0.006\" >\n    <Kern code=\"940\" val=\"-0.032\"/>\n    <Kern code=\"945\" val=\"-0.032\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"969\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"974\" val=\"-0.032\"/>\n    <Kern code=\"7936\" val=\"-0.032\"/>\n    <Kern code=\"7937\" val=\"-0.032\"/>\n    <Kern code=\"7940\" val=\"-0.032\"/>\n    <Kern code=\"7941\" val=\"-0.032\"/>\n    <Kern code=\"7942\" val=\"-0.032\"/>\n    <Kern code=\"7943\" val=\"-0.032\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8032\" val=\"-0.032\"/>\n    <Kern code=\"8033\" val=\"-0.032\"/>\n    <Kern code=\"8036\" val=\"-0.032\"/>\n    <Kern code=\"8037\" val=\"-0.032\"/>\n    <Kern code=\"8038\" val=\"-0.032\"/>\n    <Kern code=\"8039\" val=\"-0.032\"/>\n    <Kern code=\"8048\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8060\" val=\"-0.032\"/>\n    <Kern code=\"8064\" val=\"-0.032\"/>\n    <Kern code=\"8065\" val=\"-0.032\"/>\n    <Kern code=\"8068\" val=\"-0.032\"/>\n    <Kern code=\"8069\" val=\"-0.032\"/>\n    <Kern code=\"8070\" val=\"-0.032\"/>\n    <Kern code=\"8071\" val=\"-0.032\"/>\n    <Kern code=\"8096\" val=\"-0.032\"/>\n    <Kern code=\"8097\" val=\"-0.032\"/>\n    <Kern code=\"8100\" val=\"-0.032\"/>\n    <Kern code=\"8101\" val=\"-0.032\"/>\n    <Kern code=\"8102\" val=\"-0.032\"/>\n    <Kern code=\"8103\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.032\"/>\n    <Kern code=\"8116\" val=\"-0.032\"/>\n    <Kern code=\"8118\" val=\"-0.032\"/>\n    <Kern code=\"8119\" val=\"-0.032\"/>\n    <Kern code=\"8178\" val=\"-0.032\"/>\n    <Kern code=\"8180\" val=\"-0.032\"/>\n    <Kern code=\"8182\" val=\"-0.032\"/>\n    <Kern code=\"8183\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"965\" width=\"0.575\" height=\"0.468\" depth=\"0.006\" />\n  <Char code=\"966\" width=\"0.671\" height=\"0.462\" depth=\"0.268\" />\n  <Char code=\"967\" width=\"0.639\" height=\"0.452\" depth=\"0.256\" />\n  <Char code=\"968\" width=\"0.671\" height=\"0.711\" depth=\"0.268\" />\n  <Char code=\"969\" width=\"0.766\" height=\"0.457\" depth=\"0.006\" />\n  <Char code=\"970\" width=\"0.287\" height=\"0.641\" depth=\"0.007\" italic=\"0.054\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.019\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"971\" width=\"0.575\" height=\"0.641\" depth=\"0.006\" />\n  <Char code=\"972\" width=\"0.607\" height=\"0.711\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.026\"/>\n    <Kern code=\"964\" val=\"-0.026\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"973\" width=\"0.575\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"974\" width=\"0.766\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"977\" width=\"0.655\" height=\"0.701\" depth=\"0.006\" />\n  <Char code=\"984\" width=\"0.575\" height=\"0.693\" depth=\"0.003\" />\n  <Char code=\"985\" width=\"0.575\" height=\"0.64\" depth=\"0.094\" />\n  <Char code=\"986\" width=\"0.894\" height=\"0.677\" />\n  <Char code=\"987\" width=\"0.575\" height=\"0.457\" depth=\"0.024\" />\n  <Char code=\"988\" width=\"0.723\" height=\"0.681\" />\n  <Char code=\"989\" width=\"0.575\" height=\"0.446\" depth=\"0.265\" />\n  <Char code=\"991\" width=\"0.447\" height=\"0.618\" depth=\"0.144\" />\n  <Char code=\"992\" width=\"0.881\" height=\"0.706\" />\n  <Char code=\"993\" width=\"0.83\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"7936\" width=\"0.575\" height=\"0.696\" depth=\"0.006\" italic=\"0.029\" />\n  <Char code=\"7937\" width=\"0.575\" height=\"0.696\" depth=\"0.006\" italic=\"0.029\" />\n  <Char code=\"7938\" width=\"0.575\" height=\"0.711\" depth=\"0.006\" italic=\"0.029\" />\n  <Char code=\"7939\" width=\"0.575\" height=\"0.711\" depth=\"0.006\" italic=\"0.029\" />\n  <Char code=\"7940\" width=\"0.575\" height=\"0.711\" depth=\"0.006\" italic=\"0.029\" />\n  <Char code=\"7941\" width=\"0.575\" height=\"0.711\" depth=\"0.006\" italic=\"0.029\" />\n  <Char code=\"7942\" width=\"0.575\" height=\"0.696\" depth=\"0.006\" italic=\"0.029\" />\n  <Char code=\"7943\" width=\"0.575\" height=\"0.696\" depth=\"0.006\" italic=\"0.029\" />\n  <Char code=\"7952\" width=\"0.495\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"7953\" width=\"0.495\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"7954\" width=\"0.495\" height=\"0.711\" depth=\"0.01\" />\n  <Char code=\"7955\" width=\"0.495\" height=\"0.711\" depth=\"0.01\" />\n  <Char code=\"7956\" width=\"0.495\" height=\"0.711\" depth=\"0.01\" />\n  <Char code=\"7957\" width=\"0.495\" height=\"0.711\" depth=\"0.01\" />\n  <Char code=\"7968\" width=\"0.575\" height=\"0.696\" depth=\"0.26\" />\n  <Char code=\"7969\" width=\"0.575\" height=\"0.696\" depth=\"0.26\" />\n  <Char code=\"7970\" width=\"0.575\" height=\"0.712\" depth=\"0.26\" />\n  <Char code=\"7971\" width=\"0.575\" height=\"0.712\" depth=\"0.26\" />\n  <Char code=\"7972\" width=\"0.575\" height=\"0.712\" depth=\"0.26\" />\n  <Char code=\"7973\" width=\"0.575\" height=\"0.712\" depth=\"0.26\" />\n  <Char code=\"7974\" width=\"0.575\" height=\"0.696\" depth=\"0.26\" />\n  <Char code=\"7975\" width=\"0.575\" height=\"0.696\" depth=\"0.26\" />\n  <Char code=\"7984\" width=\"0.287\" height=\"0.696\" depth=\"0.007\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.031\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"7985\" width=\"0.287\" height=\"0.696\" depth=\"0.007\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.031\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"7986\" width=\"0.287\" height=\"0.711\" depth=\"0.007\" />\n  <Char code=\"7987\" width=\"0.287\" height=\"0.711\" depth=\"0.007\" />\n  <Char code=\"7988\" width=\"0.287\" height=\"0.711\" depth=\"0.007\" italic=\"0.001\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.019\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"7989\" width=\"0.287\" height=\"0.711\" depth=\"0.007\" italic=\"0.001\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.019\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"7990\" width=\"0.287\" height=\"0.696\" depth=\"0.007\" italic=\"0.029\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.019\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"7991\" width=\"0.287\" height=\"0.696\" depth=\"0.007\" italic=\"0.029\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.019\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"8000\" width=\"0.607\" height=\"0.696\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.026\"/>\n    <Kern code=\"964\" val=\"-0.026\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8001\" width=\"0.607\" height=\"0.696\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.026\"/>\n    <Kern code=\"964\" val=\"-0.026\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8002\" width=\"0.607\" height=\"0.711\" depth=\"0.006\" />\n  <Char code=\"8003\" width=\"0.607\" height=\"0.711\" depth=\"0.006\" />\n  <Char code=\"8004\" width=\"0.607\" height=\"0.711\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.026\"/>\n    <Kern code=\"964\" val=\"-0.026\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8005\" width=\"0.607\" height=\"0.711\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.026\"/>\n    <Kern code=\"964\" val=\"-0.026\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8016\" width=\"0.575\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8017\" width=\"0.575\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8018\" width=\"0.575\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"8019\" width=\"0.575\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"8020\" width=\"0.575\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"8021\" width=\"0.575\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"8022\" width=\"0.575\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8023\" width=\"0.575\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8032\" width=\"0.766\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8033\" width=\"0.766\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8034\" width=\"0.766\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"8035\" width=\"0.766\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"8036\" width=\"0.766\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"8037\" width=\"0.766\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"8038\" width=\"0.766\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8039\" width=\"0.766\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8048\" width=\"0.575\" height=\"0.711\" depth=\"0.006\" italic=\"0.029\" />\n  <Char code=\"8050\" width=\"0.495\" height=\"0.711\" depth=\"0.01\" />\n  <Char code=\"8052\" width=\"0.575\" height=\"0.712\" depth=\"0.26\" />\n  <Char code=\"8054\" width=\"0.287\" height=\"0.711\" depth=\"0.007\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.019\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"8056\" width=\"0.607\" height=\"0.711\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.026\"/>\n    <Kern code=\"964\" val=\"-0.026\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8058\" width=\"0.575\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"8060\" width=\"0.766\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"8064\" width=\"0.575\" height=\"0.696\" depth=\"0.241\" italic=\"0.029\" />\n  <Char code=\"8065\" width=\"0.575\" height=\"0.696\" depth=\"0.241\" italic=\"0.029\" />\n  <Char code=\"8066\" width=\"0.575\" height=\"0.711\" depth=\"0.241\" italic=\"0.029\" />\n  <Char code=\"8067\" width=\"0.575\" height=\"0.711\" depth=\"0.241\" italic=\"0.029\" />\n  <Char code=\"8068\" width=\"0.575\" height=\"0.711\" depth=\"0.241\" italic=\"0.029\" />\n  <Char code=\"8069\" width=\"0.575\" height=\"0.711\" depth=\"0.241\" italic=\"0.029\" />\n  <Char code=\"8070\" width=\"0.575\" height=\"0.696\" depth=\"0.241\" italic=\"0.029\" />\n  <Char code=\"8071\" width=\"0.575\" height=\"0.696\" depth=\"0.241\" italic=\"0.029\" />\n  <Char code=\"8080\" width=\"0.575\" height=\"0.696\" depth=\"0.26\" />\n  <Char code=\"8081\" width=\"0.575\" height=\"0.696\" depth=\"0.26\" />\n  <Char code=\"8082\" width=\"0.575\" height=\"0.712\" depth=\"0.26\" />\n  <Char code=\"8083\" width=\"0.575\" height=\"0.712\" depth=\"0.26\" />\n  <Char code=\"8084\" width=\"0.575\" height=\"0.712\" depth=\"0.26\" />\n  <Char code=\"8085\" width=\"0.575\" height=\"0.712\" depth=\"0.26\" />\n  <Char code=\"8086\" width=\"0.575\" height=\"0.696\" depth=\"0.26\" />\n  <Char code=\"8087\" width=\"0.575\" height=\"0.696\" depth=\"0.26\" />\n  <Char code=\"8096\" width=\"0.766\" height=\"0.696\" depth=\"0.241\" />\n  <Char code=\"8097\" width=\"0.766\" height=\"0.696\" depth=\"0.241\" />\n  <Char code=\"8098\" width=\"0.766\" height=\"0.712\" depth=\"0.241\" />\n  <Char code=\"8099\" width=\"0.766\" height=\"0.712\" depth=\"0.241\" />\n  <Char code=\"8100\" width=\"0.766\" height=\"0.712\" depth=\"0.241\" />\n  <Char code=\"8101\" width=\"0.766\" height=\"0.712\" depth=\"0.241\" />\n  <Char code=\"8102\" width=\"0.766\" height=\"0.696\" depth=\"0.241\" />\n  <Char code=\"8103\" width=\"0.766\" height=\"0.696\" depth=\"0.241\" />\n  <Char code=\"8114\" width=\"0.575\" height=\"0.711\" depth=\"0.241\" italic=\"0.029\" />\n  <Char code=\"8115\" width=\"0.575\" height=\"0.452\" depth=\"0.241\" italic=\"0.029\" />\n  <Char code=\"8116\" width=\"0.575\" height=\"0.711\" depth=\"0.241\" italic=\"0.029\" />\n  <Char code=\"8118\" width=\"0.575\" height=\"0.641\" depth=\"0.006\" italic=\"0.029\" />\n  <Char code=\"8119\" width=\"0.575\" height=\"0.641\" depth=\"0.241\" italic=\"0.029\" />\n  <Char code=\"8124\" width=\"0.869\" height=\"0.7\" depth=\"0.241\" >\n    <Kern code=\"920\" val=\"-0.096\"/>\n    <Kern code=\"927\" val=\"-0.096\"/>\n    <Kern code=\"932\" val=\"-0.096\"/>\n    <Kern code=\"933\" val=\"-0.16\"/>\n    <Kern code=\"934\" val=\"-0.096\"/>\n    <Kern code=\"936\" val=\"-0.141\"/>\n    <Kern code=\"939\" val=\"-0.16\"/>\n  </Char>\n  <Char code=\"8126\" width=\"0.255\" height=\"0.157\" depth=\"0.155\" />\n  <Char code=\"8127\" width=\"0.255\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.16\"/>\n    <Kern code=\"927\" val=\"-0.064\"/>\n    <Kern code=\"937\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.16\"/>\n    <Kern code=\"8188\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8128\" width=\"0.383\" height=\"0.641\" >\n    <Kern code=\"913\" val=\"-0.128\"/>\n    <Kern code=\"8124\" val=\"-0.128\"/>\n  </Char>\n  <Char code=\"8129\" width=\"0.511\" height=\"0.696\" />\n  <Char code=\"8130\" width=\"0.575\" height=\"0.712\" depth=\"0.26\" />\n  <Char code=\"8131\" width=\"0.575\" height=\"0.456\" depth=\"0.26\" />\n  <Char code=\"8132\" width=\"0.575\" height=\"0.712\" depth=\"0.26\" />\n  <Char code=\"8134\" width=\"0.575\" height=\"0.641\" depth=\"0.26\" />\n  <Char code=\"8135\" width=\"0.575\" height=\"0.641\" depth=\"0.26\" />\n  <Char code=\"8140\" width=\"0.9\" height=\"0.687\" depth=\"0.241\" />\n  <Char code=\"8141\" width=\"0.319\" height=\"0.711\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"927\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8142\" width=\"0.319\" height=\"0.711\" italic=\"0.004\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"927\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8143\" width=\"0.383\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.128\"/>\n    <Kern code=\"8124\" val=\"-0.128\"/>\n  </Char>\n  <Char code=\"8146\" width=\"0.287\" height=\"0.711\" depth=\"0.007\" italic=\"0.028\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.031\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"8150\" width=\"0.287\" height=\"0.641\" depth=\"0.007\" italic=\"0.029\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.019\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"8151\" width=\"0.287\" height=\"0.696\" depth=\"0.007\" italic=\"0.029\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.019\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"8157\" width=\"0.319\" height=\"0.711\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"927\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8158\" width=\"0.319\" height=\"0.711\" italic=\"0.004\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"927\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8159\" width=\"0.383\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.128\"/>\n    <Kern code=\"8124\" val=\"-0.128\"/>\n  </Char>\n  <Char code=\"8162\" width=\"0.575\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"8164\" width=\"0.543\" height=\"0.696\" depth=\"0.256\" />\n  <Char code=\"8165\" width=\"0.543\" height=\"0.696\" depth=\"0.256\" />\n  <Char code=\"8166\" width=\"0.575\" height=\"0.641\" depth=\"0.006\" />\n  <Char code=\"8167\" width=\"0.575\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8173\" width=\"0.319\" height=\"0.711\" italic=\"0.031\" />\n  <Char code=\"8175\" width=\"0.192\" height=\"0.712\" >\n    <Kern code=\"913\" val=\"-0.128\"/>\n    <Kern code=\"927\" val=\"-0.064\"/>\n    <Kern code=\"937\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.128\"/>\n    <Kern code=\"8188\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8178\" width=\"0.766\" height=\"0.712\" depth=\"0.241\" />\n  <Char code=\"8179\" width=\"0.766\" height=\"0.457\" depth=\"0.241\" />\n  <Char code=\"8180\" width=\"0.766\" height=\"0.712\" depth=\"0.241\" />\n  <Char code=\"8182\" width=\"0.766\" height=\"0.641\" depth=\"0.006\" />\n  <Char code=\"8183\" width=\"0.766\" height=\"0.641\" depth=\"0.241\" />\n  <Char code=\"8188\" width=\"0.83\" height=\"0.698\" depth=\"0.241\" />\n  <Char code=\"8190\" width=\"0.255\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.192\"/>\n    <Kern code=\"927\" val=\"-0.064\"/>\n    <Kern code=\"937\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.192\"/>\n    <Kern code=\"8188\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8217\" width=\"0.319\" height=\"0.696\" >\n  </Char>\n  <Char code=\"9001\" width=\"0.447\" height=\"0.751\" depth=\"0.251\" />\n  <Char code=\"9002\" width=\"0.447\" height=\"0.751\" depth=\"0.251\" />\n</Font>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/greek/fcmripg.xml",
    "content": "<?xml version='1.0'?>\n<Font name=\"fcmripg.ttf\" id=\"fcmripg\" space=\"0.307\" xHeight=\"0.441\" quad=\"1\" unicode=\"204\" romanVersion=\"fcmrpg\" boldVersion=\"fcmbipg\" ssVersion=\"fcsropg\" ttVersion=\"fctrpg\">\n  <Char code=\"32\" width=\"0.307\" height=\"0.0\" />\n  <Char code=\"168\" width=\"0.222\" height=\"0.609\" italic=\"0.192\" />\n  <Char code=\"884\" width=\"0.194\" height=\"0.702\" italic=\"0.145\" />\n  <Char code=\"885\" width=\"0.194\" height=\"0.003\" depth=\"0.216\" />\n  <Char code=\"890\" width=\"0.111\" height=\"-0.043\" depth=\"0.211\" italic=\"0.009\" />\n  <Char code=\"900\" width=\"0.167\" height=\"0.702\" italic=\"0.152\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"901\" width=\"0.278\" height=\"0.702\" italic=\"0.155\" />\n  <Char code=\"903\" width=\"0.278\" height=\"0.431\" italic=\"0.017\" />\n  <Char code=\"912\" width=\"0.25\" height=\"0.702\" depth=\"0.011\" italic=\"0.13\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"913\" width=\"0.75\" height=\"0.717\" >\n    <Kern code=\"920\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.083\"/>\n    <Kern code=\"932\" val=\"-0.083\"/>\n    <Kern code=\"933\" val=\"-0.139\"/>\n    <Kern code=\"934\" val=\"-0.083\"/>\n    <Kern code=\"936\" val=\"-0.122\"/>\n    <Kern code=\"939\" val=\"-0.139\"/>\n    <Kern code=\"957\" val=\"-0.097\"/>\n  </Char>\n  <Char code=\"914\" width=\"0.708\" height=\"0.685\" italic=\"0.058\" />\n  <Char code=\"915\" width=\"0.625\" height=\"0.681\" italic=\"0.111\" >\n    <Kern code=\"913\" val=\"-0.133\"/>\n    <Kern code=\"916\" val=\"-0.111\"/>\n    <Kern code=\"923\" val=\"-0.122\"/>\n    <Kern code=\"8124\" val=\"-0.133\"/>\n  </Char>\n  <Char code=\"916\" width=\"0.833\" height=\"0.718\" >\n    <Kern code=\"927\" val=\"-0.033\"/>\n    <Kern code=\"933\" val=\"-0.139\"/>\n    <Kern code=\"939\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"917\" width=\"0.68\" height=\"0.681\" italic=\"0.098\" />\n  <Char code=\"918\" width=\"0.611\" height=\"0.685\" italic=\"0.124\" />\n  <Char code=\"919\" width=\"0.75\" height=\"0.684\" italic=\"0.148\" />\n  <Char code=\"920\" width=\"0.778\" height=\"0.706\" depth=\"0.022\" italic=\"0.049\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"933\" val=\"-0.083\"/>\n    <Kern code=\"939\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"921\" width=\"0.361\" height=\"0.684\" italic=\"0.154\" />\n  <Char code=\"922\" width=\"0.778\" height=\"0.684\" italic=\"0.126\" >\n    <Kern code=\"927\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"923\" width=\"0.694\" height=\"0.717\" >\n    <Kern code=\"927\" val=\"-0.033\"/>\n    <Kern code=\"933\" val=\"-0.1\"/>\n    <Kern code=\"939\" val=\"-0.1\"/>\n  </Char>\n  <Char code=\"924\" width=\"0.916\" height=\"0.684\" italic=\"0.144\" />\n  <Char code=\"925\" width=\"0.75\" height=\"0.684\" italic=\"0.148\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"926\" width=\"0.667\" height=\"0.678\" italic=\"0.125\" />\n  <Char code=\"927\" width=\"0.778\" height=\"0.706\" depth=\"0.022\" italic=\"0.049\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"931\" val=\"-0.056\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"928\" width=\"0.75\" height=\"0.681\" italic=\"0.148\" />\n  <Char code=\"929\" width=\"0.68\" height=\"0.685\" italic=\"0.083\" >\n    <Kern code=\"913\" val=\"-0.167\"/>\n    <Kern code=\"8124\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"931\" width=\"0.722\" height=\"0.685\" italic=\"0.099\" >\n    <Kern code=\"913\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"932\" width=\"0.722\" height=\"0.678\" italic=\"0.125\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"933\" width=\"0.694\" height=\"0.684\" italic=\"0.172\" >\n    <Kern code=\"913\" val=\"-0.139\"/>\n    <Kern code=\"916\" val=\"-0.139\"/>\n    <Kern code=\"923\" val=\"-0.139\"/>\n    <Kern code=\"8124\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"934\" width=\"0.722\" height=\"0.684\" italic=\"0.041\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"935\" width=\"0.75\" height=\"0.684\" italic=\"0.117\" />\n  <Char code=\"936\" width=\"0.778\" height=\"0.685\" italic=\"0.089\" >\n    <Kern code=\"913\" val=\"-0.122\"/>\n    <Kern code=\"8124\" val=\"-0.122\"/>\n  </Char>\n  <Char code=\"937\" width=\"0.722\" height=\"0.706\" italic=\"0.074\" />\n  <Char code=\"938\" width=\"0.361\" height=\"0.834\" italic=\"0.171\" />\n  <Char code=\"939\" width=\"0.694\" height=\"0.833\" italic=\"0.172\" >\n    <Kern code=\"913\" val=\"-0.139\"/>\n    <Kern code=\"916\" val=\"-0.139\"/>\n    <Kern code=\"923\" val=\"-0.139\"/>\n    <Kern code=\"8124\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"940\" width=\"0.555\" height=\"0.702\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"941\" width=\"0.389\" height=\"0.702\" depth=\"0.011\" italic=\"0.067\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"948\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.008\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8115\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"942\" width=\"0.517\" height=\"0.702\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"943\" width=\"0.25\" height=\"0.702\" depth=\"0.011\" italic=\"0.097\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"944\" width=\"0.5\" height=\"0.729\" depth=\"0.011\" italic=\"0.045\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"945\" width=\"0.555\" height=\"0.443\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.094\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"993\" val=\"-0.222\"/>\n    <Kern code=\"8016\" val=\"-0.083\"/>\n    <Kern code=\"8018\" val=\"-0.083\"/>\n    <Kern code=\"8020\" val=\"-0.083\"/>\n    <Kern code=\"8021\" val=\"-0.083\"/>\n    <Kern code=\"8022\" val=\"-0.083\"/>\n    <Kern code=\"8023\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n    <Kern code=\"8166\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"946\" width=\"0.444\" height=\"0.707\" depth=\"0.212\" italic=\"0.093\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"943\" val=\"0.028\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"953\" val=\"0.028\"/>\n    <Kern code=\"959\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"0.028\"/>\n    <Kern code=\"966\" val=\"0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.056\"/>\n    <Kern code=\"972\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.056\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8054\" val=\"0.028\"/>\n    <Kern code=\"8056\" val=\"0.028\"/>\n    <Kern code=\"8150\" val=\"0.028\"/>\n  </Char>\n  <Char code=\"947\" width=\"0.5\" height=\"0.447\" depth=\"0.217\" italic=\"0.067\" >\n    <Kern code=\"967\" val=\"0.017\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"948\" width=\"0.467\" height=\"0.707\" depth=\"0.01\" italic=\"0.033\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"956\" val=\"-0.044\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"960\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.017\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8115\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"949\" width=\"0.389\" height=\"0.442\" depth=\"0.011\" italic=\"0.052\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"948\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.008\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8115\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"950\" width=\"0.417\" height=\"0.696\" depth=\"0.156\" italic=\"0.082\" >\n    <Kern code=\"940\" val=\"-0.083\"/>\n    <Kern code=\"941\" val=\"-0.083\"/>\n    <Kern code=\"942\" val=\"-0.083\"/>\n    <Kern code=\"945\" val=\"-0.083\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"948\" val=\"-0.056\"/>\n    <Kern code=\"949\" val=\"-0.083\"/>\n    <Kern code=\"951\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.056\"/>\n    <Kern code=\"956\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.089\"/>\n    <Kern code=\"959\" val=\"-0.083\"/>\n    <Kern code=\"960\" val=\"-0.083\"/>\n    <Kern code=\"963\" val=\"-0.083\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"966\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"969\" val=\"-0.083\"/>\n    <Kern code=\"972\" val=\"-0.083\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"974\" val=\"-0.083\"/>\n    <Kern code=\"993\" val=\"-0.056\"/>\n    <Kern code=\"8048\" val=\"-0.083\"/>\n    <Kern code=\"8050\" val=\"-0.083\"/>\n    <Kern code=\"8052\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.083\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n    <Kern code=\"8060\" val=\"-0.083\"/>\n    <Kern code=\"8114\" val=\"-0.083\"/>\n    <Kern code=\"8115\" val=\"-0.083\"/>\n    <Kern code=\"8116\" val=\"-0.083\"/>\n    <Kern code=\"8118\" val=\"-0.083\"/>\n    <Kern code=\"8119\" val=\"-0.083\"/>\n    <Kern code=\"8130\" val=\"-0.083\"/>\n    <Kern code=\"8131\" val=\"-0.083\"/>\n    <Kern code=\"8132\" val=\"-0.083\"/>\n    <Kern code=\"8134\" val=\"-0.083\"/>\n    <Kern code=\"8135\" val=\"-0.083\"/>\n    <Kern code=\"8166\" val=\"-0.083\"/>\n    <Kern code=\"8178\" val=\"-0.083\"/>\n    <Kern code=\"8179\" val=\"-0.083\"/>\n    <Kern code=\"8180\" val=\"-0.083\"/>\n    <Kern code=\"8182\" val=\"-0.083\"/>\n    <Kern code=\"8183\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"951\" width=\"0.517\" height=\"0.443\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"952\" width=\"0.514\" height=\"0.707\" depth=\"0.011\" italic=\"0.065\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"943\" val=\"0.028\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"953\" val=\"0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.056\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8054\" val=\"0.028\"/>\n    <Kern code=\"8150\" val=\"0.028\"/>\n  </Char>\n  <Char code=\"953\" width=\"0.25\" height=\"0.431\" depth=\"0.011\" italic=\"0.002\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"954\" width=\"0.528\" height=\"0.447\" depth=\"0.011\" italic=\"0.053\" >\n    <Kern code=\"946\" val=\"0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"955\" width=\"0.45\" height=\"0.707\" depth=\"0.011\" italic=\"0.011\" >\n    <Kern code=\"940\" val=\"-0.014\"/>\n    <Kern code=\"945\" val=\"-0.014\"/>\n    <Kern code=\"947\" val=\"-0.139\"/>\n    <Kern code=\"952\" val=\"-0.044\"/>\n    <Kern code=\"956\" val=\"0.014\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.056\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"973\" val=\"-0.056\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.014\"/>\n    <Kern code=\"8058\" val=\"-0.056\"/>\n    <Kern code=\"8114\" val=\"-0.014\"/>\n    <Kern code=\"8115\" val=\"-0.014\"/>\n    <Kern code=\"8116\" val=\"-0.014\"/>\n    <Kern code=\"8118\" val=\"-0.014\"/>\n    <Kern code=\"8119\" val=\"-0.014\"/>\n    <Kern code=\"8166\" val=\"-0.056\"/>\n  </Char>\n  <Char code=\"956\" width=\"0.5\" height=\"0.432\" depth=\"0.222\" italic=\"0.002\" >\n    <Kern code=\"940\" val=\"-0.056\"/>\n    <Kern code=\"945\" val=\"-0.056\"/>\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"950\" val=\"-0.028\"/>\n    <Kern code=\"952\" val=\"-0.061\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.056\"/>\n    <Kern code=\"966\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.058\"/>\n    <Kern code=\"969\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.056\"/>\n    <Kern code=\"974\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.222\"/>\n    <Kern code=\"8048\" val=\"-0.056\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.056\"/>\n    <Kern code=\"8060\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.056\"/>\n    <Kern code=\"8115\" val=\"-0.056\"/>\n    <Kern code=\"8116\" val=\"-0.056\"/>\n    <Kern code=\"8118\" val=\"-0.056\"/>\n    <Kern code=\"8119\" val=\"-0.056\"/>\n    <Kern code=\"8166\" val=\"-0.056\"/>\n    <Kern code=\"8178\" val=\"-0.028\"/>\n    <Kern code=\"8179\" val=\"-0.028\"/>\n    <Kern code=\"8180\" val=\"-0.028\"/>\n    <Kern code=\"8182\" val=\"-0.028\"/>\n    <Kern code=\"8183\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"957\" width=\"0.417\" height=\"0.442\" depth=\"0.02\" italic=\"0.068\" >\n    <Kern code=\"940\" val=\"-0.022\"/>\n    <Kern code=\"945\" val=\"-0.022\"/>\n    <Kern code=\"955\" val=\"-0.044\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"961\" val=\"-0.006\"/>\n    <Kern code=\"969\" val=\"0.008\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"974\" val=\"0.008\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.022\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8060\" val=\"0.008\"/>\n    <Kern code=\"8114\" val=\"-0.022\"/>\n    <Kern code=\"8115\" val=\"-0.022\"/>\n    <Kern code=\"8116\" val=\"-0.022\"/>\n    <Kern code=\"8118\" val=\"-0.022\"/>\n    <Kern code=\"8119\" val=\"-0.022\"/>\n    <Kern code=\"8178\" val=\"0.008\"/>\n    <Kern code=\"8179\" val=\"0.008\"/>\n    <Kern code=\"8180\" val=\"0.008\"/>\n    <Kern code=\"8182\" val=\"0.008\"/>\n    <Kern code=\"8183\" val=\"0.008\"/>\n  </Char>\n  <Char code=\"958\" width=\"0.417\" height=\"0.696\" depth=\"0.155\" italic=\"0.036\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"941\" val=\"-0.056\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"947\" val=\"-0.039\"/>\n    <Kern code=\"949\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.056\"/>\n    <Kern code=\"963\" val=\"-0.056\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"966\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.056\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.056\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"-0.056\"/>\n    <Kern code=\"8056\" val=\"-0.056\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8115\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"959\" width=\"0.472\" height=\"0.443\" depth=\"0.011\" italic=\"0.025\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"964\" val=\"-0.033\"/>\n    <Kern code=\"965\" val=\"-0.056\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.056\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8058\" val=\"-0.056\"/>\n    <Kern code=\"8166\" val=\"-0.056\"/>\n  </Char>\n  <Char code=\"960\" width=\"0.569\" height=\"0.434\" depth=\"0.011\" italic=\"0.068\" >\n    <Kern code=\"943\" val=\"0.028\"/>\n    <Kern code=\"953\" val=\"0.028\"/>\n    <Kern code=\"954\" val=\"0.028\"/>\n    <Kern code=\"959\" val=\"-0.056\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"972\" val=\"-0.056\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8054\" val=\"0.028\"/>\n    <Kern code=\"8056\" val=\"-0.056\"/>\n    <Kern code=\"8150\" val=\"0.028\"/>\n  </Char>\n  <Char code=\"961\" width=\"0.472\" height=\"0.442\" depth=\"0.212\" italic=\"0.028\" >\n    <Kern code=\"943\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.056\"/>\n    <Kern code=\"950\" val=\"0.028\"/>\n    <Kern code=\"953\" val=\"0.028\"/>\n    <Kern code=\"957\" val=\"-0.05\"/>\n    <Kern code=\"959\" val=\"0.028\"/>\n    <Kern code=\"963\" val=\"0.028\"/>\n    <Kern code=\"967\" val=\"-0.011\"/>\n    <Kern code=\"968\" val=\"0.017\"/>\n    <Kern code=\"972\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8054\" val=\"0.028\"/>\n    <Kern code=\"8056\" val=\"0.028\"/>\n    <Kern code=\"8150\" val=\"0.028\"/>\n  </Char>\n  <Char code=\"962\" width=\"0.417\" height=\"0.443\" depth=\"0.13\" italic=\"0.048\" />\n  <Char code=\"963\" width=\"0.5\" height=\"0.451\" depth=\"0.011\" italic=\"0.081\" >\n    <Kern code=\"940\" val=\"-0.044\"/>\n    <Kern code=\"945\" val=\"-0.044\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"961\" val=\"-0.028\"/>\n    <Kern code=\"969\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"974\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.044\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8060\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.044\"/>\n    <Kern code=\"8115\" val=\"-0.044\"/>\n    <Kern code=\"8116\" val=\"-0.044\"/>\n    <Kern code=\"8118\" val=\"-0.044\"/>\n    <Kern code=\"8119\" val=\"-0.044\"/>\n    <Kern code=\"8164\" val=\"-0.028\"/>\n    <Kern code=\"8165\" val=\"-0.028\"/>\n    <Kern code=\"8178\" val=\"-0.028\"/>\n    <Kern code=\"8179\" val=\"-0.028\"/>\n    <Kern code=\"8180\" val=\"-0.028\"/>\n    <Kern code=\"8182\" val=\"-0.028\"/>\n    <Kern code=\"8183\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"964\" width=\"0.458\" height=\"0.454\" depth=\"0.011\" italic=\"0.075\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"941\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"949\" val=\"-0.028\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"969\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"974\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8060\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8115\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8178\" val=\"-0.028\"/>\n    <Kern code=\"8179\" val=\"-0.028\"/>\n    <Kern code=\"8180\" val=\"-0.028\"/>\n    <Kern code=\"8182\" val=\"-0.028\"/>\n    <Kern code=\"8183\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"965\" width=\"0.517\" height=\"0.443\" depth=\"0.011\" italic=\"0.024\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"966\" width=\"0.583\" height=\"0.443\" depth=\"0.223\" italic=\"0.037\" >\n    <Kern code=\"942\" val=\"-0.028\"/>\n    <Kern code=\"947\" val=\"-0.056\"/>\n    <Kern code=\"951\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.039\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.056\"/>\n    <Kern code=\"967\" val=\"-0.011\"/>\n    <Kern code=\"973\" val=\"-0.056\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8052\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.056\"/>\n    <Kern code=\"8130\" val=\"-0.028\"/>\n    <Kern code=\"8131\" val=\"-0.028\"/>\n    <Kern code=\"8132\" val=\"-0.028\"/>\n    <Kern code=\"8134\" val=\"-0.056\"/>\n    <Kern code=\"8135\" val=\"-0.056\"/>\n    <Kern code=\"8166\" val=\"-0.056\"/>\n  </Char>\n  <Char code=\"967\" width=\"0.472\" height=\"0.442\" depth=\"0.223\" italic=\"0.031\" >\n    <Kern code=\"940\" val=\"-0.067\"/>\n    <Kern code=\"941\" val=\"-0.028\"/>\n    <Kern code=\"942\" val=\"-0.058\"/>\n    <Kern code=\"943\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.067\"/>\n    <Kern code=\"947\" val=\"-0.044\"/>\n    <Kern code=\"948\" val=\"-0.067\"/>\n    <Kern code=\"949\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.058\"/>\n    <Kern code=\"952\" val=\"-0.056\"/>\n    <Kern code=\"953\" val=\"-0.028\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"955\" val=\"-0.067\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"958\" val=\"-0.044\"/>\n    <Kern code=\"959\" val=\"-0.083\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"961\" val=\"-0.044\"/>\n    <Kern code=\"963\" val=\"-0.039\"/>\n    <Kern code=\"964\" val=\"-0.044\"/>\n    <Kern code=\"965\" val=\"-0.044\"/>\n    <Kern code=\"966\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"969\" val=\"-0.067\"/>\n    <Kern code=\"972\" val=\"-0.083\"/>\n    <Kern code=\"973\" val=\"-0.044\"/>\n    <Kern code=\"974\" val=\"-0.067\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.067\"/>\n    <Kern code=\"8050\" val=\"-0.028\"/>\n    <Kern code=\"8052\" val=\"-0.058\"/>\n    <Kern code=\"8054\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.083\"/>\n    <Kern code=\"8058\" val=\"-0.044\"/>\n    <Kern code=\"8060\" val=\"-0.067\"/>\n    <Kern code=\"8114\" val=\"-0.067\"/>\n    <Kern code=\"8115\" val=\"-0.067\"/>\n    <Kern code=\"8116\" val=\"-0.067\"/>\n    <Kern code=\"8118\" val=\"-0.067\"/>\n    <Kern code=\"8119\" val=\"-0.067\"/>\n    <Kern code=\"8130\" val=\"-0.058\"/>\n    <Kern code=\"8131\" val=\"-0.058\"/>\n    <Kern code=\"8132\" val=\"-0.058\"/>\n    <Kern code=\"8134\" val=\"-0.058\"/>\n    <Kern code=\"8135\" val=\"-0.058\"/>\n    <Kern code=\"8150\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.044\"/>\n    <Kern code=\"8178\" val=\"-0.067\"/>\n    <Kern code=\"8179\" val=\"-0.067\"/>\n    <Kern code=\"8180\" val=\"-0.067\"/>\n    <Kern code=\"8182\" val=\"-0.067\"/>\n    <Kern code=\"8183\" val=\"-0.067\"/>\n  </Char>\n  <Char code=\"968\" width=\"0.555\" height=\"0.444\" depth=\"0.226\" italic=\"0.045\" >\n    <Kern code=\"947\" val=\"-0.039\"/>\n    <Kern code=\"965\" val=\"-0.056\"/>\n    <Kern code=\"967\" val=\"-0.006\"/>\n    <Kern code=\"973\" val=\"-0.056\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8058\" val=\"-0.056\"/>\n    <Kern code=\"8166\" val=\"-0.056\"/>\n  </Char>\n  <Char code=\"969\" width=\"0.667\" height=\"0.432\" depth=\"0.011\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"970\" width=\"0.25\" height=\"0.637\" depth=\"0.011\" italic=\"0.147\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"971\" width=\"0.5\" height=\"0.637\" depth=\"0.011\" italic=\"0.06\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"972\" width=\"0.472\" height=\"0.702\" depth=\"0.011\" italic=\"0.027\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"964\" val=\"-0.033\"/>\n    <Kern code=\"965\" val=\"-0.056\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.056\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8058\" val=\"-0.056\"/>\n    <Kern code=\"8166\" val=\"-0.056\"/>\n  </Char>\n  <Char code=\"973\" width=\"0.5\" height=\"0.702\" depth=\"0.011\" italic=\"0.041\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"974\" width=\"0.667\" height=\"0.702\" depth=\"0.011\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"984\" width=\"0.5\" height=\"0.695\" depth=\"0.001\" italic=\"0.103\" />\n  <Char code=\"985\" width=\"0.5\" height=\"0.443\" depth=\"0.217\" italic=\"0.011\" >\n    <Kern code=\"993\" val=\"-0.222\"/>\n  </Char>\n  <Char code=\"986\" width=\"0.778\" height=\"0.679\" italic=\"0.125\" />\n  <Char code=\"987\" width=\"0.5\" height=\"0.496\" depth=\"0.106\" italic=\"0.086\" >\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"988\" width=\"0.653\" height=\"0.681\" italic=\"0.111\" />\n  <Char code=\"989\" width=\"0.5\" height=\"0.695\" italic=\"0.146\" />\n  <Char code=\"991\" width=\"0.389\" height=\"0.695\" depth=\"0.211\" italic=\"0.046\" >\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"992\" width=\"0.766\" height=\"0.695\" />\n  <Char code=\"993\" width=\"0.722\" height=\"0.706\" depth=\"0.029\" >\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"7936\" width=\"0.555\" height=\"0.696\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"7937\" width=\"0.555\" height=\"0.696\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"7938\" width=\"0.555\" height=\"0.702\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"7939\" width=\"0.555\" height=\"0.702\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"7940\" width=\"0.555\" height=\"0.702\" depth=\"0.011\" italic=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"7941\" width=\"0.555\" height=\"0.702\" depth=\"0.011\" italic=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.044\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"7942\" width=\"0.555\" height=\"0.723\" depth=\"0.011\" italic=\"0.055\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"7943\" width=\"0.555\" height=\"0.723\" depth=\"0.011\" italic=\"0.055\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"7952\" width=\"0.389\" height=\"0.696\" depth=\"0.011\" italic=\"0.052\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"948\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.008\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8115\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7953\" width=\"0.389\" height=\"0.696\" depth=\"0.011\" italic=\"0.052\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"948\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.008\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8115\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7954\" width=\"0.389\" height=\"0.702\" depth=\"0.011\" italic=\"0.073\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"948\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.008\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8115\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7955\" width=\"0.389\" height=\"0.702\" depth=\"0.011\" italic=\"0.073\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"948\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.008\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8115\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7956\" width=\"0.389\" height=\"0.702\" depth=\"0.011\" italic=\"0.117\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"948\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.008\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8115\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7957\" width=\"0.389\" height=\"0.702\" depth=\"0.011\" italic=\"0.117\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"948\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.008\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8115\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7968\" width=\"0.517\" height=\"0.696\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7969\" width=\"0.517\" height=\"0.696\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7970\" width=\"0.517\" height=\"0.702\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7971\" width=\"0.517\" height=\"0.702\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7972\" width=\"0.517\" height=\"0.702\" depth=\"0.214\" italic=\"0.041\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7973\" width=\"0.517\" height=\"0.702\" depth=\"0.214\" italic=\"0.041\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7974\" width=\"0.517\" height=\"0.723\" depth=\"0.214\" italic=\"0.085\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7975\" width=\"0.517\" height=\"0.723\" depth=\"0.214\" italic=\"0.085\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7984\" width=\"0.25\" height=\"0.696\" depth=\"0.011\" italic=\"0.107\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7985\" width=\"0.25\" height=\"0.696\" depth=\"0.011\" italic=\"0.065\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7986\" width=\"0.25\" height=\"0.702\" depth=\"0.011\" italic=\"0.102\" />\n  <Char code=\"7987\" width=\"0.25\" height=\"0.702\" depth=\"0.011\" italic=\"0.102\" />\n  <Char code=\"7988\" width=\"0.25\" height=\"0.702\" depth=\"0.011\" italic=\"0.148\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7989\" width=\"0.25\" height=\"0.702\" depth=\"0.011\" italic=\"0.148\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7990\" width=\"0.25\" height=\"0.723\" depth=\"0.011\" italic=\"0.191\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7991\" width=\"0.25\" height=\"0.723\" depth=\"0.011\" italic=\"0.191\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8000\" width=\"0.472\" height=\"0.696\" depth=\"0.011\" italic=\"0.05\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"964\" val=\"-0.033\"/>\n    <Kern code=\"965\" val=\"-0.056\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.056\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8058\" val=\"-0.056\"/>\n    <Kern code=\"8166\" val=\"-0.056\"/>\n  </Char>\n  <Char code=\"8001\" width=\"0.472\" height=\"0.696\" depth=\"0.011\" italic=\"0.025\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"964\" val=\"-0.033\"/>\n    <Kern code=\"965\" val=\"-0.056\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.056\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8058\" val=\"-0.056\"/>\n    <Kern code=\"8166\" val=\"-0.056\"/>\n  </Char>\n  <Char code=\"8002\" width=\"0.472\" height=\"0.702\" depth=\"0.011\" italic=\"0.031\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"964\" val=\"-0.033\"/>\n    <Kern code=\"965\" val=\"-0.056\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.056\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8058\" val=\"-0.056\"/>\n    <Kern code=\"8166\" val=\"-0.056\"/>\n  </Char>\n  <Char code=\"8003\" width=\"0.472\" height=\"0.702\" depth=\"0.011\" italic=\"0.031\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"964\" val=\"-0.033\"/>\n    <Kern code=\"965\" val=\"-0.056\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.056\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8058\" val=\"-0.056\"/>\n    <Kern code=\"8166\" val=\"-0.056\"/>\n  </Char>\n  <Char code=\"8004\" width=\"0.472\" height=\"0.701\" depth=\"0.011\" italic=\"0.077\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"964\" val=\"-0.033\"/>\n    <Kern code=\"965\" val=\"-0.056\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.056\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8058\" val=\"-0.056\"/>\n    <Kern code=\"8166\" val=\"-0.056\"/>\n  </Char>\n  <Char code=\"8005\" width=\"0.472\" height=\"0.701\" depth=\"0.011\" italic=\"0.077\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"964\" val=\"-0.033\"/>\n    <Kern code=\"965\" val=\"-0.056\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.056\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8058\" val=\"-0.056\"/>\n    <Kern code=\"8166\" val=\"-0.056\"/>\n  </Char>\n  <Char code=\"8016\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.041\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"8017\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.041\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"8018\" width=\"0.5\" height=\"0.702\" depth=\"0.011\" italic=\"0.041\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"8019\" width=\"0.5\" height=\"0.702\" depth=\"0.011\" italic=\"0.041\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"8020\" width=\"0.5\" height=\"0.702\" depth=\"0.011\" italic=\"0.059\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"8021\" width=\"0.5\" height=\"0.702\" depth=\"0.011\" italic=\"0.059\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"8022\" width=\"0.5\" height=\"0.723\" depth=\"0.011\" italic=\"0.103\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"8023\" width=\"0.5\" height=\"0.723\" depth=\"0.011\" italic=\"0.103\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"8032\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8033\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8034\" width=\"0.667\" height=\"0.702\" depth=\"0.011\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8035\" width=\"0.667\" height=\"0.702\" depth=\"0.011\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8036\" width=\"0.667\" height=\"0.702\" depth=\"0.011\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8037\" width=\"0.667\" height=\"0.702\" depth=\"0.011\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8038\" width=\"0.667\" height=\"0.724\" depth=\"0.011\" italic=\"0.05\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8039\" width=\"0.667\" height=\"0.724\" depth=\"0.011\" italic=\"0.05\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8048\" width=\"0.555\" height=\"0.702\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8050\" width=\"0.389\" height=\"0.702\" depth=\"0.011\" italic=\"0.052\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"948\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.008\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8115\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8052\" width=\"0.517\" height=\"0.702\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8054\" width=\"0.25\" height=\"0.702\" depth=\"0.011\" italic=\"0.007\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8056\" width=\"0.472\" height=\"0.702\" depth=\"0.011\" italic=\"0.025\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"964\" val=\"-0.033\"/>\n    <Kern code=\"965\" val=\"-0.056\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.056\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8058\" val=\"-0.056\"/>\n    <Kern code=\"8166\" val=\"-0.056\"/>\n  </Char>\n  <Char code=\"8058\" width=\"0.5\" height=\"0.702\" depth=\"0.011\" italic=\"0.041\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"8060\" width=\"0.667\" height=\"0.702\" depth=\"0.011\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8064\" width=\"0.555\" height=\"0.696\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8065\" width=\"0.555\" height=\"0.696\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8066\" width=\"0.555\" height=\"0.702\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8067\" width=\"0.555\" height=\"0.702\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8068\" width=\"0.555\" height=\"0.702\" depth=\"0.211\" italic=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8069\" width=\"0.555\" height=\"0.702\" depth=\"0.211\" italic=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.044\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8070\" width=\"0.555\" height=\"0.723\" depth=\"0.211\" italic=\"0.055\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8071\" width=\"0.555\" height=\"0.723\" depth=\"0.211\" italic=\"0.055\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8080\" width=\"0.517\" height=\"0.696\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8081\" width=\"0.517\" height=\"0.696\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8082\" width=\"0.517\" height=\"0.702\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8083\" width=\"0.517\" height=\"0.702\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8084\" width=\"0.517\" height=\"0.702\" depth=\"0.214\" italic=\"0.041\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8085\" width=\"0.517\" height=\"0.702\" depth=\"0.214\" italic=\"0.041\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8086\" width=\"0.517\" height=\"0.723\" depth=\"0.214\" italic=\"0.085\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8087\" width=\"0.517\" height=\"0.723\" depth=\"0.214\" italic=\"0.085\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8096\" width=\"0.667\" height=\"0.696\" depth=\"0.211\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8097\" width=\"0.667\" height=\"0.696\" depth=\"0.211\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8098\" width=\"0.667\" height=\"0.702\" depth=\"0.211\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8099\" width=\"0.667\" height=\"0.702\" depth=\"0.211\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8100\" width=\"0.667\" height=\"0.702\" depth=\"0.211\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8101\" width=\"0.667\" height=\"0.702\" depth=\"0.211\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8102\" width=\"0.667\" height=\"0.724\" depth=\"0.211\" italic=\"0.05\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8103\" width=\"0.667\" height=\"0.724\" depth=\"0.211\" italic=\"0.05\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8114\" width=\"0.555\" height=\"0.702\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8115\" width=\"0.555\" height=\"0.443\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.094\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"993\" val=\"-0.222\"/>\n    <Kern code=\"8016\" val=\"-0.083\"/>\n    <Kern code=\"8018\" val=\"-0.083\"/>\n    <Kern code=\"8020\" val=\"-0.083\"/>\n    <Kern code=\"8021\" val=\"-0.083\"/>\n    <Kern code=\"8022\" val=\"-0.083\"/>\n    <Kern code=\"8023\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n    <Kern code=\"8166\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8116\" width=\"0.555\" height=\"0.702\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8118\" width=\"0.555\" height=\"0.615\" depth=\"0.011\" italic=\"0.026\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8119\" width=\"0.555\" height=\"0.615\" depth=\"0.211\" italic=\"0.026\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8124\" width=\"0.75\" height=\"0.717\" depth=\"0.211\" >\n    <Kern code=\"920\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.083\"/>\n    <Kern code=\"932\" val=\"-0.083\"/>\n    <Kern code=\"933\" val=\"-0.139\"/>\n    <Kern code=\"934\" val=\"-0.083\"/>\n    <Kern code=\"936\" val=\"-0.122\"/>\n    <Kern code=\"939\" val=\"-0.139\"/>\n    <Kern code=\"957\" val=\"-0.097\"/>\n  </Char>\n  <Char code=\"8126\" width=\"0.222\" height=\"0.158\" depth=\"0.156\" italic=\"0.012\" />\n  <Char code=\"8127\" width=\"0.222\" height=\"0.696\" italic=\"0.175\" >\n    <Kern code=\"913\" val=\"-0.139\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.139\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8128\" width=\"0.333\" height=\"0.615\" italic=\"0.16\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n  </Char>\n  <Char code=\"8129\" width=\"0.444\" height=\"0.723\" italic=\"0.134\" />\n  <Char code=\"8130\" width=\"0.517\" height=\"0.702\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8131\" width=\"0.517\" height=\"0.443\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8132\" width=\"0.517\" height=\"0.702\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8134\" width=\"0.517\" height=\"0.616\" depth=\"0.214\" italic=\"0.056\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8135\" width=\"0.517\" height=\"0.616\" depth=\"0.214\" italic=\"0.056\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8140\" width=\"0.75\" height=\"0.684\" depth=\"0.211\" italic=\"0.148\" />\n  <Char code=\"8141\" width=\"0.278\" height=\"0.702\" italic=\"0.128\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8142\" width=\"0.278\" height=\"0.701\" italic=\"0.174\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8143\" width=\"0.333\" height=\"0.723\" italic=\"0.189\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n  </Char>\n  <Char code=\"8146\" width=\"0.25\" height=\"0.702\" depth=\"0.011\" italic=\"0.13\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8150\" width=\"0.25\" height=\"0.615\" depth=\"0.011\" italic=\"0.162\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8151\" width=\"0.25\" height=\"0.723\" depth=\"0.011\" italic=\"0.191\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8157\" width=\"0.278\" height=\"0.702\" italic=\"0.128\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8158\" width=\"0.278\" height=\"0.701\" italic=\"0.174\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8159\" width=\"0.333\" height=\"0.723\" italic=\"0.189\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n  </Char>\n  <Char code=\"8162\" width=\"0.5\" height=\"0.729\" depth=\"0.011\" italic=\"0.045\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"8164\" width=\"0.472\" height=\"0.696\" depth=\"0.212\" italic=\"0.05\" >\n    <Kern code=\"943\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.056\"/>\n    <Kern code=\"950\" val=\"0.028\"/>\n    <Kern code=\"953\" val=\"0.028\"/>\n    <Kern code=\"957\" val=\"-0.05\"/>\n    <Kern code=\"959\" val=\"0.028\"/>\n    <Kern code=\"963\" val=\"0.028\"/>\n    <Kern code=\"967\" val=\"-0.011\"/>\n    <Kern code=\"968\" val=\"0.017\"/>\n    <Kern code=\"972\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8054\" val=\"0.028\"/>\n    <Kern code=\"8056\" val=\"0.028\"/>\n    <Kern code=\"8150\" val=\"0.028\"/>\n  </Char>\n  <Char code=\"8165\" width=\"0.472\" height=\"0.696\" depth=\"0.212\" italic=\"0.028\" >\n    <Kern code=\"943\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.056\"/>\n    <Kern code=\"950\" val=\"0.028\"/>\n    <Kern code=\"953\" val=\"0.028\"/>\n    <Kern code=\"957\" val=\"-0.05\"/>\n    <Kern code=\"959\" val=\"0.028\"/>\n    <Kern code=\"963\" val=\"0.028\"/>\n    <Kern code=\"967\" val=\"-0.011\"/>\n    <Kern code=\"968\" val=\"0.017\"/>\n    <Kern code=\"972\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8054\" val=\"0.028\"/>\n    <Kern code=\"8056\" val=\"0.028\"/>\n    <Kern code=\"8150\" val=\"0.028\"/>\n  </Char>\n  <Char code=\"8166\" width=\"0.5\" height=\"0.616\" depth=\"0.011\" italic=\"0.074\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"8167\" width=\"0.5\" height=\"0.723\" depth=\"0.011\" italic=\"0.103\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"8173\" width=\"0.278\" height=\"0.702\" italic=\"0.155\" />\n  <Char code=\"8175\" width=\"0.167\" height=\"0.702\" italic=\"0.116\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8178\" width=\"0.667\" height=\"0.702\" depth=\"0.211\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8179\" width=\"0.667\" height=\"0.432\" depth=\"0.211\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8180\" width=\"0.667\" height=\"0.702\" depth=\"0.211\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8182\" width=\"0.667\" height=\"0.615\" depth=\"0.011\" italic=\"0.021\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8183\" width=\"0.667\" height=\"0.615\" depth=\"0.211\" italic=\"0.021\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8188\" width=\"0.722\" height=\"0.706\" depth=\"0.211\" italic=\"0.074\" />\n  <Char code=\"8190\" width=\"0.222\" height=\"0.696\" italic=\"0.105\" >\n    <Kern code=\"913\" val=\"-0.167\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.167\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8217\" width=\"0.278\" height=\"0.695\" italic=\"0.093\" >\n  </Char>\n  <Char code=\"9001\" width=\"0.409\" height=\"0.751\" depth=\"0.249\" italic=\"0.106\" />\n  <Char code=\"9002\" width=\"0.409\" height=\"0.751\" depth=\"0.249\" />\n</Font>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/greek/fcmrpg.xml",
    "content": "<?xml version='1.0'?>\n<Font name=\"fcmrpg.ttf\" id=\"fcmrpg\" space=\"0.278\" xHeight=\"0.443\" quad=\"1\" unicode=\"205\" itVersion=\"fcmripg\" boldVersion=\"fcmbpg\" ssVersion=\"fcsrpg\" ttVersion=\"fctrpg\">\n  <Char code=\"32\" width=\"0.278\" height=\"0.0\" />\n  <Char code=\"168\" width=\"0.222\" height=\"0.603\" italic=\"0.041\" />\n  <Char code=\"884\" width=\"0.194\" height=\"0.701\" />\n  <Char code=\"885\" width=\"0.194\" height=\"0.003\" depth=\"0.217\" />\n  <Char code=\"890\" width=\"0.111\" height=\"-0.063\" depth=\"0.228\" />\n  <Char code=\"900\" width=\"0.167\" height=\"0.701\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"901\" width=\"0.278\" height=\"0.701\" />\n  <Char code=\"903\" width=\"0.278\" height=\"0.431\" />\n  <Char code=\"912\" width=\"0.25\" height=\"0.701\" depth=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"913\" width=\"0.75\" height=\"0.717\" >\n    <Kern code=\"920\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.083\"/>\n    <Kern code=\"932\" val=\"-0.083\"/>\n    <Kern code=\"933\" val=\"-0.139\"/>\n    <Kern code=\"934\" val=\"-0.083\"/>\n    <Kern code=\"936\" val=\"-0.122\"/>\n    <Kern code=\"939\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"914\" width=\"0.708\" height=\"0.685\" />\n  <Char code=\"915\" width=\"0.625\" height=\"0.681\" >\n    <Kern code=\"913\" val=\"-0.133\"/>\n    <Kern code=\"916\" val=\"-0.111\"/>\n    <Kern code=\"923\" val=\"-0.122\"/>\n    <Kern code=\"8124\" val=\"-0.133\"/>\n  </Char>\n  <Char code=\"916\" width=\"0.833\" height=\"0.718\" >\n    <Kern code=\"927\" val=\"-0.033\"/>\n    <Kern code=\"933\" val=\"-0.139\"/>\n    <Kern code=\"939\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"917\" width=\"0.68\" height=\"0.681\" />\n  <Char code=\"918\" width=\"0.611\" height=\"0.685\" />\n  <Char code=\"919\" width=\"0.75\" height=\"0.684\" />\n  <Char code=\"920\" width=\"0.778\" height=\"0.706\" depth=\"0.021\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"921\" width=\"0.361\" height=\"0.684\" />\n  <Char code=\"922\" width=\"0.778\" height=\"0.684\" >\n    <Kern code=\"927\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"923\" width=\"0.694\" height=\"0.718\" >\n    <Kern code=\"927\" val=\"-0.033\"/>\n    <Kern code=\"933\" val=\"-0.1\"/>\n    <Kern code=\"939\" val=\"-0.1\"/>\n  </Char>\n  <Char code=\"924\" width=\"0.916\" height=\"0.684\" />\n  <Char code=\"925\" width=\"0.75\" height=\"0.684\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"926\" width=\"0.667\" height=\"0.678\" />\n  <Char code=\"927\" width=\"0.778\" height=\"0.706\" depth=\"0.021\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"931\" val=\"-0.056\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"928\" width=\"0.75\" height=\"0.681\" />\n  <Char code=\"929\" width=\"0.68\" height=\"0.685\" >\n    <Kern code=\"913\" val=\"-0.167\"/>\n    <Kern code=\"8124\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"931\" width=\"0.722\" height=\"0.684\" >\n    <Kern code=\"913\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"932\" width=\"0.722\" height=\"0.678\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"933\" width=\"0.778\" height=\"0.707\" >\n    <Kern code=\"913\" val=\"-0.139\"/>\n    <Kern code=\"916\" val=\"-0.139\"/>\n    <Kern code=\"923\" val=\"-0.139\"/>\n    <Kern code=\"8124\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"934\" width=\"0.722\" height=\"0.684\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"935\" width=\"0.75\" height=\"0.684\" />\n  <Char code=\"936\" width=\"0.778\" height=\"0.684\" >\n    <Kern code=\"913\" val=\"-0.122\"/>\n    <Kern code=\"8124\" val=\"-0.122\"/>\n  </Char>\n  <Char code=\"937\" width=\"0.722\" height=\"0.706\" />\n  <Char code=\"938\" width=\"0.361\" height=\"0.833\" />\n  <Char code=\"939\" width=\"0.778\" height=\"0.833\" >\n    <Kern code=\"913\" val=\"-0.139\"/>\n    <Kern code=\"916\" val=\"-0.139\"/>\n    <Kern code=\"923\" val=\"-0.139\"/>\n    <Kern code=\"8124\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"940\" width=\"0.5\" height=\"0.702\" depth=\"0.011\" italic=\"0.001\" />\n  <Char code=\"941\" width=\"0.43\" height=\"0.701\" depth=\"0.021\" />\n  <Char code=\"942\" width=\"0.5\" height=\"0.701\" depth=\"0.271\" />\n  <Char code=\"943\" width=\"0.25\" height=\"0.701\" depth=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"944\" width=\"0.5\" height=\"0.702\" depth=\"0.01\" />\n  <Char code=\"945\" width=\"0.5\" height=\"0.443\" depth=\"0.011\" italic=\"0.001\" />\n  <Char code=\"946\" width=\"0.5\" height=\"0.706\" depth=\"0.276\" />\n  <Char code=\"947\" width=\"0.555\" height=\"0.442\" depth=\"0.2\" />\n  <Char code=\"948\" width=\"0.472\" height=\"0.7\" depth=\"0.01\" />\n  <Char code=\"949\" width=\"0.43\" height=\"0.454\" depth=\"0.021\" />\n  <Char code=\"950\" width=\"0.472\" height=\"0.718\" depth=\"0.139\" />\n  <Char code=\"951\" width=\"0.5\" height=\"0.454\" depth=\"0.271\" />\n  <Char code=\"952\" width=\"0.472\" height=\"0.717\" depth=\"0.022\" />\n  <Char code=\"953\" width=\"0.25\" height=\"0.443\" depth=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"954\" width=\"0.528\" height=\"0.454\" depth=\"0.022\" />\n  <Char code=\"955\" width=\"0.5\" height=\"0.697\" depth=\"0.01\" />\n  <Char code=\"956\" width=\"0.519\" height=\"0.453\" depth=\"0.26\" />\n  <Char code=\"957\" width=\"0.472\" height=\"0.443\" depth=\"0.01\" />\n  <Char code=\"958\" width=\"0.472\" height=\"0.717\" depth=\"0.139\" />\n  <Char code=\"959\" width=\"0.528\" height=\"0.443\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"960\" width=\"0.514\" height=\"0.432\" depth=\"0.018\" />\n  <Char code=\"961\" width=\"0.472\" height=\"0.442\" depth=\"0.261\" />\n  <Char code=\"962\" width=\"0.444\" height=\"0.443\" depth=\"0.125\" />\n  <Char code=\"963\" width=\"0.569\" height=\"0.432\" depth=\"0.01\" />\n  <Char code=\"964\" width=\"0.458\" height=\"0.432\" depth=\"0.01\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"969\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"974\" val=\"-0.028\"/>\n    <Kern code=\"7936\" val=\"-0.028\"/>\n    <Kern code=\"7937\" val=\"-0.028\"/>\n    <Kern code=\"7940\" val=\"-0.028\"/>\n    <Kern code=\"7941\" val=\"-0.028\"/>\n    <Kern code=\"7942\" val=\"-0.028\"/>\n    <Kern code=\"7943\" val=\"-0.028\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8032\" val=\"-0.028\"/>\n    <Kern code=\"8033\" val=\"-0.028\"/>\n    <Kern code=\"8036\" val=\"-0.028\"/>\n    <Kern code=\"8037\" val=\"-0.028\"/>\n    <Kern code=\"8038\" val=\"-0.028\"/>\n    <Kern code=\"8039\" val=\"-0.028\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8060\" val=\"-0.028\"/>\n    <Kern code=\"8064\" val=\"-0.028\"/>\n    <Kern code=\"8065\" val=\"-0.028\"/>\n    <Kern code=\"8068\" val=\"-0.028\"/>\n    <Kern code=\"8069\" val=\"-0.028\"/>\n    <Kern code=\"8070\" val=\"-0.028\"/>\n    <Kern code=\"8071\" val=\"-0.028\"/>\n    <Kern code=\"8096\" val=\"-0.028\"/>\n    <Kern code=\"8097\" val=\"-0.028\"/>\n    <Kern code=\"8100\" val=\"-0.028\"/>\n    <Kern code=\"8101\" val=\"-0.028\"/>\n    <Kern code=\"8102\" val=\"-0.028\"/>\n    <Kern code=\"8103\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8178\" val=\"-0.028\"/>\n    <Kern code=\"8180\" val=\"-0.028\"/>\n    <Kern code=\"8182\" val=\"-0.028\"/>\n    <Kern code=\"8183\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"965\" width=\"0.5\" height=\"0.457\" depth=\"0.01\" />\n  <Char code=\"966\" width=\"0.583\" height=\"0.455\" depth=\"0.275\" />\n  <Char code=\"967\" width=\"0.555\" height=\"0.444\" depth=\"0.262\" />\n  <Char code=\"968\" width=\"0.583\" height=\"0.72\" depth=\"0.276\" />\n  <Char code=\"969\" width=\"0.667\" height=\"0.453\" depth=\"0.011\" />\n  <Char code=\"970\" width=\"0.25\" height=\"0.626\" depth=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"971\" width=\"0.5\" height=\"0.626\" depth=\"0.01\" />\n  <Char code=\"972\" width=\"0.528\" height=\"0.701\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"973\" width=\"0.5\" height=\"0.702\" depth=\"0.01\" />\n  <Char code=\"974\" width=\"0.667\" height=\"0.701\" depth=\"0.011\" />\n  <Char code=\"977\" width=\"0.569\" height=\"0.707\" depth=\"0.011\" />\n  <Char code=\"984\" width=\"0.5\" height=\"0.695\" depth=\"0.001\" />\n  <Char code=\"985\" width=\"0.5\" height=\"0.599\" depth=\"0.063\" />\n  <Char code=\"986\" width=\"0.778\" height=\"0.679\" />\n  <Char code=\"987\" width=\"0.5\" height=\"0.454\" depth=\"0.027\" />\n  <Char code=\"988\" width=\"0.653\" height=\"0.681\" />\n  <Char code=\"989\" width=\"0.5\" height=\"0.432\" depth=\"0.257\" />\n  <Char code=\"991\" width=\"0.389\" height=\"0.595\" depth=\"0.138\" />\n  <Char code=\"992\" width=\"0.766\" height=\"0.695\" />\n  <Char code=\"993\" width=\"0.722\" height=\"0.696\" depth=\"0.022\" />\n  <Char code=\"7936\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.001\" />\n  <Char code=\"7937\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.001\" />\n  <Char code=\"7938\" width=\"0.5\" height=\"0.702\" depth=\"0.011\" italic=\"0.001\" />\n  <Char code=\"7939\" width=\"0.5\" height=\"0.702\" depth=\"0.011\" italic=\"0.001\" />\n  <Char code=\"7940\" width=\"0.5\" height=\"0.701\" depth=\"0.011\" italic=\"0.001\" />\n  <Char code=\"7941\" width=\"0.5\" height=\"0.701\" depth=\"0.011\" italic=\"0.001\" />\n  <Char code=\"7942\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.001\" />\n  <Char code=\"7943\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.001\" />\n  <Char code=\"7952\" width=\"0.43\" height=\"0.696\" depth=\"0.021\" />\n  <Char code=\"7953\" width=\"0.43\" height=\"0.696\" depth=\"0.021\" />\n  <Char code=\"7954\" width=\"0.43\" height=\"0.701\" depth=\"0.021\" />\n  <Char code=\"7955\" width=\"0.43\" height=\"0.701\" depth=\"0.021\" />\n  <Char code=\"7956\" width=\"0.43\" height=\"0.701\" depth=\"0.021\" />\n  <Char code=\"7957\" width=\"0.43\" height=\"0.701\" depth=\"0.021\" />\n  <Char code=\"7968\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"7969\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"7970\" width=\"0.5\" height=\"0.701\" depth=\"0.271\" />\n  <Char code=\"7971\" width=\"0.5\" height=\"0.701\" depth=\"0.271\" />\n  <Char code=\"7972\" width=\"0.5\" height=\"0.701\" depth=\"0.271\" />\n  <Char code=\"7973\" width=\"0.5\" height=\"0.701\" depth=\"0.271\" />\n  <Char code=\"7974\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"7975\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"7984\" width=\"0.25\" height=\"0.696\" depth=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"7985\" width=\"0.25\" height=\"0.696\" depth=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"7986\" width=\"0.25\" height=\"0.701\" depth=\"0.012\" />\n  <Char code=\"7987\" width=\"0.25\" height=\"0.701\" depth=\"0.012\" />\n  <Char code=\"7988\" width=\"0.25\" height=\"0.701\" depth=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"7989\" width=\"0.25\" height=\"0.701\" depth=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"7990\" width=\"0.25\" height=\"0.696\" depth=\"0.012\" italic=\"0.008\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"7991\" width=\"0.25\" height=\"0.696\" depth=\"0.012\" italic=\"0.008\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"8000\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8001\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8002\" width=\"0.528\" height=\"0.701\" depth=\"0.011\" />\n  <Char code=\"8003\" width=\"0.528\" height=\"0.701\" depth=\"0.011\" />\n  <Char code=\"8004\" width=\"0.528\" height=\"0.701\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8005\" width=\"0.528\" height=\"0.701\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8016\" width=\"0.5\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8017\" width=\"0.5\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8018\" width=\"0.5\" height=\"0.701\" depth=\"0.01\" />\n  <Char code=\"8019\" width=\"0.5\" height=\"0.701\" depth=\"0.01\" />\n  <Char code=\"8020\" width=\"0.5\" height=\"0.701\" depth=\"0.01\" />\n  <Char code=\"8021\" width=\"0.5\" height=\"0.701\" depth=\"0.01\" />\n  <Char code=\"8022\" width=\"0.5\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8023\" width=\"0.5\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8032\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8033\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8034\" width=\"0.667\" height=\"0.702\" depth=\"0.011\" />\n  <Char code=\"8035\" width=\"0.667\" height=\"0.702\" depth=\"0.011\" />\n  <Char code=\"8036\" width=\"0.667\" height=\"0.701\" depth=\"0.011\" />\n  <Char code=\"8037\" width=\"0.667\" height=\"0.701\" depth=\"0.011\" />\n  <Char code=\"8038\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8039\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8048\" width=\"0.5\" height=\"0.701\" depth=\"0.011\" italic=\"0.001\" />\n  <Char code=\"8050\" width=\"0.43\" height=\"0.701\" depth=\"0.021\" />\n  <Char code=\"8052\" width=\"0.5\" height=\"0.701\" depth=\"0.271\" />\n  <Char code=\"8054\" width=\"0.25\" height=\"0.701\" depth=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"8056\" width=\"0.528\" height=\"0.701\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8058\" width=\"0.5\" height=\"0.701\" depth=\"0.01\" />\n  <Char code=\"8060\" width=\"0.667\" height=\"0.701\" depth=\"0.011\" />\n  <Char code=\"8064\" width=\"0.5\" height=\"0.696\" depth=\"0.228\" italic=\"0.001\" />\n  <Char code=\"8065\" width=\"0.5\" height=\"0.696\" depth=\"0.228\" italic=\"0.001\" />\n  <Char code=\"8066\" width=\"0.5\" height=\"0.702\" depth=\"0.228\" italic=\"0.001\" />\n  <Char code=\"8067\" width=\"0.5\" height=\"0.702\" depth=\"0.228\" italic=\"0.001\" />\n  <Char code=\"8068\" width=\"0.5\" height=\"0.701\" depth=\"0.228\" italic=\"0.001\" />\n  <Char code=\"8069\" width=\"0.5\" height=\"0.701\" depth=\"0.228\" italic=\"0.001\" />\n  <Char code=\"8070\" width=\"0.5\" height=\"0.696\" depth=\"0.228\" italic=\"0.001\" />\n  <Char code=\"8071\" width=\"0.5\" height=\"0.696\" depth=\"0.228\" italic=\"0.001\" />\n  <Char code=\"8080\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"8081\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"8082\" width=\"0.5\" height=\"0.701\" depth=\"0.271\" />\n  <Char code=\"8083\" width=\"0.5\" height=\"0.701\" depth=\"0.271\" />\n  <Char code=\"8084\" width=\"0.5\" height=\"0.701\" depth=\"0.271\" />\n  <Char code=\"8085\" width=\"0.5\" height=\"0.701\" depth=\"0.271\" />\n  <Char code=\"8086\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"8087\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"8096\" width=\"0.667\" height=\"0.696\" depth=\"0.228\" />\n  <Char code=\"8097\" width=\"0.667\" height=\"0.696\" depth=\"0.228\" />\n  <Char code=\"8098\" width=\"0.667\" height=\"0.702\" depth=\"0.228\" />\n  <Char code=\"8099\" width=\"0.667\" height=\"0.702\" depth=\"0.228\" />\n  <Char code=\"8100\" width=\"0.667\" height=\"0.701\" depth=\"0.228\" />\n  <Char code=\"8101\" width=\"0.667\" height=\"0.701\" depth=\"0.228\" />\n  <Char code=\"8102\" width=\"0.667\" height=\"0.696\" depth=\"0.228\" />\n  <Char code=\"8103\" width=\"0.667\" height=\"0.696\" depth=\"0.228\" />\n  <Char code=\"8114\" width=\"0.5\" height=\"0.701\" depth=\"0.228\" italic=\"0.001\" />\n  <Char code=\"8115\" width=\"0.5\" height=\"0.443\" depth=\"0.228\" italic=\"0.001\" />\n  <Char code=\"8116\" width=\"0.5\" height=\"0.702\" depth=\"0.228\" italic=\"0.001\" />\n  <Char code=\"8118\" width=\"0.5\" height=\"0.627\" depth=\"0.011\" italic=\"0.001\" />\n  <Char code=\"8119\" width=\"0.5\" height=\"0.627\" depth=\"0.228\" italic=\"0.001\" />\n  <Char code=\"8124\" width=\"0.75\" height=\"0.717\" depth=\"0.228\" >\n    <Kern code=\"920\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.083\"/>\n    <Kern code=\"932\" val=\"-0.083\"/>\n    <Kern code=\"933\" val=\"-0.139\"/>\n    <Kern code=\"934\" val=\"-0.083\"/>\n    <Kern code=\"936\" val=\"-0.122\"/>\n    <Kern code=\"939\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"8126\" width=\"0.222\" height=\"0.158\" depth=\"0.156\" />\n  <Char code=\"8127\" width=\"0.222\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.139\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.139\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8128\" width=\"0.333\" height=\"0.627\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n  </Char>\n  <Char code=\"8129\" width=\"0.444\" height=\"0.696\" />\n  <Char code=\"8130\" width=\"0.5\" height=\"0.701\" depth=\"0.271\" />\n  <Char code=\"8131\" width=\"0.5\" height=\"0.454\" depth=\"0.271\" />\n  <Char code=\"8132\" width=\"0.5\" height=\"0.701\" depth=\"0.271\" />\n  <Char code=\"8134\" width=\"0.5\" height=\"0.627\" depth=\"0.271\" />\n  <Char code=\"8135\" width=\"0.5\" height=\"0.627\" depth=\"0.271\" />\n  <Char code=\"8140\" width=\"0.75\" height=\"0.684\" depth=\"0.228\" />\n  <Char code=\"8141\" width=\"0.278\" height=\"0.701\" italic=\"0.016\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8142\" width=\"0.278\" height=\"0.701\" italic=\"0.012\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8143\" width=\"0.333\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n  </Char>\n  <Char code=\"8146\" width=\"0.25\" height=\"0.701\" depth=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"8150\" width=\"0.25\" height=\"0.627\" depth=\"0.012\" italic=\"0.008\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"8151\" width=\"0.25\" height=\"0.696\" depth=\"0.012\" italic=\"0.008\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"8157\" width=\"0.278\" height=\"0.701\" italic=\"0.016\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8158\" width=\"0.278\" height=\"0.701\" italic=\"0.012\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8159\" width=\"0.333\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n  </Char>\n  <Char code=\"8162\" width=\"0.5\" height=\"0.701\" depth=\"0.01\" />\n  <Char code=\"8164\" width=\"0.472\" height=\"0.696\" depth=\"0.261\" />\n  <Char code=\"8165\" width=\"0.472\" height=\"0.696\" depth=\"0.261\" />\n  <Char code=\"8166\" width=\"0.5\" height=\"0.627\" depth=\"0.01\" />\n  <Char code=\"8167\" width=\"0.5\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8173\" width=\"0.278\" height=\"0.701\" />\n  <Char code=\"8175\" width=\"0.167\" height=\"0.701\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8178\" width=\"0.667\" height=\"0.701\" depth=\"0.228\" />\n  <Char code=\"8179\" width=\"0.667\" height=\"0.453\" depth=\"0.228\" />\n  <Char code=\"8180\" width=\"0.667\" height=\"0.701\" depth=\"0.228\" />\n  <Char code=\"8182\" width=\"0.667\" height=\"0.628\" depth=\"0.011\" />\n  <Char code=\"8183\" width=\"0.667\" height=\"0.628\" depth=\"0.228\" />\n  <Char code=\"8188\" width=\"0.722\" height=\"0.706\" depth=\"0.228\" />\n  <Char code=\"8190\" width=\"0.222\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.167\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.167\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8217\" width=\"0.278\" height=\"0.695\" >\n  </Char>\n  <Char code=\"9001\" width=\"0.389\" height=\"0.751\" depth=\"0.249\" />\n  <Char code=\"9002\" width=\"0.389\" height=\"0.751\" depth=\"0.25\" />\n</Font>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/greek/fcsbpg.xml",
    "content": "<?xml version='1.0'?>\n<Font name=\"fcsbpg.ttf\" id=\"fcsbpg\" space=\"0.255\" xHeight=\"0.472\" quad=\"1\" unicode=\"204\" itVersion=\"fcsropg\" romanVersion=\"fcmbpg\" ttVersion=\"fctrpg\">\n  <Char code=\"32\" width=\"0.255\" height=\"0.0\" />\n  <Char code=\"168\" width=\"0.244\" height=\"0.63\" italic=\"0.056\" />\n  <Char code=\"884\" width=\"0.214\" height=\"0.695\" />\n  <Char code=\"885\" width=\"0.214\" height=\"0.001\" depth=\"0.188\" />\n  <Char code=\"890\" width=\"0.122\" height=\"-0.067\" depth=\"0.247\" />\n  <Char code=\"900\" width=\"0.183\" height=\"0.695\" >\n    <Kern code=\"913\" val=\"-0.122\"/>\n    <Kern code=\"927\" val=\"-0.061\"/>\n    <Kern code=\"937\" val=\"-0.031\"/>\n    <Kern code=\"8124\" val=\"-0.122\"/>\n    <Kern code=\"8188\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"901\" width=\"0.305\" height=\"0.695\" />\n  <Char code=\"903\" width=\"0.305\" height=\"0.459\" />\n  <Char code=\"912\" width=\"0.275\" height=\"0.695\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"913\" width=\"0.733\" height=\"0.687\" >\n    <Kern code=\"920\" val=\"-0.092\"/>\n    <Kern code=\"927\" val=\"-0.092\"/>\n    <Kern code=\"932\" val=\"-0.092\"/>\n    <Kern code=\"933\" val=\"-0.153\"/>\n    <Kern code=\"934\" val=\"-0.092\"/>\n    <Kern code=\"936\" val=\"-0.134\"/>\n    <Kern code=\"939\" val=\"-0.153\"/>\n  </Char>\n  <Char code=\"914\" width=\"0.733\" height=\"0.687\" />\n  <Char code=\"915\" width=\"0.58\" height=\"0.684\" >\n    <Kern code=\"913\" val=\"-0.147\"/>\n    <Kern code=\"916\" val=\"-0.122\"/>\n    <Kern code=\"923\" val=\"-0.134\"/>\n    <Kern code=\"8124\" val=\"-0.147\"/>\n  </Char>\n  <Char code=\"916\" width=\"0.916\" height=\"0.687\" >\n    <Kern code=\"927\" val=\"-0.037\"/>\n    <Kern code=\"933\" val=\"-0.153\"/>\n    <Kern code=\"939\" val=\"-0.153\"/>\n  </Char>\n  <Char code=\"917\" width=\"0.642\" height=\"0.684\" />\n  <Char code=\"918\" width=\"0.672\" height=\"0.687\" />\n  <Char code=\"919\" width=\"0.794\" height=\"0.687\" />\n  <Char code=\"920\" width=\"0.855\" height=\"0.709\" depth=\"0.022\" >\n    <Kern code=\"913\" val=\"-0.092\"/>\n    <Kern code=\"8124\" val=\"-0.092\"/>\n  </Char>\n  <Char code=\"921\" width=\"0.308\" height=\"0.687\" />\n  <Char code=\"922\" width=\"0.764\" height=\"0.687\" >\n    <Kern code=\"927\" val=\"-0.092\"/>\n  </Char>\n  <Char code=\"923\" width=\"0.672\" height=\"0.687\" >\n    <Kern code=\"927\" val=\"-0.037\"/>\n    <Kern code=\"933\" val=\"-0.11\"/>\n    <Kern code=\"939\" val=\"-0.11\"/>\n  </Char>\n  <Char code=\"924\" width=\"0.978\" height=\"0.687\" />\n  <Char code=\"925\" width=\"0.794\" height=\"0.687\" >\n    <Kern code=\"913\" val=\"-0.092\"/>\n    <Kern code=\"8124\" val=\"-0.092\"/>\n  </Char>\n  <Char code=\"926\" width=\"0.733\" height=\"0.681\" />\n  <Char code=\"927\" width=\"0.794\" height=\"0.71\" depth=\"0.022\" >\n    <Kern code=\"913\" val=\"-0.092\"/>\n    <Kern code=\"931\" val=\"-0.061\"/>\n    <Kern code=\"8124\" val=\"-0.092\"/>\n  </Char>\n  <Char code=\"928\" width=\"0.794\" height=\"0.684\" />\n  <Char code=\"929\" width=\"0.703\" height=\"0.687\" >\n    <Kern code=\"913\" val=\"-0.183\"/>\n    <Kern code=\"8124\" val=\"-0.183\"/>\n  </Char>\n  <Char code=\"931\" width=\"0.794\" height=\"0.687\" >\n    <Kern code=\"913\" val=\"-0.031\"/>\n    <Kern code=\"8124\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"932\" width=\"0.733\" height=\"0.681\" >\n    <Kern code=\"913\" val=\"-0.092\"/>\n    <Kern code=\"8124\" val=\"-0.092\"/>\n  </Char>\n  <Char code=\"933\" width=\"0.855\" height=\"0.709\" >\n    <Kern code=\"913\" val=\"-0.153\"/>\n    <Kern code=\"916\" val=\"-0.153\"/>\n    <Kern code=\"923\" val=\"-0.153\"/>\n    <Kern code=\"8124\" val=\"-0.153\"/>\n  </Char>\n  <Char code=\"934\" width=\"0.794\" height=\"0.687\" >\n    <Kern code=\"913\" val=\"-0.092\"/>\n    <Kern code=\"8124\" val=\"-0.092\"/>\n  </Char>\n  <Char code=\"935\" width=\"0.733\" height=\"0.687\" />\n  <Char code=\"936\" width=\"0.855\" height=\"0.687\" >\n    <Kern code=\"913\" val=\"-0.134\"/>\n    <Kern code=\"8124\" val=\"-0.134\"/>\n  </Char>\n  <Char code=\"937\" width=\"0.794\" height=\"0.709\" />\n  <Char code=\"938\" width=\"0.308\" height=\"0.847\" italic=\"0.01\" />\n  <Char code=\"939\" width=\"0.855\" height=\"0.847\" >\n    <Kern code=\"913\" val=\"-0.153\"/>\n    <Kern code=\"916\" val=\"-0.153\"/>\n    <Kern code=\"923\" val=\"-0.153\"/>\n    <Kern code=\"8124\" val=\"-0.153\"/>\n  </Char>\n  <Char code=\"940\" width=\"0.55\" height=\"0.695\" depth=\"0.011\" italic=\"0.061\" />\n  <Char code=\"941\" width=\"0.473\" height=\"0.695\" depth=\"0.022\" />\n  <Char code=\"942\" width=\"0.55\" height=\"0.695\" depth=\"0.272\" />\n  <Char code=\"943\" width=\"0.275\" height=\"0.695\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"944\" width=\"0.55\" height=\"0.695\" depth=\"0.011\" />\n  <Char code=\"945\" width=\"0.55\" height=\"0.471\" depth=\"0.011\" italic=\"0.061\" />\n  <Char code=\"946\" width=\"0.55\" height=\"0.706\" depth=\"0.271\" />\n  <Char code=\"947\" width=\"0.611\" height=\"0.471\" depth=\"0.228\" />\n  <Char code=\"948\" width=\"0.519\" height=\"0.707\" depth=\"0.011\" />\n  <Char code=\"949\" width=\"0.473\" height=\"0.482\" depth=\"0.022\" />\n  <Char code=\"950\" width=\"0.519\" height=\"0.718\" depth=\"0.186\" />\n  <Char code=\"951\" width=\"0.55\" height=\"0.482\" depth=\"0.272\" />\n  <Char code=\"952\" width=\"0.626\" height=\"0.706\" depth=\"0.011\" />\n  <Char code=\"953\" width=\"0.275\" height=\"0.47\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"954\" width=\"0.58\" height=\"0.487\" depth=\"0.027\" />\n  <Char code=\"955\" width=\"0.55\" height=\"0.697\" depth=\"0.01\" />\n  <Char code=\"956\" width=\"0.586\" height=\"0.482\" depth=\"0.266\" italic=\"0.001\" />\n  <Char code=\"957\" width=\"0.519\" height=\"0.472\" depth=\"0.01\" />\n  <Char code=\"958\" width=\"0.519\" height=\"0.718\" depth=\"0.186\" />\n  <Char code=\"959\" width=\"0.58\" height=\"0.471\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"955\" val=\"-0.031\"/>\n    <Kern code=\"957\" val=\"-0.024\"/>\n    <Kern code=\"964\" val=\"-0.024\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"960\" width=\"0.565\" height=\"0.459\" depth=\"0.011\" italic=\"0.027\" />\n  <Char code=\"961\" width=\"0.519\" height=\"0.471\" depth=\"0.266\" />\n  <Char code=\"962\" width=\"0.489\" height=\"0.471\" depth=\"0.125\" />\n  <Char code=\"963\" width=\"0.626\" height=\"0.459\" depth=\"0.012\" />\n  <Char code=\"964\" width=\"0.504\" height=\"0.46\" depth=\"0.011\" >\n    <Kern code=\"940\" val=\"-0.031\"/>\n    <Kern code=\"945\" val=\"-0.031\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"969\" val=\"-0.031\"/>\n    <Kern code=\"972\" val=\"-0.031\"/>\n    <Kern code=\"974\" val=\"-0.031\"/>\n    <Kern code=\"7936\" val=\"-0.031\"/>\n    <Kern code=\"7937\" val=\"-0.031\"/>\n    <Kern code=\"7940\" val=\"-0.031\"/>\n    <Kern code=\"7941\" val=\"-0.031\"/>\n    <Kern code=\"7942\" val=\"-0.031\"/>\n    <Kern code=\"7943\" val=\"-0.031\"/>\n    <Kern code=\"8000\" val=\"-0.031\"/>\n    <Kern code=\"8001\" val=\"-0.031\"/>\n    <Kern code=\"8004\" val=\"-0.031\"/>\n    <Kern code=\"8005\" val=\"-0.031\"/>\n    <Kern code=\"8032\" val=\"-0.031\"/>\n    <Kern code=\"8033\" val=\"-0.031\"/>\n    <Kern code=\"8036\" val=\"-0.031\"/>\n    <Kern code=\"8037\" val=\"-0.031\"/>\n    <Kern code=\"8038\" val=\"-0.031\"/>\n    <Kern code=\"8039\" val=\"-0.031\"/>\n    <Kern code=\"8048\" val=\"-0.031\"/>\n    <Kern code=\"8056\" val=\"-0.031\"/>\n    <Kern code=\"8060\" val=\"-0.031\"/>\n    <Kern code=\"8064\" val=\"-0.031\"/>\n    <Kern code=\"8065\" val=\"-0.031\"/>\n    <Kern code=\"8068\" val=\"-0.031\"/>\n    <Kern code=\"8069\" val=\"-0.031\"/>\n    <Kern code=\"8070\" val=\"-0.031\"/>\n    <Kern code=\"8071\" val=\"-0.031\"/>\n    <Kern code=\"8096\" val=\"-0.031\"/>\n    <Kern code=\"8097\" val=\"-0.031\"/>\n    <Kern code=\"8100\" val=\"-0.031\"/>\n    <Kern code=\"8101\" val=\"-0.031\"/>\n    <Kern code=\"8102\" val=\"-0.031\"/>\n    <Kern code=\"8103\" val=\"-0.031\"/>\n    <Kern code=\"8114\" val=\"-0.031\"/>\n    <Kern code=\"8116\" val=\"-0.031\"/>\n    <Kern code=\"8118\" val=\"-0.031\"/>\n    <Kern code=\"8119\" val=\"-0.031\"/>\n    <Kern code=\"8178\" val=\"-0.031\"/>\n    <Kern code=\"8180\" val=\"-0.031\"/>\n    <Kern code=\"8182\" val=\"-0.031\"/>\n    <Kern code=\"8183\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"965\" width=\"0.55\" height=\"0.492\" depth=\"0.01\" />\n  <Char code=\"966\" width=\"0.642\" height=\"0.486\" depth=\"0.272\" />\n  <Char code=\"967\" width=\"0.611\" height=\"0.473\" depth=\"0.263\" />\n  <Char code=\"968\" width=\"0.642\" height=\"0.718\" depth=\"0.272\" />\n  <Char code=\"969\" width=\"0.733\" height=\"0.481\" depth=\"0.011\" />\n  <Char code=\"970\" width=\"0.275\" height=\"0.641\" depth=\"0.01\" italic=\"0.001\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"971\" width=\"0.55\" height=\"0.64\" depth=\"0.01\" />\n  <Char code=\"972\" width=\"0.58\" height=\"0.695\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"955\" val=\"-0.031\"/>\n    <Kern code=\"957\" val=\"-0.024\"/>\n    <Kern code=\"964\" val=\"-0.024\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"973\" width=\"0.55\" height=\"0.695\" depth=\"0.01\" />\n  <Char code=\"974\" width=\"0.733\" height=\"0.695\" depth=\"0.011\" />\n  <Char code=\"984\" width=\"0.55\" height=\"0.698\" />\n  <Char code=\"985\" width=\"0.55\" height=\"0.646\" depth=\"0.077\" />\n  <Char code=\"986\" width=\"0.855\" height=\"0.682\" depth=\"0.001\" />\n  <Char code=\"987\" width=\"0.55\" height=\"0.481\" />\n  <Char code=\"988\" width=\"0.611\" height=\"0.684\" />\n  <Char code=\"989\" width=\"0.55\" height=\"0.461\" depth=\"0.249\" />\n  <Char code=\"991\" width=\"0.428\" height=\"0.577\" depth=\"0.075\" />\n  <Char code=\"992\" width=\"0.703\" height=\"0.686\" />\n  <Char code=\"993\" width=\"0.794\" height=\"0.695\" />\n  <Char code=\"7936\" width=\"0.55\" height=\"0.696\" depth=\"0.011\" italic=\"0.061\" />\n  <Char code=\"7937\" width=\"0.55\" height=\"0.696\" depth=\"0.011\" italic=\"0.061\" />\n  <Char code=\"7938\" width=\"0.55\" height=\"0.696\" depth=\"0.011\" italic=\"0.061\" />\n  <Char code=\"7939\" width=\"0.55\" height=\"0.696\" depth=\"0.011\" italic=\"0.061\" />\n  <Char code=\"7940\" width=\"0.55\" height=\"0.696\" depth=\"0.011\" italic=\"0.061\" />\n  <Char code=\"7941\" width=\"0.55\" height=\"0.696\" depth=\"0.011\" italic=\"0.061\" />\n  <Char code=\"7942\" width=\"0.55\" height=\"0.695\" depth=\"0.011\" italic=\"0.061\" />\n  <Char code=\"7943\" width=\"0.55\" height=\"0.695\" depth=\"0.011\" italic=\"0.061\" />\n  <Char code=\"7952\" width=\"0.473\" height=\"0.696\" depth=\"0.022\" />\n  <Char code=\"7953\" width=\"0.473\" height=\"0.696\" depth=\"0.022\" />\n  <Char code=\"7954\" width=\"0.473\" height=\"0.696\" depth=\"0.022\" />\n  <Char code=\"7955\" width=\"0.473\" height=\"0.696\" depth=\"0.022\" />\n  <Char code=\"7956\" width=\"0.473\" height=\"0.696\" depth=\"0.022\" />\n  <Char code=\"7957\" width=\"0.473\" height=\"0.696\" depth=\"0.022\" />\n  <Char code=\"7968\" width=\"0.55\" height=\"0.696\" depth=\"0.272\" />\n  <Char code=\"7969\" width=\"0.55\" height=\"0.696\" depth=\"0.272\" />\n  <Char code=\"7970\" width=\"0.55\" height=\"0.696\" depth=\"0.272\" />\n  <Char code=\"7971\" width=\"0.55\" height=\"0.696\" depth=\"0.272\" />\n  <Char code=\"7972\" width=\"0.55\" height=\"0.696\" depth=\"0.272\" />\n  <Char code=\"7973\" width=\"0.55\" height=\"0.696\" depth=\"0.272\" />\n  <Char code=\"7974\" width=\"0.55\" height=\"0.695\" depth=\"0.272\" />\n  <Char code=\"7975\" width=\"0.55\" height=\"0.695\" depth=\"0.272\" />\n  <Char code=\"7984\" width=\"0.275\" height=\"0.696\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"7985\" width=\"0.275\" height=\"0.696\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"7986\" width=\"0.275\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"7987\" width=\"0.275\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"7988\" width=\"0.275\" height=\"0.696\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"7989\" width=\"0.275\" height=\"0.696\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"7990\" width=\"0.275\" height=\"0.696\" depth=\"0.01\" italic=\"0.016\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"7991\" width=\"0.275\" height=\"0.696\" depth=\"0.01\" italic=\"0.016\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"8000\" width=\"0.58\" height=\"0.696\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"955\" val=\"-0.031\"/>\n    <Kern code=\"957\" val=\"-0.024\"/>\n    <Kern code=\"964\" val=\"-0.024\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"8001\" width=\"0.58\" height=\"0.696\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"955\" val=\"-0.031\"/>\n    <Kern code=\"957\" val=\"-0.024\"/>\n    <Kern code=\"964\" val=\"-0.024\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"8002\" width=\"0.58\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8003\" width=\"0.58\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8004\" width=\"0.58\" height=\"0.696\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"955\" val=\"-0.031\"/>\n    <Kern code=\"957\" val=\"-0.024\"/>\n    <Kern code=\"964\" val=\"-0.024\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"8005\" width=\"0.58\" height=\"0.696\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"955\" val=\"-0.031\"/>\n    <Kern code=\"957\" val=\"-0.024\"/>\n    <Kern code=\"964\" val=\"-0.024\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"8016\" width=\"0.55\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8017\" width=\"0.55\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8018\" width=\"0.55\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8019\" width=\"0.55\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8020\" width=\"0.55\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8021\" width=\"0.55\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8022\" width=\"0.55\" height=\"0.695\" depth=\"0.01\" />\n  <Char code=\"8023\" width=\"0.55\" height=\"0.695\" depth=\"0.01\" />\n  <Char code=\"8032\" width=\"0.733\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8033\" width=\"0.733\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8034\" width=\"0.733\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8035\" width=\"0.733\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8036\" width=\"0.733\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8037\" width=\"0.733\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8038\" width=\"0.733\" height=\"0.695\" depth=\"0.011\" />\n  <Char code=\"8039\" width=\"0.733\" height=\"0.695\" depth=\"0.011\" />\n  <Char code=\"8048\" width=\"0.55\" height=\"0.695\" depth=\"0.011\" italic=\"0.061\" />\n  <Char code=\"8050\" width=\"0.473\" height=\"0.695\" depth=\"0.022\" />\n  <Char code=\"8052\" width=\"0.55\" height=\"0.695\" depth=\"0.272\" />\n  <Char code=\"8054\" width=\"0.275\" height=\"0.695\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"8056\" width=\"0.58\" height=\"0.695\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"955\" val=\"-0.031\"/>\n    <Kern code=\"957\" val=\"-0.024\"/>\n    <Kern code=\"964\" val=\"-0.024\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"8058\" width=\"0.55\" height=\"0.695\" depth=\"0.01\" />\n  <Char code=\"8060\" width=\"0.733\" height=\"0.695\" depth=\"0.011\" />\n  <Char code=\"8064\" width=\"0.55\" height=\"0.696\" depth=\"0.247\" italic=\"0.061\" />\n  <Char code=\"8065\" width=\"0.55\" height=\"0.696\" depth=\"0.247\" italic=\"0.061\" />\n  <Char code=\"8066\" width=\"0.55\" height=\"0.696\" depth=\"0.247\" italic=\"0.061\" />\n  <Char code=\"8067\" width=\"0.55\" height=\"0.696\" depth=\"0.247\" italic=\"0.061\" />\n  <Char code=\"8068\" width=\"0.55\" height=\"0.696\" depth=\"0.247\" italic=\"0.061\" />\n  <Char code=\"8069\" width=\"0.55\" height=\"0.696\" depth=\"0.247\" italic=\"0.061\" />\n  <Char code=\"8070\" width=\"0.55\" height=\"0.695\" depth=\"0.247\" italic=\"0.061\" />\n  <Char code=\"8071\" width=\"0.55\" height=\"0.695\" depth=\"0.247\" italic=\"0.061\" />\n  <Char code=\"8080\" width=\"0.55\" height=\"0.696\" depth=\"0.272\" />\n  <Char code=\"8081\" width=\"0.55\" height=\"0.696\" depth=\"0.272\" />\n  <Char code=\"8082\" width=\"0.55\" height=\"0.696\" depth=\"0.272\" />\n  <Char code=\"8083\" width=\"0.55\" height=\"0.696\" depth=\"0.272\" />\n  <Char code=\"8084\" width=\"0.55\" height=\"0.696\" depth=\"0.272\" />\n  <Char code=\"8085\" width=\"0.55\" height=\"0.696\" depth=\"0.272\" />\n  <Char code=\"8086\" width=\"0.55\" height=\"0.695\" depth=\"0.272\" />\n  <Char code=\"8087\" width=\"0.55\" height=\"0.695\" depth=\"0.272\" />\n  <Char code=\"8096\" width=\"0.733\" height=\"0.696\" depth=\"0.247\" />\n  <Char code=\"8097\" width=\"0.733\" height=\"0.696\" depth=\"0.247\" />\n  <Char code=\"8098\" width=\"0.733\" height=\"0.696\" depth=\"0.247\" />\n  <Char code=\"8099\" width=\"0.733\" height=\"0.696\" depth=\"0.247\" />\n  <Char code=\"8100\" width=\"0.733\" height=\"0.696\" depth=\"0.247\" />\n  <Char code=\"8101\" width=\"0.733\" height=\"0.696\" depth=\"0.247\" />\n  <Char code=\"8102\" width=\"0.733\" height=\"0.695\" depth=\"0.247\" />\n  <Char code=\"8103\" width=\"0.733\" height=\"0.695\" depth=\"0.247\" />\n  <Char code=\"8114\" width=\"0.55\" height=\"0.695\" depth=\"0.247\" italic=\"0.061\" />\n  <Char code=\"8115\" width=\"0.55\" height=\"0.471\" depth=\"0.247\" italic=\"0.061\" />\n  <Char code=\"8116\" width=\"0.55\" height=\"0.695\" depth=\"0.247\" italic=\"0.061\" />\n  <Char code=\"8118\" width=\"0.55\" height=\"0.64\" depth=\"0.011\" italic=\"0.061\" />\n  <Char code=\"8119\" width=\"0.55\" height=\"0.64\" depth=\"0.247\" italic=\"0.061\" />\n  <Char code=\"8124\" width=\"0.733\" height=\"0.687\" depth=\"0.247\" >\n    <Kern code=\"920\" val=\"-0.092\"/>\n    <Kern code=\"927\" val=\"-0.092\"/>\n    <Kern code=\"932\" val=\"-0.092\"/>\n    <Kern code=\"933\" val=\"-0.153\"/>\n    <Kern code=\"934\" val=\"-0.092\"/>\n    <Kern code=\"936\" val=\"-0.134\"/>\n    <Kern code=\"939\" val=\"-0.153\"/>\n  </Char>\n  <Char code=\"8126\" width=\"0.244\" height=\"0.155\" depth=\"0.153\" />\n  <Char code=\"8127\" width=\"0.244\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.153\"/>\n    <Kern code=\"927\" val=\"-0.061\"/>\n    <Kern code=\"937\" val=\"-0.031\"/>\n    <Kern code=\"8124\" val=\"-0.153\"/>\n    <Kern code=\"8188\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"8128\" width=\"0.367\" height=\"0.64\" >\n    <Kern code=\"913\" val=\"-0.122\"/>\n    <Kern code=\"8124\" val=\"-0.122\"/>\n  </Char>\n  <Char code=\"8129\" width=\"0.489\" height=\"0.696\" />\n  <Char code=\"8130\" width=\"0.55\" height=\"0.695\" depth=\"0.272\" />\n  <Char code=\"8131\" width=\"0.55\" height=\"0.482\" depth=\"0.272\" />\n  <Char code=\"8132\" width=\"0.55\" height=\"0.695\" depth=\"0.272\" />\n  <Char code=\"8134\" width=\"0.55\" height=\"0.64\" depth=\"0.272\" />\n  <Char code=\"8135\" width=\"0.55\" height=\"0.64\" depth=\"0.272\" />\n  <Char code=\"8140\" width=\"0.794\" height=\"0.687\" depth=\"0.247\" />\n  <Char code=\"8141\" width=\"0.305\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.092\"/>\n    <Kern code=\"927\" val=\"-0.031\"/>\n    <Kern code=\"8124\" val=\"-0.092\"/>\n  </Char>\n  <Char code=\"8142\" width=\"0.305\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.092\"/>\n    <Kern code=\"927\" val=\"-0.031\"/>\n    <Kern code=\"8124\" val=\"-0.092\"/>\n  </Char>\n  <Char code=\"8143\" width=\"0.367\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.122\"/>\n    <Kern code=\"8124\" val=\"-0.122\"/>\n  </Char>\n  <Char code=\"8146\" width=\"0.275\" height=\"0.695\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"8150\" width=\"0.275\" height=\"0.64\" depth=\"0.01\" italic=\"0.016\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"8151\" width=\"0.275\" height=\"0.696\" depth=\"0.01\" italic=\"0.016\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"8157\" width=\"0.305\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.092\"/>\n    <Kern code=\"927\" val=\"-0.031\"/>\n    <Kern code=\"8124\" val=\"-0.092\"/>\n  </Char>\n  <Char code=\"8158\" width=\"0.305\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.092\"/>\n    <Kern code=\"927\" val=\"-0.031\"/>\n    <Kern code=\"8124\" val=\"-0.092\"/>\n  </Char>\n  <Char code=\"8159\" width=\"0.367\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.122\"/>\n    <Kern code=\"8124\" val=\"-0.122\"/>\n  </Char>\n  <Char code=\"8162\" width=\"0.55\" height=\"0.695\" depth=\"0.01\" />\n  <Char code=\"8164\" width=\"0.519\" height=\"0.696\" depth=\"0.266\" />\n  <Char code=\"8165\" width=\"0.519\" height=\"0.696\" depth=\"0.266\" />\n  <Char code=\"8166\" width=\"0.55\" height=\"0.64\" depth=\"0.01\" />\n  <Char code=\"8167\" width=\"0.55\" height=\"0.695\" depth=\"0.01\" />\n  <Char code=\"8173\" width=\"0.305\" height=\"0.695\" />\n  <Char code=\"8175\" width=\"0.183\" height=\"0.695\" >\n    <Kern code=\"913\" val=\"-0.122\"/>\n    <Kern code=\"927\" val=\"-0.061\"/>\n    <Kern code=\"937\" val=\"-0.031\"/>\n    <Kern code=\"8124\" val=\"-0.122\"/>\n    <Kern code=\"8188\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"8178\" width=\"0.733\" height=\"0.695\" depth=\"0.247\" />\n  <Char code=\"8179\" width=\"0.733\" height=\"0.481\" depth=\"0.247\" />\n  <Char code=\"8180\" width=\"0.733\" height=\"0.695\" depth=\"0.247\" />\n  <Char code=\"8182\" width=\"0.733\" height=\"0.641\" depth=\"0.011\" />\n  <Char code=\"8183\" width=\"0.733\" height=\"0.641\" depth=\"0.247\" />\n  <Char code=\"8188\" width=\"0.794\" height=\"0.709\" depth=\"0.247\" />\n  <Char code=\"8190\" width=\"0.244\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.183\"/>\n    <Kern code=\"927\" val=\"-0.061\"/>\n    <Kern code=\"937\" val=\"-0.031\"/>\n    <Kern code=\"8124\" val=\"-0.183\"/>\n    <Kern code=\"8188\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"8217\" width=\"0.305\" height=\"0.696\" >\n  </Char>\n  <Char code=\"9001\" width=\"0.428\" height=\"0.751\" depth=\"0.25\" />\n  <Char code=\"9002\" width=\"0.428\" height=\"0.751\" depth=\"0.25\" />\n</Font>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/greek/fcsropg.xml",
    "content": "<?xml version='1.0'?>\n<Font name=\"fcsropg.ttf\" id=\"fcsropg\" space=\"0.239\" xHeight=\"0.444\" quad=\"1\" unicode=\"204\" romanVersion=\"fcmripg\" boldVersion=\"fcsbpg\" ttVersion=\"fctrpg\">\n  <Char code=\"32\" width=\"0.239\" height=\"0.0\" />\n  <Char code=\"168\" width=\"0.222\" height=\"0.603\" italic=\"0.17\" />\n  <Char code=\"884\" width=\"0.194\" height=\"0.695\" italic=\"0.14\" />\n  <Char code=\"885\" width=\"0.194\" height=\"0.001\" depth=\"0.21\" italic=\"0.003\" />\n  <Char code=\"890\" width=\"0.111\" height=\"-0.064\" depth=\"0.238\" />\n  <Char code=\"900\" width=\"0.167\" height=\"0.695\" italic=\"0.145\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"901\" width=\"0.278\" height=\"0.695\" italic=\"0.117\" />\n  <Char code=\"903\" width=\"0.278\" height=\"0.431\" />\n  <Char code=\"912\" width=\"0.25\" height=\"0.695\" depth=\"0.011\" italic=\"0.099\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"913\" width=\"0.667\" height=\"0.685\" >\n    <Kern code=\"920\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.083\"/>\n    <Kern code=\"932\" val=\"-0.083\"/>\n    <Kern code=\"933\" val=\"-0.139\"/>\n    <Kern code=\"934\" val=\"-0.083\"/>\n    <Kern code=\"936\" val=\"-0.122\"/>\n    <Kern code=\"939\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"914\" width=\"0.667\" height=\"0.685\" italic=\"0.028\" />\n  <Char code=\"915\" width=\"0.542\" height=\"0.681\" italic=\"0.101\" >\n    <Kern code=\"913\" val=\"-0.133\"/>\n    <Kern code=\"916\" val=\"-0.111\"/>\n    <Kern code=\"923\" val=\"-0.122\"/>\n    <Kern code=\"8124\" val=\"-0.133\"/>\n  </Char>\n  <Char code=\"916\" width=\"0.833\" height=\"0.684\" >\n    <Kern code=\"927\" val=\"-0.033\"/>\n    <Kern code=\"933\" val=\"-0.139\"/>\n    <Kern code=\"939\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"917\" width=\"0.597\" height=\"0.681\" italic=\"0.088\" />\n  <Char code=\"918\" width=\"0.611\" height=\"0.684\" italic=\"0.089\" />\n  <Char code=\"919\" width=\"0.708\" height=\"0.684\" italic=\"0.049\" />\n  <Char code=\"920\" width=\"0.778\" height=\"0.707\" depth=\"0.022\" italic=\"0.026\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"921\" width=\"0.278\" height=\"0.684\" italic=\"0.049\" />\n  <Char code=\"922\" width=\"0.694\" height=\"0.684\" italic=\"0.089\" >\n    <Kern code=\"927\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"923\" width=\"0.611\" height=\"0.684\" >\n    <Kern code=\"927\" val=\"-0.033\"/>\n    <Kern code=\"933\" val=\"-0.1\"/>\n    <Kern code=\"939\" val=\"-0.1\"/>\n  </Char>\n  <Char code=\"924\" width=\"0.875\" height=\"0.684\" italic=\"0.044\" />\n  <Char code=\"925\" width=\"0.708\" height=\"0.684\" italic=\"0.047\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"926\" width=\"0.667\" height=\"0.679\" italic=\"0.096\" />\n  <Char code=\"927\" width=\"0.736\" height=\"0.706\" depth=\"0.021\" italic=\"0.026\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"931\" val=\"-0.056\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"928\" width=\"0.708\" height=\"0.681\" italic=\"0.048\" />\n  <Char code=\"929\" width=\"0.639\" height=\"0.685\" italic=\"0.051\" >\n    <Kern code=\"913\" val=\"-0.167\"/>\n    <Kern code=\"8124\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"931\" width=\"0.722\" height=\"0.684\" italic=\"0.089\" >\n    <Kern code=\"913\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"932\" width=\"0.68\" height=\"0.679\" italic=\"0.107\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"933\" width=\"0.778\" height=\"0.707\" italic=\"0.064\" >\n    <Kern code=\"913\" val=\"-0.139\"/>\n    <Kern code=\"916\" val=\"-0.139\"/>\n    <Kern code=\"923\" val=\"-0.139\"/>\n    <Kern code=\"8124\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"934\" width=\"0.722\" height=\"0.684\" italic=\"0.021\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"935\" width=\"0.667\" height=\"0.684\" italic=\"0.088\" />\n  <Char code=\"936\" width=\"0.778\" height=\"0.684\" italic=\"0.072\" >\n    <Kern code=\"913\" val=\"-0.122\"/>\n    <Kern code=\"8124\" val=\"-0.122\"/>\n  </Char>\n  <Char code=\"937\" width=\"0.722\" height=\"0.706\" italic=\"0.046\" />\n  <Char code=\"938\" width=\"0.278\" height=\"0.833\" italic=\"0.168\" />\n  <Char code=\"939\" width=\"0.778\" height=\"0.833\" italic=\"0.064\" >\n    <Kern code=\"913\" val=\"-0.139\"/>\n    <Kern code=\"916\" val=\"-0.139\"/>\n    <Kern code=\"923\" val=\"-0.139\"/>\n    <Kern code=\"8124\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"940\" width=\"0.5\" height=\"0.695\" depth=\"0.011\" italic=\"0.065\" />\n  <Char code=\"941\" width=\"0.43\" height=\"0.695\" depth=\"0.022\" italic=\"0.042\" />\n  <Char code=\"942\" width=\"0.5\" height=\"0.695\" depth=\"0.272\" italic=\"0.022\" />\n  <Char code=\"943\" width=\"0.25\" height=\"0.695\" depth=\"0.011\" italic=\"0.099\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"944\" width=\"0.5\" height=\"0.695\" depth=\"0.011\" italic=\"0.013\" />\n  <Char code=\"945\" width=\"0.5\" height=\"0.443\" depth=\"0.011\" italic=\"0.065\" />\n  <Char code=\"946\" width=\"0.5\" height=\"0.706\" depth=\"0.272\" italic=\"0.03\" />\n  <Char code=\"947\" width=\"0.555\" height=\"0.443\" depth=\"0.216\" italic=\"0.044\" />\n  <Char code=\"948\" width=\"0.472\" height=\"0.652\" depth=\"0.01\" italic=\"0.05\" />\n  <Char code=\"949\" width=\"0.43\" height=\"0.453\" depth=\"0.022\" italic=\"0.042\" />\n  <Char code=\"950\" width=\"0.472\" height=\"0.718\" depth=\"0.153\" italic=\"0.089\" />\n  <Char code=\"951\" width=\"0.5\" height=\"0.453\" depth=\"0.272\" italic=\"0.011\" />\n  <Char code=\"952\" width=\"0.569\" height=\"0.707\" depth=\"0.012\" italic=\"0.031\" />\n  <Char code=\"953\" width=\"0.25\" height=\"0.443\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"954\" width=\"0.528\" height=\"0.458\" depth=\"0.026\" italic=\"0.05\" />\n  <Char code=\"955\" width=\"0.5\" height=\"0.698\" depth=\"0.011\" />\n  <Char code=\"956\" width=\"0.522\" height=\"0.453\" depth=\"0.267\" italic=\"0.018\" />\n  <Char code=\"957\" width=\"0.472\" height=\"0.443\" depth=\"0.01\" italic=\"0.022\" />\n  <Char code=\"958\" width=\"0.472\" height=\"0.718\" depth=\"0.152\" italic=\"0.088\" />\n  <Char code=\"959\" width=\"0.528\" height=\"0.442\" depth=\"0.011\" italic=\"0.009\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"960\" width=\"0.514\" height=\"0.432\" depth=\"0.011\" italic=\"0.048\" />\n  <Char code=\"961\" width=\"0.472\" height=\"0.443\" depth=\"0.266\" italic=\"0.009\" />\n  <Char code=\"962\" width=\"0.444\" height=\"0.443\" depth=\"0.124\" italic=\"0.044\" />\n  <Char code=\"963\" width=\"0.569\" height=\"0.431\" depth=\"0.01\" italic=\"0.061\" />\n  <Char code=\"964\" width=\"0.458\" height=\"0.432\" depth=\"0.011\" italic=\"0.048\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"969\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"974\" val=\"-0.028\"/>\n    <Kern code=\"7936\" val=\"-0.028\"/>\n    <Kern code=\"7937\" val=\"-0.028\"/>\n    <Kern code=\"7940\" val=\"-0.028\"/>\n    <Kern code=\"7941\" val=\"-0.028\"/>\n    <Kern code=\"7942\" val=\"-0.028\"/>\n    <Kern code=\"7943\" val=\"-0.028\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8032\" val=\"-0.028\"/>\n    <Kern code=\"8033\" val=\"-0.028\"/>\n    <Kern code=\"8036\" val=\"-0.028\"/>\n    <Kern code=\"8037\" val=\"-0.028\"/>\n    <Kern code=\"8038\" val=\"-0.028\"/>\n    <Kern code=\"8039\" val=\"-0.028\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8060\" val=\"-0.028\"/>\n    <Kern code=\"8064\" val=\"-0.028\"/>\n    <Kern code=\"8065\" val=\"-0.028\"/>\n    <Kern code=\"8068\" val=\"-0.028\"/>\n    <Kern code=\"8069\" val=\"-0.028\"/>\n    <Kern code=\"8070\" val=\"-0.028\"/>\n    <Kern code=\"8071\" val=\"-0.028\"/>\n    <Kern code=\"8096\" val=\"-0.028\"/>\n    <Kern code=\"8097\" val=\"-0.028\"/>\n    <Kern code=\"8100\" val=\"-0.028\"/>\n    <Kern code=\"8101\" val=\"-0.028\"/>\n    <Kern code=\"8102\" val=\"-0.028\"/>\n    <Kern code=\"8103\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8178\" val=\"-0.028\"/>\n    <Kern code=\"8180\" val=\"-0.028\"/>\n    <Kern code=\"8182\" val=\"-0.028\"/>\n    <Kern code=\"8183\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"965\" width=\"0.5\" height=\"0.456\" depth=\"0.011\" italic=\"0.013\" />\n  <Char code=\"966\" width=\"0.583\" height=\"0.454\" depth=\"0.272\" italic=\"0.012\" />\n  <Char code=\"967\" width=\"0.555\" height=\"0.445\" depth=\"0.263\" italic=\"0.051\" />\n  <Char code=\"968\" width=\"0.583\" height=\"0.718\" depth=\"0.272\" italic=\"0.021\" />\n  <Char code=\"969\" width=\"0.667\" height=\"0.453\" depth=\"0.011\" italic=\"0.01\" />\n  <Char code=\"970\" width=\"0.25\" height=\"0.626\" depth=\"0.011\" italic=\"0.12\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"971\" width=\"0.5\" height=\"0.626\" depth=\"0.011\" italic=\"0.013\" />\n  <Char code=\"972\" width=\"0.528\" height=\"0.695\" depth=\"0.011\" italic=\"0.009\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"973\" width=\"0.5\" height=\"0.695\" depth=\"0.011\" italic=\"0.013\" />\n  <Char code=\"974\" width=\"0.667\" height=\"0.695\" depth=\"0.011\" italic=\"0.01\" />\n  <Char code=\"984\" width=\"0.5\" height=\"0.695\" italic=\"0.072\" />\n  <Char code=\"985\" width=\"0.5\" height=\"0.601\" depth=\"0.064\" italic=\"0.042\" />\n  <Char code=\"986\" width=\"0.778\" height=\"0.679\" />\n  <Char code=\"987\" width=\"0.5\" height=\"0.454\" italic=\"0.04\" />\n  <Char code=\"988\" width=\"0.569\" height=\"0.681\" italic=\"0.101\" />\n  <Char code=\"989\" width=\"0.5\" height=\"0.432\" depth=\"0.25\" italic=\"0.028\" />\n  <Char code=\"991\" width=\"0.389\" height=\"0.563\" depth=\"0.106\" italic=\"0.005\" />\n  <Char code=\"992\" width=\"0.639\" height=\"0.683\" />\n  <Char code=\"993\" width=\"0.722\" height=\"0.696\" />\n  <Char code=\"7936\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.065\" />\n  <Char code=\"7937\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.065\" />\n  <Char code=\"7938\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.065\" />\n  <Char code=\"7939\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.065\" />\n  <Char code=\"7940\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.065\" />\n  <Char code=\"7941\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.065\" />\n  <Char code=\"7942\" width=\"0.5\" height=\"0.695\" depth=\"0.011\" italic=\"0.067\" />\n  <Char code=\"7943\" width=\"0.5\" height=\"0.695\" depth=\"0.011\" italic=\"0.067\" />\n  <Char code=\"7952\" width=\"0.43\" height=\"0.696\" depth=\"0.022\" italic=\"0.042\" />\n  <Char code=\"7953\" width=\"0.43\" height=\"0.696\" depth=\"0.022\" italic=\"0.042\" />\n  <Char code=\"7954\" width=\"0.43\" height=\"0.696\" depth=\"0.022\" italic=\"0.048\" />\n  <Char code=\"7955\" width=\"0.43\" height=\"0.696\" depth=\"0.022\" italic=\"0.048\" />\n  <Char code=\"7956\" width=\"0.43\" height=\"0.696\" depth=\"0.022\" italic=\"0.083\" />\n  <Char code=\"7957\" width=\"0.43\" height=\"0.696\" depth=\"0.022\" italic=\"0.083\" />\n  <Char code=\"7968\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.011\" />\n  <Char code=\"7969\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.011\" />\n  <Char code=\"7970\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.029\" />\n  <Char code=\"7971\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.029\" />\n  <Char code=\"7972\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.064\" />\n  <Char code=\"7973\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.064\" />\n  <Char code=\"7974\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.079\" />\n  <Char code=\"7975\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.079\" />\n  <Char code=\"7984\" width=\"0.25\" height=\"0.696\" depth=\"0.011\" italic=\"0.071\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7985\" width=\"0.25\" height=\"0.696\" depth=\"0.011\" italic=\"0.022\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7986\" width=\"0.25\" height=\"0.696\" depth=\"0.011\" italic=\"0.106\" />\n  <Char code=\"7987\" width=\"0.25\" height=\"0.696\" depth=\"0.011\" italic=\"0.106\" />\n  <Char code=\"7988\" width=\"0.25\" height=\"0.696\" depth=\"0.011\" italic=\"0.141\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7989\" width=\"0.25\" height=\"0.696\" depth=\"0.011\" italic=\"0.141\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7990\" width=\"0.25\" height=\"0.696\" depth=\"0.011\" italic=\"0.155\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7991\" width=\"0.25\" height=\"0.696\" depth=\"0.011\" italic=\"0.155\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8000\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" italic=\"0.009\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8001\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" italic=\"0.009\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8002\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" italic=\"0.009\" />\n  <Char code=\"8003\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" italic=\"0.009\" />\n  <Char code=\"8004\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" italic=\"0.034\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8005\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" italic=\"0.034\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8016\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.013\" />\n  <Char code=\"8017\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.013\" />\n  <Char code=\"8018\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.013\" />\n  <Char code=\"8019\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.013\" />\n  <Char code=\"8020\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.013\" />\n  <Char code=\"8021\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.013\" />\n  <Char code=\"8022\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.026\" />\n  <Char code=\"8023\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.026\" />\n  <Char code=\"8032\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" italic=\"0.01\" />\n  <Char code=\"8033\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" italic=\"0.01\" />\n  <Char code=\"8034\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" italic=\"0.01\" />\n  <Char code=\"8035\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" italic=\"0.01\" />\n  <Char code=\"8036\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" italic=\"0.01\" />\n  <Char code=\"8037\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" italic=\"0.01\" />\n  <Char code=\"8038\" width=\"0.667\" height=\"0.695\" depth=\"0.011\" italic=\"0.035\" />\n  <Char code=\"8039\" width=\"0.667\" height=\"0.695\" depth=\"0.011\" italic=\"0.035\" />\n  <Char code=\"8048\" width=\"0.5\" height=\"0.695\" depth=\"0.011\" italic=\"0.065\" />\n  <Char code=\"8050\" width=\"0.43\" height=\"0.695\" depth=\"0.022\" italic=\"0.042\" />\n  <Char code=\"8052\" width=\"0.5\" height=\"0.695\" depth=\"0.272\" italic=\"0.011\" />\n  <Char code=\"8054\" width=\"0.25\" height=\"0.695\" depth=\"0.011\" italic=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8056\" width=\"0.528\" height=\"0.695\" depth=\"0.011\" italic=\"0.009\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8058\" width=\"0.5\" height=\"0.695\" depth=\"0.011\" italic=\"0.013\" />\n  <Char code=\"8060\" width=\"0.667\" height=\"0.695\" depth=\"0.011\" italic=\"0.01\" />\n  <Char code=\"8064\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.065\" />\n  <Char code=\"8065\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.065\" />\n  <Char code=\"8066\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.065\" />\n  <Char code=\"8067\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.065\" />\n  <Char code=\"8068\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.065\" />\n  <Char code=\"8069\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.065\" />\n  <Char code=\"8070\" width=\"0.5\" height=\"0.695\" depth=\"0.238\" italic=\"0.067\" />\n  <Char code=\"8071\" width=\"0.5\" height=\"0.695\" depth=\"0.238\" italic=\"0.067\" />\n  <Char code=\"8080\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.011\" />\n  <Char code=\"8081\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.011\" />\n  <Char code=\"8082\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.029\" />\n  <Char code=\"8083\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.029\" />\n  <Char code=\"8084\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.064\" />\n  <Char code=\"8085\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.064\" />\n  <Char code=\"8086\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.079\" />\n  <Char code=\"8087\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.079\" />\n  <Char code=\"8096\" width=\"0.667\" height=\"0.696\" depth=\"0.238\" italic=\"0.01\" />\n  <Char code=\"8097\" width=\"0.667\" height=\"0.696\" depth=\"0.238\" italic=\"0.01\" />\n  <Char code=\"8098\" width=\"0.667\" height=\"0.696\" depth=\"0.238\" italic=\"0.01\" />\n  <Char code=\"8099\" width=\"0.667\" height=\"0.696\" depth=\"0.238\" italic=\"0.01\" />\n  <Char code=\"8100\" width=\"0.667\" height=\"0.696\" depth=\"0.238\" italic=\"0.01\" />\n  <Char code=\"8101\" width=\"0.667\" height=\"0.696\" depth=\"0.238\" italic=\"0.01\" />\n  <Char code=\"8102\" width=\"0.667\" height=\"0.695\" depth=\"0.238\" italic=\"0.035\" />\n  <Char code=\"8103\" width=\"0.667\" height=\"0.695\" depth=\"0.238\" italic=\"0.035\" />\n  <Char code=\"8114\" width=\"0.5\" height=\"0.695\" depth=\"0.238\" italic=\"0.065\" />\n  <Char code=\"8115\" width=\"0.5\" height=\"0.443\" depth=\"0.238\" italic=\"0.065\" />\n  <Char code=\"8116\" width=\"0.5\" height=\"0.695\" depth=\"0.238\" italic=\"0.065\" />\n  <Char code=\"8118\" width=\"0.5\" height=\"0.627\" depth=\"0.011\" italic=\"0.065\" />\n  <Char code=\"8119\" width=\"0.5\" height=\"0.627\" depth=\"0.238\" italic=\"0.065\" />\n  <Char code=\"8124\" width=\"0.667\" height=\"0.685\" depth=\"0.238\" >\n    <Kern code=\"920\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.083\"/>\n    <Kern code=\"932\" val=\"-0.083\"/>\n    <Kern code=\"933\" val=\"-0.139\"/>\n    <Kern code=\"934\" val=\"-0.083\"/>\n    <Kern code=\"936\" val=\"-0.122\"/>\n    <Kern code=\"939\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"8126\" width=\"0.222\" height=\"0.158\" depth=\"0.156\" />\n  <Char code=\"8127\" width=\"0.222\" height=\"0.696\" italic=\"0.117\" >\n    <Kern code=\"913\" val=\"-0.139\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.139\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8128\" width=\"0.333\" height=\"0.627\" italic=\"0.132\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n  </Char>\n  <Char code=\"8129\" width=\"0.444\" height=\"0.695\" italic=\"0.091\" />\n  <Char code=\"8130\" width=\"0.5\" height=\"0.695\" depth=\"0.272\" italic=\"0.011\" />\n  <Char code=\"8131\" width=\"0.5\" height=\"0.453\" depth=\"0.272\" italic=\"0.011\" />\n  <Char code=\"8132\" width=\"0.5\" height=\"0.695\" depth=\"0.272\" italic=\"0.022\" />\n  <Char code=\"8134\" width=\"0.5\" height=\"0.626\" depth=\"0.272\" italic=\"0.064\" />\n  <Char code=\"8135\" width=\"0.5\" height=\"0.626\" depth=\"0.272\" italic=\"0.064\" />\n  <Char code=\"8140\" width=\"0.708\" height=\"0.684\" depth=\"0.238\" italic=\"0.049\" />\n  <Char code=\"8141\" width=\"0.278\" height=\"0.696\" italic=\"0.124\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8142\" width=\"0.278\" height=\"0.696\" italic=\"0.159\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8143\" width=\"0.333\" height=\"0.695\" italic=\"0.146\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n  </Char>\n  <Char code=\"8146\" width=\"0.25\" height=\"0.695\" depth=\"0.011\" italic=\"0.08\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8150\" width=\"0.25\" height=\"0.627\" depth=\"0.011\" italic=\"0.141\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8151\" width=\"0.25\" height=\"0.696\" depth=\"0.011\" italic=\"0.155\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8157\" width=\"0.278\" height=\"0.696\" italic=\"0.124\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8158\" width=\"0.278\" height=\"0.696\" italic=\"0.159\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8159\" width=\"0.333\" height=\"0.695\" italic=\"0.146\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n  </Char>\n  <Char code=\"8162\" width=\"0.5\" height=\"0.695\" depth=\"0.011\" italic=\"0.013\" />\n  <Char code=\"8164\" width=\"0.472\" height=\"0.696\" depth=\"0.266\" italic=\"0.009\" />\n  <Char code=\"8165\" width=\"0.472\" height=\"0.696\" depth=\"0.266\" italic=\"0.009\" />\n  <Char code=\"8166\" width=\"0.5\" height=\"0.627\" depth=\"0.011\" italic=\"0.013\" />\n  <Char code=\"8167\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.026\" />\n  <Char code=\"8173\" width=\"0.278\" height=\"0.695\" italic=\"0.098\" />\n  <Char code=\"8175\" width=\"0.167\" height=\"0.695\" italic=\"0.112\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8178\" width=\"0.667\" height=\"0.695\" depth=\"0.238\" italic=\"0.01\" />\n  <Char code=\"8179\" width=\"0.667\" height=\"0.453\" depth=\"0.238\" italic=\"0.01\" />\n  <Char code=\"8180\" width=\"0.667\" height=\"0.695\" depth=\"0.238\" italic=\"0.01\" />\n  <Char code=\"8182\" width=\"0.667\" height=\"0.627\" depth=\"0.011\" italic=\"0.021\" />\n  <Char code=\"8183\" width=\"0.667\" height=\"0.627\" depth=\"0.238\" italic=\"0.021\" />\n  <Char code=\"8188\" width=\"0.722\" height=\"0.706\" depth=\"0.238\" italic=\"0.046\" />\n  <Char code=\"8190\" width=\"0.222\" height=\"0.696\" italic=\"0.068\" >\n    <Kern code=\"913\" val=\"-0.167\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.167\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8217\" width=\"0.278\" height=\"0.695\" italic=\"0.057\" >\n  </Char>\n  <Char code=\"9001\" width=\"0.389\" height=\"0.752\" depth=\"0.249\" italic=\"0.099\" />\n  <Char code=\"9002\" width=\"0.389\" height=\"0.751\" depth=\"0.249\" />\n</Font>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/greek/fcsrpg.xml",
    "content": "<?xml version='1.0'?>\n<Font name=\"fcsrpg.ttf\" id=\"fcsrpg\" space=\"0.239\" xHeight=\"0.443\" quad=\"1\" unicode=\"204\" itVersion=\"fcsropg\" boldVersion=\"fcsbpg\" ttVersion=\"fctrpg\">\n  <Char code=\"32\" width=\"0.239\" height=\"0.0\" />\n  <Char code=\"168\" width=\"0.222\" height=\"0.603\" italic=\"0.052\" />\n  <Char code=\"884\" width=\"0.194\" height=\"0.695\" />\n  <Char code=\"885\" width=\"0.194\" height=\"0.001\" depth=\"0.21\" italic=\"0.003\" />\n  <Char code=\"890\" width=\"0.111\" height=\"-0.064\" depth=\"0.238\" />\n  <Char code=\"900\" width=\"0.167\" height=\"0.695\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"901\" width=\"0.278\" height=\"0.695\" />\n  <Char code=\"903\" width=\"0.278\" height=\"0.431\" />\n  <Char code=\"912\" width=\"0.25\" height=\"0.695\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"913\" width=\"0.667\" height=\"0.685\" >\n    <Kern code=\"920\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.083\"/>\n    <Kern code=\"932\" val=\"-0.083\"/>\n    <Kern code=\"933\" val=\"-0.139\"/>\n    <Kern code=\"934\" val=\"-0.083\"/>\n    <Kern code=\"936\" val=\"-0.122\"/>\n    <Kern code=\"939\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"914\" width=\"0.667\" height=\"0.684\" />\n  <Char code=\"915\" width=\"0.542\" height=\"0.681\" >\n    <Kern code=\"913\" val=\"-0.133\"/>\n    <Kern code=\"916\" val=\"-0.111\"/>\n    <Kern code=\"923\" val=\"-0.122\"/>\n    <Kern code=\"8124\" val=\"-0.133\"/>\n  </Char>\n  <Char code=\"916\" width=\"0.833\" height=\"0.685\" >\n    <Kern code=\"927\" val=\"-0.033\"/>\n    <Kern code=\"933\" val=\"-0.139\"/>\n    <Kern code=\"939\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"917\" width=\"0.597\" height=\"0.681\" />\n  <Char code=\"918\" width=\"0.611\" height=\"0.684\" />\n  <Char code=\"919\" width=\"0.708\" height=\"0.684\" />\n  <Char code=\"920\" width=\"0.778\" height=\"0.706\" depth=\"0.021\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"921\" width=\"0.278\" height=\"0.684\" />\n  <Char code=\"922\" width=\"0.694\" height=\"0.684\" >\n    <Kern code=\"927\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"923\" width=\"0.611\" height=\"0.685\" >\n    <Kern code=\"927\" val=\"-0.033\"/>\n    <Kern code=\"933\" val=\"-0.1\"/>\n    <Kern code=\"939\" val=\"-0.1\"/>\n  </Char>\n  <Char code=\"924\" width=\"0.875\" height=\"0.684\" />\n  <Char code=\"925\" width=\"0.708\" height=\"0.684\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"926\" width=\"0.667\" height=\"0.678\" />\n  <Char code=\"927\" width=\"0.736\" height=\"0.707\" depth=\"0.021\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"931\" val=\"-0.056\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"928\" width=\"0.708\" height=\"0.681\" />\n  <Char code=\"929\" width=\"0.639\" height=\"0.685\" >\n    <Kern code=\"913\" val=\"-0.167\"/>\n    <Kern code=\"8124\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"931\" width=\"0.722\" height=\"0.684\" >\n    <Kern code=\"913\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"932\" width=\"0.68\" height=\"0.678\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"933\" width=\"0.778\" height=\"0.707\" >\n    <Kern code=\"913\" val=\"-0.139\"/>\n    <Kern code=\"916\" val=\"-0.139\"/>\n    <Kern code=\"923\" val=\"-0.139\"/>\n    <Kern code=\"8124\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"934\" width=\"0.722\" height=\"0.684\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"935\" width=\"0.667\" height=\"0.684\" />\n  <Char code=\"936\" width=\"0.778\" height=\"0.684\" >\n    <Kern code=\"913\" val=\"-0.122\"/>\n    <Kern code=\"8124\" val=\"-0.122\"/>\n  </Char>\n  <Char code=\"937\" width=\"0.722\" height=\"0.707\" />\n  <Char code=\"938\" width=\"0.278\" height=\"0.833\" italic=\"0.001\" />\n  <Char code=\"939\" width=\"0.778\" height=\"0.833\" >\n    <Kern code=\"913\" val=\"-0.139\"/>\n    <Kern code=\"916\" val=\"-0.139\"/>\n    <Kern code=\"923\" val=\"-0.139\"/>\n    <Kern code=\"8124\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"940\" width=\"0.5\" height=\"0.695\" depth=\"0.011\" italic=\"0.045\" />\n  <Char code=\"941\" width=\"0.43\" height=\"0.695\" depth=\"0.022\" />\n  <Char code=\"942\" width=\"0.5\" height=\"0.695\" depth=\"0.271\" />\n  <Char code=\"943\" width=\"0.25\" height=\"0.695\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"944\" width=\"0.5\" height=\"0.695\" depth=\"0.01\" />\n  <Char code=\"945\" width=\"0.5\" height=\"0.443\" depth=\"0.011\" italic=\"0.045\" />\n  <Char code=\"946\" width=\"0.5\" height=\"0.707\" depth=\"0.271\" />\n  <Char code=\"947\" width=\"0.555\" height=\"0.444\" depth=\"0.216\" />\n  <Char code=\"948\" width=\"0.472\" height=\"0.652\" depth=\"0.011\" />\n  <Char code=\"949\" width=\"0.43\" height=\"0.453\" depth=\"0.022\" />\n  <Char code=\"950\" width=\"0.472\" height=\"0.718\" depth=\"0.153\" />\n  <Char code=\"951\" width=\"0.5\" height=\"0.454\" depth=\"0.271\" />\n  <Char code=\"952\" width=\"0.569\" height=\"0.707\" depth=\"0.011\" />\n  <Char code=\"953\" width=\"0.25\" height=\"0.442\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"954\" width=\"0.528\" height=\"0.457\" depth=\"0.025\" />\n  <Char code=\"955\" width=\"0.5\" height=\"0.697\" depth=\"0.011\" />\n  <Char code=\"956\" width=\"0.522\" height=\"0.453\" depth=\"0.266\" />\n  <Char code=\"957\" width=\"0.472\" height=\"0.443\" depth=\"0.01\" />\n  <Char code=\"958\" width=\"0.472\" height=\"0.718\" depth=\"0.152\" />\n  <Char code=\"959\" width=\"0.528\" height=\"0.443\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"960\" width=\"0.514\" height=\"0.432\" depth=\"0.01\" italic=\"0.009\" />\n  <Char code=\"961\" width=\"0.472\" height=\"0.442\" depth=\"0.266\" />\n  <Char code=\"962\" width=\"0.444\" height=\"0.443\" depth=\"0.124\" />\n  <Char code=\"963\" width=\"0.569\" height=\"0.432\" depth=\"0.01\" />\n  <Char code=\"964\" width=\"0.458\" height=\"0.432\" depth=\"0.01\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"969\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"974\" val=\"-0.028\"/>\n    <Kern code=\"7936\" val=\"-0.028\"/>\n    <Kern code=\"7937\" val=\"-0.028\"/>\n    <Kern code=\"7940\" val=\"-0.028\"/>\n    <Kern code=\"7941\" val=\"-0.028\"/>\n    <Kern code=\"7942\" val=\"-0.028\"/>\n    <Kern code=\"7943\" val=\"-0.028\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8032\" val=\"-0.028\"/>\n    <Kern code=\"8033\" val=\"-0.028\"/>\n    <Kern code=\"8036\" val=\"-0.028\"/>\n    <Kern code=\"8037\" val=\"-0.028\"/>\n    <Kern code=\"8038\" val=\"-0.028\"/>\n    <Kern code=\"8039\" val=\"-0.028\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8060\" val=\"-0.028\"/>\n    <Kern code=\"8064\" val=\"-0.028\"/>\n    <Kern code=\"8065\" val=\"-0.028\"/>\n    <Kern code=\"8068\" val=\"-0.028\"/>\n    <Kern code=\"8069\" val=\"-0.028\"/>\n    <Kern code=\"8070\" val=\"-0.028\"/>\n    <Kern code=\"8071\" val=\"-0.028\"/>\n    <Kern code=\"8096\" val=\"-0.028\"/>\n    <Kern code=\"8097\" val=\"-0.028\"/>\n    <Kern code=\"8100\" val=\"-0.028\"/>\n    <Kern code=\"8101\" val=\"-0.028\"/>\n    <Kern code=\"8102\" val=\"-0.028\"/>\n    <Kern code=\"8103\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8178\" val=\"-0.028\"/>\n    <Kern code=\"8180\" val=\"-0.028\"/>\n    <Kern code=\"8182\" val=\"-0.028\"/>\n    <Kern code=\"8183\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"965\" width=\"0.5\" height=\"0.457\" depth=\"0.01\" />\n  <Char code=\"966\" width=\"0.583\" height=\"0.454\" depth=\"0.272\" />\n  <Char code=\"967\" width=\"0.555\" height=\"0.444\" depth=\"0.262\" />\n  <Char code=\"968\" width=\"0.583\" height=\"0.717\" depth=\"0.271\" />\n  <Char code=\"969\" width=\"0.667\" height=\"0.453\" depth=\"0.011\" />\n  <Char code=\"970\" width=\"0.25\" height=\"0.626\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"971\" width=\"0.5\" height=\"0.626\" depth=\"0.01\" />\n  <Char code=\"972\" width=\"0.528\" height=\"0.695\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"973\" width=\"0.5\" height=\"0.695\" depth=\"0.01\" />\n  <Char code=\"974\" width=\"0.667\" height=\"0.695\" depth=\"0.011\" />\n  <Char code=\"984\" width=\"0.5\" height=\"0.696\" />\n  <Char code=\"985\" width=\"0.5\" height=\"0.601\" depth=\"0.064\" />\n  <Char code=\"986\" width=\"0.778\" height=\"0.679\" />\n  <Char code=\"987\" width=\"0.5\" height=\"0.454\" />\n  <Char code=\"988\" width=\"0.569\" height=\"0.681\" />\n  <Char code=\"989\" width=\"0.5\" height=\"0.432\" depth=\"0.249\" />\n  <Char code=\"991\" width=\"0.389\" height=\"0.563\" depth=\"0.107\" />\n  <Char code=\"992\" width=\"0.639\" height=\"0.683\" />\n  <Char code=\"993\" width=\"0.722\" height=\"0.695\" />\n  <Char code=\"7936\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.045\" />\n  <Char code=\"7937\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.045\" />\n  <Char code=\"7938\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.045\" />\n  <Char code=\"7939\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.045\" />\n  <Char code=\"7940\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.045\" />\n  <Char code=\"7941\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.045\" />\n  <Char code=\"7942\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.045\" />\n  <Char code=\"7943\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.045\" />\n  <Char code=\"7952\" width=\"0.43\" height=\"0.696\" depth=\"0.022\" />\n  <Char code=\"7953\" width=\"0.43\" height=\"0.696\" depth=\"0.022\" />\n  <Char code=\"7954\" width=\"0.43\" height=\"0.696\" depth=\"0.022\" />\n  <Char code=\"7955\" width=\"0.43\" height=\"0.696\" depth=\"0.022\" />\n  <Char code=\"7956\" width=\"0.43\" height=\"0.696\" depth=\"0.022\" />\n  <Char code=\"7957\" width=\"0.43\" height=\"0.696\" depth=\"0.022\" />\n  <Char code=\"7968\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"7969\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"7970\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"7971\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"7972\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"7973\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"7974\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"7975\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"7984\" width=\"0.25\" height=\"0.696\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7985\" width=\"0.25\" height=\"0.696\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7986\" width=\"0.25\" height=\"0.696\" depth=\"0.01\" italic=\"0.003\" />\n  <Char code=\"7987\" width=\"0.25\" height=\"0.696\" depth=\"0.01\" italic=\"0.003\" />\n  <Char code=\"7988\" width=\"0.25\" height=\"0.696\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7989\" width=\"0.25\" height=\"0.696\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7990\" width=\"0.25\" height=\"0.695\" depth=\"0.01\" italic=\"0.008\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7991\" width=\"0.25\" height=\"0.695\" depth=\"0.01\" italic=\"0.008\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8000\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8001\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8002\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8003\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8004\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8005\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8016\" width=\"0.5\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8017\" width=\"0.5\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8018\" width=\"0.5\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8019\" width=\"0.5\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8020\" width=\"0.5\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8021\" width=\"0.5\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8022\" width=\"0.5\" height=\"0.695\" depth=\"0.01\" />\n  <Char code=\"8023\" width=\"0.5\" height=\"0.695\" depth=\"0.01\" />\n  <Char code=\"8032\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8033\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8034\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8035\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8036\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8037\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8038\" width=\"0.667\" height=\"0.695\" depth=\"0.011\" />\n  <Char code=\"8039\" width=\"0.667\" height=\"0.695\" depth=\"0.011\" />\n  <Char code=\"8048\" width=\"0.5\" height=\"0.695\" depth=\"0.011\" italic=\"0.045\" />\n  <Char code=\"8050\" width=\"0.43\" height=\"0.695\" depth=\"0.022\" />\n  <Char code=\"8052\" width=\"0.5\" height=\"0.695\" depth=\"0.271\" />\n  <Char code=\"8054\" width=\"0.25\" height=\"0.695\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8056\" width=\"0.528\" height=\"0.695\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8058\" width=\"0.5\" height=\"0.695\" depth=\"0.01\" />\n  <Char code=\"8060\" width=\"0.667\" height=\"0.695\" depth=\"0.011\" />\n  <Char code=\"8064\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.045\" />\n  <Char code=\"8065\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.045\" />\n  <Char code=\"8066\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.045\" />\n  <Char code=\"8067\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.045\" />\n  <Char code=\"8068\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.045\" />\n  <Char code=\"8069\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.045\" />\n  <Char code=\"8070\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.045\" />\n  <Char code=\"8071\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.045\" />\n  <Char code=\"8080\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"8081\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"8082\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"8083\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"8084\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"8085\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"8086\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"8087\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"8096\" width=\"0.667\" height=\"0.696\" depth=\"0.238\" />\n  <Char code=\"8097\" width=\"0.667\" height=\"0.696\" depth=\"0.238\" />\n  <Char code=\"8098\" width=\"0.667\" height=\"0.696\" depth=\"0.238\" />\n  <Char code=\"8099\" width=\"0.667\" height=\"0.696\" depth=\"0.238\" />\n  <Char code=\"8100\" width=\"0.667\" height=\"0.696\" depth=\"0.238\" />\n  <Char code=\"8101\" width=\"0.667\" height=\"0.696\" depth=\"0.238\" />\n  <Char code=\"8102\" width=\"0.667\" height=\"0.695\" depth=\"0.238\" />\n  <Char code=\"8103\" width=\"0.667\" height=\"0.695\" depth=\"0.238\" />\n  <Char code=\"8114\" width=\"0.5\" height=\"0.695\" depth=\"0.238\" italic=\"0.045\" />\n  <Char code=\"8115\" width=\"0.5\" height=\"0.443\" depth=\"0.238\" italic=\"0.045\" />\n  <Char code=\"8116\" width=\"0.5\" height=\"0.695\" depth=\"0.238\" italic=\"0.045\" />\n  <Char code=\"8118\" width=\"0.5\" height=\"0.627\" depth=\"0.011\" italic=\"0.045\" />\n  <Char code=\"8119\" width=\"0.5\" height=\"0.627\" depth=\"0.238\" italic=\"0.045\" />\n  <Char code=\"8124\" width=\"0.667\" height=\"0.685\" depth=\"0.238\" >\n    <Kern code=\"920\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.083\"/>\n    <Kern code=\"932\" val=\"-0.083\"/>\n    <Kern code=\"933\" val=\"-0.139\"/>\n    <Kern code=\"934\" val=\"-0.083\"/>\n    <Kern code=\"936\" val=\"-0.122\"/>\n    <Kern code=\"939\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"8126\" width=\"0.222\" height=\"0.158\" depth=\"0.156\" />\n  <Char code=\"8127\" width=\"0.222\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.139\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.139\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8128\" width=\"0.333\" height=\"0.626\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n  </Char>\n  <Char code=\"8129\" width=\"0.444\" height=\"0.696\" />\n  <Char code=\"8130\" width=\"0.5\" height=\"0.695\" depth=\"0.271\" />\n  <Char code=\"8131\" width=\"0.5\" height=\"0.454\" depth=\"0.271\" />\n  <Char code=\"8132\" width=\"0.5\" height=\"0.695\" depth=\"0.271\" />\n  <Char code=\"8134\" width=\"0.5\" height=\"0.627\" depth=\"0.271\" />\n  <Char code=\"8135\" width=\"0.5\" height=\"0.627\" depth=\"0.271\" />\n  <Char code=\"8140\" width=\"0.708\" height=\"0.684\" depth=\"0.238\" />\n  <Char code=\"8141\" width=\"0.278\" height=\"0.696\" italic=\"0.021\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8142\" width=\"0.278\" height=\"0.696\" italic=\"0.012\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8143\" width=\"0.333\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n  </Char>\n  <Char code=\"8146\" width=\"0.25\" height=\"0.695\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8150\" width=\"0.25\" height=\"0.628\" depth=\"0.01\" italic=\"0.008\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8151\" width=\"0.25\" height=\"0.695\" depth=\"0.01\" italic=\"0.008\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8157\" width=\"0.278\" height=\"0.696\" italic=\"0.021\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8158\" width=\"0.278\" height=\"0.696\" italic=\"0.012\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8159\" width=\"0.333\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n  </Char>\n  <Char code=\"8162\" width=\"0.5\" height=\"0.695\" depth=\"0.01\" />\n  <Char code=\"8164\" width=\"0.472\" height=\"0.696\" depth=\"0.266\" />\n  <Char code=\"8165\" width=\"0.472\" height=\"0.696\" depth=\"0.266\" />\n  <Char code=\"8166\" width=\"0.5\" height=\"0.626\" depth=\"0.01\" />\n  <Char code=\"8167\" width=\"0.5\" height=\"0.695\" depth=\"0.01\" />\n  <Char code=\"8173\" width=\"0.278\" height=\"0.695\" />\n  <Char code=\"8175\" width=\"0.167\" height=\"0.695\" italic=\"0.009\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8178\" width=\"0.667\" height=\"0.695\" depth=\"0.238\" />\n  <Char code=\"8179\" width=\"0.667\" height=\"0.453\" depth=\"0.238\" />\n  <Char code=\"8180\" width=\"0.667\" height=\"0.695\" depth=\"0.238\" />\n  <Char code=\"8182\" width=\"0.667\" height=\"0.626\" depth=\"0.011\" />\n  <Char code=\"8183\" width=\"0.667\" height=\"0.626\" depth=\"0.238\" />\n  <Char code=\"8188\" width=\"0.722\" height=\"0.707\" depth=\"0.238\" />\n  <Char code=\"8190\" width=\"0.222\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.167\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.167\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8217\" width=\"0.278\" height=\"0.696\" >\n  </Char>\n  <Char code=\"9001\" width=\"0.389\" height=\"0.751\" depth=\"0.249\" />\n  <Char code=\"9002\" width=\"0.389\" height=\"0.751\" depth=\"0.25\" />\n</Font>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/greek/fctrpg.xml",
    "content": "<?xml version='1.0'?>\n<Font name=\"fctrpg.ttf\" id=\"fctrpg\" space=\"0.525\" xHeight=\"0.438\" quad=\"1\" unicode=\"204\">\n  <Char code=\"32\" width=\"0.525\" height=\"0.0\" />\n  <Char code=\"168\" width=\"0.525\" height=\"0.607\" />\n  <Char code=\"884\" width=\"0.525\" height=\"0.613\" />\n  <Char code=\"885\" width=\"0.525\" height=\"0.001\" depth=\"0.14\" />\n  <Char code=\"890\" width=\"0.525\" height=\"-0.053\" depth=\"0.184\" />\n  <Char code=\"900\" width=\"0.525\" height=\"0.613\" />\n  <Char code=\"901\" width=\"0.525\" height=\"0.613\" />\n  <Char code=\"903\" width=\"0.525\" height=\"0.431\" />\n  <Char code=\"912\" width=\"0.525\" height=\"0.613\" depth=\"0.006\" />\n  <Char code=\"913\" width=\"0.525\" height=\"0.653\" />\n  <Char code=\"914\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"915\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"916\" width=\"0.525\" height=\"0.653\" />\n  <Char code=\"917\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"918\" width=\"0.525\" height=\"0.64\" />\n  <Char code=\"919\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"920\" width=\"0.525\" height=\"0.652\" depth=\"0.011\" />\n  <Char code=\"921\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"922\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"923\" width=\"0.525\" height=\"0.653\" />\n  <Char code=\"924\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"925\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"926\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"927\" width=\"0.525\" height=\"0.652\" depth=\"0.011\" />\n  <Char code=\"928\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"929\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"931\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"932\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"933\" width=\"0.525\" height=\"0.651\" />\n  <Char code=\"934\" width=\"0.525\" height=\"0.64\" />\n  <Char code=\"935\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"936\" width=\"0.525\" height=\"0.64\" />\n  <Char code=\"937\" width=\"0.525\" height=\"0.651\" />\n  <Char code=\"938\" width=\"0.525\" height=\"0.783\" />\n  <Char code=\"939\" width=\"0.525\" height=\"0.783\" />\n  <Char code=\"940\" width=\"0.525\" height=\"0.613\" depth=\"0.006\" italic=\"0.002\" />\n  <Char code=\"941\" width=\"0.525\" height=\"0.613\" depth=\"0.011\" />\n  <Char code=\"942\" width=\"0.525\" height=\"0.613\" depth=\"0.232\" />\n  <Char code=\"943\" width=\"0.525\" height=\"0.613\" depth=\"0.006\" />\n  <Char code=\"944\" width=\"0.525\" height=\"0.669\" depth=\"0.006\" />\n  <Char code=\"945\" width=\"0.525\" height=\"0.438\" depth=\"0.006\" italic=\"0.002\" />\n  <Char code=\"946\" width=\"0.525\" height=\"0.647\" depth=\"0.232\" />\n  <Char code=\"947\" width=\"0.525\" height=\"0.438\" depth=\"0.177\" />\n  <Char code=\"948\" width=\"0.525\" height=\"0.637\" depth=\"0.005\" />\n  <Char code=\"949\" width=\"0.525\" height=\"0.443\" depth=\"0.011\" />\n  <Char code=\"950\" width=\"0.525\" height=\"0.651\" depth=\"0.133\" />\n  <Char code=\"951\" width=\"0.525\" height=\"0.442\" depth=\"0.232\" />\n  <Char code=\"952\" width=\"0.525\" height=\"0.652\" depth=\"0.011\" />\n  <Char code=\"953\" width=\"0.525\" height=\"0.437\" depth=\"0.006\" />\n  <Char code=\"954\" width=\"0.525\" height=\"0.445\" depth=\"0.013\" />\n  <Char code=\"955\" width=\"0.525\" height=\"0.642\" depth=\"0.005\" />\n  <Char code=\"956\" width=\"0.525\" height=\"0.442\" depth=\"0.227\" />\n  <Char code=\"957\" width=\"0.525\" height=\"0.438\" depth=\"0.005\" />\n  <Char code=\"958\" width=\"0.525\" height=\"0.651\" depth=\"0.133\" />\n  <Char code=\"959\" width=\"0.525\" height=\"0.438\" depth=\"0.006\" />\n  <Char code=\"960\" width=\"0.525\" height=\"0.432\" depth=\"0.006\" />\n  <Char code=\"961\" width=\"0.525\" height=\"0.437\" depth=\"0.221\" />\n  <Char code=\"962\" width=\"0.525\" height=\"0.437\" depth=\"0.111\" />\n  <Char code=\"963\" width=\"0.525\" height=\"0.437\" depth=\"0.005\" />\n  <Char code=\"964\" width=\"0.525\" height=\"0.431\" depth=\"0.006\" />\n  <Char code=\"965\" width=\"0.525\" height=\"0.443\" depth=\"0.006\" />\n  <Char code=\"966\" width=\"0.525\" height=\"0.443\" depth=\"0.232\" />\n  <Char code=\"967\" width=\"0.525\" height=\"0.439\" depth=\"0.229\" />\n  <Char code=\"968\" width=\"0.525\" height=\"0.651\" depth=\"0.232\" />\n  <Char code=\"969\" width=\"0.525\" height=\"0.442\" depth=\"0.006\" />\n  <Char code=\"970\" width=\"0.525\" height=\"0.641\" depth=\"0.006\" />\n  <Char code=\"971\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"972\" width=\"0.525\" height=\"0.613\" depth=\"0.006\" />\n  <Char code=\"973\" width=\"0.525\" height=\"0.613\" depth=\"0.006\" />\n  <Char code=\"974\" width=\"0.525\" height=\"0.613\" depth=\"0.006\" />\n  <Char code=\"984\" width=\"0.525\" height=\"0.647\" />\n  <Char code=\"985\" width=\"0.525\" height=\"0.609\" depth=\"0.055\" />\n  <Char code=\"986\" width=\"0.525\" height=\"0.641\" depth=\"0.028\" />\n  <Char code=\"987\" width=\"0.525\" height=\"0.443\" depth=\"0.018\" />\n  <Char code=\"988\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"989\" width=\"0.525\" height=\"0.432\" depth=\"0.221\" />\n  <Char code=\"991\" width=\"0.525\" height=\"0.542\" depth=\"0.101\" />\n  <Char code=\"992\" width=\"0.525\" height=\"0.667\" />\n  <Char code=\"993\" width=\"0.525\" height=\"0.64\" depth=\"0.011\" />\n  <Char code=\"7936\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" italic=\"0.002\" />\n  <Char code=\"7937\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" italic=\"0.002\" />\n  <Char code=\"7938\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" italic=\"0.002\" />\n  <Char code=\"7939\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" italic=\"0.002\" />\n  <Char code=\"7940\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" italic=\"0.002\" />\n  <Char code=\"7941\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" italic=\"0.002\" />\n  <Char code=\"7942\" width=\"0.525\" height=\"0.696\" depth=\"0.006\" italic=\"0.002\" />\n  <Char code=\"7943\" width=\"0.525\" height=\"0.696\" depth=\"0.006\" italic=\"0.002\" />\n  <Char code=\"7952\" width=\"0.525\" height=\"0.64\" depth=\"0.011\" />\n  <Char code=\"7953\" width=\"0.525\" height=\"0.64\" depth=\"0.011\" />\n  <Char code=\"7954\" width=\"0.525\" height=\"0.64\" depth=\"0.011\" />\n  <Char code=\"7955\" width=\"0.525\" height=\"0.64\" depth=\"0.011\" />\n  <Char code=\"7956\" width=\"0.525\" height=\"0.64\" depth=\"0.011\" />\n  <Char code=\"7957\" width=\"0.525\" height=\"0.64\" depth=\"0.011\" />\n  <Char code=\"7968\" width=\"0.525\" height=\"0.64\" depth=\"0.232\" />\n  <Char code=\"7969\" width=\"0.525\" height=\"0.64\" depth=\"0.232\" />\n  <Char code=\"7970\" width=\"0.525\" height=\"0.64\" depth=\"0.232\" />\n  <Char code=\"7971\" width=\"0.525\" height=\"0.64\" depth=\"0.232\" />\n  <Char code=\"7972\" width=\"0.525\" height=\"0.64\" depth=\"0.232\" />\n  <Char code=\"7973\" width=\"0.525\" height=\"0.64\" depth=\"0.232\" />\n  <Char code=\"7974\" width=\"0.525\" height=\"0.696\" depth=\"0.232\" />\n  <Char code=\"7975\" width=\"0.525\" height=\"0.696\" depth=\"0.232\" />\n  <Char code=\"7984\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"7985\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"7986\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"7987\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"7988\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"7989\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"7990\" width=\"0.525\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"7991\" width=\"0.525\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8000\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8001\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8002\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8003\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8004\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8005\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8016\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8017\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8018\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8019\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8020\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8021\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8022\" width=\"0.525\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8023\" width=\"0.525\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8032\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8033\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8034\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8035\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8036\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8037\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8038\" width=\"0.525\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8039\" width=\"0.525\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8048\" width=\"0.525\" height=\"0.613\" depth=\"0.006\" italic=\"0.002\" />\n  <Char code=\"8050\" width=\"0.525\" height=\"0.614\" depth=\"0.011\" />\n  <Char code=\"8052\" width=\"0.525\" height=\"0.614\" depth=\"0.232\" />\n  <Char code=\"8054\" width=\"0.525\" height=\"0.613\" depth=\"0.006\" />\n  <Char code=\"8056\" width=\"0.525\" height=\"0.614\" depth=\"0.006\" />\n  <Char code=\"8058\" width=\"0.525\" height=\"0.613\" depth=\"0.006\" />\n  <Char code=\"8060\" width=\"0.525\" height=\"0.614\" depth=\"0.006\" />\n  <Char code=\"8064\" width=\"0.525\" height=\"0.64\" depth=\"0.184\" italic=\"0.002\" />\n  <Char code=\"8065\" width=\"0.525\" height=\"0.64\" depth=\"0.184\" italic=\"0.002\" />\n  <Char code=\"8066\" width=\"0.525\" height=\"0.64\" depth=\"0.184\" italic=\"0.002\" />\n  <Char code=\"8067\" width=\"0.525\" height=\"0.64\" depth=\"0.184\" italic=\"0.002\" />\n  <Char code=\"8068\" width=\"0.525\" height=\"0.64\" depth=\"0.184\" italic=\"0.002\" />\n  <Char code=\"8069\" width=\"0.525\" height=\"0.64\" depth=\"0.184\" italic=\"0.002\" />\n  <Char code=\"8070\" width=\"0.525\" height=\"0.696\" depth=\"0.184\" italic=\"0.002\" />\n  <Char code=\"8071\" width=\"0.525\" height=\"0.696\" depth=\"0.184\" italic=\"0.002\" />\n  <Char code=\"8080\" width=\"0.525\" height=\"0.64\" depth=\"0.232\" />\n  <Char code=\"8081\" width=\"0.525\" height=\"0.64\" depth=\"0.232\" />\n  <Char code=\"8082\" width=\"0.525\" height=\"0.64\" depth=\"0.232\" />\n  <Char code=\"8083\" width=\"0.525\" height=\"0.64\" depth=\"0.232\" />\n  <Char code=\"8084\" width=\"0.525\" height=\"0.64\" depth=\"0.232\" />\n  <Char code=\"8085\" width=\"0.525\" height=\"0.64\" depth=\"0.232\" />\n  <Char code=\"8086\" width=\"0.525\" height=\"0.696\" depth=\"0.232\" />\n  <Char code=\"8087\" width=\"0.525\" height=\"0.696\" depth=\"0.232\" />\n  <Char code=\"8096\" width=\"0.525\" height=\"0.64\" depth=\"0.184\" />\n  <Char code=\"8097\" width=\"0.525\" height=\"0.64\" depth=\"0.184\" />\n  <Char code=\"8098\" width=\"0.525\" height=\"0.64\" depth=\"0.184\" />\n  <Char code=\"8099\" width=\"0.525\" height=\"0.64\" depth=\"0.184\" />\n  <Char code=\"8100\" width=\"0.525\" height=\"0.64\" depth=\"0.184\" />\n  <Char code=\"8101\" width=\"0.525\" height=\"0.64\" depth=\"0.184\" />\n  <Char code=\"8102\" width=\"0.525\" height=\"0.696\" depth=\"0.184\" />\n  <Char code=\"8103\" width=\"0.525\" height=\"0.696\" depth=\"0.184\" />\n  <Char code=\"8114\" width=\"0.525\" height=\"0.613\" depth=\"0.184\" italic=\"0.002\" />\n  <Char code=\"8115\" width=\"0.525\" height=\"0.438\" depth=\"0.184\" italic=\"0.002\" />\n  <Char code=\"8116\" width=\"0.525\" height=\"0.613\" depth=\"0.184\" italic=\"0.002\" />\n  <Char code=\"8118\" width=\"0.525\" height=\"0.641\" depth=\"0.006\" italic=\"0.002\" />\n  <Char code=\"8119\" width=\"0.525\" height=\"0.641\" depth=\"0.184\" italic=\"0.002\" />\n  <Char code=\"8124\" width=\"0.525\" height=\"0.653\" depth=\"0.184\" />\n  <Char code=\"8126\" width=\"0.525\" height=\"0.137\" depth=\"0.135\" />\n  <Char code=\"8127\" width=\"0.525\" height=\"0.64\" />\n  <Char code=\"8128\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"8129\" width=\"0.525\" height=\"0.696\" />\n  <Char code=\"8130\" width=\"0.525\" height=\"0.614\" depth=\"0.232\" />\n  <Char code=\"8131\" width=\"0.525\" height=\"0.442\" depth=\"0.232\" />\n  <Char code=\"8132\" width=\"0.525\" height=\"0.613\" depth=\"0.232\" />\n  <Char code=\"8134\" width=\"0.525\" height=\"0.641\" depth=\"0.232\" />\n  <Char code=\"8135\" width=\"0.525\" height=\"0.641\" depth=\"0.232\" />\n  <Char code=\"8140\" width=\"0.525\" height=\"0.641\" depth=\"0.184\" />\n  <Char code=\"8141\" width=\"0.525\" height=\"0.64\" >\n    <Kern code=\"913\" val=\"-0.087\"/>\n    <Kern code=\"927\" val=\"-0.029\"/>\n    <Kern code=\"8124\" val=\"-0.087\"/>\n  </Char>\n  <Char code=\"8142\" width=\"0.525\" height=\"0.64\" />\n  <Char code=\"8143\" width=\"0.525\" height=\"0.696\" />\n  <Char code=\"8146\" width=\"0.525\" height=\"0.613\" depth=\"0.006\" />\n  <Char code=\"8150\" width=\"0.525\" height=\"0.641\" depth=\"0.006\" />\n  <Char code=\"8151\" width=\"0.525\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8157\" width=\"0.525\" height=\"0.64\" >\n    <Kern code=\"913\" val=\"-0.087\"/>\n    <Kern code=\"927\" val=\"-0.029\"/>\n    <Kern code=\"8124\" val=\"-0.087\"/>\n  </Char>\n  <Char code=\"8158\" width=\"0.525\" height=\"0.64\" />\n  <Char code=\"8159\" width=\"0.525\" height=\"0.696\" />\n  <Char code=\"8162\" width=\"0.525\" height=\"0.668\" depth=\"0.006\" />\n  <Char code=\"8164\" width=\"0.525\" height=\"0.64\" depth=\"0.221\" />\n  <Char code=\"8165\" width=\"0.525\" height=\"0.64\" depth=\"0.221\" />\n  <Char code=\"8166\" width=\"0.525\" height=\"0.641\" depth=\"0.006\" />\n  <Char code=\"8167\" width=\"0.525\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8173\" width=\"0.525\" height=\"0.613\" />\n  <Char code=\"8175\" width=\"0.525\" height=\"0.614\" />\n  <Char code=\"8178\" width=\"0.525\" height=\"0.614\" depth=\"0.184\" />\n  <Char code=\"8179\" width=\"0.525\" height=\"0.442\" depth=\"0.184\" />\n  <Char code=\"8180\" width=\"0.525\" height=\"0.613\" depth=\"0.184\" />\n  <Char code=\"8182\" width=\"0.525\" height=\"0.641\" depth=\"0.006\" />\n  <Char code=\"8183\" width=\"0.525\" height=\"0.641\" depth=\"0.184\" />\n  <Char code=\"8188\" width=\"0.525\" height=\"0.651\" depth=\"0.184\" />\n  <Char code=\"8190\" width=\"0.525\" height=\"0.64\" />\n  <Char code=\"8217\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"9001\" width=\"0.525\" height=\"0.695\" depth=\"0.083\" />\n  <Char code=\"9002\" width=\"0.525\" height=\"0.695\" depth=\"0.083\" />\n</Font>"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/greek/greek.map.xml",
    "content": "<?xml version='1.0'?>\n<SymbolMappings>\n  <SymbolMapping name=\"ʹ\" ch=\"884\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"͵\" ch=\"885\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ͺ\" ch=\"890\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"΄\" ch=\"900\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"΅\" ch=\"901\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"·\" ch=\"903\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ΐ\" ch=\"912\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Α\" ch=\"913\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Β\" ch=\"914\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Γ\" ch=\"915\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Δ\" ch=\"916\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ε\" ch=\"917\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ζ\" ch=\"918\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Η\" ch=\"919\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Θ\" ch=\"920\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ι\" ch=\"921\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Κ\" ch=\"922\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Λ\" ch=\"923\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Μ\" ch=\"924\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ν\" ch=\"925\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ξ\" ch=\"926\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ο\" ch=\"927\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Π\" ch=\"928\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ρ\" ch=\"929\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Σ\" ch=\"931\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Τ\" ch=\"932\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Υ\" ch=\"933\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Φ\" ch=\"934\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Χ\" ch=\"935\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ψ\" ch=\"936\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ω\" ch=\"937\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ϊ\" ch=\"938\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ϋ\" ch=\"939\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ά\" ch=\"940\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"έ\" ch=\"941\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ή\" ch=\"942\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ί\" ch=\"943\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ΰ\" ch=\"944\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"α\" ch=\"945\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"β\" ch=\"946\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"γ\" ch=\"947\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"δ\" ch=\"948\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ε\" ch=\"949\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ζ\" ch=\"950\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"η\" ch=\"951\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"θ\" ch=\"952\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ι\" ch=\"953\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"κ\" ch=\"954\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"λ\" ch=\"955\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"μ\" ch=\"956\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ν\" ch=\"957\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ξ\" ch=\"958\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ο\" ch=\"959\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"π\" ch=\"960\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ρ\" ch=\"961\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ς\" ch=\"962\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"σ\" ch=\"963\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"τ\" ch=\"964\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"υ\" ch=\"965\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"φ\" ch=\"966\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"χ\" ch=\"967\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ψ\" ch=\"968\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ω\" ch=\"969\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ϊ\" ch=\"970\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ϋ\" ch=\"971\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ό\" ch=\"972\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ύ\" ch=\"973\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ώ\" ch=\"974\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ϑ\" ch=\"977\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ϙ\" ch=\"984\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ϙ\" ch=\"985\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ϛ\" ch=\"986\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ϛ\" ch=\"987\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ϝ\" ch=\"988\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ϝ\" ch=\"989\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ϟ\" ch=\"991\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ϡ\" ch=\"992\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ϡ\" ch=\"993\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἀ\" ch=\"7936\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἁ\" ch=\"7937\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἂ\" ch=\"7938\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἃ\" ch=\"7939\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἄ\" ch=\"7940\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἅ\" ch=\"7941\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἆ\" ch=\"7942\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἇ\" ch=\"7943\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἐ\" ch=\"7952\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἑ\" ch=\"7953\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἒ\" ch=\"7954\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἓ\" ch=\"7955\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἔ\" ch=\"7956\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἕ\" ch=\"7957\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἠ\" ch=\"7968\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἡ\" ch=\"7969\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἢ\" ch=\"7970\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἣ\" ch=\"7971\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἤ\" ch=\"7972\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἥ\" ch=\"7973\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἦ\" ch=\"7974\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἧ\" ch=\"7975\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἰ\" ch=\"7984\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἱ\" ch=\"7985\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἲ\" ch=\"7986\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἳ\" ch=\"7987\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἴ\" ch=\"7988\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἵ\" ch=\"7989\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἶ\" ch=\"7990\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἷ\" ch=\"7991\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὀ\" ch=\"8000\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὁ\" ch=\"8001\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὂ\" ch=\"8002\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὃ\" ch=\"8003\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὄ\" ch=\"8004\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὅ\" ch=\"8005\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὐ\" ch=\"8016\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὑ\" ch=\"8017\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὒ\" ch=\"8018\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὓ\" ch=\"8019\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὔ\" ch=\"8020\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὕ\" ch=\"8021\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὖ\" ch=\"8022\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὗ\" ch=\"8023\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὠ\" ch=\"8032\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὡ\" ch=\"8033\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὢ\" ch=\"8034\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὣ\" ch=\"8035\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὤ\" ch=\"8036\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὥ\" ch=\"8037\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὦ\" ch=\"8038\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὧ\" ch=\"8039\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὰ\" ch=\"8048\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὲ\" ch=\"8050\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὴ\" ch=\"8052\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὶ\" ch=\"8054\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὸ\" ch=\"8056\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὺ\" ch=\"8058\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὼ\" ch=\"8060\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾀ\" ch=\"8064\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾁ\" ch=\"8065\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾂ\" ch=\"8066\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾃ\" ch=\"8067\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾄ\" ch=\"8068\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾅ\" ch=\"8069\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾆ\" ch=\"8070\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾇ\" ch=\"8071\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾐ\" ch=\"8080\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾑ\" ch=\"8081\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾒ\" ch=\"8082\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾓ\" ch=\"8083\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾔ\" ch=\"8084\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾕ\" ch=\"8085\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾖ\" ch=\"8086\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾗ\" ch=\"8087\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾠ\" ch=\"8096\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾡ\" ch=\"8097\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾢ\" ch=\"8098\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾣ\" ch=\"8099\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾤ\" ch=\"8100\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾥ\" ch=\"8101\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾦ\" ch=\"8102\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾧ\" ch=\"8103\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾲ\" ch=\"8114\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾳ\" ch=\"8115\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾴ\" ch=\"8116\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾶ\" ch=\"8118\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾷ\" ch=\"8119\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾼ\" ch=\"8124\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ι\" ch=\"8126\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"᾿\" ch=\"8127\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"῀\" ch=\"8128\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"῁\" ch=\"8129\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῂ\" ch=\"8130\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῃ\" ch=\"8131\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῄ\" ch=\"8132\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῆ\" ch=\"8134\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῇ\" ch=\"8135\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῌ\" ch=\"8140\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"῍\" ch=\"8141\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"῎\" ch=\"8142\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"῏\" ch=\"8143\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῒ\" ch=\"8146\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῖ\" ch=\"8150\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῗ\" ch=\"8151\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"῝\" ch=\"8157\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"῞\" ch=\"8158\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"῟\" ch=\"8159\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῢ\" ch=\"8162\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῤ\" ch=\"8164\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῥ\" ch=\"8165\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῦ\" ch=\"8166\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῧ\" ch=\"8167\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"῭\" ch=\"8173\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"`\" ch=\"8175\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῲ\" ch=\"8178\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῳ\" ch=\"8179\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῴ\" ch=\"8180\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῶ\" ch=\"8182\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῷ\" ch=\"8183\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῼ\" ch=\"8188\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"῾\" ch=\"8190\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"’\" ch=\"8217\" fontId=\"fcmrpg\"/>\n</SymbolMappings>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/greek/language_greek.xml",
    "content": "<?xml version='1.0'?>\n<!--\n  language_greek.xml\n-->\n\n<TeXFont>\n\n<SymbolMappings>\n  <Mapping include=\"greek.map.xml\" />\n</SymbolMappings>\n\n<FontDescriptions>\n  <Metrics include=\"fcmbipg.xml\" />\n  <Metrics include=\"fcmbpg.xml\" />\n  <Metrics include=\"fcmripg.xml\" />\n  <Metrics include=\"fcmrpg.xml\" />\n  <Metrics include=\"fcsbpg.xml\" />\n  <Metrics include=\"fcsropg.xml\" />\n  <Metrics include=\"fcsrpg.xml\" />\n  <Metrics include=\"fctrpg.xml\" />\n</FontDescriptions>\n\n<TeXSymbols include=\"symbols_greek.xml\" />\n\n<FormulaSettings include=\"mappings_greek.xml\" />\n\n</TeXFont>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/greek/mappings_greek.xml",
    "content": "<?xml version='1.0'?>\n<!--\n  mappings_greek.xml\n-->\n\n<FormulaSettings>\n  <CharacterToSymbolMappings>\n    <Map char=\"&#884;\" symbol=\"ʹ\"/>\n    <Map char=\"&#885;\" symbol=\"͵\"/>\n    <Map char=\"&#890;\" symbol=\"ͺ\"/>\n    <Map char=\"&#900;\" symbol=\"΄\"/>\n    <Map char=\"&#901;\" symbol=\"΅\"/>\n    <Map char=\"&#903;\" symbol=\"·\"/>\n    <Map char=\"&#912;\" symbol=\"ΐ\"/>\n    <Map char=\"&#938;\" symbol=\"Ϊ\"/>\n    <Map char=\"&#939;\" symbol=\"Ϋ\"/>\n    <Map char=\"&#940;\" symbol=\"ά\"/>\n    <Map char=\"&#941;\" symbol=\"έ\"/>\n    <Map char=\"&#942;\" symbol=\"ή\"/>\n    <Map char=\"&#943;\" symbol=\"ί\"/>\n    <Map char=\"&#944;\" symbol=\"ΰ\"/>\n    <Map char=\"&#970;\" symbol=\"ϊ\"/>\n    <Map char=\"&#971;\" symbol=\"ϋ\"/>\n    <Map char=\"&#972;\" symbol=\"ό\"/>\n    <Map char=\"&#973;\" symbol=\"ύ\"/>\n    <Map char=\"&#974;\" symbol=\"ώ\"/>\n    <Map char=\"&#984;\" symbol=\"Ϙ\"/>\n    <Map char=\"&#985;\" symbol=\"ϙ\"/>\n    <Map char=\"&#986;\" symbol=\"Ϛ\"/>\n    <Map char=\"&#987;\" symbol=\"ϛ\"/>\n    <Map char=\"&#988;\" symbol=\"Ϝ\"/>\n    <Map char=\"&#989;\" symbol=\"ϝ\"/>\n    <Map char=\"&#991;\" symbol=\"ϟ\"/>\n    <Map char=\"&#992;\" symbol=\"Ϡ\"/>\n    <Map char=\"&#993;\" symbol=\"ϡ\"/>\n    <Map char=\"&#7936;\" symbol=\"ἀ\"/>\n    <Map char=\"&#7937;\" symbol=\"ἁ\"/>\n    <Map char=\"&#7938;\" symbol=\"ἂ\"/>\n    <Map char=\"&#7939;\" symbol=\"ἃ\"/>\n    <Map char=\"&#7940;\" symbol=\"ἄ\"/>\n    <Map char=\"&#7941;\" symbol=\"ἅ\"/>\n    <Map char=\"&#7942;\" symbol=\"ἆ\"/>\n    <Map char=\"&#7943;\" symbol=\"ἇ\"/>\n    <Map char=\"&#7952;\" symbol=\"ἐ\"/>\n    <Map char=\"&#7953;\" symbol=\"ἑ\"/>\n    <Map char=\"&#7954;\" symbol=\"ἒ\"/>\n    <Map char=\"&#7955;\" symbol=\"ἓ\"/>\n    <Map char=\"&#7956;\" symbol=\"ἔ\"/>\n    <Map char=\"&#7957;\" symbol=\"ἕ\"/>\n    <Map char=\"&#7968;\" symbol=\"ἠ\"/>\n    <Map char=\"&#7969;\" symbol=\"ἡ\"/>\n    <Map char=\"&#7970;\" symbol=\"ἢ\"/>\n    <Map char=\"&#7971;\" symbol=\"ἣ\"/>\n    <Map char=\"&#7972;\" symbol=\"ἤ\"/>\n    <Map char=\"&#7973;\" symbol=\"ἥ\"/>\n    <Map char=\"&#7974;\" symbol=\"ἦ\"/>\n    <Map char=\"&#7975;\" symbol=\"ἧ\"/>\n    <Map char=\"&#7984;\" symbol=\"ἰ\"/>\n    <Map char=\"&#7985;\" symbol=\"ἱ\"/>\n    <Map char=\"&#7986;\" symbol=\"ἲ\"/>\n    <Map char=\"&#7987;\" symbol=\"ἳ\"/>\n    <Map char=\"&#7988;\" symbol=\"ἴ\"/>\n    <Map char=\"&#7989;\" symbol=\"ἵ\"/>\n    <Map char=\"&#7990;\" symbol=\"ἶ\"/>\n    <Map char=\"&#7991;\" symbol=\"ἷ\"/>\n    <Map char=\"&#8000;\" symbol=\"ὀ\"/>\n    <Map char=\"&#8001;\" symbol=\"ὁ\"/>\n    <Map char=\"&#8002;\" symbol=\"ὂ\"/>\n    <Map char=\"&#8003;\" symbol=\"ὃ\"/>\n    <Map char=\"&#8004;\" symbol=\"ὄ\"/>\n    <Map char=\"&#8005;\" symbol=\"ὅ\"/>\n    <Map char=\"&#8016;\" symbol=\"ὐ\"/>\n    <Map char=\"&#8017;\" symbol=\"ὑ\"/>\n    <Map char=\"&#8018;\" symbol=\"ὒ\"/>\n    <Map char=\"&#8019;\" symbol=\"ὓ\"/>\n    <Map char=\"&#8020;\" symbol=\"ὔ\"/>\n    <Map char=\"&#8021;\" symbol=\"ὕ\"/>\n    <Map char=\"&#8022;\" symbol=\"ὖ\"/>\n    <Map char=\"&#8023;\" symbol=\"ὗ\"/>\n    <Map char=\"&#8032;\" symbol=\"ὠ\"/>\n    <Map char=\"&#8033;\" symbol=\"ὡ\"/>\n    <Map char=\"&#8034;\" symbol=\"ὢ\"/>\n    <Map char=\"&#8035;\" symbol=\"ὣ\"/>\n    <Map char=\"&#8036;\" symbol=\"ὤ\"/>\n    <Map char=\"&#8037;\" symbol=\"ὥ\"/>\n    <Map char=\"&#8038;\" symbol=\"ὦ\"/>\n    <Map char=\"&#8039;\" symbol=\"ὧ\"/>\n    <Map char=\"&#8048;\" symbol=\"ὰ\"/>\n    <Map char=\"&#8050;\" symbol=\"ὲ\"/>\n    <Map char=\"&#8052;\" symbol=\"ὴ\"/>\n    <Map char=\"&#8054;\" symbol=\"ὶ\"/>\n    <Map char=\"&#8056;\" symbol=\"ὸ\"/>\n    <Map char=\"&#8058;\" symbol=\"ὺ\"/>\n    <Map char=\"&#8060;\" symbol=\"ὼ\"/>\n    <Map char=\"&#8064;\" symbol=\"ᾀ\"/>\n    <Map char=\"&#8065;\" symbol=\"ᾁ\"/>\n    <Map char=\"&#8066;\" symbol=\"ᾂ\"/>\n    <Map char=\"&#8067;\" symbol=\"ᾃ\"/>\n    <Map char=\"&#8068;\" symbol=\"ᾄ\"/>\n    <Map char=\"&#8069;\" symbol=\"ᾅ\"/>\n    <Map char=\"&#8070;\" symbol=\"ᾆ\"/>\n    <Map char=\"&#8071;\" symbol=\"ᾇ\"/>\n    <Map char=\"&#8080;\" symbol=\"ᾐ\"/>\n    <Map char=\"&#8081;\" symbol=\"ᾑ\"/>\n    <Map char=\"&#8082;\" symbol=\"ᾒ\"/>\n    <Map char=\"&#8083;\" symbol=\"ᾓ\"/>\n    <Map char=\"&#8084;\" symbol=\"ᾔ\"/>\n    <Map char=\"&#8085;\" symbol=\"ᾕ\"/>\n    <Map char=\"&#8086;\" symbol=\"ᾖ\"/>\n    <Map char=\"&#8087;\" symbol=\"ᾗ\"/>\n    <Map char=\"&#8096;\" symbol=\"ᾠ\"/>\n    <Map char=\"&#8097;\" symbol=\"ᾡ\"/>\n    <Map char=\"&#8098;\" symbol=\"ᾢ\"/>\n    <Map char=\"&#8099;\" symbol=\"ᾣ\"/>\n    <Map char=\"&#8100;\" symbol=\"ᾤ\"/>\n    <Map char=\"&#8101;\" symbol=\"ᾥ\"/>\n    <Map char=\"&#8102;\" symbol=\"ᾦ\"/>\n    <Map char=\"&#8103;\" symbol=\"ᾧ\"/>\n    <Map char=\"&#8114;\" symbol=\"ᾲ\"/>\n    <Map char=\"&#8115;\" symbol=\"ᾳ\"/>\n    <Map char=\"&#8116;\" symbol=\"ᾴ\"/>\n    <Map char=\"&#8118;\" symbol=\"ᾶ\"/>\n    <Map char=\"&#8119;\" symbol=\"ᾷ\"/>\n    <Map char=\"&#8124;\" symbol=\"ᾼ\"/>\n    <Map char=\"&#8125;\" symbol=\"᾿\"/>\n    <Map char=\"&#8126;\" symbol=\"ι\"/>\n    <Map char=\"&#8127;\" symbol=\"᾿\"/>\n    <Map char=\"&#8128;\" symbol=\"῀\"/>\n    <Map char=\"&#8129;\" symbol=\"῁\"/>\n    <Map char=\"&#8130;\" symbol=\"ῂ\"/>\n    <Map char=\"&#8131;\" symbol=\"ῃ\"/>\n    <Map char=\"&#8132;\" symbol=\"ῄ\"/>\n    <Map char=\"&#8134;\" symbol=\"ῆ\"/>\n    <Map char=\"&#8135;\" symbol=\"ῇ\"/>\n    <Map char=\"&#8140;\" symbol=\"ῌ\"/>\n    <Map char=\"&#8141;\" symbol=\"῍\"/>\n    <Map char=\"&#8142;\" symbol=\"῎\"/>\n    <Map char=\"&#8143;\" symbol=\"῏\"/>\n    <Map char=\"&#8146;\" symbol=\"ῒ\"/>\n    <Map char=\"&#8150;\" symbol=\"ῖ\"/>\n    <Map char=\"&#8151;\" symbol=\"ῗ\"/>\n    <Map char=\"&#8157;\" symbol=\"῝\"/>\n    <Map char=\"&#8158;\" symbol=\"῞\"/>\n    <Map char=\"&#8159;\" symbol=\"῟\"/>\n    <Map char=\"&#8162;\" symbol=\"ῢ\"/>\n    <Map char=\"&#8164;\" symbol=\"ῤ\"/>\n    <Map char=\"&#8165;\" symbol=\"ῥ\"/>\n    <Map char=\"&#8166;\" symbol=\"ῦ\"/>\n    <Map char=\"&#8167;\" symbol=\"ῧ\"/>\n    <Map char=\"&#8173;\" symbol=\"῭\"/>\n    <Map char=\"&#8174;\" symbol=\"΅\"/>\n    <Map char=\"&#8175;\" symbol=\"`\"/>\n    <Map char=\"&#8178;\" symbol=\"ῲ\"/>\n    <Map char=\"&#8179;\" symbol=\"ῳ\"/>\n    <Map char=\"&#8180;\" symbol=\"ῴ\"/>\n    <Map char=\"&#8182;\" symbol=\"ῶ\"/>\n    <Map char=\"&#8183;\" symbol=\"ῷ\"/>\n    <Map char=\"&#8188;\" symbol=\"ῼ\"/>\n    <Map char=\"&#8189;\" symbol=\"ʹ\"/>\n    <Map char=\"&#8190;\" symbol=\"῾\"/>\n    <Map char=\"&#8217;\" symbol=\"’\"/>\n  </CharacterToSymbolMappings>\n  \n  <CharacterToFormulaMappings>\n    <Map char=\"&#902;\" formula=\"\\grkaccent{ʹ}{\\phantom{ι}}\\!\\!A\"/>\n    <Map char=\"&#904;\" formula=\"\\grkaccent{ʹ}{\\phantom{ι}}Ε\"/>\n    <Map char=\"&#905;\" formula=\"\\grkaccent{ʹ}{\\phantom{ι}}H\"/>\n    <Map char=\"&#906;\" formula=\"\\grkaccent{ʹ}{\\phantom{ι}}Ι\"/>\n    <Map char=\"&#908;\" formula=\"\\grkaccent{ʹ}{\\phantom{ι}}\\!Ο\"/>\n    <Map char=\"&#910;\" formula=\"\\grkaccent{ʹ}{\\phantom{ι}}Υ\"/>\n    <Map char=\"&#911;\" formula=\"\\grkaccent{ʹ}{\\phantom{ι}}\\!Ω\"/>\n    <Map char=\"&#7944;\" formula=\"’Α\"/>\n    <Map char=\"&#7945;\" formula=\"῾Α\"/>\n    <Map char=\"&#7946;\" formula=\"῍Α\"/>\n    <Map char=\"&#7947;\" formula=\"῝Α\"/>\n    <Map char=\"&#7948;\" formula=\"῎Α\"/>\n    <Map char=\"&#7949;\" formula=\"῞Α\"/>\n    <Map char=\"&#7950;\" formula=\"῏Α\"/>\n    <Map char=\"&#7951;\" formula=\"῟Α\"/>\n    <Map char=\"&#7960;\" formula=\"’Ε\"/>\n    <Map char=\"&#7961;\" formula=\"῾Ε\"/>\n    <Map char=\"&#7962;\" formula=\"῍Ε\"/>\n    <Map char=\"&#7963;\" formula=\"῝Ε\"/>\n    <Map char=\"&#7964;\" formula=\"῎Ε\"/>\n    <Map char=\"&#7965;\" formula=\"῞Ε\"/>\n    <Map char=\"&#7976;\" formula=\"’Η\"/>\n    <Map char=\"&#7977;\" formula=\"῾Η\"/>\n    <Map char=\"&#7978;\" formula=\"῍Η\"/>\n    <Map char=\"&#7979;\" formula=\"῝Η\"/>\n    <Map char=\"&#7980;\" formula=\"῎Η\"/>\n    <Map char=\"&#7981;\" formula=\"῞Η\"/>\n    <Map char=\"&#7982;\" formula=\"῏Η\"/>\n    <Map char=\"&#7983;\" formula=\"῟Η\"/>\n    <Map char=\"&#7992;\" formula=\"’Ι\"/>\n    <Map char=\"&#7993;\" formula=\"῾Ι\"/>\n    <Map char=\"&#7994;\" formula=\"῍Ι\"/>\n    <Map char=\"&#7995;\" formula=\"῝Ι\"/>\n    <Map char=\"&#7996;\" formula=\"῎Ι\"/>\n    <Map char=\"&#7997;\" formula=\"῞Ι\"/>\n    <Map char=\"&#7998;\" formula=\"῏Ι\"/>\n    <Map char=\"&#7999;\" formula=\"῟Ι\"/>\n    <Map char=\"&#8008;\" formula=\"’Ο\"/>\n    <Map char=\"&#8009;\" formula=\"῾Ο\"/>\n    <Map char=\"&#8010;\" formula=\"῍Ο\"/>\n    <Map char=\"&#8011;\" formula=\"῝Ο\"/>\n    <Map char=\"&#8012;\" formula=\"῎Ο\"/>\n    <Map char=\"&#8013;\" formula=\"῞Ο\"/>\n    <Map char=\"&#8025;\" formula=\"῾Υ\"/>\n    <Map char=\"&#8026;\" formula=\"῝Υ\"/>\n    <Map char=\"&#8027;\" formula=\"῞Υ\"/>\n    <Map char=\"&#8028;\" formula=\"῟Υ\"/>\n    <Map char=\"&#8040;\" formula=\"’Ω\"/>\n    <Map char=\"&#8041;\" formula=\"῾Ω\"/>\n    <Map char=\"&#8042;\" formula=\"῍Ω\"/>\n    <Map char=\"&#8043;\" formula=\"῝Ω\"/>\n    <Map char=\"&#8044;\" formula=\"῎Ω\"/>\n    <Map char=\"&#8045;\" formula=\"῞Ω\"/>\n    <Map char=\"&#8046;\" formula=\"῏Ω\"/>\n    <Map char=\"&#8047;\" formula=\"῟Ω\"/>\n    <Map char=\"&#8049;\" formula=\"\\grkaccent{΄}α\"/>\n    <Map char=\"&#8051;\" formula=\"\\grkaccent{΄}ε\"/>\n    <Map char=\"&#8053;\" formula=\"\\grkaccent{΄}η\"/>\n    <Map char=\"&#8055;\" formula=\"\\grkaccent{΄}ι\"/>\n    <Map char=\"&#8057;\" formula=\"\\grkaccent{΄}ο\"/>\n    <Map char=\"&#8059;\" formula=\"\\grkaccent{΄}υ\"/>\n    <Map char=\"&#8061;\" formula=\"\\grkaccent{΄}ω\"/>\n    <Map char=\"&#8072;\" formula=\"’ᾼ\"/>\n    <Map char=\"&#8073;\" formula=\"῾ᾼ\"/>\n    <Map char=\"&#8074;\" formula=\"῍ᾼ\"/>\n    <Map char=\"&#8075;\" formula=\"῝ᾼ\"/>\n    <Map char=\"&#8076;\" formula=\"῎ᾼ\"/>\n    <Map char=\"&#8077;\" formula=\"῞ᾼ\"/>\n    <Map char=\"&#8078;\" formula=\"῏ᾼ\"/>\n    <Map char=\"&#8079;\" formula=\"῟ᾼ\"/>\n    <Map char=\"&#8088;\" formula=\"’ῌ\"/>\n    <Map char=\"&#8089;\" formula=\"῾ῌ\"/>\n    <Map char=\"&#8090;\" formula=\"῍ῌ\"/>\n    <Map char=\"&#8091;\" formula=\"῝ῌ\"/>\n    <Map char=\"&#8092;\" formula=\"῎ῌ\"/>\n    <Map char=\"&#8093;\" formula=\"῞ῌ\"/>\n    <Map char=\"&#8094;\" formula=\"῏ῌ\"/>\n    <Map char=\"&#8095;\" formula=\"῟ῌ\"/>\n    <Map char=\"&#8100;\" formula=\"\\grkaccent{῎}ῳ\"/>\n    <Map char=\"&#8104;\" formula=\"’ῼ\"/>\n    <Map char=\"&#8105;\" formula=\"῾ῼ\"/>\n    <Map char=\"&#8106;\" formula=\"῍ῼ\"/>\n    <Map char=\"&#8107;\" formula=\"῝ῼ\"/>\n    <Map char=\"&#8108;\" formula=\"῎ῼ\"/>\n    <Map char=\"&#8109;\" formula=\"῞ῼ\"/>\n    <Map char=\"&#8110;\" formula=\"῏ῼ\"/>\n    <Map char=\"&#8111;\" formula=\"῟ῼ\"/>\n    <Map char=\"&#8112;\" formula=\"\\u α\"/>\n    <Map char=\"&#8113;\" formula=\"\\= α\"/>\n    <Map char=\"&#8120;\" formula=\"\\u Α\"/>\n    <Map char=\"&#8121;\" formula=\"\\= Α\"/>\n    <Map char=\"&#8122;\" formula=\"\\grkaccent{`}{\\vphantom{ι}}Α\"/>\n    <Map char=\"&#8123;\" formula=\"\\grkaccent{ʹ}{\\vphantom{ι}}\\!\\!Α\"/>\n    <Map char=\"&#8136;\" formula=\"\\grkaccent{`}{\\vphantom{ι}}Ε\"/>\n    <Map char=\"&#8137;\" formula=\"\\grkaccent{ʹ}{\\vphantom{ι}}Ε\"/>\n    <Map char=\"&#8138;\" formula=\"\\grkaccent{`}{\\vphantom{ι}}Η\"/>\n    <Map char=\"&#8139;\" formula=\"\\grkaccent{ʹ}{\\vphantom{ι}}Η\"/>\n    <Map char=\"&#8144;\" formula=\"\\u ι\"/>\n    <Map char=\"&#8145;\" formula=\"\\= ι\"/>\n    <Map char=\"&#8147;\" formula=\"\\grkaccent{΅}ι\"/>\n    <Map char=\"&#8152;\" formula=\"\\u Ι\"/>\n    <Map char=\"&#8153;\" formula=\"\\= Ι\"/>\n    <Map char=\"&#8154;\" formula=\"\\grkaccent{`}{\\phantom{ι}}Ι\"/>\n    <Map char=\"&#8155;\" formula=\"\\grkaccent{ʹ}{\\phantom{ι}}Ι\"/>\n    <Map char=\"&#8160;\" formula=\"\\u υ\"/>\n    <Map char=\"&#8161;\" formula=\"\\= υ\"/>\n    <Map char=\"&#8163;\" formula=\"\\grkaccent{΅}υ\"/>\n    <Map char=\"&#8168;\" formula=\"\\u Υ\"/>\n    <Map char=\"&#8169;\" formula=\"\\= Υ\"/>\n    <Map char=\"&#8170;\" formula=\"\\grkaccent{`}{\\phantom{ι}}Υ\"/>\n    <Map char=\"&#8171;\" formula=\"\\grkaccent{ʹ}{\\phantom{ι}}Υ\"/>\n    <Map char=\"&#8184;\" formula=\"\\grkaccent{`}{\\vphantom{ι}}Ο\"/>\n    <Map char=\"&#8185;\" formula=\"\\grkaccent{ʹ}{\\vphantom{ι}}\\!Ο\"/>\n    <Map char=\"&#8186;\" formula=\"\\grkaccent{`}{\\vphantom{ι}}Ω\"/>\n    <Map char=\"&#8187;\" formula=\"\\grkaccent{ʹ}{\\vphantom{ι}}\\!Ω\"/>\n  </CharacterToFormulaMappings>\n</FormulaSettings>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/res/greek/symbols_greek.xml",
    "content": "<?xml version='1.0'?>\n<!--\n  symbols_greek.xml\n-->\n\n<TeXSymbols>\n  <Symbol name=\"ʹ\" type=\"acc\"/>\n  <Symbol name=\"͵\" type=\"acc\"/>\n  <Symbol name=\"ͺ\" type=\"acc\"/>\n  <Symbol name=\"΄\" type=\"acc\"/>\n  <Symbol name=\"΅\" type=\"acc\"/>\n  <Symbol name=\"·\" type=\"acc\"/>\n  <Symbol name=\"ΐ\" type=\"ord\"/>\n  <Symbol name=\"Α\" type=\"ord\"/>\n  <Symbol name=\"Β\" type=\"ord\"/>\n  <Symbol name=\"Γ\" type=\"ord\"/>\n  <Symbol name=\"Δ\" type=\"ord\"/>\n  <Symbol name=\"Ε\" type=\"ord\"/>\n  <Symbol name=\"Ζ\" type=\"ord\"/>\n  <Symbol name=\"Η\" type=\"ord\"/>\n  <Symbol name=\"Θ\" type=\"ord\"/>\n  <Symbol name=\"Ι\" type=\"ord\"/>\n  <Symbol name=\"Κ\" type=\"ord\"/>\n  <Symbol name=\"Λ\" type=\"ord\"/>\n  <Symbol name=\"Μ\" type=\"ord\"/>\n  <Symbol name=\"Ν\" type=\"ord\"/>\n  <Symbol name=\"Ξ\" type=\"ord\"/>\n  <Symbol name=\"Ο\" type=\"ord\"/>\n  <Symbol name=\"Π\" type=\"ord\"/>\n  <Symbol name=\"Ρ\" type=\"ord\"/>\n  <Symbol name=\"Σ\" type=\"ord\"/>\n  <Symbol name=\"Τ\" type=\"ord\"/>\n  <Symbol name=\"Υ\" type=\"ord\"/>\n  <Symbol name=\"Φ\" type=\"ord\"/>\n  <Symbol name=\"Χ\" type=\"ord\"/>\n  <Symbol name=\"Ψ\" type=\"ord\"/>\n  <Symbol name=\"Ω\" type=\"ord\"/>\n  <Symbol name=\"Ϊ\" type=\"ord\"/>\n  <Symbol name=\"Ϋ\" type=\"ord\"/>\n  <Symbol name=\"ά\" type=\"ord\"/>\n  <Symbol name=\"έ\" type=\"ord\"/>\n  <Symbol name=\"ή\" type=\"ord\"/>\n  <Symbol name=\"ί\" type=\"ord\"/>\n  <Symbol name=\"ΰ\" type=\"ord\"/>\n  <Symbol name=\"α\" type=\"ord\"/>\n  <Symbol name=\"β\" type=\"ord\"/>\n  <Symbol name=\"γ\" type=\"ord\"/>\n  <Symbol name=\"δ\" type=\"ord\"/>\n  <Symbol name=\"ε\" type=\"ord\"/>\n  <Symbol name=\"ζ\" type=\"ord\"/>\n  <Symbol name=\"η\" type=\"ord\"/>\n  <Symbol name=\"θ\" type=\"ord\"/>\n  <Symbol name=\"ι\" type=\"ord\"/>\n  <Symbol name=\"κ\" type=\"ord\"/>\n  <Symbol name=\"λ\" type=\"ord\"/>\n  <Symbol name=\"μ\" type=\"ord\"/>\n  <Symbol name=\"ν\" type=\"ord\"/>\n  <Symbol name=\"ξ\" type=\"ord\"/>\n  <Symbol name=\"ο\" type=\"ord\"/>\n  <Symbol name=\"π\" type=\"ord\"/>\n  <Symbol name=\"ρ\" type=\"ord\"/>\n  <Symbol name=\"ς\" type=\"ord\"/>\n  <Symbol name=\"σ\" type=\"ord\"/>\n  <Symbol name=\"τ\" type=\"ord\"/>\n  <Symbol name=\"υ\" type=\"ord\"/>\n  <Symbol name=\"φ\" type=\"ord\"/>\n  <Symbol name=\"χ\" type=\"ord\"/>\n  <Symbol name=\"ψ\" type=\"ord\"/>\n  <Symbol name=\"ω\" type=\"ord\"/>\n  <Symbol name=\"ϊ\" type=\"ord\"/>\n  <Symbol name=\"ϋ\" type=\"ord\"/>\n  <Symbol name=\"ό\" type=\"ord\"/>\n  <Symbol name=\"ύ\" type=\"ord\"/>\n  <Symbol name=\"ώ\" type=\"ord\"/>\n  <Symbol name=\"ϑ\" type=\"ord\"/>\n  <Symbol name=\"Ϙ\" type=\"ord\"/>\n  <Symbol name=\"ϙ\" type=\"ord\"/>\n  <Symbol name=\"Ϛ\" type=\"ord\"/>\n  <Symbol name=\"ϛ\" type=\"ord\"/>\n  <Symbol name=\"Ϝ\" type=\"ord\"/>\n  <Symbol name=\"ϝ\" type=\"ord\"/>\n  <Symbol name=\"ϟ\" type=\"ord\"/>\n  <Symbol name=\"Ϡ\" type=\"ord\"/>\n  <Symbol name=\"ϡ\" type=\"ord\"/>\n  <Symbol name=\"ἀ\" type=\"ord\"/>\n  <Symbol name=\"ἁ\" type=\"ord\"/>\n  <Symbol name=\"ἂ\" type=\"ord\"/>\n  <Symbol name=\"ἃ\" type=\"ord\"/>\n  <Symbol name=\"ἄ\" type=\"ord\"/>\n  <Symbol name=\"ἅ\" type=\"ord\"/>\n  <Symbol name=\"ἆ\" type=\"ord\"/>\n  <Symbol name=\"ἇ\" type=\"ord\"/>\n  <Symbol name=\"ἐ\" type=\"ord\"/>\n  <Symbol name=\"ἑ\" type=\"ord\"/>\n  <Symbol name=\"ἒ\" type=\"ord\"/>\n  <Symbol name=\"ἓ\" type=\"ord\"/>\n  <Symbol name=\"ἔ\" type=\"ord\"/>\n  <Symbol name=\"ἕ\" type=\"ord\"/>\n  <Symbol name=\"ἠ\" type=\"ord\"/>\n  <Symbol name=\"ἡ\" type=\"ord\"/>\n  <Symbol name=\"ἢ\" type=\"ord\"/>\n  <Symbol name=\"ἣ\" type=\"ord\"/>\n  <Symbol name=\"ἤ\" type=\"ord\"/>\n  <Symbol name=\"ἥ\" type=\"ord\"/>\n  <Symbol name=\"ἦ\" type=\"ord\"/>\n  <Symbol name=\"ἧ\" type=\"ord\"/>\n  <Symbol name=\"ἰ\" type=\"ord\"/>\n  <Symbol name=\"ἱ\" type=\"ord\"/>\n  <Symbol name=\"ἲ\" type=\"ord\"/>\n  <Symbol name=\"ἳ\" type=\"ord\"/>\n  <Symbol name=\"ἴ\" type=\"ord\"/>\n  <Symbol name=\"ἵ\" type=\"ord\"/>\n  <Symbol name=\"ἶ\" type=\"ord\"/>\n  <Symbol name=\"ἷ\" type=\"ord\"/>\n  <Symbol name=\"ὀ\" type=\"ord\"/>\n  <Symbol name=\"ὁ\" type=\"ord\"/>\n  <Symbol name=\"ὂ\" type=\"ord\"/>\n  <Symbol name=\"ὃ\" type=\"ord\"/>\n  <Symbol name=\"ὄ\" type=\"ord\"/>\n  <Symbol name=\"ὅ\" type=\"ord\"/>\n  <Symbol name=\"ὐ\" type=\"ord\"/>\n  <Symbol name=\"ὑ\" type=\"ord\"/>\n  <Symbol name=\"ὒ\" type=\"ord\"/>\n  <Symbol name=\"ὓ\" type=\"ord\"/>\n  <Symbol name=\"ὔ\" type=\"ord\"/>\n  <Symbol name=\"ὕ\" type=\"ord\"/>\n  <Symbol name=\"ὖ\" type=\"ord\"/>\n  <Symbol name=\"ὗ\" type=\"ord\"/>\n  <Symbol name=\"ὠ\" type=\"ord\"/>\n  <Symbol name=\"ὡ\" type=\"ord\"/>\n  <Symbol name=\"ὢ\" type=\"ord\"/>\n  <Symbol name=\"ὣ\" type=\"ord\"/>\n  <Symbol name=\"ὤ\" type=\"ord\"/>\n  <Symbol name=\"ὥ\" type=\"ord\"/>\n  <Symbol name=\"ὦ\" type=\"ord\"/>\n  <Symbol name=\"ὧ\" type=\"ord\"/>\n  <Symbol name=\"ὰ\" type=\"ord\"/>\n  <Symbol name=\"ὲ\" type=\"ord\"/>\n  <Symbol name=\"ὴ\" type=\"ord\"/>\n  <Symbol name=\"ὶ\" type=\"ord\"/>\n  <Symbol name=\"ὸ\" type=\"ord\"/>\n  <Symbol name=\"ὺ\" type=\"ord\"/>\n  <Symbol name=\"ὼ\" type=\"ord\"/>\n  <Symbol name=\"ᾀ\" type=\"ord\"/>\n  <Symbol name=\"ᾁ\" type=\"ord\"/>\n  <Symbol name=\"ᾂ\" type=\"ord\"/>\n  <Symbol name=\"ᾃ\" type=\"ord\"/>\n  <Symbol name=\"ᾄ\" type=\"ord\"/>\n  <Symbol name=\"ᾅ\" type=\"ord\"/>\n  <Symbol name=\"ᾆ\" type=\"ord\"/>\n  <Symbol name=\"ᾇ\" type=\"ord\"/>\n  <Symbol name=\"ᾐ\" type=\"ord\"/>\n  <Symbol name=\"ᾑ\" type=\"ord\"/>\n  <Symbol name=\"ᾒ\" type=\"ord\"/>\n  <Symbol name=\"ᾓ\" type=\"ord\"/>\n  <Symbol name=\"ᾔ\" type=\"ord\"/>\n  <Symbol name=\"ᾕ\" type=\"ord\"/>\n  <Symbol name=\"ᾖ\" type=\"ord\"/>\n  <Symbol name=\"ᾗ\" type=\"ord\"/>\n  <Symbol name=\"ᾠ\" type=\"ord\"/>\n  <Symbol name=\"ᾡ\" type=\"ord\"/>\n  <Symbol name=\"ᾢ\" type=\"ord\"/>\n  <Symbol name=\"ᾣ\" type=\"ord\"/>\n  <Symbol name=\"ᾤ\" type=\"ord\"/>\n  <Symbol name=\"ᾥ\" type=\"ord\"/>\n  <Symbol name=\"ᾦ\" type=\"ord\"/>\n  <Symbol name=\"ᾧ\" type=\"ord\"/>\n  <Symbol name=\"ᾲ\" type=\"ord\"/>\n  <Symbol name=\"ᾳ\" type=\"ord\"/>\n  <Symbol name=\"ᾴ\" type=\"ord\"/>\n  <Symbol name=\"ᾶ\" type=\"ord\"/>\n  <Symbol name=\"ᾷ\" type=\"ord\"/>\n  <Symbol name=\"ᾼ\" type=\"ord\"/>\n  <Symbol name=\"ι\" type=\"acc\"/>\n  <Symbol name=\"᾿\" type=\"acc\"/>\n  <Symbol name=\"῀\" type=\"acc\"/>\n  <Symbol name=\"῁\" type=\"acc\"/>\n  <Symbol name=\"ῂ\" type=\"ord\"/>\n  <Symbol name=\"ῃ\" type=\"ord\"/>\n  <Symbol name=\"ῄ\" type=\"ord\"/>\n  <Symbol name=\"ῆ\" type=\"ord\"/>\n  <Symbol name=\"ῇ\" type=\"ord\"/>\n  <Symbol name=\"ῌ\" type=\"ord\"/>\n  <Symbol name=\"῍\" type=\"acc\"/>\n  <Symbol name=\"῎\" type=\"acc\"/>\n  <Symbol name=\"῏\" type=\"acc\"/>\n  <Symbol name=\"ῒ\" type=\"ord\"/>\n  <Symbol name=\"ῖ\" type=\"ord\"/>\n  <Symbol name=\"ῗ\" type=\"ord\"/>\n  <Symbol name=\"῝\" type=\"acc\"/>\n  <Symbol name=\"῞\" type=\"acc\"/>\n  <Symbol name=\"῟\" type=\"acc\"/>\n  <Symbol name=\"ῢ\" type=\"ord\"/>\n  <Symbol name=\"ῤ\" type=\"ord\"/>\n  <Symbol name=\"ῥ\" type=\"ord\"/>\n  <Symbol name=\"ῦ\" type=\"ord\"/>\n  <Symbol name=\"ῧ\" type=\"ord\"/>\n  <Symbol name=\"῭\" type=\"acc\"/>\n  <Symbol name=\"`\" type=\"acc\"/>\n  <Symbol name=\"ῲ\" type=\"ord\"/>\n  <Symbol name=\"ῳ\" type=\"ord\"/>\n  <Symbol name=\"ῴ\" type=\"ord\"/>\n  <Symbol name=\"ῶ\" type=\"ord\"/>\n  <Symbol name=\"ῷ\" type=\"ord\"/>\n  <Symbol name=\"ῼ\" type=\"ord\"/>\n  <Symbol name=\"῾\" type=\"acc\"/>\n  <Symbol name=\"’\" type=\"acc\"/>\n</TeXSymbols>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/atom/atom.h",
    "content": "#ifndef ATOM_H_INCLUDED\n#define ATOM_H_INCLUDED\n\n#undef DEBUG\n\n#include \"common.h\"\n#include \"graphic/graphic.h\"\n\n#include <list>\n\nusing namespace std;\nusing namespace tex;\n\nnamespace tex {\n\nclass TeXEnvironment;\n\n/**\n * An abstract graphical representation of a formula, that can be painted. All\n * characters, font sizes, positions are fixed. Only special Glue boxes could\n * possibly stretch or shrink. A box has 3 dimensions (width, height and depth),\n * can be composed of other child boxes that can possibly be shifted (up, down,\n * left or right). Child boxes can also be positioned outside their parent's box\n * (defined by it's dimensions).\n * @par\n * Subclasses must implement the abstract\n * Box#draw(Graphics2D, float, float) method (that paints the box). <b>\n * This implementation must start with calling the method\n * Box#startDraw(Graphics2D, float, float) and end with calling the method\n * Box#endDraw(Graphics2D)} to set and restore the colors that must be used\n * for painting the box and to draw the background.</b> They must also implement\n * the abstract Box#getLastFontId() method (the last font that will be used later\n * when this box will be painted).\n */\nclass Box {\nprotected:\n    /**\n     * the color previously used\n     */\n    color _prevColor;\n\n    /**\n     * Stores the old color setting, draws the background of the box (if any)\n     * and sets the foreground color (if any).\n     *\n     * @param g2\n     *            the graphics (2D) context\n     * @param x\n     *            the x-coordinate\n     * @param y\n     *            the y-coordinate\n     */\n    void startDraw(Graphics2D& g2, float x, float y) {\n        // old color\n        _prevColor = g2.getColor();\n        if (!istrans(_background)) {\n            g2.setColor(_background);\n            g2.fillRect(x, y - _height, _width, _height + _depth);\n        }\n        if (!istrans(_foreground)) {\n            g2.setColor(_foreground);\n        } else {\n            g2.setColor(_prevColor);\n        }\n        if (DEBUG) drawDebug(g2, x, y);\n    }\n\n    void drawDebug(Graphics2D& g2, float x, float y, bool showDepth = true) {\n        if (!DEBUG) return;\n        const Stroke& st = g2.getStroke();\n        Stroke s(abs(1.f / g2.sx()), CAP_BUTT, JOIN_MITER);\n        g2.setStroke(s);\n        if (_width < 0) {\n            x += _width;\n            _width = -_width;\n        }\n        // draw box outline\n        g2.drawRect(x, y - _height, _width, _height + _depth);\n        // draw depth\n        if (showDepth) {\n            color c = g2.getColor();\n            g2.setColor(RED);\n            if (_depth > 0) {\n                g2.fillRect(x, y, _width, _depth);\n                g2.setColor(c);\n                g2.drawRect(x, y, _width, _depth);\n            } else if (_depth < 0) {\n                g2.fillRect(x, y + _depth, _width, -_depth);\n                g2.setColor(c);\n                g2.drawRect(x, y + _depth, _width, -_depth);\n            } else {\n                g2.setColor(c);\n            }\n        }\n        g2.setStroke(st);\n    }\n\n    /**\n     * Restores the previous graphic context setting.\n     *\n     * @param g2\n     *            the graphics (2D) context\n     */\n    void endDraw(Graphics2D& g2) { g2.setColor(_prevColor); }\n\n    /**\n     * Initialize box with default options\n     */\n    void init() {\n        _foreground = trans;\n        _background = trans;\n        _prevColor = trans;\n        _width = _height = _depth = _shift = 0;\n        _type = -1;\n    }\n\npublic:\n    static bool DEBUG;\n\n    /**\n     * The foreground color of the whole box. Child boxes can override this\n     * color. If it's transparent and it has a parent box, the foreground color of the\n     * parent will be used. If it has no parent, the foreground color of the\n     * component on which it will be painted, will be used.\n     */\n    color _foreground;\n\n    /**\n     * The background color of the whole box. Child boxes can paint a background\n     * on top of this background. If it's transparent, no background will be painted.\n     */\n    color _background;\n\n    /**\n     * The width of this box, i.e. the value that will be used for further\n     * calculations.\n     */\n    float _width;\n\n    /**\n     * The height of this box, i.e. the value that will be used for further\n     * calculations.\n     */\n    float _height;\n\n    /**\n     * The depth of this box, i.e. the value that will be used for further\n     * calculations.\n     */\n    float _depth;\n\n    /**\n    * The shift amount: the meaning depends on the particular kind of box (up,\n    * down, left, right)\n    */\n    float _shift;\n\n    /**\n     * The box type (default = -1, no type)\n     */\n    int _type;\n\n    /**\n     * Children of this box\n     */\n    vector<sptr<Box>> _children;\n\n    /**\n     * Create a new box with default options\n     */\n    Box() { init(); }\n\n    /**\n     * Create a new box with given foreground and background\n     */\n    Box(color fg, color bg) {\n        init();\n        _background = bg;\n        _foreground = fg;\n    }\n\n    /**\n     * Append the given box at the end of the list of child boxes.\n     *\n     * @param b\n     *      the box to be inserted\n     */\n    virtual void add(const sptr<Box>& b) {\n        _children.push_back(b);\n    }\n\n    /**\n     * Inserts the given box at the given position in the list of child boxes.\n     *\n     * @param pos\n     *      the position at which to insert the given box\n     * @param b\n     *      the box to be inserted\n     */\n    virtual void add(int pos, const sptr<Box>& b) {\n        _children.insert(_children.begin() + pos, b);\n    }\n\n    /**\n     * Transform the width of box to negative\n     */\n    inline void negWidth() { _width = -_width; }\n\n    /**\n     * Paints this box at the given coordinates using the given 2D graphics\n     * context.\n     *\n     * @param g2\n     *      the graphics (2D) context to use for painting\n     * @param x\n     *      the x-coordinate\n     * @param y\n     *      the y-coordinate\n     */\n    virtual void draw(Graphics2D& g2, float x, float y) = 0;\n\n    /**\n     * Get the id of the last font that will be used later when this box is to be\n     * painted.\n     *\n     * @return the id of the last font that will be used later.\n     */\n    virtual int getLastFontId() = 0;\n\n    /**\n     * Get child boxes of this box, modification on the returned value by this function\n     * will not effect this box's children\n     */\n    virtual vector<sptr<Box>> getChildren() const {\n        return _children;\n    }\n};\n\n/**\n * An abstract superclass for all logical mathematical constructions that can be\n * a part of a TeXFormula. All subclasses must implement the abstract\n * Atom#createBox(TeXEnvironment) method that transforms this logical unit\n * into a concrete box (that can be painted). They also must define their type,\n * used for determining what glue to use between adjacent atoms in a\n * \"row construction\". That can be one single type by assigning one of the type\n * constants to the #_type field. But they can also be defined as having\n * two types: a \"left type\" and a \"right type\". This can be done by implementing\n * the methods Atom#getLeftType() and Atom#getRightType(). The left type\n * will then be used for determining the glue between this atom and the previous\n * one (in a row, if any) and the right type for the glue between this atom and\n * the following one (in a row, if any).\n *\n */\nclass Atom {\npublic:\n    /**\n     * The type of the atom (default value: ordinary atom) @see TeXConstants\n     */\n    int _type;\n    /**\n     * The limits type of the atom (default value: nolimits) @see TeXConstants\n     */\n    int _typelimits;\n    /**\n     * The alignment type of the atom (default value: none) @see TeXConstants\n     */\n    int _alignment;\n\n    Atom()\n        : _type(TYPE_ORDINARY),\n          _typelimits(SCRIPT_NOLIMITS),\n          _alignment(-1) {}\n\n    /**\n     * Get the type of the leftermost child atom. Most atoms have no child\n     * atoms, so the \"left type\" and the \"right type\" are the same: the atom's\n     * type. This also is the default implementation. But Some atoms are\n     * composed of child atoms put one after another in a horizontal row. These\n     * atoms must override this method.\n     *\n     * @return the type of the leftermost child atom\n     */\n    virtual int getLeftType() const { return _type; }\n\n    /**\n     * Get the type of the rightermost child atom. Most atoms have no child\n     * atoms, so the \"left type\" and the \"right type\" are the same: the atom's\n     * type. This also is the default implementation. But Some atoms are\n     * composed of child atoms put one after another in a horizontal row. These\n     * atoms must override this method.\n     *\n     * @return the type of the rightermost child atom\n     */\n    virtual int getRightType() const { return _type; }\n\n    /**\n     * Convert this atom into a {@link Box}, using properties set by \"parent\"\n     * atoms, like the TeX style, the last used font, color settings, ...\n     *\n     * @param env\n     *      the current environment settings\n     * @return the resulting box.\n     */\n    virtual sptr<Box> createBox(_out_ TeXEnvironment& env) = 0;\n\n    /**\n     * Shallow clone a atom from this atom.\n     */\n    virtual sptr<Atom> clone() const = 0;\n\n#ifndef __decl_clone\n#define __decl_clone(type) \\\n    virtual sptr<Atom> clone() const override { return sptr<Atom>(new type(*this)); }\n#endif\n};\n\n}  // namespace tex\n\n#endif  // ATOM_H_INCLUDED\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/atom/atom_basic.cpp",
    "content": "#include \"atom/atom_basic.h\"\n#include \"atom/box.h\"\n#include \"core/core.h\"\n#include \"core/formula.h\"\n#include \"fonts/fonts.h\"\n#include \"graphic/graphic.h\"\n#include \"res/parser/formula_parser.h\"\n\n#include <sstream>\n\nusing namespace std;\nusing namespace tex;\n\n/***************************************************************************************************\n *                                     basic atom implementation                                   *\n ***************************************************************************************************/\n\nsptr<Box> ScaleAtom::createBox(_out_ TeXEnvironment& env) {\n    if(_base == nullptr) throw ex_parse(\"empty atom\");\n    return sptr<Box>(new ScaleBox(_base->createBox(env), _sx, _sy));\n}\n\nsptr<Box> MathAtom::createBox(_out_ TeXEnvironment& env) {\n    TeXEnvironment& e = *(env.copy(env.getTeXFont()->copy()));\n    e.getTeXFont()->setRoman(false);\n    int style = e.getStyle();\n    e.setStyle(_style);\n    if(_base == nullptr) throw ex_parse(\"empty atom\");\n    auto box = _base->createBox(e);\n    e.setStyle(style);\n    return box;\n}\n\nsptr<Box> HlineAtom::createBox(_out_ TeXEnvironment& env) {\n    float drt = env.getTeXFont()->getDefaultRuleThickness(env.getStyle());\n    Box* b = new HorizontalRule(drt, _width, _shift, _color, false);\n    VerticalBox* vb = new VerticalBox();\n    vb->add(sptr<Box>(b));\n    vb->_type = TYPE_HLINE;\n    return sptr<Box>(vb);\n}\n\nSpaceAtom UnderScoreAtom::_w(UNIT_EM, 0.7f, 0, 0);\nSpaceAtom UnderScoreAtom::_s(UNIT_EM, 0.06f, 0, 0);\n\nsptr<Box> UnderScoreAtom::createBox(_out_ TeXEnvironment& env) {\n    float drt = env.getTeXFont()->getDefaultRuleThickness(env.getStyle());\n    HorizontalBox* hb = new HorizontalBox(_s.createBox(env));\n    hb->add(sptr<Box>(new HorizontalRule(drt, _w.createBox(env)->_width, 0)));\n    return sptr<Box>(hb);\n}\n\nCumulativeScriptsAtom::CumulativeScriptsAtom(\n    const sptr<Atom>& base, const sptr<Atom>& sub, const sptr<Atom>& sup) {\n    CumulativeScriptsAtom* ca = dynamic_cast<CumulativeScriptsAtom*>(base.get());\n    ScriptsAtom* sa = nullptr;\n    if (ca != nullptr) {\n        _base = ca->_base;\n        ca->_sup->add(sup);\n        ca->_sub->add(sub);\n        _sup = ca->_sup;\n        _sub = ca->_sub;\n    } else if (sa = dynamic_cast<ScriptsAtom*>(base.get())) {\n        _base = sa->_base;\n        _sup = sptr<RowAtom>(new RowAtom(sa->_sup));\n        _sub = sptr<RowAtom>(new RowAtom(sa->_sub));\n        _sup->add(sup);\n        _sub->add(sub);\n    } else {\n        _base = base;\n        _sup = sptr<RowAtom>(new RowAtom(sup));\n        _sub = sptr<RowAtom>(new RowAtom(sub));\n    }\n}\n\nvoid CumulativeScriptsAtom::addSuperscript(const sptr<Atom>& sup) {\n    _sup->add(sup);\n}\n\nvoid CumulativeScriptsAtom::addSubscript(const sptr<Atom>& sub) {\n    _sub->add(sub);\n}\n\nsptr<Atom> CumulativeScriptsAtom::getScriptsAtom() const {\n    return sptr<Atom>(new ScriptsAtom(_base, _sub, _sup));\n}\n\nsptr<Box> CumulativeScriptsAtom::createBox(_out_ TeXEnvironment& env) {\n    return ScriptsAtom(_base, _sub, _sup).createBox(env);\n}\n\nsptr<Box> TextRenderingAtom::createBox(_out_ TeXEnvironment& env) {\n    if (_infos == nullptr) {\n        return sptr<Box>(new TextRenderingBox(\n            _str, _type, DefaultTeXFont::getSizeFactor(env.getStyle())));\n    }\n    DefaultTeXFont* tf = (DefaultTeXFont*)(env.getTeXFont().get());\n    int type = tf->_isIt ? ITALIC : PLAIN;\n    type = type | (tf->_isBold ? BOLD : 0);\n    bool kerning = tf->_isRoman;\n    sptr<Font> font;\n    const FontInfos& infos = *_infos;\n    if (tf->_isSs) {\n        if (infos._sansserif.empty()) {\n            font = Font::_create(infos._serif, PLAIN, 10);\n        } else {\n            font = Font::_create(infos._sansserif, PLAIN, 10);\n        }\n    } else {\n        if (infos._serif.empty()) {\n            font = Font::_create(infos._sansserif, PLAIN, 10);\n        } else {\n            font = Font::_create(infos._serif, PLAIN, 10);\n        }\n    }\n    return sptr<Box>(new TextRenderingBox(\n        _str, type, DefaultTeXFont::getSizeFactor(env.getStyle()), font, kerning));\n}\n\n/***************************************************************************************************\n *                                     SpaceAtom implementation                                    *\n ***************************************************************************************************/\nconst map<string, int> SpaceAtom::_units = {\n    {\"em\", UNIT_EM},\n    {\"ex\", UNIT_EX},\n    {\"px\", UNIT_PIXEL},\n    {\"pix\", UNIT_PIXEL},\n    {\"pixel\", UNIT_PIXEL},\n    {\"pt\", UNIT_PT},\n    {\"bp\", UNIT_POINT},\n    {\"pica\", UNIT_PICA},\n    {\"pc\", UNIT_PICA},\n    {\"mu\", UNIT_MU},\n    {\"cm\", UNIT_CM},\n    {\"mm\", UNIT_MM},\n    {\"in\", UNIT_IN},\n    {\"sp\", UNIT_SP},\n    {\"dd\", UNIT_DD},\n    {\"cc\", UNIT_CC}};\n\nconst int SpaceAtom::_units_count = 14;\n\nconst function<float(_in_ const TeXEnvironment&)> SpaceAtom::_unitConversions[] = {\n    // EM\n    [](_in_ const TeXEnvironment& env) -> float {\n        return env.getTeXFont()->getEM(env.getStyle());\n    },\n    // EX\n    [](_in_ const TeXEnvironment& env) -> float {\n        return env.getTeXFont()->getXHeight(env.getStyle(), env.getLastFontId());\n    },\n    //PIXEL\n    [](_in_ const TeXEnvironment& env) -> float {\n        return 1.f / env.getSize();\n    },\n    // BP\n    [](_in_ const TeXEnvironment& env) -> float {\n        return TeXFormula::PIXELS_PER_POINT / env.getSize();\n    },\n    // PICA\n    [](_in_ const TeXEnvironment& env) -> float {\n        return (12 * TeXFormula::PIXELS_PER_POINT) / env.getSize();\n    },\n    // MU\n    [](_in_ const TeXEnvironment& env) -> float {\n        auto tf = env.getTeXFont();\n        return tf->getQuad(env.getStyle(), tf->getMuFontId()) / 18.f;\n    },\n    // CM\n    [](_in_ const TeXEnvironment& env) -> float {\n        return (28.346456693f * TeXFormula::PIXELS_PER_POINT) / env.getSize();\n    },\n    // MM\n    [](_in_ const TeXEnvironment& env) -> float {\n        return (2.8346456693f * TeXFormula::PIXELS_PER_POINT) / env.getSize();\n    },\n    // IN\n    [](_in_ const TeXEnvironment& env) -> float {\n        return (72.f * TeXFormula::PIXELS_PER_POINT) / env.getSize();\n    },\n    // SP\n    [](_in_ const TeXEnvironment& env) -> float {\n        return (65536 * TeXFormula::PIXELS_PER_POINT) / env.getSize();\n    },\n    // PT\n    [](_in_ const TeXEnvironment& env) -> float {\n        return (.9962640099f * TeXFormula::PIXELS_PER_POINT) / env.getSize();\n    },\n    // DD\n    [](_in_ const TeXEnvironment& env) -> float {\n        return (1.0660349422f * TeXFormula::PIXELS_PER_POINT) / env.getSize();\n    },\n    // CC\n    [](_in_ const TeXEnvironment& env) -> float {\n        return (12.7924193070f * TeXFormula::PIXELS_PER_POINT) / env.getSize();\n    },\n    // X8\n    [](_in_ const TeXEnvironment& env) -> float {\n        return env.getTeXFont()->getDefaultRuleThickness(env.getStyle());\n    }};\n\nsptr<Box> SpaceAtom::createBox(_out_ TeXEnvironment& env) {\n    if (!_blankSpace) {\n        float w = _width * getFactor(_wUnit, env);\n        float h = _height * getFactor(_hUnit, env);\n        float d = _depth * getFactor(_dUnit, env);\n        return sptr<Box>(new StrutBox(w, h, d, 0));\n    }\n    if (_blankType == 0) return sptr<Box>(new StrutBox(env.getSpace(), 0, 0, 0));\n    return Glue::get(_blankType, env);\n}\n\npair<int, float> SpaceAtom::getLength(const string& lgth) {\n    if (lgth.empty()) return pair<int, float>({UNIT_PIXEL, 0.f});\n\n    size_t i = 0;\n    for (; i < lgth.size() && !isalpha(lgth[i]); i++)\n        ;\n    float f = 0;\n    valueof(lgth.substr(0, i), f);\n\n    int unit = UNIT_PIXEL;\n    string x = lgth.substr(i);\n    tolower(x);\n    if (i != lgth.size()) unit = getUnit(x);\n\n    return pair<int, float>({unit, f});\n}\n\npair<int, float> SpaceAtom::getLength(const wstring& lgth) {\n    string s;\n    wide2utf8(lgth.c_str(), s);\n    return getLength(s);\n}\n\nsptr<Box> BreakMarkAtom::createBox(_out_ TeXEnvironment& env) {\n    return sptr<Box>(new StrutBox(0, 0, 0, 0));\n}\n\n/********************************** char symbol atoms implementation ******************************/\n\nsptr<CharFont> FixedCharAtom::getCharFont(_in_ TeXFont& tf) {\n    return _cf;\n}\n\nsptr<Box> FixedCharAtom::createBox(_out_ TeXEnvironment& env) {\n    auto i = env.getTeXFont();\n    TeXFont& tf = *i;\n    Char c = tf.getChar(*_cf, env.getStyle());\n    return sptr<Box>(new CharBox(c));\n}\n\nbitset<16> SymbolAtom::_validSymbolTypes;\n\nvoid SymbolAtom::_init_() {\n    _validSymbolTypes\n        .set(TYPE_ORDINARY)\n        .set(TYPE_BIG_OPERATOR)\n        .set(TYPE_BINARY_OPERATOR)\n        .set(TYPE_RELATION)\n        .set(TYPE_OPENING)\n        .set(TYPE_CLOSING)\n        .set(TYPE_PUNCTUATION)\n        .set(TYPE_ACCENT);\n#ifdef HAVE_LOG\n    __log << \"elements in _symbols\" << endl;\n    for (auto i : _symbols)\n        __log << \"\\t\" << *(i.second) << endl;\n    __log << endl;\n#endif  // HAVE_LOG\n}\n\n#ifdef HAVE_LOG\nostream& tex::operator<<(ostream& os, const SymbolAtom& s) {\n    os << \"SymbolAtom { \"\n       << \"name: \" << s._name << \", delimiter: \" << s._delimiter << \" }\";\n    return os;\n}\n#endif  // HAVE_LOG\n\nSymbolAtom::SymbolAtom(const string& name, int type, bool del) : _unicode(0) {\n    _name = name;\n    _type = type;\n    if (type == TYPE_BIG_OPERATOR) _typelimits = SCRIPT_NORMAL;\n\n    _delimiter = del;\n}\n\nsptr<Box> SymbolAtom::createBox(_out_ TeXEnvironment& env) {\n    auto i = env.getTeXFont();\n    TeXFont& tf = *i;\n    int style = env.getStyle();\n    Char c = tf.getChar(_name, style);\n    sptr<Box> cb(new CharBox(c));\n    if (env.getSmallCap() && _unicode != 0 && islower(_unicode)) {\n        // find if exists in mapping\n        auto it = TeXFormula::_symbolTextMappings.find(toupper(_unicode));\n        if (it != TeXFormula::_symbolFormulaMappings.end()) {\n            const string& name = it->second;\n            try {\n                sptr<Box> cx(new CharBox(tf.getChar(name, style)));\n                cb = sptr<Box>(new ScaleBox(cx, 0.8f, 0.8f));\n            } catch (ex_symbol_mapping_not_found& e) {}\n        }\n    }\n    if (_type == TYPE_BIG_OPERATOR) {\n        if (style < STYLE_TEXT && tf.hasNextLarger(c)) c = tf.getNextLarger(c, style);\n        cb = sptr<Box>(new CharBox(c));\n        cb->_shift = -(cb->_height + cb->_depth) / 2.f - tf.getAxisHeight(style);\n        float delta = c.getItalic();\n        sptr<HorizontalBox> hb(new HorizontalBox(cb));\n        if (delta > PREC) hb->add(sptr<Box>(new StrutBox(delta, 0, 0, 0)));\n        return hb;\n    }\n    return cb;\n}\n\nsptr<CharFont> SymbolAtom::getCharFont(_in_ TeXFont& tf) {\n    return tf.getChar(_name, STYLE_DISPLAY).getCharFont();\n}\n\nvoid SymbolAtom::addSymbolAtom(const string& file) {\n    TeXSymbolParser parser(file);\n    parser.readSymbols(_symbols);\n}\n\nvoid SymbolAtom::addSymbolAtom(const sptr<SymbolAtom>& sym) {\n    _symbols[sym->_name] = sym;\n}\n\nsptr<SymbolAtom> SymbolAtom::get(const string& name) throw(ex_symbol_not_found) {\n    auto it = _symbols.find(name);\n    if (it == _symbols.end()) throw ex_symbol_not_found(name);\n    return it->second;\n}\n\nChar CharAtom::getChar(_in_ TeXFont& tf, int style, bool smallCap) {\n    wchar_t chr = _c;\n    if (smallCap) {\n        if (islower(_c)) chr = toupper(_c);\n    }\n    if (_textStyle.empty()) return tf.getDefaultChar(chr, style);\n    return tf.getChar(chr, _textStyle, style);\n}\n\nsptr<CharFont> CharAtom::getCharFont(_in_ TeXFont& tf) {\n    return getChar(tf, STYLE_DISPLAY, false).getCharFont();\n}\n\nsptr<Box> CharAtom::createBox(_out_ TeXEnvironment& env) {\n    if (_textStyle.empty()) {\n        const string& ts = env.getTextStyle();\n        if (!ts.empty()) _textStyle = ts;\n    }\n    bool smallCap = env.getSmallCap();\n    Char ch = getChar(*env.getTeXFont(), env.getStyle(), smallCap);\n    sptr<Box> box(new CharBox(ch));\n    if (smallCap && islower(_c)) {\n        // we have a small capital\n        box = sptr<Box>(new ScaleBox(box, 0.8f, 0.8f));\n    }\n    return box;\n}\n\n/************************************** row atom implementation ***********************************/\n\nbool RowAtom::_breakEveywhere = false;\nbitset<16> RowAtom::_binSet;\nbitset<16> RowAtom::_ligKernSet = RowAtom::_init_();\n\nbitset<16> RowAtom::_init_() {\n    // fill bin-set\n    _binSet\n        .set(TYPE_BINARY_OPERATOR)\n        .set(TYPE_BIG_OPERATOR)\n        .set(TYPE_RELATION)\n        .set(TYPE_OPENING)\n        .set(TYPE_PUNCTUATION);\n    // fill lig-kern-set\n    bitset<16> ligkern;\n    ligkern\n        .set(TYPE_ORDINARY)\n        .set(TYPE_BIG_OPERATOR)\n        .set(TYPE_BINARY_OPERATOR)\n        .set(TYPE_RELATION)\n        .set(TYPE_OPENING)\n        .set(TYPE_CLOSING)\n        .set(TYPE_PUNCTUATION);\n    return ligkern;\n}\n\nRowAtom::RowAtom(const sptr<Atom>& el)\n    : _lookAtLastAtom(false), _previousAtom(nullptr), _canBreak(true) {\n    if (el != nullptr) {\n        RowAtom* x = dynamic_cast<RowAtom*>(el.get());\n        if (x != nullptr) {\n            // no need to make an mrow the only element of a mrow\n            _elements.insert(_elements.end(), x->_elements.begin(), x->_elements.end());\n        } else {\n            _elements.push_back(el);\n        }\n    }\n}\n\nsptr<Atom> RowAtom::getFirstAtom() {\n    if (!_elements.empty()) return _elements.front();\n    return nullptr;\n}\n\nsptr<Atom> RowAtom::popLastAtom() {\n    if (!_elements.empty()) {\n        sptr<Atom> x = _elements.back();\n        _elements.pop_back();\n        return x;\n    }\n    return sptr<Atom>(new SpaceAtom(UNIT_POINT, 0.f, 0.f, 0.f));\n}\n\nsptr<Atom> RowAtom::get(size_t pos) {\n    if (pos > _elements.size()) return sptr<Atom>(new SpaceAtom(UNIT_POINT, 0, 0, 0));\n    return _elements[pos];\n}\n\nvoid RowAtom::add(const sptr<Atom>& el) {\n    if (el != nullptr) _elements.push_back(el);\n}\n\nvoid RowAtom::change2Ord(_out_ Dummy* cur, _out_ Dummy* prev, _out_ Atom* next) {\n    int type = cur->getLeftType();\n    if ((type == TYPE_BINARY_OPERATOR) &&\n        ((prev == nullptr || _binSet[prev->getRightType()]) || next == nullptr)) {\n        cur->setType(TYPE_ORDINARY);\n    } else if (next != nullptr && cur->getRightType() == TYPE_BINARY_OPERATOR) {\n        int nextType = next->getLeftType();\n        if (nextType == TYPE_RELATION ||\n            nextType == TYPE_CLOSING ||\n            nextType == TYPE_PUNCTUATION) {\n            cur->setType(TYPE_ORDINARY);\n        }\n    }\n}\n\nint RowAtom::getLeftType() const {\n    if (_elements.empty()) return TYPE_ORDINARY;\n    return _elements.front()->getLeftType();\n}\n\nint RowAtom::getRightType() const {\n    if (_elements.empty()) return TYPE_ORDINARY;\n    return _elements.back()->getRightType();\n}\n\nsptr<Box> RowAtom::createBox(_out_ TeXEnvironment& env) {\n    auto x = env.getTeXFont();\n    TeXFont& tf = *x;\n    HorizontalBox* hbox = new HorizontalBox(env.getColor(), env.getBackground());\n    env.reset();\n\n    // convert atoms to boxes and add to the horizontal box\n    int e = _elements.size() - 1;\n    for (int i = -1; i < e;) {\n        auto at = _elements[++i];\n        bool markAdded = false;\n        BreakMarkAtom* ba = dynamic_cast<BreakMarkAtom*>(at.get());\n        while (ba != nullptr) {\n            if (!markAdded) markAdded = true;\n            if (i < e) {\n                at = _elements[++i];\n                ba = dynamic_cast<BreakMarkAtom*>(at.get());\n            } else {\n                break;\n            }\n        }\n\n        sptr<Dummy> atom(new Dummy(at));\n        // if necessary, change BIN type to ORD\n        // i.e. for formula: $+ e - f$, the plus sign should be traded as an ordinary type\n        sptr<Atom> nextAtom(nullptr);\n        if (i < e) nextAtom = _elements[i + 1];\n        change2Ord(&(*atom), &(*_previousAtom), &(*nextAtom));\n        // check for ligature or kerning\n        float kern = 0;\n        while (i < e && atom->getRightType() == TYPE_ORDINARY && atom->isCharSymbol()) {\n            auto next = _elements[++i];\n            CharSymbol* c = dynamic_cast<CharSymbol*>(next.get());\n            if (c != nullptr && _ligKernSet[next->getLeftType()]) {\n                atom->markAsTextSymbol();\n                auto l = atom->getCharFont(tf);\n                auto r = c->getCharFont(tf);\n                auto lig = tf.getLigature(*l, *r);\n                if (lig == nullptr) {\n                    kern = tf.getKern(*l, *r, env.getStyle());\n                    i--;\n                    break;  // iterator remains unchanged (no ligature!)\n                } else {\n                    // fixed with ligature\n                    atom->changeAtom(sptr<FixedCharAtom>(new FixedCharAtom(lig)));\n                }\n            } else {\n                i--;\n                break;\n            }  // iterator remains unchanged\n        }\n\n        // insert glue, unless it's the first element of the row\n        // or this element or the next is a kerning\n        if (i != 0 && _previousAtom != nullptr && !_previousAtom->isKern() && !atom->isKern()) {\n            hbox->add(Glue::get(_previousAtom->getRightType(), atom->getLeftType(), env));\n        }\n        // insert atom's box\n        atom->setPreviousAtom(_previousAtom);\n        auto b = atom->createBox(env);\n        CharBox* cb = dynamic_cast<CharBox*>(b.get());\n        if (cb != nullptr && atom->isCharInMathMode()) {\n            // When we have a single char, we need to add italic correction\n            // As an example: (TVY) looks crappy...\n            cb->addItalicCorrectionToWidth();\n        }\n\n        if (_canBreak) {\n            if (_breakEveywhere) {\n                hbox->addBreakPosition(hbox->_children.size());\n            } else {\n                auto ca = dynamic_cast<CharAtom*>(at.get());\n                if (markAdded || (ca != nullptr && isdigit(ca->getCharacter()))) {\n                    hbox->addBreakPosition(hbox->_children.size());\n                }\n            }\n        }\n\n        hbox->add(b);\n\n        // set last used font id (for next atom)\n        env.setLastFontId(b->getLastFontId());\n\n        // insert kerning\n        if (abs(kern) > PREC) hbox->add(sptr<Box>(new StrutBox(kern, 0, 0, 0)));\n\n        // kerning do not interfere with the normal glue-rules without kerning\n        if (!atom->isKern()) _previousAtom = atom;\n    }\n    // reset previous atom\n    _previousAtom = nullptr;\n    return sptr<Box>(hbox);\n}\n\nvoid RowAtom::setPreviousAtom(const sptr<Dummy>& prev) {\n    _previousAtom = prev;\n}\n\n/************************************ VRowAtom implementation *************************************/\n\nVRowAtom::VRowAtom() {\n    _addInterline = false;\n    _valign = ALIGN_CENTER;\n    _halign = ALIGN_NONE;\n    _raise = sptr<SpaceAtom>(new SpaceAtom(UNIT_EX, 0, 0, 0));\n}\n\nVRowAtom::VRowAtom(const sptr<Atom>& el) {\n    _addInterline = false;\n    _valign = ALIGN_CENTER;\n    _halign = ALIGN_NONE;\n    _raise = sptr<SpaceAtom>(new SpaceAtom(UNIT_EX, 0, 0, 0));\n    if (el != nullptr) {\n        VRowAtom* a = dynamic_cast<VRowAtom*>(el.get());\n        if (a != nullptr) {\n            _elements.insert(_elements.end(), a->_elements.begin(), a->_elements.end());\n        } else {\n            _elements.push_back(el);\n        }\n    }\n}\n\nvoid VRowAtom::setRaise(int unit, float r) {\n    _raise = sptr<SpaceAtom>(new SpaceAtom(unit, r, 0, 0));\n}\n\nsptr<Atom> VRowAtom::popLastAtom() {\n    auto x = _elements.back();\n    _elements.pop_back();\n    return x;\n}\n\nvoid VRowAtom::add(const sptr<Atom>& el) {\n    if (el != nullptr) _elements.insert(_elements.begin(), el);\n}\n\nvoid VRowAtom::append(const sptr<Atom>& el) {\n    if (el != nullptr) _elements.push_back(el);\n}\n\nsptr<Box> VRowAtom::createBox(_out_ TeXEnvironment& env) {\n    VerticalBox* vb = new VerticalBox();\n    sptr<Box> interline(new StrutBox(0, env.getInterline(), 0, 0));\n\n    if (_halign != ALIGN_NONE) {\n        float maxWidth = F_MIN;\n        vector<sptr<Box>> boxes;\n        const int s = _elements.size();\n        // find the width of the widest box\n        for (int i = 0; i < s; i++) {\n            sptr<Box> box = _elements[i]->createBox(env);\n            boxes.push_back(box);\n            if (maxWidth < box->_width) maxWidth = box->_width;\n        }\n        // align the boxes and add it to the vertical box\n        for (int i = 0; i < s; i++) {\n            auto box = boxes[i];\n            auto hb = sptr<Box>(new HorizontalBox(box, maxWidth, _halign));\n            vb->add(hb);\n            if (_addInterline && i < s - 1) vb->add(interline);\n        }\n    } else {\n        // convert atoms to boxes and add to the vertical box\n        const int s = _elements.size();\n        for (int i = 0; i < s; i++) {\n            vb->add(_elements[i]->createBox(env));\n            if (_addInterline && i < s - 1) vb->add(interline);\n        }\n    }\n\n    vb->_shift = -_raise->createBox(env)->_width;\n    if (_valign == ALIGN_TOP) {\n        float t = vb->getSize() == 0 ? 0 : vb->_children.front()->_height;\n        vb->_height = t;\n        vb->_depth = vb->_depth + vb->_height - t;\n    } else if (_valign == ALIGN_CENTER) {\n        float axis = env.getTeXFont()->getAxisHeight(env.getStyle());\n        float h = vb->_height + vb->_depth;\n        vb->_height = h / 2 + axis;\n        vb->_depth = h / 2 - axis;\n    } else {\n        float t = vb->getSize() == 0 ? 0 : vb->_children.back()->_depth;\n        vb->_height = vb->_depth + vb->_height - t;\n        vb->_depth = t;\n    }\n    return sptr<Box>(vb);\n}\n\n/*************************************** color atom implementation ********************************/\n\nconst color ColorAtom::_default = black;\n\nColorAtom::ColorAtom(const sptr<Atom>& atom, color bg, color c) : _background(bg), _color(c) {\n    _elements = sptr<RowAtom>(new RowAtom(atom));\n}\n\nvoid ColorAtom::defineColor(const string& name, color c) {\n    _colors[name] = c;\n}\n\ncolor ColorAtom::getColor(string s) {\n    if (s.empty()) return _default;\n    trim(s);\n    // #AARRGGBB formatted color\n    if (s[0] == '#') return decode(s);\n    if (s.find(',') == string::npos) {\n        // find from predefined colors\n        auto it = _colors.find(tolower(s));\n        if (it != _colors.end()) return it->second;\n        // AARRGGBB formatted color\n        if (s.find('.') == string::npos) return decode(\"#\" + s);\n        // gray color\n        float x = 0.f;\n        valueof(s, x);\n        if (x != 0.f) {\n            float g = min(1.f, max(x, 0.f));\n            return rgb(g, g, g);\n        }\n        return _default;\n    }\n\n    auto en = string::npos;\n    strtokenizer toks(s, \";,\");\n    int n = toks.count_tokens();\n    if (n == 3) {\n        // RGB model\n        string R = toks.next_token();\n        string G = toks.next_token();\n        string B = toks.next_token();\n\n        float r = 0.f, g = 0.f, b = 0.f;\n        valueof(trim(R), r);\n        valueof(trim(G), g);\n        valueof(trim(B), b);\n\n        if (r == 0.f && g == 0.f && b == 0.f) return _default;\n\n        if (r == (int)r && g == (int)g && b == (int)b &&\n            R.find('.') == en && G.find('.') == en && B.find('.') == en) {\n            int ir = (int)min(255.f, max(0.f, r));\n            int ig = (int)min(255.f, max(0.f, g));\n            int ib = (int)min(255.f, max(0.f, b));\n            return rgb(ir, ig, ib);\n        }\n        r = min(1.f, max(0.f, r));\n        g = min(1.f, max(0.f, g));\n        b = min(1.f, max(0.f, b));\n        return rgb(r, g, b);\n    } else if (n == 4) {\n        // CMYK model\n        float c = 0.f, m = 0.f, y = 0.f, k = 0.f;\n        string C = toks.next_token();\n        string M = toks.next_token();\n        string Y = toks.next_token();\n        string K = toks.next_token();\n        valueof(trim(C), c);\n        valueof(trim(M), m);\n        valueof(trim(Y), y);\n        valueof(trim(K), k);\n\n        if (c == 0.f && m == 0.f && y == 0.f && k == 0.f) return _default;\n\n        c = min(1.f, max(0.f, c));\n        m = min(1.f, max(0.f, m));\n        y = min(1.f, max(0.f, y));\n        k = min(1.f, max(0.f, k));\n\n        return cmyk(c, m, y, k);\n    }\n\n    return _default;\n}\n\nsptr<Box> ColorAtom::createBox(_out_ TeXEnvironment& env) {\n    env._isColored = true;\n    TeXEnvironment& c = *(env.copy());\n    if (!istrans(_background)) c.setBackground(_background);\n    if (!istrans(_color)) c.setColor(_color);\n    return _elements->createBox(c);\n}\n\nsptr<Box> RomanAtom::createBox(_out_ TeXEnvironment& env) {\n    if (_base == nullptr) return sptr<Box>(new StrutBox(0, 0, 0, 0));\n    TeXEnvironment& c = *(env.copy(env.getTeXFont()->copy()));\n    c.getTeXFont()->setRoman(true);\n    return _base->createBox(c);\n}\n\nPhantomAtom::PhantomAtom(const sptr<Atom>& el) {\n    if (el == nullptr)\n        _elements = sptr<RowAtom>(new RowAtom());\n    else\n        _elements = sptr<RowAtom>(new RowAtom(el));\n    _w = _h = _d = true;\n}\n\nPhantomAtom::PhantomAtom(const sptr<Atom>& el, bool w, bool h, bool d) {\n    if (el == nullptr)\n        _elements = sptr<RowAtom>(new RowAtom());\n    else\n        _elements = sptr<RowAtom>(new RowAtom(el));\n    _w = w, _h = h, _d = d;\n}\n\nsptr<Box> PhantomAtom::createBox(_out_ TeXEnvironment& env) {\n    auto res = _elements->createBox(env);\n    float w = (_w ? res->_width : 0);\n    float h = (_h ? res->_height : 0);\n    float d = (_d ? res->_depth : 0);\n    float s = res->_shift;\n    return sptr<Box>(new StrutBox(w, h, d, s));\n}\n\n/************************************ AccentedAtom implementation *********************************/\n\nvoid AccentedAtom::init(\n    const sptr<Atom>& base, const sptr<Atom>& accent) throw(ex_invalid_symbol_type) {\n    _base = base;\n    AccentedAtom* a = dynamic_cast<AccentedAtom*>(base.get());\n    if (a != nullptr)\n        _underbase = a->_underbase;\n    else\n        _underbase = base;\n\n    _accent = dynamic_pointer_cast<SymbolAtom>(accent);\n    if (_accent == nullptr) throw ex_invalid_symbol_type(\"Invalid accent!\");\n\n    _acc = true;\n    _changeSize = true;\n}\n\nAccentedAtom::AccentedAtom(\n    const sptr<Atom>& base, const string& name) throw(ex_invalid_symbol_type, ex_symbol_not_found) {\n    _accent = SymbolAtom::get(name);\n    if (_accent->_type == TYPE_ACCENT) {\n        _base = base;\n        AccentedAtom* a = dynamic_cast<AccentedAtom*>(base.get());\n        if (a != nullptr)\n            _underbase = a->_underbase;\n        else\n            _underbase = base;\n    } else {\n        throw ex_invalid_symbol_type(\n            \"The symbol with the name '\" +\n            name + \"' is not defined as an accent (\" +\n            TeXSymbolParser::TYPE_ATTR + \"='acc') in '\" +\n            TeXSymbolParser::RESOURCE_NAME + \"'!\");\n    }\n    _changeSize = true;\n    _acc = false;\n}\n\nAccentedAtom::AccentedAtom(\n    const sptr<Atom>& base,\n    const sptr<TeXFormula>& acc) throw(ex_invalid_symbol_type, ex_invalid_formula) {\n    if (acc == nullptr) throw ex_invalid_formula(\"the accent TeXFormula can't be null!\");\n    _changeSize = true;\n    _acc = false;\n    auto root = acc->_root;\n    _accent = dynamic_pointer_cast<SymbolAtom>(root);\n    if (_accent == nullptr)\n        throw ex_invalid_formula(\"The accent TeXFormula does not represet a single symbol!\");\n    if (_accent->_type == TYPE_ACCENT) {\n        _base = base;\n    } else {\n        throw ex_invalid_symbol_type(\n            \"The accent TeXFormula represents a single symbol with the name '\" +\n            _accent->getName() + \"', but this symbol is not defined as accent (\" +\n            TeXSymbolParser::TYPE_ATTR + \"='acc') in '\" +\n            TeXSymbolParser::RESOURCE_NAME + \"'!\");\n    }\n}\n\nsptr<Box> AccentedAtom::createBox(_out_ TeXEnvironment& env) {\n    TeXFont* tf = env.getTeXFont().get();\n    int style = env.getStyle();\n\n    // set base in cramped style\n    auto b = (_base == nullptr ? sptr<Box>(new StrutBox(0, 0, 0, 0))\n                               : _base->createBox(*(env.crampStyle())));\n\n    float u = b->_width;\n    float s = 0;\n    CharSymbol* sym = dynamic_cast<CharSymbol*>(_underbase.get());\n    if (sym != nullptr) s = tf->getSkew(*(sym->getCharFont(*tf)), style);\n\n    // retrieve best char form the accent symbol\n    SymbolAtom* acc = (SymbolAtom*)_accent.get();\n    Char ch = tf->getChar(acc->getName(), style);\n    while (tf->hasNextLarger(ch)) {\n        Char larger = tf->getNextLarger(ch, style);\n        if (larger.getWidth() <= u)\n            ch = larger;\n        else\n            break;\n    }\n\n    // calculate delta\n    float ec = -SpaceAtom::getFactor(UNIT_MU, env);\n    float delta = _acc ? ec : min(b->_height, tf->getXHeight(style, ch.getFontCode()));\n\n    // create vertical box\n    VerticalBox* vBox = new VerticalBox();\n\n    // accent\n    sptr<Box> y(nullptr);\n    float italic = ch.getItalic();\n    sptr<Box> cb(new CharBox(ch));\n    if (_acc) cb = _accent->createBox(_changeSize ? *(env.subStyle()) : env);\n\n    if (abs(italic) > PREC) {\n        y = sptr<Box>(new HorizontalBox(sptr<Box>(new StrutBox(-italic, 0, 0, 0))));\n        y->add(cb);\n    } else {\n        y = cb;\n    }\n\n    // if diff > 0, center accent, otherwise center base\n    float diff = (u - y->_width) / 2;\n    y->_shift = s + (diff > 0 ? diff : 0);\n    if (diff < 0) b = sptr<Box>(new HorizontalBox(b, y->_width, ALIGN_CENTER));\n    vBox->add(y);\n\n    // kerning\n    vBox->add(sptr<Box>(new StrutBox(0, _changeSize ? -delta : -b->_width, 0, 0)));\n    // base\n    vBox->add(b);\n\n    // set height and depth vertical box\n    float total = vBox->_height + vBox->_depth, d = b->_depth;\n    vBox->_depth = d;\n    vBox->_height = total - d;\n\n    if (diff < 0) {\n        HorizontalBox* hb = new HorizontalBox(sptr<Box>(new StrutBox(diff, 0, 0, 0)));\n        hb->add(sptr<Box>(vBox));\n        hb->_width = u;\n        return sptr<Box>(hb);\n    }\n\n    return sptr<Box>(vBox);\n}\n\n/************************************ UnderOverAtom implementation *******************************/\n\nsptr<Box> UnderOverAtom::changeWidth(const sptr<Box>& b, float maxW) {\n    if (b != nullptr && abs(maxW - b->_width) > PREC)\n        return sptr<Box>(new HorizontalBox(b, maxW, ALIGN_CENTER));\n    return b;\n}\n\nsptr<Box> UnderOverAtom::createBox(_out_ TeXEnvironment& env) {\n    // create boxes in right style and calculate maximum width\n    auto b = (_base == nullptr ? sptr<Box>(new StrutBox(0, 0, 0, 0)) : _base->createBox(env));\n    sptr<Box> o(nullptr);\n    sptr<Box> u(nullptr);\n    float mx = b->_width;\n    if (_over != nullptr) {\n        o = _over->createBox(_overSmall ? *(env.subStyle()) : env);\n        mx = max(mx, o->_width);\n    }\n    if (_under != nullptr) {\n        u = _under->createBox(_underSmall ? *(env.subStyle()) : env);\n        mx = max(mx, u->_width);\n    }\n\n    // create vertical box\n    VerticalBox* vBox = new VerticalBox();\n\n    // last font used by base (for mono-space atoms following)\n    env.setLastFontId(b->getLastFontId());\n\n    // over script + space\n    if (_over != nullptr) {\n        vBox->add(changeWidth(o, mx));\n        vBox->add(sptr<Box>(SpaceAtom(_overUnit, 0, _overSpace, 0).createBox(env)));\n    }\n\n    // base\n    auto c = changeWidth(b, mx);\n    vBox->add(c);\n\n    // calculate future height of the vertical box (to make sure that the\n    // base stays on the baseline)\n    float h = vBox->_height + vBox->_depth - c->_depth;\n\n    // under script + space\n    if (_under != nullptr) {\n        vBox->add(SpaceAtom(_underUnit, 0, _underSpace, 0).createBox(env));\n        vBox->add(changeWidth(u, mx));\n    }\n\n    // set height and depth\n    vBox->_depth = vBox->_height + vBox->_depth - h;\n    vBox->_height = h;\n    return sptr<Box>(vBox);\n}\n\n/************************************ ScriptsAtom implementation **********************************/\n\nSpaceAtom ScriptsAtom::SCRIPT_SPACE(UNIT_POINT, 0.5f, 0, 0);\n\nsptr<Box> ScriptsAtom::createBox(_out_ TeXEnvironment& env) {\n    if (_base == nullptr) {\n        sptr<Atom> in(new CharAtom(L'M', \"mathnormal\"));\n        _base = sptr<Atom>(new PhantomAtom(in, false, true, true));\n    }\n\n    auto b = _base->createBox(env);\n    sptr<Box> deltaSymbol(new StrutBox(0, 0, 0, 0));\n    if (_sub == nullptr && _sup == nullptr) return b;\n\n    TeXFont* tf = env.getTeXFont().get();\n    const int style = env.getStyle();\n\n    if (_base->_typelimits == SCRIPT_LIMITS ||\n        (_base->_typelimits == SCRIPT_NORMAL && style == STYLE_DISPLAY)) {\n        sptr<Atom> in(new UnderOverAtom(_base, _sub, UNIT_POINT, 0.3f, true, false));\n        return UnderOverAtom(in, _sup, UNIT_POINT, 3.f, true, true).createBox(env);\n    }\n\n    sptr<HorizontalBox> hor(new HorizontalBox(b));\n\n    int lastFontId = b->getLastFontId();\n    // if no last font found (whitespace box), use default \"mu font\"\n    if (lastFontId == TeXFont::NO_FONT) lastFontId = tf->getMuFontId();\n\n    TeXEnvironment subStyle = *(env.subStyle()), supStyle = *(env.supStyle());\n\n    // set delta and preliminary shift-up and shift-down values\n    float delta = 0, shiftUp = 0, shiftDown = 0;\n\n    AccentedAtom* acc = dynamic_cast<AccentedAtom*>(_base.get());\n    SymbolAtom* sym = dynamic_cast<SymbolAtom*>(_base.get());\n    CharSymbol* cs = dynamic_cast<CharSymbol*>(_base.get());\n    if (acc != nullptr) {\n        // special case: accent\n        if(acc->_base == nullptr){\n            throw ex_parse(\"Accented atom without base\");\n        }\n        auto box = acc->_base->createBox(*(env.crampStyle()));\n        shiftUp = box->_height - tf->getSupDrop(supStyle.getStyle());\n        shiftDown = box->_depth + tf->getSubDrop(subStyle.getStyle());\n    } else if (sym != nullptr && _base->_type == TYPE_BIG_OPERATOR) {\n        // single big operator symbol\n        Char c = tf->getChar(sym->getName(), style);\n        // display style\n        if (style < STYLE_TEXT && tf->hasNextLarger(c)) c = tf->getNextLarger(c, style);\n        sptr<Box> x(new CharBox(c));\n\n        float axish = env.getTeXFont()->getAxisHeight(env.getStyle());\n        x->_shift = -(x->_height + x->_depth) / 2 - axish;\n        hor = sptr<HorizontalBox>(new HorizontalBox(x));\n\n        // include delta in width or not?\n        delta = c.getItalic();\n        deltaSymbol = SpaceAtom(MEDMUSKIP).createBox(env);\n        if (delta > PREC && _sub == nullptr) hor->add(sptr<Box>(new StrutBox(delta, 0, 0, 0)));\n\n        shiftUp = hor->_height - tf->getSupDrop(supStyle.getStyle());\n        shiftDown = hor->_depth + tf->getSubDrop(subStyle.getStyle());\n    } else if (cs != nullptr) {\n        shiftUp = shiftDown = 0;\n        sptr<CharFont> pcf = cs->getCharFont(*tf);\n        CharFont& cf = *pcf;\n        if (!cs->isMarkedAsTextSymbol() || !tf->hasSpace(cf._fontId)) {\n            delta = tf->getChar(cf, style).getItalic();\n        }\n        if (delta > PREC && _sub == nullptr) {\n            hor->add(sptr<Box>(new StrutBox(delta, 0, 0, 0)));\n            delta = 0;\n        }\n    } else {\n        shiftUp = b->_height - tf->getSupDrop(supStyle.getStyle());\n        shiftDown = b->_depth + tf->getSubDrop(subStyle.getStyle());\n    }\n\n    if (_sup == nullptr) {\n        // only sub script\n        auto x = _sub->createBox(subStyle);\n        // calculate and set shift amount\n        x->_shift = max(\n            max(shiftDown, tf->getSub1(style)),\n            x->_height - 0.8f * abs(tf->getXHeight(style, lastFontId)));\n        hor->add(x);\n        hor->add(deltaSymbol);\n\n        return hor;\n    }\n\n    auto x = _sup->createBox(supStyle);\n    float msiz = x->_width;\n    if (_sub != nullptr && _align == ALIGN_RIGHT) {\n        msiz = max(msiz, _sub->createBox(subStyle)->_width);\n    }\n\n    sptr<HorizontalBox> sup(new HorizontalBox(x, msiz, _align));\n    // add space\n    sup->add(SCRIPT_SPACE.createBox(env));\n    // adjust shift-up\n    float p;\n    if (style == STYLE_DISPLAY)\n        p = tf->getSup1(style);\n    else if (env.crampStyle()->getStyle() == style)\n        p = tf->getSup3(style);\n    else\n        p = tf->getSup2(style);\n    shiftUp = max(max(shiftUp, p), x->_depth + abs(tf->getXHeight(style, lastFontId)) / 4);\n\n    if (_sub == nullptr) {\n        // only super script\n        sup->_shift = -shiftUp;\n        hor->add(sup);\n    } else {\n        // both super and sub script\n        sptr<Box> y(_sub->createBox(subStyle));\n        sptr<HorizontalBox> sub(new HorizontalBox(y, msiz, _align));\n        // add space\n        sub->add(SCRIPT_SPACE.createBox(env));\n        // adjust shift down\n        shiftDown = max(shiftDown, tf->getSub2(style));\n        // position both sub and super script\n        float drt = tf->getDefaultRuleThickness(style);\n        float interspace = shiftUp - x->_depth + shiftDown - y->_height;\n        // space between sub and super script\n        if (interspace < 4 * drt) {\n            // too small\n            shiftUp += 4 * drt - interspace;\n            // set bottom super script at least 4/5 of X-height above baseline\n            float psi = 0.8 * abs(tf->getXHeight(style, lastFontId)) - (shiftUp - x->_depth);\n\n            if (psi > 0) {\n                shiftUp += psi;\n                shiftDown -= psi;\n            }\n        }\n\n        // create total box\n        VerticalBox* vBox = new VerticalBox();\n        sup->_shift = delta;\n        vBox->add(sup);\n        // recalculate inter-space\n        interspace = shiftUp - x->_depth + shiftDown - y->_height;\n        vBox->add(sptr<Box>(new StrutBox(0, interspace, 0, 0)));\n        vBox->add(sub);\n        vBox->_height = shiftUp + x->_height;\n        vBox->_depth = shiftDown + y->_depth;\n        hor->add(sptr<Box>(vBox));\n    }\n    hor->add(deltaSymbol);\n    return hor;\n}\n\n/************************************ BigOperatorAtom implementation ******************************/\n\nvoid BigOperatorAtom::init(\n    const sptr<Atom>& base, const sptr<Atom>& under, const sptr<Atom>& over) {\n    _base = base;\n    _under = under;\n    _over = over;\n    _limits = false;\n    _limitsSet = false;\n    _type = TYPE_BIG_OPERATOR;\n}\n\nsptr<Box> BigOperatorAtom::changeWidth(const sptr<Box>& b, float maxw) {\n    if (b != nullptr && abs(maxw - b->_width) > PREC)\n        return sptr<Box>(new HorizontalBox(b, maxw, ALIGN_CENTER));\n    return b;\n}\n\nsptr<Box> BigOperatorAtom::createSideSets(_out_ TeXEnvironment& env) {\n    SideSetsAtom* sa = static_cast<SideSetsAtom*>(_base.get());\n    auto sl = sa->_left, sr = sa->_right, sb = sa->_base;\n    if (sb == nullptr) {\n        sptr<Atom> in(new CharAtom(L'M', \"mathnormal\"));\n        sb = sptr<Atom>(new PhantomAtom(in, false, true, true));\n    }\n\n    auto opbox = sb->createBox(env);\n    auto pa = sptr<Atom>(new PlaceholderAtom(0, opbox->_height, opbox->_depth, opbox->_shift));\n    pa->_typelimits = SCRIPT_NOLIMITS;\n    pa->_type = TYPE_BIG_OPERATOR;\n\n    ScriptsAtom* l = dynamic_cast<ScriptsAtom*>(sl.get());\n    ScriptsAtom* r = dynamic_cast<ScriptsAtom*>(sr.get());\n\n    if (l != nullptr && l->_base == nullptr) {\n        l->_base = pa;\n        l->_align = ALIGN_RIGHT;\n    }\n    if (r != nullptr && r->_base == nullptr) r->_base = pa;\n\n    auto y = sptr<Box>(new HorizontalBox());\n    float limitsShift = 0;\n    if (sl != nullptr) {\n        auto lb = sl->createBox(env);\n        y->add(lb);\n        limitsShift = lb->_width + opbox->_width / 2;\n    }\n    y->add(opbox);\n    if (sr != nullptr) y->add(sr->createBox(env));\n\n    TeXFont* tf = env.getTeXFont().get();\n    const int style = env.getStyle();\n\n    float delta = 0;\n    if (sb->_type == TYPE_BIG_OPERATOR) {\n        SymbolAtom* sym = dynamic_cast<SymbolAtom*>(sb.get());\n        if (sym != nullptr) {\n            Char c = tf->getChar(sym->getName(), style);\n            delta = c.getItalic();\n        }\n    }\n\n    // under and over\n    sptr<Box> x, z;\n    if (_over != nullptr) x = _over->createBox(*(env.supStyle()));\n    if (_under != nullptr) z = _under->createBox(*(env.subStyle()));\n\n    // build vertical box\n    VerticalBox* vbox = new VerticalBox();\n    float bigop5 = tf->getBigOpSpacing5(style), kern = 0;\n\n    if (_over != nullptr) {\n        vbox->add(sptr<Box>(new StrutBox(0, bigop5, 0, 0)));\n        x->_shift = limitsShift - x->_width / 2 + delta / 2;\n        vbox->add(x);\n        kern = max(tf->getBigOpSpacing1(style), tf->getBigOpSpacing3(style) - x->_depth);\n        vbox->add(sptr<Box>(new StrutBox(0, kern, 0, 0)));\n    }\n\n    vbox->add(y);\n\n    if (_under != nullptr) {\n        float k = max(tf->getBigOpSpacing2(style), tf->getBigOpSpacing4(style) - z->_height);\n        vbox->add(sptr<Box>(new StrutBox(0, k, 0, 0)));\n        z->_shift = limitsShift - z->_width / 2 - delta / 2;\n        vbox->add(z);\n        vbox->add(sptr<Box>(new StrutBox(0, bigop5, 0, 0)));\n    }\n\n    float h = y->_height, total = vbox->_height + vbox->_depth;\n    if (x != nullptr) h += bigop5 + kern + x->_height + x->_depth;\n    vbox->_height = h;\n    vbox->_depth = total - h;\n\n    return sptr<Box>(vbox);\n}\n\nsptr<Box> BigOperatorAtom::createBox(_out_ TeXEnvironment& env) {\n    if(_base == nullptr) throw ex_parse(\"empty atom\");\n    if (dynamic_cast<SideSetsAtom*>(_base.get())) return createSideSets(env);\n\n    TeXFont* tf = env.getTeXFont().get();\n    const int style = env.getStyle();\n\n    RowAtom* row = nullptr;\n    auto Base = _base;\n\n    TypedAtom* ta = dynamic_cast<TypedAtom*>(_base.get());\n    if (ta != nullptr) {\n        auto atom = ta->getBase();\n        RowAtom* ra = dynamic_cast<RowAtom*>(atom.get());\n        if (ra != nullptr && ra->_lookAtLastAtom && _base->_typelimits != SCRIPT_LIMITS) {\n            _base = ra->popLastAtom();\n            row = ra;\n        } else {\n            _base = atom;\n        }\n    }\n\n    if ((_limitsSet && !_limits) ||\n        (!_limitsSet && style >= STYLE_TEXT) ||\n        (_base->_typelimits == SCRIPT_NOLIMITS) ||\n        (_base->_typelimits == SCRIPT_NORMAL && style >= STYLE_TEXT)) {\n        // if explicitly set to not display as limits or if not set and\n        // style is not display, then attach over and under as regular sub or\n        // super script\n        if (row != nullptr) {\n            row->add(sptr<Atom>(new ScriptsAtom(_base, _under, _over)));\n            auto b = row->createBox(env);\n            row->popLastAtom();\n            row->add(_base);\n            _base = Base;\n            return b;\n        }\n        return ScriptsAtom(_base, _under, _over).createBox(env);\n    }\n\n    sptr<Box> y(nullptr);\n    float delta;\n\n    SymbolAtom* sym = dynamic_cast<SymbolAtom*>(_base.get());\n    if (sym != nullptr && _base->_type == TYPE_BIG_OPERATOR) {\n        // single big operator symbol\n        Char c = tf->getChar(sym->getName(), style);\n        y = _base->createBox(env);\n        // include delta in width\n        delta = c.getItalic();\n    } else {\n        delta = 0;\n        auto in = _base == nullptr ? sptr<Box>(new StrutBox(0, 0, 0, 0))\n                                   : _base->createBox(env);\n        y = sptr<Box>(new HorizontalBox(in));\n    }\n\n    // limits\n    sptr<Box> x, z;\n    if (_over != nullptr) x = _over->createBox(*(env.supStyle()));\n    if (_under != nullptr) z = _under->createBox(*(env.subStyle()));\n\n    // make boxes equally wide\n    float maxW = max(\n        max(x == nullptr ? 0 : x->_width, y->_width),\n        z == nullptr ? 0 : z->_width);\n    x = changeWidth(x, maxW);\n    y = changeWidth(y, maxW);\n    z = changeWidth(z, maxW);\n\n    // build vertical box\n    VerticalBox* vBox = new VerticalBox();\n\n    float bigop5 = tf->getBigOpSpacing5(style), kern = 0;\n\n    // over\n    if (_over != nullptr) {\n        vBox->add(sptr<Box>(new StrutBox(0, bigop5, 0, 0)));\n        x->_shift = delta / 2;\n        vBox->add(x);\n        kern = max(tf->getBigOpSpacing1(style), tf->getBigOpSpacing3(style) - x->_depth);\n        vBox->add(sptr<Box>(new StrutBox(0, kern, 0, 0)));\n    }\n\n    // base\n    vBox->add(y);\n\n    // under\n    if (_under != nullptr) {\n        float k = max(tf->getBigOpSpacing2(style), tf->getBigOpSpacing4(style) - z->_height);\n        vBox->add(sptr<Box>(new StrutBox(0, k, 0, 0)));\n        z->_shift = -delta / 2;\n        vBox->add(z);\n        vBox->add(sptr<Box>(new StrutBox(0, bigop5, 0, 0)));\n    }\n\n    // set height and depth of vertical box\n    float h = y->_height, total = vBox->_height + vBox->_depth;\n    if (x != nullptr) h += bigop5 + kern + x->_height + x->_depth;\n    vBox->_height = h;\n    vBox->_depth = total - h;\n\n    if (row != nullptr) {\n        HorizontalBox* hb = new HorizontalBox(row->createBox(env));\n        row->add(_base);\n        hb->add(sptr<Box>(vBox));\n        _base = Base;\n        return sptr<Box>(hb);\n    }\n    return sptr<Box>(vBox);\n}\n\n/*********************************** SideSetsAtom implementation **********************************/\n\nsptr<Box> SideSetsAtom::createBox(_out_ TeXEnvironment& env) {\n    if (_base == nullptr) {\n        // create a phatom to place side-sets\n        sptr<Atom> in(new CharAtom(L'M', \"mathnormal\"));\n        _base = sptr<Atom>(new PhantomAtom(in, false, true, true));\n    }\n\n    auto bb = _base->createBox(env);\n    auto pa = sptr<Atom>(new PlaceholderAtom(0, bb->_height, bb->_depth, bb->_shift));\n\n    ScriptsAtom* l = dynamic_cast<ScriptsAtom*>(_left.get());\n    ScriptsAtom* r = dynamic_cast<ScriptsAtom*>(_right.get());\n\n    if (l != nullptr && l->_base == nullptr) {\n        l->_base = pa;\n        l->_align = ALIGN_RIGHT;\n    }\n    if (r != nullptr && r->_base == nullptr) r->_base = pa;\n\n    auto hb = new HorizontalBox();\n    if (_left != nullptr) hb->add(_left->createBox(env));\n    hb->add(bb);\n    if (_right != nullptr) hb->add(_right->createBox(env));\n\n    return sptr<Box>(hb);\n}\n\n/******************************** OverUnderDelimiter implementation *******************************/\n\nfloat OverUnderDelimiter::getMaxWidth(const Box* b, const Box* del, const Box* script) {\n    float mx = max(b->_width, del->_height + del->_depth);\n    if (script != nullptr) mx = max(mx, script->_width);\n    return mx;\n}\n\nsptr<Box> OverUnderDelimiter::createBox(_out_ TeXEnvironment& env) {\n    auto b = (_base == nullptr ? sptr<Box>(new StrutBox(0, 0, 0, 0)) : _base->createBox(env));\n    sptr<Box> del = DelimiterFactory::create(_symbol->getName(), env, b->_width);\n\n    sptr<Box> sb(nullptr);\n    if (_script != nullptr)\n        sb = _script->createBox((_over ? *(env.supStyle()) : *(env.subStyle())));\n\n    // create centered horizontal box if smaller than maximum width\n    float mx = getMaxWidth(b.get(), del.get(), sb.get());\n    if (mx - b->_width > PREC) b = sptr<Box>(new HorizontalBox(b, mx, ALIGN_CENTER));\n\n    del = sptr<Box>(new VerticalBox(del, mx, ALIGN_CENTER));\n    if (sb != nullptr && mx - sb->_width > PREC)\n        sb = sptr<Box>(new HorizontalBox(sb, mx, ALIGN_CENTER));\n\n    return sptr<Box>(new OverUnderBox(b, del, sb, _kern.createBox(env)->_height, _over));\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/atom/atom_basic.h",
    "content": "#ifndef ATOM_BASIC_H_INCLUDED\n#define ATOM_BASIC_H_INCLUDED\n\n#include \"atom/atom.h\"\n#include \"atom/box.h\"\n#include \"common.h\"\n#include \"graphic/graphic.h\"\n\n#include <bitset>\n#include <map>\n#include <string>\n\nusing namespace std;\nusing namespace tex;\n\nnamespace tex {\n\nclass CharFont;\nclass TeXFont;\nclass FontInfos;\nclass TeXFormula;\nclass Dummy;\nclass RowAtom;\n\n/**\n * An empty atom\n */\nclass EmptyAtom : public Atom {\npublic:\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        return sptr<Box>(new StrutBox(0, 0, 0, 0));\n    }\n\n    __decl_clone(EmptyAtom)\n};\n\n/**\n * A placeholder atom\n */\nclass PlaceholderAtom : public Atom {\nprivate:\n    float _w, _h, _d, _s;\n\npublic:\n    PlaceholderAtom(float w, float h, float d, float s)\n        : _w(w), _h(h), _d(d), _s(s) {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        return sptr<Box>(new StrutBox(_w, _h, _d, _s));\n    }\n\n    __decl_clone(PlaceholderAtom)\n};\n\n/**\n * The string rendering is made in using Graphics2D\n */\nclass TextRenderingAtom : public Atom {\nprivate:\n    wstring _str;\n    int _type;\n    const FontInfos* _infos;\n\npublic:\n    TextRenderingAtom() = delete;\n\n    TextRenderingAtom(const wstring& str, int type) : _str(str), _type(type), _infos(nullptr) {}\n\n    TextRenderingAtom(const wstring& str, const FontInfos* info)\n        : _str(str), _type(0), _infos(info) {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(TextRenderingAtom)\n};\n\n/**\n * An atom representing a smashed atom (i.e. with no height and no depth)\n */\nclass SmashedAtom : public Atom {\nprivate:\n    sptr<Atom> _at;\n    bool _h, _d;\n\npublic:\n    SmashedAtom() = delete;\n\n    SmashedAtom(const sptr<Atom>& a, const string& opt) : _h(true), _d(true) {\n        _at = a;\n        if (opt == \"opt\")\n            _d = false;\n        else if (opt == \"b\")\n            _h = false;\n    }\n\n    SmashedAtom(const sptr<Atom>& a) : _at(a), _h(true), _d(true) {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        sptr<Box> b = _at->createBox(env);\n        if (_h) b->_height = 0;\n        if (_d) b->_depth = 0;\n        return b;\n    }\n\n    __decl_clone(SmashedAtom)\n};\n\n/**\n * An atom representing a scaled atom\n */\nclass ScaleAtom : public Atom {\nprotected:\n    sptr<Atom> _base;\n\nprivate:\n    float _sx, _sy;\n\npublic:\n    ScaleAtom() = delete;\n\n    ScaleAtom(const sptr<Atom>& base, float sx, float sy) {\n        _type = base->_type;\n        _base = base;\n        _sx = sx;\n        _sy = sy;\n    }\n\n    ScaleAtom(const sptr<Atom>& base, float scale)\n        : ScaleAtom(base, scale, scale) {}\n\n    int getLeftType() const override {\n        return _base->getLeftType();\n    }\n\n    int getRightType() const override {\n        return _base->getRightType();\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(ScaleAtom)\n};\n\n/**\n * An atom representing a math atom\n */\nclass MathAtom : public Atom {\nprivate:\n    int _style;\n    sptr<Atom> _base;\n\npublic:\n    MathAtom() = delete;\n\n    MathAtom(const sptr<Atom>& base, int style) {\n        _base = base;\n        _style = style;\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(MathAtom)\n};\n\n/**\n * An atom representing a horizontal-line in array environment\n */\nclass HlineAtom : public Atom {\nprivate:\n    float _width, _shift;\n    color _color;\n\npublic:\n    HlineAtom() : _color(trans), _width(0), _shift(0) {}\n\n    inline void setWidth(float w) {\n        _width = w;\n    }\n\n    inline void setShift(float s) {\n        _shift = s;\n    }\n\n    inline void setColor(color c) {\n        _color = c;\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(HlineAtom)\n};\n\n/**\n * An atom representing a cumulative scripts atom\n */\nclass CumulativeScriptsAtom : public Atom {\nprivate:\n    sptr<Atom> _base;\n    sptr<RowAtom> _sup, _sub;\n\npublic:\n    CumulativeScriptsAtom() = delete;\n\n    CumulativeScriptsAtom(const sptr<Atom>& base, const sptr<Atom>& sub, const sptr<Atom>& sup);\n\n    void addSuperscript(const sptr<Atom>& sup);\n\n    void addSubscript(const sptr<Atom>& sub);\n\n    sptr<Atom> getScriptsAtom() const;\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(CumulativeScriptsAtom)\n};\n\n/**\n * A \"composed atom\": An atom that consists of child atoms that will be\n * displayed next to each other horizontally with glue between them.\n */\nclass Row {\npublic:\n    /**\n     * Sets the given dummy containing the atom that comes just before the first\n     * child atom of this \"composed atom\". This method will always be called by\n     * another composed atom, so this composed atom will be a child of it\n     * (nested). This is necessary to determine the glue to insert between the\n     * first child atom of this nested composed atom and the atom that the dummy\n     * contains.\n     *\n     * @param dummy\n     *      the dummy that comes just before this \"composed atom\"\n     */\n    virtual void setPreviousAtom(const sptr<Dummy>& dummy) = 0;\n};\n\n/**\n * An atom representing whitespace. The dimension values can be set using different\n * unit types.\n */\nclass SpaceAtom : public Atom {\nprivate:\n    static const int _units_count;\n    static const map<string, int> _units;\n    static const function<float(_in_ const TeXEnvironment&)> _unitConversions[];\n    // whether a hard space should be represented\n    bool _blankSpace;\n    // thin-mu-skip, med-mu-skip, thick-mu-skip\n    int _blankType;\n    // dimensions\n    float _width;\n    float _height;\n    float _depth;\n    // units of the dimensions\n    int _wUnit;\n    int _hUnit;\n    int _dUnit;\n\n    void init() {\n        _blankSpace = false;\n        _blankType = 0;\n        _width = _height = _depth = 0;\n        _wUnit = _hUnit = _dUnit = 0;\n    }\n\npublic:\n    SpaceAtom() {\n        init();\n        _blankSpace = true;\n    }\n\n    SpaceAtom(int type) {\n        init();\n        _blankSpace = true;\n        _blankType = type;\n    }\n\n    SpaceAtom(int unit, float width, float height, float depth) throw(ex_invalid_unit) {\n        init();\n        // check if the unit is valid\n        checkUnit(unit);\n\n        _wUnit = _hUnit = _dUnit = unit;\n        _width = width;\n        _height = height;\n        _depth = depth;\n    }\n\n    SpaceAtom(int wu, float w, int hu, float h, int du, float d) throw(ex_invalid_unit) {\n        init();\n        // check if the unit is valid\n        checkUnit(wu);\n        checkUnit(hu);\n        checkUnit(du);\n\n        _wUnit = wu;\n        _hUnit = hu;\n        _dUnit = du;\n        _width = w;\n        _height = h;\n        _depth = d;\n    }\n\n    /**\n     * Check if the given unit is valid\n     *\n     * @param unit the unit's integer representation (a constant)\n     * @throw ex_invalid_unit if the given integer value does not represent\n     * a valid unit\n     */\n    inline static void checkUnit(int unit) throw(ex_invalid_unit) {\n        if (unit < 0 || unit >= _units_count) throw ex_invalid_unit();\n    }\n\n    inline static int getUnit(const string& unit) {\n        auto i = _units.find(unit);\n        if (i == _units.end()) return UNIT_PIXEL;\n        return i->second;\n    }\n\n    inline static float getFactor(int unit, _in_ const TeXEnvironment& env) {\n        return _unitConversions[unit](env);\n    }\n\n    inline static float getSize(int unit, float s, _in_ const TeXEnvironment& env) {\n        return _unitConversions[unit](env) * s;\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    /**\n     * Get the unit and length from given string. The string must be in the format: a number\n     * following with the unit (e.g. 10px, 1cm, 8.2em, ...) or (UNIT_PIXEL, 0) will be returned.\n     */\n    static pair<int, float> getLength(const string& lgth);\n\n    /**\n     * Get the unit and length from given string. The string must be in the format: a number\n     * following with the unit (e.g. 10px, 1cm, 8.2em, ...) or (UNIT_PIXEL, 0) will be returned.\n     */\n    static pair<int, float> getLength(const wstring& lgth);\n\n    __decl_clone(SpaceAtom)\n};\n\n/**\n * An atom representing an underscore\n */\nclass UnderScoreAtom : public Atom {\npublic:\n    static SpaceAtom _w, _s;\n\n    UnderScoreAtom() {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(UnderScoreAtom)\n};\n\n/**\n * An atom representing a middle atom which must be rounded by a left and right\n * delimiter.\n */\nclass MiddleAtom : public Atom {\npublic:\n    sptr<Atom> _base;\n    sptr<Box> _box;\n\n    MiddleAtom() = delete;\n\n    MiddleAtom(const sptr<Atom>& a)\n        : _base(a), _box(new StrutBox(0, 0, 0, 0)) {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        return _box;\n    }\n\n    __decl_clone(MiddleAtom)\n};\n\n/**\n * An common superclass for atoms that represent one single character and access\n * the font information.\n */\nclass CharSymbol : public Atom {\nprivate:\n    /**\n     * Mrow will mark certain CharSymbol atoms as a text symbol. Msubsup wil use\n     * this property for a certain spacing rule.\n     */\n    bool _textSymbol;\n\npublic:\n    CharSymbol() : _textSymbol(false) {}\n\n    /**\n     * Mark as text symbol (used by Dummy)\n     */\n    inline void markAsTextSymbol() {\n        _textSymbol = true;\n    }\n\n    /**\n     * Remove the mark so the atom remains unchanged (used by Dummy)\n     */\n    inline void removeMark() {\n        _textSymbol = false;\n    }\n\n    /**\n     * Tests if this atom is marked as a text symbol (used by Msubsup)\n     *\n     * @return whether this CharSymbol is marked as a text symbol\n     */\n    bool isMarkedAsTextSymbol() {\n        return _textSymbol;\n    }\n\n    /**\n     * Get the CharFont-object that uniquely identifies the character that is\n     * represented by this atom.\n     *\n     * @param tf\n     *       the TeXFont containing all font related information\n     * @return a CharFont\n     */\n    virtual sptr<CharFont> getCharFont(_in_ TeXFont& tf) = 0;\n};\n\n/**\n * An atom representing a fixed character (not depending on a text style).\n */\nclass FixedCharAtom : public CharSymbol {\nprivate:\n    const sptr<CharFont> _cf;\n\npublic:\n    FixedCharAtom() = delete;\n\n    FixedCharAtom(const sptr<CharFont>& c) : _cf(c) {}\n\n    sptr<CharFont> getCharFont(_in_ TeXFont& tf) override;\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(FixedCharAtom)\n};\n\nclass SymbolAtom : public CharSymbol {\nprivate:\n    // contains all defined symbols\n    static map<string, sptr<SymbolAtom>> _symbols;\n    // contains all the possible valid symbol types\n    static bitset<16> _validSymbolTypes;\n    // whether it's a delimiter symbol\n    bool _delimiter;\n    // symbol name\n    string _name;\n    wchar_t _unicode;\n\npublic:\n    SymbolAtom() = delete;\n\n    /**\n     * Constructs a new symbol. This used by \"TeXSymbolParser\" and the symbol\n     * types are guaranteed to be valid.\n     *\n     * @param name\n     *      symbol name\n     * @param type\n     *      symbol type constant\n     * @param del\n     *      whether the symbol is a delimiter\n     */\n    SymbolAtom(const string& name, int type, bool del);\n\n    inline SymbolAtom& setUnicode(wchar_t c) {\n        _unicode = c;\n        return *this;\n    }\n\n    inline wchar_t getUnicode() const {\n        return _unicode;\n    }\n\n    /**\n     * @return true if this symbol can act as a delimiter to embrace formulas\n     */\n    inline bool isDelimiter() const {\n        return _delimiter;\n    }\n\n    inline const string& getName() const {\n        return _name;\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    sptr<CharFont> getCharFont(_in_ TeXFont& tf) override;\n\n    static void addSymbolAtom(const string& file);\n\n    static void addSymbolAtom(const sptr<SymbolAtom>& sym);\n\n    /**\n     * Looks up the name in the table and returns the corresponding SymbolAtom\n     * representing the symbol (if it's found).\n     *\n     * @param name\n     *      the name of the symbol\n     * @return a SymbolAtom representing the found symbol\n     * @throw ex_symbol_not_found\n     *      if no symbol with the given name was found\n     */\n    static sptr<SymbolAtom> get(const string& name) throw(ex_symbol_not_found);\n\n    static void _init_();\n\n#ifdef HAVE_LOG\n    friend ostream& operator<<(ostream& os, const SymbolAtom& s);\n#endif  // HAVE_LOG\n\n    __decl_clone(SymbolAtom)\n};\n\n/**\n * An atom representing exactly one alphanumeric character and the text style in\n * which it should be drawn.\n */\nclass CharAtom : public CharSymbol {\nprivate:\n    // alphanumeric character\n    wchar_t _c;\n    // text style (empty means the default text style)\n    string _textStyle;\n    bool _mathMode;\n\n    /**\n     * Get the Char-object representing this character (\"c\") in the right text\n     * style\n     */\n    Char getChar(_in_ TeXFont& tf, int style, bool smallCap);\n\npublic:\n    CharAtom() = delete;\n\n    /**\n     * Creates a CharAtom that will represent the given character in the given\n     * text style. Null for the text style means the default text style.\n     *\n     * @param c\n     *      the alphanumeric character\n     * @param textStyle\n     *      the text style in which the character should be drawn\n     */\n    CharAtom(wchar_t c, const string& textStyle)\n        : _c(c), _textStyle(textStyle), _mathMode(false) {}\n\n    CharAtom(wchar_t c, const string& textStyle, bool mathMode)\n        : _c(c), _textStyle(textStyle), _mathMode(mathMode) {}\n\n    inline wchar_t getCharacter() {\n        return _c;\n    }\n\n    inline bool isMathMode() {\n        return _mathMode;\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    sptr<CharFont> getCharFont(_in_ TeXFont& tf) override;\n\n    __decl_clone(CharAtom)\n};\n\n/**\n * An empty atom just to add a mark.\n */\nclass BreakMarkAtom : public Atom {\npublic:\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(BreakMarkAtom)\n};\n\n/**\n * Used by RowAtom. The \"textSymbol\"-property and the type of An atom can change\n * (according to the TeX-algorithms used). Or this atom can be replaced by a\n * ligature, (if it was a CharAtom). But atoms cannot be changed, otherwise\n * different boxes could be made from the same TeXFormula, and that is not\n * desired! This \"dummy atom\" makes sure that changes to an atom (during the\n * createBox-method of a RowAtom) will be reset.\n */\nclass Dummy {\nprivate:\n    sptr<Atom> _el;\n    bool _textSymbol;\n    int _type;\n\npublic:\n    Dummy() = delete;\n\n    /**\n     * Create a new dummy for the given atom\n     * @param a\n     *      an atom\n     */\n    Dummy(const sptr<Atom>& a) {\n        _textSymbol = false;\n        _type = -1;\n        _el = a;\n    }\n\n    /**\n     * Changes the type of the atom\n     * @param t\n     *      the new type\n     */\n    inline void setType(int t) {\n        _type = t;\n    }\n\n    inline int getType() const {\n        return _type;\n    }\n\n    /**\n     * @return the changed type, or the old left type if it has not been changed\n     */\n    inline int getLeftType() const {\n        return (_type >= 0 ? _type : _el->getLeftType());\n    }\n\n    /**\n     * @return the changed type, or the old right type if it has not been changed\n     */\n    inline int getRightType() const {\n        return (_type >= 0 ? _type : _el->getRightType());\n    }\n\n    inline bool isCharSymbol() const {\n        CharSymbol* x = dynamic_cast<CharSymbol*>(_el.get());\n        return (x != nullptr);\n    }\n\n    inline bool isCharInMathMode() const {\n        CharAtom* at = dynamic_cast<CharAtom*>(_el.get());\n        return at != nullptr && at->isMathMode();\n    }\n\n    /**\n     * This method will only be called if isCharSymbol returns true.\n     */\n    inline sptr<CharFont> getCharFont(_in_ TeXFont& tf) const {\n        return ((CharSymbol*)_el.get())->getCharFont(tf);\n    }\n\n    /**\n     * Changes this atom into the given \"ligature atom\".\n     *\n     * @param a\n     *      the ligature atom\n     */\n    inline void changeAtom(const sptr<FixedCharAtom>& a) {\n        _textSymbol = false;\n        _type = -1;\n        _el = a;\n    }\n\n    inline sptr<Box> createBox(_out_ TeXEnvironment& env) {\n        if (_textSymbol) ((CharSymbol*)_el.get())->markAsTextSymbol();\n        auto b = _el->createBox(env);\n        if (_textSymbol) ((CharSymbol*)_el.get())->removeMark();\n        return b;\n    }\n\n    inline void markAsTextSymbol() {\n        _textSymbol = true;\n    }\n\n    inline bool isKern() const {\n        SpaceAtom* x = dynamic_cast<SpaceAtom*>(_el.get());\n        return (x != nullptr);\n    }\n\n    /**\n     * Only for row-elements\n     */\n    inline void setPreviousAtom(const sptr<Dummy>& prev) {\n        Row* row = dynamic_cast<Row*>(_el.get());\n        if (row != nullptr) {\n            row->setPreviousAtom(prev);\n        }\n    }\n};\n\n/**\n * An atom representing a horizontal row of other atoms, to be separated by\n * glue. It's also responsible for inserting kerns and ligature.\n */\nclass RowAtom : public Atom, public Row {\nprivate:\n    // set of atom types that make a previous bin atom change to ord\n    static bitset<16> _binSet;\n    // set of atom types that can possibly need a kern or, together\n    // with the previous atom, be replaced by a ligature\n    static bitset<16> _ligKernSet;\n    // whether the box generated can be broken\n    bool _canBreak;\n    // atoms to be displayed horizontally next to each-other\n    vector<sptr<Atom>> _elements;\n    // previous atom (for nested Row atoms)\n    sptr<Dummy> _previousAtom;\n\n    void change2Ord(_out_ Dummy* cur, _out_ Dummy* prev, _out_ Atom* next);\n\n    static bitset<16> _init_();\n\npublic:\n    static bool _breakEveywhere;\n\n    bool _lookAtLastAtom;\n\n    RowAtom() : _lookAtLastAtom(false), _canBreak(true) {}\n\n    RowAtom(const sptr<Atom>& el);\n\n    /**\n     * Get the atom at the front in the elements\n     */\n    sptr<Atom> getFirstAtom();\n\n    /**\n     * Get and remove the atom at the tail in the elements\n     */\n    sptr<Atom> popLastAtom();\n\n    /**\n     * Get the atom at position\n     * @param pos\n     *      the position of the atom to retrieve\n     */\n    sptr<Atom> get(size_t pos);\n\n    /**\n     * Indicate the box generated by this atom can be broken or not\n     * @param can\n     *      indicate whether the box can be broken\n     */\n    inline void setCanBreak(bool can) {\n        _canBreak = can;\n    }\n\n    /**\n     * Retrieve the size of the elements\n     */\n    inline size_t size() const {\n        return _elements.size();\n    }\n\n    /**\n     * Push An atom to back\n     */\n    void add(const sptr<Atom>& el);\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    void setPreviousAtom(const sptr<Dummy>& prev) override;\n\n    int getLeftType() const override;\n\n    int getRightType() const override;\n\n    __decl_clone(RowAtom)\n};\n\n/**\n * An atom representing a vertical row of other atoms.\n */\nclass VRowAtom : public Atom {\nprivate:\n    vector<sptr<Atom>> _elements;\n    sptr<SpaceAtom> _raise;\n    bool _addInterline;\n    int _valign;\n    int _halign;\n\npublic:\n    VRowAtom();\n\n    VRowAtom(const sptr<Atom>& el);\n\n    inline void setAddInterline(bool addInterline) {\n        _addInterline = addInterline;\n    }\n\n    inline bool getAddInterline() const {\n        return _addInterline;\n    }\n\n    /**\n     * Set the horizontal alignment\n     */\n    inline void setHalign(int halign) {\n        _halign = halign;\n    }\n\n    inline bool getHalign() const {\n        return _halign;\n    }\n\n    inline void setVtop(bool vtop) {\n        _valign = ALIGN_TOP;\n    }\n\n    inline bool getVtop() const {\n        return _valign == ALIGN_TOP;\n    }\n\n    void setRaise(int unit, float r);\n\n    sptr<Atom> popLastAtom();\n\n    /**\n     * Add an atom at the front\n     */\n    void add(const sptr<Atom>& el);\n\n    /**\n     * Add an atom at the tail\n     */\n    void append(const sptr<Atom>& el);\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(VRowAtom)\n};\n\n/**\n * An atom representing the foreground and background color of an other atom\n */\nclass ColorAtom : public Atom, public Row {\nprivate:\n    static map<string, color> _colors;\n    static const color _default;\n\n    color _background, _color;\n    // RowAtom for which the color settings apply\n    sptr<RowAtom> _elements;\n\npublic:\n    ColorAtom() = delete;\n\n    ColorAtom(const sptr<Atom>& atom, color bg, color c);\n\n    ColorAtom(color bg, color c, const sptr<Atom>& old) throw(ex_invalid_atom_type) {\n        ColorAtom* a = dynamic_cast<ColorAtom*>(old.get());\n        if (a == nullptr) throw ex_invalid_atom_type(\"Should be a ColorAtom!\");\n        _elements = a->_elements;\n        _background = istrans(bg) ? a->_background : bg;\n        _color = istrans(c) ? a->_color : c;\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    int getLeftType() const override {\n        return _elements->getLeftType();\n    }\n\n    int getRightType() const override {\n        return _elements->getRightType();\n    }\n\n    void setPreviousAtom(const sptr<Dummy>& prev) override {\n        _elements->setPreviousAtom(prev);\n    }\n\n    /**\n     * Parse color from given name. The name can be one of the following format:\n     * [#AARRGGBB] or [AARRGGBB], [gray color], [c,m,y,k], [c;m;y;k], [r,g,b], [r;g;b]\n     * or a predefined color name.  Return black if not found.\n     */\n    static color getColor(string name);\n\n    /**\n     * Define a color with given name\n     */\n    static void defineColor(const string& name, color c);\n\n    __decl_clone(ColorAtom)\n};\n\n/**\n * An atom representing a roman atom\n */\nclass RomanAtom : public Atom {\npublic:\n    sptr<Atom> _base;\n\n    RomanAtom() = delete;\n\n    RomanAtom(const sptr<Atom>& base) : _base(base) {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(RomanAtom)\n};\n\n/**\n * An atom representing another atom that should be drawn invisibly\n */\nclass PhantomAtom : public Atom, public Row {\nprivate:\n    sptr<RowAtom> _elements;\n    // if show with width, height or depth\n    bool _w, _h, _d;\n\npublic:\n    PhantomAtom() = delete;\n\n    PhantomAtom(const sptr<Atom>& el);\n\n    PhantomAtom(const sptr<Atom>& el, bool w, bool h, bool d);\n\n    int getLeftType() const override {\n        return _elements->getLeftType();\n    }\n\n    int getRightType() const override {\n        return _elements->getRightType();\n    }\n\n    void setPreviousAtom(const sptr<Dummy>& prev) override {\n        _elements->setPreviousAtom(prev);\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(PhantomAtom)\n};\n\n/**\n * An atom representing another atom with an override left-type and right-type\n * this affects the glue inserted before and after this atom.\n */\nclass TypedAtom : public Atom {\nprivate:\n    // override left-type and right-type\n    int _leftType, _rightType;\n    // atom for which new types are set\n    sptr<Atom> _atom;\n\npublic:\n    TypedAtom() = delete;\n\n    TypedAtom(int lt, int rt, const sptr<Atom>& atom) {\n        _leftType = lt;\n        _rightType = rt;\n        _atom = atom;\n        _typelimits = atom->_typelimits;\n    }\n\n    sptr<Atom> getBase() {\n        _atom->_typelimits = _typelimits;\n        return _atom;\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        return _atom->createBox(env);\n    }\n\n    int getLeftType() const override {\n        return _leftType;\n    }\n\n    int getRightType() const override {\n        return _rightType;\n    }\n\n    __decl_clone(TypedAtom)\n};\n\n/**\n * An atom representing another atom with an accent symbol above it\n */\nclass AccentedAtom : public Atom {\npublic:\n    // accent symbol\n    sptr<SymbolAtom> _accent;\n    bool _acc;\n    bool _changeSize;\n\n    // base atom\n    sptr<Atom> _base, _underbase;\n\n    void init(const sptr<Atom>& base, const sptr<Atom>& acc) throw(ex_invalid_symbol_type);\n\npublic:\n    AccentedAtom() = delete;\n\n    AccentedAtom(const sptr<Atom>& base, const sptr<Atom>& accent) throw(ex_invalid_symbol_type) {\n        init(base, accent);\n    }\n\n    AccentedAtom(\n        const sptr<Atom>& base,\n        const sptr<Atom>& accent,\n        bool changeSize) throw(ex_invalid_symbol_type) {\n        init(base, accent);\n        _changeSize = changeSize;\n    }\n\n    /**\n     * Create an AccentedAtom from a base atom and an accent symbol defined by\n     * its name\n     *\n     * @param base\n     *      base atom\n     * @param name\n     *      name of the accent symbol to be put over the base atom\n     * @throw ex_invalid_symbol_type\n     *      if the symbol is not defined as An accent ('acc')\n     * @throw ex_symbol_not_found\n     *      if there's no symbol defined with the given name\n     */\n    AccentedAtom(\n        const sptr<Atom>& base,\n        const string& name) throw(ex_invalid_symbol_type, ex_symbol_not_found);\n\n    /**\n     * Creates an AccentedAtom from a base atom and an accent symbol defined as\n     * a TeXFormula. This is used for parsing MathML.\n     *\n     * @param base\n     *      base atom\n     * @param acc\n     *      TeXFormula representing an accent (SymbolAtom)\n     * @throw ex_invalid_formula\n     *      if the given TeXFormula does not represent a single\n     *      SymbolAtom (type \"TeXConstants.TYPE_ACCENT\")\n     * @throw ex_invalid_symbol_type\n     *      if the symbol is not defined as an accent ('acc')\n     */\n    AccentedAtom(\n        const sptr<Atom>& base,\n        const sptr<TeXFormula>& acc) throw(ex_invalid_formula, ex_invalid_symbol_type);\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(AccentedAtom)\n};\n\n/**\n * An atom representing another atom with an atom above it (if not null)\n * separated by a kern and in a smaller size depending on \"overScriptSize\"\n * and/or an atom under it (if not null) seperated by a kern and in a smaller\n * size depending on \"underScriptSize\"\n */\nclass UnderOverAtom : public Atom {\nprivate:\n    // base, under script & over script\n    sptr<Atom> _base, _under, _over;\n    // kerning between base and under and over script\n    float _underSpace, _overSpace;\n    // unit\n    int _underUnit, _overUnit;\n    // whether the under over should be drawn in a smaller size\n    bool _underSmall, _overSmall;\n\n    static sptr<Box> changeWidth(const sptr<Box>& b, float maxW);\n\n    inline void init() {\n        _underSpace = _overSpace = 0;\n        _underUnit = _overUnit = 0;\n        _underSmall = _overSmall = false;\n    }\n\npublic:\n    UnderOverAtom() = delete;\n\n    UnderOverAtom(\n        const sptr<Atom>& base,\n        const sptr<Atom>& script,\n        int unit, float space, bool small, bool over) throw(ex_invalid_unit) {\n        init();\n        // check if unit is valid\n        SpaceAtom::checkUnit(unit);\n        _base = base;\n        if (over) {\n            _under = nullptr;\n            _underSpace = 0.f;\n            _underUnit = 0;\n            _underSmall = false;\n            _over = script;\n            _overUnit = unit;\n            _overSpace = space;\n            _overSmall = small;\n        } else {\n            _under = script;\n            _underUnit = unit;\n            _underSpace = space;\n            _underSmall = small;\n            _overSpace = 0.f;\n            _over = nullptr;\n            _overUnit = 0;\n            _overSmall = false;\n        }\n    }\n\n    UnderOverAtom(\n        const sptr<Atom>& base,\n        const sptr<Atom>& under,\n        int underunit, float underspace, bool undersmall,\n        const sptr<Atom>& over,\n        int overunit, float overspace, bool oversmall) throw(ex_invalid_unit) {\n        // check unit\n        SpaceAtom::checkUnit(underunit);\n        SpaceAtom::checkUnit(overunit);\n\n        _base = base;\n        _under = under;\n        _underUnit = underunit;\n        _underSpace = underspace;\n        _underSmall = undersmall;\n        _over = over;\n        _overUnit = overunit;\n        _overSpace = overspace;\n        _overSmall = oversmall;\n    }\n\n    int getLeftType() const override {\n        return _base->getLeftType();\n    }\n\n    int getRightType() const override {\n        return _base->getRightType();\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(UnderOverAtom)\n};\n\n/**\n * An atom representing scripts to be attached to another atom\n */\nclass ScriptsAtom : public Atom {\nprivate:\n    static SpaceAtom SCRIPT_SPACE;\n\npublic:\n    // base atom\n    sptr<Atom> _base;\n    // subscript and superscript to be attached to the base\n    sptr<Atom> _sub;\n    sptr<Atom> _sup;\n    // scripts alignment\n    int _align;\n\n    ScriptsAtom() = delete;\n\n    ScriptsAtom(const sptr<Atom>& base, const sptr<Atom>& sub, const sptr<Atom>& sup) {\n        _base = base;\n        _sub = sub;\n        _sup = sup;\n        _align = ALIGN_LEFT;\n    }\n\n    ScriptsAtom(const sptr<Atom>& base, const sptr<Atom>& sub, const sptr<Atom>& sup, bool left) {\n        _base = base;\n        _sub = sub;\n        _sup = sup;\n        _align = ALIGN_LEFT;\n        if (!left) _align = ALIGN_RIGHT;\n    }\n\n    int getLeftType() const override {\n        if (_base == nullptr) return _type;\n        return _base->getLeftType();\n    }\n\n    int getRightType() const override {\n        if (_base == nullptr) return _type;\n        return _base->getRightType();\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(ScriptsAtom)\n};\n\n/**\n * An atom representing a \"big operator\" (or an atom that acts as one) together\n * with its limits\n */\nclass BigOperatorAtom : public Atom {\nprivate:\n    // limits\n    sptr<Atom> _under, _over;\n    // atom representing a big operator\n    sptr<Atom> _base;\n    // whether the \"limits\"-value should be taken into account\n    // (otherwise the default rules will be applied)\n    bool _limitsSet;\n    // whether limits should be drawn over and under the base (<-> as scripts)\n    bool _limits;\n\n    void init(const sptr<Atom>& base, const sptr<Atom>& under, const sptr<Atom>& over);\n\n    sptr<Box> createSideSets(_out_ TeXEnvironment& env);\n\n    /**\n     * Center the given box in a new box that has the given width\n     */\n    static sptr<Box> changeWidth(const sptr<Box>& b, float maxW);\n\npublic:\n    BigOperatorAtom() = delete;\n\n    /**\n     * Create a new BigOperatorAtom from the given atoms. The default rules the\n     * positioning of the limits will be applied.\n     *\n     * @param base\n     *      atom representing the big operator\n     * @param under\n     *      atom representing the under limit\n     * @param over\n     *      atom representing the over limit\n     */\n    BigOperatorAtom(const sptr<Atom>& base, const sptr<Atom>& under, const sptr<Atom>& over) {\n        init(base, under, over);\n    }\n\n    /**\n     * Create a new BigOperatorAtom from the given atoms. Limits will be drawn\n     * according to the \"limits\"-value\n     *\n     * @param base\n     *      atom representing the big operator\n     * @param under\n     *      atom representing the under limit\n     * @param over\n     *      atom representing the over limit\n     * @param limits\n     *      whether limits should be drawn over and under the base (<-> as\n     *      scripts)\n     */\n    BigOperatorAtom(\n        const sptr<Atom>& base, const sptr<Atom>& under, const sptr<Atom>& over, bool limits) {\n        init(base, under, over);\n        _limits = limits;\n        _limitsSet = true;\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(BigOperatorAtom)\n};\n\n/**\n * An atom represeting scripts around a base atom\n */\nclass SideSetsAtom : public Atom {\npublic:\n    sptr<Atom> _left, _right, _base;\n\n    SideSetsAtom() = delete;\n\n    SideSetsAtom(const sptr<Atom>& base, const sptr<Atom>& left, const sptr<Atom>& right)\n        : _base(base), _left(left), _right(right) {\n        _type = TYPE_BIG_OPERATOR;\n        _typelimits = SCRIPT_NOLIMITS;\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(SideSetsAtom)\n};\n\n/**\n * An atom representing another atom with a delimiter and a script above or\n * under it, with script and delimiter separated by a kerning\n */\nclass OverUnderDelimiter : public Atom {\nprivate:\n    // base and script atom\n    sptr<Atom> _base, _script;\n    // delimiter symbol\n    sptr<SymbolAtom> _symbol;\n    // kerning between delimiter and script\n    SpaceAtom _kern;\n    // whether the delimiter should be positioned above or under the base\n    bool _over;\n\n    static float getMaxWidth(const Box* b, const Box* del, const Box* script);\n\npublic:\n    OverUnderDelimiter() = delete;\n\n    OverUnderDelimiter(\n        const sptr<Atom>& base,\n        const sptr<Atom>& script,\n        const sptr<SymbolAtom>& s,\n        int kernunit, float kern, bool over) throw(ex_invalid_unit) {\n        _type = TYPE_INNER;\n        _base = base;\n        _script = script;\n        _symbol = s;\n        _kern = SpaceAtom(kernunit, 0, kern, 0);\n        _over = over;\n    }\n\n    inline void addScript(const sptr<Atom>& script) {\n        _script = script;\n    }\n\n    inline bool isOver() {\n        return _over;\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(OverUnderDelimiter)\n};\n\n}  // namespace tex\n\n#endif  // ATOM_BASIC_H_INCLUDED\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/atom/atom_impl.cpp",
    "content": "#include \"atom/atom_impl.h\"\n\nusing namespace std;\nusing namespace tex;\n\n/*************************************** matrix atom **********************************************/\n\ncolor MatrixAtom::LINE_COLOR = trans;\n\nmap<wstring, wstring> MatrixAtom::_colspeReplacement;\n\nSpaceAtom MatrixAtom::_hsep(UNIT_EM, 1.f, 0.f, 0.f);\nSpaceAtom MatrixAtom::_semihsep(UNIT_EM, 0.5f, 0.f, 0.f);\nSpaceAtom MatrixAtom::_vsep_in(UNIT_EX, 0.f, 1.f, 0.f);\nSpaceAtom MatrixAtom::_vsep_ext_top(UNIT_EX, 0.f, 0.5f, 0.f);\nSpaceAtom MatrixAtom::_vsep_ext_bot(UNIT_EX, 0.f, 0.5f, 0.f);\nSpaceAtom MatrixAtom::_align(MEDMUSKIP);\n\nsptr<Box> MatrixAtom::_nullbox(new StrutBox(0, 0, 0, 0));\n\nvoid MatrixAtom::defineColumnSpecifier(const wstring& rep, const wstring& spe) {\n    _colspeReplacement[rep] = spe;\n}\n\nvoid MatrixAtom::parsePositions(wstring opt, _out_ vector<int>& lpos) {\n    int len = opt.length();\n    int pos = 0;\n    wchar_t ch;\n    sptr<TeXFormula> tf;\n    sptr<TeXParser> tp;\n    // clear first\n    lpos.clear();\n    while (pos < len) {\n        ch = opt[pos];\n        switch (ch) {\n        case 'l':\n            lpos.push_back(ALIGN_LEFT);\n            break;\n        case 'r':\n            lpos.push_back(ALIGN_RIGHT);\n            break;\n        case 'c':\n            lpos.push_back(ALIGN_CENTER);\n            break;\n        case '|': {\n            int nb = 1;\n            while (++pos < len) {\n                ch = opt[pos];\n                if (ch != '|') {\n                    pos--;\n                    break;\n                } else {\n                    nb++;\n                }\n            }\n            _vlines[lpos.size()] = sptr<VlineAtom>(new VlineAtom(nb));\n        } break;\n        case '@': {\n            pos++;\n            tf = sptr<TeXFormula>(new TeXFormula());\n            tp = sptr<TeXParser>(new TeXParser(_ispartial, opt.substr(pos), &(*tf), false));\n            auto atom = tp->getArgument();\n            // Keep columns same with the matrix\n            if (lpos.size() > _matrix->cols()) lpos.resize(_matrix->cols());\n            _matrix->insertAtomIntoCol(lpos.size(), atom);\n\n            lpos.push_back(ALIGN_NONE);\n            pos += tp->getPos();\n            pos--;\n        } break;\n        case '*': {\n            pos++;\n            tf = sptr<TeXFormula>(new TeXFormula());\n            tp = sptr<TeXParser>(new TeXParser(_ispartial, opt.substr(pos), &(*tf), false));\n            vector<wstring> args;\n            tp->getOptsArgs(2, 0, args);\n            pos += tp->getPos();\n            int nrep = 0;\n            valueof(args[1], nrep);\n            wstring str = L\"\";\n            for (int j = 0; j < nrep; j++) str += args[2];\n            opt.insert(pos, str);\n            len = opt.length();\n            pos--;\n        } break;\n        case '>': {\n            pos++;\n            tf = sptr<TeXFormula>(new ArrayOfAtoms());\n            tp = sptr<TeXParser>(new TeXParser(_ispartial, opt.substr(pos), &(*tf), false));\n            sptr<Atom> cs = tp->getArgument();\n            _columnSpecifiers[lpos.size()] = cs;\n            pos += tp->getPos();\n            pos--;\n        } break;\n        case ' ':\n        case '\\t':\n            break;\n        default: {\n            int spos = len + 1;\n            bool hasrep = false;\n            while (--spos > pos) {\n                auto it = _colspeReplacement.find(opt.substr(pos, spos - pos));\n                if (it != _colspeReplacement.end()) {\n                    hasrep = true;\n                    opt.insert(spos, it->second);\n                    len = opt.length();\n                    pos = spos - 1;\n                    break;\n                }\n            }\n            if (!hasrep) lpos.push_back(ALIGN_CENTER);\n        } break;\n        }\n        pos++;\n    }\n\n    for (size_t j = lpos.size(); j < _matrix->cols(); j++) lpos.push_back(ALIGN_CENTER);\n\n    if (lpos.size() == 0) lpos.push_back(ALIGN_CENTER);\n}\n\nfloat* MatrixAtom::getColumnSep(_out_ TeXEnvironment& env, float width) {\n    const int cols = _matrix->cols();\n    float* arr = new float[cols + 1]();\n    sptr<Box> Align, AlignSep, Hsep;\n    float h, w = env.getTextWidth();\n    int i = 0;\n\n    if (_ttype == ALIGNED || _ttype == ALIGNEDAT) w = POS_INF;\n\n    switch (_ttype) {\n    case ARRAY: {\n        // Array: (hsep_col/2 or 0) elem hsep_col elem hsep_col ... hsep_col elem (hsep_col/2 or 0)\n        Hsep = _hsep.createBox(env);\n        for (int i = 0; i < cols; i++) {\n            if (_position[i] == ALIGN_NONE) {\n                arr[i] = arr[i + 1] = 0;\n                i++;\n            } else {\n                arr[i] = Hsep->_width;\n            }\n        }\n        if (_spaceAround) {\n            const auto half = Hsep->_width / 2;\n            if (_position.front() != ALIGN_NONE) arr[0] = half;\n            if (_position.back() != ALIGN_NONE) arr[cols] = half;\n        }\n        return arr;\n    }\n    case MATRIX:\n    case SMALLMATRIX: {\n        // Simple matrix: 0 elem hsep_col elem hsep_col ... hsep_col elem 0\n        arr[0] = 0;\n        arr[cols] = arr[0];\n        Hsep = _hsep.createBox(env);\n        for (i = 1; i < cols; i++) arr[i] = Hsep->_width;\n        return arr;\n    }\n    case ALIGNED:\n    case ALIGN: {\n        // Align env: hsep = (textwidth - matwidth) / (2n + 1)\n        // Spaces: hsep eq_left \\medskip eq_right hsep ... hsep elem hsep\n        Align = _align.createBox(env);\n        if (w != POS_INF) {\n            h = max((w - width - cols / 2 * Align->_width) / floor((cols + 3) / 2.f), 0.f);\n            AlignSep = sptr<Box>(new StrutBox(h, 0, 0, 0));\n        } else {\n            AlignSep = _hsep.createBox(env);\n        }\n\n        arr[cols] = AlignSep->_width;\n        for (int i = 0; i < cols; i++) {\n            if (i % 2 == 0)\n                arr[i] = AlignSep->_width;\n            else\n                arr[i] = Align->_width;\n        }\n    } break;\n    case ALIGNEDAT:\n    case ALIGNAT: {\n        // Aignat env: hsep = (textwidth - matwdith) / 2\n        // Spaces: hsep elem ... elem hsep\n        if (w != POS_INF)\n            h = max((w - width) / 2, 0.f);\n        else\n            h = 0;\n        Align = _align.createBox(env);\n        arr[0] = h;\n        arr[cols] = arr[0];\n        for (int i = 1; i < cols; i++) {\n            if (i % 2 == 0)\n                arr[i] = 0;\n            else\n                arr[i] = Align->_width;\n        }\n    } break;\n    case FLALIGN: {\n        // flalgin env : hsep = (textwidth - matwidth) / (2n + 1)\n        // Spaces: hsep eq_left \\medskip el_right hsep ... hsep elem hsep\n        Align = _align.createBox(env);\n        if (w != POS_INF) {\n            h = max((w - width - (cols / 2) * Align->_width) / floor((cols - 1) / 2.f), 0.f);\n            AlignSep = sptr<Box>(new StrutBox(h, 0, 0, 0));\n        } else {\n            AlignSep = _hsep.createBox(env);\n        }\n\n        arr[0] = 0;\n        arr[cols] = arr[0];\n        for (int i = 1; i < cols; i++) {\n            if (i % 2 == 0)\n                arr[i] = AlignSep->_width;\n            else\n                arr[i] = Align->_width;\n        }\n    } break;\n    }\n\n    if (w == POS_INF) {\n        arr[0] = 0;\n        arr[cols] = arr[0];\n    }\n\n    return arr;\n}\n\nvoid MatrixAtom::recalculateLine(\n    const int rows,\n    sptr<Box>** boxarr,\n    vector<sptr<Atom>>& multiRows,\n    float* height, float* depth, float drt, float vspace) {\n    const size_t s = multiRows.size();\n    for (size_t i = 0; i < s; i++) {\n        MultiRowAtom* m = (MultiRowAtom*)multiRows[i].get();\n        const int r = m->_i;\n        const int c = m->_j;\n        int n = m->_n;\n        int skipped = 0;\n        float h = 0;\n        if (n < 0) {\n            // Across from bottom to top\n            int j = r;\n            for (; j >= 0 && j > r + n; j--) {\n                if (boxarr[j][0]->_type == TYPE_HLINE) {\n                    if (j == 0) break;\n                    h += drt;\n                    n--;\n                } else {\n                    skipped++;\n                    h += height[j] + depth[j] + vspace;\n                }\n            }\n            m->_i = ++j;\n            auto tmp = boxarr[r][c];\n            boxarr[r][c] = boxarr[j][c];\n            boxarr[j][c] = tmp;\n        } else {\n            // Across from top to bottom\n            for (int j = r; j < r + n && j < rows; j++) {\n                if (boxarr[j][0]->_type == TYPE_HLINE) {\n                    if (j == rows - 1) break;\n                    h += drt;\n                    n++;\n                } else {\n                    skipped++;\n                    h += height[j] + depth[j] + vspace;\n                }\n            }\n        }\n        m->_n = abs(n);\n        auto b = boxarr[m->_i][m->_j];\n        const float bh = b->_height + b->_depth + vspace;\n        if (h > bh) {\n            b->_height = (h - bh + vspace) / 2.f;\n        } else if (h < bh) {\n            const float ex = (bh - h) / skipped / 2.f;\n            const int mr = m->_i + m->_n;\n            for (int j = m->_i; j < mr; j++) {\n                if (boxarr[j][0]->_type != TYPE_HLINE) {\n                    height[j] += ex;\n                    depth[j] += ex;\n                }\n            }\n            b->_height = height[m->_i];\n            b->_depth = bh - b->_height - vspace;\n        }\n        boxarr[m->_i][m->_j]->_type = -1;\n    }\n}\n\nsptr<Box> MatrixAtom::generateMulticolumn(\n    _out_ TeXEnvironment& env,\n    const sptr<Box>& b,\n    const float* hsep, const float* colWidth, int i, int j) {\n    float w = 0;\n    MulticolumnAtom* mca = (MulticolumnAtom*)(_matrix->_array[i][j].get());\n    int k, n = mca->getSkipped();\n    for (k = j; k < j + n - 1; k++) {\n        w += colWidth[k] + hsep[k + 1];\n        auto it = _vlines.find(k + 1);\n        if (it != _vlines.end()) w += it->second->getWidth(env);\n    }\n    w += colWidth[k];\n\n    if (mca->isNeedWidth() && mca->getColumnWidth() <= PREC) {\n        mca->setColumnWidth(w);\n        return mca->createBox(env);\n    }\n\n    if (b->_width >= w) return b;\n\n    return sptr<Box>(new HorizontalBox(b, w, mca->getAlign()));\n}\n\nMatrixAtom::MatrixAtom(\n    bool ispar, const sptr<ArrayOfAtoms>& arr, const wstring& options, bool spaceAround) {\n    _matrix = arr;\n    _ttype = ARRAY;\n    _ispartial = ispar;\n    _spaceAround = spaceAround;\n    parsePositions(wstring(options), _position);\n}\n\nMatrixAtom::MatrixAtom(bool ispar, const sptr<ArrayOfAtoms>& arr, const wstring& options) {\n    _matrix = arr;\n    _ttype = ARRAY;\n    _ispartial = ispar;\n    _spaceAround = false;\n    parsePositions(wstring(options), _position);\n}\n\nMatrixAtom::MatrixAtom(bool ispar, const sptr<ArrayOfAtoms>& arr, int type) {\n    _matrix = arr;\n    _ttype = type;\n    _ispartial = ispar;\n    _spaceAround = false;\n\n    const int cols = arr->cols();\n    if (type != MATRIX && type != SMALLMATRIX) {\n        _position.resize(cols);\n        for (size_t i = 0; i < cols; i += 2) {\n            _position[i] = ALIGN_RIGHT;\n            if (i + 1 < cols) _position[i + 1] = ALIGN_LEFT;\n        }\n    } else {\n        _position.resize(cols);\n        for (size_t i = 0; i < cols; i++) _position[i] = ALIGN_CENTER;\n    }\n}\n\nMatrixAtom::MatrixAtom(bool ispar, const sptr<ArrayOfAtoms>& arr, int type, int align) {\n    _ispartial = ispar;\n    _matrix = arr;\n    _ttype = type;\n    _spaceAround = true;\n\n    _position.resize(arr->cols());\n    for (size_t i = 0; i < arr->cols(); i++) _position[i] = align;\n}\n\nsptr<Box> MatrixAtom::createBox(_out_ TeXEnvironment& e) {\n    TeXEnvironment& env = e;\n    const int rows = _matrix->rows();\n    const int cols = _matrix->cols();\n\n    float* lineDepth = new float[rows]();\n    float* lineHeight = new float[rows]();\n    float* colWidth = new float[cols]();\n    sptr<Box>** boxarr = new sptr<Box>*[rows]();\n    for (int i = 0; i < rows; i++) boxarr[i] = new sptr<Box>[cols]();\n\n    float matW = 0;\n    float drt = env.getTeXFont()->getDefaultRuleThickness(env.getStyle());\n\n    if (_ttype == SMALLMATRIX) {\n        auto env_ptr = e.copy();  // 持有智能指针，确保对象存活\n        env = *env_ptr;  // 此时拷贝对象由 env_ptr 管理，不会提前释放\n        env.setStyle(STYLE_SCRIPT);\n    } /* else if (_ttype == MATRIX) {\n        env = *(e.copy());\n        env.setStyle(STYLE_TEXT);\n    }*/\n\n    // multi-column & multi-row atoms\n    vector<sptr<Atom>> listMultiCol;\n    vector<sptr<Atom>> listMultiRow;\n    for (int i = 0; i < rows; i++) {\n        lineDepth[i] = 0;\n        lineHeight[i] = 0;\n        const int size = _matrix->_array[i].size();\n        for (int j = 0; j < cols; j++) {\n            if (j >= size) {\n                // If current row is not full-filled, fill the row with _nullbox\n                for (int k = j; k < cols; k++) boxarr[i][k] = _nullbox;\n                break;\n            }\n\n            sptr<Atom> atom = _matrix->_array[i][j];\n            boxarr[i][j] = (atom == nullptr) ? _nullbox : atom->createBox(env);\n            if (atom != nullptr && atom->_type == TYPE_INTERTEXT)\n                boxarr[i][j]->_type = TYPE_INTERTEXT;\n\n            if (boxarr[i][j]->_type != TYPE_MULTIROW) {\n                // Find the highest line (row)\n                lineDepth[i] = max(boxarr[i][j]->_depth, lineDepth[i]);\n                lineHeight[i] = max(boxarr[i][j]->_height, lineHeight[i]);\n            } else {\n                MultiRowAtom* mra = (MultiRowAtom*)atom.get();\n                mra->setRowColumn(i, j);\n                listMultiRow.push_back(atom);\n            }\n\n            if (boxarr[i][j]->_type != TYPE_MULTICOLUMN) {\n                // Find the widest column\n                colWidth[j] = max(boxarr[i][j]->_width, colWidth[j]);\n            } else {\n                MulticolumnAtom* mca = (MulticolumnAtom*)atom.get();\n                mca->setRowColumn(i, j);\n                listMultiCol.push_back(atom);\n            }\n        }\n    }\n\n    for (int j = 0; j < cols; j++) matW += colWidth[j];\n\n    // The horizontal separator's width\n    float* Hsep = getColumnSep(env, matW);\n\n    for (size_t i = 0; i < listMultiCol.size(); i++) {\n        MulticolumnAtom* multi = (MulticolumnAtom*)listMultiCol[i].get();\n        int c = multi->getCol();\n        int r = multi->getRow();\n        int n = multi->getSkipped();\n        float w = 0;\n        int j = 0;\n        for (j = c; j < c + n - 1; j++) w += colWidth[j] + Hsep[j + 1];\n        w += colWidth[j];\n        if (boxarr[r][c]->_width > w) {\n            // If the multi-column's width > the total width of the acrossed columns,\n            // add an extra-space to each column\n            matW += boxarr[r][c]->_width - w;\n            const float extraW = (boxarr[r][c]->_width - w) / n;\n            for (int j = c; j < c + n; j++) colWidth[j] += extraW;\n        }\n    }\n\n    // Add seprator's space to the matrix width\n    for (int j = 0; j < cols + 1; j++) {\n        matW += Hsep[j];\n        auto it = _vlines.find(j);\n        if (it != _vlines.end()) matW += it->second->getWidth(env);\n    }\n\n    auto Vsep = _vsep_in.createBox(env);\n    // Recalculate the height of the row\n    recalculateLine(rows, boxarr, listMultiRow, lineHeight, lineDepth, drt, Vsep->_height);\n\n    VerticalBox* vb = new VerticalBox();\n    float totalHeight = 0;\n    float Vspace = Vsep->_height / 2;\n\n    for (int i = 0; i < rows; i++) {\n        sptr<HorizontalBox> hb(new HorizontalBox());\n        for (int j = 0; j < cols; j++) {\n            switch (boxarr[i][j]->_type) {\n            case -1:\n            case TYPE_MULTICOLUMN: {\n                if (j == 0) {\n                    auto it = _vlines.find(0);\n                    if (it != _vlines.end()) {\n                        auto vat = it->second;\n                        vat->_height = lineHeight[i] + lineDepth[i] + Vsep->_height;\n                        vat->_shift = lineDepth[i] + Vspace;\n                        auto vatBox = vat->createBox(env);\n                        hb->add(vatBox);\n                    }\n                }\n\n                bool isLastVline = true;\n\n                WrapperBox* wb = nullptr;\n                int tj = j;\n                float l = j == 0 ? Hsep[j] : Hsep[j] / 2;\n                if (boxarr[i][j]->_type == -1) {\n                    wb = new WrapperBox(\n                        boxarr[i][j], colWidth[j], lineHeight[i], lineDepth[i], _position[j]);\n                } else {\n                    auto b = generateMulticolumn(env, boxarr[i][j], Hsep, colWidth, i, j);\n                    MulticolumnAtom* matom = (MulticolumnAtom*)_matrix->_array[i][j].get();\n                    j += matom->getSkipped() - 1;\n                    wb = new WrapperBox(b, b->_width, lineHeight[i], lineDepth[i], ALIGN_LEFT);\n                    isLastVline = matom->hasRightVline();\n                }\n                float r = j == cols - 1 ? Hsep[j + 1] : Hsep[j + 1] / 2;\n                wb->setInsets(l, Vspace, r, Vspace);\n                sptr<Box> swb(wb);\n                boxarr[i][tj] = swb;\n                hb->add(swb);\n\n                auto it = _vlines.find(j + 1);\n                if (isLastVline && it != _vlines.end()) {\n                    auto vat = it->second;\n                    vat->_height = lineHeight[i] + lineDepth[i] + Vsep->_height;\n                    vat->_shift = lineDepth[i] + Vspace;\n                    auto vatBox = vat->createBox(env);\n                    hb->add(vatBox);\n                }\n            } break;\n            case TYPE_INTERTEXT: {\n                float f = env.getTextWidth();\n                f = f == POS_INF ? colWidth[j] : f;\n                hb = sptr<HorizontalBox>(new HorizontalBox(boxarr[i][j], f, ALIGN_LEFT));\n                j = cols;\n            } break;\n            case TYPE_HLINE: {\n                HlineAtom* at = (HlineAtom*)_matrix->_array[i][j].get();\n                at->setColor(LINE_COLOR);\n                at->setWidth(matW);\n                if (i >= 1 &&\n                    dynamic_cast<HlineAtom*>(_matrix->_array[i - 1][j].get()) != nullptr) {\n                    hb->add(sptr<Box>(new StrutBox(0, 2 * drt, 0, 0)));\n                }\n\n                hb->add(at->createBox(env));\n                j = cols;\n            } break;\n            }\n        }\n\n        if (boxarr[i][0]->_type != TYPE_HLINE) {\n            hb->_height = lineHeight[i] + Vspace;\n            hb->_depth = lineDepth[i] + Vspace;\n        }\n        vb->add(hb);\n    }\n\n    // column specifiers\n    for (int i = 0; i < cols; i++) {\n        auto it = _columnSpecifiers.find(i);\n        if (it == _columnSpecifiers.end()) continue;\n        auto spe = it->second;\n        RowAtom* p = nullptr;\n        RowAtom* r = dynamic_cast<RowAtom*>(spe.get());\n        while (r != nullptr) {\n            spe = r->getFirstAtom();\n            p = r;\n            r = dynamic_cast<RowAtom*>(spe.get());\n        }\n        for (size_t j = 0; j < p->size(); j++) {\n            CellSpecifier* s = dynamic_cast<CellSpecifier*>(p->get(j).get());\n            if (s != nullptr) {\n                for (int k = 0; k < rows; k++) s->apply(boxarr[k][i]);\n            }\n        }\n    }\n\n    // row specifiers\n    for (int i = 0; i < rows; i++) {\n        auto it = _matrix->_rowSpecifiers.find(i);\n        if (it == _matrix->_rowSpecifiers.end()) continue;\n        for (auto s : it->second) {\n            for (int j = 0; j < cols; j++) s->apply(boxarr[i][j]);\n        }\n    }\n\n    // cell specifiers\n    for (int i = 0; i < rows; i++) {\n        if (boxarr[i][0]->_type == TYPE_HLINE) continue;\n        for (int j = 0; j < cols; j++) {\n            string str = tostring(i) + tostring(j);\n            auto it = _matrix->_cellSpecifiers.find(str);\n            if (it != _matrix->_cellSpecifiers.end()) {\n                for (auto s : it->second) s->apply(boxarr[i][j]);\n            }\n        }\n    }\n\n    totalHeight = vb->_height + vb->_depth;\n\n    float axis = env.getTeXFont()->getAxisHeight(env.getStyle());\n    vb->_height = totalHeight / 2 + axis;\n    vb->_depth = totalHeight / 2 - axis;\n\n    delete[] Hsep;\n    delete[] lineDepth;\n    delete[] lineHeight;\n    delete[] colWidth;\n    for (int i = 0; i < rows; i++) delete[] boxarr[i];\n    delete[] boxarr;\n\n    return sptr<Box>(vb);\n}\n\n/**************************************** small atoms *********************************************/\n\nSpaceAtom MultlineAtom::_vsep_in(UNIT_EX, 0.f, 1.f, 0.f);\n\nsptr<Box> MultlineAtom::createBox(_out_ TeXEnvironment& env) {\n    float tw = env.getTextWidth();\n    if (tw == POS_INF || _ttype == GATHERED)\n        return MatrixAtom(_ispartial, _column, L\"\").createBox(env);\n\n    VerticalBox* vb = new VerticalBox();\n    auto atom = _column->_array[0][0];\n    int alignment = _ttype == GATHER ? ALIGN_CENTER : ALIGN_LEFT;\n    if (atom->_alignment != -1) alignment = atom->_alignment;\n\n    vb->add(sptr<Box>(new HorizontalBox(atom->createBox(env), tw, alignment)));\n    auto Vsep = _vsep_in.createBox(env);\n    for (size_t i = 1; i < _column->rows() - 1; i++) {\n        atom = _column->_array[i][0];\n        alignment = ALIGN_CENTER;\n        if (atom->_alignment != -1) alignment = atom->_alignment;\n        vb->add(Vsep);\n        vb->add(sptr<Box>(new HorizontalBox(atom->createBox(env), tw, alignment)));\n    }\n\n    if (_column->rows() > 1) {\n        atom = _column->_array[_column->rows() - 1][0];\n        alignment = _ttype == GATHER ? ALIGN_CENTER : ALIGN_RIGHT;\n        if (atom->_alignment != -1) alignment = atom->_alignment;\n        vb->add(Vsep);\n        vb->add(sptr<Box>(new HorizontalBox(atom->createBox(env), tw, alignment)));\n    }\n\n    float h = vb->_height + vb->_depth;\n    vb->_height = h / 2;\n    vb->_depth = h / 2;\n\n    return sptr<Box>(vb);\n}\n\nconst float FBoxAtom::INTERSPACE = 0.65f;\nfloat OvalAtom::_multiplier = 0.5f;\nfloat OvalAtom::_diameter = 0.f;\n\nconst int FencedAtom::DELIMITER_FACTOR = 901;\nconst float FencedAtom::DELIMITER_SHORTFALL = 5.f;\n\nvoid FencedAtom::init(const sptr<Atom>& b, const sptr<SymbolAtom>& l, const sptr<SymbolAtom>& r) {\n    if (b == nullptr)\n        _base = sptr<Atom>(new RowAtom());\n    else\n        _base = b;\n    if (l == nullptr || l->getName() != \"normaldot\") _left = l;\n    if (r == nullptr || r->getName() != \"normaldot\") _right = r;\n}\n\nvoid FencedAtom::center(_out_ Box& b, float axis) {\n    float h = b._height, total = h + b._depth;\n    b._shift = -(total / 2 - h) - axis;\n}\n\nsptr<Box> FencedAtom::createBox(_out_ TeXEnvironment& env) {\n    TeXFont& tf = *(env.getTeXFont());\n    // can not break\n    RowAtom* ra = dynamic_cast<RowAtom*>(_base.get());\n    if (ra != nullptr) ra->setCanBreak(false);\n    if(_base == nullptr) throw ex_parse(\"empty atom\");\n    auto content = _base->createBox(env);\n    float shortfall = DELIMITER_SHORTFALL * SpaceAtom::getFactor(UNIT_POINT, env);\n    float axis = tf.getAxisHeight(env.getStyle());\n    float delta = max(content->_height - axis, content->_depth + axis);\n    float minh = max(delta / 500.f * DELIMITER_FACTOR, 2 * delta - shortfall);\n\n    HorizontalBox* hb = new HorizontalBox();\n\n    if (!_middle.empty()) {\n        for (auto atom : _middle) {\n            SymbolAtom* sym = dynamic_cast<SymbolAtom*>(atom->_base.get());\n            if (sym != nullptr) {\n                auto b = DelimiterFactory::create(sym->getName(), env, minh);\n                center(*b, axis);\n                atom->_box = b;\n            }\n        }\n        if (!_middle.empty()) content = _base->createBox(env);\n    }\n\n    // left delimiter\n    if (_left != nullptr) {\n        auto b = DelimiterFactory::create(_left->getName(), env, minh);\n        center(*b, axis);\n        hb->add(b);\n    }\n\n    // glue between left delimiter and content (if not whitespace)\n    SpaceAtom* sp = dynamic_cast<SpaceAtom*>(_base.get());\n    if (sp == nullptr) hb->add(Glue::get(TYPE_OPENING, _base->getLeftType(), env));\n\n    // add content\n    hb->add(content);\n\n    // glue between right delimiter and content (if not whitespace)\n    if (sp == nullptr) hb->add(Glue::get(_base->getRightType(), TYPE_CLOSING, env));\n\n    // right delimiter\n    if (_right != nullptr) {\n        auto b = DelimiterFactory::create(_right->getName(), env, minh);\n        center(*b, axis);\n        hb->add(b);\n    }\n\n    return sptr<Box>(hb);\n}\n\n/****************************************** fraction atom *****************************************/\n\nvoid FractionAtom::init(\n    const sptr<Atom>& num, const sptr<Atom>& den,\n    bool nodef, int unit, float t) throw(ex_invalid_unit) {\n    _numAlign = ALIGN_CENTER;\n    _denomAlign = ALIGN_CENTER;\n    _deffactor = 1.f;\n\n    SpaceAtom::checkUnit(unit);\n\n    _numerator = num;\n    _denominator = den;\n    _nodefault = nodef;\n    _thickness = t;\n    _unit = unit;\n    _type = TYPE_ORDINARY;\n    _useKern = true;\n    _deffactorset = false;\n}\n\nsptr<Box> FractionAtom::createBox(_out_ TeXEnvironment& env) {\n    TeXFont& tf = *(env.getTeXFont());\n    int style = env.getStyle();\n    // set thickness to default if default value should be use\n    float drt = tf.getDefaultRuleThickness(style);\n    if (_nodefault)\n        _thickness *= SpaceAtom::getFactor(_unit, env);\n    else\n        _thickness = _deffactorset ? _deffactor * drt : drt;\n\n    // create equal width boxes in appropriate styles\n    auto num = (_numerator == nullptr ? sptr<Box>(new StrutBox(0, 0, 0, 0))\n                                      : _numerator->createBox(*(env.numStyle())));\n    auto denom = (_denominator == nullptr ? sptr<Box>(new StrutBox(0, 0, 0, 0))\n                                          : _denominator->createBox(*(env.dnomStyle())));\n\n    if (num->_width < denom->_width)\n        num = sptr<Box>(new HorizontalBox(num, denom->_width, _numAlign));\n    else\n        denom = sptr<Box>(new HorizontalBox(denom, num->_width, _denomAlign));\n\n    // calculate default shift amounts\n    float shiftup, shiftdown;\n    if (style < STYLE_TEXT) {\n        shiftup = tf.getNum1(style);\n        shiftdown = tf.getDenom1(style);\n    } else {\n        shiftdown = tf.getDenom2(style);\n        if (_thickness > 0)\n            shiftup = tf.getNum2(style);\n        else\n            shiftup = tf.getNum3(style);\n    }\n\n    // upper part of vertical box = numerator\n    VerticalBox* vb = new VerticalBox();\n    vb->add(num);\n\n    // calculate clearance clr, adjust shift amounts and create vertical box\n    float clr, delta, axis = tf.getAxisHeight(style);\n\n    if (_thickness > 0) {\n        // with fraction rule\n        // clearance clr\n        if (style < STYLE_TEXT)\n            clr = 3 * _thickness;\n        else\n            clr = _thickness;\n\n        // adjust shift amount\n        delta = _thickness / 2.f;\n        float kern1 = shiftup - num->_depth - (axis + delta);\n        float kern2 = axis - delta - (denom->_height - shiftdown);\n        float delta1 = clr - kern1;\n        float delta2 = clr - kern2;\n        if (delta1 > 0) {\n            shiftup += delta1;\n            kern1 += delta1;\n        }\n        if (delta2 > 0) {\n            shiftdown += delta2;\n            kern2 += delta2;\n        }\n\n        // fill vertical box\n        vb->add(sptr<Box>(new StrutBox(0, kern1, 0, 0)));\n        vb->add(sptr<Box>(new HorizontalRule(_thickness, num->_width, 0)));\n        vb->add(sptr<Box>(new StrutBox(0, kern2, 0, 0)));\n    } else {\n        // without fraction rule\n        // clearance clr\n        if (style < STYLE_TEXT)\n            clr = 7 * drt;\n        else\n            clr = 3 * drt;\n\n        // adjust shift amounts\n        float kern = shiftup - num->_depth - (denom->_height - shiftdown);\n        delta = (clr - kern) / 2;\n        if (delta > 0) {\n            shiftup += delta;\n            shiftdown += delta;\n            kern += 2 * delta;\n        }\n        // fill vertical box\n        vb->add(sptr<Box>(new StrutBox(0, kern, 0, 0)));\n    }\n\n    // finish vertical box\n    vb->add(denom);\n    vb->_height = shiftup + num->_height;\n    vb->_depth = shiftdown + denom->_depth;\n\n    if (!_useKern) return sptr<Box>(vb);\n\n    // \\nulldelimiterspace is set by default to 1.2pt = 0.12em\n    float f = SpaceAtom::getSize(UNIT_EM, 0.12f, env);\n\n    return sptr<Box>(new HorizontalBox(sptr<Box>(vb), vb->_width + 2 * f, ALIGN_CENTER));\n}\n\n/*************************************** multicolumn atoms ****************************************/\n\nint MulticolumnAtom::parseAlign(const string& str) {\n    int pos = 0;\n    int len = str.length();\n    int align = ALIGN_CENTER;\n    bool first = true;\n    while (pos < len) {\n        char c = str[pos];\n        switch (c) {\n        case 'l': {\n            align = ALIGN_LEFT;\n            first = false;\n        } break;\n        case 'r': {\n            align = ALIGN_RIGHT;\n            first = false;\n        } break;\n        case 'c': {\n            align = ALIGN_CENTER;\n            first = false;\n        } break;\n        case '|': {\n            if (first)\n                _beforeVlines = 1;\n            else\n                _afterVlines = 1;\n            while (++pos < len) {\n                c = str[pos];\n                if (c != '|') {\n                    pos--;\n                    break;\n                } else {\n                    if (first)\n                        _beforeVlines++;\n                    else\n                        _afterVlines++;\n                }\n            }\n        } break;\n        }\n        pos++;\n    }\n    return align;\n}\n\nsptr<Box> MulticolumnAtom::createBox(_out_ TeXEnvironment& env) {\n    sptr<Box> b;\n    if (_w == 0)\n        b = _cols->createBox(env);\n    else\n        b = sptr<Box>(new HorizontalBox(_cols->createBox(env), _w, _align));\n    b->_type = TYPE_MULTICOLUMN;\n    return b;\n}\n\nsptr<Box> HdotsforAtom::createBox(\n    float space, const sptr<Box>& b, _out_ TeXEnvironment& env) {\n    auto sb = sptr<Box>(new StrutBox(0, space, 0, 0));\n    auto vb = sptr<Box>(new VerticalBox());\n    vb->add(sb);\n    vb->add(b);\n    vb->add(sb);\n    vb->_type = TYPE_MULTICOLUMN;\n    return vb;\n}\n\nsptr<Box> HdotsforAtom::createBox(_out_ TeXEnvironment& env) {\n    auto dot = _cols->createBox(env);\n    float space = Glue::getSpace(THINMUSKIP, env) * _coeff * 2;\n\n    // If no width specified, create a box with one dot\n    if (_w == 0) return createBox(space, dot, env);\n\n    float x = (_w - dot->_width) / (space + dot->_width);\n    int count = (int)floor(x);\n\n    // Only one dot can be placed in\n    if (count == 0) {\n        auto b = sptr<Box>(new HorizontalBox(dot, _w, ALIGN_CENTER));\n        return createBox(space, b, env);\n    }\n\n    // Adjust the spce between\n    space += (x - count) * space / count;\n    auto sb = sptr<Box>(new StrutBox(space, 0, 0, 0));\n    auto b = sptr<Box>(new HorizontalBox());\n    for (int i = 0; i < count; i++) {\n        b->add(dot);\n        b->add(sb);\n    }\n    b->add(dot);\n\n    auto hb = sptr<Box>(new HorizontalBox(b, _w, ALIGN_CENTER));\n    return createBox(space, hb, env);\n}\n\nsptr<Box> LaTeXAtom::createBox(_out_ TeXEnvironment& en) {\n    TeXEnvironment& env = *(en.copy(en.getTeXFont()->copy()));\n    env.getTeXFont()->setRoman(true);\n    float sc = env.getTeXFont()->getScaleFactor();\n\n    FontInfos* fontInfos = nullptr;\n    auto it = TeXFormula::_externalFontMap.find(UnicodeBlock::BASIC_LATIN);\n    if (it != TeXFormula::_externalFontMap.end()) {\n        fontInfos = it->second;\n        TeXFormula::_externalFontMap[UnicodeBlock::BASIC_LATIN] = nullptr;\n    }\n    sptr<Atom> root = TeXFormula(L\"\\\\mathrm{XETL}\")._root;\n    sptr<Atom> atom = ((RomanAtom*)root.get())->_base;\n    RowAtom* rm = (RowAtom*)(atom.get());\n    if (fontInfos != nullptr)\n        TeXFormula::_externalFontMap[UnicodeBlock::BASIC_LATIN] = fontInfos;\n\n    // L\n    HorizontalBox* hb = new HorizontalBox(rm->popLastAtom()->createBox(env));\n    hb->add(SpaceAtom(UNIT_EM, -0.35f * sc, 0, 0).createBox(env));\n    float f = SpaceAtom(UNIT_EX, 0.45f * sc, 0, 0).createBox(env)->_width;\n    float f1 = SpaceAtom(UNIT_EX, 0.5f * sc, 0, 0).createBox(env)->_width;\n\n    // A\n    CharBox* A = new CharBox(\n        env.getTeXFont()->getChar('A', \"mathnormal\", env.supStyle()->getStyle()));\n    A->_shift = -f;\n    hb->add(sptr<Box>(A));\n    hb->add(SpaceAtom(UNIT_EM, -0.15f * sc, 0, 0).createBox(env));\n\n    // T\n    hb->add(rm->popLastAtom()->createBox(env));\n    hb->add(SpaceAtom(UNIT_EM, -0.15f * sc, 0, 0).createBox(env));\n\n    // E\n    auto E = rm->popLastAtom()->createBox(env);\n    E->_shift = f1;\n    hb->add(E);\n    hb->add(SpaceAtom(UNIT_EM, -0.15f * sc, 0, 0).createBox(env));\n\n    // X\n    hb->add(rm->popLastAtom()->createBox(env));\n    return sptr<Box>(hb);\n}\n\nconst string NthRoot::_sqrtSymbol = \"sqrt\";\nconst float NthRoot::FACTOR = 0.55f;\n\nsptr<Box> NthRoot::createBox(_out_ TeXEnvironment& env) {\n    // first create a simple square root construction\n    TeXFont& tf = *(env.getTeXFont());\n    int style = env.getStyle();\n    // calculate minimum clearance clr\n    float clr, drt = tf.getDefaultRuleThickness(style);\n    if (style < STYLE_TEXT)\n        clr = tf.getXHeight(style, tf.getChar(_sqrtSymbol, style).getFontCode());\n    else\n        clr = drt;\n    clr = drt + abs(clr) / 4.f;\n\n    // cramped style for the formula under the root sign\n    TeXEnvironment& cramped = *(env.crampStyle());\n    if(_base == nullptr) throw ex_parse(\"empty atom\");\n    auto bs = _base->createBox(cramped);\n    sptr<HorizontalBox> b(new HorizontalBox(bs));\n    b->add(sptr<Box>(SpaceAtom(UNIT_MU, 1, 0, 0).createBox(cramped)));\n    // create root sign\n    float totalH = b->_height + b->_depth;\n    auto rootSign = DelimiterFactory::create(_sqrtSymbol, env, totalH + clr + drt);\n\n    // add half the excess to clr\n    float delta = rootSign->_depth - (totalH + clr);\n    clr += delta / 2;\n\n    // create total box\n    rootSign->_shift = -(b->_height + clr);\n    sptr<OverBar> ob(new OverBar(b, clr, rootSign->_height));\n    ob->_shift = -(b->_height + clr + drt);\n    sptr<HorizontalBox> squareRoot(new HorizontalBox(rootSign));\n    squareRoot->add(ob);\n\n    // simple square-root\n    if (_root == nullptr) return squareRoot;\n\n    // nth root\n    auto r = _root->createBox(*(env.rootStyle()));\n    // shift root up\n    float bottomShift = FACTOR * (squareRoot->_height + squareRoot->_depth);\n    r->_shift = squareRoot->_depth - r->_depth - bottomShift;\n\n    // negative kerning\n    sptr<Box> negkern = SpaceAtom(UNIT_MU, -10.f, 0, 0).createBox(env);\n\n    // arrange both boxes together with the negative kerning\n    sptr<Box> res(new HorizontalBox());\n    float pos = r->_width + negkern->_width;\n    if (pos < 0) res->add(sptr<Box>(new StrutBox(-pos, 0, 0, 0)));\n\n    res->add(r);\n    res->add(negkern);\n    res->add(squareRoot);\n    return res;\n}\n\nRotateAtom::RotateAtom(const sptr<Atom>& base, float angle, const wstring& option)\n    : _angle(0), _option(-1), _xunit(0), _yunit(0), _x(0), _y(0) {\n    if(_base == nullptr) throw ex_parse(\"empty atom\");\n    _type = base->_type;\n    _base = base;\n    _angle = angle;\n    map<string, string> opt;\n    string x;\n    wide2utf8(option.c_str(), x);\n    parseMap(x, opt);\n    auto it = opt.find(\"origin\");\n    if (it != opt.end()) {\n        _option = RotateBox::getOrigin(it->second);\n        return;\n    }\n    it = opt.find(\"x\");\n    if (it != opt.end()) {\n        auto xinfo = SpaceAtom::getLength(it->second);\n        _xunit = (int)xinfo.first;\n        _x = xinfo.second;\n    } else {\n        _xunit = UNIT_POINT;\n        _x = 0;\n    }\n    it = opt.find(\"y\");\n    if (it != opt.end()) {\n        auto yinfo = SpaceAtom::getLength(it->second);\n        _yunit = (int)yinfo.first;\n        _y = yinfo.second;\n    } else {\n        _yunit = UNIT_POINT;\n        _y = 0;\n    }\n}\n\nRotateAtom::RotateAtom(const sptr<Atom>& base, const wstring& angle, const wstring& option)\n    : _angle(0), _option(-1), _xunit(0), _yunit(0), _x(0), _y(0) {\n    if(_base == nullptr) throw ex_parse(\"empty atom\");\n    _type = base->_type;\n    _base = base;\n    valueof(angle, _angle);\n    string x;\n    wide2utf8(option.c_str(), x);\n    _option = RotateBox::getOrigin(x);\n}\n\nsptr<Box> RotateAtom::createBox(_out_ TeXEnvironment& env) {\n    if(_base == nullptr) throw ex_parse(\"empty atom\");\n    if (_option != -1) return sptr<Box>(new RotateBox(_base->createBox(env), _angle, _option));\n\n    float x = _x * SpaceAtom::getFactor(_xunit, env);\n    float y = _y * SpaceAtom::getFactor(_yunit, env);\n    return sptr<Box>(new RotateBox(_base->createBox(env), _angle, x, y));\n}\n\nsptr<Box> UnderOverArrowAtom::createBox(_out_ TeXEnvironment& env) {\n    auto b = _base != nullptr ? _base->createBox(env) : sptr<Box>(new StrutBox(0, 0, 0, 0));\n    float sep = SpaceAtom::getSize(UNIT_MU, 1, env);\n\n    sptr<Box> arrow;\n\n    if (_dble) {\n        arrow = XLeftRightArrowFactory::create(env, b->_width);\n    } else {\n        arrow = XLeftRightArrowFactory::create(_left, env, b->_width);\n    }\n\n    VerticalBox* vb = new VerticalBox();\n    if (_over) {\n        vb->add(arrow);\n        if (_dble) vb->add(sptr<Box>(new StrutBox(0, -sep, 0, 0)));\n        vb->add(sptr<Box>(new HorizontalBox(b, arrow->_width, ALIGN_CENTER)));\n        float h = vb->_depth + vb->_height;\n        vb->_depth = b->_depth;\n        vb->_height = h - b->_depth;\n    } else {\n        vb->add(sptr<Box>(new HorizontalBox(b, arrow->_width, ALIGN_CENTER)));\n        vb->add(sptr<Box>(new StrutBox(0, sep, 0, 0)));\n        vb->add(arrow);\n        float h = vb->_depth + vb->_height;\n        vb->_depth = h - b->_height;\n        vb->_height = b->_height;\n    }\n\n    return sptr<Box>(vb);\n}\n\nsptr<Box> XArrowAtom::createBox(_out_ TeXEnvironment& env) {\n    auto O = _over != nullptr ? _over->createBox(*(env.supStyle()))\n                              : sptr<Box>(new StrutBox(0, 0, 0, 0));\n    auto U = _under != nullptr ? _under->createBox(*(env.subStyle()))\n                               : sptr<Box>(new StrutBox(0, 0, 0, 0));\n    auto oside = SpaceAtom(UNIT_EM, 1.5f, 0, 0).createBox(*(env.supStyle()));\n    auto uside = SpaceAtom(UNIT_EM, 1.5f, 0, 0).createBox(*(env.subStyle()));\n    auto sep = SpaceAtom(UNIT_MU, 0, 2.f, 0).createBox(env);\n    float width = max(O->_width + 2 * oside->_width, U->_width + 2 * uside->_width);\n    auto arrow = XLeftRightArrowFactory::create(_left, env, width);\n\n    sptr<Box> ohb(new HorizontalBox(O, width, ALIGN_CENTER));\n    sptr<Box> uhb(new HorizontalBox(U, width, ALIGN_CENTER));\n\n    sptr<VerticalBox> vb(new VerticalBox());\n    vb->add(ohb);\n    vb->add(sep);\n    vb->add(arrow);\n    vb->add(sep);\n    vb->add(uhb);\n\n    float h = vb->_height + vb->_depth;\n    float d = sep->_height + sep->_depth + uhb->_height + uhb->_depth;\n    vb->_depth = d;\n    vb->_height = h - d;\n\n    HorizontalBox* hb = new HorizontalBox(vb, vb->_width + 2 * sep->_height, ALIGN_CENTER);\n\n    return sptr<Box>(hb);\n}\n\nvoid LongDivAtom::calculate(_out_ vector<wstring>& results) {\n    long quotient = _dividend / _divisor;\n    results.push_back(towstring(quotient));\n    string x = tostring(quotient);\n    size_t len = x.length();\n    long remaining = _dividend;\n    results.push_back(towstring(remaining));\n    for (size_t i = 0; i < len; i++) {\n        long b = (x[i] - '0') * pow(10, len - i - 1);\n        long product = b * _divisor;\n        remaining = remaining - product;\n        results.push_back(towstring(product));\n        results.push_back(towstring(remaining));\n    }\n}\n\nLongDivAtom::LongDivAtom(long divisor, long dividend)\n    : _divisor(divisor), _dividend(dividend) {\n    setHalign(ALIGN_RIGHT);\n    setVtop(true);\n    vector<wstring> results;\n    calculate(results);\n\n    auto rule = sptr<Atom>(new RuleAtom(\n        UNIT_EX, 0.f,\n        UNIT_EX, 2.6f,\n        UNIT_EX, 0.5f));\n\n    const int s = results.size();\n    for (int i = 0; i < s; i++) {\n        auto num = TeXFormula(results[i])._root;\n        if (i == 1) {\n            wstring divisor = towstring(_divisor);\n            auto rparen = SymbolAtom::get(TeXFormula::_symbolMappings[')']);\n            auto big = sptr<Atom>(new BigDelimiterAtom(rparen, 1));\n            auto ph = sptr<Atom>(new PhantomAtom(big, false, true, true));\n            auto ra = sptr<RowAtom>(new RowAtom(ph));\n            auto raised = sptr<Atom>(new RaiseAtom(\n                big,\n                UNIT_X8, 3.5f,\n                UNIT_X8, 0.f,\n                UNIT_X8, 0.f));\n            ra->add(sptr<Atom>(new SmashedAtom(raised)));\n            ra->add(num);\n            auto oa = sptr<Atom>(new OverlinedAtom(ra));\n            auto row = sptr<RowAtom>(new RowAtom(TeXFormula(divisor)._root));\n            row->add(sptr<Atom>(new SpaceAtom(THINMUSKIP)));\n            row->add(oa);\n            append(row);\n            continue;\n        }\n        if (i % 2 == 0) {\n            auto row = sptr<RowAtom>(new RowAtom(num));\n            row->add(rule);\n            if (i == 0)\n                append(row);\n            else\n                append(sptr<Atom>(new UnderlinedAtom(row)));\n        } else {\n            auto row = sptr<RowAtom>(new RowAtom(num));\n            row->add(rule);\n            append(row);\n        }\n    }\n}\n\nsptr<Box> CancelAtom::createBox(_out_ TeXEnvironment& env) {\n    if(_base == nullptr) throw ex_parse(\"empty atom\");\n    auto box = _base->createBox(env);\n    vector<float> lines;\n    if (_cancelType == SLASH) {\n        lines = {\n            0, 0,\n            box->_width, box->_height + box->_depth};\n    } else if (_cancelType == BACKSLASH) {\n        lines = {\n            box->_width, 0,\n            0, box->_height + box->_depth};\n    } else if (_cancelType == CROSS) {\n        lines = {\n            0, 0,\n            box->_width, box->_height + box->_depth,\n            box->_width, 0,\n            0, box->_height + box->_depth};\n    } else {\n        return box;\n    }\n\n    const float rt = env.getTeXFont()->getDefaultRuleThickness(env.getStyle());\n    auto overlap = sptr<Box>(new LineBox(lines, rt));\n    overlap->_width = box->_width;\n    overlap->_height = box->_height;\n    overlap->_depth = box->_depth;\n    return sptr<Box>(new OverlappedBox(box, overlap));\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/atom/atom_impl.h",
    "content": "#ifndef ATOM_IMPL_H_INCLUDED\n#define ATOM_IMPL_H_INCLUDED\n\n#include \"atom/atom.h\"\n#include \"atom/box.h\"\n#include \"common.h\"\n#include \"core/core.h\"\n#include \"core/formula.h\"\n#include \"fonts/fonts.h\"\n#include \"graphic/graphic.h\"\n\nusing namespace std;\nusing namespace tex;\n\nnamespace tex {\n\ninline static void parseMap(const string& options, _out_ map<string, string>& res) {\n    if (options.empty()) return;\n\n    strtokenizer tokens(options, \",\");\n    const int c = tokens.count_tokens();\n    for (int i = 0; i < c; i++) {\n        string tok = tokens.next_token();\n        trim(tok);\n        vector<string> optarg;\n        split(tok, '=', optarg);\n        if (!optarg.empty()) {\n            if (optarg.size() == 2)\n                res[trim(optarg[0])] = trim(optarg[1]);\n            else if (optarg.size() == 1)\n                res[trim(optarg[0])] = \"\";\n        }\n    }\n}\n\n/**\n * Atom to justify cells in array\n */\nclass CellSpecifier : public Atom {\npublic:\n    virtual void apply(const sptr<Box>& box) = 0;\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        return sptr<Box>(new StrutBox(0, 0, 0, 0));\n    }\n};\n\n/**\n * Atom representing column color in array\n */\nclass CellColorAtom : public CellSpecifier {\nprivate:\n    color _color;\n\npublic:\n    CellColorAtom() = delete;\n\n    CellColorAtom(color c) : _color(c) {}\n\n    void apply(const sptr<Box>& box) {\n        box->_background = _color;\n    }\n\n    __decl_clone(CellColorAtom)\n};\n\n/**\n * Atom representing column foreground in array\n */\nclass CellForegroundAtom : public CellSpecifier {\nprivate:\n    color _color;\n\npublic:\n    CellForegroundAtom() = delete;\n\n    CellForegroundAtom(color c) : _color(c) {}\n\n    void apply(const sptr<Box>& box) {\n        box->_foreground = _color;\n    }\n\n    __decl_clone(CellForegroundAtom)\n};\n\n/**\n * Atom representing multi-row\n */\nclass MultiRowAtom : public Atom {\nprivate:\n    sptr<Atom> _rows;\n\npublic:\n    int _i, _j, _n;\n\n    MultiRowAtom() = delete;\n\n    MultiRowAtom(int n, const wstring& option, const sptr<Atom> rows)\n        : _i(0), _j(0), _rows(rows) {\n        _n = n == 0 ? 1 : n;\n    }\n\n    inline void setRowColumn(int r, int c) {\n        _i = r;\n        _j = c;\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        auto b = _rows->createBox(env);\n        b->_type = TYPE_MULTIROW;\n        return b;\n    }\n\n    __decl_clone(MultiRowAtom)\n};\n\nclass VlineAtom;\n\n/**\n * Enum specifies matrix type\n */\nenum MAT {\n    ARRAY = 0,\n    MATRIX,\n    ALIGN,\n    ALIGNAT,\n    FLALIGN,\n    SMALLMATRIX,\n    ALIGNED,\n    ALIGNEDAT\n};\n\n/**\n * Atom represents matrix\n */\nclass MatrixAtom : public Atom {\nprivate:\n    static map<wstring, wstring> _colspeReplacement;\n\n    static SpaceAtom _align;\n\n    sptr<ArrayOfAtoms> _matrix;\n    vector<int> _position;\n    map<int, sptr<VlineAtom>> _vlines;\n    map<int, sptr<Atom>> _columnSpecifiers;\n\n    int _ttype;\n    bool _ispartial;\n    bool _spaceAround;\n\n    void parsePositions(wstring opt, _out_ vector<int>& lpos);\n\n    sptr<Box> generateMulticolumn(\n        _out_ TeXEnvironment& env,\n        const sptr<Box>& b,\n        const float* hsep,\n        const float* colWidth,\n        int i, int j);\n\n    void recalculateLine(\n        const int rows,\n        sptr<Box>** boxarr,\n        vector<sptr<Atom>>& multiRows,\n        float* height, float* depth,\n        float drt, float vspace);\n\n    float* getColumnSep(_out_ TeXEnvironment& env, float width);\n\npublic:\n    // The color to draw the rule of the matrix\n    static color LINE_COLOR;\n\n    static SpaceAtom _hsep, _semihsep, _vsep_in, _vsep_ext_top, _vsep_ext_bot;\n\n    static sptr<Box> _nullbox;\n\n    MatrixAtom() = delete;\n\n    MatrixAtom(\n        bool ispar,\n        const sptr<ArrayOfAtoms>& arr,\n        const wstring& options,\n        bool spaceAround);\n\n    MatrixAtom(\n        bool ispar,\n        const sptr<ArrayOfAtoms>& arr,\n        const wstring& options);\n\n    MatrixAtom(\n        bool ispar,\n        const sptr<ArrayOfAtoms>& arr,\n        int type);\n\n    MatrixAtom(\n        bool ispar,\n        const sptr<ArrayOfAtoms>& arr,\n        int type,\n        int align);\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    static void defineColumnSpecifier(const wstring& rep, const wstring& spe);\n\n    __decl_clone(MatrixAtom)\n};\n\n/**\n * An atom representing vertical-line in matrix environment\n */\nclass VlineAtom : public Atom {\nprivate:\n    // Number of lines to draw\n    int _n;\n\npublic:\n    float _height, _shift;\n\n    VlineAtom() = delete;\n\n    VlineAtom(int n) : _n(n), _height(0), _shift(0) {}\n\n    inline float getWidth(_in_ TeXEnvironment& env) {\n        if (_n != 0) {\n            float drt = env.getTeXFont()->getDefaultRuleThickness(env.getStyle());\n            return drt * (3 * _n - 2);\n        }\n        return 0;\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        if (_n == 0) return sptr<Box>(new StrutBox(0, 0, 0, 0));\n\n        float drt = env.getTeXFont()->getDefaultRuleThickness(env.getStyle());\n        sptr<Box> b(new HorizontalRule(_height, drt, _shift, MatrixAtom::LINE_COLOR, true));\n        sptr<Box> sep(new StrutBox(2 * drt, 0, 0, 0));\n        HorizontalBox* hb = new HorizontalBox();\n        for (int i = 0; i < _n - 1; i++) {\n            hb->add(b);\n            hb->add(sep);\n        }\n\n        if (_n > 0) hb->add(b);\n\n        return sptr<Box>(hb);\n    }\n\n    __decl_clone(VlineAtom)\n};\n\nenum MULTILINETYPE {\n    MULTILINE = 0,\n    GATHER,\n    GATHERED\n};\n\n/**\n * An atom representing a vertical row of other atoms\n */\nclass MultlineAtom : public Atom {\nprivate:\n    static SpaceAtom _vsep_in;\n    sptr<ArrayOfAtoms> _column;\n    int _ttype;\n    bool _ispartial;\n\npublic:\n    MultlineAtom() = delete;\n\n    MultlineAtom(bool ispar, const sptr<ArrayOfAtoms>& col, int type) {\n        _ispartial = ispar;\n        _ttype = type;\n        _column = col;\n    }\n\n    MultlineAtom(const sptr<ArrayOfAtoms>& col, int type) {\n        _ispartial = false;\n        _ttype = type;\n        _column = col;\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(MultlineAtom)\n};\n\n/**\n * An atom representing a big delimiter atom (i.e. sigma)\n */\nclass BigDelimiterAtom : public Atom {\nprivate:\n    int _size;\n\npublic:\n    sptr<SymbolAtom> _delim;\n\n    BigDelimiterAtom() = delete;\n\n    BigDelimiterAtom(const sptr<SymbolAtom>& delim, int s) : _delim(delim), _size(s) {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        auto b = DelimiterFactory::create(*_delim, env, _size);\n        HorizontalBox* hb = new HorizontalBox();\n        float h = b->_height;\n        float total = h + b->_depth;\n        float axis = env.getTeXFont()->getAxisHeight(env.getStyle());\n        b->_shift = -total / 2 + h - axis;\n        hb->add(b);\n        return sptr<Box>(hb);\n    }\n\n    __decl_clone(BigDelimiterAtom)\n};\n\n/**\n * An atom representing a bold atom\n */\nclass BoldAtom : public Atom {\nprivate:\n    sptr<Atom> _base;\n\npublic:\n    BoldAtom() = delete;\n\n    BoldAtom(const sptr<Atom>& base) : _base(base) {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        if (_base != nullptr) {\n            TeXEnvironment& e = *(env.copy(env.getTeXFont()->copy()));\n            e.getTeXFont()->setBold(true);\n            return _base->createBox(e);\n        }\n        return sptr<Box>(new StrutBox(0, 0, 0, 0));\n    }\n\n    __decl_clone(BoldAtom)\n};\n\n/**\n * An atom with cedilla\n */\nclass CedillAtom : public Atom {\nprivate:\n    sptr<Atom> _base;\n\npublic:\n    CedillAtom() = delete;\n\n    CedillAtom(const sptr<Atom>& base) : _base(base) {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        if(_base == nullptr) throw ex_parse(\"empty atom\");\n        auto b = _base->createBox(env);\n        VerticalBox* vb = new VerticalBox();\n        vb->add(b);\n        Char ch = env.getTeXFont()->getChar(\"mathcedilla\", env.getStyle());\n        float italic = ch.getItalic();\n        Box* cedilla = new CharBox(ch);\n        Box* y;\n        if (abs(italic) > PREC) {\n            y = new HorizontalBox(sptr<Box>(new StrutBox(-italic, 0, 0, 0)));\n            y->add(sptr<Box>(cedilla));\n        } else {\n            y = cedilla;\n        }\n\n        Box* ce = new HorizontalBox(sptr<Box>(y), b->_width, ALIGN_CENTER);\n        float x = 0.4f * SpaceAtom::getFactor(UNIT_MU, env);\n        vb->add(sptr<Box>(new StrutBox(0, -x, 0, 0)));\n        vb->add(sptr<Box>(ce));\n        float f = vb->_height + vb->_depth;\n        vb->_height = b->_height;\n        vb->_depth = f - b->_height;\n        return sptr<Box>(vb);\n    }\n\n    __decl_clone(CedillAtom)\n};\n\n/**\n * An atom representing ddots\n */\nclass DdtosAtom : public Atom {\npublic:\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        auto ldots = TeXFormula::get(L\"ldots\")->_root->createBox(env);\n        float w = ldots->_width;\n        auto dot = SymbolAtom::get(\"ldotp\")->createBox(env);\n        HorizontalBox* hb1 = new HorizontalBox(dot, w, ALIGN_LEFT);\n        HorizontalBox* hb2 = new HorizontalBox(dot, w, ALIGN_CENTER);\n        HorizontalBox* hb3 = new HorizontalBox(dot, w, ALIGN_RIGHT);\n        sptr<Box> pt4(SpaceAtom(UNIT_MU, 0, 4, 0).createBox(env));\n        VerticalBox* vb = new VerticalBox();\n        vb->add(sptr<Box>(hb1));\n        vb->add(pt4);\n        vb->add(sptr<Box>(hb2));\n        vb->add(pt4);\n        vb->add(sptr<Box>(hb3));\n\n        float h = vb->_height + vb->_depth;\n        vb->_height = h;\n        vb->_depth = 0;\n        return sptr<Box>(vb);\n    }\n\n    __decl_clone(DdtosAtom)\n};\n\n/**\n * An atom representing a boxed base atom\n */\nclass FBoxAtom : public Atom {\nprotected:\n    sptr<Atom> _base;\n    color _bg, _line;\n\npublic:\n    static const float INTERSPACE;\n\n    FBoxAtom() = delete;\n\n    FBoxAtom(const sptr<Atom>& base, color bg = TRANS, color line = TRANS) {\n        if (base == nullptr)\n            _base = sptr<Atom>(new RowAtom());\n        else {\n            _base = base;\n            _type = base->_type;\n        }\n        _bg = bg;\n        _line = line;\n    }\n\n    virtual sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        if(_base == nullptr) throw ex_parse(\"empty atom\");\n        auto bbase = _base->createBox(env);\n        float drt = env.getTeXFont()->getDefaultRuleThickness(env.getStyle());\n        float space = INTERSPACE * SpaceAtom::getFactor(UNIT_EM, env);\n        if (istrans(_bg)) return sptr<Box>(new FramedBox(bbase, drt, space));\n        env._isColored = true;\n        return sptr<Box>(new FramedBox(bbase, drt, space, _line, _bg));\n    }\n\n    __decl_clone(FBoxAtom)\n};\n\n/**\n * An atom representing a boxed base atom\n */\nclass DoubleFramedAtom : public FBoxAtom {\npublic:\n    DoubleFramedAtom() = delete;\n\n    DoubleFramedAtom(const sptr<Atom>& base) : FBoxAtom(base) {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        if(_base == nullptr) throw ex_parse(\"empty atom\");\n        auto bbase = _base->createBox(env);\n        float drt = env.getTeXFont()->getDefaultRuleThickness(env.getStyle());\n        float space = INTERSPACE * SpaceAtom::getFactor(UNIT_EM, env);\n        float sspace = 1.5f * drt + 0.5f * SpaceAtom::getFactor(UNIT_POINT, env);\n        return sptr<Box>(new FramedBox(\n            sptr<Box>(new FramedBox(bbase, 0.75 * drt, space)), 1.5f * drt, sspace));\n    }\n\n    __decl_clone(DoubleFramedAtom)\n};\n\n/**\n * An atom representing a box-shadowed atom\n */\nclass ShadowAtom : public FBoxAtom {\npublic:\n    ShadowAtom() = delete;\n\n    ShadowAtom(const sptr<Atom>& base) : FBoxAtom(base) {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        auto x = FBoxAtom::createBox(env);\n        auto box = dynamic_pointer_cast<FramedBox>(x);\n        float t = env.getTeXFont()->getDefaultRuleThickness(env.getStyle()) * 4;\n        return sptr<Box>(new ShadowBox(box, t));\n    }\n\n    __decl_clone(ShadowAtom)\n};\n\n/**\n * An atom representing a oval-boxed base atom\n */\nclass OvalAtom : public FBoxAtom {\npublic:\n    static float _multiplier;\n    static float _diameter;\n\n    OvalAtom() = delete;\n\n    OvalAtom(const sptr<Atom>& base) : FBoxAtom(base) {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        auto x = FBoxAtom::createBox(env);\n        auto box = dynamic_pointer_cast<FramedBox>(x);\n        return sptr<Box>(new OvalBox(box, _multiplier, _diameter));\n    }\n\n    __decl_clone(OvalAtom)\n};\n\n/**\n * An atom representing a base atom surrounded with delimiters that change their\n * size according to the height of the base\n */\nclass FencedAtom : public Atom {\nprivate:\n    static const int DELIMITER_FACTOR;\n    static const float DELIMITER_SHORTFALL;\n    // base atom\n    sptr<Atom> _base;\n    // delimiters\n    sptr<SymbolAtom> _left;\n    sptr<SymbolAtom> _right;\n    list<sptr<MiddleAtom>> _middle;\n\n    void init(const sptr<Atom>& b, const sptr<SymbolAtom>& l, const sptr<SymbolAtom>& r);\n\n    static void center(_out_ Box& b, float axis);\n\npublic:\n    FencedAtom(const sptr<Atom>& b, const sptr<SymbolAtom>& l, const sptr<SymbolAtom>& r) {\n        init(b, l, r);\n    }\n\n    FencedAtom(\n        const sptr<Atom>& b,\n        const sptr<SymbolAtom>& l,\n        const list<sptr<MiddleAtom>>& m,\n        const sptr<SymbolAtom>& r) {\n        init(b, l, r);\n        _middle = m;\n    }\n\n    int getLeftType() const override {\n        return TYPE_INNER;\n    }\n\n    int getRightType() const override {\n        return TYPE_INNER;\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(FencedAtom)\n};\n\n/**\n * An atom representing a fraction\n */\nclass FractionAtom : public Atom {\nprivate:\n    // whether the default thickness should not be used for fraction line\n    bool _nodefault;\n    // unit used for the thickness of the fraction line\n    int _unit;\n    // alignment settings for the numerator and denominator\n    int _numAlign, _denomAlign;\n    // the atoms representing the numerator and denominator\n    sptr<Atom> _numerator, _denominator;\n    // thickness of the fraction line\n    float _thickness;\n    // thickness of the fraction line relative to the default thickness\n    float _deffactor;\n    // whether the def-factor value should be used\n    bool _deffactorset;\n\n    inline int checkAlign(int align) {\n        if (align == ALIGN_LEFT || align == ALIGN_RIGHT) return align;\n        return ALIGN_CENTER;\n    }\n\n    void init(\n        const sptr<Atom>& num,\n        const sptr<Atom>& den,\n        bool nodef, int unit, float t) throw(ex_invalid_unit);\n\npublic:\n    /**\n     * If add space to start and end of fraction, default is true\n     */\n    bool _useKern;\n\n    FractionAtom() = delete;\n\n    FractionAtom(const sptr<Atom>& num, const sptr<Atom>& den) {\n        init(num, den, false, UNIT_PIXEL, 0.f);\n    }\n\n    FractionAtom(const sptr<Atom>& num, const sptr<Atom>& den, bool rule) {\n        init(num, den, !rule, UNIT_PIXEL, 0.f);\n    }\n\n    FractionAtom(\n        const sptr<Atom>& num, const sptr<Atom>& den,\n        bool nodef, int unit, float t) throw(ex_invalid_unit) {\n        init(num, den, nodef, unit, t);\n    }\n\n    FractionAtom(\n        const sptr<Atom>& num, const sptr<Atom>& den,\n        bool rule, int numAlign, int denomAlign) {\n        init(num, den, !rule, UNIT_PIXEL, 0.f);\n        _numAlign = checkAlign(numAlign);\n        _denomAlign = checkAlign(denomAlign);\n    }\n\n    FractionAtom(\n        const sptr<Atom>& num, const sptr<Atom>& den,\n        float deffactor, int numAlign, int denomAlign) {\n        init(num, den, false, UNIT_PIXEL, 0.f);\n        _numAlign = checkAlign(numAlign);\n        _denomAlign = checkAlign(denomAlign);\n        _deffactor = deffactor;\n        _deffactorset = true;\n    }\n\n    FractionAtom(\n        const sptr<Atom>& num, const sptr<Atom>& den,\n        int unit, float t, int numAlign, int denomAlign) {\n        init(num, den, true, unit, t);\n        _numAlign = checkAlign(numAlign);\n        _denomAlign = checkAlign(denomAlign);\n    }\n\n    FractionAtom(const sptr<Atom>& num, const sptr<Atom>& den, int unit, float t) {\n        init(num, den, true, unit, t);\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(FractionAtom)\n};\n\n/**\n * An atom used in array mode that across several columns\n */\nclass MulticolumnAtom : public Atom {\nprotected:\n    // Number of columns across\n    int _n;\n    int _align;\n    float _w;\n    int _beforeVlines, _afterVlines;\n    int _row, _col;\n    sptr<Atom> _cols;\n\n    int parseAlign(const string& str);\n\npublic:\n    MulticolumnAtom() = delete;\n\n    MulticolumnAtom(int n, const string& align, const sptr<Atom> cols)\n        : _w(0), _beforeVlines(0), _afterVlines(0), _row(0), _col(0) {\n        _n = n >= 1 ? n : 1;\n        _cols = cols;\n        _align = parseAlign(align);\n    }\n\n    virtual bool isNeedWidth() const {\n        return false;\n    }\n\n    inline void setColumnWidth(float w) {\n        _w = w;\n    }\n\n    inline float getColumnWidth() {\n        return _w;\n    }\n\n    inline int getSkipped() {\n        return _n;\n    }\n\n    inline bool hasRightVline() {\n        return _afterVlines != 0;\n    }\n\n    inline void setRowColumn(int i, int j) {\n        _row = i;\n        _col = j;\n    }\n\n    inline int getAlign() {\n        return _align;\n    }\n\n    inline int getRow() {\n        return _row;\n    }\n\n    inline int getCol() {\n        return _col;\n    }\n\n    virtual sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(MulticolumnAtom)\n};\n\n/**\n * An atom used in array mode representing \"dots\"\n */\nclass HdotsforAtom : public MulticolumnAtom {\nprivate:\n    float _coeff;\n\n    sptr<Box> createBox(\n        float space,\n        const sptr<Box>& b,\n        _out_ TeXEnvironment& env);\n\npublic:\n    HdotsforAtom() = delete;\n\n    HdotsforAtom(int n, float coeff)\n        : MulticolumnAtom(n, \"c\", SymbolAtom::get(\"ldotp\")), _coeff(coeff) {}\n\n    bool isNeedWidth() const override {\n        return true;\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(HdotsforAtom)\n};\n\n/**\n * An atom representing id-dots\n */\nclass IddotsAtom : public Atom {\npublic:\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        auto ldots = TeXFormula::get(L\"ldots\")->_root->createBox(env);\n        float w = ldots->_width;\n        auto dot = SymbolAtom::get(\"ldotp\")->createBox(env);\n        sptr<Box> hb1(new HorizontalBox(dot, w, ALIGN_RIGHT));\n        sptr<Box> hb2(new HorizontalBox(dot, w, ALIGN_CENTER));\n        sptr<Box> hb3(new HorizontalBox(dot, w, ALIGN_LEFT));\n        sptr<Box> pt4 = SpaceAtom(UNIT_MU, 0, 4, 0).createBox(env);\n        VerticalBox* vb = new VerticalBox();\n        vb->add(hb1);\n        vb->add(pt4);\n        vb->add(hb2);\n        vb->add(pt4);\n        vb->add(hb3);\n\n        float h = vb->_height + vb->_depth;\n        vb->_height = h;\n        vb->_depth = 0;\n\n        return sptr<Box>(vb);\n    }\n\n    __decl_clone(IddotsAtom)\n};\n\n/**\n * An atom representing an IJ\n */\nclass IJAtom : public Atom {\nprivate:\n    bool _upper;\n\npublic:\n    IJAtom() = delete;\n\n    IJAtom(bool upper) : _upper(upper) {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        CharBox* I = new CharBox(\n            env.getTeXFont()->getChar(_upper ? 'I' : 'i', \"mathnormal\", env.getStyle()));\n        CharBox* J = new CharBox(\n            env.getTeXFont()->getChar(_upper ? 'J' : 'j', \"mathnormal\", env.getStyle()));\n        HorizontalBox* hb = new HorizontalBox(sptr<Box>(I));\n        hb->add(SpaceAtom(UNIT_EM, -0.065f, 0, 0).createBox(env));\n        hb->add(sptr<Box>(J));\n        return sptr<Box>(hb);\n    }\n\n    __decl_clone(IJAtom)\n};\n\n/**\n * An atom representing a italic atom\n */\nclass ItAtom : public Atom {\nprivate:\n    sptr<Atom> _base;\n\npublic:\n    ItAtom() = delete;\n\n    ItAtom(const sptr<Atom> base) : _base(base) {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        sptr<Box> box;\n        if (_base != nullptr) {\n            TeXEnvironment& e = *(env.copy(env.getTeXFont()->copy()));\n            e.getTeXFont()->setIt(true);\n            box = _base->createBox(e);\n        } else {\n            box = sptr<Box>(new StrutBox(0, 0, 0, 0));\n        }\n\n        return box;\n    }\n\n    __decl_clone(ItAtom)\n};\n\n/**\n * An atom representing a lapped atom (i.e. with no width)\n */\nclass LapedAtom : public Atom {\nprivate:\n    sptr<Atom> _at;\n    wchar_t _type;\n\npublic:\n    LapedAtom() = delete;\n\n    LapedAtom(const sptr<Atom>& a, wchar_t type) : _at(a), _type(type) {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        auto b = _at->createBox(env);\n        VerticalBox* vb = new VerticalBox();\n        vb->add(b);\n        vb->_width = 0;\n        switch (_type) {\n        case 'l':\n            b->_shift = -b->_width;\n            break;\n        case 'r':\n            b->_shift = 0;\n            break;\n        default:\n            b->_shift = -b->_width / 2;\n            break;\n        }\n\n        return sptr<Box>(vb);\n    }\n\n    __decl_clone(LapedAtom)\n};\n\n/**\n * An atom representing LaTeX logo. the dimension values can be set using\n * different unit types.\n */\nclass LaTeXAtom : public Atom {\npublic:\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(LaTeXAtom)\n};\n\n/**\n * An atom representing an L with a Caron\n */\nclass LCaronAtom : public Atom {\nprivate:\n    bool _upper;\n\npublic:\n    LCaronAtom() = delete;\n\n    LCaronAtom(bool upper) : _upper(upper) {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        CharBox* A = new CharBox(\n            env.getTeXFont()->getChar(\"textapos\", env.getStyle()));\n        CharBox* L = new CharBox(\n            env.getTeXFont()->getChar(_upper ? 'L' : 'l', \"mathnormal\", env.getStyle()));\n        HorizontalBox* hb = new HorizontalBox(sptr<Box>(L));\n        if (_upper)\n            hb->add(SpaceAtom(UNIT_EM, -0.3f, 0, 0).createBox(env));\n        else\n            hb->add(SpaceAtom(UNIT_EM, -0.13f, 0, 0).createBox(env));\n        hb->add(sptr<Box>(A));\n        return sptr<Box>(hb);\n    }\n\n    __decl_clone(LCaronAtom)\n};\n\n/**\n * An atom representing a mono scale atom\n */\nclass MonoScaleAtom : public ScaleAtom {\nprivate:\n    float _factor;\n\npublic:\n    MonoScaleAtom() = delete;\n\n    MonoScaleAtom(const sptr<Atom>& base, float factor)\n        : ScaleAtom(base, factor, factor), _factor(factor) {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        if(_base == nullptr) throw ex_parse(\"empty atom\");\n        TeXEnvironment& e = *(env.copy());\n        float f = e.getScaleFactor();\n        e.setScaleFactor(_factor);\n        return sptr<Box>(new ScaleBox(_base->createBox(e), _factor / f));\n    }\n\n    __decl_clone(MonoScaleAtom)\n};\n\n/**\n * An atom with an Ogonek\n */\nclass OgonekAtom : public Atom {\nprivate:\n    sptr<Atom> _base;\n\npublic:\n    OgonekAtom() = delete;\n\n    OgonekAtom(const sptr<Atom>& base) : _base(base) {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        if(_base == nullptr) throw ex_parse(\"empty atom\");\n        auto b = _base->createBox(env);\n        VerticalBox* vb = new VerticalBox();\n        vb->add(b);\n        Char ch = env.getTeXFont()->getChar(\"ogonek\", env.getStyle());\n        float italic = ch.getItalic();\n        Box* ogonek = new CharBox(ch);\n        Box* y = nullptr;\n        if (abs(italic) > PREC) {\n            y = new HorizontalBox(sptr<Box>(new StrutBox(-italic, 0, 0, 0)));\n            y->add(sptr<Box>(ogonek));\n        } else {\n            y = ogonek;\n        }\n\n        Box* og = new HorizontalBox(sptr<Box>(y), b->_width, ALIGN_RIGHT);\n        vb->add(sptr<Box>(new StrutBox(0, -ogonek->_height, 0, 0)));\n        vb->add(sptr<Box>(og));\n        float f = vb->_height + vb->_depth;\n        vb->_height = b->_height;\n        vb->_depth = f - b->_height;\n        return sptr<Box>(vb);\n    }\n\n    __decl_clone(OgonekAtom)\n};\n\n/**\n * An atom representing a over-lined atom\n */\nclass OverlinedAtom : public Atom {\nprivate:\n    sptr<Atom> _base;\n\npublic:\n    OverlinedAtom() = delete;\n\n    OverlinedAtom(const sptr<Atom>& f) : _base(f) {\n        _type = TYPE_ORDINARY;\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        float drt = env.getTeXFont()->getDefaultRuleThickness(env.getStyle());\n        // cramp the style of the formula to be overlined and create\n        // vertical box\n        auto b = _base == nullptr ? sptr<Box>(new StrutBox(0, 0, 0, 0))\n                                  : _base->createBox(*(env.crampStyle()));\n        OverBar* ob = new OverBar(b, 3 * drt, drt);\n\n        // baseline vertical box = baseline box b\n        ob->_depth = b->_depth;\n        ob->_height = b->_height + 5 * drt;\n\n        return sptr<Box>(ob);\n    }\n\n    __decl_clone(OverlinedAtom)\n};\n\nclass RaiseAtom : public Atom {\nprivate:\n    sptr<Atom> _base;\n    int _ru, _hu, _du;\n    float _r, _h, _d;\n\npublic:\n    RaiseAtom() = delete;\n\n    RaiseAtom(const sptr<Atom>& base, int ru, float r, int hu, float h, int du, float d)\n        : _base(base), _ru(ru), _r(r), _hu(hu), _h(h), _du(du), _d(d) {}\n\n    int getLeftType() const override {\n        return _base->getLeftType();\n    }\n\n    int getRightType() const override {\n        return _base->getRightType();\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        if(_base == nullptr) throw ex_parse(\"empty atom\");\n        auto bbox = _base->createBox(env);\n        if (_ru == -1)\n            bbox->_shift = 0;\n        else\n            bbox->_shift = -_r * SpaceAtom::getFactor(_ru, env);\n\n        if (_hu == -1) return bbox;\n\n        HorizontalBox* hbox = new HorizontalBox(bbox);\n        hbox->_height = _h * SpaceAtom::getFactor(_hu, env);\n        if (_du == -1)\n            hbox->_depth = 0;\n        else\n            hbox->_depth = _d * SpaceAtom::getFactor(_du, env);\n\n        return sptr<Box>(hbox);\n    }\n\n    __decl_clone(RaiseAtom)\n};\n\n/**\n * An atom representing a reflected atom\n */\nclass ReflectAtom : public Atom {\nprivate:\n    sptr<Atom> _base;\n\npublic:\n    ReflectAtom() = delete;\n\n    ReflectAtom(const sptr<Atom>& base) : _base(base) {\n        _type = _base->_type;\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        if(_base == nullptr) throw ex_parse(\"empty atom\");\n        return sptr<Box>(new ReflectBox(_base->createBox(env)));\n    }\n\n    __decl_clone(ReflectAtom)\n};\n\n/**\n * An atom representing a resize atom\n */\nclass ResizeAtom : public Atom {\nprivate:\n    sptr<Atom> _base;\n    int _wu, _hu;\n    float _w, _h;\n    bool _keep_aspect_ratio;\n\npublic:\n    ResizeAtom() = delete;\n\n    ResizeAtom(const sptr<Atom>& base, const string& ws, const string& hs, bool keepAspectRatio) {\n        _type = base->_type;\n        _base = base;\n        _keep_aspect_ratio = keepAspectRatio;\n        auto w = SpaceAtom::getLength(ws);\n        auto h = SpaceAtom::getLength(hs);\n        _wu = (int)w.first;\n        _w = w.second;\n        _hu = (int)h.first;\n        _h = h.second;\n    }\n\n    int getLeftType() const override {\n        return _base->getLeftType();\n    }\n\n    int getRightType() const override {\n        return _base->getRightType();\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        if(_base == nullptr) throw ex_parse(\"empty atom\");\n        auto bbox = _base->createBox(env);\n        if (_wu == -1 && _hu == -1) return bbox;\n        float sx = 1.f, sy = 1.f;\n        if (_wu != -1 && _hu != -1) {\n            sx = _w * SpaceAtom::getFactor(_wu, env) / bbox->_width;\n            sy = _h * SpaceAtom::getFactor(_hu, env) / bbox->_height;\n            if (_keep_aspect_ratio) {\n                sx = min(sx, sy);\n                sy = sx;\n            }\n        } else if (_wu != -1 && _hu == -1) {\n            sx = _w * SpaceAtom::getFactor(_wu, env) / bbox->_width;\n            sy = sx;\n        } else {\n            sx = _h * SpaceAtom::getFactor(_hu, env) / bbox->_height;\n            sy = sx;\n        }\n\n        return sptr<Box>(new ScaleBox(bbox, sx, sy));\n    }\n\n    __decl_clone(ResizeAtom)\n};\n\n/**\n * An atom representing an nth-root construction\n */\nclass NthRoot : public Atom {\nprivate:\n    static const string _sqrtSymbol;\n    static const float FACTOR;\n    // base atom to be put under the root sign\n    sptr<Atom> _base;\n    // root atom to be put in the upper left corner above the root sign\n    sptr<Atom> _root;\n\npublic:\n    NthRoot() = delete;\n\n    NthRoot(const sptr<Atom>& base, const sptr<Atom>& root) {\n        _base = base == nullptr ? sptr<Atom>(new EmptyAtom()) : base;\n        _root = root == nullptr ? sptr<Atom>(new EmptyAtom()) : root;\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(NthRoot)\n};\n\n/**\n * An atom representing a rotated atom\n */\nclass RotateAtom : public Atom {\nprivate:\n    sptr<Atom> _base;\n    float _angle;\n    int _option;\n    int _xunit, _yunit;\n    float _x, _y;\n\npublic:\n    RotateAtom() = delete;\n\n    RotateAtom(const sptr<Atom>& base, const wstring& angle, const wstring& option);\n\n    RotateAtom(const sptr<Atom>& base, float angle, const wstring& option);\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(RotateAtom)\n};\n\nclass RuleAtom : public Atom {\nprivate:\n    int _wu, _hu, _ru;\n    float _w, _h, _r;\n\npublic:\n    RuleAtom() = delete;\n\n    RuleAtom(int wu, float w, int hu, float h, int ru, float r)\n        : _wu(wu), _hu(hu), _ru(ru), _w(w), _h(h), _r(r) {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        float w = SpaceAtom::getFactor(_wu, env) * _w;\n        float h = SpaceAtom::getFactor(_hu, env) * _h;\n        float r = SpaceAtom::getFactor(_ru, env) * _r;\n        return sptr<Box>(new HorizontalRule(h, w, r));\n    }\n\n    __decl_clone(RuleAtom)\n};\n\n/**\n * An atom representing a small Capital atom\n */\nclass SmallCpaAtom : public Atom {\nprivate:\n    sptr<Atom> _base;\n\npublic:\n    SmallCpaAtom() = delete;\n\n    SmallCpaAtom(const sptr<Atom>& base) : _base(base) {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        bool prev = env.getSmallCap();\n        env.setSmallCap(true);\n        if(_base == nullptr) throw ex_parse(\"empty atom\");\n        auto box = _base->createBox(env);\n        env.setSmallCap(prev);\n        return box;\n    }\n\n    __decl_clone(SmallCpaAtom)\n};\n\n/**\n * An atom representing a sans-serif atom\n */\nclass SsAtom : public Atom {\nprivate:\n    sptr<Atom> _base;\n\npublic:\n    SsAtom() = delete;\n\n    SsAtom(const sptr<Atom>& base) : _base(base) {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        bool prev = env.getTeXFont()->getSs();\n        env.getTeXFont()->setSs(true);\n        if(_base == nullptr) throw ex_parse(\"empty atom\");\n        auto box = _base->createBox(env);\n        env.getTeXFont()->setSs(prev);\n        return box;\n    }\n\n    __decl_clone(SsAtom)\n};\n\n/**\n * An atom representing a strike through atom\n */\nclass StrikeThroughAtom : public Atom {\nprivate:\n    sptr<Atom> _at;\n\npublic:\n    StrikeThroughAtom(const sptr<Atom>& a) : _at(a) {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        TeXFont& tf = *(env.getTeXFont());\n        int style = env.getStyle();\n        float axis = tf.getAxisHeight(style);\n        float drt = tf.getDefaultRuleThickness(style);\n        auto b = _at->createBox(env);\n        HorizontalRule* rule = new HorizontalRule(drt, b->_width, -axis + drt, false);\n        HorizontalBox* hb = new HorizontalBox();\n        hb->add(b);\n        hb->add(sptr<Box>(new StrutBox(-b->_width, 0, 0, 0)));\n        hb->add(sptr<Box>(rule));\n\n        return sptr<Box>(hb);\n    }\n\n    __decl_clone(StrikeThroughAtom)\n};\n\n/**\n * An atom representing a modification of style in a formula\n * (e.g. text-style or display-style)\n */\nclass StyleAtom : public Atom {\nprivate:\n    int _style;\n    sptr<Atom> _at;\n\npublic:\n    StyleAtom() = delete;\n\n    StyleAtom(int style, const sptr<Atom>& a) {\n        _style = style;\n        _at = a;\n        _type = a->_type;\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        int s = env.getStyle();\n        env.setStyle(_style);\n        auto box = _at->createBox(env);\n        env.setStyle(s);\n        return box;\n    }\n\n    __decl_clone(StyleAtom)\n};\n\n/**\n * An atom representing an t with a Caron\n */\nclass TCaronAtom : public Atom {\npublic:\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        Char a = env.getTeXFont()->getChar(\"textapos\", env.getStyle());\n        CharBox* A = new CharBox(a);\n        Char t = env.getTeXFont()->getChar('t', \"mathnormal\", env.getStyle());\n        CharBox* T = new CharBox(t);\n        HorizontalBox* hb = new HorizontalBox(sptr<Box>(T));\n        hb->add(SpaceAtom(UNIT_EM, -0.3f, 0, 0).createBox(env));\n        hb->add(sptr<Box>(A));\n        return sptr<Box>(hb);\n    }\n\n    __decl_clone(TCaronAtom)\n};\n\nclass TextCircledAtom : public Atom {\nprivate:\n    sptr<Atom> _at;\n\npublic:\n    TextCircledAtom() = delete;\n\n    TextCircledAtom(const sptr<Atom>& a) : _at(a) {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        auto circle = SymbolAtom::get(\"bigcirc\")->createBox(env);\n        circle->_shift = -0.07f * SpaceAtom::getFactor(UNIT_EX, env);\n        auto box = _at->createBox(env);\n        HorizontalBox* hb = new HorizontalBox(box, circle->_width, ALIGN_CENTER);\n        hb->add(sptr<Box>(new StrutBox(-hb->_width, 0, 0, 0)));\n        hb->add(circle);\n        return sptr<Box>(hb);\n    }\n\n    __decl_clone(TextCircledAtom)\n};\n\n/**\n * An atom representing a modification of style in a formula\n */\nclass TextStyleAtom : public Atom {\nprivate:\n    string _style;\n    sptr<Atom> _at;\n\npublic:\n    TextStyleAtom() = delete;\n\n    TextStyleAtom(const sptr<Atom>& a, const string& style) : _style(style), _at(a) {\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        string prev = env.getTextStyle();\n        env.setTextStyle(_style);\n        auto box = _at->createBox(env);\n        env.setTextStyle(prev);\n        return box;\n    }\n\n    __decl_clone(TextStyleAtom)\n};\n\n/**\n * An atom with a stroked T\n */\nclass TStrokeAtom : public Atom {\nprivate:\n    bool _upper;\n\npublic:\n    TStrokeAtom() = delete;\n\n    TStrokeAtom(bool u) : _upper(u) {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        Char ch = env.getTeXFont()->getChar(\"bar\", env.getStyle());\n        float italic = ch.getItalic();\n        Char t = env.getTeXFont()->getChar(_upper ? 'T' : 't', \"mathnormal\", env.getStyle());\n        CharBox* T = new CharBox(t);\n        CharBox* B = new CharBox(ch);\n        Box* y = nullptr;\n        if (abs(italic) > PREC) {\n            y = new HorizontalBox(sptr<Box>(new StrutBox(-italic, 0, 0, 0)));\n            y->add(sptr<Box>(B));\n        } else {\n            y = B;\n        }\n        Box* b = new HorizontalBox(sptr<Box>(y), T->_width, ALIGN_CENTER);\n        VerticalBox* vb = new VerticalBox();\n        vb->add(sptr<Box>(T));\n        vb->add(sptr<Box>(new StrutBox(0, -0.5f * T->_width, 0, 0)));\n        vb->add(sptr<Box>(b));\n        return sptr<Box>(vb);\n    }\n\n    __decl_clone(TStrokeAtom)\n};\n\n/**\n * An atom representing a typewriter atom\n */\nclass TtAtom : public Atom {\nprivate:\n    sptr<Atom> _base;\n\npublic:\n    TtAtom() = delete;\n\n    TtAtom(const sptr<Atom>& base) : _base(base) {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        bool prev = env.getTeXFont()->getTt();\n        env.getTeXFont()->setTt(true);\n        if(_base == nullptr) throw ex_parse(\"empty atom\");\n        auto box = _base->createBox(env);\n        env.getTeXFont()->setTt(prev);\n        return box;\n    }\n\n    __decl_clone(TtAtom)\n};\n\n/**\n * An atom representing another atom with a line under it\n */\nclass UnderlinedAtom : public Atom {\nprivate:\n    sptr<Atom> _base;\n\npublic:\n    UnderlinedAtom() = delete;\n\n    UnderlinedAtom(const sptr<Atom>& f) : _base(f) {\n        _type = TYPE_ORDINARY;\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        float drt = env.getTeXFont()->getDefaultRuleThickness(env.getStyle());\n\n        // create formula box in same style\n        auto b = _base == nullptr ? sptr<Box>(new StrutBox(0, 0, 0, 0)) : _base->createBox(env);\n\n        // create vertical box\n        VerticalBox* vb = new VerticalBox();\n        vb->add(b);\n        vb->add(sptr<Box>(new StrutBox(0, 3 * drt, 0, 0)));\n        vb->add(sptr<Box>(new HorizontalRule(drt, b->_width, 0)));\n\n        // baseline vertical box = baseline box b\n        // there's also an invisible strut of height drt under the rule\n        vb->_depth = b->_depth + 5 * drt;\n        vb->_height = b->_height;\n\n        return sptr<Box>(vb);\n    }\n\n    __decl_clone(UnderlinedAtom)\n};\n\n/**\n * An atom representing an other atom with an extensible arrow or double-arrow\n * over or under it\n */\nclass UnderOverArrowAtom : public Atom {\nprivate:\n    sptr<Atom> _base;\n    bool _over, _left, _dble;\n\npublic:\n    UnderOverArrowAtom() = delete;\n\n    UnderOverArrowAtom(const sptr<Atom>& base, bool left, bool over) {\n        _base = base;\n        _left = left;\n        _over = over;\n        _dble = false;\n    }\n\n    UnderOverArrowAtom(const sptr<Atom>& base, bool over) {\n        _base = base;\n        _over = over;\n        _dble = true;\n        _left = false;\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(UnderOverArrowAtom)\n};\n\n/**\n * An atom representing another atom vertically centered with respect to\n * the axis (determined by a general TeXFont parameter)\n */\nclass VCenteredAtom : public Atom {\nprivate:\n    sptr<Atom> _at;\n\npublic:\n    VCenteredAtom() = delete;\n\n    VCenteredAtom(const sptr<Atom>& a) : _at(a) {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        auto b = _at->createBox(env);\n\n        float total = b->_height + b->_depth;\n        float axis = env.getTeXFont()->getAxisHeight(env.getStyle());\n\n        // center on axis\n        b->_shift = -(total / 2) - axis;\n\n        return sptr<Box>(new HorizontalBox(b));\n    }\n\n    __decl_clone(VCenteredAtom)\n};\n\n/**\n * An atom representing vertical-dots\n */\nclass VdotsAtom : public Atom {\npublic:\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override {\n        auto dot = SymbolAtom::get(\"ldotp\")->createBox(env);\n        VerticalBox* vb = new VerticalBox(dot, 0, ALIGN_BOTTOM);\n        auto b = SpaceAtom(UNIT_MU, 0, 4, 0).createBox(env);\n        vb->add(b);\n        vb->add(dot);\n        vb->add(b);\n        vb->add(dot);\n        float d = vb->_depth;\n        float h = vb->_height;\n        vb->_depth = 0;\n        vb->_height = d + h;\n\n        return sptr<Box>(vb);\n    }\n\n    __decl_clone(VdotsAtom)\n};\n\n/**\n * An atom representing an extensible left or right arrow to handle xleftarrow\n * and xrightarrow commands in LaTeX.\n */\nclass XArrowAtom : public Atom {\nprivate:\n    sptr<Atom> _over, _under;\n    bool _left;\n\npublic:\n    XArrowAtom() = delete;\n\n    XArrowAtom(const sptr<Atom>& over, const sptr<Atom>& under, bool left) {\n        _over = over;\n        _under = under;\n        _left = left;\n    }\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(XArrowAtom)\n};\n\n/**\n * An atom representing long division\n */\nclass LongDivAtom : public VRowAtom {\nprivate:\n    long _divisor, _dividend;\n\n    void calculate(_out_ vector<wstring>& results);\n\npublic:\n    LongDivAtom() = delete;\n\n    LongDivAtom(long divisor, long dividend);\n\n    __decl_clone(LongDivAtom)\n};\n\n/**\n * An atom representing an atom with lines covered\n */\nclass CancelAtom : public Atom {\nprivate:\n    sptr<Atom> _base;\n    int _cancelType;\n\npublic:\n    enum CancelType {\n        SLASH,\n        BACKSLASH,\n        CROSS\n    };\n\n    CancelAtom() = delete;\n\n    CancelAtom(const sptr<Atom>& base, int cancelType)\n        : _base(base), _cancelType(cancelType) {}\n\n    sptr<Box> createBox(_out_ TeXEnvironment& env) override;\n\n    __decl_clone(CancelAtom)\n};\n\n}  // namespace tex\n\n#endif  // ATOM_IMPL_H_INCLUDED\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/atom/box.cpp",
    "content": "#include \"atom/box.h\"\n#include \"atom/atom_basic.h\"\n#include \"common.h\"\n#include \"core/core.h\"\n#include \"fonts/fonts.h\"\n#include \"graphic/graphic.h\"\n\n#include <utility>\n\nusing namespace std;\nusing namespace tex;\n\nbool Box::DEBUG = false;\n\n/************************************** factory implementation ************************************/\n\nsptr<Box> DelimiterFactory::create(_in_ SymbolAtom& symbol, _out_ TeXEnvironment& env, int size) {\n    if (size > 4) return symbol.createBox(env);\n\n    TeXFont& tf = *(env.getTeXFont());\n    int style = env.getStyle();\n    Char c = tf.getChar(symbol.getName(), style);\n    int i = 0;\n\n    for (int i = 1; i <= size && tf.hasNextLarger(c); i++) c = tf.getNextLarger(c, style);\n\n    if (i <= size && !tf.hasNextLarger(c)) {\n        CharBox A(tf.getChar(L'A', \"mathnormal\", style));\n        auto b = create(symbol.getName(), env, size * (A._height + A._depth));\n        return b;\n    }\n\n    return sptr<Box>(new CharBox(c));\n}\n\nsptr<Box> DelimiterFactory::create(const string& symbol, _out_ TeXEnvironment& env, float minHeight) {\n    TeXFont& tf = *(env.getTeXFont());\n    int style = env.getStyle();\n    Char c = tf.getChar(symbol, style);\n\n    // start with smallest character\n    float total = c.getHeight() + c.getDepth();\n\n    // try larger versions of the same char until min-height has been reached\n    while (total < minHeight && tf.hasNextLarger(c)) {\n        c = tf.getNextLarger(c, style);\n        total = c.getHeight() + c.getDepth();\n    }\n    // tall enough char found\n    if (total >= minHeight) {\n        /**if (total > minHeight) {\n            sptr<Box> cb(new CharBox(c));\n            float scale = minHeight / total;\n            return sptr<Box>(new ScaleBox(cb, scale));\n        }*/\n        return sptr<Box>(new CharBox(c));\n    } else if (tf.isExtensionChar(c)) {\n        // construct vertical box\n        VerticalBox* vBox = new VerticalBox();\n        Extension* ext = tf.getExtension(c, style);\n\n        // insert top part\n        if (ext->hasTop()) {\n            c = ext->getTop();\n            vBox->add(sptr<Box>(new CharBox(c)));\n        }\n\n        if (ext->hasMiddle()) {\n            c = ext->getMiddle();\n            vBox->add(sptr<Box>(new CharBox(c)));\n        }\n\n        if (ext->hasBottom()) {\n            c = ext->getBottom();\n            vBox->add(sptr<Box>(new CharBox(c)));\n        }\n\n        // insert repeatable part until tall enough\n        c = ext->getRepeat();\n        sptr<Box> rep(new CharBox(c));\n        while (vBox->_height + vBox->_depth <= minHeight) {\n            if (ext->hasTop() && ext->hasBottom()) {\n                vBox->add(1, rep);\n                if (ext->hasMiddle()) {\n                    vBox->add(vBox->getSize() - 1, rep);\n                }\n            } else if (ext->hasBottom()) {\n                vBox->add(0, rep);\n            } else {\n                vBox->add(rep);\n            }\n        }\n        delete ext;\n        return sptr<Box>(vBox);\n    }\n    // no extensions, so return the tallest possible character\n    return sptr<Box>(new CharBox(c));\n}\n\nsptr<Atom> XLeftRightArrowFactory::MINUS;\nsptr<Atom> XLeftRightArrowFactory::LEFT;\nsptr<Atom> XLeftRightArrowFactory::RIGHT;\n\nsptr<Box> XLeftRightArrowFactory::create(_out_ TeXEnvironment& env, float width) {\n    // initialize\n    if (MINUS == nullptr) {\n        MINUS = SymbolAtom::get(\"minus\");\n        LEFT = SymbolAtom::get(\"leftarrow\");\n        RIGHT = SymbolAtom::get(\"rightarrow\");\n    }\n    sptr<Box> left = LEFT->createBox(env);\n    sptr<Box> right = RIGHT->createBox(env);\n    float swidth = left->_width + right->_width;\n\n    if (width < swidth) {\n        HorizontalBox* hb = new HorizontalBox(left);\n        hb->add(sptr<Box>(new StrutBox(-min(swidth - width, left->_width), 0, 0, 0)));\n        hb->add(right);\n        return sptr<Box>(hb);\n    }\n\n    sptr<Box> minu = SmashedAtom(MINUS, \"\").createBox(env);\n    sptr<Box> kern = SpaceAtom(UNIT_MU, -3.4f, 0, 0).createBox(env);\n\n    float mwidth = minu->_width + kern->_width;\n    swidth += 2 * kern->_width;\n\n    HorizontalBox* hb = new HorizontalBox();\n    float w = 0.f;\n    for (w = 0; w < width - swidth - mwidth; w += mwidth) {\n        hb->add(minu);\n        hb->add(kern);\n    }\n\n    hb->add(sptr<Box>(new ScaleBox(minu, (width - swidth - w) / minu->_width, 1)));\n\n    hb->add(0, kern);\n    hb->add(0, left);\n    hb->add(kern);\n    hb->add(right);\n\n    return sptr<Box>(hb);\n}\n\nsptr<Box> XLeftRightArrowFactory::create(bool left, _out_ TeXEnvironment& env, float width) {\n    // initialize\n    if (MINUS == nullptr) {\n        MINUS = SymbolAtom::get(\"minus\");\n        LEFT = SymbolAtom::get(\"leftarrow\");\n        RIGHT = SymbolAtom::get(\"rightarrow\");\n    }\n    auto arr = left ? LEFT->createBox(env) : RIGHT->createBox(env);\n    float h = arr->_height;\n    float d = arr->_depth;\n\n    float swidth = arr->_width;\n    if (width <= swidth) {\n        arr->_depth = d / 2;\n        return arr;\n    }\n\n    sptr<Box> minu = SmashedAtom(MINUS, \"\").createBox(env);\n    sptr<Box> kern = SpaceAtom(UNIT_MU, -4.f, 0, 0).createBox(env);\n    float mwidth = minu->_width + kern->_width;\n    swidth += kern->_width;\n    HorizontalBox* hb = new HorizontalBox();\n    float w = 0.f;\n    for (w = 0; w < width - swidth - mwidth; w += mwidth) {\n        hb->add(minu);\n        hb->add(kern);\n    }\n\n    float sf = (width - swidth - w) / minu->_width;\n\n    hb->add(SpaceAtom(UNIT_MU, -2.f * sf, 0, 0).createBox(env));\n    hb->add(ScaleAtom(MINUS, sf, 1).createBox(env));\n\n    if (left) {\n        hb->add(0, SpaceAtom(UNIT_MU, -3.5f, 0, 0).createBox(env));\n        hb->add(0, arr);\n    } else {\n        hb->add(SpaceAtom(UNIT_MU, -2.f * sf - 2.f, 0, 0).createBox(env));\n        hb->add(arr);\n    }\n\n    hb->_depth = d / 2;\n    hb->_height = h;\n\n    return sptr<Box>(hb);\n}\n\n/************************************* horizontal box implementation ******************************/\n\nHorizontalBox::HorizontalBox(const sptr<Box>& b, float w, int aligment) {\n    if (w == POS_INF) {\n        add(b);\n        return;\n    }\n    float rest = w - b->_width;\n    if (rest <= 0) {\n        add(b);\n        return;\n    }\n    if (aligment == ALIGN_CENTER || aligment == ALIGN_NONE) {\n        sptr<Box> s(new StrutBox(rest / 2, 0, 0, 0));\n        add(s);\n        add(b);\n        add(s);\n    } else if (aligment == ALIGN_LEFT) {\n        add(b);\n        sptr<Box> s(new StrutBox(rest, 0, 0, 0));\n        add(s);\n    } else if (aligment == ALIGN_RIGHT) {\n        sptr<Box> s(new StrutBox(rest, 0, 0, 0));\n        add(s);\n        add(b);\n    } else {\n        add(b);\n    }\n}\n\nHorizontalBox::HorizontalBox(const sptr<Box>& b) {\n    add(b);\n}\n\nvoid HorizontalBox::recalculate(const Box& b) {\n    /**\n     * Commented for ticket 764\n     * \\left(\\!\\!\\!\\begin{array}{c}n\\\\\\\\r\\end{array}\\!\\!\\!\\right)+123\n     * curPos += b._width;\n     * width = max(width, curPos);\n     */\n    _width += b._width;\n    float x = _children.empty() ? NEG_INF : _height;\n    _height = max(x, b._height - b._shift);\n    x = _children.empty() ? NEG_INF : _depth;\n    _depth = max(x, b._depth + b._shift);\n}\n\nsptr<HorizontalBox> HorizontalBox::cloneBox() {\n    HorizontalBox* b = new HorizontalBox(_foreground, _background);\n    b->_shift = _shift;\n\n    return sptr<HorizontalBox>(b);\n}\n\nvoid HorizontalBox::add(const sptr<Box>& b) {\n    recalculate(*b);\n    Box::add(b);\n}\n\nvoid HorizontalBox::add(int pos, const sptr<Box>& b) {\n    recalculate(*b);\n    Box::add(pos, b);\n}\n\npair<sptr<HorizontalBox>, sptr<HorizontalBox>> HorizontalBox::split(int pos, int shift) {\n    auto hb1 = cloneBox();\n    auto hb2 = cloneBox();\n    for (int i = 0; i <= pos; i++) {\n        hb1->add(_children[i]);\n    }\n\n    for (size_t i = pos + shift; i < _children.size(); i++) {\n        hb2->add(_children[i]);\n    }\n\n    if (!_breakPositions.empty()) {\n        for (size_t i = 0; i < _breakPositions.size(); i++) {\n            if (_breakPositions[i] > pos + 1) {\n                hb2->addBreakPosition(_breakPositions[i] - pos - 1);\n            }\n        }\n    }\n\n    return make_pair(hb1, hb2);\n}\n\nvoid HorizontalBox::draw(Graphics2D& g2, float x, float y) {\n    startDraw(g2, x, y);\n    float xPos = x;\n    for (auto box : _children) {\n        box->draw(g2, xPos, y + box->_shift);\n        xPos += box->_width;\n    }\n    endDraw(g2);\n}\n\nint HorizontalBox::getLastFontId() {\n    int id = TeXFont::NO_FONT;\n    for (int i = _children.size() - 1; i >= 0 && id == TeXFont::NO_FONT; i--)\n        id = _children[i]->getLastFontId();\n    return id;\n}\n\n/********************************** horizontal rule implementation ********************************/\n\nHorizontalRule::HorizontalRule(float thickness, float width, float shift)\n    : _color(trans), _speShift(0) {\n    _height = thickness;\n    _width = width;\n    _shift = shift;\n}\n\nHorizontalRule::HorizontalRule(float thickness, float width, float shift, bool trueshift)\n    : _color(trans), _speShift(0) {\n    _height = thickness;\n    _width = width;\n    if (trueshift) {\n        _shift = shift;\n    } else {\n        _shift = 0;\n        _speShift = shift;\n    }\n}\n\nHorizontalRule::HorizontalRule(float thickness, float width, float shift, color c, bool trueshift)\n    : _color(c), _speShift(0) {\n    _height = thickness;\n    _width = width;\n    if (trueshift) {\n        _shift = shift;\n    } else {\n        _shift = 0;\n        _speShift = shift;\n    }\n}\n\nvoid HorizontalRule::draw(Graphics2D& g2, float x, float y) {\n    color oldColor = g2.getColor();\n    if (!istrans(_color)) g2.setColor(_color);\n    const Stroke& oldStroke = g2.getStroke();\n    g2.setStroke(Stroke(_height, CAP_BUTT, JOIN_BEVEL));\n    y = y - _height / 2.f - _speShift;\n    g2.drawLine(x, y, x + _width, y);\n    g2.setStroke(oldStroke);\n    g2.setColor(oldColor);\n}\n\nint HorizontalRule::getLastFontId() {\n    return TeXFont::NO_FONT;\n}\n\n/************************************* vertical box implementation ********************************/\n\nVerticalBox::VerticalBox(const sptr<Box>& b, float rest, int alignment)\n    : _leftMostPos(F_MAX), _rightMostPos(F_MIN) {\n    add(b);\n    if (alignment == ALIGN_CENTER) {\n        sptr<Box> s(new StrutBox(0, rest / 2, 0, 0));\n        Box::add(0, s);\n        _height += rest / 2.f;\n        _depth += rest / 2.f;\n        Box::add(s);\n    } else if (alignment == ALIGN_TOP) {\n        _depth += rest;\n        sptr<Box> s(new StrutBox(0, rest, 0, 0));\n        Box::add(s);\n    } else if (alignment == ALIGN_BOTTOM) {\n        _height += rest;\n        sptr<Box> s(new StrutBox(0, rest, 0, 0));\n        Box::add(0, s);\n    }\n}\n\nvoid VerticalBox::recalculateWidth(const Box& b) {\n    _leftMostPos = min(_leftMostPos, b._shift);\n    _rightMostPos = max(_rightMostPos, b._shift + (b._width > 0 ? b._width : 0));\n    _width = _rightMostPos - _leftMostPos;\n}\n\nvoid VerticalBox::add(const sptr<Box>& b) {\n    Box::add(b);\n    if (_children.size() == 1) {\n        _height = b->_height;\n        _depth = b->_depth;\n    } else {\n        _depth += b->_height + b->_depth;\n    }\n    recalculateWidth(*b);\n}\n\nvoid VerticalBox::add(const sptr<Box>& b, float interline) {\n    if (_children.size() >= 1) {\n        sptr<Box> s(new StrutBox(0, interline, 0, 0));\n        add(s);\n    }\n    add(b);\n}\n\nvoid VerticalBox::add(int pos, const sptr<Box>& b) {\n    Box::add(pos, b);\n    if (pos == 0) {\n        _depth += b->_depth + _height;\n        _height = b->_height;\n    } else {\n        _depth += b->_height + b->_depth;\n    }\n    recalculateWidth(*b);\n}\n\nvoid VerticalBox::draw(Graphics2D& g2, float x, float y) {\n    float yPos = y - _height;\n    for (auto b : _children) {\n        yPos += b->_height;\n        b->draw(g2, x + b->_shift - _leftMostPos, yPos);\n        yPos += b->_depth;\n    }\n}\n\nint VerticalBox::getLastFontId() {\n    int id = TeXFont::NO_FONT;\n    for (int i = _children.size() - 1; i >= 0 && id == TeXFont::NO_FONT; i--)\n        id = _children[i]->getLastFontId();\n    return id;\n}\n\nOverBar::OverBar(const sptr<Box>& b, float kern, float thickness) : VerticalBox() {\n    add(sptr<Box>(new StrutBox(0, thickness, 0, 0)));\n    add(sptr<Box>(new HorizontalRule(thickness, b->_width, 0)));\n    add(sptr<Box>(new StrutBox(0, kern, 0, 0)));\n    add(b);\n}\n\n/************************************ over-under box implementation *******************************/\n\nOverUnderBox::OverUnderBox(\n    const sptr<Box>& b,\n    const sptr<Box>& d,\n    const sptr<Box>& script, float kern, bool over) {\n    _base = b;\n    _del = d;\n    _script = script;\n    _kern = kern;\n    _over = over;\n    // calculate metrics of the box\n    _width = b->_width;\n    float x = (over && script != nullptr ? script->_height + script->_depth + kern : 0);\n    _height = b->_height + (over ? d->_width : 0) + x;\n    x = (!over && script != nullptr ? script->_height + script->_depth + kern : 0);\n    _depth = b->_depth + (over ? 0 : d->_width) + x;\n}\n\nvoid OverUnderBox::draw(Graphics2D& g2, float x, float y) {\n    drawDebug(g2, x, y);\n    _base->draw(g2, x, y);\n\n    float yVar = y - _base->_height - _del->_width;\n    _del->_depth += _del->_height;\n    _del->_height = 0;\n    float tx = x + (_del->_height + _del->_depth) * 0.75f;\n    // draw delimiter and script above base box\n    if (_over) {\n        float ty = yVar;\n        g2.translate(tx, ty);\n        g2.rotate(PI / 2);\n        _del->draw(g2, 0, 0);\n        // reset\n        g2.rotate(-PI / 2);\n        g2.translate(-tx, -ty);\n        // draw superscript\n        if (_script != nullptr) _script->draw(g2, x, yVar - _kern - _script->_depth);\n        return;\n    }\n    yVar = y + _base->_depth;\n    float ty = yVar;\n    g2.translate(tx, ty);\n    g2.rotate(PI / 2);\n    _del->draw(g2, 0, 0);\n    // reset\n    g2.rotate(-PI / 2);\n    g2.translate(-tx, -ty);\n    yVar += _del->_width;\n    // draw subscript\n    if (_script != nullptr) _script->draw(g2, x, yVar + _kern + _script->_height);\n}\n\nint OverUnderBox::getLastFontId() {\n    return _base->getLastFontId();\n}\n\nvector<sptr<Box>> OverUnderBox::getChildren() const {\n    return {_base, _del, _script};\n}\n\n/*************************************** scale box implementation *********************************/\n\nvoid ScaleBox::init(const sptr<Box>& b, float sx, float sy) {\n    _factor = 1;\n    _box = b;\n    _sx = (isnan(sx) || isinf(sx)) ? 1 : sx;\n    _sy = (isnan(sy) || isinf(sy)) ? 1 : sy;\n    _width = b->_width * abs(_sx);\n    _height = _sy > 0 ? b->_height * _sy : -b->_depth * _sy;\n    _depth = _sy > 0 ? b->_depth * _sy : -b->_height * _sy;\n    _shift = b->_shift * _sy;\n}\n\nvoid ScaleBox::draw(Graphics2D& g2, float x, float y) {\n    drawDebug(g2, x, y);\n    if (_sx != 0 && _sy != 0) {\n        float dec = _sx < 0 ? _width : 0;\n        g2.translate(x + dec, y);\n        g2.scale(_sx, _sy);\n        _box->draw(g2, 0, 0);\n        g2.scale(1.f / _sx, 1.f / _sy);\n        g2.translate(-x - dec, -y);\n    }\n}\n\nint ScaleBox::getLastFontId() {\n    return _box->getLastFontId();\n}\n\nvector<sptr<Box>> ScaleBox::getChildren() const {\n    return {_box};\n}\n\n/************************************** reflect box implementation ********************************/\n\nReflectBox::ReflectBox(const sptr<Box>& b) {\n    _box = b;\n    _width = b->_width;\n    _height = b->_height;\n    _depth = b->_depth;\n    _shift = b->_shift;\n}\n\nvoid ReflectBox::draw(Graphics2D& g2, float x, float y) {\n    drawDebug(g2, x, y);\n    g2.translate(x, y);\n    g2.scale(-1, 1);\n    _box->draw(g2, -_width, 0);\n    g2.scale(-1, 1);\n    g2.translate(-x, -y);\n}\n\nint ReflectBox::getLastFontId() {\n    return _box->getLastFontId();\n}\n\nvector<sptr<Box>> ReflectBox::getChildren() const {\n    return {_box};\n}\n\n/************************************** rotate box implementation *********************************/\n\nvoid RotateBox::init(const sptr<Box>& b, float angle, float x, float y) {\n    _box = b;\n    _angle = angle * PI / 180;\n    _height = b->_height;\n    _depth = b->_depth;\n    _width = b->_width;\n    float s = sin(_angle);\n    float c = cos(_angle);\n    _shiftX = x * (1 - c) + y * s;\n    _shiftY = y * (1 - c) - x * s;\n\n    _xmax = max(-_height * s,\n                max(_depth * s,\n                    max(_width * c + _depth * s, _width * c - _height * s))) +\n            _shiftX;\n    _xmin = min(-_height * s,\n                min(_depth * s,\n                    min(_width * c + _depth * s, _width * c - _height * s))) +\n            _shiftX;\n\n    _ymax = max(_height * c,\n                max(-_depth * c,\n                    max(_width * s - _depth * c, _width * s + _height * c)));\n    _ymin = min(_height * c,\n                min(-_depth * c,\n                    min(_width * s - _depth * c, _width * s + _height * c)));\n\n    _width = _xmax - _xmin;\n    _height = _ymax + _shiftY;\n    _depth = -_ymin - _shiftY;\n}\n\nPoint RotateBox::calculateShift(const Box& b, int option) {\n    Point p(0, -b._depth);\n    switch (option) {\n    case BL:\n        p.x = 0;\n        p.y = -b._depth;\n        break;\n    case BR:\n        p.x = b._width;\n        p.y = -b._depth;\n        break;\n    case BC:\n        p.x = b._width / 2.f;\n        p.y = -b._depth;\n        break;\n    case TL:\n        p.x = 0;\n        p.y = b._height;\n        break;\n    case TR:\n        p.x = b._width;\n        p.y = b._height;\n        break;\n    case TC:\n        p.x = b._width / 2.f;\n        p.y = b._height;\n        break;\n    case BBL:\n        p.x = 0;\n        p.y = 0;\n        break;\n    case BBR:\n        p.x = b._width;\n        p.y = 0;\n        break;\n    case BBC:\n        p.x = b._width / 2.f;\n        p.y = 0;\n        break;\n    case CL:\n        p.x = 0;\n        p.y = (b._height - b._depth) / 2.f;\n        break;\n    case CR:\n        p.x = b._width;\n        p.y = (b._height - b._depth) / 2.f;\n        break;\n    case CC:\n        p.x = b._width / 2.f;\n        p.y = (b._height - b._depth) / 2.f;\n        break;\n    default:\n        break;\n    }\n    return p;\n}\n\nint RotateBox::getOrigin(string option) {\n    if (option.empty()) return BBL;\n    if (option.size() == 1) option += \"c\";\n\n    if (option == \"bl\" || option == \"lb\") return BL;\n    if (option == \"bc\" || option == \"cb\") return BC;\n    if (option == \"br\" || option == \"rb\") return BR;\n    if (option == \"cl\" || option == \"lc\") return CL;\n    if (option == \"cc\") return CC;\n    if (option == \"cr\" || option == \"rc\") return CR;\n    if (option == \"tl\" || option == \"lt\") return TL;\n    if (option == \"tc\" || option == \"ct\") return TC;\n    if (option == \"tr\" || option == \"rt\") return TR;\n    if (option == \"Bl\" || option == \"lB\") return BBL;\n    if (option == \"Bc\" || option == \"cB\") return BBC;\n    if (option == \"Br\" || option == \"rB\") return BBR;\n    return BBL;\n}\n\nvoid RotateBox::draw(Graphics2D& g2, float x, float y) {\n    drawDebug(g2, x, y);\n    y -= _shiftY;\n    x += _shiftX - _xmin;\n    g2.rotate(-_angle, x, y);\n    _box->draw(g2, x, y);\n    g2.rotate(_angle, x, y);\n}\n\nint RotateBox::getLastFontId() {\n    return _box->getLastFontId();\n}\n\nvector<sptr<Box>> RotateBox::getChildren() const {\n    return {_box};\n}\n\n/************************************* framed box implementation **********************************/\n\nvoid FramedBox::init(const sptr<Box>& box, float thickness, float space) {\n    _line = trans;\n    _bg = trans;\n    _box = box;\n    const Box& b = *box;\n    _width = b._width + 2 * thickness + 2 * space;\n    _height = b._height + thickness + space;\n    _depth = b._depth + thickness + space;\n    _shift = b._shift;\n    _thickness = thickness;\n    _space = space;\n}\n\nvoid FramedBox::draw(Graphics2D& g2, float x, float y) {\n    const Stroke& st = g2.getStroke();\n    g2.setStroke(Stroke(_thickness, CAP_BUTT, JOIN_MITER));\n    float th = _thickness / 2.f;\n    if (!istrans(_bg)) {\n        color prev = g2.getColor();\n        g2.setColor(_bg);\n        g2.fillRect(x + th, y - _height + th, _width - _thickness, _height + _depth - _thickness);\n        g2.setColor(prev);\n    }\n    if (!istrans(_line)) {\n        color prev = g2.getColor();\n        g2.setColor(_line);\n        g2.drawRect(x + th, y - _height + th, _width - _thickness, _height + _depth - _thickness);\n        g2.setColor(prev);\n    } else {\n        g2.drawRect(x + th, y - _height + th, _width - _thickness, _height + _depth - _thickness);\n    }\n    g2.setStroke(st);\n    _box->draw(g2, x + _space + _thickness, y);\n}\n\nint FramedBox::getLastFontId() {\n    return _box->getLastFontId();\n}\n\nvector<sptr<Box>> FramedBox::getChildren() const {\n    return {_box};\n}\n\nvoid OvalBox::draw(Graphics2D& g2, float x, float y) {\n    _box->draw(g2, x + _space + _thickness, y);\n    const Stroke& st = g2.getStroke();\n    g2.setStroke(Stroke(_thickness, CAP_BUTT, JOIN_MITER));\n    float th = _thickness / 2.f;\n    float r = 0.f;\n    if (_diameter != 0)\n        r = _diameter;\n    else\n        r = _multiplier * min(_width - _thickness, _height + _depth - _thickness);\n    g2.drawRoundRect(\n        x + th,\n        y - _height + th,\n        _width - _thickness,\n        _height + _depth - _thickness, r, r);\n    g2.setStroke(st);\n}\n\nvoid ShadowBox::draw(Graphics2D& g2, float x, float y) {\n    float th = _thickness / 2.f;\n    _box->draw(g2, x + _space + _thickness, y);\n    const Stroke& st = g2.getStroke();\n    g2.setStroke(Stroke(_thickness, CAP_BUTT, JOIN_MITER));\n    g2.drawRect(\n        x + th,\n        y - _height + th,\n        _width - _shadowRule - _thickness,\n        _height + _depth - _shadowRule - _thickness);\n    float penth = abs(1.f / g2.sx());\n    g2.setStroke(Stroke(penth, CAP_BUTT, JOIN_MITER));\n    g2.fillRect(\n        x + _shadowRule - penth,\n        y + _depth - _shadowRule - penth,\n        _width - _shadowRule,\n        _shadowRule);\n    g2.fillRect(\n        x + _width - _shadowRule - penth,\n        y - _height + th + _shadowRule,\n        _shadowRule,\n        _depth + _height - 2 * _shadowRule - th);\n    g2.setStroke(st);\n}\n\n/************************************** basic box implementation **********************************/\n\nint StrutBox::getLastFontId() {\n    return TeXFont::NO_FONT;\n}\n\nint GlueBox::getLastFontId() {\n    return TeXFont::NO_FONT;\n}\n\nCharBox::CharBox(const Char& c) {\n    _cf = c.getCharFont();\n    _size = c.getSize();\n    _width = c.getWidth();\n    _height = c.getHeight();\n    _depth = c.getDepth();\n    _italic = c.getItalic();\n}\n\nvoid CharBox::addItalicCorrectionToWidth() {\n    _width += _italic;\n    _italic = 0;\n}\n\nvoid CharBox::draw(Graphics2D& g2, float x, float y) {\n    startDraw(g2, x, y);\n    g2.translate(x, y);\n    const Font* font = FontInfo::getFont(_cf->_fontId);\n    if (_size != 1) g2.scale(_size, _size);\n    if (g2.getFont() != font) g2.setFont(font);\n    g2.drawChar(_cf->_c, 0, 0);\n    // reset\n    if (_size != 1) g2.scale(1.f / _size, 1.f / _size);\n    g2.translate(-x, -y);\n    endDraw(g2);\n}\n\nint CharBox::getLastFontId() {\n    return _cf->_fontId;\n}\n\nsptr<Font> TextRenderingBox::_font(nullptr);\n\nvoid TextRenderingBox::_init_() {\n    _font = Font::_create(\"Serif\", PLAIN, 10);\n}\n\nvoid TextRenderingBox::_free_() {\n    // For memory check purpose\n    // to check if has memory leak\n    _font = nullptr;\n}\n\nvoid TextRenderingBox::setFont(const string& name) {\n    _font = Font::_create(name, PLAIN, 10);\n}\n\nvoid TextRenderingBox::init(\n    const wstring& str, int type, float size, const sptr<Font>& f, bool kerning) {\n    _size = size;\n    _layout = TextLayout::create(str, f->deriveFont(type));\n    Rect rect;\n    _layout->getBounds(rect);\n    _height = -rect.y * size / 10;\n    _depth = rect.h * size / 10 - _height;\n    _width = (rect.w + rect.x + 0.4f) * size / 10;\n}\n\nvoid TextRenderingBox::draw(Graphics2D& g2, float x, float y) {\n    drawDebug(g2, x, y);\n    g2.translate(x, y);\n    g2.scale(0.1f * _size, 0.1f * _size);\n    _layout->draw(g2, 0, 0);\n    g2.scale(10 / _size, 10 / _size);\n    g2.translate(-x, -y);\n}\n\nint TextRenderingBox::getLastFontId() {\n    return 0;\n}\n\nvoid WrapperBox::setInsets(float l, float t, float r, float b) {\n    _l += l;\n    _width += l + r;\n    _height += t;\n    _depth += b;\n}\n\nvoid WrapperBox::draw(Graphics2D& g2, float x, float y) {\n    startDraw(g2, x, y);\n    _base->draw(g2, x + _l, y + _base->_shift);\n    endDraw(g2);\n}\n\nint WrapperBox::getLastFontId() {\n    return _base->getLastFontId();\n}\n\nvector<sptr<Box>> WrapperBox::getChildren() const {\n    return {_base};\n}\n\nvoid ShiftBox::draw(Graphics2D& g2, float x, float y) {\n    drawDebug(g2, x, y);\n    _base->draw(g2, x, y + _sf);\n}\n\nint ShiftBox::getLastFontId() {\n    return _base->getLastFontId();\n}\n\nvector<sptr<Box>> ShiftBox::getChildren() const {\n    return {_base};\n}\n\nLineBox::LineBox(const vector<float> lines, float thickness) {\n    _thickness = thickness;\n    if (lines.size() % 4 != 0) throw ex_invalid_param(\"The vector not represent lines.\");\n    _lines = lines;\n}\n\nvoid LineBox::draw(Graphics2D& g2, float x, float y) {\n    const float oldThickness = g2.getStroke().lineWidth;\n    g2.setStrokeWidth(_thickness);\n    g2.translate(0, -_height);\n    int count = _lines.size() / 4;\n    for (int i = 0; i < count; i++) {\n        int j = i * 4;\n        float x1 = _lines[j] + x, y1 = _lines[j + 1] + y;\n        float x2 = _lines[j + 2] + x, y2 = _lines[j + 3] + y;\n        g2.drawLine(x1, y1, x2, y2);\n    }\n    g2.translate(0, _height);\n    g2.setStrokeWidth(oldThickness);\n}\n\nint LineBox::getLastFontId() {\n    return 0;\n}\n\nvoid OverlappedBox::draw(Graphics2D& g2, float x, float y) {\n    _base->draw(g2, x, y);\n    _overlap->draw(g2, x, y);\n}\n\nint OverlappedBox::getLastFontId() {\n    return _base->getLastFontId();\n}\n\nvector<sptr<Box>> OverlappedBox::getChildren() const {\n    return {_base, _overlap};\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/atom/box.h",
    "content": "#ifndef BOX_H_INCLUDED\n#define BOX_H_INCLUDED\n\n#include \"atom/atom.h\"\n\n#include <stack>\n\nusing namespace tex;\n\nnamespace tex {\n\nclass Char;\nclass CharFont;\nclass TeXFont;\nclass SymbolAtom;\n\n/***************************************************************************************************\n *                              factories to create boxes                                          *\n ***************************************************************************************************/\n\n/**\n * Responsible for creating a box containing a delimiter symbol that exists in\n * different sizes.\n */\nclass DelimiterFactory {\npublic:\n    static sptr<Box> create(_in_ SymbolAtom& symbol, _out_ TeXEnvironment& env, int size);\n\n    /**\n     * Create a delimiter with specified symbol name and min height\n     *\n     * @param symbol\n     *      the name of the delimiter symbol\n     * @param env\n     *      the TeXEnvironment in which to create the delimiter box\n     * @param minHeight\n     *      the minimum required total height of the box (height + depth).\n     * @return the box representing the delimiter variant that fits best\n     *      according to the required minimum size.\n     */\n    static sptr<Box> create(const string& symbol, _out_ TeXEnvironment& env, float minHeight);\n};\n\n/**\n * Responsible for creating a box containing a delimiter symbol that exists in\n * different sizes.\n */\nclass XLeftRightArrowFactory {\nprivate:\n    static sptr<Atom> MINUS;\n    static sptr<Atom> LEFT;\n    static sptr<Atom> RIGHT;\n\npublic:\n    static sptr<Box> create(bool left, _out_ TeXEnvironment& env, float width);\n\n    static sptr<Box> create(_out_ TeXEnvironment& env, float width);\n};\n\n/***************************************************************************************************\n *                                        rule boxes                                               *\n ***************************************************************************************************/\n\n/**\n * A box composed of a horizontal row of child boxes\n */\nclass HorizontalBox : public Box {\nprivate:\n    void recalculate(const Box& b);\n\n    pair<sptr<HorizontalBox>, sptr<HorizontalBox>> split(int pos, int shift);\n\npublic:\n    vector<int> _breakPositions;\n\n    HorizontalBox() {}\n\n    HorizontalBox(color fg, color bg) : Box(fg, bg) {}\n\n    HorizontalBox(const sptr<Box>& b, float w, int alignment);\n\n    HorizontalBox(const sptr<Box>& b);\n\n    sptr<HorizontalBox> cloneBox();\n\n    void add(const sptr<Box>& b) override;\n\n    void add(int pos, const sptr<Box>& b) override;\n\n    inline void addBreakPosition(int pos) {\n        _breakPositions.push_back(pos);\n    }\n\n    pair<sptr<HorizontalBox>, sptr<HorizontalBox>> split(int pos) {\n        return split(pos, 1);\n    }\n\n    pair<sptr<HorizontalBox>, sptr<HorizontalBox>> splitRemove(int pos) {\n        return split(pos, 2);\n    }\n\n    void draw(Graphics2D& g2, float x, float y) override;\n\n    int getLastFontId() override;\n};\n\n/**\n * A box composed of other boxes, put one above the other\n */\nclass VerticalBox : public Box {\nprivate:\n    float _leftMostPos, _rightMostPos;\n\n    void recalculateWidth(const Box& b);\n\npublic:\n    VerticalBox() : _leftMostPos(F_MAX), _rightMostPos(F_MIN) {}\n\n    VerticalBox(const sptr<Box>& b, float rest, int alignment);\n\n    void add(const sptr<Box>& b) override;\n\n    void add(const sptr<Box>& b, float interline);\n\n    void add(int pos, const sptr<Box>& b) override;\n\n    inline int getSize() const {\n        return _children.size();\n    }\n\n    void draw(Graphics2D& g2, float x, float y) override;\n\n    int getLastFontId() override;\n};\n\n/**\n * A box representing another box with a horizontal rule above it, with\n * appropriate kerning.\n */\nclass OverBar : public VerticalBox {\npublic:\n    OverBar() = delete;\n\n    OverBar(const sptr<Box>& b, float kern, float thickness);\n};\n\n/**\n * A box representing another box with a delimiter box and a script box above or\n * under it, with script and delimiter separated by a kerning.\n */\nclass OverUnderBox : public Box {\nprivate:\n    // base, delimiter and script\n    sptr<Box> _base, _del, _script;\n    // kerning amount between the delimiter and the script\n    float _kern;\n    // whether the delimiter should be drawn over (<->under) the base box\n    bool _over;\n\npublic:\n    OverUnderBox() = delete;\n\n    /**\n     * The parameter boxes must have an equal width!!\n     *\n     * @param base\n     *      base box to be drawn on the baseline\n     * @param del\n     *      delimiter box\n     * @param script\n     *      subscript or superscript box\n     * @param kern\n     *      the kerning amount to draw\n     * @param over\n     *      true : draws delimiter and script box above the base box,\n     *      false : under the base box\n     */\n    OverUnderBox(\n        const sptr<Box>& base, const sptr<Box>& del,\n        const sptr<Box>& script, float kern, bool over);\n\n    void draw(Graphics2D& g2, float x, float y) override;\n\n    int getLastFontId() override;\n\n    vector<sptr<Box>> getChildren() const override;\n};\n\n/**\n * A box representing a horizontal line.\n */\nclass HorizontalRule : public Box {\nprivate:\n    color _color;\n    float _speShift;\n\npublic:\n    HorizontalRule() = delete;\n\n    HorizontalRule(float thickness, float width, float shift);\n\n    HorizontalRule(float thickness, float width, float shift, bool trueShift);\n\n    HorizontalRule(float thickness, float width, float shift, color c, bool trueshift);\n\n    void draw(Graphics2D& g2, float x, float y) override;\n\n    int getLastFontId() override;\n};\n\n/***************************************************************************************************\n *                                   operation boxes                                               *\n ***************************************************************************************************/\n\n/**\n * A box representing a scale operation\n */\nclass ScaleBox : public Box {\nprivate:\n    sptr<Box> _box;\n    float _sx, _sy;\n    float _factor;\n\n    void init(const sptr<Box>& b, float sx, float sy);\n\npublic:\n    ScaleBox() = delete;\n\n    ScaleBox(const sptr<Box>& b, float sx, float sy) {\n        init(b, sx, sy);\n    }\n\n    ScaleBox(const sptr<Box>& b, float factor) {\n        init(b, factor, factor);\n        _factor = factor;\n    }\n\n    void draw(Graphics2D& g2, float x, float y) override;\n\n    int getLastFontId() override;\n\n    vector<sptr<Box>> getChildren() const override;\n};\n\n/**\n * A box representing a reflected box\n */\nclass ReflectBox : public Box {\nprivate:\n    sptr<Box> _box;\n\npublic:\n    ReflectBox() = delete;\n\n    ReflectBox(const sptr<Box>& b);\n\n    void draw(Graphics2D& g2, float x, float y) override;\n\n    int getLastFontId() override;\n\n    vector<sptr<Box>> getChildren() const override;\n};\n\n/**\n * Enumeration representing rotation origin\n */\nenum Rotation {\n    // Bottom Left\n    BL,\n    // Bottom Center\n    BC,\n    // Bottom Right\n    BR,\n    // Top Left\n    TL,\n    // Top Center\n    TC,\n    // Top Right\n    TR,\n    // Bottom Bottom Left\n    BBL,\n    // Bottom Bottom Right\n    BBR,\n    // Bottom Bottom Center\n    BBC,\n    // Center Left\n    CL,\n    // Center Center\n    CC,\n    // Center Right\n    CR\n};\n\n/**\n * A box representing a rotate operation\n */\nclass RotateBox : public Box {\nprivate:\n    sptr<Box> _box;\n    float _angle;\n    float _xmax, _xmin, _ymax, _ymin;\n    int _option;\n    float _shiftX, _shiftY;\n\n    void init(const sptr<Box>& b, float angle, float x, float y);\n\n    static Point calculateShift(const Box& b, int option);\n\npublic:\n    RotateBox() = delete;\n\n    RotateBox(const sptr<Box>& b, float angle, float x, float y) {\n        init(b, angle, x, y);\n    }\n\n    RotateBox(const sptr<Box>& b, float angle, const Point& origin) {\n        init(b, angle, origin.x, origin.y);\n    }\n\n    RotateBox(const sptr<Box>& b, float angle, int option) {\n        const Point& p = calculateShift(*b, option);\n        init(b, angle, p.x, p.y);\n    }\n\n    void draw(Graphics2D& g2, float x, float y) override;\n\n    int getLastFontId() override;\n\n    vector<sptr<Box>> getChildren() const override;\n\n    static int getOrigin(string option);\n};\n\n/***************************************************************************************************\n *                                  wrapped boxes                                                  *\n ***************************************************************************************************/\n\n/**\n * A box representing a wrapped box by square frame\n */\nclass FramedBox : public Box {\npublic:\n    sptr<Box> _box;\n    float _thickness;\n    float _space;\n    color _line;\n    color _bg;\n\n    void init(const sptr<Box>& box, float thickness, float space);\n\npublic:\n    FramedBox() = delete;\n\n    FramedBox(const sptr<Box>& box, float thickness, float space) {\n        init(box, thickness, space);\n    }\n\n    FramedBox(const sptr<Box>& box, float thickness, float space, color line, color bg) {\n        init(box, thickness, space);\n        _line = line;\n        _bg = bg;\n    }\n\n    virtual void draw(Graphics2D& g2, float x, float y) override;\n\n    int getLastFontId() override;\n\n    vector<sptr<Box>> getChildren() const override;\n};\n\n/**\n * A box representing a wrapped box by oval frame\n */\nclass OvalBox : public FramedBox {\nprivate:\n    float _multiplier, _diameter;\n\npublic:\n    OvalBox() = delete;\n\n    OvalBox(\n        const sptr<FramedBox>& fbox,\n        float multiplier = 0.5f,\n        float diameter = 0.f)\n        : FramedBox(fbox->_box, fbox->_thickness, fbox->_space),\n          _multiplier(multiplier),\n          _diameter(diameter) {}\n\n    void draw(Graphics2D& g2, float x, float y) override;\n};\n\n/**\n * A box representing a wrapped box by shadowed frame\n */\nclass ShadowBox : public FramedBox {\nprivate:\n    float _shadowRule;\n\npublic:\n    ShadowBox() = delete;\n\n    ShadowBox(const sptr<FramedBox>& fbox, float shadowRule)\n        : FramedBox(fbox->_box, fbox->_thickness, fbox->_space) {\n        _shadowRule = shadowRule;\n        _depth += shadowRule;\n        _width += shadowRule;\n    }\n\n    void draw(Graphics2D& g2, float x, float y) override;\n};\n\n/***************************************************************************************************\n *                                      basic boxes                                                *\n ***************************************************************************************************/\n\n/**\n * A box representing whitespace\n */\nclass StrutBox : public Box {\npublic:\n    StrutBox() = delete;\n\n    StrutBox(float w, float h, float d, float s) {\n        _width = w;\n        _height = h;\n        _depth = d;\n        _shift = s;\n    }\n\n    void draw(Graphics2D& g2, float x, float y) override {\n        // no visual effect\n    }\n\n    int getLastFontId() override;\n};\n\n/**\n * A box representing glue\n */\nclass GlueBox : public Box {\npublic:\n    float _stretch, _shrink;\n\n    GlueBox() = delete;\n\n    GlueBox(float space, float stretch, float shrink) {\n        _width = space;\n        _stretch = stretch;\n        _shrink = shrink;\n    }\n\n    void draw(Graphics2D& g2, float x, float y) override {\n        // no visual effect\n    }\n\n    int getLastFontId() override;\n};\n\n/**\n * A box representing a single character\n */\nclass CharBox : public Box {\nprivate:\n    sptr<CharFont> _cf;\n    float _size;\n    float _italic;\n\npublic:\n    CharBox() = delete;\n\n    /**\n     * Create a new CharBox that will represent the character defined by the\n     * given Char-object.\n     *\n     * @param c\n     *      a Char-object containing the character's font information.\n     */\n    CharBox(const Char& c);\n\n    void addItalicCorrectionToWidth();\n\n    void draw(Graphics2D& g2, float x, float y) override;\n\n    int getLastFontId() override;\n};\n\n/**\n * A box representing a text rendering box\n */\nclass TextRenderingBox : public Box {\nprivate:\n    static sptr<Font> _font;\n    sptr<TextLayout> _layout;\n    float _size;\n\n    void init(const wstring& str, int type, float size, const sptr<Font>& f, bool kerning);\n\npublic:\n    TextRenderingBox() = delete;\n\n    TextRenderingBox(const wstring& str, int type, float size, const sptr<Font>& f, bool kerning) {\n        init(str, type, size, f, kerning);\n    }\n\n    TextRenderingBox(const wstring& str, int type, float size) {\n        init(str, type, size, sptr<Font>(_font), true);\n    }\n\n    void draw(Graphics2D& g2, float x, float y) override;\n\n    int getLastFontId() override;\n\n    static void setFont(const string& name);\n\n    static void _init_();\n\n    static void _free_();\n};\n\n/**\n * A box representing 'wrapper' that with insets in left, top, right and bottom\n */\nclass WrapperBox : public Box {\nprivate:\n    sptr<Box> _base;\n    float _l;\n\npublic:\n    WrapperBox() = delete;\n\n    WrapperBox(const sptr<Box>& base) : _base(base), _l(0) {\n        _height = _base->_height;\n        _depth = _base->_depth;\n        _width = _base->_width;\n    }\n\n    WrapperBox(const sptr<Box>& base, float width, float rowheight, float rowdepth, float align)\n        : _base(base), _l(0) {\n        _height = rowheight;\n        _depth = rowdepth;\n        _width = width;\n        if (base->_width < 0) _width += base->_width;\n        if (align == ALIGN_RIGHT) {\n            _l = width - _base->_width;\n        } else if (align == ALIGN_CENTER) {\n            _l = (width - _base->_width) / 2.f;\n        }\n    }\n\n    void setInsets(float l, float t, float r, float b);\n\n    void draw(Graphics2D& g2, float x, float y) override;\n\n    int getLastFontId() override;\n\n    vector<sptr<Box>> getChildren() const override;\n};\n\n/**\n * Class representing a box that shifted up or down (when shift is negative)\n */\nclass ShiftBox : public Box {\nprivate:\n    float _sf;\n    sptr<Box> _base;\n\npublic:\n    ShiftBox() = delete;\n\n    ShiftBox(const sptr<Box>& base, float shift) : _base(base), _sf(shift) {}\n\n    void draw(Graphics2D& g2, float x, float y) override;\n\n    int getLastFontId() override;\n\n    vector<sptr<Box>> getChildren() const override;\n};\n\n/**\n * Class represents several lines\n */\nclass LineBox : public Box {\nprivate:\n    // Every 4 elements represent a line, thus (x1, y1, x2, y2)\n    vector<float> _lines;\n    float _thickness;\n    int _lineCount;\n\npublic:\n    LineBox() = delete;\n\n    LineBox(const vector<float> lines, float thickness);\n\n    void draw(Graphics2D& g2, float x, float y) override;\n\n    int getLastFontId() override;\n};\n\n/**\n * Class representing a box covered by another box\n */\nclass OverlappedBox : public Box {\nprivate:\n    sptr<Box> _base;\n    sptr<Box> _overlap;\n\npublic:\n    OverlappedBox() = delete;\n\n    OverlappedBox(const sptr<Box> base, const sptr<Box> overlap)\n        : _base(base), _overlap(overlap) {\n        _width = base->_width;\n        _height = base->_height;\n        _depth = base->_depth;\n        _shift = base->_shift;\n        _type = base->_type;\n    }\n\n    void draw(Graphics2D& g2, float x, float y) override;\n\n    int getLastFontId() override;\n\n    vector<sptr<Box>> getChildren() const override;\n};\n\n}  // namespace tex\n\n#endif  // BOX_H_INCLUDED\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/atom/colors_def.cpp",
    "content": "#include \"atom_basic.h\"\n\n#define c(name, c, m, y, k) \\\n    { name, cmyk(c, m, y, k) }\n\nmap<string, color> tex::ColorAtom::_colors = {\n    {\"black\", black},\n    {\"white\", white},\n    {\"red\", red},\n    {\"green\", green},\n    {\"blue\", blue},\n    {\"cyan\", cyan},\n    {\"magenta\", magenta},\n    {\"yellow\", yellow},\n    c(\"greenyellow\", 0.15f, 0.f, 0.69f, 0.f),\n    c(\"goldenrod\", 0.f, 0.10f, 0.84f, 0.f),\n    c(\"dandelion\", 0.f, 0.29f, 0.84f, 0.f),\n    c(\"apricot\", 0.f, 0.32f, 0.52f, 0.f),\n    c(\"peach\", 0.f, 0.50f, 0.70f, 0.f),\n    c(\"melon\", 0.f, 0.46f, 0.50f, 0.f),\n    c(\"yelloworange\", 0.f, 0.42f, 1.f, 0.f),\n    c(\"orange\", 0.f, 0.61f, 0.87f, 0.f),\n    c(\"burntorange\", 0.f, 0.51f, 1.f, 0.f),\n    c(\"bittersweet\", 0.f, 0.75f, 1.f, 0.24f),\n    c(\"redorange\", 0.f, 0.77f, 0.87f, 0.f),\n    c(\"mahogany\", 0.f, 0.85f, 0.87f, 0.35f),\n    c(\"maroon\", 0.f, 0.87f, 0.68f, 0.32f),\n    c(\"brickred\", 0.f, 0.89f, 0.94f, 0.28f),\n    c(\"orangered\", 0.f, 1.f, 0.50f, 0.f),\n    c(\"rubinered\", 0.f, 1.f, 0.13f, 0.f),\n    c(\"wildstrawberry\", 0.f, 0.96f, 0.39f, 0.f),\n    c(\"salmon\", 0.f, 0.53f, 0.38f, 0.f),\n    c(\"carnationpink\", 0.f, 0.63f, 0.f, 0.f),\n    c(\"magenta\", 0.f, 1.f, 0.f, 0.f),\n    c(\"violetred\", 0.f, 0.81f, 0.f, 0.f),\n    c(\"rhodamine\", 0.f, 0.82f, 0.f, 0.f),\n    c(\"mulberry\", 0.34f, 0.90f, 0.f, 0.02f),\n    c(\"redviolet\", 0.07f, 0.90f, 0.f, 0.34f),\n    c(\"fuchsia\", 0.47f, 0.91f, 0.f, 0.08f),\n    c(\"lavender\", 0.f, 0.48f, 0.f, 0.f),\n    c(\"thistle\", 0.12f, 0.59f, 0.f, 0.f),\n    c(\"orchid\", 0.32f, 0.64f, 0.f, 0.f),\n    c(\"darkorchid\", 0.40f, 0.80f, 0.20f, 0.f),\n    c(\"purple\", 0.45f, 0.86f, 0.f, 0.f),\n    c(\"plum\", 0.50f, 1.f, 0.f, 0.f),\n    c(\"violet\", 0.79f, 0.88f, 0.f, 0.f),\n    c(\"royalpurple\", 0.75f, 0.90f, 0.f, 0.f),\n    c(\"blueviolet\", 0.86f, 0.91f, 0.f, 0.04f),\n    c(\"periwinkle\", 0.57f, 0.55f, 0.f, 0.f),\n    c(\"cadetblue\", 0.62f, 0.57f, 0.23f, 0.f),\n    c(\"cornflowerblue\", 0.65f, 0.13f, 0.f, 0.f),\n    c(\"midnightblue\", 0.98f, 0.13f, 0.f, 0.43f),\n    c(\"navyblue\", 0.94f, 0.54f, 0.f, 0.f),\n    c(\"royalblue\", 1.f, 0.50f, 0.f, 0.f),\n    c(\"cerulean\", 0.94f, 0.11f, 0.f, 0.f),\n    c(\"processblue\", 0.96f, 0.f, 0.f, 0.f),\n    c(\"skyblue\", 0.62f, 0.f, 0.12f, 0.f),\n    c(\"turquoise\", 0.85f, 0.f, 0.20f, 0.f),\n    c(\"tealblue\", 0.86f, 0.f, 0.34f, 0.02f),\n    c(\"aquamarine\", 0.82f, 0.f, 0.30f, 0.f),\n    c(\"bluegreen\", 0.85f, 0.f, 0.33f, 0.f),\n    c(\"emerald\", 1.f, 0.f, 0.50f, 0.f),\n    c(\"junglegreen\", 0.99f, 0.f, 0.52f, 0.f),\n    c(\"seagreen\", 0.69f, 0.f, 0.50f, 0.f),\n    c(\"forestgreen\", 0.91f, 0.f, 0.88f, 0.12f),\n    c(\"pinegreen\", 0.92f, 0.f, 0.59f, 0.25f),\n    c(\"limegreen\", 0.50f, 0.f, 1.f, 0.f),\n    c(\"yellowgreen\", 0.44f, 0.f, 0.74f, 0.f),\n    c(\"springgreen\", 0.26f, 0.f, 0.76f, 0.f),\n    c(\"olivegreen\", 0.64f, 0.f, 0.95f, 0.40f),\n    c(\"rawsienna\", 0.f, 0.72f, 1.f, 0.45f),\n    c(\"sepia\", 0.f, 0.83f, 1.f, 0.70f),\n    c(\"brown\", 0.f, 0.81f, 1.f, 0.60f),\n    c(\"tan\", 0.14f, 0.42f, 0.56f, 0.f),\n    c(\"gray\", 0.f, 0.f, 0.f, 0.50f)};\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/common.h",
    "content": "#ifndef COMMON_H_INCLUDED\n#define COMMON_H_INCLUDED\n\n#include \"config.h\"\n\n#if defined(HAVE_LOG) && defined(__GNUC__)\n#include <cxxabi.h>\n#endif\n\n#include <algorithm>\n#include <cctype>\n#include <cerrno>\n#include <climits>\n#include <cmath>\n#include <cstdio>\n#include <cstdlib>\n#include <exception>\n#include <functional>\n#include <limits>\n#include <map>\n#include <memory>\n#include <sstream>\n#include <string>\n#include <vector>\n\nusing namespace std;\n\n#define ANSI_BOLD \"\\x1b[1m\"\n#define ANSI_COLOR_CYAN \"\\x1b[36m\"\n#define ANSI_COLOR_RED \"\\x1b[31m\"\n#define ANSI_COLOR_GREEN \"\\x1b[32m\"\n#define ANSI_COLOR_UNDERLINE \"\\x1b[4m\"\n#define ANSI_RESET \"\\x1b[0m\"\n\n#define __dbg(format, ...)                                    \\\n    {                                                         \\\n        fprintf(                                              \\\n            stdout,                                           \\\n            \"FILE: \" ANSI_COLOR_UNDERLINE                     \\\n            \"%s\" ANSI_RESET                                   \\\n            \", LINE: \" ANSI_COLOR_RED                         \\\n            \"%d\" ANSI_RESET                                   \\\n            \", FUNCTION: \" ANSI_COLOR_CYAN                    \\\n            \"%s\" ANSI_RESET                                   \\\n            \", MSG: \" format,                                 \\\n            __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \\\n    }\n\n#ifdef HAVE_LOG\n#include <iostream>\n#define __log std::cout\n#endif  // HAVE_LOG\n\n#define __print printf\n\n// OUT parameter, the parameter may be affected by this function\n#define _out_\n// IN parameter, the parameter will never be changed by this function\n#define _in_\n\nnamespace tex {\n\n/**\n * The root directory of the \"TeX resources\" (defined in latex.cpp)\n */\nextern string RES_BASE;\n\nstatic const float POS_INF = numeric_limits<float>::infinity();\nstatic const float NEG_INF = -POS_INF;\nstatic const float F_MAX = numeric_limits<float>::max();\nstatic const float F_MIN = -F_MAX;\nstatic const double PI = atan(1.0) * 4;\n\ntemplate <typename T>\nusing sptr = shared_ptr<T>;\n\n/**\n * For compare with 0.0f, if a value < PREC,  we trade it as 0.0f\n */\nstatic const float PREC = 0.0000001f;\n\n/**\n * Demangling name\n */\n#ifdef HAVE_LOG\n#ifdef __GNUC__\ninline string demangle_name(const char* name) {\n    int status = -4;\n    char* res = abi::__cxa_demangle(name, 0, 0, &status);\n    const char* const real_name = status == 0 ? res : name;\n    string res_str(real_name);\n    if (res != nullptr) {\n        free(res);\n    }\n    return res_str;\n}\n#else\ninline string demangle_name(const char* name) {\n    return name;\n}\n#endif  // __GNUC__\n#endif  // HAVE_LOG\n\n/**\n * Find the position of a value in the vector, return -1 if not found\n */\ntemplate <class T>\ninline int indexOf(const vector<T>& v, const T& x) {\n    auto it = find(v.begin(), v.end(), x);\n    int i = std::distance(v.begin(), it);\n    return (i >= v.size() ? -1 : i);\n}\n\n/**\n * Convert a value to string\n */\ntemplate <class T>\ninline string tostring(T val) {\n    ostringstream os;\n    os << val;\n    return os.str();\n}\n\n/**\n * Convert a value to wide string\n */\ntemplate <class T>\ninline wstring towstring(T val) {\n    wostringstream os;\n    os << val;\n    return os.str();\n}\n\ntemplate <class T>\ninline void valueof(const string& s, T& val) {\n    stringstream ss;\n    ss << s;\n    ss >> val;\n}\n\ntemplate <class T>\ninline void valueof(const wstring& s, T& val) {\n    wstringstream ss;\n    ss << s;\n    ss >> val;\n}\n\ninline bool str2int(const string& str, int& res, int radix) {\n    char* endptr = nullptr;\n    errno = 0;\n\n    const long val = strtol(str.c_str(), &endptr, radix);\n\n    if ((val == LONG_MAX || val == LONG_MIN) && errno == ERANGE)\n        return false;\n\n    res = static_cast<int>(val);\n    return endptr == str.c_str() + str.size();\n}\n\n/**\n * Transform a string to lowercase\n */\ninline string& tolower(_out_ string& src) {\n    transform(src.begin(), src.end(), src.begin(), ::tolower);\n    return src;\n}\n\ninline wstring& tolower(_out_ wstring& src) {\n    transform(src.begin(), src.end(), src.begin(), ::tolower);\n    return src;\n}\n\n/**\n * Ignore left side whitespace in a string\n */\ninline string& ltrim(string& s) {\n    s.erase(s.begin(), find_if(s.begin(), s.end(), not1(ptr_fun<int, int>(isspace))));\n    return s;\n}\n\n/**\n * Ignore right side whitespace in a string\n */\ninline string& rtrim(string& s) {\n    s.erase(find_if(s.rbegin(), s.rend(), not1(ptr_fun<int, int>(isspace))).base(), s.end());\n    return s;\n}\n\n/**\n * Ignore left and right side whitespace in a string\n */\ninline string& trim(string& s) {\n    return ltrim(rtrim(s));\n}\n\n/**\n * Split string with specified delimeter\n */\ninline void split(const string& str, char del, _out_ vector<string>& res) {\n    stringstream ss(str);\n    string tok;\n    while (getline(ss, tok, del)) res.push_back(tok);\n}\n\ninline bool startswith(const string& str, const string& cmp) {\n    return str.find(cmp) == 0;\n}\n\ninline bool endswith(const string& str, const string& cmp) {\n    return str.rfind(cmp) == (str.length() - cmp.length());\n}\n\ninline bool startswith(const wstring& str, const wstring& cmp) {\n    return str.find(cmp) == 0;\n}\n\ninline bool endswith(const wstring& str, const wstring& cmp) {\n    return str.rfind(cmp) == (str.length() - cmp.length());\n}\n\n/**\n * Split string with delimiter\n */\nclass strtokenizer {\nprivate:\n    string _str;\n    string _del;\n    bool _ret;\n    int _pos;\n\npublic:\n    strtokenizer(const string& str) {\n        _str = str;\n        _del = \" \\t\\n\\r\\f\";\n        _ret = false;\n        _pos = 0;\n    }\n\n    strtokenizer(const string& str, const string& del, bool ret = false) {\n        _str = str;\n        _del = del;\n        _ret = ret;\n        _pos = 0;\n    }\n\n    int count_tokens() {\n        int c = 0;\n        bool in = false;\n        for (int i = _pos, len = _str.length(); i < len; i++) {\n            if (_del.find(_str[i]) != string::npos) {\n                if (_ret) c++;\n                if (in) {\n                    c++;\n                    in = false;\n                }\n            } else {\n                in = true;\n            }\n        }\n        if (in) c++;\n        return c;\n    }\n\n    string next_token() {\n        int i = _pos;\n        int len = _str.length();\n\n        if (i < len) {\n            if (_ret) {\n                if (_del.find(_str[_pos]) != string::npos)\n                    return string({_str[_pos++]});\n                for (_pos++; _pos < len; _pos++)\n                    if (_del.find(_str[_pos]) != string::npos)\n                        return _str.substr(i, _pos - i);\n                return _str.substr(i);\n            }\n\n            while (i < len && _del.find(_str[i]) != string::npos) i++;\n\n            _pos = i;\n            if (i < len) {\n                for (_pos++; _pos < len; _pos++)\n                    if (_del.find(_str[_pos]) != string::npos)\n                        return _str.substr(i, _pos - i);\n                return _str.substr(i);\n            }\n        }\n        return \"\";\n    }\n};\n\n/**\n * Convert unicode wide string to UTF-8 encoded string\n */\ninline string& wide2utf8(const wchar_t* in, _out_ string& out) {\n    unsigned int codepoint = 0;\n    for (; *in != 0; ++in) {\n        if (*in >= 0xd800 && *in <= 0xdbff) {\n            codepoint = ((*in - 0xd800) << 10) + 0x10000;\n        } else {\n            if (*in >= 0xdc00 && *in <= 0xdfff) {\n                codepoint |= *in - 0xdc00;\n            } else {\n                codepoint = *in;\n            }\n\n            if (codepoint <= 0x7f) {\n                out.append(1, static_cast<char>(codepoint));\n            } else if (codepoint <= 0x7ff) {\n                out.append(1, static_cast<char>(0xc0 | ((codepoint >> 6) & 0x1f)));\n                out.append(1, static_cast<char>(0x80 | (codepoint & 0x3f)));\n            } else if (codepoint <= 0xffff) {\n                out.append(1, static_cast<char>(0xe0 | ((codepoint >> 12) & 0x0f)));\n                out.append(1, static_cast<char>(0x80 | ((codepoint >> 6) & 0x3f)));\n                out.append(1, static_cast<char>(0x80 | (codepoint & 0x3f)));\n            } else {\n                out.append(1, static_cast<char>(0xf0 | ((codepoint >> 18) & 0x07)));\n                out.append(1, static_cast<char>(0x80 | ((codepoint >> 12) & 0x3f)));\n                out.append(1, static_cast<char>(0x80 | ((codepoint >> 6) & 0x3f)));\n                out.append(1, static_cast<char>(0x80 | (codepoint & 0x3f)));\n            }\n            codepoint = 0;\n        }\n    }\n    return out;\n}\n\ninline string wide2utf8(const wchar_t* in) {\n    string out;\n    return wide2utf8(in, out);\n}\n\n/**\n * Convert an UTF-8 encoded char sequence to wide unicode string,\n * the encoding of input char sequence must be known as UTF-8\n */\ninline wstring& utf82wide(const char* in, _out_ wstring& out) {\n    if (in == nullptr) return out;\n    unsigned int codepoint;\n    while (*in != 0) {\n        unsigned char ch = static_cast<unsigned char>(*in);\n        if (ch <= 0x7f)\n            codepoint = ch;\n        else if (ch <= 0xbf)\n            codepoint = (codepoint << 6) | (ch & 0x3f);\n        else if (ch <= 0xdf)\n            codepoint = ch & 0x1f;\n        else if (ch <= 0xef)\n            codepoint = ch & 0x0f;\n        else\n            codepoint = ch & 0x07;\n        ++in;\n        if (((*in & 0xc0) != 0x80) && (codepoint <= 0x10ffff)) {\n            if (codepoint > 0xffff) {\n                out.append(1, static_cast<wchar_t>(0xd800 + (codepoint >> 10)));\n                out.append(1, static_cast<wchar_t>(0xdc00 + (codepoint & 0x03ff)));\n            } else if (codepoint < 0xd800 || codepoint >= 0xe000)\n                out.append(1, static_cast<wchar_t>(codepoint));\n        }\n    }\n    return out;\n}\n\ninline wstring utf82wide(const char* in) {\n    wstring out;\n    return utf82wide(in, out);\n}\n\n/**\n * Returns a replacement string for the given one that has all backslashes\n * and dollar signs escaped\n */\ninline string& quotereplace(const string& src, _out_ string& out) {\n    for (size_t i = 0; i < src.length(); i++) {\n        char c = src[i];\n        if (c == '\\\\' || c == '$') out.append(1, '\\\\');\n        out.append(1, c);\n    }\n    return out;\n}\n\ninline wstring& quotereplace(const wstring& src, _out_ wstring& out) {\n    for (size_t i = 0; i < src.length(); i++) {\n        wchar_t c = src[i];\n        if (c == L'\\\\' || c == L'$') out.append(1, L'\\\\');\n        out.append(1, c);\n    }\n    return out;\n}\n\n/**\n * Replace string with specified string in the first\n */\ninline string& replacefirst(_out_ string& src, const string& from, const string& to) {\n    size_t start = src.find(from);\n    if (start == string::npos) return src;\n    src.replace(start, from.length(), to);\n    return src;\n}\n\ninline string& replaceall(_out_ string& src, const string& from, const string& to) {\n    if (from.empty()) return src;\n    size_t start = 0;\n    while ((start = src.find(from, start)) != string::npos) {\n        src.replace(start, from.length(), to);\n        start += to.length();\n    }\n    return src;\n}\n\ninline wstring& replacefirst(_out_ wstring& src, const wstring& from, const wstring& to) {\n    size_t start = src.find(from);\n    if (start == wstring::npos) return src;\n    src.replace(start, from.length(), to);\n    return src;\n}\n\ninline wstring& replaceall(_out_ wstring& src, const wstring& from, const wstring& to) {\n    if (from.empty()) return src;\n    size_t start = 0;\n    while ((start = src.find(from, start)) != wstring::npos) {\n        src.replace(start, from.length(), to);\n        start += to.length();\n    }\n    return src;\n}\n\n/***************************************************************************************************\n *                                        exceptions                                               *\n ***************************************************************************************************/\n\n/**\n * Superclass of all the possible TeX exceptions that can be thrown\n */\nclass ex_tex : public exception {\nprivate:\n    const string _msg;\n\npublic:\n    explicit ex_tex(const string& msg) : _msg(msg) {}\n\n    explicit ex_tex(const string& msg, const exception& cause)\n        : _msg(msg + \"\\n caused by: \" + cause.what()) {}\n\n    const char* what() const throw() override {\n        return _msg.c_str();\n    }\n};\n\n/**\n * Signals that an error occurred while loading the necessary resources into\n * memory.\n */\nclass ex_res_parse : public ex_tex {\npublic:\n    explicit ex_res_parse(const string& msg)\n        : ex_tex(msg) {}\n\n    explicit ex_res_parse(const string& msg, const exception& cause)\n        : ex_tex(msg, cause) {}\n};\n\n/**\n * xml-parse exception\n */\nclass ex_xml_parse : public ex_res_parse {\npublic:\n    /**\n     * attribute problem\n     */\n    explicit ex_xml_parse(\n        const string& resName,\n        const string& elName,\n        const string& attrName,\n        const string& msg)\n        : ex_res_parse(\n              resName + \": invalid <\" + elName + \">-element found: attribute '\" +\n              attrName + \"' \" + msg) {}\n\n    /**\n     * attribute problem\n     */\n    explicit ex_xml_parse(\n        const string& resName,\n        const string& elName,\n        const string& attrName,\n        const string& msg,\n        const exception& cause)\n        : ex_res_parse(\n              resName + \": invalid <\" + elName + \">-element found: attribute '\" +\n                  attrName + \"' \" + msg,\n              cause) {}\n    /**\n     * other exceptions\n     */\n    explicit ex_xml_parse(const string& resName, const exception& e) : ex_res_parse(resName, e) {}\n\n    /**\n     * required element missing\n     */\n    explicit ex_xml_parse(const string& resName, const string& elName)\n        : ex_res_parse(\n              resName + \": the required <\" + elName + \">-elment not found!\") {}\n\n    explicit ex_xml_parse(const string& msg) : ex_res_parse(msg) {}\n};\n\n/**\n * Exception while registering an alphabet\n */\nclass ex_alphabet_registration : public ex_tex {\npublic:\n    explicit ex_alphabet_registration(const string& msg) : ex_tex(msg) {}\n};\n\n/**\n * Exception while no character-to-delimiter mapping\n */\nclass ex_delimiter_mapping_not_found : public ex_tex {\npublic:\n    explicit ex_delimiter_mapping_not_found(const char& delimiter)\n        : ex_tex(\"No mapping found for the character '\" + string({delimiter}) + \"'!\") {}\n};\n\nclass ex_empty_formula : public ex_tex {\npublic:\n    explicit ex_empty_formula() : ex_tex(\"Illegal operation with an empty formula!\") {}\n};\n\nclass ex_font_loaded : public ex_tex {\npublic:\n    explicit ex_font_loaded(const string& msg) : ex_tex(msg) {}\n};\n\n/**\n * Unknown predefined TeXFormula name was used\n */\nclass ex_formula_not_found : public ex_tex {\npublic:\n    explicit ex_formula_not_found(const string& name)\n        : ex_tex(\"There's no predefined formula with the name '\" + name) {}\n};\n\n/**\n * Unknown atom type\n */\nclass ex_invalid_atom_type : public ex_tex {\npublic:\n    explicit ex_invalid_atom_type(const string& msg) : ex_tex(msg) {}\n};\n\n/**\n * Unknown delimiter\n */\nclass ex_invalid_delimiter : public ex_tex {\npublic:\n    explicit ex_invalid_delimiter(const string& symbolName)\n        : ex_tex(\"The symbol with the name '\" + symbolName +\n                 \"' is not defined as a delimiter\") {}\n\n    explicit ex_invalid_delimiter(const char& ch, const string& symbolName)\n        : ex_tex(\n              \"The character '\" + string({ch}) + \"' is not mapped to a symbol with the name '\" +\n              symbolName + \"', but that symbol is not defined as a delimiter.\") {}\n};\n\n/**\n * Unknown delimiter type\n */\nclass ex_invalid_delimiter_type : public ex_tex {\npublic:\n    explicit ex_invalid_delimiter_type() : ex_tex(\"The delimiter type was not valid!\") {}\n};\n\n/**\n * Matrix dimension not valid\n */\nclass ex_invalid_matrix : public ex_tex {\npublic:\n    explicit ex_invalid_matrix(const string& msg) : ex_tex(msg) {}\n};\n\n/**\n * Invalid symbol\n */\nclass ex_invalid_symbol_type : public ex_tex {\npublic:\n    explicit ex_invalid_symbol_type(const string& msg) : ex_tex(msg) {}\n};\n\n/**\n * Invalid TeXFormula\n */\nclass ex_invalid_formula : public ex_tex {\npublic:\n    explicit ex_invalid_formula(const string& msg) : ex_tex(msg) {}\n};\n\n/**\n * Unknown unit constant was used\n */\nclass ex_invalid_unit : public ex_tex {\npublic:\n    explicit ex_invalid_unit()\n        : ex_tex(\"The unit was not valid! use the unit defined in 'TeXConstants'.\") {}\n};\n\n/**\n * Error occurred while parsing a string to a formula\n */\nclass ex_parse : public ex_tex {\npublic:\n    explicit ex_parse(const string& msg, const exception& cause) : ex_tex(msg, cause) {}\n\n    explicit ex_parse(const string& msg) : ex_tex(msg) {}\n};\n\n/**\n * Symbol mapping not found\n */\nclass ex_symbol_mapping_not_found : public ex_tex {\npublic:\n    explicit ex_symbol_mapping_not_found(const string& symbolName)\n        : ex_tex(\"No mapping found for the symbol '\" + symbolName + \"'!\") {}\n};\n\n/**\n * Unknown symbol\n */\nclass ex_symbol_not_found : public ex_tex {\npublic:\n    explicit ex_symbol_not_found(const string& name)\n        : ex_tex(\"There's no symbol with the name '\" + name + \"' defined.\") {}\n};\n\n/**\n * Text style mapping not found\n */\nclass ex_text_style_mapping_not_found : public ex_tex {\npublic:\n    explicit ex_text_style_mapping_not_found(const string& name)\n        : ex_tex(\"No mapping found for the text style '\" + name + \"'!\") {}\n};\n\nclass ex_invalid_state : public ex_tex {\npublic:\n    explicit ex_invalid_state(const string& e) : ex_tex(e) {}\n};\n\nclass ex_invalid_param : public ex_tex {\npublic:\n    explicit ex_invalid_param(const string& e) : ex_tex(e) {}\n};\n\n/***************************************************************************************************\n *                                      TeXConstants                                               *\n ***************************************************************************************************/\n\nenum TeXConstants {\n\n    /********************************* alignment constants ****************************************/\n    /**\n     * Extra space will be added to the right of the formula\n     */\n    ALIGN_LEFT = 0,\n    /**\n     * Extra space will be added to the left of the formula\n     */\n    ALIGN_RIGHT,  // =1\n    /**\n     * The formula will be centered in the middle. this constant\n     * can be used for both horizontal and vertical alignment\n     */\n    ALIGN_CENTER,  // =2\n    /**\n     * Extra space will be added under the formula\n     */\n    ALIGN_TOP,  // =3\n    /**\n     * Extra space will be added above the formula\n     */\n    ALIGN_BOTTOM,  // =4\n    /**\n     * None\n     */\n    ALIGN_NONE,  // =5\n\n    /********************************** space size constants **************************************/\n    THINMUSKIP = 1,\n    MEDMUSKIP = 2,\n    THICKMUSKIP = 3,\n    NEGTHINMUSKIP = -1,\n    NEGMEDMUSKIP = -2,\n    NEGTHICKMUSKP = -3,\n\n    QUAD = 3,\n\n    /****************************** script display type constants *********************************/\n    SCRIPT_NORMAL = 0,\n    SCRIPT_NOLIMITS,\n    SCRIPT_LIMITS,\n\n    /*********************************** atom type constants **************************************/\n    /**\n     * Ordinary symbol, e.g. \"slash\"\n     */\n    TYPE_ORDINARY = 0,\n    /**\n     * Big operator, e.g. \"sum\"\n     */\n    TYPE_BIG_OPERATOR,  // =1\n    /**\n     * Binary operator, e.g. \"plus\"\n     */\n    TYPE_BINARY_OPERATOR,  // =2\n    /**\n     * Relation, e.g. \"equals\"\n     */\n    TYPE_RELATION,  // =3\n    /**\n     * Opening symbol, e.g. \"lbrace\"\n     */\n    TYPE_OPENING,  // =4\n    /**\n     * Closing symbol, e.g. \"rbrace\"\n     */\n    TYPE_CLOSING,  // =5\n    /**\n     * Punctuation symbol, e.g. \"comma\"\n     */\n    TYPE_PUNCTUATION,  // =6\n    /**\n     * Atom type: inner atom (NOT FOR SYMBOLS)\n     */\n    TYPE_INNER,  // =7\n    /**\n     * Accent, e.g. \"hat\"\n     */\n    TYPE_ACCENT = 10,\n    /**\n     * Inter-text in matrix environment\n     */\n    TYPE_INTERTEXT,  // =11\n    /**\n     * Multi-column in matrix envrionment\n     */\n    TYPE_MULTICOLUMN,  // =12\n    /**\n     * Horizontal line in matrix envrionment\n     */\n    TYPE_HLINE,  // =13\n    /**\n     * Multi-row in matrix envrionment\n     */\n    TYPE_MULTIROW,  // =14\n\n    /****************************** over and under delimiter type constants ***********************/\n    DELIM_BRACE = 0,\n    DELIM_SQUARE_BRACKET,\n    DELIM_BRACKET,\n    DELIM_LEFT_ARROW,\n    DELIM_RIGHT_ARROW,\n    DELIM_LEFT_RIGHT_ARROW,\n    DELIM_DOUBLE_LEFT_ARROW,\n    DELIM_DOUBLE_RIGHT_ARROW,\n    DELIM_DOUBLE_LEFT_RIGHT_ARROW,\n    DELIM_SIGNLE_LINE,\n    DELIM_DOUBLE_LINE,\n\n    /************************************* TeX style constants ************************************/\n    /**\n     * Display style\n     * @par\n     * The larger versions of big operators are used and limits are placed under\n     * and over these operators (default). Symbols are rendered in the largest\n     * size.\n     */\n    STYLE_DISPLAY = 0,\n    /**\n     * Text style\n     * @par\n     * The small versions of big operator are used and limits are attached to\n     * these operators as scripts (default). The same size as in the display\n     * style is used to render symbols.\n     */\n    STYLE_TEXT = 2,\n    /**\n     * Script style\n     * @par\n     * The same as the the text style, but symbols are rendered in a smaller size.\n     */\n    STYLE_SCRIPT = 4,\n    /**\n     * Script_script style\n     * @par\n     * The same as the script style, but symbols are rendered in a smaller size.\n     */\n    STYLE_SCRIPT_SCRIPT = 6,\n\n    /************************************ TeX unit constants **************************************/\n    /**\n     * 1 em = the width of the capital 'M' in the current font\n     */\n    UNIT_EM = 0,\n    /**\n     * 1 ex = the height of the character 'x' in the current font\n     */\n    UNIT_EX,\n    UNIT_PIXEL,\n    /**\n     * postscript point\n     */\n    UNIT_POINT,\n    /**\n     * 1 pica = 12 point\n     */\n    UNIT_PICA,\n    /**\n     * 1 mu = 1/18 em (em taken from the \"mufont\")\n     */\n    UNIT_MU,\n    /**\n     * 1 cm = 28.346456693 point\n     */\n    UNIT_CM,\n    /**\n     * 1 mm = 2.8346456693 point\n     */\n    UNIT_MM,\n    /**\n     * 1 in = 72 point\n     */\n    UNIT_IN,\n    /**\n     * 1 sp = 65536 point\n     */\n    UNIT_SP,\n    UNIT_PT,\n    UNIT_DD,\n    UNIT_CC,\n    /**\n     * 1 x8 = 1 default rule thickness\n     */\n    UNIT_X8\n};\n\n}  // namespace tex\n\n#endif  // COMMON_H_INCLUDED\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/config.h",
    "content": "#ifndef CONFIG_H_INCLUDED\n#define CONFIG_H_INCLUDED\n\n// Flag for debug\n#if defined(_DEBUG) || defined(DEBUG) || defined(__DEBUG__) || !defined(NDEBUG)\n#   ifndef __DEBUG\n#       define __DEBUG\n#   endif\n#endif\n\n// Check platforms\n#if defined(__linux__)\n#   ifdef __ANDROID__\n#       define __OS_Android__\n#   elif defined __OHOS__\n#       define __OS_ohos__\n#   else\n#       define __OS_Linux__\n#   endif\n#elif defined(_WIN32)\n#   ifdef __OHOS__\n#       define __OS_ohos__\n#   else\n#       define __OS_Windows__\n#   endif\n#endif\n// Other platforms...\n\n// Flag for if compile samples\n#if defined(__OS_Linux__) || defined(__OS_Windows__) || defined(MEM_CHECK)\n#   define __USE_SAMPLES\n#endif\n\n// Disable log if not in debug mode\n#ifndef __DEBUG\n#   undef HAVE_LOG\n#endif\n\n#endif  // CONFIG_H_INCLUDED"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/core/core.cpp",
    "content": "#include \"core/core.h\"\n#include \"atom/atom_basic.h\"\n#include \"atom/box.h\"\n#include \"common.h\"\n\nusing namespace std;\nusing namespace tex;\n\n#ifdef HAVE_LOG\nvoid print_box(const sptr<Box>& b, int dep, vector<bool>& lines) {\n    __print(\"%-4d\", dep);\n    if (lines.size() < dep + 1) lines.resize(dep + 1, false);\n\n    for (int i = 0; i < dep - 1; i++) {\n        if (lines[i]) {\n            __print(\"    \");\n        } else {\n            __print(\" │  \");\n        }\n    }\n\n    if (dep > 0) {\n        if (lines[dep - 1]) {\n            __print(\" └──\");\n        } else {\n            __print(\" ├──\");\n        }\n    }\n\n    if (b == nullptr) {\n        __print(ANSI_COLOR_RED \" NULL\\n\");\n        return;\n    }\n\n    vector<sptr<Box>> children = b->getChildren();\n    const size_t c = children.size();\n    const string& str = demangle_name(typeid(*(b)).name());\n    string name = str.substr(str.find_last_of(\"::\") + 1);\n    if (c > 0) {\n        __print(ANSI_COLOR_CYAN \" %s\\n\" ANSI_RESET, name.c_str());\n    } else {\n        __print(\" %s\\n\", name.c_str());\n    }\n\n    for (size_t i = 0; i < c; i++) {\n        lines[dep] = i == c - 1;\n        print_box(children[i], dep + 1, lines);\n    }\n}\n\nvoid tex::print_box(const sptr<Box>& b) {\n    vector<bool> lines;\n    ::print_box(b, 0, lines);\n    __print(\"\\n\");\n}\n#endif  // HAVE_LOG\n\nsptr<Box> BoxSplitter::split(const sptr<Box>& b, float width, float lineSpace) {\n    auto h = dynamic_pointer_cast<HorizontalBox>(b);\n    sptr<Box> box;\n    if (h != nullptr) {\n        auto box = split(h, width, lineSpace);\n#ifdef HAVE_LOG\n        if (box != b) {\n            __print(\"[BEFORE SPLIT]:\\n\");\n            print_box(b);\n            __print(\"[AFTER SPLIT]:\\n\");\n            print_box(box);\n        } else {\n            __print(\"[BOX TREE]:\\n\");\n            print_box(box);\n        }\n#endif\n        return box;\n    }\n#ifdef HAVE_LOG\n    __print(\"[BOX TREE]:\\n\");\n    print_box(b);\n#endif\n    return b;\n}\n\nsptr<Box> BoxSplitter::split(const sptr<HorizontalBox>& hb, float width, float lineSpace) {\n    if (width == 0 || hb->_width <= width) return hb;\n\n    sptr<VerticalBox> vboxPtr = make_shared<VerticalBox>();\n    sptr<HorizontalBox> first, second;\n    stack<Position> positions;\n    sptr<HorizontalBox> hbox = hb;\n\n    while (hbox->_width > width && canBreak(positions, hbox, width) != hbox->_width) {\n        Position pos = positions.top();\n        positions.pop();\n        auto hboxes = pos._box->split(pos._index - 1);\n        first = hboxes.first;\n        second = hboxes.second;\n        while (!positions.empty()) {\n            pos = positions.top();\n            positions.pop();\n            hboxes = pos._box->splitRemove(pos._index);\n            hboxes.first->add(first);\n            hboxes.second->add(0, second);\n            first = hboxes.first;\n            second = hboxes.second;\n        }\n        vboxPtr->add(first, lineSpace);\n        hbox = second;\n    }\n\n    if (second != nullptr) {\n        vboxPtr->add(second, lineSpace);\n        return sptr<Box>(vboxPtr);\n    }\n\n    return hbox;\n}\n\nfloat BoxSplitter::canBreak(stack<Position>& s, const sptr<HorizontalBox>& hbox, const float width) {\n    const vector<sptr<Box>>& children = hbox->_children;\n    const int count = children.size();\n    // Cumulative width\n    float* cumWidth = new float[count + 1]();\n    cumWidth[0] = 0;\n    for (int i = 0; i < count; i++) {\n        auto box = children[i];\n        cumWidth[i + 1] = cumWidth[i] + box->_width;\n        if (cumWidth[i + 1] <= width) continue;\n        int pos = getBreakPosition(hbox, i);\n        auto h = dynamic_pointer_cast<HorizontalBox>(box);\n        if (h != nullptr) {\n            stack<Position> sub;\n            float w = canBreak(sub, h, width - cumWidth[i]);\n            if (w != box->_width && (cumWidth[i] + w <= width || pos == -1)) {\n                s.push(Position(i - 1, hbox));\n                // add to stack\n                vector<Position> p;\n                while (!sub.empty()) {\n                    p.push_back(sub.top());\n                    sub.pop();\n                }\n                for (auto it = p.rbegin(); it != p.rend(); it++) s.push(*it);\n                // release cum-width\n                float x = cumWidth[i] + w;\n                delete[] cumWidth;\n                return x;\n            }\n        }\n\n        if (pos != -1) {\n            s.push(Position(pos, hbox));\n            float x = cumWidth[pos];\n            delete[] cumWidth;\n            return x;\n        }\n    }\n\n    delete[] cumWidth;\n    return hbox->_width;\n}\n\nint BoxSplitter::getBreakPosition(const sptr<HorizontalBox>& hb, int i) {\n    if (hb->_breakPositions.empty()) return -1;\n\n    if (hb->_breakPositions.size() == 1 && hb->_breakPositions[0] <= i)\n        return hb->_breakPositions[0];\n\n    size_t pos = 0;\n    for (; pos < hb->_breakPositions.size(); pos++) {\n        if (hb->_breakPositions[pos] > i) {\n            if (pos == 0) return -1;\n            return hb->_breakPositions[pos - 1];\n        }\n    }\n\n    return hb->_breakPositions[pos - 1];\n}\n\n/************************************* TeXEnvironment implementation ******************************/\n\nTeXEnvironment::TeXEnvironment(int style, const sptr<TeXFont>& tf, int wu, float tw) {\n    init();\n    _style = style;\n    _tf = tf;\n    setInterline(TeXConstants::UNIT_EX, 1.f);\n    _textWidth = tw * SpaceAtom::getFactor(wu, *this);\n}\n\nfloat TeXEnvironment::getInterline() const {\n    return _interline * SpaceAtom::getFactor(_interlineUnit, *this);\n}\n\nvoid TeXEnvironment::setTextWidth(int wu, float w) {\n    _textWidth = w * SpaceAtom::getFactor(wu, *this);\n}\n\nsptr<TeXEnvironment>& TeXEnvironment::copy() {\n    TeXEnvironment* t = new TeXEnvironment(\n        _style, _scaleFactor, _tf, _background, _color, _textStyle, _smallCap);\n    _copy = sptr<TeXEnvironment>(t);\n    return _copy;\n}\n\nsptr<TeXEnvironment>& TeXEnvironment::copy(const sptr<TeXFont>& tf) {\n    TeXEnvironment* te = new TeXEnvironment(\n        _style, _scaleFactor, tf, _background, _color, _textStyle, _smallCap);\n    te->_textWidth = _textWidth;\n    te->_interline = _interline;\n    te->_interlineUnit = _interlineUnit;\n    _copytf = sptr<TeXEnvironment>(te);\n    return _copytf;\n}\n\nsptr<TeXEnvironment>& TeXEnvironment::crampStyle() {\n    TeXEnvironment* t = new TeXEnvironment(\n        _style, _scaleFactor, _tf, _background, _color, _textStyle, _smallCap);\n    _cramp = sptr<TeXEnvironment>(t);\n    _cramp->_style = (_style % 2 == 1 ? _style : _style + 1);\n    return _cramp;\n}\n\nsptr<TeXEnvironment>& TeXEnvironment::dnomStyle() {\n    TeXEnvironment* t = new TeXEnvironment(\n        _style, _scaleFactor, _tf, _background, _color, _textStyle, _smallCap);\n    _dnom = sptr<TeXEnvironment>(t);\n    _dnom->_style = 2 * (_style / 2) + 1 + 2 - 2 * (_style / 6);\n    return _dnom;\n}\n\nsptr<TeXEnvironment>& TeXEnvironment::numStyle() {\n    TeXEnvironment* t = new TeXEnvironment(\n        _style, _scaleFactor, _tf, _background, _color, _textStyle, _smallCap);\n    _num = sptr<TeXEnvironment>(t);\n    _num->_style = _style + 2 - 2 * (_style / 6);\n    return _num;\n}\n\nsptr<TeXEnvironment>& TeXEnvironment::rootStyle() {\n    TeXEnvironment* t = new TeXEnvironment(\n        _style, _scaleFactor, _tf, _background, _color, _textStyle, _smallCap);\n    _root = sptr<TeXEnvironment>(t);\n    _root->_style = STYLE_SCRIPT_SCRIPT;\n    return _root;\n}\n\nsptr<TeXEnvironment>& TeXEnvironment::subStyle() {\n    TeXEnvironment* t = new TeXEnvironment(\n        _style, _scaleFactor, _tf, _background, _color, _textStyle, _smallCap);\n    _sub = sptr<TeXEnvironment>(t);\n    _sub->_style = 2 * (_style / 4) + 4 + 1;\n    return _sub;\n}\n\nsptr<TeXEnvironment>& TeXEnvironment::supStyle() {\n    TeXEnvironment* t = new TeXEnvironment(\n        _style, _scaleFactor, _tf, _background, _color, _textStyle, _smallCap);\n    _sup = sptr<TeXEnvironment>(t);\n    _sup->_style = 2 * (_style / 4) + 4 + (_style % 2);\n    return _sup;\n}\n\n/************************************* Glue implementation ****************************************/\n\n#ifdef HAVE_LOG\nostream& tex::operator<<(ostream& out, const Glue& glue) {\n    out << \"Glue { space: \" << glue._space << \", stretch: \" << glue._stretch << \", shrink: \";\n    out << glue._shrink << \", name: \" << glue._name << \" }\";\n    return out;\n}\n#endif  // HAVE_LOG\n\nvoid Glue::_init_() {\n#ifdef HAVE_LOG\n    // print glue types\n    __log << \"elements in _glueTypes\" << endl;\n    for (auto x : _glueTypes) __log << \"\\t\" << x << endl;\n    __log << endl;\n#endif  // HAVE_LOG\n}\n\nvoid Glue::_free_() {\n    // delete glue-types\n    for (size_t i = 0; i < _glueTypes.size(); i++) {\n        Glue* g = _glueTypes[i];\n        delete g;\n    }\n}\n\nfloat Glue::getFactor(const TeXEnvironment& env) const {\n    auto tf = env.getTeXFont();\n    // use \"quad\" from a font marked as an \"mu font\"\n    float quad = tf->getQuad(env.getStyle(), tf->getMuFontId());\n    return quad / 18.f;\n}\n\nsptr<Box> Glue::createBox(const TeXEnvironment& env) const {\n    float factor = getFactor(env);\n    auto x = new GlueBox(_space * factor, _stretch * factor, _shrink * factor);\n    return sptr<Box>(x);\n}\n\nint Glue::getGlueIndex(int ltype, int rtype, const TeXEnvironment& env) {\n    // types > INNER are considered of type ORD for glue calculations\n    int l = (ltype > TYPE_INNER ? TYPE_ORDINARY : ltype);\n    int r = (rtype > TYPE_INNER ? TYPE_ORDINARY : rtype);\n    return _table[l][r][env.getStyle() / 2] - '0';\n}\n\nsptr<Box> Glue::get(int ltype, int rtype, const TeXEnvironment& env) {\n    int i = getGlueIndex(ltype, rtype, env);\n    return _glueTypes[i]->createBox(env);\n}\n\nGlue* Glue::getGlue(int skipType) {\n    int st = skipType < 0 ? -skipType : skipType;\n    string name;\n    switch (st) {\n    case THINMUSKIP:\n        name = \"thin\";\n        break;\n    case MEDMUSKIP:\n        name = \"med\";\n        break;\n    default:\n        name = \"thick\";\n        break;\n    }\n    auto it = find_if(_glueTypes.begin(), _glueTypes.end(), [&name](const Glue* g) {\n        return g->_name == name;\n    });\n    return *it;\n}\n\nsptr<Box> Glue::get(int skipType, const TeXEnvironment& env) {\n    auto glue = getGlue(skipType);\n    if (glue == nullptr) return sptr<Box>(new GlueBox(0, 0, 0));\n    auto b = glue->createBox(env);\n    if (skipType < 0) b->negWidth();\n    return b;\n}\n\nfloat Glue::getSpace(int ltype, int rtype, const TeXEnvironment& env) {\n    int i = getGlueIndex(ltype, rtype, env);\n    auto glueType = _glueTypes[i];\n    return glueType->_space * glueType->getFactor(env);\n}\n\nfloat Glue::getSpace(int skipType, const TeXEnvironment& env) {\n    auto glue = getGlue(skipType);\n    if (glue == nullptr) return 0;\n    return glue->_space * glue->getFactor(env);\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/core/core.h",
    "content": "#ifndef CORE_H_INCLUDED\n#define CORE_H_INCLUDED\n\n#include \"common.h\"\n#include \"fonts/fonts.h\"\n\n#include <cstring>\n\nusing namespace std;\nusing namespace tex;\n\nnamespace tex {\n\nclass Box;\n\n#ifdef HAVE_LOG\nvoid print_box(const sptr<Box>& box);\n#endif  // HAVE_LOG\n\nclass BoxSplitter {\npublic:\n    struct Position {\n        int _index;\n        sptr<HorizontalBox> _box;\n\n        Position(int index, const sptr<HorizontalBox>& box)\n            : _index(index), _box(box) {}\n    };\n\nprivate:\n    static float canBreak(_out_ stack<Position>& stack, const sptr<HorizontalBox>& hbox, float width);\n\n    static int getBreakPosition(const sptr<HorizontalBox>& hb, int index);\n\npublic:\n    static sptr<Box> split(const sptr<Box>& box, float width, float lineSpace);\n\n    static sptr<Box> split(const sptr<HorizontalBox>& hb, float width, float lineSpace);\n};\n\n/**\n * Contains the used TeXFont-object, color settings and the current style in\n * which a formula must be drawn. It's used in the createBox-methods. Contains\n * methods that apply the style changing rules for subformula's.\n */\nclass TeXEnvironment {\nprivate:\n    // colors\n    color _background, _color;\n    // current style\n    int _style;\n    // TeXFont used\n    sptr<TeXFont> _tf;\n    // last used font\n    int _lastFontId;\n    // Environment width\n    float _textWidth;\n\n    // The text style to use\n    string _textStyle;\n    // If is small capital\n    bool _smallCap;\n    float _scaleFactor;\n    // The unit of inter-line space\n    int _interlineUnit;\n    // The inter line space\n    float _interline;\n\n    // Member to store copies to prevent destruct\n    sptr<TeXEnvironment> _copy, _copytf, _cramp, _dnom;\n    sptr<TeXEnvironment> _num, _root, _sub, _sup;\n\n    inline void init() {\n        _background = trans;\n        _color = trans;\n        _style = STYLE_DISPLAY;\n        _lastFontId = TeXFont::NO_FONT;\n        _textWidth = POS_INF;\n        _smallCap = false;\n        _scaleFactor = 1.f;\n        _interlineUnit = 0;\n        _interline = 0;\n        _isColored = false;\n    }\n\n    TeXEnvironment(int style, const sptr<TeXFont>& tf, color bg, const color c) {\n        init();\n        _style = style;\n        _tf = tf;\n        _background = bg;\n        _color = c;\n        setInterline(UNIT_EX, 1.f);\n    }\n\n    TeXEnvironment(\n        int style, float scaleFactor, const sptr<TeXFont>& tf,\n        color bg, color c, const string& textstyle, bool smallCap) {\n        init();\n        _style = style;\n        _scaleFactor = scaleFactor;\n        _tf = tf;\n        _textStyle = textstyle;\n        _smallCap = smallCap;\n        _background = bg;\n        _color = c;\n        setInterline(UNIT_EX, 1.f);\n    }\n\npublic:\n    bool _isColored;\n\n    TeXEnvironment(int style, const sptr<TeXFont>& tf) {\n        init();\n        _style = style;\n        _tf = tf;\n        setInterline(UNIT_EX, 1.f);\n    }\n\n    TeXEnvironment(int style, const sptr<TeXFont>& tf, int widthUnit, float textWidth);\n\n    inline void setInterline(int unit, float len) {\n        _interline = len;\n        _interlineUnit = unit;\n    }\n\n    float getInterline() const;\n\n    void setTextWidth(int widthUnit, float width);\n\n    inline float getTextWidth() const { return _textWidth; }\n\n    inline void setScaleFactor(float f) { _scaleFactor = f; }\n\n    inline float getScaleFactor() const { return _scaleFactor; }\n\n    sptr<TeXEnvironment>& copy();\n\n    sptr<TeXEnvironment>& copy(const sptr<TeXFont>& tf);\n\n    /**\n     * Copy of this envrionment in cramped style.\n     */\n    sptr<TeXEnvironment>& crampStyle();\n\n    /**\n     * Style to display denominator.\n     */\n    sptr<TeXEnvironment>& dnomStyle();\n\n    /**\n     * Style to display numerator.\n     */\n    sptr<TeXEnvironment>& numStyle();\n\n    /**\n     * Style to display roots.\n     */\n    sptr<TeXEnvironment>& rootStyle();\n\n    /**\n     * Style to display subscripts.\n     */\n    sptr<TeXEnvironment>& subStyle();\n\n    /**\n     * Style to display superscripts.\n     */\n    sptr<TeXEnvironment>& supStyle();\n\n    inline void setBackground(color bg) { _background = bg; }\n\n    inline void setColor(color c) { _color = c; }\n\n    inline color getBackground() const { return _background; }\n\n    inline color getColor() const { return _color; }\n\n    inline float getSize() const { return _tf->getSize(); }\n\n    inline int getStyle() const { return _style; }\n\n    inline void setStyle(int style) { _style = style; }\n\n    inline const string& getTextStyle() const { return _textStyle; }\n\n    inline void setTextStyle(const string& style) { _textStyle = style; }\n\n    inline bool getSmallCap() const { return _smallCap; }\n\n    inline void setSmallCap(bool s) { _smallCap = s; }\n\n    inline const sptr<TeXFont>& getTeXFont() const { return _tf; }\n\n    inline void reset() {\n        _color = trans;\n        _background = trans;\n    }\n\n    inline float getSpace() const { return _tf->getSpace(_style) * _tf->getScaleFactor(); }\n\n    inline void setLastFontId(int id) { _lastFontId = id; }\n\n    inline int getLastFontId() const {\n        return (_lastFontId == TeXFont::NO_FONT ? _tf->getMuFontId() : _lastFontId);\n    }\n};\n\n/**\n * Represents glue by its 3 components. Contains the \"glue rules\"\n */\nclass Glue {\nprivate:\n    // contains the different glue types\n    static vector<Glue*> _glueTypes;\n#define TYPE_COUNT 8\n#define STYLE_COUNT 5\n    // the glue table represents the \"glue rules\"\n    static const char _table[TYPE_COUNT][TYPE_COUNT][STYLE_COUNT];\n    // the glue components\n    float _space;\n    float _stretch;\n    float _shrink;\n    string _name;\n\n    sptr<Box> createBox(const TeXEnvironment& env) const;\n\n    float getFactor(const TeXEnvironment& env) const;\n\n    static Glue* getGlue(int skipType);\n\n    static int getGlueIndex(int ltype, int rtype, const TeXEnvironment& env);\n\npublic:\n    Glue() = delete;\n\n    Glue(float space, float stretch, float shrink, const string& name) {\n        _space = space;\n        _stretch = stretch;\n        _shrink = shrink;\n        _name = name;\n    }\n\n    inline const string& getName() const {\n        return _name;\n    }\n\n    /**\n     * Creates a box representing the glue type according to the \"glue rules\" based\n     * on the atom types between which the glue must be inserted.\n     *\n     * @param ltype\n     *      left atom type\n     * @param rtype\n     *      right atom type\n     * @param env\n     *      the TeXEnvironment\n     * @return a box containing representing the glue\n     */\n    static sptr<Box> get(int ltype, int rtype, const TeXEnvironment& env);\n\n    /**\n     * Creates a box representing the glue type according to the \"glue rules\" based\n     * on the skip-type\n     */\n    static sptr<Box> get(int skipType, const TeXEnvironment& env);\n\n    /**\n     * Get the space amount from the given left-type and right-type of atoms\n     * according to the \"glue rules\".\n     */\n    static float getSpace(int ltype, int rtype, const TeXEnvironment& env);\n\n    /**\n     * Get the space amount from the given skip-type according to the \"glue rules\"\n     */\n    static float getSpace(int skipType, const TeXEnvironment& env);\n\n    static void _init_();\n\n    static void _free_();\n\n#ifdef HAVE_LOG\n    friend ostream& operator<<(ostream& out, const Glue& glue);\n#endif  // HAVE_LOG\n};\n\n}  // namespace tex\n\n#endif  // CORE_H_INCLUDED\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/core/formula.cpp",
    "content": "#include \"core/formula.h\"\n#include \"common.h\"\n#include \"core/core.h\"\n#include \"core/parser.h\"\n#include \"fonts/alphabet.h\"\n#include \"fonts/fonts.h\"\n#include \"graphic/graphic.h\"\n#include \"res/parser/formula_parser.h\"\n\nusing namespace std;\nusing namespace tex;\n\nmap<wstring, sptr<TeXFormula>> TeXFormula::_predefinedTeXFormulas;\n\nmap<UnicodeBlock, FontInfos*> TeXFormula::_externalFontMap;\n\nfloat TeXFormula::PIXELS_PER_POINT = 1.f;\n\nvoid TeXFormula::_init_() {\n#ifdef HAVE_LOG\n    __dbg(\"%s\\n\", \"init formula\");\n#endif  // HAVE_LOG\n    // Register external alphabet\n    DefaultTeXFont::registerAlphabet(new CyrillicRegistration());\n    DefaultTeXFont::registerAlphabet(new GreekRegistration());\n#ifdef HAVE_LOG\n    __log << \"elements in _symbolMappings:\" << endl;\n    for (auto i : _symbolMappings)\n        __log << \"\\t\" << i.first << \"->\" << i.second << endl;\n    __log << \"elements in _symbolTextMappings:\" << endl;\n    for (auto i : _symbolTextMappings)\n        __log << \"\\t\" << i.first << \"->\" << i.second << endl;\n    __log << \"elements in _symbolFormulaMappings:\" << endl;\n    for (auto i : _symbolFormulaMappings)\n        __log << \"\\t\" << i.first << \"->\" << i.second << endl;\n#endif  // HAVE_LOG\n}\n\nTeXFormula::TeXFormula(const TeXParser& tp)\n    : _parser(tp.getIsPartial(), L\"\", this, false) {\n    _xmlMap = tp._formula->_xmlMap;\n}\n\nTeXFormula::TeXFormula(\n    const TeXParser& tp,\n    const wstring& s,\n    const string& textStyle,\n    bool firstpass, bool space) throw(ex_parse)\n    : _parser(tp.getIsPartial(), s, this, firstpass, space) {\n    _textStyle = textStyle;\n    _xmlMap = tp._formula->_xmlMap;\n    if (tp.getIsPartial()) {\n        try {\n            _parser.parse();\n        } catch (exception& e) {\n            if (_root == nullptr) _root = sptr<Atom>(new EmptyAtom());\n        }\n    } else {\n        _parser.parse();\n    }\n}\n\nTeXFormula::TeXFormula(\n    const TeXParser& tp, const wstring& s, const string& textStyle) throw(ex_parse)\n    : _parser(tp.getIsPartial(), s, this) {\n    _textStyle = textStyle;\n    _xmlMap = tp._formula->_xmlMap;\n    if (tp.getIsPartial()) {\n        try {\n            _parser.parse();\n        } catch (exception& e) {\n            if (_root == nullptr) _root = sptr<Atom>(new EmptyAtom());\n        }\n    } else {\n        _parser.parse();\n    }\n}\n\nTeXFormula::TeXFormula(const TeXParser& tp, const wstring& s, bool firstpass) throw(ex_parse)\n    : _parser(tp.getIsPartial(), s, this, firstpass) {\n    _textStyle = \"\";\n    _xmlMap = tp._formula->_xmlMap;\n    if (tp.getIsPartial()) {\n        try {\n            _parser.parse();\n        } catch (exception& e) {}\n    } else {\n        _parser.parse();\n    }\n}\n\nTeXFormula::TeXFormula(const TeXParser& tp, const wstring& s) throw(ex_parse)\n    : _parser(tp.getIsPartial(), s, this) {\n    _textStyle = \"\";\n    _xmlMap = tp._formula->_xmlMap;\n    if (tp.getIsPartial()) {\n        try {\n            _parser.parse();\n        } catch (exception& e) {\n            if (_root == nullptr) _root = sptr<Atom>(new EmptyAtom());\n        }\n    } else {\n        _parser.parse();\n    }\n}\n\nTeXFormula::TeXFormula() : _parser(L\"\", this, false) {}\n\nTeXFormula::TeXFormula(const wstring& s) throw(ex_parse) : _parser(s, this) {\n    _textStyle = \"\";\n    _parser.parse();\n}\n\nTeXFormula::TeXFormula(const wstring& s, bool firstpass) throw(ex_parse)\n    : _parser(s, this, firstpass) {\n    _textStyle = \"\";\n    _parser.parse();\n}\n\nTeXFormula::TeXFormula(const wstring& s, const string& textStyle) throw(ex_parse)\n    : _parser(s, this) {\n    _textStyle = textStyle;\n    _parser.parse();\n}\n\nTeXFormula::TeXFormula(\n    const wstring& s, const string& textStyle, bool firstpass, bool space) throw(ex_parse)\n    : _parser(s, this, firstpass, space) {\n    _textStyle = textStyle;\n    _parser.parse();\n}\n\nTeXFormula::TeXFormula(const TeXFormula* f) {\n    if (f != nullptr) addImpl(f);\n}\n\nvoid TeXFormula::setLaTeX(const wstring& latex) throw(ex_parse) {\n    _parser.reset(latex);\n    if (!latex.empty()) _parser.parse();\n}\n\nTeXFormula* TeXFormula::add(const sptr<Atom>& el) {\n    if (el == nullptr) return this;\n    auto atom = dynamic_pointer_cast<MiddleAtom>(el);\n    if (atom != nullptr) _middle.push_back(atom);\n    if (_root == nullptr) {\n        _root = el;\n        return this;\n    }\n    RowAtom* rm = dynamic_cast<RowAtom*>(_root.get());\n    if (rm == nullptr) _root = sptr<Atom>(new RowAtom(_root));\n    rm = static_cast<RowAtom*>(_root.get());\n    rm->add(el);\n    TypedAtom* ta = dynamic_cast<TypedAtom*>(el.get());\n    if (ta != nullptr) {\n        int rt = ta->getRightType();\n        if (rt == TYPE_BINARY_OPERATOR || rt == TYPE_RELATION)\n            rm->add(sptr<Atom>(new BreakMarkAtom()));\n    }\n    return this;\n}\n\nTeXFormula* TeXFormula::append(bool isPartial, const wstring& s) throw(ex_parse) {\n    if (!s.empty()) {\n        TeXParser tp(isPartial, s, this);\n        tp.parse();\n    }\n    return this;\n}\n\nTeXFormula* TeXFormula::append(const wstring& s) throw(ex_parse) {\n    return append(false, s);\n}\n\nvoid TeXFormula::addImpl(const TeXFormula* f) {\n    if (f != nullptr) {\n        RowAtom* rm = dynamic_cast<RowAtom*>(f->_root.get());\n        if (rm != nullptr)\n            add(sptr<Atom>(new RowAtom(f->_root)));\n        else\n            add(f->_root);\n    }\n}\n\nsptr<Box> TeXFormula::createBox(_out_ TeXEnvironment& style) {\n    if (_root == nullptr) return sptr<Box>(new StrutBox(0, 0, 0, 0));\n    return _root->createBox(style);\n}\n\nvoid TeXFormula::setDEBUG(bool b) {\n    Box::DEBUG = b;\n}\n\nTeXFormula* TeXFormula::setBackground(color c) {\n    if (istrans(c)) return this;\n    ColorAtom* ca = dynamic_cast<ColorAtom*>(_root.get());\n    if (ca != nullptr)\n        _root = sptr<Atom>(new ColorAtom(c, TRANS, _root));\n    else\n        _root = sptr<Atom>(new ColorAtom(_root, c, TRANS));\n    return this;\n}\n\nTeXFormula* TeXFormula::setColor(color c) {\n    if (istrans(c)) return this;\n    ColorAtom* ca = dynamic_cast<ColorAtom*>(_root.get());\n    if (ca != nullptr)\n        _root = sptr<Atom>(new ColorAtom(TRANS, c, _root));\n    else\n        _root = sptr<Atom>(new ColorAtom(_root, TRANS, c));\n    return this;\n}\n\nTeXFormula* TeXFormula::setFixedTypes(int left, int right) throw(ex_invalid_atom_type) {\n    _root = sptr<Atom>(new TypedAtom(left, right, _root));\n    return this;\n}\n\nsptr<TeXFormula> TeXFormula::get(const wstring& name) throw(ex_formula_not_found) {\n    auto it = _predefinedTeXFormulas.find(name);\n    if (it == _predefinedTeXFormulas.end()) {\n        auto i = _predefinedTeXFormulasAsString.find(name);\n        if (i == _predefinedTeXFormulasAsString.end())\n            throw ex_formula_not_found(wide2utf8(name.c_str()));\n        sptr<TeXFormula> tf(new TeXFormula(i->second));\n        RowAtom* ra = dynamic_cast<RowAtom*>(tf->_root.get());\n        if (ra == nullptr) {\n            _predefinedTeXFormulas[name] = tf;\n        }\n        return tf;\n    }\n    return it->second;\n}\n\nvoid TeXFormula::setDPITarget(float dpi) {\n    PIXELS_PER_POINT = dpi / 72.f;\n}\n\nbool TeXFormula::isRegisteredBlock(const UnicodeBlock& block) {\n    return _externalFontMap.find(block) != _externalFontMap.end();\n}\n\nFontInfos* TeXFormula::getExternalFont(const UnicodeBlock& block) {\n    auto it = _externalFontMap.find(block);\n    FontInfos* infos = nullptr;\n    if (it == _externalFontMap.end()) {\n        infos = new FontInfos(\"SansSerif\", \"Serif\");\n        _externalFontMap[block] = infos;\n    } else {\n        infos = it->second;\n    }\n    return infos;\n}\n\nvoid TeXFormula::addSymbolMappings(const string& file) throw(ex_res_parse) {\n    TeXFormulaSettingParser parser(file);\n    parser.parseSymbol(_symbolMappings, _symbolTextMappings);\n    parser.parseSymbol2Formula(_symbolFormulaMappings, _symbolTextMappings);\n}\n\nvoid TeXFormula::_free_() {\n    for (auto i : _externalFontMap) {\n        delete i.second;\n        i.second = nullptr;\n    }\n    _externalFontMap.clear();\n}\n\n/*************************************** ArrayOfAtoms implementation ******************************/\n\nArrayOfAtoms::ArrayOfAtoms() : _row(0), _col(0) {\n    _array.push_back(vector<sptr<Atom>>());\n}\n\nvoid ArrayOfAtoms::addCol() {\n    _array[_row].push_back(_root);\n    _root = nullptr;\n    _col++;\n}\n\nvoid ArrayOfAtoms::addCol(int n) {\n    _array[_row].push_back(_root);\n    for (int i = 1; i < n - 1; i++) {\n        _array[_row].push_back(nullptr);\n    }\n    _root = nullptr;\n    _col += n;\n}\n\nvoid ArrayOfAtoms::insertAtomIntoCol(int col, const sptr<Atom>& atom) {\n    _col++;\n    for (size_t j = 0; j < _row; j++) {\n        auto it = _array[j].begin();\n        if(col < _array[j].size()){\n            _array[j].insert(it + col, atom);\n        }\n    }\n}\n\nvoid ArrayOfAtoms::addRow() {\n    addCol();\n    _array.push_back(vector<sptr<Atom>>());\n    _row++;\n    _col = 0;\n}\n\nvoid ArrayOfAtoms::addRowSpecifier(const sptr<CellSpecifier>& spe) {\n    auto it = _rowSpecifiers.find(_row);\n    if (it == _rowSpecifiers.end())\n        _rowSpecifiers[_row] = vector<sptr<CellSpecifier>>();\n    _rowSpecifiers[_row].push_back(spe);\n}\n\nvoid ArrayOfAtoms::addCellSpecifier(const sptr<CellSpecifier>& spe) {\n    string str = tostring(_row) + tostring(_col);\n    auto it = _cellSpecifiers.find(str);\n    if (it == _cellSpecifiers.end())\n        _cellSpecifiers[str] = vector<sptr<CellSpecifier>>();\n    _cellSpecifiers[str].push_back(spe);\n}\n\nint ArrayOfAtoms::rows() const {\n    return _row;\n}\n\nint ArrayOfAtoms::cols() const {\n    return _col;\n}\n\nsptr<VRowAtom> ArrayOfAtoms::getAsVRow() {\n    VRowAtom* vr = new VRowAtom();\n    vr->setAddInterline(true);\n    for (size_t i = 0; i < _array.size(); i++) {\n        vector<sptr<Atom>>& c = _array[i];\n        for (size_t j = 0; j < c.size(); j++) vr->append(c[j]);\n    }\n    return sptr<VRowAtom>(vr);\n}\n\nvoid ArrayOfAtoms::checkDimensions() {\n    if (_array.back().size() != 0 || _root != nullptr) addRow();\n\n    _row = _array.size() - 1;\n    _col = _array[0].size();\n\n    // Find the column count of the widest row\n    for (size_t i = 1; i < _row; i++) {\n        if (_array[i].size() > _col) _col = _array[i].size();\n    }\n\n    for (size_t i = 0; i < _row; i++) {\n        size_t j = _array[i].size();\n        if (j != _col &&\n            _array[i][0] != nullptr &&\n            _array[i][0]->_type != TYPE_INTERTEXT) {\n            // Fill the row with null atom\n            vector<sptr<Atom>>& r = _array[i];\n            for (; j < _col; j++) r.push_back(nullptr);\n        }\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/core/formula.h",
    "content": "#ifndef FORMULA_H_INCLUDED\n#define FORMULA_H_INCLUDED\n\n#include \"atom/atom_basic.h\"\n#include \"core/parser.h\"\n#include \"fonts/alphabet.h\"\n#include \"graphic/graphic.h\"\n\n#include <string>\n\nusing namespace std;\nusing namespace tex;\n\nnamespace tex {\n\nclass TeXFont;\nclass CellSpecifier;\nclass TeXParser;\n\nstruct FontInfos {\n    const string _sansserif;\n    const string _serif;\n\n    FontInfos(const string& ss, const string& s) : _sansserif(ss), _serif(s) {}\n};\n\n/**\n * Represents a logical mathematical formula that will be displayed (by creating\n * a @link TeXRender @endlink from it and painting it) using algorithms that are based\n * on the TeX algorithms.\n * <p>\n * These formula's can be built using the built-in primitive TeX parser (methods\n * with String arguments) or using other TeXFormula objects. Most methods have\n * (an) equivalent(s) where one or more TeXFormula arguments are replaced with\n * String arguments. These are just shorter notations, because all they do is\n * parse the string(s) to TeXFormula's and call an equivalent method with (a)\n * TeXFormula argument(s). Most methods also come in 2 variants. One kind will\n * use this TeXFormula to build another mathematical construction and then\n * change this object to represent the newly build construction. The other kind\n * will only use other TeXFormula's (or parse strings), build a mathematical\n * construction with them and insert this newly build construction at the end of\n * this TeXFormula. Because all the provided methods return a pointer to this\n * (modified) TeXFormula, method chaining is also possible.\n * <p>\n * <b> Important: All the provided methods modify this TeXFormula object, but\n * all the TeXFormula arguments of these methods will remain unchanged and\n * independent of this TeXFormula object!</b>\n */\nclass TeXFormula {\nprivate:\n    TeXParser _parser;\n\n    void addImpl(const TeXFormula* f);\n\npublic:\n    map<string, string> _xmlMap;\n    // point-to-pixel conversion\n    static float PIXELS_PER_POINT;\n\n    // predefined TeX formulas\n    static map<wstring, sptr<TeXFormula>> _predefinedTeXFormulas;\n    static map<wstring, wstring> _predefinedTeXFormulasAsString;\n\n    // character-to-symbol and character-to-delimiter mappings\n    static map<int, string> _symbolMappings;\n    static map<int, string> _symbolTextMappings;\n    static map<int, string> _symbolFormulaMappings;\n    static map<UnicodeBlock, FontInfos*> _externalFontMap;\n\n    list<sptr<MiddleAtom>> _middle;\n    // the root atom of the \"atom tree\" that represents the formula\n    sptr<Atom> _root;\n    // the current text style\n    string _textStyle;\n\n    TeXFormula(const TeXParser& tp);\n\n    /**\n     * Creates a new TeXFormula by parsing the given string (using a primitive\n     * TeX parser).\n     *\n     * @param tp\n     *      the given TeXParser\n     * @param s\n     *      the string to be parsed\n     * @throw ex_parse\n     *      if the string could not be parsed correctly\n     */\n    TeXFormula(const TeXParser& tp, const wstring& s) throw(ex_parse);\n\n    TeXFormula(const TeXParser& tp, const wstring& s, bool firstpass) throw(ex_parse);\n\n    /**\n     * Creates a TeXFormula by parsing the given string in the given text style.\n     * Used when a text style command was found in the parse string.\n     */\n    TeXFormula(const TeXParser& tp, const wstring& s, const string& textStyle) throw(ex_parse);\n\n    TeXFormula(\n        const TeXParser& tp, const wstring& s,\n        const string& textStyle, bool firstpass, bool space) throw(ex_parse);\n\n    /**\n     * Create an empty TeXFormula\n     */\n    TeXFormula();\n\n    /**\n     * Creates a new TeXFormula by parsing the given string (using a primitive\n     * TeX parser).\n     *\n     * @param s\n     *      the string to be parsed\n     * @throw ex_parse\n     *      if the string could not be parsed correctly\n     */\n    TeXFormula(const wstring& s) throw(ex_parse);\n\n    TeXFormula(const wstring& s, bool firstpass) throw(ex_parse);\n\n    /**\n     * Creates a TeXFormula by parsing the given string in the given text style.\n     * Used when a text style command was found in the parse string.\n     */\n    TeXFormula(const wstring& s, const string& textStyle) throw(ex_parse);\n\n    TeXFormula(\n        const wstring& s, const string& textStyle, bool firstpass, bool space) throw(ex_parse);\n\n    /**\n     * Creates a new TeXFormula that is a copy of the given TeXFormula.\n     * <p>\n     * <b>Both TeXFormula's are independent of one another!</b>\n     *\n     * @param f\n     *      the formula to be copied\n     */\n    TeXFormula(const TeXFormula* f);\n\n    /**\n     * Change the text of the TeXFormula and regenerate the root atom.\n     *\n     * @param latex\n     *      the latex formula\n     */\n    void setLaTeX(const wstring& latex) throw(ex_parse);\n\n    /**\n     * Inserts an atom at the end of the current formula.\n     */\n    TeXFormula* add(const sptr<Atom>& el);\n\n    TeXFormula* append(const wstring& s) throw(ex_parse);\n\n    TeXFormula* append(bool isPartial, const wstring& s) throw(ex_parse);\n\n    /**\n     * Convert this TeXFormula into a box, with the given style\n     */\n    sptr<Box> createBox(_out_ TeXEnvironment& style);\n\n    /**\n     * Changes the background color of the <i>current</i> TeXFormula into the\n     * given color. By default, a TeXFormula has no background color, it's\n     * transparent. The backgrounds of subformula's will be painted on top of\n     * the background of the whole formula! Any changes that will be made to\n     * this TeXFormula after this background color was set, will have the\n     * default background color (unless it will also be changed into another\n     * color afterwards)!\n     *\n     * @param c\n     *      the desired background color for the <i>current</i> TeXFormula\n     * @return the modified TeXFormula\n     */\n    TeXFormula* setBackground(color c);\n\n    /**\n     * Changes the (foreground) color of the <i>current</i> TeXFormula into the\n     * given color. By default, the foreground color of a TeXFormula is the\n     * foreground color of the component on which the TeXRender (created from this\n     * TeXFormula) will be painted. The color of subformula's overrides the\n     * color of the whole formula. Any changes that will be made to this\n     * TeXFormula after this color was set, will be painted in the default color\n     * (unless the color will also be changed afterwards into another color)!\n     *\n     * @param c\n     *      the desired foreground color for the <i>current</i> TeXFormula\n     * @return the modified TeXFormula\n     */\n    TeXFormula* setColor(color c);\n\n    /**\n     * Sets a fixed left and right type of the current TeXFormula. This has an\n     * influence on the glue that will be inserted before and after this\n     * TeXFormula.\n     *\n     * @param left\n     *      the left type of this formula @see TeXConstants\n     * @param right\n     *      the right type of this formula @see TeXConstants\n     * @return the modified TeXFormula\n     * @throw ex_invalid_atom_type\n     *      if the given value does not represent a valid atom type\n     */\n    TeXFormula* setFixedTypes(int left, int right) throw(ex_invalid_atom_type);\n\n    /**\n     * Test if this formula is in array mode.\n     */\n    virtual bool isArrayMode() const { return false; }\n\n    /**\n     * Get a predefined TeXFormula.\n     *\n     * @param name\n     *      the name of the predefined TeXFormula\n     * @return a <b>copy</b> of the predefined TeXFormula\n     * @throw ex_formula_not_found\n     *      if no predefined TeXFormula is found with the given name\n     */\n    static sptr<TeXFormula> get(const wstring& name) throw(ex_formula_not_found);\n\n    /**\n     * Set the DPI of target\n     *\n     * @param dpi\n     *      the target DPI\n     */\n    static void setDPITarget(float dpi);\n\n    /**\n     * Check if the given unicode-block is registered.\n     */\n    static bool isRegisteredBlock(const UnicodeBlock& block);\n\n    static FontInfos* getExternalFont(const UnicodeBlock& block);\n\n    static void addSymbolMappings(const string& file) throw(ex_res_parse);\n\n    /**\n     * Enable or disable debug mode.\n     */\n    static void setDEBUG(bool b);\n\n    static void _init_();\n\n    static void _free_();\n\n    virtual ~TeXFormula() {}\n};\n\nclass ArrayOfAtoms : public TeXFormula {\nprivate:\n    size_t _row, _col;\n\npublic:\n    vector<vector<sptr<Atom>>> _array;\n    map<int, vector<sptr<CellSpecifier>>> _rowSpecifiers;\n    map<string, vector<sptr<CellSpecifier>>> _cellSpecifiers;\n\n    ArrayOfAtoms();\n\n    void addCol();\n\n    void addCol(int n);\n\n    void insertAtomIntoCol(int col, const sptr<Atom>& atom);\n\n    void addRow();\n\n    void addRowSpecifier(const sptr<CellSpecifier>& spe);\n\n    void addCellSpecifier(const sptr<CellSpecifier>& spe);\n\n    int rows() const;\n\n    int cols() const;\n\n    sptr<VRowAtom> getAsVRow();\n\n    void checkDimensions();\n\n    virtual bool isArrayMode() const override { return true; }\n\n    virtual ~ArrayOfAtoms() {}\n};\n\n}  // namespace tex\n\n#endif  // FORMULA_H_INCLUDED\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/core/formula_def.cpp",
    "content": "#include \"core/formula.h\"\n\nusing namespace std;\nusing namespace tex;\n\nmap<wstring, wstring> TeXFormula::_predefinedTeXFormulasAsString = {\n    {L\"qquad\", L\"\\\\quad\\\\quad\"},\n    {L\" \", L\"\\\\nbsp\"},\n    {L\"ne\", L\"\\\\not\\\\equals\"},\n    {L\"neq\", L\"\\\\not\\\\equals\"},\n    {L\"ldots\", L\"\\\\mathinner{\\\\ldotp\\\\ldotp\\\\ldotp}\"},\n    {L\"dotsc\", L\"\\\\ldots\"},\n    {L\"dots\", L\"\\\\ldots\"},\n    {L\"cdots\", L\"\\\\mathinner{\\\\cdotp\\\\cdotp\\\\cdotp}\"},\n    {L\"dotsb\", L\"\\\\cdots\"},\n    {L\"dotso\", L\"\\\\ldots\"},\n    {L\"dotsi\", L\"\\\\!\\\\cdots\"},\n    {L\"bowtie\", L\"\\\\mathrel\\\\triangleright\\\\joinrel\\\\mathrel\\\\triangleleft\"},\n    {L\"models\", L\"\\\\mathrel|\\\\joinrel\\\\equals\"},\n    {L\"Doteq\", L\"\\\\doteqdot\"},\n    {L\"{\", L\"\\\\lbrace\"},\n    {L\"}\", L\"\\\\rbrace\"},\n    {L\"|\", L\"\\\\Vert\"},\n    {L\"&\", L\"\\\\textampersand\"},\n    {L\"%\", L\"\\\\textpercent\"},\n    {L\"_\", L\"\\\\underscore\"},\n    {L\"$\", L\"\\\\textdollar\"},\n    {L\"@\", L\"\\\\matharobase\"},\n    {L\"#\", L\"\\\\mathsharp\"},\n    {L\"relbar\", L\"\\\\mathrel{\\\\smash-}\"},\n    {L\"hookrightarrow\", L\"\\\\lhook\\\\joinrel\\\\joinrel\\\\joinrel\\\\rightarrow\"},\n    {L\"hookleftarrow\", L\"\\\\leftarrow\\\\joinrel\\\\joinrel\\\\joinrel\\\\rhook\"},\n    {L\"Longrightarrow\", L\"\\\\Relbar\\\\joinrel\\\\Rightarrow\"},\n    {L\"longrightarrow\", L\"\\\\relbar\\\\joinrel\\\\rightarrow\"},\n    {L\"Longleftarrow\", L\"\\\\Leftarrow\\\\joinrel\\\\Relbar\"},\n    {L\"longleftarrow\", L\"\\\\leftarrow\\\\joinrel\\\\relbar\"},\n    {L\"Longleftrightarrow\", L\"\\\\Leftarrow\\\\joinrel\\\\Rightarrow\"},\n    {L\"longleftrightarrow\", L\"\\\\leftarrow\\\\joinrel\\\\rightarrow\"},\n    {L\"iff\", L\"\\\\;\\\\Longleftrightarrow\\\\;\"},\n    {L\"implies\", L\"\\\\;\\\\Longrightarrow\\\\;\"},\n    {L\"impliedby\", L\"\\\\;\\\\Longleftarrow\\\\;\"},\n    {L\"mapsto\", L\"\\\\mapstochar\\\\rightarrow\"},\n    {L\"longmapsto\", L\"\\\\mapstochar\\\\longrightarrow\"},\n    {L\"log\", L\"\\\\mathop{\\\\mathrm{log}}\\\\nolimits\"},\n    {L\"lg\", L\"\\\\mathop{\\\\mathrm{lg}}\\\\nolimits\"},\n    {L\"ln\", L\"\\\\mathop{\\\\mathrm{ln}}\\\\nolimits\"},\n    {L\"ln\", L\"\\\\mathop{\\\\mathrm{ln}}\\\\nolimits\"},\n    {L\"lim\", L\"\\\\mathop{\\\\mathrm{lim}}\"},\n    {L\"limsup\", L\"\\\\mathop{\\\\mathrm{lim\\\\,sup}}\"},\n    {L\"liminf\", L\"\\\\mathop{\\\\mathrm{lim\\\\,inf}}\"},\n    {L\"injlim\", L\"\\\\mathop{\\\\mathrm{inj\\\\,lim}}\"},\n    {L\"projlim\", L\"\\\\mathop{\\\\mathrm{proj\\\\,lim}}\"},\n    {L\"varinjlim\", L\"\\\\mathop{\\\\underrightarrow{\\\\mathrm{lim}}}\"},\n    {L\"varprojlim\", L\"\\\\mathop{\\\\underleftarrow{\\\\mathrm{lim}}}\"},\n    {L\"varliminf\", L\"\\\\mathop{\\\\underline{\\\\mathrm{lim}}}\"},\n    {L\"varlimsup\", L\"\\\\mathop{\\\\overline{\\\\mathrm{lim}}}\"},\n    {L\"sin\", L\"\\\\mathop{\\\\mathrm{sin}}\\\\nolimits\"},\n    {L\"arcsin\", L\"\\\\mathop{\\\\mathrm{arcsin}}\\\\nolimits\"},\n    {L\"sinh\", L\"\\\\mathop{\\\\mathrm{sinh}}\\\\nolimits\"},\n    {L\"cos\", L\"\\\\mathop{\\\\mathrm{cos}}\\\\nolimits\"},\n    {L\"arccos\", L\"\\\\mathop{\\\\mathrm{arccos}}\\\\nolimits\"},\n    {L\"cot\", L\"\\\\mathop{\\\\mathrm{cot}}\\\\nolimits\"},\n    {L\"arccot\", L\"\\\\mathop{\\\\mathrm{arccot}}\\\\nolimits\"},\n    {L\"cosh\", L\"\\\\mathop{\\\\mathrm{cosh}}\\\\nolimits\"},\n    {L\"tan\", L\"\\\\mathop{\\\\mathrm{tan}}\\\\nolimits\"},\n    {L\"arctan\", L\"\\\\mathop{\\\\mathrm{arctan}}\\\\nolimits\"},\n    {L\"tanh\", L\"\\\\mathop{\\\\mathrm{tanh}}\\\\nolimits\"},\n    {L\"coth\", L\"\\\\mathop{\\\\mathrm{coth}}\\\\nolimits\"},\n    {L\"sec\", L\"\\\\mathop{\\\\mathrm{sec}}\\\\nolimits\"},\n    {L\"arcsec\", L\"\\\\mathop{\\\\mathrm{arcsec}}\\\\nolimits\"},\n    {L\"arccsc\", L\"\\\\mathop{\\\\mathrm{arccsc}}\\\\nolimits\"},\n    {L\"sech\", L\"\\\\mathop{\\\\mathrm{sech}}\\\\nolimits\"},\n    {L\"csc\", L\"\\\\mathop{\\\\mathrm{csc}}\\\\nolimits\"},\n    {L\"csch\", L\"\\\\mathop{\\\\mathrm{csch}}\\\\nolimits\"},\n    {L\"max\", L\"\\\\mathop{\\\\mathrm{max}}\"},\n    {L\"min\", L\"\\\\mathop{\\\\mathrm{min}}\"},\n    {L\"sup\", L\"\\\\mathop{\\\\mathrm{sup}}\"},\n    {L\"inf\", L\"\\\\mathop{\\\\mathrm{inf}}\"},\n    {L\"arg\", L\"\\\\mathop{\\\\mathrm{arg}}\\\\nolimits\"},\n    {L\"ker\", L\"\\\\mathop{\\\\mathrm{ker}}\\\\nolimits\"},\n    {L\"dim\", L\"\\\\mathop{\\\\mathrm{dim}}\\\\nolimits\"},\n    {L\"hom\", L\"\\\\mathop{\\\\mathrm{hom}}\\\\nolimits\"},\n    {L\"det\", L\"\\\\mathop{\\\\mathrm{det}}\"},\n    {L\"exp\", L\"\\\\mathop{\\\\mathrm{exp}}\\\\nolimits\"},\n    {L\"Pr\", L\"\\\\mathop{\\\\mathrm{Pr}}\"},\n    {L\"gcd\", L\"\\\\mathop{\\\\mathrm{gcd}}\"},\n    {L\"deg\", L\"\\\\mathop{\\\\mathrm{deg}}\\\\nolimits\"},\n    {L\"bmod\", L\"\\\\:\\\\mathbin{\\\\mathrm{mod}}\\\\:\"},\n    {L\"Mapsto\", L\"\\\\Mapstochar\\\\Rightarrow\"},\n    {L\"mapsfrom\", L\"\\\\leftarrow\\\\mapsfromchar\"},\n    {L\"Mapsfrom\", L\"\\\\Leftarrow\\\\Mapsfromchar\"},\n    {L\"Longmapsto\", L\"\\\\Mapstochar\\\\Longrightarrow\"},\n    {L\"longmapsfrom\", L\"\\\\longleftarrow\\\\mapsfromchar\"},\n    {L\"Longmapsfrom\", L\"\\\\Longleftarrow\\\\Mapsfromchar\"},\n    {L\"arrowvert\", L\"\\\\vert\"},\n    {L\"Arrowvert\", L\"\\\\Vert\"},\n    {L\"aa\", L\"\\\\mathring{a}\"},\n    {L\"AA\", L\"\\\\mathring{A}\"},\n    {L\"ddag\", L\"\\\\ddagger\"},\n    {L\"dag\", L\"\\\\dagger\"},\n    {L\"Doteq\", L\"\\\\doteqdot\"},\n    {L\"doublecup\", L\"\\\\Cup\"},\n    {L\"doublecap\", L\"\\\\Cap\"},\n    {L\"llless\", L\"\\\\lll\"},\n    {L\"gggtr\", L\"\\\\ggg\"},\n    {L\"Alpha\", L\"\\\\mathord{\\\\mathrm{A}}\"},\n    {L\"Beta\", L\"\\\\mathord{\\\\mathrm{B}}\"},\n    {L\"Epsilon\", L\"\\\\mathord{\\\\mathrm{E}}\"},\n    {L\"Zeta\", L\"\\\\mathord{\\\\mathrm{Z}}\"},\n    {L\"Eta\", L\"\\\\mathord{\\\\mathrm{H}}\"},\n    {L\"Iota\", L\"\\\\mathord{\\\\mathrm{I}}\"},\n    {L\"Kappa\", L\"\\\\mathord{\\\\mathrm{K}}\"},\n    {L\"Mu\", L\"\\\\mathord{\\\\mathrm{M}}\"},\n    {L\"Nu\", L\"\\\\mathord{\\\\mathrm{N}}\"},\n    {L\"Omicron\", L\"\\\\mathord{\\\\mathrm{O}}\"},\n    {L\"Rho\", L\"\\\\mathord{\\\\mathrm{P}}\"},\n    {L\"Tau\", L\"\\\\mathord{\\\\mathrm{T}}\"},\n    {L\"Chi\", L\"\\\\mathord{\\\\mathrm{X}}\"},\n    {L\"hdots\", L\"\\\\ldots\"},\n    {L\"restriction\", L\"\\\\upharpoonright\"},\n    {L\"celsius\", L\"\\\\mathord{{}^\\\\circ\\\\mathrm{C}}\"},\n    {L\"micro\", L\"\\\\textmu\"},\n    {L\"marker\", L\"\\\\kern{0.25ex}\\\\rule{0.5ex}{1.2ex}\\\\kern{0.25ex}\"},\n    {L\"hybull\", L\"\\\\rule[0.6ex]{1ex}{0.2ex}\"},\n    {L\"block\", L\"\\\\rule{1ex}{1.2ex}\"},\n    {L\"uhblk\", L\"\\\\rule[0.6ex]{1ex}{0.6ex}\"},\n    {L\"lhblk\", L\"\\\\rule{1ex}{0.6ex}\"},\n    {L\"notin\", L\"\\\\not\\\\in\"},\n    {L\"rVert\", L\"\\\\Vert\"},\n    {L\"lVert\", L\"\\\\Vert\"},\n    {L\"lvert\", L\"\\\\vert\"},\n    {L\"rvert\", L\"\\\\vert\"},\n    {L\"Android\", L\"\\\\Huge{\\\\android}\\\\normalsize\"},\n    {L\"AndroidTeX\", L\"\\\\Android\\\\large{\\\\dT\\\\dE\\\\dX}\\\\normalsize\"},\n    {L\"TeX\", L\"\\\\large{\\\\dT\\\\dE\\\\dX}\\\\normalsize\"}};\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/core/localized_num.cpp",
    "content": "#include \"core/parser.h\"\n\nwchar_t tex::convertToRomanNumber(wchar_t c) {\n    if (c == 0x66b) {  // Arabic dot\n        return '.';\n    } else if (0x660 <= c && c <= 0x669) {  // Arabic\n        return (wchar_t)(c - (wchar_t)0x630);\n    } else if (0x6f0 <= c && c <= 0x6f9) {  // Arabic\n        return (wchar_t)(c - (wchar_t)0x6c0);\n    } else if (0x966 <= c && c <= 0x96f) {  // Devanagari\n        return (wchar_t)(c - (wchar_t)0x936);\n    } else if (0x9e6 <= c && c <= 0x9ef) {  // Bengali\n        return (wchar_t)(c - (wchar_t)0x9b6);\n    } else if (0xa66 <= c && c <= 0xa6f) {  // Gurmukhi\n        return (wchar_t)(c - (wchar_t)0xa36);\n    } else if (0xae6 <= c && c <= 0xaef) {  // Gujarati\n        return (wchar_t)(c - (wchar_t)0xab6);\n    } else if (0xb66 <= c && c <= 0xb6f) {  // Oriya\n        return (wchar_t)(c - (wchar_t)0xb36);\n    } else if (0xc66 <= c && c <= 0xc6f) {  // Telugu\n        return (wchar_t)(c - (wchar_t)0xc36);\n    } else if (0xd66 <= c && c <= 0xd6f) {  // Malayalam\n        return (wchar_t)(c - (wchar_t)0xd36);\n    } else if (0xe50 <= c && c <= 0xe59) {  // Thai\n        return (wchar_t)(c - (wchar_t)0xe20);\n    } else if (0xed0 <= c && c <= 0xed9) {  // Lao\n        return (wchar_t)(c - (wchar_t)0xea0);\n    } else if (0xf20 <= c && c <= 0xf29) {  // Tibetan\n        return (wchar_t)(c - (wchar_t)0xe90);\n    } else if (0x1040 <= c && c <= 0x1049) {  // Myanmar\n        return (wchar_t)(c - (wchar_t)0x1010);\n    } else if (0x17e0 <= c && c <= 0x17e9) {  // Khmer\n        return (wchar_t)(c - (wchar_t)0x17b0);\n    } else if (0x1810 <= c && c <= 0x1819) {  // Mongolian\n        return (wchar_t)(c - (wchar_t)0x17e0);\n    } else if (0x1b50 <= c && c <= 0x1b59) {  // Balinese\n        return (wchar_t)(c - (wchar_t)0x1b20);\n    } else if (0x1bb0 <= c && c <= 0x1bb9) {  // Sundanese\n        return (wchar_t)(c - (wchar_t)0x1b80);\n    } else if (0x1c40 <= c && c <= 0x1c49) {  // Lepcha\n        return (wchar_t)(c - (wchar_t)0x1c10);\n    } else if (0x1c50 <= c && c <= 0x1c59) {  // Ol Chiki\n        return (wchar_t)(c - (wchar_t)0x1c20);\n    } else if (0xa8d0 <= c && c <= 0xa8d9) {  // Saurashtra\n        return (wchar_t)(c - (wchar_t)0xa8a0);\n    }\n\n    return c;\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/core/macro.cpp",
    "content": "#include \"core/macro.h\"\n#include \"common.h\"\n#include \"core/macro_impl.h\"\n\n#include <string>\n\nusing namespace std;\nusing namespace tex;\n\nbool NewCommandMacro::_errIfConflict = true;\n\nbool NewCommandMacro::isMacro(const wstring& name) {\n    auto it = _macrocode.find(name);\n    return (it != _macrocode.end());\n}\n\nvoid NewCommandMacro::checkNew(const wstring& name) throw(ex_parse) {\n    if (_errIfConflict && isMacro(name)) throw ex_parse(\n        \"Command \" + wide2utf8(name.c_str()) +\n        \" already exists! Use renewcommand instead!\");\n}\n\nvoid NewCommandMacro::checkRenew(const wstring& name) throw(ex_parse) {\n    if (NewCommandMacro::_errIfConflict && !isMacro(name)) throw ex_parse(\n        \"Command \" + wide2utf8(name.c_str()) +\n        \" is no defined! Use newcommand instead!\");\n}\n\nvoid NewCommandMacro::addNewCommand(\n    const wstring& name, const wstring& code, int nbargs) throw(ex_parse) {\n    checkNew(name);\n    _macrocode[name] = code;\n    MacroInfo::addMacro(name, new InflationMacroInfo(_instance, nbargs));\n}\n\nvoid NewCommandMacro::addNewCommand(\n    const wstring& name,\n    const wstring& code,\n    int nbargs,\n    const wstring& def) throw(ex_parse) {\n    checkNew(name);\n    _macrocode[name] = code;\n    _macroreplacement[name] = def;\n    MacroInfo::addMacro(name, new InflationMacroInfo(_instance, nbargs, 1));\n}\n\nvoid NewCommandMacro::addRenewCommand(\n    const wstring& name, const wstring& code, int nbargs) throw(ex_parse) {\n    checkRenew(name);\n    _macrocode[name] = code;\n    MacroInfo::addMacro(name, new InflationMacroInfo(_instance, nbargs));\n}\n\nvoid NewCommandMacro::addRenewCommand(\n    const wstring& name,\n    const wstring& code,\n    int nbargs,\n    const wstring& def) throw(ex_parse) {\n    checkRenew(name);\n    _macrocode[name] = code;\n    _macroreplacement[name] = def;\n    MacroInfo::addMacro(name, new InflationMacroInfo(_instance, nbargs, 1));\n}\n\nvoid NewCommandMacro::execute(_out_ TeXParser& tp, _out_ vector<wstring>& args) {\n    wstring code = _macrocode[args[0]];\n    wstring rep;\n    int nbargs = args.size() - 12;\n    int dec = 0;\n\n    auto it = _macroreplacement.find(args[0]);\n\n    // FIXME\n    // Keep slash \"\\\" and dollar \"$\" signs?\n    // Example:\n    //      \\newcommand{\\cmd}[2][\\sqrt{e^x}]{ #2 - #1 }\n    // we want the optional argument \"\\sqrt{e^x}\" keep the slash sign\n    if (!args[nbargs + 1].empty()) {\n        dec = 1;\n        // quotereplace(args[nbargs + 1], rep);\n        replaceall(code, L\"#1\", args[nbargs + 1]);\n    } else if (it != _macroreplacement.end()) {\n        dec = 1;\n        // quotereplace(it->second, rep);\n        replaceall(code, L\"#1\", it->second);\n    }\n\n    for (int i = 1; i <= nbargs; i++) {\n        rep = args[i];\n        replaceall(code, L\"#\" + towstring(i + dec), rep);\n    }\n    // push back as returned value (inflated macro)\n    args.push_back(code);\n}\n\nvoid NewEnvironmentMacro::addNewEnvironment(\n    const wstring& name,\n    const wstring& begdef, const wstring& enddef,\n    int nbargs) throw(ex_parse) {\n    wstring n = name + L\"@env\";\n    wstring def = begdef + L\" #\" + towstring(nbargs + 1) + L\" \" + enddef;\n    addNewCommand(n, def, nbargs + 1);\n}\n\nvoid NewEnvironmentMacro::addRenewEnvironment(\n    const wstring& name,\n    const wstring& begdef, const wstring& enddef,\n    int nbargs) throw(ex_parse) {\n    if (_macrocode.find(name + L\"@env\") == _macrocode.end()) {\n        throw ex_parse(\n            \"Environment \" + wide2utf8(name.c_str()) +\n            \"is not defined! Use newenvironment instead!\");\n    }\n    addRenewCommand(\n        name + L\"@env\",\n        begdef + L\" #\" + towstring(nbargs + 1) + L\" \" + enddef,\n        nbargs + 1);\n}\n\nvoid NewCommandMacro::_free_() {\n    if(_instance != nullptr){\n        delete _instance;\n    }\n    _instance = nullptr;\n    _macrocode.clear();\n    _macroreplacement.clear();\n}\n\nvoid MacroInfo::addMacro(const wstring& name, MacroInfo* mac) {\n    auto it = _commands.find(name);\n    if (it != _commands.end()) {\n        delete it->second;\n        it->second = nullptr;\n    }\n    _commands[name] = mac;\n}\n\nvoid MacroInfo::_free_() {\n    for (auto i : _commands) {\n        delete i.second;\n        i.second = nullptr;\n    }\n}\n\nsptr<Atom> PredefMacroInfo::invoke(\n    _out_ TeXParser& tp,\n    _out_ vector<wstring>& args) throw(ex_parse) {\n    try {\n        return _delegate(tp, args);\n    } catch (ex_parse& e) {\n        throw ex_parse(\n            \"Problem with command \" +\n            wide2utf8(args[0].c_str()) +\n            \" at position \" + tostring(tp.getLine()) + \":\" +\n            tostring(tp.getCol()) + \"\\n caused by: \" + e.what());\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/core/macro.h",
    "content": "#ifndef MACRO_H_INCLUDED\n#define MACRO_H_INCLUDED\n\n#include \"atom/atom.h\"\n#include \"common.h\"\n\n#include <map>\n#include <string>\n\nusing namespace tex;\nusing namespace std;\n\nnamespace tex {\n\nclass TeXParser;\n\nclass Macro {\npublic:\n    virtual void execute(_out_ TeXParser& tp, _out_ vector<wstring>& args) = 0;\n\n    virtual ~Macro() {}\n};\n\nclass NewCommandMacro : public Macro {\nprotected:\n    static map<wstring, wstring> _macrocode;\n    static map<wstring, wstring> _macroreplacement;\n    static Macro* _instance;\n\n    static void checkNew(const wstring& name) throw(ex_parse);\n\n    static void checkRenew(const wstring& name) throw(ex_parse);\n\npublic:\n    /**\n     * If notify a fatal error when defining a new command but it has been\n     * defined already or redefine a command but it has not been defined,\n     * default is true.\n     */\n    static bool _errIfConflict;\n\n    virtual void execute(_out_ TeXParser& tp, _out_ vector<wstring>& args) override;\n\n    static void addNewCommand(\n        const wstring& name,\n        const wstring& code,\n        int nbargs) throw(ex_parse);\n\n    static void addNewCommand(\n        const wstring& name,\n        const wstring& code,\n        int nbargs,\n        const wstring& def) throw(ex_parse);\n\n    static void addRenewCommand(\n        const wstring& name,\n        const wstring& code,\n        int nbargs) throw(ex_parse);\n\n    static void addRenewCommand(\n        const wstring& name,\n        const wstring& code,\n        int nbargs,\n        const wstring& def) throw(ex_parse);\n\n    static bool isMacro(const wstring& name);\n\n    static void _init_();\n\n    static void _free_();\n\n    virtual ~NewCommandMacro() {}\n};\n\nclass NewEnvironmentMacro : public NewCommandMacro {\npublic:\n    static void addNewEnvironment(\n        const wstring& name,\n        const wstring& begdef,\n        const wstring& enddef,\n        int nbargs) throw(ex_parse);\n\n    static void addRenewEnvironment(\n        const wstring& name,\n        const wstring& begdef,\n        const wstring& enddef,\n        int nbargs) throw(ex_parse);\n};\n\nclass MacroInfo {\npublic:\n    static map<wstring, MacroInfo*> _commands;\n\n    /**\n     * Add a macro, replace it if the macro is exists.\n     */\n    static void addMacro(const wstring& name, MacroInfo* mac);\n\n    // Number of arguments\n    const int _nbArgs;\n    // Options' position, can be  0, 1 and 2\n    // 0 represetns this macro has no options\n    // 1 represents the options appear after the command name, e.g.:\n    //      \\sqrt[3]{2}\n    // 2 represents the options appear after the first argument, e.g.:\n    //      \\scalebox{0.5}[2]{\\LaTeX}\n    const int _posOpts;\n\n    MacroInfo() : _nbArgs(0), _posOpts(0) {}\n\n    MacroInfo(int nbargs, int posOpts) : _nbArgs(nbargs), _posOpts(posOpts) {}\n\n    MacroInfo(int nbargs) : _nbArgs(nbargs), _posOpts(0) {}\n\n    inline bool hasOptions() const {\n        return _posOpts != 0;\n    }\n\n    virtual sptr<Atom> invoke(\n        _out_ TeXParser& tp,\n        _out_ vector<wstring>& args) throw(ex_parse) {\n        return nullptr;\n    }\n\n    virtual ~MacroInfo() {}\n\n    static void _free_();\n};\n\nclass InflationMacroInfo : public MacroInfo {\nprivate:\n    // The actual macro to execute\n    Macro* const _macro;\n\npublic:\n    InflationMacroInfo(Macro* macro, int nbargs)\n        : _macro(macro), MacroInfo(nbargs) {}\n\n    InflationMacroInfo(Macro* macro, int nbargs, int posOpts)\n        : _macro(macro), MacroInfo(nbargs, posOpts) {}\n\n    virtual sptr<Atom> invoke(\n        _out_ TeXParser& tp,\n        _out_ vector<wstring>& args) throw(ex_parse) override {\n        _macro->execute(tp, args);\n        return nullptr;\n    }\n};\n\ntypedef sptr<Atom> (*MacroDelegate)(\n    _out_ TeXParser& tp,\n    _out_ vector<wstring>& args);\n\nclass PredefMacroInfo : public MacroInfo {\nprivate:\n    MacroDelegate _delegate;\n\npublic:\n    PredefMacroInfo() = delete;\n\n    PredefMacroInfo(int nbargs, int posOpts, MacroDelegate delegate)\n        : MacroInfo(nbargs, posOpts), _delegate(delegate) {}\n\n    PredefMacroInfo(int nbargs, MacroDelegate delegate)\n        : MacroInfo(nbargs), _delegate(delegate) {}\n\n    sptr<Atom> invoke(\n        _out_ TeXParser& tp,\n        _out_ vector<wstring>& args) throw(ex_parse) override;\n};\n\n}  // namespace tex\n\n#endif  // MACRO_H_INCLUDED\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/core/macro_def.cpp",
    "content": "#include \"common.h\"\n#include \"core/macro.h\"\n#include \"macro_impl.h\"\n\nusing namespace std;\nusing namespace tex;\n\n#define mac3(nbargs, name, code) \\\n    { L##code, m(nbargs, name) }\n\n#define mac4(nbargs, posOpts, name, code) \\\n    { L##code, m(nbargs, posOpts, name) }\n\n#define __mac__(_1, _2, _3, _4, name, ...) name\n#define mac(...) __mac__(__VA_ARGS__, mac4, mac3)(__VA_ARGS__)\n\ninline static PredefMacroInfo* m(int nbargs, int posOpts, MacroDelegate del) {\n    return new PredefMacroInfo(nbargs, posOpts, del);\n}\n\ninline static PredefMacroInfo* m(int nbargs, MacroDelegate del) {\n    return new PredefMacroInfo(nbargs, del);\n}\n\nmap<wstring, MacroInfo*> MacroInfo::_commands = {\n    mac(2, 2, macro_newcommand, \"newcommand\"),\n    mac(2, 2, macro_renewcommand, \"renewcommand\"),\n    mac(2, 1, macro_rule, \"rule\"),\n    mac(1, 1, macro_includegraphics, \"includegraphics\"),\n    mac(2, 1, macro_cfrac, \"cfrac\"),\n    mac(1, 1, macro_xleftarrow, \"xleftarrow\"),\n    mac(1, 1, macro_xrightarrow, \"xrightarrow\"),\n    mac(1, 1, macro_sqrt, \"sqrt\"),\n    mac(1, 1, macro_smash, \"smash\"),\n    mac(1, 1, macro_hdotsfor, \"hdotsfor\"),\n    mac(2, 1, macro_stackrel, \"stackrel\"),\n    mac(2, 1, macro_stackbin, \"stackbin\"),\n    mac(2, 1, macro_rotatebox, \"rotatebox\"),\n    mac(2, 2, macro_scalebox, \"scalebox\"),\n    mac(2, 2, macro_raisebox, \"raisebox\"),\n    mac(1, 1, macro_dynamic, \"dynamic\"),\n    mac(1, macro_fatalIfCmdConflict, \"fatalIfCmdConflict\"),\n    mac(1, macro_breakEverywhere, \"breakEverywhere\"),\n    mac(3, macro_newenvironment, \"newenvironment\"),\n    mac(3, macro_renewenvironment, \"renewenvironment\"),\n    mac(0, macro_makeatletter, \"makeatletter\"),\n    mac(0, macro_makeatother, \"makeatother\"),\n    mac(1, macro_smallmatrixATATenv, \"smallmatrix@@env\"),\n    mac(1, macro_matrixATATenv, \"matrix@@env\"),\n    mac(2, macro_arrayATATenv, \"array@@env\"),\n    mac(2, macro_alignATATenv, \"align@@env\"),\n    mac(2, macro_alignedATATenv, \"aligned@@env\"),\n    mac(2, macro_flalignATATenv, \"flalign@@env\"),\n    mac(2, macro_alignatATATenv, \"alignat@@env\"),\n    mac(2, macro_alignedatATATenv, \"alignedat@@env\"),\n    mac(2, macro_multlineATATenv, \"multline@@env\"),\n    mac(2, macro_gatherATATenv, \"gather@@env\"),\n    mac(2, macro_gatheredATATenv, \"gathered@@env\"),\n    mac(1, macro_hvspace, \"hspace\"),\n    mac(1, macro_hvspace, \"vspace\"),\n    mac(1, macro_clrlap, \"llap\"),\n    mac(1, macro_clrlap, \"rlap\"),\n    mac(1, macro_clrlap, \"clap\"),\n    mac(1, macro_mathclrlap, \"mathllap\"),\n    mac(1, macro_mathclrlap, \"mathrlap\"),\n    mac(1, macro_mathclrlap, \"mathclap\"),\n    mac(2, macro_frac, \"frac\"),\n    mac(2, macro_sfrac, \"sfrac\"),\n    mac(6, macro_genfrac, \"genfrac\"),\n    mac(0, macro_over, \"over\"),\n    mac(2, macro_overwithdelims, \"overwithdelims\"),\n    mac(0, macro_atop, \"atop\"),\n    mac(2, macro_atopwithdelims, \"atopwithdelims\"),\n    mac(0, macro_choose, \"choose\"),\n    mac(0, macro_brace, \"brace\"),\n    mac(0, macro_brack, \"brack\"),\n    mac(0, macro_bangle, \"bangle\"),\n    mac(0, macro_underscore, \"underscore\"),\n    mac(1, macro_mbox, \"mbox\"),\n    mac(1, macro_text, \"text\"),\n    mac(1, macro_intertext, \"intertext\"),\n    mac(2, macro_binom, \"binom\"),\n    mac(1, macro_mathbf, \"mathbf\"),\n    mac(0, macro_bf, \"bf\"),\n    mac(1, macro_textstyles, \"mathbb\"),\n    mac(1, macro_textstyles, \"mathcal\"),\n    mac(1, macro_textstyles, \"cal\"),\n    mac(1, macro_mathit, \"mathit\"),\n    mac(0, macro_it, \"it\"),\n    mac(1, macro_mathrm, \"mathrm\"),\n    mac(0, macro_rm, \"rm\"),\n    mac(1, macro_textstyles, \"mathscr\"),\n    mac(1, macro_mathsf, \"mathsf\"),\n    mac(0, macro_sf, \"sf\"),\n    mac(1, macro_mathtt, \"mathtt\"),\n    mac(0, macro_tt, \"tt\"),\n    mac(1, macro_textstyles, \"mathfrak\"),\n    mac(1, macro_textstyles, \"mathds\"),\n    mac(1, macro_textstyles, \"frak\"),\n    mac(1, macro_textstyles, \"Bbb\"),\n    mac(1, macro_textstyles, \"oldstylenums\"),\n    mac(1, macro_textstyles, \"bold\"),\n    mac(1, macro_accentbiss, \"^\"),\n    mac(1, macro_accentbiss, \"\\'\"),\n    mac(1, macro_accentbiss, \"\\\"\"),\n    mac(1, macro_accentbiss, \"`\"),\n    mac(1, macro_accentbiss, \"=\"),\n    mac(1, macro_accentbiss, \".\"),\n    mac(1, macro_accentbiss, \"~\"),\n    mac(1, macro_accentbiss, \"u\"),\n    mac(1, macro_accentbiss, \"v\"),\n    mac(1, macro_accentbiss, \"H\"),\n    mac(1, macro_accentbiss, \"r\"),\n    mac(1, macro_accentbiss, \"U\"),\n    mac(1, macro_T, \"T\"),\n    mac(1, macro_accentbiss, \"t\"),\n    mac(2, macro_accent, \"accent\"),\n    mac(2, macro_grkaccent, \"grkaccent\"),\n    mac(1, macro_accents, \"hat\"),\n    mac(1, macro_accents, \"widehat\"),\n    mac(1, macro_accents, \"tilde\"),\n    mac(1, macro_accents, \"acute\"),\n    mac(1, macro_accents, \"grave\"),\n    mac(1, macro_accents, \"ddot\"),\n    mac(1, macro_accents, \"cyrddot\"),\n    mac(1, macro_accents, \"mathring\"),\n    mac(1, macro_accents, \"bar\"),\n    mac(1, macro_accents, \"breve\"),\n    mac(1, macro_accents, \"check\"),\n    mac(1, macro_accents, \"vec\"),\n    mac(1, macro_accents, \"dot\"),\n    mac(1, macro_accents, \"widetilde\"),\n    mac(0, macro_nbsp, \"nbsp\"),\n    mac(1, macro_overrightarrow, \"overrightarrow\"),\n    mac(1, macro_overleftarrow, \"overleftarrow\"),\n    mac(1, macro_overleftrightarrow, \"overleftrightarrow\"),\n    mac(1, macro_underrightarrow, \"underrightarrow\"),\n    mac(1, macro_underleftarrow, \"underleftarrow\"),\n    mac(1, macro_underleftrightarrow, \"underleftrightarrow\"),\n    mac(1, macro_underbrace, \"underbrace\"),\n    mac(1, macro_overbrace, \"overbrace\"),\n    mac(1, macro_underbrack, \"underbrack\"),\n    mac(1, macro_overbrack, \"overbrack\"),\n    mac(1, macro_underparen, \"underparen\"),\n    mac(1, macro_overparen, \"overparen\"),\n    mac(1, macro_sqrt, \"sqrtsign\"),\n    mac(1, macro_overline, \"overline\"),\n    mac(1, macro_underline, \"underline\"),\n    mac(1, macro_mathop, \"mathop\"),\n    mac(1, macro_mathpunct, \"mathpunct\"),\n    mac(1, macro_mathord, \"mathord\"),\n    mac(1, macro_mathrel, \"mathrel\"),\n    mac(1, macro_mathinner, \"mathinner\"),\n    mac(1, macro_mathbin, \"mathbin\"),\n    mac(1, macro_mathopen, \"mathopen\"),\n    mac(1, macro_mathclose, \"mathclose\"),\n    mac(0, macro_joinrel, \"joinrel\"),\n    mac(0, macro_vdots, \"vdots\"),\n    mac(0, macro_ddots, \"ddots\"),\n    mac(0, macro_iddots, \"iddots\"),\n    mac(0, macro_nolimits, \"nolimits\"),\n    mac(0, macro_limits, \"limits\"),\n    mac(0, macro_normal, \"normal\"),\n    mac(0, macro_leftparenthesis, \"(\"),\n    mac(0, macro_leftbracket, \"[\"),\n    mac(1, macro_left, \"left\"),\n    mac(1, macro_middle, \"middle\"),\n    mac(0, macro_cr, \"cr\"),\n    mac(3, macro_multicolumn, \"multicolumn\"),\n    mac(1, macro_shoveright, \"shoveright\"),\n    mac(1, macro_shoveleft, \"shoveleft\"),\n    mac(0, macro_backslashcr, \"\\\\\"),\n    mac(1, macro_fbox, \"fbox\"),\n    mac(1, macro_fbox, \"boxed\"),\n    mac(0, macro_questeq, \"questeq\"),\n    mac(2, macro_accentset, \"accentset\"),\n    mac(2, macro_underaccent, \"underaccent\"),\n    mac(1, macro_undertilde, \"undertilde\"),\n    mac(2, macro_overset, \"overset\"),\n    mac(1, macro_Braket, \"Braket\"),\n    mac(1, macro_Set, \"Set\"),\n    mac(2, macro_underset, \"underset\"),\n    mac(1, macro_boldsymbol, \"boldsymbol\"),\n    mac(0, macro_LaTeX, \"LaTeX\"),\n    mac(0, macro_GeoGebra, \"GeoGebra\"),\n    mac(1, macro_big, \"big\"),\n    mac(1, macro_Big, \"Big\"),\n    mac(1, macro_bigg, \"bigg\"),\n    mac(1, macro_Bigg, \"Bigg\"),\n    mac(1, macro_bigl, \"bigl\"),\n    mac(1, macro_Bigl, \"Bigl\"),\n    mac(1, macro_biggl, \"biggl\"),\n    mac(1, macro_Biggl, \"Biggl\"),\n    mac(1, macro_bigr, \"bigr\"),\n    mac(1, macro_Bigr, \"Bigr\"),\n    mac(1, macro_biggr, \"biggr\"),\n    mac(1, macro_Biggr, \"Biggr\"),\n    mac(0, macro_displaystyle, \"displaystyle\"),\n    mac(0, macro_textstyle, \"textstyle\"),\n    mac(0, macro_scriptstyle, \"scriptstyle\"),\n    mac(0, macro_scriptscriptstyle, \"scriptscriptstyle\"),\n    mac(3, macro_sideset, \"sideset\"),\n    mac(3, macro_prescript, \"prescript\"),\n    mac(1, macro_reflectbox, \"reflectbox\"),\n    mac(3, macro_resizebox, \"resizebox\"),\n    mac(1, macro_shadowbox, \"shadowbox\"),\n    mac(1, macro_ovalbox, \"ovalbox\"),\n    mac(1, macro_cornersize, \"cornersize\"),\n    mac(1, macro_doublebox, \"doublebox\"),\n    mac(1, macro_phantom, \"phantom\"),\n    mac(1, macro_hphantom, \"hphantom\"),\n    mac(1, macro_vphantom, \"vphantom\"),\n    mac(0, macro_spATbreve, \"sp@breve\"),\n    mac(0, macro_spAThat, \"sp@hat\"),\n    mac(3, macro_definecolor, \"definecolor\"),\n    mac(2, macro_textcolor, \"textcolor\"),\n    mac(2, macro_fgcolor, \"fgcolor\"),\n    mac(2, macro_bgcolor, \"bgcolor\"),\n    mac(2, macro_colorbox, \"colorbox\"),\n    mac(3, macro_fcolorbox, \"fcolorbox\"),\n    mac(1, macro_cedilla, \"c\"),\n    mac(0, macro_IJ, \"IJ\"),\n    mac(0, macro_IJ, \"ij\"),\n    mac(0, macro_TStroke, \"TStroke\"),\n    mac(0, macro_TStroke, \"tStroke\"),\n    mac(0, macro_LCaron, \"Lcaron\"),\n    mac(0, macro_tcaron, \"tcaron\"),\n    mac(0, macro_LCaron, \"lcaron\"),\n    mac(1, macro_ogonek, \"k\"),\n    mac(0, macro_cong, \"cong\"),\n    mac(0, macro_doteq, \"doteq\"),\n    mac(1, macro_externalfont, \"externalFont\"),\n    mac(1, macro_text, \"Text\"),\n    mac(1, macro_textit, \"Textit\"),\n    mac(1, macro_textbf, \"Textbf\"),\n    mac(1, macro_textitbf, \"Textitbf\"),\n    mac(4, macro_declaremathsizes, \"DeclareMathSizes\"),\n    mac(1, macro_magnification, \"magnification\"),\n    mac(0, macro_hline, \"hline\"),\n    mac(0, macro_sizes, \"tiny\"),\n    mac(0, macro_sizes, \"scriptsize\"),\n    mac(0, macro_sizes, \"footnotesize\"),\n    mac(0, macro_sizes, \"small\"),\n    mac(0, macro_sizes, \"normalsize\"),\n    mac(0, macro_sizes, \"large\"),\n    mac(0, macro_sizes, \"Large\"),\n    mac(0, macro_sizes, \"LARGE\"),\n    mac(0, macro_sizes, \"huge\"),\n    mac(0, macro_sizes, \"Huge\"),\n    mac(1, macro_mathcumsup, \"mathcumsup\"),\n    mac(1, macro_mathcumsub, \"mathcumsub\"),\n    mac(0, macro_hstrok, \"hstrok\"),\n    mac(0, macro_Hstrok, \"Hstrok\"),\n    mac(0, macro_dstrok, \"dstrok\"),\n    mac(0, macro_Dstrok, \"Dstrok\"),\n    mac(0, macro_dotminus, \"dotminus\"),\n    mac(0, macro_ratio, \"ratio\"),\n    mac(0, macro_smallfrowneq, \"smallfrowneq\"),\n    mac(0, macro_geoprop, \"geoprop\"),\n    mac(0, macro_minuscolon, \"minuscolon\"),\n    mac(0, macro_minuscoloncolon, \"minuscoloncolon\"),\n    mac(0, macro_simcolon, \"simcolon\"),\n    mac(0, macro_simcoloncolon, \"simcoloncolon\"),\n    mac(0, macro_approxcolon, \"approxcolon\"),\n    mac(0, macro_approxcoloncolon, \"approxcoloncolon\"),\n    mac(0, macro_coloncolon, \"coloncolon\"),\n    mac(0, macro_equalscolon, \"equalscolon\"),\n    mac(0, macro_equalscoloncolon, \"equalscoloncolon\"),\n    mac(0, macro_colonminus, \"colonminus\"),\n    mac(0, macro_coloncolonminus, \"coloncolonminus\"),\n    mac(0, macro_colonequals, \"colonequals\"),\n    mac(0, macro_coloncolonequals, \"coloncolonequals\"),\n    mac(0, macro_colonsim, \"colonsim\"),\n    mac(0, macro_coloncolonsim, \"coloncolonsim\"),\n    mac(0, macro_colonapprox, \"colonapprox\"),\n    mac(0, macro_coloncolonapprox, \"coloncolonapprox\"),\n    mac(1, macro_kern, \"kern\"),\n    mac(1, macro_char, \"char\"),\n    mac(1, macro_romannumeral, \"roman\"),\n    mac(1, macro_romannumeral, \"Roman\"),\n    mac(1, macro_textcircled, \"textcircled\"),\n    mac(1, macro_textsc, \"textsc\"),\n    mac(0, macro_sc, \"sc\"),\n    mac(0, macro_muskips, \",\"),\n    mac(0, macro_muskips, \":\"),\n    mac(0, macro_muskips, \";\"),\n    mac(0, macro_muskips, \"thinspace\"),\n    mac(0, macro_muskips, \"medspace\"),\n    mac(0, macro_muskips, \"thickspace\"),\n    mac(0, macro_muskips, \"!\"),\n    mac(0, macro_muskips, \"negthinspace\"),\n    mac(0, macro_muskips, \"negmedspace\"),\n    mac(0, macro_muskips, \"negthickspace\"),\n    mac(0, macro_quad, \"quad\"),\n    mac(0, macro_surd, \"surd\"),\n    mac(0, macro_iint, \"iint\"),\n    mac(0, macro_iiint, \"iiint\"),\n    mac(0, macro_iiiint, \"iiiint\"),\n    mac(0, macro_idotsint, \"idotsint\"),\n    mac(0, macro_int, \"int\"),\n    mac(0, macro_oint, \"oint\"),\n    mac(0, macro_lmoustache, \"lmoustache\"),\n    mac(0, macro_rmoustache, \"rmoustache\"),\n    mac(0, macro_insertBreakMark, \"-\"),\n    mac(1, macro_xml, \"XML\"),\n    mac(0, macro_above, \"above\"),\n    mac(2, macro_abovewithdelims, \"abovewithdelims\"),\n    mac(1, macro_st, \"st\"),\n    mac(1, macro_fcscore, \"fcscore\"),\n    mac(1, macro_rowcolor, \"rowcolor\"),\n    mac(1, macro_columnbg, \"columncolor\"),\n    mac(1, macro_arrayrulecolor, \"arrayrulecolor\"),\n    mac(2, macro_newcolumntype, \"newcolumntype\"),\n    mac(1, macro_color, \"color\"),\n    mac(1, macro_cellcolor, \"cellcolor\"),\n    mac(3, macro_multirow, \"multirow\"),\n    mac(2, macro_longdiv, \"longdiv\"),\n    mac(1, macro_cancel, \"cancel\"),\n    mac(1, macro_bcancel, \"bcancel\"),\n    mac(1, macro_xcancel, \"xcancel\")\n#ifdef GRAPHICS_DEBUG\n        ,\n    mac(0, macro_debug, \"debug\"),\n    mac(0, macro_undebug, \"undebug\")\n#endif  // GRAPHICS_DEBUG\n};\n\nmap<wstring, wstring> NewCommandMacro::_macrocode;\nmap<wstring, wstring> NewCommandMacro::_macroreplacement;\nMacro* NewCommandMacro::_instance = nullptr;\n\ninline static void e(\n    int nbargs,\n    const wstring& name,\n    const wstring& begdef,\n    const wstring& enddef) throw(ex_parse) {\n    NewEnvironmentMacro::addNewEnvironment(name, begdef, enddef, nbargs);\n}\n\ninline static void c(\n    int nbargs,\n    const wstring& name,\n    const wstring& code) throw(ex_parse) {\n    NewCommandMacro::addNewCommand(name, code, nbargs);\n}\n\nvoid NewCommandMacro::_init_() {\n    if (_instance == nullptr) {\n        _instance = new NewCommandMacro();\n    }\n    // Predefined environments\n    e(1, L\"array\", L\"\\\\array@@env{#1}{\", L\"}\");\n    e(1, L\"tabular\", L\"\\\\array@@env{#1}{\", L\"}\");\n    e(0, L\"matrix\", L\"\\\\matrix@@env{\", L\"}\");\n    e(0, L\"smallmatrix\", L\"\\\\smallmatrix@@env{\", L\"}\");\n    e(0, L\"pmatrix\", L\"\\\\left(\\\\begin{matrix}\", L\"\\\\end{matrix}\\\\right)\");\n    e(0, L\"bmatrix\", L\"\\\\left[\\\\begin{matrix}\", L\"\\\\end{matrix}\\\\right]\");\n    e(0, L\"Bmatrix\", L\"\\\\left\\\\{\\\\begin{matrix}\", L\"\\\\end{matrix}\\\\right\\\\}\");\n    e(0, L\"vmatrix\", L\"\\\\left|\\\\begin{matrix}\", L\"\\\\end{matrix}\\\\right|\");\n    e(0, L\"Vmatrix\", L\"\\\\left\\\\|\\\\begin{matrix}\", L\"\\\\end{matrix}\\\\right\\\\|\");\n    e(0, L\"eqnarray\", L\"\\\\begin{array}{rcl}\", L\"\\\\end{array}\");\n    e(0, L\"align\", L\"\\\\align@@env{\", L\"}\");\n    e(0, L\"flalign\", L\"\\\\flalign@@env{\", L\"}\");\n    e(1, L\"alignat\", L\"\\\\alignat@@env{#1}{\", L\"}\");\n    e(0, L\"aligned\", L\"\\\\aligned@@env{\", L\"}\");\n    e(1, L\"alignedat\", L\"\\\\alignedat@@env{#1}{\", L\"}\");\n    e(0, L\"multline\", L\"\\\\multline@@env{\", L\"}\");\n    e(0, L\"cases\", L\"\\\\left\\\\{\\\\begin{array}{@{}ll@{\\\\,}}\", L\"\\\\end{array}\\\\right.\");\n    e(0, L\"split\", L\"\\\\begin{array}{r@{\\\\;}l}\", L\"\\\\end{array}\");\n    e(0, L\"gather\", L\"\\\\gather@@env{\", L\"}\");\n    e(0, L\"gathered\", L\"\\\\gathered@@env{\", L\"}\");\n    e(0, L\"math\", L\"\\\\(\", L\"\\\\)\");\n    e(0, L\"displaymath\", L\"\\\\[\", L\"\\\\]\");\n    // Predefined commands\n    c(1, L\"operatorname\", L\"\\\\mathop{\\\\mathrm{#1}}\\\\nolimits \");\n    c(2, L\"DeclareMathOperator\", L\"\\\\newcommand{#1}{\\\\mathop{\\\\mathrm{#2}}\\\\nolimits}\");\n    c(1, L\"substack\", L\"{\\\\scriptstyle\\\\begin{array}{c}#1\\\\end{array}}\");\n    c(2, L\"dfrac\", L\"\\\\genfrac{}{}{}{}{#1}{#2}\");\n    c(2, L\"tfrac\", L\"\\\\genfrac{}{}{}{1}{#1}{#2}\");\n    c(2, L\"dbinom\", L\"\\\\genfrac{(}{)}{0pt}{}{#1}{#2}\");\n    c(2, L\"tbinom\", L\"\\\\genfrac{(}{)}{0pt}{1}{#1}{#2}\");\n    c(1, L\"pmod\", L\"\\\\qquad\\\\mathbin{(\\\\mathrm{mod}\\\\ #1)}\");\n    c(1, L\"mod\", L\"\\\\qquad\\\\mathbin{\\\\mathrm{mod}\\\\ #1}\");\n    c(1, L\"pod\", L\"\\\\qquad\\\\mathbin{(#1)}\");\n    c(1, L\"dddot\", L\"\\\\mathop{#1}\\\\limits^{...}\");\n    c(1, L\"ddddot\", L\"\\\\mathop{#1}\\\\limits^{....}\");\n    c(0, L\"spdddot\", L\"^{\\\\mathrm{...}}\");\n    c(0, L\"spbreve\", L\"^{\\\\makeatletter\\\\sp@breve\\\\makeatother}\");\n    c(0, L\"sphat\", L\"^{\\\\makeatletter\\\\sp@hat\\\\makeatother}\");\n    c(0, L\"spddot\", L\"^{\\\\displaystyle..}\");\n    c(0, L\"spcheck\", L\"^{\\\\vee}\");\n    c(0, L\"sptilde\", L\"^{\\\\sim}\");\n    c(0, L\"spdot\", L\"^{\\\\displaystyle.}\");\n    c(1, L\"d\", L\"\\\\underaccent{\\\\dot}{#1}\");\n    c(1, L\"b\", L\"\\\\underaccent{\\\\bar}{#1}\");\n    c(1, L\"Bra\", L\"\\\\left\\\\langle{#1}\\\\right\\\\vert\");\n    c(1, L\"Ket\", L\"\\\\left\\\\vert{#1}\\\\right\\\\rangle\");\n    c(1, L\"textsuperscript\", L\"{}^{\\\\text{#1}}\");\n    c(1, L\"textsubscript\", L\"{}_{\\\\text{#1}}\");\n    c(1, L\"textit\", L\"\\\\mathit{\\\\text{#1}}\");\n    c(1, L\"textbf\", L\"\\\\mathbf{\\\\text{#1}}\");\n    c(1, L\"textsf\", L\"\\\\mathsf{\\\\text{#1}}\");\n    c(1, L\"texttt\", L\"\\\\mathtt{\\\\text{#1}}\");\n    c(1, L\"textrm\", L\"\\\\text{#1}\");\n    c(0, L\"degree\", L\"^\\\\circ\");\n    c(0, L\"with\", L\"\\\\mathbin{\\\\&}\");\n    c(0, L\"parr\", L\"\\\\mathbin{\\\\rotatebox[origin=c]{180}{\\\\&}}\");\n    c(0, L\"copyright\", L\"\\\\textcircled{\\\\raisebox{0.2ex}{c}}\");\n    c(0, L\"L\", L\"\\\\mathrm{\\\\polishlcross L}\");\n    c(0, L\"l\", L\"\\\\mathrm{\\\\polishlcross l}\");\n    c(0, L\"Join\", L\"\\\\mathop{\\\\rlap{\\\\ltimes}\\\\rtimes}\");\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/core/macro_impl.cpp",
    "content": "#include \"core/macro_impl.h\"\n#include \"graphic/graphic.h\"\n\nusing namespace tex;\nusing namespace std;\n\nnamespace tex {\n\nmacro(hvspace) {\n    size_t i;\n    for (i = 0; i < args[1].length() && !isalpha(args[1][i]); i++)\n        ;\n    float f = 0;\n    valueof(args[1].substr(0, i), f);\n\n    int unit;\n    if (i != args[1].length()) {\n        wstring s = args[1].substr(i);\n        string str;\n        wide2utf8(s.c_str(), str);\n        tolower(str);\n        unit = SpaceAtom::getUnit(str);\n    } else {\n        unit = UNIT_POINT;\n    }\n    if (unit == -1) {\n        string str;\n        wide2utf8(args[1].c_str(), str);\n        throw ex_parse(\"Unknown unit '\" + str + \"'!\");\n    }\n\n    return args[0][0] == L'h' ? sptr<Atom>(new SpaceAtom(unit, f, 0, 0))\n                              : sptr<Atom>(new SpaceAtom(unit, 0, f, 0));\n}\n\nmacro(rule) {\n    auto w = SpaceAtom::getLength(args[1]);\n    auto h = SpaceAtom::getLength(args[2]);\n    auto r = SpaceAtom::getLength(args[3]);\n\n    return sptr<Atom>(new RuleAtom(w.first, w.second, h.first, h.second, r.first, -r.second));\n}\n\nmacro(cfrac) {\n    int numAlign = ALIGN_CENTER;\n    if (args[3] == L\"r\")\n        numAlign = ALIGN_RIGHT;\n    else if (args[3] == L\"l\")\n        numAlign = ALIGN_LEFT;\n    TeXFormula num(tp, args[1], false);\n    TeXFormula denom(tp, args[2], false);\n    if (num._root == nullptr || denom._root == nullptr)\n        throw ex_parse(\"Both numerator and denominator of a fraction can't be empty!\");\n    sptr<FractionAtom> f(new FractionAtom(num._root, denom._root, true, numAlign, ALIGN_CENTER));\n    f->_useKern = false;\n    f->_type = TYPE_INNER;\n    RowAtom* r = new RowAtom();\n    r->add(sptr<Atom>(new StyleAtom(STYLE_DISPLAY, f)));\n    return sptr<Atom>(r);\n}\n\nmacro(sfrac) {\n    TeXFormula num(tp, args[1], false);\n    TeXFormula den(tp, args[2], false);\n    if (num._root == nullptr || den._root == nullptr)\n        throw ex_parse(\"Both numerator and denominator of a fraction can't be empty!\");\n\n    float sx = 0.75f, sy = 0.75f, r = 0.45f, sL = -0.13f, sR = -0.065f;\n    sptr<Atom> slash = SymbolAtom::get(\"slash\");\n\n    if (!tp.isMathMode()) {\n        sx = 0.6f;\n        sy = 0.5f;\n        r = 0.75f;\n        sL = -0.24f;\n        sR = -0.24f;\n        auto in = sptr<Atom>(new ScaleAtom(SymbolAtom::get(\"textfractionsolidus\"), 1.25f, 0.65f));\n        VRowAtom* vr = new VRowAtom(in);\n        vr->setRaise(UNIT_EX, 0.4f);\n        slash = sptr<Atom>(vr);\n    }\n\n    VRowAtom* snum = new VRowAtom(sptr<Atom>(new ScaleAtom(num._root, sx, sy)));\n    snum->setRaise(UNIT_EX, r);\n    RowAtom* ra = new RowAtom(sptr<Atom>(snum));\n    ra->add(sptr<Atom>(new SpaceAtom(UNIT_EM, sL, 0, 0)));\n    ra->add(slash);\n    ra->add(sptr<Atom>(new SpaceAtom(UNIT_EM, sR, 0, 0)));\n    ra->add(sptr<Atom>(new ScaleAtom(den._root, sx, sy)));\n\n    return sptr<Atom>(ra);\n}\n\nmacro(genfrac) {\n    sptr<SymbolAtom> L, R;\n\n    TeXFormula left(tp, args[1], false);\n    L = dynamic_pointer_cast<SymbolAtom>(left._root);\n\n    TeXFormula right(tp, args[2], false);\n    R = dynamic_pointer_cast<SymbolAtom>(right._root);\n\n    bool rule = true;\n    pair<int, float> ths = SpaceAtom::getLength(args[3]);\n    if (args[3].empty()) {\n        ths = make_pair(0, 0.f);\n        rule = false;\n    }\n\n    int style = 0;\n    if (!args[4].empty()) valueof(args[4], style);\n\n    TeXFormula num(tp, args[5], false);\n    TeXFormula den(tp, args[6], false);\n    if (num._root == nullptr || den._root == nullptr)\n        throw ex_parse(\"Both numerator and denominator of a fraction can't be empty!\");\n    sptr<Atom> fa(new FractionAtom(num._root, den._root, rule, ths.first, ths.second));\n    RowAtom* ra = new RowAtom();\n    ra->add(sptr<Atom>(new StyleAtom(style * 2, sptr<Atom>(new FencedAtom(fa, L, R)))));\n\n    return sptr<Atom>(ra);\n}\n\nmacro(overwithdelims) {\n    auto num = tp.getFormulaAtom();\n    auto den = TeXFormula(tp, tp.getOverArgument(), false)._root;\n\n    if (num == nullptr || den == nullptr)\n        throw ex_parse(\"Both numerator and denominator of a fraction can't be empty!\");\n\n    auto left = TeXFormula(tp, args[1], false)._root;\n    BigDelimiterAtom* a = dynamic_cast<BigDelimiterAtom*>(left.get());\n    if (a != nullptr) left = a->_delim;\n\n    auto right = TeXFormula(tp, args[2], false)._root;\n    a = dynamic_cast<BigDelimiterAtom*>(right.get());\n    if (a != nullptr) right = a->_delim;\n\n    auto sl = dynamic_pointer_cast<SymbolAtom>(left);\n    auto sr = dynamic_pointer_cast<SymbolAtom>(right);\n    if (sl != nullptr && sr != nullptr) {\n        sptr<FractionAtom> f(new FractionAtom(num, den, true));\n        return sptr<Atom>(new FencedAtom(f, sl, sr));\n    }\n\n    RowAtom* ra = new RowAtom();\n    ra->add(left);\n    ra->add(sptr<Atom>(new FractionAtom(num, den, true)));\n    ra->add(right);\n    return sptr<Atom>(ra);\n}\n\nmacro(atopwithdelims) {\n    auto num = tp.getFormulaAtom();\n    auto den = TeXFormula(tp, tp.getOverArgument(), false)._root;\n\n    if (num == nullptr || den == nullptr)\n        throw ex_parse(\"Both numerator and denominator of a fraction can't be empty!\");\n\n    auto left = TeXFormula(tp, args[1], false)._root;\n    BigDelimiterAtom* big = dynamic_cast<BigDelimiterAtom*>(left.get());\n    if (big != nullptr) left = big->_delim;\n\n    auto right = TeXFormula(tp, args[2], false)._root;\n    big = dynamic_cast<BigDelimiterAtom*>(right.get());\n    if (big != nullptr) right = big->_delim;\n\n    auto sl = dynamic_pointer_cast<SymbolAtom>(left);\n    auto sr = dynamic_pointer_cast<SymbolAtom>(right);\n    if (sl != nullptr && sr != nullptr) {\n        sptr<Atom> f(new FractionAtom(num, den, false));\n        return sptr<Atom>(new FencedAtom(f, sl, sr));\n    }\n\n    RowAtom* ra = new RowAtom();\n    ra->add(left);\n    ra->add(sptr<Atom>(new FractionAtom(num, den, false)));\n    ra->add(right);\n    return sptr<Atom>(ra);\n}\n\nmacro(abovewithdelims) {\n    auto num = tp.getFormulaAtom();\n    pair<int, float> dim = tp.getLength();\n    auto den = TeXFormula(tp, tp.getOverArgument(), false)._root;\n    if (num == nullptr || den == nullptr)\n        throw ex_parse(\"Both numerator and denominator of a fraction can't be empty!\");\n\n    auto left = TeXFormula(tp, args[1], false)._root;\n    BigDelimiterAtom* big = dynamic_cast<BigDelimiterAtom*>(left.get());\n    if (big != nullptr) left = big->_delim;\n\n    auto right = TeXFormula(tp, args[2], false)._root;\n    big = dynamic_cast<BigDelimiterAtom*>(right.get());\n    if (big != nullptr) right = big->_delim;\n\n    auto sl = dynamic_pointer_cast<SymbolAtom>(left);\n    auto sr = dynamic_pointer_cast<SymbolAtom>(right);\n    if (sl != nullptr && sr != nullptr) {\n        sptr<Atom> f(new FractionAtom(num, den, dim.first, dim.second));\n        return sptr<Atom>(new FencedAtom(f, sl, sr));\n    }\n\n    RowAtom* ra = new RowAtom();\n    ra->add(left);\n    ra->add(sptr<Atom>(new FractionAtom(num, den, true)));\n    ra->add(right);\n    return sptr<Atom>(ra);\n}\n\nmacro(textstyles) {\n    wstring style(args[0]);\n    if (style == L\"frak\")\n        style = L\"mathfrak\";\n    else if (style == L\"Bbb\")\n        style = L\"mathbb\";\n    else if (style == L\"bold\")\n        return sptr<Atom>(new BoldAtom(TeXFormula(tp, args[1], false)._root));\n    else if (style == L\"cal\")\n        style = L\"mathcal\";\n\n    FontInfos* info = nullptr;\n    auto it = TeXFormula::_externalFontMap.find(UnicodeBlock::BASIC_LATIN);\n    if (it != TeXFormula::_externalFontMap.end()) {\n        info = it->second;\n        TeXFormula::_externalFontMap[UnicodeBlock::BASIC_LATIN] = nullptr;\n    }\n    auto atom = TeXFormula(tp, args[1], false)._root;\n    if (info != nullptr) {\n        TeXFormula::_externalFontMap[UnicodeBlock::BASIC_LATIN] = info;\n    }\n\n    string s;\n    wide2utf8(style.c_str(), s);\n    return sptr<Atom>(new TextStyleAtom(atom, s));\n}\n\nmacro(accentbiss) {\n    string acc;\n    switch (args[0][0]) {\n    case '~':\n        acc = \"tilde\";\n        break;\n    case '\\'':\n        acc = \"acute\";\n        break;\n    case '^':\n        acc = \"hat\";\n        break;\n    case '\\\"':\n        acc = \"ddot\";\n        break;\n    case '`':\n        acc = \"grave\";\n        break;\n    case '=':\n        acc = \"bar\";\n        break;\n    case '.':\n        acc = \"dot\";\n        break;\n    case 'u':\n        acc = \"breve\";\n        break;\n    case 'v':\n        acc = \"check\";\n        break;\n    case 'H':\n        acc = \"doubleacute\";\n        break;\n    case 't':\n        acc = \"tie\";\n        break;\n    case 'r':\n        acc = \"mathring\";\n        break;\n    case 'U':\n        acc = \"cyrbreve\";\n        break;\n    }\n\n    return sptr<Atom>(new AccentedAtom(TeXFormula(tp, args[1], false)._root, acc));\n}\n\nmacro(left) {\n    wstring grep = tp.getGroup(L\"\\\\left\", L\"\\\\right\");\n\n    auto left = TeXFormula(tp, args[1], false)._root;\n    BigDelimiterAtom* big = dynamic_cast<BigDelimiterAtom*>(left.get());\n    if (big != nullptr) left = big->_delim;\n\n    auto right = tp.getArgument();\n    big = dynamic_cast<BigDelimiterAtom*>(right.get());\n    if (big != nullptr) right = big->_delim;\n\n    auto sl = dynamic_pointer_cast<SymbolAtom>(left);\n    auto sr = dynamic_pointer_cast<SymbolAtom>(right);\n    if (sl != nullptr && sr != nullptr) {\n        TeXFormula tf(tp, grep, false);\n        return sptr<Atom>(new FencedAtom(tf._root, sl, tf._middle, sr));\n    }\n\n    RowAtom* ra = new RowAtom();\n    ra->add(left);\n    ra->add(TeXFormula(tp, grep, false)._root);\n    ra->add(right);\n\n    return sptr<Atom>(ra);\n}\n\nmacro(intertext) {\n    if (!tp.isArrayMode())\n        throw ex_parse(\"Command \\\\intertext must used in array environment!\");\n\n    wstring str(args[1]);\n    replaceall(str, L\"^{\\\\prime}\", L\"\\'\");\n    replaceall(str, L\"^{\\\\prime\\\\prime}\", L\"\\'\\'\");\n\n    sptr<RomanAtom> ra(new RomanAtom(TeXFormula(tp, str, \"mathnormal\", false, false)._root));\n    ra->_type = TYPE_INTERTEXT;\n    tp.addAtom(ra);\n    tp.addRow();\n\n    return nullptr;\n}\n\nmacro(newcommand) {\n    wstring newcmd(args[1]);\n    int nbArgs = 0;\n    if (!tp.isValidName(newcmd))\n        throw ex_parse(\"Invalid name for the command '\" + wide2utf8(newcmd.c_str()));\n\n    if (!args[3].empty()) valueof(args[3], nbArgs);\n\n    if (args[4].empty()) {\n        NewCommandMacro::addNewCommand(newcmd.substr(1), args[2], nbArgs);\n    } else {\n        NewCommandMacro::addNewCommand(newcmd.substr(1), args[2], nbArgs, args[4]);\n    }\n\n    return nullptr;\n}\n\nmacro(renewcommand) {\n    wstring newcmd(args[1]);\n    int nbArgs = 0;\n    if (!tp.isValidName(newcmd))\n        throw ex_parse(\"Invalid name for the command: \" + wide2utf8(newcmd.c_str()));\n\n    if (!args[3].empty()) valueof(args[3], nbArgs);\n\n    if (args[4].empty()) {\n        NewCommandMacro::addRenewCommand(newcmd.substr(1), args[2], nbArgs);\n    } else {\n        NewCommandMacro::addRenewCommand(newcmd.substr(1), args[2], nbArgs, args[4]);\n    }\n\n    return nullptr;\n}\n\nmacro(raisebox) {\n    pair<int, float> r = SpaceAtom::getLength(args[1]);\n    pair<int, float> h = SpaceAtom::getLength(args[3]);\n    pair<int, float> d = SpaceAtom::getLength(args[4]);\n\n    return sptr<Atom>(new RaiseAtom(\n        TeXFormula(tp, args[2])._root,\n        r.first, r.second,\n        h.first, h.second,\n        d.first, d.second));\n}\n\nmacro(definecolor) {\n    color c = TRANS;\n    string cs;\n    wide2utf8(args[3].c_str(), cs);\n    if (args[2] == L\"gray\") {\n        float f = 0;\n        valueof(args[3], f);\n        c = rgb(f, f, f);\n    } else if (args[2] == L\"rgb\") {\n        strtokenizer stok(cs, \":,\");\n        if (stok.count_tokens() != 3)\n            throw ex_parse(\"The color definition must have three components!\");\n        float r, g, b;\n        string R = stok.next_token(), G = stok.next_token(), B = stok.next_token();\n        valueof(trim(R), r);\n        valueof(trim(G), g);\n        valueof(trim(B), b);\n        c = rgb(r, g, b);\n    } else if (args[2] == L\"cmyk\") {\n        strtokenizer stok(cs, \":,\");\n        if (stok.count_tokens() != 4)\n            throw ex_parse(\"The color definition must have four components!\");\n        float cmyk[4];\n        for (int i = 0; i < 4; i++) {\n            string X = stok.next_token();\n            valueof(trim(X), cmyk[i]);\n        }\n        float k = 1 - cmyk[3];\n        c = rgb(k * (1 - cmyk[0]), k * (1 - cmyk[1]), k * (1 - cmyk[2]));\n    } else {\n        throw ex_parse(\"Color model is incorrect!\");\n    }\n\n    ColorAtom::defineColor(wide2utf8(args[1].c_str()), c);\n    return nullptr;\n}\n\nmacro(sizes) {\n    float f = 1;\n    if (args[0] == L\"tiny\")\n        f = 0.5f;\n    else if (args[0] == L\"scriptsize\")\n        f = 0.7f;\n    else if (args[0] == L\"footnotesize\")\n        f = 0.8f;\n    else if (args[0] == L\"small\")\n        f = 0.9f;\n    else if (args[0] == L\"normalsize\")\n        f = 1.f;\n    else if (args[0] == L\"large\")\n        f = 1.2f;\n    else if (args[0] == L\"Large\")\n        f = 1.4f;\n    else if (args[0] == L\"LARGE\")\n        f = 1.8f;\n    else if (args[0] == L\"huge\")\n        f = 2.f;\n    else if (args[0] == L\"Huge\")\n        f = 2.5f;\n\n    auto a = TeXFormula(tp, tp.getOverArgument(), \"\", false, tp.isIgnoreWhiteSpace())._root;\n    return sptr<Atom>(new MonoScaleAtom(a, f));\n}\n\nmacro(romannumeral) {\n    int numbers[] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};\n    string letters[] = {\"M\", \"CM\", \"D\", \"CD\", \"C\", \"XC\", \"L\", \"XL\", \"X\", \"IX\", \"V\", \"IV\", \"I\"};\n    string roman = \"\";\n\n    int num;\n    string x;\n    wide2utf8(args[1].c_str(), x);\n    valueof(trim(x), num);\n    for (int i = 0; i < 13; i++) {\n        while (num >= numbers[i]) {\n            roman += letters[i];\n            num -= numbers[i];\n        }\n    }\n\n    if (args[0][0] == 'r') {\n        tolower(roman);\n    }\n\n    wstring str;\n    utf82wide(roman.c_str(), str);\n    return TeXFormula(str, false)._root;\n}\n\nmacro(muskips) {\n    int type = 0;\n    if (args[0] == L\",\")\n        type = THINMUSKIP;\n    else if (args[0] == L\":\")\n        type = MEDMUSKIP;\n    else if (args[0] == L\";\")\n        type = THICKMUSKIP;\n    else if (args[0] == L\"thinspace\")\n        type = THINMUSKIP;\n    else if (args[0] == L\"medspace\")\n        type = MEDMUSKIP;\n    else if (args[0] == L\"thickspace\")\n        type = THICKMUSKIP;\n    else if (args[0] == L\"!\")\n        type = NEGTHINMUSKIP;\n    else if (args[0] == L\"negthinspace\")\n        type = NEGTHINMUSKIP;\n    else if (args[0] == L\"negmedspace\")\n        type = NEGMEDMUSKIP;\n    else if (args[0] == L\"negthickspace\")\n        type = NEGTHICKMUSKP;\n\n    return sptr<Atom>(new SpaceAtom(type));\n}\n\nmacro(xml) {\n    map<string, string>& m = tp._formula->_xmlMap;\n    wstring str(args[1]);\n    wstring buf;\n    size_t start = 0;\n    size_t pos;\n    while ((pos = str.find(L\"$\")) != wstring::npos) {\n        if (pos < str.length() - 1) {\n            start = pos;\n            while (++start < str.length() && isalpha(str[start]))\n                ;\n            wstring key = str.substr(pos + 1, start - pos - 1);\n            string x = wide2utf8(key.c_str());\n            auto it = m.find(x);\n            if (it != m.end()) {\n                buf.append(str.substr(0, pos));\n                wstring x = utf82wide(it->second.c_str());\n                buf.append(x);\n            } else {\n                buf.append(str.substr(0, start));\n            }\n            str = str.substr(start);\n        } else {\n            buf.append(str);\n            str = L\"\";\n        }\n    }\n    buf.append(str);\n    str = buf;\n\n    return TeXFormula(tp, str)._root;\n}\n\n}  // namespace tex\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/core/macro_impl.h",
    "content": "#ifndef MACRO_IMPL_H_INCLUDED\n#define MACRO_IMPL_H_INCLUDED\n\n#include \"atom/atom_basic.h\"\n#include \"atom/atom_impl.h\"\n#include \"common.h\"\n#include \"core/core.h\"\n#include \"core/formula.h\"\n#include \"core/macro.h\"\n#include \"core/parser.h\"\n#include \"fonts/alphabet.h\"\n#include \"graphic/graphic.h\"\n\nusing namespace std;\nusing namespace tex;\n\nnamespace tex {\n\n#ifndef macro\n#define macro(name) sptr<Atom> macro_##name(TeXParser& tp, vector<wstring>& args)\n#endif\n\n#ifdef GRAPHICS_DEBUG\ninline macro(debug) {\n    TeXFormula::setDEBUG(true);\n    return nullptr;\n}\n\ninline macro(undebug) {\n    TeXFormula::setDEBUG(false);\n    return nullptr;\n}\n#endif  // GRAPHICS_DEBUG\n\ninline macro(fatalIfCmdConflict) {\n    NewCommandMacro::_errIfConflict = args[1] == L\"true\";\n    return nullptr;\n}\n\ninline macro(breakEverywhere) {\n    RowAtom::_breakEveywhere = args[1] == L\"true\";\n    return nullptr;\n}\n\ninline macro(multirow) {\n    if (!tp.isArrayMode()) throw ex_parse(\"Command \\\\multirow must used in array environment!\");\n    int n = 0;\n    valueof(args[1], n);\n    tp.addAtom(sptr<Atom>(new MultiRowAtom(n, args[2], TeXFormula(tp, args[3])._root)));\n    return nullptr;\n}\n\ninline macro(longdiv) {\n    long dividend = 0;\n    valueof(args[1], dividend);\n    long divisor = 0;\n    valueof(args[2], divisor);\n    if (divisor == 0) throw ex_parse(\"Divisor must not be 0.\");\n    return sptr<Atom>(new LongDivAtom(divisor, dividend));\n}\n\ninline macro(cellcolor) {\n    if (!tp.isArrayMode()) throw ex_parse(\"Command \\\\cellcolor must used in array environment!\");\n    color c = ColorAtom::getColor(wide2utf8(args[1].c_str()));\n    sptr<CellSpecifier> atom(new CellColorAtom(c));\n    if(tp._formula == nullptr) throw ex_parse(\"_formula is null!\");\n    ArrayOfAtoms* arr = dynamic_cast<ArrayOfAtoms*>(tp._formula);\n    if(arr == nullptr) throw ex_parse(\"dynamic_cast<ArrayOfAtoms*>(_formula) is null!\");\n    arr->addCellSpecifier(atom);\n    return nullptr;\n}\n\ninline macro(color) {\n    // We do not care the \\color command in non-array mode, since we did pass a color as a parameter\n    // when parsing a LaTeX string, it is useless to specify a global foreground color again, but in\n    // array mode, the \\color command is useful to specify the foreground color of the columns.\n    if (tp.isArrayMode()) {\n        color c = ColorAtom::getColor(wide2utf8(args[1].c_str()));\n        return sptr<Atom>(new CellForegroundAtom(c));\n    }\n    return nullptr;\n}\n\ninline macro(newcolumntype) {\n    MatrixAtom::defineColumnSpecifier(args[1], args[2]);\n    return nullptr;\n}\n\ninline macro(arrayrulecolor) {\n    color c = ColorAtom::getColor(wide2utf8(args[1].c_str()));\n    MatrixAtom::LINE_COLOR = c;\n    return nullptr;\n}\n\ninline macro(columnbg) {\n    color c = ColorAtom::getColor(wide2utf8(args[1].c_str()));\n    return sptr<Atom>(new CellColorAtom(c));\n}\n\ninline macro(rowcolor) {\n    if (!tp.isArrayMode()) throw ex_parse(\"Command \\\\rowcolor must used in array environment!\");\n    color c = ColorAtom::getColor(wide2utf8(args[1].c_str()));\n    sptr<CellSpecifier> spe(new CellColorAtom(c));\n    if(tp._formula == nullptr) throw ex_parse(\"_formula is null!\");\n    ArrayOfAtoms* arr = dynamic_cast<ArrayOfAtoms*>(tp._formula);\n    if(arr == nullptr) throw ex_parse(\"dynamic_cast<ArrayOfAtoms*>(_formula) is null!\");\n    arr->addRowSpecifier(spe);\n    return nullptr;\n}\n\ninline macro(st) {\n    auto base = TeXFormula(tp, args[1], false)._root;\n    return sptr<Atom>(new StrikeThroughAtom(base));\n}\n\ninline macro(Braket) {\n    wstring str(args[1]);\n    replaceall(str, L\"\\\\|\", L\"\\\\middle\\\\vert \");\n    return TeXFormula(tp, L\"\\\\left\\\\langle \" + str + L\"\\\\right\\\\rangle\")._root;\n}\n\ninline macro(Set) {\n    wstring str(args[1]);\n    replacefirst(str, L\"\\\\|\", L\"\\\\middle\\\\vert \");\n    return TeXFormula(tp, L\"\\\\left\\\\{\" + str + L\"\\\\right\\\\}\")._root;\n}\n\ninline macro(spATbreve) {\n    VRowAtom* vra = new VRowAtom(TeXFormula(L\"\\\\displaystyle\\\\!\\\\breve{}\")._root);\n    vra->setRaise(UNIT_EX, 0.6f);\n    return sptr<Atom>(new SmashedAtom(sptr<Atom>(vra), \"\"));\n}\n\ninline macro(spAThat) {\n    VRowAtom* vra = new VRowAtom(TeXFormula(L\"\\\\displaystyle\\\\widehat{}\")._root);\n    vra->setRaise(UNIT_EX, 0.6f);\n    return sptr<Atom>(new SmashedAtom(sptr<Atom>(vra), \"\"));\n}\n\ninline macro(clrlap) {\n    return sptr<Atom>(new LapedAtom(TeXFormula(tp, args[1])._root, args[0][0]));\n}\n\ninline macro(mathclrlap) {\n    return sptr<Atom>(new LapedAtom(TeXFormula(tp, args[1])._root, args[0][4]));\n}\n\ninline macro(frac) {\n    TeXFormula num(tp, args[1], false);\n    TeXFormula den(tp, args[2], false);\n    if (num._root == nullptr || den._root == nullptr)\n        throw ex_parse(\"Both numerator and denominator of a fraction can't be empty!\");\n    return sptr<Atom>(new FractionAtom(num._root, den._root, true));\n}\n\ninline macro(over) {\n    auto num = tp.getFormulaAtom();\n    auto den = TeXFormula(tp, tp.getOverArgument(), false)._root;\n    if (num == nullptr || den == nullptr)\n        throw ex_parse(\"Both numerator and denominator of a fraction can't be empty!\");\n    return sptr<Atom>(new FractionAtom(num, den, true));\n}\n\ninline macro(atop) {\n    auto num = tp.getFormulaAtom();\n    auto den = TeXFormula(tp, tp.getOverArgument(), false)._root;\n    if (num == nullptr || den == nullptr)\n        throw ex_parse(\"Both numerator and denominator of a fraction can't be empty!\");\n    return sptr<Atom>(new FractionAtom(num, den, false));\n}\n\ninline sptr<Atom> _macro_choose(\n    const string& left, const string& right,\n    _out_ TeXParser& tp, _out_ vector<wstring>& args) throw(ex_parse) {\n    auto num = tp.getFormulaAtom();\n    auto den = TeXFormula(tp, tp.getOverArgument(), false)._root;\n    if (num == nullptr || den == nullptr)\n        throw ex_parse(\"Both numerator and denominator of choos can't be empty!\");\n    sptr<Atom> f(new FractionAtom(num, den, false));\n    sptr<SymbolAtom> l(new SymbolAtom(left, TYPE_OPENING, true));\n    sptr<SymbolAtom> r(new SymbolAtom(right, TYPE_CLOSING, true));\n    return sptr<Atom>(new FencedAtom(f, l, r));\n}\n\ninline macro(choose) {\n    return _macro_choose(\"lbrack\", \"rbrack\", tp, args);\n}\n\ninline macro(brack) {\n    return _macro_choose(\"lsqbrack\", \"rsqbrack\", tp, args);\n}\n\ninline macro(bangle) {\n    return _macro_choose(\"langle\", \"rangle\", tp, args);\n}\n\ninline macro(brace) {\n    return _macro_choose(\"lbrace\", \"rbrace\", tp, args);\n}\n\ninline sptr<Atom> _marco_cancel(\n    int cancelType,\n    _out_ TeXParser& tp, _out_ vector<wstring>& args) throw(ex_parse) {\n    auto base = TeXFormula(tp, args[1], false)._root;\n    if (base == nullptr)\n        throw ex_parse(\"Cancel content must not be empty!\");\n    return sptr<Atom>(new CancelAtom(base, cancelType));\n}\n\ninline macro(cancel) {\n    return _marco_cancel(CancelAtom::SLASH, tp, args);\n}\n\ninline macro(bcancel) {\n    return _marco_cancel(CancelAtom::BACKSLASH, tp, args);\n}\n\ninline macro(xcancel) {\n    return _marco_cancel(CancelAtom::CROSS, tp, args);\n}\n\ninline macro(binom) {\n    TeXFormula num(tp, args[1], false);\n    TeXFormula den(tp, args[2], false);\n    if (num._root == nullptr || den._root == nullptr)\n        throw ex_parse(\"Both binomial coefficients must be not empty!\");\n    sptr<Atom> f(new FractionAtom(num._root, den._root, false));\n    sptr<SymbolAtom> s1(new SymbolAtom(\"lbrack\", TYPE_OPENING, true));\n    sptr<SymbolAtom> s2(new SymbolAtom(\"rbrack\", TYPE_CLOSING, true));\n    return sptr<Atom>(new FencedAtom(f, s1, s2));\n}\n\ninline macro(above) {\n    auto num = tp.getFormulaAtom();\n    pair<int, float> dim = tp.getLength();\n    auto den = TeXFormula(tp, tp.getOverArgument(), false)._root;\n    if (num == nullptr || den == nullptr)\n        throw ex_parse(\"Both numerator and denominator of a fraction can't be empty!\");\n\n    return sptr<Atom>(new FractionAtom(num, den, dim.first, dim.second));\n}\n\ninline macro(mbox) {\n    sptr<Atom> group(new RomanAtom(TeXFormula(tp, args[1], \"mathnormal\", false, false)._root));\n    return sptr<Atom>(new StyleAtom(STYLE_TEXT, group));\n}\n\ninline macro(text) {\n    return sptr<Atom>(new RomanAtom(TeXFormula(tp, args[1], \"mathnormal\", false, false)._root));\n}\n\ninline macro(underscore) {\n    return sptr<Atom>(new UnderScoreAtom());\n}\n\ninline macro(accents) {\n    string x;\n    wide2utf8(args[0].c_str(), x);\n    return sptr<Atom>(new AccentedAtom(TeXFormula(tp, args[1], false)._root, x));\n}\n\ninline macro(grkaccent) {\n    return sptr<Atom>(new AccentedAtom(\n        TeXFormula(tp, args[2], false)._root, TeXFormula(tp, args[1], false)._root, false));\n}\n\ninline macro(accent) {\n    return sptr<Atom>(new AccentedAtom(\n        TeXFormula(tp, args[2], false)._root, TeXFormula(tp, args[1], false)._root));\n}\n\ninline macro(cedilla) {\n    return sptr<Atom>(new CedillAtom(TeXFormula(tp, args[1])._root));\n}\n\ninline macro(IJ) {\n    return sptr<Atom>(new IJAtom(args[0][0] == 'I'));\n}\n\ninline macro(TStroke) {\n    return sptr<Atom>(new TStrokeAtom(args[0][0] == 'T'));\n}\n\ninline macro(LCaron) {\n    return sptr<Atom>(new LCaronAtom(args[0][0] == 'L'));\n}\n\ninline macro(tcaron) {\n    return sptr<Atom>(new TCaronAtom());\n}\n\ninline macro(ogonek) {\n    return sptr<Atom>(new OgonekAtom(TeXFormula(tp, args[1])._root));\n}\n\ninline macro(nbsp) {\n    return sptr<Atom>(new SpaceAtom());\n}\n\ninline macro(sqrt) {\n    if (args[2].empty())\n        return sptr<Atom>(new NthRoot(TeXFormula(tp, args[1], false)._root, nullptr));\n    return sptr<Atom>(new NthRoot(\n        TeXFormula(tp, args[1], false)._root, TeXFormula(tp, args[2], false)._root));\n}\n\ninline macro(overrightarrow) {\n    return sptr<Atom>(new UnderOverArrowAtom(TeXFormula(tp, args[1], false)._root, false, true));\n}\n\ninline macro(overleftarrow) {\n    return sptr<Atom>(new UnderOverArrowAtom(TeXFormula(tp, args[1], false)._root, true, true));\n}\n\ninline macro(overleftrightarrow) {\n    return sptr<Atom>(new UnderOverArrowAtom(TeXFormula(tp, args[1], false)._root, true));\n}\n\ninline macro(underrightarrow) {\n    return sptr<Atom>(new UnderOverArrowAtom(TeXFormula(tp, args[1], false)._root, false, false));\n}\n\ninline macro(underleftarrow) {\n    return sptr<Atom>(new UnderOverArrowAtom(TeXFormula(tp, args[1], false)._root, true, false));\n}\n\ninline macro(underleftrightarrow) {\n    return sptr<Atom>(new UnderOverArrowAtom(TeXFormula(tp, args[1], false)._root, false));\n}\n\ninline macro(xleftarrow) {\n    return sptr<Atom>(new XArrowAtom(\n        TeXFormula(tp, args[1], false)._root, TeXFormula(tp, args[2])._root, true));\n}\n\ninline macro(xrightarrow) {\n    return sptr<Atom>(new XArrowAtom(\n        TeXFormula(tp, args[1], false)._root, TeXFormula(tp, args[2])._root, false));\n}\n\ninline macro(sideset) {\n    auto l = TeXFormula(tp, args[1])._root;\n    auto r = TeXFormula(tp, args[2])._root;\n    auto op = TeXFormula(tp, args[3])._root;\n    if (op == nullptr) {\n        sptr<Atom> in(new CharAtom(L'M', \"mathnormal\"));\n        op = sptr<Atom>(new PhantomAtom(in, false, true, true));\n    }\n    auto cl = dynamic_cast<CumulativeScriptsAtom*>(l.get());\n    auto cr = dynamic_cast<CumulativeScriptsAtom*>(r.get());\n    if (cl != nullptr) l = cl->getScriptsAtom();\n    if (cr != nullptr) r = cr->getScriptsAtom();\n    return sptr<Atom>(new SideSetsAtom(op, l, r));\n}\n\ninline macro(prescript) {\n    auto base = TeXFormula(tp, args[3])._root;\n    sptr<Atom> p(new PhantomAtom(base, false, true, true));\n    sptr<Atom> s(new ScriptsAtom(\n        p, TeXFormula(tp, args[2])._root, TeXFormula(tp, args[1])._root, false));\n    tp.addAtom(s);\n    tp.addAtom(sptr<Atom>(new SpaceAtom(UNIT_MU, -0.3f, 0, 0)));\n    return sptr<Atom>(new TypedAtom(TYPE_ORDINARY, TYPE_ORDINARY, base));\n}\n\ninline macro(underbrace) {\n    return sptr<Atom>(new OverUnderDelimiter(\n        TeXFormula(tp, args[1], false)._root,\n        nullptr,\n        SymbolAtom::get(\"rbrace\"),\n        UNIT_EX, 0, false));\n}\n\ninline macro(overbrace) {\n    return sptr<Atom>(new OverUnderDelimiter(\n        TeXFormula(tp, args[1], false)._root,\n        nullptr,\n        SymbolAtom::get(\"lbrace\"),\n        UNIT_EX, 0, true));\n}\n\ninline macro(underbrack) {\n    return sptr<Atom>(new OverUnderDelimiter(\n        TeXFormula(tp, args[1], false)._root,\n        nullptr,\n        SymbolAtom::get(\"rsqbrack\"),\n        UNIT_EX, 0, false));\n}\n\ninline macro(overbrack) {\n    return sptr<Atom>(new OverUnderDelimiter(\n        TeXFormula(tp, args[1], false)._root,\n        nullptr,\n        SymbolAtom::get(\"lsqbrack\"),\n        UNIT_EX, 0, true));\n}\n\ninline macro(underparen) {\n    return sptr<Atom>(new OverUnderDelimiter(\n        TeXFormula(tp, args[1], false)._root,\n        nullptr,\n        SymbolAtom::get(\"rbrack\"),\n        UNIT_EX, 0, false));\n}\n\ninline macro(overparen) {\n    return sptr<Atom>(new OverUnderDelimiter(\n        TeXFormula(tp, args[1], false)._root,\n        nullptr,\n        SymbolAtom::get(\"lbrack\"),\n        UNIT_EX, 0, true));\n}\n\ninline macro(overline) {\n    return sptr<Atom>(new OverlinedAtom(TeXFormula(tp, args[1], false)._root));\n}\n\ninline macro(underline) {\n    return sptr<Atom>(new UnderlinedAtom(TeXFormula(tp, args[1], false)._root));\n}\n\ninline macro(mathop) {\n    sptr<TypedAtom> a(new TypedAtom(\n        TYPE_BIG_OPERATOR, TYPE_BIG_OPERATOR, TeXFormula(tp, args[1], false)._root));\n    a->_typelimits = SCRIPT_NORMAL;\n    return a;\n}\n\ninline macro(mathpunct) {\n    return sptr<Atom>(new TypedAtom(\n        TYPE_PUNCTUATION, TYPE_PUNCTUATION, TeXFormula(tp, args[1], false)._root));\n}\n\ninline macro(mathord) {\n    return sptr<Atom>(new TypedAtom(\n        TYPE_ORDINARY, TYPE_ORDINARY, TeXFormula(tp, args[1], false)._root));\n}\n\ninline macro(mathrel) {\n    return sptr<Atom>(new TypedAtom(\n        TYPE_RELATION, TYPE_RELATION, TeXFormula(tp, args[1], false)._root));\n}\n\ninline macro(mathinner) {\n    return sptr<Atom>(new TypedAtom(\n        TYPE_INNER, TYPE_INNER, TeXFormula(tp, args[1], false)._root));\n}\n\ninline macro(mathbin) {\n    return sptr<Atom>(new TypedAtom(\n        TYPE_BINARY_OPERATOR, TYPE_BINARY_OPERATOR, TeXFormula(tp, args[1], false)._root));\n}\n\ninline macro(mathopen) {\n    return sptr<Atom>(new TypedAtom(\n        TYPE_OPENING, TYPE_OPENING, TeXFormula(tp, args[1], false)._root));\n}\n\ninline macro(mathclose) {\n    return sptr<Atom>(new TypedAtom(\n        TYPE_CLOSING, TYPE_CLOSING, TeXFormula(tp, args[1], false)._root));\n}\n\ninline macro(joinrel) {\n    return sptr<Atom>(new TypedAtom(\n        TYPE_RELATION, TYPE_RELATION, sptr<Atom>(new SpaceAtom(UNIT_MU, -2.6f, 0, 0))));\n}\n\ninline macro(smash) {\n    string x;\n    wide2utf8(args[2].c_str(), x);\n    return sptr<Atom>(new SmashedAtom(TeXFormula(tp, args[1], false)._root, x));\n}\n\ninline macro(vdots) {\n    return sptr<Atom>(new VdotsAtom());\n}\n\ninline macro(ddots) {\n    return sptr<Atom>(new TypedAtom(\n        TYPE_INNER, TYPE_INNER, sptr<Atom>(new DdtosAtom())));\n}\n\ninline macro(iddots) {\n    return sptr<Atom>(new TypedAtom(\n        TYPE_INNER, TYPE_INNER, sptr<Atom>(new IddotsAtom())));\n}\n\ninline macro(leftparenthesis) {\n    wstring grp = tp.getGroup(L\"\\\\(\", L\"\\\\)\");\n    return sptr<Atom>(new MathAtom(TeXFormula(tp, grp, false)._root, STYLE_TEXT));\n}\n\ninline macro(leftbracket) {\n    wstring grp = tp.getGroup(L\"\\\\[\", L\"\\\\]\");\n    return sptr<Atom>(new MathAtom(TeXFormula(tp, grp, false)._root, STYLE_DISPLAY));\n}\n\ninline macro(middle) {\n    return sptr<Atom>(new MiddleAtom(TeXFormula(tp, args[1])._root));\n}\n\ninline macro(cr) {\n    if (tp.isArrayMode()) {\n        tp.addRow();\n    } else {\n        ArrayOfAtoms arr;\n        arr.add(tp._formula->_root);\n        arr.addRow();\n        TeXParser parser(\n            tp.getIsPartial(), tp.forwardFromCurrentPos(),\n            &arr, false, tp.isIgnoreWhiteSpace());\n        parser.parse();\n        arr.checkDimensions();\n        tp._formula->_root = arr.getAsVRow();\n    }\n\n    return nullptr;\n}\n\ninline macro(backslashcr) {\n    return macro_cr(tp, args);\n}\n\ninline macro(smallmatrixATATenv) {\n    sptr<ArrayOfAtoms> arr(new ArrayOfAtoms());\n    TeXParser parser(tp.getIsPartial(), args[1], arr.get(), false);\n    parser.parse();\n    arr->checkDimensions();\n    return sptr<Atom>(new MatrixAtom(\n        tp.getIsPartial(), arr, SMALLMATRIX));\n}\n\ninline macro(matrixATATenv) {\n    sptr<ArrayOfAtoms> arr(new ArrayOfAtoms());\n    TeXParser parser(tp.getIsPartial(), args[1], arr.get(), false);\n    parser.parse();\n    arr->checkDimensions();\n    return sptr<Atom>(new MatrixAtom(\n        tp.getIsPartial(), arr, MATRIX));\n}\n\ninline macro(multicolumn) {\n    int n = 0;\n    valueof(args[1], n);\n    string x;\n    wide2utf8(args[2].c_str(), x);\n    tp.addAtom(sptr<Atom>(new MulticolumnAtom(n, x, TeXFormula(tp, args[3])._root)));\n    if(tp._formula == nullptr) throw ex_parse(\"_formula is null!\");\n    ArrayOfAtoms* arr = dynamic_cast<ArrayOfAtoms*>(tp._formula);\n    if(arr == nullptr) throw ex_parse(\"dynamic_cast<ArrayOfAtoms*>(_formula) is null!\");\n    arr->addCol(n);\n    return nullptr;\n}\n\ninline macro(hdotsfor) {\n    if (!tp.isArrayMode())\n        throw ex_parse(\"Command 'hdotsfor' only available in array mode!\");\n    int n = 0;\n    valueof(args[1], n);\n    float f = 1.f;\n    if (!args[2].empty()) valueof(args[2], f);\n    tp.addAtom(sptr<Atom>(new HdotsforAtom(n, f)));\n    if(tp._formula == nullptr) throw ex_parse(\"_formula is null!\");\n    ArrayOfAtoms* arr = dynamic_cast<ArrayOfAtoms*>(tp._formula);\n    if(arr == nullptr) throw ex_parse(\"dynamic_cast<ArrayOfAtoms*>(_formula) is null!\");\n    arr->addCol(n);\n    return nullptr;\n}\n\ninline macro(arrayATATenv) {\n    sptr<ArrayOfAtoms> arr(new ArrayOfAtoms());\n    TeXParser parser(tp.getIsPartial(), args[2], arr.get(), false);\n    parser.parse();\n    arr->checkDimensions();\n    return sptr<Atom>(new MatrixAtom(\n        tp.getIsPartial(), arr, args[1], true));\n}\n\ninline macro(alignATATenv) {\n    sptr<ArrayOfAtoms> arr(new ArrayOfAtoms());\n    TeXParser parser(tp.getIsPartial(), args[1], arr.get(), false);\n    parser.parse();\n    arr->checkDimensions();\n    return sptr<Atom>(new MatrixAtom(\n        tp.getIsPartial(), arr, ALIGN));\n}\n\ninline macro(flalignATATenv) {\n    sptr<ArrayOfAtoms> arr(new ArrayOfAtoms());\n    TeXParser parser(tp.getIsPartial(), args[1], arr.get(), false);\n    parser.parse();\n    arr->checkDimensions();\n    return sptr<Atom>(new MatrixAtom(\n        tp.getIsPartial(), arr, FLALIGN));\n}\n\ninline macro(alignatATATenv) {\n    sptr<ArrayOfAtoms> arr(new ArrayOfAtoms());\n    TeXParser par(tp.getIsPartial(), args[2], arr.get(), false);\n    par.parse();\n    arr->checkDimensions();\n    size_t n = 0;\n    valueof(args[1], n);\n    if (arr->cols() != 2 * n) throw ex_parse(\"Bad number of equations in alignat environment!\");\n\n    return sptr<Atom>(new MatrixAtom(\n        tp.getIsPartial(), arr, ALIGNAT));\n}\n\ninline macro(alignedATATenv) {\n    sptr<ArrayOfAtoms> arr(new ArrayOfAtoms());\n    TeXParser p(tp.getIsPartial(), args[1], arr.get(), false);\n    p.parse();\n    arr->checkDimensions();\n    return sptr<Atom>(new MatrixAtom(\n        tp.getIsPartial(), arr, ALIGNED));\n}\n\ninline macro(alignedatATATenv) {\n    sptr<ArrayOfAtoms> arr(new ArrayOfAtoms());\n    TeXParser p(tp.getIsPartial(), args[2], arr.get(), false);\n    p.parse();\n    arr->checkDimensions();\n    size_t n = 0;\n    valueof(args[1], n);\n    if (arr->cols() != 2 * n)\n        throw ex_parse(\"Bad number of equations in alignedat environment!\");\n\n    return sptr<Atom>(new MatrixAtom(\n        tp.getIsPartial(), arr, ALIGNEDAT));\n}\n\ninline macro(multlineATATenv) {\n    sptr<ArrayOfAtoms> arr(new ArrayOfAtoms());\n    TeXParser p(tp.getIsPartial(), args[1], arr.get(), false);\n    p.parse();\n    arr->checkDimensions();\n    if (arr->cols() > 1)\n        throw ex_parse(\"Requires exact one column in multiline envrionment!\");\n    if (arr->cols() == 0)\n        return nullptr;\n\n    return sptr<Atom>(new MultlineAtom(\n        tp.getIsPartial(), arr, MULTILINE));\n}\n\ninline macro(gatherATATenv) {\n    sptr<ArrayOfAtoms> arr(new ArrayOfAtoms());\n    TeXParser p(tp.getIsPartial(), args[1], arr.get(), false);\n    p.parse();\n    arr->checkDimensions();\n    if (arr->cols() > 1) throw ex_parse(\"Requires exact one column in gather envrionment!\");\n    if (arr->cols() == 0) return nullptr;\n\n    return sptr<Atom>(new MultlineAtom(\n        tp.getIsPartial(), arr, GATHER));\n}\n\ninline macro(gatheredATATenv) {\n    sptr<ArrayOfAtoms> arr(new ArrayOfAtoms());\n    TeXParser p(tp.getIsPartial(), args[1], arr.get(), false);\n    p.parse();\n    arr->checkDimensions();\n    if (arr->cols() > 1) throw ex_parse(\"Requires exact one column in gathered envrionment!\");\n    if (arr->cols() == 0) return nullptr;\n\n    return sptr<Atom>(new MultlineAtom(\n        tp.getIsPartial(), arr, GATHERED));\n}\n\ninline macro(shoveright) {\n    auto a = TeXFormula(tp, args[1])._root;\n    a->_alignment = ALIGN_RIGHT;\n    return a;\n}\n\ninline macro(shoveleft) {\n    auto a = TeXFormula(tp, args[1])._root;\n    a->_alignment = ALIGN_LEFT;\n    return a;\n}\n\ninline macro(makeatletter) {\n    tp.makeAtLetter();\n    return nullptr;\n}\n\ninline macro(makeatother) {\n    tp.makeAtOther();\n    return nullptr;\n}\n\ninline macro(newenvironment) {\n    int opt = 0;\n    if (!args[4].empty()) valueof(args[4], opt);\n\n    NewEnvironmentMacro::addNewEnvironment(args[1], args[2], args[3], opt);\n    return nullptr;\n}\n\ninline macro(renewenvironment) {\n    int opt = 0;\n    if (!args[4].empty()) valueof(args[4], opt);\n\n    NewEnvironmentMacro::addRenewEnvironment(args[1], args[2], args[3], opt);\n    return nullptr;\n}\n\ninline macro(fbox) {\n    return sptr<Atom>(new FBoxAtom(TeXFormula(tp, args[1], false)._root));\n}\n\ninline macro(questeq) {\n    auto eq = SymbolAtom::get(TeXFormula::_symbolMappings['=']);\n    auto quest = SymbolAtom::get(TeXFormula::_symbolMappings['?']);\n    auto sq = sptr<Atom>(new ScaleAtom(quest, 0.75f));\n    auto at = sptr<Atom>(new UnderOverAtom(eq, sq, UNIT_MU, 2.5f, true, true));\n    return sptr<Atom>(new TypedAtom(TYPE_RELATION, TYPE_RELATION, at));\n}\n\ninline macro(stackrel) {\n    sptr<Atom> a(new UnderOverAtom(\n        TeXFormula(tp, args[2], false)._root,\n        TeXFormula(tp, args[3], false)._root,\n        UNIT_MU, 0.5f, true,\n        TeXFormula(tp, args[1], false)._root,\n        UNIT_MU, 2.5f, true));\n    return sptr<Atom>(new TypedAtom(TYPE_RELATION, TYPE_RELATION, a));\n}\n\ninline macro(stackbin) {\n    sptr<Atom> a(new UnderOverAtom(\n        TeXFormula(tp, args[2], false)._root,\n        TeXFormula(tp, args[3], false)._root,\n        UNIT_MU, 0.5f, true,\n        TeXFormula(tp, args[1], false)._root,\n        UNIT_MU, 2.5f, true));\n    return sptr<Atom>(new TypedAtom(TYPE_BINARY_OPERATOR, TYPE_BINARY_OPERATOR, a));\n}\n\ninline macro(overset) {\n    sptr<Atom> a(new UnderOverAtom(\n        TeXFormula(tp, args[2], false)._root,\n        TeXFormula(tp, args[1], false)._root,\n        UNIT_MU, 2.5f, true, true));\n    return sptr<Atom>(new TypedAtom(TYPE_RELATION, TYPE_RELATION, a));\n}\n\ninline macro(underset) {\n    sptr<Atom> a(new UnderOverAtom(\n        TeXFormula(tp, args[2], false)._root,\n        TeXFormula(tp, args[1], false)._root,\n        UNIT_MU, 0.5f, true, false));\n    return sptr<Atom>(new TypedAtom(TYPE_RELATION, TYPE_RELATION, a));\n}\n\ninline macro(accentset) {\n    return sptr<Atom>(new AccentedAtom(\n        TeXFormula(tp, args[2], false)._root, TeXFormula(tp, args[1], false)._root));\n}\n\ninline macro(underaccent) {\n    return sptr<Atom>(new UnderOverAtom(\n        TeXFormula(tp, args[2], false)._root,\n        TeXFormula(tp, args[1], false)._root,\n        UNIT_MU, 0.3f, true, false));\n}\n\ninline macro(undertilde) {\n    auto a = TeXFormula(tp, args[1], false)._root;\n    sptr<PhantomAtom> p(new PhantomAtom(a, true, false, false));\n    sptr<AccentedAtom> acc(new AccentedAtom(p, \"widetilde\"));\n    return sptr<Atom>(new UnderOverAtom(a, acc, UNIT_MU, 0.3f, true, false));\n}\n\ninline macro(boldsymbol) {\n    return sptr<Atom>(new BoldAtom(TeXFormula(tp, args[1], false)._root));\n}\n\ninline macro(mathrm) {\n    return sptr<Atom>(new RomanAtom(TeXFormula(tp, args[1], false)._root));\n}\n\ninline macro(rm) {\n    return sptr<Atom>(new RomanAtom(\n        TeXFormula(tp, tp.getOverArgument(), \"\", false, tp.isIgnoreWhiteSpace())._root));\n}\n\ninline macro(mathbf) {\n    return sptr<Atom>(new BoldAtom(\n        sptr<Atom>(new RomanAtom(TeXFormula(tp, args[1], false)._root))));\n}\n\ninline macro(bf) {\n    return sptr<Atom>(new BoldAtom(sptr<Atom>(new RomanAtom(\n        TeXFormula(tp, tp.getOverArgument(), \"\", false, tp.isIgnoreWhiteSpace())._root))));\n}\n\ninline macro(mathtt) {\n    return sptr<Atom>(new TtAtom(TeXFormula(tp, args[1], false)._root));\n}\n\ninline macro(tt) {\n    return sptr<Atom>(new TtAtom(\n        TeXFormula(tp, tp.getOverArgument(), \"\", false, tp.isIgnoreWhiteSpace())._root));\n}\n\ninline macro(mathit) {\n    return sptr<Atom>(new ItAtom(TeXFormula(tp, args[1], false)._root));\n}\n\ninline macro(it) {\n    return sptr<Atom>(new ItAtom(\n        TeXFormula(tp, tp.getOverArgument(), \"\", false, tp.isIgnoreWhiteSpace())._root));\n}\n\ninline macro(mathsf) {\n    return sptr<Atom>(new SsAtom(TeXFormula(tp, args[1], false)._root));\n}\n\ninline macro(sf) {\n    return sptr<Atom>(new SsAtom(\n        TeXFormula(tp, tp.getOverArgument(), \"\", false, tp.isIgnoreWhiteSpace())._root));\n}\n\ninline macro(LaTeX) {\n    return sptr<Atom>(new LaTeXAtom());\n}\n\ninline macro(hphantom) {\n    return sptr<Atom>(\n        new PhantomAtom(TeXFormula(tp, args[1], false)._root, true, false, false));\n}\n\ninline macro(vphantom) {\n    return sptr<Atom>(\n        new PhantomAtom(TeXFormula(tp, args[1], false)._root, false, true, true));\n}\n\ninline macro(phantom) {\n    return sptr<Atom>(\n        new PhantomAtom(TeXFormula(tp, args[1], false)._root, true, true, true));\n}\n\ninline sptr<Atom> _macro_big(TeXParser& tp, vector<wstring>& args, int size, int type = -1) {\n    auto a = TeXFormula(tp, args[1], false)._root;\n    auto s = dynamic_pointer_cast<SymbolAtom>(a);\n    if (s == nullptr) return a;\n    sptr<Atom> t(new BigDelimiterAtom(s, size));\n    if (type != -1) t->_type = type;\n    return t;\n}\n\ninline macro(big) { return _macro_big(tp, args, 1); }\n\ninline macro(Big) { return _macro_big(tp, args, 2); }\n\ninline macro(bigg) { return _macro_big(tp, args, 3); }\n\ninline macro(Bigg) { return _macro_big(tp, args, 4); }\n\ninline macro(bigl) { return _macro_big(tp, args, 1, TYPE_OPENING); }\n\ninline macro(Bigl) { return _macro_big(tp, args, 2, TYPE_OPENING); }\n\ninline macro(biggl) { return _macro_big(tp, args, 3, TYPE_OPENING); }\n\ninline macro(Biggl) { return _macro_big(tp, args, 4, TYPE_OPENING); }\n\ninline macro(bigr) { return _macro_big(tp, args, 1, TYPE_CLOSING); }\n\ninline macro(Bigr) { return _macro_big(tp, args, 2, TYPE_CLOSING); }\n\ninline macro(biggr) { return _macro_big(tp, args, 3, TYPE_CLOSING); }\n\ninline macro(Biggr) { return _macro_big(tp, args, 4, TYPE_CLOSING); }\n\ninline macro(displaystyle) {\n    auto g = TeXFormula(tp, tp.getOverArgument(), false)._root;\n    return sptr<Atom>(new StyleAtom(STYLE_DISPLAY, g));\n}\n\ninline macro(scriptstyle) {\n    auto g = TeXFormula(tp, tp.getOverArgument(), false)._root;\n    return sptr<Atom>(new StyleAtom(STYLE_SCRIPT, g));\n}\n\ninline macro(textstyle) {\n    auto g = TeXFormula(tp, tp.getOverArgument(), false)._root;\n    return sptr<Atom>(new StyleAtom(STYLE_TEXT, g));\n}\n\ninline macro(scriptscriptstyle) {\n    auto g = TeXFormula(tp, tp.getOverArgument(), false)._root;\n    return sptr<Atom>(new StyleAtom(STYLE_SCRIPT_SCRIPT, g));\n}\n\ninline macro(rotatebox) {\n    float x = 0;\n    if (!args[1].empty()) valueof(args[1], x);\n    return sptr<Atom>(new RotateAtom(TeXFormula(tp, args[2])._root, x, args[3]));\n}\n\ninline macro(reflectbox) {\n    return sptr<Atom>(new ReflectAtom(TeXFormula(tp, args[1])._root));\n}\n\ninline macro(scalebox) {\n    float sx = 1, sy = 1;\n    valueof(args[1], sx);\n    if (args[3].empty())\n        sy = sx;\n    else\n        valueof(args[3], sy);\n    if (sx == 0) sx = 1;\n    if (sy == 0) sy = 1;\n    return sptr<Atom>(new ScaleAtom(TeXFormula(tp, args[2])._root, sx, sy));\n}\n\ninline macro(resizebox) {\n    string ws, hs;\n    wide2utf8(args[1].c_str(), ws);\n    wide2utf8(args[2].c_str(), hs);\n    return sptr<Atom>(new ResizeAtom(\n        TeXFormula(tp, args[3])._root, ws, hs, ws == \"!\" || hs == \"!\"));\n}\n\ninline macro(shadowbox) {\n    return sptr<Atom>(new ShadowAtom(TeXFormula(tp, args[1])._root));\n}\n\ninline macro(ovalbox) {\n    return sptr<Atom>(new OvalAtom(TeXFormula(tp, args[1])._root));\n}\n\ninline macro(cornersize) {\n    float size = 0.5f;\n    valueof(args[1], size);\n    if (size <= 0 || size > 0.5f) size = 0.5f;\n    OvalAtom::_multiplier = size;\n    OvalAtom::_diameter = 0;\n    return nullptr;\n}\n\ninline macro(doublebox) {\n    return sptr<Atom>(new DoubleFramedAtom(TeXFormula(tp, args[1])._root));\n}\n\ninline macro(fgcolor) {\n    auto a = TeXFormula(tp, args[2])._root;\n    string x = wide2utf8(args[1].c_str());\n    return sptr<Atom>(new ColorAtom(a, TRANS, ColorAtom::getColor(x)));\n}\n\ninline macro(bgcolor) {\n    auto a = TeXFormula(tp, args[2])._root;\n    string x = wide2utf8(args[1].c_str());\n    return sptr<Atom>(new ColorAtom(a, ColorAtom::getColor(x), TRANS));\n}\n\ninline macro(textcolor) {\n    auto a = TeXFormula(tp, args[2])._root;\n    string x = wide2utf8(args[1].c_str());\n    return sptr<Atom>(new ColorAtom(a, TRANS, ColorAtom::getColor(x)));\n}\n\ninline macro(colorbox) {\n    string x = wide2utf8(args[1].c_str());\n    color c = ColorAtom::getColor(x);\n    return sptr<Atom>(new FBoxAtom(TeXFormula(tp, args[2])._root, c, c));\n}\n\ninline macro(fcolorbox) {\n    string x = wide2utf8(args[2].c_str());\n    color f = ColorAtom::getColor(x);\n    string y = wide2utf8(args[1].c_str());\n    color b = ColorAtom::getColor(y);\n    return sptr<Atom>(new FBoxAtom(TeXFormula(tp, args[3])._root, f, b));\n}\n\ninline macro(cong) {\n    VRowAtom* vra = new VRowAtom(SymbolAtom::get(\"equals\"));\n    vra->add(sptr<Atom>(new SpaceAtom(UNIT_MU, 0, 1.5f, 0)));\n    vra->add(SymbolAtom::get(\"sim\"));\n    vra->setRaise(UNIT_MU, -1);\n    return sptr<Atom>(new TypedAtom(TYPE_RELATION, TYPE_RELATION, sptr<Atom>(vra)));\n}\n\ninline macro(doteq) {\n    auto e = SymbolAtom::get(\"equals\");\n    auto l = SymbolAtom::get(\"ldotp\");\n    sptr<Atom> u(new UnderOverAtom(e, l, UNIT_MU, 3.7f, false, true));\n    return sptr<Atom>(new TypedAtom(TYPE_RELATION, TYPE_RELATION, u));\n}\n\ninline macro(externalfont) {\n    string x = wide2utf8(args[1].c_str());\n    TextRenderingBox::setFont(x);\n    return nullptr;\n}\n\ninline macro(ctext) {\n    return sptr<Atom>(new TextRenderingAtom(args[1], PLAIN));\n}\n\ninline macro(textit) {\n    return sptr<Atom>(new TextRenderingAtom(args[1], ITALIC));\n}\n\ninline macro(textbf) {\n    return sptr<Atom>(new TextRenderingAtom(args[1], BOLD));\n}\n\ninline macro(textitbf) {\n    return sptr<Atom>(new TextRenderingAtom(args[1], BOLD | ITALIC));\n}\n\ninline macro(declaremathsizes) {\n    float a, b, c, d;\n    valueof(args[1], a), valueof(args[2], b), valueof(args[3], c), valueof(args[4], d);\n    DefaultTeXFont::setMathSizes(a, b, c, c);\n    return nullptr;\n}\n\ninline macro(magnification) {\n    float x;\n    valueof(args[1], x);\n    DefaultTeXFont::setMagnification(x);\n    return nullptr;\n}\n\ninline macro(hline) {\n    if (!tp.isArrayMode())\n        throw ex_parse(\"The macro \\\\hline only available in array mode!\");\n    return sptr<Atom>(new HlineAtom());\n}\n\ninline macro(mathcumsup) {\n    return sptr<Atom>(new CumulativeScriptsAtom(\n        tp.popLastAtom(), nullptr, TeXFormula(tp, args[1])._root));\n}\n\ninline macro(mathcumsub) {\n    return sptr<Atom>(new CumulativeScriptsAtom(\n        tp.popLastAtom(), TeXFormula(tp, args[1])._root, nullptr));\n}\n\ninline macro(dotminus) {\n    sptr<Atom> a(new UnderOverAtom(\n        SymbolAtom::get(\"minus\"),\n        SymbolAtom::get(\"normaldot\"),\n        UNIT_MU, -3.3f, false, true));\n    return sptr<Atom>(new TypedAtom(TYPE_BINARY_OPERATOR, TYPE_BINARY_OPERATOR, a));\n}\n\ninline macro(ratio) {\n    sptr<Atom> a(new UnderOverAtom(\n        SymbolAtom::get(\"normaldot\"),\n        SymbolAtom::get(\"normaldot\"),\n        UNIT_MU, 5.2f, false, true));\n    return sptr<Atom>(new TypedAtom(TYPE_RELATION, TYPE_RELATION, a));\n}\n\ninline macro(geoprop) {\n    sptr<RowAtom> ddot(new RowAtom(SymbolAtom::get(\"normaldot\")));\n    ddot->add(sptr<Atom>(new SpaceAtom(UNIT_MU, 4, 0, 0)));\n    ddot->add(SymbolAtom::get(\"normaldot\"));\n    sptr<Atom> a(new UnderOverAtom(\n        SymbolAtom::get(\"minus\"),\n        ddot, UNIT_MU, -3.4f, false, ddot, UNIT_MU, -3.4f, false));\n    return sptr<Atom>(new TypedAtom(TYPE_RELATION, TYPE_RELATION, a));\n}\n\ninline macro(minuscolon) {\n    RowAtom* ra = new RowAtom(SymbolAtom::get(\"minus\"));\n    ra->add(sptr<Atom>(new SpaceAtom(UNIT_EM, -0.095f, 0, 0)));\n    sptr<Atom> colon(new UnderOverAtom(\n        SymbolAtom::get(\"normaldot\"),\n        SymbolAtom::get(\"normaldot\"),\n        UNIT_MU, 5.2f, false, true));\n    ra->add(colon);\n    return sptr<Atom>(new TypedAtom(TYPE_RELATION, TYPE_RELATION, sptr<Atom>(ra)));\n}\n\ninline macro(minuscoloncolon) {\n    RowAtom* ra = new RowAtom(SymbolAtom::get(\"minus\"));\n    ra->add(sptr<Atom>(new SpaceAtom(UNIT_EM, -0.095f, 0, 0)));\n    sptr<Atom> colon(new UnderOverAtom(\n        SymbolAtom::get(\"normaldot\"),\n        SymbolAtom::get(\"normaldot\"),\n        UNIT_MU, 5.2f, false, true));\n    ra->add(colon);\n    ra->add(colon);\n    return sptr<Atom>(new TypedAtom(TYPE_RELATION, TYPE_RELATION, sptr<Atom>(ra)));\n}\n\ninline macro(simcolon) {\n    RowAtom* ra = new RowAtom(SymbolAtom::get(\"sim\"));\n    ra->add(sptr<Atom>(new SpaceAtom(UNIT_EM, -0.095f, 0, 0)));\n    sptr<Atom> colon(new UnderOverAtom(\n        SymbolAtom::get(\"normaldot\"),\n        SymbolAtom::get(\"normaldot\"),\n        UNIT_MU, 5.2f, false, true));\n    ra->add(colon);\n    return sptr<Atom>(new TypedAtom(TYPE_RELATION, TYPE_RELATION, sptr<Atom>(ra)));\n}\n\ninline macro(simcoloncolon) {\n    RowAtom* ra = new RowAtom(SymbolAtom::get(\"sim\"));\n    ra->add(sptr<Atom>(new SpaceAtom(UNIT_EM, -0.095f, 0, 0)));\n    sptr<Atom> colon(new UnderOverAtom(\n        SymbolAtom::get(\"normaldot\"),\n        SymbolAtom::get(\"normaldot\"),\n        UNIT_MU, 5.2f, false, true));\n    ra->add(colon);\n    ra->add(colon);\n    return sptr<Atom>(new TypedAtom(TYPE_RELATION, TYPE_RELATION, sptr<Atom>(ra)));\n}\n\ninline macro(approxcolon) {\n    RowAtom* ra = new RowAtom(SymbolAtom::get(\"approx\"));\n    ra->add(sptr<Atom>(new SpaceAtom(UNIT_EM, -0.095f, 0, 0)));\n    sptr<Atom> colon(new UnderOverAtom(\n        SymbolAtom::get(\"normaldot\"),\n        SymbolAtom::get(\"normaldot\"),\n        UNIT_MU, 5.2f, false, true));\n    ra->add(colon);\n    return sptr<Atom>(new TypedAtom(TYPE_RELATION, TYPE_RELATION, sptr<Atom>(ra)));\n}\n\ninline macro(approxcoloncolon) {\n    RowAtom* ra = new RowAtom(SymbolAtom::get(\"approx\"));\n    ra->add(sptr<Atom>(new SpaceAtom(UNIT_EM, -0.095f, 0, 0)));\n    sptr<Atom> colon(new UnderOverAtom(\n        SymbolAtom::get(\"normaldot\"),\n        SymbolAtom::get(\"normaldot\"),\n        UNIT_MU, 5.2f, false, true));\n    ra->add(colon);\n    ra->add(colon);\n    return sptr<Atom>(new TypedAtom(TYPE_RELATION, TYPE_RELATION, sptr<Atom>(ra)));\n}\n\ninline macro(equalscolon) {\n    RowAtom* ra = new RowAtom(SymbolAtom::get(\"equals\"));\n    ra->add(sptr<Atom>(new SpaceAtom(UNIT_EM, -0.095f, 0, 0)));\n    sptr<Atom> colon(new UnderOverAtom(\n        SymbolAtom::get(\"normaldot\"),\n        SymbolAtom::get(\"normaldot\"),\n        UNIT_MU, 5.2f, false, true));\n    ra->add(colon);\n    return sptr<Atom>(new TypedAtom(TYPE_RELATION, TYPE_RELATION, sptr<Atom>(ra)));\n}\n\ninline macro(equalscoloncolon) {\n    RowAtom* ra = new RowAtom(SymbolAtom::get(\"equals\"));\n    ra->add(sptr<Atom>(new SpaceAtom(UNIT_EM, -0.095f, 0, 0)));\n    sptr<Atom> colon(new UnderOverAtom(\n        SymbolAtom::get(\"normaldot\"),\n        SymbolAtom::get(\"normaldot\"),\n        UNIT_MU, 5.2f, false, true));\n    ra->add(colon);\n    ra->add(colon);\n    return sptr<Atom>(new TypedAtom(TYPE_RELATION, TYPE_RELATION, sptr<Atom>(ra)));\n}\n\ninline macro(colonminus) {\n    sptr<Atom> u(new UnderOverAtom(\n        SymbolAtom::get(\"normaldot\"),\n        SymbolAtom::get(\"normaldot\"),\n        UNIT_MU, 5.2f, false, true));\n    RowAtom* ra = new RowAtom(u);\n    ra->add(sptr<Atom>(new SpaceAtom(UNIT_EM, -0.32f, 0, 0)));\n    ra->add(SymbolAtom::get(\"minus\"));\n    return sptr<Atom>(new TypedAtom(TYPE_RELATION, TYPE_RELATION, sptr<Atom>(ra)));\n}\n\ninline macro(coloncolonminus) {\n    sptr<Atom> u(new UnderOverAtom(\n        SymbolAtom::get(\"normaldot\"),\n        SymbolAtom::get(\"normaldot\"),\n        UNIT_MU, 5.2f, false, true));\n    RowAtom* ra = new RowAtom(u);\n    ra->add(u);\n    ra->add(sptr<Atom>(new SpaceAtom(UNIT_EM, -0.32f, 0, 0)));\n    ra->add(SymbolAtom::get(\"minus\"));\n    return sptr<Atom>(new TypedAtom(TYPE_RELATION, TYPE_RELATION, sptr<Atom>(ra)));\n}\n\ninline macro(colonequals) {\n    sptr<Atom> u(new UnderOverAtom(\n        SymbolAtom::get(\"normaldot\"),\n        SymbolAtom::get(\"normaldot\"),\n        UNIT_MU, 5.2f, false, true));\n    RowAtom* ra = new RowAtom(u);\n    ra->add(sptr<Atom>(new SpaceAtom(UNIT_EM, -0.32f, 0, 0)));\n    ra->add(SymbolAtom::get(\"equals\"));\n    return sptr<Atom>(new TypedAtom(TYPE_RELATION, TYPE_RELATION, sptr<Atom>(ra)));\n}\n\ninline macro(coloncolonequals) {\n    sptr<Atom> u(new UnderOverAtom(\n        SymbolAtom::get(\"normaldot\"),\n        SymbolAtom::get(\"normaldot\"),\n        UNIT_MU, 5.2f, false, true));\n    RowAtom* ra = new RowAtom(u);\n    ra->add(u);\n    ra->add(sptr<Atom>(new SpaceAtom(UNIT_EM, -0.32f, 0, 0)));\n    ra->add(SymbolAtom::get(\"equals\"));\n    return sptr<Atom>(new TypedAtom(TYPE_RELATION, TYPE_RELATION, sptr<Atom>(ra)));\n}\n\ninline macro(coloncolon) {\n    sptr<Atom> u(new UnderOverAtom(\n        SymbolAtom::get(\"normaldot\"),\n        SymbolAtom::get(\"normaldot\"),\n        UNIT_MU, 5.2f, false, true));\n    RowAtom* ra = new RowAtom(u);\n    ra->add(u);\n    return sptr<Atom>(new TypedAtom(TYPE_RELATION, TYPE_RELATION, sptr<Atom>(ra)));\n}\n\ninline macro(colonsim) {\n    sptr<Atom> u(new UnderOverAtom(\n        SymbolAtom::get(\"normaldot\"),\n        SymbolAtom::get(\"normaldot\"),\n        UNIT_MU, 5.2f, false, true));\n    RowAtom* ra = new RowAtom(u);\n    ra->add(sptr<Atom>(new SpaceAtom(UNIT_EM, -0.32f, 0, 0)));\n    ra->add(SymbolAtom::get(\"sim\"));\n    return sptr<Atom>(new TypedAtom(TYPE_RELATION, TYPE_RELATION, sptr<Atom>(ra)));\n}\n\ninline macro(coloncolonsim) {\n    sptr<Atom> u(new UnderOverAtom(\n        SymbolAtom::get(\"normaldot\"),\n        SymbolAtom::get(\"normaldot\"),\n        UNIT_MU, 5.2f, false, true));\n    RowAtom* ra = new RowAtom(u);\n    ra->add(u);\n    ra->add(sptr<Atom>(new SpaceAtom(UNIT_EM, -0.32f, 0, 0)));\n    ra->add(SymbolAtom::get(\"sim\"));\n    return sptr<Atom>(new TypedAtom(TYPE_RELATION, TYPE_RELATION, sptr<Atom>(ra)));\n}\n\ninline macro(colonapprox) {\n    sptr<Atom> u(new UnderOverAtom(\n        SymbolAtom::get(\"normaldot\"),\n        SymbolAtom::get(\"normaldot\"),\n        UNIT_MU, 5.2f, false, true));\n    RowAtom* ra = new RowAtom(u);\n    ra->add(sptr<Atom>(new SpaceAtom(UNIT_EM, -0.32f, 0, 0)));\n    ra->add(SymbolAtom::get(\"approx\"));\n    return sptr<Atom>(new TypedAtom(TYPE_RELATION, TYPE_RELATION, sptr<Atom>(ra)));\n}\n\ninline macro(coloncolonapprox) {\n    sptr<Atom> u(new UnderOverAtom(\n        SymbolAtom::get(\"normaldot\"),\n        SymbolAtom::get(\"normaldot\"),\n        UNIT_MU, 5.2f, false, true));\n    RowAtom* ra = new RowAtom(u);\n    ra->add(u);\n    ra->add(sptr<Atom>(new SpaceAtom(UNIT_EM, -0.32f, 0, 0)));\n    ra->add(SymbolAtom::get(\"approx\"));\n    return sptr<Atom>(new TypedAtom(TYPE_RELATION, TYPE_RELATION, sptr<Atom>(ra)));\n}\n\ninline macro(smallfrowneq) {\n    sptr<Atom> u(new UnderOverAtom(\n        SymbolAtom::get(\"equals\"),\n        SymbolAtom::get(\"smallfrown\"),\n        UNIT_MU, -2, true, true));\n    return sptr<Atom>(new TypedAtom(TYPE_RELATION, TYPE_RELATION, u));\n}\n\ninline macro(hstrok) {\n    sptr<RowAtom> ra(new RowAtom(sptr<Atom>(new SpaceAtom(UNIT_EX, -0.1f, 0, 0))));\n    ra->add(SymbolAtom::get(\"bar\"));\n    VRowAtom* vra = new VRowAtom(sptr<Atom>(new LapedAtom(ra, 'r')));\n    vra->setRaise(UNIT_EX, -0.1f);\n    RowAtom* a = new RowAtom(sptr<Atom>(vra));\n    a->add(sptr<Atom>(new RomanAtom(sptr<Atom>(new CharAtom('h', tp._formula->_textStyle)))));\n    return sptr<Atom>(a);\n}\n\ninline macro(Hstrok) {\n    RowAtom* ra = new RowAtom(sptr<Atom>(new SpaceAtom(UNIT_EX, -0.28f, 0, 0)));\n    ra->add(SymbolAtom::get(\"textendash\"));\n    VRowAtom* vra = new VRowAtom(sptr<Atom>(new LapedAtom(sptr<Atom>(ra), 'r')));\n    vra->setRaise(UNIT_EX, 0.55f);\n    RowAtom* a = new RowAtom(sptr<Atom>(vra));\n    a->add(sptr<Atom>(new RomanAtom(sptr<Atom>(new CharAtom('H', tp._formula->_textStyle)))));\n    return sptr<Atom>(a);\n}\n\ninline macro(dstrok) {\n    RowAtom* ra = new RowAtom(sptr<Atom>(new SpaceAtom(UNIT_EX, 0.25f, 0, 0)));\n    ra->add(SymbolAtom::get(\"bar\"));\n    VRowAtom* vra = new VRowAtom(sptr<Atom>(new LapedAtom(sptr<Atom>(ra), 'r')));\n    vra->setRaise(UNIT_EX, -0.1f);\n    RowAtom* a = new RowAtom(sptr<Atom>(vra));\n    a->add(sptr<Atom>(new RomanAtom(sptr<Atom>(new CharAtom('d', tp._formula->_textStyle)))));\n    return sptr<Atom>(a);\n}\n\ninline macro(Dstrok) {\n    RowAtom* ra = new RowAtom(sptr<Atom>(new SpaceAtom(UNIT_EX, -0.1f, 0, 0)));\n    ra->add(SymbolAtom::get(\"bar\"));\n    VRowAtom* vra = new VRowAtom(sptr<Atom>(new LapedAtom(sptr<Atom>(ra), 'r')));\n    vra->setRaise(UNIT_EX, -0.55f);\n    RowAtom* a = new RowAtom(sptr<Atom>(vra));\n    a->add(sptr<Atom>(new RomanAtom(sptr<Atom>(new CharAtom('D', tp._formula->_textStyle)))));\n    return sptr<Atom>(a);\n}\n\ninline macro(kern) {\n    pair<int, float> info = SpaceAtom::getLength(args[1]);\n\n    return sptr<Atom>(new SpaceAtom(info.first, info.second, 0, 0));\n}\n\ninline macro(char) {\n    string x;\n    wide2utf8(args[1].c_str(), x);\n    int radix = 10;\n    if (startswith(x, \"0x\") || startswith(x, \"0X\")) {\n        x = x.substr(2);\n        radix = 16;\n    } else if (startswith(x, \"x\") || startswith(x, \"X\")) {\n        x = x.substr(1);\n        radix = 16;\n    } else if (startswith(x, \"0\")) {\n        x = x.substr(1);\n        radix = 8;\n    }\n    int n = 0;\n    str2int(x, n, radix);\n    return tp.convertCharacter((wchar_t)n, true);\n}\n\ninline macro(T) {\n    return sptr<Atom>(new RotateAtom(TeXFormula(tp, args[1])._root, 180, L\"origin=cc\"));\n}\n\ninline macro(textcircled) {\n    return sptr<Atom>(new TextCircledAtom(\n        sptr<Atom>(new RomanAtom(TeXFormula(tp, args[1])._root))));\n}\n\ninline macro(textsc) {\n    return sptr<Atom>(new SmallCpaAtom(TeXFormula(tp, args[1], false)._root));\n}\n\ninline macro(sc) {\n    return sptr<Atom>(new SmallCpaAtom(\n        TeXFormula(tp, tp.getOverArgument(), \"\", false, tp.isIgnoreWhiteSpace())._root));\n}\n\ninline macro(quad) {\n    return sptr<Atom>(new SpaceAtom(UNIT_EM, 1, 0, 0));\n}\n\ninline macro(surd) {\n    return sptr<Atom>(new VCenteredAtom(SymbolAtom::get(\"surdsign\")));\n}\n\ninline macro(int) {\n    SymbolAtom* integral = new SymbolAtom(*(SymbolAtom::get(\"int\")));\n    integral->_typelimits = SCRIPT_NOLIMITS;\n    return sptr<Atom>(integral);\n}\n\ninline macro(oint) {\n    SymbolAtom* integral = new SymbolAtom(*(SymbolAtom::get(\"oint\")));\n    integral->_typelimits = SCRIPT_NOLIMITS;\n    return sptr<Atom>(integral);\n}\n\ninline macro(iint) {\n    SymbolAtom* integral = new SymbolAtom(*(SymbolAtom::get(\"int\")));\n    integral->_typelimits = SCRIPT_NOLIMITS;\n    sptr<Atom> i(integral);\n    RowAtom* ra = new RowAtom(i);\n    ra->add(sptr<Atom>(new SpaceAtom(UNIT_MU, -8.f, 0, 0)));\n    ra->add(i);\n    ra->_lookAtLastAtom = true;\n    return sptr<Atom>(new TypedAtom(TYPE_BIG_OPERATOR, TYPE_BIG_OPERATOR, sptr<Atom>(ra)));\n}\n\ninline macro(iiint) {\n    SymbolAtom* integral = new SymbolAtom(*(SymbolAtom::get(\"int\")));\n    integral->_typelimits = SCRIPT_NOLIMITS;\n    sptr<Atom> i(integral);\n    RowAtom* ra = new RowAtom(i);\n    ra->add(sptr<Atom>(new SpaceAtom(UNIT_MU, -8.f, 0, 0)));\n    ra->add(i);\n    ra->add(sptr<Atom>(new SpaceAtom(UNIT_MU, -8.f, 0, 0)));\n    ra->add(i);\n    ra->_lookAtLastAtom = true;\n    return sptr<Atom>(new TypedAtom(TYPE_BIG_OPERATOR, TYPE_BIG_OPERATOR, sptr<Atom>(ra)));\n}\n\ninline macro(iiiint) {\n    SymbolAtom* integral = new SymbolAtom(*(SymbolAtom::get(\"int\")));\n    integral->_typelimits = SCRIPT_NOLIMITS;\n    sptr<Atom> i(integral);\n    RowAtom* ra = new RowAtom(i);\n    ra->add(sptr<Atom>(new SpaceAtom(UNIT_MU, -8.f, 0, 0)));\n    ra->add(i);\n    ra->add(sptr<Atom>(new SpaceAtom(UNIT_MU, -8.f, 0, 0)));\n    ra->add(i);\n    ra->add(sptr<Atom>(new SpaceAtom(UNIT_MU, -8.f, 0, 0)));\n    ra->add(i);\n    ra->_lookAtLastAtom = true;\n    return sptr<Atom>(new TypedAtom(TYPE_BIG_OPERATOR, TYPE_BIG_OPERATOR, sptr<Atom>(ra)));\n}\n\ninline macro(idotsint) {\n    SymbolAtom* integral = new SymbolAtom(*(SymbolAtom::get(\"int\")));\n    integral->_typelimits = SCRIPT_NOLIMITS;\n    sptr<Atom> i(integral);\n    RowAtom* ra = new RowAtom(i);\n    ra->add(sptr<Atom>(new SpaceAtom(UNIT_MU, -1.f, 0, 0)));\n    auto cdotp = SymbolAtom::get(\"cdotp\");\n    RowAtom* cdots = new RowAtom(cdotp);\n    cdots->add(cdotp);\n    cdots->add(cdotp);\n    ra->add(sptr<Atom>(new TypedAtom(TYPE_INNER, TYPE_INNER, sptr<Atom>(cdots))));\n    ra->add(sptr<Atom>(new SpaceAtom(UNIT_MU, -1.f, 0, 0)));\n    ra->add(i);\n    ra->_lookAtLastAtom = true;\n    return sptr<Atom>(new TypedAtom(TYPE_BIG_OPERATOR, TYPE_BIG_OPERATOR, sptr<Atom>(ra)));\n}\n\ninline macro(lmoustache) {\n    SymbolAtom* s = new SymbolAtom(*(SymbolAtom::get(\"lmoustache\")));\n    sptr<Atom> b(new BigDelimiterAtom(sptr<SymbolAtom>(s), 1));\n    b->_type = TYPE_OPENING;\n    return b;\n}\n\ninline macro(rmoustache) {\n    SymbolAtom* s = new SymbolAtom(*(SymbolAtom::get(\"rmoustache\")));\n    sptr<Atom> b(new BigDelimiterAtom(sptr<SymbolAtom>(s), 1));\n    b->_type = TYPE_CLOSING;\n    return b;\n}\n\ninline macro(insertBreakMark) {\n    return sptr<Atom>(new BreakMarkAtom());\n}\n\n/**************************************** limits macros *******************************************/\n\ninline sptr<Atom> _macro_typelimits(_out_ TeXParser& tp, _out_ vector<wstring>& args, int type) {\n    auto atom = tp.popLastAtom();\n    auto copy = atom->clone();\n    copy->_typelimits = type;\n    return copy;\n}\n\ninline macro(nolimits) {\n    return _macro_typelimits(tp, args, SCRIPT_NOLIMITS);\n}\n\ninline macro(limits) {\n    return _macro_typelimits(tp, args, SCRIPT_LIMITS);\n}\n\ninline macro(normal) {\n    return _macro_typelimits(tp, args, SCRIPT_NORMAL);\n}\n\n/***************************************** implement at .cpp **************************************/\n\nmacro(hvspace);\n\nmacro(rule);\n\nmacro(cfrac);\n\nmacro(sfrac);\n\nmacro(genfrac);\n\nmacro(overwithdelims);\n\nmacro(atopwithdelims);\n\nmacro(abovewithdelims);\n\nmacro(textstyles);\n\nmacro(accentbiss);\n\nmacro(left);\n\nmacro(intertext);\n\nmacro(newcommand);\n\nmacro(renewcommand);\n\nmacro(raisebox);\n\nmacro(definecolor);\n\nmacro(sizes);\n\nmacro(romannumeral);\n\nmacro(muskips);\n\nmacro(xml);\n\n/**************************************** not implemented *****************************************/\n\ninline macro(includegraphics) {\n    return nullptr;\n}\n\ninline macro(fcscore) {\n    return nullptr;\n}\n\ninline macro(GeoGebra) {\n    return nullptr;\n}\n\ninline macro(dynamic) {\n    return nullptr;\n}\n\n}  // namespace tex\n\n#endif  // MACRO_IMPL_H_INCLUDED\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/core/parser.cpp",
    "content": "#include \"core/parser.h\"\n#include \"atom/atom.h\"\n#include \"atom/atom_basic.h\"\n#include \"common.h\"\n#include \"core/formula.h\"\n#include \"core/macro.h\"\n#include \"fonts/alphabet.h\"\n#include \"fonts/fonts.h\"\n#include \"graphic/graphic.h\"\n\nusing namespace std;\nusing namespace tex;\n\nconst wchar_t TeXParser::ESCAPE = '\\\\';\nconst wchar_t TeXParser::L_GROUP = '{';\nconst wchar_t TeXParser::R_GROUP = '}';\nconst wchar_t TeXParser::L_BRACK = '[';\nconst wchar_t TeXParser::R_BRACK = ']';\nconst wchar_t TeXParser::DOLLAR = '$';\nconst wchar_t TeXParser::DQUOTE = '\\\"';\nconst wchar_t TeXParser::PERCENT = '%';\nconst wchar_t TeXParser::SUB_SCRIPT = '_';\nconst wchar_t TeXParser::SUPER_SCRIPT = '^';\nconst wchar_t TeXParser::PRIME = '\\'';\nconst wchar_t TeXParser::PRIME_UTF = 0x2019;\nconst wchar_t TeXParser::BACKPRIME = 0x2035;\nconst wchar_t TeXParser::DEGRE = 0x00B0;\n\nconst map<wchar_t, char> TeXParser::SUP_SCRIPT_MAP = {\n    {0x2070, '0'},\n    {0x00B9, '1'},\n    {0x00B2, '2'},\n    {0x00B3, '3'},\n    {0x2074, '4'},\n    {0x2075, '5'},\n    {0x2076, '6'},\n    {0x2077, '7'},\n    {0x2078, '8'},\n    {0x2079, '9'},\n    {0x207A, '+'},\n    {0x207B, '-'},\n    {0x207C, '='},\n    {0x207D, '('},\n    {0x207E, ')'},\n    {0x207F, 'n'}};\nconst map<wchar_t, char> TeXParser::SUB_SCRIPT_MAP = {\n    {0x2080, '0'},\n    {0x2081, '1'},\n    {0x2082, '2'},\n    {0x2083, '3'},\n    {0x2084, '4'},\n    {0x2085, '5'},\n    {0x2086, '6'},\n    {0x2087, '7'},\n    {0x2088, '8'},\n    {0x2089, '9'},\n    {0x208A, '+'},\n    {0x208B, '-'},\n    {0x208C, '='},\n    {0x208D, '('},\n    {0x208E, ')'},\n};\n\nconst set<wstring> TeXParser::_unparsedContents = {\n    L\"dynamic\",\n    L\"Text\",\n    L\"Textit\",\n    L\"Textbf\",\n    L\"Textitbf\",\n    L\"externalFont\"};\n\nbool TeXParser::_isLoading = false;\n\nvoid TeXParser::init(\n    bool ispartial,\n    const wstring& parsestring,\n    _out_ TeXFormula* formula, bool fp) throw(ex_parse) {\n    _pos = _spos = _len = 0;\n    _line = _col = 0;\n    _group = 0;\n    _atIsLetter = 0;\n    _insertion = _arrayMode = _ignoreWhiteSpace = false;\n    _isPartial = _hideUnknownChar = true;\n\n    _formula = formula;\n    _ignoreWhiteSpace = true;\n    _isPartial = ispartial;\n    if (!parsestring.empty()) {\n        _parseString = parsestring;\n        _len = parsestring.length();\n        _pos = 0;\n        if (fp) firstpass();\n    } else {\n        _parseString = L\"\";\n        _pos = 0;\n        _len = 0;\n    }\n    _arrayMode = formula->isArrayMode();\n}\n\nvoid TeXParser::reset(const wstring& latex) {\n    _parseString = latex;\n    _len = latex.length();\n    _formula->_root = nullptr;\n    _pos = 0;\n    _spos = 0;\n    _line = 0;\n    _col = 0;\n    _group = 0;\n    _insertion = false;\n    _atIsLetter = 0;\n    _arrayMode = false;\n    _ignoreWhiteSpace = true;\n    firstpass();\n}\n\nsptr<Atom> TeXParser::popLastAtom() {\n    auto a = _formula->_root;\n    RowAtom* ra = dynamic_cast<RowAtom*>(a.get());\n    if (ra != nullptr) return ra->popLastAtom();\n    _formula->_root = nullptr;\n    return a;\n}\n\nsptr<Atom> TeXParser::getFormulaAtom() {\n    auto a = _formula->_root;\n    _formula->_root = nullptr;\n    return a;\n}\n\nvoid TeXParser::addAtom(const sptr<Atom>& atom) {\n    _formula->add(atom);\n}\n\nvoid TeXParser::addRow() throw(ex_parse) {\n    if (!_arrayMode) throw ex_parse(\"Can not add row in none-array mode!\");\n\n    if(_formula == nullptr) throw ex_parse(\"_formula is null!\");\n    ArrayOfAtoms* arr = dynamic_cast<ArrayOfAtoms*>(_formula);\n    if(arr == nullptr) throw ex_parse(\"dynamic_cast<ArrayOfAtoms*>(_formula) is null!\");\n    arr->addRow();\n}\n\nwstring TeXParser::getDollarGroup(wchar_t openclose) throw(ex_parse) {\n    int spos = _pos;\n    wchar_t ch;\n\n    do {\n        ch = _parseString[_pos++];\n        if (ch == ESCAPE) _pos++;\n    } while (_pos < _len && ch != openclose);\n\n    if (ch == openclose) return _parseString.substr(spos, _pos - spos - 1);\n    return _parseString.substr(spos, _pos - spos);\n}\n\nwstring TeXParser::getGroup(wchar_t open, wchar_t close) throw(ex_parse) {\n    if (_pos == _len) return L\"\";\n\n    int group, spos;\n    wchar_t ch = _parseString[_pos];\n\n    if (_pos < _len && ch == open) {\n        group = 1;\n        spos = _pos;\n        while (_pos < _len - 1 && group != 0) {\n            _pos++;\n            ch = _parseString[_pos];\n            if (ch == open)\n                group++;\n            else if (ch == close)\n                group--;\n            else if (ch == ESCAPE && _pos != _len - 1)\n                _pos++;\n        }\n\n        _pos++;\n\n        if (group != 0) return _parseString.substr(spos + 1, _pos - spos - 1);\n        return _parseString.substr(spos + 1, _pos - spos - 2);\n    }\n    throw ex_parse(\"Missing '\" + tostring((char)open) + \"'!\");\n}\n\nwstring TeXParser::getGroup(const wstring& open, const wstring& close) throw(ex_parse) {\n    int group = 1;\n    int ol = open.length();\n    int cl = close.length();\n    bool lastO = isValidCharacterInCommand(open[ol - 1]);\n    bool lastC = isValidCharacterInCommand(close[cl - 1]);\n    int oc = 0;\n    int cc = 0;\n    int startC = 0;\n    wchar_t prev = L'\\0';\n    wstring buf;\n\n    while (_pos < _len && group != 0) {\n        wchar_t c = _parseString[_pos];\n        wchar_t c1;\n\n        if (prev != ESCAPE && c == ' ') {\n            while (_pos < _len && _parseString[_pos++] == ' ') buf.append(1, L' ');\n            c = _parseString[--_pos];\n            if (isValidCharacterInCommand(prev) && isValidCharacterInCommand(c)) {\n                oc = cc = 0;\n            }\n        }\n\n        if (c == open[oc])\n            oc++;\n        else\n            oc = 0;\n\n        if (c == close[cc]) {\n            if (cc == 0) startC = _pos;\n            cc++;\n        } else {\n            cc = 0;\n        }\n\n        if (_pos + 1 < _len) {\n            c1 = _parseString[_pos + 1];\n\n            if (oc == ol) {\n                if (!lastO || !isValidCharacterInCommand(c1)) group++;\n                oc = 0;\n            }\n\n            if (cc == cl) {\n                if (!lastC || !isValidCharacterInCommand(c1)) group--;\n                cc = 0;\n            }\n        } else {\n            if (oc == ol) {\n                group++;\n                oc = 0;\n            }\n            if (cc == cl) {\n                group--;\n                cc = 0;\n            }\n        }\n\n        prev = c;\n        buf.append(1, c);\n        _pos++;\n    }\n\n    if (group != 0) {\n        if (_isPartial) return buf;\n        throw ex_parse(\"Parse string not closed correctly!\");\n    }\n\n    return buf.substr(0, buf.length() - _pos + startC);\n}\n\nwstring TeXParser::getOverArgument() throw(ex_parse) {\n    if (_pos == _len) return L\"\";\n\n    int ogroup = 1, spos;\n    wchar_t ch = L'\\0';\n\n    spos = _pos;\n    while (_pos < _len && ogroup != 0) {\n        ch = _parseString[_pos];\n        switch (ch) {\n        case L_GROUP:\n            ogroup++;\n            break;\n        case '&':\n            // if a & is encountered at the same level as \\over we must break the argument\n            if (ogroup == 1) ogroup--;\n            break;\n        case R_GROUP:\n            ogroup--;\n            break;\n        case ESCAPE:\n            _pos++;\n            // if a \\\\ or \\cr is encountered at the same level as \\over\n            // we must break the argument\n            if (_pos < _len && _parseString[_pos] == '\\\\' && ogroup == 1) {\n                ogroup--;\n                _pos--;\n            } else if (_pos < _len - 1 &&\n                       _parseString[_pos] == 'c' &&\n                       _parseString[_pos + 1] == 'r' &&\n                       ogroup == 1) {\n                ogroup--;\n                _pos--;\n            }\n            break;\n        }\n        _pos++;\n    }\n\n    // end of string reached, bu not processed properly\n    if (ogroup >= 2) throw ex_parse(\"Illegal end, missing '}'!\");\n\n    wstring str;\n    if (ogroup == 0) {\n        str = _parseString.substr(spos, _pos - spos - 1);\n    } else {\n        str = _parseString.substr(spos, _pos - spos);\n        ch = '\\0';\n    }\n\n    if (ch == '&' || ch == '\\\\' || ch == R_GROUP) _pos--;\n\n    return str;\n}\n\nwstring TeXParser::getCommand() {\n    int spos = ++_pos;\n    wchar_t ch = L'\\0';\n\n    while (_pos < _len) {\n        ch = _parseString[_pos];\n        if ((ch < 'a' || ch > 'z') &&\n            (ch < 'A' || ch > 'Z') &&\n            (_atIsLetter == 0 || ch != '@'))\n            break;\n\n        _pos++;\n    }\n\n    if (ch == L'\\0') return L\"\";\n\n    if (_pos == spos) _pos++;\n\n    wstring com = _parseString.substr(spos, _pos - spos);\n    if (com == L\"cr\" && _pos < _len && _parseString[_pos] == ' ') _pos++;\n\n    return com;\n}\n\nvoid TeXParser::insert(int s, int e, const wstring& formula) {\n    _parseString.replace(s, e - s, formula);\n    _len = _parseString.length();\n    _pos = s;\n    _insertion = true;\n}\n\nwstring TeXParser::getCommandWithArgs(const wstring& command) {\n    if (command == L\"left\") return getGroup(L\"\\\\left\", L\"\\\\right\");\n\n    auto it = MacroInfo::_commands.find(command);\n    if (it == MacroInfo::_commands.end()) return L\"\\\\\" + command;\n\n    MacroInfo* mac = it->second;\n    int mac_opts = mac->_posOpts;\n\n    // return as format: \\cmd[opt][...]{arg}{...}\n\n    vector<wstring> mac_args;\n    getOptsArgs(mac->_nbArgs, mac_opts, mac_args);\n    wstring mac_arg(L\"\\\\\");\n    mac_arg.append(command);\n    for (int j = 0; j < mac->_posOpts; j++) {\n        wstring arg_t = mac_args[mac->_nbArgs + j + 1];\n        if (!arg_t.empty()) {\n            mac_arg.append(L\"[\");\n            mac_arg.append(arg_t);\n            mac_arg.append(L\"]\");\n        }\n    }\n\n    for (int j = 0; j < mac->_nbArgs; j++) {\n        wstring arg_t = mac_args[j + 1];\n        if (!arg_t.empty()) {\n            mac_arg.append(L\"{\");\n            mac_arg.append(arg_t);\n            mac_arg.append(L\"}\");\n        }\n    }\n\n    return mac_arg;\n}\n\nvoid TeXParser::skipWhiteSpace() {\n    wchar_t c;\n    while (_pos < _len) {\n        c = _parseString[_pos];\n        if (c != ' ' && c != '\\t' && c != '\\n' && c != '\\r') break;\n        if (c == '\\n') {\n            _line++;\n            _col = _pos;\n        }\n        _pos++;\n    }\n}\n\nwstring TeXParser::forwardFromCurrentPos() {\n    if (_group == 0) {\n        const wstring& sub = _parseString.substr(_pos);\n        finish();\n        return sub;\n    }\n    int closing = _group;\n    auto i = _parseString.length() - 1;\n    for (; i >= _pos; i--) {\n        auto ch = _parseString[i];\n        if (ch == R_GROUP) {\n            closing--;\n            if (closing == 0) break;\n        }\n    }\n    if (closing != 0) {\n        throw ex_parse(\n            \"Found a closing '\" +\n            tostring((char)R_GROUP) +\n            \"' without an opening '\" + tostring((char)L_GROUP) + \"'!\");\n    }\n    const wstring& sub = _parseString.substr(_pos, i - _pos);\n    _pos = i;\n    return sub;\n}\n\nvoid TeXParser::getOptsArgs(int nbArgs, int opts, _out_ vector<wstring>& args) {\n    /*\n     * A maximum of 10 options can be passed to a command,\n     * the value will be added at the tail of the args if found any\n     */\n    args.resize(nbArgs + 10 + 1 + 1);\n    if (nbArgs != 0) {\n        // we get the options just after the command name\n        if (opts == 1) {\n            int j = nbArgs + 1;\n            try {\n                for (; j < nbArgs + 11; j++) {\n                    skipWhiteSpace();\n                    args[j] = getGroup(L_BRACK, R_BRACK);\n                }\n            } catch (ex_parse& e) {\n                args[j] = L\"\";\n            }\n        }\n\n        // we get the first argument\n        skipWhiteSpace();\n        try {\n            args[1] = getGroup(L_GROUP, R_GROUP);\n        } catch (ex_parse& e) {\n            if (_parseString[_pos] != '\\\\') {\n                args[1] = towstring(_parseString[_pos]);\n                _pos++;\n            } else {\n                args[1] = getCommandWithArgs(getCommand());\n            }\n        }\n\n        // we get the options after the first argument\n        if (opts == 2) {\n            int j = nbArgs + 1;\n            try {\n                for (; j < nbArgs + 11; j++) {\n                    skipWhiteSpace();\n                    args[j] = getGroup(L_BRACK, R_BRACK);\n                }\n            } catch (ex_parse& e) {\n                args[j] = L\"\";\n            }\n        }\n\n        // we get the next arguments\n        for (int i = 2; i <= nbArgs; i++) {\n            skipWhiteSpace();\n            try {\n                args[i] = getGroup(L_GROUP, R_GROUP);\n            } catch (ex_parse& e) {\n                if (_parseString[_pos] != '\\\\') {\n                    args[i] = towstring(_parseString[_pos]);\n                    _pos++;\n                } else {\n                    args[i] = getCommandWithArgs(getCommand());\n                }\n            }\n        }\n\n        if (_ignoreWhiteSpace) skipWhiteSpace();\n    }\n}\n\nbool TeXParser::isValidName(const wstring& com) {\n    if (com.empty()) return false;\n    if (com[0] != '\\\\') return false;\n\n    wchar_t c = L'\\0';\n    int p = 1;\n    int l = com.length();\n    while (p < l) {\n        c = com[p];\n        if (!isalpha(c) && (_atIsLetter == 0 || c != '@'))\n            break;\n        p++;\n    }\n\n    return isalpha(c);\n}\n\nsptr<Atom> TeXParser::processEscape() throw(ex_parse) {\n    _spos = _pos;\n    wstring command = getCommand();\n\n    if (command.length() == 0) return sptr<Atom>(new EmptyAtom());\n\n    string cmd;\n    wide2utf8(command.c_str(), cmd);\n    auto it = MacroInfo::_commands.find(command);\n    if (it != MacroInfo::_commands.end()) return processCommands(command);\n\n    try {\n        return TeXFormula::get(command)->_root;\n    } catch (ex_formula_not_found& e) {\n        try {\n            return SymbolAtom::get(cmd);\n        } catch (ex_symbol_not_found& ex) {}\n    }\n\n    // not a valid command or symbol or predefined TeXFormula found\n    if (!_isPartial)\n        throw ex_parse(\"Unknown symbol or command or predefined TeXFormula: '\" + cmd + \"'\");\n    sptr<Atom> rm(new RomanAtom(TeXFormula(L\"\\\\backslash \" + command)._root));\n    return sptr<Atom>(new ColorAtom(rm, TRANS, RED));\n}\n\nsptr<Atom> TeXParser::processCommands(const wstring& command) throw(ex_parse) {\n    MacroInfo* mac = MacroInfo::_commands[command];\n    int opts = mac->_posOpts;\n\n    vector<wstring> args;\n    getOptsArgs(mac->_nbArgs, opts, args);\n    args[0] = command;\n\n    if (NewCommandMacro::isMacro(command)) {\n        auto ret = mac->invoke(*this, args);\n        insert(_spos, _pos, args.back());\n        return ret;\n    }\n\n    return mac->invoke(*this, args);\n}\n\nsptr<Atom> TeXParser::getScripts(wchar_t f) throw(ex_parse) {\n    _pos++;\n    // get the first script\n    sptr<Atom> first = getArgument();\n    sptr<Atom> second(nullptr);\n    wchar_t s = '\\0';\n\n    if (_pos < _len) s = _parseString[_pos];\n\n    /*\n     * 4 conditions\n     *\n     * \\cmd_{\\sub}^{\\super}\n     *\n     * \\cmd_{\\sub}\n     *\n     * \\cmd^{\\super}_{\\sub}\n     *\n     * \\cmd^{\\super}\n     */\n    if (f == SUPER_SCRIPT && s == SUPER_SCRIPT) {\n        second = first;\n        first = nullptr;\n    } else if (f == SUB_SCRIPT && s == SUPER_SCRIPT) {\n        _pos++;\n        second = getArgument();\n    } else if (f == SUPER_SCRIPT && s == SUB_SCRIPT) {\n        _pos++;\n        second = first;\n        first = getArgument();\n    } else if (f == SUPER_SCRIPT && s != SUB_SCRIPT) {\n        second = first;\n        first = nullptr;\n    }\n\n    sptr<Atom> atom;\n    RowAtom* rm = nullptr;\n    if (_formula->_root == nullptr) {\n        /*\n         * If there's no root exists, passing a null atom to ScriptsAtom as base is OK,\n         * the ScriptsAtom will handle it\n         */\n        return sptr<Atom>(new ScriptsAtom(nullptr, first, second));\n    } else if (rm = dynamic_cast<RowAtom*>(_formula->_root.get())) {\n        atom = rm->popLastAtom();\n    } else {\n        atom = _formula->_root;\n        _formula->_root = nullptr;\n    }\n\n    // Check if previous atom is CumulativeScriptsAtom\n    CumulativeScriptsAtom* ca = dynamic_cast<CumulativeScriptsAtom*>(atom.get());\n    if (ca != nullptr) {\n        ca->addSubscript(first);\n        ca->addSuperscript(second);\n        return atom;\n    }\n\n    if (atom->getRightType() == TYPE_BIG_OPERATOR)\n        return sptr<Atom>(new BigOperatorAtom(atom, first, second));\n\n    OverUnderDelimiter* del = dynamic_cast<OverUnderDelimiter*>(atom.get());\n    if (del != nullptr) {\n        if (del->isOver()) {\n            if (second != nullptr) {\n                del->addScript(second);\n                return sptr<Atom>(new ScriptsAtom(atom, first, nullptr));\n            }\n        } else if (first != nullptr) {\n            del->addScript(first);\n            return sptr<Atom>(new ScriptsAtom(atom, nullptr, second));\n        }\n    }\n\n    return sptr<Atom>(new ScriptsAtom(atom, first, second));\n}\n\nsptr<Atom> TeXParser::getArgument() throw(ex_parse) {\n    skipWhiteSpace();\n    wchar_t ch;\n    if (_pos < _len)\n        ch = _parseString[_pos];\n    else\n        return sptr<Atom>(new EmptyAtom());\n\n    if (ch == L_GROUP) {\n        TeXFormula tf;\n        TeXFormula* tmp = _formula;\n        _formula = &tf;\n        _pos++;\n        _group++;\n        try{\n            parse();\n        }catch(ex_parse& e) {\n            _formula = tmp;\n            throw ex_parse(\"parse() failed:\");\n        }\n        _formula = tmp;\n        if (_formula->_root == nullptr) {\n            RowAtom* rm = new RowAtom();\n            rm->add(tf._root);\n            return sptr<Atom>(rm);\n        }\n        return tf._root;\n    }\n\n    if (ch == ESCAPE) {\n        auto atom = processEscape();\n        if (_insertion) {\n            _insertion = false;\n            return getArgument();\n        }\n        return atom;\n    }\n\n    auto atom = convertCharacter(ch, true);\n    _pos++;\n    return atom;\n}\n\npair<int, float> TeXParser::getLength() throw(ex_parse) {\n    if (_pos == _len) return make_pair(-1.f, -1.f);\n\n    int spos;\n    wchar_t ch = L'\\0';\n\n    skipWhiteSpace();\n    spos = _pos;\n    while (_pos < _len && ch != ' ') {\n        ch = _parseString[_pos++];\n    }\n    skipWhiteSpace();\n\n    return SpaceAtom::getLength(_parseString.substr(spos, _pos - spos - 1));\n}\n\nbool TeXParser::replaceScript() {\n    wchar_t ch = _parseString[_pos];\n    auto it = SUP_SCRIPT_MAP.find(ch);\n    if (it != SUP_SCRIPT_MAP.end()) {\n        wstring sup = wstring(L\"\\\\mathcumsup{\").append(1, (wchar_t)(it->second)).append(L\"}\");\n        _parseString.replace(_pos, 1, sup);\n        _len = _parseString.length();\n        _pos += sup.size();\n        return true;\n    }\n    it = SUB_SCRIPT_MAP.find(ch);\n    if (it != SUB_SCRIPT_MAP.end()) {\n        wstring sub = wstring(L\"\\\\mathcumsub{\").append(1, (wchar_t)(it->second)).append(L\"}\");\n        _parseString.replace(_pos, 1, sub);\n        _len = _parseString.length();\n        _pos += sub.size();\n        return true;\n    }\n    return false;\n}\n\nvoid TeXParser::preprocess(wstring& cmd, vector<wstring>& args, int& pos) throw(ex_parse) {\n    if (cmd == L\"newcommand\" || cmd == L\"renewcommand\") {\n        preprocessNewCmd(cmd, args, pos);\n    } else if (cmd == L\"newenvironment\" || cmd == L\"renewenvironment\") {\n        preprocessNewCmd(cmd, args, pos);\n    } else if (NewCommandMacro::isMacro(cmd)) {\n        inflateNewCmd(cmd, args, pos);\n    } else if (cmd == L\"begin\") {\n        inflateEnv(cmd, args, pos);\n    } else if (cmd == L\"makeatletter\") {\n        _atIsLetter++;\n    } else if (cmd == L\"makeatother\") {\n        _atIsLetter--;\n    } else if (_unparsedContents.find(cmd) != _unparsedContents.end()) {\n        getOptsArgs(1, 0, args);\n    }\n}\n\nvoid TeXParser::preprocessNewCmd(wstring& cmd, vector<wstring>& args, int& pos) throw(ex_parse) {\n    MacroInfo* const mac = MacroInfo::_commands[cmd];\n    getOptsArgs(mac->_nbArgs, mac->_posOpts, args);\n    mac->invoke(*this, args);\n    _parseString.erase(pos, _pos - pos);\n    _len = _parseString.length();\n    _pos = pos;\n}\n\nvoid TeXParser::inflateNewCmd(wstring& cmd, vector<wstring>& args, int& pos) throw(ex_parse) {\n    MacroInfo* const mac = MacroInfo::_commands[cmd];\n    getOptsArgs(mac->_nbArgs, mac->_posOpts, args);\n    args[0] = cmd;\n    try {\n        mac->invoke(*this, args);\n        // The last element is the returned value (after inflated macro)\n        _parseString.replace(pos, _pos - pos, args.back());\n    } catch (ex_parse& e) {\n        if (!_isPartial) throw;\n        pos += cmd.length() + 1;\n    }\n    _len = _parseString.length();\n    _pos = pos;\n}\n\nvoid TeXParser::inflateEnv(wstring& cmd, vector<wstring>& args, int& pos) throw(ex_parse) {\n    getOptsArgs(1, 0, args);\n    wstring env = args[1] + L\"@env\";\n    auto it = MacroInfo::_commands.find(env);\n    if (it == MacroInfo::_commands.end()) {\n        throw ex_parse(\n            \"Unknown environment: \" +\n            wide2utf8(args[1].c_str()) +\n            \" at position \" + tostring(getLine()) + \":\" + tostring(getCol()));\n    }\n    MacroInfo* const mac = it->second;\n    vector<wstring> optargs;\n    getOptsArgs(mac->_nbArgs - 1, 0, optargs);\n    wstring grp = getGroup(L\"\\\\begin{\" + args[1] + L\"}\", L\"\\\\end{\" + args[1] + L\"}\");\n    wstring expr = L\"{\\\\makeatletter \\\\\" + args[1] + L\"@env\";\n    for (int i = 1; i <= mac->_nbArgs - 1; i++) expr += L\"{\" + optargs[i] + L\"}\";\n    expr += L\"{\" + grp + L\"}\\\\makeatother}\";\n    _parseString.replace(pos, _pos - pos, expr);\n    _len = _parseString.length();\n    _pos = pos;\n}\n\nvoid TeXParser::firstpass() throw(ex_parse) {\n    if (_len == 0) return;\n\n    wchar_t ch;\n    int spos;\n    vector<wstring> args;\n    while (_pos < _len) {\n        if (replaceScript()) continue;\n\n        ch = _parseString[_pos];\n        switch (ch) {\n        case ESCAPE: {\n            spos = _pos;\n            wstring cmd = getCommand();\n            try {\n                preprocess(cmd, args, spos);\n            } catch (ex_parse& e) {\n                if (!_isPartial) throw;\n            }\n            args.clear();\n        } break;\n        case PERCENT: {\n            spos = _pos++;\n            wchar_t chr;\n            while (_pos < _len) {\n                chr = _parseString[_pos++];\n                if (chr == '\\r' || chr == '\\n') break;\n            }\n            if (_pos < _len) _pos--;\n            _parseString.replace(spos, _pos - spos, L\"\");\n            _len = _parseString.length();\n            _pos = spos;\n        } break;\n        case DEGRE: {\n            _parseString.replace(_pos, 1, L\"^{\\\\circ}\");\n            _len = _parseString.length();\n            _pos++;\n        } break;\n        default:\n            _pos++;\n            break;\n        }\n    }\n    _pos = 0;\n    _len = _parseString.length();\n}\n\nvoid TeXParser::parse() throw(ex_parse) {\n    if (_len == 0) {\n        if (_formula->_root == nullptr && !_arrayMode)\n            _formula->add(sptr<Atom>(new EmptyAtom()));\n        return;\n    }\n\n    wchar_t ch;\n    while (_pos < _len) {\n        ch = _parseString[_pos];\n\n        switch (ch) {\n        case '\\n':\n            _line++;\n            _col = _pos;\n        case '\\t':\n        case '\\r':\n            _pos++;\n            break;\n        case ' ': {\n            _pos++;\n            if (!_ignoreWhiteSpace) {  // we are in mbox\n                _formula->add(sptr<Atom>(new SpaceAtom()));\n                _formula->add(sptr<Atom>(new BreakMarkAtom()));\n                while (_pos < _len) {\n                    ch = _parseString[_pos];\n                    if (ch != ' ' || ch != '\\t' || ch != '\\r') break;\n                    _pos++;\n                }\n            }\n        } break;\n        case DOLLAR: {\n            _pos++;\n            if (!_ignoreWhiteSpace) {  // we are in mbox\n                int style = STYLE_TEXT;\n                bool doubleDollar = false;\n                if (_parseString[_pos] == DOLLAR) {\n                    style = STYLE_DISPLAY;\n                    doubleDollar = true;\n                    _pos++;\n                }\n\n                _formula->add(sptr<Atom>(new MathAtom(\n                    TeXFormula(*this, getDollarGroup(DOLLAR), false)._root, style)));\n                if (doubleDollar) {\n                    if (_parseString[_pos] == DOLLAR) _pos++;\n                }\n            }\n        } break;\n        case ESCAPE: {\n            sptr<Atom> atom = processEscape();\n            _formula->add(atom);\n            HlineAtom* h = dynamic_cast<HlineAtom*>(atom.get());\n            if (_arrayMode && h != nullptr) {\n                ArrayOfAtoms* arr = dynamic_cast<ArrayOfAtoms*>(_formula);\n                if(arr == nullptr) throw ex_parse(\"dynamic_cast<ArrayOfAtoms*>(_formula) is null!\");\n                arr->addRow();\n\t\t\t}\n            if (_insertion) _insertion = false;\n        } break;\n        case L_GROUP: {\n            auto atom = getArgument();\n            if (atom != nullptr) atom->_type = TYPE_ORDINARY;\n            _formula->add(atom);\n        } break;\n        case R_GROUP: {\n            _group--;\n            _pos++;\n            if (_group == -1) {\n                throw ex_parse(\n                    \"Found a closing '\" +\n                    tostring((char)R_GROUP) +\n                    \"' without an opening '\" + tostring((char)L_GROUP) + \"'!\");\n            }\n            // End of a group\n            return;\n        }\n        case SUPER_SCRIPT: {\n            _formula->add(getScripts(ch));\n        } break;\n        case SUB_SCRIPT: {\n            if (_ignoreWhiteSpace) {\n                _formula->add(getScripts(ch));\n            } else {\n                _formula->add(sptr<Atom>(new UnderScoreAtom()));\n                _pos++;\n            }\n        } break;\n        case '&': {\n            if (!_arrayMode) throw ex_parse(\"Character '&' is only available in array mode!\");\n            if(_formula == nullptr) throw ex_parse(\"_formula is null!\");\n            ArrayOfAtoms* arr = dynamic_cast<ArrayOfAtoms*>(_formula);\n            if(arr == nullptr) throw ex_parse(\"dynamic_cast<ArrayOfAtoms*>(_formula) is null!\");\n            arr->addCol();\n            _pos++;\n        } break;\n        case '~': {\n            _formula->add(sptr<Atom>(new SpaceAtom()));\n            _pos++;\n        } break;\n        case PRIME_UTF:\n        case PRIME: {\n            if (_ignoreWhiteSpace) {\n                _formula->add(sptr<Atom>(new CumulativeScriptsAtom(\n                    popLastAtom(), nullptr, SymbolAtom::get(\"prime\"))));\n            } else {\n                _formula->add(convertCharacter(PRIME, true));\n            }\n            _pos++;\n        } break;\n        case BACKPRIME: {\n            if (_ignoreWhiteSpace) {\n                _formula->add(sptr<Atom>(new CumulativeScriptsAtom(\n                    popLastAtom(), nullptr, SymbolAtom::get(\"backprime\"))));\n            } else {\n                _formula->add(convertCharacter(BACKPRIME, true));\n            }\n            _pos++;\n        } break;\n        case DQUOTE: {\n            if (_ignoreWhiteSpace) {\n                _formula->add(sptr<Atom>(new CumulativeScriptsAtom(\n                    popLastAtom(), nullptr, SymbolAtom::get(\"prime\"))));\n                _formula->add(sptr<Atom>(new CumulativeScriptsAtom(\n                    popLastAtom(), nullptr, SymbolAtom::get(\"prime\"))));\n            } else {\n                _formula->add(convertCharacter(PRIME, true));\n                _formula->add(convertCharacter(PRIME, true));\n            }\n            _pos++;\n        } break;\n        default: {\n            _formula->add(convertCharacter(ch, false));\n            _pos++;\n        } break;\n        }\n    }\n}\n\nsptr<Atom> TeXParser::convertCharacter(wchar_t c, bool oneChar) throw(ex_parse) {\n    if (_ignoreWhiteSpace) {\n        // the unicode Greek Letters in math mode are not drawn with the Greek font\n        if (c >= 945 && c <= 969) {\n            // Greek small letter\n            return SymbolAtom::get(TeXFormula::_symbolMappings[c]);\n        } else if (c >= 913 && c <= 937) {\n            // Greek capital letter\n            wstring ltx;\n            utf82wide(TeXFormula::_symbolFormulaMappings[c].c_str(), ltx);\n            return TeXFormula(ltx)._root;\n        }\n    }\n\n    c = tex::convertToRomanNumber(c);\n\n    /*\n     * None alphanumeric character\n     */\n    if ((c < '0' || c > '9') && (c < 'a' || c > 'z') && (c < 'A' || c > 'Z')) {\n        /*\n         * Find from registered UNICODE-table\n         */\n        const UnicodeBlock& block = UnicodeBlock::of(c);\n#ifdef HAVE_LOG\n        int idx = indexOf(DefaultTeXFont::_loadedAlphabets, block);\n        __log << \"block of char: \" << c << \" is \" << idx << endl;\n#endif  // HAVE_LOG\n        bool exist = (indexOf(DefaultTeXFont::_loadedAlphabets, block) != -1);\n        if (!_isLoading && !exist) {\n            auto it = DefaultTeXFont::_registeredAlphabets.find(block);\n            if (it != DefaultTeXFont::_registeredAlphabets.end())\n                DefaultTeXFont::addAlphabet(DefaultTeXFont::_registeredAlphabets[block]);\n        }\n\n        auto sit = TeXFormula::_symbolMappings.find(c);\n        auto fit = TeXFormula::_symbolFormulaMappings.find(c);\n\n        /*\n         * Character not in the symbol-mapping and not in the formula-mapping, find from\n         * external font-mapping\n         */\n        if (sit == TeXFormula::_symbolMappings.end() &&\n            fit == TeXFormula::_symbolFormulaMappings.end()) {\n            FontInfos* fontInfos = nullptr;\n            bool isLatin = UnicodeBlock::BASIC_LATIN == block;\n            if ((isLatin && TeXFormula::isRegisteredBlock(UnicodeBlock::BASIC_LATIN)) || !isLatin) {\n                fontInfos = TeXFormula::getExternalFont(block);\n            }\n            if (fontInfos != nullptr) {\n                if (oneChar) return sptr<Atom>(new TextRenderingAtom(towstring(c), fontInfos));\n                int start = _pos++;\n                int en = _len - 1;\n                while (_pos < _len) {\n                    c = _parseString[_pos];\n                    if (!block.contains(c)) {\n                        en = --_pos;\n                        break;\n                    }\n                    _pos++;\n                }\n                return sptr<Atom>(new TextRenderingAtom(\n                    _parseString.substr(start, en - start + 1), fontInfos));\n            }\n\n            if (!_isPartial)\n                throw ex_parse(\"Unknown character : '\" + tostring(c) + \"'\");\n            else {\n                if (_hideUnknownChar) return nullptr;\n                sptr<Atom> rm(new RomanAtom(\n                    TeXFormula(L\"\\\\text{(unknown char \" + towstring((int)c) + L\")}\")._root));\n                return sptr<Atom>(new ColorAtom(rm, TRANS, RED));\n            }\n        } else {\n            /*\n             * In text mode (with command \\text{})\n             */\n            if (!_ignoreWhiteSpace) {\n                auto it = TeXFormula::_symbolTextMappings.find(c);\n                if (it != TeXFormula::_symbolTextMappings.end()) {\n                    auto atom = SymbolAtom::get(it->second);\n                    atom->setUnicode(c);\n                    return atom;\n                }\n            }\n            auto it = TeXFormula::_symbolFormulaMappings.find(c);\n            if (it != TeXFormula::_symbolFormulaMappings.end()) {\n                wstring wstr;\n                utf82wide(it->second.c_str(), wstr);\n                return TeXFormula(wstr)._root;\n            }\n\n            if (sit != TeXFormula::_symbolMappings.end()) {\n                string symbolName = sit->second;\n                try {\n                    return SymbolAtom::get(symbolName);\n                } catch (ex_symbol_not_found& e) {\n                    throw ex_parse(\n                        \"The character '\" + tostring(c) +\n                            \"' was mapped to an unknown symbol with the name '\" + symbolName + \"'!\",\n                        e);\n                }\n            }\n        }\n    } else {\n        /*\n         * Alphanumeric character\n         */\n        FontInfos* infos = nullptr;\n        auto it = TeXFormula::_externalFontMap.find(UnicodeBlock::BASIC_LATIN);\n        if (it != TeXFormula::_externalFontMap.end()) {\n            infos = it->second;\n            if (oneChar) return sptr<Atom>(new TextRenderingAtom(towstring(c), infos));\n\n            int start = _pos++;\n            int en = _len - 1;\n            while (_pos < _len) {\n                c = _parseString[_pos];\n                if ((c < '0' || c > '9') && (c < 'a' || c > 'z') && (c < 'A' || c > 'Z')) {\n                    en = --_pos;\n                    break;\n                }\n                _pos++;\n            }\n            return sptr<Atom>(\n                new TextRenderingAtom(_parseString.substr(start, en - start + 1), infos));\n        }\n    }\n    return sptr<Atom>(new CharAtom(c, _formula->_textStyle, _ignoreWhiteSpace));\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/core/parser.h",
    "content": "#ifndef PARSER_H_INCLUDED\n#define PARSER_H_INCLUDED\n\n#include \"atom/atom.h\"\n#include \"common.h\"\n\n#include <set>\n#include <string>\n\nusing namespace std;\n\nnamespace tex {\n\n/**\n * Convert a character to roman-number if it is a digit localized\n * @param c character to be converted\n */\nwchar_t convertToRomanNumber(wchar_t c);\n\nclass TeXFormula;\n\n/**\n * This class implements a parser for latex formulas\n */\nclass TeXParser {\nprivate:\n    wstring _parseString;\n    int _pos, _spos, _len;\n    int _line, _col;\n    int _group;\n    int _atIsLetter;\n    bool _insertion;\n    bool _arrayMode;\n    bool _ignoreWhiteSpace;\n    bool _isPartial;\n    bool _hideUnknownChar;\n\n    /**\n     * escape character\n     */\n    static const wchar_t ESCAPE;\n    /**\n     * grouping characters (for parsing)\n     */\n    static const wchar_t L_GROUP;\n    static const wchar_t R_GROUP;\n    static const wchar_t L_BRACK;\n    static const wchar_t R_BRACK;\n    static const wchar_t DOLLAR;\n    static const wchar_t DQUOTE;\n    /**\n     * percent char for comments\n     */\n    static const wchar_t PERCENT;\n    /**\n     * script character (for parsing)\n     */\n    static const wchar_t SUB_SCRIPT;\n    static const wchar_t SUPER_SCRIPT;\n    static const wchar_t PRIME;\n    static const wchar_t PRIME_UTF;\n    static const wchar_t BACKPRIME;\n    static const wchar_t DEGRE;\n    /**\n     * scripts to formula map\n     */\n    static const map<wchar_t, char> SUP_SCRIPT_MAP;\n    static const map<wchar_t, char> SUB_SCRIPT_MAP;\n\n    static const set<wstring> _unparsedContents;\n\n    /**\n     * Preprocess parse string\n     */\n    void firstpass() throw(ex_parse);\n\n    sptr<Atom> getScripts(wchar_t f) throw(ex_parse);\n\n    wstring getCommand();\n\n    sptr<Atom> processEscape() throw(ex_parse);\n\n    void insert(int beg, int end, const wstring& formula);\n\n    /**\n     * Return a string with command, options and arguments.\n     *\n     * @param command\n     *      name of command\n     * @return command with arguments string with format: \\cmd[opt][...]{arg}{...}\n     */\n    wstring getCommandWithArgs(const wstring& command);\n\n    /**\n     * Process the given TeX command (by parsing following command\n     * arguments in the parse string).\n     */\n    sptr<Atom> processCommands(const wstring& cmd) throw(ex_parse);\n\n    void skipWhiteSpace();\n\n    /**\n     * Replace the script-characters with command.\n     */\n    bool replaceScript();\n\n    void preprocess(wstring& cmd, vector<wstring>& args, int& pos) throw(ex_parse);\n\n    void preprocessNewCmd(wstring& cmd, vector<wstring>& args, int& pos) throw(ex_parse);\n\n    void inflateNewCmd(wstring& cmd, vector<wstring>& args, int& pos) throw(ex_parse);\n\n    void inflateEnv(wstring& cmd, vector<wstring>& args, int& pos) throw(ex_parse);\n\n    void init(\n        bool ispartial,\n        const wstring& parsestring,\n        _out_ TeXFormula* formula,\n        bool firstpass) throw(ex_parse);\n\npublic:\n    static bool _isLoading;\n\n    TeXFormula* _formula;\n\n    TeXParser() {\n        init(true, L\"\", nullptr, false);\n    }\n\n    /**\n     * Create a new TeXParser\n     * @param latex\n     *      the string to be parsed\n     * @param formula\n     *      the formula where to put the atoms\n     * @throw ex_parse\n     *      if the string could not be parsed correctly\n     */\n    TeXParser(const wstring& latex, _out_ TeXFormula* formula) throw(ex_parse) {\n        init(true, latex, formula, true);\n    }\n\n    /**\n     * Create a new TeXParser\n     * @param isPartial\n     *      if true certain exceptions are not thrown\n     * @param latex\n     *      the string to be parsed\n     * @param formula\n     *      the formula where to put the atoms\n     * @throw ex_parse\n     *      if the string could not be parsed correctly\n     */\n    TeXParser(bool isPartial, const wstring& latex, _out_ TeXFormula* formula) throw(ex_parse) {\n        init(isPartial, latex, formula, true);\n    }\n\n    /**\n     * Create a new TeXParser with or without a first pass\n     * @param isPartial\n     *      if true certain exceptions are not thrown\n     * @param latex\n     *      the string to be parsed\n     * @param formula\n     *      the formula where to put the atoms\n     * @param firstPass\n     *      a boolean to indicate if the parser must replace the user-defined macros by their content\n     * @throw ex_parse\n     *      if the string could not be parsed correctly\n     */\n    TeXParser(\n        bool isPartial,\n        const wstring& latex,\n        _out_ TeXFormula* formula,\n        bool firstPass) throw(ex_parse) {\n        init(isPartial, latex, formula, firstPass);\n    }\n\n    /**\n     * Create a new TeXParser with or without a first pass\n     * @param latex\n     *      the string to be parsed\n     * @param formula\n     *      the formula where to put the atoms\n     * @param firstPass\n     *      a boolean to indicate if the parser must replace the user-defined macros by their content\n     * @throw ex_parse\n     *      if the string could not be parsed correctly\n     */\n    TeXParser(const wstring& latex, _out_ TeXFormula* formula, bool firstPass) throw(ex_parse) {\n        init(true, latex, formula, firstPass);\n    }\n\n    /**\n     * Create a new TeXParser which ignores or not the white spaces, it's useful\n     * for mbox command\n     *\n     * @param isPartial\n     *      if true certains exceptions are not thrown\n     * @param latex\n     *      the string to be parsed\n     * @param formula\n     *      the formula to hold the atoms\n     * @param firstpass\n     *      a boolean to indicate if the parser must replace the\n     *      user-defined macros by their content\n     * @param space\n     *      a boolean to indicate if the parser must ignore or not the\n     *      white space\n     * @throw ex_parse\n     *      if the string could not be parsed correctly\n     */\n    TeXParser(\n        bool isPartial,\n        const wstring& latex,\n        _out_ TeXFormula* formula,\n        bool firstpass,\n        bool ignoreWhiteSpace) throw(ex_parse) {\n        init(isPartial, latex, formula, firstpass);\n        _ignoreWhiteSpace = ignoreWhiteSpace;\n    }\n\n    /**\n     * Create a new TeXParser which ignores or not the white spaces, it's useful\n     * for mbox command\n     *\n     * @param latex\n     *      the string to be parsed\n     * @param formula\n     *      the formula to hold the atoms\n     * @param firstpass\n     *      a boolean to indicate if the parser must replace the\n     *      user-defined macros by their content\n     * @param space\n     *      a boolean to indicate if the parser must ignore or not the\n     *      white space\n     * @throw ex_parse\n     *      if the string could not be parsed correctly\n     */\n    TeXParser(\n        const wstring& latex,\n        _out_ TeXFormula* formula,\n        bool firstpass,\n        bool ignoreWhiteSpace) throw(ex_parse) {\n        init(true, latex, formula, firstpass);\n        _ignoreWhiteSpace = ignoreWhiteSpace;\n    }\n\n    /**\n     * Reset the parser with a new latex expression\n     */\n    void reset(const wstring& latex);\n\n    /**\n     * Return true if we get a partial formula\n     */\n    inline bool getIsPartial() const {\n        return _isPartial;\n    }\n\n    /**\n     * Get the number of the current line\n     */\n    inline int getLine() const {\n        return _line;\n    }\n\n    /**\n     * Get the number of the current column\n     */\n    inline int getCol() const {\n        return _pos - _col - 1;\n    }\n\n    /**\n     * Get and remove the last atom of the current formula\n     */\n    sptr<Atom> popLastAtom();\n\n    /**\n     * Get and remove the atom represented by the current formula\n     */\n    sptr<Atom> getFormulaAtom();\n\n    /**\n     * Put an atom in the current formula\n     */\n    void addAtom(const sptr<Atom>& atom);\n\n    /**\n     * Indicate if the character @ can be used in the command's name\n     */\n    inline void makeAtLetter() {\n        _atIsLetter++;\n    }\n\n    /**\n     * Indicate if the character @ can be used in the command's name\n     */\n    inline void makeAtOther() {\n        _atIsLetter--;\n    }\n\n    /**\n     * Test if the character @ is considered as a letter or not\n     */\n    inline bool isAtLetter() {\n        return (_atIsLetter != 0);\n    }\n\n    /**\n     * Test if the parser is used to parse an array or not\n     */\n    inline bool isArrayMode() const {\n        return _arrayMode;\n    }\n\n    inline void setArrayMode(bool arrayMode) {\n        _arrayMode = arrayMode;\n    }\n\n    /**\n     * Test if the parser must ignore white spaces\n     */\n    inline bool isIgnoreWhiteSpace() const {\n        return _ignoreWhiteSpace;\n    }\n\n    /**\n     * Test if the parser is in math mode\n     */\n    inline bool isMathMode() const {\n        return _ignoreWhiteSpace;\n    }\n\n    /**\n     * Return the current position in the parsed string\n     */\n    inline int getPos() const {\n        return _pos;\n    }\n\n    /**\n     * Rewind the current parsed string\n     *\n     * @param n\n     *      the number of character to be rewinded\n     * @return the new position in the parsed string\n     */\n    inline int rewind(int n) {\n        _pos -= n;\n        return _pos;\n    }\n\n    inline void finish() {\n        _pos = _parseString.size();\n    }\n\n    wstring forwardFromCurrentPos();\n\n    /**\n     * Add a new row when the parser is in array mode\n     *\n     * @throw ex_parse\n     *      if the parser is not in array mode\n     */\n    void addRow() throw(ex_parse);\n\n    /**\n     * Parse the input string\n     * \n     * @throw ex_parse\n     *      if an error is encountered during parse\n     */\n    void parse() throw(ex_parse);\n\n    /**\n     * Get the contents between two delimiters\n     *\n     * @param openClose\n     *      the opening and closing character (such as $)\n     * @return the enclosed contents\n     * @throw ex_parse\n     *      if the contents are badly enclosed\n     */\n    wstring getDollarGroup(wchar_t openClose) throw(ex_parse);\n\n    /**\n     * Get the contents between two delimiters\n     *\n     * @param open\n     *      the opening character\n     * @param close\n     *      the closing character\n     * @return the enclosed contents\n     * @throw ex_parse\n     *      if the contents are badly enclosed\n     */\n    wstring getGroup(wchar_t open, wchar_t close) throw(ex_parse);\n\n    /**\n     * Get the contents between two strings as in \\\\begin{foo}... \\\\end{foo}\n     *\n     * @param open\n     *      the opening string\n     * @param close\n     *      the closing string\n     * @return the enclosed contents\n     * @throw ex_parse\n     *      if the contents are badly enclosed\n     */\n    wstring getGroup(const wstring& open, const wstring& close) throw(ex_parse);\n\n    /**\n     * Get the argument of a command in his atomic format\n     *\n     * @return the corresponding atom\n     * @throw ex_parse\n     *      if the argument is incorrect\n     */\n    sptr<Atom> getArgument() throw(ex_parse);\n\n    /**\n     * Get the supscript argument\n     */\n    wstring getOverArgument() throw(ex_parse);\n\n    /**\n     * Get the unit and length from given string. The string must be in the format: a digital\n     * following with the unit (e.g. 10px, 1cm, 8.2em, ...) or a pair (UNIT_PIXEL, 0) will be\n     * returned.\n     */\n    pair<int, float> getLength() throw(ex_parse);\n\n    /**\n     * Convert a character in the corresponding atom in using the file\n     * TeXFormulaSettings.xml for non-alphanumeric characters\n     *\n     * @param c\n     *      the character to be converted\n     * @param onChar\n     *      if convert only one char in the parse string\n     * @return the corresponding atom\n     * @throw ex_parse\n     *      if the character is unknown\n     */\n    sptr<Atom> convertCharacter(wchar_t c, bool oneChar) throw(ex_parse);\n\n    /**\n     * Get the arguments and the options of a command\n     *\n     * @param nbArgs\n     *      the number of arguments of the command\n     * @param opts\n     *      must be 1 if the options are found before the first argument,\n     *      and must be 2 if they must be found before the second argument,\n     *      otherwise there're no options for the command.\n     * @param args\n     *      a vector to put with argument strings\n     */\n    void getOptsArgs(int nbArgs, int opts, _out_ vector<wstring>& args);\n\n    /**\n     * Test the validity of the name of a command. It must contains only alpha\n     * characters and eventually a @ if makeAtletter activated\n     *\n     * @param cmd\n     *      the command's name\n     * @return the validity of the name\n     */\n    bool isValidName(const wstring& cmd);\n\n    /**\n     * Test the validity of a character in a command. It must contains only\n     * alpha characters and eventually a @ if makeAtletter activated\n     */\n    inline bool isValidCharacterInCommand(wchar_t ch) const {\n        return isalpha(ch) || (_atIsLetter != 0 && ch == '@');\n    }\n};\n\n}  // namespace tex\n\n#endif  // PARSER_H_INCLUDED\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/fonts/alphabet.cpp",
    "content": "#include \"fonts/alphabet.h\"\n#include \"common.h\"\n\nusing namespace tex;\n\nconst UnicodeBlock UnicodeBlock::BASIC_LATIN      (0x0020, 0x007f);\nconst UnicodeBlock UnicodeBlock::LATIN1_SUPPLEMENT(0x0080, 0x00ff);\nconst UnicodeBlock UnicodeBlock::CYRILLIC         (0x0400, 0x04ff);\nconst UnicodeBlock UnicodeBlock::GREEK            (0x0370, 0x03ff);\nconst UnicodeBlock UnicodeBlock::GREEK_EXTENDED   (0x1f00, 0x1fff);\nconst UnicodeBlock UnicodeBlock::UNKNOWN          (0xffff, 0xffff);\n\nvector<const UnicodeBlock*> UnicodeBlock::_defined = {\n    &BASIC_LATIN,\n    &LATIN1_SUPPLEMENT,\n    &CYRILLIC,\n    &GREEK,\n    &GREEK_EXTENDED};\n\nbool UnicodeBlock::contains(wchar_t c) const {\n    // if this block is UNKNOWN, check others first\n    if (*this == UNKNOWN) {\n        for (auto b : _defined)\n            if (b->contains(c)) return false;\n        return true;\n    }\n    return (c >= _start && c <= _end);\n}\n\nbool UnicodeBlock::operator<(const UnicodeBlock& ub) const {\n    return (_end < ub._end);\n}\n\nbool UnicodeBlock::operator>(const UnicodeBlock& ub) const {\n    return (_end > ub._end);\n}\n\nbool UnicodeBlock::operator==(const UnicodeBlock& ub) const {\n    return (ub._start == _start && ub._end == _end);\n}\n\nconst UnicodeBlock& UnicodeBlock::define(wchar_t codePointStart, wchar_t codePointEnd) {\n    auto ub = new UnicodeBlock(codePointStart, codePointEnd);\n    _defined.push_back(ub);\n    return *ub;\n}\n\nconst UnicodeBlock& UnicodeBlock::of(wchar_t c) {\n    for (auto x : _defined) {\n        if (x->contains(c)) return *x;\n    }\n    return UNKNOWN;\n}\n\n/*********************************** alphabet implementation **************************/\n\nAlphabetRegistration::~AlphabetRegistration() {}\n\nconst vector<UnicodeBlock> CyrillicRegistration::_block = {UnicodeBlock::CYRILLIC};\nconst string CyrillicRegistration::_package = \"cyrillic\";\nconst string CyrillicRegistration::_font = \"cyrillic/language_cyrillic.xml\";\n\nconst vector<UnicodeBlock>& CyrillicRegistration::getUnicodeBlock() const {\n    return _block;\n}\n\nconst string CyrillicRegistration::getPackage() const {\n    return RES_BASE + \"/\" + _package;\n}\n\nconst string CyrillicRegistration::getTeXFontFile() const {\n    return RES_BASE + \"/\" + _font;\n}\n\nconst vector<UnicodeBlock> GreekRegistration::_block = {\n    UnicodeBlock::GREEK,\n    UnicodeBlock::GREEK_EXTENDED};\n\nconst string GreekRegistration::_package = \"greek\";\nconst string GreekRegistration::_font = \"greek/language_greek.xml\";\n\nconst vector<UnicodeBlock>& GreekRegistration::getUnicodeBlock() const {\n    return _block;\n}\n\nconst string GreekRegistration::getPackage() const {\n    return RES_BASE + \"/\" + _package;\n}\n\nconst string GreekRegistration::getTeXFontFile() const {\n    return RES_BASE + \"/\" + _font;\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/fonts/alphabet.h",
    "content": "#ifndef ALPHABET_H_INCLUDED\n#define ALPHABET_H_INCLUDED\n\n#include <string>\n#include <vector>\nusing namespace std;\n\nnamespace tex {\n\nclass UnicodeBlock {\nprivate:\n    static vector<const UnicodeBlock*> _defined;\n\npublic:\n    // predefined unicode-blocks\n    static const UnicodeBlock BASIC_LATIN;\n    static const UnicodeBlock LATIN1_SUPPLEMENT;\n    static const UnicodeBlock CYRILLIC;\n    static const UnicodeBlock GREEK;\n    static const UnicodeBlock GREEK_EXTENDED;\n    static const UnicodeBlock UNKNOWN;\n\n    const wchar_t _start, _end;\n\n    UnicodeBlock(wchar_t codePointStart, wchar_t codePointEnd)\n        : _start(codePointStart), _end(codePointEnd) {}\n\n    bool contains(wchar_t c) const;\n\n    bool operator==(const UnicodeBlock& ub) const;\n\n    bool operator<(const UnicodeBlock& ub) const;\n\n    bool operator>(const UnicodeBlock& ub) const;\n\n    static const UnicodeBlock& define(wchar_t codePointStart, wchar_t codePointEnd);\n\n    static const UnicodeBlock& of(wchar_t c);\n};\n\nclass AlphabetRegistration {\npublic:\n    virtual const vector<UnicodeBlock>& getUnicodeBlock() const = 0;\n\n    virtual const string getPackage() const = 0;\n\n    virtual const string getTeXFontFile() const = 0;\n\n    virtual ~AlphabetRegistration();\n};\n\nclass CyrillicRegistration : public AlphabetRegistration {\nprivate:\n    static const vector<UnicodeBlock> _block;\n    static const string _package;\n    static const string _font;\n\npublic:\n    const vector<UnicodeBlock>& getUnicodeBlock() const override;\n\n    const string getPackage() const override;\n\n    const string getTeXFontFile() const override;\n};\n\nclass GreekRegistration : public AlphabetRegistration {\nprivate:\n    static const vector<UnicodeBlock> _block;\n    static const string _package;\n    static const string _font;\n\npublic:\n    const vector<UnicodeBlock>& getUnicodeBlock() const override;\n\n    const string getPackage() const override;\n\n    const string getTeXFontFile() const override;\n};\n\n}  // namespace tex\n\n#endif  // ALPHABET_H_INCLUDED\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/fonts/font_info.cpp",
    "content": "#include \"fonts/font_info.h\"\n#include \"core/formula.h\"\n#include \"fonts/font_reg.h\"\n\nChar::Char(wchar_t c, const Font* f, int fc, const sptr<Metrics>& m)\n    : _c(c), _fontCode(fc), _font(f), _m(m), _cf(new CharFont(_c, _fontCode)) {}\n\nExtension::~Extension() {\n    if (hasTop()) delete _top;\n    if (hasMiddle()) delete _middle;\n    if (hasRepeat()) delete _repeat;\n    if (hasBottom()) delete _bottom;\n}\n\nvector<FontInfo*> FontInfo::_infos;\nvector<string> FontInfo::_names;\n\nvoid FontInfo::__free() {\n    for (auto f : _infos) {\n        if(f != nullptr){\n            delete f;\n        }\n        f = nullptr;\n    }\n    _infos.clear();\n}\n\nvoid FontInfo::__register(const FontSet& set) {\n    const vector<FontReg>& regs = set.regs();\n    for (auto r : regs) __predefine_name(r.name);\n    for (auto r : regs) r.reg();\n}\n\nvoid FontInfo::init(int unicode) {\n    int num = NUMBER_OF_CHAR_CODES;\n    _unicodeCount = unicode;\n    if (unicode != 0) num = unicode;\n    _charCount = num;\n    _metrics = new float*[num]();\n    _nextLarger = new CharFont*[num]();\n    _extensions = new int*[num]();\n\n    _boldId = _romanId = _ssId = _ttId = _itId = _id;\n    _skewChar = (wchar_t)-1;\n    _font = nullptr;\n}\n\nFontInfo::FontInfo(int id, const string& path, int unicode, float xHeight, float space, float quad)\n    : _id(id), _path(path), _xHeight(xHeight), _space(space), _quad(quad) { init(unicode); }\n\nvoid FontInfo::__push_metrics(const float* arr, int len) {\n    const int count = len / 5;\n    for (int i = 0; i < count; i++) {\n        int j = i * 5;\n        setMetrics(\n            (wchar_t)arr[j],\n            new float[4]{arr[j + 1], arr[j + 2], arr[j + 3], arr[j + 4]});\n    }\n}\n\nvoid FontInfo::__push_extensions(const int* arr, int len) {\n    const int count = len / 5;\n    for (int i = 0; i < count; i++) {\n        int j = i * 5;\n        setExtension(\n            (wchar_t)arr[j],\n            new int[4]{arr[j + 1], arr[j + 2], arr[j + 3], arr[j + 4]});\n    }\n}\n\nvoid FontInfo::__push_largers(const int* arr, int len) {\n    const int count = len / 3;\n    for (int i = 0; i < count; i++) {\n        int j = i * 3;\n        setNextLarger((wchar_t)arr[j], (wchar_t)arr[j + 1], arr[j + 2]);\n    }\n}\n\nvoid FontInfo::__push_ligtures(const wchar_t* arr, int len) {\n    const int count = len / 3;\n    for (int i = 0; i < count; i++) {\n        int j = i * 3;\n        addLigture(arr[j], arr[j + 1], arr[j + 2]);\n    }\n}\n\nvoid FontInfo::__push_kerns(const float* arr, int len) {\n    const int count = len / 3;\n    for (int i = 0; i < count; i++) {\n        int j = i * 3;\n        addKern((wchar_t)arr[j], (wchar_t)arr[j + 1], arr[j + 2]);\n    }\n}\n\nvoid FontInfo::setExtension(wchar_t ch, _in_ int* ext) {\n    if (_unicodeCount == 0) {\n        _extensions[ch] = ext;\n    } else if (_unicode.find(ch) == _unicode.end()) {\n        wchar_t s = (wchar_t)_unicode.size();\n        _unicode[ch] = s;\n        _extensions[s] = ext;\n    } else {\n        _extensions[_unicode[ch]] = ext;\n    }\n}\n\nvoid FontInfo::setMetrics(wchar_t c, _in_ float* arr) {\n    if (_unicodeCount == 0) {\n        _metrics[c] = arr;\n    } else if (_unicode.find(c) == _unicode.end()) {\n        wchar_t s = (wchar_t)_unicode.size();\n        _unicode[c] = s;\n        _metrics[s] = arr;\n    } else {\n        _metrics[_unicode[c]] = arr;\n    }\n}\n\nvoid FontInfo::setNextLarger(wchar_t c, wchar_t larger, int fontLarger) {\n    if (_unicodeCount == 0)\n        _nextLarger[c] = new CharFont(larger, fontLarger);\n    else if (_unicode.find(c) == _unicode.end()) {\n        wchar_t s = (wchar_t)_unicode.size();\n        _unicode[c] = s;\n        _nextLarger[s] = new CharFont(larger, fontLarger);\n    } else {\n        _nextLarger[_unicode[c]] = new CharFont(larger, fontLarger);\n    }\n}\n\nvoid FontInfo::addKern(wchar_t left, wchar_t right, float kern) {\n    _kern[CharCouple(left, right)] = kern;\n}\n\nvoid FontInfo::addLigture(wchar_t left, wchar_t right, wchar_t lig) {\n    _lig[CharCouple(left, right)] = lig;\n}\n\nconst int* const FontInfo::getExtension(wchar_t ch) {\n    if (_unicodeCount == 0) return _extensions[ch];\n    return _extensions[_unicode[ch]];\n}\n\nfloat FontInfo::getkern(wchar_t left, wchar_t right, float factor) {\n    CharCouple c(left, right);\n    auto it = _kern.find(c);\n    if (it == _kern.end()) return 0;\n    return it->second * factor;\n}\n\nconst float* FontInfo::getMetrics(wchar_t c) {\n    if (_unicodeCount == 0) return _metrics[c];\n    return _metrics[_unicode[c]];\n}\n\nconst CharFont* FontInfo::getNextLarger(wchar_t c) {\n    if (_unicodeCount == 0) return _nextLarger[c];\n    return _nextLarger[_unicode[c]];\n}\n\nsptr<CharFont> FontInfo::getLigture(wchar_t left, wchar_t right) {\n    CharCouple c(left, right);\n    auto it = _lig.find(c);\n    if (it == _lig.end()) return nullptr;\n    return sptr<CharFont>(new CharFont(it->second, _id));\n}\n\nconst Font* FontInfo::getFont() {\n    if (_font == nullptr) _font = Font::create(_path, TeXFormula::PIXELS_PER_POINT);\n    return _font;\n}\n\nvoid FontInfo::setVariousId(\n    const string& bold,\n    const string& roman,\n    const string& ss,\n    const string& tt,\n    const string& it) {\n    setBoldId(__id(bold));\n    setRomanId(__id(roman));\n    setSsId(__id(ss));\n    setTtId(__id(tt));\n    setItId(__id(it));\n}\n\nFontInfo::~FontInfo() {\n    // delete metrics\n    for (int i = 0; i < _charCount; i++) {\n        if (_metrics[i] != nullptr) delete[] _metrics[i];\n        _metrics[i] = nullptr;\n    }\n    delete[] _metrics;\n    // delete extensions\n    for (int i = 0; i < _charCount; i++) {\n        if (_extensions[i] != nullptr) delete[] _extensions[i];\n        _extensions[i] = nullptr;\n    }\n    delete[] _extensions;\n    // delete next-larger\n    for (int i = 0; i < _charCount; i++) {\n        if (_nextLarger[i] != nullptr) delete _nextLarger[i];\n        _nextLarger[i] = nullptr;\n    }\n    delete[] _nextLarger;\n    // delete font\n    if (_font != nullptr) delete _font;\n}\n\n#ifdef HAVE_LOG\n#include <iomanip>\nostream& tex::operator<<(ostream& os, const FontInfo& info) {\n    // base information\n    os << \"\\nID: \" << info._id;\n    os << \" path: \" << info._path << endl;\n    // font information\n    os << \"---------------------------------------------------\" << endl;\n    os << \"x height    space     quad  bold  roman  ss  tt  it\" << endl;\n    os << setw(8) << info._xHeight << setw(9) << info._space;\n    os << setw(9) << info._quad << setw(6) << info._boldId;\n    os << setw(7) << info._romanId << setw(4) << info._ssId;\n    os << setw(4) << info._ttId << setw(4) << info._itId;\n    os << endl;\n\n    if (!info._lig.empty()) {\n        os << \"ligatures:\" << endl;\n        for (auto x : info._lig) {\n            os << \"\\t[\"\n               << setw(3) << x.first._left << \", \"\n               << setw(3) << x.first._right << \"] = \"\n               << x.second << endl;\n        }\n    }\n\n    os << \"---------------------------------------------------\" << endl;\n    return os;\n}\n\nostream& tex::operator<<(ostream& os, const CharFont& font) {\n    os << \"CharFont { char: \" << font._c\n       << \", font: \" << font._fontId\n       << \", bold font: \" << font._boldFontId\n       << \" }\";\n    return os;\n}\n#endif\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/fonts/font_info.h",
    "content": "#ifndef FONT_INFO_H_INCLUDED\n#define FONT_INFO_H_INCLUDED\n\n#include <unordered_map>\n#include \"common.h\"\n#include \"graphic/graphic.h\"\n\nnamespace tex {\n/**\n * Contains the metrics for 1 character: width, height, depth and italic correction\n */\nclass Metrics {\nprivate:\n    float _w, _h, _d, _i, _s;\n\npublic:\n    Metrics() = delete;\n\n    Metrics(const Metrics&) = delete;\n\n    Metrics(float w, float h, float d, float i, float factor, float s)\n        : _w(w * factor), _h(h * factor), _d(d * factor), _i(i * factor), _s(s) {}\n\n    inline float getWidth() const { return _w; }\n\n    inline float getHeight() const { return _h; }\n\n    inline float getDepth() const { return _d; }\n\n    inline float getItalic() const { return _i; }\n\n    inline float getSize() const { return _s; }\n};\n\n/**\n * Represents a specific character in a specific font (identified by its font id)\n */\nclass CharFont {\npublic:\n    wchar_t _c;\n    int _fontId;\n    int _boldFontId;\n\n    CharFont() : _c(0), _fontId(0), _boldFontId(0) {}\n\n    CharFont(wchar_t ch, int f) : _c(ch), _fontId(f), _boldFontId(f) {}\n\n    CharFont(wchar_t ch, int f, int bf) : _c(ch), _fontId(f), _boldFontId(bf) {}\n\n#ifdef HAVE_LOG\n    friend ostream& operator<<(ostream& os, const CharFont& info);\n#endif\n};\n\n/**\n * Class represents a character together with its font, font id and metric information\n */\nclass Char {\nprivate:\n    wchar_t _c;\n    int _fontCode;\n    const Font* _font;\n    sptr<CharFont> _cf;\n    sptr<Metrics> _m;\n\npublic:\n    Char() = delete;\n\n    Char(wchar_t c, const Font* f, int fc, const sptr<Metrics>& m);\n\n    sptr<CharFont> getCharFont() const { return _cf; }\n\n    inline wchar_t getChar() const { return _c; }\n\n    inline const Font* getFont() const { return _font; }\n\n    inline int getFontCode() const { return _fontCode; }\n\n    inline float getWidth() const { return _m->getWidth(); }\n\n    inline float getItalic() const { return _m->getItalic(); }\n\n    inline float getHeight() const { return _m->getHeight(); }\n\n    inline float getDepth() const { return _m->getDepth(); }\n\n    inline float getSize() const { return _m->getSize(); }\n};\n\n/**\n * Represents an extension character that is defined by Char-objects of it's 4\n * possible parts (null means part not present).\n */\nclass Extension {\nprivate:\n    const Char* const _top;\n    const Char* const _middle;\n    const Char* const _bottom;\n    const Char* const _repeat;\n\npublic:\n    Extension() = delete;\n\n    Extension(const Extension&) = delete;\n\n    Extension(Char* t, Char* m, Char* r, Char* b)\n        : _top(t), _middle(m), _repeat(r), _bottom(b) {}\n\n    inline bool hasTop() const { return _top != nullptr; }\n\n    inline bool hasMiddle() const { return _middle != nullptr; }\n\n    inline bool hasBottom() const { return _bottom != nullptr; }\n\n    inline bool hasRepeat() const { return _repeat != nullptr; }\n\n    inline const Char& getTop() const { return *_top; }\n\n    inline const Char& getMiddle() const { return *_middle; }\n\n    inline const Char& getRepeat() const { return *_repeat; }\n\n    inline const Char& getBottom() const { return *_bottom; }\n\n    ~Extension();\n};\n\nclass CharCouple {\npublic:\n    wchar_t _left, _right;\n\n    CharCouple(wchar_t l, wchar_t r) : _left(l), _right(r) {}\n\n    inline bool operator==(const CharCouple& c) const {\n        return (_left == c._left && _right == c._right);\n    }\n};\n\n/**\n * Function to check if two CharCouple is equal.\n */\ntypedef struct {\n    bool operator()(const CharCouple& c1, const CharCouple& c2) const {\n        return c1 == c2;\n    }\n} __char_couple_eq;\n\n/**\n * Function to generate hash code for one CharCouple.\n */\ntypedef struct {\n    size_t operator()(const CharCouple& c) const {\n        return (c._left + c._right) % 128;\n    }\n} __char_couple_hash;\n\n#define NUMBER_OF_CHAR_CODES 256\n\nclass FontSet;\n\n/**\n * Class contains all the font information for 1 font\n */\nclass FontInfo {\nprivate:\n    static vector<FontInfo*> _infos;\n    static vector<string> _names;\n    // The id of this font info\n    int _id;\n    const Font* _font;\n    // The path of the font file\n    string _path;\n\n    // ligatures\n    unordered_map<CharCouple, wchar_t, __char_couple_hash, __char_couple_eq> _lig;\n    // kerning\n    unordered_map<CharCouple, float, __char_couple_hash, __char_couple_eq> _kern;\n    // unicode mapping\n    map<wchar_t, wchar_t> _unicode;\n    int _unicodeCount;\n    // font metrics\n    float** _metrics;\n    // the next larger font, e.g. sigma\n    CharFont** _nextLarger;\n    // extensions for big delimiter\n    int** _extensions;\n    // number of characters\n    int _charCount;\n    // skew character of the font (used for positioning accents)\n    wchar_t _skewChar;\n\n    // basic informations for this font\n    float _xHeight, _space, _quad;\n    // BOLD, ROMAN, SANS-SERIF, TYPE-WIRTER, ITALIC\n    // the default is -1 (no that version)\n    int _boldId, _romanId, _ssId, _ttId, _itId;\n\n    void init(int unicode);\n\n    FontInfo();\n\n    FontInfo(const FontInfo&);\n\n    FontInfo(int id, const string& path, int unicode, float xHeight, float space, float quad);\n\n    static inline void __add(FontInfo* info) {\n        if (info->_id >= _infos.size()) _infos.resize(info->_id + 1);\n        _infos[info->_id] = info;\n    }\n\npublic:\n    /************************************** INTERNAL USE ******************************************/\n    static inline FontInfo* __create(\n        int id, const string& path, int unicode,\n        float xHeight = 0, float space = 0, float quad = 0) {\n        auto i = new FontInfo(id, path, unicode, xHeight, space, quad);\n        __add(i);\n        return i;\n    }\n\n    static inline void __predefine_name(const string& name) { _names.push_back(name); }\n\n    static inline int __id(const string& name) { return indexOf(_names, name); }\n\n    static inline const vector<FontInfo*>& __infos() { return _infos; }\n\n    static inline FontInfo* __get(int id) { return _infos[id]; }\n\n    static void __free();\n\n    static void __register(const FontSet& set);\n\n    void __push_metrics(const float* arr, int len);\n\n    void __push_extensions(const int* arr, int len);\n\n    void __push_largers(const int* arr, int len);\n\n    void __push_ligtures(const wchar_t* arr, int len);\n\n    void __push_kerns(const float* arr, int len);\n\n    inline void __set_space(float s) { _space = s; }\n\n    inline void __set_xheight(float h) { _xHeight = h; }\n\n    inline void __set_quad(float q) { _quad = q; }\n    /**********************************************************************************************/\n\n    void setExtension(wchar_t ch, _in_ int* ext);\n\n    void setMetrics(wchar_t c, _in_ float* arr);\n\n    void setNextLarger(wchar_t c, wchar_t larger, int fontLarger);\n\n    void addKern(wchar_t left, wchar_t right, float kern);\n\n    void addLigture(wchar_t left, wchar_t right, wchar_t lig);\n\n    const int* const getExtension(wchar_t ch);\n\n    float getkern(wchar_t left, wchar_t right, float factor);\n\n    const float* getMetrics(wchar_t c);\n\n    const CharFont* getNextLarger(wchar_t c);\n\n    sptr<CharFont> getLigture(wchar_t left, wchar_t right);\n\n    inline bool hasNextLarger(wchar_t c) { return getNextLarger(c) != nullptr; }\n\n    inline bool isExtensionChar(wchar_t c) { return (getExtension(c) != nullptr); }\n\n    inline float getQuad(float factor) const { return _quad * factor; }\n\n    inline wchar_t getSkewChar() const { return _skewChar; }\n\n    inline float getSpace(float factor) const { return _space * factor; }\n\n    inline float getXHeight(float factor) const { return _xHeight * factor; }\n\n    inline bool hasSpace() const { return _space > PREC; }\n\n    inline void setSkewChar(wchar_t c) { _skewChar = c; }\n\n    inline int getId() const { return _id; }\n\n    inline int getBoldId() const { return _boldId; }\n\n    inline int getRomanId() const { return _romanId; }\n\n    inline int getTtId() const { return _ttId; }\n\n    inline int getItId() const { return _itId; }\n\n    inline int getSsId() const { return _ssId; }\n\n    inline void setSsId(int id) { _ssId = id == -1 ? _id : id; }\n\n    inline void setTtId(int id) { _ttId = id == -1 ? _id : id; }\n\n    inline void setItId(int id) { _itId = id == -1 ? _id : id; }\n\n    inline void setRomanId(int id) { _romanId = id == -1 ? _id : id; }\n\n    inline void setBoldId(int id) { _boldId = id == -1 ? _id : id; }\n\n    inline const string& getPath() const { return _path; }\n\n    const Font* getFont();\n\n    void setVariousId(\n        const string& bold,\n        const string& roman,\n        const string& ss,\n        const string& tt,\n        const string& it);\n\n    inline static const Font* getFont(int id) { return _infos[id]->getFont(); }\n\n    ~FontInfo();\n\n#ifdef HAVE_LOG\n    friend ostream& operator<<(ostream& os, const FontInfo& info);\n#endif\n};\n}  // namespace tex\n\n#endif\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/fonts/font_reg.h",
    "content": "#ifndef FONT_REG_H_INCLUDED\n#define FONT_REG_H_INCLUDED\n\n#include <string>\n#include <vector>\n\nusing namespace std;\n\nnamespace tex {\n\nclass FontInfo;\n\n/** Font registration function */\ntypedef void (*__reg_font_func)(void);\n\n/** Represents a font description registration */\ntypedef struct {\n    string name;\n    __reg_font_func reg;\n} FontReg;\n\n/** Represents a set of font descriptions */\nclass FontSet {\npublic:\n    virtual vector<FontReg> regs() const = 0;\n};\n\n}  // namespace tex\n\n#define __font_reg(name) \\\n    __reg_font_##name\n\n#define DECL_FONT_REG(name) \\\n    extern void __font_reg(name)()\n\n#define DECL_FONT_SET(name)                                      \\\n    class FontSet##name : public tex::FontSet {                  \\\n    public:                                                      \\\n        virtual std::vector<tex::FontReg> regs() const override; \\\n    };\n\n#define REG_FONT(name) \\\n    {#name, __font_reg(name)},\n\n#define DEF_FONT_SET(name)                                  \\\n    std::vector<tex::FontReg> FontSet##name::regs() const { \\\n        return {\n#define END_DEF_FONT_SET \\\n    }                    \\\n    ;                    \\\n    }\n\n#endif\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/fonts/fonts.cpp",
    "content": "#include \"fonts/fonts.h\"\n#include \"common.h\"\n#include \"fonts/symbol_reg.h\"\n#include \"graphic/graphic.h\"\n#include \"render.h\"\n#include \"res/parser/font_parser.h\"\n\n#include <cmath>\n\nusing namespace tex;\n\nconst int TeXFont::NO_FONT = -1;\n\nstring* DefaultTeXFont::_defaultTextStyleMappings;\nmap<string, vector<CharFont*>> DefaultTeXFont::_textStyleMappings;\n\nmap<string, sptr<CharFont>> DefaultTeXFont::_symbolMappings;\nmap<string, float> DefaultTeXFont::_generalSettings;\nvector<UnicodeBlock> DefaultTeXFont::_loadedAlphabets;\nmap<UnicodeBlock, AlphabetRegistration*> DefaultTeXFont::_registeredAlphabets;\n\n/** no extension part for that kind (TOP, MID, REP or BOT) */\nconst int DefaultTeXFont::NONE = -1;\n/** font type */\nconst int DefaultTeXFont::NUMBERS = 0;\nconst int DefaultTeXFont::CAPITAL = 1;\nconst int DefaultTeXFont::SMALL = 2;\nconst int DefaultTeXFont::UNICODE = 3;\n/** font information */\nconst int DefaultTeXFont::WIDTH = 0;\nconst int DefaultTeXFont::HEIGHT = 1;\nconst int DefaultTeXFont::DEPTH = 2;\nconst int DefaultTeXFont::IT = 3;\n/** extensions */\nconst int DefaultTeXFont::TOP = 0;\nconst int DefaultTeXFont::MID = 1;\nconst int DefaultTeXFont::REP = 2;\nconst int DefaultTeXFont::BOT = 3;\n\nbool DefaultTeXFont::_magnificationEnable = true;\n\nTeXFont::~TeXFont() {}\n\nDefaultTeXFont::~DefaultTeXFont() {\n#ifdef HAVE_LOG\n    __dbg(\"DefaultTeXFont destruct\\n\");\n#endif  // HAVE_LOG\n}\n\nvoid DefaultTeXFont::__register_symbols_set(const SymbolsSet& set) {\n    for (auto reg : set.regs()) reg();\n}\n\nvoid DefaultTeXFont::__push_symbols(const __symbol_component* symbols, const int len) {\n    for (int i = 0; i < len; i++) {\n        const __symbol_component& c = symbols[i];\n        _symbolMappings[c.name] = sptr<CharFont>(new CharFont(c.code, c.font));\n    }\n}\n\nvoid DefaultTeXFont::addTeXFontDescription(\n    const string& base, const string& file) throw(ex_res_parse) {\n    DefaultTeXFontParser parser(base, file);\n    parser.parseFontDescriptions();\n    parser.parseExtraPath();\n    const auto x = parser.parseTextStyleMappings();\n    _textStyleMappings.insert(x.begin(), x.end());\n    parser.parseSymbolMappings(_symbolMappings);\n}\n\nvoid DefaultTeXFont::addAlphabet(\n    const string& base,\n    const vector<UnicodeBlock>& alphabet,\n    const string& lang) throw(ex_res_parse) {\n    bool b = false;\n    for (size_t i = 0; !b && i < alphabet.size(); i++) {\n        b = (indexOf(_loadedAlphabets, alphabet[i]) != -1) || b;\n    }\n    if (!b) {\n        TeXParser::_isLoading = true;\n        string file = lang;\n        addTeXFontDescription(base, file);\n        for (size_t i = 0; i < alphabet.size(); i++) {\n            _loadedAlphabets.push_back(alphabet[i]);\n        }\n        TeXParser::_isLoading = false;\n    }\n}\n\nvoid DefaultTeXFont::addAlphabet(AlphabetRegistration* reg) {\n    try {\n        addAlphabet(reg->getPackage(), reg->getUnicodeBlock(), reg->getTeXFontFile());\n    } catch (ex_font_loaded& e) {\n    } catch (ex_alphabet_registration& e) {\n#ifdef HAVE_LOG\n        __dbg(\"%s\", e.what());\n#endif  // HAVE_LOG\n    }\n}\n\nvoid DefaultTeXFont::registerAlphabet(AlphabetRegistration* reg) {\n    const vector<UnicodeBlock>& blocks = reg->getUnicodeBlock();\n    for (size_t i = 0; i < blocks.size(); i++) {\n        _registeredAlphabets[blocks[i]] = reg;\n    }\n}\n\ninline sptr<TeXFont> DefaultTeXFont::copy() {\n    return sptr<TeXFont>(new DefaultTeXFont(\n        _size, _factor, _isBold, _isRoman, _isSs, _isTt, _isIt));\n}\n\nChar DefaultTeXFont::getChar(wchar_t c, _in_ const vector<CharFont*>& cf, int style) {\n    int kind, offset;\n    if (c >= '0' && c <= '9') {\n        kind = NUMBERS;\n        offset = c - '0';\n    } else if (c >= 'a' && c <= 'z') {\n        kind = SMALL;\n        offset = c - 'a';\n    } else if (c >= 'A' && c <= 'Z') {\n        kind = CAPITAL;\n        offset = c - 'A';\n    } else {\n        kind = UNICODE;\n        offset = c;\n    }\n    // if no mapping for the character's range, then use the default style\n    auto x = cf[kind];\n    if (x == nullptr) return getDefaultChar(c, style);\n    return getChar(CharFont(x->_c + offset, x->_fontId), style);\n}\n\nChar DefaultTeXFont::getDefaultChar(wchar_t c, int style) {\n    // the default text style mappings will always exist,\n    // because it's checked during parsing\n    if (c >= '0' && c <= '9') return getChar(c, _defaultTextStyleMappings[NUMBERS], style);\n    // small letter\n    if (c >= 'a' && c <= 'z') return getChar(c, _defaultTextStyleMappings[SMALL], style);\n    // capital\n    return getChar(c, _defaultTextStyleMappings[CAPITAL], style);\n}\n\nChar DefaultTeXFont::getChar(\n    wchar_t c,\n    const string& textStyle,\n    int style) throw(ex_text_style_mapping_not_found) {\n    // find first\n    auto i = _textStyleMappings.find(textStyle);\n    if (i == _textStyleMappings.end()) throw ex_text_style_mapping_not_found(textStyle);\n    return getChar(c, i->second, style);\n}\n\nChar DefaultTeXFont::getChar(const CharFont& c, int style) {\n    CharFont cf = c;\n    float fsize = getSizeFactor(style);\n    int id = _isBold ? cf._boldFontId : cf._fontId;\n    auto info = getInfo(id);\n\n    if (_isBold && cf._fontId == cf._boldFontId) {\n        id = info->getBoldId();\n        info = getInfo(id);\n        cf = CharFont(cf._c, id, style);\n    }\n    if (_isRoman) {\n        id = info->getRomanId();\n        info = getInfo(id);\n        cf = CharFont(cf._c, id, style);\n    }\n    if (_isSs) {\n        id = info->getSsId();\n        info = getInfo(id);\n        cf = CharFont(cf._c, id, style);\n    }\n    if (_isTt) {\n        id = info->getTtId();\n        info = getInfo(id);\n        cf = CharFont(cf._c, id, style);\n    }\n    if (_isIt) {\n        id = info->getItId();\n        info = getInfo(id);\n        cf = CharFont(cf._c, id, style);\n    }\n\n#ifdef HAVE_LOG\n    __dbg(\n        ANSI_COLOR_GREEN \"{ char: %c, font id: %d, path: %s }\\n\" ANSI_RESET,\n        cf._c, id, info->getPath().c_str());\n#endif\n\n    return Char(cf._c, info->getFont(), id, getMetrics(cf, _factor * fsize));\n}\n\nChar DefaultTeXFont::getChar(\n    const string& symbolName, int style) throw(ex_symbol_mapping_not_found) {\n    // find first\n    auto i = _symbolMappings.find(symbolName);\n    // no symbol mapping found\n    if (i == _symbolMappings.end()) throw ex_symbol_mapping_not_found(symbolName);\n    return getChar(*(i->second), style);\n}\n\nsptr<Metrics> DefaultTeXFont::getMetrics(_in_ const CharFont& cf, float size) {\n    auto info = getInfo(cf._fontId);\n    const float* m = info->getMetrics(cf._c);\n    Metrics* met = new Metrics(\n        m[WIDTH], m[HEIGHT], m[DEPTH], m[IT],\n        size * TeXFormula::PIXELS_PER_POINT, size);\n    return sptr<Metrics>(met);\n}\n\nExtension* DefaultTeXFont::getExtension(_in_ const Char& c, int style) {\n    const Font* f = c.getFont();\n    int fc = c.getFontCode();\n    float s = getSizeFactor(style);\n    // construct Char for every part\n    auto info = getInfo(fc);\n    const int* ext = info->getExtension(c.getChar());\n    // 4 parts of extensions, TOP, MID, REP, BOT\n    Char* parts[4] = {nullptr};\n    for (int i = 0; i < 4; i++) {\n        if (ext[i] == NONE) {\n            parts[i] = nullptr;\n        } else {\n            auto m = getMetrics(CharFont(ext[i], fc), s);\n            parts[i] = new Char(ext[i], f, fc, m);\n        }\n    }\n    return new Extension(parts[TOP], parts[MID], parts[REP], parts[BOT]);\n}\n\nfloat DefaultTeXFont::getKern(_in_ const CharFont& left, _in_ const CharFont& right, int style) {\n    if (left._fontId == right._fontId) {\n        auto info = getInfo(left._fontId);\n        return info->getkern(\n            left._c, right._c, getSizeFactor(style) * TeXFormula::PIXELS_PER_POINT);\n    }\n    return 0;\n}\n\nsptr<CharFont> DefaultTeXFont::getLigature(_in_ const CharFont& left, _in_ const CharFont& right) {\n    if (left._fontId == right._fontId) {\n        auto info = getInfo(left._fontId);\n        return info->getLigture(left._c, right._c);\n    }\n    return nullptr;\n}\n\ninline int DefaultTeXFont::getMuFontId() {\n    return _generalSettings[DefaultTeXFontParser::MUFONTID_ATTR];\n}\n\nChar DefaultTeXFont::getNextLarger(_in_ const Char& c, int style) {\n    auto info = getInfo(c.getFontCode());\n    const CharFont* ch = info->getNextLarger(c.getChar());\n    auto newInfo = getInfo(ch->_fontId);\n    return Char(ch->_c, newInfo->getFont(), ch->_fontId, getMetrics(*ch, getSizeFactor(style)));\n}\n\ninline float DefaultTeXFont::getSpace(int style) {\n    int spaceFontId = _generalSettings[DefaultTeXFontParser::SPACEFONTID_ATTR];\n    auto info = getInfo(spaceFontId);\n    return info->getSpace(getSizeFactor(style) * TeXFormula::PIXELS_PER_POINT);\n}\n\nvoid DefaultTeXFont::setMathSizes(float ds, float ts, float ss, float sss) {\n    if (!_magnificationEnable) return;\n    _generalSettings[\"scriptfactor\"] = abs(ss / ds);\n    _generalSettings[\"scriptscriptfactor\"] = abs(sss / ds);\n    _generalSettings[\"textfactor\"] = abs(ts / ds);\n    TeXRender::_defaultSize = abs(ds);\n}\n\nvoid DefaultTeXFont::setMagnification(float mag) {\n    if (!_magnificationEnable) return;\n    TeXRender::_magFactor = mag / 1000.f;\n}\n\nvoid DefaultTeXFont::enableMagnification(bool b) {\n    _magnificationEnable = b;\n}\n\n#include \"res/reg/builtin_font_reg.h\"\n#include \"res/reg/builtin_syms_reg.h\"\n\nvoid DefaultTeXFont::_init_() {\n    _loadedAlphabets.push_back(UnicodeBlock::of('a'));\n    FontInfo::__register(FontSetBuiltin());\n    __default_general_settings();\n    __default_text_style_mapping();\n    __register_symbols_set(SymbolsSetBuiltin());\n\n#ifdef HAVE_LOG\n    log();\n#endif\n}\n\nvoid DefaultTeXFont::_free_() {\n    delete[] _defaultTextStyleMappings;\n    _defaultTextStyleMappings = nullptr;\n    for (auto f : _textStyleMappings) {\n        vector<CharFont*> x = f.second;\n        for (auto i : x) {\n            if (i != nullptr) {\n                delete i;\n                i = nullptr;\n            }\n        }\n    }\n    for (auto& f : _symbolMappings) {\n        f.second = nullptr;\n    }\n    _symbolMappings.clear();\n    FontInfo::__free();\n    // _registeredAlphabets :=> map<UnicodeBlock, AlphabetRegistration>\n    // multi => one\n    vector<AlphabetRegistration*> cleaned;\n    for (auto i : _registeredAlphabets) {\n        if (i.second != nullptr && indexOf(cleaned, i.second) < 0) {\n            delete i.second;\n            cleaned.push_back(i.second);\n            i.second = nullptr;\n        }\n        i.second = nullptr;\n    }\n}\n\n#ifdef HAVE_LOG\n#include <iomanip>\nvoid DefaultTeXFont::log() {\n    // default text style mappings\n    __log << \"\\nDEFAULT TEXT STYLE MAPPINGS: { \";\n    for (int i = 0; i < 4; i++) __log << _defaultTextStyleMappings[i] << \"; \";\n    __log << \"}\\n\\n\";\n    // text style mappings\n    __log << \"TEXT STYLE MAPPINGS:\" << endl;\n    for (auto i : _textStyleMappings) {\n        __log << \"  \" << i.first << \":\" << endl;\n        for (auto j : i.second) {\n            if (j == nullptr)\n                __log << \"\\tnull\" << endl;\n            else\n                __log << \"\\t\" << *j << endl;\n        }\n        __log << endl;\n    }\n    __log << endl;\n    // parameters\n    __log << \"PARAMETERS:\" << endl;\n    for (auto i : _parameters) __log << setw(20) << i.first << \" : \" << i.second << endl;\n    __log << endl;\n    // general settings\n    __log << \"GENERALSETTINGS:\" << endl;\n    for (auto i : _generalSettings) __log << setw(20) << i.first << \" : \" << i.second << endl;\n    __log << endl;\n    // symbol mappings\n    __log << \"SYMBOL MAPPINGS:\" << endl\n          << \"\\t\";\n    for (auto i : _symbolMappings) __log << i.first << \"; \";\n    __log << \"\\n\\n\";\n    // font information\n    __log << \"FONTINFOS:\" << endl;\n    for (auto i : FontInfo::__infos()) __log << *i;\n    __log << endl;\n}\n#endif\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/fonts/fonts.h",
    "content": "#ifndef FONTS_H_INCLUDED\n#define FONTS_H_INCLUDED\n\n#include \"common.h\"\n#include \"core/formula.h\"\n#include \"fonts/alphabet.h\"\n#include \"fonts/font_info.h\"\n#include \"graphic/graphic.h\"\n\n#include <cstring>\n#include <map>\n#include <string>\n#include <unordered_map>\n#include <vector>\n\nusing namespace std;\nusing namespace tex;\n\nnamespace tex {\n\n/**\n * An interface representing a \"TeXFont\", which is responsible for all the\n * necessary fonts and font information.\n */\nclass TeXFont {\npublic:\n    static const int NO_FONT;\n\n    virtual float getScaleFactor() = 0;\n\n    virtual float getAxisHeight(int style) = 0;\n\n    virtual float getBigOpSpacing1(int style) = 0;\n\n    virtual float getBigOpSpacing2(int style) = 0;\n\n    virtual float getBigOpSpacing3(int style) = 0;\n\n    virtual float getBigOpSpacing4(int style) = 0;\n\n    virtual float getBigOpSpacing5(int style) = 0;\n\n    /**\n     * Get a Char-object specifying the given character in the given text style\n     * with metric information depending on the given \"style\".\n     * @param c\n     *      alphanumeric character\n     * @param textStyle\n     *      the text style in which the character should be drawn\n     * @param style\n     *      the style in which the atom should be drawn\n     * @return\n     *      the Char-object specifying the given character in the given text style\n     * @throw ex_text_style_mapping_not_found\n     *      if the text style mapping not found\n     */\n    virtual Char getChar(\n        wchar_t c,\n        const string& textStyle,\n        int style) throw(ex_text_style_mapping_not_found) = 0;\n\n    /**\n     * Get a Char-object for this specific character containing the metric information\n     * @param cf\n     *      CharFont-object determine a specific character of a specific font\n     * @param style\n     *      the style in which the atom should be drawn\n     * @return the Char-object for this character containing metric information\n     */\n    virtual Char getChar(const CharFont& cf, int style) = 0;\n\n    /**\n     * Get a Char-object for the given symbol with metric information depending on \"style\"\n     * @param name\n     *      the symbol name\n     * @param style\n     *      the style in which the atom should be drawn\n     * @return a Char-object for this symbol with metric information\n     */\n    virtual Char getChar(const string& name, int style) throw(ex_symbol_mapping_not_found) = 0;\n\n    /**\n     * Get a Char-object specifying the given character in the default text style\n     * with metric information depending on the given \"style\"\n     * @param c\n     *      alphanumeric character\n     * @param style\n     *      the style in which the atom should be drawn\n     * @return the Char-object specifying the given character in the default text style\n     */\n    virtual Char getDefaultChar(wchar_t c, int style) = 0;\n\n    virtual float getDefaultRuleThickness(int style) = 0;\n\n    virtual float getDenom1(int style) = 0;\n\n    virtual float getDenom2(int style) = 0;\n\n    /**\n     * Get an Extension-object for the given Char containing the 4 possible\n     * parts to build an arbitrary large variant. This will only be called if\n     * isExtensionChar(Char) returns true.\n     * @param c\n     *      a Char-object for a specific character\n     * @param style\n     *      the style in which the atom should be drawn\n     * @return an extension object containing the 4 possible parts\n     */\n    virtual Extension* getExtension(const Char& c, int style) = 0;\n\n    /**\n     * Get the kern value to be inserted between the given characters in the\n     * given style\n     * @param left\n     *      left character\n     * @param right\n     *      right character\n     * @param style\n     *      the style in which the atom should be drawn\n     * @return the kern value between both characters (default 0)\n     */\n    virtual float getKern(const CharFont& left, const CharFont& right, int style) = 0;\n\n    /**\n     * Get the ligature that replaces both characters (if any).\n     * @param left\n     *      left character\n     * @param right\n     *      right character\n     * @return a ligature replacing both characters (or null if no any ligature)\n     */\n    virtual sptr<CharFont> getLigature(const CharFont& left, const CharFont& right) = 0;\n\n    /**\n     * Get the id of mu font\n     */\n    virtual int getMuFontId() = 0;\n\n    /**\n     * Get the next larger version of the given character. This is only called\n     * if hasNextLarger(Char) returns true.\n     * @param c\n     *      specified character\n     * @param style\n     *      the style in which the atom should be drawn\n     * @return the next larger version of this character\n     */\n    virtual Char getNextLarger(const Char& c, int style) = 0;\n\n    virtual float getNum1(int style) = 0;\n\n    virtual float getNum2(int style) = 0;\n\n    virtual float getNum3(int style) = 0;\n\n    virtual float getQuad(int style, int fontCode) = 0;\n\n    /**\n     * @return the point size of this TeXFont\n     */\n    virtual float getSize() = 0;\n\n    /**\n     * Get the kern amount of the character defined by the given CharFont\n     * followed by the \"skewChar\" of it's font. This is used in the algorithm\n     * for placing an accent above a single character.\n     * @param cf\n     *      the character an it's font above which an accent has to be placed\n     * @param style\n     *      the render style\n     * @return the kern amount of the character defined by cf followed by the\n     * \"skewChar\" of it's font\n     */\n    virtual float getSkew(const CharFont& cf, int style) = 0;\n\n    virtual float getSpace(int style) = 0;\n\n    virtual float getSub1(int style) = 0;\n\n    virtual float getSub2(int style) = 0;\n\n    virtual float getSubDrop(int style) = 0;\n\n    virtual float getSup1(int style) = 0;\n\n    virtual float getSup2(int style) = 0;\n\n    virtual float getSup3(int style) = 0;\n\n    virtual float getSupDrop(int style) = 0;\n\n    virtual float getXHeight(int style, int fontCode) = 0;\n\n    virtual float getEM(int style) = 0;\n\n    /**\n     * Test if a character has larger version.\n     * \n     * @param c\n     *      a character\n     * @return true if the given character has a larger version, false otherwise\n     */\n    virtual bool hasNextLarger(const Char& c) = 0;\n\n    virtual bool hasSpace(int font) = 0;\n\n    virtual void setBold(bool bold) = 0;\n\n    virtual bool getBold() = 0;\n\n    virtual void setRoman(bool rm) = 0;\n\n    virtual bool getRoman() = 0;\n\n    virtual void setTt(bool tt) = 0;\n\n    virtual bool getTt() = 0;\n\n    virtual void setIt(bool it) = 0;\n\n    virtual bool getIt() = 0;\n\n    virtual void setSs(bool ss) = 0;\n\n    virtual bool getSs() = 0;\n\n    /**\n     * Test if the given character is an extension character.\n     * \n     * @param c\n     *      a character\n     * @return true if the given character contains extension information to\n     * build an arbitrary large version of this character.\n     */\n    virtual bool isExtensionChar(const Char& c) = 0;\n\n    virtual sptr<TeXFont> copy() = 0;\n\n    virtual ~TeXFont();\n};\n\ntypedef struct {\n    int font;\n    int code;\n    string name;\n} __symbol_component;\n\nclass SymbolsSet;\n\n/**\n * The default implementation of the TeXFont-interface.\n */\nclass DefaultTeXFont : public TeXFont {\nprivate:\n    // font related\n    static string* _defaultTextStyleMappings;\n    static map<string, vector<CharFont*>> _textStyleMappings;\n    static map<string, sptr<CharFont>> _symbolMappings;\n    static map<string, float> _parameters;\n    static map<string, float> _generalSettings;\n    static bool _magnificationEnable;\n\n    float _factor, _size;\n\n    Char getChar(wchar_t c, _in_ const vector<CharFont*>& cf, int style);\n\n    sptr<Metrics> getMetrics(_in_ const CharFont& cf, float size);\n\n    inline FontInfo* getInfo(int id) { return FontInfo::__get(id); }\n\n    static void __default_general_settings();\n\n    static void __default_text_style_mapping();\n\npublic:\n    static vector<UnicodeBlock> _loadedAlphabets;\n    static map<UnicodeBlock, AlphabetRegistration*> _registeredAlphabets;\n    // no extension part for that kind (TOP, MID, REP or BOT)\n    static const int NONE;\n\n    // font type\n    static const int NUMBERS, CAPITAL, SMALL, UNICODE;\n    // font information\n    static const int WIDTH, HEIGHT, DEPTH, IT;\n    // extensions\n    static const int TOP, MID, REP, BOT;\n\n    bool _isBold, _isRoman, _isSs, _isTt, _isIt;\n\n    DefaultTeXFont(\n        float pointSize,\n        float f = 1,\n        bool b = false,\n        bool rm = false,\n        bool ss = false,\n        bool tt = false,\n        bool it = false)\n        : _size(pointSize),\n          _factor(f),\n          _isBold(b),\n          _isRoman(rm),\n          _isSs(ss),\n          _isTt(tt),\n          _isIt(it) {}\n\n    static void __register_symbols_set(const SymbolsSet& set);\n\n    static void __push_symbols(const __symbol_component* symbols, const int len);\n\n    static void addTeXFontDescription(const string& base, const string& file) throw(ex_res_parse);\n\n    static void addAlphabet(AlphabetRegistration* reg);\n\n    static void addAlphabet(\n        const string& base,\n        const vector<UnicodeBlock>& alphabet,\n        const string& lang) throw(ex_res_parse);\n\n    static void registerAlphabet(AlphabetRegistration* reg);\n\n    inline static float getParameter(const string& name) {\n        auto it = _parameters.find(name);\n        if (it == _parameters.end()) return 0;\n        return it->second;\n    }\n\n    /**\n     * Get the size factor of given style\n     */\n    inline static float getSizeFactor(int style) {\n        if (style < STYLE_TEXT) return 1;\n        if (style < STYLE_SCRIPT) return _generalSettings[\"textfactor\"];\n        if (style < STYLE_SCRIPT_SCRIPT) return _generalSettings[\"scriptfactor\"];\n        return _generalSettings[\"scriptscriptfactor\"];\n    }\n\n    inline float styleParam(const string& name, int style) {\n        return getParameter(name) * getSizeFactor(style) * TeXFormula::PIXELS_PER_POINT;\n    }\n\n    /************************************ get char ************************************************/\n\n    Char getDefaultChar(wchar_t c, int style) override;\n\n    Char getChar(\n        wchar_t c,\n        const string& textStyle,\n        int style) throw(ex_text_style_mapping_not_found) override;\n\n    Char getChar(const CharFont& cf, int style) override;\n\n    Char getChar(const string& symbolName, int style) throw(ex_symbol_mapping_not_found) override;\n\n    /*********************************** font information *****************************************/\n\n    Extension* getExtension(_in_ const Char& c, int style) override;\n\n    float getKern(_in_ const CharFont& left, _in_ const CharFont& right, int style) override;\n\n    sptr<CharFont> getLigature(_in_ const CharFont& left, _in_ const CharFont& right) override;\n\n    Char getNextLarger(_in_ const Char& c, int style) override;\n\n    inline sptr<TeXFont> copy() override;\n\n    inline float getScaleFactor() override { return _factor; }\n\n    inline float getAxisHeight(int style) override { return styleParam(\"axisheight\", style); }\n\n    inline float getBigOpSpacing1(int style) override { return styleParam(\"bigopspacing1\", style); }\n\n    inline float getBigOpSpacing2(int style) override { return styleParam(\"bigopspacing2\", style); }\n\n    inline float getBigOpSpacing3(int style) override { return styleParam(\"bigopspacing3\", style); }\n\n    inline float getBigOpSpacing4(int style) override { return styleParam(\"bigopspacing4\", style); }\n\n    inline float getBigOpSpacing5(int style) override { return styleParam(\"bigopspacing5\", style); }\n\n    inline float getNum1(int style) override { return styleParam(\"num1\", style); }\n\n    inline float getNum2(int style) override { return styleParam(\"num2\", style); }\n\n    inline float getNum3(int style) override { return styleParam(\"num3\", style); }\n\n    inline float getSub1(int style) override { return styleParam(\"sub1\", style); }\n\n    inline float getSub2(int style) override { return styleParam(\"sub2\", style); }\n\n    inline float getSubDrop(int style) override { return styleParam(\"subdrop\", style); }\n\n    inline float getSup1(int style) override { return styleParam(\"sup1\", style); }\n\n    inline float getSup2(int style) override { return styleParam(\"sup2\", style); }\n\n    inline float getSup3(int style) override { return styleParam(\"sup3\", style); }\n\n    inline float getSupDrop(int style) override { return styleParam(\"supdrop\", style); }\n\n    inline float getDenom1(int style) override { return styleParam(\"denom1\", style); }\n\n    inline float getDenom2(int style) override { return styleParam(\"denom2\", style); }\n\n    inline float getDefaultRuleThickness(int style) override {\n        return styleParam(\"defaultrulethickness\", style);\n    }\n\n    inline float getQuad(int style, int fontCode) override {\n        return getInfo(fontCode)->getQuad(getSizeFactor(style) * TeXFormula::PIXELS_PER_POINT);\n    }\n\n    int getMuFontId() override;\n\n    inline float getSize() override { return _size; }\n\n    inline float getSkew(_in_ const CharFont& cf, int style) override {\n        FontInfo* info = getInfo(cf._fontId);\n        wchar_t skew = info->getSkewChar();\n        if (skew == -1) return 0;\n        return getKern(cf, CharFont(skew, cf._fontId), style);\n    }\n\n    inline float getSpace(int style) override;\n\n    inline float getXHeight(int style, int fontCode) override {\n        FontInfo* info = getInfo(fontCode);\n        return info->getXHeight(getSizeFactor(style) * TeXFormula::PIXELS_PER_POINT);\n    }\n\n    inline float getEM(int style) override {\n        return getSizeFactor(style) * TeXFormula::PIXELS_PER_POINT;\n    }\n\n    inline bool hasNextLarger(_in_ const Char& c) override {\n        FontInfo* info = getInfo(c.getFontCode());\n        return info->hasNextLarger(c.getChar());\n    }\n\n    inline void setBold(bool bold) override { _isBold = bold; }\n\n    inline bool getBold() override { return _isBold; }\n\n    inline void setRoman(bool rm) override { _isRoman = rm; }\n\n    inline bool getRoman() override { return _isRoman; }\n\n    inline void setTt(bool tt) override { _isTt = tt; }\n\n    inline bool getTt() override { return _isTt; }\n\n    inline void setSs(bool ss) override { _isSs = ss; }\n\n    inline bool getSs() override { return _isSs; }\n\n    inline void setIt(bool it) override { _isIt = it; }\n\n    inline bool getIt() override { return _isIt; }\n\n    inline bool hasSpace(int font) override {\n        FontInfo* info = getInfo(font);\n        return info->hasSpace();\n    }\n\n    inline bool isExtensionChar(_in_ const Char& c) override {\n        FontInfo* info = getInfo(c.getFontCode());\n        return info->isExtensionChar(c.getChar());\n    }\n\n    /**\n     * Set the various sizes of the envrionment\n     */\n    static void setMathSizes(\n        float defaultSize,\n        float textStyleSize,\n        float scriptStyleSize,\n        float scriptsScriptStyleSize);\n\n    static void setMagnification(float mag);\n\n    static void enableMagnification(bool b);\n\n    /**\n     * initialize the class (actually load resources), must be called before use\n     */\n    static void _init_();\n\n    static void _free_();\n\n    virtual ~DefaultTeXFont();\n\n#ifdef HAVE_LOG\n    static void log();\n#endif\n};\n\n}  // namespace tex\n\n#endif  // FONTS_H_INCLUDED\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/fonts/symbol_reg.h",
    "content": "#ifndef SYMBOL_REG_H_INCLUDED\n#define SYMBOL_REG_H_INCLUDED\n\n#include <vector>\n\nusing namespace std;\n\nnamespace tex {\n\n/** Symbols registration function */\ntypedef void (*__reg_symbols_func)(void);\n\n/** Represents a set of symbols registration */\nclass SymbolsSet {\npublic:\n    virtual vector<__reg_symbols_func> regs() const = 0;\n};\n\n}  // namespace tex\n\n#define __symbols_reg(name) \\\n    __reg_symbols_##name\n\n#define DECL_SYMBOLS_REG(name) \\\n    extern void __symbols_reg(name)()\n\n#define DECL_SYMBOLS_SET(name)                                              \\\n    class SymbolsSet##name : public tex::SymbolsSet {                       \\\n    public:                                                                 \\\n        virtual std::vector<tex::__reg_symbols_func> regs() const override; \\\n    };\n\n#define REG_SYMBOLS(name) \\\n    __symbols_reg(name),\n\n#define DEF_SYMBOLS_SET(name)                                             \\\n    std::vector<tex::__reg_symbols_func> SymbolsSet##name::regs() const { \\\n        return {\n#define END_DEF_SYMBOLS_SET \\\n    }                       \\\n    ;                       \\\n    }\n\n#endif\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/graphic/graphic.h",
    "content": "#ifndef GRAPHIC_H_INCLUDED\n#define GRAPHIC_H_INCLUDED\n\n#include \"graphic/graphic_basic.h\"\n\nusing namespace std;\nusing namespace tex;\n\nnamespace tex {\n\nclass Graphics2D;\n\nenum TypefaceStyle {\n    PLAIN = 0,\n    BOLD = 1,\n    ITALIC = 2,\n    BOLDITALIC = BOLD | ITALIC\n};\n\n/**\n * Abstract class represents a font.\n */\nclass Font {\npublic:\n    /**\n     * Get the font size\n     */\n    virtual float getSize() const = 0;\n\n    /**\n     * Derive font from current font with given style\n     *\n     * @param style\n     *      required style, defined in enum TypefaceStyle,\n     *      we use integer type to represents style here\n     */\n    virtual sptr<Font> deriveFont(int style) const = 0;\n\n    /**\n     * Check if current font equals another\n     */\n    virtual bool operator==(const Font& f) const = 0;\n\n    /**\n     * Check if current font not equals another\n     */\n    virtual bool operator!=(const Font& f) const = 0;\n\n    /**\n     * Create font from file\n     * \n     * @param file\n     *      the path of the font file\n     * @param size\n     *      required font size\n     */\n    static Font* create(const string& file, float size);\n\n    /**\n     * Create font with given name, style and size\n     *\n     * @param name\n     *      the font name\n     * @param style\n     *      the font style\n     * @param size\n     *      the font size\n     */\n    static sptr<Font> _create(const string& name, int style, float size);\n};\n\n/**\n * To layout the text that the program cannot recognize.\n */\nclass TextLayout {\npublic:\n    /**\n     * Get the layout bounds with current text and font\n     *\n     * @param bounds\n     *      rectangle to retrieve the bounds\n     */\n    virtual void getBounds(_out_ Rect& bounds) = 0;\n\n    /**\n     * Draw the layout\n     *\n     * @param g2\n     *      the graphics (2D) context\n     * @param x\n     *      the x coordinate\n     * @param y\n     *      the y coordinate, is basline aligned\n     */\n    virtual void draw(Graphics2D& g2, float x, float y) = 0;\n\n    /**\n     * Create a TextLayout with given text and font\n     *\n     * @param src\n     *      the text to layout\n     * @param font\n     *      the specified font\n     * @return\n     *      new TextLayout\n     */\n    static sptr<TextLayout> create(const wstring& src, const sptr<Font>& font);\n};\n\n/**\n * Abstract class to represents a graphics (2D) context, all the TeX drawing operations will on it.\n * It must have scale, translation, and rotation support. You should notice that the scaling on\n * y-direction will be selected as the base if they are different on x and y-direction when drawing\n * characters. In most cases, you should never use different scalings, unless you are really sure the\n * coordinates are correct (i.e. draw a hyphen).\n */\nclass Graphics2D {\npublic:\n    /**\n     * Set the color of the context\n     * \n     * @param c\n     *      required color\n     */\n    virtual void setColor(color c) = 0;\n\n    /**\n     * Get the color of the context\n     */\n    virtual color getColor() const = 0;\n\n    /**\n     * Set the stroke of the context\n     */\n    virtual void setStroke(const Stroke& s) = 0;\n\n    /**\n     * Get the stroke of the context\n     */\n    virtual const Stroke& getStroke() const = 0;\n\n    /**\n     * Set the stroke width of the context\n     */\n    virtual void setStrokeWidth(float w) = 0;\n\n    /**\n     * Get the current font\n     */\n    virtual const Font* getFont() const = 0;\n\n    /**\n     * Set the font of the context\n     */\n    virtual void setFont(const Font* font) = 0;\n\n    /**\n     * Translate the context with distance dx, dy\n     *\n     * @param dx\n     *      distance in x-direction to translate\n     * @param dy\n     *      distance in y-direction to translate\n     */\n    virtual void translate(float dx, float dy) = 0;\n\n    /**\n     * Scale the context with sx, sy\n     *\n     * @param sx\n     *      scale ratio in x-direction\n     * @param sy\n     *      scale ratio in y-direction\n     */\n    virtual void scale(float sx, float sy) = 0;\n\n    /**\n     * Rotate the context with the given angle (in radian), with pivot (0, 0).\n     *\n     * @param angle\n     *      angle (in radian) amount to rotate\n     */\n    virtual void rotate(float angle) = 0;\n\n    /**\n     * Rotate the context with the given angle (in radian), with pivot (px, py).\n     *\n     * @param angle\n     *      angle (in radian) amount to rotate\n     * @param px\n     *      pivot in x-direction\n     * @param py\n     *      pivot in y-direction\n     */\n    virtual void rotate(float angle, float px, float py) = 0;\n\n    /**\n     * Reset transformations\n     */\n    virtual void reset() = 0;\n\n    /**\n     * Get the scale of the context in x-direction\n     *\n     * @return the scale in x-direction\n     */\n    virtual float sx() const = 0;\n\n    /**\n     * Get the scale of the context in y-direction\n     *\n     * @return the scale in y-direction\n     */\n    virtual float sy() const = 0;\n\n    /**\n     * Draw character, is baseline aligned\n     * \n     * @param c\n     *      specified character\n     * @param x\n     *      x-coordinate\n     * @param y\n     *      y-coordinate, is baseline aligned\n     */\n    virtual void drawChar(wchar_t c, float x, float y) = 0;\n\n    /**\n     * Draw text, is baseline aligned\n     * \n     * @param c\n     *      specified text\n     * @param x\n     *      x-coordinate\n     * @param y\n     *      y-coordinate, is baseline aligned\n     */\n    virtual void drawText(const wstring& c, float x, float y) = 0;\n\n    /**\n     * Draw line\n     * \n     * @param x1\n     *      start point in x-direction\n     * @param y1\n     *      start point in y-direction\n     * @param x2\n     *      end point in x-direction\n     * @param y2\n     *      end point in y-direction\n     */\n    virtual void drawLine(float x1, float y1, float x2, float y2) = 0;\n\n    /**\n     * Draw rectangle\n     *\n     * @param x\n     *      left position\n     * @param y\n     *      top position\n     * @param w\n     *      width\n     * @param h\n     *      height\n     */\n    virtual void drawRect(float x, float y, float w, float h) = 0;\n\n    /**\n     * Fill rectangle\n     *\n     * @param x\n     *      left position\n     * @param y\n     *      top position\n     * @param w\n     *      width\n     * @param h\n     *      height\n     */\n    virtual void fillRect(float x, float y, float w, float h) = 0;\n\n    /**\n     * Draw round rectangle\n     *\n     * @param x\n     *      left position\n     * @param y\n     *      top position\n     * @param w\n     *      width\n     * @param h\n     *      height\n     * @param rx\n     *      radius in x-direction\n     * @param ry\n     *      radius in y-direction\n     */\n    virtual void drawRoundRect(float x, float y, float w, float h, float rx, float ry) = 0;\n\n    /**\n     * Fill round rectangle\n     *\n     * @param x\n     *      left position\n     * @param y\n     *      top position\n     * @param w\n     *      width\n     * @param h\n     *      height\n     * @param rx\n     *      radius in x-direction\n     * @param ry\n     *      radius in y-direction\n     */\n    virtual void fillRoundRect(float x, float y, float w, float h, float rx, float ry) = 0;\n};\n\n}  // namespace tex\n\n#endif  // GRAPHIC_H_INCLUDED\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/graphic/graphic_basic.h",
    "content": "#ifndef GRAPHIC_BASIC_H_INCLUDED\n#define GRAPHIC_BASIC_H_INCLUDED\n\n#include <sstream>\n#include <string>\n#include \"common.h\"\n\nusing namespace std;\nusing namespace tex;\n\nnamespace tex {\n\ntypedef unsigned int color;\n\nstatic const color trans = 0x00000000;\nstatic const color black = 0xff000000;\nstatic const color white = 0xffffffff;\nstatic const color red = 0xffff0000;\nstatic const color green = 0xff00ff00;\nstatic const color blue = 0xff0000ff;\nstatic const color yellow = 0xffffff00;\nstatic const color cyan = 0xff00ffff;\nstatic const color magenta = 0xffff00ff;\n\nstatic const color TRANS = trans;\nstatic const color BLACK = black;\nstatic const color WHITE = white;\nstatic const color RED = red;\nstatic const color GREEN = green;\nstatic const color BLUE = blue;\nstatic const color YELLOW = yellow;\nstatic const color CYAN = cyan;\nstatic const color MAGENTA = magenta;\n\ninline color argb(int a, int r, int g, int b) {\n    return (a << 24) | (r << 16) | (g << 8) | b;\n}\n\ninline color rgb(int r, int g, int b) {\n    return argb(0xff, r, g, b);\n}\n\ninline color argb(float a, float r, float g, float b) {\n    return argb((int)(a * 255), (int)(r * 255), (int)(g * 255), (int)(b * 255));\n}\n\ninline color rgb(float r, float g, float b) {\n    return argb(1.f, r, g, b);\n}\n\ninline int color_a(color c) {\n    return c >> 24;\n}\n\ninline int color_r(color c) {\n    return c >> 16 & 0x00ff;\n}\n\ninline int color_g(color c) {\n    return c >> 8 & 0x0000ff;\n}\n\ninline int color_b(color c) {\n    return c & 0x000000ff;\n}\n\ninline color cmyk(float c, float m, float y, float k) {\n    float kk = 1.f - k;\n    return rgb(kk * (1 - c), kk * (1 - m), kk * (1 - y));\n}\n\n/**\n * Test if the given color is transparent\n */\ninline bool istrans(color c) {\n    return (c >> 24 == 0);\n}\n\n/**\n * Convert #AARRGGBB or #RRGGBB formatted string into color.\n */\ninline color decode(const string& s) {\n    if (s[0] == '#') {\n        const string x = s.substr(1);\n        stringstream ss;\n        ss << std::hex << x;\n        color c;\n        ss >> c;\n        if (s.size() == 7) {\n            // set alpha value\n            c |= 0xff000000;\n        } else if (s.size() != 9) {\n            return black;\n        }\n        return c;\n    }\n    return black;\n}\n\nstruct Point {\n    float x, y;\n\n    Point() : x(0), y(0) {}\n\n    Point(float x1, float y1) : x(x1), y(y1) {}\n};\n\nstruct Rect {\n    float x, y, w, h;\n\n    Rect() : x(0), y(0), w(0), h(0) {}\n\n    Rect(float x1, float y1, float w1, float h1) : x(x1), y(y1), w(w1), h(h1) {}\n};\n\nstruct Insets {\n    int left, top, right, bottom;\n\n    Insets() : left(0), top(0), right(0), bottom(0) {}\n\n    Insets(int t, int l, int b, int r) : left(t), top(t), right(r), bottom(b) {}\n\n    void set(int t, int l, int b, int r) {\n        left = l;\n        top = t;\n        right = r;\n        bottom = b;\n    }\n\n    Insets& operator+=(const int offset) {\n        left += offset;\n        top += offset;\n        right += offset;\n        bottom += offset;\n        return *this;\n    }\n};\n\nenum Cap {\n    CAP_BUTT,\n    CAP_ROUND,\n    CAP_SQUARE\n};\nenum Join {\n    JOIN_BEVEL,\n    JOIN_MITER,\n    JOIN_ROUND\n};\n\nstruct Stroke {\n    float lineWidth;\n    float miterLimit;\n    Cap cap;\n    Join join;\n\n    Stroke()\n        : lineWidth(1.f), cap(CAP_ROUND), join(JOIN_ROUND), miterLimit(0) {}\n\n    Stroke(float w, Cap c, Join j, float ml = 0)\n        : lineWidth(w), cap(c), join(j), miterLimit(ml) {}\n\n    void setStroke(float w, Cap c, Join j, float ml = 0) {\n        lineWidth = w;\n        cap = c;\n        join = j;\n        miterLimit = ml;\n    }\n};\n\n}  // namespace tex\n\n#endif  // GRAPHIC_BASIC_H_INCLUDED\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/latex.cpp",
    "content": "#include \"latex.h\"\n#include \"core/core.h\"\n#include \"core/formula.h\"\n#include \"core/macro.h\"\n#include \"fonts/fonts.h\"\n\nusing namespace std;\nusing namespace tex;\n\nstring tex::RES_BASE = \"res\";\n\nTeXFormula* LaTeX::_formula = nullptr;\nTeXRenderBuilder* LaTeX::_builder = nullptr;\n\nvoid LaTeX::init(const string& res_root_path) {\n    RES_BASE = res_root_path;\n    if (_formula != nullptr) return;\n\n    NewCommandMacro::_init_();\n    DefaultTeXFont::_init_();\n    SymbolAtom::_init_();\n    Glue::_init_();\n    TeXFormula::_init_();\n    TextRenderingBox::_init_();\n\n    _formula = new TeXFormula();\n    _builder = new TeXRenderBuilder();\n}\n\nvoid LaTeX::release() {\n    DefaultTeXFont::_free_();\n    TeXFormula::_free_();\n    NewCommandMacro::_free_();\n    TextRenderingBox::_free_();\n\n    if (_formula != nullptr) {\n        delete _formula;\n        _formula = nullptr;\n    }\n    if (_builder != nullptr) {\n        delete _builder;\n        _builder = nullptr;\n    }\n}\n\nvoid LaTeX::releaseGlueAndMacroInfo() {\n    Glue::_free_();\n    MacroInfo::_free_();\n}\n\nconst string& LaTeX::getResRootPath() {\n    return RES_BASE;\n}\n\nvoid LaTeX::setDebug(bool debug) {\n    TeXFormula::setDEBUG(debug);\n}\n\nTeXRender* LaTeX::parse(const wstring& latex, int width, float textSize, float lineSpace, color fg) {\n    bool lined = true;\n    if (startswith(latex, L\"$$\") || startswith(latex, L\"\\\\[\")) {\n        lined = false;\n    }\n    int align = lined ? ALIGN_LEFT : ALIGN_CENTER;\n    _formula->setLaTeX(latex);\n    TeXRender* render =\n        _builder->setStyle(STYLE_DISPLAY)\n            .setTextSize(textSize)\n            .setWidth(UNIT_PIXEL, width, align)\n            .setIsMaxWidth(lined)\n            .setLineSpace(UNIT_PIXEL, lineSpace)\n            .setForeground(fg)\n            .build(*_formula);\n    return render;\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/latex.h",
    "content": "#ifndef LATEX_H_INCLUDED\n#define LATEX_H_INCLUDED\n\n#include \"common.h\"\n#include \"graphic/graphic.h\"\n#include \"graphic/graphic_basic.h\"\n#include \"render.h\"\n\n#include <string>\n\nusing namespace std;\nusing namespace tex;\n\nnamespace tex {\n\nclass TeXFormula;\n\nclass LaTeX {\nprivate:\n    static TeXFormula* _formula;\n    static TeXRenderBuilder* _builder;\n\npublic:\n    /**\n     * Initialize TeX context with given root path of the TeX resources\n     *\n     * @param res_root_path\n     *      root path of the resources, default is 'res'\n     */\n    static void init(const string& res_root_path = \"res\");\n\n    /**\n     * Get the root path of the \"TeX resources\"\n     */\n    static const string& getResRootPath();\n\n    /**\n     * If open debug\n     */\n    static void setDebug(bool debug);\n\n    /**\n     * Parse TeX formatted string to TeXRender\n     *\n     * @param tex\n     *      the TeX formatted string\n     * @param width\n     *      the width of the 2D graphics context\n     * @param textSize\n     *      the text size\n     * @param lineSpace\n     *      the line space\n     * @param fg\n     *      the foreground color\n     */\n    static TeXRender* parse(const wstring& tex, int width, float textSize, float lineSpace, color fg);\n\n    /**\n     * Release the LaTeX context\n     */\n    static void release();\n\n    /**\n     * Release the LaTeX releaseGlueAndMacroInfo\n     */\n    static void releaseGlueAndMacroInfo();\n};\n\n}  // namespace tex\n\n#endif  // LATEX_H_INCLUDED\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/platform/cairo/graphic_cairo.cpp",
    "content": "#include \"config.h\"\n\n#if defined(__OS_Linux__) && !defined(MEM_CHECK)\n\n#include \"platform/cairo/graphic_cairo.h\"\n\n#include <fontconfig/fontconfig.h>\n\nusing namespace tex;\nusing namespace std;\n\nmap<string, string> Font_cairo::_file_name_map;\n\nFont_cairo::Font_cairo(const string& family, int style, float size)\n    : _family(family), _style(style), _size((double)size) {}\n\nFont_cairo::Font_cairo(const string& file, float size) : Font_cairo(\"\", PLAIN, size) {\n    loadFont(file);\n}\n\nvoid Font_cairo::loadFont(const string& file) {\n    auto it = _file_name_map.find(file);\n    if (it != _file_name_map.end()) {\n        // already loaded\n        _family = _file_name_map[file];\n#ifdef HAVE_LOG\n        __log << file << \" already loaded, skip\\n\";\n#endif\n        return;\n    }\n    const FcChar8* f = (const FcChar8*)file.c_str();\n\n    // get font family from file first\n    int count;\n    FcChar8* family = NULL;\n    FcBlanks* blanks = FcConfigGetBlanks(NULL);\n    FcPattern* p = FcFreeTypeQuery(f, 0, blanks, &count);\n    FcPatternGetString(p, FC_FAMILY, 0, &family);\n#ifdef HAVE_LOG\n    __dbg(\"Load font: %s, count: %d\\n\", file.c_str(), count);\n    FcPatternPrint(p);\n#endif\n\n    // load font to fontconfig\n    FcBool status = FcConfigAppFontAddFile(NULL, f);\n#ifdef HAVE_LOG\n    if (!status) __dbg(ANSI_COLOR_RED \"Load %s failed\\n\" ANSI_RESET, file.c_str());\n#endif\n\n    _family = (const char*)family;\n    _file_name_map[file] = _family;\n\n    // release\n    FcPatternDestroy(p);\n}\n\nstring Font_cairo::getFamily() const {\n    return _family;\n}\n\nint Font_cairo::getStyle() const {\n    return _style;\n}\n\nfloat Font_cairo::getSize() const {\n    return (float)_size;\n}\n\nsptr<Font> Font_cairo::deriveFont(int style) const {\n    return sptr<Font>(new Font_cairo(_family, style, _size));\n}\n\nbool Font_cairo::operator==(const Font& ft) const {\n    const Font_cairo& f = static_cast<const Font_cairo&>(ft);\n    return _size == f._size && _style == f._style && _family == f._family;\n}\n\nbool Font_cairo::operator!=(const Font& f) const {\n    return !(*this == f);\n}\n\nFont* Font::create(const string& file, float size) {\n    return new Font_cairo(file, size);\n}\n\nsptr<Font> Font::_create(const string& name, int style, float size) {\n    return sptr<Font>(new Font_cairo(name, style, size));\n}\n\n/**************************************************************************************************/\n\nCairo::RefPtr<Cairo::Context> TextLayout_cairo::_img_context;\n\nTextLayout_cairo::TextLayout_cairo(const wstring& src, const sptr<Font_cairo>& f) {\n    if (!_img_context) {\n        auto surface = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, 1, 1);\n        _img_context = Cairo::Context::create(surface);\n    }\n\n    _layout = Pango::Layout::create(_img_context);\n\n    Pango::FontDescription fd;\n    fd.set_family(f->getFamily());\n    fd.set_absolute_size(f->getSize() * Pango::SCALE);\n    fd.set_style(Pango::STYLE_NORMAL);\n    fd.set_weight(Pango::WEIGHT_NORMAL);\n\n    switch (f->getStyle()) {\n    case BOLD:\n        fd.set_weight(Pango::WEIGHT_BOLD);\n        break;\n    case ITALIC:\n        fd.set_style(Pango::STYLE_ITALIC);\n        break;\n    case BOLDITALIC:\n        fd.set_style(Pango::STYLE_ITALIC);\n        fd.set_weight(Pango::WEIGHT_BOLD);\n        break;\n    }\n\n    _layout->set_text(wide2utf8(src.c_str()));\n    _layout->set_font_description(fd);\n\n    _ascent = (float)(_layout->get_baseline() / Pango::SCALE);\n}\n\nvoid TextLayout_cairo::getBounds(_out_ Rect& r) {\n    int w, h;\n    _layout->get_pixel_size(w, h);\n    r.x = 0;\n    r.y = -_ascent;\n    r.w = (float)w;\n    r.h = (float)h;\n}\n\nvoid TextLayout_cairo::draw(Graphics2D& g2, float x, float y) {\n    // FIXME\n    // draw line, I don't know why the layout is shown in wrong position\n    // when line was not drawn\n    color old = g2.getColor();\n    g2.setColor(0x00000000);\n    g2.drawLine(x, y, x + 1, y);\n    // draw layout\n    g2.setColor(old);\n    g2.translate(x, y - _ascent);\n    Graphics2D_cairo& g = static_cast<Graphics2D_cairo&>(g2);\n    _layout->show_in_cairo_context(g.getCairoContext());\n    g2.translate(-x, -y + _ascent);\n}\n\nsptr<TextLayout> TextLayout::create(const wstring& src, const sptr<Font>& font) {\n    sptr<Font_cairo> f = static_pointer_cast<Font_cairo>(font);\n    return sptr<TextLayout>(new TextLayout_cairo(src, f));\n}\n\n/**************************************************************************************************/\n\nFont_cairo Graphics2D_cairo::_default_font(\"SansSerif\", PLAIN, 20.f);\n\nGraphics2D_cairo::Graphics2D_cairo(const Cairo::RefPtr<Cairo::Context>& context)\n    : _context(context) {\n    _sx = _sy = 1.f;\n    setColor(BLACK);\n    setStroke(Stroke());\n    setFont(&_default_font);\n}\n\nconst Cairo::RefPtr<Cairo::Context>& Graphics2D_cairo::getCairoContext() const {\n    return _context;\n}\n\nvoid Graphics2D_cairo::setColor(color c) {\n    _color = c;\n    const double a = color_a(c) / 255.;\n    const double r = color_r(c) / 255.;\n    const double g = color_g(c) / 255.;\n    const double b = color_b(c) / 255.;\n    _context->set_source_rgba(r, g, b, a);\n}\n\ncolor Graphics2D_cairo::getColor() const {\n    return _color;\n}\n\nvoid Graphics2D_cairo::setStroke(const Stroke& s) {\n    _stroke = s;\n    _context->set_line_width((double)s.lineWidth);\n\n    // convert abstract line cap to platform line cap\n    Cairo::LineCap c;\n    switch (s.cap) {\n    case CAP_BUTT:\n        c = Cairo::LINE_CAP_BUTT;\n        break;\n    case CAP_ROUND:\n        c = Cairo::LINE_CAP_ROUND;\n        break;\n    case CAP_SQUARE:\n        c = Cairo::LINE_CAP_SQUARE;\n        break;\n    }\n    _context->set_line_cap(c);\n\n    // conver abstract line join to platform line join\n    Cairo::LineJoin j;\n    switch (s.join) {\n    case JOIN_BEVEL:\n        j = Cairo::LINE_JOIN_BEVEL;\n        break;\n    case JOIN_ROUND:\n        j = Cairo::LINE_JOIN_ROUND;\n        break;\n    case JOIN_MITER:\n        j = Cairo::LINE_JOIN_MITER;\n        break;\n    }\n    _context->set_line_join(j);\n\n    _context->set_miter_limit((double)s.miterLimit);\n}\n\nconst Stroke& Graphics2D_cairo::getStroke() const {\n    return _stroke;\n}\n\nvoid Graphics2D_cairo::setStrokeWidth(float w) {\n    _stroke.lineWidth = w;\n    _context->set_line_width((double)w);\n}\n\nconst Font* Graphics2D_cairo::getFont() const {\n    return _font;\n}\n\nvoid Graphics2D_cairo::setFont(const Font* font) {\n    _font = static_cast<const Font_cairo*>(font);\n}\n\nvoid Graphics2D_cairo::translate(float dx, float dy) {\n    _context->translate((double)dx, (double)dy);\n}\n\nvoid Graphics2D_cairo::scale(float sx, float sy) {\n    _sx *= sx;\n    _sy *= sy;\n    _context->scale((double)sx, (double)sy);\n}\n\nvoid Graphics2D_cairo::rotate(float angle) {\n    _context->rotate(angle);\n}\n\nvoid Graphics2D_cairo::rotate(float angle, float px, float py) {\n    _context->translate((double)px, (double)py);\n    _context->rotate(angle);\n    _context->translate((double)-px, (double)-py);\n}\n\nvoid Graphics2D_cairo::reset() {\n    _context->set_identity_matrix();\n    _sx = _sy = 1.f;\n}\n\nfloat Graphics2D_cairo::sx() const {\n    return _sx;\n}\n\nfloat Graphics2D_cairo::sy() const {\n    return _sy;\n}\n\nvoid Graphics2D_cairo::drawChar(wchar_t c, float x, float y) {\n    wstring str = {c, L'\\0'};\n    drawText(str, x, y);\n}\n\nvoid Graphics2D_cairo::drawText(const wstring& t, float x, float y) {\n    Cairo::FontSlant slant = Cairo::FONT_SLANT_NORMAL;\n    Cairo::FontWeight weight = Cairo::FONT_WEIGHT_NORMAL;\n    switch (_font->getStyle()) {\n    case BOLD:\n        weight = Cairo::FONT_WEIGHT_BOLD;\n        break;\n    case ITALIC:\n        slant = Cairo::FONT_SLANT_ITALIC;\n        break;\n    case BOLDITALIC:\n        slant = Cairo::FONT_SLANT_ITALIC;\n        weight = Cairo::FONT_WEIGHT_BOLD;\n        break;\n    }\n    _context->select_font_face(_font->getFamily(), slant, weight);\n    _context->set_font_size(_font->getSize());\n    _context->move_to(x, y);\n    _context->show_text(wide2utf8(t.c_str()));\n}\n\nvoid Graphics2D_cairo::drawLine(float x1, float y1, float x2, float y2) {\n    _context->move_to(x1, y1);\n    _context->line_to(x2, y2);\n    _context->stroke();\n}\n\nvoid Graphics2D_cairo::drawRect(float x, float y, float w, float h) {\n    _context->rectangle(x, y, w, h);\n    _context->stroke();\n}\n\nvoid Graphics2D_cairo::fillRect(float x, float y, float w, float h) {\n    _context->rectangle(x, y, w, h);\n    _context->fill();\n}\n\nvoid Graphics2D_cairo::roundRect(float x, float y, float w, float h, float rx, float ry) {\n    double r = max(rx, ry);\n    double d = M_PI / 180.;\n    _context->begin_new_sub_path();\n    _context->arc(x + r, y + r, r, 180 * d, 270 * d);\n    _context->arc(x + w - r, y + r, r, -90 * d, 0);\n    _context->arc(x + w - r, y + h - r, r, 0, 90 * d);\n    _context->arc(x + r, y + h - r, r, 90 * d, 180 * d);\n    _context->close_path();\n}\n\nvoid Graphics2D_cairo::drawRoundRect(float x, float y, float w, float h, float rx, float ry) {\n    roundRect(x, y, w, h, rx, ry);\n    _context->stroke();\n}\n\nvoid Graphics2D_cairo::fillRoundRect(float x, float y, float w, float h, float rx, float ry) {\n    roundRect(x, y, w, h, rx, ry);\n    _context->fill();\n}\n\n#endif\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/platform/cairo/graphic_cairo.h",
    "content": "#include \"config.h\"\n\n#if defined(__OS_Linux__) && !defined(MEM_CHECK)\n\n#ifndef GRAPHIC_CAIRO_H_INCLUDED\n#define GRAPHIC_CAIRO_H_INCLUDED\n\n#include \"graphic/graphic.h\"\n\n#include <cairomm/context.h>\n#include <pangomm/fontdescription.h>\n#include <pangomm/layout.h>\n\nusing namespace std;\n\nnamespace tex {\n\nclass Font_cairo : public Font {\nprivate:\n    static map<string, string> _file_name_map;\n\n    int _style;\n    double _size;\n    string _family;\n\n    void loadFont(const string& file);\n\npublic:\n    Font_cairo(const string& family = \"\", int style = PLAIN, float size = 1.f);\n\n    Font_cairo(const string& file, float size);\n\n    string getFamily() const;\n\n    int getStyle() const;\n\n    virtual float getSize() const override;\n\n    virtual sptr<Font> deriveFont(int style) const override;\n\n    virtual bool operator==(const Font& f) const override;\n\n    virtual bool operator!=(const Font& f) const override;\n};\n\n/**************************************************************************************************/\n\nclass TextLayout_cairo : public TextLayout {\nprivate:\n    static Cairo::RefPtr<Cairo::Context> _img_context;\n    Glib::RefPtr<Pango::Layout> _layout;\n    float _ascent;\n\npublic:\n    TextLayout_cairo(const wstring& src, const sptr<Font_cairo>& font);\n\n    virtual void getBounds(_out_ Rect& r) override;\n\n    virtual void draw(Graphics2D& g2, float x, float y) override;\n};\n\n/**************************************************************************************************/\n\nclass Graphics2D_cairo : public Graphics2D {\nprivate:\n    static Font_cairo _default_font;\n\n    Cairo::RefPtr<Cairo::Context> _context;\n    color _color;\n    Stroke _stroke;\n    const Font_cairo* _font;\n    float _sx, _sy;\n\n    void roundRect(float x, float y, float w, float h, float rx, float ry);\n\npublic:\n    Graphics2D_cairo(const Cairo::RefPtr<Cairo::Context>& context);\n\n    const Cairo::RefPtr<Cairo::Context>& getCairoContext() const;\n\n    virtual void setColor(color c) override;\n\n    virtual color getColor() const override;\n\n    virtual void setStroke(const Stroke& s) override;\n\n    virtual const Stroke& getStroke() const override;\n\n    virtual void setStrokeWidth(float w) override;\n\n    virtual const Font* getFont() const override;\n\n    virtual void setFont(const Font* font) override;\n\n    virtual void translate(float dx, float dy) override;\n\n    virtual void scale(float sx, float sy) override;\n\n    virtual void rotate(float angle) override;\n\n    virtual void rotate(float angle, float px, float py) override;\n\n    virtual void reset() override;\n\n    virtual float sx() const override;\n\n    virtual float sy() const override;\n\n    virtual void drawChar(wchar_t c, float x, float y) override;\n\n    virtual void drawText(const wstring& t, float x, float y) override;\n\n    virtual void drawLine(float x, float y1, float x2, float y2) override;\n\n    virtual void drawRect(float x, float y, float w, float h) override;\n\n    virtual void fillRect(float x, float y, float w, float h) override;\n\n    virtual void drawRoundRect(float x, float y, float w, float h, float rx, float ry) override;\n\n    virtual void fillRoundRect(float x, float y, float w, float h, float rx, float ry) override;\n};\n\n}  // namespace tex\n\n#endif  // GRAPHIC_CAIRO_H_INCLUDED\n#endif  // __OS_Linux__ && !MEM_CHECK\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/platform/gdi_win/graphic_win32.cpp",
    "content": "#include \"config.h\"\n\n#if defined(__OS_Windows__) && !defined(MEM_CHECK)\n\n#include \"platform/gdi_win/graphic_win32.h\"\n\n#include <sstream>\n\n#include <gdiplus.h>\n#include <windows.h>\n\nusing namespace std;\nusing namespace tex;\n\n/**************************************************************************************************/\n\nint Font_win32::convertStyle(int style) {\n    int s;\n    switch (style) {\n    case PLAIN:\n        s = Gdiplus::FontStyleRegular;\n        break;\n    case BOLD:\n        s = Gdiplus::FontStyleBold;\n        break;\n    case ITALIC:\n        s = Gdiplus::FontStyleItalic;\n        break;\n    case BOLDITALIC:\n        s = Gdiplus::FontStyleBoldItalic;\n        break;\n    default:\n        s = -1;\n        break;\n    }\n    return s;\n}\n\nconst Gdiplus::FontFamily* Font_win32::_serif;\nconst Gdiplus::FontFamily* Font_win32::_sansserif;\n\nFont_win32::~Font_win32() {\n    if (_family == _serif || _family == _sansserif) {\n        return;\n    }\n    delete _family;\n}\n\nFont_win32::Font_win32() : _size(0) {}\n\nFont_win32::Font_win32(const string& name, int style, float size) : _size(size) {\n    if (_serif == nullptr) {\n        _serif = Gdiplus::FontFamily::GenericSerif();\n        _sansserif = Gdiplus::FontFamily::GenericSansSerif();\n    }\n    const Gdiplus::FontFamily* f = nullptr;\n    if (name == \"Serif\" || name == \"SansSerif\") {\n        if (name == \"Serif\") {\n            f = _serif;\n        } else {\n            f = _sansserif;\n        }\n    } else {\n        wstring wname = utf82wide(name.c_str());\n        f = new Gdiplus::FontFamily(wname.c_str());\n    }\n    int s = convertStyle(style);\n    if (!f->IsStyleAvailable(s)) {\n        throw ex_invalid_state(\"specified font style not available!\");\n    }\n    Gdiplus::Font* tf = new Gdiplus::Font(f, _size, s, Gdiplus::UnitPixel);\n    _style = s;\n    _family = f;\n    _typeface = sptr<Gdiplus::Font>(tf);\n}\n\nFont_win32::Font_win32(const string& file, float size) {\n    // add font to font collection\n    // some like fontconfig\n    Gdiplus::PrivateFontCollection c;\n    wstring wfile = utf82wide(file.c_str());\n    c.AddFontFile(wfile.c_str());\n    Gdiplus::FontFamily* ff = new Gdiplus::FontFamily();\n    int num = 0;\n    c.GetFamilies(1, ff, &num);\n    if (num <= 0) {\n        throw ex_invalid_state(\"cannot load font file \" + file);\n    }\n    // search order :\n    // regular -> bold -> italic -> bold-italic\n    _size = size;\n    _family = ff;\n    Gdiplus::Font* f = nullptr;\n    if (ff->IsStyleAvailable(Gdiplus::FontStyleRegular)) {\n        f = new Gdiplus::Font(ff, size, Gdiplus::FontStyleRegular, Gdiplus::UnitPixel);\n        _style = Gdiplus::FontStyleRegular;\n    } else if (ff->IsStyleAvailable(Gdiplus::FontStyleBold)) {\n        f = new Gdiplus::Font(ff, size, Gdiplus::FontStyleBold, Gdiplus::UnitPixel);\n        _style = Gdiplus::FontStyleBold;\n    } else if (ff->IsStyleAvailable(Gdiplus::FontStyleItalic)) {\n        f = new Gdiplus::Font(ff, size, Gdiplus::FontStyleItalic, Gdiplus::UnitPixel);\n        _style = Gdiplus::FontStyleItalic;\n    } else if (ff->IsStyleAvailable(Gdiplus::FontStyleBoldItalic)) {\n        f = new Gdiplus::Font(ff, size, Gdiplus::FontStyleBoldItalic, Gdiplus::UnitPixel);\n        _style = Gdiplus::FontStyleBoldItalic;\n    } else {\n        throw ex_invalid_state(\"no available font in file \" + file);\n    }\n    _typeface = sptr<Gdiplus::Font>(f);\n}\n\nfloat Font_win32::getSize() const {\n    return _size;\n}\n\nsptr<Font> Font_win32::deriveFont(int style) const {\n    int s = convertStyle(style);\n    if (!_family->IsStyleAvailable(s)) {\n        throw ex_invalid_state(\"specified font style not available!\");\n    }\n    Font_win32* f = new Font_win32();\n    f->_family = _family;\n    f->_style = s;\n    f->_size = _size;\n    Gdiplus::Font* ff = new Gdiplus::Font(&(*_family), _size, s, Gdiplus::UnitPixel);\n    f->_typeface = sptr<Gdiplus::Font>(ff);\n    return sptr<Font>(f);\n}\n\nbool Font_win32::operator==(const Font& ft) const {\n    const Font_win32& f = static_cast<const Font_win32&>(ft);\n    return _typeface.get() == f._typeface.get() && _size == f._size;\n}\n\nbool Font_win32::operator!=(const Font& f) const {\n    return !(*this == f);\n}\n\nFont* Font::create(const string& file, float s) {\n    return new Font_win32(file, s);\n}\n\nsptr<Font> Font::_create(const string& name, int style, float size) {\n    return sptr<Font>(new Font_win32(name, style, size));\n}\n\n/**************************************************************************************************/\n\nGdiplus::Graphics* TextLayout_win32::_g = nullptr;\nGdiplus::Bitmap* TextLayout_win32::_img = nullptr;\nconst Gdiplus::StringFormat* TextLayout_win32::_format = nullptr;\n\nTextLayout_win32::TextLayout_win32(const wstring& src, const sptr<Font_win32>& font)\n    : _txt(src), _font(font) {\n    if (_img == nullptr) {\n        _img = new Gdiplus::Bitmap(1, 1, PixelFormat32bppARGB);\n        _g = Gdiplus::Graphics::FromImage(_img);\n        _format = Gdiplus::StringFormat::GenericTypographic();\n    }\n}\n\nvoid TextLayout_win32::getBounds(_out_ Rect& r) {\n    int em = _font->_family->GetEmHeight(_font->_style);\n    int ascent = _font->_family->GetCellAscent(_font->_style);\n    float ap = _font->getSize() * ascent / em;\n    Gdiplus::RectF r1;\n    _g->MeasureString(\n        _txt.c_str(), wcslen(_txt.c_str()), &(*_font->_typeface), Gdiplus::PointF(0, 0), _format, &r1);\n    r.x = 0;\n    r.y = -ap;\n    r.w = r1.Width;\n    r.h = r1.Height;\n}\n\nvoid TextLayout_win32::draw(Graphics2D& g2, float x, float y) {\n    const Font* prev = g2.getFont();\n    g2.setFont(_font.get());\n    g2.drawText(_txt, x, y);\n    g2.setFont(prev);\n}\n\nsptr<TextLayout> TextLayout::create(const wstring& src, const sptr<Font>& font) {\n    sptr<Font_win32> f = static_pointer_cast<Font_win32>(font);\n    return sptr<TextLayout>(new TextLayout_win32(src, f));\n}\n\n/**************************************************************************************************/\n\nconst Gdiplus::StringFormat* Graphics2D_win32::_format = nullptr;\nconst Font* Graphics2D_win32::_defaultFont = nullptr;\n\nGraphics2D_win32::Graphics2D_win32(Gdiplus::Graphics* g) {\n    if (_format == nullptr) {\n        _format = Gdiplus::StringFormat::GenericTypographic();\n    }\n    if (_defaultFont == nullptr) {\n        _defaultFont = new Font_win32(\"Arial\", PLAIN, 72.f);\n    }\n    _sx = _sy = 1.f;\n    _color = black;\n    _font = _defaultFont;\n    _g = g;\n    _g->ResetTransform();\n    _g->SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);\n    _g->SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias);\n    _pen = new Gdiplus::Pen(Gdiplus::Color(_color));\n    _brush = new Gdiplus::SolidBrush(Gdiplus::Color(_color));\n}\n\nGraphics2D_win32::~Graphics2D_win32() {\n    delete _pen;\n    delete _brush;\n}\n\nvoid Graphics2D_win32::setColor(color color) {\n    _color = color;\n    _pen->SetColor(Gdiplus::Color(color));\n    _brush->SetColor(Gdiplus::Color(color));\n}\n\ncolor Graphics2D_win32::getColor() const {\n    return _color;\n}\n\nvoid Graphics2D_win32::setStroke(const Stroke& s) {\n    _stroke = s;\n    _pen->SetWidth(s.lineWidth);\n    Gdiplus::LineCap c;\n    switch (s.cap) {\n    case CAP_BUTT:\n        c = Gdiplus::LineCapFlat;\n        break;\n    case CAP_ROUND:\n        c = Gdiplus::LineCapRound;\n        break;\n    case CAP_SQUARE:\n        c = Gdiplus::LineCapSquare;\n        break;\n    }\n    _pen->SetLineCap(c, c, Gdiplus::DashCapRound);\n    Gdiplus::LineJoin j;\n    switch (s.join) {\n    case JOIN_BEVEL:\n        j = Gdiplus::LineJoinBevel;\n        break;\n    case JOIN_ROUND:\n        j = Gdiplus::LineJoinRound;\n        break;\n    case JOIN_MITER:\n        j = Gdiplus::LineJoinMiter;\n        break;\n    }\n    _pen->SetLineJoin(j);\n    _pen->SetMiterLimit(s.miterLimit);\n}\n\nconst Stroke& Graphics2D_win32::getStroke() const {\n    return _stroke;\n}\n\nvoid Graphics2D_win32::setStrokeWidth(float w) {\n    _stroke.lineWidth = w;\n    _pen->SetWidth(w);\n}\n\nconst Font* Graphics2D_win32::getFont() const {\n    return _font;\n}\n\nvoid Graphics2D_win32::setFont(const Font* font) {\n    _font = font;\n}\n\nvoid Graphics2D_win32::translate(float dx, float dy) {\n    _g->TranslateTransform(dx, dy);\n}\n\nvoid Graphics2D_win32::scale(float sx, float sy) {\n    _sx *= sx;\n    _sy *= sy;\n    _g->ScaleTransform(sx, sy);\n}\n\nvoid Graphics2D_win32::rotate(float angle) {\n    _g->RotateTransform(angle / PI * 180);\n}\n\nvoid Graphics2D_win32::rotate(float angle, float px, float py) {\n    _g->TranslateTransform(px, py);\n    _g->RotateTransform(angle / PI * 180);\n    _g->TranslateTransform(-px, -py);\n}\n\nvoid Graphics2D_win32::reset() {\n    _g->ResetTransform();\n    _sx = _sy = 1.f;\n}\n\nfloat Graphics2D_win32::sx() const {\n    return _sx;\n}\n\nfloat Graphics2D_win32::sy() const {\n    return _sy;\n}\n\nvoid Graphics2D_win32::drawChar(wchar_t c, float x, float y) {\n    wchar_t str[]{c, L'\\0'};\n    drawText(str, x, y);\n}\n\nvoid Graphics2D_win32::drawText(const wstring& c, float x, float y) {\n    const wchar_t* str = c.c_str();\n    const Font_win32* f = (const Font_win32*)_font;\n    int em = f->_family->GetEmHeight(f->_style);\n    int ascent = f->_family->GetCellAscent(f->_style);\n    float ap = f->getSize() * ascent / em;\n    int len = wcslen(str);\n    Gdiplus::RectF r1, r2;\n    _g->MeasureString(str, len, &(*f->_typeface), Gdiplus::PointF(0, 0), &r1);\n    _g->MeasureString(str, len, &(*f->_typeface), Gdiplus::PointF(0, 0), _format, &r2);\n    float off = (r1.Width - r2.Width) / 2.f;\n    _g->DrawString(str, len, &(*f->_typeface), Gdiplus::PointF(x - off, y - ap), _brush);\n}\n\nvoid Graphics2D_win32::drawLine(float x1, float y1, float x2, float y2) {\n    _g->DrawLine(_pen, x1, y1, x2, y2);\n}\n\nvoid Graphics2D_win32::drawRect(float x, float y, float w, float h) {\n    _g->DrawRectangle(_pen, x, y, w, h);\n}\n\nvoid Graphics2D_win32::fillRect(float x, float y, float w, float h) {\n    _g->FillRectangle(_brush, x, y, w, h);\n}\n\nvoid Graphics2D_win32::drawRoundRect(float x, float y, float w, float h, float rx, float ry) {\n    // not supported\n    drawRect(x, y, w, h);\n}\n\nvoid Graphics2D_win32::fillRoundRect(float x, float y, float w, float h, float rx, float ry) {\n    // not supported\n    fillRect(x, y, w, h);\n}\n\n#endif\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/platform/gdi_win/graphic_win32.h",
    "content": "#include \"config.h\"\n\n#if defined(__OS_Windows__) && !defined(MEM_CHECK)\n\n#ifndef GRAPHIC_WIN32_H_INCLUDED\n#define GRAPHIC_WIN32_H_INCLUDED\n\n#include \"common.h\"\n#include \"graphic/graphic.h\"\n\nusing namespace std;\nusing namespace tex;\n\nnamespace Gdiplus {\n\nclass Font;\nclass FontFamily;\nclass Graphics;\nclass Pen;\nclass Brush;\nclass SolidBrush;\nclass StringFormat;\nclass Bitmap;\n\n}  // namespace Gdiplus\n\nnamespace tex {\n\nclass Font_win32 : public Font {\nprivate:\n    static const Gdiplus::FontFamily* _serif;\n    static const Gdiplus::FontFamily* _sansserif;\n\n    float _size;\n\n    Font_win32();\n\npublic:\n    int _style;\n    sptr<Gdiplus::Font> _typeface;\n    const Gdiplus::FontFamily* _family;\n\n    Font_win32(const string& name, int style, float size);\n\n    Font_win32(const string& file, float size);\n\n    virtual float getSize() const override;\n\n    virtual sptr<Font> deriveFont(int style) const override;\n\n    virtual bool operator==(const Font& f) const override;\n\n    virtual bool operator!=(const Font& f) const override;\n\n    virtual ~Font_win32();\n\n    static int convertStyle(int style);\n};\n\n/**************************************************************************************************/\n\nclass TextLayout_win32 : public TextLayout {\nprivate:\n    sptr<Font_win32> _font;\n    wstring _txt;\n\npublic:\n    static const Gdiplus::StringFormat* _format;\n    static Gdiplus::Graphics* _g;\n    static Gdiplus::Bitmap* _img;\n\n    TextLayout_win32(const wstring& src, const sptr<Font_win32>& font);\n\n    virtual void getBounds(_out_ Rect& bounds) override;\n\n    virtual void draw(Graphics2D& g2, float x, float y) override;\n};\n\n/**************************************************************************************************/\n\nclass Graphics2D_win32 : public Graphics2D {\nprivate:\n    static const Gdiplus::StringFormat* _format;\n    static const Font* _defaultFont;\n\n    color _color;\n    const Font* _font;\n    Stroke _stroke;\n    Gdiplus::Graphics* _g;\n    Gdiplus::Pen* _pen;\n    Gdiplus::SolidBrush* _brush;\n\n    float _sx, _sy;\n\npublic:\n    Graphics2D_win32(Gdiplus::Graphics* g);\n\n    ~Graphics2D_win32();\n\n    virtual void setColor(color c) override;\n\n    virtual color getColor() const override;\n\n    virtual void setStroke(const Stroke& s) override;\n\n    virtual const Stroke& getStroke() const override;\n\n    virtual void setStrokeWidth(float w) override;\n\n    virtual const Font* getFont() const override;\n\n    virtual void setFont(const Font* font) override;\n\n    virtual void translate(float dx, float dy) override;\n\n    virtual void scale(float sx, float sy) override;\n\n    virtual void rotate(float angle) override;\n\n    virtual void rotate(float angle, float px, float py) override;\n\n    virtual void reset() override;\n\n    virtual float sx() const override;\n\n    virtual float sy() const override;\n\n    virtual void drawChar(wchar_t c, float x, float y) override;\n\n    virtual void drawText(const wstring& c, float x, float y) override;\n\n    virtual void drawLine(float x1, float y1, float x2, float y2) override;\n\n    virtual void drawRect(float x, float y, float w, float h) override;\n\n    virtual void fillRect(float x, float y, float w, float h) override;\n\n    virtual void drawRoundRect(float x, float y, float w, float h, float rx, float ry) override;\n\n    virtual void fillRoundRect(float x, float y, float w, float h, float rx, float ry) override;\n};\n\n}  // namespace tex\n\n#endif  // GRAPHIC_WIN32_H_INCLUDED\n#endif\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/render.cpp",
    "content": "#include \"render.h\"\n#include \"atom/atom.h\"\n#include \"core/core.h\"\n#include \"core/formula.h\"\n\nusing namespace tex;\n\nconst color TeXRender::_defaultcolor = black;\nfloat TeXRender::_defaultSize = -1;\nfloat TeXRender::_magFactor = 0;\n\nTeXRender::TeXRender(const sptr<Box> box, float textSize, bool trueValues) {\n    _box = box;\n    if (_defaultSize != -1) _textSize = _defaultSize;\n    if (_magFactor != 0) {\n        _textSize = textSize * abs(_magFactor);\n    } else {\n        _textSize = textSize;\n    }\n    if (!trueValues) _insets += (int)(0.18f * textSize);\n}\n\nfloat TeXRender::getTextSize() const {\n    return _textSize;\n}\n\nint TeXRender::getHeight() const {\n    return (int)(_box->_height * _textSize + 0.99f +\n                 _box->_depth * _textSize + 0.99f +\n                 _insets.top + _insets.bottom);\n}\n\nint TeXRender::getDepth() const {\n    return (int)(_box->_depth * _textSize + 0.99f + _insets.bottom);\n}\n\nint TeXRender::getWidth() const {\n    return (int)(_box->_width * _textSize + 0.99f + _insets.left + _insets.right);\n}\n\nfloat TeXRender::getBaseline() const {\n    return ((_box->_height * _textSize + 0.99f + _insets.top) /\n            ((_box->_height + _box->_depth) * _textSize + 0.99f + _insets.top + _insets.bottom));\n}\n\nvoid TeXRender::setTextSize(float textSize) {\n    _textSize = textSize;\n}\n\nvoid TeXRender::setForeground(color fg) {\n    _fg = fg;\n}\n\nInsets TeXRender::getInsets() {\n    return _insets;\n}\n\nvoid TeXRender::setInsets(const Insets& insets, bool trueval) {\n    _insets = insets;\n    if (!trueval) _insets += (int)(0.18f * _textSize);\n}\n\nvoid TeXRender::setWidth(int width, int align) {\n    float diff = width - getWidth();\n    // FIXME\n    // only care if new width larger than old\n    if (diff > 0) {\n        _box = sptr<Box>(new HorizontalBox(_box, (float)width, align));\n    }\n}\n\nvoid TeXRender::setHeight(int height, int align) {\n    float diff = height - getHeight();\n    // FIXME\n    // only care if new height larger than old\n    if (diff > 0) {\n        _box = sptr<Box>(new VerticalBox(_box, diff, align));\n    }\n}\n\nvoid TeXRender::draw(_out_ Graphics2D& g2, int x, int y) {\n    color old = g2.getColor();\n    g2.scale(_textSize, _textSize);\n    if (!istrans(_fg)) {\n        g2.setColor(_fg);\n    } else {\n        g2.setColor(_defaultcolor);\n    }\n\n    // draw formula box\n    _box->draw(g2, (x + _insets.left) / _textSize, (y + _insets.top) / _textSize + _box->_height);\n\n    // restore\n    g2.reset();\n    g2.setColor(old);\n}\n\nDefaultTeXFont* TeXRenderBuilder::createFont(float size, int type) {\n    DefaultTeXFont* tf = new DefaultTeXFont(size);\n    if (type == 0) tf->setSs(false);\n    if ((type & ROMAN) != 0) tf->setRoman(true);\n    if ((type & TYPEWRITER) != 0) tf->setTt(true);\n    if ((type & SANSSERIF) != 0) tf->setSs(true);\n    if ((type & ITALIC) != 0) tf->setIt(true);\n    if ((type & BOLD) != 0) tf->setBold(true);\n    return tf;\n}\n\nTeXRender* TeXRenderBuilder::build(TeXFormula& f) {\n    return build(f._root);\n}\n\nTeXRender* TeXRenderBuilder::build(const sptr<Atom>& fc) {\n    sptr<Atom> f = fc;\n    if (f == nullptr) f = sptr<Atom>(new EmptyAtom());\n    if (_style == -1) {\n        throw ex_invalid_state(\"A style is required, call function setStyle before build.\");\n    }\n    if (_textSize == -1) {\n        throw ex_invalid_state(\"A size is required, call function setSize before build.\");\n    }\n\n    DefaultTeXFont* font = (_type == -1) ? new DefaultTeXFont(_textSize)\n                                         : createFont(_textSize, _type);\n    sptr<TeXFont> tf(font);\n    TeXEnvironment* te = nullptr;\n    if (_widthUnit != -1 && _textWidth != 0) {\n        te = new TeXEnvironment(_style, tf, _widthUnit, _textWidth);\n    } else {\n        te = new TeXEnvironment(_style, tf);\n    }\n\n    if (_lineSpaceUnit != -1) te->setInterline(_lineSpaceUnit, _lineSpace);\n\n    auto box = f->createBox(*te);\n    TeXRender* ti = nullptr;\n    if (_widthUnit != -1 && _textWidth != 0) {\n        HorizontalBox* hb = nullptr;\n        if (_lineSpaceUnit != -1 && _lineSpace != 0) {\n            float il = _lineSpace * SpaceAtom::getFactor(_lineSpaceUnit, *te);\n            auto b = BoxSplitter::split(box, te->getTextWidth(), il);\n            hb = new HorizontalBox(b, _isMaxWidth ? b->_width : te->getTextWidth(), _align);\n        } else {\n            hb = new HorizontalBox(box, _isMaxWidth ? box->_width : te->getTextWidth(), _align);\n        }\n        ti = new TeXRender(sptr<Box>(hb), _textSize, _trueValues);\n    } else {\n        ti = new TeXRender(box, _textSize, _trueValues);\n    }\n\n    if (!istrans(_fg)) ti->setForeground(_fg);\n    ti->_iscolored = te->_isColored;\n\n    delete te;\n    return ti;\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/render.h",
    "content": "#ifndef RENDER_H_INCLUDED\n#define RENDER_H_INCLUDED\n\n#include \"graphic/graphic.h\"\n\nusing namespace std;\nusing namespace tex;\n\nnamespace tex {\n\nclass DefaultTeXFont;\nclass TeXFormula;\nclass Box;\nclass Atom;\n\nclass TeXRender {\nprivate:\n    static const color _defaultcolor;\n\n    sptr<Box> _box;\n    float _textSize;\n    color _fg;\n    Insets _insets;\n\npublic:\n    static float _defaultSize;\n    static float _magFactor;\n    bool _iscolored;\n\n    TeXRender(const sptr<Box> box, float textSize, bool trueValues = false);\n\n    float getTextSize() const;\n\n    int getHeight() const;\n\n    int getDepth() const;\n\n    int getWidth() const;\n\n    float getBaseline() const;\n\n    void setTextSize(float textSize);\n\n    void setForeground(color fg);\n\n    Insets getInsets();\n\n    void setInsets(const Insets& insets, bool trueval = false);\n\n    void setWidth(int width, int align);\n\n    void setHeight(int height, int align);\n\n    void draw(_out_ Graphics2D& g2, int x, int y);\n};\n\nclass TeXRenderBuilder {\nprivate:\n    int _style, _type, _widthUnit, _align, _lineSpaceUnit;\n    float _textSize, _textWidth, _lineSpace;\n    bool _trueValues, _isMaxWidth;\n    color _fg;\n\npublic:\n    // TODO declaration conflict with TypefaceStyle defined in graphic/graphic.h\n    enum TeXFontStyle {\n        SERIF = 0,\n        SANSSERIF = 1,\n        BOLD = 2,\n        ITALIC = 4,\n        ROMAN = 8,\n        TYPEWRITER = 16\n    };\n\n    TeXRenderBuilder()\n        : _style(-1),\n          _type(-1),\n          _widthUnit(-1),\n          _align(-1),\n          _lineSpaceUnit(-1),\n          _textSize(0),\n          _textWidth(0),\n          _lineSpace(0),\n          _trueValues(false),\n          _isMaxWidth(false),\n          _fg(black) {}\n\n    inline TeXRenderBuilder& setStyle(int style) {\n        _style = style;\n        return *this;\n    }\n\n    inline TeXRenderBuilder& setTextSize(float textSize) {\n        _textSize = textSize;\n        return *this;\n    }\n\n    inline TeXRenderBuilder& setType(int type) {\n        _type = type;\n        return *this;\n    }\n\n    inline TeXRenderBuilder& setForeground(color c) {\n        _fg = c;\n        return *this;\n    }\n\n    inline TeXRenderBuilder& setTrueValues(bool t) {\n        _trueValues = t;\n        return *this;\n    }\n\n    inline TeXRenderBuilder& setWidth(int unit, float width, int align) {\n        _widthUnit = unit;\n        _textWidth = width;\n        _align = align;\n        _trueValues = true;\n        return *this;\n    }\n\n    inline TeXRenderBuilder& setIsMaxWidth(bool i) {\n        if (_widthUnit == -1)\n            throw ex_invalid_state(\"Cannot set 'isMaxWidth' without having specified a width!\");\n        if (i) {\n            // Currently isMaxWidth==true does not work with\n            // ALIGN_CENTER or ALIGN_RIGHT (see HorizontalBox constructor)\n            //\n            // The case (1) we don't support by setting align := ALIGN_LEFT\n            // here is this:\n            //      \\text{hello world\\\\hello} with align=ALIGN_CENTER (but forced\n            //      to ALIGN_LEFT) and isMaxWidth==true results in:\n            //      [hello world]\n            //      [hello ]\n            // and NOT:\n            //      [hello world]\n            //      [ hello ]\n            //\n            // However, this case (2) is currently not supported anyway\n            // (ALIGN_CENTER with isMaxWidth==false):\n            //      [ hello world ]\n            //      [ hello ]\n            // and NOT:\n            //      [ hello world ]\n            //      [ hello ]\n            //\n            // => until (2) is solved, we stick with the hack to set align\n            // := ALIGN_LEFT!\n            _align = ALIGN_LEFT;\n        }\n        _isMaxWidth = i;\n        return *this;\n    }\n\n    inline TeXRenderBuilder& setLineSpace(int unit, float space) {\n        if (_widthUnit == -1) {\n            throw ex_invalid_state(\"Cannot set line space without having specified a width!\");\n        }\n        _lineSpace = space;\n        _lineSpaceUnit = unit;\n        return *this;\n    }\n\n    TeXRender* build(const sptr<Atom>& f);\n\n    TeXRender* build(TeXFormula& f);\n\n    static DefaultTeXFont* createFont(float size, int type);\n};\n\n}  // namespace tex\n\n#endif  // RENDER_H_INCLUDED\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/builtin/formula_mappings.res.cpp",
    "content": "#include \"core/formula.h\"\n\nmap<int, string> TeXFormula::_symbolFormulaMappings = {\n    {160, \"\\\\ \"},\n    {161, \"!`\"},\n    {169, \"\\\\copyright\"},\n    {192, \"\\\\`A\"},\n    {193, \"\\\\'A\"},\n    {194, \"\\\\^A\"},\n    {195, \"\\\\~A\"},\n    {196, \"\\\\\\\"A\"},\n    {197, \"\\\\r A\"},\n    {198, \"\\\\AE\"},\n    {199, \"\\\\c C\"},\n    {200, \"\\\\`E\"},\n    {201, \"\\\\'E\"},\n    {202, \"\\\\^E\"},\n    {203, \"\\\\\\\"E\"},\n    {204, \"\\\\`I\"},\n    {205, \"\\\\'I\"},\n    {206, \"\\\\^I\"},\n    {207, \"\\\\\\\"I\"},\n    // ETH {208, \"\"},\n    {209, \"\\\\~N\"},\n    {210, \"\\\\`O\"},\n    {211, \"\\\\'O\"},\n    {212, \"\\\\^O\"},\n    {213, \"\\\\~O\"},\n    {214, \"\\\\\\\"O\"},\n    {216, \"\\\\O\"},\n    {217, \"\\\\`U\"},\n    {218, \"\\\\'U\"},\n    {219, \"\\\\^U\"},\n    {220, \"\\\\\\\"U\"},\n    {221, \"\\\\'Y\"},\n    // THORN {222, \"\"},\n    {223, \"\\\\ss\"},\n    {224, \"\\\\`a\"},\n    {225, \"\\\\'a\"},\n    {226, \"\\\\^a\"},\n    {227, \"\\\\~a\"},\n    {228, \"\\\\\\\"a\"},\n    {229, \"\\\\aa\"},\n    {230, \"\\\\ae\"},\n    {231, \"\\\\c c\"},\n    {232, \"\\\\`e\"},\n    {233, \"\\\\'e\"},\n    {234, \"\\\\^e\"},\n    {235, \"\\\\\\\"e\"},\n    {236, \"\\\\`\\\\i\"},\n    {237, \"\\\\'\\\\i\"},\n    {238, \"\\\\^\\\\i\"},\n    {239, \"\\\\\\\"\\\\i\"},\n    {240, \"\\\\eth\"},\n    {241, \"\\\\~n\"},\n    {242, \"\\\\`o\"},\n    {243, \"\\\\'o\"},\n    {244, \"\\\\^o\"},\n    {245, \"\\\\~o\"},\n    {246, \"\\\\\\\"o\"},\n    {247, \"\\\\div\"},\n    {248, \"\\\\o\"},\n    {249, \"\\\\`u\"},\n    {250, \"\\\\'u\"},\n    {251, \"\\\\^u\"},\n    {252, \"\\\\\\\"u\"},\n    {253, \"\\\\'y\"},\n    // thorn {254, \"\"},\n    {255, \"\\\\\\\"y\"},\n    {256, \"\\\\=A\"},\n    {257, \"\\\\=a\"},\n    {258, \"\\\\u A\"},\n    {259, \"\\\\u a\"},\n    {260, \"\\\\k A\"},\n    {261, \"\\\\k a\"},\n    {262, \"\\\\'C\"},\n    {263, \"\\\\'c\"},\n    {264, \"\\\\^C\"},\n    {265, \"\\\\^c\"},\n    {266, \"\\\\.C\"},\n    {267, \"\\\\.c\"},\n    {268, \"\\\\v C\"},\n    {269, \"\\\\v c\"},\n    {270, \"\\\\v D\"},\n    {271, \"d\\\\text{'}\"},\n    {272, \"\\\\Dstrok\"},\n    {273, \"\\\\dstrok\"},\n    {274, \"\\\\=E\"},\n    {275, \"\\\\=e\"},\n    {276, \"\\\\u E\"},\n    {277, \"\\\\u e\"},\n    {278, \"\\\\.E\"},\n    {279, \"\\\\.e\"},\n    {280, \"\\\\k E\"},\n    {281, \"\\\\k e\"},\n    {282, \"\\\\v E\"},\n    {283, \"\\\\v e\"},\n    {284, \"\\\\^G\"},\n    {285, \"\\\\^g\"},\n    {286, \"\\\\u G\"},\n    {287, \"\\\\u g\"},\n    {288, \"\\\\.G\"},\n    {289, \"\\\\.g\"},\n    {290, \"\\\\underaccent{,}G\"},\n    {291, \"\\\\'g\"},\n    {292, \"\\\\^H\"},\n    {293, \"\\\\^h\"},\n    {294, \"\\\\Hstrok\"},\n    {295, \"\\\\hstrok\"},\n    {296, \"\\\\~I\"},\n    {297, \"\\\\~\\\\i\"},\n    {298, \"\\\\=I\"},\n    {299, \"\\\\=\\\\i\"},\n    {300, \"\\\\u I\"},\n    {301, \"\\\\u \\\\i\"},\n    {302, \"\\\\k I\"},\n    {303, \"\\\\k i\"},\n    {304, \"\\\\.I\"},\n    {305, \"\\\\i\"},\n    {306, \"\\\\IJ\"},\n    {307, \"\\\\ij\"},\n    {308, \"\\\\^J\"},\n    {309, \"\\\\^\\\\j\"},\n    {310, \"\\\\underaccent{,}K\"},\n    {311, \"\\\\underaccent{,}k\"},\n    // kra groenland\n    {313, \"\\\\'L\"},\n    {314, \"\\\\'l\"},\n    {315, \"\\\\underaccent{,}L\"},\n    {316, \"\\\\underaccent{,}l\"},\n    {317, \"\\\\Lcaron\"},\n    {318, \"\\\\lcaron\"},\n    {319, \"L\\\\cdot\"},\n    {320, \"l\\\\cdot\"},\n    {321, \"\\\\L\"},\n    {322, \"\\\\l\"},\n    // L barre\n    {323, \"\\\\'N\"},\n    {324, \"\\\\'n\"},\n    {325, \"\\\\underaccent{,}N\"},\n    {326, \"\\\\underaccent{,}n\"},\n    {327, \"\\\\v N\"},\n    {328, \"\\\\v n\"},\n    {329, \"\\\\text{'}n\"},\n    // Nj\n    {332, \"\\\\=O\"},\n    {333, \"\\\\=o\"},\n    {334, \"\\\\u O\"},\n    {335, \"\\\\u o\"},\n    {336, \"\\\\H O\"},\n    {337, \"\\\\H o\"},\n    {338, \"\\\\OE\"},\n    {339, \"\\\\oe\"},\n    {340, \"\\\\'R\"},\n    {341, \"\\\\'r\"},\n    {342, \"\\\\underaccent{,}R\"},\n    {343, \"\\\\underaccent{,}r\"},\n    {344, \"\\\\v R\"},\n    {345, \"\\\\v r\"},\n    {346, \"\\\\'S\"},\n    {347, \"\\\\'s\"},\n    {348, \"\\\\^S\"},\n    {349, \"\\\\^s\"},\n    {350, \"\\\\c S\"},\n    {351, \"\\\\c s\"},\n    {352, \"\\\\v S\"},\n    {353, \"\\\\v s\"},\n    {354, \"\\\\c T\"},\n    {355, \"\\\\c t\"},\n    {356, \"\\\\v T\"},\n    {357, \"\\\\tcaron\"},\n    {358, \"\\\\TStroke\"},\n    {359, \"\\\\tStroke\"},\n    {360, \"\\\\~U\"},\n    {361, \"\\\\~u\"},\n    {362, \"\\\\=U\"},\n    {363, \"\\\\=u\"},\n    {364, \"\\\\u U\"},\n    {365, \"\\\\u u\"},\n    {366, \"\\\\r U\"},\n    {367, \"\\\\r u\"},\n    {368, \"\\\\H U\"},\n    {369, \"\\\\H u\"},\n    {370, \"\\\\k U\"},\n    {371, \"\\\\k u\"},\n    {372, \"\\\\^W\"},\n    {373, \"\\\\^w\"},\n    {374, \"\\\\^Y\"},\n    {375, \"\\\\^y\"},\n    {376, \"\\\\\\\"Y\"},\n    {377, \"\\\\'Z\"},\n    {378, \"\\\\'z\"},\n    {379, \"\\\\.Z\"},\n    {380, \"\\\\.z\"},\n    {381, \"\\\\v Z\"},\n    {382, \"\\\\v z\"},\n    // f avec demi-barre\n    // greek capitals\n    {913, \"\\\\Alpha\"},\n    {914, \"\\\\Beta\"},\n    {915, \"\\\\Gamma\"},\n    {916, \"\\\\Delta\"},\n    {917, \"\\\\Epsilon\"},\n    {918, \"\\\\Zeta\"},\n    {919, \"\\\\Eta\"},\n    {920, \"\\\\Theta\"},\n    {921, \"\\\\Iota\"},\n    {922, \"\\\\Kappa\"},\n    {923, \"\\\\Lambda\"},\n    {924, \"\\\\Mu\"},\n    {925, \"\\\\Nu\"},\n    {926, \"\\\\Xi\"},\n    {927, \"\\\\Omicron\"},\n    {928, \"\\\\Pi\"},\n    {929, \"\\\\Rho\"},\n    {931, \"\\\\Sigma\"},\n    {932, \"\\\\Tau\"},\n    {933, \"\\\\Upsilon\"},\n    {934, \"\\\\Phi\"},\n    {935, \"\\\\Chi\"},\n    {936, \"\\\\Psi\"},\n    {937, \"\\\\Omega\"},\n    // Unicode to symbols\n    {8742, \"\\\\nshortparallel\"},\n    {8651, \"\\\\leftrightharpoons\"},\n    {8667, \"\\\\Rrightarrow\"},\n    {10956, \"\\\\supsetneqq\"},\n    {8805, \"\\\\ge\"},\n    {8883, \"\\\\rhd\"},\n    {10877, \"\\\\leqslant\"},\n    {8650, \"\\\\downdownarrows\"},\n    {8819, \"\\\\gtrsim\"},\n    {8822, \"\\\\lessgtr\"},\n    {10230, \"\\\\longrightarrow\"},\n    {8660, \"\\\\Leftrightarrow\"},\n    {8592, \"\\\\leftarrow\"},\n    {8854, \"\\\\ominus\"},\n    {8203, \"\\\\!\"},\n    {8855, \"\\\\otimes\"},\n    {8968, \"\\\\lceil\"},\n    {8706, \"\\\\partial\"},\n    {8994, \"\\\\smallfrown\"},\n    {8196, \"\\\\,\"},\n    {10914, \"\\\\gg\"},\n    {10916, \"\\\\mathbin{\\\\rlap{>}\\\\!<}\"},\n    {10917, \"\\\\mathbin{><}\"},\n    {10918, \"\\\\leftslice\"},\n    {10919, \"\\\\rightslice\"},\n    {8194, \"\\\\;\"},\n    {8197, \"\\\\:\"},\n    {8463, \"\\\\hbar\"},\n    {8601, \"\\\\swarrow\"},\n    {8809, \"\\\\gneqq\"},\n    {8800, \"\\\\neq\"},\n    {215, \"\\\\times\"},\n    {172, \"\\\\lnot\"},\n    {10949, \"\\\\nsubseteqq\"},\n    {8593, \"\\\\uparrow\"},\n    {8910, \"\\\\curlyvee\"},\n    {8726, \"\\\\setminus\"},\n    {8727, \"{}_\\\\ast\"},\n    {8843, \"\\\\supsetneq\"},\n    {8602, \"\\\\nleftarrow\"},\n    {8654, \"\\\\nLeftrightarrow\"},\n    {9662, \"\\\\blacktriangledown\"},\n    {8642, \"\\\\downharpoonright\"},\n    {10949, \"\\\\subseteqq\"},\n    {8707, \"\\\\exists\"},\n    {8709, \"\\\\emptyset\"},\n    {8921, \"\\\\ggg\"},\n    {8764, \"\\\\sim\"},\n    {8808, \"\\\\lvertneqq\"},\n    {8214, \"\\\\|\"},\n    {8744, \"\\\\vee\"},\n    {8729, \"\\\\bullet\"},\n    {10955, \"\\\\subsetneqq\"},\n    {9663, \"\\\\triangledown\"},\n    {8771, \"\\\\simeq\"},\n    {8649, \"\\\\rightrightarrows\"},\n    {9661, \"\\\\bigtriangledown\"},\n    {8816, \"\\\\nleqslant\"},\n    {8625, \"\\\\Rsh\"},\n    {8600, \"\\\\searrow\"},\n    {9664, \"\\\\blacktriangleleft\"},\n    {8805, \"\\\\geq\"},\n    {8741, \"\\\\Vert\"},\n    {8941, \"\\\\ntrianglerighteq\"},\n    {8596, \"\\\\leftrightarrow\"},\n    {8965, \"\\\\barwedge\"},\n    {8939, \"\\\\ntriangleright\"},\n    {8906, \"\\\\rtimes\"},\n    {8660, \"\\\\iff\"},\n    {8861, \"\\\\circleddash\"},\n    {8915, \"\\\\Cup\"},\n    {8648, \"\\\\upuparrows\"},\n    {8815, \"\\\\ngtr\"},\n    {8937, \"\\\\succnsim\"},\n    {10868, \"\\\\coloncolonequals\"},\n    {10889, \"\\\\lnapprox\"},\n    {8919, \"\\\\gtrdot\"},\n    {8230, \"\\\\ldots\"},\n    {8776, \"\\\\approx\"},\n    {10885, \"\\\\lessapprox\"},\n    {8911, \"\\\\curlywedge\"},\n    {8809, \"\\\\gvertneqq\"},\n    {8775, \"\\\\ncong\"},\n    {8783, \"\\\\bumpeq\"},\n    {10232, \"\\\\Longleftarrow\"},\n    {8741, \"\\\\parallel\"},\n    {8196, \"\\\\thinspace\"},\n    {9002, \"\\\\rangle\"},\n    {8898, \"\\\\bigcap\"},\n    {9827, \"\\\\clubsuit\"},\n    {8835, \"\\\\supset\"},\n    {8836, \"\\\\not\\\\subset\"},\n    {8837, \"\\\\not\\\\supset\"},\n    {8856, \"\\\\oslash\"},\n    {8756, \"\\\\therefore\"},\n    {8758, \"\\\\ratio\"},\n    {8759, \"\\\\mathbin{\\\\ratio\\\\ratio}\"},\n    {10936, \"\\\\succapprox\"},\n    {8869, \"\\\\bot\"},\n    {8923, \"\\\\gtreqless\"},\n    {8782, \"\\\\Bumpeq\"},\n    {8661, \"\\\\Updownarrow\"},\n    {1014, \"\\\\backepsilon\"},\n    {8746, \"\\\\cup\"},\n    {10234, \"\\\\Longleftrightarrow\"},\n    {10927, \"\\\\preceq\"},\n    {8915, \"\\\\doublecup\"},\n    {8214, \"\\\\lVert\"},\n    {8839, \"\\\\supseteq\"},\n    {8817, \"\\\\ngeqslant\"},\n    {8224, \"\\\\dagger\"},\n    {10928, \"\\\\nsucceq\"},\n    {10815, \"\\\\amalg\"},\n    {10891, \"\\\\lesseqqgtr\"},\n    {8806, \"\\\\leqq\"},\n    {8791, \"\\\\circeq\"},\n    {8792, \"\\\\smallfrowneq\"},\n    {8793, \"\\\\stackrel{\\\\wedge}{=}\"},\n    {8794, \"\\\\stackrel{\\\\vee}{=}\"},\n    {8795, \"\\\\stackrel{\\\\scalebox{0.8}{\\\\bigstar}}{=}\"},\n    {8796, \"\\\\triangleq\"},\n    {8797, \"\\\\stackrel{\\\\scalebox{0.75}{\\\\mathrm{def}}}{=}\"},\n    {8798, \"\\\\stackrel{\\\\scalebox{0.75}{\\\\mathrm{m}}}{=}\"},\n    {8799, \"\\\\stackrel{\\\\scalebox{0.75}{\\\\mathrm{?}}}{=}\"},\n    {8636, \"\\\\leftharpoonup\"},\n    {8858, \"\\\\circledcirc\"},\n    {8598, \"\\\\nwarrow\"},\n    {8934, \"\\\\lnsim\"},\n    {8995, \"\\\\smallsmile\"},\n    {8857, \"\\\\odot\"},\n    {8740, \"\\\\nmid\"},\n    {8918, \"\\\\lessdot\"},\n    {8242, \"\\\\prime\"},\n    {177, \"\\\\pm\"},\n    {8850, \"\\\\sqsupseteq\"},\n    {8784, \"\\\\doteq\"},\n    {8810, \"\\\\ll\"},\n    {8807, \"\\\\geqq\"},\n    {9825, \"\\\\heartsuit\"},\n    {8638, \"\\\\upharpoonright\"},\n    {8646, \"\\\\leftrightarrows\"},\n    {8908, \"\\\\rightthreetimes\"},\n    {8723, \"\\\\mp\"},\n    {10927, \"\\\\npreceq\"},\n    {8942, \"\\\\vdots\"},\n    {8938, \"\\\\ntriangleleft\"},\n    {8733, \"\\\\varpropto\"},\n    {8902, \"\\\\star\"},\n    {8761, \"\\\\minuscolon\"},\n    {8762, \"\\\\geoprop\"},\n    {8764, \"\\\\thicksim\"},\n    {8882, \"\\\\vartriangleleft\"},\n    {9642, \"\\\\blacksquare\"},\n    {9646, \"\\\\marker\"},\n    {9653, \"\\\\triangle\"},\n    {10756, \"\\\\biguplus\"},\n    {10938, \"\\\\succnapprox\"},\n    {10890, \"\\\\gnapprox\"},\n    {8800, \"\\\\ne\"},\n    {9633, \"\\\\square\"},\n    {8717, \"\\\\ni\"},\n    {8944, \"\\\\iddots\"},\n    {8945, \"\\\\ddots\"},\n    {8948, \"\\\\inplus\"},\n    {8876, \"\\\\nvdash\"},\n    {8720, \"\\\\coprod\"},\n    {8739, \"\\\\shortmid\"},\n    {8617, \"\\\\hookleftarrow\"},\n    {8655, \"\\\\nRightarrow\"},\n    {8639, \"\\\\upharpoonleft\"},\n    {8865, \"\\\\boxdot\"},\n    {8841, \"\\\\nsupseteq\"},\n    {8712, \"\\\\in\"},\n    {8713, \"\\\\notin\"},\n    {8905, \"\\\\ltimes\"},\n    {8827, \"\\\\succ\"},\n    {8722, \"\\\\minus\"},\n    {10928, \"\\\\succeq\"},\n    {8638, \"\\\\restriction\"},\n    {8747, \"\\\\int\"},\n    {9837, \"\\\\flat\"},\n    {8513, \"\\\\Game\"},\n    {8523, \"\\\\parr\"},\n    {8829, \"\\\\succcurlyeq\"},\n    {9001, \"\\\\langle\"},\n    {8901, \"\\\\cdot\"},\n    {8852, \"\\\\sqcup\"},\n    {8503, \"\\\\gimel\"},\n    {8859, \"\\\\circledast\"},\n    {10901, \"\\\\eqslantless\"},\n    {8804, \"\\\\le\"},\n    {8823, \"\\\\gtrless\"},\n    {8733, \"\\\\propto\"},\n    {9665, \"\\\\triangleleft\"},\n    {9652, \"\\\\blacktriangle\"},\n    {8465, \"\\\\Im\"},\n    {10753, \"\\\\bigoplus\"},\n    {10764, \"\\\\iiiint\"},\n    {8765, \"\\\\backsim\"},\n    {8734, \"\\\\infty\"},\n    {8834, \"\\\\subset\"},\n    {8914, \"\\\\Cap\"},\n    {8900, \"\\\\diamond\"},\n    {8878, \"\\\\nVdash\"},\n    {8786, \"\\\\fallingdotseq\"},\n    {8788, \"\\\\colonequals\"},\n    {8789, \"\\\\equalscolon\"},\n    {8812, \"\\\\between\"},\n    {8595, \"\\\\downarrow\"},\n    {8592, \"\\\\gets\"},\n    {8927, \"\\\\curlyeqsucc\"},\n    {8846, \"\\\\uplus\"},\n    {8714, \"\\\\in\"},\n    {8840, \"\\\\nsubseteq\"},\n    {8903, \"\\\\divideontimes\"},\n    {8808, \"\\\\lneqq\"},\n    {8936, \"\\\\precnsim\"},\n    {8956, \"\\\\niplus\"},\n    {8197, \"\\\\medspace\"},\n    {10878, \"\\\\geqslant\"},\n    {8781, \"\\\\asymp\"},\n    {8966, \"\\\\doublebarwedge\"},\n    {8849, \"\\\\sqsubseteq\"},\n    {9136, \"\\\\lmoustache\"},\n    {8769, \"\\\\nsim\"},\n    {8851, \"\\\\sqcap\"},\n    {10950, \"\\\\supseteqq\"},\n    {8907, \"\\\\leftthreetimes\"},\n    {8741, \"\\\\shortparallel\"},\n    {8866, \"\\\\vdash\"},\n    {8737, \"\\\\measuredangle\"},\n    {8838, \"\\\\subseteq\"},\n    {8920, \"\\\\llless\"},\n    {8744, \"\\\\lor\"},\n    {8656, \"\\\\Leftarrow\"},\n    {8472, \"\\\\wp\"},\n    {8768, \"\\\\wr\"},\n    {10754, \"\\\\bigotimes\"},\n    {8807, \"\\\\ngeqq\"},\n    {8871, \"\\\\models\"},\n    {8862, \"\\\\boxplus\"},\n    {8611, \"\\\\rightarrowtail\"},\n    {8863, \"\\\\boxminus\"},\n    {8726, \"\\\\smallsetminus\"},\n    {10886, \"\\\\gtrapprox\"},\n    {8826, \"\\\\prec\"},\n    {8643, \"\\\\downharpoonleft\"},\n    {10239, \"\\\\leadsto\"},\n    {8717, \"\\\\owns\"},\n    {10902, \"\\\\eqslantgtr\"},\n    {8773, \"\\\\cong\"},\n    {8619, \"\\\\looparrowleft\"},\n    {8502, \"\\\\beth\"},\n    {8748, \"\\\\iint\"},\n    {9653, \"\\\\vartriangle\"},\n    {8869, \"\\\\perp\"},\n    {8653, \"\\\\nLeftarrow\"},\n    {10758, \"\\\\bigsqcup\"},\n    {8711, \"\\\\nabla\"},\n    {8884, \"\\\\trianglelefteq\"},\n    {8847, \"\\\\sqsubset\"},\n    {8708, \"\\\\nexists\"},\n    {9654, \"\\\\blacktriangleright\"},\n    {8743, \"\\\\wedge\"},\n    {8736, \"\\\\angle\"},\n    {8242, \"\\\\'\"},\n    {10752, \"\\\\bigodot\"},\n    {8195, \"\\\\quad\"},\n    {9416, \"\\\\circledS\"},\n    {8874, \"\\\\Vvdash\"},\n    {8828, \"\\\\preccurlyeq\"},\n    {9655, \"\\\\triangleright\"},\n    {8778, \"\\\\approxeq\"},\n    {8594, \"\\\\to\"},\n    {10849, \"\\\\veebar\"},\n    {8659, \"\\\\Downarrow\"},\n    {8877, \"\\\\nvDash\"},\n    {8818, \"\\\\lesssim\"},\n    {8830, \"\\\\precsim\"},\n    {8750, \"\\\\oint\"},\n    {8842, \"\\\\subsetneq\"},\n    {8873, \"\\\\Vdash\"},\n    {9585, \"\\\\diagup\"},\n    {8738, \"\\\\sphericalangle\"},\n    {9826, \"\\\\diamondsuit\"},\n    {8867, \"\\\\dashv\"},\n    {8599, \"\\\\nearrow\"},\n    {8603, \"\\\\nrightarrow\"},\n    {10892, \"\\\\gtreqqless\"},\n    {8904, \"\\\\bowtie\"},\n    {8916, \"\\\\pitchfork\"},\n    {9838, \"\\\\natural\"},\n    {10934, \"\\\\succneqq\"},\n    {8843, \"\\\\varsupsetneq\"},\n    {8621, \"\\\\leftrightsquigarrow\"},\n    {8745, \"\\\\cap\"},\n    {9137, \"\\\\rmoustache\"},\n    {8743, \"\\\\land\"},\n    {8913, \"\\\\Supset\"},\n    {8721, \"\\\\sum\"},\n    {8888, \"\\\\multimap\"},\n    {8971, \"\\\\rfloor\"},\n    {8622, \"\\\\nleftrightarrow\"},\n    {9674, \"\\\\lozenge\"},\n    {8647, \"\\\\leftleftarrows\"},\n    {8605, \"\\\\rightsquigarrow\"},\n    {8864, \"\\\\boxtimes\"},\n    {8644, \"\\\\rightleftarrows\"},\n    {8940, \"\\\\ntrianglelefteq\"},\n    {8749, \"\\\\iiint\"},\n    {8868, \"\\\\top\"},\n    {8594, \"\\\\rightarrow\"},\n    {8476, \"\\\\Re\"},\n    {8848, \"\\\\sqsupset\"},\n    {8608, \"\\\\twoheadrightarrow\"},\n    {9632, \"\\\\blacksquare\"},\n    {10956, \"\\\\varsupsetneqq\"},\n    {8630, \"\\\\curvearrowleft\"},\n    {8504, \"\\\\daleth\"},\n    {8194, \"\\\\thickspace\"},\n    {8921, \"\\\\gggtr\"},\n    {8790, \"\\\\eqcirc\"},\n    {10955, \"\\\\varsubsetneqq\"},\n    {8739, \"\\\\vert\"},\n    {8831, \"\\\\succsim\"},\n    {8657, \"\\\\Uparrow\"},\n    {8806, \"\\\\nleqq\"},\n    {8487, \"\\\\mho\"},\n    {8491, \"\\\\text{\\\\AA}\"},\n    {8770, \"\\\\eqsim\"},\n    {8620, \"\\\\looparrowright\"},\n    {8640, \"\\\\rightharpoonup\"},\n    {8801, \"\\\\equiv\"},\n    {8802, \"\\\\not\\\\equiv\"},\n    {8610, \"\\\\leftarrowtail\"},\n    {8882, \"\\\\lhd\"},\n    {9733, \"\\\\bigstar\"},\n    {8935, \"\\\\gnsim\"},\n    {8872, \"\\\\vDash\"},\n    {10731, \"\\\\blacklozenge\"},\n    {183, \"\\\\cdot\"},\n    {8814, \"\\\\nless\"},\n    {8225, \"\\\\ddagger\"},\n    {8787, \"\\\\risingdotseq\"},\n    {8467, \"\\\\ell\"},\n    {8785, \"\\\\doteqdot\"},\n    {10887, \"\\\\lneq\"},\n    {8658, \"\\\\Rightarrow\"},\n    {10233, \"\\\\Longrightarrow\"},\n    {8631, \"\\\\curvearrowright\"},\n    {8618, \"\\\\hookrightarrow\"},\n    {8214, \"\\\\rVert\"},\n    {10231, \"\\\\longleftrightarrow\"},\n    {8926, \"\\\\curlyeqprec\"},\n    {10229, \"\\\\longleftarrow\"},\n    {8641, \"\\\\rightharpoondown\"},\n    {8463, \"\\\\hslash\"},\n    {8914, \"\\\\doublecap\"},\n    {8719, \"\\\\prod\"},\n    {8597, \"\\\\updownarrow\"},\n    {8624, \"\\\\Lsh\"},\n    {8833, \"\\\\nsucc\"},\n    {8725, \"\\\\slash\"},\n    {8637, \"\\\\leftharpoondown\"},\n    {8804, \"\\\\leq\"},\n    {8500, \"\\\\mathit{o}\"},\n    {8501, \"\\\\aleph\"},\n    {8879, \"\\\\nVDash\"},\n    {8970, \"\\\\lfloor\"},\n    {8728, \"\\\\circ\"},\n    {8899, \"\\\\bigcup\"},\n    {8740, \"\\\\nshortmid\"},\n    {10935, \"\\\\precapprox\"},\n    {8885, \"\\\\trianglerighteq\"},\n    {8739, \"\\\\mid\"},\n    {8724, \"\\\\dotplus\"},\n    {8832, \"\\\\nprec\"},\n    {8943, \"\\\\cdots\"},\n    {8666, \"\\\\Lleftarrow\"},\n    {10933, \"\\\\precneqq\"},\n    {8495, \"e\"},\n    {8498, \"\\\\Finv\"},\n    {8890, \"\\\\intercal\"},\n    {8730, \"\\\\surd\"},\n    {8897, \"\\\\bigvee\"},\n    {10888, \"\\\\gneq\"},\n    {8704, \"\\\\forall\"},\n    {10937, \"\\\\precnapprox\"},\n    {9824, \"\\\\spadesuit\"},\n    {10236, \"\\\\longmapsto\"},\n    {10214, \"\\\\llbracket\"},\n    {10215, \"\\\\rrbracket\"},\n    {10216, \"\\\\langle\"},\n    {10217, \"\\\\rangle\"},\n    {9711, \"\\\\bigcirc\"},\n    {8909, \"\\\\backsimeq\"},\n    {247, \"\\\\div\"},\n    {125, \"\\\\rbrace\"},\n    {8705, \"\\\\complement\"},\n    {8757, \"\\\\because\"},\n    {8760, \"\\\\dotminus\"},\n    {9651, \"\\\\triangle\"},\n    {8606, \"\\\\twoheadleftarrow\"},\n    {1013, \"\\\\epsilon\"},\n    {8741, \"\\\\Arrowvert\"},\n    {9674, \"\\\\Diamond\"},\n    {8842, \"\\\\varsubsetneq\"},\n    {8739, \"\\\\arrowvert\"},\n    {9839, \"\\\\sharp\"},\n    {8896, \"\\\\bigwedge\"},\n    {8709, \"\\\\varnothing\"},\n    {9586, \"\\\\diagdown\"},\n    {8614, \"\\\\mapsto\"},\n    {8883, \"\\\\vartriangleright\"},\n    {8853, \"\\\\oplus\"},\n    {8776, \"\\\\thickapprox\"},\n    {8969, \"\\\\rceil\"},\n    {8912, \"\\\\Subset\"},\n    {8652, \"\\\\rightleftharpoons\"},\n    {769, \"\\\\acute\"},\n    {768, \"\\\\grave\"},\n    {776, \"\\\\ddot\"},\n    {779, \"\\\\doubleacute\"},\n    {771, \"\\\\tilde\"},\n    {730, \"\\\\bmathring\"},\n    {772, \"\\\\bar\"},\n    {774, \"\\\\breve\"},\n    {780, \"\\\\check\"},\n    {770, \"\\\\hat\"},\n    {8407, \"\\\\vec\"},\n    {775, \"\\\\dot\"},\n    {770, \"\\\\widehat\"},\n    {771, \"\\\\widetilde\"},\n    {8450, \"\\\\mathbb{C}\"},\n    {8451, \"\\\\sideset{^\\\\circ}{}\\\\text{C}\"},\n    {8455, \"\\\\euler\"},\n    {8457, \"\\\\sideset{^\\\\circ}{}\\\\text{F}\"},\n    {8461, \"\\\\mathbb{H}\"},\n    {8469, \"\\\\mathbb{N}\"},\n    {8473, \"\\\\mathbb{P}\"},\n    {8474, \"\\\\mathbb{Q}\"},\n    {8477, \"\\\\mathbb{R}\"},\n    {8484, \"\\\\mathbb{Z}\"},\n    {8488, \"\\\\mathfrak{Z}\"},\n    {8459, \"\\\\mathscr{H}\"},\n    {8460, \"\\\\mathfrak{H}\"},\n    {8464, \"\\\\mathscr{I}\"},\n    {8466, \"\\\\mathscr{L}\"},\n    {8475, \"\\\\mathscr{R}\"},\n    {8492, \"\\\\mathscr{B}\"},\n    {8493, \"\\\\mathfrak{C}\"},\n    {8496, \"\\\\mathscr{E}\"},\n    {8497, \"\\\\mathscr{F}\"},\n    {8499, \"\\\\mathscr{M}\"},\n    {64256, \"ff\"},\n    {64257, \"fi\"},\n    {58290, \"fj\"},\n    {64258, \"fl\"},\n    {64259, \"ffi\"},\n    {64260, \"ffl\"},\n    {10643, \"\\\\mathbin{\\\\rlap{<}\\\\;(}\"},\n    {10644, \"\\\\mathbin{\\\\rlap{>}\\\\,)}\"},\n    {10677, \"\\\\minuso\"},\n    {10686, \"\\\\varocircle\"},\n    {10688, \"\\\\olessthan\"},\n    {10689, \"\\\\ogreaterthan\"},\n    {10692, \"\\\\boxslash\"},\n    {10693, \"\\\\boxbslash\"},\n    {10016, \"\\\\maltese\"},\n    {10016, \"\\\\checkmark\"},\n    {8254, \"\\\\mathpunct{\\\\={\\\\ }}\"},\n    {8259, \"\\\\hybull\"},\n    {8240, \"\\\\textperthousand\"},\n    {8241, \"\\\\textpertenthousand\"},\n    {8249, \"\\\\guilsinglleft\"},\n    {8250, \"\\\\guilsinglright\"},\n    {8772, \"\\\\not\\\\simeq\"},\n    {8244, \"'''\"},\n    {8411, \"''\"},\n    {8216, \"`\"},\n    {8220, \"``\"},\n    {8217, \"\\\\textapos\"},\n    {8218, \",\"},\n    {8221, \"\\\\textapos\\\\textapos\"},\n    {8222, \",,\"},\n    {8206, \" \"},\n    {8207, \" \"},\n    {8364, \"\\\\euro\"},\n    {8208, \"\\\\textminus\"},\n    {8211, \"\\\\textendash\"},\n    {8212, \"\\\\textemdash\"},\n    {8448, \"\\\\sfrac{a}{c}\"},\n    {8449, \"\\\\sfrac{a}{s}\"},\n    {8453, \"\\\\sfrac{c}{o}\"},\n    {8454, \"\\\\sfrac{c}{u}\"},\n    {8480, \"{}^{\\\\text{TM}}\"},\n    {8988, \"\\\\ulcorner\"},\n    {8989, \"\\\\urcorner\"},\n    {8990, \"\\\\llcorner\"},\n    {8991, \"\\\\lrcorner\"},\n    {8531, \"\\\\text{\\\\sfrac13}\"},\n    {8532, \"\\\\text{sfrac23}\"},\n    {8533, \"\\\\text{\\\\sfrac15}\"},\n    {8534, \"\\\\text{\\\\sfrac25}\"},\n    {8535, \"\\\\text{\\\\sfrac35}\"},\n    {8536, \"\\\\text{\\\\sfrac45}\"},\n    {8537, \"\\\\text{\\\\sfrac16}\"},\n    {8538, \"\\\\text{\\\\sfrac56}\"},\n    {189, \"\\\\text{\\\\sfrac12}\"},\n    {188, \"\\\\text{\\\\sfrac14}\"},\n    {190, \"\\\\text{\\\\sfrac34}\"},\n    {8539, \"\\\\text{\\\\sfrac18}\"},\n    {8540, \"\\\\text{\\\\sfrac38}\"},\n    {8541, \"\\\\text{\\\\sfrac58}\"},\n    {8542, \"\\\\text{\\\\sfrac78}\"},\n    {8543, \"\\\\text{\\\\sfrac{1}{\\\\ }}\"},\n    {8544, \"\\\\text{I}\"},\n    {8545, \"\\\\text{II}\"},\n    {8546, \"\\\\text{III}\"},\n    {8547, \"\\\\text{IV}\"},\n    {8548, \"\\\\text{V}\"},\n    {8549, \"\\\\text{VI}\"},\n    {8550, \"\\\\text{VII}\"},\n    {8551, \"\\\\text{VIII}\"},\n    {8552, \"\\\\text{IX}\"},\n    {8553, \"\\\\text{X}\"},\n    {8554, \"\\\\text{XI}\"},\n    {8555, \"\\\\text{XII}\"},\n    {8556, \"\\\\text{L}\"},\n    {8557, \"\\\\text{C}\"},\n    {8558, \"\\\\text{D}\"},\n    {8559, \"\\\\text{M}\"},\n    {8560, \"\\\\text{i}\"},\n    {8561, \"\\\\text{ii}\"},\n    {8562, \"\\\\text{iii}\"},\n    {8563, \"\\\\text{iv}\"},\n    {8564, \"\\\\text{v}\"},\n    {8565, \"\\\\text{vi}\"},\n    {8566, \"\\\\text{vii}\"},\n    {8567, \"\\\\text{viii}\"},\n    {8568, \"\\\\text{ix}\"},\n    {8569, \"\\\\text{x}\"},\n    {8570, \"\\\\text{xi}\"},\n    {8571, \"\\\\text{xii}\"},\n    {8572, \"\\\\text{l}\"},\n    {8573, \"\\\\text{c}\"},\n    {8574, \"\\\\text{d}\"},\n    {8575, \"\\\\text{m}\"},\n    {9600, \"\\\\uhblk\"},\n    {9601, \"\\\\lhblk\"},\n    {9608, \"\\\\block\"},\n    {9617, \"\\\\fgcolor{bfbfbf}{\\\\block}\"},\n    {9618, \"\\\\fgcolor{808080}{\\\\block}\"},\n    {9619, \"\\\\fgcolor{404040}{\\\\block}\"},\n    {9312, \"\\\\textcircled{\\\\texttt 1}\"},\n    {9313, \"\\\\textcircled{\\\\texttt 2}\"},\n    {9314, \"\\\\textcircled{\\\\texttt 3}\"},\n    {9315, \"\\\\textcircled{\\\\texttt 4}\"},\n    {9316, \"\\\\textcircled{\\\\texttt 5}\"},\n    {9317, \"\\\\textcircled{\\\\texttt 6}\"},\n    {9318, \"\\\\textcircled{\\\\texttt 7}\"},\n    {9319, \"\\\\textcircled{\\\\texttt 8}\"},\n    {9320, \"\\\\textcircled{\\\\texttt 9}\"},\n    {9398, \"\\\\textcircled{\\\\texttt A}\"},\n    {9399, \"\\\\textcircled{\\\\texttt B}\"},\n    {9400, \"\\\\textcircled{\\\\texttt C}\"},\n    {9401, \"\\\\textcircled{\\\\texttt D}\"},\n    {9402, \"\\\\textcircled{\\\\texttt E}\"},\n    {9403, \"\\\\textcircled{\\\\texttt F}\"},\n    {9404, \"\\\\textcircled{\\\\texttt G}\"},\n    {9405, \"\\\\textcircled{\\\\texttt H}\"},\n    {9406, \"\\\\textcircled{\\\\texttt I}\"},\n    {9407, \"\\\\textcircled{\\\\texttt J}\"},\n    {9408, \"\\\\textcircled{\\\\texttt K}\"},\n    {9409, \"\\\\textcircled{\\\\texttt L}\"},\n    {9410, \"\\\\textcircled{\\\\texttt M}\"},\n    {9411, \"\\\\textcircled{\\\\texttt N}\"},\n    {9412, \"\\\\textcircled{\\\\texttt O}\"},\n    {9413, \"\\\\textcircled{\\\\texttt P}\"},\n    {9414, \"\\\\textcircled{\\\\texttt Q}\"},\n    {9415, \"\\\\textcircled{\\\\texttt R}\"},\n    {9416, \"\\\\textcircled{\\\\texttt S}\"},\n    {9417, \"\\\\textcircled{\\\\texttt T}\"},\n    {9418, \"\\\\textcircled{\\\\texttt U}\"},\n    {9419, \"\\\\textcircled{\\\\texttt V}\"},\n    {9420, \"\\\\textcircled{\\\\texttt W}\"},\n    {9421, \"\\\\textcircled{\\\\texttt X}\"},\n    {9422, \"\\\\textcircled{\\\\texttt Y}\"},\n    {9423, \"\\\\textcircled{\\\\texttt Z}\"},\n    {9424, \"\\\\textcircled{\\\\texttt a}\"},\n    {9425, \"\\\\textcircled{\\\\texttt b}\"},\n    {9426, \"\\\\textcircled{\\\\texttt c}\"},\n    {9427, \"\\\\textcircled{\\\\texttt d}\"},\n    {9428, \"\\\\textcircled{\\\\texttt e}\"},\n    {9429, \"\\\\textcircled{\\\\texttt f}\"},\n    {9430, \"\\\\textcircled{\\\\texttt g}\"},\n    {9431, \"\\\\textcircled{\\\\texttt h}\"},\n    {9432, \"\\\\textcircled{\\\\texttt i}\"},\n    {9433, \"\\\\textcircled{\\\\texttt j}\"},\n    {9434, \"\\\\textcircled{\\\\texttt k}\"},\n    {9435, \"\\\\textcircled{\\\\texttt l}\"},\n    {9436, \"\\\\textcircled{\\\\texttt m}\"},\n    {9437, \"\\\\textcircled{\\\\texttt n}\"},\n    {9438, \"\\\\textcircled{\\\\texttt o}\"},\n    {9439, \"\\\\textcircled{\\\\texttt p}\"},\n    {9440, \"\\\\textcircled{\\\\texttt q}\"},\n    {9441, \"\\\\textcircled{\\\\texttt r}\"},\n    {9442, \"\\\\textcircled{\\\\texttt s}\"},\n    {9443, \"\\\\textcircled{\\\\texttt t}\"},\n    {9444, \"\\\\textcircled{\\\\texttt u}\"},\n    {9445, \"\\\\textcircled{\\\\texttt v}\"},\n    {9446, \"\\\\textcircled{\\\\texttt w}\"},\n    {9447, \"\\\\textcircled{\\\\texttt x}\"},\n    {9448, \"\\\\textcircled{\\\\texttt y}\"},\n    {9449, \"\\\\textcircled{\\\\texttt z}\"}};\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/builtin/glue.res.cpp",
    "content": "#include \"core/core.h\"\n\nusing namespace tex;\n\ninline static Glue* g(const string& name, float space, float stretch, float shrink) {\n    return new Glue(space, stretch, shrink, name);\n}\n\nvector<Glue*> Glue::_glueTypes = {\n    g(\"default\", 0, 0, 0),\n    g(\"thin\", 3, 0, 0),\n    g(\"med\", 4, 4, 2),\n    g(\"thick\", 5, 0, 5)};\n\n/**\n GLUE TABLE\n Page 181 in [The TeXBook]\n -------------------------------------------------------\n       ORD   OP    BIN   REL   OPEN  CLOSE  PUNCT  INNER\n ORD    0     1    (2)   (3)    0     0      0     (1)\n OP     1     1     *    (3)    0     0      0     (1)\n BIN   (2)   (2)    *     *    (2)    *      *     (2)\n REL   (3)   (3)    *     0    (3)    0      0     (3)\n OPEN  (0)    0     *     0     0     0      0      0\n CLOSE (0)    1    (2)   (3)    0     0      0     (1)\n PUNCT (1)   (1)    *    (1)   (1)   (1)    (1)    (1)\n INNER (1)    1    (2)   (3)   (1)    0     (1)    (1)\n */\nconst char Glue::_table[TYPE_COUNT][TYPE_COUNT][STYLE_COUNT] = {\n    {\"0000\", \"1111\", \"2200\", \"3300\", \"0000\", \"0000\", \"0000\", \"1100\"},\n    {\"1111\", \"1111\", \"0000\", \"3300\", \"0000\", \"0000\", \"0000\", \"1100\"},\n    {\"2200\", \"2200\", \"0000\", \"0000\", \"2200\", \"0000\", \"0000\", \"2200\"},\n    {\"3300\", \"3300\", \"0000\", \"0000\", \"3300\", \"0000\", \"0000\", \"3300\"},\n    {\"0000\", \"0000\", \"0000\", \"0000\", \"0000\", \"0000\", \"0000\", \"0000\"},\n    {\"0000\", \"1111\", \"2200\", \"3300\", \"0000\", \"0000\", \"0000\", \"1100\"},\n    {\"1100\", \"1100\", \"0000\", \"1100\", \"1100\", \"1100\", \"1100\", \"1100\"},\n    {\"1100\", \"1111\", \"2200\", \"3300\", \"1100\", \"0000\", \"1100\", \"1100\"}};\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/builtin/symbol_mapping.res.cpp",
    "content": "#include \"core/formula.h\"\n\nmap<int, string> TeXFormula::_symbolMappings = {\n    {'+', \"plus\"},\n    {'*', \"ast\"},\n    {'(', \"lbrack\"},\n    {';', \"semicolon\"},\n    {'{', \"lbrace\"},\n    {'!', \"faculty\"},\n    {')', \"rbrack\"},\n    {',', \"comma\"},\n    {'?', \"question\"},\n    {']', \"rsqbrack\"},\n    {'|', \"vert\"},\n    {':', \"colon\"},\n    {'=', \"equals\"},\n    {'[', \"lsqbrack\"},\n    {'}', \"rbrace\"},\n    {'`', \"mathlapos\"},\n    {'#', \"mathsharp\"},\n    {'-', \"minus\"},\n    {'/', \"slash\"},\n    {'.', \"normaldot\"},\n    {'>', \"gt\"},\n    {'<', \"lt\"},\n    {'\\'', \"textapos\"},\n    {163, \"mathsterling\"},\n    {165, \"yen\"},\n    {167, \"S\"},\n    {171, \"guillemotleft\"},\n    {174, \"textregistered\"},\n    {181, \"textmu\"},\n    {182, \"P\"},\n    {187, \"guillemotright\"},\n    {191, \"questiondown\"},\n    {981, \"phi\"},\n    {982, \"varpi\"},\n    {1008, \"varkappa\"},\n    {1009, \"varrho\"},\n    {945, \"alpha\"},\n    {946, \"beta\"},\n    {947, \"gamma\"},\n    {948, \"delta\"},\n    {949, \"varepsilon\"},\n    {950, \"zeta\"},\n    {951, \"eta\"},\n    {952, \"theta\"},\n    {953, \"iota\"},\n    {954, \"kappa\"},\n    {955, \"lambda\"},\n    {956, \"mu\"},\n    {957, \"nu\"},\n    {958, \"xi\"},\n    {959, \"omicron\"},\n    {960, \"pi\"},\n    {961, \"rho\"},\n    {962, \"varsigma\"},\n    {963, \"sigma\"},\n    {964, \"tau\"},\n    {965, \"upsilon\"},\n    {966, \"varphi\"},\n    {967, \"chi\"},\n    {968, \"psi\"},\n    {969, \"omega\"},\n    {977, \"vartheta\"},\n    {65288, \"lbrack\"},\n    {65289, \"rbrack\"},\n    {65292, \"comma\"}};\n\nmap<int, string> TeXFormula::_symbolTextMappings = {\n    {'-', \"textminus\"},\n    {'/', \"textfractionsolidus\"},\n    {'.', \"textnormaldot\"},\n    {913, \"Α\"},\n    {914, \"Β\"},\n    {915, \"Γ\"},\n    {916, \"Δ\"},\n    {917, \"Ε\"},\n    {918, \"Ζ\"},\n    {919, \"Η\"},\n    {920, \"Θ\"},\n    {921, \"Ι\"},\n    {922, \"Κ\"},\n    {923, \"Λ\"},\n    {924, \"Μ\"},\n    {925, \"Ν\"},\n    {926, \"Ξ\"},\n    {927, \"Ο\"},\n    {928, \"Π\"},\n    {929, \"Ρ\"},\n    {931, \"Σ\"},\n    {932, \"Τ\"},\n    {933, \"Υ\"},\n    {934, \"Φ\"},\n    {935, \"Χ\"},\n    {936, \"Ψ\"},\n    {937, \"Ω\"},\n    {945, \"α\"},\n    {946, \"β\"},\n    {947, \"γ\"},\n    {948, \"δ\"},\n    {949, \"ε\"},\n    {950, \"ζ\"},\n    {951, \"η\"},\n    {952, \"θ\"},\n    {953, \"ι\"},\n    {954, \"κ\"},\n    {955, \"λ\"},\n    {956, \"μ\"},\n    {957, \"ν\"},\n    {958, \"ξ\"},\n    {959, \"ο\"},\n    {960, \"π\"},\n    {961, \"ρ\"},\n    {962, \"ς\"},\n    {963, \"σ\"},\n    {964, \"τ\"},\n    {965, \"υ\"},\n    {966, \"φ\"},\n    {967, \"χ\"},\n    {968, \"ψ\"},\n    {969, \"ω\"},\n    {977, \"ϑ\"},\n    {65288, \"lbrack\"},\n    {65289, \"rbrack\"},\n    {65292, \"comma\"}};\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/builtin/tex_param.res.cpp",
    "content": "#include \"fonts/fonts.h\"\n\n/**\n * General parameters used in the TeX algorithms, \n * specific for the computer modern font family\n */\nmap<string, float> DefaultTeXFont::_parameters = {\n    {\"num1\", 0.676508},\n    {\"num2\", 0.393732},\n    {\"num3\", 0.443731},\n    {\"denom1\", 0.685951},\n    {\"denom2\", 0.344841},\n    {\"sup1\", 0.412892},\n    {\"sup2\", 0.362892},\n    {\"sup3\", 0.288889},\n    {\"sub1\", 0.15},\n    {\"sub2\", 0.247217},\n    {\"supdrop\", 0.386108},\n    {\"subdrop\", 0.05},\n    {\"axisheight\", 0.25},\n    {\"defaultrulethickness\", 0.039999},\n    {\"bigopspacing1\", 0.111112},\n    {\"bigopspacing2\", 0.166667},\n    {\"bigopspacing3\", 0.2},\n    {\"bigopspacing4\", 0.6},\n    {\"bigopspacing5\", 0.1}};\n\n#define __id(name) FontInfo::__id(#name)\n\nvoid DefaultTeXFont::__default_general_settings() {\n    _generalSettings = {\n        {\"mufontid\", __id(cmsy10)},\n        {\"spacefontid\", __id(cmr10)},\n        {\"textfactor\", 1},\n        {\"scriptfactor\", 0.7},\n        {\"scriptscriptfactor\", 0.5}};\n}\n\n#define cf(c, f) new CharFont(c, __id(f))\n\nvoid DefaultTeXFont::__default_text_style_mapping() {\n    _textStyleMappings = {\n        {\"mathnormal\", {cf(48, cmr10), cf(65, cmmi10), cf(97, cmmi10), cf(0, cmmi10)}},\n        {\"mathfrak\", {cf(48, eufm10), cf(65, eufm10), cf(97, eufm10), nullptr}},\n        {\"mathcal\", {nullptr, cf(65, cmsy10), nullptr, nullptr}},\n        {\"mathbb\", {nullptr, cf(65, msbm10), nullptr, nullptr}},\n        {\"mathscr\", {nullptr, cf(65, rsfs10), nullptr, nullptr}},\n        {\"mathds\", {nullptr, cf(65, dsrom10), nullptr, nullptr}},\n        {\"oldstylenums\", {cf(48, cmmi10), nullptr, nullptr, nullptr}},\n    };\n    _defaultTextStyleMappings = new string[4];\n    for (int i = 0; i < 4; i++) _defaultTextStyleMappings[i] = \"mathnormal\";\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/builtin/tex_symbols.res.cpp",
    "content": "#include \"atom/atom_basic.h\"\n\n#define sym(type, name) \\\n    { #name, sptr < SymbolAtom > (new SymbolAtom(#name, type, false)) }\n\n#define del(type, name) \\\n    { #name, sptr < SymbolAtom > (new SymbolAtom(#name, type, true)) }\n\n#define ord TYPE_ORDINARY\n#define rel TYPE_RELATION\n#define acc TYPE_ACCENT\n#define bin TYPE_BINARY_OPERATOR\n#define op TYPE_BIG_OPERATOR\n#define open TYPE_OPENING\n#define close TYPE_CLOSING\n#define punct TYPE_PUNCTUATION\n\n/**\n * BUILTIN SYMBOLS\n * Page 445 in the [The TeXBook]\n */\nmap<string, sptr<SymbolAtom>> SymbolAtom::_symbols = {\n    sym(ord, ae),\n    sym(ord, AE),\n    sym(ord, OE),\n    sym(ord, oe),\n    sym(ord, ss),\n    sym(ord, o),\n    sym(ord, O),\n    sym(ord, i),\n    sym(ord, j),\n    sym(ord, euler),\n    sym(ord, textapos),\n    sym(ord, mathlapos),\n    sym(ord, mathcedilla),\n    sym(acc, ogonek),\n    sym(ord, polishlcross),\n    sym(ord, lq),\n    sym(ord, rq),\n    sym(ord, textdbend),\n    sym(ord, dbend),\n    sym(rel, shortleftarrow),\n    sym(rel, shortrightarrow),\n    sym(rel, shortuparrow),\n    sym(rel, shortdownarrow),\n    sym(bin, Yup),\n    sym(bin, Ydown),\n    sym(bin, Yleft),\n    sym(bin, Yright),\n    sym(bin, varcurlyvee),\n    sym(bin, varcurlywedge),\n    sym(bin, minuso),\n    sym(bin, baro),\n    sym(bin, sslash),\n    sym(bin, bbslash),\n    sym(bin, moo),\n    sym(bin, varotimes),\n    sym(bin, varoast),\n    sym(bin, varobar),\n    sym(bin, varodot),\n    sym(bin, varoslash),\n    sym(bin, varobslash),\n    sym(bin, varocircle),\n    sym(bin, varoplus),\n    sym(bin, varominus),\n    sym(bin, boxast),\n    sym(bin, boxbar),\n    sym(bin, boxdot),\n    sym(bin, boxslash),\n    sym(bin, boxbslash),\n    sym(bin, boxcircle),\n    sym(bin, boxbox),\n    sym(bin, boxempty),\n    sym(ord, lightning),\n    sym(bin, merge),\n    sym(bin, vartimes),\n    sym(bin, fatsemi),\n    sym(rel, sswarrow),\n    sym(rel, ssearrow),\n    sym(rel, curlywedgeuparrow),\n    sym(rel, curlywedgedownarrow),\n    sym(bin, fatslash),\n    sym(bin, fatbslash),\n    sym(bin, lbag),\n    sym(bin, rbag),\n    sym(bin, varbigcirc),\n    sym(rel, leftrightarroweq),\n    sym(rel, curlyveedownarrow),\n    sym(rel, curlyveeuparrow),\n    sym(rel, nnwarrow),\n    sym(rel, nnearrow),\n    sym(bin, leftslice),\n    sym(bin, rightslice),\n    sym(bin, varolessthan),\n    sym(bin, varogreaterthan),\n    sym(bin, varovee),\n    sym(bin, varowedge),\n    sym(bin, talloblong),\n    sym(bin, interleave),\n    sym(bin, obar),\n    sym(bin, obslash),\n    sym(bin, olessthan),\n    sym(bin, ogreaterthan),\n    sym(bin, ovee),\n    sym(bin, owedge),\n    sym(bin, oblong),\n    sym(rel, inplus),\n    sym(rel, niplus),\n    sym(bin, nplus),\n    sym(rel, subsetplus),\n    sym(rel, supsetplus),\n    sym(rel, subsetpluseq),\n    sym(rel, supsetpluseq),\n    sym(open, Lbag),\n    sym(close, Rbag),\n    sym(open, llbracket),\n    sym(close, rrbracket),\n    sym(open, llparenthesis),\n    sym(close, rrparenthesis),\n    sym(open, binampersand),\n    sym(close, bindnasrepma),\n    sym(rel, trianglelefteqslant),\n    sym(rel, trianglerighteqslant),\n    sym(rel, ntrianglelefteqslant),\n    sym(rel, ntrianglerighteqslant),\n    sym(open, llfloor),\n    sym(close, rrfloor),\n    sym(open, llceil),\n    sym(close, rrceil),\n    sym(rel, arrownot),\n    sym(rel, Arrownot),\n    sym(rel, Mapstochar),\n    sym(rel, mapsfromchar),\n    sym(rel, Mapsfromchar),\n    sym(bin, leftrightarrowtriangle),\n    sym(rel, leftarrowtriangle),\n    sym(rel, rightarrowtriangle),\n    sym(op, bigtriangledown),\n    sym(op, bigtriangleup),\n    sym(op, bigcurlyvee),\n    sym(op, bigcurlywedge),\n    sym(op, bigsqcap),\n    sym(op, bigbox),\n    sym(op, bigparallel),\n    sym(op, biginterleave),\n    sym(op, bignplus),\n    sym(open, ulcorner),\n    sym(close, urcorner),\n    sym(open, llcorner),\n    sym(close, lrcorner),\n    sym(ord, maltese),\n    sym(ord, textregistered),\n    sym(ord, lhook),\n    sym(ord, rhook),\n    sym(rel, mapstochar),\n    sym(ord, angle),\n    sym(ord, hbar),\n    sym(rel, sqsubset),\n    sym(rel, sqsupset),\n    sym(ord, mho),\n    sym(ord, square),\n    sym(ord, lozenge),\n    sym(rel, vartriangleright),\n    sym(rel, vartriangleleft),\n    sym(rel, trianglerighteq),\n    sym(rel, trianglelefteq),\n    sym(rel, rightsquigarrow),\n    sym(rel, lhd),\n    sym(rel, unlhd),\n    sym(rel, rhd),\n    sym(rel, unrhd),\n    sym(ord, Box),\n\n    sym(bin, boxdot),\n    sym(bin, boxplus),\n    sym(bin, boxtimes),\n    sym(ord, square),\n    sym(ord, blacksquare),\n    sym(bin, centerdot),\n    sym(ord, lozenge),\n    sym(ord, blacklozenge),\n    sym(rel, circlearrowright),\n    sym(rel, circlearrowleft),\n    sym(rel, leftrightharpoons),\n    sym(rel, rightleftharpoons),\n    sym(bin, boxminus),\n    sym(rel, Vdash),\n    sym(rel, Vvdash),\n    sym(rel, vDash),\n    sym(rel, twoheadrightarrow),\n    sym(rel, twoheadleftarrow),\n    sym(rel, leftleftarrows),\n    sym(rel, rightrightarrows),\n    sym(rel, upuparrows),\n    sym(rel, downdownarrows),\n    sym(rel, upharpoonright),\n    sym(rel, downharpoonright),\n    sym(rel, upharpoonleft),\n    sym(rel, downharpoonleft),\n    sym(rel, rightarrowtail),\n    sym(rel, leftarrowtail),\n    sym(rel, leftrightarrows),\n    sym(rel, rightleftarrows),\n    sym(rel, Lsh),\n    sym(rel, Rsh),\n    sym(rel, rightsquigarrow),\n    sym(rel, leftrightsquigarrow),\n    sym(rel, looparrowleft),\n    sym(rel, looparrowright),\n    sym(rel, circeq),\n    sym(rel, succsim),\n    sym(rel, gtrsim),\n    sym(rel, gtrapprox),\n    sym(rel, multimap),\n    sym(rel, therefore),\n    sym(rel, because),\n    sym(rel, doteqdot),\n    sym(rel, triangleq),\n    sym(rel, precsim),\n    sym(rel, lesssim),\n    sym(rel, lessapprox),\n    sym(rel, eqslantless),\n    sym(rel, eqslantgtr),\n    sym(rel, curlyeqprec),\n    sym(rel, curlyeqsucc),\n    sym(rel, preccurlyeq),\n    sym(rel, leqq),\n    sym(rel, leqslant),\n    sym(rel, lessgtr),\n    sym(ord, backprime),\n    sym(rel, risingdotseq),\n    sym(rel, fallingdotseq),\n    sym(rel, succcurlyeq),\n    sym(rel, geqq),\n    sym(rel, geqslant),\n    sym(rel, gtrless),\n    sym(rel, vartriangleright),\n    sym(rel, vartriangleleft),\n    sym(rel, trianglerighteq),\n    sym(rel, trianglelefteq),\n    sym(ord, bigstar),\n    sym(rel, between),\n    sym(ord, blacktriangledown),\n    sym(rel, blacktriangleright),\n    sym(rel, blacktriangleleft),\n    sym(rel, vartriangle),\n    sym(ord, blacktriangle),\n    sym(ord, triangledown),\n    sym(rel, eqcirc),\n    sym(rel, lesseqgtr),\n    sym(rel, gtreqless),\n    sym(rel, lesseqqgtr),\n    sym(rel, gtreqqless),\n    sym(rel, Rrightarrow),\n    sym(rel, Lleftarrow),\n    sym(bin, veebar),\n    sym(bin, barwedge),\n    sym(bin, doublebarwedge),\n    sym(ord, measuredangle),\n    sym(ord, sphericalangle),\n    sym(rel, varpropto),\n    sym(rel, smallsmile),\n    sym(rel, smallfrown),\n    sym(rel, Subset),\n    sym(rel, Supset),\n    sym(bin, Cup),\n    sym(bin, Cap),\n    sym(bin, curlywedge),\n    sym(bin, curlyvee),\n    sym(bin, leftthreetimes),\n    sym(bin, rightthreetimes),\n    sym(rel, subseteqq),\n    sym(rel, supseteqq),\n    sym(rel, bumpeq),\n    sym(rel, Bumpeq),\n    sym(rel, lll),\n    sym(rel, ggg),\n    sym(ord, circledS),\n    sym(rel, pitchfork),\n    sym(bin, dotplus),\n    sym(rel, backsim),\n    sym(rel, backsimeq),\n    sym(ord, complement),\n    sym(bin, intercal),\n    sym(bin, circledcirc),\n    sym(bin, circledast),\n    sym(bin, circleddash),\n    sym(rel, lvertneqq),\n    sym(rel, gvertneqq),\n    sym(rel, nleq),\n    sym(rel, ngeq),\n    sym(rel, nless),\n    sym(rel, ngtr),\n    sym(rel, nprec),\n    sym(rel, nsucc),\n    sym(rel, lneqq),\n    sym(rel, gneqq),\n    sym(rel, nleqslant),\n    sym(rel, ngeqslant),\n    sym(rel, lneq),\n    sym(rel, gneq),\n    sym(rel, npreceq),\n    sym(rel, nsucceq),\n    sym(rel, precnsim),\n    sym(rel, succnsim),\n    sym(rel, lnsim),\n    sym(rel, gnsim),\n    sym(rel, nleqq),\n    sym(rel, ngeqq),\n    sym(rel, precneqq),\n    sym(rel, succneqq),\n    sym(rel, precnapprox),\n    sym(rel, succnapprox),\n    sym(rel, lnapprox),\n    sym(rel, gnapprox),\n    sym(rel, nsim),\n    sym(rel, ncong),\n    sym(ord, diagup),\n    sym(ord, diagdown),\n    sym(rel, varsubsetneq),\n    sym(rel, varsupsetneq),\n    sym(rel, nsubseteqq),\n    sym(rel, nsupseteqq),\n    sym(rel, subsetneqq),\n    sym(rel, supsetneqq),\n    sym(rel, varsubsetneqq),\n    sym(rel, varsupsetneqq),\n    sym(rel, subsetneq),\n    sym(rel, supsetneq),\n    sym(rel, nsubseteq),\n    sym(rel, nsupseteq),\n    sym(rel, nparallel),\n    sym(rel, nmid),\n    sym(rel, nshortmid),\n    sym(rel, nshortparallel),\n    sym(rel, nvdash),\n    sym(rel, nVdash),\n    sym(rel, nvDash),\n    sym(rel, nVDash),\n    sym(rel, ntrianglerighteq),\n    sym(rel, ntrianglelefteq),\n    sym(rel, ntriangleleft),\n    sym(rel, ntriangleright),\n    sym(rel, nleftarrow),\n    sym(rel, nrightarrow),\n    sym(rel, nLeftarrow),\n    sym(rel, nRightarrow),\n    sym(rel, nLeftrightarrow),\n    sym(rel, nleftrightarrow),\n    sym(bin, divideontimes),\n    sym(ord, varnothing),\n    sym(ord, nexists),\n    sym(ord, Finv),\n    sym(ord, Game),\n    sym(ord, eth),\n    sym(rel, eqsim),\n    sym(ord, beth),\n    sym(ord, gimel),\n    sym(ord, daleth),\n    sym(bin, lessdot),\n    sym(bin, gtrdot),\n    sym(bin, ltimes),\n    sym(bin, rtimes),\n    sym(rel, shortmid),\n    sym(rel, shortparallel),\n    sym(bin, smallsetminus),\n    sym(rel, thicksim),\n    sym(rel, thickapprox),\n    sym(rel, approxeq),\n    sym(rel, succapprox),\n    sym(rel, precapprox),\n    sym(rel, curvearrowleft),\n    sym(rel, curvearrowright),\n    sym(ord, digamma),\n    sym(ord, varkappa),\n    sym(ord, Bbbk),\n    sym(ord, hslash),\n    sym(rel, backepsilon),\n    sym(rel, Diamond),\n    sym(rel, leadsto),\n    // miscellaneous symbols\n    sym(punct, guillemotleft),\n    sym(punct, guillemotright),\n    sym(punct, guilsinglleft),\n    sym(punct, guilsinglright),\n    sym(punct, fg),\n    sym(punct, og),\n    sym(ord, textperthousand),\n    sym(ord, textpertenthousand),\n    sym(ord, textminus),\n    sym(ord, textendash),\n    sym(ord, textemdash),\n    sym(ord, S),\n    sym(ord, P),\n    sym(punct, comma),\n    sym(punct, ldotp),\n    sym(punct, cdotp),\n    sym(ord, normaldot),\n    sym(punct, textnormaldot),\n    sym(ord, slash),\n    sym(punct, semicolon),\n    sym(ord, faculty),\n    sym(ord, question),\n    sym(ord, questiondown),\n    sym(ord, mathsharp),\n    sym(ord, textdollar),\n    sym(ord, textpercent),\n    sym(ord, textampersand),\n    sym(ord, textfractionsolidus),\n    sym(ord, matharobase),\n    sym(ord, underscore),\n    sym(ord, checkmark),\n    sym(ord, mathsterling),\n    sym(ord, yen),\n    // math accents\n    sym(acc, acute),\n    sym(acc, grave),\n    sym(acc, ddot),\n    sym(acc, doubleacute),\n    sym(acc, tilde),\n    sym(acc, mathring),\n    sym(acc, mathring),\n    sym(acc, bar),\n    sym(acc, breve),\n    sym(acc, check),\n    sym(acc, hat),\n    sym(acc, vec),\n    sym(acc, dot),\n    sym(acc, widehat),\n    sym(acc, widetilde),\n    sym(acc, tie),\n    // delimiters that can change size\n    del(open, lbrace),\n    del(close, rbrace),\n    del(open, lbrack),\n    del(close, rbrack),\n    del(close, rsqbrack),\n    del(open, lsqbrack),\n    del(open, langle),\n    del(close, rangle),\n    del(open, lfloor),\n    del(close, rfloor),\n    del(open, lceil),\n    del(close, rceil),\n    del(rel, uparrow),\n    del(rel, Uparrow),\n    del(rel, downarrow),\n    del(rel, Downarrow),\n    del(rel, updownarrow),\n    del(rel, Updownarrow),\n    del(ord, vert),\n    del(ord, Vert),\n    del(open, slashdel),\n    del(rel, Relbar),\n    del(open, lgroup),\n    del(close, rgroup),\n    del(ord, bracevert),\n    del(open, lmoustache),\n    del(close, rmoustache),\n    // lowercase Greek letters\n    sym(ord, alpha),\n    sym(ord, beta),\n    sym(ord, gamma),\n    sym(ord, delta),\n    sym(ord, epsilon),\n    sym(ord, varepsilon),\n    sym(ord, zeta),\n    sym(ord, eta),\n    sym(ord, theta),\n    sym(ord, vartheta),\n    sym(ord, iota),\n    sym(ord, kappa),\n    sym(ord, lambda),\n    sym(ord, mu),\n    sym(ord, nu),\n    sym(ord, xi),\n    sym(ord, omicron),\n    sym(ord, pi),\n    sym(ord, varpi),\n    sym(ord, rho),\n    sym(ord, varrho),\n    sym(ord, sigma),\n    sym(ord, varsigma),\n    sym(ord, tau),\n    sym(ord, upsilon),\n    sym(ord, phi),\n    sym(ord, varphi),\n    sym(ord, chi),\n    sym(ord, psi),\n    sym(ord, omega),\n    // uppercase Greek letters\n    sym(ord, Gamma),\n    sym(ord, Delta),\n    sym(ord, Theta),\n    sym(ord, Lambda),\n    sym(ord, Xi),\n    sym(ord, Pi),\n    sym(ord, Sigma),\n    sym(ord, Upsilon),\n    sym(ord, Phi),\n    sym(ord, Psi),\n    sym(ord, Omega),\n    sym(ord, varGamma),\n    sym(ord, varDelta),\n    sym(ord, varTheta),\n    sym(ord, varLambda),\n    sym(ord, varXi),\n    sym(ord, varPi),\n    sym(ord, varSigma),\n    sym(ord, varUpsilon),\n    sym(ord, varPhi),\n    sym(ord, varPsi),\n    sym(ord, varOmega),\n    // miscellaneous symbols of type \"ord\"\n    sym(ord, aleph),\n    sym(ord, imath),\n    sym(ord, jmath),\n    sym(ord, ell),\n    sym(ord, wp),\n    sym(ord, Re),\n    sym(ord, Im),\n    sym(ord, partial),\n    sym(ord, infty),\n    sym(ord, prime),\n    sym(ord, emptyset),\n    sym(ord, nabla),\n    sym(ord, surdsign),\n    sym(ord, top),\n    sym(ord, bot),\n    sym(ord, |),\n    sym(ord, triangle),\n    del(ord, backslash),\n    sym(ord, forall),\n    sym(ord, exists),\n    sym(ord, neg),\n    sym(ord, lnot),\n    sym(ord, flat),\n    sym(ord, natural),\n    sym(ord, sharp),\n    sym(ord, clubsuit),\n    sym(ord, diamondsuit),\n    sym(ord, heartsuit),\n    sym(ord, spadesuit),\n    sym(ord, lacc),\n    sym(ord, racc),\n    // \"large\" operators\n    sym(op, bigcap),\n    sym(op, bigcup),\n    sym(op, bigodot),\n    sym(op, bigoplus),\n    sym(op, bigotimes),\n    sym(op, bigsqcup),\n    sym(op, biguplus),\n    sym(op, bigvee),\n    sym(op, bigwedge),\n    sym(op, coprod),\n    sym(op, int),\n    sym(op, oint),\n    sym(op, sum),\n    sym(op, prod),\n    sym(op, smallint),\n    // binary operators\n    sym(bin, minus),\n    sym(bin, plus),\n    sym(bin, pm),\n    sym(bin, mp),\n    sym(bin, setminus),\n    sym(bin, cdot),\n    sym(bin, times),\n    sym(bin, ast),\n    sym(bin, star),\n    sym(bin, diamond),\n    sym(bin, circ),\n    sym(bin, bullet),\n    sym(bin, div),\n    sym(bin, cap),\n    sym(bin, cup),\n    sym(bin, uplus),\n    sym(bin, sqcap),\n    sym(bin, sqcup),\n    sym(bin, triangleleft),\n    sym(bin, triangleright),\n    sym(bin, wr),\n    sym(bin, bigcirc),\n    sym(bin, vee),\n    sym(bin, lor),\n    sym(bin, land),\n    sym(bin, wedge),\n    sym(bin, oplus),\n    sym(bin, ominus),\n    sym(bin, otimes),\n    sym(bin, oslash),\n    sym(bin, odot),\n    sym(bin, dagger),\n    sym(bin, ddagger),\n    sym(bin, amalg),\n    // relations\n    sym(rel, equals),\n    sym(rel, gt),\n    sym(rel, lt),\n    sym(rel, leq),\n    sym(rel, le),\n    sym(rel, prec),\n    sym(rel, preceq),\n    sym(rel, ll),\n    sym(rel, subset),\n    sym(rel, subseteq),\n    sym(rel, sqsubseteq),\n    sym(rel, in),\n    sym(rel, vdash),\n    sym(rel, smile),\n    sym(rel, frown),\n    sym(rel, geq),\n    sym(rel, ge),\n    sym(rel, succ),\n    sym(rel, succeq),\n    sym(rel, gg),\n    sym(rel, supset),\n    sym(rel, supseteq),\n    sym(rel, sqsupseteq),\n    sym(rel, ni),\n    sym(rel, owns),\n    sym(rel, dashv),\n    sym(rel, mid),\n    sym(rel, parallel),\n    sym(rel, equiv),\n    sym(rel, sim),\n    sym(rel, simeq),\n    sym(rel, asymp),\n    sym(rel, approx),\n    sym(rel, propto),\n    sym(rel, perp),\n    // special relation symbol with \"width=0\" (to overlap other relational symbols)\n    sym(rel, not),\n    // arrows = pointing relations\n    sym(rel, colon),\n    sym(rel, nearrow),\n    sym(rel, searrow),\n    sym(rel, swarrow),\n    sym(rel, nwarrow),\n    sym(rel, leftarrow),\n    sym(rel, gets),\n    sym(rel, Leftarrow),\n    sym(rel, rightarrow),\n    sym(rel, to),\n    sym(rel, Rightarrow),\n    sym(rel, leftrightarrow),\n    sym(rel, Leftrightarrow),\n    sym(rel, leftharpoonup),\n    sym(rel, leftharpoondown),\n    sym(rel, rightharpoonup),\n    sym(rel, rightharpoondown),\n    // specials\n    sym(ord, textmu),\n    sym(ord, texteuro),\n    sym(ord, euro),\n    sym(ord, android),\n    sym(ord, dT),\n    sym(ord, dE),\n    sym(ord, dX),\n    sym(ord, varparallel),\n    sym(ord, nvarparallel),\n    sym(ord, varparalleleq),\n    sym(ord, parallelogram)};\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/README",
    "content": "The original TFM files can be found at:\n\n    https://ctan.org/texarchive/fonts/cm/tfm\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/bi10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(bi10, fonts/latin/bi10.ttf, 0)\n\nxHeight(0.0) quad(1.000003) space(0.333334)\n\nroman(r10) ss(sbi10) tt(tt10)\n\nMETRICS_START\n33, 0.634, 0.472, 0, 0.09,\n34, 0.507, 0.472, 0, 0.03,\n35, 0.507, 0.472, 0, -0.026,\n36, 0.634, 0.472, 0, -0.026,\n37, 1.284, 0.752, 0, 0.022,\n38, 1.704, 0.752, 0, 0.022\nMETRICS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/bx10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(bx10, fonts/latin/bx10.ttf, 0)\n\nxHeight(0.0) quad(1.000003) space(0.333334)\n\nroman(r10) ss(sb10) tt(tt10) it(bi10)\n\nMETRICS_START\n33, 0.643, 0.474, 0, 0,\n34, 0.507, 0.474, 0, 0,\n35, 0.507, 0.474, 0, 0,\n36, 0.643, 0.474, 0, 0,\n37, 1.332, 0.751, 0, 0,\n38, 1.786, 0.751, 0, 0\nMETRICS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/cmbsy10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(cmbsy10, fonts/maths/cmbsy10.ttf, 0)\n\nxHeight(0.444445) quad(1.149994)\n\nMETRICS_START\n33, 1.149994, 0.391111, -0.108889, 0,\n34, 0.574997, 0.694445, 0.194443, 0,\n35, 0.574997, 0.694445, 0.194443, 0,\n36, 1.149994, 0.391111, -0.108889, 0,\n37, 1.149994, 0.694445, 0.194443, 0,\n38, 1.149994, 0.694445, 0.194443, 0,\n39, 0.89444, 0.502223, 0.002223, 0,\n40, 1.149994, 0.391111, -0.108889, 0,\n41, 1.149994, 0.391111, -0.108889, 0,\n42, 0.702774, 0.694445, 0.194443, 0,\n43, 0.702774, 0.694445, 0.194443, 0,\n44, 1.149994, 0.391111, -0.108889, 0,\n45, 1.149994, 0.694445, 0.194443, 0,\n46, 1.149994, 0.694445, 0.194443, 0,\n47, 0.89444, 0.444445, 0, 0,\n48, 0.344442, 0.555557, 0, 0,\n49, 1.149994, 0.444445, 0, 0,\n50, 0.766663, 0.585556, 0.085556, 0,\n51, 0.766663, 0.585556, 0.085556, 0,\n52, 1.022217, 0.694445, 0.194445, 0,\n53, 1.022217, 0.694445, 0.194445, 0,\n54, 0.0, 0.694445, 0.194443, 0,\n55, 0.0, 0.391111, -0.108889, 0,\n56, 0.6388855, 0.694445, 0, 0,\n57, 0.6388855, 0.694445, 0, 0,\n58, 0.766663, 0.444445, 0, 0,\n59, 0.574997, 0.75, 0.055555, 0,\n60, 0.830551, 0.694445, 0, 0,\n61, 0.830551, 0.694445, 0, 0,\n62, 0.89444, 0.694445, 0, 0,\n63, 0.89444, 0.694445, 0, 0,\n64, 0.702774, 0.694445, 0, 0,\n65, 0.920728, 0.686111, 0, 0,\n66, 0.747844, 0.686111, 0, 0.02251,\n67, 0.612982, 0.686111, 0, 0.047145,\n68, 0.892079, 0.686111, 0, 0.031944,\n69, 0.606941, 0.686111, 0, 0.082914,\n70, 0.814089, 0.686111, 0, 0.101736,\n71, 0.681595, 0.686111, 0.097223, 0.055736,\n72, 0.987389, 0.686111, 0, 0,\n73, 0.64239, 0.686111, 0, 0.081415,\n74, 0.77944, 0.686111, 0.097223, 0.187502,\n75, 0.871249, 0.686111, 0, 0,\n76, 0.78819, 0.686111, 0, 0,\n77, 1.377826, 0.686111, 0, 0,\n78, 0.937322, 0.686111, 0, 0.152014,\n79, 0.905551, 0.686111, 0, 0.031944,\n80, 0.809857, 0.686111, 0, 0.084582,\n81, 0.939161, 0.686111, 0.097223, 0,\n82, 0.989576, 0.686111, 0, 0,\n83, 0.696385, 0.686111, 0, 0.071289,\n84, 0.644142, 0.686111, 0, 0.267362,\n85, 0.714714, 0.686111, 0, 0.101736,\n86, 0.737358, 0.686111, 0, 0.084582,\n87, 1.168605, 0.686111, 0, 0.084582,\n88, 0.816722, 0.686111, 0, 0.147024,\n89, 0.758609, 0.686111, 0.097223, 0.084582,\n90, 0.818471, 0.686111, 0, 0.0813875,\n91, 0.766663, 0.555557, 0, 0,\n92, 0.766663, 0.555557, 0, 0,\n93, 0.766663, 0.555557, 0, 0,\n94, 0.766663, 0.555557, 0, 0,\n95, 0.766663, 0.555557, 0, 0,\n96, 0.702774, 0.694445, 0, 0,\n97, 0.702774, 0.694445, 0, 0,\n98, 0.511108, 0.75, 0.25, 0,\n99, 0.511108, 0.75, 0.25, 0,\n100, 0.511108, 0.75, 0.25, 0,\n101, 0.511108, 0.75, 0.25, 0,\n102, 0.574997, 0.75, 0.25, 0,\n103, 0.574997, 0.75, 0.25, 0,\n104, 0.44722, 0.75, 0.25, 0,\n105, 0.44722, 0.75, 0.25, 0,\n106, 0.319443, 0.75, 0.25, 0,\n107, 0.574997, 0.75, 0.25, 0,\n108, 0.574997, 0.75, 0.25, 0,\n109, 0.702774, 0.75, 0.25, 0,\n110, 0.574997, 0.75, 0.25, 0,\n111, 0.319443, 0.694445, 0.194443, 0,\n112, 0.958328, 0.06, 0.94, 0,\n113, 0.899996, 0.686111, 0, 0,\n114, 0.958328, 0.686111, 0, 0,\n115, 0.56875, 0.694445, 0.194445, 0.127777,\n116, 0.766663, 0.555557, 0, 0,\n117, 0.766663, 0.555557, 0, 0,\n118, 0.89444, 0.696668, 0.196668, 0,\n119, 0.89444, 0.696668, 0.196668, 0,\n120, 0.526387, 0.694445, 0.194445, 0,\n121, 0.511108, 0.694445, 0.194445, 0,\n122, 0.511108, 0.694445, 0.194445, 0,\n123, 0.702774, 0.694445, 0.194445, 0,\n124, 0.89444, 0.694445, 0.129629, 0,\n125, 0.89444, 0.694445, 0.129629, 0,\n126, 0.89444, 0.694445, 0.129629, 0,\n161, 0.89444, 0.633331, 0.133331, 0,\n162, 0.319443, 0.47361, -0.02639, 0,\n163, 0.89444, 0.633331, 0.133331, 0,\n164, 0.574997, 0.472223, -0.027777, 0,\n165, 0.89444, 0.633331, 0.133331, 0,\n166, 0.574997, 0.47361, -0.02639, 0,\n167, 0.89444, 0.633331, 0.133331, 0,\n168, 0.89444, 0.633331, 0.133331, 0,\n169, 0.89444, 0.633331, 0.133331, 0,\n170, 0.89444, 0.633331, 0.133331, 0,\n173, 0.89444, 0.633331, 0.133331, 0,\n174, 0.89444, 0.633331, 0.133331, 0,\n175, 0.89444, 0.633331, 0.133331, 0,\n176, 1.149994, 0.694445, 0.194445, 0,\n177, 0.574997, 0.47361, -0.02639, 0,\n178, 0.574997, 0.47361, -0.02639, 0,\n179, 0.89444, 0.502223, 0.002223, 0,\n180, 0.89444, 0.502223, 0.002223, 0,\n181, 0.89444, 0.696668, 0.196668, 0,\n182, 0.89444, 0.696668, 0.196668, 0,\n183, 0.89444, 0.696668, 0.196668, 0,\n184, 0.89444, 0.696668, 0.196668, 0,\n185, 0.89444, 0.696668, 0.196668, 0,\n186, 0.89444, 0.696668, 0.196668, 0,\n187, 0.89444, 0.391111, -0.108889, 0,\n188, 0.89444, 0.524445, 0.024445, 0,\n189, 0.89444, 0.585556, 0.085556, 0,\n190, 0.89444, 0.585556, 0.085556, 0,\n191, 1.149994, 0.585556, 0.085556, 0,\n192, 1.149994, 0.585556, 0.085556, 0,\n193, 0.89444, 0.585556, 0.085556, 0,\n194, 0.89444, 0.585556, 0.085556, 0,\n195, 1.149994, 0.391111, -0.108889, 0,\n196, 0.89444, 0.694445, 0.129629, 0\nMETRICS_END\n\nLARGERS_START\n34, 120, 1,\n35, 121, 1,\n42, 126, 1,\n43, 196, 1,\n98, 165, 1,\n99, 166, 1,\n100, 167, 1,\n101, 168, 1,\n102, 169, 1,\n103, 170, 1,\n104, 173, 1,\n105, 174, 1,\n106, 175, 1,\n107, 176, 1,\n108, 63, 1,\n109, 119, 1,\n110, 178, 1,\n112, 112, 1\nLARGERS_END\n\nKERNS_START\n65, 48, 0.22361,\n66, 48, 0.159721,\n67, 48, 0.159721,\n68, 48, 0.095833,\n69, 48, 0.127777,\n70, 48, 0.127777,\n71, 48, 0.127777,\n72, 48, 0.127777,\n73, 48, 0.031944,\n74, 48, 0.191666,\n75, 48, 0.063889,\n76, 48, 0.159721,\n77, 48, 0.159721,\n78, 48, 0.095833,\n79, 48, 0.127777,\n80, 48, 0.095833,\n81, 48, 0.127777,\n82, 48, 0.095833,\n83, 48, 0.159721,\n84, 48, 0.031944,\n85, 48, 0.095833,\n86, 48, 0.031944,\n87, 48, 0.095833,\n88, 48, 0.159721,\n89, 48, 0.095833,\n90, 48, 0.159721\nKERNS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/cmbx10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(cmbx10, fonts/latin/optional/cmbx10.ttf, 0)\n\nxHeight(0.444445) quad(1.149994) space(0.383331)\n\nss(cmssbx10) tt(cmtt10) it(cmbxti10)\n\nMETRICS_START\n33, 0.349998, 0.694445, 0, 0,\n34, 0.602776, 0.694445, 0, 0,\n35, 0.958328, 0.694445, 0.194443, 0,\n36, 0.574997, 0.75, 0.055555, 0,\n37, 0.958328, 0.75, 0.055555, 0,\n38, 0.89444, 0.694445, 0, 0,\n39, 0.319443, 0.694445, 0, 0,\n40, 0.44722, 0.75, 0.25, 0,\n41, 0.44722, 0.75, 0.25, 0,\n42, 0.574997, 0.75, 0, 0,\n43, 0.89444, 0.633331, 0.133331, 0,\n44, 0.319443, 0.155556, 0.194445, 0,\n45, 0.383331, 0.444445, 0, 0,\n46, 0.319443, 0.155556, 0, 0,\n47, 0.574997, 0.75, 0.25, 0,\n48, 0.574997, 0.644444, 0, 0,\n49, 0.574997, 0.644444, 0, 0,\n50, 0.574997, 0.644444, 0, 0,\n51, 0.574997, 0.644444, 0, 0,\n52, 0.574997, 0.644444, 0, 0,\n53, 0.574997, 0.644444, 0, 0,\n54, 0.574997, 0.644444, 0, 0,\n55, 0.574997, 0.644444, 0, 0,\n56, 0.574997, 0.644444, 0, 0,\n57, 0.574997, 0.644444, 0, 0,\n58, 0.319443, 0.444445, 0, 0,\n59, 0.319443, 0.444445, 0.194445, 0,\n60, 0.349998, 0.5, 0.194445, 0,\n61, 0.89444, 0.391111, -0.108889, 0,\n62, 0.543053, 0.5, 0.194445, 0,\n63, 0.543053, 0.694445, 0, 0,\n64, 0.89444, 0.694445, 0, 0,\n65, 0.86944, 0.686111, 0, 0,\n66, 0.818051, 0.686111, 0, 0,\n67, 0.830551, 0.686111, 0, 0,\n68, 0.88194, 0.686111, 0, 0,\n69, 0.755551, 0.686111, 0, 0,\n70, 0.723607, 0.686111, 0, 0,\n71, 0.904162, 0.686111, 0, 0,\n72, 0.899996, 0.686111, 0, 0,\n73, 0.43611, 0.686111, 0, 0,\n74, 0.594441, 0.686111, 0, 0,\n75, 0.901384, 0.686111, 0, 0,\n76, 0.691663, 0.686111, 0, 0,\n77, 1.091661, 0.686111, 0, 0,\n78, 0.899996, 0.686111, 0, 0,\n79, 0.863884, 0.686111, 0, 0,\n80, 0.786107, 0.686111, 0, 0,\n81, 0.863884, 0.686111, 0.194445, 0,\n82, 0.862495, 0.686111, 0, 0,\n83, 0.6388855, 0.686111, 0, 0,\n84, 0.799995, 0.686111, 0, 0,\n85, 0.884718, 0.686111, 0, 0,\n86, 0.86944, 0.686111, 0, 0.015973,\n87, 1.188883, 0.686111, 0, 0.015973,\n88, 0.86944, 0.686111, 0, 0,\n89, 0.86944, 0.686111, 0, 0.028749,\n90, 0.702774, 0.686111, 0, 0,\n91, 0.319443, 0.75, 0.25, 0,\n92, 0.602776, 0.694445, 0, 0,\n93, 0.319443, 0.75, 0.25, 0,\n94, 0.574997, 0.694445, 0, 0,\n95, 0.319443, 0.694445, 0, 0,\n96, 0.319443, 0.694445, 0, 0,\n97, 0.559024, 0.444445, 0, 0,\n98, 0.6388855, 0.694445, 0, 0,\n99, 0.511108, 0.444445, 0, 0,\n100, 0.6388855, 0.694445, 0, 0,\n101, 0.5270815, 0.444445, 0, 0,\n102, 0.351387, 0.694445, 0, 0.109027,\n103, 0.574997, 0.444445, 0.194445, 0.015973,\n104, 0.6388855, 0.694445, 0, 0,\n105, 0.319443, 0.694445, 0, 0,\n106, 0.351387, 0.694445, 0.194445, 0,\n107, 0.606941, 0.694445, 0, 0,\n108, 0.319443, 0.694445, 0, 0,\n109, 0.958328, 0.444445, 0, 0,\n110, 0.6388855, 0.444445, 0, 0,\n111, 0.574997, 0.444445, 0, 0,\n112, 0.6388855, 0.444445, 0.194445, 0,\n113, 0.606941, 0.444445, 0.194445, 0,\n114, 0.47361, 0.444445, 0, 0,\n115, 0.4536085, 0.444445, 0, 0,\n116, 0.44722, 0.634921, 0, 0,\n117, 0.6388855, 0.444445, 0, 0,\n118, 0.606941, 0.444445, 0, 0.015973,\n119, 0.830551, 0.444445, 0, 0.015973,\n120, 0.606941, 0.444445, 0, 0,\n121, 0.606941, 0.444445, 0.194445, 0.015973,\n122, 0.511108, 0.444445, 0, 0,\n123, 0.574997, 0.444445, 0, 0.031944,\n124, 1.149994, 0.444445, 0, 0.031944,\n125, 0.574997, 0.694445, 0, 0,\n126, 0.574997, 0.694445, 0, 0,\n161, 0.691663, 0.686111, 0, 0,\n162, 0.958328, 0.686111, 0, 0,\n163, 0.89444, 0.686111, 0, 0,\n164, 0.805552, 0.686111, 0, 0,\n165, 0.766663, 0.686111, 0, 0,\n166, 0.899996, 0.686111, 0, 0,\n167, 0.830551, 0.686111, 0, 0,\n168, 0.89444, 0.686111, 0, 0,\n169, 0.830551, 0.686111, 0, 0,\n170, 0.89444, 0.686111, 0, 0,\n171, 0.830551, 0.686111, 0, 0,\n174, 0.67083, 0.694445, 0, 0.109027,\n175, 0.6388855, 0.694445, 0, 0,\n176, 0.6388855, 0.694445, 0, 0,\n177, 0.958328, 0.694445, 0, 0,\n178, 0.958328, 0.694445, 0, 0,\n179, 0.319443, 0.444445, 0, 0,\n180, 0.351387, 0.444445, 0.194445, 0,\n181, 0.574997, 0.694445, 0, 0,\n182, 0.574997, 0.694445, 0, 0,\n183, 0.574997, 0.631945, 0, 0,\n184, 0.574997, 0.694445, 0, 0,\n185, 0.574997, 0.596109, 0, 0,\n186, 0.86944, 0.694445, 0, 0,\n187, 0.511108, 0, 0.170138, 0,\n188, 0.597219, 0.694445, 0, 0,\n189, 0.830551, 0.444445, 0, 0,\n190, 0.89444, 0.444445, 0, 0,\n191, 0.574997, 0.541667, 0.097223, 0,\n192, 1.041661, 0.686111, 0, 0,\n193, 1.169438, 0.686111, 0, 0,\n194, 0.89444, 0.734723, 0.048612, 0,\n195, 0.319443, 0.444445, 0, 0,\n196, 0.574997, 0.694445, 0, 0,\n197, 0.319366, 0.029, 0.215, 0\nMETRICS_END\n\nLARGERS_START\n40, 161, 1,\n41, 162, 1,\n47, 177, 1,\n91, 163, 1,\n93, 164, 1\nLARGERS_END\n\nLIGTURES_START\n33, 96, 60,\n39, 39, 34,\n45, 45, 123,\n63, 96, 62,\n96, 96, 92,\n102, 105, 175,\n102, 102, 174,\n102, 108, 176,\n123, 45, 124,\n174, 105, 177,\n174, 108, 178\nLIGTURES_END\n\nKERNS_START\n39, 63, 0.127777,\n39, 33, 0.127777,\n65, 116, -0.031944,\n65, 67, -0.031944,\n65, 79, -0.031944,\n65, 71, -0.031944,\n65, 85, -0.031944,\n65, 81, -0.031944,\n65, 84, -0.095833,\n65, 89, -0.095833,\n65, 86, -0.127777,\n65, 87, -0.127777,\n68, 88, -0.031944,\n68, 87, -0.031944,\n68, 65, -0.031944,\n68, 86, -0.031944,\n68, 89, -0.031944,\n70, 111, -0.095833,\n70, 101, -0.095833,\n70, 117, -0.095833,\n70, 114, -0.095833,\n70, 97, -0.095833,\n70, 65, -0.127777,\n70, 79, -0.031944,\n70, 67, -0.031944,\n70, 71, -0.031944,\n70, 81, -0.031944,\n73, 73, 0.031944,\n75, 79, -0.031944,\n75, 67, -0.031944,\n75, 71, -0.031944,\n75, 81, -0.031944,\n76, 84, -0.095833,\n76, 89, -0.095833,\n76, 86, -0.127777,\n76, 87, -0.127777,\n79, 88, -0.031944,\n79, 87, -0.031944,\n79, 65, -0.031944,\n79, 86, -0.031944,\n79, 89, -0.031944,\n80, 65, -0.095833,\n80, 111, -0.031944,\n80, 101, -0.031944,\n80, 97, -0.031944,\n80, 46, -0.095833,\n80, 44, -0.095833,\n82, 116, -0.031944,\n82, 67, -0.031944,\n82, 79, -0.031944,\n82, 71, -0.031944,\n82, 85, -0.031944,\n82, 81, -0.031944,\n82, 84, -0.095833,\n82, 89, -0.095833,\n82, 86, -0.127777,\n82, 87, -0.127777,\n84, 121, -0.031944,\n84, 101, -0.095833,\n84, 111, -0.095833,\n84, 114, -0.095833,\n84, 97, -0.095833,\n84, 65, -0.095833,\n84, 117, -0.095833,\n86, 111, -0.095833,\n86, 101, -0.095833,\n86, 117, -0.095833,\n86, 114, -0.095833,\n86, 97, -0.095833,\n86, 65, -0.127777,\n86, 79, -0.031944,\n86, 67, -0.031944,\n86, 71, -0.031944,\n86, 81, -0.031944,\n87, 111, -0.095833,\n87, 101, -0.095833,\n87, 117, -0.095833,\n87, 114, -0.095833,\n87, 97, -0.095833,\n87, 65, -0.127777,\n87, 79, -0.031944,\n87, 67, -0.031944,\n87, 71, -0.031944,\n87, 81, -0.031944,\n88, 79, -0.031944,\n88, 67, -0.031944,\n88, 71, -0.031944,\n88, 81, -0.031944,\n89, 101, -0.095833,\n89, 111, -0.095833,\n89, 114, -0.095833,\n89, 97, -0.095833,\n89, 65, -0.095833,\n89, 117, -0.095833,\n97, 118, -0.031944,\n97, 106, 0.063889,\n97, 121, -0.031944,\n97, 119, -0.031944,\n98, 101, 0.031944,\n98, 111, 0.031944,\n98, 120, -0.031944,\n98, 100, 0.031944,\n98, 99, 0.031944,\n98, 113, 0.031944,\n98, 118, -0.031944,\n98, 106, 0.063889,\n98, 121, -0.031944,\n98, 119, -0.031944,\n99, 104, -0.031944,\n99, 107, -0.031944,\n102, 39, 0.109027,\n102, 63, 0.109027,\n102, 33, 0.109027,\n102, 41, 0.109027,\n102, 93, 0.109027,\n103, 106, 0.031944,\n104, 116, -0.031944,\n104, 117, -0.031944,\n104, 98, -0.031944,\n104, 121, -0.031944,\n104, 118, -0.031944,\n104, 119, -0.031944,\n107, 97, -0.063889,\n107, 101, -0.031944,\n107, 97, -0.031944,\n107, 111, -0.031944,\n107, 99, -0.031944,\n109, 116, -0.031944,\n109, 117, -0.031944,\n109, 98, -0.031944,\n109, 121, -0.031944,\n109, 118, -0.031944,\n109, 119, -0.031944,\n110, 116, -0.031944,\n110, 117, -0.031944,\n110, 98, -0.031944,\n110, 121, -0.031944,\n110, 118, -0.031944,\n110, 119, -0.031944,\n111, 101, 0.031944,\n111, 111, 0.031944,\n111, 120, -0.031944,\n111, 100, 0.031944,\n111, 99, 0.031944,\n111, 113, 0.031944,\n111, 118, -0.031944,\n111, 106, 0.063889,\n111, 121, -0.031944,\n111, 119, -0.031944,\n112, 101, 0.031944,\n112, 111, 0.031944,\n112, 120, -0.031944,\n112, 100, 0.031944,\n112, 99, 0.031944,\n112, 113, 0.031944,\n112, 118, -0.031944,\n112, 106, 0.063889,\n112, 121, -0.031944,\n112, 119, -0.031944,\n116, 121, -0.031944,\n116, 119, -0.031944,\n117, 119, -0.031944,\n118, 97, -0.063889,\n118, 101, -0.031944,\n118, 97, -0.031944,\n118, 111, -0.031944,\n118, 99, -0.031944,\n119, 101, -0.031944,\n119, 97, -0.031944,\n119, 111, -0.031944,\n119, 99, -0.031944,\n121, 111, -0.031944,\n121, 101, -0.031944,\n121, 97, -0.031944,\n121, 46, -0.095833,\n121, 44, -0.095833,\n174, 39, 0.109027,\n174, 63, 0.109027,\n174, 33, 0.109027,\n174, 41, 0.109027,\n174, 93, 0.109027,\n195, 108, -0.319443,\n195, 76, -0.377777\nKERNS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/cmbxti10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(cmbxti10, fonts/latin/optional/cmbxti10.ttf, 0)\n\nxHeight(0.444445) quad(1.182211) space(0.414441)\n\nroman(cmbx10) ss(cmssbx10) tt(cmtt10)\n\nMETRICS_START\n33, 0.386108, 0.694445, 0, 0.114168,\n34, 0.620552, 0.694445, 0, 0.0793915,\n35, 0.944435, 0.694445, 0.194443, 0.068334,\n36, 0.868533, 0.694445, 0, 0,\n37, 0.944435, 0.75, 0.055555, 0.128612,\n38, 0.885547, 0.694445, 0, 0.0852785,\n39, 0.355553, 0.694445, 0, 0.129446,\n40, 0.47333, 0.75, 0.25, 0.158055,\n41, 0.47333, 0.75, 0.25, 0.033055,\n42, 0.591105, 0.75, 0, 0.143333,\n43, 0.885547, 0.60333, 0.10333, 0.033055,\n44, 0.355553, 0.1472225, 0.194445, 0,\n45, 0.414441, 0.444445, 0, 0.026111,\n46, 0.355553, 0.1472225, 0, 0,\n47, 0.591105, 0.75, 0.25, 0.158055,\n48, 0.591105, 0.644444, 0, 0.131666,\n49, 0.591105, 0.644444, 0, 0.131666,\n50, 0.591105, 0.644444, 0, 0.131666,\n51, 0.591105, 0.644444, 0, 0.131666,\n52, 0.591105, 0.644444, 0.194445, 0.131666,\n53, 0.591105, 0.644444, 0, 0.131666,\n54, 0.591105, 0.644444, 0, 0.131666,\n55, 0.591105, 0.644444, 0.194445, 0.131666,\n56, 0.591105, 0.644444, 0, 0.131666,\n57, 0.591105, 0.644444, 0, 0.131666,\n58, 0.355553, 0.444445, 0, 0.066946,\n59, 0.355553, 0.444445, 0.194445, 0.066946,\n60, 0.386108, 0.5, 0.194445, 0.065557,\n61, 0.885547, 0.391111, -0.108889, 0.068334,\n62, 0.591105, 0.5, 0.194445, 0,\n63, 0.591105, 0.694445, 0, 0.114723,\n64, 0.885547, 0.694445, 0, 0.092082,\n65, 0.865547, 0.686111, 0, 0,\n66, 0.81666, 0.686111, 0, 0.099202,\n67, 0.826658, 0.686111, 0, 0.142084,\n68, 0.875547, 0.686111, 0, 0.090625,\n69, 0.756659, 0.686111, 0, 0.114306,\n70, 0.727216, 0.686111, 0, 0.12903,\n71, 0.895269, 0.686111, 0, 0.073473,\n72, 0.896103, 0.686111, 0, 0.172084,\n73, 0.471664, 0.686111, 0, 0.156807,\n74, 0.61055, 0.686111, 0, 0.145001,\n75, 0.894992, 0.686111, 0, 0.142084,\n76, 0.697771, 0.686111, 0, 0,\n77, 1.072767, 0.686111, 0, 0.172084,\n78, 0.896103, 0.686111, 0, 0.172084,\n79, 0.854991, 0.686111, 0, 0.090625,\n80, 0.787214, 0.686111, 0, 0.099202,\n81, 0.854991, 0.686111, 0.194445, 0.090625,\n82, 0.859438, 0.686111, 0, 0.025592,\n83, 0.649994, 0.686111, 0, 0.11264,\n84, 0.796103, 0.686111, 0, 0.12903,\n85, 0.880826, 0.686111, 0, 0.172084,\n86, 0.865547, 0.686111, 0, 0.186251,\n87, 1.159988, 0.686111, 0, 0.186251,\n88, 0.865547, 0.686111, 0, 0.156807,\n89, 0.865547, 0.686111, 0, 0.198029,\n90, 0.708882, 0.686111, 0, 0.142084,\n91, 0.35611, 0.75, 0.25, 0.1875,\n92, 0.620552, 0.694445, 0, 0.167722,\n93, 0.35611, 0.75, 0.25, 0.099724,\n94, 0.591105, 0.694445, 0, 0.067085,\n95, 0.355553, 0.694445, 0, 0.129446,\n96, 0.355553, 0.694445, 0, 0.129446,\n97, 0.591105, 0.444445, 0, 0.094261,\n98, 0.532217, 0.694445, 0, 0.078611,\n99, 0.532217, 0.444445, 0, 0.052223,\n100, 0.591105, 0.694445, 0, 0.108614,\n101, 0.532217, 0.444445, 0, 0.085002,\n102, 0.400002, 0.694445, 0.194445, 0.217778,\n103, 0.532217, 0.444445, 0.194445, 0.105001,\n104, 0.591105, 0.694445, 0, 0.094261,\n105, 0.355553, 0.693255, 0, 0.113872,\n106, 0.355553, 0.693255, 0.194445, 0.167204,\n107, 0.532217, 0.694445, 0, 0.111112,\n108, 0.296664, 0.694445, 0, 0.108614,\n109, 0.944435, 0.444445, 0, 0.094261,\n110, 0.649994, 0.444445, 0, 0.094261,\n111, 0.591105, 0.444445, 0, 0.078611,\n112, 0.591105, 0.444445, 0.194445, 0.078611,\n113, 0.532217, 0.444445, 0.194445, 0.105001,\n114, 0.501665, 0.444445, 0, 0.111112,\n115, 0.486941, 0.444445, 0, 0.081667,\n116, 0.384997, 0.634921, 0, 0.09639,\n117, 0.62055, 0.444445, 0, 0.094261,\n118, 0.532217, 0.444445, 0, 0.111112,\n119, 0.767771, 0.444445, 0, 0.111112,\n120, 0.560553, 0.444445, 0, 0.1258335,\n121, 0.561663, 0.444445, 0.194445, 0.105001,\n122, 0.490553, 0.444445, 0, 0.13889,\n123, 0.591105, 0.444445, 0, 0.098114,\n124, 1.182211, 0.444445, 0, 0.098114,\n125, 0.591105, 0.694445, 0, 0.114723,\n126, 0.591105, 0.694445, 0, 0.114723,\n161, 0.697771, 0.686111, 0, 0.12903,\n162, 0.944435, 0.686111, 0, 0,\n163, 0.885547, 0.686111, 0, 0.090625,\n164, 0.806659, 0.686111, 0, 0,\n165, 0.767771, 0.686111, 0, 0.150917,\n166, 0.896103, 0.686111, 0, 0.172084,\n167, 0.826658, 0.686111, 0, 0.114306,\n168, 0.885547, 0.686111, 0, 0.107778,\n169, 0.826658, 0.686111, 0, 0.056318,\n170, 0.885547, 0.686111, 0, 0.107778,\n173, 0.826658, 0.686111, 0, 0.099202,\n174, 0.755554, 0.694445, 0.194445, 0.217778,\n175, 0.674443, 0.694445, 0.194445, 0.108614,\n176, 0.703886, 0.694445, 0.194445, 0.108614,\n177, 1.044718, 0.694445, 0.194445, 0.108614,\n178, 1.059439, 0.694445, 0.194445, 0.108614,\n179, 0.355553, 0.444445, 0, 0.094261,\n180, 0.384997, 0.444445, 0.194445, 0.046114,\n181, 0.591105, 0.694445, 0, 0,\n182, 0.591105, 0.694445, 0, 0.0852785,\n183, 0.591105, 0.631945, 0, 0.08271,\n184, 0.591105, 0.694445, 0, 0.103334,\n185, 0.591105, 0.594442, 0, 0.1044445,\n186, 0.94888, 0.694445, 0, 0,\n187, 0.532217, 0, 0.170138, 0,\n188, 0.664999, 0.694445, 0.194445, 0.097361,\n189, 0.826658, 0.444445, 0, 0.085002,\n190, 0.826658, 0.444445, 0, 0.085002,\n191, 0.591105, 0.541667, 0.097223, 0.094584,\n192, 1.022768, 0.686111, 0, 0.114306,\n193, 1.140544, 0.686111, 0, 0.114306,\n194, 0.885547, 0.734723, 0.048612, 0.090625,\n195, 0.296664, 0.444445, 0, 0,\n196, 0.591105, 0.694445, 0, 0.114725,\n197, 0.355469, 0.037, 0.193, 0\nMETRICS_END\n\nLARGERS_START\n40, 161, 1,\n41, 162, 1,\n47, 177, 1,\n91, 163, 1,\n93, 164, 1\nLARGERS_END\n\nLIGTURES_START\n33, 96, 60,\n39, 39, 34,\n45, 45, 123,\n63, 96, 62,\n96, 96, 92,\n102, 105, 175,\n102, 102, 174,\n102, 108, 176,\n123, 45, 124,\n174, 105, 177,\n174, 108, 178\nLIGTURES_END\n\nKERNS_START\n39, 63, 0.117777,\n39, 33, 0.117777,\n65, 110, -0.029445,\n65, 108, -0.029445,\n65, 114, -0.029445,\n65, 117, -0.029445,\n65, 109, -0.029445,\n65, 116, -0.029445,\n65, 105, -0.029445,\n65, 67, -0.029445,\n65, 79, -0.029445,\n65, 71, -0.029445,\n65, 104, -0.029445,\n65, 98, -0.029445,\n65, 85, -0.029445,\n65, 107, -0.029445,\n65, 118, -0.029445,\n65, 119, -0.029445,\n65, 81, -0.029445,\n65, 84, -0.088333,\n65, 89, -0.088333,\n65, 86, -0.117777,\n65, 87, -0.117777,\n65, 101, -0.058888,\n65, 97, -0.058888,\n65, 111, -0.058888,\n65, 100, -0.058888,\n65, 99, -0.058888,\n65, 103, -0.058888,\n65, 113, -0.058888,\n68, 88, -0.029445,\n68, 87, -0.029445,\n68, 65, -0.029445,\n68, 86, -0.029445,\n68, 89, -0.029445,\n70, 111, -0.088333,\n70, 101, -0.088333,\n70, 117, -0.088333,\n70, 114, -0.088333,\n70, 97, -0.088333,\n70, 65, -0.117777,\n70, 79, -0.029445,\n70, 67, -0.029445,\n70, 71, -0.029445,\n70, 81, -0.029445,\n75, 79, -0.029445,\n75, 67, -0.029445,\n75, 71, -0.029445,\n75, 81, -0.029445,\n76, 84, -0.088333,\n76, 89, -0.088333,\n76, 86, -0.117777,\n76, 87, -0.117777,\n76, 101, -0.058888,\n76, 97, -0.058888,\n76, 111, -0.058888,\n76, 100, -0.058888,\n76, 99, -0.058888,\n76, 103, -0.058888,\n76, 113, -0.058888,\n79, 88, -0.029445,\n79, 87, -0.029445,\n79, 65, -0.029445,\n79, 86, -0.029445,\n79, 89, -0.029445,\n80, 65, -0.088333,\n82, 110, -0.029445,\n82, 108, -0.029445,\n82, 114, -0.029445,\n82, 117, -0.029445,\n82, 109, -0.029445,\n82, 116, -0.029445,\n82, 105, -0.029445,\n82, 67, -0.029445,\n82, 79, -0.029445,\n82, 71, -0.029445,\n82, 104, -0.029445,\n82, 98, -0.029445,\n82, 85, -0.029445,\n82, 107, -0.029445,\n82, 118, -0.029445,\n82, 119, -0.029445,\n82, 81, -0.029445,\n82, 84, -0.088333,\n82, 89, -0.088333,\n82, 86, -0.117777,\n82, 87, -0.117777,\n82, 101, -0.058888,\n82, 97, -0.058888,\n82, 111, -0.058888,\n82, 100, -0.058888,\n82, 99, -0.058888,\n82, 103, -0.058888,\n82, 113, -0.058888,\n84, 121, -0.088333,\n84, 101, -0.088333,\n84, 111, -0.088333,\n84, 114, -0.088333,\n84, 97, -0.088333,\n84, 117, -0.088333,\n84, 65, -0.088333,\n86, 111, -0.088333,\n86, 101, -0.088333,\n86, 117, -0.088333,\n86, 114, -0.088333,\n86, 97, -0.088333,\n86, 65, -0.117777,\n86, 79, -0.029445,\n86, 67, -0.029445,\n86, 71, -0.029445,\n86, 81, -0.029445,\n87, 65, -0.088333,\n88, 79, -0.029445,\n88, 67, -0.029445,\n88, 71, -0.029445,\n88, 81, -0.029445,\n89, 101, -0.088333,\n89, 111, -0.088333,\n89, 114, -0.088333,\n89, 97, -0.088333,\n89, 117, -0.088333,\n89, 65, -0.088333,\n98, 101, -0.058888,\n98, 97, -0.058888,\n98, 111, -0.058888,\n98, 100, -0.058888,\n98, 99, -0.058888,\n98, 103, -0.058888,\n98, 113, -0.058888,\n99, 101, -0.058888,\n99, 97, -0.058888,\n99, 111, -0.058888,\n99, 100, -0.058888,\n99, 99, -0.058888,\n99, 103, -0.058888,\n99, 113, -0.058888,\n100, 108, 0.058888,\n101, 101, -0.058888,\n101, 97, -0.058888,\n101, 111, -0.058888,\n101, 100, -0.058888,\n101, 99, -0.058888,\n101, 103, -0.058888,\n101, 113, -0.058888,\n102, 39, 0.106667,\n102, 63, 0.106667,\n102, 33, 0.106667,\n102, 41, 0.106667,\n102, 93, 0.106667,\n108, 108, 0.058888,\n110, 39, -0.117777,\n111, 101, -0.058888,\n111, 97, -0.058888,\n111, 111, -0.058888,\n111, 100, -0.058888,\n111, 99, -0.058888,\n111, 103, -0.058888,\n111, 113, -0.058888,\n112, 101, -0.058888,\n112, 97, -0.058888,\n112, 111, -0.058888,\n112, 100, -0.058888,\n112, 99, -0.058888,\n112, 103, -0.058888,\n112, 113, -0.058888,\n114, 101, -0.058888,\n114, 97, -0.058888,\n114, 111, -0.058888,\n114, 100, -0.058888,\n114, 99, -0.058888,\n114, 103, -0.058888,\n114, 113, -0.058888,\n119, 108, 0.058888,\n174, 39, 0.106667,\n174, 63, 0.106667,\n174, 33, 0.106667,\n174, 41, 0.106667,\n174, 93, 0.106667,\n195, 108, -0.296664,\n195, 76, -0.384165\nKERNS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/cmex10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(cmex10, fonts/base/cmex10.ttf, 0)\n\nxHeight(0.430555) quad(1.000003)\n\nMETRICS_START\n33, 0.79167, 0.039999, 2.9600315, 0,\n34, 0.583336, 0.039999, 2.9600315, 0,\n35, 0.583336, 0.039999, 2.9600315, 0,\n36, 0.638891, 0.039999, 2.9600315, 0,\n37, 0.638891, 0.039999, 2.9600315, 0,\n38, 0.638891, 0.039999, 2.9600315, 0,\n39, 0.638891, 0.039999, 2.9600315, 0,\n40, 0.80556, 0.039999, 2.9600315, 0,\n41, 0.80556, 0.039999, 2.9600315, 0,\n42, 0.80556, 0.039999, 2.9600315, 0,\n43, 0.80556, 0.039999, 2.9600315, 0,\n44, 1.2777815, 0.039999, 2.9600315, 0,\n45, 1.2777815, 0.039999, 2.9600315, 0,\n46, 0.811114, 0.039999, 1.760019, 0,\n47, 0.811114, 0.039999, 1.760019, 0,\n48, 0.875003, 0.039999, 1.760019, 0,\n49, 0.875003, 0.039999, 1.760019, 0,\n50, 0.666669, 0.039999, 1.760019, 0,\n51, 0.666669, 0.039999, 1.760019, 0,\n52, 0.666669, 0.039999, 1.760019, 0,\n53, 0.666669, 0.039999, 1.760019, 0,\n54, 0.666669, 0, 0.600006, 0,\n55, 0.666669, 0, 0.600006, 0,\n56, 0.888891, 0, 0.900009, 0,\n57, 0.888891, 0, 0.900009, 0,\n58, 0.888891, 0, 0.900009, 0,\n59, 0.888891, 0, 0.900009, 0,\n60, 0.888891, 0, 1.800018, 0,\n61, 0.888891, 0, 1.800018, 0,\n62, 0.888891, 0, 0.300003, 0,\n63, 0.666669, 0, 0.600006, 0,\n64, 0.875003, 0.039999, 1.760019, 0,\n65, 0.875003, 0.039999, 1.760019, 0,\n66, 0.875003, 0, 0.600006, 0,\n67, 0.875003, 0, 0.600006, 0,\n68, 0.611113, 0.039999, 1.760019, 0,\n69, 0.611113, 0.039999, 1.760019, 0,\n70, 0.833336, 0, 1.000013, 0,\n71, 1.1111145, 0.100001, 1.500012, 0,\n72, 0.472223, 0, 1.111122, 0.194446,\n73, 0.555557, 0, 2.222246, 0.444446,\n74, 1.1111145, 0, 1.000013, 0,\n75, 1.511116, 0.100001, 1.500012, 0,\n76, 1.1111145, 0, 1.000013, 0,\n77, 1.511116, 0.100001, 1.500012, 0,\n78, 1.1111145, 0, 1.000013, 0,\n79, 1.511116, 0.100001, 1.500012, 0,\n80, 1.055559, 0, 1.000013, 0,\n81, 0.9444475, 0, 1.000013, 0,\n82, 0.472223, 0, 1.111122, 0.194446,\n83, 0.833336, 0, 1.000013, 0,\n84, 0.833336, 0, 1.000013, 0,\n85, 0.833336, 0, 1.000013, 0,\n86, 0.833336, 0, 1.000013, 0,\n87, 0.833336, 0, 1.000013, 0,\n88, 1.444448, 0.100001, 1.500012, 0,\n89, 1.2777815, 0.100001, 1.500012, 0,\n90, 0.555557, 0, 2.222246, 0.444446,\n91, 1.1111145, 0.100001, 1.500012, 0,\n92, 1.1111145, 0.100001, 1.500012, 0,\n93, 1.1111145, 0.100001, 1.500012, 0,\n94, 1.1111145, 0.100001, 1.500012, 0,\n95, 1.1111145, 0.100001, 1.500012, 0,\n96, 0.9444475, 0, 1.000013, 0,\n97, 1.2777815, 0.100001, 1.500012, 0,\n98, 0.555557, 0.722223, 0, 0,\n99, 1.000003, 0.75, 0, 0,\n100, 1.444448, 0.75, 0, 0,\n101, 0.555557, 0.722223, 0, 0,\n102, 1.000003, 0.75, 0, 0,\n103, 1.444448, 0.75, 0, 0,\n104, 0.472224, 0.039999, 1.760019, 0,\n105, 0.472224, 0.039999, 1.760019, 0,\n106, 0.527781, 0.039999, 1.760019, 0,\n107, 0.527781, 0.039999, 1.760019, 0,\n108, 0.527781, 0.039999, 1.760019, 0,\n109, 0.527781, 0.039999, 1.760019, 0,\n110, 0.666669, 0.039999, 1.760019, 0,\n111, 0.666669, 0.039999, 1.760019, 0,\n112, 1.000003, 0.039999, 1.160013, 0,\n113, 1.000003, 0.039999, 1.760019, 0,\n114, 1.000003, 0.039999, 2.360025, 0,\n115, 1.000003, 0.039999, 2.9600315, 0,\n116, 1.055559, 0, 1.800018, 0,\n117, 1.055559, 0, 0.585006, 0,\n118, 1.055559, 0.039999, 0.550007, 0,\n119, 0.777781, 0, 0.600006, 0,\n120, 0.666669, 0, 0.600006, 0,\n121, 0.666669, 0, 0.600006, 0,\n122, 0.450005, 0.119998, 0, 0,\n123, 0.450005, 0.119998, 0, 0,\n124, 0.450005, 0.119998, 0, 0,\n125, 0.450005, 0.119998, 0, 0,\n126, 0.777781, 0, 0.600006, 0,\n161, 0.458336, 0.039999, 1.160013, 0,\n162, 0.458336, 0.039999, 1.160013, 0,\n163, 0.416669, 0.039999, 1.160013, 0,\n164, 0.416669, 0.039999, 1.160013, 0,\n165, 0.472224, 0.039999, 1.160013, 0,\n166, 0.472224, 0.039999, 1.160013, 0,\n167, 0.472224, 0.039999, 1.160013, 0,\n168, 0.472224, 0.039999, 1.160013, 0,\n169, 0.583336, 0.039999, 1.160013, 0,\n170, 0.583336, 0.039999, 1.160013, 0,\n173, 0.472224, 0.039999, 1.160013, 0,\n174, 0.472224, 0.039999, 1.160013, 0,\n175, 0.333334, 0, 0.600006, 0,\n176, 0.555557, 0, 0.600006, 0,\n177, 0.577779, 0.039999, 1.160013, 0,\n178, 0.577779, 0.039999, 1.160013, 0,\n179, 0.597224, 0.039999, 1.760019, 0,\n180, 0.597224, 0.039999, 1.760019, 0,\n181, 0.7361145, 0.039999, 2.360025, 0,\n182, 0.7361145, 0.039999, 2.360025, 0,\n183, 0.527781, 0.039999, 2.360025, 0,\n184, 0.527781, 0.039999, 2.360025, 0,\n185, 0.583336, 0.039999, 2.360025, 0,\n186, 0.583336, 0.039999, 2.360025, 0,\n187, 0.583336, 0.039999, 2.360025, 0,\n188, 0.583336, 0.039999, 2.360025, 0,\n189, 0.750002, 0.039999, 2.360025, 0,\n190, 0.750002, 0.039999, 2.360025, 0,\n191, 0.750002, 0.039999, 2.360025, 0,\n192, 0.750002, 0.039999, 2.360025, 0,\n193, 1.044447, 0.039999, 2.360025, 0,\n194, 1.044447, 0.039999, 2.360025, 0,\n195, 0.79167, 0.039999, 2.9600315, 0,\n196, 0.777781, 0, 0.600006, 0\nMETRICS_END\n\nEXTENSIONS_START\n48, 48, -1, 66, 64,\n49, 49, -1, 67, 65,\n50, 50, -1, 54, 52,\n51, 51, -1, 55, 53,\n52, -1, -1, 54, 52,\n53, -1, -1, 55, 53,\n54, 50, -1, 54, -1,\n55, 51, -1, 55, -1,\n56, 56, 60, 62, 58,\n57, 57, 61, 62, 59,\n58, 56, -1, 62, 58,\n59, 57, -1, 62, 59,\n60, -1, -1, 63, -1,\n61, -1, -1, 119, -1,\n62, -1, -1, 62, -1,\n63, 120, -1, 63, 121,\n64, 56, -1, 62, 59,\n65, 57, -1, 62, 58,\n66, -1, -1, 66, -1,\n67, -1, -1, 67, -1,\n116, 118, -1, 117, 116,\n119, 126, -1, 119, 196,\n120, 120, -1, 63, -1,\n121, -1, -1, 63, 121,\n126, 126, -1, 119, -1,\n175, -1, -1, 175, -1,\n176, -1, -1, 176, -1,\n196, -1, -1, 119, 196\nEXTENSIONS_END\n\nLARGERS_START\n33, 49, 1,\n34, 50, 1,\n35, 51, 1,\n36, 52, 1,\n37, 53, 1,\n38, 54, 1,\n39, 55, 1,\n40, 56, 1,\n41, 57, 1,\n46, 193, 1,\n47, 194, 1,\n68, 191, 1,\n69, 192, 1,\n70, 71, 1,\n72, 73, 1,\n74, 75, 1,\n76, 77, 1,\n78, 79, 1,\n80, 88, 1,\n81, 89, 1,\n82, 90, 1,\n83, 91, 1,\n84, 92, 1,\n85, 93, 1,\n86, 94, 1,\n87, 95, 1,\n96, 97, 1,\n98, 99, 1,\n99, 100, 1,\n100, 91, 0,\n101, 102, 1,\n102, 103, 1,\n103, 93, 0,\n104, 183, 1,\n105, 184, 1,\n106, 185, 1,\n107, 186, 1,\n108, 187, 1,\n109, 188, 1,\n110, 189, 1,\n111, 190, 1,\n112, 113, 1,\n113, 114, 1,\n114, 115, 1,\n115, 116, 1,\n161, 179, 1,\n162, 180, 1,\n163, 104, 1,\n164, 105, 1,\n165, 106, 1,\n166, 107, 1,\n167, 108, 1,\n168, 109, 1,\n169, 110, 1,\n170, 111, 1,\n173, 68, 1,\n174, 69, 1,\n177, 46, 1,\n178, 47, 1,\n179, 181, 1,\n180, 182, 1,\n181, 195, 1,\n182, 33, 1,\n183, 34, 1,\n184, 35, 1,\n185, 36, 1,\n186, 37, 1,\n187, 38, 1,\n188, 39, 1,\n189, 40, 1,\n190, 41, 1,\n191, 42, 1,\n192, 43, 1,\n193, 44, 1,\n194, 45, 1,\n195, 48, 1\nLARGERS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/cmmi10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(cmmi10, fonts/base/cmmi10.ttf, 0)\n\nxHeight(0.430555) quad(1.000003) skew(196)\n\nbold(cmmib10) roman(cmr10) ss(cmss10) tt(cmtt10) it(cmti10)\n\nMETRICS_START\n33, 0.622455, 0.430555, 0, 0.035879,\n34, 0.466318, 0.430555, 0, 0,\n35, 0.59144, 0.694445, 0, 0,\n36, 0.82813, 0.430555, 0, 0.027779,\n37, 0.517015, 0.430555, 0.194445, 0,\n38, 0.362848, 0.430555, 0.097223, 0.07986,\n39, 0.654167, 0.430555, 0.194445, 0,\n40, 1.000003, 0.366875, -0.133125, 0,\n41, 1.000003, 0.366875, -0.133125, 0,\n42, 1.000003, 0.366875, -0.133125, 0,\n43, 1.000003, 0.366875, -0.133125, 0,\n44, 0.277779, 0.463748, -0.036252, 0,\n45, 0.277779, 0.463748, -0.036252, 0,\n46, 0.500002, 0.465279, -0.034721, 0,\n47, 0.500002, 0.465279, -0.034721, 0,\n48, 0.500002, 0.430555, 0, 0,\n49, 0.500002, 0.430555, 0, 0,\n50, 0.500002, 0.430555, 0, 0,\n51, 0.500002, 0.430555, 0.194445, 0,\n52, 0.500002, 0.430555, 0.194445, 0,\n53, 0.500002, 0.430555, 0.194445, 0,\n54, 0.500002, 0.644444, 0, 0,\n55, 0.500002, 0.430555, 0.194445, 0,\n56, 0.500002, 0.644444, 0, 0,\n57, 0.500002, 0.430555, 0.194445, 0,\n58, 0.277779, 0.105556, 0, 0,\n59, 0.277779, 0.105556, 0.194445, 0,\n60, 0.777781, 0.539098, 0.039098, 0,\n61, 0.500002, 0.75, 0.25, 0,\n62, 0.777781, 0.539098, 0.039098, 0,\n63, 0.500002, 0.465279, -0.034721, 0,\n64, 0.530904, 0.694445, 0, 0.055555,\n65, 0.750002, 0.683332, 0, 0,\n66, 0.75851, 0.683332, 0, 0.050173,\n67, 0.714722, 0.683332, 0, 0.0715275,\n68, 0.827917, 0.683332, 0, 0.027779,\n69, 0.738195, 0.683332, 0, 0.057638,\n70, 0.643057, 0.683332, 0, 0.13889,\n71, 0.786249, 0.683332, 0, 0,\n72, 0.831251, 0.683332, 0, 0.081248,\n73, 0.439585, 0.683332, 0, 0.078471,\n74, 0.554514, 0.683332, 0, 0.096181,\n75, 0.849307, 0.683332, 0, 0.0715275,\n76, 0.680557, 0.683332, 0, 0,\n77, 0.97014, 0.683332, 0, 0.109027,\n78, 0.8034725, 0.683332, 0, 0.109027,\n79, 0.762776, 0.683332, 0, 0.027779,\n80, 0.692014, 0.683332, 0, 0.13889,\n81, 0.790555, 0.683332, 0.194445, 0,\n82, 0.75929, 0.683332, 0, 0.007726,\n83, 0.613195, 0.683332, 0, 0.057638,\n84, 0.584376, 0.683332, 0, 0.13889,\n85, 0.682777, 0.683332, 0, 0.109027,\n86, 0.583334, 0.683332, 0, 0.222223,\n87, 0.944446, 0.683332, 0, 0.13889,\n88, 0.828474, 0.683332, 0, 0.078471,\n89, 0.580557, 0.683332, 0, 0.222223,\n90, 0.68264, 0.683332, 0, 0.0715275,\n91, 0.38889, 0.75, 0, 0,\n92, 0.38889, 0.694445, 0.194445, 0,\n93, 0.38889, 0.694445, 0.194445, 0,\n94, 1.000003, 0.35764, -0.14236, 0,\n95, 1.000003, 0.35764, -0.14236, 0,\n96, 0.41667, 0.694445, 0, 0,\n97, 0.52859, 0.430555, 0, 0,\n98, 0.429167, 0.694445, 0, 0,\n99, 0.432756, 0.430555, 0, 0,\n100, 0.520488, 0.694445, 0, 0,\n101, 0.465627, 0.430555, 0, 0,\n102, 0.489586, 0.694445, 0.194445, 0.10764,\n103, 0.476969, 0.430555, 0.194445, 0.035879,\n104, 0.5761595, 0.694445, 0, 0,\n105, 0.344513, 0.659525, 0, 0,\n106, 0.411807, 0.659525, 0.194445, 0.057243,\n107, 0.520604, 0.694445, 0, 0.031481,\n108, 0.29838, 0.694445, 0, 0.019678,\n109, 0.878014, 0.430555, 0, 0,\n110, 0.600235, 0.430555, 0, 0,\n111, 0.484723, 0.430555, 0, 0,\n112, 0.503126, 0.430555, 0.194445, 0,\n113, 0.446414, 0.430555, 0.194445, 0.035879,\n114, 0.4511595, 0.430555, 0, 0.027779,\n115, 0.46875, 0.430555, 0, 0,\n116, 0.361113, 0.61508, 0, 0,\n117, 0.572458, 0.430555, 0, 0,\n118, 0.484724, 0.430555, 0, 0.035879,\n119, 0.715918, 0.430555, 0, 0.026909,\n120, 0.571528, 0.430555, 0, 0,\n121, 0.490282, 0.430555, 0.194445, 0.035879,\n122, 0.46505, 0.430555, 0, 0.043981,\n123, 0.322456, 0.430555, 0, 0,\n124, 0.38403, 0.430555, 0.194445, 0,\n125, 0.636459, 0.430555, 0.194445, 0,\n126, 0.500002, 0.714444, 0, 0.153819,\n161, 0.615278, 0.683332, 0, 0.13889,\n162, 0.833336, 0.683332, 0, 0,\n163, 0.762776, 0.683332, 0, 0.027779,\n164, 0.694446, 0.683332, 0, 0,\n165, 0.742363, 0.683332, 0, 0.075694,\n166, 0.831251, 0.683332, 0, 0.081248,\n167, 0.779863, 0.683332, 0, 0.057638,\n168, 0.583333, 0.683332, 0, 0.13889,\n169, 0.666667, 0.683332, 0, 0,\n170, 0.612223, 0.683332, 0, 0.110001,\n171, 0.772398, 0.683332, 0, 0.050173,\n174, 0.639702, 0.430555, 0, 0.003702,\n175, 0.565626, 0.694445, 0.194445, 0.052778,\n176, 0.517731, 0.430555, 0.194445, 0.055555,\n177, 0.444445, 0.694445, 0, 0.037847,\n178, 0.405904, 0.430555, 0, 0,\n179, 0.437502, 0.694445, 0.194445, 0.073784,\n180, 0.4965315, 0.430555, 0.194445, 0.035879,\n181, 0.469444, 0.694445, 0, 0.027779,\n182, 0.353937, 0.430555, 0, 0,\n183, 0.5761595, 0.430555, 0, 0,\n184, 0.583336, 0.694445, 0, 0,\n185, 0.60255, 0.430555, 0.194445, 0,\n186, 0.493983, 0.430555, 0, 0.063658,\n187, 0.437502, 0.694445, 0.194445, 0.046007,\n188, 0.570027, 0.430555, 0, 0.035879,\n189, 0.517015, 0.430555, 0.194445, 0,\n190, 0.571414, 0.430555, 0, 0.035879,\n191, 0.437155, 0.430555, 0, 0.113195,\n192, 0.54028, 0.430555, 0, 0.035879,\n193, 0.595835, 0.694445, 0.194445, 0,\n194, 0.625692, 0.430555, 0.194445, 0,\n195, 0.651392, 0.694445, 0.194445, 0.035879,\n196, 0.277779, 0.694445, 0, 0.399462\nMETRICS_END\n\nLARGERS_START\n60, 173, 1,\n61, 177, 1,\n62, 174, 1\nLARGERS_END\n\nKERNS_START\n34, 196, 0.083336,\n35, 196, 0.083336,\n37, 196, 0.083336,\n38, 196, 0.083336,\n39, 196, 0.083336,\n61, 162, -0.055555,\n61, 65, -0.055555,\n61, 77, -0.055555,\n61, 78, -0.055555,\n61, 89, 0.055555,\n61, 90, -0.055555,\n64, 196, 0.083336,\n65, 196, 0.138893,\n66, 196, 0.083336,\n67, 61, -0.027779,\n67, 59, -0.055555,\n67, 58, -0.055555,\n67, 196, 0.083336,\n68, 196, 0.055557,\n69, 196, 0.083336,\n70, 61, -0.055555,\n70, 59, -0.111112,\n70, 58, -0.111112,\n70, 196, 0.083336,\n71, 196, 0.083336,\n72, 61, -0.055555,\n72, 59, -0.055555,\n72, 58, -0.055555,\n72, 196, 0.055557,\n73, 196, 0.1111145,\n74, 61, -0.055555,\n74, 59, -0.111112,\n74, 58, -0.111112,\n74, 196, 0.166672,\n75, 61, -0.055555,\n75, 59, -0.055555,\n75, 58, -0.055555,\n75, 196, 0.055557,\n76, 196, 0.027779,\n77, 61, -0.055555,\n77, 59, -0.055555,\n77, 58, -0.055555,\n77, 196, 0.083336,\n78, 61, -0.083334,\n78, 61, -0.027779,\n78, 59, -0.055555,\n78, 58, -0.055555,\n78, 196, 0.083336,\n79, 196, 0.083336,\n80, 61, -0.055555,\n80, 59, -0.111112,\n80, 58, -0.111112,\n80, 196, 0.083336,\n81, 196, 0.083336,\n82, 196, 0.083336,\n83, 61, -0.055555,\n83, 59, -0.055555,\n83, 58, -0.055555,\n83, 196, 0.083336,\n84, 61, -0.027779,\n84, 59, -0.055555,\n84, 58, -0.055555,\n84, 196, 0.083336,\n85, 59, -0.111112,\n85, 58, -0.111112,\n85, 61, -0.055555,\n85, 196, 0.027779,\n86, 59, -0.166667,\n86, 58, -0.166667,\n86, 61, -0.111112,\n87, 59, -0.166667,\n87, 58, -0.166667,\n87, 61, -0.111112,\n88, 61, -0.083334,\n88, 61, -0.027779,\n88, 59, -0.055555,\n88, 58, -0.055555,\n88, 196, 0.083336,\n89, 59, -0.166667,\n89, 58, -0.166667,\n89, 61, -0.111112,\n90, 61, -0.055555,\n90, 59, -0.055555,\n90, 58, -0.055555,\n90, 196, 0.083336,\n96, 196, 0.1111145,\n99, 196, 0.055557,\n100, 89, 0.055555,\n100, 90, -0.055555,\n100, 106, -0.111112,\n100, 102, -0.166667,\n100, 196, 0.166672,\n101, 196, 0.055557,\n102, 59, -0.055555,\n102, 58, -0.055555,\n102, 196, 0.166672,\n103, 196, 0.027779,\n104, 196, -0.027779,\n106, 59, -0.055555,\n106, 58, -0.055555,\n108, 196, 0.083336,\n111, 196, 0.055557,\n112, 196, 0.083336,\n113, 196, 0.083336,\n114, 59, -0.055555,\n114, 58, -0.055555,\n114, 196, 0.055557,\n115, 196, 0.055557,\n116, 196, 0.083336,\n117, 196, 0.027779,\n118, 196, 0.027779,\n119, 196, 0.083336,\n120, 196, 0.027779,\n121, 196, 0.055557,\n122, 196, 0.055557,\n123, 196, 0.027779,\n124, 196, 0.083336,\n125, 196, 0.1111145,\n161, 61, -0.055555,\n161, 59, -0.111112,\n161, 58, -0.111112,\n161, 196, 0.083336,\n162, 196, 0.166672,\n163, 196, 0.083336,\n164, 196, 0.166672,\n165, 196, 0.083336,\n166, 61, -0.055555,\n166, 59, -0.055555,\n166, 58, -0.055555,\n166, 196, 0.055557,\n167, 196, 0.083336,\n168, 61, -0.055555,\n168, 59, -0.111112,\n168, 58, -0.111112,\n168, 196, 0.055557,\n169, 196, 0.083336,\n170, 61, -0.055555,\n170, 59, -0.055555,\n170, 58, -0.055555,\n170, 196, 0.055557,\n171, 196, 0.083336,\n174, 196, 0.027779,\n175, 196, 0.083336,\n177, 59, -0.055555,\n177, 58, -0.055555,\n177, 196, 0.055557,\n178, 196, 0.055557,\n179, 196, 0.083336,\n180, 196, 0.055557,\n181, 196, 0.083336,\n182, 196, 0.055557,\n185, 196, 0.027779,\n186, 59, -0.055555,\n186, 58, -0.055555,\n186, 196, 0.027779,\n187, 196, 0.1111145,\n189, 196, 0.083336,\n190, 59, -0.055555,\n190, 58, -0.055555,\n191, 59, -0.055555,\n191, 58, -0.055555,\n191, 196, 0.027779,\n192, 196, 0.027779,\n193, 196, 0.083336,\n194, 196, 0.055557,\n195, 196, 0.1111145\nKERNS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/cmmi10_unchanged.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(cmmi10_unchanged, fonts/base/cmmi10.ttf, 0)\n\nxHeight(0.430555) quad(1.000003) skew(196)\n\nbold(cmmib10_unchanged)\n\nMETRICS_START\n33, 0.622455, 0.430555, 0, 0.035879,\n34, 0.466318, 0.430555, 0, 0,\n35, 0.59144, 0.694445, 0, 0,\n36, 0.82813, 0.430555, 0, 0.027779,\n37, 0.517015, 0.430555, 0.194445, 0,\n38, 0.362848, 0.430555, 0.097223, 0.07986,\n39, 0.654167, 0.430555, 0.194445, 0,\n40, 1.000003, 0.366875, -0.133125, 0,\n41, 1.000003, 0.366875, -0.133125, 0,\n42, 1.000003, 0.366875, -0.133125, 0,\n43, 1.000003, 0.366875, -0.133125, 0,\n44, 0.277779, 0.463748, -0.036252, 0,\n45, 0.277779, 0.463748, -0.036252, 0,\n46, 0.500002, 0.465279, -0.034721, 0,\n47, 0.500002, 0.465279, -0.034721, 0,\n58, 0.277779, 0.105556, 0, 0,\n59, 0.277779, 0.105556, 0.194445, 0,\n60, 0.777781, 0.539098, 0.039098, 0,\n61, 0.500002, 0.75, 0.25, 0,\n62, 0.777781, 0.539098, 0.039098, 0,\n63, 0.500002, 0.465279, -0.034721, 0,\n64, 0.530904, 0.694445, 0, 0.055555,\n91, 0.38889, 0.75, 0, 0,\n92, 0.38889, 0.694445, 0.194445, 0,\n93, 0.38889, 0.694445, 0.194445, 0,\n94, 1.000003, 0.35764, -0.14236, 0,\n95, 1.000003, 0.35764, -0.14236, 0,\n96, 0.41667, 0.694445, 0, 0,\n101, 0.465627, 0.430555, 0, 0,\n111, 0.484723, 0.430555, 0, 0,\n123, 0.322456, 0.430555, 0, 0,\n124, 0.38403, 0.430555, 0.194445, 0,\n125, 0.636459, 0.430555, 0.194445, 0,\n126, 0.500002, 0.714444, 0, 0.153819,\n174, 0.639702, 0.430555, 0, 0.003702,\n175, 0.565626, 0.694445, 0.194445, 0.052778,\n176, 0.517731, 0.430555, 0.194445, 0.055555,\n177, 0.444445, 0.694445, 0, 0.037847,\n178, 0.405904, 0.430555, 0, 0,\n179, 0.437502, 0.694445, 0.194445, 0.073784,\n180, 0.4965315, 0.430555, 0.194445, 0.035879,\n181, 0.469444, 0.694445, 0, 0.027779,\n182, 0.353937, 0.430555, 0, 0,\n183, 0.5761595, 0.430555, 0, 0,\n184, 0.583336, 0.694445, 0, 0,\n185, 0.60255, 0.430555, 0.194445, 0,\n186, 0.493983, 0.430555, 0, 0.063658,\n187, 0.437502, 0.694445, 0.194445, 0.046007,\n188, 0.570027, 0.430555, 0, 0.035879,\n189, 0.517015, 0.430555, 0.194445, 0,\n190, 0.571414, 0.430555, 0, 0.035879,\n191, 0.437155, 0.430555, 0, 0.113195,\n192, 0.54028, 0.430555, 0, 0.035879,\n193, 0.595835, 0.694445, 0.194445, 0,\n194, 0.625692, 0.430555, 0.194445, 0,\n195, 0.651392, 0.694445, 0.194445, 0.035879,\n196, 0.277779, 0.694445, 0, 0.399462\nMETRICS_END\n\nLARGERS_START\n60, 173, 1,\n61, 177, 1,\n62, 174, 1\nLARGERS_END\n\nKERNS_START\n34, 196, 0.083336,\n35, 196, 0.083336,\n37, 196, 0.083336,\n38, 196, 0.083336,\n39, 196, 0.083336,\n64, 196, 0.083336,\n96, 196, 0.1111145,\n101, 196, 0.055557,\n111, 196, 0.055557,\n123, 196, 0.027779,\n124, 196, 0.083336,\n125, 196, 0.1111145,\n174, 196, 0.027779,\n175, 196, 0.083336,\n177, 59, -0.055555,\n177, 58, -0.055555,\n177, 196, 0.055557,\n178, 196, 0.055557,\n179, 196, 0.083336,\n180, 196, 0.055557,\n181, 196, 0.083336,\n182, 196, 0.055557,\n185, 196, 0.027779,\n186, 59, -0.055555,\n186, 58, -0.055555,\n186, 196, 0.027779,\n187, 196, 0.1111145,\n189, 196, 0.083336,\n190, 59, -0.055555,\n190, 58, -0.055555,\n191, 59, -0.055555,\n191, 58, -0.055555,\n191, 196, 0.027779,\n192, 196, 0.027779,\n193, 196, 0.083336,\n194, 196, 0.055557,\n195, 196, 0.1111145\nKERNS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/cmmib10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(cmmib10, fonts/base/cmmib10.ttf, 0)\n\nxHeight(0.444445) quad(1.149994)\n\nroman(cmbx10) ss(cmssbx10) tt(cmtt10) it(cmbxti10)\n\nMETRICS_START\n33, 0.717819, 0.444445, 0, 0.037038,\n34, 0.528818, 0.444445, 0, 0,\n35, 0.691548, 0.694445, 0, 0,\n36, 0.974997, 0.444445, 0, 0.031944,\n37, 0.611804, 0.444445, 0.194445, 0,\n38, 0.423609, 0.444445, 0.097223, 0.079167,\n39, 0.747217, 0.444445, 0.194445, 0,\n40, 1.149994, 0.391111, -0.108889, 0,\n41, 1.149994, 0.391111, -0.108889, 0,\n42, 1.149994, 0.391111, -0.108889, 0,\n43, 1.149994, 0.391111, -0.108889, 0,\n44, 0.319443, 0.502223, 0.002223, 0,\n45, 0.319443, 0.502223, 0.002223, 0,\n46, 0.574997, 0.472223, -0.027777, 0,\n47, 0.574997, 0.472223, -0.027777, 0,\n48, 0.574997, 0.444445, 0, 0,\n49, 0.574997, 0.444445, 0, 0,\n50, 0.574997, 0.444445, 0, 0,\n51, 0.574997, 0.444445, 0.194445, 0,\n52, 0.574997, 0.444445, 0.194445, 0,\n53, 0.574997, 0.444445, 0.194445, 0,\n54, 0.574997, 0.644444, 0, 0,\n55, 0.574997, 0.444445, 0.194445, 0,\n56, 0.574997, 0.644444, 0, 0,\n57, 0.574997, 0.444445, 0.194445, 0,\n58, 0.319443, 0.155556, 0, 0,\n59, 0.319443, 0.155556, 0.194445, 0,\n60, 0.89444, 0.585556, 0.085556, 0,\n61, 0.574997, 0.75, 0.25, 0,\n62, 0.89444, 0.585556, 0.085556, 0,\n63, 0.574997, 0.472223, -0.027777, 0,\n64, 0.6284685, 0.694445, 0, 0.063889,\n65, 0.86944, 0.686111, 0, 0,\n66, 0.866404, 0.686111, 0, 0.04835,\n67, 0.81694, 0.686111, 0, 0.069792,\n68, 0.938121, 0.686111, 0, 0.031944,\n69, 0.810066, 0.686111, 0, 0.054514,\n70, 0.688886, 0.686111, 0, 0.159721,\n71, 0.886732, 0.686111, 0, 0,\n72, 0.982287, 0.686111, 0, 0.082293,\n73, 0.51111, 0.686111, 0, 0.077777,\n74, 0.631248, 0.686111, 0, 0.100695,\n75, 0.971176, 0.686111, 0, 0.069792,\n76, 0.755551, 0.686111, 0, 0,\n77, 1.142009, 0.686111, 0, 0.114237,\n78, 0.950343, 0.686111, 0, 0.114237,\n79, 0.836662, 0.686111, 0, 0.031944,\n80, 0.723088, 0.686111, 0, 0.159721,\n81, 0.868607, 0.686111, 0.194445, 0,\n82, 0.87235, 0.686111, 0, 0.0042095,\n83, 0.692706, 0.686111, 0, 0.05382,\n84, 0.636627, 0.686111, 0, 0.159721,\n85, 0.800275, 0.686111, 0, 0.114237,\n86, 0.677775, 0.686111, 0, 0.255554,\n87, 1.093051, 0.686111, 0, 0.159721,\n88, 0.947218, 0.686111, 0, 0.077777,\n89, 0.674579, 0.686111, 0, 0.255554,\n90, 0.772566, 0.686111, 0, 0.069792,\n91, 0.44722, 0.75, 0, 0,\n92, 0.44722, 0.694445, 0.194445, 0,\n93, 0.44722, 0.694445, 0.194445, 0,\n94, 1.149994, 0.361112, -0.138888, 0,\n95, 1.149994, 0.361112, -0.138888, 0,\n96, 0.473612, 0.694445, 0, 0,\n97, 0.632868, 0.444445, 0, 0,\n98, 0.52083, 0.694445, 0, 0,\n99, 0.513423, 0.444445, 0, 0,\n100, 0.60972, 0.694445, 0, 0,\n101, 0.553609, 0.444445, 0, 0,\n102, 0.568057, 0.694445, 0.194445, 0.110417,\n103, 0.544904, 0.444445, 0.194445, 0.037038,\n104, 0.66759, 0.694445, 0, 0,\n105, 0.404796, 0.693255, 0, 0,\n106, 0.470833, 0.693255, 0.194445, 0.062202,\n107, 0.603702, 0.694445, 0, 0.018518,\n108, 0.348147, 0.694445, 0, 0.008797,\n109, 1.032404, 0.444445, 0, 0,\n110, 0.712961, 0.444445, 0, 0,\n111, 0.584719, 0.444445, 0, 0,\n112, 0.600924, 0.444445, 0.194445, 0,\n113, 0.542127, 0.444445, 0.194445, 0.037038,\n114, 0.528704, 0.444445, 0, 0.031944,\n115, 0.53125, 0.444445, 0, 0,\n116, 0.415276, 0.634921, 0, 0,\n117, 0.681017, 0.444445, 0, 0,\n118, 0.566664, 0.444445, 0, 0.037038,\n119, 0.831479, 0.444445, 0, 0.027777,\n120, 0.659027, 0.444445, 0, 0,\n121, 0.590276, 0.444445, 0.194445, 0.037038,\n122, 0.555092, 0.444445, 0, 0.0421295,\n123, 0.393518, 0.444445, 0, 0,\n124, 0.438889, 0.444445, 0.194445, 0,\n125, 0.740274, 0.444445, 0.194445, 0,\n126, 0.574997, 0.724444, 0, 0.154861,\n161, 0.656941, 0.686111, 0, 0.159721,\n162, 0.958328, 0.686111, 0, 0,\n163, 0.867218, 0.686111, 0, 0.031944,\n164, 0.805552, 0.686111, 0, 0,\n165, 0.841246, 0.686111, 0, 0.074583,\n166, 0.982287, 0.686111, 0, 0.082293,\n167, 0.885066, 0.686111, 0, 0.054514,\n168, 0.67083, 0.686111, 0, 0.159721,\n169, 0.766663, 0.686111, 0, 0,\n170, 0.714022, 0.686111, 0, 0.116529,\n173, 0.878903, 0.686111, 0, 0.04835,\n174, 0.760645, 0.444445, 0, 0,\n175, 0.659719, 0.694445, 0.194445, 0.034029,\n176, 0.59003, 0.444445, 0.194445, 0.063889,\n177, 0.522219, 0.694445, 0, 0.038195,\n178, 0.483332, 0.444445, 0, 0,\n179, 0.508331, 0.694445, 0.194445, 0.062154,\n180, 0.599998, 0.444445, 0.194445, 0.037038,\n181, 0.561803, 0.694445, 0, 0.031944,\n182, 0.412036, 0.444445, 0, 0,\n183, 0.66759, 0.444445, 0, 0,\n184, 0.67083, 0.694445, 0, 0,\n185, 0.707869, 0.444445, 0.194445, 0,\n186, 0.576849, 0.444445, 0, 0.068982,\n187, 0.508331, 0.694445, 0.194445, 0.03021,\n188, 0.682405, 0.444445, 0, 0.037038,\n189, 0.611804, 0.444445, 0.194445, 0,\n190, 0.685877, 0.444445, 0, 0.037038,\n191, 0.520831, 0.444445, 0, 0.134723,\n192, 0.630552, 0.444445, 0, 0.037038,\n193, 0.712496, 0.694445, 0.194445, 0,\n194, 0.718054, 0.444445, 0.194445, 0,\n195, 0.758329, 0.694445, 0.194445, 0.037038,\n196, 0.319443, 0.694445, 0, 0.449999\nMETRICS_END\n\nLARGERS_START\n60, 173, 1,\n61, 177, 1,\n62, 174, 1\nLARGERS_END\n\nKERNS_START\n34, 196, 0.095833,\n35, 196, 0.095833,\n37, 196, 0.095833,\n38, 196, 0.095833,\n39, 196, 0.095833,\n61, 162, -0.063889,\n61, 65, -0.063889,\n61, 77, -0.063889,\n61, 78, -0.063889,\n61, 89, 0.063889,\n61, 90, -0.063889,\n64, 196, 0.095833,\n65, 196, 0.159721,\n66, 196, 0.095833,\n67, 61, -0.031944,\n67, 59, -0.063889,\n67, 58, -0.063889,\n67, 196, 0.095833,\n68, 196, 0.063889,\n69, 196, 0.095833,\n70, 61, -0.063889,\n70, 59, -0.127777,\n70, 58, -0.127777,\n70, 196, 0.095833,\n71, 196, 0.095833,\n72, 61, -0.063889,\n72, 59, -0.063889,\n72, 58, -0.063889,\n72, 196, 0.063889,\n73, 196, 0.127777,\n74, 61, -0.063889,\n74, 59, -0.127777,\n74, 58, -0.127777,\n74, 196, 0.191666,\n75, 61, -0.063889,\n75, 59, -0.063889,\n75, 58, -0.063889,\n75, 196, 0.063889,\n76, 196, 0.031944,\n77, 61, -0.063889,\n77, 59, -0.063889,\n77, 58, -0.063889,\n77, 196, 0.095833,\n78, 61, -0.095833,\n78, 61, -0.031944,\n78, 59, -0.063889,\n78, 58, -0.063889,\n78, 196, 0.095833,\n79, 196, 0.095833,\n80, 61, -0.063889,\n80, 59, -0.127777,\n80, 58, -0.127777,\n80, 196, 0.095833,\n81, 196, 0.095833,\n82, 196, 0.095833,\n83, 61, -0.063889,\n83, 59, -0.063889,\n83, 58, -0.063889,\n83, 196, 0.095833,\n84, 61, -0.031944,\n84, 59, -0.063889,\n84, 58, -0.063889,\n84, 196, 0.095833,\n85, 59, -0.127777,\n85, 58, -0.127777,\n85, 61, -0.063889,\n85, 196, 0.031944,\n86, 59, -0.191666,\n86, 58, -0.191666,\n86, 61, -0.127777,\n87, 59, -0.191666,\n87, 58, -0.191666,\n87, 61, -0.127777,\n88, 61, -0.095833,\n88, 61, -0.031944,\n88, 59, -0.063889,\n88, 58, -0.063889,\n88, 196, 0.095833,\n89, 59, -0.191666,\n89, 58, -0.191666,\n89, 61, -0.127777,\n90, 61, -0.063889,\n90, 59, -0.063889,\n90, 58, -0.063889,\n90, 196, 0.095833,\n96, 196, 0.127777,\n99, 196, 0.063889,\n100, 89, 0.063889,\n100, 90, -0.063889,\n100, 106, -0.127777,\n100, 102, -0.191666,\n100, 196, 0.191666,\n101, 196, 0.063889,\n102, 59, -0.063889,\n102, 58, -0.063889,\n102, 196, 0.191666,\n103, 196, 0.031944,\n104, 196, -0.031944,\n106, 59, -0.063889,\n106, 58, -0.063889,\n108, 196, 0.095833,\n111, 196, 0.063889,\n112, 196, 0.095833,\n113, 196, 0.095833,\n114, 59, -0.063889,\n114, 58, -0.063889,\n114, 196, 0.063889,\n115, 196, 0.063889,\n116, 196, 0.095833,\n117, 196, 0.031944,\n118, 196, 0.031944,\n119, 196, 0.095833,\n120, 196, 0.031944,\n121, 196, 0.063889,\n122, 196, 0.063889,\n123, 196, 0.031944,\n124, 196, 0.095833,\n125, 196, 0.127777,\n161, 61, -0.063889,\n161, 59, -0.127777,\n161, 58, -0.127777,\n161, 196, 0.095833,\n162, 196, 0.191666,\n163, 196, 0.095833,\n164, 196, 0.191666,\n165, 196, 0.095833,\n166, 61, -0.063889,\n166, 59, -0.063889,\n166, 58, -0.063889,\n166, 196, 0.063889,\n167, 196, 0.095833,\n168, 61, -0.063889,\n168, 59, -0.127777,\n168, 58, -0.127777,\n168, 196, 0.063889,\n169, 196, 0.095833,\n170, 61, -0.063889,\n170, 59, -0.063889,\n170, 58, -0.063889,\n170, 196, 0.063889,\n173, 196, 0.095833,\n174, 196, 0.031944,\n175, 196, 0.095833,\n177, 59, -0.063889,\n177, 58, -0.063889,\n177, 196, 0.063889,\n178, 196, 0.063889,\n179, 196, 0.095833,\n180, 196, 0.063889,\n181, 196, 0.095833,\n182, 196, 0.063889,\n185, 196, 0.031944,\n186, 59, -0.063889,\n186, 58, -0.063889,\n186, 196, 0.031944,\n187, 196, 0.127777,\n189, 196, 0.095833,\n190, 59, -0.063889,\n190, 58, -0.063889,\n191, 59, -0.063889,\n191, 58, -0.063889,\n191, 196, 0.031944,\n192, 196, 0.031944,\n193, 196, 0.095833,\n194, 196, 0.063889,\n195, 196, 0.127777\nKERNS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/cmmib10_unchanged.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(cmmib10_unchanged, fonts/base/cmmib10.ttf, 0)\n\nxHeight(0.444445) quad(1.149994)\n\nMETRICS_START\n33, 0.717819, 0.444445, 0, 0.037038,\n34, 0.528818, 0.444445, 0, 0,\n35, 0.691548, 0.694445, 0, 0,\n36, 0.974997, 0.444445, 0, 0.031944,\n37, 0.611804, 0.444445, 0.194445, 0,\n38, 0.423609, 0.444445, 0.097223, 0.079167,\n39, 0.747217, 0.444445, 0.194445, 0,\n40, 1.149994, 0.391111, -0.108889, 0,\n41, 1.149994, 0.391111, -0.108889, 0,\n42, 1.149994, 0.391111, -0.108889, 0,\n43, 1.149994, 0.391111, -0.108889, 0,\n44, 0.319443, 0.502223, 0.002223, 0,\n45, 0.319443, 0.502223, 0.002223, 0,\n46, 0.574997, 0.472223, -0.027777, 0,\n47, 0.574997, 0.472223, -0.027777, 0,\n48, 0.574997, 0.444445, 0, 0,\n49, 0.574997, 0.444445, 0, 0,\n50, 0.574997, 0.444445, 0, 0,\n51, 0.574997, 0.444445, 0.194445, 0,\n52, 0.574997, 0.444445, 0.194445, 0,\n53, 0.574997, 0.444445, 0.194445, 0,\n54, 0.574997, 0.644444, 0, 0,\n55, 0.574997, 0.444445, 0.194445, 0,\n56, 0.574997, 0.644444, 0, 0,\n57, 0.574997, 0.444445, 0.194445, 0,\n58, 0.319443, 0.155556, 0, 0,\n59, 0.319443, 0.155556, 0.194445, 0,\n60, 0.89444, 0.585556, 0.085556, 0,\n61, 0.574997, 0.75, 0.25, 0,\n62, 0.89444, 0.585556, 0.085556, 0,\n63, 0.574997, 0.472223, -0.027777, 0,\n64, 0.6284685, 0.694445, 0, 0.063889,\n91, 0.44722, 0.75, 0, 0,\n92, 0.44722, 0.694445, 0.194445, 0,\n93, 0.44722, 0.694445, 0.194445, 0,\n94, 1.149994, 0.361112, -0.138888, 0,\n95, 1.149994, 0.361112, -0.138888, 0,\n96, 0.473612, 0.694445, 0, 0,\n101, 0.553609, 0.444445, 0, 0,\n111, 0.584719, 0.444445, 0, 0,\n123, 0.393518, 0.444445, 0, 0,\n124, 0.438889, 0.444445, 0.194445, 0,\n125, 0.740274, 0.444445, 0.194445, 0,\n126, 0.574997, 0.724444, 0, 0.154861,\n174, 0.760645, 0.444445, 0, 0,\n175, 0.659719, 0.694445, 0.194445, 0.034029,\n176, 0.59003, 0.444445, 0.194445, 0.063889,\n177, 0.522219, 0.694445, 0, 0.038195,\n178, 0.483332, 0.444445, 0, 0,\n179, 0.508331, 0.694445, 0.194445, 0.062154,\n180, 0.599998, 0.444445, 0.194445, 0.037038,\n181, 0.561803, 0.694445, 0, 0.031944,\n182, 0.412036, 0.444445, 0, 0,\n183, 0.66759, 0.444445, 0, 0,\n184, 0.67083, 0.694445, 0, 0,\n185, 0.707869, 0.444445, 0.194445, 0,\n186, 0.576849, 0.444445, 0, 0.068982,\n187, 0.508331, 0.694445, 0.194445, 0.03021,\n188, 0.682405, 0.444445, 0, 0.037038,\n189, 0.611804, 0.444445, 0.194445, 0,\n190, 0.685877, 0.444445, 0, 0.037038,\n191, 0.520831, 0.444445, 0, 0.134723,\n192, 0.630552, 0.444445, 0, 0.037038,\n193, 0.712496, 0.694445, 0.194445, 0,\n194, 0.718054, 0.444445, 0.194445, 0,\n195, 0.758329, 0.694445, 0.194445, 0.037038,\n196, 0.319443, 0.694445, 0, 0.449999\nMETRICS_END\n\nLARGERS_START\n60, 173, 1,\n61, 177, 1,\n62, 174, 1\nLARGERS_END\n\nKERNS_START\n34, 196, 0.095833,\n35, 196, 0.095833,\n37, 196, 0.095833,\n38, 196, 0.095833,\n39, 196, 0.095833,\n64, 196, 0.095833,\n96, 196, 0.127777,\n101, 196, 0.063889,\n111, 196, 0.063889,\n123, 196, 0.031944,\n124, 196, 0.095833,\n125, 196, 0.127777,\n174, 196, 0.031944,\n175, 196, 0.095833,\n177, 59, -0.063889,\n177, 58, -0.063889,\n177, 196, 0.063889,\n178, 196, 0.063889,\n179, 196, 0.095833,\n180, 196, 0.063889,\n181, 196, 0.095833,\n182, 196, 0.063889,\n185, 196, 0.031944,\n186, 59, -0.063889,\n186, 58, -0.063889,\n186, 196, 0.031944,\n187, 196, 0.127777,\n189, 196, 0.095833,\n190, 59, -0.063889,\n190, 58, -0.063889,\n191, 59, -0.063889,\n191, 58, -0.063889,\n191, 196, 0.031944,\n192, 196, 0.031944,\n193, 196, 0.095833,\n194, 196, 0.063889,\n195, 196, 0.127777\nKERNS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/cmr10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(cmr10, fonts/latin/cmr10.ttf, 0)\n\nxHeight(0.430555) quad(1.000003) space(0.333334)\n\nbold(cmbx10) ss(cmss10) tt(cmtt10) it(cmti10)\n\nMETRICS_START\n33, 0.277779, 0.694445, 0, 0,\n34, 0.500002, 0.694445, 0, 0,\n35, 0.833336, 0.694445, 0.194443, 0,\n36, 0.500002, 0.75, 0.055555, 0,\n37, 0.833336, 0.75, 0.055555, 0,\n38, 0.777781, 0.694445, 0, 0,\n39, 0.277779, 0.694445, 0, 0,\n40, 0.38889, 0.75, 0.25, 0,\n41, 0.38889, 0.75, 0.25, 0,\n42, 0.500002, 0.75, 0, 0,\n43, 0.777781, 0.583334, 0.083334, 0,\n44, 0.277779, 0.105556, 0.194445, 0,\n45, 0.333334, 0.430555, 0, 0,\n46, 0.277779, 0.105556, 0, 0,\n47, 0.500002, 0.75, 0.25, 0,\n48, 0.500002, 0.644444, 0, 0,\n49, 0.500002, 0.644444, 0, 0,\n50, 0.500002, 0.644444, 0, 0,\n51, 0.500002, 0.644444, 0, 0,\n52, 0.500002, 0.644444, 0, 0,\n53, 0.500002, 0.644444, 0, 0,\n54, 0.500002, 0.644444, 0, 0,\n55, 0.500002, 0.644444, 0, 0,\n56, 0.500002, 0.644444, 0, 0,\n57, 0.500002, 0.644444, 0, 0,\n58, 0.277779, 0.430555, 0, 0,\n59, 0.277779, 0.430555, 0.194445, 0,\n60, 0.277779, 0.5, 0.194445, 0,\n61, 0.777781, 0.366875, -0.133125, 0,\n62, 0.472224, 0.5, 0.194445, 0,\n63, 0.472224, 0.694445, 0, 0,\n64, 0.777781, 0.694445, 0, 0,\n65, 0.750002, 0.683332, 0, 0,\n66, 0.708336, 0.683332, 0, 0,\n67, 0.722224, 0.683332, 0, 0,\n68, 0.763891, 0.683332, 0, 0,\n69, 0.680557, 0.683332, 0, 0,\n70, 0.652781, 0.683332, 0, 0,\n71, 0.784724, 0.683332, 0, 0,\n72, 0.750002, 0.683332, 0, 0,\n73, 0.361112, 0.683332, 0, 0,\n74, 0.51389, 0.683332, 0, 0,\n75, 0.777781, 0.683332, 0, 0,\n76, 0.625002, 0.683332, 0, 0,\n77, 0.916669, 0.683332, 0, 0,\n78, 0.750002, 0.683332, 0, 0,\n79, 0.777781, 0.683332, 0, 0,\n80, 0.680557, 0.683332, 0, 0,\n81, 0.777781, 0.683332, 0.194445, 0,\n82, 0.736113, 0.683332, 0, 0,\n83, 0.555557, 0.683332, 0, 0,\n84, 0.722224, 0.683332, 0, 0,\n85, 0.750002, 0.683332, 0, 0,\n86, 0.750002, 0.683332, 0, 0.013888,\n87, 1.027781, 0.683332, 0, 0.013888,\n88, 0.750002, 0.683332, 0, 0,\n89, 0.750002, 0.683332, 0, 0.025,\n90, 0.611113, 0.683332, 0, 0,\n91, 0.277779, 0.75, 0.25, 0,\n92, 0.500002, 0.694445, 0, 0,\n93, 0.277779, 0.75, 0.25, 0,\n94, 0.500002, 0.694445, 0, 0,\n95, 0.277779, 0.667859, 0, 0,\n96, 0.277779, 0.694445, 0, 0,\n97, 0.500002, 0.430555, 0, 0,\n98, 0.555557, 0.694445, 0, 0,\n99, 0.444446, 0.430555, 0, 0,\n100, 0.555557, 0.694445, 0, 0,\n101, 0.444446, 0.430555, 0, 0,\n102, 0.305557, 0.694445, 0, 0.077779,\n103, 0.500002, 0.430555, 0.194445, 0.013888,\n104, 0.555557, 0.694445, 0, 0,\n105, 0.277779, 0.667859, 0, 0,\n106, 0.305557, 0.667859, 0.194445, 0,\n107, 0.527781, 0.694445, 0, 0,\n108, 0.277779, 0.694445, 0, 0,\n109, 0.833336, 0.430555, 0, 0,\n110, 0.555557, 0.430555, 0, 0,\n111, 0.500002, 0.430555, 0, 0,\n112, 0.555557, 0.430555, 0.194445, 0,\n113, 0.527779, 0.430555, 0.194445, 0,\n114, 0.391668, 0.430555, 0, 0,\n115, 0.394445, 0.430555, 0, 0,\n116, 0.38889, 0.61508, 0, 0,\n117, 0.555557, 0.430555, 0, 0,\n118, 0.527781, 0.430555, 0, 0.013888,\n119, 0.722224, 0.430555, 0, 0.013888,\n120, 0.527781, 0.430555, 0, 0,\n121, 0.527781, 0.430555, 0.194445, 0.013888,\n122, 0.444446, 0.430555, 0, 0,\n123, 0.500002, 0.430555, 0, 0.027779,\n124, 1.000003, 0.430555, 0, 0.027779,\n125, 0.500002, 0.694445, 0, 0,\n126, 0.500002, 0.667859, 0, 0,\n161, 0.625002, 0.683332, 0, 0,\n162, 0.833336, 0.683332, 0, 0,\n163, 0.777781, 0.683332, 0, 0,\n164, 0.694446, 0.683332, 0, 0,\n165, 0.666669, 0.683332, 0, 0,\n166, 0.750002, 0.683332, 0, 0,\n167, 0.722224, 0.683332, 0, 0,\n168, 0.777781, 0.683332, 0, 0,\n169, 0.722224, 0.683332, 0, 0,\n170, 0.777781, 0.683332, 0, 0,\n171, 0.722224, 0.683332, 0, 0,\n174, 0.583336, 0.694445, 0, 0.077779,\n175, 0.555557, 0.694445, 0, 0,\n176, 0.555557, 0.694445, 0, 0,\n177, 0.833336, 0.694445, 0, 0,\n178, 0.833336, 0.694445, 0, 0,\n179, 0.277779, 0.430555, 0, 0,\n180, 0.305557, 0.430555, 0.194445, 0,\n181, 0.500002, 0.694445, 0, 0,\n182, 0.500002, 0.694445, 0, 0,\n183, 0.500002, 0.628473, 0, 0,\n184, 0.500002, 0.694445, 0, 0,\n185, 0.500002, 0.567777, 0, 0,\n186, 0.750002, 0.694445, 0, 0,\n187, 0.444446, 0, 0.170138, 0,\n188, 0.500003, 0.694445, 0, 0,\n189, 0.722224, 0.430555, 0, 0,\n190, 0.777781, 0.430555, 0, 0,\n191, 0.500002, 0.527779, 0.097223, 0,\n192, 0.902781, 0.683332, 0, 0,\n193, 1.013891, 0.683332, 0, 0,\n194, 0.777781, 0.731944, 0.048612, 0,\n195, 0.277779, 0.430555, 0, 0,\n196, 0.500002, 0.667859, 0, 0,\n197, 0.27771, 0.018, 0.197, 0\nMETRICS_END\n\nLARGERS_START\n40, 161, 1,\n41, 162, 1,\n47, 177, 1,\n91, 163, 1,\n93, 164, 1\nLARGERS_END\n\nLIGTURES_START\n33, 96, 60,\n39, 39, 34,\n45, 45, 123,\n63, 96, 62,\n96, 96, 92,\n102, 105, 175,\n102, 102, 174,\n102, 108, 176,\n123, 45, 124,\n174, 105, 177,\n174, 108, 178\nLIGTURES_END\n\nKERNS_START\n39, 63, 0.111112,\n39, 33, 0.111112,\n65, 116, -0.027779,\n65, 67, -0.027779,\n65, 79, -0.027779,\n65, 71, -0.027779,\n65, 85, -0.027779,\n65, 81, -0.027779,\n65, 84, -0.083334,\n65, 89, -0.083334,\n65, 86, -0.111112,\n65, 87, -0.111112,\n68, 88, -0.027779,\n68, 87, -0.027779,\n68, 65, -0.027779,\n68, 86, -0.027779,\n68, 89, -0.027779,\n70, 111, -0.083334,\n70, 101, -0.083334,\n70, 117, -0.083334,\n70, 114, -0.083334,\n70, 97, -0.083334,\n70, 65, -0.111112,\n70, 79, -0.027779,\n70, 67, -0.027779,\n70, 71, -0.027779,\n70, 81, -0.027779,\n73, 73, 0.027779,\n75, 79, -0.027779,\n75, 67, -0.027779,\n75, 71, -0.027779,\n75, 81, -0.027779,\n76, 84, -0.083334,\n76, 89, -0.083334,\n76, 86, -0.111112,\n76, 87, -0.111112,\n79, 88, -0.027779,\n79, 87, -0.027779,\n79, 65, -0.027779,\n79, 86, -0.027779,\n79, 89, -0.027779,\n80, 65, -0.083334,\n80, 111, -0.027779,\n80, 101, -0.027779,\n80, 97, -0.027779,\n80, 46, -0.083334,\n80, 44, -0.083334,\n82, 116, -0.027779,\n82, 67, -0.027779,\n82, 79, -0.027779,\n82, 71, -0.027779,\n82, 85, -0.027779,\n82, 81, -0.027779,\n82, 84, -0.083334,\n82, 89, -0.083334,\n82, 86, -0.111112,\n82, 87, -0.111112,\n84, 121, -0.027779,\n84, 101, -0.083334,\n84, 111, -0.083334,\n84, 114, -0.083334,\n84, 97, -0.083334,\n84, 65, -0.083334,\n84, 117, -0.083334,\n86, 111, -0.083334,\n86, 101, -0.083334,\n86, 117, -0.083334,\n86, 114, -0.083334,\n86, 97, -0.083334,\n86, 65, -0.111112,\n86, 79, -0.027779,\n86, 67, -0.027779,\n86, 71, -0.027779,\n86, 81, -0.027779,\n87, 111, -0.083334,\n87, 101, -0.083334,\n87, 117, -0.083334,\n87, 114, -0.083334,\n87, 97, -0.083334,\n87, 65, -0.111112,\n87, 79, -0.027779,\n87, 67, -0.027779,\n87, 71, -0.027779,\n87, 81, -0.027779,\n88, 79, -0.027779,\n88, 67, -0.027779,\n88, 71, -0.027779,\n88, 81, -0.027779,\n89, 101, -0.083334,\n89, 111, -0.083334,\n89, 114, -0.083334,\n89, 97, -0.083334,\n89, 65, -0.083334,\n89, 117, -0.083334,\n97, 118, -0.027779,\n97, 106, 0.055555,\n97, 121, -0.027779,\n97, 119, -0.027779,\n98, 101, 0.027779,\n98, 111, 0.027779,\n98, 120, -0.027779,\n98, 100, 0.027779,\n98, 99, 0.027779,\n98, 113, 0.027779,\n98, 118, -0.027779,\n98, 106, 0.055555,\n98, 121, -0.027779,\n98, 119, -0.027779,\n99, 104, -0.027779,\n99, 107, -0.027779,\n102, 39, 0.077779,\n102, 63, 0.077779,\n102, 33, 0.077779,\n102, 41, 0.077779,\n102, 93, 0.077779,\n103, 106, 0.027779,\n104, 116, -0.027779,\n104, 117, -0.027779,\n104, 98, -0.027779,\n104, 121, -0.027779,\n104, 118, -0.027779,\n104, 119, -0.027779,\n107, 97, -0.055555,\n107, 101, -0.027779,\n107, 97, -0.027779,\n107, 111, -0.027779,\n107, 99, -0.027779,\n109, 116, -0.027779,\n109, 117, -0.027779,\n109, 98, -0.027779,\n109, 121, -0.027779,\n109, 118, -0.027779,\n109, 119, -0.027779,\n110, 116, -0.027779,\n110, 117, -0.027779,\n110, 98, -0.027779,\n110, 121, -0.027779,\n110, 118, -0.027779,\n110, 119, -0.027779,\n111, 101, 0.027779,\n111, 111, 0.027779,\n111, 120, -0.027779,\n111, 100, 0.027779,\n111, 99, 0.027779,\n111, 113, 0.027779,\n111, 118, -0.027779,\n111, 106, 0.055555,\n111, 121, -0.027779,\n111, 119, -0.027779,\n112, 101, 0.027779,\n112, 111, 0.027779,\n112, 120, -0.027779,\n112, 100, 0.027779,\n112, 99, 0.027779,\n112, 113, 0.027779,\n112, 118, -0.027779,\n112, 106, 0.055555,\n112, 121, -0.027779,\n112, 119, -0.027779,\n116, 121, -0.027779,\n116, 119, -0.027779,\n117, 119, -0.027779,\n118, 97, -0.055555,\n118, 101, -0.027779,\n118, 97, -0.027779,\n118, 111, -0.027779,\n118, 99, -0.027779,\n119, 101, -0.027779,\n119, 97, -0.027779,\n119, 111, -0.027779,\n119, 99, -0.027779,\n121, 111, -0.027779,\n121, 101, -0.027779,\n121, 97, -0.027779,\n121, 46, -0.083334,\n121, 44, -0.083334,\n174, 39, 0.077779,\n174, 63, 0.077779,\n174, 33, 0.077779,\n174, 41, 0.077779,\n174, 93, 0.077779,\n195, 108, -0.277779,\n195, 76, -0.319446\nKERNS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/cmss10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(cmss10, fonts/latin/optional/cmss10.ttf, 0)\n\nxHeight(0.444445) quad(1.000003) space(0.333334)\n\nbold(cmssbx10) roman(cmr10) tt(cmtt10) it(cmssi10)\n\nMETRICS_START\n33, 0.319446, 0.694445, 0, 0,\n34, 0.500002, 0.694445, 0, 0,\n35, 0.833336, 0.694445, 0.194443, 0,\n36, 0.500002, 0.75, 0.055555, 0,\n37, 0.833336, 0.75, 0.055555, 0,\n38, 0.758336, 0.694445, 0, 0,\n39, 0.277779, 0.694445, 0, 0,\n40, 0.38889, 0.75, 0.25, 0,\n41, 0.38889, 0.75, 0.25, 0,\n42, 0.500002, 0.75, 0, 0,\n43, 0.777781, 0.583334, 0.083334, 0,\n44, 0.277779, 0.083333, 0.125, 0,\n45, 0.333334, 0.444445, 0, 0,\n46, 0.277779, 0.083333, 0, 0,\n47, 0.500002, 0.75, 0.25, 0,\n48, 0.500002, 0.655556, 0, 0,\n49, 0.500002, 0.655556, 0, 0,\n50, 0.500002, 0.655556, 0, 0,\n51, 0.500002, 0.655556, 0, 0,\n52, 0.500002, 0.655556, 0, 0,\n53, 0.500002, 0.655556, 0, 0,\n54, 0.500002, 0.655556, 0, 0,\n55, 0.500002, 0.655556, 0, 0,\n56, 0.500002, 0.655556, 0, 0,\n57, 0.500002, 0.655556, 0, 0,\n58, 0.277779, 0.444445, 0, 0,\n59, 0.277779, 0.444445, 0.125, 0,\n60, 0.319446, 0.5, 0.194445, 0,\n61, 0.777781, 0.37, -0.13, 0,\n62, 0.472224, 0.5, 0.194445, 0,\n63, 0.472224, 0.694445, 0, 0,\n64, 0.666669, 0.694445, 0, 0,\n65, 0.66667, 0.694445, 0, 0,\n66, 0.66667, 0.694445, 0, 0,\n67, 0.638891, 0.694445, 0, 0,\n68, 0.722226, 0.694445, 0, 0,\n69, 0.597224, 0.694445, 0, 0,\n70, 0.5694475, 0.694445, 0, 0,\n71, 0.666669, 0.694445, 0, 0,\n72, 0.708338, 0.694445, 0, 0,\n73, 0.277781, 0.694445, 0, 0,\n74, 0.472224, 0.694445, 0, 0,\n75, 0.694448, 0.694445, 0, 0,\n76, 0.541669, 0.694445, 0, 0,\n77, 0.875005, 0.694445, 0, 0,\n78, 0.708338, 0.694445, 0, 0,\n79, 0.736113, 0.694445, 0, 0,\n80, 0.638891, 0.694445, 0, 0,\n81, 0.736113, 0.694445, 0.125, 0,\n82, 0.645836, 0.694445, 0, 0,\n83, 0.555557, 0.694445, 0, 0,\n84, 0.680557, 0.694445, 0, 0,\n85, 0.687505, 0.694445, 0, 0,\n86, 0.66667, 0.694445, 0, 0.013888,\n87, 0.944448, 0.694445, 0, 0.013888,\n88, 0.66667, 0.694445, 0, 0,\n89, 0.66667, 0.694445, 0, 0.025,\n90, 0.611113, 0.694445, 0, 0,\n91, 0.28889, 0.75, 0.25, 0,\n92, 0.500002, 0.694445, 0, 0,\n93, 0.28889, 0.75, 0.25, 0,\n94, 0.500002, 0.694445, 0, 0,\n95, 0.277779, 0.679365, 0, 0,\n96, 0.277779, 0.694445, 0, 0,\n97, 0.480557, 0.444445, 0, 0,\n98, 0.516668, 0.694445, 0, 0,\n99, 0.444446, 0.444445, 0, 0,\n100, 0.516668, 0.694445, 0, 0,\n101, 0.444446, 0.444445, 0, 0,\n102, 0.305557, 0.694445, 0, 0.069445,\n103, 0.500002, 0.444445, 0.194445, 0.013888,\n104, 0.516668, 0.694445, 0, 0,\n105, 0.23889, 0.679365, 0, 0,\n106, 0.266668, 0.679365, 0.194445, 0,\n107, 0.488892, 0.694445, 0, 0,\n108, 0.23889, 0.694445, 0, 0,\n109, 0.794447, 0.444445, 0, 0,\n110, 0.516668, 0.444445, 0, 0,\n111, 0.500002, 0.444445, 0, 0,\n112, 0.516668, 0.444445, 0.194445, 0,\n113, 0.516668, 0.444445, 0.194445, 0,\n114, 0.341669, 0.444445, 0, 0.013888,\n115, 0.383334, 0.444445, 0, 0,\n116, 0.361112, 0.571431, 0, 0,\n117, 0.516668, 0.444445, 0, 0,\n118, 0.461113, 0.444445, 0, 0.013888,\n119, 0.683336, 0.444445, 0, 0.013888,\n120, 0.461113, 0.444445, 0, 0,\n121, 0.461113, 0.444445, 0.194445, 0.013888,\n122, 0.434723, 0.444445, 0, 0,\n123, 0.500002, 0.444445, 0, 0.027779,\n124, 1.000003, 0.444445, 0, 0.027779,\n125, 0.500002, 0.694445, 0, 0,\n126, 0.500002, 0.676588, 0, 0,\n161, 0.541669, 0.694445, 0, 0,\n162, 0.833336, 0.694445, 0, 0,\n163, 0.777781, 0.694445, 0, 0,\n164, 0.6111145, 0.694445, 0, 0,\n165, 0.666669, 0.694445, 0, 0,\n166, 0.708338, 0.694445, 0, 0,\n167, 0.722224, 0.694445, 0, 0,\n168, 0.777781, 0.694445, 0, 0,\n169, 0.722224, 0.694445, 0, 0,\n170, 0.777781, 0.694445, 0, 0,\n173, 0.722224, 0.694445, 0, 0,\n174, 0.583336, 0.694445, 0, 0.069445,\n175, 0.536113, 0.694445, 0, 0,\n176, 0.536113, 0.694445, 0, 0,\n177, 0.813891, 0.694445, 0, 0,\n178, 0.813891, 0.694445, 0, 0,\n179, 0.23889, 0.444445, 0, 0,\n180, 0.266668, 0.444445, 0.194445, 0,\n181, 0.500002, 0.694445, 0, 0,\n182, 0.500002, 0.694445, 0, 0,\n183, 0.500002, 0.631945, 0, 0,\n184, 0.500002, 0.694445, 0, 0,\n185, 0.500002, 0.608887, 0, 0,\n186, 0.66667, 0.694445, 0, 0,\n187, 0.444446, 0, 0.170138, 0,\n188, 0.480558, 0.694445, 0, 0,\n189, 0.722224, 0.444445, 0, 0,\n190, 0.777781, 0.444445, 0, 0,\n191, 0.500002, 0.541667, 0.097223, 0,\n192, 0.8611145, 0.694445, 0, 0,\n193, 0.972226, 0.694445, 0, 0,\n194, 0.777781, 0.743055, 0.048612, 0,\n195, 0.23889, 0.444445, 0, 0,\n196, 0.500002, 0.679365, 0, 0,\n197, 0.27771, 0.048, 0.212, 0\nMETRICS_END\n\nLARGERS_START\n40, 161, 1,\n41, 162, 1,\n47, 177, 1,\n91, 163, 1,\n93, 164, 1\nLARGERS_END\n\nLIGTURES_START\n33, 96, 60,\n39, 39, 34,\n45, 45, 123,\n63, 96, 62,\n96, 96, 92,\n102, 105, 175,\n102, 102, 174,\n102, 108, 176,\n123, 45, 124,\n174, 105, 177,\n174, 108, 178\nLIGTURES_END\n\nKERNS_START\n39, 63, 0.111112,\n39, 33, 0.111112,\n65, 116, -0.027779,\n65, 67, -0.027779,\n65, 79, -0.027779,\n65, 71, -0.027779,\n65, 85, -0.027779,\n65, 81, -0.027779,\n65, 84, -0.083334,\n65, 89, -0.083334,\n65, 86, -0.111112,\n65, 87, -0.111112,\n68, 88, -0.027779,\n68, 87, -0.027779,\n68, 65, -0.027779,\n68, 86, -0.027779,\n68, 89, -0.027779,\n70, 111, -0.027779,\n70, 101, -0.027779,\n70, 117, -0.027779,\n70, 114, -0.027779,\n70, 97, -0.027779,\n70, 65, -0.083334,\n70, 79, -0.027779,\n70, 67, -0.027779,\n70, 71, -0.027779,\n70, 81, -0.027779,\n73, 73, 0.027779,\n75, 79, -0.027779,\n75, 67, -0.027779,\n75, 71, -0.027779,\n75, 81, -0.027779,\n76, 84, -0.083334,\n76, 89, -0.083334,\n76, 86, -0.111112,\n76, 87, -0.111112,\n79, 88, -0.027779,\n79, 87, -0.027779,\n79, 65, -0.027779,\n79, 86, -0.027779,\n79, 89, -0.027779,\n80, 65, -0.083334,\n80, 111, -0.027779,\n80, 101, -0.027779,\n80, 97, -0.027779,\n80, 46, -0.083334,\n80, 44, -0.083334,\n84, 121, -0.083334,\n84, 101, -0.083334,\n84, 111, -0.083334,\n84, 114, -0.083334,\n84, 97, -0.083334,\n84, 65, -0.083334,\n84, 117, -0.083334,\n86, 111, -0.027779,\n86, 101, -0.027779,\n86, 117, -0.027779,\n86, 114, -0.027779,\n86, 97, -0.027779,\n86, 65, -0.083334,\n86, 79, -0.027779,\n86, 67, -0.027779,\n86, 71, -0.027779,\n86, 81, -0.027779,\n87, 111, -0.027779,\n87, 101, -0.027779,\n87, 117, -0.027779,\n87, 114, -0.027779,\n87, 97, -0.027779,\n87, 65, -0.083334,\n87, 79, -0.027779,\n87, 67, -0.027779,\n87, 71, -0.027779,\n87, 81, -0.027779,\n88, 79, -0.027779,\n88, 67, -0.027779,\n88, 71, -0.027779,\n88, 81, -0.027779,\n89, 101, -0.083334,\n89, 111, -0.083334,\n89, 114, -0.083334,\n89, 97, -0.083334,\n89, 65, -0.083334,\n89, 117, -0.083334,\n97, 114, -0.027779,\n97, 121, -0.027779,\n97, 119, -0.027779,\n98, 101, 0.027779,\n98, 111, 0.027779,\n98, 120, -0.027779,\n98, 100, 0.027779,\n98, 99, 0.027779,\n98, 113, 0.027779,\n98, 114, -0.027779,\n98, 121, -0.027779,\n98, 119, -0.027779,\n102, 39, 0.069445,\n102, 63, 0.069445,\n102, 33, 0.069445,\n102, 41, 0.069445,\n102, 93, 0.069445,\n103, 106, 0.027779,\n107, 101, -0.027779,\n107, 97, -0.027779,\n107, 111, -0.027779,\n107, 99, -0.027779,\n111, 101, 0.027779,\n111, 111, 0.027779,\n111, 120, -0.027779,\n111, 100, 0.027779,\n111, 99, 0.027779,\n111, 113, 0.027779,\n111, 114, -0.027779,\n111, 121, -0.027779,\n111, 119, -0.027779,\n112, 101, 0.027779,\n112, 111, 0.027779,\n112, 120, -0.027779,\n112, 100, 0.027779,\n112, 99, 0.027779,\n112, 113, 0.027779,\n112, 114, -0.027779,\n112, 121, -0.027779,\n112, 119, -0.027779,\n116, 121, -0.027779,\n116, 119, -0.027779,\n117, 119, -0.027779,\n119, 101, -0.027779,\n119, 97, -0.027779,\n119, 111, -0.027779,\n119, 99, -0.027779,\n121, 111, -0.027779,\n121, 101, -0.027779,\n121, 97, -0.027779,\n121, 46, -0.083334,\n121, 44, -0.083334,\n174, 39, 0.069445,\n174, 63, 0.069445,\n174, 33, 0.069445,\n174, 41, 0.069445,\n174, 93, 0.069445,\n195, 108, -0.23889,\n195, 76, -0.258336\nKERNS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/cmssbx10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(cmssbx10, fonts/latin/optional/cmssbx10.ttf, 0)\n\nxHeight(0.458333) quad(1.100006) space(0.366669)\n\nroman(cmbx10) tt(cmtt10) it(cmbxti10)\n\nMETRICS_START\n33, 0.366669, 0.694445, 0, 0,\n34, 0.558336, 0.694445, 0, 0,\n35, 0.916672, 0.694445, 0.194443, 0,\n36, 0.550003, 0.75, 0.055555, 0,\n37, 1.029119, 0.75, 0.055555, 0,\n38, 0.830561, 0.694445, 0, 0,\n39, 0.305557, 0.694445, 0, 0,\n40, 0.42778, 0.75, 0.25, 0,\n41, 0.42778, 0.75, 0.25, 0,\n42, 0.550003, 0.75, 0, 0,\n43, 0.85556, 0.616669, 0.116669, 0,\n44, 0.305557, 0.130556, 0.105556, 0,\n45, 0.366669, 0.458333, 0, 0,\n46, 0.305557, 0.130556, 0, 0,\n47, 0.550003, 0.75, 0.25, 0,\n48, 0.550003, 0.694445, 0, 0,\n49, 0.550003, 0.694445, 0, 0,\n50, 0.550003, 0.694445, 0, 0,\n51, 0.550003, 0.694445, 0, 0,\n52, 0.550003, 0.694445, 0, 0,\n53, 0.550003, 0.694445, 0, 0,\n54, 0.550003, 0.694445, 0, 0,\n55, 0.550003, 0.694445, 0, 0,\n56, 0.550003, 0.694445, 0, 0,\n57, 0.550003, 0.694445, 0, 0,\n58, 0.305557, 0.458333, 0, 0,\n59, 0.305557, 0.458333, 0.105556, 0,\n60, 0.366669, 0.5, 0.194445, 0,\n61, 0.85556, 0.40625, -0.09375, 0,\n62, 0.519447, 0.5, 0.194445, 0,\n63, 0.519447, 0.694445, 0, 0,\n64, 0.733337, 0.694445, 0, 0,\n65, 0.733337, 0.694445, 0, 0,\n66, 0.733337, 0.694445, 0, 0,\n67, 0.702782, 0.694445, 0, 0,\n68, 0.794449, 0.694445, 0, 0,\n69, 0.64167, 0.694445, 0, 0,\n70, 0.6111145, 0.694445, 0, 0,\n71, 0.733337, 0.694445, 0, 0,\n72, 0.794449, 0.694445, 0, 0,\n73, 0.330557, 0.694445, 0, 0,\n74, 0.519447, 0.694445, 0, 0,\n75, 0.763893, 0.694445, 0, 0,\n76, 0.580559, 0.694445, 0, 0,\n77, 0.977783, 0.694445, 0, 0,\n78, 0.794449, 0.694445, 0, 0,\n79, 0.794449, 0.694445, 0, 0,\n80, 0.702782, 0.694445, 0, 0,\n81, 0.794449, 0.694445, 0.105556, 0,\n82, 0.702782, 0.694445, 0, 0,\n83, 0.6111145, 0.694445, 0, 0,\n84, 0.733337, 0.694445, 0, 0,\n85, 0.763893, 0.694445, 0, 0,\n86, 0.733337, 0.694445, 0, 0.015279,\n87, 1.038895, 0.694445, 0, 0.015279,\n88, 0.733337, 0.694445, 0, 0,\n89, 0.733337, 0.694445, 0, 0.027499,\n90, 0.672226, 0.694445, 0, 0,\n91, 0.343058, 0.75, 0.25, 0,\n92, 0.558336, 0.694445, 0, 0,\n93, 0.343058, 0.75, 0.25, 0,\n94, 0.550003, 0.694445, 0, 0,\n95, 0.305557, 0.694445, 0, 0,\n96, 0.305557, 0.694445, 0, 0,\n97, 0.525003, 0.458333, 0, 0,\n98, 0.561114, 0.694445, 0, 0,\n99, 0.488892, 0.458333, 0, 0,\n100, 0.561114, 0.694445, 0, 0,\n101, 0.511114, 0.458333, 0, 0,\n102, 0.336113, 0.694445, 0, 0.07639,\n103, 0.550003, 0.458333, 0.194445, 0.015279,\n104, 0.561114, 0.694445, 0, 0,\n105, 0.255557, 0.694445, 0, 0,\n106, 0.286113, 0.694445, 0.194445, 0,\n107, 0.530559, 0.694445, 0, 0,\n108, 0.255557, 0.694445, 0, 0,\n109, 0.866672, 0.458333, 0, 0,\n110, 0.561114, 0.458333, 0, 0,\n111, 0.550003, 0.458333, 0, 0,\n112, 0.561114, 0.458333, 0.194445, 0,\n113, 0.561114, 0.458333, 0.194445, 0,\n114, 0.372225, 0.458333, 0, 0.015279,\n115, 0.421669, 0.458333, 0, 0,\n116, 0.404169, 0.589289, 0, 0,\n117, 0.561114, 0.458333, 0, 0,\n118, 0.500003, 0.458333, 0, 0.015279,\n119, 0.744449, 0.458333, 0, 0.015279,\n120, 0.500003, 0.458333, 0, 0,\n121, 0.500003, 0.458333, 0.194445, 0.015279,\n122, 0.476392, 0.458333, 0, 0,\n123, 0.550003, 0.458333, 0, 0.030556,\n124, 1.100006, 0.458333, 0, 0.030556,\n125, 0.550003, 0.694445, 0, 0,\n126, 0.550003, 0.694445, 0, 0,\n161, 0.580559, 0.694445, 0, 0,\n162, 0.916672, 0.694445, 0, 0,\n163, 0.85556, 0.694445, 0, 0,\n164, 0.672226, 0.694445, 0, 0,\n165, 0.733337, 0.694445, 0, 0,\n166, 0.794449, 0.694445, 0, 0,\n167, 0.794449, 0.694445, 0, 0,\n168, 0.85556, 0.694445, 0, 0,\n169, 0.794449, 0.694445, 0, 0,\n170, 0.85556, 0.694445, 0, 0,\n173, 0.794449, 0.694445, 0, 0,\n174, 0.64167, 0.694445, 0, 0.07639,\n175, 0.586115, 0.694445, 0, 0,\n176, 0.586115, 0.694445, 0, 0,\n177, 0.891672, 0.694445, 0, 0,\n178, 0.891672, 0.694445, 0, 0,\n179, 0.255557, 0.458333, 0, 0,\n180, 0.286113, 0.458333, 0.194445, 0,\n181, 0.550003, 0.694445, 0, 0,\n182, 0.550003, 0.694445, 0, 0,\n183, 0.550003, 0.635417, 0, 0,\n184, 0.550003, 0.694445, 0, 0,\n185, 0.550003, 0.637776, 0, 0,\n186, 0.733337, 0.694445, 0, 0,\n187, 0.488892, 0, 0.170138, 0,\n188, 0.56528, 0.694445, 0, 0,\n189, 0.794449, 0.458333, 0, 0,\n190, 0.85556, 0.458333, 0, 0,\n191, 0.550003, 0.555555, 0.097223, 0,\n192, 0.9472275, 0.694445, 0, 0,\n193, 1.06945, 0.694445, 0, 0,\n194, 0.85556, 0.743055, 0.048612, 0,\n195, 0.255557, 0.458333, 0, 0,\n196, 0.550003, 0.694445, 0, 0,\n197, 0.305481, 0.073, 0.194, 0\nMETRICS_END\n\nLARGERS_START\n40, 161, 1,\n41, 162, 1,\n47, 177, 1,\n91, 163, 1,\n93, 164, 1\nLARGERS_END\n\nLIGTURES_START\n33, 96, 60,\n39, 39, 34,\n45, 45, 123,\n63, 196, 62,\n96, 96, 92,\n102, 105, 175,\n102, 102, 174,\n102, 108, 176,\n123, 45, 124,\n174, 105, 177,\n174, 108, 178\nLIGTURES_END\n\nKERNS_START\n39, 63, 0.122223,\n39, 33, 0.122223,\n65, 116, -0.030556,\n65, 67, -0.030556,\n65, 79, -0.030556,\n65, 71, -0.030556,\n65, 85, -0.030556,\n65, 81, -0.030556,\n65, 84, -0.091667,\n65, 89, -0.091667,\n65, 86, -0.122223,\n65, 87, -0.122223,\n68, 88, -0.030556,\n68, 87, -0.030556,\n68, 65, -0.030556,\n68, 86, -0.030556,\n68, 89, -0.030556,\n70, 111, -0.030556,\n70, 101, -0.030556,\n70, 117, -0.030556,\n70, 114, -0.030556,\n70, 97, -0.030556,\n70, 65, -0.091667,\n70, 79, -0.030556,\n70, 67, -0.030556,\n70, 71, -0.030556,\n70, 81, -0.030556,\n73, 73, 0.030556,\n75, 79, -0.030556,\n75, 67, -0.030556,\n75, 71, -0.030556,\n75, 81, -0.030556,\n76, 84, -0.091667,\n76, 89, -0.091667,\n76, 86, -0.122223,\n76, 87, -0.122223,\n79, 88, -0.030556,\n79, 87, -0.030556,\n79, 65, -0.030556,\n79, 86, -0.030556,\n79, 89, -0.030556,\n80, 65, -0.091667,\n80, 111, -0.030556,\n80, 101, -0.030556,\n80, 97, -0.030556,\n80, 46, -0.091667,\n80, 44, -0.091667,\n84, 121, -0.091667,\n84, 101, -0.091667,\n84, 111, -0.091667,\n84, 114, -0.091667,\n84, 97, -0.091667,\n84, 65, -0.091667,\n84, 117, -0.091667,\n86, 111, -0.030556,\n86, 101, -0.030556,\n86, 117, -0.030556,\n86, 114, -0.030556,\n86, 97, -0.030556,\n86, 65, -0.091667,\n86, 79, -0.030556,\n86, 67, -0.030556,\n86, 71, -0.030556,\n86, 81, -0.030556,\n87, 111, -0.030556,\n87, 101, -0.030556,\n87, 117, -0.030556,\n87, 114, -0.030556,\n87, 97, -0.030556,\n87, 65, -0.091667,\n87, 79, -0.030556,\n87, 67, -0.030556,\n87, 71, -0.030556,\n87, 81, -0.030556,\n88, 79, -0.030556,\n88, 67, -0.030556,\n88, 71, -0.030556,\n88, 81, -0.030556,\n89, 101, -0.091667,\n89, 111, -0.091667,\n89, 114, -0.091667,\n89, 97, -0.091667,\n89, 65, -0.091667,\n89, 117, -0.091667,\n97, 114, -0.030556,\n97, 121, -0.030556,\n97, 119, -0.030556,\n98, 101, 0.030556,\n98, 111, 0.030556,\n98, 120, -0.030556,\n98, 100, 0.030556,\n98, 99, 0.030556,\n98, 113, 0.030556,\n98, 114, -0.030556,\n98, 121, -0.030556,\n98, 119, -0.030556,\n102, 39, 0.07639,\n102, 63, 0.07639,\n102, 33, 0.07639,\n102, 41, 0.07639,\n102, 93, 0.07639,\n103, 106, 0.030556,\n107, 101, -0.030556,\n107, 97, -0.030556,\n107, 111, -0.030556,\n107, 99, -0.030556,\n111, 101, 0.030556,\n111, 111, 0.030556,\n111, 120, -0.030556,\n111, 100, 0.030556,\n111, 99, 0.030556,\n111, 113, 0.030556,\n111, 114, -0.030556,\n111, 121, -0.030556,\n111, 119, -0.030556,\n112, 101, 0.030556,\n112, 111, 0.030556,\n112, 120, -0.030556,\n112, 100, 0.030556,\n112, 99, 0.030556,\n112, 113, 0.030556,\n112, 114, -0.030556,\n112, 121, -0.030556,\n112, 119, -0.030556,\n116, 121, -0.030556,\n116, 119, -0.030556,\n117, 119, -0.030556,\n119, 101, -0.030556,\n119, 97, -0.030556,\n119, 111, -0.030556,\n119, 99, -0.030556,\n121, 111, -0.030556,\n121, 101, -0.030556,\n121, 97, -0.030556,\n121, 46, -0.091667,\n121, 44, -0.091667,\n174, 39, 0.07639,\n174, 63, 0.07639,\n174, 33, 0.07639,\n174, 41, 0.07639,\n174, 93, 0.07639,\n195, 108, -0.255557,\n195, 76, -0.293057\nKERNS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/cmssi10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(cmssi10, fonts/latin/optional/cmssi10.ttf, 0)\n\nxHeight(0.444445) quad(1.000003) space(0.333334)\n\nbold(cmssbx10) roman(cmti10) tt(cmtt10)\n\nMETRICS_START\n33, 0.319446, 0.694445, 0, 0.057329,\n34, 0.500002, 0.694445, 0, 0.003161,\n35, 0.833336, 0.694445, 0.194443, 0.050867,\n36, 0.500002, 0.75, 0.055555, 0.111563,\n37, 0.833336, 0.75, 0.055555, 0.031263,\n38, 0.758336, 0.694445, 0, 0.030579,\n39, 0.277779, 0.694445, 0, 0.078163,\n40, 0.38889, 0.75, 0.25, 0.131638,\n41, 0.38889, 0.75, 0.25, 0.02536,\n42, 0.500002, 0.75, 0, 0.117749,\n43, 0.777781, 0.583334, 0.083334, 0.02536,\n44, 0.277779, 0.083333, 0.125, 0,\n45, 0.333334, 0.444445, 0, 0.019457,\n46, 0.277779, 0.083333, 0, 0,\n47, 0.500002, 0.75, 0.25, 0.131638,\n48, 0.500002, 0.655556, 0, 0.111563,\n49, 0.500002, 0.655556, 0, 0.111563,\n50, 0.500002, 0.655556, 0, 0.111563,\n51, 0.500002, 0.655556, 0, 0.111563,\n52, 0.500002, 0.655556, 0, 0.111563,\n53, 0.500002, 0.655556, 0, 0.111563,\n54, 0.500002, 0.655556, 0, 0.111563,\n55, 0.500002, 0.655556, 0, 0.111563,\n56, 0.500002, 0.655556, 0, 0.111563,\n57, 0.500002, 0.655556, 0, 0.111563,\n58, 0.277779, 0.444445, 0, 0.025024,\n59, 0.277779, 0.444445, 0.125, 0.025024,\n60, 0.319446, 0.5, 0.194445, 0.015999,\n61, 0.777781, 0.37, -0.13, 0.050867,\n62, 0.472224, 0.5, 0.194445, 0,\n63, 0.472224, 0.694445, 0, 0.118086,\n64, 0.666669, 0.694445, 0, 0.075546,\n65, 0.66667, 0.694445, 0, 0,\n66, 0.66667, 0.694445, 0, 0.082927,\n67, 0.638891, 0.694445, 0, 0.119829,\n68, 0.722226, 0.694445, 0, 0.075546,\n69, 0.597224, 0.694445, 0, 0.119829,\n70, 0.5694475, 0.694445, 0, 0.1337185,\n71, 0.666669, 0.694445, 0, 0.119829,\n72, 0.708338, 0.694445, 0, 0.080938,\n73, 0.277781, 0.694445, 0, 0.1337185,\n74, 0.472224, 0.694445, 0, 0.080938,\n75, 0.694448, 0.694445, 0, 0.119829,\n76, 0.541669, 0.694445, 0, 0,\n77, 0.875005, 0.694445, 0, 0.080938,\n78, 0.708338, 0.694445, 0, 0.080938,\n79, 0.736113, 0.694445, 0, 0.075546,\n80, 0.638891, 0.694445, 0, 0.082927,\n81, 0.736113, 0.694445, 0.125, 0.075546,\n82, 0.645836, 0.694445, 0, 0.082927,\n83, 0.555557, 0.694445, 0, 0.0920515,\n84, 0.680557, 0.694445, 0, 0.1337185,\n85, 0.687505, 0.694445, 0, 0.080938,\n86, 0.66667, 0.694445, 0, 0.161496,\n87, 0.944448, 0.694445, 0, 0.161496,\n88, 0.66667, 0.694445, 0, 0.1337185,\n89, 0.66667, 0.694445, 0, 0.172607,\n90, 0.611113, 0.694445, 0, 0.119829,\n91, 0.28889, 0.75, 0.25, 0.159416,\n92, 0.500002, 0.694445, 0, 0.142052,\n93, 0.28889, 0.75, 0.25, 0.0871935,\n94, 0.500002, 0.694445, 0, 0.079895,\n95, 0.277779, 0.679365, 0, 0.077736,\n96, 0.277779, 0.694445, 0, 0.078163,\n97, 0.480557, 0.444445, 0, 0.009807,\n98, 0.516668, 0.694445, 0, 0.030568,\n99, 0.444446, 0.444445, 0, 0.083357,\n100, 0.516668, 0.694445, 0, 0.094829,\n101, 0.444446, 0.444445, 0, 0.067778,\n102, 0.305557, 0.694445, 0, 0.2170515,\n103, 0.500002, 0.444445, 0.194445, 0.108357,\n104, 0.516668, 0.694445, 0, 0.017778,\n105, 0.23889, 0.679365, 0, 0.09718,\n106, 0.266668, 0.679365, 0.194445, 0.091624,\n107, 0.488892, 0.694445, 0, 0.083357,\n108, 0.23889, 0.694445, 0, 0.094829,\n109, 0.794447, 0.444445, 0, 0.017778,\n110, 0.516668, 0.444445, 0, 0.017778,\n111, 0.500002, 0.444445, 0, 0.066129,\n112, 0.516668, 0.444445, 0.194445, 0.0389,\n113, 0.516668, 0.444445, 0.194445, 0.04169,\n114, 0.341669, 0.444445, 0, 0.108357,\n115, 0.383334, 0.444445, 0, 0.077802,\n116, 0.361112, 0.571431, 0, 0.0722475,\n117, 0.516668, 0.444445, 0, 0.04169,\n118, 0.461113, 0.444445, 0, 0.108357,\n119, 0.683336, 0.444445, 0, 0.108357,\n120, 0.461113, 0.444445, 0, 0.09169,\n121, 0.461113, 0.444445, 0.194445, 0.108357,\n122, 0.434723, 0.444445, 0, 0.087524,\n123, 0.500002, 0.444445, 0, 0.0861635,\n124, 1.000003, 0.444445, 0, 0.0861635,\n125, 0.500002, 0.694445, 0, 0.0920515,\n126, 0.500002, 0.676588, 0, 0.088257,\n161, 0.541669, 0.694445, 0, 0.1337185,\n162, 0.833336, 0.694445, 0, 0,\n163, 0.777781, 0.694445, 0, 0.075546,\n164, 0.6111145, 0.694445, 0, 0,\n165, 0.666669, 0.694445, 0, 0.128163,\n166, 0.708338, 0.694445, 0, 0.080938,\n167, 0.722224, 0.694445, 0, 0.119829,\n168, 0.777781, 0.694445, 0, 0.090307,\n169, 0.722224, 0.694445, 0, 0.046025,\n170, 0.777781, 0.694445, 0, 0.090307,\n173, 0.722224, 0.694445, 0, 0.082927,\n174, 0.583336, 0.694445, 0, 0.2170515,\n175, 0.536113, 0.694445, 0, 0.097608,\n176, 0.536113, 0.694445, 0, 0.094829,\n177, 0.813891, 0.694445, 0, 0.097608,\n178, 0.813891, 0.694445, 0, 0.094829,\n179, 0.23889, 0.444445, 0, 0.04169,\n180, 0.266668, 0.444445, 0.194445, 0.04169,\n181, 0.500002, 0.694445, 0, 0,\n182, 0.500002, 0.694445, 0, 0.0920515,\n183, 0.500002, 0.631945, 0, 0.084323,\n184, 0.500002, 0.694445, 0, 0.094829,\n185, 0.500002, 0.608887, 0, 0.087755,\n186, 0.737521, 0.694445, 0, 0,\n187, 0.444446, 0, 0.170138, 0,\n188, 0.480558, 0.694445, 0, 0.0920515,\n189, 0.722224, 0.444445, 0, 0.067778,\n190, 0.777781, 0.444445, 0, 0.067778,\n191, 0.500002, 0.541667, 0.097223, 0.048467,\n192, 0.8611145, 0.694445, 0, 0.119829,\n193, 0.972226, 0.694445, 0, 0.119829,\n194, 0.777781, 0.743055, 0.048612, 0.075546,\n195, 0.23889, 0.444445, 0, 0,\n196, 0.500002, 0.679365, 0, 0.063848,\n197, 0.27771, 0.048, 0.212, 0\nMETRICS_END\n\nLARGERS_START\n40, 161, 1,\n41, 162, 1,\n47, 177, 1,\n91, 163, 1,\n93, 164, 1\nLARGERS_END\n\nLIGTURES_START\n33, 96, 60,\n39, 39, 34,\n45, 45, 123,\n63, 96, 62,\n96, 96, 92,\n102, 105, 175,\n102, 102, 174,\n102, 108, 176,\n123, 45, 124,\n174, 105, 177,\n174, 108, 178\nLIGTURES_END\n\nKERNS_START\n39, 63, 0.111112,\n39, 33, 0.111112,\n65, 116, -0.027779,\n65, 67, -0.027779,\n65, 79, -0.027779,\n65, 71, -0.027779,\n65, 85, -0.027779,\n65, 81, -0.027779,\n65, 84, -0.083334,\n65, 89, -0.083334,\n65, 86, -0.111112,\n65, 87, -0.111112,\n68, 88, -0.027779,\n68, 87, -0.027779,\n68, 65, -0.027779,\n68, 86, -0.027779,\n68, 89, -0.027779,\n70, 111, -0.027779,\n70, 101, -0.027779,\n70, 117, -0.027779,\n70, 114, -0.027779,\n70, 97, -0.027779,\n70, 65, -0.083334,\n70, 79, -0.027779,\n70, 67, -0.027779,\n70, 71, -0.027779,\n70, 81, -0.027779,\n73, 73, 0.027779,\n75, 79, -0.027779,\n75, 67, -0.027779,\n75, 71, -0.027779,\n75, 81, -0.027779,\n76, 84, -0.083334,\n76, 89, -0.083334,\n76, 86, -0.111112,\n76, 87, -0.111112,\n79, 88, -0.027779,\n79, 87, -0.027779,\n79, 65, -0.027779,\n79, 86, -0.027779,\n79, 89, -0.027779,\n80, 65, -0.083334,\n80, 111, -0.027779,\n80, 101, -0.027779,\n80, 97, -0.027779,\n80, 46, -0.083334,\n80, 44, -0.083334,\n84, 121, -0.083334,\n84, 101, -0.083334,\n84, 111, -0.083334,\n84, 114, -0.083334,\n84, 97, -0.083334,\n84, 65, -0.083334,\n84, 117, -0.083334,\n86, 111, -0.027779,\n86, 101, -0.027779,\n86, 117, -0.027779,\n86, 114, -0.027779,\n86, 97, -0.027779,\n86, 65, -0.083334,\n86, 79, -0.027779,\n86, 67, -0.027779,\n86, 71, -0.027779,\n86, 81, -0.027779,\n87, 111, -0.027779,\n87, 101, -0.027779,\n87, 117, -0.027779,\n87, 114, -0.027779,\n87, 97, -0.027779,\n87, 65, -0.083334,\n87, 79, -0.027779,\n87, 67, -0.027779,\n87, 71, -0.027779,\n87, 81, -0.027779,\n88, 79, -0.027779,\n88, 67, -0.027779,\n88, 71, -0.027779,\n88, 81, -0.027779,\n89, 101, -0.083334,\n89, 111, -0.083334,\n89, 114, -0.083334,\n89, 97, -0.083334,\n89, 65, -0.083334,\n89, 117, -0.083334,\n97, 114, -0.027779,\n97, 121, -0.027779,\n97, 119, -0.027779,\n98, 101, 0.027779,\n98, 111, 0.027779,\n98, 120, -0.027779,\n98, 100, 0.027779,\n98, 99, 0.027779,\n98, 113, 0.027779,\n98, 114, -0.027779,\n98, 121, -0.027779,\n98, 119, -0.027779,\n102, 39, 0.069445,\n102, 63, 0.069445,\n102, 33, 0.069445,\n102, 41, 0.069445,\n102, 93, 0.069445,\n103, 106, 0.027779,\n107, 101, -0.027779,\n107, 97, -0.027779,\n107, 111, -0.027779,\n107, 99, -0.027779,\n111, 101, 0.027779,\n111, 111, 0.027779,\n111, 120, -0.027779,\n111, 100, 0.027779,\n111, 99, 0.027779,\n111, 113, 0.027779,\n111, 114, -0.027779,\n111, 121, -0.027779,\n111, 119, -0.027779,\n112, 101, 0.027779,\n112, 111, 0.027779,\n112, 120, -0.027779,\n112, 100, 0.027779,\n112, 99, 0.027779,\n112, 113, 0.027779,\n112, 114, -0.027779,\n112, 121, -0.027779,\n112, 119, -0.027779,\n116, 121, -0.027779,\n116, 119, -0.027779,\n117, 119, -0.027779,\n119, 101, -0.027779,\n119, 97, -0.027779,\n119, 111, -0.027779,\n119, 99, -0.027779,\n121, 111, -0.027779,\n121, 101, -0.027779,\n121, 97, -0.027779,\n121, 46, -0.083334,\n121, 44, -0.083334,\n174, 39, 0.069445,\n174, 63, 0.069445,\n174, 33, 0.069445,\n174, 41, 0.069445,\n174, 93, 0.069445,\n195, 108, -0.23889,\n195, 76, -0.258336\nKERNS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/cmsy10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(cmsy10, fonts/maths/cmsy10.ttf, 0)\n\nxHeight(0.430555) quad(1.000003) skew(48)\n\nbold(cmbsy10)\n\nMETRICS_START\n33, 1.000003, 0.366875, -0.133125, 0,\n34, 0.500002, 0.694445, 0.194443, 0,\n35, 0.500002, 0.694445, 0.194443, 0,\n36, 1.000003, 0.366875, -0.133125, 0,\n37, 1.000003, 0.694445, 0.194443, 0,\n38, 1.000003, 0.694445, 0.194443, 0,\n39, 0.777781, 0.463748, -0.036252, 0,\n40, 1.000003, 0.366875, -0.133125, 0,\n41, 1.000003, 0.366875, -0.133125, 0,\n42, 0.611113, 0.694445, 0.194443, 0,\n43, 0.611113, 0.694445, 0.194443, 0,\n44, 1.000003, 0.366875, -0.133125, 0,\n45, 1.000003, 0.694445, 0.194443, 0,\n46, 1.000003, 0.694445, 0.194443, 0,\n47, 0.777781, 0.430555, 0, 0,\n48, 0.275, 0.555557, 0, 0,\n49, 1.000003, 0.430555, 0, 0,\n50, 0.666669, 0.539098, 0.039098, 0,\n51, 0.666669, 0.539098, 0.039098, 0,\n52, 0.888891, 0.694445, 0.194445, 0,\n53, 0.888891, 0.694445, 0.194445, 0,\n54, 0.0, 0.694445, 0.194443, 0,\n55, 0.0, 0.366875, -0.133125, 0,\n56, 0.555557, 0.694445, 0, 0,\n57, 0.555557, 0.694445, 0, 0,\n58, 0.666669, 0.430555, 0, 0,\n59, 0.500002, 0.75, 0.055555, 0,\n60, 0.722224, 0.694445, 0, 0,\n61, 0.722224, 0.694445, 0, 0,\n62, 0.777781, 0.694445, 0, 0,\n63, 0.777781, 0.694445, 0, 0,\n64, 0.611113, 0.694445, 0, 0,\n65, 0.798471, 0.683332, 0, 0,\n66, 0.65681, 0.683332, 0, 0.030413,\n67, 0.526529, 0.683332, 0, 0.058336,\n68, 0.771393, 0.683332, 0, 0.027779,\n69, 0.5277815, 0.683332, 0, 0.089441,\n70, 0.718748, 0.683332, 0, 0.099306,\n71, 0.594866, 0.683332, 0.097223, 0.059303,\n72, 0.844518, 0.683332, 0, 0.009654,\n73, 0.544516, 0.683332, 0, 0.073822,\n74, 0.67778, 0.683332, 0.097223, 0.184721,\n75, 0.7619505, 0.683332, 0, 0.014445,\n76, 0.689725, 0.683332, 0, 0,\n77, 1.2009, 0.683332, 0, 0,\n78, 0.820491, 0.683332, 0, 0.14736,\n79, 0.796114, 0.683332, 0, 0.027779,\n80, 0.6955595, 0.683332, 0, 0.082222,\n81, 0.81667, 0.683332, 0.097223, 0,\n82, 0.847504, 0.683332, 0, 0,\n83, 0.605558, 0.683332, 0, 0.074995,\n84, 0.544644, 0.683332, 0, 0.254168,\n85, 0.625832, 0.683332, 0, 0.099306,\n86, 0.6127825, 0.683332, 0, 0.082222,\n87, 0.987783, 0.683332, 0, 0.082222,\n88, 0.713297, 0.683332, 0, 0.146428,\n89, 0.668337, 0.683332, 0.097223, 0.082222,\n90, 0.724726, 0.683332, 0, 0.079443,\n91, 0.666669, 0.555557, 0, 0,\n92, 0.666669, 0.555557, 0, 0,\n93, 0.666669, 0.555557, 0, 0,\n94, 0.666669, 0.555557, 0, 0,\n95, 0.666669, 0.555557, 0, 0,\n96, 0.611113, 0.694445, 0, 0,\n97, 0.611113, 0.694445, 0, 0,\n98, 0.444446, 0.75, 0.25, 0,\n99, 0.444446, 0.75, 0.25, 0,\n100, 0.444446, 0.75, 0.25, 0,\n101, 0.444446, 0.75, 0.25, 0,\n102, 0.500002, 0.75, 0.25, 0,\n103, 0.500002, 0.75, 0.25, 0,\n104, 0.38889, 0.75, 0.25, 0,\n105, 0.38889, 0.75, 0.25, 0,\n106, 0.277779, 0.75, 0.25, 0,\n107, 0.500002, 0.75, 0.25, 0,\n108, 0.500002, 0.75, 0.25, 0,\n109, 0.611113, 0.75, 0.25, 0,\n110, 0.500002, 0.75, 0.25, 0,\n111, 0.277779, 0.694445, 0.194443, 0,\n112, 0.833336, 0.039999, 0.960001, 0,\n113, 0.750002, 0.683332, 0, 0,\n114, 0.833336, 0.683332, 0, 0,\n115, 0.416669, 0.694445, 0.194445, 0.111112,\n116, 0.666669, 0.555557, 0, 0,\n117, 0.666669, 0.555557, 0, 0,\n118, 0.777781, 0.635971, 0.135971, 0,\n119, 0.777781, 0.635971, 0.135971, 0,\n120, 0.4444475, 0.694445, 0.194445, 0,\n121, 0.444446, 0.694445, 0.194445, 0,\n122, 0.444446, 0.694445, 0.194445, 0,\n123, 0.611113, 0.694445, 0.194445, 0,\n124, 0.777781, 0.694445, 0.129629, 0,\n125, 0.777781, 0.694445, 0.129629, 0,\n126, 0.777781, 0.694445, 0.129629, 0,\n161, 0.777781, 0.583334, 0.083334, 0,\n162, 0.277779, 0.444446, -0.055554, 0,\n163, 0.777781, 0.583334, 0.083334, 0,\n164, 0.500002, 0.465279, -0.034721, 0,\n165, 0.777781, 0.583334, 0.083334, 0,\n166, 0.500002, 0.444446, -0.055554, 0,\n167, 0.777781, 0.583334, 0.083334, 0,\n168, 0.777781, 0.583334, 0.083334, 0,\n169, 0.777781, 0.583334, 0.083334, 0,\n170, 0.777781, 0.583334, 0.083334, 0,\n171, 0.777781, 0.583334, 0.083334, 0,\n174, 0.777781, 0.583334, 0.083334, 0,\n175, 0.777781, 0.583334, 0.083334, 0,\n176, 1.000003, 0.694445, 0.194445, 0,\n177, 0.500002, 0.444446, -0.055554, 0,\n178, 0.500002, 0.444446, -0.055554, 0,\n179, 0.777781, 0.463748, -0.036252, 0,\n180, 0.777781, 0.463748, -0.036252, 0,\n181, 0.777781, 0.635971, 0.135971, 0,\n182, 0.777781, 0.635971, 0.135971, 0,\n183, 0.777781, 0.635971, 0.135971, 0,\n184, 0.777781, 0.635971, 0.135971, 0,\n185, 0.777781, 0.635971, 0.135971, 0,\n186, 0.777781, 0.635971, 0.135971, 0,\n187, 0.777781, 0.366875, -0.133125, 0,\n188, 0.777781, 0.483122, -0.016878, 0,\n189, 0.777781, 0.539098, 0.039098, 0,\n190, 0.777781, 0.539098, 0.039098, 0,\n191, 1.000003, 0.539098, 0.039098, 0,\n192, 1.000003, 0.539098, 0.039098, 0,\n193, 0.777781, 0.539098, 0.039098, 0,\n194, 0.777781, 0.539098, 0.039098, 0,\n195, 1.000003, 0.366875, -0.133125, 0,\n196, 0.777781, 0.694445, 0.129629, 0,\n197, 0.700002, 0.75, 0.05, 0,\n198, 0.700002, 0.75, 0.05, 0,\n199, 0.8, 0.75, 0.05, 0\nMETRICS_END\n\nLARGERS_START\n34, 120, 1,\n35, 121, 1,\n42, 126, 1,\n43, 196, 1,\n52, 129, 7,\n53, 128, 7,\n98, 165, 1,\n99, 166, 1,\n100, 167, 1,\n101, 168, 1,\n102, 169, 1,\n103, 170, 1,\n104, 173, 1,\n105, 174, 1,\n106, 175, 1,\n107, 176, 1,\n108, 63, 1,\n109, 119, 1,\n110, 178, 1,\n112, 112, 1\nLARGERS_END\n\nKERNS_START\n65, 48, 0.19445,\n66, 48, 0.138893,\n67, 48, 0.138893,\n68, 48, 0.083336,\n69, 48, 0.1111145,\n70, 48, 0.1111145,\n71, 48, 0.1111145,\n72, 48, 0.1111145,\n73, 48, 0.027779,\n74, 48, 0.166672,\n75, 48, 0.055557,\n76, 48, 0.138893,\n77, 48, 0.138893,\n78, 48, 0.083336,\n79, 48, 0.1111145,\n80, 48, 0.083336,\n81, 48, 0.1111145,\n82, 48, 0.083336,\n83, 48, 0.138893,\n84, 48, 0.027779,\n85, 48, 0.083336,\n86, 48, 0.027779,\n87, 48, 0.083336,\n88, 48, 0.138893,\n89, 48, 0.083336,\n90, 48, 0.138893\nKERNS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/cmti10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(cmti10, fonts/latin/optional/cmti10.ttf, 0)\n\nxHeight(0.430555) quad(1.022217) space(0.357776)\n\nbold(cmbxti10) roman(cmr10) ss(cmssi10) tt(cmtt10)\n\nMETRICS_START\n33, 0.306665, 0.694445, 0, 0.124168,\n34, 0.514442, 0.694445, 0, 0.0696125,\n35, 0.817774, 0.694445, 0.194443, 0.066164,\n36, 0.7690935, 0.694445, 0, 0,\n37, 0.817774, 0.75, 0.055555, 0.136389,\n38, 0.766663, 0.694445, 0, 0.096945,\n39, 0.306665, 0.694445, 0, 0.124168,\n40, 0.408887, 0.75, 0.25, 0.161944,\n41, 0.408887, 0.75, 0.25, 0.036944,\n42, 0.511108, 0.75, 0, 0.149167,\n43, 0.766663, 0.561666, 0.056665, 0.036944,\n44, 0.306665, 0.105556, 0.194445, 0,\n45, 0.357776, 0.430555, 0, 0.028264,\n46, 0.306665, 0.105556, 0, 0,\n47, 0.511108, 0.75, 0.25, 0.161944,\n48, 0.511108, 0.644444, 0, 0.135556,\n49, 0.511108, 0.644444, 0, 0.135556,\n50, 0.511108, 0.644444, 0, 0.135556,\n51, 0.511108, 0.644444, 0, 0.135556,\n52, 0.511108, 0.644444, 0.194445, 0.135556,\n53, 0.511108, 0.644444, 0, 0.135556,\n54, 0.511108, 0.644444, 0, 0.135556,\n55, 0.511108, 0.644444, 0.194445, 0.135556,\n56, 0.511108, 0.644444, 0, 0.135556,\n57, 0.511108, 0.644444, 0, 0.135556,\n58, 0.306665, 0.430555, 0, 0.058195,\n59, 0.306665, 0.430555, 0.194445, 0.058195,\n60, 0.306665, 0.5, 0.194445, 0.075557,\n61, 0.766663, 0.366875, -0.133125, 0.066164,\n62, 0.511108, 0.5, 0.194445, 0,\n63, 0.511108, 0.694445, 0, 0.1225,\n64, 0.766663, 0.694445, 0, 0.095972,\n65, 0.743329, 0.683332, 0, 0,\n66, 0.703885, 0.683332, 0, 0.10257,\n67, 0.715551, 0.683332, 0, 0.145277,\n68, 0.754995, 0.683332, 0, 0.0940275,\n69, 0.678329, 0.683332, 0, 0.120277,\n70, 0.652774, 0.683332, 0, 0.133055,\n71, 0.773607, 0.683332, 0, 0.087222,\n72, 0.743329, 0.683332, 0, 0.16389,\n73, 0.385553, 0.683332, 0, 0.158055,\n74, 0.524997, 0.683332, 0, 0.140279,\n75, 0.768885, 0.683332, 0, 0.145277,\n76, 0.627218, 0.683332, 0, 0,\n77, 0.896662, 0.683332, 0, 0.16389,\n78, 0.743329, 0.683332, 0, 0.16389,\n79, 0.766663, 0.683332, 0, 0.0940275,\n80, 0.678329, 0.683332, 0, 0.10257,\n81, 0.766663, 0.683332, 0.194445, 0.0940275,\n82, 0.729441, 0.683332, 0, 0.038681,\n83, 0.56222, 0.683332, 0, 0.119722,\n84, 0.715551, 0.683332, 0, 0.133055,\n85, 0.743329, 0.683332, 0, 0.16389,\n86, 0.743329, 0.683332, 0, 0.183611,\n87, 0.998883, 0.683332, 0, 0.183611,\n88, 0.743329, 0.683332, 0, 0.158055,\n89, 0.743329, 0.683332, 0, 0.193832,\n90, 0.61333, 0.683332, 0, 0.145277,\n91, 0.306665, 0.75, 0.25, 0.1875,\n92, 0.514442, 0.694445, 0, 0.1685,\n93, 0.306665, 0.75, 0.25, 0.105278,\n94, 0.511108, 0.694445, 0, 0.06646,\n95, 0.306665, 0.667859, 0, 0.117521,\n96, 0.306665, 0.694445, 0, 0.124168,\n97, 0.511108, 0.430555, 0, 0.076714,\n98, 0.459997, 0.694445, 0, 0.063124,\n99, 0.459997, 0.430555, 0, 0.056528,\n100, 0.511108, 0.694445, 0, 0.103334,\n101, 0.459997, 0.430555, 0, 0.075139,\n102, 0.306665, 0.694445, 0.194445, 0.211945,\n103, 0.459997, 0.430555, 0.194445, 0.088472,\n104, 0.511108, 0.694445, 0, 0.076714,\n105, 0.306665, 0.655359, 0, 0.101896,\n106, 0.306665, 0.655359, 0.194445, 0.144673,\n107, 0.459997, 0.694445, 0, 0.107638,\n108, 0.255554, 0.694445, 0, 0.103334,\n109, 0.817774, 0.430555, 0, 0.076714,\n110, 0.56222, 0.430555, 0, 0.076714,\n111, 0.511108, 0.430555, 0, 0.063124,\n112, 0.511108, 0.430555, 0.194445, 0.063124,\n113, 0.459997, 0.430555, 0.194445, 0.088472,\n114, 0.421664, 0.430555, 0, 0.107638,\n115, 0.408887, 0.430555, 0, 0.082083,\n116, 0.33222, 0.61508, 0, 0.094861,\n117, 0.536664, 0.430555, 0, 0.076714,\n118, 0.459997, 0.430555, 0, 0.107638,\n119, 0.664441, 0.430555, 0, 0.107638,\n120, 0.463887, 0.430555, 0, 0.120417,\n121, 0.485553, 0.430555, 0.194445, 0.088472,\n122, 0.408887, 0.430555, 0, 0.122917,\n123, 0.511108, 0.430555, 0, 0.092079,\n124, 1.022217, 0.430555, 0, 0.092079,\n125, 0.511108, 0.694445, 0, 0.1225,\n126, 0.511108, 0.667859, 0, 0.115854,\n161, 0.627218, 0.683332, 0, 0.133055,\n162, 0.817774, 0.683332, 0, 0,\n163, 0.766663, 0.683332, 0, 0.0940275,\n164, 0.692218, 0.683332, 0, 0,\n165, 0.664441, 0.683332, 0, 0.152944,\n166, 0.743329, 0.683332, 0, 0.16389,\n167, 0.715551, 0.683332, 0, 0.120277,\n168, 0.766663, 0.683332, 0, 0.111112,\n169, 0.715551, 0.683332, 0, 0.059862,\n170, 0.766663, 0.683332, 0, 0.111112,\n173, 0.715551, 0.683332, 0, 0.10257,\n174, 0.61333, 0.694445, 0.194445, 0.211945,\n175, 0.56222, 0.694445, 0.194445, 0.103334,\n176, 0.587774, 0.694445, 0.194445, 0.103334,\n177, 0.881662, 0.694445, 0.194445, 0.103334,\n178, 0.89444, 0.694445, 0.194445, 0.103334,\n179, 0.306665, 0.430555, 0, 0.076714,\n180, 0.33222, 0.430555, 0.194445, 0.037361,\n181, 0.511108, 0.694445, 0, 0,\n182, 0.511108, 0.694445, 0, 0.096945,\n183, 0.511108, 0.628473, 0, 0.0829525,\n184, 0.511108, 0.694445, 0, 0.108057,\n185, 0.511108, 0.561666, 0, 0.103334,\n186, 0.831291, 0.694445, 0, 0,\n187, 0.459997, 0, 0.170138, 0,\n188, 0.536664, 0.694445, 0.194445, 0.105138,\n189, 0.715551, 0.430555, 0, 0.075139,\n190, 0.715551, 0.430555, 0, 0.075139,\n191, 0.511108, 0.527779, 0.097223, 0.091945,\n192, 0.882772, 0.683332, 0, 0.120277,\n193, 0.984995, 0.683332, 0, 0.120277,\n194, 0.766663, 0.731944, 0.048612, 0.0940275,\n195, 0.255554, 0.430555, 0, 0,\n196, 0.511108, 0.667859, 0, 0.104744,\n197, 0.306592, 0.022, 0.178, 0.178\nMETRICS_END\n\nLARGERS_START\n40, 161, 1,\n41, 162, 1,\n47, 177, 1,\n91, 163, 1,\n93, 164, 1\nLARGERS_END\n\nLIGTURES_START\n33, 96, 60,\n39, 39, 34,\n45, 45, 123,\n63, 96, 62,\n96, 96, 92,\n102, 105, 175,\n102, 102, 174,\n102, 108, 176,\n123, 45, 124,\n174, 105, 177,\n174, 108, 178\nLIGTURES_END\n\nKERNS_START\n39, 63, 0.1022215,\n39, 33, 0.1022215,\n65, 110, -0.025556,\n65, 108, -0.025556,\n65, 114, -0.025556,\n65, 117, -0.025556,\n65, 109, -0.025556,\n65, 116, -0.025556,\n65, 105, -0.025556,\n65, 67, -0.025556,\n65, 79, -0.025556,\n65, 71, -0.025556,\n65, 104, -0.025556,\n65, 98, -0.025556,\n65, 85, -0.025556,\n65, 107, -0.025556,\n65, 118, -0.025556,\n65, 119, -0.025556,\n65, 81, -0.025556,\n65, 84, -0.076666,\n65, 89, -0.076666,\n65, 86, -0.1022215,\n65, 87, -0.1022215,\n65, 101, -0.051111,\n65, 97, -0.051111,\n65, 111, -0.051111,\n65, 100, -0.051111,\n65, 99, -0.051111,\n65, 103, -0.051111,\n65, 113, -0.051111,\n68, 88, -0.025556,\n68, 87, -0.025556,\n68, 65, -0.025556,\n68, 86, -0.025556,\n68, 89, -0.025556,\n70, 111, -0.076666,\n70, 101, -0.076666,\n70, 117, -0.076666,\n70, 114, -0.076666,\n70, 97, -0.076666,\n70, 65, -0.1022215,\n70, 79, -0.025556,\n70, 67, -0.025556,\n70, 71, -0.025556,\n70, 81, -0.025556,\n75, 79, -0.025556,\n75, 67, -0.025556,\n75, 71, -0.025556,\n75, 81, -0.025556,\n76, 84, -0.076666,\n76, 89, -0.076666,\n76, 86, -0.1022215,\n76, 87, -0.1022215,\n76, 101, -0.051111,\n76, 97, -0.051111,\n76, 111, -0.051111,\n76, 100, -0.051111,\n76, 99, -0.051111,\n76, 103, -0.051111,\n76, 113, -0.051111,\n79, 88, -0.025556,\n79, 87, -0.025556,\n79, 65, -0.025556,\n79, 86, -0.025556,\n79, 89, -0.025556,\n80, 65, -0.076666,\n82, 110, -0.025556,\n82, 108, -0.025556,\n82, 114, -0.025556,\n82, 117, -0.025556,\n82, 109, -0.025556,\n82, 116, -0.025556,\n82, 105, -0.025556,\n82, 67, -0.025556,\n82, 79, -0.025556,\n82, 71, -0.025556,\n82, 104, -0.025556,\n82, 98, -0.025556,\n82, 85, -0.025556,\n82, 107, -0.025556,\n82, 118, -0.025556,\n82, 119, -0.025556,\n82, 81, -0.025556,\n82, 84, -0.076666,\n82, 89, -0.076666,\n82, 86, -0.1022215,\n82, 87, -0.1022215,\n82, 101, -0.051111,\n82, 97, -0.051111,\n82, 111, -0.051111,\n82, 100, -0.051111,\n82, 99, -0.051111,\n82, 103, -0.051111,\n82, 113, -0.051111,\n84, 121, -0.076666,\n84, 101, -0.076666,\n84, 111, -0.076666,\n84, 114, -0.076666,\n84, 97, -0.076666,\n84, 117, -0.076666,\n84, 65, -0.076666,\n86, 111, -0.076666,\n86, 101, -0.076666,\n86, 117, -0.076666,\n86, 114, -0.076666,\n86, 97, -0.076666,\n86, 65, -0.1022215,\n86, 79, -0.025556,\n86, 67, -0.025556,\n86, 71, -0.025556,\n86, 81, -0.025556,\n87, 65, -0.076666,\n88, 79, -0.025556,\n88, 67, -0.025556,\n88, 71, -0.025556,\n88, 81, -0.025556,\n89, 101, -0.076666,\n89, 111, -0.076666,\n89, 114, -0.076666,\n89, 97, -0.076666,\n89, 117, -0.076666,\n89, 65, -0.076666,\n98, 101, -0.051111,\n98, 97, -0.051111,\n98, 111, -0.051111,\n98, 100, -0.051111,\n98, 99, -0.051111,\n98, 103, -0.051111,\n98, 113, -0.051111,\n99, 101, -0.051111,\n99, 97, -0.051111,\n99, 111, -0.051111,\n99, 100, -0.051111,\n99, 99, -0.051111,\n99, 103, -0.051111,\n99, 113, -0.051111,\n100, 108, 0.051111,\n101, 101, -0.051111,\n101, 97, -0.051111,\n101, 111, -0.051111,\n101, 100, -0.051111,\n101, 99, -0.051111,\n101, 103, -0.051111,\n101, 113, -0.051111,\n102, 39, 0.104306,\n102, 63, 0.104306,\n102, 33, 0.104306,\n102, 41, 0.104306,\n102, 93, 0.104306,\n108, 108, 0.051111,\n110, 39, -0.1022215,\n111, 101, -0.051111,\n111, 97, -0.051111,\n111, 111, -0.051111,\n111, 100, -0.051111,\n111, 99, -0.051111,\n111, 103, -0.051111,\n111, 113, -0.051111,\n112, 101, -0.051111,\n112, 97, -0.051111,\n112, 111, -0.051111,\n112, 100, -0.051111,\n112, 99, -0.051111,\n112, 103, -0.051111,\n112, 113, -0.051111,\n114, 101, -0.051111,\n114, 97, -0.051111,\n114, 111, -0.051111,\n114, 100, -0.051111,\n114, 99, -0.051111,\n114, 103, -0.051111,\n114, 113, -0.051111,\n119, 108, 0.051111,\n174, 39, 0.104306,\n174, 63, 0.104306,\n174, 33, 0.104306,\n174, 41, 0.104306,\n174, 93, 0.104306,\n195, 108, -0.255554,\n195, 76, -0.320554\nKERNS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/cmti10_unchanged.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(cmti10_unchanged, fonts/latin/optional/cmti10.ttf, 0)\n\nxHeight(0.430555) quad(1.022217) space(0.357776)\n\nbold(cmbxti10)\n\nMETRICS_START\n36, 0.7690935, 0.694445, 0, 0\nMETRICS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/cmtt10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(cmtt10, fonts/latin/optional/cmtt10.ttf, 0)\n\nxHeight(0.430555) quad(1.049991) space(0.524996)\n\nMETRICS_START\n33, 0.524996, 0.611112, 0, 0,\n34, 0.524996, 0.611112, 0, 0,\n35, 0.524996, 0.611112, 0, 0,\n36, 0.524996, 0.694445, 0.083333, 0,\n37, 0.524996, 0.694445, 0.083333, 0,\n38, 0.524996, 0.611112, 0, 0,\n39, 0.524996, 0.611112, 0, 0,\n40, 0.524996, 0.694445, 0.083331, 0,\n41, 0.524996, 0.694445, 0.083331, 0,\n42, 0.524996, 0.520834, 0, 0,\n43, 0.524996, 0.530554, -0.080557, 0,\n44, 0.524996, 0.125, 0.138888, 0,\n45, 0.524996, 0.530554, -0.080557, 0,\n46, 0.524996, 0.125, 0, 0,\n47, 0.524996, 0.694445, 0.083331, 0,\n48, 0.524996, 0.611112, 0, 0,\n49, 0.524996, 0.611112, 0, 0,\n50, 0.524996, 0.611112, 0, 0,\n51, 0.524996, 0.611112, 0, 0,\n52, 0.524996, 0.611112, 0, 0,\n53, 0.524996, 0.611112, 0, 0,\n54, 0.524996, 0.611112, 0, 0,\n55, 0.524996, 0.611112, 0, 0,\n56, 0.524996, 0.611112, 0, 0,\n57, 0.524996, 0.611112, 0, 0,\n58, 0.524996, 0.430555, 0, 0,\n59, 0.524996, 0.430555, 0.138888, 0,\n60, 0.524996, 0.555555, -0.055555, 0,\n61, 0.524996, 0.415624, -0.195488, 0,\n62, 0.524996, 0.555555, -0.055555, 0,\n63, 0.524996, 0.611112, 0, 0,\n64, 0.524996, 0.611112, 0, 0,\n65, 0.524996, 0.611112, 0, 0,\n66, 0.524996, 0.611112, 0, 0,\n67, 0.524996, 0.611112, 0, 0,\n68, 0.524996, 0.611112, 0, 0,\n69, 0.524996, 0.611112, 0, 0,\n70, 0.524996, 0.611112, 0, 0,\n71, 0.524996, 0.611112, 0, 0,\n72, 0.524996, 0.611112, 0, 0,\n73, 0.524996, 0.611112, 0, 0,\n74, 0.524996, 0.611112, 0, 0,\n75, 0.524996, 0.611112, 0, 0,\n76, 0.524996, 0.611112, 0, 0,\n77, 0.524996, 0.611112, 0, 0,\n78, 0.524996, 0.611112, 0, 0,\n79, 0.524996, 0.611112, 0, 0,\n80, 0.524996, 0.611112, 0, 0,\n81, 0.524996, 0.611112, 0.138888, 0,\n82, 0.524996, 0.611112, 0, 0,\n83, 0.524996, 0.611112, 0, 0,\n84, 0.524996, 0.611112, 0, 0,\n85, 0.524996, 0.611112, 0, 0,\n86, 0.524996, 0.611112, 0, 0,\n87, 0.524996, 0.611112, 0, 0,\n88, 0.524996, 0.611112, 0, 0,\n89, 0.524996, 0.611112, 0, 0,\n90, 0.524996, 0.611112, 0, 0,\n91, 0.524996, 0.694445, 0.083331, 0,\n92, 0.524996, 0.694445, 0.083331, 0,\n93, 0.524996, 0.694445, 0.083331, 0,\n94, 0.524996, 0.611112, 0, 0,\n95, 0.524996, 0, 0.095136, 0,\n96, 0.524996, 0.611112, 0, 0,\n97, 0.524996, 0.430555, 0, 0,\n98, 0.524996, 0.611112, 0, 0,\n99, 0.524996, 0.430555, 0, 0,\n100, 0.524996, 0.611112, 0, 0,\n101, 0.524996, 0.430555, 0, 0,\n102, 0.524996, 0.611112, 0, 0,\n103, 0.524996, 0.430555, 0.222223, 0,\n104, 0.524996, 0.611112, 0, 0,\n105, 0.524996, 0.611112, 0, 0,\n106, 0.524996, 0.611112, 0.222223, 0,\n107, 0.524996, 0.611112, 0, 0,\n108, 0.524996, 0.611112, 0, 0,\n109, 0.524996, 0.430555, 0, 0,\n110, 0.524996, 0.430555, 0, 0,\n111, 0.524996, 0.430555, 0, 0,\n112, 0.524996, 0.430555, 0.222223, 0,\n113, 0.524996, 0.430555, 0.222223, 0,\n114, 0.524996, 0.430555, 0, 0,\n115, 0.524996, 0.430555, 0, 0,\n116, 0.524996, 0.5535755, 0, 0,\n117, 0.524996, 0.430555, 0, 0,\n118, 0.524996, 0.430555, 0, 0,\n119, 0.524996, 0.430555, 0, 0,\n120, 0.524996, 0.430555, 0, 0,\n121, 0.524996, 0.430555, 0.222223, 0,\n122, 0.524996, 0.430555, 0, 0,\n123, 0.524996, 0.694445, 0.083331, 0,\n124, 0.524996, 0.694445, 0.083331, 0,\n125, 0.524996, 0.694445, 0.083331, 0,\n126, 0.524996, 0.611112, 0, 0,\n161, 0.524996, 0.611112, 0, 0,\n162, 0.524996, 0.611112, 0, 0,\n163, 0.524996, 0.611112, 0, 0,\n164, 0.524996, 0.611112, 0, 0,\n165, 0.524996, 0.611112, 0, 0,\n166, 0.524996, 0.611112, 0, 0,\n167, 0.524996, 0.611112, 0, 0,\n168, 0.524996, 0.611112, 0, 0,\n169, 0.524996, 0.611112, 0, 0,\n170, 0.524996, 0.611112, 0, 0,\n173, 0.524996, 0.611112, 0, 0,\n174, 0.524996, 0.611112, 0, 0,\n175, 0.524996, 0.611112, 0, 0,\n176, 0.524996, 0.611112, 0, 0,\n177, 0.524996, 0.388888, 0.222223, 0,\n178, 0.524996, 0.388888, 0.222223, 0,\n179, 0.524996, 0.430555, 0, 0,\n180, 0.524996, 0.430555, 0.222223, 0,\n181, 0.524996, 0.611112, 0, 0,\n182, 0.524996, 0.611112, 0, 0,\n183, 0.524996, 0.565973, 0, 0,\n184, 0.524996, 0.611112, 0, 0,\n185, 0.524996, 0.565555, 0, 0,\n186, 0.524996, 0.611112, 0, 0,\n187, 0.524996, 0, 0.194446, 0,\n188, 0.524996, 0.611112, 0, 0,\n189, 0.524996, 0.430555, 0, 0,\n190, 0.524996, 0.430555, 0, 0,\n191, 0.524996, 0.541667, 0.111112, 0,\n192, 0.524996, 0.611112, 0, 0,\n193, 0.524996, 0.611112, 0, 0,\n194, 0.524996, 0.666667, 0.055555, 0,\n195, 0.524996, 0.219444, 0.111112, 0,\n196, 0.524996, 0.611112, 0, 0,\n197, 0.524872, 0.057, 0.191, 0\nMETRICS_END\n\nLARGERS_START\n40, 161, 1,\n41, 162, 1,\n47, 177, 1,\n91, 163, 1,\n93, 164, 1\nLARGERS_END\n\nLIGTURES_START\n33, 96, 177,\n63, 96, 178\nLIGTURES_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/dsrom10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(dsrom10, fonts/maths/optional/dsrom10.ttf, 0)\n\nxHeight(0.462964) quad(1.0) space(0.300003)\n\nMETRICS_START\n49, 0.611113, 0.644444, 0, 0,\n65, 0.833336, 0.683332, 0, 0,\n66, 0.763891, 0.683332, 0, 0,\n67, 0.722224, 0.683332, 0, 0,\n68, 0.791669, 0.683332, 0, 0,\n69, 0.736113, 0.683332, 0, 0,\n70, 0.708336, 0.683332, 0, 0,\n71, 0.784724, 0.683332, 0, 0,\n72, 0.833336, 0.683332, 0, 0,\n73, 0.444446, 0.683332, 0, 0,\n74, 0.597224, 0.683332, 0, 0,\n75, 0.833336, 0.683332, 0, 0,\n76, 0.680557, 0.683332, 0, 0,\n77, 1.000003, 0.683332, 0, 0,\n78, 0.833336, 0.683332, 0, 0,\n79, 0.777781, 0.683332, 0, 0,\n80, 0.736113, 0.683332, 0, 0,\n81, 0.777781, 0.683332, 0.194445, 0,\n82, 0.791669, 0.683332, 0, 0,\n83, 0.555557, 0.683332, 0, 0,\n84, 0.750003, 0.683332, 0, 0,\n85, 0.805557, 0.683332, 0, 0,\n86, 0.805557, 0.683332, 0, 0.013888,\n87, 1.083336, 0.683332, 0, 0.013888,\n88, 0.861113, 0.683332, 0, 0,\n89, 0.805557, 0.683332, 0, 0.025,\n90, 0.750003, 0.683332, 0, 0,\n97, 0.833336, 0.683332, 0, 0,\n104, 0.655558, 0.694445, 0, 0,\n107, 0.62778, 0.694445, 0, 0\nMETRICS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/eufb10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(eufb10, fonts/euler/eufb10.ttf, 0)\n\nxHeight(0.475342) quad(1.0) space(0.333333)\n\nMETRICS_START\n33, 0.349205, 0.691406, 0, 0,\n38, 0.871259, 0.691406, 0, 0,\n39, 0.250343, 0.691406, 0, 0,\n40, 0.45891, 0.749474, 0.249825, 0,\n41, 0.45891, 0.749474, 0.249825, 0,\n42, 0.327838, 0.629288, 0, 0,\n43, 0.892944, 0.582834, 0.083185, 0,\n44, 0.327838, 0.108032, 0, 0,\n45, 0.892944, 0.582834, 0.083185, 0,\n46, 0.327838, 0.108032, 0, 0,\n47, 0.592532, 0.749474, 0.249825, 0,\n48, 0.592532, 0.475342, 0, 0,\n49, 0.592532, 0.475342, 0, 0,\n50, 0.592532, 0.475342, 0, 0,\n51, 0.592532, 0.475342, 0.189056, 0,\n52, 0.592532, 0.475342, 0.189056, 0,\n53, 0.592532, 0.475342, 0.189056, 0,\n54, 0.592532, 0.691406, 0, 0,\n55, 0.592532, 0.475342, 0.189056, 0,\n56, 0.592532, 0.691406, 0, 0,\n57, 0.592532, 0.475342, 0.189056, 0,\n58, 0.255127, 0.475342, 0, 0,\n59, 0.255127, 0.475342, 0.126038, 0,\n61, 0.58169, 0.475342, 0, 0,\n63, 0.427976, 0.691406, 0, 0,\n65, 0.847341, 0.691406, 0, 0,\n66, 1.043788, 0.691406, 0, 0,\n67, 0.723285, 0.691406, 0, 0,\n68, 0.98192, 0.691406, 0, 0,\n69, 0.782602, 0.691406, 0, 0,\n70, 0.72169, 0.691406, 0.126038, 0,\n71, 0.927386, 0.691406, 0, 0,\n72, 0.85053, 0.691406, 0.063019, 0,\n73, 0.654719, 0.691406, 0, 0,\n74, 0.652168, 0.691406, 0.126038, 0,\n75, 0.789299, 0.691406, 0, 0,\n76, 0.786428, 0.691406, 0, 0,\n77, 1.239279, 0.691406, 0, 0,\n78, 0.982557, 0.691406, 0, 0,\n79, 0.976499, 0.691406, 0, 0,\n80, 0.977137, 0.691406, 0.189056, 0,\n81, 0.976499, 0.691406, 0.037811, 0,\n82, 0.977774, 0.691406, 0, 0,\n83, 0.978412, 0.691406, 0, 0,\n84, 0.789937, 0.691406, 0, 0,\n85, 0.85053, 0.691406, 0, 0,\n86, 0.981601, 0.691406, 0, 0,\n87, 1.235133, 0.691406, 0, 0,\n88, 0.849254, 0.691406, 0, 0,\n89, 0.983515, 0.691406, 0.189056, 0,\n90, 0.710848, 0.691406, 0.126038, 0,\n91, 0.2567215, 0.749474, 0.249825, 0,\n93, 0.2567215, 0.749474, 0.249825, 0,\n94, 0.589981, 0.691406, 0, 0,\n97, 0.602737, 0.475342, 0, 0,\n98, 0.589981, 0.691406, 0, 0,\n99, 0.463694, 0.475342, 0, 0,\n100, 0.588705, 0.629288, 0, 0,\n101, 0.471985, 0.475342, 0, 0,\n102, 0.388431, 0.691406, 0.189056, 0,\n103, 0.594765, 0.475342, 0.189056, 0,\n104, 0.615494, 0.691406, 0.189056, 0,\n105, 0.3313465, 0.691406, 0, 0,\n106, 0.331665, 0.691406, 0, 0,\n107, 0.464012, 0.691406, 0, 0,\n108, 0.336767, 0.691406, 0, 0,\n109, 0.921328, 0.475342, 0, 0,\n110, 0.653763, 0.475342, 0, 0,\n111, 0.609116, 0.475342, 0, 0,\n112, 0.603694, 0.526655, 0.189056, 0,\n113, 0.595721, 0.475342, 0.189056, 0,\n114, 0.459547, 0.475342, 0, 0,\n115, 0.522692, 0.475342, 0, 0,\n116, 0.393214, 0.629288, 0, 0,\n117, 0.588705, 0.475342, 0, 0,\n118, 0.604332, 0.526655, 0, 0,\n119, 0.9175005, 0.526655, 0, 0,\n120, 0.45891, 0.475342, 0.189056, 0,\n121, 0.589025, 0.475342, 0.189056, 0,\n122, 0.461142, 0.475342, 0.189056, 0,\n125, 0.253532, 0.691406, 0, 0,\n162, 0.58743, 0.629288, 0, 0,\n163, 0.393534, 0.691406, 0.189056, 0,\n164, 0.387474, 0.629288, 0, 0,\n165, 0.592532, 0.691406, 0.189056, 0,\n166, 0.393214, 0.691406, 0, 0,\n167, 0.397679, 0.691406, 0, 0,\n169, 0.980644, 0.691406, 0, 0,\n170, 0.726793, 0.475342, 0, 0,\n181, 0.253532, 0.691406, 0, 0,\n182, 0.253532, 0.691406, 0, 0,\n196, 0.542145, 0.691406, 0, 0\nMETRICS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/eufm10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(eufm10, fonts/euler/eufm10.ttf, 0)\n\nxHeight(0.475342) quad(1.0) space(0.333333)\n\nbold(eufb10)\n\nMETRICS_START\n33, 0.295738, 0.691406, 0, 0,\n38, 0.73786, 0.691406, 0, 0,\n39, 0.212013, 0.691406, 0, 0,\n40, 0.388646, 0.749474, 0.249825, 0,\n41, 0.388646, 0.749474, 0.249825, 0,\n42, 0.277643, 0.621185, 0, 0,\n43, 0.756226, 0.582834, 0.083185, 0,\n44, 0.277643, 0.108032, 0, 0,\n45, 0.756226, 0.582834, 0.083185, 0,\n46, 0.277643, 0.108032, 0, 0,\n47, 0.50181, 0.749474, 0.249825, 0,\n48, 0.50181, 0.475342, 0, 0,\n49, 0.50181, 0.475342, 0, 0,\n50, 0.50181, 0.475342, 0, 0,\n51, 0.50181, 0.475342, 0.189056, 0,\n52, 0.50181, 0.475342, 0.189056, 0,\n53, 0.50181, 0.475342, 0.189056, 0,\n54, 0.50181, 0.691406, 0, 0,\n55, 0.50181, 0.475342, 0.189056, 0,\n56, 0.50181, 0.691406, 0, 0,\n57, 0.50181, 0.475342, 0.189056, 0,\n58, 0.216064, 0.475342, 0, 0,\n59, 0.216064, 0.475342, 0.126038, 0,\n61, 0.756226, 0.36866, -0.130989, 0,\n63, 0.362448, 0.691406, 0, 0,\n65, 0.717604, 0.691406, 0, 0,\n66, 0.883974, 0.691406, 0, 0,\n67, 0.612543, 0.691406, 0, 0,\n68, 0.831578, 0.691406, 0, 0,\n69, 0.662778, 0.691406, 0, 0,\n70, 0.611193, 0.691406, 0.126038, 0,\n71, 0.785395, 0.691406, 0, 0,\n72, 0.7203045, 0.691406, 0.063019, 0,\n73, 0.554476, 0.691406, 0, 0,\n74, 0.552315, 0.691406, 0.126038, 0,\n75, 0.668449, 0.691406, 0, 0,\n76, 0.6660185, 0.691406, 0, 0,\n77, 1.049533, 0.691406, 0, 0,\n78, 0.832118, 0.691406, 0, 0,\n79, 0.826986, 0.691406, 0, 0,\n80, 0.827527, 0.691406, 0.189056, 0,\n81, 0.826986, 0.691406, 0.037811, 0,\n82, 0.828067, 0.691406, 0, 0,\n83, 0.828608, 0.691406, 0, 0,\n84, 0.668989, 0.691406, 0, 0,\n85, 0.645762, 0.691406, 0, 0,\n86, 0.831308, 0.691406, 0, 0,\n87, 1.046022, 0.691406, 0, 0,\n88, 0.719225, 0.691406, 0, 0,\n89, 0.832929, 0.691406, 0.189056, 0,\n90, 0.60201, 0.691406, 0.126038, 0,\n91, 0.277643, 0.749474, 0.249825, 0,\n93, 0.277643, 0.749474, 0.249825, 0,\n94, 0.499649, 0.691406, 0, 0,\n97, 0.50046, 0.475342, 0, 0,\n98, 0.513153, 0.691406, 0, 0,\n99, 0.389456, 0.475342, 0, 0,\n100, 0.498569, 0.621185, 0, 0,\n101, 0.40053, 0.475342, 0, 0,\n102, 0.326258, 0.691406, 0.189056, 0,\n103, 0.5037, 0.475342, 0.189056, 0,\n104, 0.5212555, 0.691406, 0.189056, 0,\n105, 0.278994, 0.691406, 0, 0,\n106, 0.280884, 0.691406, 0, 0,\n107, 0.389456, 0.691406, 0, 0,\n108, 0.279533, 0.691406, 0, 0,\n109, 0.766759, 0.475342, 0, 0,\n110, 0.526657, 0.475342, 0, 0,\n111, 0.488846, 0.475342, 0, 0,\n112, 0.50046, 0.523956, 0.189056, 0,\n113, 0.489116, 0.475342, 0.189056, 0,\n114, 0.389186, 0.475342, 0, 0,\n115, 0.442662, 0.475342, 0, 0,\n116, 0.33301, 0.621185, 0, 0,\n117, 0.517204, 0.475342, 0, 0,\n118, 0.511803, 0.523956, 0, 0,\n119, 0.773511, 0.523956, 0, 0,\n120, 0.388646, 0.475342, 0.189056, 0,\n121, 0.498838, 0.475342, 0.189056, 0,\n122, 0.390536, 0.475342, 0.189056, 0,\n125, 0.214714, 0.691406, 0, 0,\n161, 0.497488, 0.621185, 0, 0,\n162, 0.498299, 0.621185, 0, 0,\n163, 0.33328, 0.691406, 0.189056, 0,\n164, 0.329228, 0.691406, 0.189056, 0,\n165, 0.50343, 0.475342, 0.189056, 0,\n166, 0.33301, 0.691406, 0, 0,\n167, 0.334089, 0.621185, 0, 0,\n168, 0.50073, 0.475342, 0, 0,\n181, 0.214714, 0.691406, 0, 0,\n182, 0.214714, 0.691406, 0, 0,\n196, 0.378113, 0.691406, 0, 0\nMETRICS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/i10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(i10, fonts/latin/i10.ttf, 0)\n\nxHeight(0.0) quad(1.000003) space(0.333334)\n\nbold(bi10) roman(r10) ss(si10) tt(tt10)\n\nMETRICS_START\n33, 0.557, 0.485, 0, 0.14,\n34, 0.456, 0.485, 0, 0.052,\n35, 0.456, 0.485, 0, -0.006,\n36, 0.557, 0.485, 0, -0.004,\n37, 1.115, 0.751, 0, 0.032,\n38, 1.432, 0.751, 0, 0.032\nMETRICS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/moustache.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(moustache, fonts/base/cmex10.ttf, 0)\n\nxHeight(0.430555) quad(1.000003)\n\nMETRICS_START\n56, 0.888891, 0, 0.900009, 0,\n57, 0.888891, 0, 0.900009, 0,\n58, 0.888891, 0, 0.900009, 0,\n59, 0.888891, 0, 0.900009, 0,\n62, 0.888891, 0, 0.300003, 0,\n64, 0.458336, 0.0, 0.0, 0,\n65, 0.875003, 0.0, 0.0, 0\nMETRICS_END\n\nEXTENSIONS_START\n62, -1, -1, 62, -1,\n64, 56, -1, 62, 59,\n65, 57, -1, 62, 58\nEXTENSIONS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/msam10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(msam10, fonts/maths/msam10.ttf, 0)\n\nxHeight(0.430555) quad(1.000003)\n\nMETRICS_START\n33, 1.388893, 0.377882, -0.133125, 0,\n34, 1.000003, 0.54986, 0, 0,\n35, 1.000003, 0.54986, 0, 0,\n36, 0.777781, 0.729581, 0.229581, 0,\n37, 0.777781, 0.729581, 0.229581, 0,\n38, 0.777781, 0.729581, 0.229581, 0,\n39, 0.777781, 0.755834, 0.255834, 0,\n40, 1.1111145, 0.54986, 0, 0,\n41, 0.666669, 0.692241, 0, 0,\n42, 0.666669, 0.692241, 0, 0,\n43, 0.777781, 0.581978, 0.081978, 0,\n44, 0.777781, 0.916669, 0.081978, 0,\n45, 0.777781, 0.729581, 0.229581, 0,\n46, 0.777781, 0.729581, 0.229581, 0,\n47, 0.777781, 0.755834, 0.255834, 0,\n48, 0.777781, 0.636665, 0.136665, 0,\n49, 0.777781, 0.636665, 0.136665, 0,\n50, 0.777781, 0.636665, 0.136665, 0,\n51, 0.777781, 0.636665, 0.136665, 0,\n52, 0.777781, 0.636665, 0.136665, 0,\n53, 0.777781, 0.755834, 0.255834, 0,\n54, 0.777781, 0.636665, 0.136665, 0,\n55, 0.777781, 0.675, 0.180801, 0,\n56, 0.275, 0.54986, 0, 0,\n57, 0.500002, 0.464017, -0.035983, 0,\n58, 0.777781, 0.581978, 0.081978, 0,\n59, 0.777781, 0.581978, 0.081978, 0,\n60, 0.777781, 0.636665, 0.136665, 0,\n61, 0.777781, 0.755834, 0.255834, 0,\n62, 0.777781, 0.636665, 0.136665, 0,\n63, 0.777781, 0.675, 0.180801, 0,\n64, 0.777781, 0.54986, 0.035173, 0,\n65, 0.777781, 0.54986, 0.035173, 0,\n66, 0.777781, 0.54986, 0.035173, 0,\n67, 0.777781, 0.54986, 0.035173, 0,\n68, 0.777781, 0.636665, 0.136665, 0,\n69, 0.777781, 0.636665, 0.136665, 0,\n70, 0.944446, 0.692241, 0.194443, 0,\n71, 0.500002, 0.755834, 0.255834, 0,\n72, 0.722224, 0.54986, 0, 0,\n73, 0.777781, 0.54986, 0.035173, 0,\n74, 0.777781, 0.54986, 0.035173, 0,\n75, 0.500002, 0.464017, -0.035983, 0,\n76, 0.500002, 0.464017, -0.035983, 0,\n77, 0.722224, 0.54986, 0, 0,\n78, 0.722224, 0.54986, 0, 0,\n79, 0.722224, 0.54986, 0, 0,\n80, 0.777781, 0.692241, 0, 0,\n81, 0.777781, 0.885691, 0.385691, 0,\n82, 0.777781, 0.885691, 0.385691, 0,\n83, 0.777781, 0.982565, 0.482565, 0,\n84, 0.777781, 0.982565, 0.482565, 0,\n85, 0.750002, 0.675, 0, 0.025,\n86, 1.000003, 0.636665, 0.136665, 0,\n87, 1.000003, 0.636665, 0.136665, 0,\n88, 0.833336, 0.692241, 0, 0,\n89, 0.611113, 0.692241, 0.194443, 0,\n90, 0.611113, 0.692241, 0.194443, 0,\n91, 0.611113, 0.755834, 0.194443, 0,\n92, 0.722224, 0.692241, 0, 0,\n93, 0.722224, 0.692241, 0, 0,\n94, 0.722224, 0.522394, 0.035173, 0,\n95, 0.777781, 0.692241, 0, 0,\n96, 0.777781, 0.692241, 0.194443, 0,\n97, 0.777781, 0.692241, 0.194443, 0,\n98, 0.777781, 0.54986, 0.035173, 0,\n99, 0.777781, 0.54986, 0.035173, 0,\n100, 0.666669, 0.54986, 0, 0,\n101, 0.666669, 0.54986, 0, 0,\n102, 0.760417, 0.54986, 0, 0,\n103, 0.760417, 0.54986, 0, 0,\n104, 0.777781, 0.692241, 0, 0,\n105, 0.777781, 0.692241, 0, 0,\n106, 0.777781, 0.755834, 0.255834, 0,\n107, 0.777781, 0.755834, 0.255834, 0,\n108, 0.777781, 0.54986, 0.060623, 0,\n109, 0.777781, 0.54986, 0.060623, 0,\n110, 1.333338, 0.54986, 0.035173, 0,\n111, 1.333338, 0.54986, 0.035173, 0,\n112, 0.500002, 0.692241, 0, 0,\n113, 0.500002, 0.692241, 0, 0,\n114, 0.946663, 0.692241, 0.155588, 0,\n115, 0.902219, 0.692241, 0.155588, 0,\n116, 0.666669, 0.692241, 0, 0,\n117, 0.777781, 0.692241, 0.081978, 0,\n118, 0.777781, 0.377882, -0.133125, 0,\n119, 0.777781, 0.464017, -0.035983, 0,\n120, 0.500002, 0.377882, 0, 0,\n121, 0.500002, 0.377882, 0, 0,\n122, 0.833336, 0.692241, 0, 0,\n123, 0.500002, 0.825005, 0, 0,\n124, 0.555557, 0.430555, 0.194443, 0,\n125, 0.777781, 0.581978, 0.081978, 0,\n126, 0.777781, 0.581978, 0.081978, 0,\n161, 0.777781, 0.675, 0, 0,\n162, 0.777781, 0.675, 0, 0,\n163, 0.777781, 0.675, 0, 0,\n164, 0.777781, 0.675, 0, 0,\n165, 0.777781, 0.675, 0, 0,\n166, 0.277779, 0.54986, 0, 0,\n167, 0.666669, 0.692241, 0.111112, 0,\n168, 0.666669, 0.692241, 0.111112, 0,\n169, 0.777781, 0.581978, 0.081978, 0,\n170, 0.777781, 0.581978, 0.081978, 0,\n171, 1.000003, 0.522394, 0.013539, 0,\n174, 1.000003, 0.522394, 0.013539, 0,\n175, 0.777781, 0.675, 0, 0,\n176, 0.722224, 0.692241, 0, 0,\n177, 0.888891, 0.692241, 0, 0,\n178, 0.611113, 0.692241, 0, 0,\n179, 1.000003, 0.522394, 0.013539, 0,\n180, 1.000003, 0.522394, 0.013539, 0,\n181, 1.000003, 0.675, 0.180801, 0,\n182, 1.000003, 0.675, 0.180801, 0,\n183, 0.833336, 0.692241, 0.194443, 0,\n184, 0.833336, 0.692241, 0.194443, 0,\n185, 0.416669, 0.692241, 0.194443, 0,\n186, 0.416669, 0.692241, 0.194443, 0,\n187, 0.416669, 0.692241, 0.194443, 0,\n188, 0.416669, 0.692241, 0.194443, 0,\n189, 1.1111145, 0.522394, 0.013539, 0,\n190, 1.1111145, 0.522394, 0.013539, 0,\n191, 1.000003, 0.675, 0.180801, 0,\n192, 1.000003, 0.675, 0.180801, 0,\n193, 0.500002, 0.692241, 0, 0,\n194, 0.500002, 0.692241, 0, 0,\n195, 1.000003, 0.377882, -0.133125, 0,\n196, 0.777781, 0.581978, 0.081978, 0\nMETRICS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/msbm10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(msbm10, fonts/maths/msbm10.ttf, 0)\n\nxHeight(0.462964) quad(1.0) space(0.300003)\n\nMETRICS_START\n33, 0.777781, 0.635971, 0.135971, 0,\n34, 0.777781, 0.757257, 0.251422, 0,\n35, 0.777781, 0.757257, 0.251422, 0,\n36, 0.777781, 0.793829, 0.284815, 0,\n37, 0.777781, 0.793829, 0.284815, 0,\n38, 0.777781, 0.757257, 0.251422, 0,\n39, 0.777781, 0.757257, 0.251422, 0,\n40, 0.777781, 0.635971, 0.135971, 0,\n41, 0.777781, 0.635971, 0.135971, 0,\n42, 0.777781, 0.793829, 0.302742, 0,\n43, 0.777781, 0.793829, 0.302742, 0,\n44, 0.500002, 0.74111, 0.251422, 0,\n45, 0.277779, 0.74111, 0.251422, 0,\n46, 0.222223, 0.581665, 0.081665, 0,\n47, 0.38889, 0.581665, 0.081665, 0,\n48, 0.611113, 0.688889, 0, 0,\n49, 0.722224, 0.688889, 0, 0,\n50, 0.611113, 0.688889, 0, 0,\n51, 0.722224, 0.688889, 0, 0,\n52, 0.777781, 0.793829, 0.302742, 0,\n53, 0.777781, 0.793829, 0.302742, 0,\n54, 0.777781, 0.705765, 0.205765, 0,\n55, 0.777781, 0.705765, 0.205765, 0,\n56, 1.000003, 0.366875, -0.133125, 0,\n57, 1.000003, 0.366875, -0.133125, 0,\n58, 1.000003, 0.366875, -0.133125, 0,\n59, 1.000003, 0.366875, -0.133125, 0,\n60, 1.000003, 0.366875, -0.133125, 0,\n61, 1.000003, 0.366875, -0.133125, 0,\n62, 0.777781, 0.581665, 0.081665, 0,\n63, 0.777781, 0.581665, 0.081665, 0,\n64, 0.555557, 0.688889, 0, 0,\n65, 0.722224, 0.688889, 0, 0,\n66, 0.666669, 0.688889, 0, 0,\n67, 0.722224, 0.688889, 0, 0,\n68, 0.722224, 0.688889, 0, 0,\n69, 0.666669, 0.688889, 0, 0,\n70, 0.611113, 0.688889, 0, 0,\n71, 0.777781, 0.688889, 0, 0,\n72, 0.777781, 0.688889, 0, 0,\n73, 0.38889, 0.688889, 0, 0,\n74, 0.500002, 0.688889, 0.166667, 0,\n75, 0.777781, 0.688889, 0, 0,\n76, 0.666669, 0.688889, 0, 0,\n77, 0.9444475, 0.688889, 0, 0,\n78, 0.722224, 0.688889, 0, 0,\n79, 0.777781, 0.688889, 0.166667, 0,\n80, 0.611113, 0.688889, 0, 0,\n81, 0.777781, 0.688889, 0.166667, 0,\n82, 0.722224, 0.688889, 0, 0,\n83, 0.555557, 0.688889, 0, 0,\n84, 0.666669, 0.688889, 0, 0,\n85, 0.722224, 0.688889, 0, 0,\n86, 0.722224, 0.688889, 0, 0,\n87, 1.000003, 0.688889, 0, 0,\n88, 0.722224, 0.688889, 0, 0,\n89, 0.722224, 0.688889, 0, 0,\n90, 0.666669, 0.688889, 0, 0,\n91, 1.888895, 0.825005, 0, 0,\n92, 2.333341, 0.825005, 0, 0,\n93, 1.888895, 0.825005, 0, 0,\n94, 2.333341, 0.899999, 0, 0,\n96, 0.555557, 0.688889, 0, 0,\n97, 0.63889, 0.688889, 0, 0,\n102, 0.722224, 0.688889, 0, 0,\n103, 0.555557, 0.688889, 0, 0,\n104, 0.777781, 0.463748, -0.036252, 0,\n105, 0.666669, 0.688889, 0, 0,\n106, 0.444446, 0.688889, 0, 0,\n107, 0.666669, 0.688889, 0, 0,\n108, 0.777781, 0.539098, 0.039098, 0,\n109, 0.777781, 0.539098, 0.039098, 0,\n110, 0.777781, 0.581665, 0.081665, 0,\n111, 0.777781, 0.581665, 0.081665, 0,\n112, 0.222223, 0.581665, 0.081665, 0,\n113, 0.38889, 0.581665, 0.081665, 0,\n114, 0.777781, 0.581665, 0.081665, 0,\n115, 0.777781, 0.366875, -0.133125, 0,\n116, 0.777781, 0.483122, -0.016878, 0,\n117, 0.777781, 0.581665, 0.081665, 0,\n118, 0.777781, 0.757257, 0.261668, 0,\n119, 0.777781, 0.757257, 0.261668, 0,\n120, 1.000003, 0.430555, 0, 0,\n121, 1.000003, 0.430555, 0, 0,\n122, 0.777781, 0.581665, 0.081665, 0,\n123, 0.666669, 0.430555, 0, 0.040278,\n124, 0.555557, 0.688889, 0, 0,\n125, 0.54028, 0.688889, 0, 0,\n126, 0.54028, 0.688889, 0, 0,\n161, 0.777781, 0.757257, 0.251422, 0,\n162, 0.777781, 0.757257, 0.251422, 0,\n163, 0.777781, 0.793829, 0.302742, 0,\n164, 0.777781, 0.793829, 0.302742, 0,\n165, 0.777781, 0.705765, 0.205765, 0,\n166, 0.777781, 0.705765, 0.205765, 0,\n167, 0.777781, 0.705765, 0.205765, 0,\n168, 0.777781, 0.705765, 0.205765, 0,\n169, 0.777781, 0.757257, 0.251422, 0,\n170, 0.777781, 0.757257, 0.251422, 0,\n171, 0.777781, 0.793829, 0.302742, 0,\n174, 0.777781, 0.793829, 0.302742, 0,\n175, 0.777781, 0.635971, 0.135971, 0,\n176, 0.777781, 0.635971, 0.135971, 0,\n177, 0.777781, 0.793829, 0.302742, 0,\n178, 0.777781, 0.793829, 0.302742, 0,\n179, 0.777781, 0.74111, 0.232221, 0,\n180, 0.777781, 0.74111, 0.232221, 0,\n181, 0.777781, 0.74111, 0.232221, 0,\n182, 0.777781, 0.74111, 0.232221, 0,\n183, 0.777781, 0.919513, 0.419513, 0,\n184, 0.777781, 0.919513, 0.419513, 0,\n185, 0.777781, 0.757257, 0.251422, 0,\n186, 0.777781, 0.757257, 0.251422, 0,\n187, 0.777781, 0.757257, 0.261668, 0,\n188, 0.777781, 0.757257, 0.261668, 0,\n189, 0.777781, 0.757257, 0.261668, 0,\n190, 0.777781, 0.757257, 0.261668, 0,\n191, 0.777781, 0.366875, -0.133125, 0,\n192, 0.777781, 0.793829, 0.302742, 0,\n193, 0.888891, 0.688889, 0.194443, 0,\n194, 0.888891, 0.74111, 0.194443, 0,\n195, 0.777781, 0.635971, 0.135971, 0,\n196, 0.429169, 0.430555, 0, 0\nMETRICS_END\n\nLARGERS_START\n91, 92, 0,\n93, 94, 0\nLARGERS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/r10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(r10, fonts/latin/r10.ttf, 0)\n\nxHeight(0.430555) quad(1.000003) space(0.333334)\n\nbold(bx10) ss(ss10) tt(tt10) it(i10)\n\nMETRICS_START\n33, 0.552, 0.485, 0, 0,\n34, 0.441, 0.485, 0, 0,\n35, 0.441, 0.485, 0, 0,\n36, 0.552, 0.485, 0, 0,\n37, 1.159, 0.751, 0, 0,\n38, 1.501, 0.751, 0, 0\nMETRICS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/r10_unchanged.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(r10_unchanged, fonts/latin/r10.ttf, 0)\n\nxHeight(0.430555) quad(1.000003) space(0.333334)\n\nMETRICS_START\n126, 1.389, 1.9, 0, 0,\n127, 1.389, 0.8, 0, 0\nMETRICS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/rsfs10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(rsfs10, fonts/maths/rsfs10.ttf, 0)\n\nxHeight(0.233333) quad(1.000003)\n\nMETRICS_START\n65, 0.802526, 0.7, 0, 0.229254,\n66, 0.907575, 0.7, 0, 0.040873,\n67, 0.666188, 0.7, 0, 0.168904,\n68, 0.774431, 0.7, 0, 0.093714,\n69, 0.561621, 0.7, 0, 0.185831,\n70, 0.895442, 0.7, 0, 0.136339,\n71, 0.60961, 0.7, 0, 0.173218,\n72, 0.969194, 0.7, 0, 0.296942,\n73, 0.80907, 0.7, 0, 0.191895,\n74, 1.05159, 0.7, 0.277777, 0.191895,\n75, 0.913638, 0.7, 0, 0.312587,\n76, 0.873729, 0.7, 0, 0.191895,\n77, 1.080305, 0.7, 0, 0.15981,\n78, 0.9015045, 0.7, 0, 0.352499,\n79, 0.737871, 0.7, 0, 0.080783,\n80, 1.012616, 0.7, 0, 0.080783,\n81, 0.882822, 0.7, 0, 0.033052,\n82, 0.850003, 0.7, 0, 0.062587,\n83, 0.867665, 0.7, 0, 0.191895,\n84, 0.746969, 0.7, 0, 0.290874,\n85, 0.799963, 0.7, 0, 0.258148,\n86, 0.622035, 0.7, 0, 0.275228,\n87, 0.805315, 0.7, 0, 0.275228,\n88, 0.9444475, 0.7, 0, 0.260063,\n89, 0.70961, 0.7, 0, 0.293904,\n90, 0.821203, 0.7, 0, 0.240366,\n196, 0.277779, 0.555555, 0, 0.52594\nMETRICS_END\n\nKERNS_START\n65, 196, 0.388901,\n66, 196, 0.19445,\n67, 196, 0.277786,\n68, 196, 0.1111145,\n69, 196, 0.138893,\n70, 196, 0.222229,\n71, 196, 0.250008,\n72, 196, 0.3333435,\n73, 196, 0.3333435,\n74, 196, 0.416679,\n75, 196, 0.361122,\n76, 196, 0.305565,\n77, 196, 0.444458,\n78, 196, 0.388901,\n79, 196, 0.166672,\n80, 196, 0.222229,\n81, 196, 0.277786,\n82, 196, 0.19445,\n83, 196, 0.3333435,\n84, 196, 0.222229,\n85, 196, 0.250008,\n86, 196, 0.222229,\n87, 196, 0.250008,\n88, 196, 0.277786,\n89, 196, 0.19445,\n90, 196, 0.305565\nKERNS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/sb10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(sb10, fonts/latin/sb10.ttf, 0)\n\nxHeight(0.0) quad(1.000003) space(0.333334)\n\nroman(bx10) tt(tt10) it(sbi10)\n\nMETRICS_START\n33, 0.734, 0.455, 0, 0,\n34, 0.489, 0.455, 0, 0,\n35, 0.489, 0.455, 0, 0,\n36, 0.734, 0.455, 0, 0,\n37, 1.33, 0.752, 0, 0,\n38, 1.826, 0.752, 0, 0\nMETRICS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/sbi10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(sbi10, fonts/latin/sbi10.ttf, 0)\n\nxHeight(0.0) quad(1.000003) space(0.333334)\n\nroman(ss10) tt(tt10)\n\nMETRICS_START\n33, 0.734, 0.454, 0, 0.046,\n34, 0.489, 0.454, 0, 0.034,\n35, 0.489, 0.454, 0, -0.012,\n36, 0.734, 0.454, 0, 0.004,\n37, 1.33, 0.751, 0, 0.046,\n38, 1.826, 0.751, 0, 0.046\nMETRICS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/si10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(si10, fonts/latin/si10.ttf, 0)\n\nxHeight(0.0) quad(1.000003) space(0.333334)\n\nbold(sbi10) roman(ss10) tt(tt10)\n\nMETRICS_START\n33, 0.662, 0.448, 0, 0.058,\n34, 0.441, 0.448, 0, 0.048,\n35, 0.441, 0.448, 0, -0.002,\n36, 0.662, 0.448, 0, 0.0,\n37, 1.159, 0.751, 0, 0.05,\n38, 1.533, 0.751, 0, 0.05\nMETRICS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/special.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(special, fonts/maths/special.ttf, 0)\n\nxHeight(0.233333) quad(1.000003)\n\nMETRICS_START\n65, 0.705, 0.7, 0.015, 0,\n66, 0.705, 0.7, 0.015, 0,\n67, 0.705, 0.7, 0.015, 0,\n68, 0.705, 0.7, 0.015, 0,\n69, 0.705, 0.7, 0.015, 0,\n70, 0.881, 0.7, 0.0, 0,\n101, 0.5, 0.68, 0.013, 0,\n109, 0.5, 0.45, 0.2, 0\nMETRICS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/ss10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(ss10, fonts/latin/ss10.ttf, 0)\n\nxHeight(0.0) quad(1.000003) space(0.333334)\n\nbold(sb10) roman(r10) tt(tt10) it(si10)\n\nMETRICS_START\n33, 0.662, 0.448, 0, 0,\n34, 0.441, 0.448, 0, 0,\n35, 0.441, 0.448, 0, 0,\n36, 0.662, 0.448, 0, 0,\n37, 1.159, 0.752, 0, 0,\n38, 1.533, 0.752, 0, 0\nMETRICS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/stmary10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(stmary10, fonts/maths/stmary10.ttf, 0)\n\nxHeight(0.430555) quad(1.000003)\n\nMETRICS_START\n32, 0.777781, 0.366875, -0.133125, 0,\n33, 0.777781, 0.366875, -0.133125, 0,\n34, 0.500002, 0.583334, 0.083334, 0,\n35, 0.500002, 0.583334, 0.083334, 0,\n36, 0.555557, 0.583334, 0.033438, 0,\n37, 0.555557, 0.527779, 0.083334, 0,\n38, 0.611113, 0.527779, 0.033438, 0,\n39, 0.611113, 0.527779, 0.033438, 0,\n40, 0.666669, 0.694445, 0.187327, 0,\n41, 0.666669, 0.694445, 0.187327, 0,\n42, 0.777781, 0.527779, 0.033438, 0,\n43, 0.555557, 0.583334, 0.083334, 0,\n44, 0.666669, 0.75, 0.25, 0,\n45, 0.666669, 0.75, 0.25, 0,\n46, 0.777781, 0.583334, 0.083334, 0,\n47, 0.777781, 0.583334, 0.083334, 0,\n48, 0.777781, 0.583334, 0.083334, 0,\n49, 0.777781, 0.583334, 0.083334, 0,\n50, 0.777781, 0.583334, 0.083334, 0,\n51, 0.777781, 0.583334, 0.083334, 0,\n52, 0.777781, 0.583334, 0.083334, 0,\n53, 0.777781, 0.583334, 0.083334, 0,\n54, 0.777781, 0.583334, 0.083334, 0,\n55, 0.777781, 0.583334, 0.083334, 0,\n56, 0.777781, 0.583334, 0.083334, 0,\n57, 0.777781, 0.583334, 0.083334, 0,\n58, 0.777781, 0.583334, 0.083334, 0,\n59, 0.777781, 0.583334, 0.083334, 0,\n60, 0.777781, 0.583334, 0.083334, 0,\n61, 0.777781, 0.583334, 0.083334, 0,\n62, 0.777781, 0.583334, 0.083334, 0,\n63, 0.777781, 0.583334, 0.083334, 0,\n64, 0.611113, 0.694445, 0.187327, 0,\n65, 0.888891, 0.694445, 0, 0,\n66, 0.555557, 0.694445, 0, 0,\n67, 0.333334, 0.5625, 0.187327, 0,\n68, 0.611113, 0.694445, 0.187327, 0,\n69, 0.611113, 0.694445, 0.187327, 0,\n70, 0.666669, 0.694445, 0.187327, 0,\n71, 0.666669, 0.694445, 0.187327, 0,\n72, 0.722224, 0.75, 0.25, 0,\n73, 0.722224, 0.75, 0.25, 0,\n74, 0.444446, 0.75, 0.25, 0,\n75, 0.444446, 0.75, 0.25, 0,\n76, 1.000003, 0.694445, 0.187327, 0,\n77, 0.777781, 0.680211, 0.187327, 0,\n78, 0.666669, 0.694445, 0.187327, 0,\n79, 0.666669, 0.694445, 0.187327, 0,\n80, 0.611113, 0.694445, 0.187327, 0,\n81, 0.611113, 0.694445, 0.187327, 0,\n82, 0.777781, 0.583334, 0.083334, 0,\n83, 0.777781, 0.583334, 0.083334, 0,\n84, 0.777781, 0.583334, 0.083334, 0,\n85, 0.777781, 0.583334, 0.083334, 0,\n86, 0.777781, 0.583334, 0.083334, 0,\n87, 0.777781, 0.583334, 0.083334, 0,\n88, 0.500002, 0.75, 0.25, 0,\n89, 0.6944475, 0.75, 0.25, 0,\n90, 0.777781, 0.583334, 0.083334, 0,\n91, 0.777781, 0.583334, 0.083334, 0,\n92, 0.777781, 0.583334, 0.083334, 0,\n93, 0.777781, 0.583334, 0.083334, 0,\n94, 0.777781, 0.583334, 0.083334, 0,\n95, 0.777781, 0.583334, 0.083334, 0,\n96, 0.666669, 0.555557, 0, 0,\n97, 0.666669, 0.539098, 0.033438, 0,\n98, 0.666669, 0.539098, 0.033438, 0,\n99, 0.666669, 0.555557, 0, 0,\n100, 0.777781, 0.539098, 0.033438, 0,\n101, 0.777781, 0.539098, 0.033438, 0,\n102, 0.777781, 0.635971, 0.135971, 0,\n103, 0.777781, 0.635971, 0.135971, 0,\n104, 0.444446, 0.75, 0.25, 0,\n105, 0.444446, 0.75, 0.25, 0,\n106, 0.402779, 0.75, 0.25, 0,\n107, 0.402779, 0.75, 0.25, 0,\n108, 0.38889, 0.75, 0.25, 0,\n109, 0.38889, 0.75, 0.25, 0,\n110, 0.777781, 0.583334, 0.083334, 0,\n111, 0.777781, 0.583334, 0.083334, 0,\n112, 0.777781, 0.635971, 0.135971, 0,\n113, 0.777781, 0.635971, 0.135971, 0,\n114, 0.777781, 0.802638, 0.302638, 0,\n115, 0.777781, 0.802638, 0.302638, 0,\n116, 0.555557, 0.75, 0.25, 0,\n117, 0.555557, 0.75, 0.25, 0,\n118, 0.555557, 0.75, 0.25, 0,\n119, 0.555557, 0.75, 0.25, 0,\n120, 0.0, 0.366875, -0.133125, 0,\n121, 0.0, 0.366875, -0.133125, 0,\n122, 0.0, 0.366875, -0.133125, 0,\n123, 0.0, 0.366875, -0.133125, 0,\n124, 0.0, 0.366875, -0.133125, 0,\n125, 1.000003, 0.472223, -0.027777, 0,\n126, 1.000003, 0.472223, -0.027777, 0,\n127, 1.000003, 0.472223, -0.027777, 0,\n128, 0.833336, 0, 1.000013, 0,\n129, 0.833336, 0, 1.000013, 0,\n130, 0.833336, 0, 1.000013, 0,\n131, 0.833336, 0, 1.000013, 0,\n132, 0.833336, 0, 1.000013, 0,\n133, 0.833336, 0, 1.000013, 0,\n134, 0.444446, 0, 1.000013, 0,\n135, 0.611113, 0, 1.000013, 0,\n136, 1.1111145, 0.100001, 1.500012, 0,\n137, 1.1111145, 0.100001, 1.500012, 0,\n138, 1.1111145, 0.100001, 1.500012, 0,\n139, 1.1111145, 0.100001, 1.500012, 0,\n140, 1.1111145, 0.100001, 1.500012, 0,\n141, 1.1111145, 0.100001, 1.500012, 0,\n142, 0.555557, 0.100001, 1.500012, 0,\n143, 0.833336, 0.100001, 1.500012, 0,\n144, 0.833336, 0, 1.000013, 0,\n145, 0.527781, 0.039999, 1.160013, 0,\n146, 0.583336, 0.039999, 1.760019, 0,\n147, 0.638891, 0.039999, 2.360025, 0,\n148, 0.6944475, 0.039999, 2.9600315, 0,\n149, 0.777781, 0.039999, 1.760019, 0,\n150, 0.777781, 0.039999, 1.760019, 0,\n151, 0.777781, 0, 0.600006, 0,\n152, 1.1111145, 0.100001, 1.500012, 0,\n153, 0.527781, 0.039999, 1.160013, 0,\n154, 0.583336, 0.039999, 1.760019, 0,\n155, 0.638891, 0.039999, 2.360025, 0,\n156, 0.6944475, 0.039999, 2.9600315, 0,\n157, 0.777781, 0.039999, 1.760019, 0,\n158, 0.777781, 0.039999, 1.760019, 0,\n159, 0.777781, 0, 0.600006, 0\nMETRICS_END\n\nEXTENSIONS_START\n149, 117, -1, 151, 118,\n157, 125, -1, 159, 126\nEXTENSIONS_END\n\nLARGERS_START\n106, 145, 7,\n107, 153, 7,\n128, 136, 7,\n129, 137, 7,\n130, 138, 7,\n131, 139, 7,\n132, 140, 7,\n133, 141, 7,\n134, 142, 7,\n135, 143, 7,\n144, 152, 7,\n145, 146, 7,\n146, 147, 7,\n147, 148, 7,\n148, 149, 7,\n153, 154, 7,\n154, 155, 7,\n155, 156, 7,\n156, 157, 7\nLARGERS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font/tt10.def.cpp",
    "content": "#include \"res/font_def.res.h\"\n\nDEF_FONT(tt10, fonts/latin/tt10.ttf, 0)\n\nxHeight(0.0) quad(1.000003) space(0.333334)\n\nMETRICS_START\n33, 0.516, 0.441, 0, 0,\n34, 0.516, 0.441, 0, 0,\n35, 0.516, 0.441, 0, 0,\n36, 0.516, 0.441, 0, 0,\n37, 0.516, 0.695, 0, 0,\n38, 0.516, 0.695, 0, 0\nMETRICS_END\n\nEND\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/font_def.res.h",
    "content": "#ifndef FONT_DEF_RES_H_INCLUDED\n#define FONT_DEF_RES_H_INCLUDED\n\n#include \"fonts/font_info.h\"\n#include \"fonts/font_reg.h\"\n\n#define __len(x) ((int)(sizeof(x) / sizeof((x)[0])))\n\n#define DEF_FONT(name, path, unicode)   \\\n    void __font_reg(name)() {           \\\n        int id = FontInfo::__id(#name); \\\n        auto info = FontInfo::__create(id, RES_BASE + \"/\" + #path, unicode);\n\n#define space(x)   info->__set_space(x);\n#define xHeight(x) info->__set_xheight(x);\n#define quad(x)    info->__set_quad(x);\n#define skew(x)    info->setSkewChar(x);\n\n#define __ver(m, v) info->m(FontInfo::__id(#v));\n#define roman(x)    __ver(setRomanId, x)\n#define bold(x)     __ver(setBoldId, x)\n#define it(x)       __ver(setItId, x)\n#define ss(x)       __ver(setSsId, x)\n#define tt(x)       __ver(setTtId, x)\n\n#define __start_def(type) \\\n    {                     \\\n        const type x[] = {\n#define __end_def(method)      \\\n    }                          \\\n    ;                          \\\n    info->method(x, __len(x)); \\\n    }                          \\\n    ;\n\n/**\n * Define the metrics of this font.\n * \n * There 5 components for each item:\n * \n *      [code, width, height, depth, italic-correction]\n */\n#define METRICS_START __start_def(float)\n#define METRICS_END   __end_def(__push_metrics)\n\n/**\n * Define the extensions of this font.\n * \n * There 5 components for each item:\n * \n *      [code, top, middle, repeat, bottom]\n */\n#define EXTENSIONS_START __start_def(int)\n#define EXTENSIONS_END   __end_def(__push_extensions)\n\n/**\n * Define the larger-version of a specific character.\n * \n * There 3 components for each item:\n * \n *      [code, larger-code, larger-font-id]\n */\n#define LARGERS_START __start_def(int)\n#define LARGERS_END   __end_def(__push_largers)\n\n/**\n * Define the ligtures for 2 characters.\n * \n * There 3 components for each item:\n * \n *      [left-code, right-code, lig-code]\n */\n#define LIGTURES_START __start_def(wchar_t)\n#define LIGTURES_END   __end_def(__push_ligtures)\n\n/**\n * Define the kerning for 2 characters.\n * \n * There 3 components for each item:\n * \n *      [left-code, right-code, kerning]\n */\n#define KERNS_START __start_def(float)\n#define KERNS_END   __end_def(__push_kerns)\n\n#define END }\n\n#endif\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/parser/font_parser.cpp",
    "content": "#include \"res/parser/font_parser.h\"\n\n#define __id(x) FontInfo::__id(x)\n\nconst string DefaultTeXFontParser::FONTS_RES_BASE = \"fonts\";\n/** document define  */\nconst string DefaultTeXFontParser::RESOURCE_NAME = FONTS_RES_BASE + \"/DefaultTeXFont.xml\";\n/** element define  */\nconst string DefaultTeXFontParser::STYLE_MAPPING_EL = \"TextStyleMapping\";\n/** attribute define */\nconst string DefaultTeXFontParser::GEN_SET_EL = \"GeneralSettings\";\nconst string DefaultTeXFontParser::MUFONTID_ATTR = \"mufontid\";\nconst string DefaultTeXFontParser::SPACEFONTID_ATTR = \"spacefontid\";\n\n/** static const member initialize */\nconst map<string, int> DefaultTeXFontParser::_rangeTypeMappings(\n    {{\"numbers\", DefaultTeXFont::NUMBERS},\n     {\"capitals\", DefaultTeXFont::CAPITAL},\n     {\"small\", DefaultTeXFont::SMALL},\n     {\"unicode\", DefaultTeXFont::UNICODE}});  // range mapping\n\nconst map<string, ChildParser> DefaultTeXFontParser::_charChildParsers(\n    {{\"Kern\", DefaultTeXFontParser::parse_kern},\n     {\"Lig\", DefaultTeXFontParser::parse_lig},\n     {\"NextLarger\", DefaultTeXFontParser::parse_larger},\n     {\"Extension\", DefaultTeXFontParser::parse_extension}});  // child parsers\n\n/**************************************** child parsers *******************************************/\n\nvoid DefaultTeXFontParser::parse_extension(\n    const XMLElement* e, wchar_t c, _out_ FontInfo& f) throw(ex_xml_parse) {\n    int* extensions = new int[4];\n    // get required integer attributes\n    extensions[DefaultTeXFont::REP] = getIntAndCheck(\"rep\", e);\n    // get optional integer attributes\n    extensions[DefaultTeXFont::TOP] = getOptionalInt(\"top\", e, DefaultTeXFont::NONE);\n    extensions[DefaultTeXFont::MID] = getOptionalInt(\"mid\", e, DefaultTeXFont::NONE);\n    extensions[DefaultTeXFont::BOT] = getOptionalInt(\"bot\", e, DefaultTeXFont::NONE);\n    // parsing OK, add extension info\n    f.setExtension(c, extensions);\n}\n\nvoid DefaultTeXFontParser::parse_kern(\n    const XMLElement* e, wchar_t c, _out_ FontInfo& f) throw(ex_xml_parse) {\n    // get required integer attributes\n    int code = getIntAndCheck(\"code\", e);\n    // get required float attributes\n    float kern = getFloatAndCheck(\"val\", e);\n    // parsing OK, add kern info\n    f.addKern(c, (wchar_t)code, kern);\n}\n\nvoid DefaultTeXFontParser::parse_lig(\n    const XMLElement* e, wchar_t c, _out_ FontInfo& f) throw(ex_xml_parse) {\n    int code = getIntAndCheck(\"code\", e);\n    int lig = getIntAndCheck(\"ligCode\", e);\n    f.addLigture(c, (wchar_t)code, (wchar_t)lig);\n}\n\nvoid DefaultTeXFontParser::parse_larger(\n    const XMLElement* e, wchar_t c, _out_ FontInfo& f) throw(ex_xml_parse) {\n    const string name = getAttrValueAndCheckIfNotNull(\"fontId\", e);\n    int code = getIntAndCheck(\"code\", e);\n    f.setNextLarger(c, (wchar_t)code, __id(name));\n}\n\n/**************************************** font information ****************************************/\n\nvoid DefaultTeXFontParser::processCharElement(\n    const XMLElement* e, _out_ FontInfo& info) throw(ex_res_parse) {\n    // retrieve required integer value\n    wchar_t ch = (wchar_t)getIntAndCheck(\"code\", e);\n    // retrieve optional value\n    float* metrics = new float[4];\n    metrics[DefaultTeXFont::WIDTH] = getOptionalFloat(\"width\", e, 0);\n    metrics[DefaultTeXFont::HEIGHT] = getOptionalFloat(\"height\", e, 0);\n    metrics[DefaultTeXFont::DEPTH] = getOptionalFloat(\"depth\", e, 0);\n    metrics[DefaultTeXFont::IT] = getOptionalFloat(\"italic\", e, 0);\n    // set metrics\n    info.setMetrics(ch, metrics);\n    // process children (kerning, ligature...)\n    const XMLElement* x = e->FirstChildElement();\n    while (x != nullptr) {\n        auto it = _charChildParsers.find(x->Name());\n        if (it == _charChildParsers.end()) {\n            throw ex_xml_parse(\n                RESOURCE_NAME + \": a <Char-element> has an unknown child element '\" +\n                x->Name() + \"'!\");\n        }\n        it->second(x, ch, info);\n        x = x->NextSiblingElement();\n    }\n}\n\nvoid DefaultTeXFontParser::parseStyleMappings(\n    _out_ map<string, vector<CharFont*>>& res) throw(ex_res_parse) {\n    const XMLElement* mapping = _root->FirstChildElement(\"TextStyleMappings\");\n    // no defined style mappings\n    if (mapping == nullptr) return;\n#ifdef HAVE_LOG\n    __dbg(\"TextStyleMappings tag name: %s\\n\", mapping->Name());\n#endif  // HAVE_LOG\n    // iterate all mappings\n    mapping = mapping->FirstChildElement(\"TextStyleMapping\");\n    while (mapping != nullptr) {\n        const string textStyleName = getAttrValueAndCheckIfNotNull(\"name\", mapping);\n        string boldFontId = \"\";\n        obtainAttr(\"bold\", mapping, boldFontId);\n        // parse range\n        const XMLElement* range = mapping->FirstChildElement(\"MapRange\");\n#ifdef HAVE_LOG\n        __dbg(\"MapRange tag name: %s\\n\", range->Name());\n#endif  // HAVE_LOG\n        vector<CharFont*> charFonts(4);\n        while (range != nullptr) {\n            const string fontId = getAttrValueAndCheckIfNotNull(\"fontId\", range);\n            int ch = getIntAndCheck(\"start\", range);\n            const string code = getAttrValueAndCheckIfNotNull(\"code\", range);\n            // find the code mapping\n            auto it = _rangeTypeMappings.find(code);\n            if (it == _rangeTypeMappings.end()) {\n                throw ex_xml_parse(\n                    RESOURCE_NAME,\n                    \"MapRange\", \"code\", \"contains an unknown 'range name' '\" + code + \"'!\");\n            }\n            CharFont* f = nullptr;\n            if (boldFontId.empty()) {\n                f = new CharFont((wchar_t)ch, __id(fontId));\n            } else {\n                f = new CharFont((wchar_t)ch, __id(fontId), __id(boldFontId));\n            }\n            charFonts[it->second] = f;\n            range = range->NextSiblingElement(\"MapRange\");\n        }\n        res[textStyleName] = charFonts;\n        mapping = mapping->NextSiblingElement(\"TextStyleMapping\");\n    }\n}\n\nvoid DefaultTeXFontParser::parseExtraPath() throw(ex_res_parse) {\n    const XMLElement* syms = _root->FirstChildElement(\"TeXSymbols\");\n    if (syms != nullptr) {  // element present\n        string include = getAttrValueAndCheckIfNotNull(\"include\", syms);\n        SymbolAtom::addSymbolAtom(_base + \"/\" + include);\n    }\n    const XMLElement* settings = _root->FirstChildElement(\"FormulaSettings\");\n    if (settings != nullptr) {\n        string include = getAttrValueAndCheckIfNotNull(\"include\", settings);\n        TeXFormula::addSymbolMappings(_base + \"/\" + include);\n    }\n}\n\nvoid DefaultTeXFontParser::parseFontDescriptions() throw(ex_res_parse) {\n    const XMLElement* des = _root->FirstChildElement(\"FontDescriptions\");\n    if (des == nullptr) return;\n\n#ifdef HAVE_LOG\n    __dbg(\"FontDescriptions, tag name:%s <should be FontDescriptions>\\n\", des->Name());\n#endif  // HAVE_LOG\n\n    const XMLElement* met = des->FirstChildElement(\"Metrics\");\n    while (met != nullptr) {\n        const string include = getAttrValueAndCheckIfNotNull(\"include\", met);\n        string path = \"\";\n        if (_base.empty()) {\n            path = RES_BASE + \"/\" + FONTS_RES_BASE + \"/\" + include;\n        } else {\n            path = _base + \"/\" + include;\n        }\n        parseFontDescriptions(path);\n\n#ifdef HAVE_LOG\n        __dbg(\"Metrics file path, path:%s\\n\", path.c_str());\n#endif  // HAVE_LOG\n\n        met = met->NextSiblingElement(\"Metrics\");\n    }\n    parseStyleMappings(_parsedTextStyles);\n    // set various versions\n    for (auto i : FontInfo::__infos()) {\n        if(i == nullptr){\n            continue;\n        }\n        auto it = _variousVersion.find(i->getId());\n        if (it == _variousVersion.end()) continue;\n        auto v = it->second;\n        i->setVariousId(v.bold, v.roman, v.ss, v.tt, v.it);\n    }\n}\n\nvoid DefaultTeXFontParser::parseFontDescriptions(const string& file) throw(ex_res_parse) {\n    if (file.empty()) return;\n\n    XMLDocument doc(true, COLLAPSE_WHITESPACE);\n    int err = doc.LoadFile(file.c_str());\n    if (err != XML_NO_ERROR) throw ex_xml_parse(\"Cannot open file \" + file + \"!\");\n    // get root\n    const XMLElement* font = doc.RootElement();\n\n#ifdef HAVE_LOG\n    __dbg(\"Font root element, tag name:%s <should be Font>\\n\", font->Name());\n#endif\n\n    // get required string attribute\n    const string fontName = getAttrValueAndCheckIfNotNull(\"name\", font);\n    const string fontId = getAttrValueAndCheckIfNotNull(\"id\", font);\n    if (__id(fontId) < 0) {\n        FontInfo::__predefine_name(fontId);\n    } else {\n        throw ex_font_loaded(\"Font \" + fontId + \" is already loaded!\");\n    }\n\n    const int __id = __id(fontId);\n    // get required real attributes\n    const float space = getFloatAndCheck(\"space\", font);\n    const float xHeight = getFloatAndCheck(\"xHeight\", font);\n    const float quad = getFloatAndCheck(\"quad\", font);\n    // optional\n    const int skewChar = getOptionalInt(\"skewChar\", font, -1);\n    const int unicode = getOptionalInt(\"unicode\", font, 0);\n    // get various versions of the font\n    __Versions v;\n    obtainAttr(\"boldVersion\", font, v.bold);\n    obtainAttr(\"romanVersion\", font, v.roman);\n    obtainAttr(\"ssVersion\", font, v.ss);\n    obtainAttr(\"ttVersion\", font, v.tt);\n    obtainAttr(\"itVersion\", font, v.it);\n    _variousVersion[__id] = v;\n\n    /**\n     * a name contains the file path relative to package \"fonts\",\n     * \"base/cmex10.xml\" as an example, the font file is represents\n     * with \"base/cemx10.ttf\"\n     */\n    string path = file.substr(0, file.find_last_of(\"/\") + 1) + fontName;\n    auto info = FontInfo::__create(__id, path, unicode, xHeight, space, quad);\n\n    // attribute set\n    if (skewChar != -1) info->setSkewChar((wchar_t)skewChar);\n    // process all \"Char\"-elements\n    const XMLElement* e = font->FirstChildElement(\"Char\");\n\n#ifdef HAVE_LOG\n    __dbg(\"parse Char, tag name: %s <should be Char>\\n\", e->Name());\n#endif  // HAVE_LOG\n\n    while (e != nullptr) {\n        processCharElement(e, *info);\n        e = e->NextSiblingElement(\"Char\");\n    }\n}\n\nvoid DefaultTeXFontParser::parseSymbolMappings(\n    _out_ map<string, sptr<CharFont>>& res) throw(ex_res_parse) {\n    const XMLElement* mapping = _root->FirstChildElement(\"SymbolMappings\");\n    if (mapping == nullptr) throw ex_xml_parse(RESOURCE_NAME, \"SymbolMappings\");\n\n#ifdef HAVE_LOG\n    __dbg(\"parse SymbolMappings, tag name:%s <should be SymbolMappings>\\n\", mapping->Name());\n#endif  // HAVE_LOG\n\n    // iterate all mappings\n    mapping = mapping->FirstChildElement(\"Mapping\");\n    XMLDocument doc(true, COLLAPSE_WHITESPACE);\n    while (mapping != nullptr) {\n        const string include = getAttrValueAndCheckIfNotNull(\"include\", mapping);\n        string path = \"\";\n        if (_base.empty()) {\n            path = RES_BASE + \"/\" + FONTS_RES_BASE + \"/\" + include;\n        } else {\n            path = _base + \"/\" + include;\n        }\n\n#ifdef HAVE_LOG\n        __dbg(\"symbol map path: %s \\n\", path.c_str());\n#endif\n\n        int err = doc.LoadFile(path.c_str());\n        if (err != XML_NO_ERROR)\n            throw ex_xml_parse(\"Cannot open the file '\" + path + \"'!\");\n        const XMLElement* symbol = doc.RootElement()->FirstChildElement(\"SymbolMapping\");\n\n#ifdef HAVE_LOG\n        __dbg(\"parse symbol, tag name:%s <should be SymbolMapping>\\n\", symbol->Name());\n#endif  // HAVE_LOG\n\n        while (symbol != nullptr) {\n            const string name = getAttrValueAndCheckIfNotNull(\"name\", symbol);\n            const wchar_t ch = (wchar_t)getIntAndCheck(\"ch\", symbol);\n            const string fontId = getAttrValueAndCheckIfNotNull(\"fontId\", symbol);\n            string boldFontId = \"\";\n            obtainAttr(\"boldId\", symbol, boldFontId);\n\n            auto it = res.find(name);\n            if (it != res.end()) {\n                it->second = nullptr;\n            }\n\n            CharFont* f = nullptr;\n            if (boldFontId.empty()) {\n                f = new CharFont(ch, __id(fontId));\n            } else {\n                f = new CharFont(ch, __id(fontId), __id(boldFontId));\n            }\n            res[name] = sptr<CharFont>(f);\n            symbol = symbol->NextSiblingElement(\"SymbolMapping\");\n        }\n        mapping = mapping->NextSiblingElement(\"Mapping\");\n    }\n}\n\nstring* DefaultTeXFontParser::parseDefaultTextStyleMappins() throw(ex_res_parse) {\n    string* res = new string[4];\n    const XMLElement* mappings = _root->FirstChildElement(\"DefaultTextStyleMapping\");\n    if (mappings == nullptr) return res;\n\n#ifdef HAVE_LOG\n    __dbg(\"tag name:%s <should be DefaultTextStyleMapping>\\n\", mappings->Name());\n#endif\n\n    // iterate all mappings\n    const XMLElement* mapping = mappings->FirstChildElement(\"MapStyle\");\n    while (mapping != nullptr) {\n        // get range name and check\n        const string code = getAttrValueAndCheckIfNotNull(\"code\", mapping);\n        auto mit = _rangeTypeMappings.find(code);\n        if (mit == _rangeTypeMappings.end()) {\n            throw ex_xml_parse(\n                RESOURCE_NAME,\n                \"MapStyle\", \"code\", \"contains an unknown 'range name' '\" + code + \"'!\");\n        }\n        int codeMapping = mit->second;\n        // get mapped style and check\n        const string textStyleName = getAttrValueAndCheckIfNotNull(\"textStyle\", mapping);\n\n        const auto& it = _parsedTextStyles.find(textStyleName);\n        if (it == _parsedTextStyles.end()) {\n            throw ex_xml_parse(\n                RESOURCE_NAME,\n                \"Mapstyle\", \"textStyle\",\n                \"contains an unknown 'range name' '\" + textStyleName + \"'!\");\n        }\n\n        const auto& charFonts = it->second;\n        // now check if the range is defined within the mapped text style\n        int index = codeMapping;\n        if (charFonts[index] == nullptr)\n            throw ex_xml_parse(\n                RESOURCE_NAME + \": the default text style mapping '\" +\n                textStyleName + \"' for the range '\" + code +\n                \"' contains no mapping for that range!\");\n\n        res[index] = textStyleName;\n        mapping = mapping->NextSiblingElement(\"MapStyle\");\n    }\n    return res;\n}\n\nmap<string, vector<CharFont*>> DefaultTeXFontParser::parseTextStyleMappings() {\n    if (_parsedTextStyles.empty()) parseStyleMappings(_parsedTextStyles);\n    return _parsedTextStyles;\n}\n\nvoid DefaultTeXFontParser::parseParameters(_out_ map<string, float>& res) throw(ex_res_parse) {\n    const XMLElement* parameters = _root->FirstChildElement(\"Parameters\");\n    if (parameters == nullptr) throw ex_xml_parse(RESOURCE_NAME, \"Parameter\");\n\n    const XMLAttribute* attr = parameters->FirstAttribute();\n    // iterate all attributes\n    while (attr != nullptr) {\n        const string name = attr->Name();\n        float value = getFloatAndCheck(name.c_str(), parameters);\n        res[name] = value;\n        attr = attr->Next();\n    }\n}\n\nvoid DefaultTeXFontParser::parseGeneralSettings(_out_ map<string, float>& res) throw(ex_res_parse) {\n    const XMLElement* settings = _root->FirstChildElement(\"GeneralSettings\");\n    if (settings == nullptr) throw ex_xml_parse(RESOURCE_NAME, \"GeneralSettings\");\n\n    int index = 0;\n    const string& v1 = getAttrValueAndCheckIfNotNull(\"mufontid\", settings);\n    res[\"mufontid\"] = __id(v1);\n    const string& v2 = getAttrValueAndCheckIfNotNull(\"spacefontid\", settings);\n    res[\"spacefontid\"] = __id(v2);\n    res[\"scriptfactor\"] = getFloatAndCheck(\"scriptfactor\", settings);\n    res[\"scriptscriptfactor\"] = getFloatAndCheck(\"scriptscriptfactor\", settings);\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/parser/font_parser.h",
    "content": "#ifndef FONT_PARSER_H_INCLUDED\n#define FONT_PARSER_H_INCLUDED\n\n#include \"common.h\"\n#include \"fonts/fonts.h\"\n#include \"xml/tinyxml2.h\"\n\nusing namespace tinyxml2;\n\nnamespace tex {\n\ntypedef void (*ChildParser)(const XMLElement*, wchar_t, FontInfo&);\n\nstruct __Versions {\n    string bold, roman, ss, tt, it;\n};\n\n/**\n * Parses the font information from an XML-file\n */\nclass DefaultTeXFontParser {\npublic:\n    static const string FONTS_RES_BASE;\n    // document define\n    static const string RESOURCE_NAME;\n    // element define\n    static const string STYLE_MAPPING_EL;\n    static const string GEN_SET_EL;\n    // attribute define\n    static const string MUFONTID_ATTR;\n    static const string SPACEFONTID_ATTR;\n\nprivate:\n    static const map<string, int> _rangeTypeMappings;\n\n    static const map<string, ChildParser> _charChildParsers;\n    // the xml-document we used\n    XMLDocument _doc;\n\n    map<int, __Versions> _variousVersion;\n    map<string, vector<CharFont*>> _parsedTextStyles;\n    const XMLElement* _root;\n    string _base;\n\n    static void parse_extension(const XMLElement*, wchar_t, _out_ FontInfo&) throw(ex_xml_parse);\n    static void parse_kern(const XMLElement*, wchar_t, _out_ FontInfo&) throw(ex_xml_parse);\n    static void parse_lig(const XMLElement*, wchar_t, _out_ FontInfo&) throw(ex_xml_parse);\n    static void parse_larger(const XMLElement*, wchar_t, _out_ FontInfo&) throw(ex_xml_parse);\n\n    void parseStyleMappings(_out_ map<string, vector<CharFont*>>& styles) throw(ex_res_parse);\n\n    static void processCharElement(const XMLElement* e, _out_ FontInfo& info) throw(ex_res_parse);\n\n    inline static bool exists(const char* attr, const XMLElement* e) throw() {\n        const XMLAttribute* value = e->FindAttribute(attr);\n        return (value != nullptr);\n    }\n\n    inline static void obtainAttr(\n        const char* attr, const XMLElement* e, _out_ string& val) throw() {\n        const char* value = e->Attribute(attr);\n        if (value == nullptr || strlen(value) == 0) return;\n        val.assign(value);\n    }\n\n    inline static string getAttrValueAndCheckIfNotNull(\n        const char* attr, const XMLElement* e) throw(ex_xml_parse) {\n        // find if attr is exists\n        const char* value = e->Attribute(attr);\n        if (value == nullptr || strlen(value) == 0)\n            throw ex_xml_parse(RESOURCE_NAME, e->Name(), attr, \"no mapping\");\n        return value;\n    }\n\n    inline static float getFloatAndCheck(\n        const char* attr, const XMLElement* e) throw(ex_xml_parse) {\n        // get value\n        float v = 0;\n        int err = e->QueryFloatAttribute(attr, &v);\n        // no attribute mapped by attr\n        if (err != XML_NO_ERROR)\n            throw ex_xml_parse(RESOURCE_NAME, e->Name(), attr, \"has invalid real value\");\n        return v;\n    }\n\n    inline static int getIntAndCheck(\n        const char* attr, const XMLElement* e) throw(ex_xml_parse) {\n        // get value\n        int v = 0;\n        int err = e->QueryIntAttribute(attr, &v);\n        if (err != XML_NO_ERROR)\n            throw ex_xml_parse(RESOURCE_NAME, e->Name(), attr, \"has invalid integer value\");\n        return v;\n    }\n\n    inline static int getOptionalInt(\n        const char* attr, const XMLElement* e, const int def) throw(ex_xml_parse) {\n        // check exists\n        if (!exists(attr, e)) return def;\n        // get value\n        int v = 0;\n        int err = e->QueryAttribute(attr, &v);\n        if (err != XML_NO_ERROR)\n            throw ex_xml_parse(RESOURCE_NAME, e->Name(), attr, \"has invalid integer value\");\n        return v;\n    }\n\n    inline static float getOptionalFloat(\n        const char* attr, const XMLElement* e, const float def) throw(ex_xml_parse) {\n        // check exists\n        if (!exists(attr, e)) return def;\n        // get value\n        float v = 0;\n        int err = e->QueryFloatAttribute(attr, &v);\n        if (err != XML_NO_ERROR)\n            throw ex_xml_parse(RESOURCE_NAME, e->Name(), attr, \"has invalid real value\");\n        return v;\n    }\n\n    void init(const string& file) throw(ex_xml_parse) {\n        int err = _doc.LoadFile(file.c_str());\n        if (err != XML_NO_ERROR) throw ex_xml_parse(file + \" not found\");\n        _root = _doc.RootElement();\n#ifdef HAVE_LOG\n        __dbg(\"root name:%s\\n\", _root->Name());\n#endif  // HAVE_LOG\n    }\n\npublic:\n    DefaultTeXFontParser() throw(ex_res_parse) : _doc(true, COLLAPSE_WHITESPACE) {\n        string file = RES_BASE + \"/\" + RESOURCE_NAME;\n        init(file);\n    }\n\n    DefaultTeXFontParser(const string& file) throw(ex_xml_parse) : _doc(true, COLLAPSE_WHITESPACE) {\n        init(file);\n    }\n\n    DefaultTeXFontParser(const string& base, const string& file) throw(ex_xml_parse)\n        : _doc(true, COLLAPSE_WHITESPACE), _base(base) {\n        init(file);\n    }\n\n    void parseExtraPath() throw(ex_res_parse);\n\n    void parseFontDescriptions(const string& file) throw(ex_res_parse);\n\n    void parseFontDescriptions() throw(ex_res_parse);\n\n    void parseSymbolMappings(_out_ map<string, sptr<CharFont>>& res) throw(ex_res_parse);\n\n    string* parseDefaultTextStyleMappins() throw(ex_res_parse);\n\n    void parseParameters(_out_ map<string, float>& res) throw(ex_res_parse);\n\n    void parseGeneralSettings(_out_ map<string, float>& res) throw(ex_res_parse);\n\n    map<string, vector<CharFont*>> parseTextStyleMappings();\n};\n\n}  // namespace tex\n\n#endif  // FONT_PARSER_H_INCLUDED\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/parser/formula_parser.cpp",
    "content": "#include \"res/parser/formula_parser.h\"\n\nconst string TeXSymbolParser::RESOURCE_NAME = \"TeXSymbols\";\nconst string TeXSymbolParser::DELIMITER_ATTR = \"del\";\nconst string TeXSymbolParser::TYPE_ATTR = \"type\";\n\nconst map<string, int> TeXSymbolParser::_typeMappings = {\n    {\"ord\", TYPE_ORDINARY},\n    {\"op\", TYPE_BIG_OPERATOR},\n    {\"bin\", TYPE_BINARY_OPERATOR},\n    {\"rel\", TYPE_RELATION},\n    {\"open\", TYPE_OPENING},\n    {\"close\", TYPE_CLOSING},\n    {\"punct\", TYPE_PUNCTUATION},\n    {\"acc\", TYPE_ACCENT}};\n\nstring TeXSymbolParser::getAttr(const char* attr, const XMLElement* e) throw(ex_res_parse) {\n    const char* x = e->Attribute(attr);\n    if (x == nullptr || strlen(x) == 0) throw ex_xml_parse(RESOURCE_NAME, e->Name(), attr, \"no mapping!\");\n    return x;\n}\n\nTeXSymbolParser::TeXSymbolParser(const string& file) throw(ex_res_parse)\n    : _doc(true, COLLAPSE_WHITESPACE) {\n    int err = _doc.LoadFile(file.c_str());\n    if (err != XML_NO_ERROR) throw ex_res_parse(file + \" not found!\");\n    _root = _doc.RootElement();\n}\n\nvoid TeXSymbolParser::readSymbols(_out_ map<string, sptr<SymbolAtom>>& res) throw(ex_res_parse) {\n    const XMLElement* e = _root->FirstChildElement(\"Symbol\");\n    while (e != nullptr) {\n        const string name = getAttr(\"name\", e);\n        const string type = getAttr(\"type\", e);\n        bool isDelimiter = false;\n        e->QueryBoolAttribute(\"del\", &isDelimiter);\n        // check if type is valid\n        auto it = _typeMappings.find(type);\n        if (it == _typeMappings.end()) {\n            throw ex_xml_parse(RESOURCE_NAME, \"Symbol\", \"type\", \"has an unknown value '\" + type + \"'!\");\n        }\n        res[name] = sptr<SymbolAtom>(new SymbolAtom(name, it->second, isDelimiter));\n        e = e->NextSiblingElement(\"Symbol\");\n    }\n}\n\nconst string TeXFormulaSettingParser::RESOURCE_NAME = \"TeXFormulaSettings\";\n\nTeXFormulaSettingParser::TeXFormulaSettingParser(const string& file) throw(ex_res_parse)\n    : _doc(true, COLLAPSE_WHITESPACE) {\n    int err = _doc.LoadFile(file.c_str());\n    if (err != XML_NO_ERROR) throw ex_xml_parse(file + \" not found!\");\n    _root = _doc.RootElement();\n}\n\nint TeXFormulaSettingParser::getUtf(const XMLElement* e, const char* attr) throw(ex_res_parse) {\n    const char* val = e->Attribute(attr);\n    if (val == nullptr || strlen(val) == 0) {\n        throw ex_xml_parse(RESOURCE_NAME, e->Name(), attr, \"no mapping!\");\n    }\n    wstring wstr;\n    utf82wide(val, wstr);\n    if (wstr.empty() || wstr.length() != 1) {\n        throw ex_xml_parse(RESOURCE_NAME, e->Name(), attr, \"unknown code point!\");\n    }\n    return wstr[0];\n}\n\nvoid TeXFormulaSettingParser::add2map(\n    const XMLElement* r,\n    _out_ map<int, string>& math,\n    _out_ map<int, string>& txt) throw(ex_res_parse) {\n    while (r != nullptr) {\n        int ch = getUtf(r, \"char\");\n        const char* symbol = r->Attribute(\"symbol\");\n        const char* text = r->Attribute(\"text\");\n        // check\n        if (symbol == nullptr) {\n            throw ex_xml_parse(RESOURCE_NAME, r->Name(), \"symbol\", \"no mapping!\");\n        }\n        math[ch] = symbol;\n        if (text != nullptr) txt[ch] = text;\n        r = r->NextSiblingElement(\"Map\");\n    }\n}\n\nvoid TeXFormulaSettingParser::addFormula2map(\n    const XMLElement* r,\n    _out_ map<int, string>& math,\n    _out_ map<int, string>& txt) throw(ex_res_parse) {\n    while (r != nullptr) {\n        int ch = getUtf(r, \"char\");\n        const char* formula = r->Attribute(\"formula\");\n        const char* text = r->Attribute(\"text\");\n        // check\n        if (formula == nullptr) {\n            throw ex_xml_parse(RESOURCE_NAME, r->Name(), \"formula\", \"no mapping!\");\n        }\n        math[ch] = formula;\n        if (text != nullptr) txt[ch] = text;\n        r = r->NextSiblingElement(\"Map\");\n    }\n}\n\nvoid TeXFormulaSettingParser::parseSymbol2Formula(\n    _out_ map<int, string>& mappings, _out_ map<int, string>& txt) throw(ex_res_parse) {\n    const XMLElement* e = _root->FirstChildElement(\"CharacterToFormulaMappings\");\n    if (e != nullptr) {\n        e = e->FirstChildElement(\"Map\");\n        if (e != nullptr) addFormula2map(e, mappings, txt);\n    }\n}\n\nvoid TeXFormulaSettingParser::parseSymbol(\n    _out_ map<int, string>& mappings, _out_ map<int, string>& txt) throw(ex_res_parse) {\n    const XMLElement* e = _root->FirstChildElement(\"CharacterToSymbolMappings\");\n    if (e != nullptr) {\n        e = e->FirstChildElement(\"Map\");\n        if (e != nullptr) add2map(e, mappings, txt);\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/parser/formula_parser.h",
    "content": "#ifndef FORMULA_PARSER_H_INCLUDED\n#define FORMULA_PARSER_H_INCLUDED\n\n#include \"atom/atom_basic.h\"\n#include \"common.h\"\n#include \"xml/tinyxml2.h\"\n\nusing namespace std;\nusing namespace tinyxml2;\n\nnamespace tex {\n\n/**\n * Parse TeX symbol definitions from an XML-file\n */\nclass TeXSymbolParser {\nprivate:\n    static const map<string, int> _typeMappings;\n    XMLDocument _doc;\n    XMLElement* _root;\n\n    static string getAttr(const char* attr, const XMLElement* e) throw(ex_res_parse);\n\npublic:\n    static const string RESOURCE_NAME;\n    static const string DELIMITER_ATTR;\n    static const string TYPE_ATTR;\n\n    TeXSymbolParser() = delete;\n\n    TeXSymbolParser(const string& file) throw(ex_res_parse);\n\n    void readSymbols(_out_ map<string, sptr<SymbolAtom>>& res) throw(ex_res_parse);\n};\n\n/**\n * Parse TeXFormulas form an XML-file\n */\nclass TeXFormulaSettingParser {\nprivate:\n    XMLDocument _doc;\n    XMLElement* _root;\n\n    static int getUtf(const XMLElement* e, const char* attr) throw(ex_res_parse);\n\n    static void add2map(\n        const XMLElement* mapping,\n        _out_ map<int, string>& tableMath,\n        _out_ map<int, string>& tableTxt) throw(ex_res_parse);\n\n    static void addFormula2map(\n        const XMLElement* mapping,\n        _out_ map<int, string>& tableMath,\n        _out_ map<int, string>& tableTxt) throw(ex_res_parse);\n\npublic:\n    static const string RESOURCE_NAME;\n\n    TeXFormulaSettingParser() = delete;\n\n    TeXFormulaSettingParser(const string& file) throw(ex_res_parse);\n\n    void parseSymbol2Formula(\n        _out_ map<int, string>& mappings,\n        _out_ map<int, string>& textMappings) throw(ex_res_parse);\n\n    void parseSymbol(\n        _out_ map<int, string>& mappings,\n        _out_ map<int, string>& textMappings) throw(ex_res_parse);\n};\n}  // namespace tex\n\n#endif  // FORMULA_PARSER_H_INCLUDED\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/reg/builtin_font_reg.cpp",
    "content": "#include \"res/reg/builtin_font_reg.h\"\n\nDEF_FONT_SET(Builtin)\n\nREG_FONT(msbm10)\nREG_FONT(cmex10)\nREG_FONT(cmmi10)\nREG_FONT(cmmib10)\nREG_FONT(moustache)\nREG_FONT(cmmi10_unchanged)\nREG_FONT(cmmib10_unchanged)\nREG_FONT(stmary10)\nREG_FONT(cmsy10)\nREG_FONT(msam10)\nREG_FONT(cmbsy10)\nREG_FONT(dsrom10)\nREG_FONT(rsfs10)\nREG_FONT(eufm10)\nREG_FONT(eufb10)\nREG_FONT(cmti10)\nREG_FONT(cmti10_unchanged)\nREG_FONT(cmbxti10)\nREG_FONT(cmr10)\nREG_FONT(cmss10)\nREG_FONT(cmssi10)\nREG_FONT(cmtt10)\nREG_FONT(cmbx10)\nREG_FONT(cmssbx10)\nREG_FONT(special)\nREG_FONT(r10)\nREG_FONT(r10_unchanged)\nREG_FONT(ss10)\nREG_FONT(si10)\nREG_FONT(i10)\nREG_FONT(bx10)\nREG_FONT(bi10)\nREG_FONT(sbi10)\nREG_FONT(sb10)\nREG_FONT(tt10)\n\nEND_DEF_FONT_SET\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/reg/builtin_font_reg.h",
    "content": "#ifndef BUILTIN_FONT_REG_H_INCLUDED\n#define BUILTIN_FONT_REG_H_INCLUDED\n\n#include \"fonts/font_info.h\"\n#include \"fonts/font_reg.h\"\n\n/**\n * DEFAULT FONT TABLES\n * Page 437 in [The TeXBook]\n */\nDECL_FONT_REG(msbm10);\nDECL_FONT_REG(cmex10);\nDECL_FONT_REG(cmmi10);\nDECL_FONT_REG(cmmib10);\nDECL_FONT_REG(moustache);\nDECL_FONT_REG(cmmi10_unchanged);\nDECL_FONT_REG(cmmib10_unchanged);\nDECL_FONT_REG(stmary10);\nDECL_FONT_REG(cmsy10);\nDECL_FONT_REG(msam10);\nDECL_FONT_REG(cmbsy10);\nDECL_FONT_REG(dsrom10);\nDECL_FONT_REG(rsfs10);\nDECL_FONT_REG(eufm10);\nDECL_FONT_REG(eufb10);\nDECL_FONT_REG(cmti10);\nDECL_FONT_REG(cmti10_unchanged);\nDECL_FONT_REG(cmbxti10);\nDECL_FONT_REG(cmr10);\nDECL_FONT_REG(cmss10);\nDECL_FONT_REG(cmssi10);\nDECL_FONT_REG(cmtt10);\nDECL_FONT_REG(cmbx10);\nDECL_FONT_REG(cmssbx10);\nDECL_FONT_REG(special);\nDECL_FONT_REG(r10);\nDECL_FONT_REG(r10_unchanged);\nDECL_FONT_REG(ss10);\nDECL_FONT_REG(si10);\nDECL_FONT_REG(i10);\nDECL_FONT_REG(bx10);\nDECL_FONT_REG(bi10);\nDECL_FONT_REG(sbi10);\nDECL_FONT_REG(sb10);\nDECL_FONT_REG(tt10);\n\nnamespace tex {\n\nDECL_FONT_SET(Builtin);\n\n}  // namespace tex\n\n#endif\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/reg/builtin_syms_reg.cpp",
    "content": "#include \"res/reg/builtin_syms_reg.h\"\n\nDEF_SYMBOLS_SET(Builtin)\n\nREG_SYMBOLS(base)\nREG_SYMBOLS(amssymb)\nREG_SYMBOLS(amsfonts)\nREG_SYMBOLS(stmaryrd)\nREG_SYMBOLS(special)\n\nEND_DEF_SYMBOLS_SET\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/reg/builtin_syms_reg.h",
    "content": "#ifndef BUILTIN_SYMS_REG_H_INCLUDED\n#define BUILTIN_SYMS_REG_H_INCLUDED\n\n#include \"fonts/symbol_reg.h\"\n\nusing namespace tex;\n\nDECL_SYMBOLS_REG(base);\nDECL_SYMBOLS_REG(amssymb);\nDECL_SYMBOLS_REG(amsfonts);\nDECL_SYMBOLS_REG(stmaryrd);\nDECL_SYMBOLS_REG(special);\n\nnamespace tex {\n\nDECL_SYMBOLS_SET(Builtin);\n\n}  // namespace tex\n\n#endif\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/sym/amsfonts.def.cpp",
    "content": "#include \"res/symbol_def.res.h\"\n\nDEF_SYMBOLS(amsfonts)\n\nE(0, 102, mho)\nE(0, 126, hbar)\nE(5, 101, euler)\nE(9, 64, sqsubset)\nE(9, 65, sqsupset)\nE(9, 66, rhd)\nE(9, 67, lhd)\nE(9, 68, unrhd)\nE(9, 69, unlhd)\nE(9, 92, angle)\nE(9, 164, Box)\nE(9, 167, Diamond)\nE(9, 171, rightleftharpoons)\nE(9, 195, leadsto)\n\nEND_DEF_SYMBOLS\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/sym/amssymb.def.cpp",
    "content": "#include \"res/symbol_def.res.h\"\n\nDEF_SYMBOLS(amssymb)\n\nE(0, 33, varsupsetneq)\nE(0, 34, nsubseteqq)\nE(0, 35, nsupseteqq)\nE(0, 36, subsetneqq)\nE(0, 37, supsetneqq)\nE(0, 38, varsubsetneqq)\nE(0, 39, varsupsetneqq)\nE(0, 40, subsetneq)\nE(0, 41, supsetneq)\nE(0, 42, nsubseteq)\nE(0, 43, nsupseteq)\nE(0, 44, nparallel)\nE(0, 45, nmid)\nE(0, 46, nshortmid)\nE(0, 47, nshortparallel)\nE(0, 48, nvdash)\nE(0, 49, nVdash)\nE(0, 50, nvDash)\nE(0, 51, nVDash)\nE(0, 52, ntrianglerighteq)\nE(0, 53, ntrianglelefteq)\nE(0, 54, ntriangleleft)\nE(0, 55, ntriangleright)\nE(0, 56, nleftarrow)\nE(0, 57, nrightarrow)\nE(0, 58, nLeftarrow)\nE(0, 59, nRightarrow)\nE(0, 60, nLeftrightarrow)\nE(0, 61, nleftrightarrow)\nE(0, 62, divideontimes)\nE(0, 63, varnothing)\nE(0, 64, nexists)\nE(0, 96, Finv)\nE(0, 97, Game)\nE(0, 103, eth)\nE(0, 104, eqsim)\nE(0, 105, beth)\nE(0, 106, gimel)\nE(0, 107, daleth)\nE(0, 108, lessdot)\nE(0, 109, gtrdot)\nE(0, 110, ltimes)\nE(0, 111, rtimes)\nE(0, 112, shortmid)\nE(0, 113, shortparallel)\nE(0, 114, smallsetminus)\nE(0, 115, thicksim)\nE(0, 116, thickapprox)\nE(0, 117, approxeq)\nE(0, 118, succapprox)\nE(0, 119, precapprox)\nE(0, 120, curvearrowleft)\nE(0, 121, curvearrowright)\nE(0, 122, digamma)\nE(0, 123, varkappa)\nE(0, 124, Bbbk)\nE(0, 125, hslash)\nE(0, 161, lvertneqq)\nE(0, 162, gvertneqq)\nE(0, 163, nleq)\nE(0, 164, ngeq)\nE(0, 165, nless)\nE(0, 166, ngtr)\nE(0, 167, nprec)\nE(0, 168, nsucc)\nE(0, 169, lneqq)\nE(0, 170, gneqq)\nE(0, 171, nleqslant)\nE(0, 174, ngeqslant)\nE(0, 175, lneq)\nE(0, 176, gneq)\nE(0, 177, npreceq)\nE(0, 178, nsucceq)\nE(0, 179, precnsim)\nE(0, 180, succnsim)\nE(0, 181, lnsim)\nE(0, 182, gnsim)\nE(0, 183, nleqq)\nE(0, 184, ngeqq)\nE(0, 185, precneqq)\nE(0, 186, succneqq)\nE(0, 187, precnapprox)\nE(0, 188, succnapprox)\nE(0, 189, lnapprox)\nE(0, 190, gnapprox)\nE(0, 191, nsim)\nE(0, 192, ncong)\nE(0, 193, diagup)\nE(0, 194, diagdown)\nE(0, 195, varsubsetneq)\nE(0, 196, backepsilon)\nE(9, 33, leftrightsquigarrow)\nE(9, 34, looparrowleft)\nE(9, 35, looparrowright)\nE(9, 36, circeq)\nE(9, 37, succsim)\nE(9, 38, gtrsim)\nE(9, 39, gtrapprox)\nE(9, 40, multimap)\nE(9, 41, therefore)\nE(9, 42, because)\nE(9, 43, doteqdot)\nE(9, 44, triangleq)\nE(9, 45, precsim)\nE(9, 46, lesssim)\nE(9, 47, lessapprox)\nE(9, 48, eqslantless)\nE(9, 49, eqslantgtr)\nE(9, 50, curlyeqprec)\nE(9, 51, curlyeqsucc)\nE(9, 52, preccurlyeq)\nE(9, 53, leqq)\nE(9, 54, leqslant)\nE(9, 55, lessgtr)\nE(9, 56, backprime)\nE(9, 58, risingdotseq)\nE(9, 59, fallingdotseq)\nE(9, 60, succcurlyeq)\nE(9, 61, geqq)\nE(9, 62, geqslant)\nE(9, 63, gtrless)\nE(9, 66, vartriangleright)\nE(9, 67, vartriangleleft)\nE(9, 68, trianglerighteq)\nE(9, 69, trianglelefteq)\nE(9, 70, bigstar)\nE(9, 71, between)\nE(9, 72, blacktriangledown)\nE(9, 73, blacktriangleright)\nE(9, 74, blacktriangleleft)\nE(9, 77, vartriangle)\nE(9, 78, blacktriangle)\nE(9, 79, triangledown)\nE(9, 80, eqcirc)\nE(9, 81, lesseqgtr)\nE(9, 82, gtreqless)\nE(9, 83, lesseqqgtr)\nE(9, 84, gtreqqless)\nE(9, 85, yen)\nE(9, 86, Rrightarrow)\nE(9, 87, Lleftarrow)\nE(9, 88, checkmark)\nE(9, 89, veebar)\nE(9, 90, barwedge)\nE(9, 91, doublebarwedge)\nE(9, 93, measuredangle)\nE(9, 94, sphericalangle)\nE(9, 95, varpropto)\nE(9, 96, smallsmile)\nE(9, 97, smallfrown)\nE(9, 98, Subset)\nE(9, 99, Supset)\nE(9, 100, Cup)\nE(9, 101, Cap)\nE(9, 102, curlywedge)\nE(9, 103, curlyvee)\nE(9, 104, leftthreetimes)\nE(9, 105, rightthreetimes)\nE(9, 106, subseteqq)\nE(9, 107, supseteqq)\nE(9, 108, bumpeq)\nE(9, 109, Bumpeq)\nE(9, 110, lll)\nE(9, 111, ggg)\nE(9, 112, ulcorner)\nE(9, 113, urcorner)\nE(9, 114, textregistered)\nE(9, 115, circledS)\nE(9, 116, pitchfork)\nE(9, 117, dotplus)\nE(9, 118, backsim)\nE(9, 119, backsimeq)\nE(9, 120, llcorner)\nE(9, 121, lrcorner)\nE(9, 122, maltese)\nE(9, 123, complement)\nE(9, 124, intercal)\nE(9, 125, circledcirc)\nE(9, 126, circledast)\nE(9, 161, boxdot)\nE(9, 162, boxplus)\nE(9, 163, boxtimes)\nE(9, 164, square)\nE(9, 165, blacksquare)\nE(9, 166, centerdot)\nE(9, 167, lozenge)\nE(9, 168, blacklozenge)\nE(9, 169, circlearrowright)\nE(9, 170, circlearrowleft)\nE(9, 174, leftrightharpoons)\nE(9, 175, boxminus)\nE(9, 176, Vdash)\nE(9, 177, Vvdash)\nE(9, 178, vDash)\nE(9, 179, twoheadrightarrow)\nE(9, 180, twoheadleftarrow)\nE(9, 181, leftleftarrows)\nE(9, 182, rightrightarrows)\nE(9, 183, upuparrows)\nE(9, 184, downdownarrows)\nE(9, 185, upharpoonright)\nE(9, 186, downharpoonright)\nE(9, 187, upharpoonleft)\nE(9, 188, downharpoonleft)\nE(9, 189, rightarrowtail)\nE(9, 190, leftarrowtail)\nE(9, 191, leftrightarrows)\nE(9, 192, rightleftarrows)\nE(9, 193, Lsh)\nE(9, 194, Rsh)\nE(9, 195, rightsquigarrow)\nE(9, 196, circleddash)\n\nEND_DEF_SYMBOLS\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/sym/base.def.cpp",
    "content": "#include \"res/symbol_def.res.h\"\n\nDEF_SYMBOLS(base)\n\nE(1, 58, lgroup)\nE(1, 59, rgroup)\nE(1, 62, bracevert)\nE(1, 70, bigsqcup)\nE(1, 72, oint)\nE(1, 74, bigodot)\nE(1, 76, bigoplus)\nE(1, 78, bigotimes)\nE(1, 80, sum)\nE(1, 81, prod)\nE(1, 82, int)\nE(1, 83, bigcup)\nE(1, 84, bigcap)\nE(1, 85, biguplus)\nE(1, 86, bigwedge)\nE(1, 87, bigvee)\nE(1, 96, coprod)\nE(1, 98, widehat)\nE(1, 101, widetilde)\nE(2, 161, varGamma)\nE(2, 162, varDelta)\nE(2, 163, varTheta)\nE(2, 164, varLambda)\nE(2, 165, varXi)\nE(2, 166, varPi)\nE(2, 167, varSigma)\nE(2, 168, varUpsilon)\nE(2, 169, varPhi)\nE(2, 170, varPsi)\nE(2, 171, varOmega)\nE(4, 64, lmoustache)\nE(4, 65, rmoustache)\nE(5, 33, omega)\nE(5, 34, varepsilon)\nE(5, 35, vartheta)\nE(5, 36, varpi)\nE(5, 37, varrho)\nE(5, 38, varsigma)\nE(5, 39, varphi)\nE(5, 40, leftharpoonup)\nE(5, 41, leftharpoondown)\nE(5, 42, rightharpoonup)\nE(5, 43, rightharpoondown)\nE(5, 44, lhook)\nE(5, 45, rhook)\nE(5, 46, triangleright)\nE(5, 47, triangleleft)\nE(5, 58, ldotp)\nE(5, 58, normaldot)\nE(5, 58, textnormaldot)\nE(5, 59, comma)\nE(5, 60, lt)\nE(5, 61, slash)\nE(5, 62, gt)\nE(5, 63, star)\nE(5, 64, partial)\nE(5, 91, flat)\nE(5, 92, natural)\nE(5, 93, sharp)\nE(5, 94, smile)\nE(5, 95, frown)\nE(5, 96, ell)\nE(5, 111, omicron)\nE(5, 123, imath)\nE(5, 124, jmath)\nE(5, 125, wp)\nE(5, 126, vec)\nE(5, 174, alpha)\nE(5, 175, beta)\nE(5, 176, gamma)\nE(5, 177, delta)\nE(5, 178, epsilon)\nE(5, 179, zeta)\nE(5, 180, eta)\nE(5, 181, theta)\nE(5, 182, iota)\nE(5, 183, kappa)\nE(5, 184, lambda)\nE(5, 185, mu)\nE(5, 186, nu)\nE(5, 187, xi)\nE(5, 188, pi)\nE(5, 189, rho)\nE(5, 190, sigma)\nE(5, 191, tau)\nE(5, 192, upsilon)\nE(5, 193, phi)\nE(5, 194, chi)\nE(5, 195, psi)\nE(5, 196, tie)\nE(8, 33, rightarrow)\nE(8, 33, to)\nE(8, 34, uparrow)\nE(8, 35, downarrow)\nE(8, 36, leftrightarrow)\nE(8, 37, nearrow)\nE(8, 38, searrow)\nE(8, 39, simeq)\nE(8, 40, Leftarrow)\nE(8, 41, Rightarrow)\nE(8, 42, Uparrow)\nE(8, 43, Downarrow)\nE(8, 44, Leftrightarrow)\nE(8, 45, nwarrow)\nE(8, 46, swarrow)\nE(8, 47, propto)\nE(8, 48, prime)\nE(8, 49, infty)\nE(8, 50, in)\nE(8, 51, ni)\nE(8, 51, owns)\nE(8, 52, triangle)\nE(8, 54, not)\nE(8, 55, mapstochar)\nE(8, 56, forall)\nE(8, 57, exists)\nE(8, 58, neg)\nE(8, 58, lnot)\nE(8, 59, emptyset)\nE(8, 60, Re)\nE(8, 61, Im)\nE(8, 62, top)\nE(8, 63, bot)\nE(8, 63, perp)\nE(8, 64, aleph)\nE(8, 91, cup)\nE(8, 92, cap)\nE(8, 93, uplus)\nE(8, 94, wedge)\nE(8, 94, land)\nE(8, 95, vee)\nE(8, 95, lor)\nE(8, 96, vdash)\nE(8, 97, dashv)\nE(8, 98, lfloor)\nE(8, 99, rfloor)\nE(8, 100, lceil)\nE(8, 101, rceil)\nE(8, 102, lbrace)\nE(8, 102, lacc)\nE(8, 103, rbrace)\nE(8, 103, racc)\nE(8, 104, langle)\nE(8, 105, rangle)\nE(8, 106, vert)\nE(8, 106, mid)\nE(8, 107, Vert)\nE(8, 107, |)\nE(8, 107, parallel)\nE(8, 108, updownarrow)\nE(8, 109, Updownarrow)\nE(8, 110, backslash)\nE(8, 110, setminus)\nE(8, 111, wr)\nE(8, 112, sqrt)\nE(8, 112, surdsign)\nE(8, 113, amalg)\nE(8, 114, nabla)\nE(8, 115, smallint)\nE(8, 116, sqcup)\nE(8, 117, sqcap)\nE(8, 118, sqsubseteq)\nE(8, 119, sqsupseteq)\nE(8, 120, S)\nE(8, 121, dagger)\nE(8, 122, ddagger)\nE(8, 123, P)\nE(8, 124, clubsuit)\nE(8, 125, diamondsuit)\nE(8, 126, heartsuit)\nE(8, 161, minus)\nE(8, 162, cdotp)\nE(8, 162, cdot)\nE(8, 163, times)\nE(8, 164, ast)\nE(8, 165, div)\nE(8, 166, diamond)\nE(8, 167, pm)\nE(8, 168, mp)\nE(8, 169, oplus)\nE(8, 170, ominus)\nE(8, 171, otimes)\nE(8, 174, oslash)\nE(8, 175, odot)\nE(8, 176, bigcirc)\nE(8, 177, circ)\nE(8, 178, bullet)\nE(8, 179, asymp)\nE(8, 180, equiv)\nE(8, 181, subseteq)\nE(8, 182, supseteq)\nE(8, 183, leq)\nE(8, 183, le)\nE(8, 184, geq)\nE(8, 184, ge)\nE(8, 185, preceq)\nE(8, 186, succeq)\nE(8, 187, sim)\nE(8, 188, approx)\nE(8, 189, subset)\nE(8, 190, supset)\nE(8, 191, ll)\nE(8, 192, gg)\nE(8, 193, prec)\nE(8, 194, succ)\nE(8, 195, leftarrow)\nE(8, 195, gets)\nE(8, 196, spadesuit)\nE(15, 39, rq)\nE(15, 96, lq)\nE(15, 179, i)\nE(15, 180, j)\nE(15, 187, mathcedilla)\nE(15, 188, ss)\nE(15, 189, ae)\nE(15, 190, oe)\nE(15, 191, o)\nE(15, 192, AE)\nE(15, 193, OE)\nE(15, 194, O)\nE(16, 36, mathsterling)\nE(18, 33, faculty)\nE(18, 35, mathsharp)\nE(18, 36, textdollar)\nE(18, 37, textpercent)\nE(18, 38, textampersand)\nE(18, 39, textapos)\nE(18, 40, lbrack)\nE(18, 41, rbrack)\nE(18, 43, plus)\nE(18, 45, textminus)\nE(18, 47, textfractionsolidus)\nE(18, 47, slashdel)\nE(18, 58, colon)\nE(18, 59, semicolon)\nE(18, 61, Relbar)\nE(18, 61, equals)\nE(18, 62, questiondown)\nE(18, 63, question)\nE(18, 64, matharobase)\nE(18, 91, lsqbrack)\nE(18, 93, rsqbrack)\nE(18, 94, hat)\nE(18, 95, dot)\nE(18, 96, mathlapos)\nE(18, 123, textendash)\nE(18, 124, textemdash)\nE(18, 125, doubleacute)\nE(18, 126, tilde)\nE(18, 161, Gamma)\nE(18, 162, Delta)\nE(18, 163, Theta)\nE(18, 164, Lambda)\nE(18, 165, Xi)\nE(18, 166, Pi)\nE(18, 167, Sigma)\nE(18, 168, Upsilon)\nE(18, 169, Phi)\nE(18, 170, Psi)\nE(18, 171, Omega)\nE(18, 181, grave)\nE(18, 182, acute)\nE(18, 183, check)\nE(18, 184, breve)\nE(18, 185, bar)\nE(18, 186, mathring)\nE(18, 186, bmathring)\nE(18, 195, polishlcross)\nE(18, 196, ddot)\nE(18, 197, ogonek)\nE(25, 37, textperthousand)\nE(25, 38, textpertenthousand)\nE(26, 126, textdbend)\nE(26, 127, dbend)\nE(29, 33, guillemotleft)\nE(29, 33, og)\nE(29, 34, guilsinglleft)\nE(29, 35, guilsinglright)\nE(29, 36, guillemotright)\nE(29, 36, fg)\n\nEND_DEF_SYMBOLS\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/sym/special.def.cpp",
    "content": "#include \"res/symbol_def.res.h\"\n\nDEF_SYMBOLS(special)\n\nE(8, 197, varparallel)\nE(8, 198, nvarparallel)\nE(8, 199, varparalleleq)\nE(24, 65, android)\nE(24, 66, dT)\nE(24, 67, dE)\nE(24, 68, dX)\nE(24, 69, euro)\nE(24, 70, parallelogram)\nE(24, 101, texteuro)\nE(24, 109, textmu)\n\nEND_DEF_SYMBOLS\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/sym/stmaryrd.def.cpp",
    "content": "#include \"res/symbol_def.res.h\"\n\nDEF_SYMBOLS(stmaryrd)\n\nE(7, 32, shortleftarrow)\nE(7, 33, shortrightarrow)\nE(7, 34, shortuparrow)\nE(7, 35, shortdownarrow)\nE(7, 36, Yup)\nE(7, 37, Ydown)\nE(7, 38, Yleft)\nE(7, 39, Yright)\nE(7, 40, varcurlyvee)\nE(7, 41, varcurlywedge)\nE(7, 42, minuso)\nE(7, 43, baro)\nE(7, 44, sslash)\nE(7, 45, bbslash)\nE(7, 46, moo)\nE(7, 47, varotimes)\nE(7, 48, varoast)\nE(7, 49, varobar)\nE(7, 50, varodot)\nE(7, 51, varoslash)\nE(7, 52, varobslash)\nE(7, 53, varocircle)\nE(7, 54, varoplus)\nE(7, 55, varominus)\nE(7, 56, boxast)\nE(7, 57, boxbar)\nE(7, 58, boxdot)\nE(7, 59, boxslash)\nE(7, 60, boxbslash)\nE(7, 61, boxcircle)\nE(7, 62, boxbox)\nE(7, 63, boxempty)\nE(7, 64, lightning)\nE(7, 65, merge)\nE(7, 66, vartimes)\nE(7, 67, fatsemi)\nE(7, 68, sswarrow)\nE(7, 69, ssearrow)\nE(7, 70, curlywedgeuparrow)\nE(7, 71, curlywedgedownarrow)\nE(7, 72, fatslash)\nE(7, 73, fatbslash)\nE(7, 74, lbag)\nE(7, 75, rbag)\nE(7, 76, varbigcirc)\nE(7, 77, leftrightarroweq)\nE(7, 78, curlyveedownarrow)\nE(7, 79, curlyveeuparrow)\nE(7, 80, nnwarrow)\nE(7, 81, nnearrow)\nE(7, 82, leftslice)\nE(7, 83, rightslice)\nE(7, 84, varolessthan)\nE(7, 85, varogreaterthan)\nE(7, 86, varovee)\nE(7, 87, varowedge)\nE(7, 88, talloblong)\nE(7, 89, interleave)\nE(7, 90, obar)\nE(7, 91, obslash)\nE(7, 92, olessthan)\nE(7, 93, ogreaterthan)\nE(7, 94, ovee)\nE(7, 95, owedge)\nE(7, 96, oblong)\nE(7, 97, inplus)\nE(7, 98, niplus)\nE(7, 99, nplus)\nE(7, 100, subsetplus)\nE(7, 101, supsetplus)\nE(7, 102, subsetpluseq)\nE(7, 103, supsetpluseq)\nE(7, 104, Lbag)\nE(7, 105, Rbag)\nE(7, 106, llbracket)\nE(7, 107, rrbracket)\nE(7, 108, llparenthesis)\nE(7, 109, rrparenthesis)\nE(7, 110, binampersand)\nE(7, 111, bindnasrepma)\nE(7, 112, trianglelefteqslant)\nE(7, 113, trianglerighteqslant)\nE(7, 114, ntrianglelefteqslant)\nE(7, 115, ntrianglerighteqslant)\nE(7, 116, llfloor)\nE(7, 117, rrfloor)\nE(7, 118, llceil)\nE(7, 119, rrceil)\nE(7, 120, arrownot)\nE(7, 121, Arrownot)\nE(7, 122, Mapstochar)\nE(7, 123, mapsfromchar)\nE(7, 124, Mapsfromchar)\nE(7, 125, leftrightarrowtriangle)\nE(7, 126, leftarrowtriangle)\nE(7, 127, rightarrowtriangle)\nE(7, 128, bigtriangledown)\nE(7, 129, bigtriangleup)\nE(7, 130, bigcurlyvee)\nE(7, 131, bigcurlywedge)\nE(7, 132, bigsqcap)\nE(7, 133, bigbox)\nE(7, 134, bigparallel)\nE(7, 135, biginterleave)\nE(7, 136, bignplus)\n\nEND_DEF_SYMBOLS\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/res/symbol_def.res.h",
    "content": "#ifndef SYMBOL_DEF_H_INCLUDED\n#define SYMBOL_DEF_H_INCLUDED\n\n#include \"fonts/fonts.h\"\n#include \"fonts/symbol_reg.h\"\n\n#define __len(x) ((int)(sizeof(x) / sizeof((x)[0])))\n\n#define DEF_SYMBOLS(name)        \\\n    void __symbols_reg(name)() { \\\n        const __symbol_component x[] = {\n#define END_DEF_SYMBOLS                          \\\n    }                                            \\\n    ;                                            \\\n    DefaultTeXFont::__push_symbols(x, __len(x)); \\\n    }\n\n/**\n * Define a symbol mapping.\n * \n * Consists of 3 component:\n * \n *      [font-id, code, symbol-name]\n */\n#define E(fontId, code, name) \\\n    {fontId, code, #name},\n\n#endif\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/samples/gtkmm_main.cpp",
    "content": "#include \"config.h\"\n\n#if defined(__OS_Linux__) && !defined(MEM_CHECK)\n\n#include \"latex.h\"\n#include \"platform/cairo/graphic_cairo.h\"\n#include \"samples.h\"\n\n#include <gdkmm/rgba.h>\n#include <gtkmm/adjustment.h>\n#include <gtkmm/application.h>\n#include <gtkmm/box.h>\n#include <gtkmm/button.h>\n#include <gtkmm/drawingarea.h>\n#include <gtkmm/filechooserdialog.h>\n#include <gtkmm/paned.h>\n#include <gtkmm/scrolledwindow.h>\n#include <gtkmm/spinbutton.h>\n#include <gtkmm/window.h>\n\n#include <gtksourceviewmm/init.h>\n#include <gtksourceviewmm/languagemanager.h>\n#include <gtksourceviewmm/view.h>\n\n#include <pangomm/init.h>\n\nusing namespace tex;\n\nclass TeXDrawingArea : public Gtk::DrawingArea {\nprivate:\n    TeXRender* _render;\n    float _text_size;\n    int _padding;\n\n    void checkInvalidate() {\n        if (_render == nullptr) return;\n\n        int parent_width = get_parent()->get_width();\n        int parent_height = get_parent()->get_height();\n        int target_width = parent_width;\n        int target_height = parent_height;\n\n        int extra = (int)(_padding * 2);\n        if (parent_width < _render->getWidth() + extra) {\n            target_width = _render->getWidth() + extra;\n        }\n        if (parent_height < _render->getHeight() + extra) {\n            target_height = _render->getHeight() + extra;\n        }\n\n        set_size_request(target_width, target_height);\n\n        auto win = get_window();\n        if (win) {\n            auto al = get_allocation();\n            Gdk::Rectangle r(0, 0, al.get_width(), al.get_height());\n            win->invalidate_rect(r, false);\n        }\n    }\n\npublic:\n    TeXDrawingArea() : _render(nullptr), _text_size(20.f), _padding(10) {\n        override_background_color(Gdk::RGBA(\"White\"));\n    }\n\n    float getTextSize() {\n        return _text_size;\n    }\n\n    void setTextSize(float size) {\n        if (size == _text_size) return;\n        _text_size = size;\n        if (_render != nullptr) {\n            _render->setTextSize(_text_size);\n            checkInvalidate();\n        }\n    }\n\n    void setLaTeX(const wstring& latex) {\n        if (_render != nullptr) delete _render;\n\n        _render = LaTeX::parse(\n            latex,\n            get_allocated_width() - _padding * 2,\n            _text_size,\n            _text_size / 3.f,\n            0xff424242);\n\n        checkInvalidate();\n    }\n\n    bool isRenderDisplayed() {\n        return _render != nullptr;\n    }\n\n    int getRenderWidth() {\n        return _render == nullptr ? 0 : _render->getWidth() + _padding * 2;\n    }\n\n    int getRenderHeight() {\n        return _render == nullptr ? 0 : _render->getHeight() + _padding * 2;\n    }\n\n    void drawInContext(const Cairo::RefPtr<Cairo::Context>& cr) {\n        if (_render == nullptr) return;\n        Graphics2D_cairo g2(cr);\n        _render->draw(g2, _padding, _padding);\n    }\n\n    virtual ~TeXDrawingArea() {\n        if (_render != nullptr) delete _render;\n    }\n\nprotected:\n    bool on_draw(const Cairo::RefPtr<Cairo::Context>& cr) override {\n        if (_render == nullptr) return true;\n        Graphics2D_cairo g2(cr);\n        _render->draw(g2, _padding, _padding);\n        return true;\n    }\n};\n\nclass MainWindow : public Gtk::Window {\nprotected:\n    Gsv::View _tex_editor;\n    Gtk::SpinButton _size_spin;\n    TeXDrawingArea _tex;\n\n    Gtk::Label _size_change_info;\n    Gtk::Button _next, _rendering, _save;\n\n    Gtk::ScrolledWindow _text_scroller, _drawing_scroller;\n    Gtk::Box _side_box, _bottom_box;\n    Gtk::Paned _main_box;\n\n    Samples _samples;\n\npublic:\n    MainWindow()\n        : _size_change_info(\"change text size: \"),\n          _next(\"Next Example\"),\n          _rendering(\"Rendering\"),\n          _save(\"Save as SVG\"),\n          _side_box(Gtk::ORIENTATION_VERTICAL),\n          _samples() {\n        // init before use\n        Gsv::init();\n\n        set_border_width(10);\n        set_size_request(1220, 640);\n\n        _drawing_scroller.set_size_request(720);\n        _drawing_scroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);\n        _drawing_scroller.add(_tex);\n\n        auto lang = Gsv::LanguageManager::get_default()->get_language(\"latex\");\n        auto buffer = Gsv::Buffer::create(lang);\n        buffer->set_highlight_syntax(true);\n        _tex_editor.set_source_buffer(buffer);\n        _tex_editor.set_show_line_numbers(true);\n        _tex_editor.set_highlight_current_line(true);\n        _tex_editor.set_tab_width(4);\n        _tex_editor.override_font(Pango::FontDescription(\"Monospace 12\"));\n        _tex_editor.signal_key_press_event().connect(\n            sigc::mem_fun(*this, &MainWindow::on_text_key_press), false);\n        _tex_editor.set_border_width(5);\n\n        _text_scroller.set_size_request(480);\n        _text_scroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);\n        _text_scroller.add(_tex_editor);\n\n        Glib::RefPtr<Gtk::Adjustment> adj = Gtk::Adjustment::create(_tex.getTextSize(), 1, 300);\n        adj->signal_value_changed().connect(\n            sigc::mem_fun(*this, &MainWindow::on_text_size_changed));\n        _size_spin.set_adjustment(adj);\n        _next.signal_clicked().connect(\n            sigc::mem_fun(*this, &MainWindow::on_next_clicked));\n        _rendering.signal_clicked().connect(\n            sigc::mem_fun(*this, &MainWindow::on_rendering_clicked));\n        _save.signal_clicked().connect(\n            sigc::mem_fun(*this, &MainWindow::on_save_clicked));\n        _save.set_sensitive(_tex.isRenderDisplayed());\n\n        _bottom_box.set_spacing(10);\n        _bottom_box.pack_start(_size_change_info, Gtk::PACK_SHRINK);\n        _bottom_box.pack_start(_size_spin);\n        _bottom_box.pack_start(_next, Gtk::PACK_SHRINK);\n        _bottom_box.pack_start(_rendering, Gtk::PACK_SHRINK);\n        _bottom_box.pack_start(_save, Gtk::PACK_SHRINK);\n\n        _side_box.set_spacing(5);\n        _side_box.set_size_request(480);\n        _side_box.pack_start(_text_scroller);\n        _side_box.pack_start(_bottom_box, Gtk::PACK_SHRINK);\n\n        _main_box.pack1(_drawing_scroller, true, false);\n        _main_box.pack2(_side_box, true, false);\n\n        add(_main_box);\n\n        show_all_children();\n    }\n\n    ~MainWindow() {}\n\nprotected:\n    void on_next_clicked() {\n        auto sample = _samples.next();\n        string x;\n        wide2utf8(sample.c_str(), x);\n        _tex_editor.get_buffer()->set_text(x);\n        _tex.setLaTeX(sample);\n        _save.set_sensitive(_tex.isRenderDisplayed());\n    }\n\n    void on_save_clicked() {\n        Gtk::FileChooserDialog dialog(*this, \"Save as SVG\", Gtk::FILE_CHOOSER_ACTION_SAVE);\n        dialog.add_button(\"Cancel\", Gtk::RESPONSE_CANCEL);\n        dialog.add_button(\"Confirm\", Gtk::RESPONSE_OK);\n        int result = dialog.run();\n        if (result == Gtk::RESPONSE_OK) {\n            auto file = dialog.get_filename();\n            auto surface = Cairo::SvgSurface::create(\n                file,\n                _tex.getRenderWidth(),\n                _tex.getRenderHeight());\n            auto context = Cairo::Context::create(surface);\n            _tex.drawInContext(context);\n        }\n    }\n\n    void on_rendering_clicked() {\n        wstring x;\n        utf82wide(_tex_editor.get_buffer()->get_text().c_str(), x);\n        _tex.setLaTeX(x);\n        _save.set_sensitive(_tex.isRenderDisplayed());\n    }\n\n    void on_text_size_changed() {\n        float size = _size_spin.get_adjustment()->get_value();\n        _tex.setTextSize(size);\n    }\n\n    bool on_text_key_press(GdkEventKey* e) {\n        if (e->keyval == GDK_KEY_Return && e->state & GDK_CONTROL_MASK) {\n            on_rendering_clicked();\n            return true;\n        }\n        return false;\n    }\n};\n\nclass Headless {\npublic:\n    string _outputDir;\n    string _samplesFile;\n    string _prefix;\n\n    string _input;\n    string _outputFile;\n\n    float _textSize = 20.f;\n    color _foreground = BLACK;\n    color _background = TRANS;\n    float _padding = 10.f;\n    float _maxWidth = 720.f;\n\n    void generateSingle(const wstring& code, const string& file) {\n        auto r = LaTeX::parse(code, _maxWidth, _textSize, _textSize / 3.f, _foreground);\n        const float w = r->getWidth() + _padding * 2;\n        const float h = r->getHeight() + _padding * 2;\n        auto surface = Cairo::SvgSurface::create(file, w, h);\n        auto context = Cairo::Context::create(surface);\n        Graphics2D_cairo g2(context);\n        if (!istrans(_background)) {\n            g2.setColor(_background);\n            g2.fillRect(0, 0, w, h);\n        }\n        r->draw(g2, _padding, _padding);\n        delete r;\n    }\n\n    int runBatch() {\n        if (_outputDir.empty()) {\n            __print(ANSI_COLOR_RED \"Error: the option '-outputdir' must be specified\\n\" ANSI_RESET);\n            return 1;\n        }\n        Samples samples(_samplesFile);\n        if (samples.count() == 0) return 1;\n        for (int i = 0; i < samples.count(); i++) {\n            generateSingle(samples.next(), _outputDir + \"/\" + _prefix + tostring(i) + \".svg\");\n        }\n        return 0;\n    }\n\n    int runSingle() {\n        if (_outputFile.empty()) {\n            __print(ANSI_COLOR_RED \"Error: the option '-output' must be specified\\n\" ANSI_RESET);\n            return 1;\n        }\n        wstring code;\n        utf82wide(_input.c_str(), code);\n        generateSingle(code, _outputFile);\n        return 0;\n    }\n\n    int run() {\n        if (_textSize <= 0.f) _textSize = 20.f;\n        if (istrans(_foreground)) _foreground = BLACK;\n        if (_maxWidth <= 0.f) _maxWidth = 720.f;\n        if (!_input.empty()) return runSingle();\n        return runBatch();\n    }\n};\n\n#include \"atom/atom_basic.h\"\n\nint runHeadless(const vector<string>& opts) {\n    Headless h;\n    for (size_t i = 0; i < opts.size(); i++) {\n        auto x = opts[i];\n        if (startswith(x, \"-outputdir\")) {\n            h._outputDir = x.substr(x.find(\"=\") + 1);\n        } else if (startswith(x, \"-samples\")) {\n            h._samplesFile = x.substr(x.find(\"=\") + 1);\n        } else if (startswith(x, \"-prefix\")) {\n            h._prefix = x.substr(x.find(\"=\") + 1);\n        } else if (startswith(x, \"-textsize\")) {\n            auto str = x.substr(x.find(\"=\") + 1);\n            valueof(str, h._textSize);\n        } else if (startswith(x, \"-foreground\")) {\n            auto str = x.substr(x.find(\"=\") + 1);\n            h._foreground = tex::ColorAtom::getColor(str);\n        } else if (startswith(x, \"-background\")) {\n            auto str = x.substr(x.find(\"=\") + 1);\n            h._background = tex::ColorAtom::getColor(str);\n        } else if (startswith(x, \"-input\")) {\n            h._input = x.substr(x.find(\"=\") + 1);\n        } else if (startswith(x, \"-output\")) {\n            h._outputFile = x.substr(x.find(\"=\") + 1);\n        } else if (startswith(x, \"-padding\")) {\n            auto str = x.substr(x.find(\"=\") + 1);\n            valueof(str, h._padding);\n        } else if (startswith(x, \"-maxwidth\")) {\n            auto str = x.substr(x.find(\"=\") + 1);\n            valueof(str, h._maxWidth);\n        }\n    }\n\n    return h.run();\n}\n\nint runWindow(int argc, char* argv[]) {\n    auto app = Gtk::Application::create(argc, argv, \"io.nano.LaTeX\");\n    MainWindow win;\n    int result = app->run(win);\n    return result;\n}\n\nint runHelp() {\n#define B ANSI_BOLD\n#define R ANSI_RESET\n    const char* msg =\n        \"Application to parse and display LaTeX code. The application will run with the headless \"\n        \"mode if the option '-headless' has given, otherwise, it will run with the GUI mode.\\n\\n\" B\n        \"NOTICE\\n\" R\n        \"  If both '-outputdir' and '-input' are specified, the '-input' option wins.\\n\\n\" B\n        \"COMMON OPTIONS\\n\\n\"\n        \"  -h\\n\" R\n        \"      show usages and exit\\n\\n\" B\n        \"  -headless\\n\" R\n        \"      run the application with the headless mode (no GUI), \"\n        \"that converts the input LaTeX code into SVG file\\n\\n\" B\n        \"  -textsize=[VALUE]\\n\" R\n        \"      a float value to config the text size (in point) to display formulas, \"\n        \"the default is 20\\n\\n\" B\n        \"  -foreground=[COLOR]\\n\" R\n        \"      config the foreground color to display formulas; \"\n        \"the value can be a color name or in the form of #AARRGGBB; default is black\\n\\n\" B\n        \"  -background=[COLOR]\\n\" R\n        \"      config the background color to display formulas; \"\n        \"the value can be a color name or in the form of #AARRGGBB; default is transparent\\n\\n\" B\n        \"  -padding=[VALUE]\\n\" R\n        \"      a float value to config spaces (in pixel) to add to the SVG images, \"\n        \"the default is 10\\n\\n\" B\n        \"  -maxwidth=[VALUE]\\n\" R\n        \"      config the max width of the graphics context, the default is 720 pixels; \"\n        \"this option has weak limits on the SVG images, thus the width of the SVG image may be \"\n        \"wider than the value defined by this option\\n\\n\" B\n        \"BATCH MODE\\n\" R\n        \"The application will save the SVG images produced by the LaTeX codes that parsed \"\n        \"from the given file (specified by the option '-samples') into the directory specified \"\n        \"by the option '-outputdir'.\\n\\n\" B\n        \"  -outputdir=[WHERE]\\n\" R\n        \"      indicates the directory to save the SVG images\\n\\n\" B\n        \"  -samples=[FILE]\\n\" R\n        \"      specifies the file that contains various LaTeX codes split by a line that consists \"\n        \"of the character '\\%' only, the default is './res/SAMPLES.tex'\\n\\n\" B\n        \"  -prefix=[VALUE]\\n\" R\n        \"      specifies the prefix of the filename of the SVG images, the default is ''; \"\n        \"for example, if 2 pieces of code has given with the option '-prefix=a_', \"\n        \"the filename of the SVG images will be 'a_0.svg' and 'a_1.svg'\\n\\n\" B\n        \"SINGLE MODE\\n\\n\"\n        \"  -input=[CODE]\\n\" R\n        \"      the source code that is written in LaTeX\\n\\n\" B\n        \"  -output=[FILE]\\n\" R\n        \"      indicates where to save the produced SVG image, only works if the option \"\n        \"'-input' has given\\n\\n\";\n    __print(\"%s\", msg);\n    return 0;\n}\n\nint main(int argc, char* argv[]) {\n    vector<string> opts;\n    for (int i = 0; i < argc; i++) opts.push_back(argv[i]);\n\n    if (indexOf(opts, string(\"-h\")) >= 0) return runHelp();\n\n    Pango::init();\n    LaTeX::init();\n\n    int result = 0;\n    if (indexOf(opts, string(\"-headless\")) >= 0) {\n        result = runHeadless(opts);\n    } else {\n        result = runWindow(argc, argv);\n    }\n\n    LaTeX::release();\n    return result;\n}\n\n#endif\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/samples/mem_check_main.cpp",
    "content": "#include \"config.h\"\n\n#ifdef MEM_CHECK\n\n#include \"graphic/graphic.h\"\n#include \"latex.h\"\n\nnamespace tex {\n\nclass Font_none : public Font {\npublic:\n    Font_none() {}\n\n    float getSize() const override {\n        return 1.f;\n    }\n\n    sptr<Font> deriveFont(int style) const override {\n        return sptr<Font>(new Font_none());\n    }\n\n    bool operator==(const Font& f) const override {\n        return false;\n    }\n\n    bool operator!=(const Font& f) const override {\n        return !(*this == f);\n    }\n};\n\nFont* Font::create(const string& file, float size) {\n    return new Font_none();\n}\n\nsptr<Font> Font::_create(const string& name, int style, float size) {\n    return sptr<Font>(new Font_none());\n}\n\n/**************************************************************************************************/\n\nclass TextLayout_none : public TextLayout {\npublic:\n    TextLayout_none() {}\n\n    void getBounds(_out_ Rect& bounds) override {\n        bounds.x = bounds.y = bounds.w = bounds.h = 0.f;\n    }\n\n    void draw(Graphics2D& g2, float x, float y) override {\n    }\n};\n\nsptr<TextLayout> TextLayout::create(const wstring& src, const sptr<Font>& font) {\n    return sptr<TextLayout>(new TextLayout_none());\n}\n\n/**************************************************************************************************/\n\nclass Graphics2D_none : public Graphics2D {\nprivate:\n    static Font* _default_font;\n    const Font* _font;\n    Stroke _stroke;\n\npublic:\n    Graphics2D_none() : _font(_default_font), _stroke() {}\n\n    static void release() {\n        delete _default_font;\n    }\n\n    void setColor(color c) override {\n    }\n\n    color getColor() const override {\n        return 0;\n    }\n\n    void setStroke(const Stroke& s) override {\n        _stroke = s;\n    }\n\n    const Stroke& getStroke() const override {\n        return _stroke;\n    }\n\n    void setStrokeWidth(float w) override {\n    }\n\n    const Font* getFont() const override {\n        return _font;\n    }\n\n    void setFont(const Font* font) override {\n        _font = font;\n    }\n\n    void translate(float dx, float dy) override {\n    }\n\n    void scale(float sx, float sy) override {\n    }\n\n    void rotate(float angle) override {\n    }\n\n    void rotate(float angle, float px, float py) override {\n    }\n\n    void reset() override {\n    }\n\n    float sx() const override {\n        return 1.f;\n    }\n\n    float sy() const override {\n        return 1.f;\n    }\n\n    void drawChar(wchar_t c, float x, float y) override {\n    }\n\n    void drawText(const wstring& c, float x, float y) override {\n    }\n\n    void drawLine(float x1, float y1, float x2, float y2) override {\n    }\n\n    void drawRect(float x, float y, float w, float h) override {\n    }\n\n    void fillRect(float x, float y, float w, float h) override {\n    }\n\n    void drawRoundRect(float x, float y, float w, float h, float rx, float ry) override {\n    }\n\n    void fillRoundRect(float x, float y, float w, float h, float rx, float ry) override {\n    }\n};\n\nFont* Graphics2D_none::_default_font = new Font_none();\n\n}  // namespace tex\n\n#include \"samples/samples.h\"\n\nint main(int argc, char* argv[]) {\n    LaTeX::init();\n\n    tex::Samples samples;\n    for (int i = 0; i < samples.count(); i++) {\n        auto r = LaTeX::parse(samples.next(), 720, 20, 20 / 3.f, black);\n        Graphics2D_none g2;\n        r->draw(g2, 0, 0);\n        delete r;\n    }\n\n    LaTeX::release();\n    Graphics2D_none::release();\n    return 0;\n}\n\n#endif  // MEM_CHECK\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/samples/samples.h",
    "content": "#include \"config.h\"\n\n#ifdef __USE_SAMPLES\n\n#ifndef SAMPLES_H_INCLUDED\n#define SAMPLES_H_INCLUDED\n\n#include <algorithm>\n#include <fstream>\n#include \"latex.h\"\n\nnamespace tex {\n\nclass Samples {\nprivate:\n    int _index;\n    vector<wstring> _samples;\n\n    void readSamples(const string& file = \"\") {\n        string path = file;\n        if (path.empty()) path = LaTeX::getResRootPath() + \"/SAMPLES.tex\";\n        string line = \"\";\n        string sample = \"\";\n        std::ifstream f(path);\n        if (f.is_open()) {\n            while (getline(f, line)) {\n                if (!line.empty() &&\n                    !isSpace(line) &&\n                    std::all_of(line.begin(), line.end(), [](char c) { return c == '%'; })) {\n                    add(sample);\n                    sample = \"\";\n                } else {\n                    if (!line.empty() && !isSpace(line)) sample += line + \"\\n\";\n                }\n            }\n            f.close();\n        }\n        add(sample);\n    }\n\n    void add(const string& str) {\n        if (str.empty()) return;\n        if (isSpace(str)) return;\n        _samples.push_back(utf82wide(str.c_str()));\n    }\n\n    bool isSpace(const string& str) {\n        return std::all_of(str.begin(), str.end(), [](char c) { return isspace(c); });\n    }\n\npublic:\n    Samples(const string& file = \"\") : _index(0) { readSamples(file); }\n\n    const wstring& next() {\n        if (_index >= _samples.size()) _index = 0;\n        const wstring& x = _samples[_index];\n        _index++;\n        return x;\n    }\n\n    int count() const {\n        return _samples.size();\n    }\n};\n\n}  // namespace tex\n\n#endif  // SAMPLES_H_INCLUDED\n#endif  // __USE_SAMPLES\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/samples/win32_main.cpp",
    "content": "#if defined(__OS_Windows__) && !defined(MEM_CHECK)\n\n#include \"latex.h\"\n#include \"platform/gdi_win/graphic_win32.h\"\n#include \"samples.h\"\n\n#include <time.h>\n#include <cstdlib>\n#include <iostream>\n\n#include <gdiplus.h>\n#include <objidl.h>\n#include <tchar.h>\n#include <windows.h>\n\n#define ID_SETTER 256\n#define ID_CANVAS 512\n#define ID_EDITBOX 1024\n#define ID_BUTTON_SIZE 2048\n#define ID_BUTTON_RANDOM 4096\n\n#define BUTTON_WIDTH 140\n#define BUTTON_HEIGHT 35\n#define EDITOR_WIDTH 480\n\nusing namespace std;\nusing namespace tex;\nusing namespace Gdiplus;\n\nTeXRender* _render = nullptr;\nint _size = 26;\ncolor _color = 0xff424242;\n\nHWND hEditor, hBtnSize, hBtnRandom, hCanvas, hEditSize;\nWNDPROC editorProc, setterProc;\n\nvoid RegisterCanvas();\n\nvoid CreateCtrl(HINSTANCE, HWND);\n\nvoid ResizeCtrl(HWND);\n\nvoid HandleOK();\n\nvoid HandleRandom();\n\nvoid HandleSize();\n\nvoid RenderFormula(HWND, HDC);\n\nvoid init();\n\nLRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);\n\nLRESULT CALLBACK CanvasProc(HWND, UINT, WPARAM, LPARAM);\n\nLRESULT CALLBACK EditorProc(HWND, UINT, WPARAM, LPARAM);\n\nLRESULT CALLBACK SetterProc(HWND, UINT, WPARAM, LPARAM);\n\nINT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, INT iCmdShow) {\n    HWND hWnd;\n    MSG msg;\n    WNDCLASS wndClass;\n    GdiplusStartupInput gdiplusStartupInput;\n    ULONG_PTR gdiplusToken;\n\n    // Initialize GDI+.\n    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);\n    init();\n\n    RegisterCanvas();\n\n    wndClass.style = CS_HREDRAW | CS_VREDRAW;\n    wndClass.lpfnWndProc = WndProc;\n    wndClass.cbClsExtra = 0;\n    wndClass.cbWndExtra = 0;\n    wndClass.hInstance = hInstance;\n    wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);\n    wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);\n    wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);\n    wndClass.lpszMenuName = NULL;\n    wndClass.lpszClassName = TEXT(\"LaTeX\");\n\n    RegisterClass(&wndClass);\n\n    hWnd = CreateWindow(\n        TEXT(\"LaTeX\"),        // window class name\n        TEXT(\"LaTeX\"),        // window caption\n        WS_OVERLAPPEDWINDOW,  // window style\n        0,                    // initial x position\n        0,                    // initial y position\n        780,                  // initial x size\n        480,                  // initial y size\n        NULL,                 // parent window handle\n        NULL,                 // window menu handle\n        hInstance,            // program instance handle\n        NULL);                // creation parameters\n\n    CreateCtrl(hInstance, hWnd);\n    ShowWindow(hWnd, SW_SHOWMAXIMIZED);\n    UpdateWindow(hWnd);\n\n    while (GetMessage(&msg, NULL, 0, 0)) {\n        TranslateMessage(&msg);\n        DispatchMessage(&msg);\n    }\n\n    delete _render;\n    LaTeX::release();\n    GdiplusShutdown(gdiplusToken);\n    return msg.wParam;\n}  // WinMain\n\nLRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {\n    switch (message) {\n    case WM_DESTROY:\n        PostQuitMessage(0);\n        return 0;\n    case WM_COMMAND:\n        if (wParam == ID_BUTTON_SIZE) {\n            HandleSize();\n        } else if (wParam == ID_BUTTON_RANDOM) {\n            HandleRandom();\n        }\n        return 0;\n    case WM_SIZE:\n        ResizeCtrl(hWnd);\n        return 0;\n    default:\n        return DefWindowProc(hWnd, message, wParam, lParam);\n    }\n}  // WndProc\n\nvoid init() {\n    LaTeX::init();\n    _render = LaTeX::parse(L\"\\\\text{What a beautiful day}\", 720, _size, _size / 3.f, _color);\n}\n\nvoid HandleRandom() {\n    srand(time(NULL));\n    int idx = rand() % tex::SAMPLES_COUNT;\n    if (_render != nullptr) {\n        delete _render;\n    }\n    RECT r;\n    GetClientRect(hCanvas, &r);\n    _render = LaTeX::parse(wstring(tex::SAMPLES[idx]), r.right - r.left, _size, _size / 3.f, _color);\n    InvalidateRect(hCanvas, NULL, TRUE);\n    UpdateWindow(hCanvas);\n}\n\nvoid HandleOK() {\n    int len = GetWindowTextLengthW(hEditor);\n    wchar_t* txt = new wchar_t[len + 10];\n    GetWindowTextW(hEditor, txt, len + 10);\n    if (_render != nullptr) {\n        delete _render;\n    }\n    RECT r;\n    GetClientRect(hCanvas, &r);\n    _render = LaTeX::parse(wstring(txt), r.right - r.left, _size, _size / 3.f, _color);\n    InvalidateRect(hCanvas, NULL, TRUE);\n    UpdateWindow(hCanvas);\n    delete[] txt;\n}\n\nvoid HandleSize() {\n    if (_render == nullptr)\n        return;\n    int len = GetWindowTextLength(hEditSize);\n    if (len == 0)\n        return;\n    char* txt = new char[len + 10];\n    GetWindowText(hEditSize, txt, len + 10);\n    string x = txt;\n    valueof(x, _size);\n    _render->setTextSize(_size);\n    InvalidateRect(hCanvas, NULL, TRUE);\n    UpdateWindow(hCanvas);\n    delete[] txt;\n}\n\nvoid RenderFormula(HWND hwnd, HDC hdc) {\n    // draw rectangle\n    RECT r;\n    GetClientRect(hwnd, &r);\n    Graphics g(hdc);\n    Graphics2D_win32 g2(&g);\n    g2.drawRect(r.left, r.top, r.right - r.left - 1, r.bottom - r.top - 1);\n    // draw formula\n    if (_render != nullptr) {\n        _render->draw(g2, 10, 10);\n    }\n}\n\nvoid CreateCtrl(HINSTANCE hInst, HWND hwnd) {\n    // create first, relayout through message WM_SIZE\n    int l = 0, t = 0, w = 10, h = 10;\n    // edit-box\n    hEditor = CreateWindowEx(\n        WS_EX_TOPMOST,\n        \"edit\", NULL,\n        WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE | ES_AUTOVSCROLL,\n        l, t, w, h,\n        hwnd,\n        (HMENU)ID_EDITBOX,\n        hInst, NULL);\n    HFONT hf = CreateFont(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \"Consolas\");\n    SendMessage(hEditor, WM_SETFONT, (WPARAM)hf, 0);\n    SetFocus(hEditor);\n    editorProc = (WNDPROC)SetWindowLongPtr(hEditor, GWLP_WNDPROC, (LONG_PTR)EditorProc);\n    // size setter\n    hEditSize = CreateWindowEx(\n        WS_EX_TOPMOST,\n        \"edit\", NULL,\n        WS_CHILD | WS_VISIBLE | WS_BORDER | ES_CENTER | ES_NUMBER,\n        l, t, w, h,\n        hwnd,\n        (HMENU)ID_SETTER,\n        hInst, NULL);\n    SendMessage(hEditSize, WM_SETFONT, (WPARAM)hf, 0);\n    setterProc = (WNDPROC)SetWindowLongPtr(hEditSize, GWLP_WNDPROC, (LONG_PTR)SetterProc);\n    // button size\n    hBtnSize = CreateWindowEx(\n        WS_EX_TOPMOST,\n        \"Button\", NULL,\n        WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,\n        l, t, w, h,\n        hwnd,\n        (HMENU)ID_BUTTON_SIZE,\n        hInst, NULL);\n    SendMessage(hBtnSize, WM_SETFONT, (WPARAM)hf, 0);\n    SendMessage(hBtnSize, WM_SETTEXT, (WPARAM)NULL, (LPARAM)(\"Set Text Size\"));\n    // button random\n    hBtnRandom = CreateWindowEx(\n        WS_EX_TOPMOST,\n        \"Button\", NULL,\n        WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,\n        l, t, w, h,\n        hwnd,\n        (HMENU)ID_BUTTON_RANDOM,\n        hInst, NULL);\n    SendMessage(hBtnRandom, WM_SETFONT, (WPARAM)hf, 0);\n    SendMessage(hBtnRandom, WM_SETTEXT, (WPARAM)NULL, (LPARAM)(\"Random Example\"));\n    // canvas\n    hCanvas = CreateWindowEx(\n        WS_EX_TOPMOST,\n        \"canvas\", NULL,\n        WS_CHILD | WS_VISIBLE,\n        l, t, w, h,\n        hwnd,\n        (HMENU)ID_CANVAS,\n        hInst, NULL);\n}\n\nvoid ResizeCtrl(HWND hwnd) {\n    RECT r;\n    GetClientRect(hwnd, &r);\n    const int margin = 10;\n    // editor\n    int w = EDITOR_WIDTH, h = BUTTON_HEIGHT;\n    int l = r.right - w - margin, t = r.top + margin;\n    h = r.bottom - t - h - 2 * margin;\n    MoveWindow(hEditor, l, t, w, h, TRUE);\n    // setter\n    w = EDITOR_WIDTH - BUTTON_WIDTH * 2 - margin * 2, h = BUTTON_HEIGHT, t = r.bottom - h - margin;\n    MoveWindow(hEditSize, l, t, w, h, TRUE);\n    // button size\n    w = BUTTON_WIDTH;\n    l = r.right - w * 2 - margin * 2;\n    MoveWindow(hBtnSize, l, t, w, h, TRUE);\n    // button random\n    w = BUTTON_WIDTH;\n    l = r.right - w - margin;\n    MoveWindow(hBtnRandom, l, t, w, h, TRUE);\n    // canvas\n    l = r.left + margin, t = r.top + margin;\n    w = r.right - EDITOR_WIDTH - 2 * margin - l, h = r.bottom - t - margin;\n    MoveWindow(hCanvas, l, t, w, h, TRUE);\n}\n\nvoid RegisterCanvas() {\n    WNDCLASS wnd = {0};\n    wnd.style = CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW;\n    wnd.lpfnWndProc = CanvasProc;\n    wnd.hCursor = LoadCursor(NULL, IDC_ARROW);\n    wnd.lpszClassName = \"canvas\";\n    RegisterClass(&wnd);\n}\n\nLRESULT CALLBACK EditorProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {\n    if (msg == WM_KEYDOWN && wp == VK_RETURN && GetKeyState(VK_CONTROL) < 0) {\n        HandleOK();\n        return 0;\n    }\n    if (msg == WM_CHAR && wp == '\\n' && GetKeyState(VK_CONTROL) < 0) {\n        return 0;\n    }\n    return CallWindowProc(editorProc, hwnd, msg, wp, lp);\n}\n\nLRESULT CALLBACK SetterProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {\n    if (msg == WM_KEYDOWN && wp == VK_RETURN) {\n        HandleSize();\n        return 0;\n    }\n    return CallWindowProc(setterProc, hwnd, msg, wp, lp);\n}\n\nvoid ScrollCanvas(int d) {\n    ScrollWindow(hCanvas, 0, d, NULL, NULL);\n    UpdateWindow(hCanvas);\n}\n\nLRESULT CALLBACK CanvasProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {\n    HDC hdc;\n    PAINTSTRUCT ps;\n\n    switch (message) {\n    case WM_PAINT: {\n        hdc = BeginPaint(hWnd, &ps);\n        RenderFormula(hWnd, hdc);\n        EndPaint(hWnd, &ps);\n        break;\n    }\n    case WM_ERASEBKGND: {\n        hdc = (HDC)wParam;\n        RECT r;\n        GetClientRect(hWnd, &r);\n        FillRect(hdc, &r, (HBRUSH)GetStockObject(WHITE_BRUSH));\n        break;\n    }\n    default:\n        return DefWindowProc(hWnd, message, wParam, lParam);\n    }\n    return 0;\n}\n\n#endif\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/xml/tinyxml2.cpp",
    "content": "/*\nOriginal code by Lee Thomason (www.grinninglizard.com)\n\nThis software is provided 'as-is', without any express or implied\nwarranty. In no event will the authors be held liable for any\ndamages arising from the use of this software.\n\nPermission is granted to anyone to use this software for any\npurpose, including commercial applications, and to alter it and\nredistribute it freely, subject to the following restrictions:\n\n1. The origin of this software must not be misrepresented; you must\nnot claim that you wrote the original software. If you use this\nsoftware in a product, an acknowledgment in the product documentation\nwould be appreciated but is not required.\n\n2. Altered source versions must be plainly marked as such, and\nmust not be misrepresented as being the original software.\n\n3. This notice may not be removed or altered from any source\ndistribution.\n*/\n\n#include \"tinyxml2.h\"\n\n#include <new>      // yes, this one new style header, is in the Android SDK.\n#if defined(ANDROID_NDK) || defined(__QNXNTO__)\n#   include <stddef.h>\n#else\n#   include <cstddef>\n#endif\n\nstatic const char LINE_FEED             = (char)0x0a;           // all line endings are normalized to LF\nstatic const char LF = LINE_FEED;\nstatic const char CARRIAGE_RETURN       = (char)0x0d;           // CR gets filtered out\nstatic const char CR = CARRIAGE_RETURN;\nstatic const char SINGLE_QUOTE          = '\\'';\nstatic const char DOUBLE_QUOTE          = '\\\"';\n\n// Bunch of unicode info at:\n//      http://www.unicode.org/faq/utf_bom.html\n//  ef bb bf (Microsoft \"lead bytes\") - designates UTF-8\n\nstatic const unsigned char TIXML_UTF_LEAD_0 = 0xefU;\nstatic const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;\nstatic const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;\n\nnamespace tinyxml2 {\n\nstruct Entity {\n    const char* pattern;\n    int length;\n    char value;\n};\n\nstatic const int NUM_ENTITIES = 5;\nstatic const Entity entities[NUM_ENTITIES] = {\n    { \"quot\", 4,    DOUBLE_QUOTE },\n    { \"amp\", 3,     '&'  },\n    { \"apos\", 4,    SINGLE_QUOTE },\n    { \"lt\", 2,      '<'  },\n    { \"gt\", 2,      '>'  }\n};\n\n\nStrPair::~StrPair() {\n    Reset();\n}\n\n\nvoid StrPair::TransferTo( StrPair* other ) {\n    if ( this == other ) {\n        return;\n    }\n    // This in effect implements the assignment operator by \"moving\"\n    // ownership (as in auto_ptr).\n\n    TIXMLASSERT( other->_flags == 0 );\n    TIXMLASSERT( other->_start == 0 );\n    TIXMLASSERT( other->_end == 0 );\n\n    other->Reset();\n\n    other->_flags = _flags;\n    other->_start = _start;\n    other->_end = _end;\n\n    _flags = 0;\n    _start = 0;\n    _end = 0;\n}\n\nvoid StrPair::Reset() {\n    if ( _flags & NEEDS_DELETE ) {\n        delete [] _start;\n    }\n    _flags = 0;\n    _start = 0;\n    _end = 0;\n}\n\n\nvoid StrPair::SetStr( const char* str, int flags ) {\n    Reset();\n    size_t len = strlen( str );\n    _start = new char[ len+1 ];\n    memcpy( _start, str, len+1 );\n    _end = _start + len;\n    _flags = flags | NEEDS_DELETE;\n}\n\n\nchar* StrPair::ParseText( char* p, const char* endTag, int strFlags ) {\n    TIXMLASSERT( endTag && *endTag );\n\n    char* start = p;\n    char  endChar = *endTag;\n    size_t length = strlen( endTag );\n\n    // Inner loop of text parsing.\n    while ( *p ) {\n        if ( *p == endChar && strncmp( p, endTag, length ) == 0 ) {\n            Set( start, p, strFlags );\n            return p + length;\n        }\n        ++p;\n    }\n    return 0;\n}\n\n\nchar* StrPair::ParseName( char* p ) {\n    if ( !p || !(*p) ) {\n        return 0;\n    }\n    if ( !XMLUtil::IsNameStartChar( *p ) ) {\n        return 0;\n    }\n\n    char* const start = p;\n    ++p;\n    while ( *p && XMLUtil::IsNameChar( *p ) ) {\n        ++p;\n    }\n\n    Set( start, p, 0 );\n    return p;\n}\n\n\nvoid StrPair::CollapseWhitespace() {\n    // Adjusting _start would cause undefined behavior on delete[]\n    TIXMLASSERT( ( _flags & NEEDS_DELETE ) == 0 );\n    // Trim leading space.\n    _start = XMLUtil::SkipWhiteSpace( _start );\n\n    if ( *_start ) {\n        char* p = _start;   // the read pointer\n        char* q = _start;   // the write pointer\n\n        while( *p ) {\n            if ( XMLUtil::IsWhiteSpace( *p )) {\n                p = XMLUtil::SkipWhiteSpace( p );\n                if ( *p == 0 ) {\n                    break;    // don't write to q; this trims the trailing space.\n                }\n                *q = ' ';\n                ++q;\n            }\n            *q = *p;\n            ++q;\n            ++p;\n        }\n        *q = 0;\n    }\n}\n\n\nconst char* StrPair::GetStr() {\n    TIXMLASSERT( _start );\n    TIXMLASSERT( _end );\n    if ( _flags & NEEDS_FLUSH ) {\n        *_end = 0;\n        _flags ^= NEEDS_FLUSH;\n\n        if ( _flags ) {\n            char* p = _start;   // the read pointer\n            char* q = _start;   // the write pointer\n\n            while( p < _end ) {\n                if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == CR ) {\n                    // CR-LF pair becomes LF\n                    // CR alone becomes LF\n                    // LF-CR becomes LF\n                    if ( *(p+1) == LF ) {\n                        p += 2;\n                    } else {\n                        ++p;\n                    }\n                    *q++ = LF;\n                } else if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == LF ) {\n                    if ( *(p+1) == CR ) {\n                        p += 2;\n                    } else {\n                        ++p;\n                    }\n                    *q++ = LF;\n                } else if ( (_flags & NEEDS_ENTITY_PROCESSING) && *p == '&' ) {\n                    // Entities handled by tinyXML2:\n                    // - special entities in the entity table [in/out]\n                    // - numeric character reference [in]\n                    //   &#20013; or &#x4e2d;\n\n                    if ( *(p+1) == '#' ) {\n                        const int buflen = 10;\n                        char buf[buflen] = { 0 };\n                        int len = 0;\n                        char* adjusted = const_cast<char*>( XMLUtil::GetCharacterRef( p, buf, &len ) );\n                        if ( adjusted == 0 ) {\n                            *q = *p;\n                            ++p;\n                            ++q;\n                        } else {\n                            TIXMLASSERT( 0 <= len && len <= buflen );\n                            TIXMLASSERT( q + len <= adjusted );\n                            p = adjusted;\n                            memcpy( q, buf, len );\n                            q += len;\n                        }\n                    } else {\n                        int i=0;\n                        for(; i<NUM_ENTITIES; ++i ) {\n                            const Entity& entity = entities[i];\n                            if ( strncmp( p + 1, entity.pattern, entity.length ) == 0\n                                    && *( p + entity.length + 1 ) == ';' ) {\n                                // Found an entity - convert.\n                                *q = entity.value;\n                                ++q;\n                                p += entity.length + 2;\n                                break;\n                            }\n                        }\n                        if ( i == NUM_ENTITIES ) {\n                            // fixme: treat as error?\n                            ++p;\n                            ++q;\n                        }\n                    }\n                } else {\n                    *q = *p;\n                    ++p;\n                    ++q;\n                }\n            }\n            *q = 0;\n        }\n        // The loop below has plenty going on, and this\n        // is a less useful mode. Break it out.\n        if ( _flags & COLLAPSE_WHITESPACE ) {\n            CollapseWhitespace();\n        }\n        _flags = (_flags & NEEDS_DELETE);\n    }\n    TIXMLASSERT( _start );\n    return _start;\n}\n\n\n\n\n// --------- XMLUtil ----------- //\n\nconst char* XMLUtil::ReadBOM( const char* p, bool* bom ) {\n    TIXMLASSERT( p );\n    TIXMLASSERT( bom );\n    *bom = false;\n    const unsigned char* pu = reinterpret_cast<const unsigned char*>(p);\n    // Check for BOM:\n    if (    *(pu+0) == TIXML_UTF_LEAD_0\n            && *(pu+1) == TIXML_UTF_LEAD_1\n            && *(pu+2) == TIXML_UTF_LEAD_2 ) {\n        *bom = true;\n        p += 3;\n    }\n    TIXMLASSERT( p );\n    return p;\n}\n\n\nvoid XMLUtil::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ) {\n    const unsigned long BYTE_MASK = 0xBF;\n    const unsigned long BYTE_MARK = 0x80;\n    const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };\n\n    if (input < 0x80) {\n        *length = 1;\n    } else if ( input < 0x800 ) {\n        *length = 2;\n    } else if ( input < 0x10000 ) {\n        *length = 3;\n    } else if ( input < 0x200000 ) {\n        *length = 4;\n    } else {\n        *length = 0;    // This code won't convert this correctly anyway.\n        return;\n    }\n\n    output += *length;\n\n    // Scary scary fall throughs.\n    switch (*length) {\n    case 4:\n        --output;\n        *output = (char)((input | BYTE_MARK) & BYTE_MASK);\n        input >>= 6;\n    case 3:\n        --output;\n        *output = (char)((input | BYTE_MARK) & BYTE_MASK);\n        input >>= 6;\n    case 2:\n        --output;\n        *output = (char)((input | BYTE_MARK) & BYTE_MASK);\n        input >>= 6;\n    case 1:\n        --output;\n        *output = (char)(input | FIRST_BYTE_MARK[*length]);\n        break;\n    default:\n        TIXMLASSERT( false );\n    }\n}\n\n\nconst char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length ) {\n    // Presume an entity, and pull it out.\n    *length = 0;\n\n    if ( *(p+1) == '#' && *(p+2) ) {\n        unsigned long ucs = 0;\n        TIXMLASSERT( sizeof( ucs ) >= 4 );\n        ptrdiff_t delta = 0;\n        unsigned mult = 1;\n        static const char SEMICOLON = ';';\n\n        if ( *(p+2) == 'x' ) {\n            // Hexadecimal.\n            const char* q = p+3;\n            if ( !(*q) ) {\n                return 0;\n            }\n\n            q = strchr( q, SEMICOLON );\n\n            if ( !q ) {\n                return 0;\n            }\n            TIXMLASSERT( *q == SEMICOLON );\n\n            delta = q-p;\n            --q;\n\n            while ( *q != 'x' ) {\n                unsigned int digit = 0;\n\n                if ( *q >= '0' && *q <= '9' ) {\n                    digit = *q - '0';\n                } else if ( *q >= 'a' && *q <= 'f' ) {\n                    digit = *q - 'a' + 10;\n                } else if ( *q >= 'A' && *q <= 'F' ) {\n                    digit = *q - 'A' + 10;\n                } else {\n                    return 0;\n                }\n                TIXMLASSERT( digit >= 0 && digit < 16);\n                TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit );\n                const unsigned int digitScaled = mult * digit;\n                TIXMLASSERT( ucs <= ULONG_MAX - digitScaled );\n                ucs += digitScaled;\n                TIXMLASSERT( mult <= UINT_MAX / 16 );\n                mult *= 16;\n                --q;\n            }\n        } else {\n            // Decimal.\n            const char* q = p+2;\n            if ( !(*q) ) {\n                return 0;\n            }\n\n            q = strchr( q, SEMICOLON );\n\n            if ( !q ) {\n                return 0;\n            }\n            TIXMLASSERT( *q == SEMICOLON );\n\n            delta = q-p;\n            --q;\n\n            while ( *q != '#' ) {\n                if ( *q >= '0' && *q <= '9' ) {\n                    const unsigned int digit = *q - '0';\n                    TIXMLASSERT( digit >= 0 && digit < 10);\n                    TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit );\n                    const unsigned int digitScaled = mult * digit;\n                    TIXMLASSERT( ucs <= ULONG_MAX - digitScaled );\n                    ucs += digitScaled;\n                } else {\n                    return 0;\n                }\n                TIXMLASSERT( mult <= UINT_MAX / 10 );\n                mult *= 10;\n                --q;\n            }\n        }\n        // convert the UCS to UTF-8\n        ConvertUTF32ToUTF8( ucs, value, length );\n        return p + delta + 1;\n    }\n    return p+1;\n}\n\n\nvoid XMLUtil::ToStr( int v, char* buffer, int bufferSize ) {\n    TIXML_SNPRINTF( buffer, bufferSize, \"%d\", v );\n}\n\n\nvoid XMLUtil::ToStr( unsigned v, char* buffer, int bufferSize ) {\n    TIXML_SNPRINTF( buffer, bufferSize, \"%u\", v );\n}\n\n\nvoid XMLUtil::ToStr( bool v, char* buffer, int bufferSize ) {\n    TIXML_SNPRINTF( buffer, bufferSize, \"%d\", v ? 1 : 0 );\n}\n\n/*\n    ToStr() of a number is a very tricky topic.\n    https://github.com/leethomason/tinyxml2/issues/106\n*/\nvoid XMLUtil::ToStr( float v, char* buffer, int bufferSize ) {\n    TIXML_SNPRINTF( buffer, bufferSize, \"%.8g\", v );\n}\n\n\nvoid XMLUtil::ToStr( double v, char* buffer, int bufferSize ) {\n    TIXML_SNPRINTF( buffer, bufferSize, \"%.17g\", v );\n}\n\n\nbool XMLUtil::ToInt( const char* str, int* value ) {\n    if ( TIXML_SSCANF( str, \"%d\", value ) == 1 ) {\n        return true;\n    }\n    return false;\n}\n\nbool XMLUtil::ToUnsigned( const char* str, unsigned *value ) {\n    if ( TIXML_SSCANF( str, \"%u\", value ) == 1 ) {\n        return true;\n    }\n    return false;\n}\n\nbool XMLUtil::ToBool( const char* str, bool* value ) {\n    int ival = 0;\n    if ( ToInt( str, &ival )) {\n        *value = (ival==0) ? false : true;\n        return true;\n    }\n    if ( StringEqual( str, \"true\" ) ) {\n        *value = true;\n        return true;\n    } else if ( StringEqual( str, \"false\" ) ) {\n        *value = false;\n        return true;\n    }\n    return false;\n}\n\n\nbool XMLUtil::ToFloat( const char* str, float* value ) {\n    if ( TIXML_SSCANF( str, \"%f\", value ) == 1 ) {\n        return true;\n    }\n    return false;\n}\n\nbool XMLUtil::ToDouble( const char* str, double* value ) {\n    if ( TIXML_SSCANF( str, \"%lf\", value ) == 1 ) {\n        return true;\n    }\n    return false;\n}\n\n\nchar* XMLDocument::Identify( char* p, XMLNode** node ) {\n    TIXMLASSERT( node );\n    TIXMLASSERT( p );\n    char* const start = p;\n    p = XMLUtil::SkipWhiteSpace( p );\n    if( !*p ) {\n        *node = 0;\n        TIXMLASSERT( p );\n        return p;\n    }\n\n    // What is this thing?\n    // These strings define the matching patters:\n    static const char* xmlHeader        = { \"<?\" };\n    static const char* commentHeader    = { \"<!--\" };\n    static const char* dtdHeader        = { \"<!\" };\n    static const char* cdataHeader      = { \"<![CDATA[\" };\n    static const char* elementHeader    = { \"<\" };  // and a header for everything else; check last.\n\n    static const int xmlHeaderLen       = 2;\n    static const int commentHeaderLen   = 4;\n    static const int dtdHeaderLen       = 2;\n    static const int cdataHeaderLen     = 9;\n    static const int elementHeaderLen   = 1;\n\n    TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLUnknown ) );        // use same memory pool\n    TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLDeclaration ) );    // use same memory pool\n    XMLNode* returnNode = 0;\n    if ( XMLUtil::StringEqual( p, xmlHeader, xmlHeaderLen ) ) {\n        TIXMLASSERT( sizeof( XMLDeclaration ) == _commentPool.ItemSize() );\n        returnNode = new (_commentPool.Alloc()) XMLDeclaration( this );\n        returnNode->_memPool = &_commentPool;\n        p += xmlHeaderLen;\n    } else if ( XMLUtil::StringEqual( p, commentHeader, commentHeaderLen ) ) {\n        TIXMLASSERT( sizeof( XMLComment ) == _commentPool.ItemSize() );\n        returnNode = new (_commentPool.Alloc()) XMLComment( this );\n        returnNode->_memPool = &_commentPool;\n        p += commentHeaderLen;\n    } else if ( XMLUtil::StringEqual( p, cdataHeader, cdataHeaderLen ) ) {\n        TIXMLASSERT( sizeof( XMLText ) == _textPool.ItemSize() );\n        XMLText* text = new (_textPool.Alloc()) XMLText( this );\n        returnNode = text;\n        returnNode->_memPool = &_textPool;\n        p += cdataHeaderLen;\n        text->SetCData( true );\n    } else if ( XMLUtil::StringEqual( p, dtdHeader, dtdHeaderLen ) ) {\n        TIXMLASSERT( sizeof( XMLUnknown ) == _commentPool.ItemSize() );\n        returnNode = new (_commentPool.Alloc()) XMLUnknown( this );\n        returnNode->_memPool = &_commentPool;\n        p += dtdHeaderLen;\n    } else if ( XMLUtil::StringEqual( p, elementHeader, elementHeaderLen ) ) {\n        TIXMLASSERT( sizeof( XMLElement ) == _elementPool.ItemSize() );\n        returnNode = new (_elementPool.Alloc()) XMLElement( this );\n        returnNode->_memPool = &_elementPool;\n        p += elementHeaderLen;\n    } else {\n        TIXMLASSERT( sizeof( XMLText ) == _textPool.ItemSize() );\n        returnNode = new (_textPool.Alloc()) XMLText( this );\n        returnNode->_memPool = &_textPool;\n        p = start;  // Back it up, all the text counts.\n    }\n\n    TIXMLASSERT( returnNode );\n    TIXMLASSERT( p );\n    *node = returnNode;\n    return p;\n}\n\n\nbool XMLDocument::Accept( XMLVisitor* visitor ) const {\n    TIXMLASSERT( visitor );\n    if ( visitor->VisitEnter( *this ) ) {\n        for ( const XMLNode* node=FirstChild(); node; node=node->NextSibling() ) {\n            if ( !node->Accept( visitor ) ) {\n                break;\n            }\n        }\n    }\n    return visitor->VisitExit( *this );\n}\n\n\n// --------- XMLNode ----------- //\n\nXMLNode::XMLNode( XMLDocument* doc ) :\n    _document( doc ),\n    _parent( 0 ),\n    _firstChild( 0 ), _lastChild( 0 ),\n    _prev( 0 ), _next( 0 ),\n    _memPool( 0 ) {\n}\n\n\nXMLNode::~XMLNode() {\n    DeleteChildren();\n    if ( _parent ) {\n        _parent->Unlink( this );\n    }\n}\n\nconst char* XMLNode::Value() const {\n    return _value.GetStr();\n}\n\nvoid XMLNode::SetValue( const char* str, bool staticMem ) {\n    if ( staticMem ) {\n        _value.SetInternedStr( str );\n    } else {\n        _value.SetStr( str );\n    }\n}\n\n\nvoid XMLNode::DeleteChildren() {\n    while( _firstChild ) {\n        TIXMLASSERT( _firstChild->_document == _document );\n        XMLNode* node = _firstChild;\n        Unlink( node );\n\n        DeleteNode( node );\n    }\n    _firstChild = _lastChild = 0;\n}\n\n\nvoid XMLNode::Unlink( XMLNode* child ) {\n    TIXMLASSERT( child );\n    TIXMLASSERT( child->_document == _document );\n    if ( child == _firstChild ) {\n        _firstChild = _firstChild->_next;\n    }\n    if ( child == _lastChild ) {\n        _lastChild = _lastChild->_prev;\n    }\n\n    if ( child->_prev ) {\n        child->_prev->_next = child->_next;\n    }\n    if ( child->_next ) {\n        child->_next->_prev = child->_prev;\n    }\n    child->_parent = 0;\n}\n\n\nvoid XMLNode::DeleteChild( XMLNode* node ) {\n    TIXMLASSERT( node );\n    TIXMLASSERT( node->_document == _document );\n    TIXMLASSERT( node->_parent == this );\n    DeleteNode( node );\n}\n\n\nXMLNode* XMLNode::InsertEndChild( XMLNode* addThis ) {\n    TIXMLASSERT( addThis );\n    if ( addThis->_document != _document ) {\n        TIXMLASSERT( false );\n        return 0;\n    }\n    InsertChildPreamble( addThis );\n\n    if ( _lastChild ) {\n        TIXMLASSERT( _firstChild );\n        TIXMLASSERT( _lastChild->_next == 0 );\n        _lastChild->_next = addThis;\n        addThis->_prev = _lastChild;\n        _lastChild = addThis;\n\n        addThis->_next = 0;\n    } else {\n        TIXMLASSERT( _firstChild == 0 );\n        _firstChild = _lastChild = addThis;\n\n        addThis->_prev = 0;\n        addThis->_next = 0;\n    }\n    addThis->_parent = this;\n    return addThis;\n}\n\n\nXMLNode* XMLNode::InsertFirstChild( XMLNode* addThis ) {\n    TIXMLASSERT( addThis );\n    if ( addThis->_document != _document ) {\n        TIXMLASSERT( false );\n        return 0;\n    }\n    InsertChildPreamble( addThis );\n\n    if ( _firstChild ) {\n        TIXMLASSERT( _lastChild );\n        TIXMLASSERT( _firstChild->_prev == 0 );\n\n        _firstChild->_prev = addThis;\n        addThis->_next = _firstChild;\n        _firstChild = addThis;\n\n        addThis->_prev = 0;\n    } else {\n        TIXMLASSERT( _lastChild == 0 );\n        _firstChild = _lastChild = addThis;\n\n        addThis->_prev = 0;\n        addThis->_next = 0;\n    }\n    addThis->_parent = this;\n    return addThis;\n}\n\n\nXMLNode* XMLNode::InsertAfterChild( XMLNode* afterThis, XMLNode* addThis ) {\n    TIXMLASSERT( addThis );\n    if ( addThis->_document != _document ) {\n        TIXMLASSERT( false );\n        return 0;\n    }\n\n    TIXMLASSERT( afterThis );\n\n    if ( afterThis->_parent != this ) {\n        TIXMLASSERT( false );\n        return 0;\n    }\n\n    if ( afterThis->_next == 0 ) {\n        // The last node or the only node.\n        return InsertEndChild( addThis );\n    }\n    InsertChildPreamble( addThis );\n    addThis->_prev = afterThis;\n    addThis->_next = afterThis->_next;\n    afterThis->_next->_prev = addThis;\n    afterThis->_next = addThis;\n    addThis->_parent = this;\n    return addThis;\n}\n\n\n\n\nconst XMLElement* XMLNode::FirstChildElement( const char* value ) const {\n    for( XMLNode* node=_firstChild; node; node=node->_next ) {\n        XMLElement* element = node->ToElement();\n        if ( element ) {\n            if ( !value || XMLUtil::StringEqual( element->Name(), value ) ) {\n                return element;\n            }\n        }\n    }\n    return 0;\n}\n\n\nconst XMLElement* XMLNode::LastChildElement( const char* value ) const {\n    for( XMLNode* node=_lastChild; node; node=node->_prev ) {\n        XMLElement* element = node->ToElement();\n        if ( element ) {\n            if ( !value || XMLUtil::StringEqual( element->Name(), value ) ) {\n                return element;\n            }\n        }\n    }\n    return 0;\n}\n\n\nconst XMLElement* XMLNode::NextSiblingElement( const char* value ) const {\n    for( XMLNode* node=this->_next; node; node = node->_next ) {\n        const XMLElement* element = node->ToElement();\n        if ( element\n                && (!value || XMLUtil::StringEqual( value, node->Value() ))) {\n            return element;\n        }\n    }\n    return 0;\n}\n\n\nconst XMLElement* XMLNode::PreviousSiblingElement( const char* value ) const {\n    for( XMLNode* node=_prev; node; node = node->_prev ) {\n        const XMLElement* element = node->ToElement();\n        if ( element\n                && (!value || XMLUtil::StringEqual( value, node->Value() ))) {\n            return element;\n        }\n    }\n    return 0;\n}\n\n\nchar* XMLNode::ParseDeep( char* p, StrPair* parentEnd ) {\n    // This is a recursive method, but thinking about it \"at the current level\"\n    // it is a pretty simple flat list:\n    //      <foo/>\n    //      <!-- comment -->\n    //\n    // With a special case:\n    //      <foo>\n    //      </foo>\n    //      <!-- comment -->\n    //\n    // Where the closing element (/foo) *must* be the next thing after the opening\n    // element, and the names must match. BUT the tricky bit is that the closing\n    // element will be read by the child.\n    //\n    // 'endTag' is the end tag for this node, it is returned by a call to a child.\n    // 'parentEnd' is the end tag for the parent, which is filled in and returned.\n\n    while( p && *p ) {\n        XMLNode* node = 0;\n\n        p = _document->Identify( p, &node );\n        if ( node == 0 ) {\n            break;\n        }\n\n        StrPair endTag;\n        p = node->ParseDeep( p, &endTag );\n        if ( !p ) {\n            DeleteNode( node );\n            if ( !_document->Error() ) {\n                _document->SetError( XML_ERROR_PARSING, 0, 0 );\n            }\n            break;\n        }\n\n        XMLElement* ele = node->ToElement();\n        if ( ele ) {\n            // We read the end tag. Return it to the parent.\n            if ( ele->ClosingType() == XMLElement::CLOSING ) {\n                if ( parentEnd ) {\n                    ele->_value.TransferTo( parentEnd );\n                }\n                node->_memPool->SetTracked();   // created and then immediately deleted.\n                DeleteNode( node );\n                return p;\n            }\n\n            // Handle an end tag returned to this level.\n            // And handle a bunch of annoying errors.\n            bool mismatch = false;\n            if ( endTag.Empty() ) {\n                if ( ele->ClosingType() == XMLElement::OPEN ) {\n                    mismatch = true;\n                }\n            } else {\n                if ( ele->ClosingType() != XMLElement::OPEN ) {\n                    mismatch = true;\n                } else if ( !XMLUtil::StringEqual( endTag.GetStr(), node->Value() ) ) {\n                    mismatch = true;\n                }\n            }\n            if ( mismatch ) {\n                _document->SetError( XML_ERROR_MISMATCHED_ELEMENT, node->Value(), 0 );\n                DeleteNode( node );\n                break;\n            }\n        }\n        InsertEndChild( node );\n    }\n    return 0;\n}\n\nvoid XMLNode::DeleteNode( XMLNode* node ) {\n    if ( node == 0 ) {\n        return;\n    }\n    MemPool* pool = node->_memPool;\n    node->~XMLNode();\n    pool->Free( node );\n}\n\nvoid XMLNode::InsertChildPreamble( XMLNode* insertThis ) const {\n    TIXMLASSERT( insertThis );\n    TIXMLASSERT( insertThis->_document == _document );\n\n    if ( insertThis->_parent )\n        insertThis->_parent->Unlink( insertThis );\n    else\n        insertThis->_memPool->SetTracked();\n}\n\n// --------- XMLText ---------- //\nchar* XMLText::ParseDeep( char* p, StrPair* ) {\n    const char* start = p;\n    if ( this->CData() ) {\n        p = _value.ParseText( p, \"]]>\", StrPair::NEEDS_NEWLINE_NORMALIZATION );\n        if ( !p ) {\n            _document->SetError( XML_ERROR_PARSING_CDATA, start, 0 );\n        }\n        return p;\n    } else {\n        int flags = _document->ProcessEntities() ? StrPair::TEXT_ELEMENT : StrPair::TEXT_ELEMENT_LEAVE_ENTITIES;\n        if ( _document->WhitespaceMode() == COLLAPSE_WHITESPACE ) {\n            flags |= StrPair::COLLAPSE_WHITESPACE;\n        }\n\n        p = _value.ParseText( p, \"<\", flags );\n        if ( p && *p ) {\n            return p-1;\n        }\n        if ( !p ) {\n            _document->SetError( XML_ERROR_PARSING_TEXT, start, 0 );\n        }\n    }\n    return 0;\n}\n\n\nXMLNode* XMLText::ShallowClone( XMLDocument* doc ) const {\n    if ( !doc ) {\n        doc = _document;\n    }\n    XMLText* text = doc->NewText( Value() );    // fixme: this will always allocate memory. Intern?\n    text->SetCData( this->CData() );\n    return text;\n}\n\n\nbool XMLText::ShallowEqual( const XMLNode* compare ) const {\n    const XMLText* text = compare->ToText();\n    return ( text && XMLUtil::StringEqual( text->Value(), Value() ) );\n}\n\n\nbool XMLText::Accept( XMLVisitor* visitor ) const {\n    TIXMLASSERT( visitor );\n    return visitor->Visit( *this );\n}\n\n\n// --------- XMLComment ---------- //\n\nXMLComment::XMLComment( XMLDocument* doc ) : XMLNode( doc ) {\n}\n\n\nXMLComment::~XMLComment() {\n}\n\n\nchar* XMLComment::ParseDeep( char* p, StrPair* ) {\n    // Comment parses as text.\n    const char* start = p;\n    p = _value.ParseText( p, \"-->\", StrPair::COMMENT );\n    if ( p == 0 ) {\n        _document->SetError( XML_ERROR_PARSING_COMMENT, start, 0 );\n    }\n    return p;\n}\n\n\nXMLNode* XMLComment::ShallowClone( XMLDocument* doc ) const {\n    if ( !doc ) {\n        doc = _document;\n    }\n    XMLComment* comment = doc->NewComment( Value() );   // fixme: this will always allocate memory. Intern?\n    return comment;\n}\n\n\nbool XMLComment::ShallowEqual( const XMLNode* compare ) const {\n    TIXMLASSERT( compare );\n    const XMLComment* comment = compare->ToComment();\n    return ( comment && XMLUtil::StringEqual( comment->Value(), Value() ));\n}\n\n\nbool XMLComment::Accept( XMLVisitor* visitor ) const {\n    TIXMLASSERT( visitor );\n    return visitor->Visit( *this );\n}\n\n\n// --------- XMLDeclaration ---------- //\n\nXMLDeclaration::XMLDeclaration( XMLDocument* doc ) : XMLNode( doc ) {\n}\n\n\nXMLDeclaration::~XMLDeclaration() {\n    //printf( \"~XMLDeclaration\\n\" );\n}\n\n\nchar* XMLDeclaration::ParseDeep( char* p, StrPair* ) {\n    // Declaration parses as text.\n    const char* start = p;\n    p = _value.ParseText( p, \"?>\", StrPair::NEEDS_NEWLINE_NORMALIZATION );\n    if ( p == 0 ) {\n        _document->SetError( XML_ERROR_PARSING_DECLARATION, start, 0 );\n    }\n    return p;\n}\n\n\nXMLNode* XMLDeclaration::ShallowClone( XMLDocument* doc ) const {\n    if ( !doc ) {\n        doc = _document;\n    }\n    XMLDeclaration* dec = doc->NewDeclaration( Value() );   // fixme: this will always allocate memory. Intern?\n    return dec;\n}\n\n\nbool XMLDeclaration::ShallowEqual( const XMLNode* compare ) const {\n    TIXMLASSERT( compare );\n    const XMLDeclaration* declaration = compare->ToDeclaration();\n    return ( declaration && XMLUtil::StringEqual( declaration->Value(), Value() ));\n}\n\n\n\nbool XMLDeclaration::Accept( XMLVisitor* visitor ) const {\n    TIXMLASSERT( visitor );\n    return visitor->Visit( *this );\n}\n\n// --------- XMLUnknown ---------- //\n\nXMLUnknown::XMLUnknown( XMLDocument* doc ) : XMLNode( doc ) {\n}\n\n\nXMLUnknown::~XMLUnknown() {\n}\n\n\nchar* XMLUnknown::ParseDeep( char* p, StrPair* ) {\n    // Unknown parses as text.\n    const char* start = p;\n\n    p = _value.ParseText( p, \">\", StrPair::NEEDS_NEWLINE_NORMALIZATION );\n    if ( !p ) {\n        _document->SetError( XML_ERROR_PARSING_UNKNOWN, start, 0 );\n    }\n    return p;\n}\n\n\nXMLNode* XMLUnknown::ShallowClone( XMLDocument* doc ) const {\n    if ( !doc ) {\n        doc = _document;\n    }\n    XMLUnknown* text = doc->NewUnknown( Value() );  // fixme: this will always allocate memory. Intern?\n    return text;\n}\n\n\nbool XMLUnknown::ShallowEqual( const XMLNode* compare ) const {\n    TIXMLASSERT( compare );\n    const XMLUnknown* unknown = compare->ToUnknown();\n    return ( unknown && XMLUtil::StringEqual( unknown->Value(), Value() ));\n}\n\n\nbool XMLUnknown::Accept( XMLVisitor* visitor ) const {\n    TIXMLASSERT( visitor );\n    return visitor->Visit( *this );\n}\n\n// --------- XMLAttribute ---------- //\n\nconst char* XMLAttribute::Name() const {\n    return _name.GetStr();\n}\n\nconst char* XMLAttribute::Value() const {\n    return _value.GetStr();\n}\n\nchar* XMLAttribute::ParseDeep( char* p, bool processEntities ) {\n    // Parse using the name rules: bug fix, was using ParseText before\n    p = _name.ParseName( p );\n    if ( !p || !*p ) {\n        return 0;\n    }\n\n    // Skip white space before =\n    p = XMLUtil::SkipWhiteSpace( p );\n    if ( *p != '=' ) {\n        return 0;\n    }\n\n    ++p;    // move up to opening quote\n    p = XMLUtil::SkipWhiteSpace( p );\n    if ( *p != '\\\"' && *p != '\\'' ) {\n        return 0;\n    }\n\n    char endTag[2] = { *p, 0 };\n    ++p;    // move past opening quote\n\n    p = _value.ParseText( p, endTag, processEntities ? StrPair::ATTRIBUTE_VALUE : StrPair::ATTRIBUTE_VALUE_LEAVE_ENTITIES );\n    return p;\n}\n\n\nvoid XMLAttribute::SetName( const char* n ) {\n    _name.SetStr( n );\n}\n\n\nXMLError XMLAttribute::QueryIntValue( int* value ) const {\n    if ( XMLUtil::ToInt( Value(), value )) {\n        return XML_NO_ERROR;\n    }\n    return XML_WRONG_ATTRIBUTE_TYPE;\n}\n\n\nXMLError XMLAttribute::QueryUnsignedValue( unsigned int* value ) const {\n    if ( XMLUtil::ToUnsigned( Value(), value )) {\n        return XML_NO_ERROR;\n    }\n    return XML_WRONG_ATTRIBUTE_TYPE;\n}\n\n\nXMLError XMLAttribute::QueryBoolValue( bool* value ) const {\n    if ( XMLUtil::ToBool( Value(), value )) {\n        return XML_NO_ERROR;\n    }\n    return XML_WRONG_ATTRIBUTE_TYPE;\n}\n\n\nXMLError XMLAttribute::QueryFloatValue( float* value ) const {\n    if ( XMLUtil::ToFloat( Value(), value )) {\n        return XML_NO_ERROR;\n    }\n    return XML_WRONG_ATTRIBUTE_TYPE;\n}\n\n\nXMLError XMLAttribute::QueryDoubleValue( double* value ) const {\n    if ( XMLUtil::ToDouble( Value(), value )) {\n        return XML_NO_ERROR;\n    }\n    return XML_WRONG_ATTRIBUTE_TYPE;\n}\n\n\nvoid XMLAttribute::SetAttribute( const char* v ) {\n    _value.SetStr( v );\n}\n\n\nvoid XMLAttribute::SetAttribute( int v ) {\n    char buf[BUF_SIZE];\n    XMLUtil::ToStr( v, buf, BUF_SIZE );\n    _value.SetStr( buf );\n}\n\n\nvoid XMLAttribute::SetAttribute( unsigned v ) {\n    char buf[BUF_SIZE];\n    XMLUtil::ToStr( v, buf, BUF_SIZE );\n    _value.SetStr( buf );\n}\n\n\nvoid XMLAttribute::SetAttribute( bool v ) {\n    char buf[BUF_SIZE];\n    XMLUtil::ToStr( v, buf, BUF_SIZE );\n    _value.SetStr( buf );\n}\n\nvoid XMLAttribute::SetAttribute( double v ) {\n    char buf[BUF_SIZE];\n    XMLUtil::ToStr( v, buf, BUF_SIZE );\n    _value.SetStr( buf );\n}\n\nvoid XMLAttribute::SetAttribute( float v ) {\n    char buf[BUF_SIZE];\n    XMLUtil::ToStr( v, buf, BUF_SIZE );\n    _value.SetStr( buf );\n}\n\n\n// --------- XMLElement ---------- //\nXMLElement::XMLElement( XMLDocument* doc ) : XMLNode( doc ),\n    _closingType( 0 ),\n    _rootAttribute( 0 ) {\n}\n\n\nXMLElement::~XMLElement() {\n    while( _rootAttribute ) {\n        XMLAttribute* next = _rootAttribute->_next;\n        DeleteAttribute( _rootAttribute );\n        _rootAttribute = next;\n    }\n}\n\n\nconst XMLAttribute* XMLElement::FindAttribute( const char* name ) const {\n    for( XMLAttribute* a = _rootAttribute; a; a = a->_next ) {\n        if ( XMLUtil::StringEqual( a->Name(), name ) ) {\n            return a;\n        }\n    }\n    return 0;\n}\n\n\nconst char* XMLElement::Attribute( const char* name, const char* value ) const {\n    const XMLAttribute* a = FindAttribute( name );\n    if ( !a ) {\n        return 0;\n    }\n    if ( !value || XMLUtil::StringEqual( a->Value(), value )) {\n        return a->Value();\n    }\n    return 0;\n}\n\n\nconst char* XMLElement::GetText() const {\n    if ( FirstChild() && FirstChild()->ToText() ) {\n        return FirstChild()->Value();\n    }\n    return 0;\n}\n\n\nvoid    XMLElement::SetText( const char* inText ) {\n    if ( FirstChild() && FirstChild()->ToText() )\n        FirstChild()->SetValue( inText );\n    else {\n        XMLText*    theText = GetDocument()->NewText( inText );\n        InsertFirstChild( theText );\n    }\n}\n\n\nvoid XMLElement::SetText( int v ) {\n    char buf[BUF_SIZE];\n    XMLUtil::ToStr( v, buf, BUF_SIZE );\n    SetText( buf );\n}\n\n\nvoid XMLElement::SetText( unsigned v ) {\n    char buf[BUF_SIZE];\n    XMLUtil::ToStr( v, buf, BUF_SIZE );\n    SetText( buf );\n}\n\n\nvoid XMLElement::SetText( bool v ) {\n    char buf[BUF_SIZE];\n    XMLUtil::ToStr( v, buf, BUF_SIZE );\n    SetText( buf );\n}\n\n\nvoid XMLElement::SetText( float v ) {\n    char buf[BUF_SIZE];\n    XMLUtil::ToStr( v, buf, BUF_SIZE );\n    SetText( buf );\n}\n\n\nvoid XMLElement::SetText( double v ) {\n    char buf[BUF_SIZE];\n    XMLUtil::ToStr( v, buf, BUF_SIZE );\n    SetText( buf );\n}\n\n\nXMLError XMLElement::QueryIntText( int* ival ) const {\n    if ( FirstChild() && FirstChild()->ToText() ) {\n        const char* t = FirstChild()->Value();\n        if ( XMLUtil::ToInt( t, ival ) ) {\n            return XML_SUCCESS;\n        }\n        return XML_CAN_NOT_CONVERT_TEXT;\n    }\n    return XML_NO_TEXT_NODE;\n}\n\n\nXMLError XMLElement::QueryUnsignedText( unsigned* uval ) const {\n    if ( FirstChild() && FirstChild()->ToText() ) {\n        const char* t = FirstChild()->Value();\n        if ( XMLUtil::ToUnsigned( t, uval ) ) {\n            return XML_SUCCESS;\n        }\n        return XML_CAN_NOT_CONVERT_TEXT;\n    }\n    return XML_NO_TEXT_NODE;\n}\n\n\nXMLError XMLElement::QueryBoolText( bool* bval ) const {\n    if ( FirstChild() && FirstChild()->ToText() ) {\n        const char* t = FirstChild()->Value();\n        if ( XMLUtil::ToBool( t, bval ) ) {\n            return XML_SUCCESS;\n        }\n        return XML_CAN_NOT_CONVERT_TEXT;\n    }\n    return XML_NO_TEXT_NODE;\n}\n\n\nXMLError XMLElement::QueryDoubleText( double* dval ) const {\n    if ( FirstChild() && FirstChild()->ToText() ) {\n        const char* t = FirstChild()->Value();\n        if ( XMLUtil::ToDouble( t, dval ) ) {\n            return XML_SUCCESS;\n        }\n        return XML_CAN_NOT_CONVERT_TEXT;\n    }\n    return XML_NO_TEXT_NODE;\n}\n\n\nXMLError XMLElement::QueryFloatText( float* fval ) const {\n    if ( FirstChild() && FirstChild()->ToText() ) {\n        const char* t = FirstChild()->Value();\n        if ( XMLUtil::ToFloat( t, fval ) ) {\n            return XML_SUCCESS;\n        }\n        return XML_CAN_NOT_CONVERT_TEXT;\n    }\n    return XML_NO_TEXT_NODE;\n}\n\n\n\nXMLAttribute* XMLElement::FindOrCreateAttribute( const char* name ) {\n    XMLAttribute* last = 0;\n    XMLAttribute* attrib = 0;\n    for( attrib = _rootAttribute;\n            attrib;\n            last = attrib, attrib = attrib->_next ) {\n        if ( XMLUtil::StringEqual( attrib->Name(), name ) ) {\n            break;\n        }\n    }\n    if ( !attrib ) {\n        TIXMLASSERT( sizeof( XMLAttribute ) == _document->_attributePool.ItemSize() );\n        attrib = new (_document->_attributePool.Alloc() ) XMLAttribute();\n        attrib->_memPool = &_document->_attributePool;\n        if ( last ) {\n            last->_next = attrib;\n        } else {\n            _rootAttribute = attrib;\n        }\n        attrib->SetName( name );\n        attrib->_memPool->SetTracked(); // always created and linked.\n    }\n    return attrib;\n}\n\n\nvoid XMLElement::DeleteAttribute( const char* name ) {\n    XMLAttribute* prev = 0;\n    for( XMLAttribute* a=_rootAttribute; a; a=a->_next ) {\n        if ( XMLUtil::StringEqual( name, a->Name() ) ) {\n            if ( prev ) {\n                prev->_next = a->_next;\n            } else {\n                _rootAttribute = a->_next;\n            }\n            DeleteAttribute( a );\n            break;\n        }\n        prev = a;\n    }\n}\n\n\nchar* XMLElement::ParseAttributes( char* p ) {\n    const char* start = p;\n    XMLAttribute* prevAttribute = 0;\n\n    // Read the attributes.\n    while( p ) {\n        p = XMLUtil::SkipWhiteSpace( p );\n        if ( !(*p) ) {\n            _document->SetError( XML_ERROR_PARSING_ELEMENT, start, Name() );\n            return 0;\n        }\n\n        // attribute.\n        if (XMLUtil::IsNameStartChar( *p ) ) {\n            TIXMLASSERT( sizeof( XMLAttribute ) == _document->_attributePool.ItemSize() );\n            XMLAttribute* attrib = new (_document->_attributePool.Alloc() ) XMLAttribute();\n            attrib->_memPool = &_document->_attributePool;\n            attrib->_memPool->SetTracked();\n\n            p = attrib->ParseDeep( p, _document->ProcessEntities() );\n            if ( !p || Attribute( attrib->Name() ) ) {\n                DeleteAttribute( attrib );\n                _document->SetError( XML_ERROR_PARSING_ATTRIBUTE, start, p );\n                return 0;\n            }\n            // There is a minor bug here: if the attribute in the source xml\n            // document is duplicated, it will not be detected and the\n            // attribute will be doubly added. However, tracking the 'prevAttribute'\n            // avoids re-scanning the attribute list. Preferring performance for\n            // now, may reconsider in the future.\n            if ( prevAttribute ) {\n                prevAttribute->_next = attrib;\n            } else {\n                _rootAttribute = attrib;\n            }\n            prevAttribute = attrib;\n        }\n        // end of the tag\n        else if ( *p == '/' && *(p+1) == '>' ) {\n            _closingType = CLOSED;\n            return p+2; // done; sealed element.\n        }\n        // end of the tag\n        else if ( *p == '>' ) {\n            ++p;\n            break;\n        } else {\n            _document->SetError( XML_ERROR_PARSING_ELEMENT, start, p );\n            return 0;\n        }\n    }\n    return p;\n}\n\nvoid XMLElement::DeleteAttribute( XMLAttribute* attribute ) {\n    if ( attribute == 0 ) {\n        return;\n    }\n    MemPool* pool = attribute->_memPool;\n    attribute->~XMLAttribute();\n    pool->Free( attribute );\n}\n\n//\n//  <ele></ele>\n//  <ele>foo<b>bar</b></ele>\n//\nchar* XMLElement::ParseDeep( char* p, StrPair* strPair ) {\n    // Read the element name.\n    p = XMLUtil::SkipWhiteSpace( p );\n\n    // The closing element is the </element> form. It is\n    // parsed just like a regular element then deleted from\n    // the DOM.\n    if ( *p == '/' ) {\n        _closingType = CLOSING;\n        ++p;\n    }\n\n    p = _value.ParseName( p );\n    if ( _value.Empty() ) {\n        return 0;\n    }\n\n    p = ParseAttributes( p );\n    if ( !p || !*p || _closingType ) {\n        return p;\n    }\n\n    p = XMLNode::ParseDeep( p, strPair );\n    return p;\n}\n\n\n\nXMLNode* XMLElement::ShallowClone( XMLDocument* doc ) const {\n    if ( !doc ) {\n        doc = _document;\n    }\n    XMLElement* element = doc->NewElement( Value() );                   // fixme: this will always allocate memory. Intern?\n    for( const XMLAttribute* a=FirstAttribute(); a; a=a->Next() ) {\n        element->SetAttribute( a->Name(), a->Value() );                 // fixme: this will always allocate memory. Intern?\n    }\n    return element;\n}\n\n\nbool XMLElement::ShallowEqual( const XMLNode* compare ) const {\n    TIXMLASSERT( compare );\n    const XMLElement* other = compare->ToElement();\n    if ( other && XMLUtil::StringEqual( other->Value(), Value() )) {\n\n        const XMLAttribute* a=FirstAttribute();\n        const XMLAttribute* b=other->FirstAttribute();\n\n        while ( a && b ) {\n            if ( !XMLUtil::StringEqual( a->Value(), b->Value() ) ) {\n                return false;\n            }\n            a = a->Next();\n            b = b->Next();\n        }\n        if ( a || b ) {\n            // different count\n            return false;\n        }\n        return true;\n    }\n    return false;\n}\n\n\nbool XMLElement::Accept( XMLVisitor* visitor ) const {\n    TIXMLASSERT( visitor );\n    if ( visitor->VisitEnter( *this, _rootAttribute ) ) {\n        for ( const XMLNode* node=FirstChild(); node; node=node->NextSibling() ) {\n            if ( !node->Accept( visitor ) ) {\n                break;\n            }\n        }\n    }\n    return visitor->VisitExit( *this );\n}\n\n\n// --------- XMLDocument ----------- //\n\n// Warning: List must match 'enum XMLError'\nconst char* XMLDocument::_errorNames[XML_ERROR_COUNT] = {\n    \"XML_SUCCESS\",\n    \"XML_NO_ATTRIBUTE\",\n    \"XML_WRONG_ATTRIBUTE_TYPE\",\n    \"XML_ERROR_FILE_NOT_FOUND\",\n    \"XML_ERROR_FILE_COULD_NOT_BE_OPENED\",\n    \"XML_ERROR_FILE_READ_ERROR\",\n    \"XML_ERROR_ELEMENT_MISMATCH\",\n    \"XML_ERROR_PARSING_ELEMENT\",\n    \"XML_ERROR_PARSING_ATTRIBUTE\",\n    \"XML_ERROR_IDENTIFYING_TAG\",\n    \"XML_ERROR_PARSING_TEXT\",\n    \"XML_ERROR_PARSING_CDATA\",\n    \"XML_ERROR_PARSING_COMMENT\",\n    \"XML_ERROR_PARSING_DECLARATION\",\n    \"XML_ERROR_PARSING_UNKNOWN\",\n    \"XML_ERROR_EMPTY_DOCUMENT\",\n    \"XML_ERROR_MISMATCHED_ELEMENT\",\n    \"XML_ERROR_PARSING\",\n    \"XML_CAN_NOT_CONVERT_TEXT\",\n    \"XML_NO_TEXT_NODE\"\n};\n\n\nXMLDocument::XMLDocument( bool processEntities, Whitespace whitespace ) :\n    XMLNode( 0 ),\n    _writeBOM( false ),\n    _processEntities( processEntities ),\n    _errorID( XML_NO_ERROR ),\n    _whitespace( whitespace ),\n    _errorStr1( 0 ),\n    _errorStr2( 0 ),\n    _charBuffer( 0 ) {\n    _document = this;   // avoid warning about 'this' in initializer list\n}\n\n\nXMLDocument::~XMLDocument() {\n    Clear();\n}\n\n\nvoid XMLDocument::Clear() {\n    DeleteChildren();\n\n#ifdef DEBUG\n    const bool hadError = Error();\n#endif\n    _errorID = XML_NO_ERROR;\n    _errorStr1 = 0;\n    _errorStr2 = 0;\n\n    delete [] _charBuffer;\n    _charBuffer = 0;\n\n#if 0\n    _textPool.Trace( \"text\" );\n    _elementPool.Trace( \"element\" );\n    _commentPool.Trace( \"comment\" );\n    _attributePool.Trace( \"attribute\" );\n#endif\n\n#ifdef DEBUG\n    if ( !hadError ) {\n        TIXMLASSERT( _elementPool.CurrentAllocs()   == _elementPool.Untracked() );\n        TIXMLASSERT( _attributePool.CurrentAllocs() == _attributePool.Untracked() );\n        TIXMLASSERT( _textPool.CurrentAllocs()      == _textPool.Untracked() );\n        TIXMLASSERT( _commentPool.CurrentAllocs()   == _commentPool.Untracked() );\n    }\n#endif\n}\n\n\nXMLElement* XMLDocument::NewElement( const char* name ) {\n    TIXMLASSERT( sizeof( XMLElement ) == _elementPool.ItemSize() );\n    XMLElement* ele = new (_elementPool.Alloc()) XMLElement( this );\n    ele->_memPool = &_elementPool;\n    ele->SetName( name );\n    return ele;\n}\n\n\nXMLComment* XMLDocument::NewComment( const char* str ) {\n    TIXMLASSERT( sizeof( XMLComment ) == _commentPool.ItemSize() );\n    XMLComment* comment = new (_commentPool.Alloc()) XMLComment( this );\n    comment->_memPool = &_commentPool;\n    comment->SetValue( str );\n    return comment;\n}\n\n\nXMLText* XMLDocument::NewText( const char* str ) {\n    TIXMLASSERT( sizeof( XMLText ) == _textPool.ItemSize() );\n    XMLText* text = new (_textPool.Alloc()) XMLText( this );\n    text->_memPool = &_textPool;\n    text->SetValue( str );\n    return text;\n}\n\n\nXMLDeclaration* XMLDocument::NewDeclaration( const char* str ) {\n    TIXMLASSERT( sizeof( XMLDeclaration ) == _commentPool.ItemSize() );\n    XMLDeclaration* dec = new (_commentPool.Alloc()) XMLDeclaration( this );\n    dec->_memPool = &_commentPool;\n    dec->SetValue( str ? str : \"xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"\" );\n    return dec;\n}\n\n\nXMLUnknown* XMLDocument::NewUnknown( const char* str ) {\n    TIXMLASSERT( sizeof( XMLUnknown ) == _commentPool.ItemSize() );\n    XMLUnknown* unk = new (_commentPool.Alloc()) XMLUnknown( this );\n    unk->_memPool = &_commentPool;\n    unk->SetValue( str );\n    return unk;\n}\n\nstatic FILE* callfopen( const char* filepath, const char* mode ) {\n    TIXMLASSERT( filepath );\n    TIXMLASSERT( mode );\n#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE)\n    FILE* fp = 0;\n    errno_t err = fopen_s( &fp, filepath, mode );\n    if ( err ) {\n        return 0;\n    }\n#else\n    FILE* fp = fopen( filepath, mode );\n#endif\n    return fp;\n}\n\nvoid XMLDocument::DeleteNode( XMLNode* node )   {\n    TIXMLASSERT( node );\n    TIXMLASSERT(node->_document == this );\n    if (node->_parent) {\n        node->_parent->DeleteChild( node );\n    } else {\n        // Isn't in the tree.\n        // Use the parent delete.\n        // Also, we need to mark it tracked: we 'know'\n        // it was never used.\n        node->_memPool->SetTracked();\n        // Call the static XMLNode version:\n        XMLNode::DeleteNode(node);\n    }\n}\n\n\nXMLError XMLDocument::LoadFile( const char* filename ) {\n    Clear();\n    FILE* fp = callfopen( filename, \"rb\" );\n    if ( !fp ) {\n        SetError( XML_ERROR_FILE_NOT_FOUND, filename, 0 );\n        return _errorID;\n    }\n    LoadFile( fp );\n    fclose( fp );\n    return _errorID;\n}\n\n\nXMLError XMLDocument::LoadFile( FILE* fp ) {\n    Clear();\n\n    fseek( fp, 0, SEEK_SET );\n    if ( fgetc( fp ) == EOF && ferror( fp ) != 0 ) {\n        SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 );\n        return _errorID;\n    }\n\n    fseek( fp, 0, SEEK_END );\n    const long filelength = ftell( fp );\n    fseek( fp, 0, SEEK_SET );\n    if ( filelength == -1L ) {\n        SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 );\n        return _errorID;\n    }\n\n    const size_t size = filelength;\n    if ( size == 0 ) {\n        SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 );\n        return _errorID;\n    }\n\n    _charBuffer = new char[size+1];\n    size_t read = fread( _charBuffer, 1, size, fp );\n    if ( read != size ) {\n        SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 );\n        return _errorID;\n    }\n\n    _charBuffer[size] = 0;\n\n    Parse();\n    return _errorID;\n}\n\n\nXMLError XMLDocument::SaveFile( const char* filename, bool compact ) {\n    FILE* fp = callfopen( filename, \"w\" );\n    if ( !fp ) {\n        SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, filename, 0 );\n        return _errorID;\n    }\n    SaveFile(fp, compact);\n    fclose( fp );\n    return _errorID;\n}\n\n\nXMLError XMLDocument::SaveFile( FILE* fp, bool compact ) {\n    XMLPrinter stream( fp, compact );\n    Print( &stream );\n    return _errorID;\n}\n\n\nXMLError XMLDocument::Parse( const char* p, size_t len ) {\n    Clear();\n\n    if ( len == 0 || !p || !*p ) {\n        SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 );\n        return _errorID;\n    }\n    if ( len == (size_t)(-1) ) {\n        len = strlen( p );\n    }\n    _charBuffer = new char[ len+1 ];\n    memcpy( _charBuffer, p, len );\n    _charBuffer[len] = 0;\n\n    Parse();\n    if ( Error() ) {\n        // clean up now essentially dangling memory.\n        // and the parse fail can put objects in the\n        // pools that are dead and inaccessible.\n        DeleteChildren();\n        _elementPool.Clear();\n        _attributePool.Clear();\n        _textPool.Clear();\n        _commentPool.Clear();\n    }\n    return _errorID;\n}\n\n\nvoid XMLDocument::Print( XMLPrinter* streamer ) const {\n    XMLPrinter stdStreamer( stdout );\n    if ( !streamer ) {\n        streamer = &stdStreamer;\n    }\n    Accept( streamer );\n}\n\n\nvoid XMLDocument::SetError( XMLError error, const char* str1, const char* str2 ) {\n    TIXMLASSERT( error >= 0 && error < XML_ERROR_COUNT );\n    _errorID = error;\n    _errorStr1 = str1;\n    _errorStr2 = str2;\n}\n\nconst char* XMLDocument::ErrorName() const {\n    TIXMLASSERT( _errorID >= 0 && _errorID < XML_ERROR_COUNT );\n    return _errorNames[_errorID];\n}\n\nvoid XMLDocument::PrintError() const {\n    if ( Error() ) {\n        static const int LEN = 20;\n        char buf1[LEN] = { 0 };\n        char buf2[LEN] = { 0 };\n\n        if ( _errorStr1 ) {\n            TIXML_SNPRINTF( buf1, LEN, \"%s\", _errorStr1 );\n        }\n        if ( _errorStr2 ) {\n            TIXML_SNPRINTF( buf2, LEN, \"%s\", _errorStr2 );\n        }\n\n        printf( \"XMLDocument error id=%d '%s' str1=%s str2=%s\\n\",\n                _errorID, ErrorName(), buf1, buf2 );\n    }\n}\n\nvoid XMLDocument::Parse() {\n    TIXMLASSERT( NoChildren() ); // Clear() must have been called previously\n    TIXMLASSERT( _charBuffer );\n    char* p = _charBuffer;\n    p = XMLUtil::SkipWhiteSpace( p );\n    p = const_cast<char*>( XMLUtil::ReadBOM( p, &_writeBOM ) );\n    if ( !*p ) {\n        SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 );\n        return;\n    }\n    ParseDeep(p, 0 );\n}\n\nXMLPrinter::XMLPrinter( FILE* file, bool compact, int depth ) :\n    _elementJustOpened( false ),\n    _firstElement( true ),\n    _fp( file ),\n    _depth( depth ),\n    _textDepth( -1 ),\n    _processEntities( true ),\n    _compactMode( compact ) {\n    for( int i=0; i<ENTITY_RANGE; ++i ) {\n        _entityFlag[i] = false;\n        _restrictedEntityFlag[i] = false;\n    }\n    for( int i=0; i<NUM_ENTITIES; ++i ) {\n        const char entityValue = entities[i].value;\n        TIXMLASSERT( 0 <= entityValue && entityValue < ENTITY_RANGE );\n        _entityFlag[ (unsigned char)entityValue ] = true;\n    }\n    _restrictedEntityFlag[(unsigned char)'&'] = true;\n    _restrictedEntityFlag[(unsigned char)'<'] = true;\n    _restrictedEntityFlag[(unsigned char)'>'] = true;   // not required, but consistency is nice\n    _buffer.Push( 0 );\n}\n\n\nvoid XMLPrinter::Print( const char* format, ... ) {\n    va_list     va;\n    va_start( va, format );\n\n    if ( _fp ) {\n        vfprintf( _fp, format, va );\n    } else {\n#if defined(_MSC_VER) && (_MSC_VER >= 1400 )\n#if defined(WINCE)\n        int len = 512;\n        do {\n            len = len*2;\n            char* str = new char[len]();\n            len = _vsnprintf(str, len, format, va);\n            delete[] str;\n        } while (len < 0);\n#else\n        int len = _vscprintf( format, va );\n#endif\n#else\n        int len = vsnprintf( 0, 0, format, va );\n#endif\n        // Close out and re-start the va-args\n        va_end( va );\n        va_start( va, format );\n        TIXMLASSERT( _buffer.Size() > 0 && _buffer[_buffer.Size() - 1] == 0 );\n        char* p = _buffer.PushArr( len ) - 1;   // back up over the null terminator.\n#if defined(_MSC_VER) && (_MSC_VER >= 1400 )\n#if defined(WINCE)\n        _vsnprintf( p, len+1, format, va );\n#else\n        vsnprintf_s( p, len+1, _TRUNCATE, format, va );\n#endif\n#else\n        vsnprintf( p, len+1, format, va );\n#endif\n    }\n    va_end( va );\n}\n\n\nvoid XMLPrinter::PrintSpace( int depth ) {\n    for( int i=0; i<depth; ++i ) {\n        Print( \"    \" );\n    }\n}\n\n\nvoid XMLPrinter::PrintString( const char* p, bool restricted ) {\n    // Look for runs of bytes between entities to print.\n    const char* q = p;\n\n    if ( _processEntities ) {\n        const bool* flag = restricted ? _restrictedEntityFlag : _entityFlag;\n        while ( *q ) {\n            // Remember, char is sometimes signed. (How many times has that bitten me?)\n            if ( *q > 0 && *q < ENTITY_RANGE ) {\n                // Check for entities. If one is found, flush\n                // the stream up until the entity, write the\n                // entity, and keep looking.\n                if ( flag[(unsigned char)(*q)] ) {\n                    while ( p < q ) {\n                        Print( \"%c\", *p );\n                        ++p;\n                    }\n                    for( int i=0; i<NUM_ENTITIES; ++i ) {\n                        if ( entities[i].value == *q ) {\n                            Print( \"&%s;\", entities[i].pattern );\n                            break;\n                        }\n                    }\n                    ++p;\n                }\n            }\n            ++q;\n        }\n    }\n    // Flush the remaining string. This will be the entire\n    // string if an entity wasn't found.\n    if ( !_processEntities || (q-p > 0) ) {\n        Print( \"%s\", p );\n    }\n}\n\n\nvoid XMLPrinter::PushHeader( bool writeBOM, bool writeDec ) {\n    if ( writeBOM ) {\n        static const unsigned char bom[] = { TIXML_UTF_LEAD_0, TIXML_UTF_LEAD_1, TIXML_UTF_LEAD_2, 0 };\n        Print( \"%s\", bom );\n    }\n    if ( writeDec ) {\n        PushDeclaration( \"xml version=\\\"1.0\\\"\" );\n    }\n}\n\n\nvoid XMLPrinter::OpenElement( const char* name, bool compactMode ) {\n    SealElementIfJustOpened();\n    _stack.Push( name );\n\n    if ( _textDepth < 0 && !_firstElement && !compactMode ) {\n        Print( \"\\n\" );\n    }\n    if ( !compactMode ) {\n        PrintSpace( _depth );\n    }\n\n    Print( \"<%s\", name );\n    _elementJustOpened = true;\n    _firstElement = false;\n    ++_depth;\n}\n\n\nvoid XMLPrinter::PushAttribute( const char* name, const char* value ) {\n    TIXMLASSERT( _elementJustOpened );\n    Print( \" %s=\\\"\", name );\n    PrintString( value, false );\n    Print( \"\\\"\" );\n}\n\n\nvoid XMLPrinter::PushAttribute( const char* name, int v ) {\n    char buf[BUF_SIZE];\n    XMLUtil::ToStr( v, buf, BUF_SIZE );\n    PushAttribute( name, buf );\n}\n\n\nvoid XMLPrinter::PushAttribute( const char* name, unsigned v ) {\n    char buf[BUF_SIZE];\n    XMLUtil::ToStr( v, buf, BUF_SIZE );\n    PushAttribute( name, buf );\n}\n\n\nvoid XMLPrinter::PushAttribute( const char* name, bool v ) {\n    char buf[BUF_SIZE];\n    XMLUtil::ToStr( v, buf, BUF_SIZE );\n    PushAttribute( name, buf );\n}\n\n\nvoid XMLPrinter::PushAttribute( const char* name, double v ) {\n    char buf[BUF_SIZE];\n    XMLUtil::ToStr( v, buf, BUF_SIZE );\n    PushAttribute( name, buf );\n}\n\n\nvoid XMLPrinter::CloseElement( bool compactMode ) {\n    --_depth;\n    const char* name = _stack.Pop();\n\n    if ( _elementJustOpened ) {\n        Print( \"/>\" );\n    } else {\n        if ( _textDepth < 0 && !compactMode) {\n            Print( \"\\n\" );\n            PrintSpace( _depth );\n        }\n        Print( \"</%s>\", name );\n    }\n\n    if ( _textDepth == _depth ) {\n        _textDepth = -1;\n    }\n    if ( _depth == 0 && !compactMode) {\n        Print( \"\\n\" );\n    }\n    _elementJustOpened = false;\n}\n\n\nvoid XMLPrinter::SealElementIfJustOpened() {\n    if ( !_elementJustOpened ) {\n        return;\n    }\n    _elementJustOpened = false;\n    Print( \">\" );\n}\n\n\nvoid XMLPrinter::PushText( const char* text, bool cdata ) {\n    _textDepth = _depth-1;\n\n    SealElementIfJustOpened();\n    if ( cdata ) {\n        Print( \"<![CDATA[\" );\n        Print( \"%s\", text );\n        Print( \"]]>\" );\n    } else {\n        PrintString( text, true );\n    }\n}\n\nvoid XMLPrinter::PushText( int value ) {\n    char buf[BUF_SIZE];\n    XMLUtil::ToStr( value, buf, BUF_SIZE );\n    PushText( buf, false );\n}\n\n\nvoid XMLPrinter::PushText( unsigned value ) {\n    char buf[BUF_SIZE];\n    XMLUtil::ToStr( value, buf, BUF_SIZE );\n    PushText( buf, false );\n}\n\n\nvoid XMLPrinter::PushText( bool value ) {\n    char buf[BUF_SIZE];\n    XMLUtil::ToStr( value, buf, BUF_SIZE );\n    PushText( buf, false );\n}\n\n\nvoid XMLPrinter::PushText( float value ) {\n    char buf[BUF_SIZE];\n    XMLUtil::ToStr( value, buf, BUF_SIZE );\n    PushText( buf, false );\n}\n\n\nvoid XMLPrinter::PushText( double value ) {\n    char buf[BUF_SIZE];\n    XMLUtil::ToStr( value, buf, BUF_SIZE );\n    PushText( buf, false );\n}\n\n\nvoid XMLPrinter::PushComment( const char* comment ) {\n    SealElementIfJustOpened();\n    if ( _textDepth < 0 && !_firstElement && !_compactMode) {\n        Print( \"\\n\" );\n        PrintSpace( _depth );\n    }\n    _firstElement = false;\n    Print( \"<!--%s-->\", comment );\n}\n\n\nvoid XMLPrinter::PushDeclaration( const char* value ) {\n    SealElementIfJustOpened();\n    if ( _textDepth < 0 && !_firstElement && !_compactMode) {\n        Print( \"\\n\" );\n        PrintSpace( _depth );\n    }\n    _firstElement = false;\n    Print( \"<?%s?>\", value );\n}\n\n\nvoid XMLPrinter::PushUnknown( const char* value ) {\n    SealElementIfJustOpened();\n    if ( _textDepth < 0 && !_firstElement && !_compactMode) {\n        Print( \"\\n\" );\n        PrintSpace( _depth );\n    }\n    _firstElement = false;\n    Print( \"<!%s>\", value );\n}\n\n\nbool XMLPrinter::VisitEnter( const XMLDocument& doc ) {\n    _processEntities = doc.ProcessEntities();\n    if ( doc.HasBOM() ) {\n        PushHeader( true, false );\n    }\n    return true;\n}\n\n\nbool XMLPrinter::VisitEnter( const XMLElement& element, const XMLAttribute* attribute ) {\n    const XMLElement* parentElem = NULL;\n    if (  element.Parent() ) {\n        parentElem = element.Parent()->ToElement();\n    }\n    bool compactMode = parentElem ? CompactMode(*parentElem) : _compactMode;\n    OpenElement( element.Name(), compactMode );\n    while ( attribute ) {\n        PushAttribute( attribute->Name(), attribute->Value() );\n        attribute = attribute->Next();\n    }\n    return true;\n}\n\n\nbool XMLPrinter::VisitExit( const XMLElement& element ) {\n    CloseElement( CompactMode(element) );\n    return true;\n}\n\n\nbool XMLPrinter::Visit( const XMLText& text ) {\n    PushText( text.Value(), text.CData() );\n    return true;\n}\n\n\nbool XMLPrinter::Visit( const XMLComment& comment ) {\n    PushComment( comment.Value() );\n    return true;\n}\n\nbool XMLPrinter::Visit( const XMLDeclaration& declaration ) {\n    PushDeclaration( declaration.Value() );\n    return true;\n}\n\n\nbool XMLPrinter::Visit( const XMLUnknown& unknown ) {\n    PushUnknown( unknown.Value() );\n    return true;\n}\n\n}   // namespace tinyxml2\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/latex/src/xml/tinyxml2.h",
    "content": "/*\nOriginal code by Lee Thomason (www.grinninglizard.com)\n\nThis software is provided 'as-is', without any express or implied\nwarranty. In no event will the authors be held liable for any\ndamages arising from the use of this software.\n\nPermission is granted to anyone to use this software for any\npurpose, including commercial applications, and to alter it and\nredistribute it freely, subject to the following restrictions:\n\n1. The origin of this software must not be misrepresented; you must\nnot claim that you wrote the original software. If you use this\nsoftware in a product, an acknowledgment in the product documentation\nwould be appreciated but is not required.\n\n2. Altered source versions must be plainly marked as such, and\nmust not be misrepresented as being the original software.\n\n3. This notice may not be removed or altered from any source\ndistribution.\n*/\n\n#ifndef TINYXML2_INCLUDED\n#define TINYXML2_INCLUDED\n\n#if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__)\n#   include <ctype.h>\n#   include <limits.h>\n#   include <stdio.h>\n#   include <stdlib.h>\n#   include <string.h>\n#   include <stdarg.h>\n#else\n#   include <cctype>\n#   include <climits>\n#   include <cstdio>\n#   include <cstdlib>\n#   include <cstring>\n#   include <cstdarg>\n#endif\n\n/*\n   TODO: intern strings instead of allocation.\n*/\n/*\n    gcc:\n        g++ -Wall -DDEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe\n\n    Formatting, Artistic Style:\n        AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h\n*/\n\n#if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__)\n#   ifndef DEBUG\n#       define DEBUG\n#   endif\n#endif\n\n#ifdef _MSC_VER\n#   pragma warning(push)\n#   pragma warning(disable: 4251)\n#endif\n\n#ifdef _WIN32\n#   ifdef TINYXML2_EXPORT\n#       define TINYXML2_LIB __declspec(dllexport)\n#   elif defined(TINYXML2_IMPORT)\n#       define TINYXML2_LIB __declspec(dllimport)\n#   else\n#       define TINYXML2_LIB\n#   endif\n#else\n#   define TINYXML2_LIB\n#endif\n\n\n#if defined(DEBUG)\n#   if defined(_MSC_VER)\n#       // \"(void)0,\" is for suppressing C4127 warning in \"assert(false)\", \"assert(true)\" and the like\n#       define TIXMLASSERT( x )           if ( !((void)0,(x))) { __debugbreak(); } //if ( !(x)) WinDebugBreak()\n#   elif defined (ANDROID_NDK)\n#       include <android/log.h>\n#       define TIXMLASSERT( x )           if ( !(x)) { __android_log_assert( \"assert\", \"grinliz\", \"ASSERT in '%s' at %d.\", __FILE__, __LINE__ ); }\n#   else\n#       include <assert.h>\n#       define TIXMLASSERT                assert\n#   endif\n#   else\n#       define TIXMLASSERT( x )           {}\n#endif\n\n\n#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE)\n// Microsoft visual studio, version 2005 and higher.\n/*int _snprintf_s(\n   char *buffer,\n   size_t sizeOfBuffer,\n   size_t count,\n   const char *format [,\n      argument] ...\n);*/\ninline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... ) {\n    va_list va;\n    va_start( va, format );\n    int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va );\n    va_end( va );\n    return result;\n}\n#define TIXML_SSCANF   sscanf_s\n#elif defined WINCE\n#define TIXML_SNPRINTF _snprintf\n#define TIXML_SSCANF   sscanf\n#else\n// GCC version 3 and higher\n//#warning( \"Using sn* functions.\" )\n#define TIXML_SNPRINTF snprintf\n#define TIXML_SSCANF   sscanf\n#endif\n\n/* Versioning, past 1.0.14:\n    http://semver.org/\n*/\nstatic const int TIXML2_MAJOR_VERSION = 3;\nstatic const int TIXML2_MINOR_VERSION = 0;\nstatic const int TIXML2_PATCH_VERSION = 0;\n\nnamespace tinyxml2 {\nclass XMLDocument;\nclass XMLElement;\nclass XMLAttribute;\nclass XMLComment;\nclass XMLText;\nclass XMLDeclaration;\nclass XMLUnknown;\nclass XMLPrinter;\n\n/*\n    A class that wraps strings. Normally stores the start and end\n    pointers into the XML file itself, and will apply normalization\n    and entity translation if actually read. Can also store (and memory\n    manage) a traditional char[]\n*/\nclass StrPair {\npublic:\n    enum {\n        NEEDS_ENTITY_PROCESSING         = 0x01,\n        NEEDS_NEWLINE_NORMALIZATION     = 0x02,\n        COLLAPSE_WHITESPACE                 = 0x04,\n\n        TEXT_ELEMENT                        = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,\n        TEXT_ELEMENT_LEAVE_ENTITIES     = NEEDS_NEWLINE_NORMALIZATION,\n        ATTRIBUTE_NAME                      = 0,\n        ATTRIBUTE_VALUE                     = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,\n        ATTRIBUTE_VALUE_LEAVE_ENTITIES      = NEEDS_NEWLINE_NORMALIZATION,\n        COMMENT                     = NEEDS_NEWLINE_NORMALIZATION\n    };\n\n    StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {}\n    ~StrPair();\n\n    void Set( char* start, char* end, int flags ) {\n        Reset();\n        _start  = start;\n        _end    = end;\n        _flags  = flags | NEEDS_FLUSH;\n    }\n\n    const char* GetStr();\n\n    bool Empty() const {\n        return _start == _end;\n    }\n\n    void SetInternedStr( const char* str ) {\n        Reset();\n        _start = const_cast<char*>(str);\n    }\n\n    void SetStr( const char* str, int flags=0 );\n\n    char* ParseText( char* in, const char* endTag, int strFlags );\n    char* ParseName( char* in );\n\n    void TransferTo( StrPair* other );\n\nprivate:\n    void Reset();\n    void CollapseWhitespace();\n\n    enum {\n        NEEDS_FLUSH = 0x100,\n        NEEDS_DELETE = 0x200\n    };\n\n    // After parsing, if *_end != 0, it can be set to zero.\n    int     _flags;\n    char*   _start;\n    char*   _end;\n\n    StrPair( const StrPair& other );    // not supported\n    void operator=( StrPair& other );   // not supported, use TransferTo()\n};\n\n\n/*\n    A dynamic array of Plain Old Data. Doesn't support constructors, etc.\n    Has a small initial memory pool, so that low or no usage will not\n    cause a call to new/delete\n*/\ntemplate <class T, int INIT>\nclass DynArray {\npublic:\n    DynArray() {\n        _mem = _pool;\n        _allocated = INIT;\n        _size = 0;\n    }\n\n    ~DynArray() {\n        if ( _mem != _pool ) {\n            delete [] _mem;\n        }\n    }\n\n    void Clear() {\n        _size = 0;\n    }\n\n    void Push( T t ) {\n        TIXMLASSERT( _size < INT_MAX );\n        EnsureCapacity( _size+1 );\n        _mem[_size++] = t;\n    }\n\n    T* PushArr( int count ) {\n        TIXMLASSERT( count >= 0 );\n        TIXMLASSERT( _size <= INT_MAX - count );\n        EnsureCapacity( _size+count );\n        T* ret = &_mem[_size];\n        _size += count;\n        return ret;\n    }\n\n    T Pop() {\n        TIXMLASSERT( _size > 0 );\n        return _mem[--_size];\n    }\n\n    void PopArr( int count ) {\n        TIXMLASSERT( _size >= count );\n        _size -= count;\n    }\n\n    bool Empty() const                  {\n        return _size == 0;\n    }\n\n    T& operator[](int i)                {\n        TIXMLASSERT( i>= 0 && i < _size );\n        return _mem[i];\n    }\n\n    const T& operator[](int i) const    {\n        TIXMLASSERT( i>= 0 && i < _size );\n        return _mem[i];\n    }\n\n    const T& PeekTop() const            {\n        TIXMLASSERT( _size > 0 );\n        return _mem[ _size - 1];\n    }\n\n    int Size() const                    {\n        TIXMLASSERT( _size >= 0 );\n        return _size;\n    }\n\n    int Capacity() const                {\n        return _allocated;\n    }\n\n    const T* Mem() const                {\n        return _mem;\n    }\n\n    T* Mem()                            {\n        return _mem;\n    }\n\nprivate:\n    DynArray( const DynArray& ); // not supported\n    void operator=( const DynArray& ); // not supported\n\n    void EnsureCapacity( int cap ) {\n        TIXMLASSERT( cap > 0 );\n        if ( cap > _allocated ) {\n            TIXMLASSERT( cap <= INT_MAX / 2 );\n            int newAllocated = cap * 2;\n            T* newMem = new T[newAllocated];\n            memcpy( newMem, _mem, sizeof(T)*_size );    // warning: not using constructors, only works for PODs\n            if ( _mem != _pool ) {\n                delete [] _mem;\n            }\n            _mem = newMem;\n            _allocated = newAllocated;\n        }\n    }\n\n    T*  _mem;\n    T   _pool[INIT];\n    int _allocated;     // objects allocated\n    int _size;          // number objects in use\n};\n\n\n/*\n    Parent virtual class of a pool for fast allocation\n    and deallocation of objects.\n*/\nclass MemPool {\npublic:\n    MemPool() {}\n    virtual ~MemPool() {}\n\n    virtual int ItemSize() const = 0;\n    virtual void* Alloc() = 0;\n    virtual void Free( void* ) = 0;\n    virtual void SetTracked() = 0;\n    virtual void Clear() = 0;\n};\n\n\n/*\n    Template child class to create pools of the correct type.\n*/\ntemplate< int SIZE >\nclass MemPoolT : public MemPool {\npublic:\n    MemPoolT() : _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0)    {}\n    ~MemPoolT() {\n        Clear();\n    }\n\n    void Clear() {\n        // Delete the blocks.\n        while( !_blockPtrs.Empty()) {\n            Block* b  = _blockPtrs.Pop();\n            delete b;\n        }\n        _root = 0;\n        _currentAllocs = 0;\n        _nAllocs = 0;\n        _maxAllocs = 0;\n        _nUntracked = 0;\n    }\n\n    virtual int ItemSize() const    {\n        return SIZE;\n    }\n    int CurrentAllocs() const       {\n        return _currentAllocs;\n    }\n\n    virtual void* Alloc() {\n        if ( !_root ) {\n            // Need a new block.\n            Block* block = new Block();\n            _blockPtrs.Push( block );\n\n            for( int i=0; i<COUNT-1; ++i ) {\n                block->chunk[i].next = &block->chunk[i+1];\n            }\n            block->chunk[COUNT-1].next = 0;\n            _root = block->chunk;\n        }\n        void* result = _root;\n        _root = _root->next;\n\n        ++_currentAllocs;\n        if ( _currentAllocs > _maxAllocs ) {\n            _maxAllocs = _currentAllocs;\n        }\n        _nAllocs++;\n        _nUntracked++;\n        return result;\n    }\n\n    virtual void Free( void* mem ) {\n        if ( !mem ) {\n            return;\n        }\n        --_currentAllocs;\n        Chunk* chunk = static_cast<Chunk*>( mem );\n#ifdef DEBUG\n        memset( chunk, 0xfe, sizeof(Chunk) );\n#endif\n        chunk->next = _root;\n        _root = chunk;\n    }\n    void Trace( const char* name ) {\n        printf( \"Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\\n\",\n                name, _maxAllocs, _maxAllocs*SIZE/1024, _currentAllocs, SIZE, _nAllocs, _blockPtrs.Size() );\n    }\n\n    void SetTracked() {\n        _nUntracked--;\n    }\n\n    int Untracked() const {\n        return _nUntracked;\n    }\n\n    // This number is perf sensitive. 4k seems like a good tradeoff on my machine.\n    // The test file is large, 170k.\n    // Release:     VS2010 gcc(no opt)\n    //      1k:     4000\n    //      2k:     4000\n    //      4k:     3900    21000\n    //      16k:    5200\n    //      32k:    4300\n    //      64k:    4000    21000\n    enum { COUNT = (4*1024)/SIZE }; // Some compilers do not accept to use COUNT in private part if COUNT is private\n\nprivate:\n    MemPoolT( const MemPoolT& ); // not supported\n    void operator=( const MemPoolT& ); // not supported\n\n    union Chunk {\n        Chunk*  next;\n        char    mem[SIZE];\n    };\n    struct Block {\n        Chunk chunk[COUNT];\n    };\n    DynArray< Block*, 10 > _blockPtrs;\n    Chunk* _root;\n\n    int _currentAllocs;\n    int _nAllocs;\n    int _maxAllocs;\n    int _nUntracked;\n};\n\n\n\n/**\n    Implements the interface to the \"Visitor pattern\" (see the Accept() method.)\n    If you call the Accept() method, it requires being passed a XMLVisitor\n    class to handle callbacks. For nodes that contain other nodes (Document, Element)\n    you will get called with a VisitEnter/VisitExit pair. Nodes that are always leafs\n    are simply called with Visit().\n\n    If you return 'true' from a Visit method, recursive parsing will continue. If you return\n    false, <b>no children of this node or its siblings</b> will be visited.\n\n    All flavors of Visit methods have a default implementation that returns 'true' (continue\n    visiting). You need to only override methods that are interesting to you.\n\n    Generally Accept() is called on the XMLDocument, although all nodes support visiting.\n\n    You should never change the document from a callback.\n\n    @sa XMLNode::Accept()\n*/\nclass TINYXML2_LIB XMLVisitor {\npublic:\n    virtual ~XMLVisitor() {}\n\n    /// Visit a document.\n    virtual bool VisitEnter( const XMLDocument& /*doc*/ )           {\n        return true;\n    }\n    /// Visit a document.\n    virtual bool VisitExit( const XMLDocument& /*doc*/ )            {\n        return true;\n    }\n\n    /// Visit an element.\n    virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ )    {\n        return true;\n    }\n    /// Visit an element.\n    virtual bool VisitExit( const XMLElement& /*element*/ )         {\n        return true;\n    }\n\n    /// Visit a declaration.\n    virtual bool Visit( const XMLDeclaration& /*declaration*/ )     {\n        return true;\n    }\n    /// Visit a text node.\n    virtual bool Visit( const XMLText& /*text*/ )                   {\n        return true;\n    }\n    /// Visit a comment node.\n    virtual bool Visit( const XMLComment& /*comment*/ )             {\n        return true;\n    }\n    /// Visit an unknown node.\n    virtual bool Visit( const XMLUnknown& /*unknown*/ )             {\n        return true;\n    }\n};\n\n// WARNING: must match XMLDocument::_errorNames[]\nenum XMLError {\n    XML_SUCCESS = 0,\n    XML_NO_ERROR = 0,\n    XML_NO_ATTRIBUTE,\n    XML_WRONG_ATTRIBUTE_TYPE,\n    XML_ERROR_FILE_NOT_FOUND,\n    XML_ERROR_FILE_COULD_NOT_BE_OPENED,\n    XML_ERROR_FILE_READ_ERROR,\n    XML_ERROR_ELEMENT_MISMATCH,\n    XML_ERROR_PARSING_ELEMENT,\n    XML_ERROR_PARSING_ATTRIBUTE,\n    XML_ERROR_IDENTIFYING_TAG,\n    XML_ERROR_PARSING_TEXT,\n    XML_ERROR_PARSING_CDATA,\n    XML_ERROR_PARSING_COMMENT,\n    XML_ERROR_PARSING_DECLARATION,\n    XML_ERROR_PARSING_UNKNOWN,\n    XML_ERROR_EMPTY_DOCUMENT,\n    XML_ERROR_MISMATCHED_ELEMENT,\n    XML_ERROR_PARSING,\n    XML_CAN_NOT_CONVERT_TEXT,\n    XML_NO_TEXT_NODE,\n\n    XML_ERROR_COUNT\n};\n\n\n/*\n    Utility functionality.\n*/\nclass XMLUtil {\npublic:\n    static const char* SkipWhiteSpace( const char* p )  {\n        TIXMLASSERT( p );\n        while( IsWhiteSpace(*p) ) {\n            ++p;\n        }\n        TIXMLASSERT( p );\n        return p;\n    }\n    static char* SkipWhiteSpace( char* p )              {\n        return const_cast<char*>( SkipWhiteSpace( const_cast<const char*>(p) ) );\n    }\n\n    // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't\n    // correct, but simple, and usually works.\n    static bool IsWhiteSpace( char p )                  {\n        return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) );\n    }\n\n    inline static bool IsNameStartChar( unsigned char ch ) {\n        if ( ch >= 128 ) {\n            // This is a heuristic guess in attempt to not implement Unicode-aware isalpha()\n            return true;\n        }\n        if ( isalpha( ch ) ) {\n            return true;\n        }\n        return ch == ':' || ch == '_';\n    }\n\n    inline static bool IsNameChar( unsigned char ch ) {\n        return IsNameStartChar( ch )\n               || isdigit( ch )\n               || ch == '.'\n               || ch == '-';\n    }\n\n    inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX )  {\n        if ( p == q ) {\n            return true;\n        }\n        int n = 0;\n        while( *p && *q && *p == *q && n<nChar ) {\n            ++p;\n            ++q;\n            ++n;\n        }\n        if ( (n == nChar) || ( *p == 0 && *q == 0 ) ) {\n            return true;\n        }\n        return false;\n    }\n\n    inline static bool IsUTF8Continuation( const char p ) {\n        return ( p & 0x80 ) != 0;\n    }\n\n    static const char* ReadBOM( const char* p, bool* hasBOM );\n    // p is the starting location,\n    // the UTF-8 value of the entity will be placed in value, and length filled in.\n    static const char* GetCharacterRef( const char* p, char* value, int* length );\n    static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );\n\n    // converts primitive types to strings\n    static void ToStr( int v, char* buffer, int bufferSize );\n    static void ToStr( unsigned v, char* buffer, int bufferSize );\n    static void ToStr( bool v, char* buffer, int bufferSize );\n    static void ToStr( float v, char* buffer, int bufferSize );\n    static void ToStr( double v, char* buffer, int bufferSize );\n\n    // converts strings to primitive types\n    static bool ToInt( const char* str, int* value );\n    static bool ToUnsigned( const char* str, unsigned* value );\n    static bool ToBool( const char* str, bool* value );\n    static bool ToFloat( const char* str, float* value );\n    static bool ToDouble( const char* str, double* value );\n};\n\n\n/** XMLNode is a base class for every object that is in the\n    XML Document Object Model (DOM), except XMLAttributes.\n    Nodes have siblings, a parent, and children which can\n    be navigated. A node is always in a XMLDocument.\n    The type of a XMLNode can be queried, and it can\n    be cast to its more defined type.\n\n    A XMLDocument allocates memory for all its Nodes.\n    When the XMLDocument gets deleted, all its Nodes\n    will also be deleted.\n\n    @verbatim\n    A Document can contain: Element (container or leaf)\n                            Comment (leaf)\n                            Unknown (leaf)\n                            Declaration( leaf )\n\n    An Element can contain: Element (container or leaf)\n                            Text    (leaf)\n                            Attributes (not on tree)\n                            Comment (leaf)\n                            Unknown (leaf)\n\n    @endverbatim\n*/\nclass TINYXML2_LIB XMLNode {\n    friend class XMLDocument;\n    friend class XMLElement;\npublic:\n\n    /// Get the XMLDocument that owns this XMLNode.\n    const XMLDocument* GetDocument() const  {\n        return _document;\n    }\n    /// Get the XMLDocument that owns this XMLNode.\n    XMLDocument* GetDocument()              {\n        return _document;\n    }\n\n    /// Safely cast to an Element, or null.\n    virtual XMLElement*     ToElement()     {\n        return 0;\n    }\n    /// Safely cast to Text, or null.\n    virtual XMLText*        ToText()        {\n        return 0;\n    }\n    /// Safely cast to a Comment, or null.\n    virtual XMLComment*     ToComment()     {\n        return 0;\n    }\n    /// Safely cast to a Document, or null.\n    virtual XMLDocument*    ToDocument()    {\n        return 0;\n    }\n    /// Safely cast to a Declaration, or null.\n    virtual XMLDeclaration* ToDeclaration() {\n        return 0;\n    }\n    /// Safely cast to an Unknown, or null.\n    virtual XMLUnknown*     ToUnknown()     {\n        return 0;\n    }\n\n    virtual const XMLElement*       ToElement() const       {\n        return 0;\n    }\n    virtual const XMLText*          ToText() const          {\n        return 0;\n    }\n    virtual const XMLComment*       ToComment() const       {\n        return 0;\n    }\n    virtual const XMLDocument*      ToDocument() const      {\n        return 0;\n    }\n    virtual const XMLDeclaration*   ToDeclaration() const   {\n        return 0;\n    }\n    virtual const XMLUnknown*       ToUnknown() const       {\n        return 0;\n    }\n\n    /** The meaning of 'value' changes for the specific type.\n        @verbatim\n        Document:   empty\n        Element:    name of the element\n        Comment:    the comment text\n        Unknown:    the tag contents\n        Text:       the text string\n        @endverbatim\n    */\n    const char* Value() const;\n\n    /** Set the Value of an XML node.\n        @sa Value()\n    */\n    void SetValue( const char* val, bool staticMem=false );\n\n    /// Get the parent of this node on the DOM.\n    const XMLNode*  Parent() const          {\n        return _parent;\n    }\n\n    XMLNode* Parent()                       {\n        return _parent;\n    }\n\n    /// Returns true if this node has no children.\n    bool NoChildren() const                 {\n        return !_firstChild;\n    }\n\n    /// Get the first child node, or null if none exists.\n    const XMLNode*  FirstChild() const      {\n        return _firstChild;\n    }\n\n    XMLNode*        FirstChild()            {\n        return _firstChild;\n    }\n\n    /** Get the first child element, or optionally the first child\n        element with the specified name.\n    */\n    const XMLElement* FirstChildElement( const char* value=0 ) const;\n\n    XMLElement* FirstChildElement( const char* value=0 )    {\n        return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->FirstChildElement( value ));\n    }\n\n    /// Get the last child node, or null if none exists.\n    const XMLNode*  LastChild() const                       {\n        return _lastChild;\n    }\n\n    XMLNode*        LastChild()                             {\n        return const_cast<XMLNode*>(const_cast<const XMLNode*>(this)->LastChild() );\n    }\n\n    /** Get the last child element or optionally the last child\n        element with the specified name.\n    */\n    const XMLElement* LastChildElement( const char* value=0 ) const;\n\n    XMLElement* LastChildElement( const char* value=0 ) {\n        return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->LastChildElement(value) );\n    }\n\n    /// Get the previous (left) sibling node of this node.\n    const XMLNode*  PreviousSibling() const                 {\n        return _prev;\n    }\n\n    XMLNode*    PreviousSibling()                           {\n        return _prev;\n    }\n\n    /// Get the previous (left) sibling element of this node, with an optionally supplied name.\n    const XMLElement*   PreviousSiblingElement( const char* value=0 ) const ;\n\n    XMLElement* PreviousSiblingElement( const char* value=0 ) {\n        return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->PreviousSiblingElement( value ) );\n    }\n\n    /// Get the next (right) sibling node of this node.\n    const XMLNode*  NextSibling() const                     {\n        return _next;\n    }\n\n    XMLNode*    NextSibling()                               {\n        return _next;\n    }\n\n    /// Get the next (right) sibling element of this node, with an optionally supplied name.\n    const XMLElement*   NextSiblingElement( const char* value=0 ) const;\n\n    XMLElement* NextSiblingElement( const char* value=0 )   {\n        return const_cast<XMLElement*>(const_cast<const XMLNode*>(this)->NextSiblingElement( value ) );\n    }\n\n    /**\n        Add a child node as the last (right) child.\n        If the child node is already part of the document,\n        it is moved from its old location to the new location.\n        Returns the addThis argument or 0 if the node does not\n        belong to the same document.\n    */\n    XMLNode* InsertEndChild( XMLNode* addThis );\n\n    XMLNode* LinkEndChild( XMLNode* addThis )   {\n        return InsertEndChild( addThis );\n    }\n    /**\n        Add a child node as the first (left) child.\n        If the child node is already part of the document,\n        it is moved from its old location to the new location.\n        Returns the addThis argument or 0 if the node does not\n        belong to the same document.\n    */\n    XMLNode* InsertFirstChild( XMLNode* addThis );\n    /**\n        Add a node after the specified child node.\n        If the child node is already part of the document,\n        it is moved from its old location to the new location.\n        Returns the addThis argument or 0 if the afterThis node\n        is not a child of this node, or if the node does not\n        belong to the same document.\n    */\n    XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );\n\n    /**\n        Delete all the children of this node.\n    */\n    void DeleteChildren();\n\n    /**\n        Delete a child of this node.\n    */\n    void DeleteChild( XMLNode* node );\n\n    /**\n        Make a copy of this node, but not its children.\n        You may pass in a Document pointer that will be\n        the owner of the new Node. If the 'document' is\n        null, then the node returned will be allocated\n        from the current Document. (this->GetDocument())\n\n        Note: if called on a XMLDocument, this will return null.\n    */\n    virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0;\n\n    /**\n        Test if 2 nodes are the same, but don't test children.\n        The 2 nodes do not need to be in the same Document.\n\n        Note: if called on a XMLDocument, this will return false.\n    */\n    virtual bool ShallowEqual( const XMLNode* compare ) const = 0;\n\n    /** Accept a hierarchical visit of the nodes in the TinyXML-2 DOM. Every node in the\n        XML tree will be conditionally visited and the host will be called back\n        via the XMLVisitor interface.\n\n        This is essentially a SAX interface for TinyXML-2. (Note however it doesn't re-parse\n        the XML for the callbacks, so the performance of TinyXML-2 is unchanged by using this\n        interface versus any other.)\n\n        The interface has been based on ideas from:\n\n        - http://www.saxproject.org/\n        - http://c2.com/cgi/wiki?HierarchicalVisitorPattern\n\n        Which are both good references for \"visiting\".\n\n        An example of using Accept():\n        @verbatim\n        XMLPrinter printer;\n        tinyxmlDoc.Accept( &printer );\n        const char* xmlcstr = printer.CStr();\n        @endverbatim\n    */\n    virtual bool Accept( XMLVisitor* visitor ) const = 0;\n\n    // internal\n    virtual char* ParseDeep( char*, StrPair* );\n\nprotected:\n    XMLNode( XMLDocument* );\n    virtual ~XMLNode();\n\n    XMLDocument*    _document;\n    XMLNode*        _parent;\n    mutable StrPair _value;\n\n    XMLNode*        _firstChild;\n    XMLNode*        _lastChild;\n\n    XMLNode*        _prev;\n    XMLNode*        _next;\n\nprivate:\n    MemPool*        _memPool;\n    void Unlink( XMLNode* child );\n    static void DeleteNode( XMLNode* node );\n    void InsertChildPreamble( XMLNode* insertThis ) const;\n\n    XMLNode( const XMLNode& );  // not supported\n    XMLNode& operator=( const XMLNode& );   // not supported\n};\n\n\n/** XML text.\n\n    Note that a text node can have child element nodes, for example:\n    @verbatim\n    <root>This is <b>bold</b></root>\n    @endverbatim\n\n    A text node can have 2 ways to output the next. \"normal\" output\n    and CDATA. It will default to the mode it was parsed from the XML file and\n    you generally want to leave it alone, but you can change the output mode with\n    SetCData() and query it with CData().\n*/\nclass TINYXML2_LIB XMLText : public XMLNode {\n    friend class XMLBase;\n    friend class XMLDocument;\npublic:\n    virtual bool Accept( XMLVisitor* visitor ) const;\n\n    virtual XMLText* ToText()           {\n        return this;\n    }\n    virtual const XMLText* ToText() const   {\n        return this;\n    }\n\n    /// Declare whether this should be CDATA or standard text.\n    void SetCData( bool isCData )           {\n        _isCData = isCData;\n    }\n    /// Returns true if this is a CDATA text element.\n    bool CData() const                      {\n        return _isCData;\n    }\n\n    char* ParseDeep( char*, StrPair* endTag );\n    virtual XMLNode* ShallowClone( XMLDocument* document ) const;\n    virtual bool ShallowEqual( const XMLNode* compare ) const;\n\nprotected:\n    XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {}\n    virtual ~XMLText()                                              {}\n\nprivate:\n    bool _isCData;\n\n    XMLText( const XMLText& );  // not supported\n    XMLText& operator=( const XMLText& );   // not supported\n};\n\n\n/** An XML Comment. */\nclass TINYXML2_LIB XMLComment : public XMLNode {\n    friend class XMLDocument;\npublic:\n    virtual XMLComment* ToComment()                 {\n        return this;\n    }\n    virtual const XMLComment* ToComment() const     {\n        return this;\n    }\n\n    virtual bool Accept( XMLVisitor* visitor ) const;\n\n    char* ParseDeep( char*, StrPair* endTag );\n    virtual XMLNode* ShallowClone( XMLDocument* document ) const;\n    virtual bool ShallowEqual( const XMLNode* compare ) const;\n\nprotected:\n    XMLComment( XMLDocument* doc );\n    virtual ~XMLComment();\n\nprivate:\n    XMLComment( const XMLComment& );    // not supported\n    XMLComment& operator=( const XMLComment& ); // not supported\n};\n\n\n/** In correct XML the declaration is the first entry in the file.\n    @verbatim\n        <?xml version=\"1.0\" standalone=\"yes\"?>\n    @endverbatim\n\n    TinyXML-2 will happily read or write files without a declaration,\n    however.\n\n    The text of the declaration isn't interpreted. It is parsed\n    and written as a string.\n*/\nclass TINYXML2_LIB XMLDeclaration : public XMLNode {\n    friend class XMLDocument;\npublic:\n    virtual XMLDeclaration* ToDeclaration()                 {\n        return this;\n    }\n    virtual const XMLDeclaration* ToDeclaration() const     {\n        return this;\n    }\n\n    virtual bool Accept( XMLVisitor* visitor ) const;\n\n    char* ParseDeep( char*, StrPair* endTag );\n    virtual XMLNode* ShallowClone( XMLDocument* document ) const;\n    virtual bool ShallowEqual( const XMLNode* compare ) const;\n\nprotected:\n    XMLDeclaration( XMLDocument* doc );\n    virtual ~XMLDeclaration();\n\nprivate:\n    XMLDeclaration( const XMLDeclaration& );    // not supported\n    XMLDeclaration& operator=( const XMLDeclaration& ); // not supported\n};\n\n\n/** Any tag that TinyXML-2 doesn't recognize is saved as an\n    unknown. It is a tag of text, but should not be modified.\n    It will be written back to the XML, unchanged, when the file\n    is saved.\n\n    DTD tags get thrown into XMLUnknowns.\n*/\nclass TINYXML2_LIB XMLUnknown : public XMLNode {\n    friend class XMLDocument;\npublic:\n    virtual XMLUnknown* ToUnknown()                 {\n        return this;\n    }\n    virtual const XMLUnknown* ToUnknown() const     {\n        return this;\n    }\n\n    virtual bool Accept( XMLVisitor* visitor ) const;\n\n    char* ParseDeep( char*, StrPair* endTag );\n    virtual XMLNode* ShallowClone( XMLDocument* document ) const;\n    virtual bool ShallowEqual( const XMLNode* compare ) const;\n\nprotected:\n    XMLUnknown( XMLDocument* doc );\n    virtual ~XMLUnknown();\n\nprivate:\n    XMLUnknown( const XMLUnknown& );    // not supported\n    XMLUnknown& operator=( const XMLUnknown& ); // not supported\n};\n\n\n\n/** An attribute is a name-value pair. Elements have an arbitrary\n    number of attributes, each with a unique name.\n\n    @note The attributes are not XMLNodes. You may only query the\n    Next() attribute in a list.\n*/\nclass TINYXML2_LIB XMLAttribute {\n    friend class XMLElement;\npublic:\n    /// The name of the attribute.\n    const char* Name() const;\n\n    /// The value of the attribute.\n    const char* Value() const;\n\n    /// The next attribute in the list.\n    const XMLAttribute* Next() const {\n        return _next;\n    }\n\n    /** IntValue interprets the attribute as an integer, and returns the value.\n        If the value isn't an integer, 0 will be returned. There is no error checking;\n        use QueryIntValue() if you need error checking.\n    */\n    int      IntValue() const               {\n        int i=0;\n        QueryIntValue( &i );\n        return i;\n    }\n    /// Query as an unsigned integer. See IntValue()\n    unsigned UnsignedValue() const          {\n        unsigned i=0;\n        QueryUnsignedValue( &i );\n        return i;\n    }\n    /// Query as a boolean. See IntValue()\n    bool     BoolValue() const              {\n        bool b=false;\n        QueryBoolValue( &b );\n        return b;\n    }\n    /// Query as a double. See IntValue()\n    double   DoubleValue() const            {\n        double d=0;\n        QueryDoubleValue( &d );\n        return d;\n    }\n    /// Query as a float. See IntValue()\n    float    FloatValue() const             {\n        float f=0;\n        QueryFloatValue( &f );\n        return f;\n    }\n\n    /** QueryIntValue interprets the attribute as an integer, and returns the value\n        in the provided parameter. The function will return XML_NO_ERROR on success,\n        and XML_WRONG_ATTRIBUTE_TYPE if the conversion is not successful.\n    */\n    XMLError QueryIntValue( int* value ) const;\n    /// See QueryIntValue\n    XMLError QueryUnsignedValue( unsigned int* value ) const;\n    /// See QueryIntValue\n    XMLError QueryBoolValue( bool* value ) const;\n    /// See QueryIntValue\n    XMLError QueryDoubleValue( double* value ) const;\n    /// See QueryIntValue\n    XMLError QueryFloatValue( float* value ) const;\n\n    /// Set the attribute to a string value.\n    void SetAttribute( const char* value );\n    /// Set the attribute to value.\n    void SetAttribute( int value );\n    /// Set the attribute to value.\n    void SetAttribute( unsigned value );\n    /// Set the attribute to value.\n    void SetAttribute( bool value );\n    /// Set the attribute to value.\n    void SetAttribute( double value );\n    /// Set the attribute to value.\n    void SetAttribute( float value );\n\nprivate:\n    enum { BUF_SIZE = 200 };\n\n    XMLAttribute() : _next( 0 ), _memPool( 0 ) {}\n    virtual ~XMLAttribute() {}\n\n    XMLAttribute( const XMLAttribute& );    // not supported\n    void operator=( const XMLAttribute& );  // not supported\n    void SetName( const char* name );\n\n    char* ParseDeep( char* p, bool processEntities );\n\n    mutable StrPair _name;\n    mutable StrPair _value;\n    XMLAttribute*   _next;\n    MemPool*        _memPool;\n};\n\n\n/** The element is a container class. It has a value, the element name,\n    and can contain other elements, text, comments, and unknowns.\n    Elements also contain an arbitrary number of attributes.\n*/\nclass TINYXML2_LIB XMLElement : public XMLNode {\n    friend class XMLBase;\n    friend class XMLDocument;\npublic:\n    /// Get the name of an element (which is the Value() of the node.)\n    const char* Name() const        {\n        return Value();\n    }\n    /// Set the name of the element.\n    void SetName( const char* str, bool staticMem=false )   {\n        SetValue( str, staticMem );\n    }\n\n    virtual XMLElement* ToElement()             {\n        return this;\n    }\n    virtual const XMLElement* ToElement() const {\n        return this;\n    }\n    virtual bool Accept( XMLVisitor* visitor ) const;\n\n    /** Given an attribute name, Attribute() returns the value\n        for the attribute of that name, or null if none\n        exists. For example:\n\n        @verbatim\n        const char* value = ele->Attribute( \"foo\" );\n        @endverbatim\n\n        The 'value' parameter is normally null. However, if specified,\n        the attribute will only be returned if the 'name' and 'value'\n        match. This allow you to write code:\n\n        @verbatim\n        if ( ele->Attribute( \"foo\", \"bar\" ) ) callFooIsBar();\n        @endverbatim\n\n        rather than:\n        @verbatim\n        if ( ele->Attribute( \"foo\" ) ) {\n            if ( strcmp( ele->Attribute( \"foo\" ), \"bar\" ) == 0 ) callFooIsBar();\n        }\n        @endverbatim\n    */\n    const char* Attribute( const char* name, const char* value=0 ) const;\n\n    /** Given an attribute name, IntAttribute() returns the value\n        of the attribute interpreted as an integer. 0 will be\n        returned if there is an error. For a method with error\n        checking, see QueryIntAttribute()\n    */\n    int      IntAttribute( const char* name ) const     {\n        int i=0;\n        QueryIntAttribute( name, &i );\n        return i;\n    }\n    /// See IntAttribute()\n    unsigned UnsignedAttribute( const char* name ) const {\n        unsigned i=0;\n        QueryUnsignedAttribute( name, &i );\n        return i;\n    }\n    /// See IntAttribute()\n    bool     BoolAttribute( const char* name ) const    {\n        bool b=false;\n        QueryBoolAttribute( name, &b );\n        return b;\n    }\n    /// See IntAttribute()\n    double   DoubleAttribute( const char* name ) const  {\n        double d=0;\n        QueryDoubleAttribute( name, &d );\n        return d;\n    }\n    /// See IntAttribute()\n    float    FloatAttribute( const char* name ) const   {\n        float f=0;\n        QueryFloatAttribute( name, &f );\n        return f;\n    }\n\n    /** Given an attribute name, QueryIntAttribute() returns\n        XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion\n        can't be performed, or XML_NO_ATTRIBUTE if the attribute\n        doesn't exist. If successful, the result of the conversion\n        will be written to 'value'. If not successful, nothing will\n        be written to 'value'. This allows you to provide default\n        value:\n\n        @verbatim\n        int value = 10;\n        QueryIntAttribute( \"foo\", &value );     // if \"foo\" isn't found, value will still be 10\n        @endverbatim\n    */\n    XMLError QueryIntAttribute( const char* name, int* value ) const                {\n        const XMLAttribute* a = FindAttribute( name );\n        if ( !a ) {\n            return XML_NO_ATTRIBUTE;\n        }\n        return a->QueryIntValue( value );\n    }\n    /// See QueryIntAttribute()\n    XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const  {\n        const XMLAttribute* a = FindAttribute( name );\n        if ( !a ) {\n            return XML_NO_ATTRIBUTE;\n        }\n        return a->QueryUnsignedValue( value );\n    }\n    /// See QueryIntAttribute()\n    XMLError QueryBoolAttribute( const char* name, bool* value ) const              {\n        const XMLAttribute* a = FindAttribute( name );\n        if ( !a ) {\n            return XML_NO_ATTRIBUTE;\n        }\n        return a->QueryBoolValue( value );\n    }\n    /// See QueryIntAttribute()\n    XMLError QueryDoubleAttribute( const char* name, double* value ) const          {\n        const XMLAttribute* a = FindAttribute( name );\n        if ( !a ) {\n            return XML_NO_ATTRIBUTE;\n        }\n        return a->QueryDoubleValue( value );\n    }\n    /// See QueryIntAttribute()\n    XMLError QueryFloatAttribute( const char* name, float* value ) const            {\n        const XMLAttribute* a = FindAttribute( name );\n        if ( !a ) {\n            return XML_NO_ATTRIBUTE;\n        }\n        return a->QueryFloatValue( value );\n    }\n\n\n    /** Given an attribute name, QueryAttribute() returns\n        XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion\n        can't be performed, or XML_NO_ATTRIBUTE if the attribute\n        doesn't exist. It is overloaded for the primitive types,\n        and is a generally more convenient replacement of\n        QueryIntAttribute() and related functions.\n\n        If successful, the result of the conversion\n        will be written to 'value'. If not successful, nothing will\n        be written to 'value'. This allows you to provide default\n        value:\n\n        @verbatim\n        int value = 10;\n        QueryAttribute( \"foo\", &value );        // if \"foo\" isn't found, value will still be 10\n        @endverbatim\n    */\n    int QueryAttribute( const char* name, int* value ) const {\n        return QueryIntAttribute( name, value );\n    }\n\n    int QueryAttribute( const char* name, unsigned int* value ) const {\n        return QueryUnsignedAttribute( name, value );\n    }\n\n    int QueryAttribute( const char* name, bool* value ) const {\n        return QueryBoolAttribute( name, value );\n    }\n\n    int QueryAttribute( const char* name, double* value ) const {\n        return QueryDoubleAttribute( name, value );\n    }\n\n    int QueryAttribute( const char* name, float* value ) const {\n        return QueryFloatAttribute( name, value );\n    }\n\n    /// Sets the named attribute to value.\n    void SetAttribute( const char* name, const char* value )    {\n        XMLAttribute* a = FindOrCreateAttribute( name );\n        a->SetAttribute( value );\n    }\n    /// Sets the named attribute to value.\n    void SetAttribute( const char* name, int value )            {\n        XMLAttribute* a = FindOrCreateAttribute( name );\n        a->SetAttribute( value );\n    }\n    /// Sets the named attribute to value.\n    void SetAttribute( const char* name, unsigned value )       {\n        XMLAttribute* a = FindOrCreateAttribute( name );\n        a->SetAttribute( value );\n    }\n    /// Sets the named attribute to value.\n    void SetAttribute( const char* name, bool value )           {\n        XMLAttribute* a = FindOrCreateAttribute( name );\n        a->SetAttribute( value );\n    }\n    /// Sets the named attribute to value.\n    void SetAttribute( const char* name, double value )     {\n        XMLAttribute* a = FindOrCreateAttribute( name );\n        a->SetAttribute( value );\n    }\n    /// Sets the named attribute to value.\n    void SetAttribute( const char* name, float value )      {\n        XMLAttribute* a = FindOrCreateAttribute( name );\n        a->SetAttribute( value );\n    }\n\n    /**\n        Delete an attribute.\n    */\n    void DeleteAttribute( const char* name );\n\n    /// Return the first attribute in the list.\n    const XMLAttribute* FirstAttribute() const {\n        return _rootAttribute;\n    }\n    /// Query a specific attribute in the list.\n    const XMLAttribute* FindAttribute( const char* name ) const;\n\n    /** Convenience function for easy access to the text inside an element. Although easy\n        and concise, GetText() is limited compared to getting the XMLText child\n        and accessing it directly.\n\n        If the first child of 'this' is a XMLText, the GetText()\n        returns the character string of the Text node, else null is returned.\n\n        This is a convenient method for getting the text of simple contained text:\n        @verbatim\n        <foo>This is text</foo>\n            const char* str = fooElement->GetText();\n        @endverbatim\n\n        'str' will be a pointer to \"This is text\".\n\n        Note that this function can be misleading. If the element foo was created from\n        this XML:\n        @verbatim\n            <foo><b>This is text</b></foo>\n        @endverbatim\n\n        then the value of str would be null. The first child node isn't a text node, it is\n        another element. From this XML:\n        @verbatim\n            <foo>This is <b>text</b></foo>\n        @endverbatim\n        GetText() will return \"This is \".\n    */\n    const char* GetText() const;\n\n    /** Convenience function for easy access to the text inside an element. Although easy\n        and concise, SetText() is limited compared to creating an XMLText child\n        and mutating it directly.\n\n        If the first child of 'this' is a XMLText, SetText() sets its value to\n        the given string, otherwise it will create a first child that is an XMLText.\n\n        This is a convenient method for setting the text of simple contained text:\n        @verbatim\n        <foo>This is text</foo>\n            fooElement->SetText( \"Hullaballoo!\" );\n        <foo>Hullaballoo!</foo>\n        @endverbatim\n\n        Note that this function can be misleading. If the element foo was created from\n        this XML:\n        @verbatim\n            <foo><b>This is text</b></foo>\n        @endverbatim\n\n        then it will not change \"This is text\", but rather prefix it with a text element:\n        @verbatim\n            <foo>Hullaballoo!<b>This is text</b></foo>\n        @endverbatim\n\n        For this XML:\n        @verbatim\n            <foo />\n        @endverbatim\n        SetText() will generate\n        @verbatim\n            <foo>Hullaballoo!</foo>\n        @endverbatim\n    */\n    void SetText( const char* inText );\n    /// Convenience method for setting text inside and element. See SetText() for important limitations.\n    void SetText( int value );\n    /// Convenience method for setting text inside and element. See SetText() for important limitations.\n    void SetText( unsigned value );\n    /// Convenience method for setting text inside and element. See SetText() for important limitations.\n    void SetText( bool value );\n    /// Convenience method for setting text inside and element. See SetText() for important limitations.\n    void SetText( double value );\n    /// Convenience method for setting text inside and element. See SetText() for important limitations.\n    void SetText( float value );\n\n    /**\n        Convenience method to query the value of a child text node. This is probably best\n        shown by example. Given you have a document is this form:\n        @verbatim\n            <point>\n                <x>1</x>\n                <y>1.4</y>\n            </point>\n        @endverbatim\n\n        The QueryIntText() and similar functions provide a safe and easier way to get to the\n        \"value\" of x and y.\n\n        @verbatim\n            int x = 0;\n            float y = 0;    // types of x and y are contrived for example\n            const XMLElement* xElement = pointElement->FirstChildElement( \"x\" );\n            const XMLElement* yElement = pointElement->FirstChildElement( \"y\" );\n            xElement->QueryIntText( &x );\n            yElement->QueryFloatText( &y );\n        @endverbatim\n\n        @returns XML_SUCCESS (0) on success, XML_CAN_NOT_CONVERT_TEXT if the text cannot be converted\n                 to the requested type, and XML_NO_TEXT_NODE if there is no child text to query.\n\n    */\n    XMLError QueryIntText( int* ival ) const;\n    /// See QueryIntText()\n    XMLError QueryUnsignedText( unsigned* uval ) const;\n    /// See QueryIntText()\n    XMLError QueryBoolText( bool* bval ) const;\n    /// See QueryIntText()\n    XMLError QueryDoubleText( double* dval ) const;\n    /// See QueryIntText()\n    XMLError QueryFloatText( float* fval ) const;\n\n    // internal:\n    enum {\n        OPEN,       // <foo>\n        CLOSED,     // <foo/>\n        CLOSING     // </foo>\n    };\n    int ClosingType() const {\n        return _closingType;\n    }\n    char* ParseDeep( char* p, StrPair* endTag );\n    virtual XMLNode* ShallowClone( XMLDocument* document ) const;\n    virtual bool ShallowEqual( const XMLNode* compare ) const;\n\nprivate:\n    XMLElement( XMLDocument* doc );\n    virtual ~XMLElement();\n    XMLElement( const XMLElement& );    // not supported\n    void operator=( const XMLElement& );    // not supported\n\n    XMLAttribute* FindAttribute( const char* name ) {\n        return const_cast<XMLAttribute*>(const_cast<const XMLElement*>(this)->FindAttribute( name ));\n    }\n    XMLAttribute* FindOrCreateAttribute( const char* name );\n    //void LinkAttribute( XMLAttribute* attrib );\n    char* ParseAttributes( char* p );\n    static void DeleteAttribute( XMLAttribute* attribute );\n\n    enum { BUF_SIZE = 200 };\n    int _closingType;\n    // The attribute list is ordered; there is no 'lastAttribute'\n    // because the list needs to be scanned for dupes before adding\n    // a new attribute.\n    XMLAttribute* _rootAttribute;\n};\n\n\nenum Whitespace {\n    PRESERVE_WHITESPACE,\n    COLLAPSE_WHITESPACE\n};\n\n\n/** A Document binds together all the functionality.\n    It can be saved, loaded, and printed to the screen.\n    All Nodes are connected and allocated to a Document.\n    If the Document is deleted, all its Nodes are also deleted.\n*/\nclass TINYXML2_LIB XMLDocument : public XMLNode {\n    friend class XMLElement;\npublic:\n    /// constructor\n    XMLDocument( bool processEntities = true, Whitespace = PRESERVE_WHITESPACE );\n    ~XMLDocument();\n\n    virtual XMLDocument* ToDocument()               {\n        return this;\n    }\n    virtual const XMLDocument* ToDocument() const   {\n        return this;\n    }\n\n    /**\n        Parse an XML file from a character string.\n        Returns XML_NO_ERROR (0) on success, or\n        an errorID.\n\n        You may optionally pass in the 'nBytes', which is\n        the number of bytes which will be parsed. If not\n        specified, TinyXML-2 will assume 'xml' points to a\n        null terminated string.\n    */\n    XMLError Parse( const char* xml, size_t nBytes=(size_t)(-1) );\n\n    /**\n        Load an XML file from disk.\n        Returns XML_NO_ERROR (0) on success, or\n        an errorID.\n    */\n    XMLError LoadFile( const char* filename );\n\n    /**\n        Load an XML file from disk. You are responsible\n        for providing and closing the FILE*.\n\n        NOTE: The file should be opened as binary (\"rb\")\n        not text in order for TinyXML-2 to correctly\n        do newline normalization.\n\n        Returns XML_NO_ERROR (0) on success, or\n        an errorID.\n    */\n    XMLError LoadFile( FILE* );\n\n    /**\n        Save the XML file to disk.\n        Returns XML_NO_ERROR (0) on success, or\n        an errorID.\n    */\n    XMLError SaveFile( const char* filename, bool compact = false );\n\n    /**\n        Save the XML file to disk. You are responsible\n        for providing and closing the FILE*.\n\n        Returns XML_NO_ERROR (0) on success, or\n        an errorID.\n    */\n    XMLError SaveFile( FILE* fp, bool compact = false );\n\n    bool ProcessEntities() const        {\n        return _processEntities;\n    }\n    Whitespace WhitespaceMode() const   {\n        return _whitespace;\n    }\n\n    /**\n        Returns true if this document has a leading Byte Order Mark of UTF8.\n    */\n    bool HasBOM() const {\n        return _writeBOM;\n    }\n    /** Sets whether to write the BOM when writing the file.\n    */\n    void SetBOM( bool useBOM ) {\n        _writeBOM = useBOM;\n    }\n\n    /** Return the root element of DOM. Equivalent to FirstChildElement().\n        To get the first node, use FirstChild().\n    */\n    XMLElement* RootElement()               {\n        return FirstChildElement();\n    }\n    const XMLElement* RootElement() const   {\n        return FirstChildElement();\n    }\n\n    /** Print the Document. If the Printer is not provided, it will\n        print to stdout. If you provide Printer, this can print to a file:\n        @verbatim\n        XMLPrinter printer( fp );\n        doc.Print( &printer );\n        @endverbatim\n\n        Or you can use a printer to print to memory:\n        @verbatim\n        XMLPrinter printer;\n        doc.Print( &printer );\n        // printer.CStr() has a const char* to the XML\n        @endverbatim\n    */\n    void Print( XMLPrinter* streamer=0 ) const;\n    virtual bool Accept( XMLVisitor* visitor ) const;\n\n    /**\n        Create a new Element associated with\n        this Document. The memory for the Element\n        is managed by the Document.\n    */\n    XMLElement* NewElement( const char* name );\n    /**\n        Create a new Comment associated with\n        this Document. The memory for the Comment\n        is managed by the Document.\n    */\n    XMLComment* NewComment( const char* comment );\n    /**\n        Create a new Text associated with\n        this Document. The memory for the Text\n        is managed by the Document.\n    */\n    XMLText* NewText( const char* text );\n    /**\n        Create a new Declaration associated with\n        this Document. The memory for the object\n        is managed by the Document.\n\n        If the 'text' param is null, the standard\n        declaration is used.:\n        @verbatim\n            <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n        @endverbatim\n    */\n    XMLDeclaration* NewDeclaration( const char* text=0 );\n    /**\n        Create a new Unknown associated with\n        this Document. The memory for the object\n        is managed by the Document.\n    */\n    XMLUnknown* NewUnknown( const char* text );\n\n    /**\n        Delete a node associated with this document.\n        It will be unlinked from the DOM.\n    */\n    void DeleteNode( XMLNode* node );\n\n    void SetError( XMLError error, const char* str1, const char* str2 );\n\n    /// Return true if there was an error parsing the document.\n    bool Error() const {\n        return _errorID != XML_NO_ERROR;\n    }\n    /// Return the errorID.\n    XMLError  ErrorID() const {\n        return _errorID;\n    }\n    const char* ErrorName() const;\n\n    /// Return a possibly helpful diagnostic location or string.\n    const char* GetErrorStr1() const {\n        return _errorStr1;\n    }\n    /// Return a possibly helpful secondary diagnostic location or string.\n    const char* GetErrorStr2() const {\n        return _errorStr2;\n    }\n    /// If there is an error, print it to stdout.\n    void PrintError() const;\n\n    /// Clear the document, resetting it to the initial state.\n    void Clear();\n\n    // internal\n    char* Identify( char* p, XMLNode** node );\n\n    virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const    {\n        return 0;\n    }\n    virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const   {\n        return false;\n    }\n\nprivate:\n    XMLDocument( const XMLDocument& );  // not supported\n    void operator=( const XMLDocument& );   // not supported\n\n    bool        _writeBOM;\n    bool        _processEntities;\n    XMLError    _errorID;\n    Whitespace  _whitespace;\n    const char* _errorStr1;\n    const char* _errorStr2;\n    char*       _charBuffer;\n\n    MemPoolT< sizeof(XMLElement) >   _elementPool;\n    MemPoolT< sizeof(XMLAttribute) > _attributePool;\n    MemPoolT< sizeof(XMLText) >      _textPool;\n    MemPoolT< sizeof(XMLComment) >   _commentPool;\n\n    static const char* _errorNames[XML_ERROR_COUNT];\n\n    void Parse();\n};\n\n\n/**\n    A XMLHandle is a class that wraps a node pointer with null checks; this is\n    an incredibly useful thing. Note that XMLHandle is not part of the TinyXML-2\n    DOM structure. It is a separate utility class.\n\n    Take an example:\n    @verbatim\n    <Document>\n        <Element attributeA = \"valueA\">\n            <Child attributeB = \"value1\" />\n            <Child attributeB = \"value2\" />\n        </Element>\n    </Document>\n    @endverbatim\n\n    Assuming you want the value of \"attributeB\" in the 2nd \"Child\" element, it's very\n    easy to write a *lot* of code that looks like:\n\n    @verbatim\n    XMLElement* root = document.FirstChildElement( \"Document\" );\n    if ( root )\n    {\n        XMLElement* element = root->FirstChildElement( \"Element\" );\n        if ( element )\n        {\n            XMLElement* child = element->FirstChildElement( \"Child\" );\n            if ( child )\n            {\n                XMLElement* child2 = child->NextSiblingElement( \"Child\" );\n                if ( child2 )\n                {\n                    // Finally do something useful.\n    @endverbatim\n\n    And that doesn't even cover \"else\" cases. XMLHandle addresses the verbosity\n    of such code. A XMLHandle checks for null pointers so it is perfectly safe\n    and correct to use:\n\n    @verbatim\n    XMLHandle docHandle( &document );\n    XMLElement* child2 = docHandle.FirstChildElement( \"Document\" ).FirstChildElement( \"Element\" ).FirstChildElement().NextSiblingElement();\n    if ( child2 )\n    {\n        // do something useful\n    @endverbatim\n\n    Which is MUCH more concise and useful.\n\n    It is also safe to copy handles - internally they are nothing more than node pointers.\n    @verbatim\n    XMLHandle handleCopy = handle;\n    @endverbatim\n\n    See also XMLConstHandle, which is the same as XMLHandle, but operates on const objects.\n*/\nclass TINYXML2_LIB XMLHandle {\npublic:\n    /// Create a handle from any node (at any depth of the tree.) This can be a null pointer.\n    XMLHandle( XMLNode* node )                                              {\n        _node = node;\n    }\n    /// Create a handle from a node.\n    XMLHandle( XMLNode& node )                                              {\n        _node = &node;\n    }\n    /// Copy constructor\n    XMLHandle( const XMLHandle& ref )                                       {\n        _node = ref._node;\n    }\n    /// Assignment\n    XMLHandle& operator=( const XMLHandle& ref )                            {\n        _node = ref._node;\n        return *this;\n    }\n\n    /// Get the first child of this handle.\n    XMLHandle FirstChild()                                                  {\n        return XMLHandle( _node ? _node->FirstChild() : 0 );\n    }\n    /// Get the first child element of this handle.\n    XMLHandle FirstChildElement( const char* value=0 )                      {\n        return XMLHandle( _node ? _node->FirstChildElement( value ) : 0 );\n    }\n    /// Get the last child of this handle.\n    XMLHandle LastChild()                                                   {\n        return XMLHandle( _node ? _node->LastChild() : 0 );\n    }\n    /// Get the last child element of this handle.\n    XMLHandle LastChildElement( const char* _value=0 )                      {\n        return XMLHandle( _node ? _node->LastChildElement( _value ) : 0 );\n    }\n    /// Get the previous sibling of this handle.\n    XMLHandle PreviousSibling()                                             {\n        return XMLHandle( _node ? _node->PreviousSibling() : 0 );\n    }\n    /// Get the previous sibling element of this handle.\n    XMLHandle PreviousSiblingElement( const char* _value=0 )                {\n        return XMLHandle( _node ? _node->PreviousSiblingElement( _value ) : 0 );\n    }\n    /// Get the next sibling of this handle.\n    XMLHandle NextSibling()                                                 {\n        return XMLHandle( _node ? _node->NextSibling() : 0 );\n    }\n    /// Get the next sibling element of this handle.\n    XMLHandle NextSiblingElement( const char* _value=0 )                    {\n        return XMLHandle( _node ? _node->NextSiblingElement( _value ) : 0 );\n    }\n\n    /// Safe cast to XMLNode. This can return null.\n    XMLNode* ToNode()                           {\n        return _node;\n    }\n    /// Safe cast to XMLElement. This can return null.\n    XMLElement* ToElement()                     {\n        return ( ( _node == 0 ) ? 0 : _node->ToElement() );\n    }\n    /// Safe cast to XMLText. This can return null.\n    XMLText* ToText()                           {\n        return ( ( _node == 0 ) ? 0 : _node->ToText() );\n    }\n    /// Safe cast to XMLUnknown. This can return null.\n    XMLUnknown* ToUnknown()                     {\n        return ( ( _node == 0 ) ? 0 : _node->ToUnknown() );\n    }\n    /// Safe cast to XMLDeclaration. This can return null.\n    XMLDeclaration* ToDeclaration()             {\n        return ( ( _node == 0 ) ? 0 : _node->ToDeclaration() );\n    }\n\nprivate:\n    XMLNode* _node;\n};\n\n\n/**\n    A variant of the XMLHandle class for working with const XMLNodes and Documents. It is the\n    same in all regards, except for the 'const' qualifiers. See XMLHandle for API.\n*/\nclass TINYXML2_LIB XMLConstHandle {\npublic:\n    XMLConstHandle( const XMLNode* node )                                           {\n        _node = node;\n    }\n    XMLConstHandle( const XMLNode& node )                                           {\n        _node = &node;\n    }\n    XMLConstHandle( const XMLConstHandle& ref )                                     {\n        _node = ref._node;\n    }\n\n    XMLConstHandle& operator=( const XMLConstHandle& ref )                          {\n        _node = ref._node;\n        return *this;\n    }\n\n    const XMLConstHandle FirstChild() const                                         {\n        return XMLConstHandle( _node ? _node->FirstChild() : 0 );\n    }\n    const XMLConstHandle FirstChildElement( const char* value=0 ) const             {\n        return XMLConstHandle( _node ? _node->FirstChildElement( value ) : 0 );\n    }\n    const XMLConstHandle LastChild()    const                                       {\n        return XMLConstHandle( _node ? _node->LastChild() : 0 );\n    }\n    const XMLConstHandle LastChildElement( const char* _value=0 ) const             {\n        return XMLConstHandle( _node ? _node->LastChildElement( _value ) : 0 );\n    }\n    const XMLConstHandle PreviousSibling() const                                    {\n        return XMLConstHandle( _node ? _node->PreviousSibling() : 0 );\n    }\n    const XMLConstHandle PreviousSiblingElement( const char* _value=0 ) const       {\n        return XMLConstHandle( _node ? _node->PreviousSiblingElement( _value ) : 0 );\n    }\n    const XMLConstHandle NextSibling() const                                        {\n        return XMLConstHandle( _node ? _node->NextSibling() : 0 );\n    }\n    const XMLConstHandle NextSiblingElement( const char* _value=0 ) const           {\n        return XMLConstHandle( _node ? _node->NextSiblingElement( _value ) : 0 );\n    }\n\n\n    const XMLNode* ToNode() const               {\n        return _node;\n    }\n    const XMLElement* ToElement() const         {\n        return ( ( _node == 0 ) ? 0 : _node->ToElement() );\n    }\n    const XMLText* ToText() const               {\n        return ( ( _node == 0 ) ? 0 : _node->ToText() );\n    }\n    const XMLUnknown* ToUnknown() const         {\n        return ( ( _node == 0 ) ? 0 : _node->ToUnknown() );\n    }\n    const XMLDeclaration* ToDeclaration() const {\n        return ( ( _node == 0 ) ? 0 : _node->ToDeclaration() );\n    }\n\nprivate:\n    const XMLNode* _node;\n};\n\n\n/**\n    Printing functionality. The XMLPrinter gives you more\n    options than the XMLDocument::Print() method.\n\n    It can:\n    -# Print to memory.\n    -# Print to a file you provide.\n    -# Print XML without a XMLDocument.\n\n    Print to Memory\n\n    @verbatim\n    XMLPrinter printer;\n    doc.Print( &printer );\n    SomeFunction( printer.CStr() );\n    @endverbatim\n\n    Print to a File\n\n    You provide the file pointer.\n    @verbatim\n    XMLPrinter printer( fp );\n    doc.Print( &printer );\n    @endverbatim\n\n    Print without a XMLDocument\n\n    When loading, an XML parser is very useful. However, sometimes\n    when saving, it just gets in the way. The code is often set up\n    for streaming, and constructing the DOM is just overhead.\n\n    The Printer supports the streaming case. The following code\n    prints out a trivially simple XML file without ever creating\n    an XML document.\n\n    @verbatim\n    XMLPrinter printer( fp );\n    printer.OpenElement( \"foo\" );\n    printer.PushAttribute( \"foo\", \"bar\" );\n    printer.CloseElement();\n    @endverbatim\n*/\nclass TINYXML2_LIB XMLPrinter : public XMLVisitor {\npublic:\n    /** Construct the printer. If the FILE* is specified,\n        this will print to the FILE. Else it will print\n        to memory, and the result is available in CStr().\n        If 'compact' is set to true, then output is created\n        with only required whitespace and newlines.\n    */\n    XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 );\n    virtual ~XMLPrinter()   {}\n\n    /** If streaming, write the BOM and declaration. */\n    void PushHeader( bool writeBOM, bool writeDeclaration );\n    /** If streaming, start writing an element.\n        The element must be closed with CloseElement()\n    */\n    void OpenElement( const char* name, bool compactMode=false );\n    /// If streaming, add an attribute to an open element.\n    void PushAttribute( const char* name, const char* value );\n    void PushAttribute( const char* name, int value );\n    void PushAttribute( const char* name, unsigned value );\n    void PushAttribute( const char* name, bool value );\n    void PushAttribute( const char* name, double value );\n    /// If streaming, close the Element.\n    virtual void CloseElement( bool compactMode=false );\n\n    /// Add a text node.\n    void PushText( const char* text, bool cdata=false );\n    /// Add a text node from an integer.\n    void PushText( int value );\n    /// Add a text node from an unsigned.\n    void PushText( unsigned value );\n    /// Add a text node from a bool.\n    void PushText( bool value );\n    /// Add a text node from a float.\n    void PushText( float value );\n    /// Add a text node from a double.\n    void PushText( double value );\n\n    /// Add a comment\n    void PushComment( const char* comment );\n\n    void PushDeclaration( const char* value );\n    void PushUnknown( const char* value );\n\n    virtual bool VisitEnter( const XMLDocument& /*doc*/ );\n    virtual bool VisitExit( const XMLDocument& /*doc*/ )            {\n        return true;\n    }\n\n    virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute );\n    virtual bool VisitExit( const XMLElement& element );\n\n    virtual bool Visit( const XMLText& text );\n    virtual bool Visit( const XMLComment& comment );\n    virtual bool Visit( const XMLDeclaration& declaration );\n    virtual bool Visit( const XMLUnknown& unknown );\n\n    /**\n        If in print to memory mode, return a pointer to\n        the XML file in memory.\n    */\n    const char* CStr() const {\n        return _buffer.Mem();\n    }\n    /**\n        If in print to memory mode, return the size\n        of the XML file in memory. (Note the size returned\n        includes the terminating null.)\n    */\n    int CStrSize() const {\n        return _buffer.Size();\n    }\n    /**\n        If in print to memory mode, reset the buffer to the\n        beginning.\n    */\n    void ClearBuffer() {\n        _buffer.Clear();\n        _buffer.Push(0);\n    }\n\nprotected:\n    virtual bool CompactMode( const XMLElement& )   {\n        return _compactMode;\n    }\n\n    /** Prints out the space before an element. You may override to change\n        the space and tabs used. A PrintSpace() override should call Print().\n    */\n    virtual void PrintSpace( int depth );\n    void Print( const char* format, ... );\n\n    void SealElementIfJustOpened();\n    bool _elementJustOpened;\n    DynArray< const char*, 10 > _stack;\n\nprivate:\n    void PrintString( const char*, bool restrictedEntitySet );  // prints out, after detecting entities.\n\n    bool _firstElement;\n    FILE* _fp;\n    int _depth;\n    int _textDepth;\n    bool _processEntities;\n    bool _compactMode;\n\n    enum {\n        ENTITY_RANGE = 64,\n        BUF_SIZE = 200\n    };\n    bool _entityFlag[ENTITY_RANGE];\n    bool _restrictedEntityFlag[ENTITY_RANGE];\n\n    DynArray< char, 20 > _buffer;\n};\n\n\n}   // tinyxml2\n\n#if defined(_MSC_VER)\n#   pragma warning(pop)\n#endif\n\n#endif // TINYXML2_INCLUDED\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/.gitignore",
    "content": "*.o\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/BUILD.gn",
    "content": "#\n# Copyright (c) 2020 Huawei Device Co., Ltd.\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\nif (defined(ohos_lite)) {\n  import(\"//build/lite/config/component/lite_component.gni\")\n} else {\n  import(\"//build/ohos.gni\")\n}\nimport(\"libsec_src.gni\")\n\nconfig(\"libsec_public_config\") {\n  include_dirs = [ \"include\" ]\n}\n\nif (defined(ohos_lite)) {\n  # When the kernel is liteos_m, use //kernel/liteos_m/kal/libsec/BUILD.gn to compile.\n  if (current_toolchain == \"//build/toolchain/linux:clang_x64\" ||\n      ohos_kernel_type != \"liteos_m\") {\n    lite_library(\"libsec_static\") {\n      target_type = \"static_library\"\n      sources = libsec_sources\n      public_configs = [ \":libsec_public_config\" ]\n    }\n  } else if (ohos_kernel_type == \"liteos_m\") {\n    group(\"libsec_static\") {\n    }\n  }\n  lite_library(\"libsec_shared\") {\n    target_type = \"shared_library\"\n    sources = libsec_sources\n    public_configs = [ \":libsec_public_config\" ]\n  }\n  group(\"sec_shared\") {\n    deps = [ \":libsec_shared\" ]\n  }\n} else {\n  ohos_static_library(\"libsec_static\") {\n    sources = libsec_sources\n    public_configs = [ \":libsec_public_config\" ]\n\n    cflags = [\n      \"-D_INC_STRING_S\",\n      \"-D_INC_WCHAR_S\",\n      \"-D_SECIMP=//\",\n      \"-D_STDIO_S_DEFINED\",\n      \"-D_INC_STDIO_S\",\n      \"-D_INC_STDLIB_S\",\n      \"-D_INC_MEMORY_S\",\n    ]\n    part_name = \"bounds_checking_function\"\n    subsystem_name = \"thirdparty\"\n  }\n  ohos_shared_library(\"libsec_shared\") {\n    sources = libsec_sources\n    public_configs = [ \":libsec_public_config\" ]\n\n    branch_protector_ret = \"pac_ret\"\n\n    cflags = [\n      \"-D_INC_STRING_S\",\n      \"-D_INC_WCHAR_S\",\n      \"-D_SECIMP=//\",\n      \"-D_STDIO_S_DEFINED\",\n      \"-D_INC_STDIO_S\",\n      \"-D_INC_STDLIB_S\",\n      \"-D_INC_MEMORY_S\",\n    ]\n    innerapi_tags = [\n      \"chipsetsdk_sp\",\n      \"platformsdk\",\n      \"sasdk\",\n    ]\n    part_name = \"bounds_checking_function\"\n    subsystem_name = \"thirdparty\"\n    install_images = [\n      \"system\",\n      \"updater\",\n      \"ramdisk\",\n    ]\n  }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/CMakeLists.txt",
    "content": "\n# the minimum version of CMake.\ncmake_minimum_required(VERSION 3.5.0)\nproject(securec)\n\ninclude_directories(${NATIVERENDER_ROOT_PATH}\n                    ${NATIVERENDER_ROOT_PATH}/include\n                    \"include\"\n                    )\n\nfile(GLOB_RECURSE SRC \"src/*.c\")\n\nadd_library(securec SHARED ${SRC})\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/LICENSE",
    "content": "木兰宽松许可证， 第2版\n\n2020年1月 http://license.coscl.org.cn/MulanPSL2\n\n您对“软件”的复制、使用、修改及分发受木兰宽松许可证，第2版（“本许可证”）的如下条款的约束：\n\n0.   定义\n\n“软件” 是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。\n\n“贡献” 是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。\n\n“贡献者” 是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。\n\n“法人实体” 是指提交贡献的机构及其“关联实体”。\n\n“关联实体” 是指，对“本许可证”下的行为方而言，控制、受控制或与其共同受控制的机构，此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。\n\n1.   授予版权许可\n\n每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可，您可以复制、使用、修改、分发其“贡献”，不论修改与否。\n\n2.   授予专利许可\n\n每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的（根据本条规定撤销除外）专利许可，供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软件”结合而将必然会侵犯的专利权利要求，不包括对“贡献”的修改或包含“贡献”的其他结合。如果您或您的“关联实体”直接或间接地，就“软件”或其中的“贡献”对任何人发起专利侵权诉讼（包括反诉或交叉诉讼）或其他专利维权行动，指控其侵犯专利权，则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权行动之日终止。\n\n3.   无商标许可\n\n“本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可，但您为满足第4条规定的声明义务而必须使用除外。\n\n4.   分发限制\n\n您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发，不论修改与否，但您必须向接收者提供“本许可证”的副本，并保留“软件”中的版权、商标、专利及免责声明。\n\n5.   免责声明与责任限制\n\n“软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下，“贡献者”或版权所有者不对任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任，不论因何种原因导致或者基于何种法律理论，即使其曾被建议有此种损失的可能性。\n\n6.   语言\n\n“本许可证”以中英文双语表述，中英文版本具有同等法律效力。如果中英文版本存在任何冲突不一致，以中文版为准。\n\n条款结束\n\n如何将木兰宽松许可证，第2版，应用到您的软件\n\n如果您希望将木兰宽松许可证，第2版，应用到您的新软件，为了方便接收者查阅，建议您完成如下三步：\n\n1， 请您补充如下声明中的空白，包括软件名、软件的首次发表年份以及您作为版权人的名字；\n\n2， 请您在软件包的一级目录下创建以“LICENSE”为名的文件，将整个许可证文本放入该文件中；\n\n3， 请将如下声明文本放入每个源文件的头部注释中。\n\nCopyright (c) [Year] [name of copyright holder]\n[Software Name] is licensed under Mulan PSL v2.\nYou can use this software according to the terms and conditions of the Mulan PSL v2.\nYou may obtain a copy of Mulan PSL v2 at:\n         http://license.coscl.org.cn/MulanPSL2\nTHIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\nEITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\nMERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\nSee the Mulan PSL v2 for more details.\nMulan Permissive Software License,Version 2\nMulan Permissive Software License,Version 2 (Mulan PSL v2)\n\nJanuary 2020 http://license.coscl.org.cn/MulanPSL2\n\nYour reproduction, use, modification and distribution of the Software shall be subject to Mulan PSL v2 (this License) with the following terms and conditions:\n\n0. Definition\n\nSoftware means the program and related documents which are licensed under this License and comprise all Contribution(s).\n\nContribution means the copyrightable work licensed by a particular Contributor under this License.\n\nContributor means the Individual or Legal Entity who licenses its copyrightable work under this License.\n\nLegal Entity means the entity making a Contribution and all its Affiliates.\n\nAffiliates means entities that control, are controlled by, or are under common control with the acting entity under this License, 'control' means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity.\n\n1. Grant of Copyright License\n\nSubject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not.\n\n2. Grant of Patent License\n\nSubject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution, where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Software to which the Contribution was contributed. The patent license shall not apply to any modification of the Contribution, and any other combination which includes the Contribution. If you or your Affiliates directly or indirectly institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that the Software or any Contribution in it infringes patents, then any patent license granted to you under this License for the Software shall terminate as of the date such litigation or activity is filed or taken.\n\n3. No Trademark License\n\nNo trademark license is granted to use the trade names, trademarks, service marks, or product names of Contributor, except as required to fulfill notice requirements in section 4.\n\n4. Distribution Restriction\n\nYou may distribute the Software in any medium with or without modification, whether in source or executable forms, provided that you provide recipients with a copy of this License and retain copyright, patent, trademark and disclaimer statements in the Software.\n\n5. Disclaimer of Warranty and Limitation of Liability\n\nTHE SOFTWARE AND CONTRIBUTION IN IT ARE PROVIDED WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING FROM YOUR USE OR INABILITY TO USE THE SOFTWARE OR THE CONTRIBUTION IN IT, NO MATTER HOW IT'S CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\n\n6. Language\n\nTHIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION SHALL PREVAIL.\n\nEND OF THE TERMS AND CONDITIONS\n\nHow to Apply the Mulan Permissive Software License,Version 2 (Mulan PSL v2) to Your Software\n\nTo apply the Mulan PSL v2 to your work, for easy identification by recipients, you are suggested to complete following three steps:\n\nFill in the blanks in following statement, including insert your software name, the year of the first publication of your software, and your name identified as the copyright owner;\nCreate a file named \"LICENSE\" which contains the whole context of this License in the first directory of your software package;\nAttach the statement to the appropriate annotated syntax at the beginning of each source file.\nCopyright (c) [Year] [name of copyright holder]\n[Software Name] is licensed under Mulan PSL v2.\nYou can use this software according to the terms and conditions of the Mulan PSL v2.\nYou may obtain a copy of Mulan PSL v2 at:\n         http://license.coscl.org.cn/MulanPSL2\nTHIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\nEITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\nMERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\nSee the Mulan PSL v2 for more details."
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/Makefile",
    "content": "PROJECT=libboundscheck.so\n\nCC?=gcc\n\nOPTION  = -fPIC\nOPTION += -fstack-protector-all\nOPTION += -D_FORTIFY_SOURCE=2 -O2\nOPTION += -Wformat=2 -Wfloat-equal -Wshadow\nOPTION += -Wconversion\nOPTION += -Wformat-security\nOPTION += -Wextra\nOPTION += --param ssp-buffer-size=4\nOPTION += -Warray-bounds\nOPTION += -Wpointer-arith\nOPTION += -Wcast-qual\nOPTION += -Wstrict-prototypes\nOPTION += -Wmissing-prototypes\nOPTION += -Wstrict-overflow=1\nOPTION += -Wstrict-aliasing=2\nOPTION += -Wswitch -Wswitch-default\n\nCFLAG   =  -Wall -DNDEBUG -O2 $(OPTION)\n\nSOURCES=$(wildcard src/*.c)\n\nOBJECTS=$(patsubst %.c,%.o,$(SOURCES))\n\n.PHONY:clean\n\nCFLAG += -Iinclude\nLD_FLAG = -fPIC -s -Wl,-z,relro,-z,now,-z,noexecstack -fstack-protector-all\n\n$(PROJECT): $(OBJECTS)\n\tmkdir -p lib\n\t$(CC)  -shared -o lib/$@ $(patsubst %.o,obj/%.o,$(notdir $(OBJECTS))) $(LD_FLAG)\n\t@echo \"finish $(PROJECT)\"\n\n.c.o:\n\t@mkdir -p obj\n\t$(CC) -c $< $(CFLAG) -o obj/$(patsubst %.c,%.o,$(notdir $<))\n\nclean:\n\t-rm -rf obj lib\n\t@echo \"clean up\"\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/OAT.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<!-- Copyright (c) 2021 Huawei Device Co., Ltd.\r\n\r\n     Licensed under the Apache License, Version 2.0 (the \"License\");\r\n     you may not use this file except in compliance with the License.\r\n     You may obtain a copy of the License at\r\n\r\n          http://www.apache.org/licenses/LICENSE-2.0\r\n\r\n     Unless required by applicable law or agreed to in writing, software\r\n     distributed under the License is distributed on an \"AS IS\" BASIS,\r\n     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n     See the License for the specific language governing permissions and\r\n     limitations under the License.\r\n\r\n    This is the configuration file template for OpenHarmony OSS Audit Tool, please copy it to your project root dir and modify it refer to OpenHarmony/tools_oat/README.\r\n    All configurations in this file will be merged to OAT-Default.xml, if you have any questions or concerns, please create issue in OpenHarmony/tools_oat and @jalenchen or chenyaxun.\r\n\r\n    licensefile:\r\n    1.If the project don't have \"LICENSE\" in root dir, please define all the license files in this project in , OAT will check license files according to this rule.\r\n\r\n    policylist:\r\n    1. policy: If the OAT-Default.xml policies do not meet your requirements, please add policies here.\r\n    2. policyitem: The fields type, name, path, desc is required, and the fields rule, group, filefilter is optional,the default value is:\r\n    <policyitem type=\"\" name=\"\" path=\"\" desc=\"\" rule=\"may\" group=\"defaultGroup\" filefilter=\"defaultPolicyFilter\"/>\r\n    3. policyitem type:\r\n        \"compatibility\" is used to check license compatibility in the specified path;\r\n        \"license\" is used to check source license header in the specified path;\r\n        \"copyright\" is used to check source copyright header in the specified path;\r\n        \"import\" is used to check source dependency in the specified path, such as import ... ,include ...\r\n        \"filetype\" is used to check file type in the specified path, supported file types: archive, binary\r\n        \"filename\" is used to check whether the specified file exists in the specified path(projectroot means the root dir of the project), supported file names: LICENSE, README, README.OpenSource\r\n    4. policyitem name: This field is used for define the license, copyright, \"*\" means match all, the \"!\" prefix means could not match this value. For example, \"!GPL\" means can not use GPL license.\r\n    5. policyitem path: This field is used for define the source file scope to apply this policyitem, the \"!\" prefix means exclude the files. For example, \"!.*/lib/.*\" means files in lib dir will be exclude while process this policyitem.\r\n    6. policyitem rule and group: These two fields are used together to merge policy results. \"may\" policyitems in the same group means any one in this group passed, the result will be passed.\r\n    7. policyitem filefilter: Used to bind filefilter which define filter rules.\r\n    7. policyitem desc: Used to describe the reason of this policy item, committers will check this while merging the code.\r\n    8. filefilter: Filter rules, the type filename is used to filter file name, the type filepath is used to filter file path.\r\n\r\n    Note:If the text contains special characters, please escape them according to the following rules:\r\n    \" == &gt;\r\n    & == &gt;\r\n    ' == &gt;\r\n    < == &gt;\r\n    > == &gt;\r\n-->\r\n\r\n<configuration>\r\n    <oatconfig>\r\n        <filefilterlist>\r\n            <filefilter name=\"binaryFileTypePolicyFilter\" desc=\"Filters for binary file policies\">\r\n                <filteritem type=\"filename\" name=\"LICENSE\" desc=\"官方自带文件\"/>\r\n            </filefilter>\r\n        </filefilterlist>\r\n    </oatconfig>\r\n</configuration>\r\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/README.OpenSource",
    "content": "[\r\n    {\r\n        \"Name\"                  : \"openEuler:libboundscheck\",\r\n        \"License\"               : \"Mulan Permissive Software License，Version 2\",\r\n        \"License File\"          : \"LICENSE\",\r\n        \"Version Number\"        : \"v1.1.16\",\r\n        \"Owner\"                 : \"jianghan2@huawei.com\",\r\n        \"Upstream URL\"          : \"https://gitee.com/openeuler/libboundscheck\",\r\n        \"Description\"           : \"following the standard of C11 Annex K (bound-checking interfaces), functions of the common memory/string operation classes, such as memcpy_s, strcpy_s, are selected and implemented.\"\r\n    }\r\n]\r\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/README.en.md",
    "content": "# libboundscheck\n\n#### Description\n\n- following the standard of C11 Annex K (bound-checking interfaces), functions of the common memory/string operation classes, such as memcpy_s, strcpy_s, are selected and implemented.\n\n- other standard functions in C11 Annex K will be analyzed in the future and implemented in this organization if necessary.\n\n- handles the release, update, and maintenance of bounds_checking_function.\n\n#### Function List\n\n- memcpy_s\n- wmemcpy_s\n- memmove_s\n- wmemmove_s\n- memset_s\n- strcpy_s\n- wcscpy_s\n- strncpy_s\n- wcsncpy_s\n- strcat_s\n- wcscat_s\n- strncat_s\n- wcsncat_s\n- strtok_s\n- wcstok_s\n- sprintf_s\n- swprintf_s\n- vsprintf_s\n- vswprintf_s\n- snprintf_s\n- vsnprintf_s\n- scanf_s\n- wscanf_s\n- vscanf_s\n- vwscanf_s\n- fscanf_s\n- fwscanf_s\n- vfscanf_s\n- vfwscanf_s\n- sscanf_s\n- swscanf_s\n- vsscanf_s\n- vswscanf_s\n- gets_s\n\n\n#### Build\n\n```\nCC=gcc make\n```\nThe generated Dynamic library libboundscheck.so is stored in the newly created directory lib.\n\n#### How to use\n1. Copy the libboundscheck.so to the library file directory, for example: \"/usr/local/lib/\".\n\n2. To use the libboundscheck, add the “-lboundscheck” parameters to the compiler, for example: “gcc -g -o test test.c -lboundscheck”. "
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/README.md",
    "content": "# libboundscheck\n\n#### 介绍\n- 遵循C11 Annex K (Bounds-checking interfaces)的标准，选取并实现了常见的内存/字符串操作类的函数，如memcpy_s、strcpy_s等函数。\n- 未来将分析C11 Annex K中的其他标准函数，如果有必要，将在该组织中实现。\n- 处理边界检查函数的版本发布、更新以及维护。\n\n#### 函数清单\n\n- memcpy_s\n- wmemcpy_s\n- memmove_s\n- wmemmove_s\n- memset_s\n- strcpy_s\n- wcscpy_s\n- strncpy_s\n- wcsncpy_s\n- strcat_s\n- wcscat_s\n- strncat_s\n- wcsncat_s\n- strtok_s\n- wcstok_s\n- sprintf_s\n- swprintf_s\n- vsprintf_s\n- vswprintf_s\n- snprintf_s\n- vsnprintf_s\n- scanf_s\n- wscanf_s\n- vscanf_s\n- vwscanf_s\n- fscanf_s\n- fwscanf_s\n- vfscanf_s\n- vfwscanf_s\n- sscanf_s\n- swscanf_s\n- vsscanf_s\n- vswscanf_s\n- gets_s\n\n#### 构建方法\n\n运行命令\n```\nmake CC=gcc\n```\n生成的动态库libboundscheck.so存放在新创建的lib目录下。\n\n#### 使用方法\n1. 将构建生成的动态库libboundscheck.so放到库文件目录下，例如：\"/usr/local/lib/\"。\n\n2. 为使用libboundscheck，编译程序时需增加编译参数\"-lboundscheck\"，例如：\"gcc -g -o test test.c -lboundscheck\"。"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/bundle.json",
    "content": "{\n    \"name\": \"@ohos/bounds_checking_function\",\n    \"description\": \"following the standard of C11 Annex K (bound-checking interfaces), functions of the common memory/string operation classes, such as memcpy_s, strcpy_s, are selected and implemented.\",\n    \"version\": \"3.1\",\n    \"license\": \"MulanPSL-2.0\",\n    \"publishAs\": \"code-segment\",\n    \"segment\": {\n        \"destPath\": \"third_party/bounds_checking_function\"\n    },\n    \"dirs\": {},\n    \"scripts\": {},\n    \"component\": {\n        \"name\": \"bounds_checking_function\",\n        \"subsystem\": \"thirdparty\",\n        \"syscap\": [],\n        \"features\": [],\n        \"adapted_system_type\": [\n            \"mini\",\n            \"small\",\n            \"standard\"\n        ],\n        \"rom\": \"\",\n        \"ram\": \"\",\n        \"deps\": {\n            \"components\": [],\n            \"third_party\": []\n        },\n        \"build\": {\n            \"sub_component\": [\n                \"//third_party/bounds_checking_function:libsec_shared\"\n            ],\n            \"inner_kits\": [\n                {\n                    \"name\": \"//third_party/bounds_checking_function:libsec_shared\",\n                    \"header\": {\n                        \"header_files\": [\n                            \"securec.h\",\n                            \"securectype.h\"\n                        ],\n                        \"header_base\": \"//third_party/bounds_checking_function/include\"\n                    }\n                },\n                {\n                    \"name\": \"//third_party/bounds_checking_function:libsec_static\",\n                    \"header\": {\n                        \"header_files\": [\n                            \"securec.h\",\n                            \"securectype.h\"\n                        ],\n                        \"header_base\": \"//third_party/bounds_checking_function/include\"\n                    }\n                }\n            ],\n            \"test\": []\n        }\n    }\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/include/securec.h",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: The user of this secure c library should include this header file in you source code.\n *              This header file declare all supported API prototype of the library,\n *              such as memcpy_s, strcpy_s, wcscpy_s,strcat_s, strncat_s, sprintf_s, scanf_s, and so on.\n * Create: 2014-02-25\n * Notes: Do not modify this file by yourself.\n */\n\n#ifndef SECUREC_H_5D13A042_DC3F_4ED9_A8D1_882811274C27\n#define SECUREC_H_5D13A042_DC3F_4ED9_A8D1_882811274C27\n\n#include \"securectype.h\"\n#ifndef SECUREC_HAVE_STDARG_H\n#define SECUREC_HAVE_STDARG_H 1\n#endif\n\n#if SECUREC_HAVE_STDARG_H\n#include <stdarg.h>\n#endif\n\n#ifndef SECUREC_HAVE_ERRNO_H\n#define SECUREC_HAVE_ERRNO_H 1\n#endif\n\n/* EINVAL ERANGE may defined in errno.h */\n#if SECUREC_HAVE_ERRNO_H\n#if SECUREC_IN_KERNEL\n#include <linux/errno.h>\n#else\n#include <errno.h>\n#endif\n#endif\n\n/* Define error code */\n#if defined(SECUREC_NEED_ERRNO_TYPE) || !defined(__STDC_WANT_LIB_EXT1__) || \\\n    (defined(__STDC_WANT_LIB_EXT1__) && (!__STDC_WANT_LIB_EXT1__))\n#ifndef SECUREC_DEFINED_ERRNO_TYPE\n#define SECUREC_DEFINED_ERRNO_TYPE\n/* Just check whether macrodefinition exists. */\n#ifndef errno_t\ntypedef int errno_t;\n#endif\n#endif\n#endif\n\n/* Success */\n#ifndef EOK\n#define EOK 0\n#endif\n\n#ifndef EINVAL\n/* The src buffer is not correct and destination buffer can not be reset */\n#define EINVAL 22\n#endif\n\n#ifndef EINVAL_AND_RESET\n/* Once the error is detected, the dest buffer must be reset! Value is 22 or 128 */\n#define EINVAL_AND_RESET 150\n#endif\n\n#ifndef ERANGE\n/* The destination buffer is not long enough and destination buffer can not be reset */\n#define ERANGE 34\n#endif\n\n#ifndef ERANGE_AND_RESET\n/* Once the error is detected, the dest buffer must be reset! Value is 34 or 128 */\n#define ERANGE_AND_RESET  162\n#endif\n\n#ifndef EOVERLAP_AND_RESET\n/* Once the buffer overlap is detected, the dest buffer must be reset! Value is 54 or 128 */\n#define EOVERLAP_AND_RESET 182\n#endif\n\n/* If you need export the function of this library in Win32 dll, use __declspec(dllexport) */\n#ifndef SECUREC_API\n#if defined(SECUREC_DLL_EXPORT)\n#if defined(_MSC_VER)\n#define SECUREC_API __declspec(dllexport)\n#else /* build for linux */\n#define SECUREC_API __attribute__((visibility(\"default\")))\n#endif /* end of _MSC_VER and SECUREC_DLL_EXPORT */\n#elif defined(SECUREC_DLL_IMPORT)\n#if defined(_MSC_VER)\n#define SECUREC_API __declspec(dllimport)\n#else\n#define SECUREC_API\n#endif /* end of _MSC_VER and SECUREC_DLL_IMPORT */\n#else\n/*\n * Standardized function declaration. If a security function is declared in the your code,\n * it may cause a compilation alarm,Please delete the security function you declared.\n * Adding extern under windows will cause the system to have inline functions to expand,\n * so do not add the extern in default\n */\n#if defined(_MSC_VER)\n#define SECUREC_API\n#else\n#define SECUREC_API extern\n#endif\n#endif\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n/*\n * Description: The GetHwSecureCVersion function get SecureC Version string and version number.\n * Parameter: verNumber - to store version number (for example value is 0x500 | 0xa)\n * Return:   version string\n */\nSECUREC_API const char *GetHwSecureCVersion(unsigned short *verNumber);\n\n#if SECUREC_ENABLE_MEMSET\n/*\n * Description: The memset_s function copies the value of c (converted to an unsigned char) into each of\n * the first count characters of the object pointed to by dest.\n * Parameter: dest - destination address\n * Parameter: destMax - The maximum length of destination buffer\n * Parameter: c - the value to be copied\n * Parameter: count - copies count bytes of value to dest\n * Return:    EOK if there was no runtime-constraint violation\n */\nSECUREC_API errno_t memset_s(void *dest, size_t destMax, int c, size_t count);\n#endif\n\n#ifndef SECUREC_ONLY_DECLARE_MEMSET\n#define SECUREC_ONLY_DECLARE_MEMSET     0\n#endif\n\n#if !SECUREC_ONLY_DECLARE_MEMSET\n\n#if SECUREC_ENABLE_MEMMOVE\n/*\n * Description: The memmove_s function copies n characters from the object pointed to by src\n * into the object pointed to by dest.\n * Parameter: dest - destination  address\n * Parameter: destMax - The maximum length of destination buffer\n * Parameter: src - source address\n * Parameter: count - copies count bytes from the src\n * Return:    EOK if there was no runtime-constraint violation\n */\nSECUREC_API errno_t memmove_s(void *dest, size_t destMax, const void *src, size_t count);\n#endif\n\n#if SECUREC_ENABLE_MEMCPY\n/*\n * Description: The memcpy_s function copies n characters from the object pointed to\n * by src into the object pointed to by dest.\n * Parameter: dest - destination  address\n * Parameter: destMax - The maximum length of destination buffer\n * Parameter: src - source address\n * Parameter: count - copies count bytes from the  src\n * Return:    EOK if there was no runtime-constraint violation\n */\nSECUREC_API errno_t memcpy_s(void *dest, size_t destMax, const void *src, size_t count);\n#endif\n\n#if SECUREC_ENABLE_STRCPY\n/*\n * Description: The strcpy_s function copies the string pointed to by strSrc (including\n * the terminating null character) into the array pointed to by strDest\n * Parameter: strDest - destination  address\n * Parameter: destMax - The maximum length of destination buffer(including the terminating null character)\n * Parameter: strSrc - source address\n * Return:    EOK if there was no runtime-constraint violation\n */\nSECUREC_API errno_t strcpy_s(char *strDest, size_t destMax, const char *strSrc);\n#endif\n\n#if SECUREC_ENABLE_STRNCPY\n/*\n * Description: The strncpy_s function copies not more than n successive characters (not including\n * the terminating null character) from the array pointed to by strSrc to the array pointed to by strDest.\n * Parameter: strDest - destination  address\n * Parameter: destMax - The maximum length of destination buffer(including the terminating null character)\n * Parameter: strSrc - source  address\n * Parameter: count - copies count characters from the src\n * Return:    EOK if there was no runtime-constraint violation\n */\nSECUREC_API errno_t strncpy_s(char *strDest, size_t destMax, const char *strSrc, size_t count);\n#endif\n\n#if SECUREC_ENABLE_STRCAT\n/*\n * Description: The strcat_s function appends a copy of the string pointed to by strSrc (including\n * the terminating null character) to the end of the string pointed to by strDest.\n * Parameter: strDest - destination  address\n * Parameter: destMax - The maximum length of destination buffer(including the terminating null wide character)\n * Parameter: strSrc - source address\n * Return:    EOK if there was no runtime-constraint violation\n */\nSECUREC_API errno_t strcat_s(char *strDest, size_t destMax, const char *strSrc);\n#endif\n\n#if SECUREC_ENABLE_STRNCAT\n/*\n * Description: The strncat_s function appends not more than n successive characters (not including\n * the terminating null character)\n * from the array pointed to by strSrc to the end of the string pointed to by strDest.\n * Parameter: strDest - destination address\n * Parameter: destMax - The maximum length of destination buffer(including the terminating null character)\n * Parameter: strSrc - source address\n * Parameter: count - copies count characters from the src\n * Return:    EOK if there was no runtime-constraint violation\n */\nSECUREC_API errno_t strncat_s(char *strDest, size_t destMax, const char *strSrc, size_t count);\n#endif\n\n#if SECUREC_ENABLE_VSPRINTF\n/*\n * Description: The vsprintf_s function is equivalent to the vsprintf function except for the parameter destMax\n * and the explicit runtime-constraints violation\n * Parameter: strDest -  produce output according to a format,write to the character string strDest.\n * Parameter: destMax - The maximum length of destination buffer(including the terminating null wide character)\n * Parameter: format - format string\n * Parameter: argList - instead of a variable number of arguments\n * Return:    the number of characters printed(not including the terminating null byte '\\0'),\n * If an error occurred Return: -1.\n */\nSECUREC_API int vsprintf_s(char *strDest, size_t destMax, const char *format,\n                           va_list argList) SECUREC_ATTRIBUTE(3, 0);\n#endif\n\n#if SECUREC_ENABLE_SPRINTF\n/*\n * Description: The sprintf_s function is equivalent to the sprintf function except for the parameter destMax\n * and the explicit runtime-constraints violation\n * Parameter: strDest -  produce output according to a format ,write to the character string strDest.\n * Parameter: destMax - The maximum length of destination buffer(including the terminating null byte '\\0')\n * Parameter: format - format string\n * Return:    the number of characters printed(not including the terminating null byte '\\0'),\n * If an error occurred Return: -1.\n*/\nSECUREC_API int sprintf_s(char *strDest, size_t destMax, const char *format, ...) SECUREC_ATTRIBUTE(3, 4);\n#endif\n\n#if SECUREC_ENABLE_VSNPRINTF\n/*\n * Description: The vsnprintf_s function is equivalent to the vsnprintf function except for\n * the parameter destMax/count and the explicit runtime-constraints violation\n * Parameter: strDest -  produce output according to a format ,write to the character string strDest.\n * Parameter: destMax - The maximum length of destination buffer(including the terminating null  byte '\\0')\n * Parameter: count - do not write more than count bytes to strDest(not including the terminating null  byte '\\0')\n * Parameter: format - format string\n * Parameter: argList - instead of  a variable number of arguments\n * Return:    the number of characters printed(not including the terminating null byte '\\0'),\n * If an error occurred Return: -1.Pay special attention to returning -1 when truncation occurs.\n */\nSECUREC_API int vsnprintf_s(char *strDest, size_t destMax, size_t count, const char *format,\n                            va_list argList) SECUREC_ATTRIBUTE(4, 0);\n#endif\n\n#if SECUREC_ENABLE_SNPRINTF\n/*\n * Description: The snprintf_s function is equivalent to the snprintf function except for\n * the parameter destMax/count and the explicit runtime-constraints violation\n * Parameter: strDest - produce output according to a format ,write to the character string strDest.\n * Parameter: destMax - The maximum length of destination buffer(including the terminating null  byte '\\0')\n * Parameter: count - do not write more than count bytes to strDest(not including the terminating null  byte '\\0')\n * Parameter: format - format string\n * Return:    the number of characters printed(not including the terminating null byte '\\0'),\n * If an error occurred Return: -1.Pay special attention to returning -1 when truncation occurs.\n */\nSECUREC_API int snprintf_s(char *strDest, size_t destMax, size_t count, const char *format,\n                           ...) SECUREC_ATTRIBUTE(4, 5);\n#endif\n\n#if SECUREC_SNPRINTF_TRUNCATED\n/*\n * Description: The vsnprintf_truncated_s function is equivalent to the vsnprintf_s function except\n * no count parameter and return value\n * Parameter: strDest -  produce output according to a format ,write to the character string strDest\n * Parameter: destMax - The maximum length of destination buffer(including the terminating null  byte '\\0')\n * Parameter: format - format string\n * Parameter: argList - instead of  a variable  number of arguments\n * Return:    the number of characters printed(not including the terminating null byte '\\0'),\n * If an error occurred Return: -1.Pay special attention to returning destMax - 1 when truncation occurs\n*/\nSECUREC_API int vsnprintf_truncated_s(char *strDest, size_t destMax, const char *format,\n                                      va_list argList) SECUREC_ATTRIBUTE(3, 0);\n\n/*\n * Description: The snprintf_truncated_s function is equivalent to the snprintf_s function except\n * no count parameter and return value\n * Parameter: strDest - produce output according to a format,write to the character string strDest.\n * Parameter: destMax - The maximum length of destination buffer(including the terminating null byte '\\0')\n * Parameter: format - format string\n * Return:    the number of characters printed(not including the terminating null byte '\\0'),\n * If an error occurred Return: -1.Pay special attention to returning destMax - 1 when truncation occurs.\n */\nSECUREC_API int snprintf_truncated_s(char *strDest, size_t destMax,\n                                     const char *format, ...) SECUREC_ATTRIBUTE(3, 4);\n#endif\n\n#if SECUREC_ENABLE_SCANF\n/*\n * Description: The scanf_s function is equivalent to fscanf_s with the argument stdin\n * interposed before the arguments to scanf_s\n * Parameter: format - format string\n * Return:    the number of input items assigned, If an error occurred Return: -1.\n */\nSECUREC_API int scanf_s(const char *format, ...);\n#endif\n\n#if SECUREC_ENABLE_VSCANF\n/*\n * Description: The vscanf_s function is equivalent to scanf_s, with the variable argument list replaced by argList\n * Parameter: format - format string\n * Parameter: argList - instead of a variable number of arguments\n * Return:    the number of input items assigned, If an error occurred Return: -1.\n */\nSECUREC_API int vscanf_s(const char *format, va_list argList);\n#endif\n\n#if SECUREC_ENABLE_SSCANF\n/*\n * Description: The sscanf_s function is equivalent to fscanf_s, except that input is obtained from a\n * string (specified by the argument buffer) rather than from a stream\n * Parameter: buffer - read character from buffer\n * Parameter: format - format string\n * Return:    the number of input items assigned, If an error occurred Return: -1.\n */\nSECUREC_API int sscanf_s(const char *buffer, const char *format, ...);\n#endif\n\n#if SECUREC_ENABLE_VSSCANF\n/*\n * Description: The vsscanf_s function is equivalent to sscanf_s, with the variable argument list\n * replaced by argList\n * Parameter: buffer -  read character from buffer\n * Parameter: format - format string\n * Parameter: argList - instead of a variable number of arguments\n * Return:    the number of input items assigned, If an error occurred Return: -1.\n */\nSECUREC_API int vsscanf_s(const char *buffer, const char *format, va_list argList);\n#endif\n\n#if SECUREC_ENABLE_FSCANF\n/*\n * Description: The fscanf_s function is equivalent to fscanf except that the c, s, and [ conversion specifiers\n * apply to a pair of arguments (unless assignment suppression is indicated by a *)\n * Parameter: stream - stdio file stream\n * Parameter: format - format string\n * Return:    the number of input items assigned, If an error occurred Return: -1.\n */\nSECUREC_API int fscanf_s(FILE *stream, const char *format, ...);\n#endif\n\n#if SECUREC_ENABLE_VFSCANF\n/*\n * Description: The vfscanf_s function is equivalent to fscanf_s, with the variable argument list\n * replaced by argList\n * Parameter: stream - stdio file stream\n * Parameter: format - format string\n * Parameter: argList - instead of a variable number of arguments\n * Return:    the number of input items assigned, If an error occurred Return: -1.\n */\nSECUREC_API int vfscanf_s(FILE *stream, const char *format, va_list argList);\n#endif\n\n#if SECUREC_ENABLE_STRTOK\n/*\n * Description: The strtok_s function parses a string into a sequence of strToken,\n * replace all characters in strToken string that match to strDelimit set with 0.\n * On the first call to strtok_s the string to be parsed should be specified in strToken.\n * In each subsequent call that should parse the same string, strToken should be NULL\n * Parameter: strToken - the string to be delimited\n * Parameter: strDelimit - specifies a set of characters that delimit the tokens in the parsed string\n * Parameter: context - is a pointer to a char * variable that is used internally by strtok_s function\n * Return:  On the first call returns the address of the first non \\0 character, otherwise NULL is returned.\n * In subsequent calls, the strtoken is set to NULL, and the context set is the same as the previous call,\n * return NULL if the *context string length is equal 0, otherwise return *context.\n */\nSECUREC_API char *strtok_s(char *strToken, const char *strDelimit, char **context);\n#endif\n\n#if SECUREC_ENABLE_GETS && !SECUREC_IN_KERNEL\n/*\n * Description: The gets_s function reads at most one less than the number of characters specified\n * by destMax from the stream pointed to by stdin, into the array pointed to by buffer\n * Parameter: buffer - destination address\n * Parameter: destMax - The maximum length of destination buffer(including the terminating null character)\n * Return:    buffer if there was no runtime-constraint violation,If an error occurred Return: NULL.\n */\nSECUREC_API char *gets_s(char *buffer, size_t destMax);\n#endif\n\n#if SECUREC_ENABLE_WCHAR_FUNC\n#if SECUREC_ENABLE_MEMCPY\n/*\n * Description: The wmemcpy_s function copies n successive wide characters from the object pointed to\n * by src into the object pointed to by dest.\n * Parameter: dest - destination  address\n * Parameter: destMax - The maximum length of destination buffer\n * Parameter: src - source address\n * Parameter: count - copies count wide characters from the  src\n * Return:    EOK if there was no runtime-constraint violation\n */\nSECUREC_API errno_t wmemcpy_s(wchar_t *dest, size_t destMax, const wchar_t *src, size_t count);\n#endif\n\n#if SECUREC_ENABLE_MEMMOVE\n/*\n * Description: The wmemmove_s function copies n successive wide characters from the object\n * pointed to by src into the object pointed to by dest.\n * Parameter: dest - destination  address\n * Parameter: destMax - The maximum length of destination buffer\n * Parameter: src - source address\n * Parameter: count - copies count wide characters from the  src\n * Return:    EOK if there was no runtime-constraint violation\n */\nSECUREC_API errno_t wmemmove_s(wchar_t *dest, size_t destMax, const wchar_t *src, size_t count);\n#endif\n\n#if SECUREC_ENABLE_STRCPY\n/*\n * Description: The wcscpy_s function copies the wide string pointed to by strSrc(including the terminating\n * null wide character) into the array pointed to by strDest\n * Parameter: strDest - destination address\n * Parameter: destMax - The maximum length of destination buffer\n * Parameter: strSrc - source address\n * Return:    EOK if there was no runtime-constraint violation\n */\nSECUREC_API errno_t wcscpy_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc);\n#endif\n\n#if SECUREC_ENABLE_STRNCPY\n/*\n * Description: The wcsncpy_s function copies not more than n successive wide characters (not including the\n * terminating null wide character) from the array pointed to by strSrc to the array pointed to by strDest\n * Parameter: strDest - destination address\n * Parameter: destMax - The maximum length of destination buffer(including the terminating wide character)\n * Parameter: strSrc - source address\n * Parameter: count - copies count wide characters from the src\n * Return:    EOK if there was no runtime-constraint violation\n */\nSECUREC_API errno_t wcsncpy_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, size_t count);\n#endif\n\n#if SECUREC_ENABLE_STRCAT\n/*\n * Description: The wcscat_s function appends a copy of the wide string pointed to by strSrc (including the\n * terminating null wide character) to the end of the wide string pointed to by strDest\n * Parameter: strDest - destination  address\n * Parameter: destMax - The maximum length of destination buffer(including the terminating wide character)\n * Parameter: strSrc - source address\n * Return:    EOK if there was no runtime-constraint violation\n */\nSECUREC_API errno_t wcscat_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc);\n#endif\n\n#if SECUREC_ENABLE_STRNCAT\n/*\n * Description: The wcsncat_s function appends not more than n successive wide characters (not including the\n * terminating null wide character) from the array pointed to by strSrc to the end of the wide string pointed to\n * by strDest.\n * Parameter: strDest - destination  address\n * Parameter: destMax - The maximum length of destination buffer(including the terminating wide character)\n * Parameter: strSrc - source  address\n * Parameter: count - copies count wide characters from the  src\n * Return:    EOK if there was no runtime-constraint violation\n */\nSECUREC_API errno_t wcsncat_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, size_t count);\n#endif\n\n#if SECUREC_ENABLE_STRTOK\n/*\n * Description: The wcstok_s function is the wide-character equivalent of the strtok_s function\n * Parameter: strToken - the string to be delimited\n * Parameter: strDelimit - specifies a set of characters that delimit the tokens in the parsed string\n * Parameter: context - is a pointer to a char * variable that is used internally by strtok_s function\n * Return:    a pointer to the first character of a token, or a null pointer if there is no token\n * or there is a runtime-constraint violation.\n */\nSECUREC_API wchar_t *wcstok_s(wchar_t *strToken, const wchar_t *strDelimit, wchar_t **context);\n#endif\n\n#if SECUREC_ENABLE_VSPRINTF\n/*\n * Description: The vswprintf_s function is the wide-character equivalent of the vsprintf_s function\n * Parameter: strDest - produce output according to a format,write to the character string strDest\n * Parameter: destMax - The maximum length of destination buffer(including the terminating null)\n * Parameter: format - format string\n * Parameter: argList - instead of a variable number of arguments\n * Return:    the number of characters printed(not including the terminating null wide character),\n * If an error occurred Return: -1.\n */\nSECUREC_API int vswprintf_s(wchar_t *strDest, size_t destMax, const wchar_t *format, va_list argList);\n#endif\n\n#if SECUREC_ENABLE_SPRINTF\n/*\n * Description: The swprintf_s function is the wide-character equivalent of the sprintf_s function\n * Parameter: strDest - produce output according to a format,write to the character string strDest\n * Parameter: destMax - The maximum length of destination buffer(including the terminating null)\n * Parameter: format - format string\n * Return:    the number of characters printed(not including the terminating null wide character),\n * If an error occurred Return: -1.\n */\nSECUREC_API int swprintf_s(wchar_t *strDest, size_t destMax, const wchar_t *format, ...);\n#endif\n\n#if SECUREC_ENABLE_FSCANF\n/*\n * Description: The fwscanf_s function is the wide-character equivalent of the fscanf_s function\n * Parameter: stream - stdio file stream\n * Parameter: format - format string\n * Return:    the number of input items assigned, If an error occurred Return: -1.\n */\nSECUREC_API int fwscanf_s(FILE *stream, const wchar_t *format, ...);\n#endif\n\n#if SECUREC_ENABLE_VFSCANF\n/*\n * Description: The vfwscanf_s function is the wide-character equivalent of the vfscanf_s function\n * Parameter: stream - stdio file stream\n * Parameter: format - format string\n * Parameter: argList - instead of  a variable number of arguments\n * Return:    the number of input items assigned, If an error occurred Return: -1.\n */\nSECUREC_API int vfwscanf_s(FILE *stream, const wchar_t *format, va_list argList);\n#endif\n\n#if SECUREC_ENABLE_SCANF\n/*\n * Description: The wscanf_s function is the wide-character equivalent of the scanf_s function\n * Parameter: format - format string\n * Return:    the number of input items assigned, If an error occurred Return: -1.\n */\nSECUREC_API int wscanf_s(const wchar_t *format, ...);\n#endif\n\n#if SECUREC_ENABLE_VSCANF\n/*\n * Description: The vwscanf_s function is the wide-character equivalent of the vscanf_s function\n * Parameter: format - format string\n * Parameter: argList - instead of  a variable number of arguments\n * Return:    the number of input items assigned, If an error occurred Return: -1.\n */\nSECUREC_API int vwscanf_s(const wchar_t *format, va_list argList);\n#endif\n\n#if SECUREC_ENABLE_SSCANF\n/*\n * Description: The swscanf_s function is the wide-character equivalent of the sscanf_s function\n * Parameter: buffer - read character from buffer\n * Parameter: format - format string\n * Return:    the number of input items assigned, If an error occurred Return: -1.\n */\nSECUREC_API int swscanf_s(const wchar_t *buffer, const wchar_t *format, ...);\n#endif\n\n#if SECUREC_ENABLE_VSSCANF\n/*\n * Description: The vswscanf_s function is the wide-character equivalent of the vsscanf_s function\n * Parameter: buffer -  read character from  buffer\n * Parameter: format - format string\n * Parameter: argList - instead of  a variable number of arguments\n * Return:    the number of input items assigned, If an error occurred Return: -1.\n */\nSECUREC_API int vswscanf_s(const wchar_t *buffer, const wchar_t *format, va_list argList);\n#endif\n#endif /* SECUREC_ENABLE_WCHAR_FUNC */\n#endif\n\n/* Those functions are used by macro,must declare hare, also for without function declaration warning */\nextern errno_t strncpy_error(char *strDest, size_t destMax, const char *strSrc, size_t count);\nextern errno_t strcpy_error(char *strDest, size_t destMax, const char *strSrc);\n\n#if SECUREC_WITH_PERFORMANCE_ADDONS\n/* Those functions are used by macro */\nextern errno_t memset_sOptAsm(void *dest, size_t destMax, int c, size_t count);\nextern errno_t memset_sOptTc(void *dest, size_t destMax, int c, size_t count);\nextern errno_t memcpy_sOptAsm(void *dest, size_t destMax, const void *src, size_t count);\nextern errno_t memcpy_sOptTc(void *dest, size_t destMax, const void *src, size_t count);\n\n/* The strcpy_sp is a macro, not a function in performance optimization mode. */\n#define strcpy_sp(dest, destMax, src)  ((__builtin_constant_p((destMax)) && \\\n    __builtin_constant_p((src))) ?  \\\n    SECUREC_STRCPY_SM((dest), (destMax), (src)) : \\\n    strcpy_s((dest), (destMax), (src)))\n\n/* The strncpy_sp is a macro, not a function in performance optimization mode. */\n#define strncpy_sp(dest, destMax, src, count)  ((__builtin_constant_p((count)) && \\\n    __builtin_constant_p((destMax)) && \\\n    __builtin_constant_p((src))) ?  \\\n    SECUREC_STRNCPY_SM((dest), (destMax), (src), (count)) : \\\n    strncpy_s((dest), (destMax), (src), (count)))\n\n/* The strcat_sp is a macro, not a function in performance optimization mode. */\n#define strcat_sp(dest, destMax, src) ((__builtin_constant_p((destMax)) && \\\n    __builtin_constant_p((src))) ?  \\\n    SECUREC_STRCAT_SM((dest), (destMax), (src)) : \\\n    strcat_s((dest), (destMax), (src)))\n\n/* The strncat_sp is a macro, not a function in performance optimization mode. */\n#define strncat_sp(dest, destMax, src, count) ((__builtin_constant_p((count)) &&  \\\n    __builtin_constant_p((destMax)) && \\\n    __builtin_constant_p((src))) ?  \\\n    SECUREC_STRNCAT_SM((dest), (destMax), (src), (count)) : \\\n    strncat_s((dest), (destMax), (src), (count)))\n\n/* The memcpy_sp is a macro, not a function in performance optimization mode. */\n#define memcpy_sp(dest, destMax, src, count)  (__builtin_constant_p((count)) ? \\\n    (SECUREC_MEMCPY_SM((dest), (destMax), (src), (count))) : \\\n    (__builtin_constant_p((destMax)) ? \\\n    (((size_t)(destMax) > 0 && \\\n    (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_MEM_MAX_LEN)) ? \\\n    memcpy_sOptTc((dest), (destMax), (src), (count)) : ERANGE) : \\\n    memcpy_sOptAsm((dest), (destMax), (src), (count))))\n\n/* The memset_sp is a macro, not a function in performance optimization mode. */\n#define memset_sp(dest, destMax, c, count)  (__builtin_constant_p((count)) ? \\\n    (SECUREC_MEMSET_SM((dest), (destMax), (c), (count))) : \\\n    (__builtin_constant_p((destMax)) ? \\\n    (((((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_MEM_MAX_LEN)) ? \\\n    memset_sOptTc((dest), (destMax), (c), (count)) : ERANGE) : \\\n    memset_sOptAsm((dest), (destMax), (c), (count))))\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/include/securectype.h",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: Define internal used macro and data type. The marco of SECUREC_ON_64BITS\n *              will be determined in this header file, which is a switch for part\n *              of code. Some macro are used to suppress warning by MS compiler.\n * Create: 2014-02-25\n * Notes: User can change the value of SECUREC_STRING_MAX_LEN and SECUREC_MEM_MAX_LEN\n *        macro to meet their special need, but The maximum value should not exceed 2G.\n */\n/*\n * [Standardize-exceptions]: Performance-sensitive\n * [reason]: Strict parameter verification has been done before use\n */\n\n#ifndef SECURECTYPE_H_A7BBB686_AADA_451B_B9F9_44DACDAE18A7\n#define SECURECTYPE_H_A7BBB686_AADA_451B_B9F9_44DACDAE18A7\n\n#ifndef SECUREC_USING_STD_SECURE_LIB\n#if defined(_MSC_VER) && _MSC_VER >= 1400\n#if defined(__STDC_WANT_SECURE_LIB__) && (!__STDC_WANT_SECURE_LIB__)\n/* Security functions have been provided since vs2005, default use of system library functions */\n#define SECUREC_USING_STD_SECURE_LIB    0\n#else\n#define SECUREC_USING_STD_SECURE_LIB    1\n#endif\n#else\n#define SECUREC_USING_STD_SECURE_LIB    0\n#endif\n#endif\n\n/* Compatibility with older Secure C versions, shielding VC symbol redefinition warning */\n#if defined(_MSC_VER) && (_MSC_VER >= 1400) && (!SECUREC_USING_STD_SECURE_LIB)\n#ifndef SECUREC_DISABLE_CRT_FUNC\n#define SECUREC_DISABLE_CRT_FUNC        1\n#endif\n#ifndef SECUREC_DISABLE_CRT_IMP\n#define SECUREC_DISABLE_CRT_IMP         1\n#endif\n#else /*  MSC VER */\n#ifndef SECUREC_DISABLE_CRT_FUNC\n#define SECUREC_DISABLE_CRT_FUNC        0\n#endif\n#ifndef SECUREC_DISABLE_CRT_IMP\n#define SECUREC_DISABLE_CRT_IMP         0\n#endif\n#endif\n\n#if SECUREC_DISABLE_CRT_FUNC\n#ifdef __STDC_WANT_SECURE_LIB__\n#undef __STDC_WANT_SECURE_LIB__\n#endif\n#define __STDC_WANT_SECURE_LIB__        0\n#endif\n\n#if SECUREC_DISABLE_CRT_IMP\n#ifdef _CRTIMP_ALTERNATIVE\n#undef _CRTIMP_ALTERNATIVE\n#endif\n#define _CRTIMP_ALTERNATIVE     /* Comment Microsoft *_s function */\n#endif\n\n/* Compile in kernel under macro control */\n#ifndef SECUREC_IN_KERNEL\n#ifdef __KERNEL__\n#define SECUREC_IN_KERNEL               1\n#else\n#define SECUREC_IN_KERNEL               0\n#endif\n#endif\n\n/* make kernel symbols of functions available to loadable modules */\n#ifndef SECUREC_EXPORT_KERNEL_SYMBOL\n#if SECUREC_IN_KERNEL\n#define SECUREC_EXPORT_KERNEL_SYMBOL    1\n#else\n#define SECUREC_EXPORT_KERNEL_SYMBOL    0\n#endif\n#endif\n\n#if SECUREC_IN_KERNEL\n#ifndef SECUREC_ENABLE_SCANF_FILE\n#define SECUREC_ENABLE_SCANF_FILE       0\n#endif\n#ifndef SECUREC_ENABLE_WCHAR_FUNC\n#define SECUREC_ENABLE_WCHAR_FUNC       0\n#endif\n#else /* SECUREC_IN_KERNEL */\n#ifndef SECUREC_ENABLE_SCANF_FILE\n#define SECUREC_ENABLE_SCANF_FILE       1\n#endif\n#ifndef SECUREC_ENABLE_WCHAR_FUNC\n#define SECUREC_ENABLE_WCHAR_FUNC       1\n#endif\n#endif\n\n/* Default secure function declaration, default declarations for non-standard functions */\n#ifndef SECUREC_SNPRINTF_TRUNCATED\n#define SECUREC_SNPRINTF_TRUNCATED      1\n#endif\n\n#if SECUREC_USING_STD_SECURE_LIB\n#if defined(_MSC_VER) && _MSC_VER >= 1400\n/* Declare secure functions that are not available in the VS compiler */\n#ifndef SECUREC_ENABLE_MEMSET\n#define SECUREC_ENABLE_MEMSET           1\n#endif\n/* VS 2005 have vsnprintf_s function */\n#ifndef SECUREC_ENABLE_VSNPRINTF\n#define SECUREC_ENABLE_VSNPRINTF        0\n#endif\n#ifndef SECUREC_ENABLE_SNPRINTF\n/* VS 2005 have vsnprintf_s function Adapt the snprintf_s of the security function */\n#define snprintf_s _snprintf_s\n#define SECUREC_ENABLE_SNPRINTF         0\n#endif\n/* Before VS 2010 do not have v functions */\n#if _MSC_VER <= 1600 || defined(SECUREC_FOR_V_SCANFS)\n#ifndef SECUREC_ENABLE_VFSCANF\n#define SECUREC_ENABLE_VFSCANF          1\n#endif\n#ifndef SECUREC_ENABLE_VSCANF\n#define SECUREC_ENABLE_VSCANF           1\n#endif\n#ifndef SECUREC_ENABLE_VSSCANF\n#define SECUREC_ENABLE_VSSCANF          1\n#endif\n#endif\n\n#else /* MSC VER */\n#ifndef SECUREC_ENABLE_MEMSET\n#define SECUREC_ENABLE_MEMSET           0\n#endif\n#ifndef SECUREC_ENABLE_SNPRINTF\n#define SECUREC_ENABLE_SNPRINTF         0\n#endif\n#ifndef SECUREC_ENABLE_VSNPRINTF\n#define SECUREC_ENABLE_VSNPRINTF        0\n#endif\n#endif\n\n#ifndef SECUREC_ENABLE_MEMMOVE\n#define SECUREC_ENABLE_MEMMOVE          0\n#endif\n#ifndef SECUREC_ENABLE_MEMCPY\n#define SECUREC_ENABLE_MEMCPY           0\n#endif\n#ifndef SECUREC_ENABLE_STRCPY\n#define SECUREC_ENABLE_STRCPY           0\n#endif\n#ifndef SECUREC_ENABLE_STRNCPY\n#define SECUREC_ENABLE_STRNCPY          0\n#endif\n#ifndef SECUREC_ENABLE_STRCAT\n#define SECUREC_ENABLE_STRCAT           0\n#endif\n#ifndef SECUREC_ENABLE_STRNCAT\n#define SECUREC_ENABLE_STRNCAT          0\n#endif\n#ifndef SECUREC_ENABLE_SPRINTF\n#define SECUREC_ENABLE_SPRINTF          0\n#endif\n#ifndef SECUREC_ENABLE_VSPRINTF\n#define SECUREC_ENABLE_VSPRINTF          0\n#endif\n#ifndef SECUREC_ENABLE_SSCANF\n#define SECUREC_ENABLE_SSCANF           0\n#endif\n#ifndef SECUREC_ENABLE_VSSCANF\n#define SECUREC_ENABLE_VSSCANF          0\n#endif\n#ifndef SECUREC_ENABLE_SCANF\n#define SECUREC_ENABLE_SCANF            0\n#endif\n#ifndef SECUREC_ENABLE_VSCANF\n#define SECUREC_ENABLE_VSCANF           0\n#endif\n\n#ifndef SECUREC_ENABLE_FSCANF\n#define SECUREC_ENABLE_FSCANF           0\n#endif\n#ifndef SECUREC_ENABLE_VFSCANF\n#define SECUREC_ENABLE_VFSCANF          0\n#endif\n#ifndef SECUREC_ENABLE_STRTOK\n#define SECUREC_ENABLE_STRTOK           0\n#endif\n#ifndef SECUREC_ENABLE_GETS\n#define SECUREC_ENABLE_GETS             0\n#endif\n\n#else /* SECUREC USE STD SECURE LIB */\n\n#ifndef SECUREC_ENABLE_MEMSET\n#define SECUREC_ENABLE_MEMSET           1\n#endif\n#ifndef SECUREC_ENABLE_MEMMOVE\n#define SECUREC_ENABLE_MEMMOVE          1\n#endif\n#ifndef SECUREC_ENABLE_MEMCPY\n#define SECUREC_ENABLE_MEMCPY           1\n#endif\n#ifndef SECUREC_ENABLE_STRCPY\n#define SECUREC_ENABLE_STRCPY           1\n#endif\n#ifndef SECUREC_ENABLE_STRNCPY\n#define SECUREC_ENABLE_STRNCPY          1\n#endif\n#ifndef SECUREC_ENABLE_STRCAT\n#define SECUREC_ENABLE_STRCAT           1\n#endif\n#ifndef SECUREC_ENABLE_STRNCAT\n#define SECUREC_ENABLE_STRNCAT          1\n#endif\n#ifndef SECUREC_ENABLE_SPRINTF\n#define SECUREC_ENABLE_SPRINTF          1\n#endif\n#ifndef SECUREC_ENABLE_VSPRINTF\n#define SECUREC_ENABLE_VSPRINTF          1\n#endif\n#ifndef SECUREC_ENABLE_SNPRINTF\n#define SECUREC_ENABLE_SNPRINTF         1\n#endif\n#ifndef SECUREC_ENABLE_VSNPRINTF\n#define SECUREC_ENABLE_VSNPRINTF        1\n#endif\n#ifndef SECUREC_ENABLE_SSCANF\n#define SECUREC_ENABLE_SSCANF           1\n#endif\n#ifndef SECUREC_ENABLE_VSSCANF\n#define SECUREC_ENABLE_VSSCANF          1\n#endif\n#ifndef SECUREC_ENABLE_SCANF\n#if SECUREC_ENABLE_SCANF_FILE\n#define SECUREC_ENABLE_SCANF            1\n#else\n#define SECUREC_ENABLE_SCANF            0\n#endif\n#endif\n#ifndef SECUREC_ENABLE_VSCANF\n#if SECUREC_ENABLE_SCANF_FILE\n#define SECUREC_ENABLE_VSCANF           1\n#else\n#define SECUREC_ENABLE_VSCANF           0\n#endif\n#endif\n\n#ifndef SECUREC_ENABLE_FSCANF\n#if SECUREC_ENABLE_SCANF_FILE\n#define SECUREC_ENABLE_FSCANF           1\n#else\n#define SECUREC_ENABLE_FSCANF           0\n#endif\n#endif\n#ifndef SECUREC_ENABLE_VFSCANF\n#if SECUREC_ENABLE_SCANF_FILE\n#define SECUREC_ENABLE_VFSCANF          1\n#else\n#define SECUREC_ENABLE_VFSCANF          0\n#endif\n#endif\n\n#ifndef SECUREC_ENABLE_STRTOK\n#define SECUREC_ENABLE_STRTOK           1\n#endif\n#ifndef SECUREC_ENABLE_GETS\n#define SECUREC_ENABLE_GETS             1\n#endif\n#endif /* SECUREC_USE_STD_SECURE_LIB */\n\n#if !SECUREC_ENABLE_SCANF_FILE\n#if SECUREC_ENABLE_FSCANF\n#undef SECUREC_ENABLE_FSCANF\n#define SECUREC_ENABLE_FSCANF           0\n#endif\n#if SECUREC_ENABLE_VFSCANF\n#undef SECUREC_ENABLE_VFSCANF\n#define SECUREC_ENABLE_VFSCANF          0\n#endif\n#if SECUREC_ENABLE_SCANF\n#undef SECUREC_ENABLE_SCANF\n#define SECUREC_ENABLE_SCANF            0\n#endif\n#if SECUREC_ENABLE_FSCANF\n#undef SECUREC_ENABLE_FSCANF\n#define SECUREC_ENABLE_FSCANF           0\n#endif\n\n#endif\n\n#if SECUREC_IN_KERNEL\n#include <linux/kernel.h>\n#include <linux/module.h>\n#else\n#ifndef SECUREC_HAVE_STDIO_H\n#define SECUREC_HAVE_STDIO_H 1\n#endif\n#ifndef SECUREC_HAVE_STRING_H\n#define SECUREC_HAVE_STRING_H 1\n#endif\n#ifndef SECUREC_HAVE_STDLIB_H\n#define SECUREC_HAVE_STDLIB_H 1\n#endif\n#if SECUREC_HAVE_STDIO_H\n#include <stdio.h>\n#endif\n#if SECUREC_HAVE_STRING_H\n#include <string.h>\n#endif\n#if SECUREC_HAVE_STDLIB_H\n#include <stdlib.h>\n#endif\n#endif\n\n/*\n * If you need high performance, enable the SECUREC_WITH_PERFORMANCE_ADDONS macro, default is enable.\n * The macro is automatically closed on the windows platform and linux kernel\n */\n#ifndef SECUREC_WITH_PERFORMANCE_ADDONS\n#if SECUREC_IN_KERNEL\n#define SECUREC_WITH_PERFORMANCE_ADDONS 0\n#else\n#define SECUREC_WITH_PERFORMANCE_ADDONS 1\n#endif\n#endif\n\n/* If enable SECUREC_COMPATIBLE_WIN_FORMAT, the output format will be compatible to Windows. */\n#if (defined(_WIN32) || defined(_WIN64) || defined(_MSC_VER)) && !defined(SECUREC_COMPATIBLE_LINUX_FORMAT)\n#ifndef SECUREC_COMPATIBLE_WIN_FORMAT\n#define SECUREC_COMPATIBLE_WIN_FORMAT\n#endif\n#endif\n\n#if defined(SECUREC_COMPATIBLE_WIN_FORMAT)\n/* On windows platform, can't use optimized function for there is no __builtin_constant_p like function */\n/* If need optimized macro, can define this: define __builtin_constant_p(x) 0 */\n#ifdef SECUREC_WITH_PERFORMANCE_ADDONS\n#undef SECUREC_WITH_PERFORMANCE_ADDONS\n#define SECUREC_WITH_PERFORMANCE_ADDONS 0\n#endif\n#endif\n\n#if defined(__VXWORKS__) || defined(__vxworks) || defined(__VXWORKS) || defined(_VXWORKS_PLATFORM_)  || \\\n    defined(SECUREC_VXWORKS_VERSION_5_4)\n#ifndef SECUREC_VXWORKS_PLATFORM\n#define SECUREC_VXWORKS_PLATFORM\n#endif\n#endif\n\n/* If enable SECUREC_COMPATIBLE_LINUX_FORMAT, the output format will be compatible to Linux. */\n#if !defined(SECUREC_COMPATIBLE_WIN_FORMAT) && !defined(SECUREC_VXWORKS_PLATFORM)\n#ifndef SECUREC_COMPATIBLE_LINUX_FORMAT\n#define SECUREC_COMPATIBLE_LINUX_FORMAT\n#endif\n#endif\n\n#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT\n#ifndef SECUREC_HAVE_STDDEF_H\n#define SECUREC_HAVE_STDDEF_H 1\n#endif\n/* Some system may no stddef.h */\n#if SECUREC_HAVE_STDDEF_H\n#if !SECUREC_IN_KERNEL\n#include <stddef.h>\n#endif\n#endif\n#endif\n\n/*\n * Add  the -DSECUREC_SUPPORT_FORMAT_WARNING=1  compiler option to supoort  -Wformat=2.\n * Default does not check the format is that the same data type in the actual code.\n * In the product is different in the original data type definition of VxWorks and Linux.\n */\n#ifndef SECUREC_SUPPORT_FORMAT_WARNING\n#define SECUREC_SUPPORT_FORMAT_WARNING 0\n#endif\n\n#if SECUREC_SUPPORT_FORMAT_WARNING\n#define SECUREC_ATTRIBUTE(x, y)  __attribute__((format(printf, (x), (y))))\n#else\n#define SECUREC_ATTRIBUTE(x, y)\n#endif\n\n/*\n * Add the -DSECUREC_SUPPORT_BUILTIN_EXPECT=0 compiler option, if compiler can not support __builtin_expect.\n */\n#ifndef SECUREC_SUPPORT_BUILTIN_EXPECT\n#define SECUREC_SUPPORT_BUILTIN_EXPECT 1\n#endif\n\n#if SECUREC_SUPPORT_BUILTIN_EXPECT && defined(__GNUC__) && ((__GNUC__ > 3) || \\\n    (defined(__GNUC_MINOR__) && (__GNUC__ == 3 && __GNUC_MINOR__ > 3)))\n/*\n * This is a built-in function that can be used without a declaration, if warning for declaration not found occurred,\n * you can add -DSECUREC_NEED_BUILTIN_EXPECT_DECLARE to compiler options\n */\n#ifdef SECUREC_NEED_BUILTIN_EXPECT_DECLARE\nlong __builtin_expect(long exp, long c);\n#endif\n\n#define SECUREC_LIKELY(x) __builtin_expect(!!(x), 1)\n#define SECUREC_UNLIKELY(x) __builtin_expect(!!(x), 0)\n#else\n#define SECUREC_LIKELY(x) (x)\n#define SECUREC_UNLIKELY(x) (x)\n#endif\n\n/* Define the max length of the string */\n#ifndef SECUREC_STRING_MAX_LEN\n#define SECUREC_STRING_MAX_LEN 0x7fffffffUL\n#endif\n#define SECUREC_WCHAR_STRING_MAX_LEN (SECUREC_STRING_MAX_LEN / sizeof(wchar_t))\n\n/* Add SECUREC_MEM_MAX_LEN for memcpy and memmove */\n#ifndef SECUREC_MEM_MAX_LEN\n#define SECUREC_MEM_MAX_LEN 0x7fffffffUL\n#endif\n#define SECUREC_WCHAR_MEM_MAX_LEN (SECUREC_MEM_MAX_LEN / sizeof(wchar_t))\n\n#if SECUREC_STRING_MAX_LEN > 0x7fffffffUL\n#error \"max string is 2G\"\n#endif\n\n#if (defined(__GNUC__) && defined(__SIZEOF_POINTER__))\n#if (__SIZEOF_POINTER__ != 4) && (__SIZEOF_POINTER__ != 8)\n#error \"unsupported system\"\n#endif\n#endif\n\n#if defined(_WIN64) || defined(WIN64) || defined(__LP64__) || defined(_LP64)\n#define SECUREC_ON_64BITS\n#endif\n\n#if (!defined(SECUREC_ON_64BITS) && defined(__GNUC__) && defined(__SIZEOF_POINTER__))\n#if __SIZEOF_POINTER__ == 8\n#define SECUREC_ON_64BITS\n#endif\n#endif\n\n#if defined(__SVR4) || defined(__svr4__)\n#define SECUREC_ON_SOLARIS\n#endif\n\n#if (defined(__hpux) || defined(_AIX) || defined(SECUREC_ON_SOLARIS))\n#define SECUREC_ON_UNIX\n#endif\n\n/*\n * Codes should run under the macro SECUREC_COMPATIBLE_LINUX_FORMAT in unknown system on default,\n * and strtold.\n * The function strtold is referenced first at ISO9899:1999(C99), and some old compilers can\n * not support these functions. Here provides a macro to open these functions:\n * SECUREC_SUPPORT_STRTOLD  -- If defined, strtold will be used\n */\n#ifndef SECUREC_SUPPORT_STRTOLD\n#define SECUREC_SUPPORT_STRTOLD 0\n#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT))\n#if defined(__USE_ISOC99)  || \\\n    (defined(_AIX) && defined(_ISOC99_SOURCE)) || \\\n    (defined(__hpux) && defined(__ia64)) || \\\n    (defined(SECUREC_ON_SOLARIS) && (!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) || \\\n    defined(_STDC_C99) || defined(__EXTENSIONS__))\n#undef  SECUREC_SUPPORT_STRTOLD\n#define SECUREC_SUPPORT_STRTOLD 1\n#endif\n#endif\n#if ((defined(SECUREC_WRLINUX_BELOW4) || defined(_WRLINUX_BELOW4_)))\n#undef  SECUREC_SUPPORT_STRTOLD\n#define SECUREC_SUPPORT_STRTOLD 0\n#endif\n#endif\n\n#if SECUREC_WITH_PERFORMANCE_ADDONS\n\n#ifndef SECUREC_TWO_MIN\n#define SECUREC_TWO_MIN(a, b) ((a) < (b) ? (a) : (b))\n#endif\n\n/* For strncpy_s performance optimization */\n#define SECUREC_STRNCPY_SM(dest, destMax, src, count) \\\n    (((void *)(dest) != NULL && (const void *)(src) != NULL && (size_t)(destMax) > 0 && \\\n    (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN) && \\\n    (SECUREC_TWO_MIN((size_t)(count), strlen(src)) + 1) <= (size_t)(destMax)) ? \\\n    (((size_t)(count) < strlen(src)) ? (memcpy((dest), (src), (count)), *((char *)(dest) + (count)) = '\\0', EOK) : \\\n    (memcpy((dest), (src), strlen(src) + 1), EOK)) : (strncpy_error((dest), (destMax), (src), (count))))\n\n#define SECUREC_STRCPY_SM(dest, destMax, src) \\\n    (((void *)(dest) != NULL && (const void *)(src) != NULL && (size_t)(destMax) > 0 && \\\n    (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN) && \\\n    (strlen(src) + 1) <= (size_t)(destMax)) ? (memcpy((dest), (src), strlen(src) + 1), EOK) : \\\n    (strcpy_error((dest), (destMax), (src))))\n\n/* For strcat_s performance optimization */\n#if defined(__GNUC__)\n#define SECUREC_STRCAT_SM(dest, destMax, src) ({ \\\n    int catRet_ = EOK; \\\n    if ((void *)(dest) != NULL && (const void *)(src) != NULL && (size_t)(destMax) > 0 && \\\n        (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN)) { \\\n        char *catTmpDst_ = (char *)(dest); \\\n        size_t catRestSize_ = (destMax); \\\n        while (catRestSize_ > 0 && *catTmpDst_ != '\\0') { \\\n            ++catTmpDst_; \\\n            --catRestSize_; \\\n        } \\\n        if (catRestSize_ == 0) { \\\n            catRet_ = EINVAL; \\\n        } else if ((strlen(src) + 1) <= catRestSize_) { \\\n            memcpy(catTmpDst_, (src), strlen(src) + 1); \\\n            catRet_ = EOK; \\\n        } else { \\\n            catRet_ = ERANGE; \\\n        } \\\n        if (catRet_ != EOK) { \\\n            catRet_ = strcat_s((dest), (destMax), (src)); \\\n        } \\\n    } else { \\\n        catRet_ = strcat_s((dest), (destMax), (src)); \\\n    } \\\n    catRet_; \\\n})\n#else\n#define SECUREC_STRCAT_SM(dest, destMax, src) strcat_s((dest), (destMax), (src))\n#endif\n\n/* For strncat_s performance optimization */\n#if defined(__GNUC__)\n#define SECUREC_STRNCAT_SM(dest, destMax, src, count) ({ \\\n    int ncatRet_ = EOK; \\\n    if ((void *)(dest) != NULL && (const void *)(src) != NULL && (size_t)(destMax) > 0 && \\\n        (((unsigned long long)(destMax) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN)  && \\\n        (((unsigned long long)(count) & (unsigned long long)(-2)) < SECUREC_STRING_MAX_LEN)) { \\\n        char *ncatTmpDest_ = (char *)(dest); \\\n        size_t ncatRestSize_ = (size_t)(destMax); \\\n        while (ncatRestSize_ > 0 && *ncatTmpDest_ != '\\0') { \\\n            ++ncatTmpDest_; \\\n            --ncatRestSize_; \\\n        } \\\n        if (ncatRestSize_ == 0) { \\\n            ncatRet_ = EINVAL; \\\n        } else if ((SECUREC_TWO_MIN((count), strlen(src)) + 1) <= ncatRestSize_) { \\\n            if ((size_t)(count) < strlen(src)) { \\\n                memcpy(ncatTmpDest_, (src), (count)); \\\n                *(ncatTmpDest_ + (count)) = '\\0'; \\\n            } else { \\\n                memcpy(ncatTmpDest_, (src), strlen(src) + 1); \\\n            } \\\n        } else { \\\n            ncatRet_ = ERANGE; \\\n        } \\\n        if (ncatRet_ != EOK) { \\\n            ncatRet_ = strncat_s((dest), (destMax), (src), (count)); \\\n        } \\\n    } else { \\\n        ncatRet_ = strncat_s((dest), (destMax), (src), (count)); \\\n    } \\\n    ncatRet_; \\\n})\n#else\n#define SECUREC_STRNCAT_SM(dest, destMax, src, count) strncat_s((dest), (destMax), (src), (count))\n#endif\n\n/* This macro do not check buffer overlap by default */\n#define  SECUREC_MEMCPY_SM(dest, destMax, src, count) \\\n    (!(((size_t)(destMax) == 0) || \\\n        (((unsigned long long)(destMax) & (unsigned long long)(-2)) > SECUREC_MEM_MAX_LEN) || \\\n        ((size_t)(count) > (size_t)(destMax)) || ((void *)(dest)) == NULL || ((const void *)(src) == NULL)) ? \\\n        (memcpy((dest), (src), (count)), EOK) : \\\n        (memcpy_s((dest), (destMax), (src), (count))))\n\n#define  SECUREC_MEMSET_SM(dest, destMax, c, count) \\\n    (!((((unsigned long long)(destMax) & (unsigned long long)(-2)) > SECUREC_MEM_MAX_LEN) || \\\n        ((void *)(dest) == NULL) || ((size_t)(count) > (size_t)(destMax))) ? \\\n        (memset((dest), (c), (count)), EOK) : \\\n        (memset_s((dest), (destMax), (c), (count))))\n\n#endif\n#endif\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/libsec_src.gni",
    "content": "#\n# Copyright (c) 2021 Huawei Device Co., Ltd.\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\nlibsec_include_dirs = [ \"//third_party/bounds_checking_function/include\" ]\n\nlibsec_sources = [\n  \"//third_party/bounds_checking_function/src/fscanf_s.c\",\n  \"//third_party/bounds_checking_function/src/fwscanf_s.c\",\n  \"//third_party/bounds_checking_function/src/gets_s.c\",\n  \"//third_party/bounds_checking_function/src/memcpy_s.c\",\n  \"//third_party/bounds_checking_function/src/memmove_s.c\",\n  \"//third_party/bounds_checking_function/src/memset_s.c\",\n  \"//third_party/bounds_checking_function/src/scanf_s.c\",\n  \"//third_party/bounds_checking_function/src/securecutil.c\",\n  \"//third_party/bounds_checking_function/src/secureinput_a.c\",\n  \"//third_party/bounds_checking_function/src/secureinput_w.c\",\n  \"//third_party/bounds_checking_function/src/secureprintoutput_a.c\",\n  \"//third_party/bounds_checking_function/src/secureprintoutput_w.c\",\n  \"//third_party/bounds_checking_function/src/snprintf_s.c\",\n  \"//third_party/bounds_checking_function/src/sprintf_s.c\",\n  \"//third_party/bounds_checking_function/src/sscanf_s.c\",\n  \"//third_party/bounds_checking_function/src/strcat_s.c\",\n  \"//third_party/bounds_checking_function/src/strcpy_s.c\",\n  \"//third_party/bounds_checking_function/src/strncat_s.c\",\n  \"//third_party/bounds_checking_function/src/strncpy_s.c\",\n  \"//third_party/bounds_checking_function/src/strtok_s.c\",\n  \"//third_party/bounds_checking_function/src/swprintf_s.c\",\n  \"//third_party/bounds_checking_function/src/swscanf_s.c\",\n  \"//third_party/bounds_checking_function/src/vfscanf_s.c\",\n  \"//third_party/bounds_checking_function/src/vfwscanf_s.c\",\n  \"//third_party/bounds_checking_function/src/vscanf_s.c\",\n  \"//third_party/bounds_checking_function/src/vsnprintf_s.c\",\n  \"//third_party/bounds_checking_function/src/vsprintf_s.c\",\n  \"//third_party/bounds_checking_function/src/vsscanf_s.c\",\n  \"//third_party/bounds_checking_function/src/vswprintf_s.c\",\n  \"//third_party/bounds_checking_function/src/vswscanf_s.c\",\n  \"//third_party/bounds_checking_function/src/vwscanf_s.c\",\n  \"//third_party/bounds_checking_function/src/wcscat_s.c\",\n  \"//third_party/bounds_checking_function/src/wcscpy_s.c\",\n  \"//third_party/bounds_checking_function/src/wcsncat_s.c\",\n  \"//third_party/bounds_checking_function/src/wcsncpy_s.c\",\n  \"//third_party/bounds_checking_function/src/wcstok_s.c\",\n  \"//third_party/bounds_checking_function/src/wmemcpy_s.c\",\n  \"//third_party/bounds_checking_function/src/wmemmove_s.c\",\n  \"//third_party/bounds_checking_function/src/wscanf_s.c\",\n]\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/fscanf_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: fscanf_s function\n * Create: 2014-02-25\n */\n\n#include \"securec.h\"\n\n/*\n * <FUNCTION DESCRIPTION>\n *    The fscanf_s function is equivalent to fscanf except that the c, s,\n *    and [ conversion specifiers apply to a pair of arguments (unless assignment suppression is indicated by a*)\n *    The fscanf function reads data from the current position of stream into\n *    the locations given by argument (if any). Each argument must be a pointer\n *    to a variable of a type that corresponds to a type specifier in format.\n *    format controls the interpretation of the input fields and has the same\n *    form and function as the format argument for scanf.\n *\n * <INPUT PARAMETERS>\n *    stream              Pointer to FILE structure.\n *    format              Format control string, see Format Specifications.\n *    ...                 Optional arguments.\n *\n * <OUTPUT PARAMETERS>\n *    ...                 The converted value stored in user assigned address\n *\n * <RETURN VALUE>\n *    Each of these functions returns the number of fields successfully converted\n *    and assigned; the return value does not include fields that were read but\n *    not assigned. A return value of 0 indicates that no fields were assigned.\n *    return -1 if an error occurs.\n */\nint fscanf_s(FILE *stream, const char *format, ...)\n{\n    int ret;                    /* If initialization causes  e838 */\n    va_list argList;\n\n    va_start(argList, format);\n    ret = vfscanf_s(stream, format, argList);\n    va_end(argList);\n    (void)argList;              /* To clear e438 last value assigned not used , the compiler will optimize this code */\n\n    return ret;\n}\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/fwscanf_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: fwscanf_s function\n * Create: 2014-02-25\n */\n\n#include \"securec.h\"\n\n/*\n * <FUNCTION DESCRIPTION>\n *    The fwscanf_s function  is  the  wide-character  equivalent  of the fscanf_s function\n *    The fwscanf_s function reads data from the current position of stream into\n *    the locations given by argument (if any). Each argument must be a pointer\n *    to a variable of a type that corresponds to a type specifier in format.\n *    format controls the interpretation of the input fields and has the same\n *    form and function as the format argument for scanf.\n *\n * <INPUT PARAMETERS>\n *    stream                   Pointer to FILE structure.\n *    format                   Format control string, see Format Specifications.\n *    ...                      Optional arguments.\n *\n * <OUTPUT PARAMETERS>\n *    ...                      The converted value stored in user assigned address\n *\n * <RETURN VALUE>\n *    Each of these functions returns the number of fields successfully converted\n *    and assigned; the return value does not include fields that were read but\n *    not assigned. A return value of 0 indicates that no fields were assigned.\n *    return -1 if an error occurs.\n */\nint fwscanf_s(FILE *stream, const wchar_t *format, ...)\n{\n    int ret;                    /* If initialization causes  e838 */\n    va_list argList;\n\n    va_start(argList, format);\n    ret = vfwscanf_s(stream, format, argList);\n    va_end(argList);\n    (void)argList;              /* To clear e438 last value assigned not used , the compiler will optimize this code */\n\n    return ret;\n}\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/gets_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: gets_s function\n * Create: 2014-02-25\n */\n\n#include \"securecutil.h\"\n\n/*\n * The parameter size is buffer size in byte\n */\nSECUREC_INLINE void SecTrimCRLF(char *buffer, size_t size)\n{\n    size_t len = strlen(buffer);\n    --len; /* Unsigned integer wrapping is accepted and is checked afterwards */\n    while (len < size && (buffer[len] == '\\r' || buffer[len] == '\\n')) {\n        buffer[len] = '\\0';\n        --len; /* Unsigned integer wrapping is accepted and is checked next loop */\n    }\n}\n\n/*\n * <FUNCTION DESCRIPTION>\n *    The gets_s function reads at most one less than the number of characters\n *    specified by destMax from the std input stream, into the array pointed to by buffer\n *    The line consists of all characters up to and including\n *    the first newline character ('\\n'). gets_s then replaces the newline\n *    character with a null character ('\\0') before returning the line.\n *    If the first character read is the end-of-file character, a null character\n *    is stored at the beginning of buffer and NULL is returned.\n *\n * <INPUT PARAMETERS>\n *    buffer                         Storage location for input string.\n *    destMax                        The size of the buffer.\n *\n * <OUTPUT PARAMETERS>\n *    buffer                         is updated\n *\n * <RETURN VALUE>\n *    buffer                         Successful operation\n *    NULL                           Improper parameter or read fail\n */\nchar *gets_s(char *buffer, size_t destMax)\n{\n#ifdef SECUREC_COMPATIBLE_WIN_FORMAT\n    size_t bufferSize = ((destMax == (size_t)(-1)) ? SECUREC_STRING_MAX_LEN : destMax);\n#else\n    size_t bufferSize = destMax;\n#endif\n\n    if (buffer == NULL || bufferSize == 0 || bufferSize > SECUREC_STRING_MAX_LEN) {\n        SECUREC_ERROR_INVALID_PARAMTER(\"gets_s\");\n        return NULL;\n    }\n\n    if (fgets(buffer, (int)bufferSize, SECUREC_STREAM_STDIN) != NULL) {\n        SecTrimCRLF(buffer, bufferSize);\n        return buffer;\n    }\n\n    return NULL;\n}\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/input.inl",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: Used by secureinput_a.c and secureinput_w.c to include.\n *              This file provides a template function for ANSI and UNICODE compiling by\n *              different type definition. The functions of SecInputS or\n *              SecInputSW provides internal implementation for scanf family API, such as sscanf_s, fscanf_s.\n * Create: 2014-02-25\n * Notes: The formatted input processing results of integers on different platforms are different.\n */\n/*\n * [Standardize-exceptions] Use unsafe function: Performance-sensitive\n * [reason] Always used in the performance critical path,\n *          and sufficient input validation is performed before calling\n */\n#ifndef INPUT_INL_5D13A042_DC3F_4ED9_A8D1_882811274C27\n#define INPUT_INL_5D13A042_DC3F_4ED9_A8D1_882811274C27\n\n#if SECUREC_IN_KERNEL\n#if !defined(SECUREC_CTYPE_MACRO_ADAPT)\n#include <linux/ctype.h>\n#endif\n#else\n#if !defined(SECUREC_SYSAPI4VXWORKS) && !defined(SECUREC_CTYPE_MACRO_ADAPT)\n#include <ctype.h>\n#ifdef SECUREC_FOR_WCHAR\n#include <wctype.h>             /* For iswspace */\n#endif\n#endif\n#endif\n\n#ifndef EOF\n#define EOF  (-1)\n#endif\n\n#define SECUREC_NUM_WIDTH_SHORT                 0\n#define SECUREC_NUM_WIDTH_INT                   1\n#define SECUREC_NUM_WIDTH_LONG                  2\n#define SECUREC_NUM_WIDTH_LONG_LONG             3 /* Also long double */\n\n#define SECUREC_BUFFERED_BLOK_SIZE              1024U\n\n#if defined(SECUREC_VXWORKS_PLATFORM) && !defined(va_copy) && !defined(__va_copy)\n/* The name is the same as system macro. */\n#define __va_copy(dest, src) do { \\\n    size_t destSize_ = (size_t)sizeof(dest); \\\n    size_t srcSize_ = (size_t)sizeof(src); \\\n    if (destSize_ != srcSize_) { \\\n        SECUREC_MEMCPY_WARP_OPT((dest), (src), sizeof(va_list)); \\\n    } else { \\\n        SECUREC_MEMCPY_WARP_OPT(&(dest), &(src), sizeof(va_list)); \\\n    } \\\n} SECUREC_WHILE_ZERO\n#endif\n\n#define SECUREC_MULTI_BYTE_MAX_LEN              6\n\n/* Compatibility macro name cannot be modifie */\n#ifndef UNALIGNED\n#if !(defined(_M_IA64)) && !(defined(_M_AMD64))\n#define UNALIGNED\n#else\n#define UNALIGNED __unaligned\n#endif\n#endif\n\n#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))\n/* Max 64bit value is 0xffffffffffffffff */\n#define SECUREC_MAX_64BITS_VALUE                18446744073709551615ULL\n#define SECUREC_MAX_64BITS_VALUE_DIV_TEN        1844674407370955161ULL\n#define SECUREC_MAX_64BITS_VALUE_CUT_LAST_DIGIT 18446744073709551610ULL\n#define SECUREC_MIN_64BITS_NEG_VALUE            9223372036854775808ULL\n#define SECUREC_MAX_64BITS_POS_VALUE            9223372036854775807ULL\n#define SECUREC_MIN_32BITS_NEG_VALUE            2147483648UL\n#define SECUREC_MAX_32BITS_POS_VALUE            2147483647UL\n#define SECUREC_MAX_32BITS_VALUE                4294967295UL\n#define SECUREC_MAX_32BITS_VALUE_INC            4294967296UL\n#define SECUREC_MAX_32BITS_VALUE_DIV_TEN        429496729UL\n#define SECUREC_LONG_BIT_NUM                    ((unsigned int)(sizeof(long) << 3U))\n/* Use ULL to clean up cl6x compilation alerts */\n#define SECUREC_MAX_LONG_POS_VALUE              ((unsigned long)(1ULL << (SECUREC_LONG_BIT_NUM - 1)) - 1)\n#define SECUREC_MIN_LONG_NEG_VALUE              ((unsigned long)(1ULL << (SECUREC_LONG_BIT_NUM - 1)))\n\n/* Covert to long long to clean up cl6x compilation alerts */\n#define SECUREC_LONG_HEX_BEYOND_MAX(number)     (((unsigned long long)(number) >> (SECUREC_LONG_BIT_NUM - 4U)) > 0)\n#define SECUREC_LONG_OCTAL_BEYOND_MAX(number)   (((unsigned long long)(number) >> (SECUREC_LONG_BIT_NUM - 3U)) > 0)\n\n#define SECUREC_QWORD_HEX_BEYOND_MAX(number)    (((number) >> (64U - 4U)) > 0)\n#define SECUREC_QWORD_OCTAL_BEYOND_MAX(number)  (((number) >> (64U - 3U)) > 0)\n\n#define SECUREC_LP64_BIT_WIDTH                  64\n#define SECUREC_LP32_BIT_WIDTH                  32\n\n#define SECUREC_CONVERT_IS_SIGNED(conv) ((conv) == 'd' || (conv) == 'i')\n#endif\n\n#define SECUREC_BRACE                           '{'     /* [ to { */\n#define SECUREC_FILED_WIDTH_ENOUGH(spec) ((spec)->widthSet == 0 || (spec)->width > 0)\n#define SECUREC_FILED_WIDTH_DEC(spec) do { \\\n    if ((spec)->widthSet != 0) { \\\n        --(spec)->width; \\\n    } \\\n} SECUREC_WHILE_ZERO\n\n#ifdef SECUREC_FOR_WCHAR\n/* Bits for all wchar, size is 65536/8, only supports wide characters with a maximum length of two bytes */\n#define SECUREC_BRACKET_TABLE_SIZE    8192\n#define SECUREC_EOF WEOF\n#define SECUREC_MB_LEN 16       /* Max. # bytes in multibyte char  ,see MB_LEN_MAX */\n#else\n/* Bits for all char, size is 256/8 */\n#define SECUREC_BRACKET_TABLE_SIZE    32\n#define SECUREC_EOF EOF\n#endif\n\n#if SECUREC_HAVE_WCHART\n#define SECUREC_ARRAY_WIDTH_IS_WRONG(spec) ((spec).arrayWidth == 0 || \\\n    ((spec).isWCharOrLong <= 0 && (spec).arrayWidth > SECUREC_STRING_MAX_LEN) || \\\n    ((spec).isWCharOrLong > 0 && (spec).arrayWidth > SECUREC_WCHAR_STRING_MAX_LEN))\n#else\n#define SECUREC_ARRAY_WIDTH_IS_WRONG(spec) ((spec).arrayWidth == 0 || (spec).arrayWidth > SECUREC_STRING_MAX_LEN)\n#endif\n\n#ifdef SECUREC_ON_64BITS\n/* Use 0xffffffffUL mask to pass integer as array length */\n#define SECUREC_GET_ARRAYWIDTH(argList) (((size_t)va_arg((argList), size_t)) & 0xffffffffUL)\n#else /* !SECUREC_ON_64BITS */\n#define SECUREC_GET_ARRAYWIDTH(argList) ((size_t)va_arg((argList), size_t))\n#endif\n\ntypedef struct {\n#ifdef SECUREC_FOR_WCHAR\n    unsigned char *table; /* Default NULL */\n#else\n    unsigned char table[SECUREC_BRACKET_TABLE_SIZE]; /* Array length is large enough in application scenarios */\n#endif\n    unsigned char mask; /* Default 0 */\n} SecBracketTable;\n\n#ifdef SECUREC_FOR_WCHAR\n#define SECUREC_INIT_BRACKET_TABLE { NULL, 0 }\n#else\n#define SECUREC_INIT_BRACKET_TABLE { {0}, 0 }\n#endif\n\n#if SECUREC_ENABLE_SCANF_FLOAT\ntypedef struct {\n    size_t floatStrTotalLen;       /* Initialization must be length of buffer in charater */\n    size_t floatStrUsedLen;        /* Store float string len */\n    SecChar *floatStr;             /* Initialization must point to buffer */\n    SecChar *allocatedFloatStr;    /* Initialization must be NULL  to store alloced point */\n    SecChar buffer[SECUREC_FLOAT_BUFSIZE + 1];\n} SecFloatSpec;\n#endif\n\n#define SECUREC_NUMBER_STATE_DEFAULT 0U\n#define SECUREC_NUMBER_STATE_STARTED 1U\n\ntypedef struct {\n    SecInt ch;            /* Char read from input */\n    int charCount;        /* Number of characters processed */\n    void *argPtr;         /* Variable parameter pointer, point to the end of the string */\n    size_t arrayWidth;    /* Length of pointer Variable parameter, in charaters */\n    SecUnsignedInt64 number64; /* Store input number64 value */\n    unsigned long number; /* Store input number32 value */\n    int numberWidth;      /* 0 = SHORT, 1 = int, > 1  long or L_DOUBLE */\n    int numberArgType;       /* 1 for 64-bit integer, 0 otherwise. use it as decode function index */\n    unsigned int negative;         /* 0 is positive */\n#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))\n    unsigned int beyondMax;        /* Non-zero means beyond */\n#endif\n    unsigned int numberState; /* Identifies whether to start processing numbers, 1 is can input number */\n    int width;            /* Width number in format */\n    int widthSet;         /* 0 is not set width in format */\n    int convChr;          /* Lowercase format conversion characters */\n    int oriConvChr;       /* Store  original format conversion, convChr may change when parsing integers */\n    signed char isWCharOrLong;  /* -1/0 not wchar or long, 1 for wchar or long */\n    unsigned char suppress;     /* 0 is not have %* in format */\n} SecScanSpec;\n\n#ifdef SECUREC_FOR_WCHAR\n#define SECUREC_GETC fgetwc\n#define SECUREC_UN_GETC ungetwc\n/* Only supports wide characters with a maximum length of two bytes in format string */\n#define SECUREC_BRACKET_CHAR_MASK 0xffffU\n#else\n#define SECUREC_GETC fgetc\n#define SECUREC_UN_GETC ungetc\n#define SECUREC_BRACKET_CHAR_MASK 0xffU\n#endif\n\n#define SECUREC_CHAR_SIZE ((unsigned int)(sizeof(SecChar)))\n/* To avoid 648, mask high bit: 0x00ffffff 0x0000ffff or 0x00000000 */\n#define SECUREC_CHAR_MASK_HIGH (((((((((unsigned int)(-1) >> SECUREC_CHAR_SIZE) >> SECUREC_CHAR_SIZE) >> \\\n    SECUREC_CHAR_SIZE) >> SECUREC_CHAR_SIZE) >> \\\n    SECUREC_CHAR_SIZE) >> SECUREC_CHAR_SIZE) >> \\\n    SECUREC_CHAR_SIZE) >> SECUREC_CHAR_SIZE)\n\n/* For char is 0xff, wcahr_t is 0xffff or 0xffffffff. */\n#define SECUREC_CHAR_MASK (~((((((((((unsigned int)(-1) & SECUREC_CHAR_MASK_HIGH) << \\\n    SECUREC_CHAR_SIZE) << SECUREC_CHAR_SIZE) << \\\n    SECUREC_CHAR_SIZE) << SECUREC_CHAR_SIZE) << \\\n    SECUREC_CHAR_SIZE) << SECUREC_CHAR_SIZE) << \\\n    SECUREC_CHAR_SIZE) << SECUREC_CHAR_SIZE))\n\n/* According wchar_t has multiple bytes, so use sizeof */\n#define SECUREC_GET_CHAR(stream, outCh) do { \\\n    if ((stream)->count >= sizeof(SecChar)) { \\\n        *(outCh) = (SecInt)(SECUREC_CHAR_MASK & \\\n            (unsigned int)(int)(*((const SecChar *)(const void *)(stream)->cur))); \\\n        (stream)->cur += sizeof(SecChar); \\\n        (stream)->count -= sizeof(SecChar); \\\n    } else { \\\n        *(outCh) = SECUREC_EOF; \\\n    } \\\n} SECUREC_WHILE_ZERO\n\n#define SECUREC_UN_GET_CHAR(stream) do { \\\n    if ((stream)->cur > (stream)->base) { \\\n        (stream)->cur -= sizeof(SecChar); \\\n        (stream)->count += sizeof(SecChar); \\\n    } \\\n} SECUREC_WHILE_ZERO\n\n/* Convert wchar_t to int and then to unsigned int  to keep data clearing warning */\n#define SECUREC_TO_LOWERCASE(chr) ((int)((unsigned int)(int)(chr) | (unsigned int)('a' - 'A')))\n\n/* Record a flag for each bit */\n#define SECUREC_BRACKET_INDEX(x)  ((unsigned int)(x) >> 3U)\n#define SECUREC_BRACKET_VALUE(x)  ((unsigned char)(1U << ((unsigned int)(x) & 7U)))\n#if SECUREC_IN_KERNEL\n#define SECUREC_CONVERT_IS_UNSIGNED(conv) ((conv) == 'x' || (conv) == 'o' || (conv) == 'u')\n#endif\n\n/*\n * Set char in %[xxx] into table, only supports wide characters with a maximum length of two bytes\n */\nSECUREC_INLINE void SecBracketSetBit(unsigned char *table, SecUnsignedChar ch)\n{\n    unsigned int tableIndex = SECUREC_BRACKET_INDEX(((unsigned int)(int)ch & SECUREC_BRACKET_CHAR_MASK));\n    unsigned int tableValue = SECUREC_BRACKET_VALUE(((unsigned int)(int)ch & SECUREC_BRACKET_CHAR_MASK));\n    /* Do not use   |=   optimize this code, it will cause compiling warning */\n    table[tableIndex] = (unsigned char)(table[tableIndex] | tableValue);\n}\n\nSECUREC_INLINE void SecBracketSetBitRange(unsigned char *table, SecUnsignedChar startCh, SecUnsignedChar endCh)\n{\n    SecUnsignedChar expCh;\n    /* %[a-z] %[a-a] Format %[a-\\xff] end is 0xFF, condition (expCh <= endChar) cause dead loop */\n    for (expCh = startCh; expCh < endCh; ++expCh) {\n        SecBracketSetBit(table, expCh);\n    }\n    SecBracketSetBit(table, endCh);\n}\n/*\n * Determine whether the expression can be satisfied\n */\nSECUREC_INLINE int SecCanInputForBracket(int convChr, SecInt ch, const SecBracketTable *bracketTable)\n{\n    unsigned int tableIndex = SECUREC_BRACKET_INDEX(((unsigned int)(int)ch & SECUREC_BRACKET_CHAR_MASK));\n    unsigned int tableValue = SECUREC_BRACKET_VALUE(((unsigned int)(int)ch & SECUREC_BRACKET_CHAR_MASK));\n#ifdef SECUREC_FOR_WCHAR\n    if (((unsigned int)(int)ch & (~(SECUREC_BRACKET_CHAR_MASK))) != 0) {\n        /* The value of the wide character exceeds the size of two bytes */\n        return 0;\n    }\n    return (int)(convChr == SECUREC_BRACE &&\n        (((unsigned int)bracketTable->table[tableIndex] ^ (unsigned int)bracketTable->mask) & tableValue) != 0);\n#else\n    return (int)(convChr == SECUREC_BRACE &&\n        (((unsigned int)bracketTable->table[tableIndex] ^ (unsigned int)bracketTable->mask) & tableValue) != 0);\n#endif\n}\n\n/*\n * String input ends when blank character is encountered\n */\nSECUREC_INLINE int SecCanInputString(int convChr, SecInt ch)\n{\n    return (int)(convChr == 's' &&\n        (!(ch >= SECUREC_CHAR('\\t') && ch <= SECUREC_CHAR('\\r')) && ch != SECUREC_CHAR(' ')));\n}\n\n/*\n * Can input a character when format is %c\n */\nSECUREC_INLINE int SecCanInputCharacter(int convChr)\n{\n    return (int)(convChr == 'c');\n}\n\n/*\n * Determine if it is a 64-bit pointer  function\n * Return 0 is not ,1 is 64bit pointer\n */\nSECUREC_INLINE int SecNumberArgType(size_t sizeOfVoidStar)\n{\n    /* Point size is 4 or 8 , Under the 64 bit system, the value not 0 */\n    /* To clear e778 */\n    if ((sizeOfVoidStar & sizeof(SecInt64)) != 0) {\n        return 1;\n    }\n    return 0;\n}\nSECUREC_INLINE int SecIsDigit(SecInt ch);\nSECUREC_INLINE int SecIsXdigit(SecInt ch);\nSECUREC_INLINE int SecIsSpace(SecInt ch);\nSECUREC_INLINE SecInt SecSkipSpaceChar(SecFileStream *stream, int *counter);\nSECUREC_INLINE SecInt SecGetChar(SecFileStream *stream, int *counter);\nSECUREC_INLINE void SecUnGetChar(SecInt ch, SecFileStream *stream, int *counter);\n\n#if SECUREC_ENABLE_SCANF_FLOAT\n\n/*\n * Convert a floating point string to a floating point number\n */\nSECUREC_INLINE int SecAssignNarrowFloat(const char *floatStr, const SecScanSpec *spec)\n{\n    char *endPtr = NULL;\n    double d;\n#if SECUREC_SUPPORT_STRTOLD\n    if (spec->numberWidth == SECUREC_NUM_WIDTH_LONG_LONG) {\n        long double d2 = strtold(floatStr, &endPtr);\n        if (endPtr == floatStr) {\n            return -1;\n        }\n        *(long double UNALIGNED *)(spec->argPtr) = d2;\n        return 0;\n    }\n#endif\n    d = strtod(floatStr, &endPtr);\n    /* cannot detect if endPtr points to the end of floatStr,because strtod handles only two characters for 1.E */\n    if (endPtr == floatStr) {\n        return -1;\n    }\n    if (spec->numberWidth > SECUREC_NUM_WIDTH_INT) {\n        *(double UNALIGNED *)(spec->argPtr) = (double)d;\n    } else {\n        *(float UNALIGNED *)(spec->argPtr) = (float)d;\n    }\n    return 0;\n}\n\n#ifdef SECUREC_FOR_WCHAR\n/*\n * Convert a floating point wchar string to a floating point number\n * Success  ret 0\n */\nSECUREC_INLINE int SecAssignWideFloat(const SecFloatSpec *floatSpec, const SecScanSpec *spec)\n{\n    int retVal;\n    /* Convert float string */\n    size_t mbsLen;\n    size_t tempFloatStrLen = (size_t)(floatSpec->floatStrUsedLen + 1) * sizeof(wchar_t);\n    char *tempFloatStr = (char *)SECUREC_MALLOC(tempFloatStrLen);\n    if (tempFloatStr == NULL) {\n        return -1;\n    }\n    tempFloatStr[0] = '\\0';\n    SECUREC_MASK_MSVC_CRT_WARNING\n    mbsLen = wcstombs(tempFloatStr, floatSpec->floatStr, tempFloatStrLen - 1);\n    SECUREC_END_MASK_MSVC_CRT_WARNING\n    /* This condition must satisfy mbsLen is not -1 */\n    if (mbsLen >= tempFloatStrLen) {\n        SECUREC_FREE(tempFloatStr);\n        return -1;\n    }\n    tempFloatStr[mbsLen] = '\\0';\n    retVal = SecAssignNarrowFloat(tempFloatStr, spec);\n    SECUREC_FREE(tempFloatStr);\n    return retVal;\n}\n#endif\n\nSECUREC_INLINE int SecAssignFloat(const SecFloatSpec *floatSpec, const SecScanSpec *spec)\n{\n#ifdef SECUREC_FOR_WCHAR\n    return SecAssignWideFloat(floatSpec, spec);\n#else\n    return SecAssignNarrowFloat(floatSpec->floatStr, spec);\n#endif\n}\n\n/*\n * Init SecFloatSpec before parse format\n */\nSECUREC_INLINE void SecInitFloatSpec(SecFloatSpec *floatSpec)\n{\n    floatSpec->floatStr = floatSpec->buffer;\n    floatSpec->allocatedFloatStr = NULL;\n    floatSpec->floatStrTotalLen = sizeof(floatSpec->buffer) / sizeof(floatSpec->buffer[0]);\n    floatSpec->floatStrUsedLen = 0;\n}\n\nSECUREC_INLINE void SecFreeFloatSpec(SecFloatSpec *floatSpec, int *doneCount)\n{\n    /* 2014.3.6 add, clear the stack data */\n    if (memset_s(floatSpec->buffer, sizeof(floatSpec->buffer), 0, sizeof(floatSpec->buffer)) != EOK) {\n        *doneCount = 0; /* This code just to meet the coding requirements */\n    }\n    /* The pFloatStr can be alloced in SecExtendFloatLen function, clear and free it */\n    if (floatSpec->allocatedFloatStr != NULL) {\n        size_t bufferSize = floatSpec->floatStrTotalLen * sizeof(SecChar);\n        if (memset_s(floatSpec->allocatedFloatStr, bufferSize, 0, bufferSize) != EOK) {\n            *doneCount = 0; /* This code just to meet the coding requirements */\n        }\n        SECUREC_FREE(floatSpec->allocatedFloatStr);\n        floatSpec->allocatedFloatStr = NULL;\n        floatSpec->floatStr = NULL;\n    }\n}\n\n/*\n * Splice floating point string\n * Return 0 OK\n */\nSECUREC_INLINE int SecExtendFloatLen(SecFloatSpec *floatSpec)\n{\n    if (floatSpec->floatStrUsedLen >= floatSpec->floatStrTotalLen) {\n        /* Buffer size is len x sizeof(SecChar) */\n        size_t oriSize = floatSpec->floatStrTotalLen * sizeof(SecChar);\n        /* Add one character to clear tool warning */\n        size_t nextSize = (oriSize * 2) + sizeof(SecChar); /* Multiply 2 to extend buffer size */\n\n        /* Prevents integer overflow, the maximum length of SECUREC_MAX_WIDTH_LEN is enough */\n        if (nextSize <= (size_t)SECUREC_MAX_WIDTH_LEN) {\n            void *nextBuffer = (void *)SECUREC_MALLOC(nextSize);\n            if (nextBuffer == NULL) {\n                return -1;\n            }\n            if (memcpy_s(nextBuffer, nextSize, floatSpec->floatStr, oriSize) != EOK) {\n                SECUREC_FREE(nextBuffer);   /* This is a dead code, just to meet the coding requirements */\n                return -1;\n            }\n            /* Clear old buffer memory */\n            if (memset_s(floatSpec->floatStr, oriSize, 0, oriSize) != EOK) {\n                SECUREC_FREE(nextBuffer);   /* This is a dead code, just to meet the coding requirements */\n                return -1;\n            }\n            /* Free old allocated buffer */\n            if (floatSpec->allocatedFloatStr != NULL) {\n                SECUREC_FREE(floatSpec->allocatedFloatStr);\n            }\n            floatSpec->allocatedFloatStr = (SecChar *)(nextBuffer);    /* Use to clear free on stack warning */\n            floatSpec->floatStr = (SecChar *)(nextBuffer);\n            floatSpec->floatStrTotalLen = nextSize / sizeof(SecChar); /* Get buffer total len in character */\n            return 0;\n        }\n        return -1; /* Next size is beyond max */\n    }\n    return 0;\n}\n\n/* Do not use localeconv()->decimal_pointif  only support  '.' */\nSECUREC_INLINE int SecIsFloatDecimal(SecChar ch)\n{\n    return (int)(ch == SECUREC_CHAR('.'));\n}\n\nSECUREC_INLINE int SecInputFloatSign(SecFileStream *stream, SecScanSpec *spec, SecFloatSpec *floatSpec)\n{\n    if (!SECUREC_FILED_WIDTH_ENOUGH(spec)) {\n        return 0;\n    }\n    spec->ch = SecGetChar(stream, &(spec->charCount));\n    if (spec->ch == SECUREC_CHAR('+') || spec->ch == SECUREC_CHAR('-')) {\n        SECUREC_FILED_WIDTH_DEC(spec); /* Make sure the count after un get char is correct */\n        if (spec->ch == SECUREC_CHAR('-')) {\n            floatSpec->floatStr[floatSpec->floatStrUsedLen] = SECUREC_CHAR('-');\n            ++floatSpec->floatStrUsedLen;\n            if (SecExtendFloatLen(floatSpec) != 0) {\n                return -1;\n            }\n        }\n    } else {\n        SecUnGetChar(spec->ch, stream, &(spec->charCount));\n    }\n    return 0;\n}\n\nSECUREC_INLINE int SecInputFloatDigit(SecFileStream *stream, SecScanSpec *spec, SecFloatSpec *floatSpec)\n{\n    /* Now get integral part */\n    while (SECUREC_FILED_WIDTH_ENOUGH(spec)) {\n        spec->ch = SecGetChar(stream, &(spec->charCount));\n        if (SecIsDigit(spec->ch) == 0) {\n            SecUnGetChar(spec->ch, stream, &(spec->charCount));\n            return 0;\n        }\n        SECUREC_FILED_WIDTH_DEC(spec); /* Must be behind un get char, otherwise the logic is incorrect */\n        spec->numberState = SECUREC_NUMBER_STATE_STARTED;\n        floatSpec->floatStr[floatSpec->floatStrUsedLen] = (SecChar)spec->ch;\n        ++floatSpec->floatStrUsedLen;\n        if (SecExtendFloatLen(floatSpec) != 0) {\n            return -1;\n        }\n    }\n    return 0;\n}\n\n/*\n* Scan value of exponent.\n* Return 0 OK\n*/\nSECUREC_INLINE int SecInputFloatE(SecFileStream *stream, SecScanSpec *spec, SecFloatSpec *floatSpec)\n{\n    if (SecInputFloatSign(stream, spec, floatSpec) == -1) {\n        return -1;\n    }\n    if (SecInputFloatDigit(stream, spec, floatSpec) != 0) {\n        return -1;\n    }\n    return 0;\n}\n\nSECUREC_INLINE int SecInputFloatFractional(SecFileStream *stream, SecScanSpec *spec, SecFloatSpec *floatSpec)\n{\n    if (SECUREC_FILED_WIDTH_ENOUGH(spec)) {\n        spec->ch = SecGetChar(stream, &(spec->charCount));\n        if (SecIsFloatDecimal((SecChar)spec->ch) == 0) {\n            SecUnGetChar(spec->ch, stream, &(spec->charCount));\n            return 0;\n        }\n        SECUREC_FILED_WIDTH_DEC(spec); /* Must be behind un get char, otherwise the logic is incorrect */\n        /* Now check for decimal */\n        floatSpec->floatStr[floatSpec->floatStrUsedLen] = (SecChar)spec->ch;\n        ++floatSpec->floatStrUsedLen;\n        if (SecExtendFloatLen(floatSpec) != 0) {\n            return -1;\n        }\n        if (SecInputFloatDigit(stream, spec, floatSpec) != 0) {\n            return -1;\n        }\n    }\n    return 0;\n}\n\nSECUREC_INLINE int SecInputFloatExponent(SecFileStream *stream, SecScanSpec *spec, SecFloatSpec *floatSpec)\n{\n    /* Now get exponent part */\n    if (spec->numberState == SECUREC_NUMBER_STATE_STARTED && SECUREC_FILED_WIDTH_ENOUGH(spec)) {\n        spec->ch = SecGetChar(stream, &(spec->charCount));\n        if (spec->ch != SECUREC_CHAR('e') && spec->ch != SECUREC_CHAR('E')) {\n            SecUnGetChar(spec->ch, stream, &(spec->charCount));\n            return 0;\n        }\n        SECUREC_FILED_WIDTH_DEC(spec); /* Must be behind un get char, otherwise the logic is incorrect */\n        floatSpec->floatStr[floatSpec->floatStrUsedLen] = SECUREC_CHAR('e');\n        ++floatSpec->floatStrUsedLen;\n        if (SecExtendFloatLen(floatSpec) != 0) {\n            return -1;\n        }\n        if (SecInputFloatE(stream, spec, floatSpec) != 0) {\n            return -1;\n        }\n    }\n    return 0;\n}\n\n/*\n* Scan %f.\n* Return 0 OK\n*/\nSECUREC_INLINE int SecInputFloat(SecFileStream *stream, SecScanSpec *spec, SecFloatSpec *floatSpec)\n{\n    floatSpec->floatStrUsedLen = 0;\n\n    /* The following code sequence is strict */\n    if (SecInputFloatSign(stream, spec, floatSpec) != 0) {\n        return -1;\n    }\n    if (SecInputFloatDigit(stream, spec, floatSpec) != 0) {\n        return -1;\n    }\n    if (SecInputFloatFractional(stream, spec, floatSpec) != 0) {\n        return -1;\n    }\n    if (SecInputFloatExponent(stream, spec, floatSpec) != 0) {\n        return -1;\n    }\n\n    /* Make sure  have a string terminator, buffer is large enough */\n    floatSpec->floatStr[floatSpec->floatStrUsedLen] = SECUREC_CHAR('\\0');\n    if (spec->numberState == SECUREC_NUMBER_STATE_STARTED) {\n        return 0;\n    }\n    return -1;\n}\n#endif\n\n#if (!defined(SECUREC_FOR_WCHAR) && SECUREC_HAVE_WCHART && SECUREC_HAVE_MBTOWC) || \\\n    (!defined(SECUREC_FOR_WCHAR) && defined(SECUREC_COMPATIBLE_VERSION))\n/* only multi-bytes string need isleadbyte() function */\nSECUREC_INLINE int SecIsLeadByte(SecInt ch)\n{\n    unsigned int c = (unsigned int)ch;\n#if !(defined(_MSC_VER) || defined(_INC_WCTYPE))\n    return (int)(c & 0x80U); /* Use bitwise operation to check if the most significant bit is 1 */\n#else\n    return (int)isleadbyte((int)(c & 0xffU)); /* Use bitwise operations to limit character values to valid ranges */\n#endif\n}\n#endif\n\n/*\n * Parsing whether it is a wide character\n */\nSECUREC_INLINE void SecUpdateWcharFlagByType(SecUnsignedChar ch, SecScanSpec *spec)\n{\n    if (spec->isWCharOrLong != 0) {\n        /* Wide character identifiers have been explicitly set by l or h flag */\n        return;\n    }\n\n    /* Set default flag */\n#if defined(SECUREC_FOR_WCHAR) && defined(SECUREC_COMPATIBLE_WIN_FORMAT)\n    spec->isWCharOrLong = 1;  /* On windows wide char version %c %s %[ is wide char */\n#else\n    spec->isWCharOrLong = -1; /* On linux all version %c %s %[ is multi char */\n#endif\n\n    if (ch == SECUREC_CHAR('C') || ch == SECUREC_CHAR('S')) {\n#if defined(SECUREC_FOR_WCHAR) && defined(SECUREC_COMPATIBLE_WIN_FORMAT)\n        spec->isWCharOrLong = -1; /* On windows wide char version %C %S is multi char */\n#else\n        spec->isWCharOrLong = 1;  /* On linux all version %C %S is wide char */\n#endif\n    }\n\n    return;\n}\n/*\n * Decode  %l %ll\n */\nSECUREC_INLINE void SecDecodeScanQualifierL(const SecUnsignedChar **format, SecScanSpec *spec)\n{\n    const SecUnsignedChar *fmt = *format;\n    if (*(fmt + 1) == SECUREC_CHAR('l')) {\n        spec->numberArgType = 1;\n        spec->numberWidth = SECUREC_NUM_WIDTH_LONG_LONG;\n        ++fmt;\n    } else {\n        spec->numberWidth = SECUREC_NUM_WIDTH_LONG;\n#if defined(SECUREC_ON_64BITS) && !(defined(SECUREC_COMPATIBLE_WIN_FORMAT))\n        /* On window 64 system sizeof long is 32bit */\n        spec->numberArgType = 1;\n#endif\n        spec->isWCharOrLong = 1;\n    }\n    *format = fmt;\n}\n\n/*\n * Decode  %I %I43 %I64 %Id %Ii %Io ...\n * Set finishFlag to  1  finish Flag\n */\nSECUREC_INLINE void SecDecodeScanQualifierI(const SecUnsignedChar **format, SecScanSpec *spec, int *finishFlag)\n{\n    const SecUnsignedChar *fmt = *format;\n    if ((*(fmt + 1) == SECUREC_CHAR('6')) &&\n        (*(fmt + 2) == SECUREC_CHAR('4'))) { /* Offset 2 for I64 */\n        spec->numberArgType = 1;\n        *format = *format + 2; /* Add 2 to skip I64 point to '4' next loop will inc */\n    } else if ((*(fmt + 1) == SECUREC_CHAR('3')) &&\n                (*(fmt + 2) == SECUREC_CHAR('2'))) { /* Offset 2 for I32 */\n        *format = *format + 2; /* Add 2 to skip I32 point to '2' next loop will inc */\n    } else if ((*(fmt + 1) == SECUREC_CHAR('d')) ||\n                (*(fmt + 1) == SECUREC_CHAR('i')) ||\n                (*(fmt + 1) == SECUREC_CHAR('o')) ||\n                (*(fmt + 1) == SECUREC_CHAR('x')) ||\n                (*(fmt + 1) == SECUREC_CHAR('X'))) {\n        spec->numberArgType = SecNumberArgType(sizeof(void *));\n    } else {\n        /* For %I */\n        spec->numberArgType = SecNumberArgType(sizeof(void *));\n        *finishFlag = 1;\n    }\n}\n\nSECUREC_INLINE int SecDecodeScanWidth(const SecUnsignedChar **format, SecScanSpec *spec)\n{\n    const SecUnsignedChar *fmt = *format;\n    while (SecIsDigit((SecInt)(int)(*fmt)) != 0) {\n        spec->widthSet = 1;\n        if (SECUREC_MUL_TEN_ADD_BEYOND_MAX(spec->width)) {\n            return -1;\n        }\n        spec->width = (int)SECUREC_MUL_TEN((unsigned int)spec->width) + (unsigned char)(*fmt - SECUREC_CHAR('0'));\n        ++fmt;\n    }\n    *format = fmt;\n    return 0;\n}\n\n/*\n * Init default flags for each format. do not init ch this variable is context-dependent\n */\nSECUREC_INLINE void SecSetDefaultScanSpec(SecScanSpec *spec)\n{\n    /* The ch and charCount member variables cannot be initialized here */\n    spec->argPtr = NULL;\n    spec->arrayWidth = 0;\n    spec->number64 = 0;\n    spec->number = 0;\n    spec->numberWidth = SECUREC_NUM_WIDTH_INT;    /* 0 = SHORT, 1 = int, > 1  long or L_DOUBLE */\n    spec->numberArgType = 0;                         /* 1 for 64-bit integer, 0 otherwise */\n    spec->width = 0;\n    spec->widthSet = 0;\n    spec->convChr = 0;\n    spec->oriConvChr = 0;\n    spec->isWCharOrLong = 0;\n    spec->suppress = 0;\n#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))\n    spec->beyondMax = 0;\n#endif\n    spec->negative = 0;\n    spec->numberState = SECUREC_NUMBER_STATE_DEFAULT;\n}\n\n/*\n * Decode qualifier %I %L %h ...\n * Set finishFlag to  1  finish Flag\n */\nSECUREC_INLINE void  SecDecodeScanQualifier(const SecUnsignedChar **format, SecScanSpec *spec, int *finishFlag)\n{\n    switch (**format) {\n        case SECUREC_CHAR('F'): /* fall-through */ /* FALLTHRU */\n        case SECUREC_CHAR('N'):\n            break;\n        case SECUREC_CHAR('h'):\n            --spec->numberWidth; /* The h for SHORT , hh for CHAR */\n            spec->isWCharOrLong = -1;\n            break;\n#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT\n        case SECUREC_CHAR('j'):\n            spec->numberWidth = SECUREC_NUM_WIDTH_LONG_LONG;  /* For intmax_t or uintmax_t */\n            spec->numberArgType = 1;\n            break;\n        case SECUREC_CHAR('t'): /* fall-through */ /* FALLTHRU */\n#endif\n#if SECUREC_IN_KERNEL\n        case SECUREC_CHAR('Z'): /* fall-through */ /* FALLTHRU */\n#endif\n        case SECUREC_CHAR('z'):\n#ifdef SECUREC_ON_64BITS\n            spec->numberWidth = SECUREC_NUM_WIDTH_LONG_LONG;\n            spec->numberArgType = 1;\n#else\n            spec->numberWidth = SECUREC_NUM_WIDTH_LONG;\n#endif\n            break;\n        case SECUREC_CHAR('L'):    /* For long double */ /* fall-through */ /* FALLTHRU */\n        case SECUREC_CHAR('q'):\n            spec->numberWidth = SECUREC_NUM_WIDTH_LONG_LONG;\n            spec->numberArgType = 1;\n            break;\n        case SECUREC_CHAR('l'):\n            SecDecodeScanQualifierL(format, spec);\n            break;\n        case SECUREC_CHAR('w'):\n            spec->isWCharOrLong = 1;\n            break;\n        case SECUREC_CHAR('*'):\n            spec->suppress = 1;\n            break;\n        case SECUREC_CHAR('I'):\n            SecDecodeScanQualifierI(format, spec, finishFlag);\n            break;\n        default:\n            *finishFlag = 1;\n            break;\n    }\n}\n/*\n * Decode width and qualifier in format\n */\nSECUREC_INLINE int SecDecodeScanFlag(const SecUnsignedChar **format, SecScanSpec *spec)\n{\n    const SecUnsignedChar *fmt = *format;\n    int finishFlag = 0;\n\n    do {\n        ++fmt; /*  First skip % , next  seek fmt */\n        /* May %*6d , so put it inside the loop */\n        if (SecDecodeScanWidth(&fmt, spec) != 0) {\n            return -1;\n        }\n        SecDecodeScanQualifier(&fmt, spec, &finishFlag);\n    } while (finishFlag == 0);\n    *format = fmt;\n    return 0;\n}\n\n/*\n * Judging whether a zeroing buffer is needed according to different formats\n */\nSECUREC_INLINE int SecDecodeClearFormat(const SecUnsignedChar *format, int *convChr)\n{\n    const SecUnsignedChar *fmt = format;\n    /* To lowercase */\n    int ch = SECUREC_TO_LOWERCASE(*fmt);\n    if (!(ch == 'c' || ch == 's' || ch == SECUREC_BRACE)) {\n        return -1;     /* First argument is not a string type */\n    }\n    if (ch == SECUREC_BRACE) {\n#if !(defined(SECUREC_COMPATIBLE_WIN_FORMAT))\n        if (*fmt == SECUREC_CHAR('{')) {\n            return -1;\n        }\n#endif\n        ++fmt;\n        if (*fmt == SECUREC_CHAR('^')) {\n            ++fmt;\n        }\n        if (*fmt == SECUREC_CHAR(']')) {\n            ++fmt;\n        }\n        while (*fmt != SECUREC_CHAR('\\0') && *fmt != SECUREC_CHAR(']')) {\n            ++fmt;\n        }\n        if (*fmt == SECUREC_CHAR('\\0')) {\n            return -1; /* Trunc'd format string */\n        }\n    }\n    *convChr = ch;\n    return 0;\n}\n\n/*\n * Add L'\\0' for wchar string , add '\\0' for char string\n */\nSECUREC_INLINE void SecAddEndingZero(void *ptr, const SecScanSpec *spec)\n{\n    if (spec->suppress == 0) {\n        *(char *)ptr = '\\0';\n#if SECUREC_HAVE_WCHART\n        if (spec->isWCharOrLong > 0) {\n            *(wchar_t UNALIGNED *)ptr = L'\\0';\n        }\n#endif\n    }\n}\n\nSECUREC_INLINE void SecDecodeClearArg(SecScanSpec *spec, va_list argList)\n{\n    va_list argListSave; /* Backup for argList value, this variable don't need initialized */\n    (void)SECUREC_MEMSET_FUNC_OPT(&argListSave, 0, sizeof(va_list)); /* To clear e530 argListSave not initialized */\n#if defined(va_copy)\n    va_copy(argListSave, argList);\n#elif defined(__va_copy)        /* For vxworks */\n    __va_copy(argListSave, argList);\n#else\n    argListSave = argList;\n#endif\n    spec->argPtr = (void *)va_arg(argListSave, void *);\n    /* Get the next argument, size of the array in characters */\n    /* Use 0xffffffffUL mask to Support  pass integer as array length */\n    spec->arrayWidth = ((size_t)(va_arg(argListSave, size_t))) & 0xffffffffUL;\n    va_end(argListSave);\n    /* To clear e438 last value assigned not used , the compiler will optimize this code */\n    (void)argListSave;\n}\n\n#ifdef SECUREC_FOR_WCHAR\n/*\n *  Clean up the first %s %c buffer to zero for wchar version\n */\nvoid SecClearDestBufW(const wchar_t *buffer, const wchar_t *format, va_list argList)\n#else\n/*\n *  Clean up the first %s %c buffer to zero for char version\n */\nvoid SecClearDestBuf(const char *buffer, const char *format, va_list argList)\n#endif\n{\n    SecScanSpec spec;\n    int convChr = 0;\n    const SecUnsignedChar *fmt = (const SecUnsignedChar *)format;\n\n    /* Find first % */\n    while (*fmt != SECUREC_CHAR('\\0') && *fmt != SECUREC_CHAR('%')) {\n        ++fmt;\n    }\n    if (*fmt == SECUREC_CHAR('\\0')) {\n        return;\n    }\n\n    SecSetDefaultScanSpec(&spec);\n    if (SecDecodeScanFlag(&fmt, &spec) != 0) {\n        return;\n    }\n\n    /* Update wchar flag for %S %C */\n    SecUpdateWcharFlagByType(*fmt, &spec);\n    if (spec.suppress != 0) {\n        return;\n    }\n\n    if (SecDecodeClearFormat(fmt, &convChr) != 0) {\n        return;\n    }\n\n    if (*buffer != SECUREC_CHAR('\\0') && convChr != 's') {\n        /*\n         * When buffer not empty just clear %s.\n         * Example call sscanf by  argment of (\" \\n\", \"%s\", s, sizeof(s))\n         */\n        return;\n    }\n\n    SecDecodeClearArg(&spec, argList);\n    /* There is no need to judge the upper limit */\n    if (spec.arrayWidth == 0 || spec.argPtr == NULL) {\n        return;\n    }\n    /* Clear one char */\n    SecAddEndingZero(spec.argPtr, &spec);\n    return;\n}\n\n/*\n *  Assign number  to output buffer\n */\nSECUREC_INLINE void SecAssignNumber(const SecScanSpec *spec)\n{\n    void *argPtr = spec->argPtr;\n    if (spec->numberArgType != 0) {\n#if defined(SECUREC_VXWORKS_PLATFORM)\n#if defined(SECUREC_VXWORKS_PLATFORM_COMP)\n        *(SecInt64 UNALIGNED *)argPtr = (SecInt64)(spec->number64);\n#else\n        /* Take number64 as unsigned number unsigned to int clear Compile warning */\n        *(SecInt64 UNALIGNED *)argPtr = *(SecUnsignedInt64 *)(&(spec->number64));\n#endif\n#else\n        /* Take number64 as unsigned number */\n        *(SecInt64 UNALIGNED *)argPtr = (SecInt64)(spec->number64);\n#endif\n        return;\n    }\n    if (spec->numberWidth > SECUREC_NUM_WIDTH_INT) {\n        /* Take number as unsigned number */\n        *(long UNALIGNED *)argPtr = (long)(spec->number);\n    } else if (spec->numberWidth == SECUREC_NUM_WIDTH_INT) {\n        *(int UNALIGNED *)argPtr = (int)(spec->number);\n    } else if (spec->numberWidth == SECUREC_NUM_WIDTH_SHORT) {\n        /* Take number as unsigned number */\n        *(short UNALIGNED *)argPtr = (short)(spec->number);\n    } else {  /* < 0 for hh format modifier */\n        /* Take number as unsigned number */\n        *(char UNALIGNED *)argPtr = (char)(spec->number);\n    }\n}\n\n#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))\n/*\n *  Judge the long bit width\n */\nSECUREC_INLINE int SecIsLongBitEqual(int bitNum)\n{\n    return (int)((unsigned int)bitNum == SECUREC_LONG_BIT_NUM);\n}\n#endif\n\n/*\n * Convert hexadecimal characters to decimal value\n */\nSECUREC_INLINE int SecHexValueOfChar(SecInt ch)\n{\n    /* Use isdigit Causing tool false alarms */\n    return (int)((ch >= '0' && ch <= '9') ? ((unsigned char)ch - '0') :\n            ((((unsigned char)ch | (unsigned char)('a' - 'A')) - ('a')) + 10)); /* Adding 10 is to hex value */\n}\n\n/*\n * Parse decimal character to integer for 32bit .\n */\nstatic void SecDecodeNumberDecimal(SecScanSpec *spec)\n{\n#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))\n    unsigned long decimalEdge = SECUREC_MAX_32BITS_VALUE_DIV_TEN;\n#ifdef SECUREC_ON_64BITS\n    if (SecIsLongBitEqual(SECUREC_LP64_BIT_WIDTH) != 0) {\n        decimalEdge = (unsigned long)SECUREC_MAX_64BITS_VALUE_DIV_TEN;\n    }\n#endif\n    if (spec->number > decimalEdge) {\n        spec->beyondMax = 1;\n    }\n#endif\n    spec->number = SECUREC_MUL_TEN(spec->number);\n#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))\n    if (spec->number == SECUREC_MUL_TEN(decimalEdge)) {\n        /* This code is specially converted to unsigned long type for compatibility */\n        SecUnsignedInt64 number64As = (unsigned long)SECUREC_MAX_64BITS_VALUE - spec->number;\n        if (number64As < (SecUnsignedInt64)(SecUnsignedInt)spec->ch - (SecUnsignedInt)SECUREC_CHAR('0')) {\n            spec->beyondMax = 1;\n        }\n    }\n#endif\n    spec->number += ((unsigned long)(SecUnsignedInt)spec->ch - (SecUnsignedInt)SECUREC_CHAR('0'));\n}\n\n/*\n * Parse Hex character to integer for 32bit .\n */\nstatic void SecDecodeNumberHex(SecScanSpec *spec)\n{\n#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))\n    if (SECUREC_LONG_HEX_BEYOND_MAX(spec->number)) {\n        spec->beyondMax = 1;\n    }\n#endif\n    spec->number = SECUREC_MUL_SIXTEEN(spec->number);\n    spec->number += (unsigned long)(unsigned int)SecHexValueOfChar(spec->ch);\n}\n\n/*\n * Parse Octal character to integer for 32bit .\n */\nstatic void SecDecodeNumberOctal(SecScanSpec *spec)\n{\n#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))\n    if (SECUREC_LONG_OCTAL_BEYOND_MAX(spec->number)) {\n        spec->beyondMax = 1;\n    }\n#endif\n    spec->number = SECUREC_MUL_EIGHT(spec->number);\n    spec->number += ((unsigned long)(SecUnsignedInt)spec->ch - (SecUnsignedInt)SECUREC_CHAR('0'));\n}\n\n#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))\n/* Compatible with integer negative values other than int */\nSECUREC_INLINE void SecFinishNumberNegativeOther(SecScanSpec *spec)\n{\n    if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) {\n        if (spec->number > SECUREC_MIN_LONG_NEG_VALUE) {\n            spec->number = SECUREC_MIN_LONG_NEG_VALUE;\n        } else {\n            spec->number = (unsigned long)(0U - spec->number); /* Wrap with unsigned long numbers */\n        }\n        if (spec->beyondMax != 0) {\n            if (spec->numberWidth < SECUREC_NUM_WIDTH_INT) {\n                spec->number = 0;\n            }\n            if (spec->numberWidth == SECUREC_NUM_WIDTH_LONG) {\n                spec->number = SECUREC_MIN_LONG_NEG_VALUE;\n            }\n        }\n    } else { /* For o, u, x, X, p */\n        spec->number = (unsigned long)(0U - spec->number); /* Wrap with unsigned long numbers */\n        if (spec->beyondMax != 0) {\n            spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE;\n        }\n    }\n}\n/* Compatible processing of integer negative numbers */\nSECUREC_INLINE void SecFinishNumberNegativeInt(SecScanSpec *spec)\n{\n    if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) {\n#ifdef SECUREC_ON_64BITS\n        if (SecIsLongBitEqual(SECUREC_LP64_BIT_WIDTH) != 0) {\n            if ((spec->number > SECUREC_MIN_64BITS_NEG_VALUE)) {\n                spec->number = 0;\n            } else {\n                spec->number = (unsigned int)(0U - (unsigned int)spec->number); /* Wrap with unsigned int numbers */\n            }\n        }\n#else\n        if (SecIsLongBitEqual(SECUREC_LP32_BIT_WIDTH) != 0) {\n            if ((spec->number > SECUREC_MIN_32BITS_NEG_VALUE)) {\n                spec->number = SECUREC_MIN_32BITS_NEG_VALUE;\n            } else {\n                spec->number = (unsigned int)(0U - (unsigned int)spec->number); /* Wrap with unsigned int numbers */\n            }\n        }\n#endif\n        if (spec->beyondMax != 0) {\n#ifdef SECUREC_ON_64BITS\n            if (SecIsLongBitEqual(SECUREC_LP64_BIT_WIDTH) != 0) {\n                spec->number = 0;\n            }\n#else\n            if (SecIsLongBitEqual(SECUREC_LP32_BIT_WIDTH) != 0) {\n                spec->number = SECUREC_MIN_32BITS_NEG_VALUE;\n            }\n#endif\n        }\n    } else {            /* For o, u, x, X ,p */\n#ifdef SECUREC_ON_64BITS\n        if (spec->number > SECUREC_MAX_32BITS_VALUE_INC) {\n            spec->number = SECUREC_MAX_32BITS_VALUE;\n        } else {\n            spec->number = (unsigned int)(0U - (unsigned int)spec->number); /* Wrap with unsigned int numbers */\n        }\n#else\n        spec->number = (unsigned int)(0U - (unsigned int)spec->number); /* Wrap with unsigned int numbers */\n#endif\n        if (spec->beyondMax != 0) {\n            spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE;\n        }\n    }\n}\n\n/* Compatible with integer positive values other than int */\nSECUREC_INLINE void SecFinishNumberPositiveOther(SecScanSpec *spec)\n{\n    if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) {\n        if (spec->number > SECUREC_MAX_LONG_POS_VALUE) {\n            spec->number = SECUREC_MAX_LONG_POS_VALUE;\n        }\n        if ((spec->beyondMax != 0 && spec->numberWidth < SECUREC_NUM_WIDTH_INT)) {\n            spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE;\n        }\n        if (spec->beyondMax != 0 && spec->numberWidth == SECUREC_NUM_WIDTH_LONG) {\n            spec->number = SECUREC_MAX_LONG_POS_VALUE;\n        }\n    } else {\n        if (spec->beyondMax != 0) {\n            spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE;\n        }\n    }\n}\n\n/* Compatible processing of integer positive numbers */\nSECUREC_INLINE void SecFinishNumberPositiveInt(SecScanSpec *spec)\n{\n    if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) {\n#ifdef SECUREC_ON_64BITS\n        if (SecIsLongBitEqual(SECUREC_LP64_BIT_WIDTH) != 0) {\n            if (spec->number > SECUREC_MAX_64BITS_POS_VALUE) {\n                spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE;\n            }\n        }\n        if (spec->beyondMax != 0 && SecIsLongBitEqual(SECUREC_LP64_BIT_WIDTH) != 0) {\n            spec->number = (unsigned long)SECUREC_MAX_64BITS_VALUE;\n        }\n#else\n        if (SecIsLongBitEqual(SECUREC_LP32_BIT_WIDTH) != 0) {\n            if (spec->number > SECUREC_MAX_32BITS_POS_VALUE) {\n                spec->number = SECUREC_MAX_32BITS_POS_VALUE;\n            }\n        }\n        if (spec->beyondMax != 0 && SecIsLongBitEqual(SECUREC_LP32_BIT_WIDTH) != 0) {\n            spec->number = SECUREC_MAX_32BITS_POS_VALUE;\n        }\n#endif\n    } else {            /* For o,u,x,X,p */\n        if (spec->beyondMax != 0) {\n            spec->number = SECUREC_MAX_32BITS_VALUE;\n        }\n    }\n}\n\n#endif\n\n/*\n * Parse decimal character to integer for 64bit .\n */\nstatic void SecDecodeNumber64Decimal(SecScanSpec *spec)\n{\n#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))\n    if (spec->number64 > SECUREC_MAX_64BITS_VALUE_DIV_TEN) {\n        spec->beyondMax = 1;\n    }\n#endif\n    spec->number64 = SECUREC_MUL_TEN(spec->number64);\n#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))\n    if (spec->number64 == SECUREC_MAX_64BITS_VALUE_CUT_LAST_DIGIT) {\n        SecUnsignedInt64 number64As = (SecUnsignedInt64)SECUREC_MAX_64BITS_VALUE - spec->number64;\n        if (number64As < (SecUnsignedInt64)(SecUnsignedInt)spec->ch - (SecUnsignedInt)SECUREC_CHAR('0')) {\n            spec->beyondMax = 1;\n        }\n    }\n#endif\n    spec->number64 += ((SecUnsignedInt64)(SecUnsignedInt)spec->ch - (SecUnsignedInt)SECUREC_CHAR('0'));\n}\n\n/*\n * Parse Hex character to integer for 64bit .\n */\nstatic void SecDecodeNumber64Hex(SecScanSpec *spec)\n{\n#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))\n    if (SECUREC_QWORD_HEX_BEYOND_MAX(spec->number64)) {\n        spec->beyondMax = 1;\n    }\n#endif\n    spec->number64 = SECUREC_MUL_SIXTEEN(spec->number64);\n    spec->number64 += (SecUnsignedInt64)(unsigned int)SecHexValueOfChar(spec->ch);\n}\n\n/*\n * Parse Octal character to integer for 64bit .\n */\nstatic void SecDecodeNumber64Octal(SecScanSpec *spec)\n{\n#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))\n    if (SECUREC_QWORD_OCTAL_BEYOND_MAX(spec->number64)) {\n        spec->beyondMax = 1;\n    }\n#endif\n    spec->number64 = SECUREC_MUL_EIGHT(spec->number64);\n    spec->number64 += ((SecUnsignedInt64)(SecUnsignedInt)spec->ch - (SecUnsignedInt)SECUREC_CHAR('0'));\n}\n\n#define SECUREC_DECODE_NUMBER_FUNC_NUM 2\n\n/*\n * Parse 64-bit integer formatted input, return 0 when ch is a number.\n */\nSECUREC_INLINE int SecDecodeNumber(SecScanSpec *spec)\n{\n    /* Function name cannot add address symbol, causing 546 alarm */\n    static void (* const secDecodeNumberHex[SECUREC_DECODE_NUMBER_FUNC_NUM])(SecScanSpec *spec) = {\n        SecDecodeNumberHex, SecDecodeNumber64Hex\n    };\n    static void (* const secDecodeNumberOctal[SECUREC_DECODE_NUMBER_FUNC_NUM])(SecScanSpec *spec) = {\n        SecDecodeNumberOctal, SecDecodeNumber64Octal\n    };\n    static void (* const secDecodeNumberDecimal[SECUREC_DECODE_NUMBER_FUNC_NUM])(SecScanSpec *spec) = {\n        SecDecodeNumberDecimal, SecDecodeNumber64Decimal\n    };\n    if (spec->convChr == 'x' || spec->convChr == 'p') {\n        if (SecIsXdigit(spec->ch) != 0) {\n            (*secDecodeNumberHex[spec->numberArgType])(spec);\n        } else {\n            return -1;\n        }\n        return 0;\n    }\n    if (SecIsDigit(spec->ch) == 0) {\n        return -1;\n    }\n    if (spec->convChr == 'o') {\n        if (spec->ch < SECUREC_CHAR('8')) { /* Octal maximum limit '8' */\n            (*secDecodeNumberOctal[spec->numberArgType])(spec);\n        } else {\n            return -1;\n        }\n    } else { /* The convChr is 'd' */\n        (*secDecodeNumberDecimal[spec->numberArgType])(spec);\n    }\n    return 0;\n}\n\n/*\n * Complete the final 32-bit integer formatted input\n */\nstatic void SecFinishNumber(SecScanSpec *spec)\n{\n#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))\n    if (spec->negative != 0) {\n        if (spec->numberWidth == SECUREC_NUM_WIDTH_INT) {\n            SecFinishNumberNegativeInt(spec);\n        } else {\n            SecFinishNumberNegativeOther(spec);\n        }\n    } else {\n        if (spec->numberWidth == SECUREC_NUM_WIDTH_INT) {\n            SecFinishNumberPositiveInt(spec);\n        } else {\n            SecFinishNumberPositiveOther(spec);\n        }\n    }\n#else\n    if (spec->negative != 0) {\n#if defined(__hpux)\n        if (spec->oriConvChr != 'p') {\n            spec->number = (unsigned long)(0U - spec->number); /* Wrap with unsigned long numbers */\n        }\n#else\n        spec->number = (unsigned long)(0U - spec->number); /* Wrap with unsigned long numbers */\n#endif\n    }\n#endif\n    return;\n}\n\n/*\n * Complete the final 64-bit integer formatted input\n */\nstatic void SecFinishNumber64(SecScanSpec *spec)\n{\n#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && !(defined(SECUREC_ON_UNIX)))\n    if (spec->negative != 0) {\n        if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) {\n            if (spec->number64 > SECUREC_MIN_64BITS_NEG_VALUE) {\n                spec->number64 = SECUREC_MIN_64BITS_NEG_VALUE;\n            } else {\n                spec->number64 = (SecUnsignedInt64)(0U - spec->number64); /* Wrap with unsigned int64 numbers */\n            }\n            if (spec->beyondMax != 0) {\n                spec->number64 = SECUREC_MIN_64BITS_NEG_VALUE;\n            }\n        } else {                /* For o, u, x, X, p */\n            spec->number64 = (SecUnsignedInt64)(0U - spec->number64); /* Wrap with unsigned int64 numbers */\n            if (spec->beyondMax != 0) {\n                spec->number64 = SECUREC_MAX_64BITS_VALUE;\n            }\n        }\n    } else {\n        if (SECUREC_CONVERT_IS_SIGNED(spec->oriConvChr)) {\n            if (spec->number64 > SECUREC_MAX_64BITS_POS_VALUE) {\n                spec->number64 = SECUREC_MAX_64BITS_POS_VALUE;\n            }\n            if (spec->beyondMax != 0) {\n                spec->number64 = SECUREC_MAX_64BITS_POS_VALUE;\n            }\n        } else {\n            if (spec->beyondMax != 0) {\n                spec->number64 = SECUREC_MAX_64BITS_VALUE;\n            }\n        }\n    }\n#else\n    if (spec->negative != 0) {\n#if defined(__hpux)\n        if (spec->oriConvChr != 'p') {\n            spec->number64 = (SecUnsignedInt64)(0U - spec->number64); /* Wrap with unsigned int64 numbers */\n        }\n#else\n        spec->number64 = (SecUnsignedInt64)(0U - spec->number64); /* Wrap with unsigned int64 numbers */\n#endif\n    }\n#endif\n    return;\n}\n\n#if SECUREC_ENABLE_SCANF_FILE\n\n/*\n *  Adjust the pointer position of the file stream\n */\nSECUREC_INLINE void SecSeekStream(SecFileStream *stream)\n{\n    if (stream->count == 0) {\n        if (feof(stream->pf) != 0) {\n            /* File pointer at the end of file, don't need to seek back */\n            stream->base[0] = '\\0';\n            return;\n        }\n    }\n    /* Seek to original position, for file read, but nothing to input */\n    if (fseek(stream->pf, stream->oriFilePos, SEEK_SET) != 0) {\n        /* Seek failed, ignore it */\n        stream->oriFilePos = 0;\n        return;\n    }\n\n    if (stream->fileRealRead > 0) { /* Do not seek without input data */\n#if defined(SECUREC_COMPATIBLE_WIN_FORMAT)\n        size_t residue = stream->fileRealRead % SECUREC_BUFFERED_BLOK_SIZE;\n        size_t loops;\n        for (loops = 0; loops < (stream->fileRealRead / SECUREC_BUFFERED_BLOK_SIZE); ++loops) {\n            if (fread(stream->base, (size_t)SECUREC_BUFFERED_BLOK_SIZE, (size_t)1, stream->pf) != (size_t)1) {\n                break;\n            }\n        }\n        if (residue != 0) {\n            long curFilePos;\n            if (fread(stream->base, residue, (size_t)1, stream->pf) != (size_t)1) {\n                return;\n            }\n            curFilePos = ftell(stream->pf);\n            if (curFilePos < stream->oriFilePos ||\n                (size_t)(unsigned long)(curFilePos - stream->oriFilePos) < stream->fileRealRead) {\n                /* Try to remedy the problem */\n                long adjustNum = (long)(stream->fileRealRead - (size_t)(unsigned long)(curFilePos - stream->oriFilePos));\n                (void)fseek(stream->pf, adjustNum, SEEK_CUR);\n            }\n        }\n#else\n        /* Seek from oriFilePos. Regardless of the integer sign problem, call scanf will not read very large data */\n        if (fseek(stream->pf, (long)stream->fileRealRead, SEEK_CUR) != 0) {\n            /* Seek failed, ignore it */\n            stream->oriFilePos = 0;\n            return;\n        }\n#endif\n    }\n    return;\n}\n\n/*\n *  Adjust the pointer position of the file stream and free memory\n */\nSECUREC_INLINE void SecAdjustStream(SecFileStream *stream)\n{\n    if ((stream->flag & SECUREC_FILE_STREAM_FLAG) != 0 && stream->base != NULL) {\n        SecSeekStream(stream);\n        SECUREC_FREE(stream->base);\n        stream->base = NULL;\n    }\n    return;\n}\n#endif\n\nSECUREC_INLINE void SecSkipSpaceFormat(const SecUnsignedChar **format)\n{\n    const SecUnsignedChar *fmt = *format;\n    while (SecIsSpace((SecInt)(int)(*fmt)) != 0) {\n        ++fmt;\n    }\n    *format = fmt;\n}\n\n#if !defined(SECUREC_FOR_WCHAR) && defined(SECUREC_COMPATIBLE_VERSION)\n/*\n * Handling multi-character characters\n */\nSECUREC_INLINE int SecDecodeLeadByte(SecScanSpec *spec, const SecUnsignedChar **format, SecFileStream *stream)\n{\n#if SECUREC_HAVE_MBTOWC\n    const SecUnsignedChar *fmt = *format;\n    int ch1 = (int)spec->ch;\n    int ch2 = SecGetChar(stream, &(spec->charCount));\n    spec->ch = (SecInt)ch2;\n    if (*fmt == SECUREC_CHAR('\\0') || (int)(*fmt) != ch2) {\n        /* in console mode, ungetc twice may cause problem */\n        SecUnGetChar(ch2, stream, &(spec->charCount));\n        SecUnGetChar(ch1, stream, &(spec->charCount));\n        return -1;\n    }\n    ++fmt;\n    if ((unsigned int)MB_CUR_MAX >= SECUREC_UTF8_BOM_HEADER_SIZE &&\n        (((unsigned char)ch1 & SECUREC_UTF8_LEAD_1ST) == SECUREC_UTF8_LEAD_1ST) &&\n        (((unsigned char)ch2 & SECUREC_UTF8_LEAD_2ND) == SECUREC_UTF8_LEAD_2ND)) {\n        /* This char is very likely to be a UTF-8 char */\n        wchar_t tempWChar;\n        char temp[SECUREC_MULTI_BYTE_MAX_LEN];\n        int ch3 = (int)SecGetChar(stream, &(spec->charCount));\n        spec->ch = (SecInt)ch3;\n        if (*fmt == SECUREC_CHAR('\\0') || (int)(*fmt) != ch3) {\n            SecUnGetChar(ch3, stream, &(spec->charCount));\n            return -1;\n        }\n        temp[0] = (char)ch1;\n        temp[1] = (char)ch2; /* 1 index of second character */\n        temp[2] = (char)ch3; /* 2 index of third character */\n        temp[3] = '\\0';      /* 3 of string terminator position */\n        if (mbtowc(&tempWChar, temp, sizeof(temp)) > 0) {\n            /* Succeed */\n            ++fmt;\n            --spec->charCount;\n        } else {\n            SecUnGetChar(ch3, stream, &(spec->charCount));\n        }\n    }\n    --spec->charCount;    /* Only count as one character read */\n    *format = fmt;\n    return 0;\n#else\n    SecUnGetChar(spec->ch, stream, &(spec->charCount));\n    (void)format; /* To clear e438 last value assigned not used , the compiler will optimize this code */\n    return -1;\n#endif\n}\n\nSECUREC_INLINE int SecFilterWcharInFormat(SecScanSpec *spec, const SecUnsignedChar **format, SecFileStream *stream)\n{\n    if (SecIsLeadByte(spec->ch) != 0) {\n        if (SecDecodeLeadByte(spec, format, stream) != 0) {\n            return -1;\n        }\n    }\n    return 0;\n}\n#endif\n\n/*\n *  Resolving sequence of characters from %[ format, format wile point to ']'\n */\nSECUREC_INLINE int SecSetupBracketTable(const SecUnsignedChar **format, SecBracketTable *bracketTable)\n{\n    const SecUnsignedChar *fmt = *format;\n    SecUnsignedChar prevChar = 0;\n#if !(defined(SECUREC_COMPATIBLE_WIN_FORMAT))\n    if (*fmt == SECUREC_CHAR('{')) {\n        return -1;\n    }\n#endif\n    /* For building \"table\" data */\n    ++fmt; /* Skip [ */\n    bracketTable->mask = 0; /* Set all bits to 0 */\n    if (*fmt == SECUREC_CHAR('^')) {\n        ++fmt;\n        bracketTable->mask = (unsigned char)0xffU; /* Use 0xffU to set all bits to 1 */\n    }\n    if (*fmt == SECUREC_CHAR(']')) {\n        prevChar = SECUREC_CHAR(']');\n        ++fmt;\n        SecBracketSetBit(bracketTable->table, SECUREC_CHAR(']'));\n    }\n    while (*fmt != SECUREC_CHAR('\\0') && *fmt != SECUREC_CHAR(']')) {\n        SecUnsignedChar expCh = *fmt;\n        ++fmt;\n        if (expCh != SECUREC_CHAR('-') || prevChar == 0 || *fmt == SECUREC_CHAR(']')) {\n            /* Normal character */\n            prevChar = expCh;\n            SecBracketSetBit(bracketTable->table, expCh);\n        } else {\n            /* For %[a-z] */\n            expCh = *fmt;   /* Get end of range */\n            ++fmt;\n            if (prevChar <= expCh) {  /* %[a-z] %[a-a] */\n                SecBracketSetBitRange(bracketTable->table, prevChar, expCh);\n            } else {\n                /* For %[z-a] */\n#if defined(SECUREC_COMPATIBLE_WIN_FORMAT)\n                /* Swap start and end characters */\n                SecBracketSetBitRange(bracketTable->table, expCh, prevChar);\n#else\n                SecBracketSetBit(bracketTable->table, SECUREC_CHAR('-'));\n                SecBracketSetBit(bracketTable->table, expCh);\n#endif\n            }\n            prevChar = 0;\n        }\n    }\n    *format = fmt;\n    return 0;\n}\n\n#ifdef SECUREC_FOR_WCHAR\nSECUREC_INLINE int SecInputForWchar(SecScanSpec *spec)\n{\n    void *endPtr = spec->argPtr;\n    if (spec->isWCharOrLong > 0) {\n        *(wchar_t UNALIGNED *)endPtr = (wchar_t)spec->ch;\n        endPtr = (wchar_t *)endPtr + 1;\n        --spec->arrayWidth;\n    } else {\n#if SECUREC_HAVE_WCTOMB\n        int temp;\n        char tmpBuf[SECUREC_MB_LEN + 1];\n        SECUREC_MASK_MSVC_CRT_WARNING temp = wctomb(tmpBuf, (wchar_t)spec->ch);\n        SECUREC_END_MASK_MSVC_CRT_WARNING\n        if (temp <= 0 || (size_t)(unsigned int)temp > sizeof(tmpBuf)) {\n            /* If wctomb  error, then ignore character */\n            return 0;\n        }\n        if (((size_t)(unsigned int)temp) > spec->arrayWidth) {\n            return -1;\n        }\n        if (memcpy_s(endPtr, spec->arrayWidth, tmpBuf, (size_t)(unsigned int)temp) != EOK) {\n            return -1;\n        }\n        endPtr = (char *)endPtr + temp;\n        spec->arrayWidth -= (size_t)(unsigned int)temp;\n#else\n        return -1;\n#endif\n    }\n    spec->argPtr = endPtr;\n    return 0;\n}\n#endif\n\n#ifndef SECUREC_FOR_WCHAR\n#if SECUREC_HAVE_WCHART\nSECUREC_INLINE wchar_t SecConvertInputCharToWchar(SecScanSpec *spec, SecFileStream *stream)\n{\n    wchar_t tempWChar = L'?';   /* Set default char is ? */\n#if SECUREC_HAVE_MBTOWC\n    char temp[SECUREC_MULTI_BYTE_MAX_LEN + 1];\n    temp[0] = (char)spec->ch;\n    temp[1] = '\\0';\n#if defined(SECUREC_COMPATIBLE_WIN_FORMAT)\n    if (SecIsLeadByte(spec->ch) != 0) {\n        spec->ch = SecGetChar(stream, &(spec->charCount));\n        temp[1] = (char)spec->ch;\n        temp[2] = '\\0'; /* 2 of string terminator position */\n    }\n    if (mbtowc(&tempWChar, temp, sizeof(temp)) <= 0) {\n        /* No string termination error for tool */\n        tempWChar = L'?';\n    }\n#else\n    if (SecIsLeadByte(spec->ch) != 0) {\n        int convRes = 0;\n        int di = 1;\n        /* On Linux like system, the string is encoded in UTF-8 */\n        while (convRes <= 0 && di < (int)MB_CUR_MAX && di < SECUREC_MULTI_BYTE_MAX_LEN) {\n            spec->ch = SecGetChar(stream, &(spec->charCount));\n            temp[di] = (char)spec->ch;\n            ++di;\n            temp[di] = '\\0';\n            convRes = mbtowc(&tempWChar, temp, sizeof(temp));\n        }\n        if (convRes <= 0) {\n            tempWChar = L'?';\n        }\n    } else {\n        if (mbtowc(&tempWChar, temp, sizeof(temp)) <= 0) {\n            tempWChar = L'?';\n        }\n    }\n#endif\n#else\n    (void)spec;      /* To clear e438 last value assigned not used , the compiler will optimize this code */\n    (void)stream;    /* To clear e438 last value assigned not used , the compiler will optimize this code */\n#endif /* SECUREC_HAVE_MBTOWC */\n\n    return tempWChar;\n}\n#endif /* SECUREC_HAVE_WCHART */\n\nSECUREC_INLINE int SecInputForChar(SecScanSpec *spec, SecFileStream *stream)\n{\n    void *endPtr = spec->argPtr;\n    if (spec->isWCharOrLong > 0) {\n#if SECUREC_HAVE_WCHART\n        *(wchar_t UNALIGNED *)endPtr = SecConvertInputCharToWchar(spec, stream);\n        endPtr = (wchar_t *)endPtr + 1;\n        --spec->arrayWidth;\n#else\n    (void)stream;    /* To clear e438 last value assigned not used , the compiler will optimize this code */\n    return -1;\n#endif\n    } else {\n        *(char *)endPtr = (char)spec->ch;\n        endPtr = (char *)endPtr + 1;\n        --spec->arrayWidth;\n    }\n    spec->argPtr = endPtr;\n    return 0;\n}\n#endif\n\n/*\n * Scan digital part of %d %i %o %u %x %p.\n * Return 0 OK\n */\nSECUREC_INLINE int SecInputNumberDigital(SecFileStream *stream, SecScanSpec *spec)\n{\n    static void (* const secFinishNumber[SECUREC_DECODE_NUMBER_FUNC_NUM])(SecScanSpec *spec) = {\n        SecFinishNumber, SecFinishNumber64\n    };\n    while (SECUREC_FILED_WIDTH_ENOUGH(spec)) {\n        spec->ch = SecGetChar(stream, &(spec->charCount));\n        /* Decode ch to number */\n        if (SecDecodeNumber(spec) != 0) {\n            SecUnGetChar(spec->ch, stream, &(spec->charCount));\n            break;\n        }\n        SECUREC_FILED_WIDTH_DEC(spec); /* Must be behind un get char, otherwise the logic is incorrect */\n        spec->numberState = SECUREC_NUMBER_STATE_STARTED;\n    }\n    /* Handling integer negative numbers and beyond max */\n    (*secFinishNumber[spec->numberArgType])(spec);\n    if (spec->numberState == SECUREC_NUMBER_STATE_STARTED) {\n        return 0;\n    }\n    return -1;\n}\n\n/*\n * Scan %d %i %o %u %x %p.\n * Return 0 OK\n */\nSECUREC_INLINE int SecInputNumber(SecFileStream *stream, SecScanSpec *spec)\n{\n    /* Character already read */\n    if (spec->ch == SECUREC_CHAR('+') || spec->ch == SECUREC_CHAR('-')) {\n        if (spec->ch == SECUREC_CHAR('-')) {\n            spec->negative = 1;\n#if SECUREC_IN_KERNEL\n            /* In kernel Refuse to enter negative number */\n            if (SECUREC_CONVERT_IS_UNSIGNED(spec->oriConvChr)) {\n                return -1;\n            }\n#endif\n        }\n        SECUREC_FILED_WIDTH_DEC(spec); /* Do not need to check width here, must be greater than 0 */\n        spec->ch = SecGetChar(stream, &(spec->charCount)); /* Eat + or - */\n        spec->ch = SecGetChar(stream, &(spec->charCount)); /* Get next character, used for the '0' judgments */\n        SecUnGetChar(spec->ch, stream, &(spec->charCount)); /* Not sure if it was actually read, so push back */\n    }\n\n    if (spec->oriConvChr == 'i') {\n        spec->convChr = 'd'; /* The i could be d, o, or x, use d as default */\n    }\n\n    if (spec->ch == SECUREC_CHAR('0') && (spec->oriConvChr == 'x' || spec->oriConvChr == 'i') &&\n        SECUREC_FILED_WIDTH_ENOUGH(spec)) {\n        /* Input string begin with 0, may be 0x123  0X123  0123  0x  01  0yy  09  0  0ab 00 */\n        SECUREC_FILED_WIDTH_DEC(spec);\n        spec->ch = SecGetChar(stream, &(spec->charCount)); /* ch is '0' */\n\n        /* Read only '0' due to width limitation */\n        if (!SECUREC_FILED_WIDTH_ENOUGH(spec)) {\n            /* The number or number64 in spec has been set 0 */\n            return 0;\n        }\n\n        spec->ch = SecGetChar(stream, &(spec->charCount)); /* Get next char to check x or X, do not dec width */\n        if ((SecChar)spec->ch == SECUREC_CHAR('x') || (SecChar)spec->ch == SECUREC_CHAR('X')) {\n            spec->convChr = 'x';\n            SECUREC_FILED_WIDTH_DEC(spec); /* Make incorrect width for x or X */\n        } else {\n            if (spec->oriConvChr == 'i') {\n                spec->convChr = 'o';\n            }\n            /* For \"0y\" \"08\" \"01\" \"0a\" ... ,push the 'y' '8' '1' 'a'  back */\n            SecUnGetChar(spec->ch, stream, &(spec->charCount));\n            /* Since 0 has been read, it indicates that a valid character has been read */\n            spec->numberState = SECUREC_NUMBER_STATE_STARTED;\n        }\n    }\n    return SecInputNumberDigital(stream, spec);\n}\n\n/*\n * Scan %c %s %[\n * Return 0 OK\n */\nSECUREC_INLINE int SecInputString(SecFileStream *stream, SecScanSpec *spec,\n    const SecBracketTable *bracketTable, int *doneCount)\n{\n    void *startPtr = spec->argPtr;\n    int suppressed = 0;\n    int errNoMem = 0;\n\n    while (SECUREC_FILED_WIDTH_ENOUGH(spec)) {\n        SECUREC_FILED_WIDTH_DEC(spec);\n        spec->ch = SecGetChar(stream, &(spec->charCount));\n        /*\n         * The char condition or string condition and bracket condition.\n         * Only supports wide characters with a maximum length of two bytes\n         */\n        if (spec->ch != SECUREC_EOF && (SecCanInputCharacter(spec->convChr) != 0 ||\n            SecCanInputString(spec->convChr, spec->ch) != 0 ||\n            SecCanInputForBracket(spec->convChr, spec->ch, bracketTable) != 0)) {\n            if (spec->suppress != 0) {\n                /* Used to identify processed data for %*, use argPtr to identify will cause 613, so use suppressed */\n                suppressed = 1;\n                continue;\n            }\n            /* Now suppress is not set */\n            if (spec->arrayWidth == 0) {\n                errNoMem = 1; /* We have exhausted the user's buffer */\n                break;\n            }\n#ifdef SECUREC_FOR_WCHAR\n            errNoMem = SecInputForWchar(spec);\n#else\n            errNoMem = SecInputForChar(spec, stream);\n#endif\n            if (errNoMem != 0) {\n                break;\n            }\n        } else {\n            SecUnGetChar(spec->ch, stream, &(spec->charCount));\n            break;\n        }\n    }\n\n    if (errNoMem != 0) {\n        /* In case of error, blank out the input buffer */\n        SecAddEndingZero(startPtr, spec);\n        return -1;\n    }\n    if ((spec->suppress != 0 && suppressed == 0) ||\n        (spec->suppress == 0 && startPtr == spec->argPtr)) {\n        /* No input was scanned */\n        return -1;\n    }\n    if (spec->convChr != 'c') {\n        /* Add null-terminate for strings */\n        SecAddEndingZero(spec->argPtr, spec);\n    }\n    if (spec->suppress == 0) {\n        *doneCount = *doneCount + 1;\n    }\n    return 0;\n}\n\n#ifdef SECUREC_FOR_WCHAR\n/*\n * Allocate buffer for wchar version of %[.\n * Return 0 OK\n */\nSECUREC_INLINE int SecAllocBracketTable(SecBracketTable *bracketTable)\n{\n    if (bracketTable->table == NULL) {\n        /* Table should be freed after use */\n        bracketTable->table = (unsigned char *)SECUREC_MALLOC(SECUREC_BRACKET_TABLE_SIZE);\n        if (bracketTable->table == NULL) {\n            return -1;\n        }\n    }\n    return 0;\n}\n\n/*\n * Free buffer for wchar version of %[\n */\nSECUREC_INLINE void SecFreeBracketTable(SecBracketTable *bracketTable)\n{\n    if (bracketTable->table != NULL) {\n        SECUREC_FREE(bracketTable->table);\n        bracketTable->table = NULL;\n    }\n}\n#endif\n\n#ifdef SECUREC_FOR_WCHAR\n/*\n *  Formatting input core functions for wchar version.Called by a function such as vswscanf_s\n */\nint SecInputSW(SecFileStream *stream, const wchar_t *cFormat, va_list argList)\n#else\n/*\n * Formatting input core functions for char version.Called by a function such as vsscanf_s\n */\nint SecInputS(SecFileStream *stream, const char *cFormat, va_list argList)\n#endif\n{\n    const SecUnsignedChar *format = (const SecUnsignedChar *)cFormat;\n    SecBracketTable bracketTable = SECUREC_INIT_BRACKET_TABLE;\n    SecScanSpec spec;\n    int doneCount = 0;\n    int formatError = 0;\n    int paraIsNull = 0;\n    int match = 0; /* When % is found , inc this value */\n    int errRet = 0;\n#if SECUREC_ENABLE_SCANF_FLOAT\n    SecFloatSpec floatSpec;\n    SecInitFloatSpec(&floatSpec);\n#endif\n    spec.ch = 0; /* Need to initialize to 0 */\n    spec.charCount = 0; /* Need to initialize to 0 */\n\n    /* Format must not NULL, use err < 1 to clear 845 */\n    while (errRet < 1 && *format != SECUREC_CHAR('\\0')) {\n        /* Skip space in format and space in input */\n        if (SecIsSpace((SecInt)(int)(*format)) != 0) {\n            /* Read first no space char */\n            spec.ch = SecSkipSpaceChar(stream, &(spec.charCount));\n            /* Read the EOF cannot be returned directly here, because the case of \" %n\" needs to be handled */\n            /* Put fist no space char backup. put EOF back is also OK, and to modify the character count */\n            SecUnGetChar(spec.ch, stream, &(spec.charCount));\n            SecSkipSpaceFormat(&format);\n            continue;\n        }\n\n        if (*format != SECUREC_CHAR('%')) {\n            spec.ch = SecGetChar(stream, &(spec.charCount));\n            if ((int)(*format) != (int)(spec.ch)) {\n                SecUnGetChar(spec.ch, stream, &(spec.charCount));\n                break;\n            }\n            ++format;\n#if !defined(SECUREC_FOR_WCHAR) && defined(SECUREC_COMPATIBLE_VERSION)\n            if (SecFilterWcharInFormat(&spec, &format, stream) != 0) {\n                break;\n            }\n#endif\n            continue;\n        }\n\n        /* Now *format is % */\n        /* Set default value for each % */\n        SecSetDefaultScanSpec(&spec);\n        if (SecDecodeScanFlag(&format, &spec) != 0) {\n            formatError = 1;\n            ++errRet;\n            continue;\n        }\n        if (!SECUREC_FILED_WIDTH_ENOUGH(&spec)) {\n            /* 0 width in format */\n            ++errRet;\n            continue;\n        }\n\n        /* Update wchar flag for %S %C */\n        SecUpdateWcharFlagByType(*format, &spec);\n\n        spec.convChr = SECUREC_TO_LOWERCASE(*format);\n        spec.oriConvChr = spec.convChr; /* convChr may be modified to handle integer logic */\n        if (spec.convChr != 'n') {\n            if (spec.convChr != 'c' && spec.convChr != SECUREC_BRACE) {\n                spec.ch = SecSkipSpaceChar(stream, &(spec.charCount));\n            } else {\n                spec.ch = SecGetChar(stream, &(spec.charCount));\n            }\n            if (spec.ch == SECUREC_EOF) {\n                ++errRet;\n                continue;\n            }\n        }\n\n        /* Now no 0 width in format and get one char from input */\n        switch (spec.oriConvChr) {\n            case 'c': /* Also 'C' */\n                if (spec.widthSet == 0) {\n                    spec.widthSet = 1;\n                    spec.width = 1;\n                }\n                /* fall-through */ /* FALLTHRU */\n            case 's': /* Also 'S': */\n                /* fall-through */ /* FALLTHRU */\n            case SECUREC_BRACE:\n                /* Unset last char to stream */\n                SecUnGetChar(spec.ch, stream, &(spec.charCount));\n                /* Check dest buffer and size */\n                if (spec.suppress == 0) {\n                    spec.argPtr = (void *)va_arg(argList, void *);\n                    if (spec.argPtr == NULL) {\n                        paraIsNull = 1;\n                        ++errRet;\n                        continue;\n                    }\n                    /* Get the next argument, size of the array in characters */\n                    spec.arrayWidth = SECUREC_GET_ARRAYWIDTH(argList);\n                    if (SECUREC_ARRAY_WIDTH_IS_WRONG(spec)) {\n                        /* Do not clear buffer just go error */\n                        ++errRet;\n                        continue;\n                    }\n                    /* One element is needed for '\\0' for %s and %[ */\n                    if (spec.convChr != 'c') {\n                        --spec.arrayWidth;\n                    }\n                } else {\n                    /* Set argPtr to  NULL  is necessary, in suppress mode we don't use argPtr to store data */\n                    spec.argPtr = NULL;\n                }\n\n                if (spec.convChr == SECUREC_BRACE) {\n                    /* Malloc when first %[ is meet  for wchar version */\n#ifdef SECUREC_FOR_WCHAR\n                    if (SecAllocBracketTable(&bracketTable) != 0) {\n                        ++errRet;\n                        continue;\n                    }\n#endif\n                    (void)SECUREC_MEMSET_FUNC_OPT(bracketTable.table, 0, (size_t)SECUREC_BRACKET_TABLE_SIZE);\n                    if (SecSetupBracketTable(&format, &bracketTable) != 0) {\n                        ++errRet;\n                        continue;\n                    }\n\n                    if (*format == SECUREC_CHAR('\\0')) {\n                        /* Default add string terminator */\n                        SecAddEndingZero(spec.argPtr, &spec);\n                        ++errRet;\n                        /* Truncated format */\n                        continue;\n                    }\n                }\n\n                /* Set completed.  Now read string or character */\n                if (SecInputString(stream, &spec, &bracketTable, &doneCount) != 0) {\n                    ++errRet;\n                    continue;\n                }\n                break;\n            case 'p':\n                /* Make %hp same as %p */\n                spec.numberWidth = SECUREC_NUM_WIDTH_INT;\n#ifdef SECUREC_ON_64BITS\n                spec.numberArgType = 1;\n#endif\n                /* fall-through */ /* FALLTHRU */\n            case 'o': /* fall-through */ /* FALLTHRU */\n            case 'u': /* fall-through */ /* FALLTHRU */\n            case 'd': /* fall-through */ /* FALLTHRU */\n            case 'i': /* fall-through */ /* FALLTHRU */\n            case 'x':\n                /* Unset last char to stream */\n                SecUnGetChar(spec.ch, stream, &(spec.charCount));\n                if (SecInputNumber(stream, &spec) != 0) {\n                    ++errRet;\n                    continue;\n                }\n                if (spec.suppress == 0) {\n                    spec.argPtr = (void *)va_arg(argList, void *);\n                    if (spec.argPtr == NULL) {\n                        paraIsNull = 1;\n                        ++errRet;\n                        continue;\n                    }\n                    SecAssignNumber(&spec);\n                    ++doneCount;\n                }\n                break;\n            case 'n': /* Char count */\n                if (spec.suppress == 0) {\n                    spec.argPtr = (void *)va_arg(argList, void *);\n                    if (spec.argPtr == NULL) {\n                        paraIsNull = 1;\n                        ++errRet;\n                        continue;\n                    }\n                    spec.number = (unsigned long)(unsigned int)(spec.charCount);\n                    spec.numberArgType = 0;\n                    SecAssignNumber(&spec);\n                }\n                break;\n            case 'e': /* fall-through */ /* FALLTHRU */\n            case 'f': /* fall-through */ /* FALLTHRU */\n            case 'g': /* Scan a float */\n                /* Unset last char to stream */\n                SecUnGetChar(spec.ch, stream, &(spec.charCount));\n#if SECUREC_ENABLE_SCANF_FLOAT\n                if (SecInputFloat(stream, &spec, &floatSpec) != 0) {\n                    ++errRet;\n                    continue;\n                }\n                if (spec.suppress == 0) {\n                    spec.argPtr = (void *)va_arg(argList, void *);\n                    if (spec.argPtr == NULL) {\n                        ++errRet;\n                        paraIsNull = 1;\n                        continue;\n                    }\n                    if (SecAssignFloat(&floatSpec, &spec) != 0) {\n                        ++errRet;\n                        continue;\n                    }\n                    ++doneCount;\n                }\n                break;\n#else /* SECUREC_ENABLE_SCANF_FLOAT */\n                ++errRet;\n                continue;\n#endif\n            default:\n                if ((int)(*format) != (int)spec.ch) {\n                    SecUnGetChar(spec.ch, stream, &(spec.charCount));\n                    formatError = 1;\n                    ++errRet;\n                    continue;\n                } else {\n                    --match; /* Compensate for the self-increment of the following code */\n                }\n                break;\n        }\n        ++match;\n        ++format;\n    }\n\n#ifdef SECUREC_FOR_WCHAR\n    SecFreeBracketTable(&bracketTable);\n#endif\n\n#if SECUREC_ENABLE_SCANF_FLOAT\n    SecFreeFloatSpec(&floatSpec, &doneCount);\n#endif\n\n#if SECUREC_ENABLE_SCANF_FILE\n    SecAdjustStream(stream);\n#endif\n\n    if (spec.ch == SECUREC_EOF) {\n        return ((doneCount != 0 || match != 0) ? doneCount : SECUREC_SCANF_EINVAL);\n    }\n    if (formatError != 0 || paraIsNull != 0) {\n        /* Invalid Input Format or parameter, but not meet EOF */\n        return SECUREC_SCANF_ERROR_PARA;\n    }\n    return doneCount;\n}\n\n#if SECUREC_ENABLE_SCANF_FILE\n/*\n *  Get char from stream use std function\n */\nSECUREC_INLINE SecInt SecGetCharFromStream(const SecFileStream *stream)\n{\n    SecInt ch;\n    ch = SECUREC_GETC(stream->pf);\n    return ch;\n}\n\n/*\n * Try to read the BOM header, when meet a BOM head, discard it, then data is Aligned to base\n */\nSECUREC_INLINE void SecReadAndSkipBomHeader(SecFileStream *stream)\n{\n    /* Use size_t type conversion  to clean e747 */\n    stream->count = fread(stream->base, (size_t)1, (size_t)SECUREC_BOM_HEADER_SIZE, stream->pf);\n    if (stream->count > SECUREC_BOM_HEADER_SIZE) {\n        stream->count = 0;\n    }\n    if (SECUREC_BEGIN_WITH_BOM(stream->base, stream->count)) {\n        /* It's BOM header, discard it */\n        stream->count = 0;\n    }\n}\n\n/*\n *  Get char  from file stream or buffer\n */\nSECUREC_INLINE SecInt SecGetCharFromFile(SecFileStream *stream)\n{\n    SecInt ch;\n    if (stream->count < sizeof(SecChar)) {\n        /* Load file to buffer */\n        size_t len;\n        if (stream->base != NULL) {\n            /* Put the last unread data in the buffer head */\n            for (len = 0; len < stream->count; ++len) {\n                stream->base[len] = stream->cur[len];\n            }\n        } else {\n            stream->oriFilePos = ftell(stream->pf);   /* Save original file read position */\n            if (stream->oriFilePos == -1) {\n                /* It may be a pipe stream */\n                stream->flag = SECUREC_PIPE_STREAM_FLAG;\n                return SecGetCharFromStream(stream);\n            }\n            /* Reserve the length of BOM head */\n            stream->base = (char *)SECUREC_MALLOC(SECUREC_BUFFERED_BLOK_SIZE +\n                SECUREC_BOM_HEADER_SIZE + sizeof(SecChar)); /* To store '\\0' and aligned to wide char */\n            if (stream->base == NULL) {\n                return SECUREC_EOF;\n            }\n            /* First read file */\n            if (stream->oriFilePos == 0) {\n                /* Make sure the data is aligned to base */\n                SecReadAndSkipBomHeader(stream);\n            }\n        }\n\n        /* Skip existing data and read data */\n        len = fread(stream->base + stream->count, (size_t)1, (size_t)SECUREC_BUFFERED_BLOK_SIZE, stream->pf);\n        if (len > SECUREC_BUFFERED_BLOK_SIZE) { /* It won't happen, */\n            len = 0;\n        }\n        stream->count += len;\n        stream->cur = stream->base;\n        stream->flag |= SECUREC_LOAD_FILE_TO_MEM_FLAG;\n        stream->base[stream->count] = '\\0';   /* For tool Warning string null */\n    }\n\n    SECUREC_GET_CHAR(stream, &ch);\n    if (ch != SECUREC_EOF) {\n        stream->fileRealRead += sizeof(SecChar);\n    }\n    return ch;\n}\n#endif\n\n/*\n *  Get char  for wchar version\n */\nSECUREC_INLINE SecInt SecGetChar(SecFileStream *stream, int *counter)\n{\n    *counter = *counter + 1; /* Always plus 1 */\n    /* The main scenario is scanf str */\n    if ((stream->flag & SECUREC_MEM_STR_FLAG) != 0) {\n        SecInt ch;\n        SECUREC_GET_CHAR(stream, &ch);\n        return ch;\n    }\n#if SECUREC_ENABLE_SCANF_FILE\n    if ((stream->flag & SECUREC_FILE_STREAM_FLAG) != 0) {\n        return SecGetCharFromFile(stream);\n    }\n    if ((stream->flag & SECUREC_PIPE_STREAM_FLAG) != 0) {\n        return SecGetCharFromStream(stream);\n    }\n#endif\n    return SECUREC_EOF;\n}\n\n/*\n *  Unget Public realization char for wchar and char version\n */\nSECUREC_INLINE void SecUnGetCharImpl(SecInt ch, SecFileStream *stream)\n{\n    if ((stream->flag & SECUREC_MEM_STR_FLAG) != 0) {\n        SECUREC_UN_GET_CHAR(stream);\n        return;\n    }\n#if SECUREC_ENABLE_SCANF_FILE\n    if ((stream->flag & SECUREC_LOAD_FILE_TO_MEM_FLAG) != 0) {\n        SECUREC_UN_GET_CHAR(stream);\n        if (stream->fileRealRead > 0) {\n            stream->fileRealRead -= sizeof(SecChar);\n        }\n        return;\n    }\n    if ((stream->flag & SECUREC_PIPE_STREAM_FLAG) != 0) {\n        (void)SECUREC_UN_GETC(ch, stream->pf);\n        return;\n    }\n#else\n    (void)ch; /* To clear e438 last value assigned not used , the compiler will optimize this code */\n#endif\n}\n\n/*\n *  Unget char  for char version\n */\nSECUREC_INLINE void SecUnGetChar(SecInt ch, SecFileStream *stream, int *counter)\n{\n    *counter = *counter - 1; /* Always minus 1 */\n    if (ch != SECUREC_EOF) {\n        SecUnGetCharImpl(ch, stream);\n    }\n}\n\n/*\n *  Skip space char by isspace\n */\nSECUREC_INLINE SecInt SecSkipSpaceChar(SecFileStream *stream, int *counter)\n{\n    SecInt ch;\n    do {\n        ch = SecGetChar(stream, counter);\n        if (ch == SECUREC_EOF) {\n            break;\n        }\n    } while (SecIsSpace(ch) != 0);\n    return ch;\n}\n#endif /* INPUT_INL_5D13A042_DC3F_4ED9_A8D1_882811274C27 */\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/memcpy_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: memcpy_s function\n * Create: 2014-02-25\n */\n/*\n * [Standardize-exceptions] Use unsafe function: Portability\n * [reason] Use unsafe function to implement security function to maintain platform compatibility.\n *          And sufficient input validation is performed before calling\n */\n\n#include \"securecutil.h\"\n\n#if SECUREC_WITH_PERFORMANCE_ADDONS\n#ifndef SECUREC_MEMCOPY_THRESHOLD_SIZE\n#define SECUREC_MEMCOPY_THRESHOLD_SIZE 64UL\n#endif\n\n#define SECUREC_SMALL_MEM_COPY(dest, src, count) do { \\\n    if (SECUREC_ADDR_ALIGNED_8(dest) && SECUREC_ADDR_ALIGNED_8(src)) { \\\n        /* Use struct assignment */ \\\n        switch (count) { \\\n            case 1: \\\n                *(unsigned char *)(dest) = *(const unsigned char *)(src); \\\n                break; \\\n            case 2: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 2); \\\n                break; \\\n            case 3: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 3); \\\n                break; \\\n            case 4: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 4); \\\n                break; \\\n            case 5: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 5); \\\n                break; \\\n            case 6: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 6); \\\n                break; \\\n            case 7: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 7); \\\n                break; \\\n            case 8: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 8); \\\n                break; \\\n            case 9: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 9); \\\n                break; \\\n            case 10: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 10); \\\n                break; \\\n            case 11: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 11); \\\n                break; \\\n            case 12: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 12); \\\n                break; \\\n            case 13: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 13); \\\n                break; \\\n            case 14: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 14); \\\n                break; \\\n            case 15: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 15); \\\n                break; \\\n            case 16: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 16); \\\n                break; \\\n            case 17: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 17); \\\n                break; \\\n            case 18: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 18); \\\n                break; \\\n            case 19: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 19); \\\n                break; \\\n            case 20: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 20); \\\n                break; \\\n            case 21: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 21); \\\n                break; \\\n            case 22: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 22); \\\n                break; \\\n            case 23: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 23); \\\n                break; \\\n            case 24: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 24); \\\n                break; \\\n            case 25: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 25); \\\n                break; \\\n            case 26: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 26); \\\n                break; \\\n            case 27: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 27); \\\n                break; \\\n            case 28: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 28); \\\n                break; \\\n            case 29: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 29); \\\n                break; \\\n            case 30: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 30); \\\n                break; \\\n            case 31: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 31); \\\n                break; \\\n            case 32: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 32); \\\n                break; \\\n            case 33: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 33); \\\n                break; \\\n            case 34: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 34); \\\n                break; \\\n            case 35: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 35); \\\n                break; \\\n            case 36: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 36); \\\n                break; \\\n            case 37: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 37); \\\n                break; \\\n            case 38: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 38); \\\n                break; \\\n            case 39: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 39); \\\n                break; \\\n            case 40: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 40); \\\n                break; \\\n            case 41: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 41); \\\n                break; \\\n            case 42: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 42); \\\n                break; \\\n            case 43: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 43); \\\n                break; \\\n            case 44: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 44); \\\n                break; \\\n            case 45: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 45); \\\n                break; \\\n            case 46: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 46); \\\n                break; \\\n            case 47: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 47); \\\n                break; \\\n            case 48: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 48); \\\n                break; \\\n            case 49: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 49); \\\n                break; \\\n            case 50: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 50); \\\n                break; \\\n            case 51: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 51); \\\n                break; \\\n            case 52: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 52); \\\n                break; \\\n            case 53: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 53); \\\n                break; \\\n            case 54: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 54); \\\n                break; \\\n            case 55: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 55); \\\n                break; \\\n            case 56: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 56); \\\n                break; \\\n            case 57: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 57); \\\n                break; \\\n            case 58: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 58); \\\n                break; \\\n            case 59: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 59); \\\n                break; \\\n            case 60: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 60); \\\n                break; \\\n            case 61: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 61); \\\n                break; \\\n            case 62: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 62); \\\n                break; \\\n            case 63: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 63); \\\n                break; \\\n            case 64: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((dest), (src), 64); \\\n                break; \\\n            default: \\\n                /* Do nothing */ \\\n                break; \\\n        } /* END switch */ \\\n    } else { \\\n        unsigned char *tmpDest_ = (unsigned char *)(dest); \\\n        const unsigned char *tmpSrc_ = (const unsigned char *)(src); \\\n        switch (count) { \\\n            case 64: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 63: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 62: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 61: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 60: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 59: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 58: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 57: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 56: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 55: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 54: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 53: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 52: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 51: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 50: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 49: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 48: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 47: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 46: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 45: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 44: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 43: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 42: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 41: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 40: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 39: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 38: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 37: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 36: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 35: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 34: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 33: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 32: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 31: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 30: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 29: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 28: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 27: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 26: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 25: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 24: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 23: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 22: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 21: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 20: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 19: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 18: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 17: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 16: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 15: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 14: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 13: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 12: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 11: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 10: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 9: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 8: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 7: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 6: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 5: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 4: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 3: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 2: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 1: \\\n                *(tmpDest_++) = *(tmpSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            default: \\\n                /* Do nothing */ \\\n                break; \\\n        } \\\n    } \\\n} SECUREC_WHILE_ZERO\n\n/*\n * Performance optimization\n */\n#define SECUREC_MEMCPY_OPT(dest, src, count) do { \\\n    if ((count) > SECUREC_MEMCOPY_THRESHOLD_SIZE) { \\\n        SECUREC_MEMCPY_WARP_OPT((dest), (src), (count)); \\\n    } else { \\\n        SECUREC_SMALL_MEM_COPY((dest), (src), (count)); \\\n    } \\\n} SECUREC_WHILE_ZERO\n#endif\n\n/*\n * Handling errors\n */\nSECUREC_INLINE errno_t SecMemcpyError(void *dest, size_t destMax, const void *src, size_t count)\n{\n    if (destMax == 0 || destMax > SECUREC_MEM_MAX_LEN) {\n        SECUREC_ERROR_INVALID_RANGE(\"memcpy_s\");\n        return ERANGE;\n    }\n    if (dest == NULL || src == NULL) {\n        SECUREC_ERROR_INVALID_PARAMTER(\"memcpy_s\");\n        if (dest != NULL) {\n            (void)SECUREC_MEMSET_FUNC_OPT(dest, 0, destMax);\n            return EINVAL_AND_RESET;\n        }\n        return EINVAL;\n    }\n    if (count > destMax) {\n        (void)SECUREC_MEMSET_FUNC_OPT(dest, 0, destMax);\n        SECUREC_ERROR_INVALID_RANGE(\"memcpy_s\");\n        return ERANGE_AND_RESET;\n    }\n    if (SECUREC_MEMORY_IS_OVERLAP(dest, src, count)) {\n        (void)SECUREC_MEMSET_FUNC_OPT(dest, 0, destMax);\n        SECUREC_ERROR_BUFFER_OVERLAP(\"memcpy_s\");\n        return EOVERLAP_AND_RESET;\n    }\n    /* Count is 0 or dest equal src also ret EOK */\n    return EOK;\n}\n\n#if defined(SECUREC_COMPATIBLE_WIN_FORMAT)\n    /*\n     * The fread API in windows will call memcpy_s and pass 0xffffffff to destMax.\n     * To avoid the failure of fread, we don't check desMax limit.\n     */\n#define SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count) (SECUREC_LIKELY((count) <= (destMax) && \\\n    (dest) != NULL && (src) != NULL && \\\n    (count) > 0 && SECUREC_MEMORY_NO_OVERLAP((dest), (src), (count))))\n#else\n#define SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count) (SECUREC_LIKELY((count) <= (destMax) && \\\n    (dest) != NULL && (src) != NULL && (destMax) <= SECUREC_MEM_MAX_LEN && \\\n    (count) > 0 && SECUREC_MEMORY_NO_OVERLAP((dest), (src), (count))))\n#endif\n\n/*\n * <FUNCTION DESCRIPTION>\n *    The memcpy_s function copies n characters from the object pointed to by src into the object pointed to by dest\n *\n * <INPUT PARAMETERS>\n *    dest                      Destination buffer.\n *    destMax                   Size of the destination buffer.\n *    src                       Buffer to copy from.\n *    count                     Number of characters to copy\n *\n * <OUTPUT PARAMETERS>\n *    dest buffer               is updated.\n *\n * <RETURN VALUE>\n *    EOK                      Success\n *    EINVAL                   dest is  NULL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN\n *    EINVAL_AND_RESET         dest != NULL and src is NULL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN\n *    ERANGE                   destMax > SECUREC_MEM_MAX_LEN or destMax is 0\n *    ERANGE_AND_RESET         count > destMax and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN\n *                             and dest  !=  NULL  and src != NULL\n *    EOVERLAP_AND_RESET       dest buffer and source buffer are overlapped and\n *                             count <= destMax destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN and dest  !=  NULL\n *                             and src != NULL  and dest != src\n *\n *    if an error occurred, dest will be filled with 0.\n *    If the source and destination overlap, the behavior of memcpy_s is undefined.\n *    Use memmove_s to handle overlapping regions.\n */\nerrno_t memcpy_s(void *dest, size_t destMax, const void *src, size_t count)\n{\n    if (SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count)) {\n        SECUREC_MEMCPY_WARP_OPT(dest, src, count);\n        return EOK;\n    }\n    /* Meet some runtime violation, return error code */\n    return SecMemcpyError(dest, destMax, src, count);\n}\n\n#if SECUREC_EXPORT_KERNEL_SYMBOL\nEXPORT_SYMBOL(memcpy_s);\n#endif\n\n#if SECUREC_WITH_PERFORMANCE_ADDONS\n/*\n * Performance optimization\n */\nerrno_t memcpy_sOptAsm(void *dest, size_t destMax, const void *src, size_t count)\n{\n    if (SECUREC_MEMCPY_PARAM_OK(dest, destMax, src, count)) {\n        SECUREC_MEMCPY_OPT(dest, src, count);\n        return EOK;\n    }\n    /* Meet some runtime violation, return error code */\n    return SecMemcpyError(dest, destMax, src, count);\n}\n\n/* Trim judgement on \"destMax <= SECUREC_MEM_MAX_LEN\" */\nerrno_t memcpy_sOptTc(void *dest, size_t destMax, const void *src, size_t count)\n{\n    if (SECUREC_LIKELY(count <= destMax && dest != NULL && src != NULL && \\\n                       count > 0 && SECUREC_MEMORY_NO_OVERLAP((dest), (src), (count)))) {\n        SECUREC_MEMCPY_OPT(dest, src, count);\n        return EOK;\n    }\n    /* Meet some runtime violation, return error code */\n    return SecMemcpyError(dest, destMax, src, count);\n}\n#endif\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/memmove_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: memmove_s function\n * Create: 2014-02-25\n */\n/*\n * [Standardize-exceptions] Use unsafe function: Portability\n * [reason] Use unsafe function to implement security function to maintain platform compatibility.\n *          And sufficient input validation is performed before calling\n */\n\n#include \"securecutil.h\"\n\n#ifdef SECUREC_NOT_CALL_LIBC_CORE_API\n/*\n * Implementing memory data movement\n */\nSECUREC_INLINE void SecUtilMemmove(void *dst, const void *src, size_t count)\n{\n    unsigned char *pDest = (unsigned char *)dst;\n    const unsigned char *pSrc = (const unsigned char *)src;\n    size_t maxCount = count;\n\n    if (dst <= src || pDest >= (pSrc + maxCount)) {\n        /*\n         * Non-Overlapping Buffers\n         * Copy from lower addresses to higher addresses\n         */\n        while (maxCount > 0) {\n            --maxCount;\n            *pDest = *pSrc;\n            ++pDest;\n            ++pSrc;\n        }\n    } else {\n        /*\n         * Overlapping Buffers\n         * Copy from higher addresses to lower addresses\n         */\n        pDest = pDest + maxCount - 1;\n        pSrc = pSrc + maxCount - 1;\n        while (maxCount > 0) {\n            --maxCount;\n            *pDest = *pSrc;\n            --pDest;\n            --pSrc;\n        }\n    }\n}\n#endif\n\n/*\n * <FUNCTION DESCRIPTION>\n *    The memmove_s function copies count bytes of characters from src to dest.\n *    This function can be assigned correctly when memory overlaps.\n * <INPUT PARAMETERS>\n *    dest                    Destination object.\n *    destMax                 Size of the destination buffer.\n *    src                     Source object.\n *    count                   Number of characters to copy.\n *\n * <OUTPUT PARAMETERS>\n *    dest buffer             is updated.\n *\n * <RETURN VALUE>\n *    EOK                     Success\n *    EINVAL                  dest is  NULL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN\n *    EINVAL_AND_RESET        dest != NULL and src is NULL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN\n *    ERANGE                  destMax > SECUREC_MEM_MAX_LEN or destMax is 0\n *    ERANGE_AND_RESET        count > destMax and dest  !=  NULL and src != NULL and destMax != 0\n *                            and destMax <= SECUREC_MEM_MAX_LEN\n *\n *    If an error occurred, dest will  be filled with 0 when dest and destMax valid.\n *    If some regions of the source area and the destination overlap, memmove_s\n *    ensures that the original source bytes in the overlapping region are copied\n *    before being overwritten.\n */\nerrno_t memmove_s(void *dest, size_t destMax, const void *src, size_t count)\n{\n    if (destMax == 0 || destMax > SECUREC_MEM_MAX_LEN) {\n        SECUREC_ERROR_INVALID_RANGE(\"memmove_s\");\n        return ERANGE;\n    }\n    if (dest == NULL || src == NULL) {\n        SECUREC_ERROR_INVALID_PARAMTER(\"memmove_s\");\n        if (dest != NULL) {\n            (void)SECUREC_MEMSET_FUNC_OPT(dest, 0, destMax);\n            return EINVAL_AND_RESET;\n        }\n        return EINVAL;\n    }\n    if (count > destMax) {\n        (void)SECUREC_MEMSET_FUNC_OPT(dest, 0, destMax);\n        SECUREC_ERROR_INVALID_RANGE(\"memmove_s\");\n        return ERANGE_AND_RESET;\n    }\n    if (dest == src) {\n        return EOK;\n    }\n\n    if (count > 0) {\n#ifdef SECUREC_NOT_CALL_LIBC_CORE_API\n        SecUtilMemmove(dest, src, count);\n#else\n        /* Use underlying memmove for performance consideration */\n        (void)memmove(dest, src, count);\n#endif\n    }\n    return EOK;\n}\n\n#if SECUREC_EXPORT_KERNEL_SYMBOL\nEXPORT_SYMBOL(memmove_s);\n#endif\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/memset_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: memset_s function\n * Create: 2014-02-25\n */\n/*\n * [Standardize-exceptions] Use unsafe function: Portability\n * [reason] Use unsafe function to implement security function to maintain platform compatibility.\n *          And sufficient input validation is performed before calling\n */\n\n#include \"securecutil.h\"\n\n#define SECUREC_MEMSET_PARAM_OK(dest, destMax, count) (SECUREC_LIKELY((destMax) <= SECUREC_MEM_MAX_LEN && \\\n    (dest) != NULL && (count) <= (destMax)))\n\n#if SECUREC_WITH_PERFORMANCE_ADDONS\n\n/* Use union to clear strict-aliasing warning */\ntypedef union {\n    SecStrBuf32 buf32;\n    SecStrBuf31 buf31;\n    SecStrBuf30 buf30;\n    SecStrBuf29 buf29;\n    SecStrBuf28 buf28;\n    SecStrBuf27 buf27;\n    SecStrBuf26 buf26;\n    SecStrBuf25 buf25;\n    SecStrBuf24 buf24;\n    SecStrBuf23 buf23;\n    SecStrBuf22 buf22;\n    SecStrBuf21 buf21;\n    SecStrBuf20 buf20;\n    SecStrBuf19 buf19;\n    SecStrBuf18 buf18;\n    SecStrBuf17 buf17;\n    SecStrBuf16 buf16;\n    SecStrBuf15 buf15;\n    SecStrBuf14 buf14;\n    SecStrBuf13 buf13;\n    SecStrBuf12 buf12;\n    SecStrBuf11 buf11;\n    SecStrBuf10 buf10;\n    SecStrBuf9 buf9;\n    SecStrBuf8 buf8;\n    SecStrBuf7 buf7;\n    SecStrBuf6 buf6;\n    SecStrBuf5 buf5;\n    SecStrBuf4 buf4;\n    SecStrBuf3 buf3;\n    SecStrBuf2 buf2;\n} SecStrBuf32Union;\n/* C standard initializes the first member of the consortium. */\nstatic const SecStrBuf32 g_allZero = {{\n    0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U,\n    0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U,\n    0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U,\n    0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U\n}};\nstatic const SecStrBuf32 g_allFF = {{\n    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\n    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\n    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\n    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF\n}};\n\n/* Clear conversion warning strict aliasing\" */\nSECUREC_INLINE const SecStrBuf32Union *SecStrictAliasingCast(const SecStrBuf32 *buf)\n{\n    return (const SecStrBuf32Union *)buf;\n}\n\n#ifndef SECUREC_MEMSET_THRESHOLD_SIZE\n#define SECUREC_MEMSET_THRESHOLD_SIZE 32UL\n#endif\n\n#define SECUREC_UNALIGNED_SET(dest, c, count) do { \\\n    unsigned char *pDest_ = (unsigned char *)(dest); \\\n    switch (count) { \\\n        case 32: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 31: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 30: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 29: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 28: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 27: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 26: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 25: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 24: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 23: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 22: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 21: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 20: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 19: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 18: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 17: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 16: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 15: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 14: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 13: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 12: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 11: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 10: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 9: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 8: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 7: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 6: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 5: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 4: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 3: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 2: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        case 1: \\\n            *(pDest_++) = (unsigned char)(c); \\\n            /* fall-through */ /* FALLTHRU */ \\\n        default: \\\n            /* Do nothing */ \\\n            break; \\\n    } \\\n} SECUREC_WHILE_ZERO\n\n#define SECUREC_SET_VALUE_BY_STRUCT(dest, dataName, n) do { \\\n    *(SecStrBuf##n *)(dest) = *(const SecStrBuf##n *)(&((SecStrictAliasingCast(&(dataName)))->buf##n)); \\\n} SECUREC_WHILE_ZERO\n\n#define SECUREC_ALIGNED_SET_OPT_ZERO_FF(dest, c, count) do { \\\n    switch (c) { \\\n        case 0: \\\n            switch (count) { \\\n                case 1: \\\n                    *(unsigned char *)(dest) = (unsigned char)0; \\\n                    break; \\\n                case 2: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 2); \\\n                    break; \\\n                case 3: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 3); \\\n                    break; \\\n                case 4: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 4); \\\n                    break; \\\n                case 5: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 5); \\\n                    break; \\\n                case 6: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 6); \\\n                    break; \\\n                case 7: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 7); \\\n                    break; \\\n                case 8: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 8); \\\n                    break; \\\n                case 9: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 9); \\\n                    break; \\\n                case 10: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 10); \\\n                    break; \\\n                case 11: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 11); \\\n                    break; \\\n                case 12: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 12); \\\n                    break; \\\n                case 13: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 13); \\\n                    break; \\\n                case 14: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 14); \\\n                    break; \\\n                case 15: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 15); \\\n                    break; \\\n                case 16: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 16); \\\n                    break; \\\n                case 17: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 17); \\\n                    break; \\\n                case 18: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 18); \\\n                    break; \\\n                case 19: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 19); \\\n                    break; \\\n                case 20: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 20); \\\n                    break; \\\n                case 21: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 21); \\\n                    break; \\\n                case 22: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 22); \\\n                    break; \\\n                case 23: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 23); \\\n                    break; \\\n                case 24: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 24); \\\n                    break; \\\n                case 25: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 25); \\\n                    break; \\\n                case 26: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 26); \\\n                    break; \\\n                case 27: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 27); \\\n                    break; \\\n                case 28: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 28); \\\n                    break; \\\n                case 29: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 29); \\\n                    break; \\\n                case 30: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 30); \\\n                    break; \\\n                case 31: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 31); \\\n                    break; \\\n                case 32: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allZero, 32); \\\n                    break; \\\n                default: \\\n                    /* Do nothing */ \\\n                    break; \\\n            } \\\n            break; \\\n        case 0xFF: \\\n            switch (count) { \\\n                case 1: \\\n                    *(unsigned char *)(dest) = (unsigned char)0xffU; \\\n                    break; \\\n                case 2: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 2); \\\n                    break; \\\n                case 3: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 3); \\\n                    break; \\\n                case 4: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 4); \\\n                    break; \\\n                case 5: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 5); \\\n                    break; \\\n                case 6: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 6); \\\n                    break; \\\n                case 7: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 7); \\\n                    break; \\\n                case 8: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 8); \\\n                    break; \\\n                case 9: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 9); \\\n                    break; \\\n                case 10: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 10); \\\n                    break; \\\n                case 11: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 11); \\\n                    break; \\\n                case 12: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 12); \\\n                    break; \\\n                case 13: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 13); \\\n                    break; \\\n                case 14: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 14); \\\n                    break; \\\n                case 15: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 15); \\\n                    break; \\\n                case 16: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 16); \\\n                    break; \\\n                case 17: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 17); \\\n                    break; \\\n                case 18: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 18); \\\n                    break; \\\n                case 19: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 19); \\\n                    break; \\\n                case 20: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 20); \\\n                    break; \\\n                case 21: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 21); \\\n                    break; \\\n                case 22: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 22); \\\n                    break; \\\n                case 23: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 23); \\\n                    break; \\\n                case 24: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 24); \\\n                    break; \\\n                case 25: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 25); \\\n                    break; \\\n                case 26: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 26); \\\n                    break; \\\n                case 27: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 27); \\\n                    break; \\\n                case 28: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 28); \\\n                    break; \\\n                case 29: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 29); \\\n                    break; \\\n                case 30: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 30); \\\n                    break; \\\n                case 31: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 31); \\\n                    break; \\\n                case 32: \\\n                    SECUREC_SET_VALUE_BY_STRUCT((dest), g_allFF, 32); \\\n                    break; \\\n                default: \\\n                    /* Do nothing */ \\\n                    break; \\\n            } \\\n            break; \\\n        default: \\\n            SECUREC_UNALIGNED_SET((dest), (c), (count)); \\\n            break; \\\n    } /* END switch */ \\\n} SECUREC_WHILE_ZERO\n\n#define SECUREC_SMALL_MEM_SET(dest, c, count) do { \\\n    if (SECUREC_ADDR_ALIGNED_8((dest))) { \\\n        SECUREC_ALIGNED_SET_OPT_ZERO_FF((dest), (c), (count)); \\\n    } else { \\\n        SECUREC_UNALIGNED_SET((dest), (c), (count)); \\\n    } \\\n} SECUREC_WHILE_ZERO\n\n/*\n * Performance optimization\n */\n#define SECUREC_MEMSET_OPT(dest, c, count) do { \\\n    if ((count) > SECUREC_MEMSET_THRESHOLD_SIZE) { \\\n        SECUREC_MEMSET_PREVENT_DSE((dest), (c), (count)); \\\n    } else { \\\n        SECUREC_SMALL_MEM_SET((dest), (c), (count)); \\\n    } \\\n} SECUREC_WHILE_ZERO\n#endif\n\n/*\n * Handling errors\n */\nSECUREC_INLINE errno_t SecMemsetError(void *dest, size_t destMax, int c)\n{\n    /* Check destMax is 0 compatible with _sp macro */\n    if (destMax == 0 || destMax > SECUREC_MEM_MAX_LEN) {\n        SECUREC_ERROR_INVALID_RANGE(\"memset_s\");\n        return ERANGE;\n    }\n    if (dest == NULL) {\n        SECUREC_ERROR_INVALID_PARAMTER(\"memset_s\");\n        return EINVAL;\n    }\n    SECUREC_MEMSET_PREVENT_DSE(dest, c, destMax); /* Set entire buffer to value c */\n    SECUREC_ERROR_INVALID_RANGE(\"memset_s\");\n    return ERANGE_AND_RESET;\n}\n\n/*\n * <FUNCTION DESCRIPTION>\n *    The memset_s function copies the value of c (converted to an unsigned char)\n *     into each of the first count characters of the object pointed to by dest.\n *\n * <INPUT PARAMETERS>\n *    dest                Pointer to destination.\n *    destMax             The size of the buffer.\n *    c                   Character to set.\n *    count               Number of characters.\n *\n * <OUTPUT PARAMETERS>\n *    dest buffer         is updated.\n *\n * <RETURN VALUE>\n *    EOK                 Success\n *    EINVAL              dest == NULL and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN\n *    ERANGE              destMax > SECUREC_MEM_MAX_LEN or (destMax is 0 and count > destMax)\n *    ERANGE_AND_RESET    count > destMax and destMax != 0 and destMax <= SECUREC_MEM_MAX_LEN and dest != NULL\n *\n *    if return ERANGE_AND_RESET then fill dest to c ,fill length is destMax\n */\nerrno_t memset_s(void *dest, size_t destMax, int c, size_t count)\n{\n    if (SECUREC_MEMSET_PARAM_OK(dest, destMax, count)) {\n        SECUREC_MEMSET_PREVENT_DSE(dest, c, count);\n        return EOK;\n    }\n    /* Meet some runtime violation, return error code */\n    return SecMemsetError(dest, destMax, c);\n}\n\n#if SECUREC_EXPORT_KERNEL_SYMBOL\nEXPORT_SYMBOL(memset_s);\n#endif\n\n#if SECUREC_WITH_PERFORMANCE_ADDONS\n/*\n * Performance optimization\n */\nerrno_t memset_sOptAsm(void *dest, size_t destMax, int c, size_t count)\n{\n    if (SECUREC_MEMSET_PARAM_OK(dest, destMax, count)) {\n        SECUREC_MEMSET_OPT(dest, c, count);\n        return EOK;\n    }\n    /* Meet some runtime violation, return error code */\n    return SecMemsetError(dest, destMax, c);\n}\n\n/*\n * Performance optimization, trim judgement on \"destMax <= SECUREC_MEM_MAX_LEN\"\n */\nerrno_t memset_sOptTc(void *dest, size_t destMax, int c, size_t count)\n{\n    if (SECUREC_LIKELY(count <= destMax && dest != NULL)) {\n        SECUREC_MEMSET_OPT(dest, c, count);\n        return EOK;\n    }\n    /* Meet some runtime violation, return error code */\n    return SecMemsetError(dest, destMax, c);\n}\n#endif\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/output.inl",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: Used by secureprintoutput_a.c and secureprintoutput_w.c to include.\n *              This file provides a template function for ANSI and UNICODE compiling\n *              by different type definition. The functions of SecOutputS or\n *              SecOutputSW  provides internal implementation for printf family API, such as sprintf, swprintf_s.\n * Create: 2014-02-25\n * Notes: see www.cplusplus.com/reference/cstdio/printf/\n */\n/*\n * [Standardize-exceptions] Use unsafe function: Portability\n * [reason] Use unsafe function to implement security function to maintain platform compatibility.\n *          And sufficient input validation is performed before calling\n */\n#ifndef OUTPUT_INL_2B263E9C_43D8_44BB_B17A_6D2033DECEE5\n#define OUTPUT_INL_2B263E9C_43D8_44BB_B17A_6D2033DECEE5\n\n#ifndef SECUREC_ENABLE_SPRINTF_LONG_DOUBLE\n/* Some compilers do not support long double */\n#define SECUREC_ENABLE_SPRINTF_LONG_DOUBLE 1\n#endif\n\n#define SECUREC_NULL_STRING_SIZE            8\n#define SECUREC_STATE_TABLE_SIZE            337\n\n#if defined(SECUREC_VXWORKS_VERSION_5_4) && !defined(SECUREC_ON_64BITS)\n#define SECUREC_DIV_QUOTIENT_OCTAL(val64)     ((val64) >> 3ULL)\n#define SECUREC_DIV_RESIDUE_OCTAL(val64)      ((val64) & 7ULL)\n\n#define SECUREC_DIV_QUOTIENT_HEX(val64)       ((val64) >> 4ULL)\n#define SECUREC_DIV_RESIDUE_HEX(val64)        ((val64) & 0xfULL)\n#endif\n\n#define SECUREC_RADIX_OCTAL                 8U\n#define SECUREC_RADIX_DECIMAL               10U\n#define SECUREC_RADIX_HEX                   16U\n#define SECUREC_PREFIX_LEN                  2\n/* Size include '+' and '\\0' */\n#define SECUREC_FLOAT_BUF_EXT               2\n\n/* Sign extend or Zero-extend */\n#define SECUREC_GET_LONG_FROM_ARG(attr) ((((attr).flags & SECUREC_FLAG_SIGNED) != 0) ? \\\n    (SecInt64)(long)va_arg(argList, long) : \\\n    (SecInt64)(unsigned long)va_arg(argList, long))\n\n/* Sign extend or Zero-extend */\n#define SECUREC_GET_CHAR_FROM_ARG(attr) ((((attr).flags & SECUREC_FLAG_SIGNED) != 0) ? \\\n    SecUpdateNegativeChar(&(attr), ((char)va_arg(argList, int))) : \\\n    (SecInt64)(unsigned char)va_arg(argList, int))\n\n/* Sign extend or Zero-extend */\n#define SECUREC_GET_SHORT_FROM_ARG(attr) ((((attr).flags & SECUREC_FLAG_SIGNED) != 0) ? \\\n    (SecInt64)(short)va_arg(argList, int) : \\\n    (SecInt64)(unsigned short)va_arg(argList, int))\n\n/* Sign extend or Zero-extend */\n#define SECUREC_GET_INT_FROM_ARG(attr) ((((attr).flags & SECUREC_FLAG_SIGNED) != 0) ? \\\n    (SecInt64)(int)va_arg(argList, int) : \\\n    (SecInt64)(unsigned int)va_arg(argList, int))\n\n#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT\n/* Sign extend or Zero-extend. No suitable macros were found to handle the branch */\n#define SECUREC_GET_SIZE_FROM_ARG(attr) ((((attr).flags & SECUREC_FLAG_SIGNED) != 0) ? \\\n    ((SecIsSameSize(sizeof(size_t), sizeof(long)) != 0) ? (SecInt64)(long)va_arg(argList, long) : \\\n    ((SecIsSameSize(sizeof(size_t), sizeof(long long)) != 0) ? (SecInt64)(long long)va_arg(argList, long long) : \\\n    (SecInt64)(int)va_arg(argList, int))) : \\\n    (SecInt64)(size_t)va_arg(argList, size_t))\n#endif\n\n/* Format output buffer pointer and available size */\ntypedef struct {\n    int count;\n    SecChar *cur;\n} SecPrintfStream;\n\ntypedef union {\n    /* Integer formatting refers to the end of the buffer, plus 1 to prevent tool alarms */\n    char str[SECUREC_BUFFER_SIZE + 1];\n#if SECUREC_HAVE_WCHART\n    wchar_t wStr[SECUREC_WCHAR_BUFFER_SIZE]; /* Just for %lc */\n#endif\n} SecBuffer;\n\ntypedef union {\n    char *str;                  /* Not a null terminated  string */\n#if SECUREC_HAVE_WCHART\n    wchar_t *wStr;\n#endif\n} SecFormatBuf;\n\ntypedef struct {\n    const char *digits;                 /* Point to the hexadecimal subset */\n    SecFormatBuf text;                  /* Point to formatted string */\n    int textLen;                        /* Length of the text */\n    int textIsWide;                     /* Flag for text is wide chars ; 0 is not wide char */\n    unsigned int radix;                 /* Use for output number , default set to 10 */\n    unsigned int flags;\n    int fldWidth;\n    int precision;\n    int dynWidth;                       /* %*   1 width from variable parameter ;0 not */\n    int dynPrecision;                   /* %.*  1 precision from variable parameter ;0 not */\n    int padding;                        /* Padding len */\n    int prefixLen;                      /* Length of prefix, 0 or 1 or 2 */\n    SecChar prefix[SECUREC_PREFIX_LEN]; /* Prefix is  0 or 0x */\n    SecBuffer buffer;\n} SecFormatAttr;\n\n#if SECUREC_ENABLE_SPRINTF_FLOAT\n#ifdef SECUREC_STACK_SIZE_LESS_THAN_1K\n#define SECUREC_FMT_STR_LEN                 8\n#else\n#define SECUREC_FMT_STR_LEN                 16\n#endif\ntypedef struct {\n    char buffer[SECUREC_FMT_STR_LEN];\n    char *fmtStr;                     /* Initialization must point to buffer */\n    char *allocatedFmtStr;            /* Initialization must be NULL  to store allocated point */\n    char *floatBuffer;                /* Use heap memory if the SecFormatAttr.buffer is not enough */\n    int bufferSize;                   /* The size of floatBuffer */\n} SecFloatAdapt;\n#endif\n\n/* Use 20 to Align the data */\n#define SECUREC_DIGITS_BUF_SIZE  20\n/* The serial number of 'x' or 'X' is 16 */\n#define SECUREC_NUMBER_OF_X  16\n/* Some systems can not use pointers to point to string literals, but can use string arrays. */\n/* For example, when handling code under uboot, there is a problem with the pointer */\nstatic const char g_itoaUpperDigits[SECUREC_DIGITS_BUF_SIZE] = \"0123456789ABCDEFX\";\nstatic const char g_itoaLowerDigits[SECUREC_DIGITS_BUF_SIZE] = \"0123456789abcdefx\";\n\n#if SECUREC_ENABLE_SPRINTF_FLOAT\n/* Call system sprintf to format float value */\nSECUREC_INLINE int SecFormatFloat(char *strDest, const char *format, ...)\n{\n    int ret;                    /* If initialization causes  e838 */\n    va_list argList;\n\n    va_start(argList, format);\n    SECUREC_MASK_VSPRINTF_WARNING\n    ret = vsprintf(strDest, format, argList);\n    SECUREC_END_MASK_VSPRINTF_WARNING\n    va_end(argList);\n    (void)argList; /* To clear e438 last value assigned not used , the compiler will optimize this code */\n\n    return ret;\n}\n\n#if defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && SECUREC_ENABLE_SPRINTF_LONG_DOUBLE\n/* Out put long double value to dest */\nSECUREC_INLINE void SecFormatLongDouble(SecFormatAttr *attr, const SecFloatAdapt *floatAdapt, long double ldValue)\n{\n    int fldWidth = (((attr->flags & SECUREC_FLAG_LEFT) != 0) ? (-attr->fldWidth) : attr->fldWidth);\n    if (attr->dynWidth != 0 && attr->dynPrecision != 0) {\n        attr->textLen = SecFormatFloat(attr->text.str, floatAdapt->fmtStr, fldWidth, attr->precision, ldValue);\n    } else if (attr->dynWidth != 0) {\n        attr->textLen = SecFormatFloat(attr->text.str, floatAdapt->fmtStr, fldWidth, ldValue);\n    } else if (attr->dynPrecision != 0) {\n        attr->textLen = SecFormatFloat(attr->text.str, floatAdapt->fmtStr, attr->precision, ldValue);\n    } else {\n        attr->textLen = SecFormatFloat(attr->text.str, floatAdapt->fmtStr, ldValue);\n    }\n    if (attr->textLen < 0 || attr->textLen >= floatAdapt->bufferSize) {\n        attr->textLen = 0;\n    }\n}\n#endif\n\n/* Out put double value to dest */\nSECUREC_INLINE void SecFormatDouble(SecFormatAttr *attr, const SecFloatAdapt *floatAdapt, double dValue)\n{\n    int fldWidth = (((attr->flags & SECUREC_FLAG_LEFT) != 0) ? (-attr->fldWidth) : attr->fldWidth);\n    if (attr->dynWidth != 0 && attr->dynPrecision != 0) {\n        attr->textLen = SecFormatFloat(attr->text.str, floatAdapt->fmtStr, fldWidth, attr->precision, dValue);\n    } else if (attr->dynWidth != 0) {\n        attr->textLen = SecFormatFloat(attr->text.str, floatAdapt->fmtStr, fldWidth, dValue);\n    } else if (attr->dynPrecision != 0) {\n        attr->textLen = SecFormatFloat(attr->text.str, floatAdapt->fmtStr, attr->precision, dValue);\n    } else {\n        attr->textLen = SecFormatFloat(attr->text.str, floatAdapt->fmtStr, dValue);\n    }\n    if (attr->textLen < 0 || attr->textLen >= floatAdapt->bufferSize) {\n        attr->textLen = 0;\n    }\n}\n#endif\n\n#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT\n/* To clear e506 warning */\nSECUREC_INLINE int SecIsSameSize(size_t sizeA, size_t sizeB)\n{\n    return (int)(sizeA == sizeB);\n}\n#endif\n\n#ifndef SECUREC_ON_64BITS\n/*\n * Compiler Optimized Division 8.\n * The text.str point to buffer end, must be Large enough\n */\nSECUREC_INLINE void SecNumber32ToOctalString(SecUnsignedInt32 number, SecFormatAttr *attr)\n{\n    SecUnsignedInt32 val32 = number;\n    do {\n        --attr->text.str;\n        /* Just use lowerDigits for 0 - 9 */\n        *(attr->text.str) = g_itoaLowerDigits[val32 % SECUREC_RADIX_OCTAL];\n        val32 /= SECUREC_RADIX_OCTAL;\n    } while (val32 != 0);\n}\n\n#ifdef _AIX\n/*\n * Compiler Optimized Division 10.\n * The text.str point to buffer end, must be Large enough\n */\nSECUREC_INLINE void SecNumber32ToDecString(SecUnsignedInt32 number, SecFormatAttr *attr)\n{\n    SecUnsignedInt32 val32 = number;\n    do {\n        --attr->text.str;\n        /* Just use lowerDigits for 0 - 9 */\n        *(attr->text.str) = g_itoaLowerDigits[val32 % SECUREC_RADIX_DECIMAL];\n        val32 /= SECUREC_RADIX_DECIMAL;\n    } while (val32 != 0);\n}\n#endif\n/*\n * Compiler Optimized Division 16.\n * The text.str point to buffer end, must be Large enough\n */\nSECUREC_INLINE void SecNumber32ToHexString(SecUnsignedInt32 number, SecFormatAttr *attr)\n{\n    SecUnsignedInt32 val32 = number;\n    do {\n        --attr->text.str;\n        *(attr->text.str) = attr->digits[val32 % SECUREC_RADIX_HEX];\n        val32 /= SECUREC_RADIX_HEX;\n    } while (val32 != 0);\n}\n\n#ifndef _AIX\n/* Use fast div 10 */\nSECUREC_INLINE void SecNumber32ToDecStringFast(SecUnsignedInt32 number, SecFormatAttr *attr)\n{\n    SecUnsignedInt32 val32 = number;\n    do {\n        SecUnsignedInt32 quotient;\n        SecUnsignedInt32 remain;\n        --attr->text.str;\n        *(attr->text.str) = g_itoaLowerDigits[val32 % SECUREC_RADIX_DECIMAL];\n        quotient = (val32 >> 1U) + (val32 >> 2U); /* Fast div  magic 2 */\n        quotient = quotient + (quotient >> 4U); /* Fast div  magic 4 */\n        quotient = quotient + (quotient >> 8U); /* Fast div  magic 8 */\n        quotient = quotient + (quotient >> 16U); /* Fast div  magic 16 */\n        quotient = quotient >> 3U; /* Fast div  magic 3 */\n        remain = val32 - SECUREC_MUL_TEN(quotient);\n        val32 = (remain > 9U) ? (quotient + 1U) : quotient; /* Fast div  magic 9 */\n    } while (val32 != 0);\n}\n#endif\n\nSECUREC_INLINE void SecNumber32ToString(SecUnsignedInt32 number, SecFormatAttr *attr)\n{\n    switch (attr->radix) {\n        case SECUREC_RADIX_HEX:\n            SecNumber32ToHexString(number, attr);\n            break;\n        case SECUREC_RADIX_OCTAL:\n            SecNumber32ToOctalString(number, attr);\n            break;\n        case SECUREC_RADIX_DECIMAL:\n#ifdef _AIX\n            /* The compiler will optimize div 10 */\n            SecNumber32ToDecString(number, attr);\n#else\n            SecNumber32ToDecStringFast(number, attr);\n#endif\n            break;\n        default:\n            /* Do nothing */\n            break;\n    }\n}\n#endif\n\n#if defined(SECUREC_USE_SPECIAL_DIV64) || (defined(SECUREC_VXWORKS_VERSION_5_4) && !defined(SECUREC_ON_64BITS))\n/*\n * This function just to clear warning, on sume vxworks compiler shift 32 bit make warnings\n */\nSECUREC_INLINE SecUnsignedInt64 SecU64Shr32(SecUnsignedInt64 number)\n{\n    return (((number) >> 16U) >> 16U); /* Two shifts of 16 bits to realize shifts of 32 bits */\n}\n/*\n * Fast divide by 10 algorithm.\n * Calculation divisor multiply  0xcccccccccccccccdULL, resultHi64 >> 3 as quotient\n */\nSECUREC_INLINE void SecU64Div10(SecUnsignedInt64 divisor, SecUnsignedInt64 *quotient, SecUnsignedInt32 *residue)\n{\n    SecUnsignedInt64 mask = 0xffffffffULL; /* Use 0xffffffffULL as 32 bit mask */\n    SecUnsignedInt64 magicHi = 0xccccccccULL; /* Fast divide 10 magic numbers high 32bit 0xccccccccULL */\n    SecUnsignedInt64 magicLow = 0xcccccccdULL; /* Fast divide 10 magic numbers low 32bit  0xcccccccdULL */\n    SecUnsignedInt64 divisorHi = (SecUnsignedInt64)(SecU64Shr32(divisor)); /* High 32 bit use  */\n    SecUnsignedInt64 divisorLow = (SecUnsignedInt64)(divisor & mask); /* Low 32 bit mask */\n    SecUnsignedInt64 factorHi = divisorHi * magicHi;\n    SecUnsignedInt64 factorLow1 = divisorHi * magicLow;\n    SecUnsignedInt64 factorLow2 = divisorLow * magicHi;\n    SecUnsignedInt64 factorLow3 = divisorLow * magicLow;\n    SecUnsignedInt64 carry = (factorLow1 & mask) + (factorLow2 & mask) + SecU64Shr32(factorLow3);\n    SecUnsignedInt64 resultHi64 = factorHi + SecU64Shr32(factorLow1) + SecU64Shr32(factorLow2) + SecU64Shr32(carry);\n\n    *quotient = resultHi64 >> 3U; /* Fast divide 10 magic numbers 3 */\n    *residue = (SecUnsignedInt32)(divisor - ((*quotient) * 10)); /* Quotient mul 10 */\n    return;\n}\n#if defined(SECUREC_VXWORKS_VERSION_5_4) && !defined(SECUREC_ON_64BITS)\n/*\n * Divide function for VXWORKS\n */\nSECUREC_INLINE int SecU64Div32(SecUnsignedInt64 divisor, SecUnsignedInt32 radix,\n    SecUnsignedInt64 *quotient, SecUnsignedInt32 *residue)\n{\n    switch (radix) {\n        case SECUREC_RADIX_DECIMAL:\n            SecU64Div10(divisor, quotient, residue);\n            break;\n        case SECUREC_RADIX_HEX:\n            *quotient = SECUREC_DIV_QUOTIENT_HEX(divisor);\n            *residue = (SecUnsignedInt32)SECUREC_DIV_RESIDUE_HEX(divisor);\n            break;\n        case SECUREC_RADIX_OCTAL:\n            *quotient = SECUREC_DIV_QUOTIENT_OCTAL(divisor);\n            *residue = (SecUnsignedInt32)SECUREC_DIV_RESIDUE_OCTAL(divisor);\n            break;\n        default:\n            return -1; /* This does not happen in the current file */\n    }\n    return 0;\n}\nSECUREC_INLINE void SecNumber64ToStringSpecial(SecUnsignedInt64 number, SecFormatAttr *attr)\n{\n    SecUnsignedInt64 val64 = number;\n    do {\n        SecUnsignedInt32 digit = 0; /* Ascii value of digit */\n        SecUnsignedInt64 quotient = 0;\n        if (SecU64Div32(val64, (SecUnsignedInt32)attr->radix, &quotient, &digit) != 0) {\n            /* Just break, when enter this function, no error is returned */\n            break;\n        }\n        --attr->text.str;\n        *(attr->text.str) = attr->digits[digit];\n        val64 = quotient;\n    } while (val64 != 0);\n}\n#endif\n#endif\n\n#if defined(SECUREC_ON_64BITS) || !defined(SECUREC_VXWORKS_VERSION_5_4)\n#if defined(SECUREC_USE_SPECIAL_DIV64)\n/* The compiler does not provide 64 bit division problems */\nSECUREC_INLINE void SecNumber64ToDecString(SecUnsignedInt64 number, SecFormatAttr *attr)\n{\n    SecUnsignedInt64 val64 = number;\n    do {\n        SecUnsignedInt64 quotient = 0;\n        SecUnsignedInt32 digit = 0;\n        SecU64Div10(val64, &quotient, &digit);\n        --attr->text.str;\n        /* Just use lowerDigits for 0 - 9 */\n        *(attr->text.str) = g_itoaLowerDigits[digit];\n        val64 = quotient;\n    } while (val64 != 0);\n}\n#else\n/*\n * Compiler Optimized Division 10.\n * The text.str point to buffer end, must be Large enough\n */\nSECUREC_INLINE void SecNumber64ToDecString(SecUnsignedInt64 number, SecFormatAttr *attr)\n{\n    SecUnsignedInt64 val64 = number;\n    do {\n        --attr->text.str;\n        /* Just use lowerDigits for 0 - 9 */\n        *(attr->text.str) = g_itoaLowerDigits[val64 % SECUREC_RADIX_DECIMAL];\n        val64 /= SECUREC_RADIX_DECIMAL;\n    } while (val64 != 0);\n}\n#endif\n\n/*\n * Compiler Optimized Division 8.\n * The text.str point to buffer end, must be Large enough\n */\nSECUREC_INLINE void SecNumber64ToOctalString(SecUnsignedInt64 number, SecFormatAttr *attr)\n{\n    SecUnsignedInt64 val64 = number;\n    do {\n        --attr->text.str;\n        /* Just use lowerDigits for 0 - 9 */\n        *(attr->text.str) = g_itoaLowerDigits[val64 % SECUREC_RADIX_OCTAL];\n        val64 /= SECUREC_RADIX_OCTAL;\n    } while (val64 != 0);\n}\n/*\n * Compiler Optimized Division 16.\n * The text.str point to buffer end, must be Large enough\n */\nSECUREC_INLINE void SecNumber64ToHexString(SecUnsignedInt64 number, SecFormatAttr *attr)\n{\n    SecUnsignedInt64 val64 = number;\n    do {\n        --attr->text.str;\n        *(attr->text.str) = attr->digits[val64 % SECUREC_RADIX_HEX];\n        val64 /= SECUREC_RADIX_HEX;\n    } while (val64 != 0);\n}\n\nSECUREC_INLINE void SecNumber64ToString(SecUnsignedInt64 number, SecFormatAttr *attr)\n{\n    switch (attr->radix) {\n        /* The compiler will optimize div 10 */\n        case SECUREC_RADIX_DECIMAL:\n            SecNumber64ToDecString(number, attr);\n            break;\n        case SECUREC_RADIX_OCTAL:\n            SecNumber64ToOctalString(number, attr);\n            break;\n        case SECUREC_RADIX_HEX:\n            SecNumber64ToHexString(number, attr);\n            break;\n        default:\n            /* Do nothing */\n            break;\n    }\n}\n#endif\n\n/*\n * Converting integers to string\n */\nSECUREC_INLINE void SecNumberToString(SecUnsignedInt64 number, SecFormatAttr *attr)\n{\n#ifdef SECUREC_ON_64BITS\n    SecNumber64ToString(number, attr);\n#else /* For 32 bits system */\n    if (number <= 0xffffffffUL) { /* Use 0xffffffffUL to check if the value is in the 32-bit range */\n        /* In most case, the value to be converted is small value */\n        SecUnsignedInt32 n32Tmp = (SecUnsignedInt32)number;\n        SecNumber32ToString(n32Tmp, attr);\n    } else {\n        /* The value to be converted is greater than 4G */\n#if defined(SECUREC_VXWORKS_VERSION_5_4)\n        SecNumber64ToStringSpecial(number, attr);\n#else\n        SecNumber64ToString(number, attr);\n#endif\n    }\n#endif\n}\n\nSECUREC_INLINE int SecIsNumberNeedTo32Bit(const SecFormatAttr *attr)\n{\n    return (int)(((attr->flags & SECUREC_FLAG_I64) == 0) &&\n#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT\n            ((attr->flags & SECUREC_FLAG_INTMAX) == 0) &&\n#endif\n#ifdef SECUREC_ON_64BITS\n            ((attr->flags & SECUREC_FLAG_PTRDIFF) == 0) &&\n            ((attr->flags & SECUREC_FLAG_SIZE) == 0) &&\n#if !defined(SECUREC_COMPATIBLE_WIN_FORMAT)  /* on window 64 system sizeof long is 32bit */\n            ((attr->flags & SECUREC_FLAG_LONG) == 0) &&\n#endif\n#endif\n            ((attr->flags & SECUREC_FLAG_LONGLONG) == 0));\n}\n\nSECUREC_INLINE void SecNumberToBuffer(SecFormatAttr *attr, SecInt64 num64)\n{\n    SecUnsignedInt64 number;\n    /* Check for negative; copy into number */\n    if ((attr->flags & SECUREC_FLAG_SIGNED) != 0 && num64 < 0) {\n        number = (SecUnsignedInt64)(0 - (SecUnsignedInt64)num64); /* Wrap with unsigned int64 numbers */\n        attr->flags |= SECUREC_FLAG_NEGATIVE;\n    } else {\n        number = (SecUnsignedInt64)num64;\n    }\n    if (SecIsNumberNeedTo32Bit(attr) != 0) {\n        number = (number & (SecUnsignedInt64)0xffffffffUL);  /* Use 0xffffffff as 32 bit mask */\n    }\n\n    /* The text.str must be point to buffer.str, this pointer is used outside the function */\n    attr->text.str = &attr->buffer.str[SECUREC_BUFFER_SIZE];\n\n    if (number == 0) {\n        /* Turn off hex prefix default, and textLen is zero */\n        attr->prefixLen = 0;\n        attr->textLen = 0;\n        return;\n    }\n\n    /* Convert integer to string. It must be invoked when number > 0, otherwise the following logic is incorrect */\n    SecNumberToString(number, attr);\n    /* Compute length of number,  text.str must be in buffer.str */\n    attr->textLen = (int)(size_t)((char *)&attr->buffer.str[SECUREC_BUFFER_SIZE] - attr->text.str);\n}\n\n/*\n * Write one character to dest buffer\n */\nSECUREC_INLINE void SecWriteChar(SecPrintfStream *stream, SecChar ch, int *charsOut)\n{\n    /* Count must be reduced first, In order to identify insufficient length */\n    --stream->count;\n    if (stream->count >= 0) {\n        *(stream->cur) = ch;\n        ++stream->cur;\n        *charsOut = *charsOut + 1;\n        return;\n    }\n    /* No enough length */\n    *charsOut = -1;\n}\n\n/*\n* Write multiple identical characters.\n*/\nSECUREC_INLINE void SecWriteMultiChar(SecPrintfStream *stream, SecChar ch, int num, int *charsOut)\n{\n    int count;\n    for (count = num; count > 0; --count) {\n        --stream->count; /* count may be negative,indicating insufficient space */\n        if (stream->count < 0) {\n            *charsOut = -1;\n            return;\n        }\n        *(stream->cur) = ch;\n        ++stream->cur;\n    }\n    *charsOut = *charsOut + num;\n}\n\n/*\n* Write string function, where this function is called, make sure that len is greater than 0\n*/\nSECUREC_INLINE void SecWriteString(SecPrintfStream *stream, const SecChar *str, int len, int *charsOut)\n{\n    const SecChar *tmp = str;\n    int count;\n    for (count = len; count > 0; --count) {\n        --stream->count; /* count may be negative,indicating insufficient space */\n        if (stream->count < 0) {\n            *charsOut = -1;\n            return;\n        }\n        *(stream->cur) = *tmp;\n        ++stream->cur;\n        ++tmp;\n    }\n    *charsOut = *charsOut + len;\n}\n\n/* Use loop copy char or wchar_t string */\nSECUREC_INLINE void SecWriteStringByLoop(SecPrintfStream *stream, const SecChar *str, int len)\n{\n    int i;\n    const SecChar *tmp = str;\n    for (i = 0; i < len; ++i) {\n        *stream->cur = *tmp;\n        ++stream->cur;\n        ++tmp;\n    }\n    stream->count -= len;\n}\n\nSECUREC_INLINE void SecWriteStringOpt(SecPrintfStream *stream, const SecChar *str, int len)\n{\n    if (len < 12) { /* Performance optimization for mobile number length 12 */\n        SecWriteStringByLoop(stream, str, len);\n    } else {\n        size_t count = (size_t)(unsigned int)len * sizeof(SecChar);\n        SECUREC_MEMCPY_WARP_OPT(stream->cur, str, count);\n        stream->cur += len;\n        stream->count -= len;\n    }\n}\n\n/*\n * Return if buffer length is enough\n * The count variable can be reduced to 0, and the external function complements the \\0 terminator.\n */\nSECUREC_INLINE int SecIsStreamBufEnough(const SecPrintfStream *stream, int needLen)\n{\n    return (int)(stream->count >= needLen);\n}\n\n/* Write text string */\nSECUREC_INLINE void SecWriteTextOpt(SecPrintfStream *stream, const SecChar *str, int len, int *charsOut)\n{\n    if (SecIsStreamBufEnough(stream, len) != 0) {\n        SecWriteStringOpt(stream, str, len);\n        *charsOut += len;\n    } else {\n        SecWriteString(stream, str, len, charsOut);\n    }\n}\n\n/* Write left padding */\nSECUREC_INLINE void SecWriteLeftPadding(SecPrintfStream *stream, const SecFormatAttr *attr, int *charsOut)\n{\n    if ((attr->flags & (SECUREC_FLAG_LEFT | SECUREC_FLAG_LEADZERO)) == 0 && attr->padding > 0) {\n        /* Pad on left with blanks */\n        SecWriteMultiChar(stream, SECUREC_CHAR(' '), attr->padding, charsOut);\n    }\n}\n\n/* Write prefix */\nSECUREC_INLINE void SecWritePrefix(SecPrintfStream *stream, const SecFormatAttr *attr, int *charsOut)\n{\n    if (attr->prefixLen > 0) {\n        SecWriteString(stream, attr->prefix, attr->prefixLen, charsOut);\n    }\n}\n\n/* Write leading zeros */\nSECUREC_INLINE void SecWriteLeadingZero(SecPrintfStream *stream, const SecFormatAttr *attr, int *charsOut)\n{\n    if ((attr->flags & SECUREC_FLAG_LEADZERO) != 0 && (attr->flags & SECUREC_FLAG_LEFT) == 0 &&\n        attr->padding > 0) {\n        SecWriteMultiChar(stream, SECUREC_CHAR('0'), attr->padding, charsOut);\n    }\n}\n\n/* Write right padding */\nSECUREC_INLINE void SecWriteRightPadding(SecPrintfStream *stream, const SecFormatAttr *attr, int *charsOut)\n{\n    if (*charsOut >= 0 && (attr->flags & SECUREC_FLAG_LEFT) != 0 && attr->padding > 0) {\n        /* Pad on right with blanks */\n        SecWriteMultiChar(stream, SECUREC_CHAR(' '), attr->padding, charsOut);\n    }\n}\n\n#ifdef SECUREC_FOR_WCHAR\n#define SECUREC_TEXT_CHAR_PTR(text)  ((text).wStr)\n#define SECUREC_NEED_CONVERT_TEXT(attr) ((attr)->textIsWide == 0)\n#if SECUREC_HAVE_MBTOWC\n#define SECUREC_WRITE_TEXT_AFTER_CONVERT(stream, attr, charsOut) SecWriteTextAfterMbtowc((stream), (attr), (charsOut))\n#else\n#define SECUREC_WRITE_TEXT_AFTER_CONVERT(stream, attr, charsOut) (*(charsOut) = -1)\n#endif\n#else\n#define SECUREC_TEXT_CHAR_PTR(text)  ((text).str)\n#define SECUREC_NEED_CONVERT_TEXT(attr) ((attr)->textIsWide != 0)\n#if SECUREC_HAVE_WCTOMB\n#define SECUREC_WRITE_TEXT_AFTER_CONVERT(stream, attr, charsOut) SecWriteTextAfterWctomb((stream), (attr), (charsOut))\n#else\n#define SECUREC_WRITE_TEXT_AFTER_CONVERT(stream, attr, charsOut) (*(charsOut) = -1)\n#endif\n#endif\n\n#ifdef SECUREC_FOR_WCHAR\n#if SECUREC_HAVE_MBTOWC\nSECUREC_INLINE void SecWriteTextAfterMbtowc(SecPrintfStream *stream, const SecFormatAttr *attr, int *charsOut)\n{\n    const char *p = attr->text.str;\n    int count = attr->textLen;\n    while (count > 0) {\n        wchar_t wChar = L'\\0';\n        int retVal = mbtowc(&wChar, p, (size_t)MB_CUR_MAX);\n        if (retVal <= 0) {\n            *charsOut = -1;\n            break;\n        }\n        SecWriteChar(stream, wChar, charsOut);\n        if (*charsOut == -1) {\n            break;\n        }\n        p += retVal;\n        count -= retVal;\n    }\n}\n#endif\n#else  /* Not SECUREC_FOR_WCHAR */\n#if SECUREC_HAVE_WCTOMB\nSECUREC_INLINE void SecWriteTextAfterWctomb(SecPrintfStream *stream, const SecFormatAttr *attr, int *charsOut)\n{\n    const wchar_t *p = attr->text.wStr;\n    int count = attr->textLen;\n    while (count > 0) {\n        char tmpBuf[SECUREC_MB_LEN + 1];\n        SECUREC_MASK_MSVC_CRT_WARNING\n        int retVal = wctomb(tmpBuf, *p);\n        SECUREC_END_MASK_MSVC_CRT_WARNING\n        if (retVal <= 0) {\n            *charsOut = -1;\n            break;\n        }\n        SecWriteString(stream, tmpBuf, retVal, charsOut);\n        if (*charsOut == -1) {\n            break;\n        }\n        --count;\n        ++p;\n    }\n}\n#endif\n#endif\n\n#if SECUREC_ENABLE_SPRINTF_FLOAT\n/*\n * Write text of float\n * Using independent functions to optimize the expansion of inline functions by the compiler\n */\nSECUREC_INLINE void SecWriteFloatText(SecPrintfStream *stream, const SecFormatAttr *attr, int *charsOut)\n{\n#ifdef SECUREC_FOR_WCHAR\n#if SECUREC_HAVE_MBTOWC\n    SecWriteTextAfterMbtowc(stream, attr, charsOut);\n#else\n    *charsOut = -1;\n    (void)stream; /* To clear e438 last value assigned not used , the compiler will optimize this code */\n    (void)attr;   /* To clear e438 last value assigned not used , the compiler will optimize this code */\n#endif\n#else /* Not SECUREC_FOR_WCHAR */\n    SecWriteString(stream, attr->text.str, attr->textLen, charsOut);\n#endif\n}\n#endif\n\n/* Write text of integer or string ... */\nSECUREC_INLINE void SecWriteText(SecPrintfStream *stream, const SecFormatAttr *attr, int *charsOut)\n{\n    if (SECUREC_NEED_CONVERT_TEXT(attr)) {\n        SECUREC_WRITE_TEXT_AFTER_CONVERT(stream, attr, charsOut);\n    } else {\n        SecWriteTextOpt(stream, SECUREC_TEXT_CHAR_PTR(attr->text), attr->textLen, charsOut);\n    }\n}\n\n#define SECUREC_FMT_STATE_OFFSET  256\n\nSECUREC_INLINE SecFmtState SecDecodeState(SecChar ch, SecFmtState lastState)\n{\n    static const unsigned char stateTable[SECUREC_STATE_TABLE_SIZE] = {\n        /*\n         * Type\n         * 0:    nospecial meaning;\n         * 1:    '%'\n         * 2:    '.'\n         * 3:    '*'\n         * 4:    '0'\n         * 5:    '1' ... '9'\n         * 6:    ' ', '+', '-', '#'\n         * 7:    'h', 'l', 'L', 'w' , 'N', 'z', 'q', 't', 'j'\n         * 8:    'd', 'o', 'u', 'i', 'x', 'X', 'e', 'f', 'g', 'E', 'F', 'G', 's', 'c', '[', 'p'\n         */\n        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n        0x06, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x00, 0x06, 0x02, 0x00,\n        0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n        0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x08, 0x08, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00,\n        0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,\n        0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x08, 0x07, 0x00, 0x07, 0x00, 0x00, 0x08,\n        0x08, 0x07, 0x00, 0x08, 0x07, 0x08, 0x00, 0x07, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,\n        /* Fill zero  for normal char 128 byte for 0x80 - 0xff */\n        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n        /*\n         * State\n         * 0: normal\n         * 1: percent\n         * 2: flag\n         * 3: width\n         * 4: dot\n         * 5: precis\n         * 6: size\n         * 7: type\n         * 8: invalid\n         */\n        0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x01, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08,\n        0x01, 0x00, 0x00, 0x04, 0x04, 0x04, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x03, 0x03, 0x08, 0x05,\n        0x08, 0x08, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03, 0x05, 0x05, 0x08, 0x00, 0x00, 0x00, 0x03, 0x03,\n        0x03, 0x05, 0x05, 0x08, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00,\n        0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x00,\n        0x00\n    };\n\n#ifdef SECUREC_FOR_WCHAR\n    /* Convert to unsigned char to clear gcc 4.3.4 warning */\n    unsigned char fmtType = (unsigned char)((((unsigned int)(int)(ch)) <= (unsigned int)(int)(L'~')) ? \\\n        (stateTable[(unsigned char)(ch)]) : 0);\n    return (SecFmtState)(stateTable[fmtType * ((unsigned char)STAT_INVALID + 1) +\n        (unsigned char)(lastState) + SECUREC_FMT_STATE_OFFSET]);\n#else\n    unsigned char fmtType = stateTable[(unsigned char)(ch)];\n    return (SecFmtState)(stateTable[fmtType * ((unsigned char)STAT_INVALID + 1) +\n        (unsigned char)(lastState) + SECUREC_FMT_STATE_OFFSET]);\n#endif\n}\n\nSECUREC_INLINE void SecDecodeFlags(SecChar ch, SecFormatAttr *attr)\n{\n    switch (ch) {\n        case SECUREC_CHAR(' '):\n            attr->flags |= SECUREC_FLAG_SIGN_SPACE;\n            break;\n        case SECUREC_CHAR('+'):\n            attr->flags |= SECUREC_FLAG_SIGN;\n            break;\n        case SECUREC_CHAR('-'):\n            attr->flags |= SECUREC_FLAG_LEFT;\n            break;\n        case SECUREC_CHAR('0'):\n            attr->flags |= SECUREC_FLAG_LEADZERO;   /* Add zero th the front */\n            break;\n        case SECUREC_CHAR('#'):\n            attr->flags |= SECUREC_FLAG_ALTERNATE;  /* Output %x with 0x */\n            break;\n        default:\n            /* Do nothing */\n            break;\n    }\n    return;\n}\n\n/*\n * Decoded size identifier in format string to Reduce the number of lines of function code\n */\nSECUREC_INLINE int SecDecodeSizeI(SecFormatAttr *attr, const SecChar **format)\n{\n#ifdef SECUREC_ON_64BITS\n    attr->flags |= SECUREC_FLAG_I64;    /* %I  to  INT64 */\n#endif\n    if ((**format == SECUREC_CHAR('6')) && (*((*format) + 1) == SECUREC_CHAR('4'))) {\n        (*format) += 2; /* Add 2 to skip I64 */\n        attr->flags |= SECUREC_FLAG_I64;    /* %I64  to  INT64 */\n    } else if ((**format == SECUREC_CHAR('3')) && (*((*format) + 1) == SECUREC_CHAR('2'))) {\n        (*format) += 2; /* Add 2 to skip I32 */\n        attr->flags &= ~SECUREC_FLAG_I64;   /* %I64  to  INT32 */\n    } else if ((**format == SECUREC_CHAR('d')) || (**format == SECUREC_CHAR('i')) ||\n        (**format == SECUREC_CHAR('o')) || (**format == SECUREC_CHAR('u')) ||\n        (**format == SECUREC_CHAR('x')) || (**format == SECUREC_CHAR('X'))) {\n        /* Do nothing */\n    } else {\n        /* Compatibility  code for \"%I\" just print I */\n        return -1;\n    }\n    return 0;\n}\n\n/*\n * Decoded size identifier in format string, and skip format to next charater\n */\nSECUREC_INLINE int SecDecodeSize(SecChar ch, SecFormatAttr *attr, const SecChar **format)\n{\n    switch (ch) {\n        case SECUREC_CHAR('l'):\n            if (**format == SECUREC_CHAR('l')) {\n                *format = *format + 1;\n                attr->flags |= SECUREC_FLAG_LONGLONG; /* For long long */\n            } else {\n                attr->flags |= SECUREC_FLAG_LONG;     /* For long int or wchar_t */\n            }\n            break;\n#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT\n        case SECUREC_CHAR('z'): /* fall-through */ /* FALLTHRU */\n        case SECUREC_CHAR('Z'):\n            attr->flags |= SECUREC_FLAG_SIZE;\n            break;\n        case SECUREC_CHAR('j'):\n            attr->flags |= SECUREC_FLAG_INTMAX;\n            break;\n#endif\n        case SECUREC_CHAR('t'):\n            attr->flags |= SECUREC_FLAG_PTRDIFF;\n            break;\n        case SECUREC_CHAR('q'): /* fall-through */ /* FALLTHRU */\n        case SECUREC_CHAR('L'):\n            attr->flags |= (SECUREC_FLAG_LONGLONG | SECUREC_FLAG_LONG_DOUBLE);\n            break;\n        case SECUREC_CHAR('I'):\n            if (SecDecodeSizeI(attr, format) != 0) {\n                /* Compatibility  code for \"%I\" just print I */\n                return -1;\n            }\n            break;\n        case SECUREC_CHAR('h'):\n            if (**format == SECUREC_CHAR('h')) {\n                *format = *format + 1;\n                attr->flags |= SECUREC_FLAG_CHAR;   /* For char */\n            } else {\n                attr->flags |= SECUREC_FLAG_SHORT;  /* For short int */\n            }\n            break;\n        case SECUREC_CHAR('w'):\n            attr->flags |= SECUREC_FLAG_WIDECHAR;   /* For wide char */\n            break;\n        default:\n            /* Do nothing */\n            break;\n    }\n    return 0;\n}\n\n/*\n * Decoded char type identifier\n */\nSECUREC_INLINE void SecDecodeTypeC(SecFormatAttr *attr, unsigned int c)\n{\n    attr->textLen = 1; /* Only 1 wide character */\n\n#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT)) && !(defined(__hpux)) && !(defined(SECUREC_ON_SOLARIS))\n    attr->flags &= ~SECUREC_FLAG_LEADZERO;\n#endif\n\n#ifdef SECUREC_FOR_WCHAR\n    if ((attr->flags & SECUREC_FLAG_SHORT) != 0) {\n        /* Get  multibyte character from argument */\n        attr->buffer.str[0] = (char)c;\n        attr->text.str = attr->buffer.str;\n        attr->textIsWide = 0;\n    } else {\n        attr->buffer.wStr[0] = (wchar_t)c;\n        attr->text.wStr = attr->buffer.wStr;\n        attr->textIsWide = 1;\n    }\n#else /* Not SECUREC_FOR_WCHAR */\n    if ((attr->flags & (SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR)) != 0) {\n#if SECUREC_HAVE_WCHART\n        attr->buffer.wStr[0] = (wchar_t)c;\n        attr->text.wStr = attr->buffer.wStr;\n        attr->textIsWide = 1;\n#else\n        attr->textLen = 0; /* Ignore unsupported characters */\n        attr->fldWidth = 0; /* No paddings  */\n#endif\n    } else {\n        /* Get  multibyte character from argument */\n        attr->buffer.str[0] = (char)c;\n        attr->text.str = attr->buffer.str;\n        attr->textIsWide = 0;\n    }\n#endif\n}\n\n#ifdef SECUREC_FOR_WCHAR\n#define SECUREC_IS_NARROW_STRING(attr) (((attr)->flags & SECUREC_FLAG_SHORT) != 0)\n#else\n#define SECUREC_IS_NARROW_STRING(attr) (((attr)->flags & (SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR)) == 0)\n#endif\n\nSECUREC_INLINE void SecDecodeTypeSchar(SecFormatAttr *attr)\n{\n    size_t textLen;\n    if (attr->text.str == NULL) {\n        /*\n         * Literal string to print null ptr, define it as array rather than const text area\n         * To avoid gcc warning with pointing const text with variable\n         */\n        static char strNullString[SECUREC_NULL_STRING_SIZE] = \"(null)\";\n        attr->text.str = strNullString;\n    }\n    if (attr->precision == -1) {\n        /* Precision NOT assigned */\n        /* The strlen performance is high when the string length is greater than 32 */\n        textLen = strlen(attr->text.str);\n        if (textLen > SECUREC_STRING_MAX_LEN) {\n            textLen = 0;\n        }\n    } else {\n        /* Precision assigned */\n        SECUREC_CALC_STR_LEN(attr->text.str, (size_t)(unsigned int)attr->precision, &textLen);\n    }\n    attr->textLen = (int)textLen;\n}\n\nSECUREC_INLINE void SecDecodeTypeSwchar(SecFormatAttr *attr)\n{\n#if SECUREC_HAVE_WCHART\n    size_t textLen;\n    attr->textIsWide = 1;\n    if (attr->text.wStr == NULL) {\n        /*\n         * Literal string to print null ptr, define it as array rather than const text area\n         * To avoid gcc warning with pointing const text with variable\n         */\n        static wchar_t wStrNullString[SECUREC_NULL_STRING_SIZE] = { L'(', L'n', L'u', L'l', L'l', L')', L'\\0', L'\\0' };\n        attr->text.wStr = wStrNullString;\n    }\n    /* The textLen in wchar_t,when precision is -1, it is unlimited  */\n    SECUREC_CALC_WSTR_LEN(attr->text.wStr, (size_t)(unsigned int)attr->precision, &textLen);\n    if (textLen > SECUREC_WCHAR_STRING_MAX_LEN) {\n        textLen = 0;\n    }\n    attr->textLen = (int)textLen;\n#else\n    attr->textLen = 0;\n#endif\n}\n\n/*\n * Decoded string identifier\n */\nSECUREC_INLINE void SecDecodeTypeS(SecFormatAttr *attr, char *argPtr)\n{\n#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT))\n#if (!defined(SECUREC_ON_UNIX))\n    attr->flags &= ~SECUREC_FLAG_LEADZERO;\n#endif\n#if (defined(SECUREC_FOR_WCHAR))\n    if ((attr->flags & SECUREC_FLAG_LONG) == 0) {\n        attr->flags |= SECUREC_FLAG_SHORT;\n    }\n#endif\n#endif\n    attr->text.str = argPtr;\n    if (SECUREC_IS_NARROW_STRING(attr)) {\n        /* The textLen now contains length in multibyte chars */\n        SecDecodeTypeSchar(attr);\n    } else {\n        /* The textLen now contains length in wide chars */\n        SecDecodeTypeSwchar(attr);\n    }\n}\n\n/*\n * Check precision in format\n */\nSECUREC_INLINE int SecDecodePrecision(SecChar ch, SecFormatAttr *attr)\n{\n    if (attr->dynPrecision == 0) {\n        /* Add digit to current precision */\n        if (SECUREC_MUL_TEN_ADD_BEYOND_MAX(attr->precision)) {\n            return -1;\n        }\n        attr->precision = (int)SECUREC_MUL_TEN((unsigned int)attr->precision) +\n            (unsigned char)(ch - SECUREC_CHAR('0'));\n    } else {\n        if (attr->precision < 0) {\n            attr->precision = -1;\n        }\n        if (attr->precision > SECUREC_MAX_WIDTH_LEN) {\n            return -1;\n        }\n    }\n    return 0;\n}\n\n/*\n * Check width in format\n */\nSECUREC_INLINE int SecDecodeWidth(SecChar ch, SecFormatAttr *attr, SecFmtState lastState)\n{\n    if (attr->dynWidth == 0) {\n        if (lastState != STAT_WIDTH) {\n            attr->fldWidth = 0;\n        }\n        if (SECUREC_MUL_TEN_ADD_BEYOND_MAX(attr->fldWidth)) {\n            return -1;\n        }\n        attr->fldWidth = (int)SECUREC_MUL_TEN((unsigned int)attr->fldWidth) +\n            (unsigned char)(ch - SECUREC_CHAR('0'));\n    } else {\n        if (attr->fldWidth < 0) {\n            attr->flags |= SECUREC_FLAG_LEFT;\n            attr->fldWidth = (-attr->fldWidth);\n        }\n        if (attr->fldWidth > SECUREC_MAX_WIDTH_LEN) {\n            return -1;\n        }\n    }\n    return 0;\n}\n\n/*\n * The sprintf_s function processes the wide character as a parameter for %C\n * The swprintf_s function processes the multiple character as a parameter for %C\n */\nSECUREC_INLINE void SecUpdateWcharFlags(SecFormatAttr *attr)\n{\n    if ((attr->flags & (SECUREC_FLAG_SHORT | SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR)) == 0) {\n#ifdef SECUREC_FOR_WCHAR\n        attr->flags |= SECUREC_FLAG_SHORT;\n#else\n        attr->flags |= SECUREC_FLAG_WIDECHAR;\n#endif\n    }\n}\n/*\n * When encountering %S, current just same as %C\n */\nSECUREC_INLINE void SecUpdateWstringFlags(SecFormatAttr *attr)\n{\n    SecUpdateWcharFlags(attr);\n}\n\n#if SECUREC_IN_KERNEL\nSECUREC_INLINE void SecUpdatePointFlagsForKernel(SecFormatAttr *attr)\n{\n    /* Width is not set */\n    if (attr->fldWidth <= 0) {\n        attr->flags |= SECUREC_FLAG_LEADZERO;\n        attr->fldWidth = 2 * sizeof(void *);  /* 2 x byte number is the length of hex */\n    }\n    if ((attr->flags & SECUREC_FLAG_ALTERNATE) != 0) {\n        /* Alternate form means '0x' prefix */\n        attr->prefix[0] = SECUREC_CHAR('0');\n        attr->prefix[1] = SECUREC_CHAR('x');\n        attr->prefixLen = SECUREC_PREFIX_LEN;\n    }\n    attr->flags |= SECUREC_FLAG_LONG;  /* Converting a long */\n}\n#endif\n\nSECUREC_INLINE void SecUpdatePointFlags(SecFormatAttr *attr)\n{\n    attr->flags |= SECUREC_FLAG_POINTER;\n#if SECUREC_IN_KERNEL\n    SecUpdatePointFlagsForKernel(attr);\n#else\n#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) || defined(SECUREC_VXWORKS_PLATFORM)) && (!defined(SECUREC_ON_UNIX))\n#if defined(SECUREC_VXWORKS_PLATFORM)\n    attr->precision = 1;\n#else\n    attr->precision = 0;\n#endif\n    attr->flags |= SECUREC_FLAG_ALTERNATE; /* \"0x\" is not default prefix in UNIX */\n    attr->digits = g_itoaLowerDigits;\n#else /* On unix or win */\n#if defined(_AIX) || defined(SECUREC_ON_SOLARIS)\n    attr->precision = 1;\n#else\n    attr->precision = 2 * sizeof(void *);  /* 2 x byte number is the length of hex */\n#endif\n#if defined(SECUREC_ON_UNIX)\n    attr->digits = g_itoaLowerDigits;\n#else\n    attr->digits = g_itoaUpperDigits;\n#endif\n#endif\n\n#if defined(SECUREC_COMPATIBLE_WIN_FORMAT)\n    attr->flags &= ~SECUREC_FLAG_LEADZERO;\n#endif\n\n#ifdef SECUREC_ON_64BITS\n    attr->flags |= SECUREC_FLAG_I64;   /* Converting an int64 */\n#else\n    attr->flags |= SECUREC_FLAG_LONG;  /* Converting a long */\n#endif\n    /* Set up for %#p on different system */\n    if ((attr->flags & SECUREC_FLAG_ALTERNATE) != 0) {\n        /* Alternate form means '0x' prefix */\n        attr->prefix[0] = SECUREC_CHAR('0');\n#if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) || defined(SECUREC_VXWORKS_PLATFORM))\n        attr->prefix[1] = SECUREC_CHAR('x');\n#else\n        attr->prefix[1] = (SecChar)(attr->digits[SECUREC_NUMBER_OF_X]);\n#endif\n#if defined(_AIX) || defined(SECUREC_ON_SOLARIS)\n        attr->prefixLen = 0;\n#else\n        attr->prefixLen = SECUREC_PREFIX_LEN;\n#endif\n    }\n#endif\n}\n\nSECUREC_INLINE void SecUpdateXpxFlags(SecFormatAttr *attr, SecChar ch)\n{\n    /* Use unsigned lower hex output for 'x' */\n    attr->digits = g_itoaLowerDigits;\n    attr->radix = SECUREC_RADIX_HEX;\n    switch (ch) {\n        case SECUREC_CHAR('p'):\n            /* Print a pointer */\n            SecUpdatePointFlags(attr);\n            break;\n        case SECUREC_CHAR('X'): /* fall-through */ /* FALLTHRU */\n            /* Unsigned upper hex output */\n            attr->digits = g_itoaUpperDigits;\n            /* fall-through */ /* FALLTHRU */\n        default:\n            /* For %#x or %#X */\n            if ((attr->flags & SECUREC_FLAG_ALTERNATE) != 0) {\n                /* Alternate form means '0x' prefix */\n                attr->prefix[0] = SECUREC_CHAR('0');\n                attr->prefix[1] = (SecChar)(attr->digits[SECUREC_NUMBER_OF_X]);\n                attr->prefixLen = SECUREC_PREFIX_LEN;\n            }\n            break;\n    }\n}\n\nSECUREC_INLINE void SecUpdateOudiFlags(SecFormatAttr *attr, SecChar ch)\n{\n    /* Do not set digits here */\n    switch (ch) {\n        case SECUREC_CHAR('i'): /* fall-through */ /* FALLTHRU */\n        case SECUREC_CHAR('d'): /* fall-through */ /* FALLTHRU */\n            /* For signed decimal output */\n            attr->flags |= SECUREC_FLAG_SIGNED;\n            /* fall-through */ /* FALLTHRU */\n        case SECUREC_CHAR('u'):\n            attr->radix = SECUREC_RADIX_DECIMAL;\n            attr->digits = g_itoaLowerDigits;\n            break;\n        case SECUREC_CHAR('o'):\n            /* For unsigned octal output */\n            attr->radix = SECUREC_RADIX_OCTAL;\n            attr->digits = g_itoaLowerDigits;\n            if ((attr->flags & SECUREC_FLAG_ALTERNATE) != 0) {\n                /* Alternate form means force a leading 0 */\n                attr->flags |= SECUREC_FLAG_FORCE_OCTAL;\n            }\n            break;\n        default:\n            /* Do nothing */\n            break;\n    }\n}\n\n#if SECUREC_ENABLE_SPRINTF_FLOAT\nSECUREC_INLINE void SecFreeFloatBuffer(SecFloatAdapt *floatAdapt)\n{\n    if (floatAdapt->floatBuffer != NULL) {\n        SECUREC_FREE(floatAdapt->floatBuffer);\n    }\n    if (floatAdapt->allocatedFmtStr != NULL) {\n        SECUREC_FREE(floatAdapt->allocatedFmtStr);\n    }\n    floatAdapt->floatBuffer = NULL;\n    floatAdapt->allocatedFmtStr = NULL;\n    floatAdapt->fmtStr = NULL;\n    floatAdapt->bufferSize = 0;\n}\n\nSECUREC_INLINE void SecSeekToFrontPercent(const SecChar **format)\n{\n    const SecChar *fmt = *format;\n    while (*fmt != SECUREC_CHAR('%')) { /* Must meet '%' */\n        --fmt;\n    }\n    *format = fmt;\n}\n\n/* Init float format, return 0 is OK */\nSECUREC_INLINE int SecInitFloatFmt(SecFloatAdapt *floatFmt, const SecChar *format)\n{\n    const SecChar *fmt = format - 2;  /* Sub 2 to the position before 'f' or 'g' */\n    int fmtStrLen;\n    int i;\n\n    SecSeekToFrontPercent(&fmt);\n    /* Now fmt point to '%' */\n    fmtStrLen = (int)(size_t)(format - fmt) + 1;   /* With ending terminator */\n    if (fmtStrLen > (int)sizeof(floatFmt->buffer)) {\n        /* When buffer is NOT enough, alloc a new buffer */\n        floatFmt->allocatedFmtStr = (char *)SECUREC_MALLOC((size_t)((unsigned int)fmtStrLen));\n        if (floatFmt->allocatedFmtStr == NULL) {\n            return -1;\n        }\n        floatFmt->fmtStr = floatFmt->allocatedFmtStr;\n    } else {\n        floatFmt->fmtStr = floatFmt->buffer;\n        floatFmt->allocatedFmtStr = NULL; /* Must set to NULL, later code free memory based on this identity */\n    }\n\n    for (i = 0; i < fmtStrLen - 1; ++i) {\n        /* Convert wchar to char */\n        floatFmt->fmtStr[i] = (char)(fmt[i]);  /* Copy the format string */\n    }\n    floatFmt->fmtStr[fmtStrLen - 1] = '\\0';\n\n    return 0;\n}\n\n/* Init float buffer and format, return 0 is OK */\nSECUREC_INLINE int SecInitFloatBuffer(SecFloatAdapt *floatAdapt, const SecChar *format, SecFormatAttr *attr)\n{\n    floatAdapt->allocatedFmtStr = NULL;\n    floatAdapt->fmtStr = NULL;\n    floatAdapt->floatBuffer = NULL;\n    /* Compute the precision value */\n    if (attr->precision < 0) {\n        attr->precision = SECUREC_FLOAT_DEFAULT_PRECISION;\n    }\n    /*\n     * Calc buffer size to store double value\n     * The maximum length of SECUREC_MAX_WIDTH_LEN is enough\n     */\n    if ((attr->flags & SECUREC_FLAG_LONG_DOUBLE) != 0) {\n        if (attr->precision > (SECUREC_MAX_WIDTH_LEN - SECUREC_FLOAT_BUFSIZE_LB)) {\n            return -1;\n        }\n        /* Long double needs to meet the basic print length */\n        floatAdapt->bufferSize = SECUREC_FLOAT_BUFSIZE_LB + attr->precision + SECUREC_FLOAT_BUF_EXT;\n    } else {\n        if (attr->precision > (SECUREC_MAX_WIDTH_LEN - SECUREC_FLOAT_BUFSIZE)) {\n            return -1;\n        }\n        /* Double needs to meet the basic print length */\n        floatAdapt->bufferSize = SECUREC_FLOAT_BUFSIZE + attr->precision + SECUREC_FLOAT_BUF_EXT;\n    }\n    if (attr->fldWidth > floatAdapt->bufferSize) {\n        floatAdapt->bufferSize = attr->fldWidth + SECUREC_FLOAT_BUF_EXT;\n    }\n\n    if (floatAdapt->bufferSize > SECUREC_BUFFER_SIZE) {\n        /* The current value of SECUREC_BUFFER_SIZE could not store the formatted float string */\n        floatAdapt->floatBuffer = (char *)SECUREC_MALLOC(((size_t)(unsigned int)floatAdapt->bufferSize));\n        if (floatAdapt->floatBuffer == NULL) {\n            return -1;\n        }\n        attr->text.str = floatAdapt->floatBuffer;\n    } else {\n        attr->text.str = attr->buffer.str; /* Output buffer for float string with default size */\n    }\n\n    if (SecInitFloatFmt(floatAdapt, format) != 0) {\n        if (floatAdapt->floatBuffer != NULL) {\n            SECUREC_FREE(floatAdapt->floatBuffer);\n            floatAdapt->floatBuffer = NULL;\n        }\n        return -1;\n    }\n    return 0;\n}\n#endif\n\nSECUREC_INLINE SecInt64 SecUpdateNegativeChar(SecFormatAttr *attr, char ch)\n{\n    SecInt64 num64 = ch; /* Sign extend */\n    if (num64 >= 128) { /* 128 on some platform, char is always unsigned */\n        unsigned char tmp = (unsigned char)(~((unsigned char)ch));\n        num64 = tmp + 1;\n        attr->flags |= SECUREC_FLAG_NEGATIVE;\n    }\n    return num64;\n}\n\n/*\n * If the precision is not satisfied, zero is added before the string\n */\nSECUREC_INLINE void SecNumberSatisfyPrecision(SecFormatAttr *attr)\n{\n    int precision;\n    if (attr->precision < 0) {\n        precision = 1; /* Default precision 1 */\n    } else {\n#if defined(SECUREC_COMPATIBLE_WIN_FORMAT)\n        attr->flags &= ~SECUREC_FLAG_LEADZERO;\n#else\n        if ((attr->flags & SECUREC_FLAG_POINTER) == 0) {\n            attr->flags &= ~SECUREC_FLAG_LEADZERO;\n        }\n#endif\n        if (attr->precision > SECUREC_MAX_PRECISION) {\n            attr->precision = SECUREC_MAX_PRECISION;\n        }\n        precision = attr->precision;\n    }\n    while (attr->textLen < precision) {\n        --attr->text.str;\n        *(attr->text.str) = '0';\n        ++attr->textLen;\n    }\n}\n\n/*\n * Add leading zero for %#o\n */\nSECUREC_INLINE void SecNumberForceOctal(SecFormatAttr *attr)\n{\n    /* Force a leading zero if FORCEOCTAL flag set */\n    if ((attr->flags & SECUREC_FLAG_FORCE_OCTAL) != 0 &&\n        (attr->textLen == 0 || attr->text.str[0] != '0')) {\n        --attr->text.str;\n        *(attr->text.str) = '0';\n        ++attr->textLen;\n    }\n}\n\nSECUREC_INLINE void SecUpdateSignedNumberPrefix(SecFormatAttr *attr)\n{\n    if ((attr->flags & SECUREC_FLAG_SIGNED) == 0) {\n        return;\n    }\n    if ((attr->flags & SECUREC_FLAG_NEGATIVE) != 0) {\n        /* Prefix is '-' */\n        attr->prefix[0] = SECUREC_CHAR('-');\n        attr->prefixLen = 1;\n        return;\n    }\n    if ((attr->flags & SECUREC_FLAG_SIGN) != 0) {\n        /* Prefix is '+' */\n        attr->prefix[0] = SECUREC_CHAR('+');\n        attr->prefixLen = 1;\n        return;\n    }\n    if ((attr->flags & SECUREC_FLAG_SIGN_SPACE) != 0) {\n        /* Prefix is ' ' */\n        attr->prefix[0] = SECUREC_CHAR(' ');\n        attr->prefixLen = 1;\n        return;\n    }\n    return;\n}\n\nSECUREC_INLINE void SecNumberCompatZero(SecFormatAttr *attr)\n{\n#if SECUREC_IN_KERNEL\n    if ((attr->flags & SECUREC_FLAG_POINTER) != 0) {\n        static char strNullPointer[SECUREC_NULL_STRING_SIZE] = \"(null)\";\n        attr->text.str = strNullPointer;\n        attr->textLen = 6; /* Length of (null) is 6 */\n        attr->flags &= ~SECUREC_FLAG_LEADZERO;\n        attr->prefixLen = 0;\n        if (attr->precision >= 0 && attr->precision < attr->textLen) {\n            attr->textLen = attr->precision;\n        }\n    }\n    if ((attr->flags & SECUREC_FLAG_POINTER) == 0 && attr->radix == SECUREC_RADIX_HEX &&\n        (attr->flags & SECUREC_FLAG_ALTERNATE) != 0) {\n        /* Add 0x prefix for %x or %X, the prefix string has been set before */\n        attr->prefixLen = SECUREC_PREFIX_LEN;\n    }\n#elif defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && (!defined(SECUREC_ON_UNIX))\n    if ((attr->flags & SECUREC_FLAG_POINTER) != 0) {\n        static char strNullPointer[SECUREC_NULL_STRING_SIZE] = \"(nil)\";\n        attr->text.str = strNullPointer;\n        attr->textLen = 5; /* Length of (nil) is 5 */\n        attr->flags &= ~SECUREC_FLAG_LEADZERO;\n    }\n#elif defined(SECUREC_VXWORKS_PLATFORM) || defined(__hpux)\n    if ((attr->flags & SECUREC_FLAG_POINTER) != 0 && (attr->flags & SECUREC_FLAG_ALTERNATE) != 0) {\n        /* Add 0x prefix for %p, the prefix string has been set before */\n        attr->prefixLen = SECUREC_PREFIX_LEN;\n    }\n#endif\n    (void)attr; /* To clear e438 last value assigned not used , the compiler will optimize this code */\n}\n\n/*\n * Formatting output core function\n */\nSECUREC_INLINE int SecOutput(SecPrintfStream *stream, const SecChar *cFormat, va_list argList)\n{\n    const SecChar *format = cFormat;\n    int charsOut;               /* Characters written */\n    int noOutput = 0; /* Must be initialized or compiler alerts */\n    SecFmtState state;\n    SecFormatAttr formatAttr;\n\n    formatAttr.flags = 0;\n    formatAttr.textIsWide = 0;    /* Flag for buffer contains wide chars */\n    formatAttr.fldWidth = 0;\n    formatAttr.precision = 0;\n    formatAttr.dynWidth = 0;\n    formatAttr.dynPrecision = 0;\n    formatAttr.digits = g_itoaUpperDigits;\n    formatAttr.radix = SECUREC_RADIX_DECIMAL;\n    formatAttr.padding = 0;\n    formatAttr.textLen = 0;\n    formatAttr.text.str = NULL;\n    formatAttr.prefixLen = 0;\n    formatAttr.prefix[0] = SECUREC_CHAR('\\0');\n    formatAttr.prefix[1] = SECUREC_CHAR('\\0');\n    charsOut = 0;\n    state = STAT_NORMAL;        /* Starting state */\n\n    /* Loop each format character */\n    while (*format != SECUREC_CHAR('\\0') && charsOut >= 0) {\n        SecFmtState lastState = state;\n        SecChar ch = *format; /* Currently read character */\n        ++format;\n        state = SecDecodeState(ch, lastState);\n        switch (state) {\n            case STAT_NORMAL:\n                SecWriteChar(stream, ch, &charsOut);\n                continue;\n            case STAT_PERCENT:\n                /* Set default values */\n                noOutput = 0;\n                formatAttr.prefixLen = 0;\n                formatAttr.textLen = 0;\n                formatAttr.flags = 0;\n                formatAttr.fldWidth = 0;\n                formatAttr.precision = -1;\n                formatAttr.textIsWide = 0;\n                formatAttr.dynWidth = 0;\n                formatAttr.dynPrecision = 0;\n                break;\n            case STAT_FLAG:\n                /* Set flag based on which flag character */\n                SecDecodeFlags(ch, &formatAttr);\n                break;\n            case STAT_WIDTH:\n                /* Update width value */\n                if (ch == SECUREC_CHAR('*')) {\n                    /* get width from arg list */\n                    formatAttr.fldWidth = (int)va_arg(argList, int);\n                    formatAttr.dynWidth = 1;\n                }\n                if (SecDecodeWidth(ch, &formatAttr, lastState) != 0) {\n                    return -1;\n                }\n                break;\n            case STAT_DOT:\n                formatAttr.precision = 0;\n                break;\n            case STAT_PRECIS:\n                /* Update precision value */\n                if (ch == SECUREC_CHAR('*')) {\n                    /* Get precision from arg list */\n                    formatAttr.precision = (int)va_arg(argList, int);\n                    formatAttr.dynPrecision = 1;\n                }\n                if (SecDecodePrecision(ch, &formatAttr) != 0) {\n                    return -1;\n                }\n                break;\n            case STAT_SIZE:\n                /* Read a size specifier, set the formatAttr.flags based on it, and skip format to next character */\n                if (SecDecodeSize(ch, &formatAttr, &format) != 0) {\n                    /* Compatibility  code for \"%I\" just print I */\n                    SecWriteChar(stream, ch, &charsOut);\n                    state = STAT_NORMAL;\n                    continue;\n                }\n                break;\n            case STAT_TYPE:\n                switch (ch) {\n                    case SECUREC_CHAR('C'): /* Wide char */\n                        SecUpdateWcharFlags(&formatAttr);\n                        /* fall-through */ /* FALLTHRU */\n                    case SECUREC_CHAR('c'): {\n                        unsigned int cValue = (unsigned int)va_arg(argList, int);\n                        SecDecodeTypeC(&formatAttr, cValue);\n                        break;\n                    }\n                    case SECUREC_CHAR('S'):    /* Wide char string */\n                        SecUpdateWstringFlags(&formatAttr);\n                        /* fall-through */ /* FALLTHRU */\n                    case SECUREC_CHAR('s'): {\n                        char *argPtr = (char *)va_arg(argList, char *);\n                        SecDecodeTypeS(&formatAttr, argPtr);\n                        break;\n                    }\n                    case SECUREC_CHAR('G'): /* fall-through */ /* FALLTHRU */\n                    case SECUREC_CHAR('g'): /* fall-through */ /* FALLTHRU */\n                    case SECUREC_CHAR('E'): /* fall-through */ /* FALLTHRU */\n                    case SECUREC_CHAR('F'): /* fall-through */ /* FALLTHRU */\n                    case SECUREC_CHAR('e'): /* fall-through */ /* FALLTHRU */\n                    case SECUREC_CHAR('f'): {\n#if SECUREC_ENABLE_SPRINTF_FLOAT\n                        /* Add following code to call system sprintf API for float number */\n                        SecFloatAdapt floatAdapt;\n                        noOutput = 1; /* It's no more data needs to be written */\n\n                        /* Now format is pointer to the next character of 'f' */\n                        if (SecInitFloatBuffer(&floatAdapt, format, &formatAttr) != 0) {\n                            break;\n                        }\n\n                        if ((formatAttr.flags & SECUREC_FLAG_LONG_DOUBLE) != 0) {\n#if defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && SECUREC_ENABLE_SPRINTF_LONG_DOUBLE\n                            long double tmp = (long double)va_arg(argList, long double);\n                            SecFormatLongDouble(&formatAttr, &floatAdapt, tmp);\n#else\n                            double tmp = (double)va_arg(argList, double);\n                            SecFormatDouble(&formatAttr, &floatAdapt, tmp);\n#endif\n                        } else {\n                            double tmp = (double)va_arg(argList, double);\n                            SecFormatDouble(&formatAttr, &floatAdapt, tmp);\n                        }\n\n                        /* Only need write formatted float string */\n                        SecWriteFloatText(stream, &formatAttr, &charsOut);\n                        SecFreeFloatBuffer(&floatAdapt);\n                        break;\n#else\n                        return -1;\n#endif\n                    }\n                    case SECUREC_CHAR('X'): /* fall-through */ /* FALLTHRU */\n                    case SECUREC_CHAR('p'): /* fall-through */ /* FALLTHRU */\n                    case SECUREC_CHAR('x'): /* fall-through */ /* FALLTHRU */\n                        SecUpdateXpxFlags(&formatAttr, ch);\n                        /* fall-through */ /* FALLTHRU */\n                    case SECUREC_CHAR('i'): /* fall-through */ /* FALLTHRU */\n                    case SECUREC_CHAR('d'): /* fall-through */ /* FALLTHRU */\n                    case SECUREC_CHAR('u'): /* fall-through */ /* FALLTHRU */\n                    case SECUREC_CHAR('o'): {\n                        SecInt64 num64;\n                        SecUpdateOudiFlags(&formatAttr, ch);\n                        /* Read argument into variable num64. Be careful, depend on the order of judgment */\n                        if ((formatAttr.flags & SECUREC_FLAG_I64) != 0 ||\n                            (formatAttr.flags & SECUREC_FLAG_LONGLONG) != 0) {\n                            num64 = (SecInt64)va_arg(argList, SecInt64); /* Maximum Bit Width sign bit unchanged */\n                        } else if ((formatAttr.flags & SECUREC_FLAG_LONG) != 0) {\n                            num64 = SECUREC_GET_LONG_FROM_ARG(formatAttr);\n                        } else if ((formatAttr.flags & SECUREC_FLAG_CHAR) != 0) {\n                            num64 = SECUREC_GET_CHAR_FROM_ARG(formatAttr);\n                        } else if ((formatAttr.flags & SECUREC_FLAG_SHORT) != 0) {\n                            num64 = SECUREC_GET_SHORT_FROM_ARG(formatAttr);\n#ifdef SECUREC_COMPATIBLE_LINUX_FORMAT\n                        } else if ((formatAttr.flags & SECUREC_FLAG_PTRDIFF) != 0) {\n                            num64 = (ptrdiff_t)va_arg(argList, ptrdiff_t);  /* Sign extend */\n                        } else if ((formatAttr.flags & SECUREC_FLAG_SIZE) != 0) {\n                            num64 = SECUREC_GET_SIZE_FROM_ARG(formatAttr);\n                        } else if ((formatAttr.flags & SECUREC_FLAG_INTMAX) != 0) {\n                            num64 = (SecInt64)va_arg(argList, SecInt64);\n#endif\n                        } else {\n                            num64 = SECUREC_GET_INT_FROM_ARG(formatAttr);\n                        }\n\n                        /* The order of the following calls must be correct */\n                        SecNumberToBuffer(&formatAttr, num64);\n                        SecNumberSatisfyPrecision(&formatAttr);\n                        SecNumberForceOctal(&formatAttr);\n                        SecUpdateSignedNumberPrefix(&formatAttr);\n                        if (num64 == 0) {\n                            SecNumberCompatZero(&formatAttr);\n                        }\n                        break;\n                    }\n                    default:\n                        /* Do nothing */\n                        break;\n                }\n\n                if (noOutput == 0) {\n                    /* Calculate amount of padding */\n                    formatAttr.padding = (formatAttr.fldWidth - formatAttr.textLen) - formatAttr.prefixLen;\n\n                    /* Put out the padding, prefix, and text, in the correct order */\n                    SecWriteLeftPadding(stream, &formatAttr, &charsOut);\n                    SecWritePrefix(stream, &formatAttr, &charsOut);\n                    SecWriteLeadingZero(stream, &formatAttr, &charsOut);\n                    SecWriteText(stream, &formatAttr, &charsOut);\n                    SecWriteRightPadding(stream, &formatAttr, &charsOut);\n                }\n                break;\n            case STAT_INVALID: /* fall-through */ /* FALLTHRU */\n            default:\n                return -1;  /* Input format is wrong(STAT_INVALID), directly return */\n        }\n    }\n\n    if (state != STAT_NORMAL && state != STAT_TYPE) {\n        return -1;\n    }\n\n    return charsOut;            /* The number of characters written */\n}\n\n/*\n * Output one zero character zero into the SecPrintfStream structure\n * If there is not enough space, make sure f->count is less than 0\n */\nSECUREC_INLINE int SecPutZeroChar(SecPrintfStream *stream)\n{\n    --stream->count;\n    if (stream->count >= 0) {\n        *(stream->cur) = SECUREC_CHAR('\\0');\n        ++stream->cur;\n        return 0;\n    }\n    return -1;\n}\n\n/*\n * Multi character formatted output implementation\n */\n#ifdef SECUREC_FOR_WCHAR\nint SecVswprintfImpl(wchar_t *string, size_t count, const wchar_t *format, va_list argList)\n#else\nint SecVsnprintfImpl(char *string, size_t count, const char *format, va_list argList)\n#endif\n{\n    SecPrintfStream stream;\n    int retVal;\n\n    stream.count = (int)count; /* The count include \\0 character, must be greater than zero */\n    stream.cur = string;\n\n    retVal = SecOutput(&stream, format, argList);\n    if (retVal >= 0) {\n        if (SecPutZeroChar(&stream) == 0) {\n            return retVal;\n        }\n    }\n    if (stream.count < 0) {\n        /* The buffer was too small, then truncate */\n        string[count - 1] = SECUREC_CHAR('\\0');\n        return SECUREC_PRINTF_TRUNCATE;\n    }\n    string[0] = SECUREC_CHAR('\\0'); /* Empty the dest string */\n    return -1;\n}\n#endif /* OUTPUT_INL_2B263E9C_43D8_44BB_B17A_6D2033DECEE5 */\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/scanf_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: scanf_s function\n * Create: 2014-02-25\n */\n\n#include \"securec.h\"\n\n/*\n * <FUNCTION DESCRIPTION>\n *    The scanf_s function is equivalent to fscanf_s with the argument stdin interposed before the arguments to scanf_s\n *     The scanf_s function reads data from the standard input stream stdin and\n *    writes the data into the location that's given by argument. Each argument\n *    must be a pointer to a variable of a type that corresponds to a type specifier\n *    in format. If copying occurs between strings that overlap, the behavior is\n *    undefined.\n *\n * <INPUT PARAMETERS>\n *    format                  Format control string.\n *    ...                       Optional arguments.\n *\n * <OUTPUT PARAMETERS>\n *    ...                       The converted value stored in user assigned address\n *\n * <RETURN VALUE>\n *    Returns the number of fields successfully converted and assigned;\n *    the return value does not include fields that were read but not assigned.\n *    A return value of 0 indicates that no fields were assigned.\n *    return -1 if an error occurs.\n */\nint scanf_s(const char *format, ...)\n{\n    int ret;                    /* If initialization causes  e838 */\n    va_list argList;\n\n    va_start(argList, format);\n    ret = vscanf_s(format, argList);\n    va_end(argList);\n    (void)argList;              /* To clear e438 last value assigned not used , the compiler will optimize this code */\n\n    return ret;\n}\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/secinput.h",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: Define macro, data struct, and declare function prototype,\n *              which is used by input.inl, secureinput_a.c and secureinput_w.c.\n * Create: 2014-02-25\n */\n\n#ifndef SEC_INPUT_H_E950DA2C_902F_4B15_BECD_948E99090D9C\n#define SEC_INPUT_H_E950DA2C_902F_4B15_BECD_948E99090D9C\n#include \"securecutil.h\"\n\n#define SECUREC_SCANF_EINVAL             (-1)\n#define SECUREC_SCANF_ERROR_PARA         (-2)\n\n/* For internal stream flag */\n#define SECUREC_MEM_STR_FLAG             0x01U\n#define SECUREC_FILE_STREAM_FLAG         0x02U\n#define SECUREC_PIPE_STREAM_FLAG         0x04U\n#define SECUREC_LOAD_FILE_TO_MEM_FLAG    0x08U\n\n#define SECUREC_UCS_BOM_HEADER_SIZE      2U\n#define SECUREC_UCS_BOM_HEADER_BE_1ST    0xfeU\n#define SECUREC_UCS_BOM_HEADER_BE_2ST    0xffU\n#define SECUREC_UCS_BOM_HEADER_LE_1ST    0xffU\n#define SECUREC_UCS_BOM_HEADER_LE_2ST    0xfeU\n#define SECUREC_UTF8_BOM_HEADER_SIZE     3U\n#define SECUREC_UTF8_BOM_HEADER_1ST      0xefU\n#define SECUREC_UTF8_BOM_HEADER_2ND      0xbbU\n#define SECUREC_UTF8_BOM_HEADER_3RD      0xbfU\n#define SECUREC_UTF8_LEAD_1ST            0xe0U\n#define SECUREC_UTF8_LEAD_2ND            0x80U\n\n#define SECUREC_BEGIN_WITH_UCS_BOM(s, len) ((len) == SECUREC_UCS_BOM_HEADER_SIZE && \\\n    (((unsigned char)((s)[0]) == SECUREC_UCS_BOM_HEADER_LE_1ST && \\\n    (unsigned char)((s)[1]) == SECUREC_UCS_BOM_HEADER_LE_2ST) || \\\n    ((unsigned char)((s)[0]) == SECUREC_UCS_BOM_HEADER_BE_1ST && \\\n    (unsigned char)((s)[1]) == SECUREC_UCS_BOM_HEADER_BE_2ST)))\n\n#define SECUREC_BEGIN_WITH_UTF8_BOM(s, len) ((len) == SECUREC_UTF8_BOM_HEADER_SIZE && \\\n    (unsigned char)((s)[0]) == SECUREC_UTF8_BOM_HEADER_1ST && \\\n    (unsigned char)((s)[1]) == SECUREC_UTF8_BOM_HEADER_2ND && \\\n    (unsigned char)((s)[2]) == SECUREC_UTF8_BOM_HEADER_3RD)\n\n#ifdef SECUREC_FOR_WCHAR\n#define SECUREC_BOM_HEADER_SIZE SECUREC_UCS_BOM_HEADER_SIZE\n#define SECUREC_BEGIN_WITH_BOM(s, len) SECUREC_BEGIN_WITH_UCS_BOM((s), (len))\n#else\n#define SECUREC_BOM_HEADER_SIZE SECUREC_UTF8_BOM_HEADER_SIZE\n#define SECUREC_BEGIN_WITH_BOM(s, len) SECUREC_BEGIN_WITH_UTF8_BOM((s), (len))\n#endif\n\ntypedef struct {\n    unsigned int flag;          /* Mark the properties of input stream */\n    char *base;                 /* The pointer to the header of buffered string */\n    const char *cur;            /* The pointer to next read position */\n    size_t count;               /* The size of buffered string in bytes */\n#if SECUREC_ENABLE_SCANF_FILE\n    FILE *pf;                   /* The file pointer */\n    size_t fileRealRead;\n    long oriFilePos;            /* The original position of file offset when fscanf is called */\n#endif\n} SecFileStream;\n\n#if SECUREC_ENABLE_SCANF_FILE\n#define SECUREC_FILE_STREAM_INIT_FILE(stream, fp) do { \\\n    (stream)->pf = (fp); \\\n    (stream)->fileRealRead = 0; \\\n    (stream)->oriFilePos = 0; \\\n} SECUREC_WHILE_ZERO\n#else\n/* Disable file */\n#define SECUREC_FILE_STREAM_INIT_FILE(stream, fp)\n#endif\n\n/* This initialization for eliminating redundant initialization. */\n#define SECUREC_FILE_STREAM_FROM_STRING(stream, buf, cnt) do { \\\n    (stream)->flag = SECUREC_MEM_STR_FLAG; \\\n    (stream)->base = NULL; \\\n    (stream)->cur = (buf); \\\n    (stream)->count = (cnt); \\\n    SECUREC_FILE_STREAM_INIT_FILE((stream), NULL); \\\n} SECUREC_WHILE_ZERO\n\n/* This initialization for eliminating redundant initialization. */\n#define SECUREC_FILE_STREAM_FROM_FILE(stream, fp) do { \\\n    (stream)->flag = SECUREC_FILE_STREAM_FLAG; \\\n    (stream)->base = NULL; \\\n    (stream)->cur = NULL; \\\n    (stream)->count = 0; \\\n    SECUREC_FILE_STREAM_INIT_FILE((stream), (fp)); \\\n} SECUREC_WHILE_ZERO\n\n/* This initialization for eliminating redundant initialization. */\n#define SECUREC_FILE_STREAM_FROM_STDIN(stream) do { \\\n    (stream)->flag = SECUREC_PIPE_STREAM_FLAG; \\\n    (stream)->base = NULL; \\\n    (stream)->cur = NULL; \\\n    (stream)->count = 0; \\\n    SECUREC_FILE_STREAM_INIT_FILE((stream), SECUREC_STREAM_STDIN); \\\n} SECUREC_WHILE_ZERO\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\nint SecInputS(SecFileStream *stream, const char *cFormat, va_list argList);\nvoid SecClearDestBuf(const char *buffer, const char *format, va_list argList);\n#ifdef SECUREC_FOR_WCHAR\nint SecInputSW(SecFileStream *stream, const wchar_t *cFormat, va_list argList);\nvoid SecClearDestBufW(const wchar_t *buffer, const wchar_t *format, va_list argList);\n#endif\n\n/* 20150105 For software and hardware decoupling,such as UMG */\n#ifdef SECUREC_SYSAPI4VXWORKS\n#ifdef feof\n#undef feof\n#endif\nextern int feof(FILE *stream);\n#endif\n\n#if defined(SECUREC_SYSAPI4VXWORKS) || defined(SECUREC_CTYPE_MACRO_ADAPT)\n#ifndef isspace\n#define isspace(c) (((c) == ' ') || ((c) == '\\t') || ((c) == '\\r') || ((c) == '\\n'))\n#endif\n#ifndef iswspace\n#define iswspace(c) (((c) == L' ') || ((c) == L'\\t') || ((c) == L'\\r') || ((c) == L'\\n'))\n#endif\n#ifndef isascii\n#define isascii(c) (((unsigned char)(c)) <= 0x7f)\n#endif\n#ifndef isupper\n#define isupper(c) ((c) >= 'A' && (c) <= 'Z')\n#endif\n#ifndef islower\n#define islower(c) ((c) >= 'a' && (c) <= 'z')\n#endif\n#ifndef isalpha\n#define isalpha(c) (isupper(c) || (islower(c)))\n#endif\n#ifndef isdigit\n#define isdigit(c) ((c) >= '0' && (c) <= '9')\n#endif\n#ifndef isxupper\n#define isxupper(c) ((c) >= 'A' && (c) <= 'F')\n#endif\n#ifndef isxlower\n#define isxlower(c) ((c) >= 'a' && (c) <= 'f')\n#endif\n#ifndef isxdigit\n#define isxdigit(c) (isdigit(c) || isxupper(c) || isxlower(c))\n#endif\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n/* Reserved file operation macro interface, s is FILE *, i is fileno zero. */\n#ifndef SECUREC_LOCK_FILE\n#define SECUREC_LOCK_FILE(s)\n#endif\n\n#ifndef SECUREC_UNLOCK_FILE\n#define SECUREC_UNLOCK_FILE(s)\n#endif\n\n#ifndef SECUREC_LOCK_STDIN\n#define SECUREC_LOCK_STDIN(i, s)\n#endif\n\n#ifndef SECUREC_UNLOCK_STDIN\n#define SECUREC_UNLOCK_STDIN(i, s)\n#endif\n#endif\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/securecutil.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: Provides internal functions used by this library, such as memory\n *              copy and memory move. Besides, include some helper function for\n *              printf family API, such as SecVsnprintfImpl\n * Create: 2014-02-25\n */\n\n/* Avoid duplicate header files,not include securecutil.h */\n#include \"securecutil.h\"\n\n#if defined(ANDROID) && !defined(SECUREC_CLOSE_ANDROID_HANDLE) && (SECUREC_HAVE_WCTOMB || SECUREC_HAVE_MBTOWC)\n#include <wchar.h>\n#if SECUREC_HAVE_WCTOMB\n/*\n * Convert wide characters to narrow multi-bytes\n */\nint wctomb(char *s, wchar_t wc)\n{\n    return (int)wcrtomb(s, wc, NULL);\n}\n#endif\n\n#if SECUREC_HAVE_MBTOWC\n/*\n * Converting narrow multi-byte characters to wide characters\n * mbrtowc returns -1 or -2 upon failure, unlike mbtowc, which only returns -1\n * When the return value is less than zero, we treat it as a failure\n */\nint mbtowc(wchar_t *pwc, const char *s, size_t n)\n{\n    return (int)mbrtowc(pwc, s, n, NULL);\n}\n#endif\n#endif\n\n/* The V100R001C01 version num is 0x5 (High 8 bits) */\n#define SECUREC_C_VERSION     0x500U\n#define SECUREC_SPC_VERSION   0x10U\n#define SECUREC_VERSION_STR   \"1.1.16\"\n\n/*\n * Get version string and version number.\n * The rules for version number are as follows:\n * 1) SPC verNumber<->verStr like:\n * 0x201<->C01\n * 0x202<->C01SPC001   Redefine numbers after this version\n * 0x502<->C01SPC002\n * 0x503<->C01SPC003\n * ...\n * 0X50a<->SPC010\n * 0X50b<->SPC011\n * ...\n * 0x700<->C02\n * 0x701<->C01SPC001\n * 0x702<->C02SPC002\n * ...\n * 2) CP verNumber<->verStr like:\n * 0X601<->CP0001\n * 0X602<->CP0002\n * ...\n */\nconst char *GetHwSecureCVersion(unsigned short *verNumber)\n{\n    if (verNumber != NULL) {\n        *verNumber = (unsigned short)(SECUREC_C_VERSION | SECUREC_SPC_VERSION);\n    }\n    return SECUREC_VERSION_STR;\n}\n#if SECUREC_EXPORT_KERNEL_SYMBOL\nEXPORT_SYMBOL(GetHwSecureCVersion);\n#endif\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/securecutil.h",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: Define macro, data struct, and declare internal used function prototype,\n *              which is used by secure functions.\n * Create: 2014-02-25\n */\n\n#ifndef SECURECUTIL_H_46C86578_F8FF_4E49_8E64_9B175241761F\n#define SECURECUTIL_H_46C86578_F8FF_4E49_8E64_9B175241761F\n#include \"securec.h\"\n\n#if (defined(_MSC_VER)) && (_MSC_VER >= 1400)\n/* Shield compilation alerts using discarded functions and Constant  expression to maximize code compatibility */\n#define SECUREC_MASK_MSVC_CRT_WARNING __pragma(warning(push)) \\\n    __pragma(warning(disable : 4996 4127))\n#define SECUREC_END_MASK_MSVC_CRT_WARNING  __pragma(warning(pop))\n#else\n#define SECUREC_MASK_MSVC_CRT_WARNING\n#define SECUREC_END_MASK_MSVC_CRT_WARNING\n#endif\n#define SECUREC_WHILE_ZERO SECUREC_MASK_MSVC_CRT_WARNING while (0) SECUREC_END_MASK_MSVC_CRT_WARNING\n\n/* Automatically identify the platform that supports strnlen function, and use this function to improve performance */\n#ifndef SECUREC_HAVE_STRNLEN\n#if (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 700) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200809L)\n#if SECUREC_IN_KERNEL\n#define SECUREC_HAVE_STRNLEN 0\n#else\n#if defined(__GLIBC__) && __GLIBC__ >= 2 && defined(__GLIBC_MINOR__) && __GLIBC_MINOR__ >= 10\n#define SECUREC_HAVE_STRNLEN 1\n#else\n#define SECUREC_HAVE_STRNLEN 0\n#endif\n#endif\n#else\n#define SECUREC_HAVE_STRNLEN 0\n#endif\n#endif\n\n#if SECUREC_IN_KERNEL\n/* In kernel disable functions */\n#ifndef SECUREC_ENABLE_SCANF_FILE\n#define SECUREC_ENABLE_SCANF_FILE 0\n#endif\n#ifndef SECUREC_ENABLE_SCANF_FLOAT\n#define SECUREC_ENABLE_SCANF_FLOAT 0\n#endif\n#ifndef SECUREC_ENABLE_SPRINTF_FLOAT\n#define SECUREC_ENABLE_SPRINTF_FLOAT 0\n#endif\n#ifndef SECUREC_HAVE_MBTOWC\n#define SECUREC_HAVE_MBTOWC 0\n#endif\n#ifndef SECUREC_HAVE_WCTOMB\n#define SECUREC_HAVE_WCTOMB 0\n#endif\n#ifndef SECUREC_HAVE_WCHART\n#define SECUREC_HAVE_WCHART 0\n#endif\n#else /* Not in kernel */\n/* Systems that do not support file, can define this macro to 0. */\n#ifndef SECUREC_ENABLE_SCANF_FILE\n#define SECUREC_ENABLE_SCANF_FILE 1\n#endif\n#ifndef SECUREC_ENABLE_SCANF_FLOAT\n#define SECUREC_ENABLE_SCANF_FLOAT 1\n#endif\n/* Systems that do not support float, can define this macro to 0. */\n#ifndef SECUREC_ENABLE_SPRINTF_FLOAT\n#define SECUREC_ENABLE_SPRINTF_FLOAT 1\n#endif\n#ifndef SECUREC_HAVE_MBTOWC\n#define SECUREC_HAVE_MBTOWC 1\n#endif\n#ifndef SECUREC_HAVE_WCTOMB\n#define SECUREC_HAVE_WCTOMB 1\n#endif\n#ifndef SECUREC_HAVE_WCHART\n#define SECUREC_HAVE_WCHART 1\n#endif\n#endif\n\n#ifndef SECUREC_ENABLE_INLINE\n#define SECUREC_ENABLE_INLINE 0\n#endif\n\n#ifndef SECUREC_INLINE\n#if SECUREC_ENABLE_INLINE\n#define SECUREC_INLINE static inline\n#else\n#define SECUREC_INLINE static\n#endif\n#endif\n\n#ifndef SECUREC_WARP_OUTPUT\n#if SECUREC_IN_KERNEL\n#define SECUREC_WARP_OUTPUT 1\n#else\n#define SECUREC_WARP_OUTPUT 0\n#endif\n#endif\n\n#ifndef SECUREC_STREAM_STDIN\n#define SECUREC_STREAM_STDIN stdin\n#endif\n\n#define SECUREC_MUL_SIXTEEN(x)              ((x) << 4U)\n#define SECUREC_MUL_EIGHT(x)                ((x) << 3U)\n#define SECUREC_MUL_TEN(x)                  ((((x) << 2U) + (x)) << 1U)\n/* Limited format input and output width, use signed integer */\n#define SECUREC_MAX_WIDTH_LEN_DIV_TEN       21474836\n#define SECUREC_MAX_WIDTH_LEN               (SECUREC_MAX_WIDTH_LEN_DIV_TEN * 10)\n/* Is the x multiplied by 10 greater than */\n#define SECUREC_MUL_TEN_ADD_BEYOND_MAX(x)   (((x) > SECUREC_MAX_WIDTH_LEN_DIV_TEN))\n\n#define SECUREC_FLOAT_BUFSIZE               (309 + 40)  /* Max length of double value */\n#define SECUREC_FLOAT_BUFSIZE_LB            (4932 + 40) /* Max length of long double value */\n#define SECUREC_FLOAT_DEFAULT_PRECISION     6\n\n/* This macro does not handle pointer equality or integer overflow */\n#define SECUREC_MEMORY_NO_OVERLAP(dest, src, count) \\\n    (((src) < (dest) && ((const char *)(src) + (count)) <= (char *)(dest)) || \\\n    ((dest) < (src) && ((char *)(dest) + (count)) <= (const char *)(src)))\n\n#define SECUREC_MEMORY_IS_OVERLAP(dest, src, count) \\\n    (((src) < (dest) && ((const char *)(src) + (count)) > (char *)(dest)) || \\\n    ((dest) < (src) && ((char *)(dest) + (count)) > (const char *)(src)))\n\n/*\n * Check whether the strings overlap, len is the length of the string not include terminator\n * Length is related to data type char or wchar , do not force conversion of types\n */\n#define SECUREC_STRING_NO_OVERLAP(dest, src, len) \\\n    (((src) < (dest) && ((src) + (len)) < (dest)) || \\\n    ((dest) < (src) && ((dest) + (len)) < (src)))\n\n/*\n * Check whether the strings overlap for strcpy wcscpy function, dest len and src Len are not include terminator\n * Length is related to data type char or wchar , do not force conversion of types\n */\n#define SECUREC_STRING_IS_OVERLAP(dest, src, len) \\\n    (((src) < (dest) && ((src) + (len)) >= (dest)) || \\\n    ((dest) < (src) && ((dest) + (len)) >= (src)))\n\n/*\n * Check whether the strings overlap for strcat wcscat function, dest len and src Len are not include terminator\n * Length is related to data type char or wchar , do not force conversion of types\n */\n#define SECUREC_CAT_STRING_IS_OVERLAP(dest, destLen, src, srcLen) \\\n    (((dest) < (src) && ((dest) + (destLen) + (srcLen)) >= (src)) || \\\n    ((src) < (dest) && ((src) + (srcLen)) >= (dest)))\n\n#if SECUREC_HAVE_STRNLEN\n#define SECUREC_CALC_STR_LEN(str, maxLen, outLen) do { \\\n    *(outLen) = strnlen((str), (maxLen)); \\\n} SECUREC_WHILE_ZERO\n#define SECUREC_CALC_STR_LEN_OPT(str, maxLen, outLen) do { \\\n    if ((maxLen) > 8) { \\\n        /* Optimization or len less then 8 */ \\\n        if (*((str) + 0) == '\\0') { \\\n            *(outLen) = 0; \\\n        } else if (*((str) + 1) == '\\0') { \\\n            *(outLen) = 1; \\\n        } else if (*((str) + 2) == '\\0') { \\\n            *(outLen) = 2; \\\n        } else if (*((str) + 3) == '\\0') { \\\n            *(outLen) = 3; \\\n        } else if (*((str) + 4) == '\\0') { \\\n            *(outLen) = 4; \\\n        } else if (*((str) + 5) == '\\0') { \\\n            *(outLen) = 5; \\\n        } else if (*((str) + 6) == '\\0') { \\\n            *(outLen) = 6; \\\n        } else if (*((str) + 7) == '\\0') { \\\n            *(outLen) = 7; \\\n        } else if (*((str) + 8) == '\\0') { \\\n            /* Optimization with a length of 8 */ \\\n            *(outLen) = 8; \\\n        } else { \\\n            /* The offset is 8 because the performance of 8 byte alignment is high */ \\\n            *(outLen) = 8 + strnlen((str) + 8, (maxLen) - 8); \\\n        } \\\n    } else { \\\n        SECUREC_CALC_STR_LEN((str), (maxLen), (outLen)); \\\n    } \\\n} SECUREC_WHILE_ZERO\n#else\n#define SECUREC_CALC_STR_LEN(str, maxLen, outLen) do { \\\n    const char *strEnd_ = (const char *)(str); \\\n    size_t availableSize_ = (size_t)(maxLen); \\\n    while (availableSize_ > 0 && *strEnd_ != '\\0') { \\\n        --availableSize_; \\\n        ++strEnd_; \\\n    } \\\n    *(outLen) = (size_t)(strEnd_ - (str)); \\\n} SECUREC_WHILE_ZERO\n#define SECUREC_CALC_STR_LEN_OPT SECUREC_CALC_STR_LEN\n#endif\n\n#define SECUREC_CALC_WSTR_LEN(str, maxLen, outLen) do { \\\n    const wchar_t *strEnd_ = (const wchar_t *)(str); \\\n    size_t len_ = 0; \\\n    while (len_ < (maxLen) && *strEnd_ != L'\\0') { \\\n        ++len_; \\\n        ++strEnd_; \\\n    } \\\n    *(outLen) = len_; \\\n} SECUREC_WHILE_ZERO\n\n/*\n * Performance optimization, product may disable inline function.\n * Using function pointer for MEMSET to prevent compiler optimization when cleaning up memory.\n */\n#ifdef SECUREC_USE_ASM\n#define SECUREC_MEMSET_FUNC_OPT  memset_opt\n#define SECUREC_MEMCPY_FUNC_OPT  memcpy_opt\n#else\n#define SECUREC_MEMSET_FUNC_OPT  memset\n#define SECUREC_MEMCPY_FUNC_OPT  memcpy\n#endif\n\n#define SECUREC_MEMCPY_WARP_OPT(dest, src, count)    (void)SECUREC_MEMCPY_FUNC_OPT((dest), (src), (count))\n\n#ifndef SECUREC_MEMSET_BARRIER\n#if defined(__GNUC__)\n/* Can be turned off for scenarios that do not use memory barrier */\n#define SECUREC_MEMSET_BARRIER 1\n#else\n#define SECUREC_MEMSET_BARRIER 0\n#endif\n#endif\n\n#ifndef SECUREC_MEMSET_INDIRECT_USE\n/* Can be turned off for scenarios that do not allow pointer calls */\n#define SECUREC_MEMSET_INDIRECT_USE 1\n#endif\n\n#if SECUREC_MEMSET_BARRIER\n#define SECUREC_MEMORY_BARRIER(dest) __asm__ __volatile__(\"\": : \"r\"(dest) : \"memory\")\n#else\n#define SECUREC_MEMORY_BARRIER(dest)\n#endif\n\n#if SECUREC_MEMSET_BARRIER\n#define SECUREC_MEMSET_PREVENT_DSE(dest, value, count)  do { \\\n        (void)SECUREC_MEMSET_FUNC_OPT(dest, value, count); \\\n        SECUREC_MEMORY_BARRIER(dest); \\\n} SECUREC_WHILE_ZERO\n#elif SECUREC_MEMSET_INDIRECT_USE\n#define SECUREC_MEMSET_PREVENT_DSE(dest, value, count)  do { \\\n    void *(* const volatile fn_)(void *s_, int c_, size_t n_) = SECUREC_MEMSET_FUNC_OPT; \\\n    (void)(*fn_)((dest), (value), (count)); \\\n} SECUREC_WHILE_ZERO\n#else\n#define SECUREC_MEMSET_PREVENT_DSE(dest, value, count)  (void)SECUREC_MEMSET_FUNC_OPT((dest), (value), (count))\n#endif\n\n#ifdef SECUREC_FORMAT_OUTPUT_INPUT\n#if defined(SECUREC_COMPATIBLE_WIN_FORMAT) || defined(__ARMCC_VERSION)\ntypedef __int64 SecInt64;\ntypedef unsigned __int64 SecUnsignedInt64;\n#if defined(__ARMCC_VERSION)\ntypedef unsigned int SecUnsignedInt32;\n#else\ntypedef unsigned __int32 SecUnsignedInt32;\n#endif\n#else\ntypedef unsigned int SecUnsignedInt32;\ntypedef long long SecInt64;\ntypedef unsigned long long SecUnsignedInt64;\n#endif\n\n#ifdef SECUREC_FOR_WCHAR\n#if defined(SECUREC_VXWORKS_PLATFORM) && !defined(__WINT_TYPE__)\ntypedef wchar_t wint_t;\n#endif\n#ifndef WEOF\n#define WEOF ((wchar_t)(-1))\n#endif\n#define SECUREC_CHAR(x) L ## x\ntypedef wchar_t SecChar;\ntypedef wchar_t SecUnsignedChar;\ntypedef wint_t SecInt;\ntypedef wint_t SecUnsignedInt;\n#else /*  no SECUREC_FOR_WCHAR */\n#define SECUREC_CHAR(x) (x)\ntypedef char SecChar;\ntypedef unsigned char SecUnsignedChar;\ntypedef int SecInt;\ntypedef unsigned int SecUnsignedInt;\n#endif\n#endif\n\n/*\n * Determine whether the address is 8-byte aligned\n * Some systems do not have uintptr_t type, so  use NULL to clear tool alarm 507\n */\n#define SECUREC_ADDR_ALIGNED_8(addr) ((((size_t)(addr)) & 7U) == 0) /* Use 7 to check aligned 8 */\n\n/*\n * If you define the memory allocation function, you need to define the function prototype.\n * You can define this macro as a header file.\n */\n#if defined(SECUREC_MALLOC_PROTOTYPE)\nSECUREC_MALLOC_PROTOTYPE\n#endif\n\n#ifndef SECUREC_MALLOC\n#define SECUREC_MALLOC(x) malloc((size_t)(x))\n#endif\n\n#ifndef SECUREC_FREE\n#define SECUREC_FREE(x)   free((void *)(x))\n#endif\n\n/* Improve performance with struct assignment, buf1 is not defined to avoid tool false positive */\n#define SECUREC_COPY_VALUE_BY_STRUCT(dest, src, n) do { \\\n    *(SecStrBuf##n *)(void *)(dest) = *(const SecStrBuf##n *)(const void *)(src); \\\n} SECUREC_WHILE_ZERO\n\ntypedef struct {\n    unsigned char buf[2]; /* Performance optimization code structure assignment length 2 bytes */\n} SecStrBuf2;\ntypedef struct {\n    unsigned char buf[3]; /* Performance optimization code structure assignment length 3 bytes */\n} SecStrBuf3;\ntypedef struct {\n    unsigned char buf[4]; /* Performance optimization code structure assignment length 4 bytes */\n} SecStrBuf4;\ntypedef struct {\n    unsigned char buf[5]; /* Performance optimization code structure assignment length 5 bytes */\n} SecStrBuf5;\ntypedef struct {\n    unsigned char buf[6]; /* Performance optimization code structure assignment length 6 bytes */\n} SecStrBuf6;\ntypedef struct {\n    unsigned char buf[7]; /* Performance optimization code structure assignment length 7 bytes */\n} SecStrBuf7;\ntypedef struct {\n    unsigned char buf[8]; /* Performance optimization code structure assignment length 8 bytes */\n} SecStrBuf8;\ntypedef struct {\n    unsigned char buf[9]; /* Performance optimization code structure assignment length 9 bytes */\n} SecStrBuf9;\ntypedef struct {\n    unsigned char buf[10]; /* Performance optimization code structure assignment length 10 bytes */\n} SecStrBuf10;\ntypedef struct {\n    unsigned char buf[11]; /* Performance optimization code structure assignment length 11 bytes */\n} SecStrBuf11;\ntypedef struct {\n    unsigned char buf[12]; /* Performance optimization code structure assignment length 12 bytes */\n} SecStrBuf12;\ntypedef struct {\n    unsigned char buf[13]; /* Performance optimization code structure assignment length 13 bytes */\n} SecStrBuf13;\ntypedef struct {\n    unsigned char buf[14]; /* Performance optimization code structure assignment length 14 bytes */\n} SecStrBuf14;\ntypedef struct {\n    unsigned char buf[15]; /* Performance optimization code structure assignment length 15 bytes */\n} SecStrBuf15;\ntypedef struct {\n    unsigned char buf[16]; /* Performance optimization code structure assignment length 16 bytes */\n} SecStrBuf16;\ntypedef struct {\n    unsigned char buf[17]; /* Performance optimization code structure assignment length 17 bytes */\n} SecStrBuf17;\ntypedef struct {\n    unsigned char buf[18]; /* Performance optimization code structure assignment length 18 bytes */\n} SecStrBuf18;\ntypedef struct {\n    unsigned char buf[19]; /* Performance optimization code structure assignment length 19 bytes */\n} SecStrBuf19;\ntypedef struct {\n    unsigned char buf[20]; /* Performance optimization code structure assignment length 20 bytes */\n} SecStrBuf20;\ntypedef struct {\n    unsigned char buf[21]; /* Performance optimization code structure assignment length 21 bytes */\n} SecStrBuf21;\ntypedef struct {\n    unsigned char buf[22]; /* Performance optimization code structure assignment length 22 bytes */\n} SecStrBuf22;\ntypedef struct {\n    unsigned char buf[23]; /* Performance optimization code structure assignment length 23 bytes */\n} SecStrBuf23;\ntypedef struct {\n    unsigned char buf[24]; /* Performance optimization code structure assignment length 24 bytes */\n} SecStrBuf24;\ntypedef struct {\n    unsigned char buf[25]; /* Performance optimization code structure assignment length 25 bytes */\n} SecStrBuf25;\ntypedef struct {\n    unsigned char buf[26]; /* Performance optimization code structure assignment length 26 bytes */\n} SecStrBuf26;\ntypedef struct {\n    unsigned char buf[27]; /* Performance optimization code structure assignment length 27 bytes */\n} SecStrBuf27;\ntypedef struct {\n    unsigned char buf[28]; /* Performance optimization code structure assignment length 28 bytes */\n} SecStrBuf28;\ntypedef struct {\n    unsigned char buf[29]; /* Performance optimization code structure assignment length 29 bytes */\n} SecStrBuf29;\ntypedef struct {\n    unsigned char buf[30]; /* Performance optimization code structure assignment length 30 bytes */\n} SecStrBuf30;\ntypedef struct {\n    unsigned char buf[31]; /* Performance optimization code structure assignment length 31 bytes */\n} SecStrBuf31;\ntypedef struct {\n    unsigned char buf[32]; /* Performance optimization code structure assignment length 32 bytes */\n} SecStrBuf32;\ntypedef struct {\n    unsigned char buf[33]; /* Performance optimization code structure assignment length 33 bytes */\n} SecStrBuf33;\ntypedef struct {\n    unsigned char buf[34]; /* Performance optimization code structure assignment length 34 bytes */\n} SecStrBuf34;\ntypedef struct {\n    unsigned char buf[35]; /* Performance optimization code structure assignment length 35 bytes */\n} SecStrBuf35;\ntypedef struct {\n    unsigned char buf[36]; /* Performance optimization code structure assignment length 36 bytes */\n} SecStrBuf36;\ntypedef struct {\n    unsigned char buf[37]; /* Performance optimization code structure assignment length 37 bytes */\n} SecStrBuf37;\ntypedef struct {\n    unsigned char buf[38]; /* Performance optimization code structure assignment length 38 bytes */\n} SecStrBuf38;\ntypedef struct {\n    unsigned char buf[39]; /* Performance optimization code structure assignment length 39 bytes */\n} SecStrBuf39;\ntypedef struct {\n    unsigned char buf[40]; /* Performance optimization code structure assignment length 40 bytes */\n} SecStrBuf40;\ntypedef struct {\n    unsigned char buf[41]; /* Performance optimization code structure assignment length 41 bytes */\n} SecStrBuf41;\ntypedef struct {\n    unsigned char buf[42]; /* Performance optimization code structure assignment length 42 bytes */\n} SecStrBuf42;\ntypedef struct {\n    unsigned char buf[43]; /* Performance optimization code structure assignment length 43 bytes */\n} SecStrBuf43;\ntypedef struct {\n    unsigned char buf[44]; /* Performance optimization code structure assignment length 44 bytes */\n} SecStrBuf44;\ntypedef struct {\n    unsigned char buf[45]; /* Performance optimization code structure assignment length 45 bytes */\n} SecStrBuf45;\ntypedef struct {\n    unsigned char buf[46]; /* Performance optimization code structure assignment length 46 bytes */\n} SecStrBuf46;\ntypedef struct {\n    unsigned char buf[47]; /* Performance optimization code structure assignment length 47 bytes */\n} SecStrBuf47;\ntypedef struct {\n    unsigned char buf[48]; /* Performance optimization code structure assignment length 48 bytes */\n} SecStrBuf48;\ntypedef struct {\n    unsigned char buf[49]; /* Performance optimization code structure assignment length 49 bytes */\n} SecStrBuf49;\ntypedef struct {\n    unsigned char buf[50]; /* Performance optimization code structure assignment length 50 bytes */\n} SecStrBuf50;\ntypedef struct {\n    unsigned char buf[51]; /* Performance optimization code structure assignment length 51 bytes */\n} SecStrBuf51;\ntypedef struct {\n    unsigned char buf[52]; /* Performance optimization code structure assignment length 52 bytes */\n} SecStrBuf52;\ntypedef struct {\n    unsigned char buf[53]; /* Performance optimization code structure assignment length 53 bytes */\n} SecStrBuf53;\ntypedef struct {\n    unsigned char buf[54]; /* Performance optimization code structure assignment length 54 bytes */\n} SecStrBuf54;\ntypedef struct {\n    unsigned char buf[55]; /* Performance optimization code structure assignment length 55 bytes */\n} SecStrBuf55;\ntypedef struct {\n    unsigned char buf[56]; /* Performance optimization code structure assignment length 56 bytes */\n} SecStrBuf56;\ntypedef struct {\n    unsigned char buf[57]; /* Performance optimization code structure assignment length 57 bytes */\n} SecStrBuf57;\ntypedef struct {\n    unsigned char buf[58]; /* Performance optimization code structure assignment length 58 bytes */\n} SecStrBuf58;\ntypedef struct {\n    unsigned char buf[59]; /* Performance optimization code structure assignment length 59 bytes */\n} SecStrBuf59;\ntypedef struct {\n    unsigned char buf[60]; /* Performance optimization code structure assignment length 60 bytes */\n} SecStrBuf60;\ntypedef struct {\n    unsigned char buf[61]; /* Performance optimization code structure assignment length 61 bytes */\n} SecStrBuf61;\ntypedef struct {\n    unsigned char buf[62]; /* Performance optimization code structure assignment length 62 bytes */\n} SecStrBuf62;\ntypedef struct {\n    unsigned char buf[63]; /* Performance optimization code structure assignment length 63 bytes */\n} SecStrBuf63;\ntypedef struct {\n    unsigned char buf[64]; /* Performance optimization code structure assignment length 64 bytes */\n} SecStrBuf64;\n\n/*\n * User can change the error handler by modify the following definition,\n * such as logging the detail error in file.\n */\n#if defined(_DEBUG) || defined(DEBUG)\n#if defined(SECUREC_ERROR_HANDLER_BY_ASSERT)\n#define SECUREC_ERROR_INVALID_PARAMTER(msg) assert(msg \"invalid argument\" == NULL)\n#define SECUREC_ERROR_INVALID_RANGE(msg)    assert(msg \"invalid dest buffer size\" == NULL)\n#define SECUREC_ERROR_BUFFER_OVERLAP(msg)   assert(msg \"buffer overlap\" == NULL)\n#elif defined(SECUREC_ERROR_HANDLER_BY_PRINTF)\n#if SECUREC_IN_KERNEL\n#define SECUREC_ERROR_INVALID_PARAMTER(msg) printk(\"%s invalid argument\\n\", msg)\n#define SECUREC_ERROR_INVALID_RANGE(msg)    printk(\"%s invalid dest buffer size\\n\", msg)\n#define SECUREC_ERROR_BUFFER_OVERLAP(msg)   printk(\"%s buffer overlap\\n\", msg)\n#else\n#define SECUREC_ERROR_INVALID_PARAMTER(msg) printf(\"%s invalid argument\\n\", msg)\n#define SECUREC_ERROR_INVALID_RANGE(msg)    printf(\"%s invalid dest buffer size\\n\", msg)\n#define SECUREC_ERROR_BUFFER_OVERLAP(msg)   printf(\"%s buffer overlap\\n\", msg)\n#endif\n#elif defined(SECUREC_ERROR_HANDLER_BY_FILE_LOG)\n#define SECUREC_ERROR_INVALID_PARAMTER(msg) LogSecureCRuntimeError(msg \" EINVAL\\n\")\n#define SECUREC_ERROR_INVALID_RANGE(msg)    LogSecureCRuntimeError(msg \" ERANGE\\n\")\n#define SECUREC_ERROR_BUFFER_OVERLAP(msg)   LogSecureCRuntimeError(msg \" EOVERLAP\\n\")\n#endif\n#endif\n\n/* Default handler is none */\n#ifndef SECUREC_ERROR_INVALID_PARAMTER\n#define SECUREC_ERROR_INVALID_PARAMTER(msg)\n#endif\n#ifndef SECUREC_ERROR_INVALID_RANGE\n#define SECUREC_ERROR_INVALID_RANGE(msg)\n#endif\n#ifndef SECUREC_ERROR_BUFFER_OVERLAP\n#define SECUREC_ERROR_BUFFER_OVERLAP(msg)\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* Assembly language memory copy and memory set for X86 or MIPS ... */\n#ifdef SECUREC_USE_ASM\nvoid *memcpy_opt(void *dest, const void *src, size_t n);\nvoid *memset_opt(void *s, int c, size_t n);\n#endif\n\n#if defined(SECUREC_ERROR_HANDLER_BY_FILE_LOG)\nvoid LogSecureCRuntimeError(const char *errDetail);\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n#endif\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/secureinput_a.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: By defining data type for ANSI string and including \"input.inl\",\n *              this file generates real underlying function used by scanf family API.\n * Create: 2014-02-25\n */\n\n#define SECUREC_FORMAT_OUTPUT_INPUT 1\n#ifdef SECUREC_FOR_WCHAR\n#undef SECUREC_FOR_WCHAR\n#endif\n\n#include \"secinput.h\"\n\n#include \"input.inl\"\n\nSECUREC_INLINE int SecIsDigit(SecInt ch)\n{\n    /* SecInt to unsigned char clear  571, use bit mask to clear negative return of ch */\n    return isdigit((int)((unsigned int)(unsigned char)(ch) & 0xffU));\n}\nSECUREC_INLINE int SecIsXdigit(SecInt ch)\n{\n    return isxdigit((int)((unsigned int)(unsigned char)(ch) & 0xffU));\n}\nSECUREC_INLINE int SecIsSpace(SecInt ch)\n{\n    return isspace((int)((unsigned int)(unsigned char)(ch) & 0xffU));\n}\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/secureinput_w.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: By defining data type for UNICODE string and including \"input.inl\",\n *             this file generates real underlying function used by scanf family API.\n * Create: 2014-02-25\n */\n\n/* If some platforms don't have wchar.h, don't include it */\n#if !(defined(SECUREC_VXWORKS_PLATFORM))\n/* If there is no macro below, it will cause vs2010 compiling alarm */\n#if defined(_MSC_VER) && (_MSC_VER >= 1400)\n#ifndef __STDC_WANT_SECURE_LIB__\n/* The order of adjustment is to eliminate alarm of Duplicate Block */\n#define __STDC_WANT_SECURE_LIB__ 0\n#endif\n#ifndef _CRTIMP_ALTERNATIVE\n#define _CRTIMP_ALTERNATIVE     /* Comment microsoft *_s function */\n#endif\n#endif\n#include <wchar.h>\n#endif\n\n/* fix redefined */\n#undef SECUREC_ENABLE_WCHAR_FUNC\n/* Disable wchar func to clear vs warning */\n#define SECUREC_ENABLE_WCHAR_FUNC       0\n#define SECUREC_FORMAT_OUTPUT_INPUT     1\n\n#ifndef SECUREC_FOR_WCHAR\n#define SECUREC_FOR_WCHAR\n#endif\n\n#include \"secinput.h\"\n\n#include \"input.inl\"\n\nSECUREC_INLINE unsigned int SecWcharHighBits(SecInt ch)\n{\n    /* Convert int to unsigned int clear 571 */\n    return ((unsigned int)(int)ch & (~0xffU));\n}\n\nSECUREC_INLINE unsigned char SecWcharLowByte(SecInt ch)\n{\n    /* Convert int to unsigned int clear 571 */\n    return (unsigned char)((unsigned int)(int)ch & 0xffU);\n}\n\nSECUREC_INLINE int SecIsDigit(SecInt ch)\n{\n    if (SecWcharHighBits(ch) != 0) {\n        return 0; /* Same as isdigit */\n    }\n    return isdigit((int)SecWcharLowByte(ch));\n}\n\nSECUREC_INLINE int SecIsXdigit(SecInt ch)\n{\n    if (SecWcharHighBits(ch) != 0) {\n        return 0; /* Same as isxdigit */\n    }\n    return isxdigit((int)SecWcharLowByte(ch));\n}\n\nSECUREC_INLINE int SecIsSpace(SecInt ch)\n{\n    return iswspace((wint_t)(int)(ch));\n}\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/secureprintoutput.h",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: Define macro, enum, data struct, and declare internal used function\n *              prototype, which is used by output.inl, secureprintoutput_w.c and\n *              secureprintoutput_a.c.\n * Create: 2014-02-25\n */\n\n#ifndef SECUREPRINTOUTPUT_H_E950DA2C_902F_4B15_BECD_948E99090D9C\n#define SECUREPRINTOUTPUT_H_E950DA2C_902F_4B15_BECD_948E99090D9C\n#include \"securecutil.h\"\n\n/* Shield compilation alerts about using sprintf without format attribute to format float value. */\n#ifndef SECUREC_HANDLE_WFORMAT\n#define SECUREC_HANDLE_WFORMAT 1\n#endif\n\n#if defined(__clang__)\n#if SECUREC_HANDLE_WFORMAT && defined(__GNUC__) && ((__GNUC__ >= 5) || \\\n    (defined(__GNUC_MINOR__) && (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)))\n#define SECUREC_MASK_WFORMAT_WARNING  _Pragma(\"GCC diagnostic push\") \\\n    _Pragma(\"GCC diagnostic ignored \\\"-Wformat-nonliteral\\\"\")\n#define SECUREC_END_MASK_WFORMAT_WARNING  _Pragma(\"GCC diagnostic pop\")\n#else\n#define SECUREC_MASK_WFORMAT_WARNING\n#define SECUREC_END_MASK_WFORMAT_WARNING\n#endif\n#else\n#if SECUREC_HANDLE_WFORMAT && defined(__GNUC__) && ((__GNUC__ >= 5 ) || \\\n    (defined(__GNUC_MINOR__) && (__GNUC__ == 4 && __GNUC_MINOR__ > 7)))\n#define SECUREC_MASK_WFORMAT_WARNING  _Pragma(\"GCC diagnostic push\") \\\n    _Pragma(\"GCC diagnostic ignored \\\"-Wformat-nonliteral\\\"\") \\\n    _Pragma(\"GCC diagnostic ignored \\\"-Wmissing-format-attribute\\\"\") \\\n    _Pragma(\"GCC diagnostic ignored \\\"-Wsuggest-attribute=format\\\"\")\n#define SECUREC_END_MASK_WFORMAT_WARNING  _Pragma(\"GCC diagnostic pop\")\n#else\n#define SECUREC_MASK_WFORMAT_WARNING\n#define SECUREC_END_MASK_WFORMAT_WARNING\n#endif\n#endif\n\n#define SECUREC_MASK_VSPRINTF_WARNING  SECUREC_MASK_WFORMAT_WARNING \\\n    SECUREC_MASK_MSVC_CRT_WARNING\n\n#define SECUREC_END_MASK_VSPRINTF_WARNING  SECUREC_END_MASK_WFORMAT_WARNING \\\n    SECUREC_END_MASK_MSVC_CRT_WARNING\n\n/*\n * Flag definitions.\n * Using macros instead of enumerations is because some of the enumerated types under the compiler are 16bit.\n */\n#define SECUREC_FLAG_SIGN           0x00001U\n#define SECUREC_FLAG_SIGN_SPACE     0x00002U\n#define SECUREC_FLAG_LEFT           0x00004U\n#define SECUREC_FLAG_LEADZERO       0x00008U\n#define SECUREC_FLAG_LONG           0x00010U\n#define SECUREC_FLAG_SHORT          0x00020U\n#define SECUREC_FLAG_SIGNED         0x00040U\n#define SECUREC_FLAG_ALTERNATE      0x00080U\n#define SECUREC_FLAG_NEGATIVE       0x00100U\n#define SECUREC_FLAG_FORCE_OCTAL    0x00200U\n#define SECUREC_FLAG_LONG_DOUBLE    0x00400U\n#define SECUREC_FLAG_WIDECHAR       0x00800U\n#define SECUREC_FLAG_LONGLONG       0x01000U\n#define SECUREC_FLAG_CHAR           0x02000U\n#define SECUREC_FLAG_POINTER        0x04000U\n#define SECUREC_FLAG_I64            0x08000U\n#define SECUREC_FLAG_PTRDIFF        0x10000U\n#define SECUREC_FLAG_SIZE           0x20000U\n#ifdef  SECUREC_COMPATIBLE_LINUX_FORMAT\n#define SECUREC_FLAG_INTMAX         0x40000U\n#endif\n\n/* State definitions. Identify the status of the current format */\ntypedef enum {\n    STAT_NORMAL,\n    STAT_PERCENT,\n    STAT_FLAG,\n    STAT_WIDTH,\n    STAT_DOT,\n    STAT_PRECIS,\n    STAT_SIZE,\n    STAT_TYPE,\n    STAT_INVALID\n} SecFmtState;\n\n#ifndef SECUREC_BUFFER_SIZE\n#if SECUREC_IN_KERNEL\n#define SECUREC_BUFFER_SIZE    32\n#elif defined(SECUREC_STACK_SIZE_LESS_THAN_1K)\n/*\n * SECUREC BUFFER SIZE Can not be less than 23\n * The length of the octal representation of 64-bit integers with zero lead\n */\n#define SECUREC_BUFFER_SIZE    256\n#else\n#define SECUREC_BUFFER_SIZE    512\n#endif\n#endif\n#if SECUREC_BUFFER_SIZE < 23\n#error SECUREC_BUFFER_SIZE Can not be less than 23\n#endif\n/* Buffer size for wchar, use 4 to make the compiler aligns as 8 bytes as possible */\n#define SECUREC_WCHAR_BUFFER_SIZE 4\n\n#define SECUREC_MAX_PRECISION  SECUREC_BUFFER_SIZE\n/* Max. # bytes in multibyte char,see MB_LEN_MAX */\n#define SECUREC_MB_LEN 16\n/* The return value of the internal function, which is returned when truncated */\n#define SECUREC_PRINTF_TRUNCATE (-2)\n\n#define SECUREC_VSPRINTF_PARAM_ERROR(format, strDest, destMax, maxLimit) \\\n    ((format) == NULL || (strDest) == NULL || (destMax) == 0 || (destMax) > (maxLimit))\n\n#define SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, maxLimit) do { \\\n    if ((strDest) != NULL && (destMax) > 0 && (destMax) <= (maxLimit)) { \\\n        *(strDest) = '\\0'; \\\n    } \\\n} SECUREC_WHILE_ZERO\n\n#ifdef SECUREC_COMPATIBLE_WIN_FORMAT\n#define SECUREC_VSNPRINTF_PARAM_ERROR(format, strDest, destMax, count, maxLimit) \\\n    (((format) == NULL || (strDest) == NULL || (destMax) == 0 || (destMax) > (maxLimit)) || \\\n    ((count) > (SECUREC_STRING_MAX_LEN - 1) && (count) != (size_t)(-1)))\n\n#else\n#define SECUREC_VSNPRINTF_PARAM_ERROR(format, strDest, destMax, count, maxLimit) \\\n    (((format) == NULL || (strDest) == NULL || (destMax) == 0 || (destMax) > (maxLimit)) || \\\n    ((count) > (SECUREC_STRING_MAX_LEN - 1)))\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n#ifdef SECUREC_FOR_WCHAR\nint SecVswprintfImpl(wchar_t *string, size_t count, const wchar_t *format, va_list argList);\n#else\nint SecVsnprintfImpl(char *string, size_t count, const char *format, va_list argList);\n#endif\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/secureprintoutput_a.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: By defining corresponding macro for ANSI string and including \"output.inl\",\n *              this file generates real underlying function used by printf family API.\n * Create: 2014-02-25\n */\n\n#define SECUREC_FORMAT_OUTPUT_INPUT 1\n\n#ifdef SECUREC_FOR_WCHAR\n#undef SECUREC_FOR_WCHAR\n#endif\n\n#include \"secureprintoutput.h\"\n#if SECUREC_WARP_OUTPUT\n#define SECUREC_FORMAT_FLAG_TABLE_SIZE 128\nSECUREC_INLINE const char *SecSkipKnownFlags(const char *format)\n{\n    static const unsigned char flagTable[SECUREC_FORMAT_FLAG_TABLE_SIZE] = {\n        /*\n         * Known flag is  \"0123456789 +-#hlLwZzjqt*I$\"\n         */\n        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n        0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00,\n        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,\n        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,\n        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,\n        0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00\n    };\n    const char *fmt = format;\n    while (*fmt != '\\0') {\n        char fmtChar = *fmt;\n        if ((unsigned char)fmtChar > 0x7f) { /* 0x7f is upper limit of format char value */\n            break;\n        }\n        if (flagTable[(unsigned char)fmtChar] == 0) {\n            break;\n        }\n        ++fmt;\n    }\n    return fmt;\n}\n\nSECUREC_INLINE int SecFormatContainN(const char *format)\n{\n    const char *fmt = format;\n    while (*fmt != '\\0') {\n        ++fmt;\n        /* Skip normal char */\n        if (*(fmt - 1) != '%') {\n            continue;\n        }\n        /* Meet %% */\n        if (*fmt == '%') {\n            ++fmt; /* Point to  the character after the %. Correct handling %%xx */\n            continue;\n        }\n        /* Now parse %..., fmt point to the character after the % */\n        fmt = SecSkipKnownFlags(fmt);\n        if (*fmt == 'n') {\n            return 1;\n        }\n    }\n    return 0;\n}\n/*\n * Multi character formatted output implementation, the count include \\0 character, must be greater than zero\n */\nint SecVsnprintfImpl(char *string, size_t count, const char *format, va_list argList)\n{\n    int retVal;\n    if (SecFormatContainN(format) != 0) {\n        string[0] = '\\0';\n        return -1;\n    }\n    SECUREC_MASK_VSPRINTF_WARNING\n    retVal = vsnprintf(string, count, format, argList);\n    SECUREC_END_MASK_VSPRINTF_WARNING\n    if (retVal >= (int)count) { /* The size_t to int is ok, count max is SECUREC_STRING_MAX_LEN */\n        /* The buffer was too small; we return truncation */\n        string[count - 1] = '\\0';\n        return SECUREC_PRINTF_TRUNCATE;\n    }\n    if (retVal < 0) {\n        string[0] = '\\0'; /* Empty the dest strDest */\n        return -1;\n    }\n    return retVal;\n}\n#else\n#if SECUREC_IN_KERNEL\n#include <linux/ctype.h>\n#endif\n\n#ifndef EOF\n#define EOF (-1)\n#endif\n\n#include \"output.inl\"\n\n#endif\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/secureprintoutput_w.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: By defining corresponding macro for UNICODE string and including \"output.inl\",\n *              this file generates real underlying function used by printf family API.\n * Create: 2014-02-25\n */\n\n/* If some platforms don't have wchar.h, don't include it */\n#if !(defined(SECUREC_VXWORKS_PLATFORM))\n/* If there is no macro above, it will cause compiling alarm */\n#if defined(_MSC_VER) && (_MSC_VER >= 1400)\n#ifndef _CRTIMP_ALTERNATIVE\n#define _CRTIMP_ALTERNATIVE     /* Comment microsoft *_s function */\n#endif\n#ifndef __STDC_WANT_SECURE_LIB__\n#define __STDC_WANT_SECURE_LIB__ 0\n#endif\n#endif\n#include <wchar.h>\n#endif\n\n/* fix redefined */\n#undef SECUREC_ENABLE_WCHAR_FUNC\n/* Disable wchar func to clear vs warning */\n#define SECUREC_ENABLE_WCHAR_FUNC   0\n#define SECUREC_FORMAT_OUTPUT_INPUT 1\n\n#ifndef SECUREC_FOR_WCHAR\n#define SECUREC_FOR_WCHAR\n#endif\n\n#include \"secureprintoutput.h\"\n\n#include \"output.inl\"\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/snprintf_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: snprintf_s  function\n * Create: 2014-02-25\n */\n\n#include \"securec.h\"\n\n#if SECUREC_ENABLE_SNPRINTF\n/*\n * <FUNCTION DESCRIPTION>\n *    The snprintf_s function is equivalent to the snprintf function\n *    except for the parameter destMax/count and the explicit runtime-constraints violation\n *    The snprintf_s function formats and stores count or fewer characters in\n *    strDest and appends a terminating null. Each argument (if any) is converted\n *    and output according to the corresponding format specification in format.\n *    The formatting is consistent with the printf family of functions; If copying\n *    occurs between strings that overlap, the behavior is undefined.\n *\n * <INPUT PARAMETERS>\n *    strDest                 Storage location for the output.\n *    destMax                 The size of the storage location for output. Size\n *                                 in bytes for snprintf_s or size in words for snwprintf_s.\n *    count                    Maximum number of character to store.\n *    format                  Format-control string.\n *    ...                        Optional arguments.\n *\n * <OUTPUT PARAMETERS>\n *    strDest                 is updated\n *\n * <RETURN VALUE>\n *    return  the number of characters written, not including the terminating null\n *    return -1 if an  error occurs.\n *    return -1 if count < destMax and the output string  has been truncated\n *\n * If there is a runtime-constraint violation, strDest[0] will be set to the '\\0' when strDest and destMax valid\n *\n */\nint snprintf_s(char *strDest, size_t destMax, size_t count, const char *format, ...)\n{\n    int ret;                    /* If initialization causes  e838 */\n    va_list argList;\n\n    va_start(argList, format);\n    ret = vsnprintf_s(strDest, destMax, count, format, argList);\n    va_end(argList);\n    (void)argList;              /* To clear e438 last value assigned not used , the compiler will optimize this code */\n\n    return ret;\n}\n#if SECUREC_EXPORT_KERNEL_SYMBOL\nEXPORT_SYMBOL(snprintf_s);\n#endif\n#endif\n\n#if SECUREC_SNPRINTF_TRUNCATED\n/*\n * <FUNCTION DESCRIPTION>\n *    The snprintf_truncated_s function is equivalent to the snprintf function\n *    except for the parameter destMax/count and the explicit runtime-constraints violation\n *    The snprintf_truncated_s function formats and stores count or fewer characters in\n *    strDest and appends a terminating null. Each argument (if any) is converted\n *    and output according to the corresponding format specification in format.\n *    The formatting is consistent with the printf family of functions; If copying\n *    occurs between strings that overlap, the behavior is undefined.\n *\n * <INPUT PARAMETERS>\n *    strDest                 Storage location for the output.\n *    destMax                 The size of the storage location for output. Size\n *                                 in bytes for snprintf_truncated_s or size in words for snwprintf_s.\n *    format                  Format-control string.\n *    ...                        Optional arguments.\n *\n * <OUTPUT PARAMETERS>\n *    strDest                 is updated\n *\n * <RETURN VALUE>\n *    return  the number of characters written, not including the terminating null\n *    return -1 if an  error occurs.\n *    return destMax-1 if output string  has been truncated\n *\n * If there is a runtime-constraint violation, strDest[0] will be set to the '\\0' when strDest and destMax valid\n *\n */\nint snprintf_truncated_s(char *strDest, size_t destMax, const char *format, ...)\n{\n    int ret;                    /* If initialization causes  e838 */\n    va_list argList;\n\n    va_start(argList, format);\n    ret = vsnprintf_truncated_s(strDest, destMax, format, argList);\n    va_end(argList);\n    (void)argList;              /* To clear e438 last value assigned not used , the compiler will optimize this code */\n\n    return ret;\n}\n#if SECUREC_EXPORT_KERNEL_SYMBOL\nEXPORT_SYMBOL(snprintf_truncated_s);\n#endif\n\n#endif\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/sprintf_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: sprintf_s  function\n * Create: 2014-02-25\n */\n\n#include \"securec.h\"\n\n/*\n * <FUNCTION DESCRIPTION>\n *    The sprintf_s function is equivalent to the sprintf function\n *    except for the parameter destMax and the explicit runtime-constraints violation\n *    The sprintf_s function formats and stores a series of characters and values\n *    in strDest. Each argument (if any) is converted and output according to\n *    the corresponding format specification in format. The format consists of\n *    ordinary characters and has the same form and function as the format argument\n *    for printf. A null character is appended after the last character written.\n *    If copying occurs between strings that overlap, the behavior is undefined.\n *\n * <INPUT PARAMETERS>\n *    strDest                 Storage location for output.\n *    destMax                Maximum number of characters to store.\n *    format                  Format-control string.\n *    ...                        Optional arguments\n *\n * <OUTPUT PARAMETERS>\n *    strDest                 is updated\n *\n * <RETURN VALUE>\n *    return the number of bytes stored in strDest, not counting the terminating null character.\n *    return -1 if an error occurred.\n *\n * If there is a runtime-constraint violation, strDest[0] will be set to the '\\0' when strDest and destMax valid\n */\nint sprintf_s(char *strDest, size_t destMax, const char *format, ...)\n{\n    int ret;                    /* If initialization causes  e838 */\n    va_list argList;\n\n    va_start(argList, format);\n    ret = vsprintf_s(strDest, destMax, format, argList);\n    va_end(argList);\n    (void)argList;              /* To clear e438 last value assigned not used , the compiler will optimize this code */\n\n    return ret;\n}\n#if SECUREC_EXPORT_KERNEL_SYMBOL\nEXPORT_SYMBOL(sprintf_s);\n#endif\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/sscanf_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: sscanf_s  function\n * Create: 2014-02-25\n */\n\n#include \"securec.h\"\n\n/*\n * <FUNCTION DESCRIPTION>\n *    The sscanf_s function is equivalent to fscanf_s,\n *     except that input is obtained from a string (specified by the argument buffer) rather than from a stream\n *    The sscanf function reads data from buffer into the location given by each\n *    argument. Every argument must be a pointer to a variable with a type that\n *    corresponds to a type specifier in format. The format argument controls the\n *    interpretation of the input fields and has the same form and function as\n *    the format argument for the scanf function.\n *    If copying takes place between strings that overlap, the behavior is undefined.\n *\n * <INPUT PARAMETERS>\n *    buffer                 Stored data.\n *    format                 Format control string, see Format Specifications.\n *    ...                    Optional arguments.\n *\n * <OUTPUT PARAMETERS>\n *    ...                    The converted value stored in user assigned address\n *\n * <RETURN VALUE>\n *    Each of these functions returns the number of fields successfully converted\n *    and assigned; the return value does not include fields that were read but\n *    not assigned.\n *    A return value of 0 indicates that no fields were assigned.\n *    return -1 if an error occurs.\n */\nint sscanf_s(const char *buffer, const char *format, ...)\n{\n    int ret;                    /* If initialization causes  e838 */\n    va_list argList;\n\n    va_start(argList, format);\n    ret = vsscanf_s(buffer, format, argList);\n    va_end(argList);\n    (void)argList;              /* To clear e438 last value assigned not used , the compiler will optimize this code */\n\n    return ret;\n}\n#if SECUREC_EXPORT_KERNEL_SYMBOL\nEXPORT_SYMBOL(sscanf_s);\n#endif\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/strcat_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: strcat_s  function\n * Create: 2014-02-25\n */\n\n#include \"securecutil.h\"\n\n/*\n * Befor this function, the basic parameter checking has been done\n */\nSECUREC_INLINE errno_t SecDoCat(char *strDest, size_t destMax, const char *strSrc)\n{\n    size_t destLen;\n    size_t srcLen;\n    size_t maxSrcLen;\n    SECUREC_CALC_STR_LEN(strDest, destMax, &destLen);\n    /* Only optimize strSrc, do not apply this function to strDest */\n    maxSrcLen = destMax - destLen;\n    SECUREC_CALC_STR_LEN_OPT(strSrc, maxSrcLen, &srcLen);\n\n    if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) {\n        strDest[0] = '\\0';\n        if (strDest + destLen <= strSrc && destLen == destMax) {\n            SECUREC_ERROR_INVALID_PARAMTER(\"strcat_s\");\n            return EINVAL_AND_RESET;\n        }\n        SECUREC_ERROR_BUFFER_OVERLAP(\"strcat_s\");\n        return EOVERLAP_AND_RESET;\n    }\n    if (srcLen + destLen >= destMax || strDest == strSrc) {\n        strDest[0] = '\\0';\n        if (destLen == destMax) {\n            SECUREC_ERROR_INVALID_PARAMTER(\"strcat_s\");\n            return EINVAL_AND_RESET;\n        }\n        SECUREC_ERROR_INVALID_RANGE(\"strcat_s\");\n        return ERANGE_AND_RESET;\n    }\n    SECUREC_MEMCPY_WARP_OPT(strDest + destLen, strSrc, srcLen + 1); /* Single character length  include \\0 */\n    return EOK;\n}\n\n/*\n * <FUNCTION DESCRIPTION>\n *  The strcat_s function appends a copy of the string pointed to by strSrc (including the terminating null character)\n *  to the end of the  string pointed to by strDest.\n *  The initial character of strSrc overwrites the terminating null character of strDest.\n *  strcat_s will return EOVERLAP_AND_RESET if the source and destination strings overlap.\n *\n *  Note that the second parameter is the total size of the buffer, not the\n *  remaining size.\n *\n * <INPUT PARAMETERS>\n *  strDest             Null-terminated destination string buffer.\n *  destMax             Size of the destination string buffer.\n *  strSrc              Null-terminated source string buffer.\n *\n * <OUTPUT PARAMETERS>\n *    strDest             is updated\n *\n * <RETURN VALUE>\n *    EOK                 Success\n *    EINVAL              strDest is  NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN\n *    EINVAL_AND_RESET    (strDest unterminated  and all other parameters are valid) or\n *                        (strDest != NULL and strSrc is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN)\n *    ERANGE              destMax is 0 and destMax > SECUREC_STRING_MAX_LEN\n *    ERANGE_AND_RESET      strDest have not enough space  and all other parameters are valid  and not overlap\n *    EOVERLAP_AND_RESET   dest buffer and source buffer are overlapped and all  parameters are valid\n *\n *    If there is a runtime-constraint violation, strDest[0] will be set to the '\\0' when strDest and destMax valid\n */\nerrno_t strcat_s(char *strDest, size_t destMax, const char *strSrc)\n{\n    if (destMax == 0 || destMax > SECUREC_STRING_MAX_LEN) {\n        SECUREC_ERROR_INVALID_RANGE(\"strcat_s\");\n        return ERANGE;\n    }\n    if (strDest == NULL || strSrc == NULL) {\n        SECUREC_ERROR_INVALID_PARAMTER(\"strcat_s\");\n        if (strDest != NULL) {\n            strDest[0] = '\\0';\n            return EINVAL_AND_RESET;\n        }\n        return EINVAL;\n    }\n    return SecDoCat(strDest, destMax, strSrc);\n}\n\n#if SECUREC_EXPORT_KERNEL_SYMBOL\nEXPORT_SYMBOL(strcat_s);\n#endif\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/strcpy_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: strcpy_s  function\n * Create: 2014-02-25\n */\n/*\n * [Standardize-exceptions] Use unsafe function: Performance-sensitive\n * [reason] Always used in the performance critical path,\n *          and sufficient input validation is performed before calling\n */\n\n#include \"securecutil.h\"\n\n#ifndef SECUREC_STRCPY_WITH_PERFORMANCE\n#define SECUREC_STRCPY_WITH_PERFORMANCE 1\n#endif\n\n#define SECUREC_STRCPY_PARAM_OK(strDest, destMax, strSrc) ((destMax) > 0 && \\\n    (destMax) <= SECUREC_STRING_MAX_LEN && (strDest) != NULL && (strSrc) != NULL && (strDest) != (strSrc))\n\n#if (!SECUREC_IN_KERNEL) && SECUREC_STRCPY_WITH_PERFORMANCE\n#ifndef SECUREC_STRCOPY_THRESHOLD_SIZE\n#define SECUREC_STRCOPY_THRESHOLD_SIZE   32UL\n#endif\n/* The purpose of converting to void is to clean up the alarm */\n#define SECUREC_SMALL_STR_COPY(strDest, strSrc, lenWithTerm) do { \\\n    if (SECUREC_ADDR_ALIGNED_8(strDest) && SECUREC_ADDR_ALIGNED_8(strSrc)) { \\\n        /* Use struct assignment */ \\\n        switch (lenWithTerm) { \\\n            case 1: \\\n                *(strDest) = *(strSrc); \\\n                break; \\\n            case 2: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 2); \\\n                break; \\\n            case 3: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 3); \\\n                break; \\\n            case 4: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 4); \\\n                break; \\\n            case 5: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 5); \\\n                break; \\\n            case 6: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 6); \\\n                break; \\\n            case 7: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 7); \\\n                break; \\\n            case 8: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 8); \\\n                break; \\\n            case 9: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 9); \\\n                break; \\\n            case 10: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 10); \\\n                break; \\\n            case 11: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 11); \\\n                break; \\\n            case 12: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 12); \\\n                break; \\\n            case 13: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 13); \\\n                break; \\\n            case 14: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 14); \\\n                break; \\\n            case 15: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 15); \\\n                break; \\\n            case 16: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 16); \\\n                break; \\\n            case 17: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 17); \\\n                break; \\\n            case 18: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 18); \\\n                break; \\\n            case 19: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 19); \\\n                break; \\\n            case 20: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 20); \\\n                break; \\\n            case 21: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 21); \\\n                break; \\\n            case 22: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 22); \\\n                break; \\\n            case 23: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 23); \\\n                break; \\\n            case 24: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 24); \\\n                break; \\\n            case 25: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 25); \\\n                break; \\\n            case 26: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 26); \\\n                break; \\\n            case 27: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 27); \\\n                break; \\\n            case 28: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 28); \\\n                break; \\\n            case 29: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 29); \\\n                break; \\\n            case 30: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 30); \\\n                break; \\\n            case 31: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 31); \\\n                break; \\\n            case 32: \\\n                SECUREC_COPY_VALUE_BY_STRUCT((strDest), (strSrc), 32); \\\n                break; \\\n            default: \\\n                /* Do nothing */ \\\n                break; \\\n        } /* END switch */ \\\n    } else { \\\n        char *tmpStrDest_ = (char *)(strDest); \\\n        const char *tmpStrSrc_ = (const char *)(strSrc); \\\n        switch (lenWithTerm) { \\\n            case 32: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 31: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 30: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 29: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 28: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 27: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 26: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 25: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 24: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 23: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 22: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 21: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 20: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 19: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 18: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 17: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 16: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 15: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 14: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 13: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 12: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 11: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 10: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 9: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 8: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 7: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 6: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 5: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 4: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 3: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 2: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            case 1: \\\n                *(tmpStrDest_++) = *(tmpStrSrc_++); \\\n                /* fall-through */ /* FALLTHRU */ \\\n            default: \\\n                /* Do nothing */ \\\n                break; \\\n        } \\\n    } \\\n} SECUREC_WHILE_ZERO\n#endif\n\n#if SECUREC_IN_KERNEL || (!SECUREC_STRCPY_WITH_PERFORMANCE)\n#define SECUREC_STRCPY_OPT(dest, src, lenWithTerm) SECUREC_MEMCPY_WARP_OPT((dest), (src), (lenWithTerm))\n#else\n/*\n * Performance optimization. lenWithTerm  include '\\0'\n */\n#define SECUREC_STRCPY_OPT(dest, src, lenWithTerm) do { \\\n    if ((lenWithTerm) > SECUREC_STRCOPY_THRESHOLD_SIZE) { \\\n        SECUREC_MEMCPY_WARP_OPT((dest), (src), (lenWithTerm)); \\\n    } else { \\\n        SECUREC_SMALL_STR_COPY((dest), (src), (lenWithTerm)); \\\n    } \\\n} SECUREC_WHILE_ZERO\n#endif\n\n/*\n * Check Src Range\n */\nSECUREC_INLINE errno_t CheckSrcRange(char *strDest, size_t destMax, const char *strSrc)\n{\n    size_t tmpDestMax = destMax;\n    const char *tmpSrc = strSrc;\n    /* Use destMax as boundary checker and destMax must be greater than zero */\n    while (*tmpSrc != '\\0' && tmpDestMax > 0) {\n        ++tmpSrc;\n        --tmpDestMax;\n    }\n    if (tmpDestMax == 0) {\n        strDest[0] = '\\0';\n        SECUREC_ERROR_INVALID_RANGE(\"strcpy_s\");\n        return ERANGE_AND_RESET;\n    }\n    return EOK;\n}\n\n/*\n * Handling errors\n */\nerrno_t strcpy_error(char *strDest, size_t destMax, const char *strSrc)\n{\n    if (destMax == 0 || destMax > SECUREC_STRING_MAX_LEN) {\n        SECUREC_ERROR_INVALID_RANGE(\"strcpy_s\");\n        return ERANGE;\n    }\n    if (strDest == NULL || strSrc == NULL) {\n        SECUREC_ERROR_INVALID_PARAMTER(\"strcpy_s\");\n        if (strDest != NULL) {\n            strDest[0] = '\\0';\n            return EINVAL_AND_RESET;\n        }\n        return EINVAL;\n    }\n    return CheckSrcRange(strDest, destMax, strSrc);\n}\n\n/*\n * <FUNCTION DESCRIPTION>\n *    The strcpy_s function copies the string pointed to  strSrc\n *          (including the terminating null character) into the array pointed to by strDest\n *    The destination string must be large enough to hold the source string,\n *    including the terminating null character. strcpy_s will return EOVERLAP_AND_RESET\n *    if the source and destination strings overlap.\n *\n * <INPUT PARAMETERS>\n *    strDest                          Location of destination string buffer\n *    destMax                        Size of the destination string buffer.\n *    strSrc                            Null-terminated source string buffer.\n *\n * <OUTPUT PARAMETERS>\n *    strDest                         is updated.\n *\n * <RETURN VALUE>\n *    EOK                               Success\n *    EINVAL                          strDest is  NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN\n *    EINVAL_AND_RESET       strDest !=  NULL and strSrc is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN\n *    ERANGE                         destMax is 0 and destMax > SECUREC_STRING_MAX_LEN\n *    ERANGE_AND_RESET      strDest have not enough space  and all other parameters are valid  and not overlap\n *    EOVERLAP_AND_RESET   dest buffer and source buffer are overlapped and all  parameters are valid\n *\n *    If there is a runtime-constraint violation, strDest[0] will be set to the '\\0' when strDest and destMax valid\n */\nerrno_t strcpy_s(char *strDest, size_t destMax, const char *strSrc)\n{\n    if (SECUREC_STRCPY_PARAM_OK(strDest, destMax, strSrc)) {\n        size_t srcStrLen;\n        SECUREC_CALC_STR_LEN(strSrc, destMax, &srcStrLen);\n        ++srcStrLen; /* The length include '\\0' */\n\n        if (srcStrLen <= destMax) {\n            /* Use mem overlap check include '\\0' */\n            if (SECUREC_MEMORY_NO_OVERLAP(strDest, strSrc, srcStrLen)) {\n                /* Performance optimization srcStrLen include '\\0' */\n                SECUREC_STRCPY_OPT(strDest, strSrc, srcStrLen);\n                return EOK;\n            } else {\n                strDest[0] = '\\0';\n                SECUREC_ERROR_BUFFER_OVERLAP(\"strcpy_s\");\n                return EOVERLAP_AND_RESET;\n            }\n        }\n    }\n    return strcpy_error(strDest, destMax, strSrc);\n}\n\n#if SECUREC_EXPORT_KERNEL_SYMBOL\nEXPORT_SYMBOL(strcpy_s);\n#endif\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/strncat_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: strncat_s  function\n * Create: 2014-02-25\n */\n\n#include \"securecutil.h\"\n\n/*\n * Befor this function, the basic parameter checking has been done\n */\nSECUREC_INLINE errno_t SecDoCatLimit(char *strDest, size_t destMax, const char *strSrc, size_t count)\n{\n    size_t destLen;\n    size_t srcLen;\n    SECUREC_CALC_STR_LEN(strDest, destMax, &destLen);\n    /*\n     * The strSrc is no longer optimized. The reason is that when count is small,\n     * the efficiency of strnlen is higher than that of self realization.\n     */\n    SECUREC_CALC_STR_LEN(strSrc, count, &srcLen);\n\n    if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) {\n        strDest[0] = '\\0';\n        if (strDest + destLen <= strSrc && destLen == destMax) {\n            SECUREC_ERROR_INVALID_PARAMTER(\"strncat_s\");\n            return EINVAL_AND_RESET;\n        }\n        SECUREC_ERROR_BUFFER_OVERLAP(\"strncat_s\");\n        return EOVERLAP_AND_RESET;\n    }\n    if (srcLen + destLen >= destMax || strDest == strSrc) {\n        strDest[0] = '\\0';\n        if (destLen == destMax) {\n            SECUREC_ERROR_INVALID_PARAMTER(\"strncat_s\");\n            return EINVAL_AND_RESET;\n        }\n        SECUREC_ERROR_INVALID_RANGE(\"strncat_s\");\n        return ERANGE_AND_RESET;\n    }\n    SECUREC_MEMCPY_WARP_OPT(strDest + destLen, strSrc, srcLen);    /* No terminator */\n    *(strDest + destLen + srcLen) = '\\0';\n    return EOK;\n}\n\n/*\n * <FUNCTION DESCRIPTION>\n *    The strncat_s function appends not more than n successive  characters\n *    (not including the terminating null  character)\n *     from the array pointed to by strSrc to the end of the  string pointed to by strDest\n *    The strncat_s function try to append the first D characters of strSrc to\n *    the end of strDest, where D is the lesser of count and the length of strSrc.\n *    If appending those D characters will fit within strDest (whose size is given\n *    as destMax) and still leave room for a null terminator, then those characters\n *    are appended, starting at the original terminating null of strDest, and a\n *    new terminating null is appended; otherwise, strDest[0] is set to the null\n *    character.\n *\n * <INPUT PARAMETERS>\n *    strDest            Null-terminated destination string.\n *    destMax            Size of the destination buffer.\n *    strSrc             Null-terminated source string.\n *    count              Number of character to append, or truncate.\n *\n * <OUTPUT PARAMETERS>\n *    strDest            is updated\n *\n * <RETURN VALUE>\n *    EOK                Success\n *    EINVAL             strDest is  NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN\n *    EINVAL_AND_RESET      (strDest unterminated  and all other parameters are valid)or\n *                        (strDest !=  NULL and strSrc is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN)\n *    ERANGE                         destMax is 0 and destMax > SECUREC_STRING_MAX_LEN\n *    ERANGE_AND_RESET      strDest have not enough space  and all other parameters are valid  and not overlap\n *    EOVERLAP_AND_RESET   dest buffer and source buffer are overlapped and all  parameters are valid\n *\n *    If there is a runtime-constraint violation, strDest[0] will be set to the '\\0' when strDest and destMax valid\n */\nerrno_t strncat_s(char *strDest, size_t destMax, const char *strSrc, size_t count)\n{\n    if (destMax == 0 || destMax > SECUREC_STRING_MAX_LEN) {\n        SECUREC_ERROR_INVALID_RANGE(\"strncat_s\");\n        return ERANGE;\n    }\n\n    if (strDest == NULL || strSrc == NULL) {\n        SECUREC_ERROR_INVALID_PARAMTER(\"strncat_s\");\n        if (strDest != NULL) {\n            strDest[0] = '\\0';\n            return EINVAL_AND_RESET;\n        }\n        return EINVAL;\n    }\n    if (count > SECUREC_STRING_MAX_LEN) {\n#ifdef  SECUREC_COMPATIBLE_WIN_FORMAT\n        if (count == (size_t)(-1)) {\n            /* Windows internal functions may pass in -1 when calling this function */\n            return SecDoCatLimit(strDest, destMax, strSrc, destMax);\n        }\n#endif\n        strDest[0] = '\\0';\n        SECUREC_ERROR_INVALID_RANGE(\"strncat_s\");\n        return ERANGE_AND_RESET;\n    }\n    return SecDoCatLimit(strDest, destMax, strSrc, count);\n}\n\n#if SECUREC_EXPORT_KERNEL_SYMBOL\nEXPORT_SYMBOL(strncat_s);\n#endif\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/strncpy_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: strncpy_s  function\n * Create: 2014-02-25\n */\n/*\n * [Standardize-exceptions] Use unsafe function: Performance-sensitive\n * [reason] Always used in the performance critical path,\n *          and sufficient input validation is performed before calling\n */\n\n#include \"securecutil.h\"\n\n#if defined(SECUREC_COMPATIBLE_WIN_FORMAT)\n#define SECUREC_STRNCPY_PARAM_OK(strDest, destMax, strSrc, count) \\\n    (((destMax) > 0 && (destMax) <= SECUREC_STRING_MAX_LEN && (strDest) != NULL && (strSrc) != NULL && \\\n    ((count) <= SECUREC_STRING_MAX_LEN || (count) == ((size_t)(-1))) && (count) > 0))\n#else\n#define SECUREC_STRNCPY_PARAM_OK(strDest, destMax, strSrc, count) \\\n    (((destMax) > 0 && (destMax) <= SECUREC_STRING_MAX_LEN && (strDest) != NULL && (strSrc) != NULL && \\\n    (count) <= SECUREC_STRING_MAX_LEN && (count) > 0))\n#endif\n\n/*\n * Check Src Count Range\n */\nSECUREC_INLINE errno_t CheckSrcCountRange(char *strDest, size_t destMax, const char *strSrc, size_t count)\n{\n    size_t tmpDestMax = destMax;\n    size_t tmpCount = count;\n    const char *endPos = strSrc;\n\n    /* Use destMax and  count as boundary checker and destMax must be greater than zero */\n    while (*(endPos) != '\\0' && tmpDestMax > 0 && tmpCount > 0) {\n        ++endPos;\n        --tmpCount;\n        --tmpDestMax;\n    }\n    if (tmpDestMax == 0) {\n        strDest[0] = '\\0';\n        SECUREC_ERROR_INVALID_RANGE(\"strncpy_s\");\n        return ERANGE_AND_RESET;\n    }\n    return EOK;\n}\n\n/*\n * Handling errors, when dest equal src return EOK\n */\nerrno_t strncpy_error(char *strDest, size_t destMax, const char *strSrc, size_t count)\n{\n    if (destMax == 0 || destMax > SECUREC_STRING_MAX_LEN) {\n        SECUREC_ERROR_INVALID_RANGE(\"strncpy_s\");\n        return ERANGE;\n    }\n    if (strDest == NULL || strSrc == NULL) {\n        SECUREC_ERROR_INVALID_PARAMTER(\"strncpy_s\");\n        if (strDest != NULL) {\n            strDest[0] = '\\0';\n            return EINVAL_AND_RESET;\n        }\n        return EINVAL;\n    }\n    if (count > SECUREC_STRING_MAX_LEN) {\n        strDest[0] = '\\0';      /* Clear dest string */\n        SECUREC_ERROR_INVALID_RANGE(\"strncpy_s\");\n        return ERANGE_AND_RESET;\n    }\n    if (count == 0) {\n        strDest[0] = '\\0';\n        return EOK;\n    }\n    return CheckSrcCountRange(strDest, destMax, strSrc, count);\n}\n\n/*\n * <FUNCTION DESCRIPTION>\n *   The strncpy_s function copies not more than n successive characters (not including the terminating null character)\n *                     from the array pointed to by strSrc to the array pointed to by strDest.\n *\n * <INPUT PARAMETERS>\n *    strDest                          Destination string.\n *    destMax                          The size of the destination string, in characters.\n *    strSrc                            Source string.\n *    count                              Number of characters to be copied.\n *\n * <OUTPUT PARAMETERS>\n *    strDest                           is updated\n *\n * <RETURN VALUE>\n *    EOK                               Success\n *    EINVAL                          strDest is  NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN\n *    EINVAL_AND_RESET       strDest !=  NULL and strSrc is NULL and destMax != 0 and destMax <= SECUREC_STRING_MAX_LEN\n *    ERANGE                         destMax is 0 and destMax > SECUREC_STRING_MAX_LEN\n *    ERANGE_AND_RESET      strDest have not enough space  and all other parameters are valid  and not overlap\n *    EOVERLAP_AND_RESET   dest buffer and source buffer are overlapped and all  parameters are valid\n *\n *    If there is a runtime-constraint violation, strDest[0] will be set to the '\\0' when strDest and destMax valid\n */\nerrno_t strncpy_s(char *strDest, size_t destMax, const char *strSrc, size_t count)\n{\n    if (SECUREC_STRNCPY_PARAM_OK(strDest, destMax, strSrc, count)) {\n        size_t minCpLen;        /* Use it to store the maxi length limit */\n        if (count < destMax) {\n            SECUREC_CALC_STR_LEN(strSrc, count, &minCpLen); /* No ending terminator */\n        } else {\n            size_t tmpCount = destMax;\n#ifdef  SECUREC_COMPATIBLE_WIN_FORMAT\n            if (count == ((size_t)(-1))) {\n                tmpCount = destMax - 1;\n            }\n#endif\n            SECUREC_CALC_STR_LEN(strSrc, tmpCount, &minCpLen); /* No ending terminator */\n            if (minCpLen == destMax) {\n                strDest[0] = '\\0';\n                SECUREC_ERROR_INVALID_RANGE(\"strncpy_s\");\n                return ERANGE_AND_RESET;\n            }\n        }\n        if (SECUREC_STRING_NO_OVERLAP(strDest, strSrc, minCpLen) || strDest == strSrc) {\n            /* Not overlap */\n            SECUREC_MEMCPY_WARP_OPT(strDest, strSrc, minCpLen);    /* Copy string without terminator */\n            strDest[minCpLen] = '\\0';\n            return EOK;\n        } else {\n            strDest[0] = '\\0';\n            SECUREC_ERROR_BUFFER_OVERLAP(\"strncpy_s\");\n            return EOVERLAP_AND_RESET;\n        }\n    }\n    return strncpy_error(strDest, destMax, strSrc, count);\n}\n\n#if SECUREC_EXPORT_KERNEL_SYMBOL\nEXPORT_SYMBOL(strncpy_s);\n#endif\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/strtok_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: strtok_s  function\n * Create: 2014-02-25\n */\n\n#include \"securecutil.h\"\n\nSECUREC_INLINE int SecIsInDelimit(char ch, const char *strDelimit)\n{\n    const char *ctl = strDelimit;\n    while (*ctl != '\\0' && *ctl != ch) {\n        ++ctl;\n    }\n    return (int)(*ctl != '\\0');\n}\n\n/*\n * Find beginning of token (skip over leading delimiters).\n * Note that there is no token if this loop sets string to point to the terminal null.\n */\nSECUREC_INLINE char *SecFindBegin(char *strToken, const char *strDelimit)\n{\n    char *token = strToken;\n    while (*token != '\\0') {\n        if (SecIsInDelimit(*token, strDelimit) != 0) {\n            ++token;\n            continue;\n        }\n        /* Don't find any delimiter in string header, break the loop */\n        break;\n    }\n    return token;\n}\n\n/*\n * Find rest of token\n */\nSECUREC_INLINE char *SecFindRest(char *strToken, const char *strDelimit)\n{\n    /* Find the rest of the token. If it is not the end of the string, put a null there */\n    char *token = strToken;\n    while (*token != '\\0') {\n        if (SecIsInDelimit(*token, strDelimit) != 0) {\n            /* Find a delimiter, set string terminator */\n            *token = '\\0';\n            ++token;\n            break;\n        }\n        ++token;\n    }\n    return token;\n}\n\n/*\n * Find the final position pointer\n */\nSECUREC_INLINE char *SecUpdateToken(char *strToken, const char *strDelimit, char **context)\n{\n    /* Point to updated position. Record string position for next search in the context */\n    *context = SecFindRest(strToken, strDelimit);\n    /* Determine if a token has been found. */\n    if (*context == strToken) {\n        return NULL;\n    }\n    return strToken;\n}\n\n/*\n * <FUNCTION DESCRIPTION>\n *    The strtok_s function parses a string into a sequence of strToken,\n *    replace all characters in strToken string that match to strDelimit set with 0.\n *    On the first call to strtok_s the string to be parsed should be specified in strToken.\n *    In each subsequent call that should parse the same string, strToken should be NULL\n * <INPUT PARAMETERS>\n *    strToken            String containing token or tokens.\n *    strDelimit          Set of delimiter characters.\n *    context             Used to store position information between calls\n *                             to strtok_s\n * <OUTPUT PARAMETERS>\n *   context               is updated\n * <RETURN VALUE>\n *   On the first call returns the address of the first non \\0 character, otherwise NULL is returned.\n *   In subsequent calls, the strtoken is set to NULL, and the context set is the same as the previous call,\n *   return NULL if the *context string length is equal 0, otherwise return *context.\n */\nchar *strtok_s(char *strToken, const char *strDelimit, char **context)\n{\n    char *orgToken = strToken;\n    /* Validate delimiter and string context */\n    if (context == NULL || strDelimit == NULL) {\n        return NULL;\n    }\n    /* Valid input string and string pointer from where to search */\n    if (orgToken == NULL && *context == NULL) {\n        return NULL;\n    }\n    /* If string is null, continue searching from previous string position stored in context */\n    if (orgToken == NULL) {\n        orgToken = *context;\n    }\n    orgToken = SecFindBegin(orgToken, strDelimit);\n    return SecUpdateToken(orgToken, strDelimit, context);\n}\n#if SECUREC_EXPORT_KERNEL_SYMBOL\nEXPORT_SYMBOL(strtok_s);\n#endif\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/swprintf_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: swprintf_s  function\n * Create: 2014-02-25\n */\n\n#include \"securec.h\"\n\n/*\n * <FUNCTION DESCRIPTION>\n *   The  swprintf_s  function  is  the  wide-character  equivalent  of the sprintf_s function\n *\n * <INPUT PARAMETERS>\n *    strDest                   Storage location for the output.\n *    destMax                   Maximum number of characters to store.\n *    format                    Format-control string.\n *    ...                        Optional arguments\n *\n * <OUTPUT PARAMETERS>\n *    strDest                    is updated\n *\n * <RETURN VALUE>\n *    return  the number of wide characters stored in strDest, not  counting the terminating null wide character.\n *    return -1  if an error occurred.\n *\n * If there is a runtime-constraint violation, strDest[0] will be set to the '\\0' when strDest and destMax valid\n */\nint swprintf_s(wchar_t *strDest, size_t destMax, const wchar_t *format, ...)\n{\n    int ret;                    /* If initialization causes  e838 */\n    va_list argList;\n\n    va_start(argList, format);\n    ret = vswprintf_s(strDest, destMax, format, argList);\n    va_end(argList);\n    (void)argList;              /* To clear e438 last value assigned not used , the compiler will optimize this code */\n\n    return ret;\n}\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/swscanf_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: swscanf_s  function\n * Create: 2014-02-25\n */\n\n#include \"securec.h\"\n\n/*\n * <FUNCTION DESCRIPTION>\n *    The  swscanf_s  function  is  the  wide-character  equivalent  of the sscanf_s function\n *    The swscanf_s function reads data from buffer into the location given by\n *    each argument. Every argument must be a pointer to a variable with a type\n *    that corresponds to a type specifier in format. The format argument controls\n *    the interpretation of the input fields and has the same form and function\n *    as the format argument for the scanf function. If copying takes place between\n *    strings that overlap, the behavior is undefined.\n *\n * <INPUT PARAMETERS>\n *    buffer                 Stored data.\n *    format                 Format control string, see Format Specifications.\n *    ...                    Optional arguments.\n *\n * <OUTPUT PARAMETERS>\n *    ...                    the converted value stored in user assigned address\n *\n * <RETURN VALUE>\n *    Each of these functions returns the number of fields successfully converted\n *    and assigned; The return value does not include fields that were read but not\n *    assigned.\n *    A return value of 0 indicates that no fields were assigned.\n *    return -1 if an error occurs.\n */\nint swscanf_s(const wchar_t *buffer, const wchar_t *format, ...)\n{\n    int ret;                    /* If initialization causes  e838 */\n    va_list argList;\n\n    va_start(argList, format);\n    ret = vswscanf_s(buffer, format, argList);\n    va_end(argList);\n    (void)argList;              /* To clear e438 last value assigned not used , the compiler will optimize this code */\n\n    return ret;\n}\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/vfscanf_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: vfscanf_s  function\n * Create: 2014-02-25\n */\n\n#include \"secinput.h\"\n\n/*\n * <FUNCTION DESCRIPTION>\n *    The vfscanf_s function is equivalent to fscanf_s, with the variable argument list replaced by argList\n *    The vfscanf_s function reads data from the current position of stream into\n *    the locations given by argument (if any). Each argument must be a pointer\n *    to a variable of a type that corresponds to a type specifier in format.\n *    format controls the interpretation of the input fields and has the same\n *    form and function as the format argument for scanf.\n *\n * <INPUT PARAMETERS>\n *    stream               Pointer to FILE structure.\n *    format               Format control string, see Format Specifications.\n *    argList              pointer to list of arguments\n *\n * <OUTPUT PARAMETERS>\n *    argList              the converted value stored in user assigned address\n *\n * <RETURN VALUE>\n *    Each of these functions returns the number of fields successfully converted\n *    and assigned; the return value does not include fields that were read but\n *    not assigned. A return value of 0 indicates that no fields were assigned.\n *    return -1 if an error occurs.\n */\nint vfscanf_s(FILE *stream, const char *format, va_list argList)\n{\n    int retVal;                 /* If initialization causes  e838 */\n    SecFileStream fStr;\n\n    if (stream == NULL || format == NULL) {\n        SECUREC_ERROR_INVALID_PARAMTER(\"vfscanf_s\");\n        return SECUREC_SCANF_EINVAL;\n    }\n    if (stream == SECUREC_STREAM_STDIN) {\n        return vscanf_s(format, argList);\n    }\n\n    SECUREC_LOCK_FILE(stream);\n    SECUREC_FILE_STREAM_FROM_FILE(&fStr, stream);\n    retVal = SecInputS(&fStr, format, argList);\n    SECUREC_UNLOCK_FILE(stream);\n    if (retVal < 0) {\n        SECUREC_ERROR_INVALID_PARAMTER(\"vfscanf_s\");\n        return SECUREC_SCANF_EINVAL;\n    }\n\n    return retVal;\n}\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/vfwscanf_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: vfwscanf_s  function\n * Create: 2014-02-25\n */\n\n#ifndef SECUREC_FOR_WCHAR\n#define SECUREC_FOR_WCHAR\n#endif\n\n#include \"secinput.h\"\n\n/*\n * <FUNCTION DESCRIPTION>\n *    The  vfwscanf_s  function  is  the  wide-character  equivalent  of the vfscanf_s function\n *    The vfwscanf_s function reads data from the current position of stream into\n *    the locations given by argument (if any). Each argument must be a pointer\n *    to a variable of a type that corresponds to a type specifier in format.\n *    format controls the interpretation of the input fields and has the same form\n *    and function as the format argument for scanf.\n *\n * <INPUT PARAMETERS>\n *    stream               Pointer to FILE structure.\n *    format               Format control string, see Format Specifications.\n *    argList              pointer to list of arguments\n *\n * <OUTPUT PARAMETERS>\n *    argList              the converted value stored in user assigned address\n *\n * <RETURN VALUE>\n *    Each of these functions returns the number of fields successfully converted\n *    and assigned; the return value does not include fields that were read but\n *    not assigned. A return value of 0 indicates that no fields were assigned.\n *    return -1 if an error occurs.\n */\nint vfwscanf_s(FILE *stream, const wchar_t *format, va_list argList)\n{\n    int retVal; /* If initialization causes  e838 */\n    SecFileStream fStr;\n\n    if (stream == NULL || format == NULL) {\n        SECUREC_ERROR_INVALID_PARAMTER(\"vfwscanf_s\");\n        return SECUREC_SCANF_EINVAL;\n    }\n    if (stream == SECUREC_STREAM_STDIN) {\n        return vwscanf_s(format, argList);\n    }\n\n    SECUREC_LOCK_FILE(stream);\n    SECUREC_FILE_STREAM_FROM_FILE(&fStr, stream);\n    retVal = SecInputSW(&fStr, format, argList);\n    SECUREC_UNLOCK_FILE(stream);\n    if (retVal < 0) {\n        SECUREC_ERROR_INVALID_PARAMTER(\"vfwscanf_s\");\n        return SECUREC_SCANF_EINVAL;\n    }\n    return retVal;\n}\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/vscanf_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: vscanf_s  function\n * Create: 2014-02-25\n */\n\n#include \"secinput.h\"\n\n/*\n * <FUNCTION DESCRIPTION>\n *     The vscanf_s function is equivalent to scanf_s, with the variable argument list replaced by argList,\n *     The vscanf_s function reads data from the standard input stream stdin and\n *    writes the data into the location that's given by argument. Each argument\n *    must be a pointer to a variable of a type that corresponds to a type specifier\n *    in format. If copying occurs between strings that overlap, the behavior is\n *    undefined.\n *\n * <INPUT PARAMETERS>\n *    format                Format control string.\n *    argList               pointer to list of arguments\n *\n * <OUTPUT PARAMETERS>\n *    argList               the converted value stored in user assigned address\n *\n * <RETURN VALUE>\n *    Returns the number of fields successfully converted and assigned;\n *    the return value does not include fields that were read but not assigned.\n *    A return value of 0 indicates that no fields were assigned.\n *    return -1 if an error occurs.\n */\nint vscanf_s(const char *format, va_list argList)\n{\n    int retVal;                 /* If initialization causes  e838 */\n    SecFileStream fStr;\n    SECUREC_FILE_STREAM_FROM_STDIN(&fStr);\n    /*\n     * The \"va_list\" has different definition on different platform, so we can't use argList == NULL\n     * To determine it's invalid. If you has fixed platform, you can check some fields to validate it,\n     * such as \"argList == NULL\" or argList.xxx != NULL or *(size_t *)&argList != 0.\n     */\n#if SECUREC_ENABLE_SCANF_FILE\n    if (format == NULL || fStr.pf == NULL) {\n#else\n    if (format == NULL) {\n#endif\n        SECUREC_ERROR_INVALID_PARAMTER(\"vscanf_s\");\n        return SECUREC_SCANF_EINVAL;\n    }\n\n#if SECUREC_ENABLE_SCANF_FILE\n    SECUREC_LOCK_STDIN(0, fStr.pf);\n#endif\n    retVal = SecInputS(&fStr, format, argList);\n#if SECUREC_ENABLE_SCANF_FILE\n    SECUREC_UNLOCK_STDIN(0, fStr.pf);\n#endif\n    if (retVal < 0) {\n        SECUREC_ERROR_INVALID_PARAMTER(\"vscanf_s\");\n        return SECUREC_SCANF_EINVAL;\n    }\n    return retVal;\n}\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/vsnprintf_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: vsnprintf_s  function\n * Create: 2014-02-25\n */\n\n#include \"secureprintoutput.h\"\n\n#if SECUREC_ENABLE_VSNPRINTF\n/*\n * <FUNCTION DESCRIPTION>\n *    The vsnprintf_s function is equivalent to the vsnprintf function\n *     except for the parameter destMax/count and the explicit runtime-constraints violation\n *    The vsnprintf_s function takes a pointer to an argument list, then formats\n *    and writes up to count characters of the given data to the memory pointed\n *    to by strDest and appends a terminating null.\n *\n * <INPUT PARAMETERS>\n *    strDest                  Storage location for the output.\n *    destMax                The size of the strDest for output.\n *    count                    Maximum number of character to write(not including\n *                                the terminating NULL)\n *    format                   Format-control string.\n *    argList                     pointer to list of arguments.\n *\n * <OUTPUT PARAMETERS>\n *    strDest                is updated\n *\n * <RETURN VALUE>\n *    return  the number of characters written, not including the terminating null\n *    return -1 if an  error occurs.\n *    return -1 if count < destMax and the output string  has been truncated\n *\n * If there is a runtime-constraint violation, strDest[0] will be set to the '\\0' when strDest and destMax valid\n */\nint vsnprintf_s(char *strDest, size_t destMax, size_t count, const char *format, va_list argList)\n{\n    int retVal;\n\n    if (SECUREC_VSNPRINTF_PARAM_ERROR(format, strDest, destMax, count, SECUREC_STRING_MAX_LEN)) {\n        SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, SECUREC_STRING_MAX_LEN);\n        SECUREC_ERROR_INVALID_PARAMTER(\"vsnprintf_s\");\n        return -1;\n    }\n\n    if (destMax > count) {\n        retVal = SecVsnprintfImpl(strDest, count + 1, format, argList);\n        if (retVal == SECUREC_PRINTF_TRUNCATE) {  /* To keep dest buffer not destroyed 2014.2.18 */\n            /* The string has been truncated, return  -1 */\n            return -1;          /* To skip error handler,  return strlen(strDest) or -1 */\n        }\n    } else {\n        retVal = SecVsnprintfImpl(strDest, destMax, format, argList);\n#ifdef SECUREC_COMPATIBLE_WIN_FORMAT\n        if (retVal == SECUREC_PRINTF_TRUNCATE && count == (size_t)(-1)) {\n            return -1;\n        }\n#endif\n    }\n\n    if (retVal < 0) {\n        strDest[0] = '\\0';      /* Empty the dest strDest */\n        if (retVal == SECUREC_PRINTF_TRUNCATE) {\n            /* Buffer too small */\n            SECUREC_ERROR_INVALID_RANGE(\"vsnprintf_s\");\n        }\n        SECUREC_ERROR_INVALID_PARAMTER(\"vsnprintf_s\");\n        return -1;\n    }\n\n    return retVal;\n}\n#if SECUREC_EXPORT_KERNEL_SYMBOL\nEXPORT_SYMBOL(vsnprintf_s);\n#endif\n#endif\n\n#if SECUREC_SNPRINTF_TRUNCATED\n/*\n * <FUNCTION DESCRIPTION>\n *    The vsnprintf_truncated_s function is equivalent to the vsnprintf function\n *     except for the parameter destMax/count and the explicit runtime-constraints violation\n *    The vsnprintf_truncated_s function takes a pointer to an argument list, then formats\n *    and writes up to count characters of the given data to the memory pointed\n *    to by strDest and appends a terminating null.\n *\n * <INPUT PARAMETERS>\n *    strDest                  Storage location for the output.\n *    destMax                The size of the strDest for output.\n *                                the terminating NULL)\n *    format                   Format-control string.\n *    argList                     pointer to list of arguments.\n *\n * <OUTPUT PARAMETERS>\n *    strDest                is updated\n *\n * <RETURN VALUE>\n *    return  the number of characters written, not including the terminating null\n *    return -1 if an  error occurs.\n *    return destMax-1 if output string  has been truncated\n *\n * If there is a runtime-constraint violation, strDest[0] will be set to the '\\0' when strDest and destMax valid\n */\nint vsnprintf_truncated_s(char *strDest, size_t destMax, const char *format, va_list argList)\n{\n    int retVal;\n\n    if (SECUREC_VSPRINTF_PARAM_ERROR(format, strDest, destMax, SECUREC_STRING_MAX_LEN)) {\n        SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, SECUREC_STRING_MAX_LEN);\n        SECUREC_ERROR_INVALID_PARAMTER(\"vsnprintf_truncated_s\");\n        return -1;\n    }\n\n    retVal = SecVsnprintfImpl(strDest, destMax, format, argList);\n    if (retVal < 0) {\n        if (retVal == SECUREC_PRINTF_TRUNCATE) {\n            return (int)(destMax - 1);  /* To skip error handler,  return strlen(strDest) */\n        }\n        strDest[0] = '\\0';      /* Empty the dest strDest */\n        SECUREC_ERROR_INVALID_PARAMTER(\"vsnprintf_truncated_s\");\n        return -1;\n    }\n\n    return retVal;\n}\n#if SECUREC_EXPORT_KERNEL_SYMBOL\nEXPORT_SYMBOL(vsnprintf_truncated_s);\n#endif\n#endif\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/vsprintf_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: vsprintf_s  function\n * Create: 2014-02-25\n */\n\n#include \"secureprintoutput.h\"\n\n/*\n * <FUNCTION DESCRIPTION>\n *    The vsprintf_s function is equivalent to the vsprintf function\n *    except for the parameter destMax and the explicit runtime-constraints violation\n *    The vsprintf_s function takes a pointer to an argument list, and then formats\n *    and writes the given data to the memory pointed to by strDest.\n *    The function differ from the non-secure versions only in that the secure\n *    versions support positional parameters.\n *\n * <INPUT PARAMETERS>\n *    strDest                Storage location for the output.\n *    destMax                Size of strDest\n *    format                 Format specification.\n *    argList                pointer to list of arguments\n *\n * <OUTPUT PARAMETERS>\n *    strDest                is updated\n *\n * <RETURN VALUE>\n *    return  the number of characters written, not including the terminating null character,\n *    return -1  if an  error occurs.\n *\n * If there is a runtime-constraint violation, strDest[0] will be set to the '\\0' when strDest and destMax valid\n */\nint vsprintf_s(char *strDest, size_t destMax, const char *format, va_list argList)\n{\n    int retVal;               /* If initialization causes  e838 */\n\n    if (SECUREC_VSPRINTF_PARAM_ERROR(format, strDest, destMax, SECUREC_STRING_MAX_LEN)) {\n        SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, SECUREC_STRING_MAX_LEN);\n        SECUREC_ERROR_INVALID_PARAMTER(\"vsprintf_s\");\n        return -1;\n    }\n\n    retVal = SecVsnprintfImpl(strDest, destMax, format, argList);\n    if (retVal < 0) {\n        strDest[0] = '\\0';\n        if (retVal == SECUREC_PRINTF_TRUNCATE) {\n            /* Buffer is too small */\n            SECUREC_ERROR_INVALID_RANGE(\"vsprintf_s\");\n        }\n        SECUREC_ERROR_INVALID_PARAMTER(\"vsprintf_s\");\n        return -1;\n    }\n\n    return retVal;\n}\n#if SECUREC_EXPORT_KERNEL_SYMBOL\nEXPORT_SYMBOL(vsprintf_s);\n#endif\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/vsscanf_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: vsscanf_s  function\n * Create: 2014-02-25\n */\n\n#include \"secinput.h\"\n#if defined(SECUREC_VXWORKS_PLATFORM) && !SECUREC_IN_KERNEL && \\\n    (!defined(SECUREC_SYSAPI4VXWORKS) && !defined(SECUREC_CTYPE_MACRO_ADAPT))\n#include <ctype.h>\n#endif\n\n/*\n * <NAME>\n *    vsscanf_s\n *\n *\n * <FUNCTION DESCRIPTION>\n *    The vsscanf_s function is equivalent to sscanf_s, with the variable argument list replaced by argList\n *    The vsscanf_s function reads data from buffer into the location given by\n *    each argument. Every argument must be a pointer to a variable with a type\n *    that corresponds to a type specifier in format. The format argument controls\n *    the interpretation of the input fields and has the same form and function\n *    as the format argument for the scanf function.\n *    If copying takes place between strings that overlap, the behavior is undefined.\n *\n * <INPUT PARAMETERS>\n *    buffer                Stored data\n *    format                Format control string, see Format Specifications.\n *    argList               pointer to list of arguments\n *\n * <OUTPUT PARAMETERS>\n *    argList               the converted value stored in user assigned address\n *\n * <RETURN VALUE>\n *    Each of these functions returns the number of fields successfully converted\n *    and assigned; the return value does not include fields that were read but\n *    not assigned. A return value of 0 indicates that no fields were assigned.\n *    return -1 if an error occurs.\n */\nint vsscanf_s(const char *buffer, const char *format, va_list argList)\n{\n    size_t count;               /* If initialization causes  e838 */\n    int retVal;\n    SecFileStream fStr;\n\n    /* Validation section */\n    if (buffer == NULL || format == NULL) {\n        SECUREC_ERROR_INVALID_PARAMTER(\"vsscanf_s\");\n        return SECUREC_SCANF_EINVAL;\n    }\n    count = strlen(buffer);\n    if (count == 0 || count > SECUREC_STRING_MAX_LEN) {\n        SecClearDestBuf(buffer, format, argList);\n        SECUREC_ERROR_INVALID_PARAMTER(\"vsscanf_s\");\n        return SECUREC_SCANF_EINVAL;\n    }\n#if defined(SECUREC_VXWORKS_PLATFORM) && !SECUREC_IN_KERNEL\n    /*\n     * On vxworks platform when buffer is white string, will set first %s argument to zero.Like following usage:\n     * \"   \\v\\f\\t\\r\\n\", \"%s\", str, strSize\n     * Do not check all character, just first and last character then consider it is white string\n     */\n    if (isspace((int)(unsigned char)buffer[0]) != 0 && isspace((int)(unsigned char)buffer[count - 1]) != 0) {\n        SecClearDestBuf(buffer, format, argList);\n    }\n#endif\n    SECUREC_FILE_STREAM_FROM_STRING(&fStr, buffer, count);\n    retVal = SecInputS(&fStr, format, argList);\n    if (retVal < 0) {\n        SECUREC_ERROR_INVALID_PARAMTER(\"vsscanf_s\");\n        return SECUREC_SCANF_EINVAL;\n    }\n    return retVal;\n}\n#if SECUREC_EXPORT_KERNEL_SYMBOL\nEXPORT_SYMBOL(vsscanf_s);\n#endif\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/vswprintf_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: vswprintf_s  function\n * Create: 2014-02-25\n */\n\n#ifndef SECUREC_FOR_WCHAR\n#define SECUREC_FOR_WCHAR\n#endif\n\n#include \"secureprintoutput.h\"\n\n/*\n * <FUNCTION DESCRIPTION>\n *    The  vswprintf_s  function  is  the  wide-character  equivalent  of the vsprintf_s function\n *\n * <INPUT PARAMETERS>\n *    strDest                  Storage location for the output.\n *    destMax                  Maximum number of characters to store\n *    format                   Format specification.\n *    argList                  pointer to list of arguments\n *\n * <OUTPUT PARAMETERS>\n *    strDest                 is updated\n *\n * <RETURN VALUE>\n *    return  the number of wide characters stored in strDest, not  counting the terminating null wide character.\n *    return -1  if an error occurred.\n *\n * If there is a runtime-constraint violation, strDest[0] will be set to the '\\0' when strDest and destMax valid\n */\nint vswprintf_s(wchar_t *strDest, size_t destMax, const wchar_t *format, va_list argList)\n{\n    int retVal;               /* If initialization causes  e838 */\n    if (SECUREC_VSPRINTF_PARAM_ERROR(format, strDest, destMax, SECUREC_WCHAR_STRING_MAX_LEN)) {\n        SECUREC_VSPRINTF_CLEAR_DEST(strDest, destMax, SECUREC_WCHAR_STRING_MAX_LEN);\n        SECUREC_ERROR_INVALID_PARAMTER(\"vswprintf_s\");\n        return -1;\n    }\n\n    retVal = SecVswprintfImpl(strDest, destMax, format, argList);\n    if (retVal < 0) {\n        strDest[0] = L'\\0';\n        if (retVal == SECUREC_PRINTF_TRUNCATE) {\n            /* Buffer too small */\n            SECUREC_ERROR_INVALID_RANGE(\"vswprintf_s\");\n        }\n        SECUREC_ERROR_INVALID_PARAMTER(\"vswprintf_s\");\n        return -1;\n    }\n\n    return retVal;\n}\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/vswscanf_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: vswscanf_s  function\n * Create: 2014-02-25\n */\n\n#ifndef SECUREC_FOR_WCHAR\n#define SECUREC_FOR_WCHAR\n#endif\n\n#include \"secinput.h\"\n\nSECUREC_INLINE size_t SecWcslen(const wchar_t *s)\n{\n    const wchar_t *end = s;\n    while (*end != L'\\0') {\n        ++end;\n    }\n    return ((size_t)((end - s)));\n}\n\n/*\n * <FUNCTION DESCRIPTION>\n *    The  vswscanf_s  function  is  the  wide-character  equivalent  of the vsscanf_s function\n *    The vsscanf_s function reads data from buffer into the location given by\n *    each argument. Every argument must be a pointer to a variable with a type\n *    that corresponds to a type specifier in format.\n *    The format argument controls the interpretation of the input fields and\n *    has the same form and function as the format argument for the scanf function.\n *    If copying takes place between strings that overlap, the behavior is undefined.\n *\n * <INPUT PARAMETERS>\n *    buffer                Stored data\n *    format                Format control string, see Format Specifications.\n *    argList               pointer to list of arguments\n *\n * <OUTPUT PARAMETERS>\n *    argList               the converted value stored in user assigned address\n *\n * <RETURN VALUE>\n *    Each of these functions returns the number of fields successfully converted\n *    and assigned; the return value does not include fields that were read but\n *    not assigned. A return value of 0 indicates that no fields were assigned.\n *    return -1 if an error occurs.\n */\nint vswscanf_s(const wchar_t *buffer, const wchar_t *format, va_list argList)\n{\n    size_t count; /* If initialization causes  e838 */\n    SecFileStream fStr;\n    int retVal;\n\n    /* Validation section */\n    if (buffer == NULL || format == NULL) {\n        SECUREC_ERROR_INVALID_PARAMTER(\"vswscanf_s\");\n        return SECUREC_SCANF_EINVAL;\n    }\n    count = SecWcslen(buffer);\n    if (count == 0 || count > SECUREC_WCHAR_STRING_MAX_LEN) {\n        SecClearDestBufW(buffer, format, argList);\n        SECUREC_ERROR_INVALID_PARAMTER(\"vswscanf_s\");\n        return SECUREC_SCANF_EINVAL;\n    }\n    SECUREC_FILE_STREAM_FROM_STRING(&fStr, (const char *)buffer, count * sizeof(wchar_t));\n    retVal = SecInputSW(&fStr, format, argList);\n    if (retVal < 0) {\n        SECUREC_ERROR_INVALID_PARAMTER(\"vswscanf_s\");\n        return SECUREC_SCANF_EINVAL;\n    }\n    return retVal;\n}\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/vwscanf_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: vwscanf_s  function\n * Create: 2014-02-25\n */\n\n#ifndef SECUREC_FOR_WCHAR\n#define SECUREC_FOR_WCHAR\n#endif\n\n#include \"secinput.h\"\n\n/*\n * <FUNCTION DESCRIPTION>\n *    The  vwscanf_s  function  is  the  wide-character  equivalent  of the vscanf_s function\n *    The vwscanf_s function is the wide-character version of vscanf_s. The\n *    function reads data from the standard input stream stdin and writes the\n *    data into the location that's given by argument. Each argument  must be a\n *    pointer to a variable of a type that corresponds to a type specifier in\n *    format. If copying occurs between strings that overlap, the behavior is\n *    undefined.\n *\n * <INPUT PARAMETERS>\n *    format                 Format control string.\n *    argList                pointer to list of arguments\n *\n * <OUTPUT PARAMETERS>\n *    argList                the converted value stored in user assigned address\n *\n * <RETURN VALUE>\n *    Returns the number of fields successfully converted and assigned;\n *    the return value does not include fields that were read but not assigned.\n *    A return value of 0 indicates that no fields were assigned.\n *    return -1 if an error occurs.\n */\nint vwscanf_s(const wchar_t *format, va_list argList)\n{\n    int retVal;                 /* If initialization causes  e838 */\n    SecFileStream fStr;\n    SECUREC_FILE_STREAM_FROM_STDIN(&fStr);\n#if SECUREC_ENABLE_SCANF_FILE\n    if (format == NULL || fStr.pf == NULL) {\n#else\n    if (format == NULL) {\n#endif\n        SECUREC_ERROR_INVALID_PARAMTER(\"vwscanf_s\");\n        return SECUREC_SCANF_EINVAL;\n    }\n\n#if SECUREC_ENABLE_SCANF_FILE\n    SECUREC_LOCK_STDIN(0, fStr.pf);\n#endif\n    retVal = SecInputSW(&fStr, format, argList);\n#if SECUREC_ENABLE_SCANF_FILE\n    SECUREC_UNLOCK_STDIN(0, fStr.pf);\n#endif\n    if (retVal < 0) {\n        SECUREC_ERROR_INVALID_PARAMTER(\"vwscanf_s\");\n        return SECUREC_SCANF_EINVAL;\n    }\n\n    return retVal;\n}\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/wcscat_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: wcscat_s  function\n * Create: 2014-02-25\n */\n\n#include \"securecutil.h\"\n\n/*\n * Befor this function, the basic parameter checking has been done\n */\nSECUREC_INLINE errno_t SecDoCatW(wchar_t *strDest, size_t destMax, const wchar_t *strSrc)\n{\n    size_t destLen;\n    size_t srcLen;\n    size_t maxCount; /* Store the maximum available count */\n\n    /* To calculate the length of a wide character, the parameter must be a wide character */\n    SECUREC_CALC_WSTR_LEN(strDest, destMax, &destLen);\n    maxCount = destMax - destLen;\n    SECUREC_CALC_WSTR_LEN(strSrc, maxCount, &srcLen);\n\n    if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) {\n        strDest[0] = L'\\0';\n        if (strDest + destLen <= strSrc && destLen == destMax) {\n            SECUREC_ERROR_INVALID_PARAMTER(\"wcscat_s\");\n            return EINVAL_AND_RESET;\n        }\n        SECUREC_ERROR_BUFFER_OVERLAP(\"wcscat_s\");\n        return EOVERLAP_AND_RESET;\n    }\n    if (srcLen + destLen >= destMax || strDest == strSrc) {\n        strDest[0] = L'\\0';\n        if (destLen == destMax) {\n            SECUREC_ERROR_INVALID_PARAMTER(\"wcscat_s\");\n            return EINVAL_AND_RESET;\n        }\n        SECUREC_ERROR_INVALID_RANGE(\"wcscat_s\");\n        return ERANGE_AND_RESET;\n    }\n    /* Copy single character length  include \\0 */\n    SECUREC_MEMCPY_WARP_OPT(strDest + destLen, strSrc, (srcLen + 1) * sizeof(wchar_t));\n    return EOK;\n}\n\n/*\n * <FUNCTION DESCRIPTION>\n *    The wcscat_s function appends a copy of the wide string pointed to by strSrc\n*      (including the terminating null wide character)\n *     to the end of the wide string pointed to by strDest.\n *    The arguments and return value of wcscat_s are wide-character strings.\n *\n *    The wcscat_s function appends strSrc to strDest and terminates the resulting\n *    string with a null character. The initial character of strSrc overwrites the\n *    terminating null character of strDest. wcscat_s will return EOVERLAP_AND_RESET if the\n *    source and destination strings overlap.\n *\n *    Note that the second parameter is the total size of the buffer, not the\n *    remaining size.\n *\n * <INPUT PARAMETERS>\n *    strDest              Null-terminated destination string buffer.\n *    destMax              Size of the destination string buffer.\n *    strSrc               Null-terminated source string buffer.\n *\n * <OUTPUT PARAMETERS>\n *    strDest               is updated\n *\n * <RETURN VALUE>\n *    EOK                   Success\n *    EINVAL                strDest is  NULL and destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN\n *    EINVAL_AND_RESET      (strDest unterminated and all other parameters are valid) or\n *                          (strDest != NULL and strSrc is NULL and destMax != 0\n *                           and destMax <= SECUREC_WCHAR_STRING_MAX_LEN)\n *    ERANGE                destMax > SECUREC_WCHAR_STRING_MAX_LEN or destMax is 0\n *    ERANGE_AND_RESET      strDest have not enough space  and all other parameters are valid  and not overlap\n *    EOVERLAP_AND_RESET     dest buffer and source buffer are overlapped and all  parameters are valid\n *\n *    If there is a runtime-constraint violation, strDest[0] will be set to the '\\0' when strDest and destMax valid\n */\nerrno_t wcscat_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc)\n{\n    if (destMax == 0 || destMax > SECUREC_WCHAR_STRING_MAX_LEN) {\n        SECUREC_ERROR_INVALID_RANGE(\"wcscat_s\");\n        return ERANGE;\n    }\n\n    if (strDest == NULL || strSrc == NULL) {\n        SECUREC_ERROR_INVALID_PARAMTER(\"wcscat_s\");\n        if (strDest != NULL) {\n            strDest[0] = L'\\0';\n            return EINVAL_AND_RESET;\n        }\n        return EINVAL;\n    }\n\n    return SecDoCatW(strDest, destMax, strSrc);\n}\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/wcscpy_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: wcscpy_s  function\n * Create: 2014-02-25\n */\n\n#include \"securecutil.h\"\n\nSECUREC_INLINE errno_t SecDoCpyW(wchar_t *strDest, size_t destMax, const wchar_t *strSrc)\n{\n    size_t srcStrLen;\n    SECUREC_CALC_WSTR_LEN(strSrc, destMax, &srcStrLen);\n\n    if (srcStrLen == destMax) {\n        strDest[0] = L'\\0';\n        SECUREC_ERROR_INVALID_RANGE(\"wcscpy_s\");\n        return ERANGE_AND_RESET;\n    }\n    if (strDest == strSrc) {\n        return EOK;\n    }\n\n    if (SECUREC_STRING_NO_OVERLAP(strDest, strSrc, srcStrLen)) {\n        /* Performance optimization, srcStrLen is single character length  include '\\0' */\n        SECUREC_MEMCPY_WARP_OPT(strDest, strSrc, (srcStrLen + 1) * sizeof(wchar_t));\n        return EOK;\n    } else {\n        strDest[0] = L'\\0';\n        SECUREC_ERROR_BUFFER_OVERLAP(\"wcscpy_s\");\n        return EOVERLAP_AND_RESET;\n    }\n}\n\n/*\n * <FUNCTION DESCRIPTION>\n *   The wcscpy_s function copies the wide string pointed to by strSrc\n *   (including the terminating null wide character) into the array pointed to by strDest\n\n * <INPUT PARAMETERS>\n *    strDest               Destination string buffer\n *    destMax               Size of the destination string buffer.\n *    strSrc                Null-terminated source string buffer.\n *\n * <OUTPUT PARAMETERS>\n *    strDest               is updated.\n *\n * <RETURN VALUE>\n *    EOK                   Success\n *    EINVAL                strDest is  NULL and destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN\n *    EINVAL_AND_RESET      strDest != NULL and strSrc is NULL and destMax != 0\n *                          and destMax <= SECUREC_WCHAR_STRING_MAX_LEN\n *    ERANGE                destMax > SECUREC_WCHAR_STRING_MAX_LEN or destMax is 0\n *    ERANGE_AND_RESET      destMax <= length of strSrc and strDest != strSrc\n *                          and strDest != NULL and strSrc != NULL and destMax != 0\n *                          and destMax <= SECUREC_WCHAR_STRING_MAX_LEN and not overlap\n *    EOVERLAP_AND_RESET    dest buffer and source buffer are overlapped and destMax != 0\n *                          and destMax <= SECUREC_WCHAR_STRING_MAX_LEN\n *                          and strDest != NULL and strSrc !=NULL and strDest != strSrc\n *\n *    If there is a runtime-constraint violation, strDest[0] will be set to the '\\0' when strDest and destMax valid\n */\nerrno_t wcscpy_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc)\n{\n    if (destMax == 0 || destMax > SECUREC_WCHAR_STRING_MAX_LEN) {\n        SECUREC_ERROR_INVALID_RANGE(\"wcscpy_s\");\n        return ERANGE;\n    }\n    if (strDest == NULL || strSrc == NULL) {\n        SECUREC_ERROR_INVALID_PARAMTER(\"wcscpy_s\");\n        if (strDest != NULL) {\n            strDest[0] = L'\\0';\n            return EINVAL_AND_RESET;\n        }\n        return EINVAL;\n    }\n    return SecDoCpyW(strDest, destMax, strSrc);\n}\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/wcsncat_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: wcsncat_s  function\n * Create: 2014-02-25\n */\n\n#include \"securecutil.h\"\n\n/*\n * Befor this function, the basic parameter checking has been done\n */\nSECUREC_INLINE errno_t SecDoCatLimitW(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, size_t count)\n{\n    /* To calculate the length of a wide character, the parameter must be a wide character */\n    size_t destLen;\n    size_t srcLen;\n    SECUREC_CALC_WSTR_LEN(strDest, destMax, &destLen);\n    SECUREC_CALC_WSTR_LEN(strSrc, count, &srcLen);\n\n    if (SECUREC_CAT_STRING_IS_OVERLAP(strDest, destLen, strSrc, srcLen)) {\n        strDest[0] = L'\\0';\n        if (strDest + destLen <= strSrc && destLen == destMax) {\n            SECUREC_ERROR_INVALID_PARAMTER(\"wcsncat_s\");\n            return EINVAL_AND_RESET;\n        }\n        SECUREC_ERROR_BUFFER_OVERLAP(\"wcsncat_s\");\n        return EOVERLAP_AND_RESET;\n    }\n    if (srcLen + destLen >= destMax || strDest == strSrc) {\n        strDest[0] = L'\\0';\n        if (destLen == destMax) {\n            SECUREC_ERROR_INVALID_PARAMTER(\"wcsncat_s\");\n            return EINVAL_AND_RESET;\n        }\n        SECUREC_ERROR_INVALID_RANGE(\"wcsncat_s\");\n        return ERANGE_AND_RESET;\n    }\n    SECUREC_MEMCPY_WARP_OPT(strDest + destLen, strSrc, srcLen * sizeof(wchar_t)); /* no  terminator */\n    *(strDest + destLen + srcLen) = L'\\0';\n    return EOK;\n}\n\n/*\n * <FUNCTION DESCRIPTION>\n *    The wcsncat_s function appends not more than n successive wide characters\n *     (not including the terminating null wide character)\n *     from the array pointed to by strSrc to the end of the wide string pointed to by strDest.\n *\n *    The wcsncat_s function try to append the first D characters of strSrc to\n *    the end of strDest, where D is the lesser of count and the length of strSrc.\n *    If appending those D characters will fit within strDest (whose size is\n *    given as destMax) and still leave room for a null terminator, then those\n *    characters are appended, starting at the original terminating null of\n *    strDest, and a new terminating null is appended; otherwise, strDest[0] is\n *    set to the null character.\n *\n * <INPUT PARAMETERS>\n *    strDest               Null-terminated destination string.\n *    destMax               Size of the destination buffer.\n *    strSrc                Null-terminated source string.\n *    count                 Number of character to append, or truncate.\n *\n * <OUTPUT PARAMETERS>\n *    strDest               is updated\n *\n * <RETURN VALUE>\n *    EOK                   Success\n *    EINVAL                strDest is  NULL and destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN\n *    EINVAL_AND_RESET      (strDest unterminated and all other parameters are valid) or\n *                          (strDest != NULL and strSrc is NULL and destMax != 0 and\n *                           destMax <= SECUREC_WCHAR_STRING_MAX_LEN)\n *    ERANGE                destMax > SECUREC_WCHAR_STRING_MAX_LEN or destMax is 0\n *    ERANGE_AND_RESET      strDest have not enough space  and all other parameters are valid  and not overlap\n *    EOVERLAP_AND_RESET     dest buffer and source buffer are overlapped and all  parameters are valid\n *\n *    If there is a runtime-constraint violation, strDest[0] will be set to the '\\0' when strDest and destMax valid\n */\nerrno_t wcsncat_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, size_t count)\n{\n    if (destMax == 0 || destMax > SECUREC_WCHAR_STRING_MAX_LEN) {\n        SECUREC_ERROR_INVALID_RANGE(\"wcsncat_s\");\n        return ERANGE;\n    }\n    if (strDest == NULL || strSrc == NULL) {\n        SECUREC_ERROR_INVALID_PARAMTER(\"wcsncat_s\");\n        if (strDest != NULL) {\n            strDest[0] = L'\\0';\n            return EINVAL_AND_RESET;\n        }\n        return EINVAL;\n    }\n    if (count > SECUREC_WCHAR_STRING_MAX_LEN) {\n#ifdef  SECUREC_COMPATIBLE_WIN_FORMAT\n        if (count == ((size_t)(-1))) {\n            /* Windows internal functions may pass in -1 when calling this function */\n            return SecDoCatLimitW(strDest, destMax, strSrc, destMax);\n        }\n#endif\n        strDest[0] = L'\\0';\n        SECUREC_ERROR_INVALID_RANGE(\"wcsncat_s\");\n        return ERANGE_AND_RESET;\n    }\n    return SecDoCatLimitW(strDest, destMax, strSrc, count);\n}\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/wcsncpy_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: wcsncpy_s  function\n * Create: 2014-02-25\n */\n\n#include \"securecutil.h\"\n\nSECUREC_INLINE errno_t SecDoCpyLimitW(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, size_t count)\n{\n    size_t srcStrLen;\n    if (count < destMax) {\n        SECUREC_CALC_WSTR_LEN(strSrc, count, &srcStrLen);\n    } else {\n        SECUREC_CALC_WSTR_LEN(strSrc, destMax, &srcStrLen);\n    }\n    if (srcStrLen == destMax) {\n        strDest[0] = L'\\0';\n        SECUREC_ERROR_INVALID_RANGE(\"wcsncpy_s\");\n        return ERANGE_AND_RESET;\n    }\n    if (strDest == strSrc) {\n        return EOK;\n    }\n    if (SECUREC_STRING_NO_OVERLAP(strDest, strSrc, srcStrLen)) {\n        /* Performance optimization srcStrLen not include '\\0' */\n        SECUREC_MEMCPY_WARP_OPT(strDest, strSrc, srcStrLen * sizeof(wchar_t));\n        *(strDest + srcStrLen) = L'\\0';\n        return EOK;\n    } else {\n        strDest[0] = L'\\0';\n        SECUREC_ERROR_BUFFER_OVERLAP(\"wcsncpy_s\");\n        return EOVERLAP_AND_RESET;\n    }\n}\n\n/*\n * <FUNCTION DESCRIPTION>\n *    The wcsncpy_s function copies not more than n successive wide characters\n *     (not including the terminating null wide character)\n *     from the array pointed to by strSrc to the array pointed to by strDest\n *\n * <INPUT PARAMETERS>\n *    strDest             Destination string.\n *    destMax             The size of the destination string, in characters.\n *    strSrc              Source string.\n *    count                Number of characters to be copied.\n *\n * <OUTPUT PARAMETERS>\n *    strDest              is updated\n *\n * <RETURN VALUE>\n *    EOK                  Success\n *    EINVAL               strDest is  NULL and destMax != 0 and destMax <= SECUREC_WCHAR_STRING_MAX_LEN\n *    EINVAL_AND_RESET     strDest != NULL and strSrc is NULL and destMax != 0\n *                         and destMax <= SECUREC_WCHAR_STRING_MAX_LEN\n *    ERANGE               destMax > SECUREC_WCHAR_STRING_MAX_LEN or destMax is 0\n *    ERANGE_AND_RESET     count > SECUREC_WCHAR_STRING_MAX_LEN or\n *                         (destMax <= length of strSrc and destMax <= count and strDest != strSrc\n *                          and strDest != NULL and strSrc != NULL and destMax != 0 and\n *                          destMax <= SECUREC_WCHAR_STRING_MAX_LEN and not overlap)\n *    EOVERLAP_AND_RESET     dest buffer and source buffer are overlapped and  all  parameters are valid\n *\n *\n *    If there is a runtime-constraint violation, strDest[0] will be set to the '\\0' when strDest and destMax valid\n */\nerrno_t wcsncpy_s(wchar_t *strDest, size_t destMax, const wchar_t *strSrc, size_t count)\n{\n    if (destMax == 0 || destMax > SECUREC_WCHAR_STRING_MAX_LEN) {\n        SECUREC_ERROR_INVALID_RANGE(\"wcsncpy_s\");\n        return ERANGE;\n    }\n    if (strDest == NULL || strSrc == NULL) {\n        SECUREC_ERROR_INVALID_PARAMTER(\"wcsncpy_s\");\n        if (strDest != NULL) {\n            strDest[0] = L'\\0';\n            return EINVAL_AND_RESET;\n        }\n        return EINVAL;\n    }\n    if (count > SECUREC_WCHAR_STRING_MAX_LEN) {\n#ifdef SECUREC_COMPATIBLE_WIN_FORMAT\n        if (count == (size_t)(-1)) {\n            return SecDoCpyLimitW(strDest, destMax, strSrc, destMax - 1);\n        }\n#endif\n        strDest[0] = L'\\0';      /* Clear dest string */\n        SECUREC_ERROR_INVALID_RANGE(\"wcsncpy_s\");\n        return ERANGE_AND_RESET;\n    }\n\n    if (count == 0) {\n        strDest[0] = L'\\0';\n        return EOK;\n    }\n\n    return SecDoCpyLimitW(strDest, destMax, strSrc, count);\n}\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/wcstok_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: wcstok_s  function\n * Create: 2014-02-25\n */\n\n#include \"securecutil.h\"\n\nSECUREC_INLINE int SecIsInDelimitW(wchar_t ch, const wchar_t *strDelimit)\n{\n    const wchar_t *ctl = strDelimit;\n    while (*ctl != L'\\0' && *ctl != ch) {\n        ++ctl;\n    }\n    return (int)(*ctl != L'\\0');\n}\n\n/*\n * Find beginning of token (skip over leading delimiters).\n * Note that there is no token if this loop sets string to point to the terminal null.\n */\nSECUREC_INLINE wchar_t *SecFindBeginW(wchar_t *strToken, const wchar_t *strDelimit)\n{\n    wchar_t *token = strToken;\n    while (*token != L'\\0') {\n        if (SecIsInDelimitW(*token, strDelimit) != 0) {\n            ++token;\n            continue;\n        }\n        /* Don't find any delimiter in string header, break the loop */\n        break;\n    }\n    return token;\n}\n\n/*\n * Find the end of the token. If it is not the end of the string, put a null there.\n */\nSECUREC_INLINE wchar_t *SecFindRestW(wchar_t *strToken, const wchar_t *strDelimit)\n{\n    wchar_t *token = strToken;\n    while (*token != L'\\0') {\n        if (SecIsInDelimitW(*token, strDelimit) != 0) {\n            /* Find a delimiter, set string terminator */\n            *token = L'\\0';\n            ++token;\n            break;\n        }\n        ++token;\n    }\n    return token;\n}\n\n/*\n * Update Token wide character  function\n */\nSECUREC_INLINE wchar_t *SecUpdateTokenW(wchar_t *strToken, const wchar_t *strDelimit, wchar_t **context)\n{\n    /* Point to updated position.  Record string position for next search in the context */\n    *context = SecFindRestW(strToken, strDelimit);\n    /* Determine if a token has been found */\n    if (*context == strToken) {\n        return NULL;\n    }\n    return strToken;\n}\n\n/*\n * <NAME>\n *    wcstok_s\n *\n *\n * <FUNCTION DESCRIPTION>\n *   The  wcstok_s  function  is  the  wide-character  equivalent  of the strtok_s function\n *\n * <INPUT PARAMETERS>\n *    strToken               String containing token or tokens.\n *    strDelimit             Set of delimiter characters.\n *    context                Used to store position information between calls to\n *                               wcstok_s.\n *\n * <OUTPUT PARAMETERS>\n *    context               is updated\n * <RETURN VALUE>\n *   The  wcstok_s  function  is  the  wide-character  equivalent  of the strtok_s function\n */\nwchar_t *wcstok_s(wchar_t *strToken, const wchar_t *strDelimit, wchar_t **context)\n{\n    wchar_t *orgToken = strToken;\n    /* Validation section */\n    if (context == NULL || strDelimit == NULL) {\n        return NULL;\n    }\n    if (orgToken == NULL && *context == NULL) {\n        return NULL;\n    }\n    /* If string==NULL, continue with previous string */\n    if (orgToken == NULL) {\n        orgToken = *context;\n    }\n    orgToken = SecFindBeginW(orgToken, strDelimit);\n    return SecUpdateTokenW(orgToken, strDelimit, context);\n}\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/wmemcpy_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: wmemcpy_s  function\n * Create: 2014-02-25\n */\n/*\n * [Standardize-exceptions] Use unsafe function: Portability\n * [reason] Use unsafe function to implement security function to maintain platform compatibility.\n *          And sufficient input validation is performed before calling\n */\n\n#include \"securecutil.h\"\n\n/*\n * <FUNCTION DESCRIPTION>\n *   The wmemcpy_s function copies n successive wide characters\n *    from the object pointed to by src into the object pointed to by dest.t.\n *\n * <INPUT PARAMETERS>\n *    dest                   Destination buffer.\n *    destMax                Size of the destination buffer.\n *    src                     Buffer to copy from.\n *    count                  Number of characters to copy.\n *\n * <OUTPUT PARAMETERS>\n *    dest buffer            is updated.\n *\n * <RETURN VALUE>\n *    EOK                    Success\n *    EINVAL                 dest is  NULL  and destMax != 0 and count <= destMax\n *                           and destMax <= SECUREC_WCHAR_MEM_MAX_LEN\n *    EINVAL_AND_RESET       dest != NULL and src is NULL and destMax != 0\n *                           and destMax <= SECUREC_WCHAR_MEM_MAX_LEN and count <= destMax\n *    ERANGE                 destMax > SECUREC_WCHAR_MEM_MAX_LEN or destMax is 0 or\n *                           (count > destMax and dest is  NULL and destMax != 0\n *                            and destMax <= SECUREC_WCHAR_MEM_MAX_LEN)\n *    ERANGE_AND_RESET       count > destMax and dest  !=  NULL and destMax != 0\n *                           and destMax <= SECUREC_WCHAR_MEM_MAX_LEN\n *    EOVERLAP_AND_RESET     dest buffer and source buffer are overlapped and\n *                           count <= destMax destMax != 0 and destMax <= SECUREC_WCHAR_MEM_MAX_LEN\n *                           and dest  !=  NULL  and src != NULL and dest != src\n *\n *    if an error occurred, dest will be filled with 0 when dest and destMax valid .\n *    If the source and destination overlap, the behavior of wmemcpy_s is undefined.\n *    Use wmemmove_s to handle overlapping regions.\n */\nerrno_t wmemcpy_s(wchar_t *dest, size_t destMax, const wchar_t *src, size_t count)\n{\n    if (destMax == 0 || destMax > SECUREC_WCHAR_MEM_MAX_LEN) {\n        SECUREC_ERROR_INVALID_PARAMTER(\"wmemcpy_s\");\n        return ERANGE;\n    }\n    if (count > destMax) {\n        SECUREC_ERROR_INVALID_PARAMTER(\"wmemcpy_s\");\n        if (dest != NULL) {\n            (void)SECUREC_MEMSET_FUNC_OPT(dest, 0, destMax * sizeof(wchar_t));\n            return ERANGE_AND_RESET;\n        }\n        return ERANGE;\n    }\n    return memcpy_s(dest, destMax * sizeof(wchar_t), src, count * sizeof(wchar_t));\n}\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/wmemmove_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: wmemmove_s  function\n * Create: 2014-02-25\n */\n/*\n * [Standardize-exceptions] Use unsafe function: Portability\n * [reason] Use unsafe function to implement security function to maintain platform compatibility.\n *          And sufficient input validation is performed before calling\n */\n\n#include \"securecutil.h\"\n\n/*\n * <FUNCTION DESCRIPTION>\n *   The wmemmove_s function copies n successive wide characters from the object pointed\n *   to by src into the object pointed to by dest.\n *\n * <INPUT PARAMETERS>\n *    dest                     Destination buffer.\n *    destMax                  Size of the destination buffer.\n *    src                      Source object.\n *    count                    Number of bytes or character to copy.\n *\n * <OUTPUT PARAMETERS>\n *    dest                     is updated.\n *\n * <RETURN VALUE>\n *    EOK                      Success\n *    EINVAL                   dest is  NULL and destMax != 0 and count <= destMax\n *                             and destMax <= SECUREC_WCHAR_MEM_MAX_LEN\n *    EINVAL_AND_RESET         dest != NULL and src is NULL and destMax != 0\n *                             and destMax <= SECUREC_WCHAR_MEM_MAX_LEN and count <= destMax\n *    ERANGE                   destMax > SECUREC_WCHAR_MEM_MAX_LEN or destMax is 0 or\n *                             (count > destMax and dest is  NULL and destMax != 0\n *                             and destMax <= SECUREC_WCHAR_MEM_MAX_LEN)\n *    ERANGE_AND_RESET        count > destMax and dest  !=  NULL and destMax != 0\n *                             and destMax <= SECUREC_WCHAR_MEM_MAX_LEN\n *\n *\n *     If an error occurred, dest will  be filled with 0 when dest and destMax valid.\n *     If some regions of the source area and the destination overlap, wmemmove_s\n *     ensures that the original source bytes in the overlapping region are copied\n *     before being overwritten\n */\nerrno_t wmemmove_s(wchar_t *dest, size_t destMax, const wchar_t *src, size_t count)\n{\n    if (destMax == 0 || destMax > SECUREC_WCHAR_MEM_MAX_LEN) {\n        SECUREC_ERROR_INVALID_PARAMTER(\"wmemmove_s\");\n        return ERANGE;\n    }\n    if (count > destMax) {\n        SECUREC_ERROR_INVALID_PARAMTER(\"wmemmove_s\");\n        if (dest != NULL) {\n            (void)SECUREC_MEMSET_FUNC_OPT(dest, 0, destMax * sizeof(wchar_t));\n            return ERANGE_AND_RESET;\n        }\n        return ERANGE;\n    }\n    return memmove_s(dest, destMax * sizeof(wchar_t), src, count * sizeof(wchar_t));\n}\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/ffi/third_party_bounds_checking_function/src/wscanf_s.c",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved.\n * Licensed under Mulan PSL v2.\n * You can use this software according to the terms and conditions of the Mulan PSL v2.\n * You may obtain a copy of Mulan PSL v2 at:\n *          http://license.coscl.org.cn/MulanPSL2\n * THIS SOFTWARE IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OF ANY KIND,\n * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,\n * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.\n * See the Mulan PSL v2 for more details.\n * Description: wscanf_s  function\n * Create: 2014-02-25\n */\n\n#include \"securec.h\"\n\n/*\n * <NAME>\n * <FUNCTION DESCRIPTION>\n *    The  wscanf_s  function  is  the  wide-character  equivalent  of the scanf_s function\n *    The wscanf_s function reads data from the standard input stream stdin and\n *    writes the data into the location that's given by argument. Each argument\n *    must be a pointer to a variable of a type that corresponds to a type specifier\n *    in format. If copying occurs between strings that overlap, the behavior is\n *    undefined.\n *\n * <INPUT PARAMETERS>\n *    format                  Format control string.\n *    ...                         Optional arguments.\n *\n * <OUTPUT PARAMETERS>\n *    ...                     the converted value stored in user assigned address\n *\n * <RETURN VALUE>\n *    Returns the number of fields successfully converted and assigned;\n *    the return value does not include fields that were read but not assigned.\n *    A return value of 0 indicates that no fields were assigned.\n *    return -1 if an error occurs.\n */\nint wscanf_s(const wchar_t *format, ...)\n{\n    int ret;                    /* If initialization causes  e838 */\n    va_list argList;\n\n    va_start(argList, format);\n    ret = vwscanf_s(format, argList);\n    va_end(argList);\n    (void)argList;              /* To clear e438 last value assigned not used , the compiler will optimize this code */\n\n    return ret;\n}\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/src/ffi.cj",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2024-2025. All rights reserved.\n */\n\npackage formula\n\nforeign {\n    func memcpy_s(dest: CPointer<UInt8>, destsz: Int64, src: CPointer<UInt8>, count: Int64): CPointer<UInt8>\n\n    /* LaTeX */\n    func LaTeX_init(rootDir: CString): Unit\n    func LaTeX_release(): Unit\n    func LaTeX_parse(ltx: CString, width: Int32, textSize: Float32, lineSpace: Float32, foreground: UInt32): CPointer<UInt8>\n    func LaTeX_setDebug(debug: Bool): Unit\n\n    /* TeXRender */\n    func TeXRender_draw(r: CPointer<UInt8>, bitmap: CPointer<UInt8>, x: Int32, y: Int32, background: UInt32): Unit\n    func TeXRender_getTextSize(r: CPointer<UInt8>): Float32\n    func TeXRender_getHeight(r: CPointer<UInt8>): Int32\n    func TeXRender_getDepth(r: CPointer<UInt8>): Int32\n    func TeXRender_getWidth(r: CPointer<UInt8>): Int32\n    func TeXRender_getBaseline(r: CPointer<UInt8>): Float32\n    func TeXRender_setTextSize(r: CPointer<UInt8>, size: Float32): Unit\n    func TeXRender_setForeground(r: CPointer<UInt8>, c: Int32): Unit\n    func TeXRender_setWidth(r: CPointer<UInt8>, width: UInt32, align: UInt32): Unit\n    func TeXRender_setHeight(r: CPointer<UInt8>, height: UInt32, align: UInt32): Unit\n    func TeXRender_finalize(r: CPointer<UInt8>): Unit\n    func TeXRender_toBitmap(r: CPointer<UInt8>, bitmap: CPointer<UInt8>, colorFormat: Int32): UInt8Data\n    func TeXRender_getMapData(r: CPointer<UInt8>, bitmap: CPointer<UInt8>, colorFormat: Int32): UInt8Data\n\n    /* Graphics2D */\n    func initGraphics2D_ffi(x: UInt32, y: UInt32, colorFormat: Int32): CPointer<UInt8>\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/src/graphic_2d.cj",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2024-2025. All rights reserved.\n */\n\npackage formula\n\npublic enum ColorFormat {\n    | COLOR_FORMAT_RGB_565 | COLOR_FORMAT_BGRA_8888\n}\nlet RGB_565: Int32 = 2\nlet BGRA_8888: Int32 = 5\n\npublic class Graphic2D {\n    var g2: CPointer<UInt8>\n    var h: UInt32\n    var w: UInt32\n    var cf: Int32\n\n    public prop width: UInt32 {\n        get() {\n            w\n        }\n    }\n\n    public prop height: UInt32 {\n        get() {\n            h\n        }\n    }\n\n    public init(render: Render, colorFormat: ColorFormat) {\n        var w = render.getWidth()\n        var h = render.getHeight()\n        var textSize = render.getTextSize()\n        this.w = w + UInt32(textSize / 9.0) + 1\n        this.h = h + UInt32(textSize / 9.0) + 1\n        this.cf = match (colorFormat) {\n            case COLOR_FORMAT_RGB_565 => RGB_565\n            case COLOR_FORMAT_BGRA_8888 => BGRA_8888\n        }\n        g2 = unsafe { initGraphics2D_ffi(this.w, this.h, this.cf) }\n    }\n\n    public func getG2(): CPointer<UInt8> {\n        return g2\n    }\n\n    public func getColorFormat(): Int32 {\n        return cf\n    }\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/src/latex.cj",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2024-2025. All rights reserved.\n */\n\npackage formula\n\npublic class LaTeX {\n    public init(rootDir: String) {\n        unsafe {\n            var cstr =  LibC.mallocCString(rootDir)\n            LaTeX_init(cstr)\n            LibC.free(cstr)\n        }\n    }\n\n    public func release(): Unit {\n        unsafe { LaTeX_release() }\n    }\n\n    public func parse(ltx: String, width: Int32, textSize: Float32, lineSpace: Float32, foreground: UInt32): Render {\n        unsafe {\n            var cstr =  LibC.mallocCString(ltx)\n            var ptr = LaTeX_parse(cstr, width, textSize, lineSpace, foreground)\n            if (ptr.isNull()) {\n                LibC.free(cstr)\n                throw Exception(\"parse failed, CPointer is null!\")\n            }\n            LibC.free(cstr)\n            Render(ptr)\n        }\n    }\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/src/render.cj",
    "content": "/*\n * Copyright (c) Huawei Technologies Co., Ltd. 2024-2025. All rights reserved.\n */\n\npackage formula\n\n@C\nstruct UInt8Data {\n    var data: CPointer<UInt8> = CPointer<UInt8>()\n    var len: Int64 = 0\n}\n\npublic class Render {\n    var nativePtr: CPointer<UInt8>\n\n    public init(ptr: CPointer<UInt8>) {\n        nativePtr = ptr\n    }\n\n    public func draw(g2: Graphic2D, background: UInt32): Unit {\n        unsafe { TeXRender_draw(nativePtr, g2.getG2(), 0, 0, background) }\n    }\n\n    public func getTextSize(): Float32 {\n        return unsafe { TeXRender_getTextSize(nativePtr) }\n    }\n\n    public func getHeight(): UInt32 {\n        return unsafe { UInt32(TeXRender_getHeight(nativePtr)) }\n    }\n\n    public func getWidth(): UInt32 {\n        return unsafe { UInt32(TeXRender_getWidth(nativePtr)) }\n    }\n\n    public func finalize(): Unit {\n        return unsafe { TeXRender_finalize(nativePtr) }\n    }\n\n    public func toBitmap(g2: Graphic2D): Array<UInt8> {\n        unsafe {\n            var bitmapData =  TeXRender_toBitmap(nativePtr, g2.getG2(), g2.getColorFormat())\n            var array = Array<UInt8>(bitmapData.len, repeat: 0)\n            var cph = acquireArrayRawData(array)\n            memcpy_s(cph.pointer, bitmapData.len, bitmapData.data, bitmapData.len)\n            releaseArrayRawData(cph)\n            LibC.free(bitmapData.data)\n            return array\n        }\n    }\n\n    public func getMapData(g2: Graphic2D): Array<UInt8> {\n        if (g2.getColorFormat() == RGB_565) {\n            throw Exception(\"COLOR_FORMAT_RGB_565 format not supported!\")\n        }\n        unsafe {\n            var bitmapData =  TeXRender_getMapData(nativePtr, g2.getG2(), g2.getColorFormat())\n            var array = Array<UInt8>(bitmapData.len, repeat: 0)\n            var cph = acquireArrayRawData(array)\n            memcpy_s(cph.pointer, bitmapData.len, bitmapData.data, bitmapData.len)\n            releaseArrayRawData(cph)\n            LibC.free(bitmapData.data)\n            return array\n        }\n    }\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/DOC/test.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\r\n// EXEC: ./main\r\n\r\nimport formula.*\r\nimport std.fs.*\r\n\r\nmain(): Int64 {\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\sideset{^\\backprime}{'}\\sum_{x=1}^{\\infty} x\\sideset{a_1^2}{}\\sum_{x=1}^\\infty x_0\r\n\\\\\r\n\\sideset{_\\text{left bottom}'''}{_{\\text{right bottom}}'''}\\sum_{\\text{quite long text}}^\\infty x\r\n\\\\\r\n\\sideset{}{'}\r\n\\sum_{n<k,\\;\\text{$n$ odd}} nE_n\r\n\\\\\r\n\\sideset{}{'}\r\n\\sum^{n<k,\\;\\text{$n$ odd}} nE_n\r\n\\\\\r\nM_x''' M'''_x M^{'''}_x M_x{'''} M^{\\prime\\backprime}\r\n\"###\r\n    var r = latex.parse(str, 2000, 40.0, 10.0, 0xFF000000)\r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n\r\n    var arr = r.toBitmap(g2)\r\n\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n\r\n    return 0\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/c_test1.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\n// sources_file:..\\..\\lib\\liblatex.so\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class c_test_test {\r\n    @TestCase\r\n    func c_testr_01(): Unit {\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\begin{array}{lr}\r\n  \\mbox{\\textcolor{Blue}{Russian}}&\\mbox{\\textcolor{Melon}{Greek}}\\\\\r\n  \\mbox{привет мир}&\\mbox{γειά κόσμο}\\\\\r\n  \\mbox{привет мир}&\\mbox{γειά κόσμο}\\\\\r\n  \\mathbf{\\mbox{привет мир}}&\\mathbf{\\mbox{γειά κόσμο}}\\\\\r\n  \\mathit{\\mbox{привет мир}}&\\mathit{\\mbox{γειά κόσμο}}\\\\\r\n  \\mathsf{\\mbox{привет мир}}&\\mathsf{\\mbox{γειά κόσμο}}\\\\\r\n  \\mathtt{\\mbox{привет мир}}&\\mathtt{\\mbox{γειά κόσμο}}\\\\\r\n  \\mathbf{\\mathit{\\mbox{привет мир}}}&\\mathbf{\\mathit{\\mbox{γειά κόσμο}}}\\\\\r\n  \\mathbf{\\mathsf{\\mbox{привет мир}}}&\\mathbf{\\mathsf{\\mbox{γειά κόσμο}}}\\\\\r\n  \\mathsf{\\mathit{\\mbox{привет мир}}}&\\mathsf{\\mathit{\\mbox{γειά κόσμο}}}\\\\\r\n  &\\\\\r\n  \\mbox{\\textcolor{Salmon}{Bulgarian}}&\\mbox{\\textcolor{Tan}{Serbian}}\\\\\r\n  \\mbox{здравей свят}&\\mbox{Хелло уорлд}\\\\\r\n  &\\\\\r\n  \\mbox{\\textcolor{Turquoise}{Bielorussian}}&\\mbox{\\textcolor{LimeGreen}{Ukrainian}}\\\\\r\n  \\mbox{прывітаньне Свет}&\\mbox{привіт світ}\\\\\r\n\\end{array}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)         \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n    @Assert(r.getTextSize(),40.0)  \r\n    var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    println(g2.width)\r\n    println(g2.height)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n}\r\n}\r\n\r\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/c_test10.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class c_test_test {\r\n    @TestCase\r\n    func c_testr_010(): Unit {\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\frac{\\sum_{n > 0} z^n}\r\n{\\prod_{1\\leq k\\leq n} (1-q^k)}\r\n\\\\\r\n\\frac{{\\displaystyle\\sum_{n > 0} z^n}}\r\n{{\\displaystyle\\prod_{1\\leq k\\leq n} (1-q^k)}}\r\n\\\\\r\n\\frac{{\\displaystyle\\sum\\nolimits_{n> 0} z^n}}\r\n{{\\displaystyle\\prod\\nolimits_{1\\leq k\\leq n} (1-q^k)}}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)       \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n\r\n    var arr = r.toBitmap(g2)\r\n\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/c_test11.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class c_test_test {\r\n    @TestCase\r\n    func c_testr_012(): Unit {\r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\cfrac{1}{\\sqrt{2}+\r\n\\cfrac{1}{\\sqrt{2}+\r\n\\cfrac{1}{\\sqrt{2}+\\dotsb\r\n}}}\r\n\\\\\r\n\\biggl[\r\n\\sum_i a_i\\biggl\\lvert\\sum_j x_{ij}\r\n\\biggr\\rvert^p\\biggr]^{1/p}\r\n\\\\\r\n\\biggl[\r\n\\sum_i a_i\\Bigl\\lvert\\sum_j x_{ij}\r\n\\Bigr\\rvert^p\\biggr]^{1/p}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)        \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n\r\n    var arr = r.toBitmap(g2)\r\n\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/c_test2.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class c_test_test {\r\n    @TestCase\r\n    func c_testr_02(): Unit {\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\begin{array}{l}\r\n  \\forall\\varepsilon\\in\\mathbb{R}_+^*\\ \\exists\\eta>0\\ |x-x_0|\\leq\\eta\\Longrightarrow|f(x)-f(x_0)|\\leq\\varepsilon\\\\\r\n  \\det\r\n  \\begin{bmatrix}\r\n      a_{11}&a_{12}&\\cdots&a_{1n}\\\\\r\n      a_{21}&\\ddots&&\\vdots\\\\\r\n      \\vdots&&\\ddots&\\vdots\\\\\r\n      a_{n1}&\\cdots&\\cdots&a_{nn}\r\n  \\end{bmatrix}\r\n  \\overset{\\mathrm{def}}{=}\\sum_{\\sigma\\in\\mathfrak{S}_n}\\varepsilon(\\sigma)\\prod_{k=1}^n a_{k\\sigma(k)}\\\\\r\n  \\sideset{_\\alpha^\\beta}{_\\gamma^\\delta}{\\begin{pmatrix}a&b\\\\c&d\\end{pmatrix}}\\\\\r\n  \\int_0^\\infty{x^{2n} e^{-a x^2}\\,dx} = \\frac{2n-1}{2a} \r\n      \\int_0^\\infty{x^{2(n-1)} e^{-a x^2}\\,dx} = \\frac{(2n-1)!!}{2^{n+1}} \\sqrt{\\frac{\\pi}{a^{2n+1}}}\\\\\r\n  \\int_a^b{f(x)\\,dx} = (b - a) \\sum\\limits_{n = 1}^\\infty  \r\n      {\\sum\\limits_{m = 1}^{2^n  - 1} {\\left( { - 1} \\right)^{m + 1} } } 2^{ - n} f(a + m\\left( {b - a} \\right)2^{-n} )\\\\\r\n  \\int_{-\\pi}^{\\pi} \\sin(\\alpha x) \\sin^n(\\beta x) dx = \\textstyle{\\left \\{\r\n      \\begin{array}{cc}\r\n          (-1)^{(n+1)/2} (-1)^m \\frac{2 \\pi}{2^n} \\binom{n}{m} & n \\mbox{ odd},\\ \\alpha = \\beta (2m-n) \\\\\r\n          0 & \\mbox{otherwise} \\\\ \\end{array} \\right .}\\\\\r\n  L = \\int_a^b \\sqrt{ \\left|\\sum_{i,j=1}^ng_{ij}(\\gamma(t))\\left(\\frac{d}{dt}x^i\\circ\\gamma(t)\\right)\r\n      \\left(\\frac{d}{dt}x^j\\circ\\gamma(t)\\right)\\right|}\\,dt\\\\\r\n  \\begin{array}{rl}\r\n      s &= \\int_a^b\\left\\|\\frac{d}{dt}\\vec{r}\\,(u(t),v(t))\\right\\|\\,dt \\\\\r\n      &= \\int_a^b \\sqrt{u'(t)^2\\,\\vec{r}_u\\cdot\\vec{r}_u + 2u'(t)v'(t)\\, \\vec{r}_u\\cdot\r\n          \\vec{r}_v+ v'(t)^2\\,\\vec{r}_v\\cdot\\vec{r}_v}\\,\\,\\, dt. \r\n  \\end{array}\\\\\r\n\\end{array}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0)        \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n    var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n\r\n    var arr = r.toBitmap(g2)\r\n\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/c_test222222222.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\n// sources_file:..\\..\\lib\\liblatex.so\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class c_test_test {\r\n    @TestCase\r\n    func c_testr_01(): Unit {\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\begin{align*}\r\n\\left(x-1\\right)\\left(x+3\\right) \r\n\\end{align*}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)         \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n    @Assert(r.getTextSize(),40.0)  \r\n    var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    println(g2.width)\r\n    println(g2.height)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n}\r\n}\r\n\r\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/c_test3.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class c_test_test {\r\n    @TestCase\r\n    func c_testr_03(): Unit {\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\definecolor{gris}{gray}{0.9}\r\n\\definecolor{noir}{rgb}{0,0,0}\r\n\\definecolor{bleu}{rgb}{0,0,1}\r\n\\fatalIfCmdConflict{false}\r\n\\newcommand{\\pa}{\\left|}\r\n\\begin{array}{c}\r\n  \\LaTeX\\\\\r\n  \\begin{split}\r\n      &Тепловой\\ поток\\ \\mathrm{Тепловой\\ поток}\\ \\mathtt{Тепловой\\ поток}\\\\\r\n      &\\boldsymbol{\\mathrm{Тепловой\\ поток}}\\ \\mathsf{Тепловой\\ поток}\\\\\r\n      |I_2| &= \\pa\\int_0^T\\psi(t)\\left\\{ u(a,t)-\\int_{\\gamma(t)}^a \\frac{d\\theta}{k} (\\theta,t) \\int_a^\\theta c(\\xi) \r\n          u_t (\\xi,t)\\,d\\xi\\right\\}dt\\right|\\\\\r\n      &\\le C_6 \\Bigg|\\pa f \\int_\\Omega \\pa\\widetilde{S}^{-1,0}_{a,-}\r\n          W_2(\\Omega, \\Gamma_1)\\right|\\ \\right|\\left| |u|\\overset{\\circ}{\\to} W_2^{\\widetilde{A}}(\\Omega\\Gamma_r,T)\\right|\\Bigg|\\\\\r\n      &\\\\\r\n      &\\begin{pmatrix}\r\n          \\alpha&\\beta&\\gamma&\\delta\\\\\r\n          \\aleph&\\beth&\\gimel&\\daleth\\\\\r\n          \\mathfrak{A}&\\mathfrak{B}&\\mathfrak{C}&\\mathfrak{D}\\\\\r\n          \\boldsymbol{\\mathfrak{a}}&\\boldsymbol{\\mathfrak{b}}&\\boldsymbol{\\mathfrak{c}}&\\boldsymbol{\\mathfrak{d}}\r\n      \\end{pmatrix}\r\n      \\quad{(a+b)}^{\\frac{n}{2}}=\\sqrt{\\sum_{k=0}^n\\tbinom{n}{k}a^kb^{n-k}}\\quad \r\n          \\Biggl(\\biggl(\\Bigl(\\bigl(()\\bigr)\\Bigr)\\biggr)\\Biggr)\\\\\r\n      &\\forall\\varepsilon\\in\\mathbb{R}_+^*\\ \\exists\\eta>0\\ |x-x_0|\\leq\\eta\\Longrightarrow|f(x)-f(x_0)|\\leq\\varepsilon\\\\\r\n      &\\det\r\n      \\begin{bmatrix}\r\n          a_{11}&a_{12}&\\cdots&a_{1n}\\\\\r\n          a_{21}&\\ddots&&\\vdots\\\\\r\n          \\vdots&&\\ddots&\\vdots\\\\\r\n          a_{n1}&\\cdots&\\cdots&a_{nn}\r\n      \\end{bmatrix}\r\n      \\overset{\\mathrm{def}}{=}\\sum_{\\sigma\\in\\mathfrak{S}_n}\\varepsilon(\\sigma)\\prod_{k=1}^n a_{k\\sigma(k)}\\\\\r\n      &\\Delta f(x,y)=\\frac{\\partial^2f}{\\partial x^2}+\\frac{\\partial^2f}{\\partial y^2}\\qquad\\qquad \\fcolorbox{noir}{gris}\r\n          {n!\\underset{n\\rightarrow+\\infty}{\\sim} {\\left(\\frac{n}{e}\\right)}^n\\sqrt{2\\pi n}}\\\\\r\n      &\\sideset{_\\alpha^\\beta}{_\\gamma^\\delta}{\r\n      \\begin{pmatrix}\r\n          a&b\\\\\r\n          c&d\r\n      \\end{pmatrix}}\r\n      \\xrightarrow[T]{n\\pm i-j}\\sideset{^t}{}A\\xleftarrow{\\overrightarrow{u}\\wedge\\overrightarrow{v}}\r\n          \\underleftrightarrow{\\iint_{\\mathds{R}^2}e^{-\\left(x^2+y^2\\right)}\\,\\mathrm{d}x\\mathrm{d}y}\r\n  \\end{split}\\\\\r\n  \\rotatebox{30}{\\sum_{n=1}^{+\\infty}}\\quad\\mbox{Mirror rorriM}\\reflectbox{\\mbox{Mirror rorriM}}\r\n\\end{array}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0)        \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n    var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n\r\n    var arr = r.toBitmap(g2)\r\n\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n}\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/c_test4.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class c_test_test {\r\n    @TestCase\r\n    func c_testr_04(): Unit {\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\begin{array}{|c|l|||r|c|}\r\n  \\hline\r\n  \\text{Matrix}&\\multicolumn{2}{|c|}{\\text{Multicolumns}}&\\text{Font sizes commands}\\cr\r\n  \\hline\r\n  \\begin{pmatrix}\r\n      \\alpha_{11}&\\cdots&\\alpha_{1n}\\cr\r\n      \\hdotsfor{3}\\cr\r\n      \\alpha_{n1}&\\cdots&\\alpha_{nn}\r\n  \\end{pmatrix}\r\n  &\\Large \\text{Large Right}&\\small \\text{small Left}&\\tiny \\text{tiny Tiny}\\cr\r\n  \\hline\r\n  \\multicolumn{4}{|c|}{\\Huge \\text{Huge Multicolumns}}\\cr\r\n  \\hline\r\n\\end{array}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)        \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n    var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n\r\n    var arr = r.toBitmap(g2)\r\n\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n\r\n  }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/c_test5.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class c_test_test {\r\n    @TestCase\r\n    func c_testr_05(): Unit {\r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\cornersize{0.2}\r\n\\begin{array}{cc}\r\n  \\fbox{\\text{A framed box with \\textdbend}}&\\shadowbox{\\text{A shadowed box}}\\cr\r\n  \\doublebox{\\text{A double framed box}}&\\ovalbox{\\text{An oval framed box}}\\cr\r\n\\end{array}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)       \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n\r\n    var arr = r.toBitmap(g2)\r\n\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n\r\n   }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/c_test6.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class c_test_test {\r\n    @TestCase\r\n    func c_testr_06(): Unit {                //定位中\r\n \r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\text{!\"#'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]\r\n^_`abcdefghijklmnopqrstuvwxyz{|}~\r\n\r\n     ¡¢£¤¥¦§¨©ª«¬­\r\n®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ}\r\n\"###\r\n    var r = latex.parse(str,2000000000, 40.0, 10.0, 0xFF000000)       \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n\r\n    var arr = r.toBitmap(g2)\r\n\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/c_test7.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class c_test_test {    //图片显示错误\r\n    @TestCase\r\n    func c_testr_07(): Unit {\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\newcolumntype{s}{>{\\color{#1234B6}}c}\r\n\\begin{array}{|c|c|c|s|}\r\n  \\hline\r\n  \\rowcolor{Tan}\\multicolumn{4}{|c|}{\\textcolor{white}{\\bold{\\text{Table Head}}}}\\\\\r\n  \\hline\r\n  \\text{Matrix}&\\multicolumn{2}{|c|}{\\text{Multicolumns}}&\\text{Font size commands}\\\\\r\n  \\hline\r\n  \\begin{pmatrix}\r\n      \\alpha_{11}&\\cdots&\\alpha_{1n}\\\\\r\n      \\hdotsfor{3}\\\\\r\n      \\alpha_{n1}&\\cdots&\\alpha_{nn}\r\n  \\end{pmatrix}\r\n  &\\large \\text{Left}&\\cellcolor{#00bde5}\\small \\textcolor{white}{\\text{\\bold{Right}}}\r\n  &\\small \\text{small Small}\\\\\r\n  \\hline\r\n  \\multicolumn{4}{|c|}{\\text{Table Foot}}\\\\\r\n  \\hline       \r\n\\end{array}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)      \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n\r\n    var arr = r.toBitmap(g2)\r\n\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/c_test8.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class c_test_test {\r\n    @TestCase\r\n    func c_testr_08(): Unit {\r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\rlap{\\overbrace{\\phantom{1 + a + b + \\cdots + z}}^{\\text{total + 1}}}\r\n1 + \\underbrace{a + b + \\cdots + z}_{\\text{total}}\r\n\\\\\r\n\\frac{a\\cancel{b}}{\\cancel{b}} = a;\r\n\\frac{a\\bcancel{b}}{\\bcancel{b}} = a;\r\n\\frac{a\\xcancel{b}}{\\xcancel{b}} = a;\r\n\\\\\r\n\\text{A long division: }\\longdiv{12345}{13}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)        \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n\r\n    var arr = r.toBitmap(g2)\r\n\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/c_test9.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class c_test_test {               //信号5异常\r\n    @TestCase\r\n    func c_testr_09(): Unit {\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\left\\{\r\n    \\begin{array}{l}\r\n    2a < -1,\\\\\r\n    a + 8 \\ge 5,\r\n    \\end{array}\r\n\\right.\r\n\\\\\r\nP_{r-j}=\\begin{cases}\r\n0& \\text{if $r-j$ is odd},\\\\\r\nr!\\,(-1)^{(r-j)/2}& \\text{if $r-j$ is even}.\r\n\\end{cases}\\text{Cases}\r\n\\\\\r\nP_{r-j}=\\left\\{\\begin{array}{@{}ll@{\\,}}\r\n0& \\text{if $r-j$ is odd},\\\\\r\nr!\\,(-1)^{(r-j)/2}& \\text{if $r-j$ is even}.\r\n\\end{array}\\right.\\text{Cases}\r\n\\\\\r\nP_{r-j}=\\begin{cases}\r\n4-x\\geq 0 \\\\\r\n3-x\\geq 1\r\n\\end{cases}\\text{Cases}\r\n\\\\\r\n\\left\\{\\begin{array}{@{}ll}\r\n1 & 2\\\\\r\n3 & 4\r\n\\end{array}\\right.\\text{Equation}\r\n\\\\\r\n\\left\\{\\begin{array}{l@{}l}\r\n1 & 2\\\\\r\n3 & 4\r\n\\end{array}\\right.\\text{Equation}\r\n\\\\\r\n\\left\\{\\begin{array}{ll@{}}\r\n1 & 2\\\\\r\n3 & 4\r\n\\end{array}\\right.\\text{Equation}\r\n\\\\\r\n\\begin{split}\r\nH_c&=\\frac{1}{2n} \\sum^n_{l=0}(-1)^{l}(n-{l})^{p-2}\r\n\\sum_{l _1+\\dots+ l _p=l}\\prod^p_{i=1} \\binom{n_i}{l _i}\\\\\r\n&\\quad\\cdot[(n-l )-(n_i-l _i)]^{n_i-l _i}\\cdot\r\n\\Bigl[(n-l )^2-\\sum^p_{j=1}(n_i-l _i)^2\\Bigr].\r\n\\end{split}\r\n\\\\\r\n\\begin{align}\r\nA_1&=N_0(\\lambda;\\Omega’)-\\phi(\\lambda;\\Omega’),\\\\\r\nA_2&=\\phi(\\lambda;\\Omega’)-\\phi(\\lambda;\\Omega),\\\\\r\n\\intertext{and}\r\nA_3&=\\mathcal{N}(\\lambda;\\omega).\r\n\\end{align}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)      \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/fortify_test1.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\n// sources_file:..\\..\\lib\\liblatex.so\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class c_test_test {\r\n    @TestCase\r\n    func c_testr_01(): Unit {\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\begin{align*}\r\n    \\sum_{t=t_0}^{t_k} Z_{i,t} \\leq \\tau \\forall i \\in V_0 \\label{Eq.3}  \\\\\r\n    0 \\leq y_{i,t}^P \\leq Q \\label{Eq.4} %% \r\n    \\\\\\dot{a},\\breve{a},\\widehat{a},\r\n    0 \\leq y_{i,t}^D \\leq Q \\label{Eq.5} %% \r\n    \\\\ \r\n\\end{align*}\r\n\"###\r\n    var r = latex.parse(str, 200000, 40.0, 10.0, 0xFF000000)         \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n    @Assert(r.getTextSize(),40.0)  \r\n    var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    println(g2.width)\r\n    println(g2.height)\r\n    r.draw(g2,0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n}\r\n}\r\n\r\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/fortify_test2.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\n// sources_file:..\\..\\lib\\liblatex.so\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class c_test_test {\r\n    @TestCase\r\n    func c_testr_01(): Unit {\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\begin{gather}\r\n    \\sum_{t=t_0}^{t_k} Z_{i,t} \\leq \\tau \\forall i \\in V_0 \\label{Eq.3}\r\n    \\\\\r\n    0 \\leq y_{i,t}^P \\leq min(Q_h, s_i^t) \\label{Eq.4} %% 拾取数目的上下限\r\n    \\\\\r\n    0 \\leq y_{i,t}^D \\leq min(Q_h, c_i-s_i^t) \\label{Eq.5} %% 卸载数目的上下限\r\n    \\\\\\dotplus, * \\ast, \\boxminus, \\ominus, \\circledcirc, \\bigodot\r\n\\end{gather}\r\n\"###\r\n    var r = latex.parse(str, 200, 40.0, 10.0, 0xFF000000)         \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n    @Assert(r.getTextSize(),40.0)  \r\n    var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    println(g2.width)\r\n    println(g2.height)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n}\r\n}\r\n\r\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/fortify_test3.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\n// sources_file:..\\..\\lib\\liblatex.so\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class c_test_test {\r\n    @TestCase\r\n    func c_testr_01(): Unit {\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\begin{align*}\r\n    \\sum_{t=t_0}^{t_k} Z_{i,t} \\leq \\tau \\forall i \\in V_0 \r\n    \\\\\r\n    0 \\leq y_{i,t}^P \\leq Q \r\n    \\\\\r\n    0 \\leq y_{i,t}^D \\leq Q \r\n    \\\\\\biguplus, \\nsupseteqq, \\supsetneq, \\Subset\r\n\\end{align*}\r\n\"###\r\n    var r = latex.parse(str, 200000, 40.0, 10.0, 0xFF000000)         \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n    @Assert(r.getTextSize(),40.0)  \r\n    var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    println(g2.width)\r\n    println(g2.height)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n}\r\n}\r\n\r\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/fortify_test4.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\n// sources_file:..\\..\\lib\\liblatex.so\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class c_test_test {\r\n    @TestCase\r\n    func c_testr_01(): Unit {\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n%split环境（用$对齐）(一个公式分为多行排版)\r\n\\begin{equation}\r\n\t\\begin{split}\r\n\t\\cos 2x &= \\cos^2 x - \\sin, \\overset{\\underset{\\mathrm{def}}{}}{=}^2 x\\\\\r\n\t        &= 2\\cos^2 x - 1, \\simeq, \\backsimeq,\\not\\ll \\nleqq,,\r\n\t\\end{split}\r\n\\end{equation}\r\n\"###\r\n    var r = latex.parse(str, 200000, 40.0, 10.0, 0xFF000000)         \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n    @Assert(r.getTextSize(),40.0)  \r\n    var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    println(g2.width)\r\n    println(g2.height)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n}\r\n}\r\n\r\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/fortify_test5.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\n// sources_file:..\\..\\lib\\liblatex.so\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class c_test_test {\r\n    @TestCase\r\n    func c_testr_01(): Unit {\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\begin{align}   \r\n\\left\\{    \\blacksquare\\bigtriangleup\\blacktriangleright\r\n\t\\begin{aligned} \\ldots \\cdots \\clubsuit \\between\r\n\tx&=eq1\\\\\\bigvee \\not\\operatorname{R}\r\n\ty&=eq2+, \\Lleftarrow1, \\Longleftarrow\\rightharpoondown\r\n\t\\end{aligned}\r\n\\right.\r\n%\r\n\\end{align}\r\n\"###\r\n    var r = latex.parse(str, 20000, 40.0, 10.0, 0xFF000000)         \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n    @Assert(r.getTextSize(),40.0)  \r\n    var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    println(g2.width)\r\n    println(g2.height)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n}\r\n}\r\n\r\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/later_test1.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class later_test {\r\n    @TestCase\r\n    func later_test01(): Unit {\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\begin{array}{lr}\\mbox{\\textcolor{Blue}{Russian}}&\\mbox{\\textcolor{Melon}{Greek}}\\\\\\mbox{ПРИВЕТ МИР}&\\mbox{ΓΕΙΆ ΚΌΣΜΟ}\\\\\\mbox{привет мир}&\\mbox{γειά κόσμο}\\\\\\mathbf{\\mbox{привет мир}}&\\mathbf{\\mbox{γειά κόσμο}}\\\\\\mathit{\\mbox{привет мир}}&\\mathit{\\mbox{γειά κόσμο}}\\\\\\mathsf{\\mbox{привет мир}}&\\mathsf{\\mbox{γειά κόσμο}}\\\\\\mathtt{\\mbox{привет мир}}&\\mathtt{\\mbox{γειά κόσμο}}\\\\\\mathbf{\\mathit{\\mbox{привет мир}}}&\\mathbf{\\mathit{\\mbox{γειά κόσμο}}}\\\\\\mathbf{\\mathsf{\\mbox{привет мир}}}&\\mathbf{\\mathsf{\\mbox{γειά κόσμο}}}\\\\\\mathsf{\\mathit{\\mbox{привет мир}}}&\\mathsf{\\mathit{\\mbox{γειά κόσμο}}}\\\\&\\\\\\mbox{\\textcolor{Salmon}{Bulgarian}}&\\mbox{\\textcolor{Tan}{Serbian}}\\\\\\mbox{здравей свят}&\\mbox{Хелло уорлд}\\\\&\\\\\\mbox{\\textcolor{Turquoise}{Bielorussian}}&\\mbox{\\textcolor{LimeGreen}{Ukrainian}}\\\\\\mbox{прывітаньне Свет}&\\mbox{привіт світ}\\\\\\end{array}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)       \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/later_test10.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class later_test {\r\n    @TestCase\r\n    func later_test010(): Unit {                //中文问题\r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\begin{array}{c} \r\n  a,b \\in R^{+} \\\\  \r\n  \\Rightarrow \\frac{a+b}{{2}}\\ge \\sqrt{ab} \\\\  \r\n  \\left( \\text{当且仅当}a=b\\text{时取“}=\\text{”号}\\right) \r\n\\end{array}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)   \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/later_test11.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class later_test {\r\n    @TestCase\r\n    func later_test011(): Unit {               \r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\left.\\begin{matrix} \r\n  m \\subset \\alpha ,n \\subset \\alpha ,m \\cap n=P \\\\  \r\n  a \\perp m,a \\perp n \r\n\\end{matrix}\\right\\}\\Rightarrow a \\perp \\alpha \r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)   \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/later_test12.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class later_test {\r\n    @TestCase\r\n    func later_test012(): Unit {                \r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\begin{array}{c} \r\n  H_{n}=\\frac{n}{\\sum \\limits_{i=1}^{n}\\frac{1}{x_{i}}}= \\frac{n}{\\frac{1}{x_{1}}+ \\frac{1}{x_{2}}+ \\cdots + \\frac{1}{x_{n}}} \\\\ G_{n}=\\sqrt[n]{\\prod \\limits_{i=1}^{n}x_{i}}= \\sqrt[n]{x_{1}x_{2}\\cdots x_{n}} \\\\ A_{n}=\\frac{1}{n}\\sum \\limits_{i=1}^{n}x_{i}=\\frac{x_{1}+ x_{2}+ \\cdots + x_{n}}{n} \\\\ Q_{n}=\\sqrt{\\sum \\limits_{i=1}^{n}x_{i}^{2}}= \\sqrt{\\frac{x_{1}^{2}+ x_{2}^{2}+ \\cdots + x_{n}^{2}}{n}} \\\\ H_{n}\\leq G_{n}\\leq A_{n}\\leq Q_{n} \r\n\\end{array}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)   \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/later_test13.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class later_test {\r\n    @TestCase\r\n    func later_test013(): Unit {                \r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\mathbf{V}_1 \\times \\mathbf{V}_2 =  \r\n\\begin{vmatrix}  \r\n  \\mathbf{i}& \\mathbf{j}& \\mathbf{k} \\\\  \r\n  \\frac{\\partial X}{\\partial u}& \\frac{\\partial Y}{\\partial u}& 0 \\\\  \r\n  \\frac{\\partial X}{\\partial v}& \\frac{\\partial Y}{\\partial v}& 0 \\\\  \r\n\\end{vmatrix} \r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)   \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/later_test14.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class later_test {\r\n    @TestCase\r\n    func later_test014(): Unit {                \r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\frac{\\sin A}{a}=\\frac{\\sin B}{b}=\\frac{\\sin C}{c}=\\frac{1}{2R} \r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)   \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/later_test15.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class later_test {\r\n    @TestCase\r\n    func later_test015(): Unit {                 \r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\begin{array}{c} \r\n  S= \\binom{N}{n},A_{k}=\\binom{M}{k}\\cdot \\binom{N-M}{n-k} \\\\ \r\n  P\\left ( A_{k}\\right ) = \\frac{\\binom{M}{k}\\cdot \\binom{N-M}{n-k}}{\\binom{N}{n}} \r\n\\end{array}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)   \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/later_test16.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class later_test {\r\n    @TestCase\r\n    func later_test016(): Unit {                //中文问题\r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\begin{array}{c} \r\n  \\text{若}\\left \\{a_{n}\\right \\}、\\left \\{b_{n}\\right \\}\\text{为等差数列}, \\\\ \r\n  \\text{则}\\left \\{a_{n}+ b_{n}\\right \\}\\text{为等差数列} \r\n\\end{array}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)   \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/later_test17.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class later_test {\r\n    @TestCase\r\n    func later_test017(): Unit {                \r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\begin{array}{l}  \r\n  \\nabla \\cdot \\mathbf{E} =\\cfrac{\\rho}{\\varepsilon _0}  \\\\  \r\n  \\nabla \\cdot \\mathbf{B} = 0 \\\\  \r\n  \\nabla \\times  \\mathbf{E} = -\\cfrac{\\partial \\mathbf{B}}{\\partial t }  \\\\  \r\n  \\nabla \\times  \\mathbf{B} = \\mu _0\\mathbf{J} + \\mu _0\\varepsilon_0 \\cfrac{\\partial \\mathbf{E}}{\\partial t }   \r\n\\end{array} \r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)   \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/later_test18.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class later_test {\r\n    @TestCase\r\n    func later_test018(): Unit {                 //中文问题\r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\begin{array}{c} \r\n  \\text{直角三角形中,直角边长a,b,斜边边长c} \\\\ \r\n  a^{2}+b^{2}=c^{2} \r\n\\end{array}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)   \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/later_test2.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class later_test {\r\n    @TestCase\r\n    func later_test02(): Unit {\r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\begin{array}{l}\\forall\\varepsilon\\in\\mathbb{R}_+^*\\ \\exists\\eta>0\\ |x-x_0|\\leq\\eta\\Longrightarrow|f(x)-f(x_0)|\\leq\\varepsilon\\\\\\det\\begin{bmatrix}a_{11}&a_{12}&\\cdots&a_{1n}\\\\a_{21}&\\ddots&&\\vdots\\\\\\vdots&&\\ddots&\\vdots\\\\a_{n1}&\\cdots&\\cdots&a_{nn}\\end{bmatrix}\\overset{\\mathrm{def}}{=}\\sum_{\\sigma\\in\\mathfrak{S}_n}\\varepsilon(\\sigma)\\prod_{k=1}^n a_{k\\sigma(k)}\\\\\\sideset{_\\alpha^\\beta}{_\\gamma^\\delta}{\\begin{pmatrix}a&b\\\\c&d\\end{pmatrix}}\\\\\\int_0^\\infty{x^{2n} e^{-a x^2}\\,dx} = \\frac{2n-1}{2a} \\int_0^\\infty{x^{2(n-1)} e^{-a x^2}\\,dx} = \\frac{(2n-1)!!}{2^{n+1}} \\sqrt{\\frac{\\pi}{a^{2n+1}}}\\\\\\int_a^b{f(x)\\,dx} = (b - a) \\sum\\limits_{n = 1}^\\infty  {\\sum\\limits_{m = 1}^{2^n  - 1} {\\left( { - 1} \\right)^{m + 1} } } 2^{ - n} f(a + m\\left( {b - a} \\right)2^{-n} )\\\\\\int_{-\\pi}^{\\pi} \\sin(\\alpha x) \\sin^n(\\beta x) dx = \\textstyle{\\left \\{ \\begin{array}{cc} (-1)^{(n+1)/2} (-1)^m \\frac{2 \\pi}{2^n} \\binom{n}{m} & n \\mbox{ odd},\\ \\alpha = \\beta (2m-n) \\\\ 0 & \\mbox{otherwise} \\\\ \\end{array} \\right .}\\\\L = \\int_a^b \\sqrt{ \\left|\\sum_{i,j=1}^ng_{ij}(\\gamma(t))\\left(\\frac{d}{dt}x^i\\circ\\gamma(t)\\right)\\left(\\frac{d}{dt}x^j\\circ\\gamma(t)\\right)\\right|}\\,dt\\\\\\begin{array}{rl} s &= \\int_a^b\\left\\|\\frac{d}{dt}\\vec{r}\\,(u(t),v(t))\\right\\|\\,dt \\\\ &= \\int_a^b \\sqrt{u'(t)^2\\,\\vec{r}_u\\cdot\\vec{r}_u + 2u'(t)v'(t)\\, \\vec{r}_u\\cdot\\vec{r}_v+ v'(t)^2\\,\\vec{r}_v\\cdot\\vec{r}_v}\\,\\,\\, dt. \\end{array}\\\\\\end{array}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)        \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/later_test3.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class later_test {\r\n    @TestCase\r\n    func later_test03(): Unit {\r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n    \\definecolor{gris}{gray}{0.9}\\definecolor{noir}{rgb}{0,0,0}\\definecolor{bleu}{rgb}{0,0,1}\\newcommand{\\pa}{\\left|}\\begin{array}{c}\\JLaTeXMath\\\\\\begin{split} &Тепловой\\ поток\\ \\mathrm{Тепловой\\ поток}\\ \\mathtt{Тепловой\\ поток}\\\\ &\\boldsymbol{\\mathrm{Тепловой\\ поток}}\\ \\mathsf{Тепловой\\ поток}\\\\|I_2| &= \\pa\\int_0^T\\psi(t)\\left\\{ u(a,t)-\\int_{\\gamma(t)}^a \\frac{d\\theta}{k} (\\theta,t) \\int_a^\\theta c(\\xi) u_t (\\xi,t)\\,d\\xi\\right\\}dt\\right|\\\\&\\le C_6 \\Bigg|\\pa f \\int_\\Omega \\pa\\widetilde{S}^{-1,0}_{a,-} W_2(\\Omega, \\Gamma_1)\\right|\\ \\right|\\left| |u|\\overset{\\circ}{\\to} W_2^{\\widetilde{A}}(\\Omega;\\Gamma_r,T)\\right|\\Bigg|\\\\&\\\\&\\textcolor{magenta}{\\mathrm{Produit\\ avec\\ Java\\ et\\ \\LaTeX\\ par\\ }\\mathscr{C}\\mathcal{A}\\mathfrak{L}\\mathbf{I}\\mathtt{X}\\mathbb{T}\\mathsf{E}}\\\\&\\begin{pmatrix}\\alpha&\\beta&\\gamma&\\delta\\\\\\aleph&\\beth&\\gimel&\\daleth\\\\\\mathfrak{A}&\\mathfrak{B}&\\mathfrak{C}&\\mathfrak{D}\\\\\\boldsymbol{\\mathfrak{a}}&\\boldsymbol{\\mathfrak{b}}&\\boldsymbol{\\mathfrak{c}}&\\boldsymbol{\\mathfrak{d}}\\end{pmatrix}\\quad{(a+b)}^{\\frac{n}{2}}=\\sqrt{\\sum_{k=0}^n\\tbinom{n}{k}a^kb^{n-k}}\\quad \\Biggl(\\biggl(\\Bigl(\\bigl(()\\bigr)\\Bigr)\\biggr)\\Biggr)\\\\&\\forall\\varepsilon\\in\\mathbb{R}_+^*\\ \\exists\\eta>0\\ |x-x_0|\\leq\\eta\\Longrightarrow|f(x)-f(x_0)|\\leq\\varepsilon\\\\&\\det\\begin{bmatrix}a_{11}&a_{12}&\\cdots&a_{1n}\\\\a_{21}&\\ddots&&\\vdots\\\\\\vdots&&\\ddots&\\vdots\\\\a_{n1}&\\cdots&\\cdots&a_{nn}\\end{bmatrix}\\overset{\\mathrm{def}}{=}\\sum_{\\sigma\\in\\mathfrak{S}_n}\\varepsilon(\\sigma)\\prod_{k=1}^n a_{k\\sigma(k)}\\\\&\\Delta f(x,y)=\\frac{\\partial^2f}{\\partial x^2}+\\frac{\\partial^2f}{\\partial y^2}\\qquad\\qquad \\fcolorbox{noir}{gris}{n!\\underset{n\\rightarrow+\\infty}{\\sim} {\\left(\\frac{n}{e}\\right)}^n\\sqrt{2\\pi n}}\\\\&\\sideset{_\\alpha^\\beta}{_\\gamma^\\delta}{\\begin{pmatrix}a&b\\\\c&d\\end{pmatrix}}\\xrightarrow[T]{n\\pm i-j}\\sideset{^t}{}A\\xleftarrow{\\overrightarrow{u}\\wedge\\overrightarrow{v}}\\underleftrightarrow{\\iint_{\\mathds{R}^2}e^{-\\left(x^2+y^2\\right)}\\,\\mathrm{d}x\\mathrm{d}y}\\end{split}\\\\\\rotatebox{30}{\\sum_{n=1}^{+\\infty}}\\quad\\mbox{Mirror rorriM}\\reflectbox{\\mbox{Mirror rorriM}}\\end{array}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)       \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/later_test4.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class later_test {\r\n    @TestCase\r\n    func later_test04(): Unit {\r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\begin{array}{|c|c|c|c|}\r\n\\multicolumn{4}{c}{\\shadowbox{\\text{\\Huge An image from the \\LaTeX3 project}}}\\cr\r\n\\hline\r\n\\text{Left}\\includegraphics{src/test/resources/lion.png}\\text{Right} & \\text{Left}\\includegraphics[width=3cm,interpolation=bicubic]{src/test/resources/lion.png}\\text{Right} & \\text{Left}\\includegraphics[angle=45,width=3cm]{src/test/resources/lion.png}\\text{Right} & \\text{Left}\\includegraphics[angle=160]{src/test/resources/lion.png}\\text{Right} \\cr\r\n\\hline\r\n\\text{\\backslash includegraphics\\{src/test/resources/lion.png\\}} & \\text{\\backslash includegraphics[width=3cm,interpolation=bicubic]\\{lion.png\\}} & \\text{\\backslash includegraphics[angle=45,width=3cm]\\{lion.png\\}} & \\text{\\backslash includegraphics[angle=160]\\{lion.png\\}}\\cr\r\n\\hline\r\n\\end{array}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)       \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/later_test5.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class later_test {\r\n    @TestCase\r\n    func later_test05(): Unit {\r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\begin{array}{|c|l|||r|c|}\\hline\\text{Matrix}&\\multicolumn{2}{|c|}{\\text{Multicolumns}}&\\text{Font sizes commands}\\cr\\hline\\begin{pmatrix}\\alpha_{11}&\\cdots&\\alpha_{1n}\\cr\\hdotsfor{3}\\cr\\alpha_{n1}&\\cdots&\\alpha_{nn}\\end{pmatrix}&\\Large \\text{Large Right}&\\small \\text{small Left}&\\tiny \\text{tiny Tiny}\\cr\\hline\\multicolumn{4}{|c|}{\\Huge \\text{Huge Multicolumns}}\\cr\\hline\\end{array}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)      \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/later_test6.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class later_test {\r\n    @TestCase\r\n    func later_test06(): Unit {\r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\begin{array}{cc}\\fbox{\\text{A framed box with \\textdbend}}&\\shadowbox{\\text{A shadowed box}}\\cr\\doublebox{\\text{A double framed box}}&\\ovalbox{\\text{An oval framed box}}\\cr\\end{array}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)        \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/later_test7.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class later_test {\r\n    @TestCase\r\n    func later_test07(): Unit {\r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\mbox{abc abc abc abc abc abc abc abc abc abc abc abc abc abc\\\\abc abc abc abc abc abc abc\\\\abc abc abc abc abc abc abc}\\\\1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)        \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n \r\n    var arr = r.toBitmap(g2)\r\n\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/later_test8.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class later_test {\r\n    @TestCase\r\n    func later_test08(): Unit {\r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\text{A long division \\longdiv{12345}{13}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0)        \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n\r\n    var arr = r.toBitmap(g2)\r\n\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/later_test9.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class later_test {\r\n    @TestCase\r\n    func later_test09(): Unit {\r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n{a \\bangle b} {c \\brace d} {e \\brack f} {g \\choose h}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0)        \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n\r\n    var arr = r.toBitmap(g2)\r\n\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/test1.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class test {\r\n    @TestCase\r\n    func test9(): Unit {\r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\"###\r\n    var color1:UInt32=0xffff0000\r\n    var r = latex.parse(str, 10, 40.0, 10.0, color1)  \r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n    var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n\r\n    }\r\n}    "
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/test2.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class test {\r\n    @TestCase\r\n    func test5(): Unit {\r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\sideset{^\\backprime}{'}\r\n\\sum_{x=1}^{\\infty} x\r\n\\sideset{a_1^2}{}\\sum_{x=1}^\\infty x_0\r\n\\\\\r\n\\sideset{_\\text{left bottom}'''}{_{\\text{right bottom}}'''}\r\n\\sum_{\\text{quite long text}}^\\infty x\r\n\\\\\r\n\\sideset{}{'}\r\n\\sum_{n<k,\\;\\text{$n$ odd}} nE_n\r\n\\\\\r\n\\sideset{}{'}\r\n\\sum^{n<k,\\;\\text{$n$ odd}} nE_n\r\n\\\\\r\nM_x''' M'''_x M^{'''}_x M_x{'''} M^{\\prime\\backprime}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n    var g2 = Graphic2D(r,COLOR_FORMAT_RGB_565)         //r.draw(g2, 0, 0, 0xFF0000FF) 异常\r\n    r.draw(g2, 0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/test3.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class test {\r\n    @TestCase\r\n    func test3(): Unit {\r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\sideset{^\\backprime}{'}\r\n\\sum_{x=1}^{\\infty} x\r\n\\sideset{a_1^2}{}\\sum_{x=1}^\\infty x_0\r\n\\\\\r\n\\sideset{_\\text{left bottom}'''}{_{\\text{right bottom}}'''}\r\n\\sum_{\\text{quite long text}}^\\infty x\r\n\\\\\r\n\\sideset{}{'}\r\n\\sum_{n<k,\\;\\text{$n$ odd}} nE_n\r\n\\\\\r\n\\sideset{}{'}\r\n\\sum^{n<k,\\;\\text{$n$ odd}} nE_n\r\n\\\\\r\nM_x''' M'''_x M^{'''}_x M_x{'''} M^{\\prime\\backprime}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 80.0, 100.0, 5)          //改变字体和行距\r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n    @Assert(r.getTextSize(),80.0)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n\r\n    var arr = r.toBitmap(g2)\r\n\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/test4.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class test {                //r.draw(g2, 0, 0, 0xFF0000FF) 异常\r\n    @TestCase\r\n    func test4(): Unit {\r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\sideset{^\\backprime}{'}\r\n\\sum_{x=1}^{\\infty} x\r\n\\sideset{a_1^2}{}\\sum_{x=1}^\\infty x_0\r\n\\\\\r\n\\sideset{_\\text{left bottom}'''}{_{\\text{right bottom}}'''}\r\n\\sum_{\\text{quite long text}}^\\infty x\r\n\\\\\r\n\\sideset{}{'}\r\n\\sum_{n<k,\\;\\text{$n$ odd}} nE_n\r\n\\\\\r\n\\sideset{}{'}\r\n\\sum^{n<k,\\;\\text{$n$ odd}} nE_n\r\n\\\\\r\nM_x''' M'''_x M^{'''}_x M_x{'''} M^{\\prime\\backprime}\r\n\"###\r\n\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)  //0xFF00FF00绿色               //0xFF000000黑色\r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n    var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2,0xFF0000FF)  //0xFFFF0000 红色  背景色   0xFF0000FF蓝色   r.draw(g2, 384, 558, 0xFF0000FF) \r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/test5.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class test {\r\n    @TestCase\r\n    func test2(): Unit {\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\sideset{^\\backprime}{'}\r\n\\sum_{x=1}^{\\infty} x\r\n\\sideset{a_1^2}{}\\sum_{x=1}^\\infty x_0\r\n\\\\\r\n\\sideset{_\\text{left bottom}'''}{_{\\text{right bottom}}'''}\r\n\\sum_{\\text{quite long text}}^\\infty x\r\n\\\\\r\n\\sideset{}{'}\r\n\\sum_{n<k,\\;\\text{$n$ odd}} nE_n\r\n\\\\\r\n\\sideset{}{'}\r\n\\sum^{n<k,\\;\\text{$n$ odd}} nE_n\r\n\\\\\r\nM_x''' M'''_x M^{'''}_x M_x{'''} M^{\\prime\\backprime}\r\n\"###\r\n    var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n     var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2, 0xFFFFFFFF)\r\n\r\n    var arr = r.toBitmap(g2)\r\n\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/test6.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class test {\r\n    @TestCase\r\n    func test6(): Unit {\r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\sideset{^\\backprime}{'}\r\n\\sum_{x=1}^{\\infty} x\r\n\\sideset{a_1^2}{}\\sum_{x=1}^\\infty x_0\r\n\\\\\r\n\\sideset{_\\text{left bottom}'''}{_{\\text{right bottom}}'''}\r\n\\sum_{\\text{quite long text}}^\\infty x\r\n\\\\\r\n\\sideset{}{'}\r\n\\sum_{n<k,\\;\\text{$n$ odd}} nE_n\r\n\\\\\r\n\\sideset{}{'}\r\n\\sum^{n<k,\\;\\text{$n$ odd}} nE_n\r\n\\\\\r\nM_x''' M'''_x M^{'''}_x M_x{'''} M^{\\prime\\backprime}\r\n\"###\r\n    var r = latex.parse(str, -2000000000, 40.0, 10.0, 0xFF000000)   //改变宽度\r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n    var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2,0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/test7.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class test {\r\n    @TestCase\r\n    func test7(): Unit {\r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\sideset{^\\backprime}{'}\r\n\\sum_{x=1}^{\\infty} x\r\n\\sideset{a_1^2}{}\\sum_{x=1}^\\infty x_0\r\n\\\\\r\n\\sideset{_\\text{left bottom}'''}{_{\\text{right bottom}}'''}\r\n\\sum_{\\text{quite long text}}^\\infty x\r\n\\\\\r\n\\sideset{}{'}\r\n\\sum_{n<k,\\;\\text{$n$ odd}} nE_n\r\n\\\\\r\n\\sideset{}{'}\r\n\\sum^{n<k,\\;\\text{$n$ odd}} nE_n\r\n\\\\\r\nM_x''' M'''_x M^{'''}_x M_x{'''} M^{\\prime\\backprime}\r\n\"###\r\n    var r = latex.parse(str, 1000000000, 40.0, 10.0, 0xFF000000)   //改变宽度  异常\r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n    var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2,0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)\r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/HLT/test8.cj",
    "content": "// 3rd_party_lib:formula/target/release/formula\r\n//3rd_party_lib_ohos:formula\\target\\aarch64-linux-ohos\\release\\formula\r\nimport formula.*\r\nimport std.unittest.*\r\nimport std.collection.*\r\nimport std.fs.*\r\n\r\n@Test\r\npublic class test {\r\n    @TestCase\r\n    func test8(): Unit {\r\n\r\n    var latex = LaTeX(\"res\")\r\n    var str = ###\"\r\n\\sideset{^\\backprime}{'}\r\n\\sum_{x=1}^{\\infty} x\r\n\\sideset{a_1^2}{}\\sum_{x=1}^\\infty x_0\r\n\\\\\r\n\\sideset{_\\text{left bottom}'''}{_{\\text{right bottom}}'''} \r\n\\sum_{\\text{quite long text}}^\\infty x\r\n\\\\\r\n\\sideset{}{'}\r\n\\sum_{n<k,\\;\\text{$n$ odd}} nE_n\r\n\\\\\r\n\\sideset{}{'}\r\n\\sum^{n<k,\\;\\text{$n$ odd}} nE_n\r\n\\\\\r\nM_x''' M'''_x M^{'''}_x M_x{'''} M^{\\prime\\backprime}\r\n\"###\r\n\r\n    var r = latex.parse(str, 10, 40.0, 10.0, 0xFF000000)  //宽度问题\r\n    var w = r.getWidth()\r\n    var h = r.getHeight()\r\n    println(w)\r\n    println(h)\r\n    var g2 = Graphic2D(r,COLOR_FORMAT_BGRA_8888)\r\n    r.draw(g2,0xFFFFFFFF)\r\n    var arr = r.toBitmap(g2)     \r\n    var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\r\n    file.write(arr)\r\n    file.close()\r\n    }\r\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/c_test1.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = c_test_test()\n    t.c_testr_01()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func c_testr_01(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\begin{array}{lr}\n  \\mbox{\\textcolor{Blue}{Russian}}&\\mbox{\\textcolor{Melon}{Greek}}\\\\\n  \\mbox{привет мир}&\\mbox{γειά κόσμο}\\\\\n  \\mbox{привет мир}&\\mbox{γειά κόσμο}\\\\\n  \\mathbf{\\mbox{привет мир}}&\\mathbf{\\mbox{γειά κόσμο}}\\\\\n  \\mathit{\\mbox{привет мир}}&\\mathit{\\mbox{γειά κόσμο}}\\\\\n  \\mathsf{\\mbox{привет мир}}&\\mathsf{\\mbox{γειά κόσμο}}\\\\\n  \\mathtt{\\mbox{привет мир}}&\\mathtt{\\mbox{γειά κόσμο}}\\\\\n  \\mathbf{\\mathit{\\mbox{привет мир}}}&\\mathbf{\\mathit{\\mbox{γειά κόσμο}}}\\\\\n  \\mathbf{\\mathsf{\\mbox{привет мир}}}&\\mathbf{\\mathsf{\\mbox{γειά κόσμο}}}\\\\\n  \\mathsf{\\mathit{\\mbox{привет мир}}}&\\mathsf{\\mathit{\\mbox{γειά κόσμο}}}\\\\\n  &\\\\\n  \\mbox{\\textcolor{Salmon}{Bulgarian}}&\\mbox{\\textcolor{Tan}{Serbian}}\\\\\n  \\mbox{здравей свят}&\\mbox{Хелло уорлд}\\\\\n  &\\\\\n  \\mbox{\\textcolor{Turquoise}{Bielorussian}}&\\mbox{\\textcolor{LimeGreen}{Ukrainian}}\\\\\n  \\mbox{прывітаньне Свет}&\\mbox{привіт світ}\\\\\n\\end{array}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n        var arr = r.toBitmap(g2)\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/c_test10.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = c_test_test()\n    t.c_testr_010()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func c_testr_010(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\frac{\\sum_{n > 0} z^n}\n{\\prod_{1\\leq k\\leq n} (1-q^k)}\n\\\\\n\\frac{{\\displaystyle\\sum_{n > 0} z^n}}\n{{\\displaystyle\\prod_{1\\leq k\\leq n} (1-q^k)}}\n\\\\\n\\frac{{\\displaystyle\\sum\\nolimits_{n> 0} z^n}}\n{{\\displaystyle\\prod\\nolimits_{1\\leq k\\leq n} (1-q^k)}}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/c_test12.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = c_test_test()\n    t.c_testr_012()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func c_testr_012(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\cfrac{1}{\\sqrt{2}+\n\\cfrac{1}{\\sqrt{2}+\n\\cfrac{1}{\\sqrt{2}+\\dotsb\n}}}\n\\\\\n\\biggl[\n\\sum_i a_i\\biggl\\lvert\\sum_j x_{ij}\n\\biggr\\rvert^p\\biggr]^{1/p}\n\\\\\n\\biggl[\n\\sum_i a_i\\Bigl\\lvert\\sum_j x_{ij}\n\\Bigr\\rvert^p\\biggr]^{1/p}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/c_test13.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = c_test_test()\n    t.c_testr_013()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func c_testr_013(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\begin{array}{lr}\n  \\mbox{\\textcolor{Blue}{Russian}}&\\mbox{\\textcolor{Melon}{Greek}}\\\\\n  \\mbox{привет мир}&\\mbox{γειά κόσμο}\\\\\n  \\mbox{привет мир}&\\mbox{γειά κόσμο}\\\\\n  \\mathbf{\\mbox{привет мир}}&\\mathbf{\\mbox{γειά κόσμο}}\\\\\n  \\mathit{\\mbox{привет мир}}&\\mathit{\\mbox{γειά κόσμο}}\\\\\n  \\mathsf{\\mbox{привет мир}}&\\mathsf{\\mbox{γειά κόσμο}}\\\\\n  \\mathtt{\\mbox{привет мир}}&\\mathtt{\\mbox{γειά κόσμο}}\\\\\n  \\mathbf{\\mathit{\\mbox{привет мир}}}&\\mathbf{\\mathit{\\mbox{γειά κόσμο}}}\\\\\n  \\mathbf{\\mathsf{\\mbox{привет мир}}}&\\mathbf{\\mathsf{\\mbox{γειά κόσμο}}}\\\\\n  \\mathsf{\\mathit{\\mbox{привет мир}}}&\\mathsf{\\mathit{\\mbox{γειά κόσμο}}}\\\\\n  &\\\\\n  \\mbox{\\textcolor{Salmon}{Bulgarian}}&\\mbox{\\textcolor{Tan}{Serbian}}\\\\\n  \\mbox{здравей свят}&\\mbox{Хелло уорлд}\\\\\n  &\\\\\n  \\mbox{\\textcolor{Turquoise}{Bielorussian}}&\\mbox{\\textcolor{LimeGreen}{Ukrainian}}\\\\\n  \\mbox{прывітаньне Свет}&\\mbox{привіт світ}\\\\\n\\end{array}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n        latex.release()\n        r.finalize()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/c_test2.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = c_test_test()\n    t.c_testr_02()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func c_testr_02(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\begin{array}{l}\n  \\forall\\varepsilon\\in\\mathbb{R}_+^*\\ \\exists\\eta>0\\ |x-x_0|\\leq\\eta\\Longrightarrow|f(x)-f(x_0)|\\leq\\varepsilon\\\\\n  \\det\n  \\begin{bmatrix}\n      a_{11}&a_{12}&\\cdots&a_{1n}\\\\\n      a_{21}&\\ddots&&\\vdots\\\\\n      \\vdots&&\\ddots&\\vdots\\\\\n      a_{n1}&\\cdots&\\cdots&a_{nn}\n  \\end{bmatrix}\n  \\overset{\\mathrm{def}}{=}\\sum_{\\sigma\\in\\mathfrak{S}_n}\\varepsilon(\\sigma)\\prod_{k=1}^n a_{k\\sigma(k)}\\\\\n  \\sideset{_\\alpha^\\beta}{_\\gamma^\\delta}{\\begin{pmatrix}a&b\\\\c&d\\end{pmatrix}}\\\\\n  \\int_0^\\infty{x^{2n} e^{-a x^2}\\,dx} = \\frac{2n-1}{2a}\n      \\int_0^\\infty{x^{2(n-1)} e^{-a x^2}\\,dx} = \\frac{(2n-1)!!}{2^{n+1}} \\sqrt{\\frac{\\pi}{a^{2n+1}}}\\\\\n  \\int_a^b{f(x)\\,dx} = (b - a) \\sum\\limits_{n = 1}^\\infty\n      {\\sum\\limits_{m = 1}^{2^n  - 1} {\\left( { - 1} \\right)^{m + 1} } } 2^{ - n} f(a + m\\left( {b - a} \\right)2^{-n} )\\\\\n  \\int_{-\\pi}^{\\pi} \\sin(\\alpha x) \\sin^n(\\beta x) dx = \\textstyle{\\left \\{\n      \\begin{array}{cc}\n          (-1)^{(n+1)/2} (-1)^m \\frac{2 \\pi}{2^n} \\binom{n}{m} & n \\mbox{ odd},\\ \\alpha = \\beta (2m-n) \\\\\n          0 & \\mbox{otherwise} \\\\ \\end{array} \\right .}\\\\\n  L = \\int_a^b \\sqrt{ \\left|\\sum_{i,j=1}^ng_{ij}(\\gamma(t))\\left(\\frac{d}{dt}x^i\\circ\\gamma(t)\\right)\n      \\left(\\frac{d}{dt}x^j\\circ\\gamma(t)\\right)\\right|}\\,dt\\\\\n  \\begin{array}{rl}\n      s &= \\int_a^b\\left\\|\\frac{d}{dt}\\vec{r}\\,(u(t),v(t))\\right\\|\\,dt \\\\\n      &= \\int_a^b \\sqrt{u'(t)^2\\,\\vec{r}_u\\cdot\\vec{r}_u + 2u'(t)v'(t)\\, \\vec{r}_u\\cdot\n          \\vec{r}_v+ v'(t)^2\\,\\vec{r}_v\\cdot\\vec{r}_v}\\,\\,\\, dt.\n  \\end{array}\\\\\n\\end{array}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/c_test3.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = c_test_test()\n    t.c_testr_03()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func c_testr_03(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\definecolor{gris}{gray}{0.9}\n\\definecolor{noir}{rgb}{0,0,0}\n\\definecolor{bleu}{rgb}{0,0,1}\n\\fatalIfCmdConflict{false}\n\\newcommand{\\pa}{\\left|}\n\\begin{array}{c}\n  \\LaTeX\\\\\n  \\begin{split}\n      &Тепловой\\ поток\\ \\mathrm{Тепловой\\ поток}\\ \\mathtt{Тепловой\\ поток}\\\\\n      &\\boldsymbol{\\mathrm{Тепловой\\ поток}}\\ \\mathsf{Тепловой\\ поток}\\\\\n      |I_2| &= \\pa\\int_0^T\\psi(t)\\left\\{ u(a,t)-\\int_{\\gamma(t)}^a \\frac{d\\theta}{k} (\\theta,t) \\int_a^\\theta c(\\xi)\n          u_t (\\xi,t)\\,d\\xi\\right\\}dt\\right|\\\\\n      &\\le C_6 \\Bigg|\\pa f \\int_\\Omega \\pa\\widetilde{S}^{-1,0}_{a,-}\n          W_2(\\Omega, \\Gamma_1)\\right|\\ \\right|\\left| |u|\\overset{\\circ}{\\to} W_2^{\\widetilde{A}}(\\Omega\\Gamma_r,T)\\right|\\Bigg|\\\\\n      &\\\\\n      &\\begin{pmatrix}\n          \\alpha&\\beta&\\gamma&\\delta\\\\\n          \\aleph&\\beth&\\gimel&\\daleth\\\\\n          \\mathfrak{A}&\\mathfrak{B}&\\mathfrak{C}&\\mathfrak{D}\\\\\n          \\boldsymbol{\\mathfrak{a}}&\\boldsymbol{\\mathfrak{b}}&\\boldsymbol{\\mathfrak{c}}&\\boldsymbol{\\mathfrak{d}}\n      \\end{pmatrix}\n      \\quad{(a+b)}^{\\frac{n}{2}}=\\sqrt{\\sum_{k=0}^n\\tbinom{n}{k}a^kb^{n-k}}\\quad\n          \\Biggl(\\biggl(\\Bigl(\\bigl(()\\bigr)\\Bigr)\\biggr)\\Biggr)\\\\\n      &\\forall\\varepsilon\\in\\mathbb{R}_+^*\\ \\exists\\eta>0\\ |x-x_0|\\leq\\eta\\Longrightarrow|f(x)-f(x_0)|\\leq\\varepsilon\\\\\n      &\\det\n      \\begin{bmatrix}\n          a_{11}&a_{12}&\\cdots&a_{1n}\\\\\n          a_{21}&\\ddots&&\\vdots\\\\\n          \\vdots&&\\ddots&\\vdots\\\\\n          a_{n1}&\\cdots&\\cdots&a_{nn}\n      \\end{bmatrix}\n      \\overset{\\mathrm{def}}{=}\\sum_{\\sigma\\in\\mathfrak{S}_n}\\varepsilon(\\sigma)\\prod_{k=1}^n a_{k\\sigma(k)}\\\\\n      &\\Delta f(x,y)=\\frac{\\partial^2f}{\\partial x^2}+\\frac{\\partial^2f}{\\partial y^2}\\qquad\\qquad \\fcolorbox{noir}{gris}\n          {n!\\underset{n\\rightarrow+\\infty}{\\sim} {\\left(\\frac{n}{e}\\right)}^n\\sqrt{2\\pi n}}\\\\\n      &\\sideset{_\\alpha^\\beta}{_\\gamma^\\delta}{\n      \\begin{pmatrix}\n          a&b\\\\\n          c&d\n      \\end{pmatrix}}\n      \\xrightarrow[T]{n\\pm i-j}\\sideset{^t}{}A\\xleftarrow{\\overrightarrow{u}\\wedge\\overrightarrow{v}}\n          \\underleftrightarrow{\\iint_{\\mathds{R}^2}e^{-\\left(x^2+y^2\\right)}\\,\\mathrm{d}x\\mathrm{d}y}\n  \\end{split}\\\\\n  \\rotatebox{30}{\\sum_{n=1}^{+\\infty}}\\quad\\mbox{Mirror rorriM}\\reflectbox{\\mbox{Mirror rorriM}}\n\\end{array}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/c_test4.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = c_test_test()\n    t.c_testr_04()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func c_testr_04(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\begin{array}{|c|l|||r|c|}\n  \\hline\n  \\text{Matrix}&\\multicolumn{2}{|c|}{\\text{Multicolumns}}&\\text{Font sizes commands}\\cr\n  \\hline\n  \\begin{pmatrix}\n      \\alpha_{11}&\\cdots&\\alpha_{1n}\\cr\n      \\hdotsfor{3}\\cr\n      \\alpha_{n1}&\\cdots&\\alpha_{nn}\n  \\end{pmatrix}\n  &\\Large \\text{Large Right}&\\small \\text{small Left}&\\tiny \\text{tiny Tiny}\\cr\n  \\hline\n  \\multicolumn{4}{|c|}{\\Huge \\text{Huge Multicolumns}}\\cr\n  \\hline\n\\end{array}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/c_test5.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = c_test_test()\n    t.c_testr_05()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func c_testr_05(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\cornersize{0.2}\n\\begin{array}{cc}\n  \\fbox{\\text{A framed box with \\textdbend}}&\\shadowbox{\\text{A shadowed box}}\\cr\n  \\doublebox{\\text{A double framed box}}&\\ovalbox{\\text{An oval framed box}}\\cr\n\\end{array}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/c_test6.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = c_test_test()\n    t.c_testr_06()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func c_testr_06(): Unit { //定位中\n\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\text{!\"#'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]\n^_`abcdefghijklmnopqrstuvwxyz{|}~\n\n     ¡¢£¤¥¦§¨©ª«¬­\n®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/c_test7.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = c_test_test()\n    t.c_testr_07()\n    return ret\n}\n\n@Test\npublic class c_test_test { //图片显示错误\n    @TestCase\n    func c_testr_07(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\newcolumntype{s}{>{\\color{#1234B6}}c}\n\\begin{array}{|c|c|c|s|}\n  \\hline\n  \\rowcolor{Tan}\\multicolumn{4}{|c|}{\\textcolor{white}{\\bold{\\text{Table Head}}}}\\\\\n  \\hline\n  \\text{Matrix}&\\multicolumn{2}{|c|}{\\text{Multicolumns}}&\\text{Font size commands}\\\\\n  \\hline\n  \\begin{pmatrix}\n      \\alpha_{11}&\\cdots&\\alpha_{1n}\\\\\n      \\hdotsfor{3}\\\\\n      \\alpha_{n1}&\\cdots&\\alpha_{nn}\n  \\end{pmatrix}\n  &\\large \\text{Left}&\\cellcolor{#00bde5}\\small \\textcolor{white}{\\text{\\bold{Right}}}\n  &\\small \\text{small Small}\\\\\n  \\hline\n  \\multicolumn{4}{|c|}{\\text{Table Foot}}\\\\\n  \\hline\n\\end{array}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/c_test8.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = c_test_test()\n    t.c_testr_08()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func c_testr_08(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\rlap{\\overbrace{\\phantom{1 + a + b + \\cdots + z}}^{\\text{total + 1}}}\n1 + \\underbrace{a + b + \\cdots + z}_{\\text{total}}\n\\\\\n\\frac{a\\cancel{b}}{\\cancel{b}} = a;\n\\frac{a\\bcancel{b}}{\\bcancel{b}} = a;\n\\frac{a\\xcancel{b}}{\\xcancel{b}} = a;\n\\\\\n\\text{A long division: }\\longdiv{12345}{13}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/c_test9.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = c_test_test()\n    t.c_testr_09()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func c_testr_09(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\left\\{\n    \\begin{array}{l}\n    2a < -1,\\\\\n    a + 8 \\ge 5,\n    \\end{array}\n\\right.\n\\\\\nP_{r-j}=\\begin{cases}\n0& \\text{if $r-j$ is odd},\\\\\nr!\\,(-1)^{(r-j)/2}& \\text{if $r-j$ is even}.\n\\end{cases}\\text{Cases}\n\\\\\nP_{r-j}=\\left\\{\\begin{array}{@{}ll@{\\,}}\n0& \\text{if $r-j$ is odd},\\\\\nr!\\,(-1)^{(r-j)/2}& \\text{if $r-j$ is even}.\n\\end{array}\\right.\\text{Cases}\n\\\\\nP_{r-j}=\\begin{cases}\n4-x\\geq 0 \\\\\n3-x\\geq 1\n\\end{cases}\\text{Cases}\n\\\\\n\\left\\{\\begin{array}{@{}ll}\n1 & 2\\\\\n3 & 4\n\\end{array}\\right.\\text{Equation}\n\\\\\n\\left\\{\\begin{array}{l@{}l}\n1 & 2\\\\\n3 & 4\n\\end{array}\\right.\\text{Equation}\n\\\\\n\\left\\{\\begin{array}{ll@{}}\n1 & 2\\\\\n3 & 4\n\\end{array}\\right.\\text{Equation}\n\\\\\n\\begin{split}\nH_c&=\\frac{1}{2n} \\sum^n_{l=0}(-1)^{l}(n-{l})^{p-2}\n\\sum_{l _1+\\dots+ l _p=l}\\prod^p_{i=1} \\binom{n_i}{l _i}\\\\\n&\\quad\\cdot[(n-l )-(n_i-l _i)]^{n_i-l _i}\\cdot\n\\Bigl[(n-l )^2-\\sum^p_{j=1}(n_i-l _i)^2\\Bigr].\n\\end{split}\n\\\\\n\\begin{align}\nA_1&=N_0(\\lambda;\\Omega’)-\\phi(\\lambda;\\Omega’),\\\\\nA_2&=\\phi(\\lambda;\\Omega’)-\\phi(\\lambda;\\Omega),\\\\\n\\intertext{and}\nA_3&=\\mathcal{N}(\\lambda;\\omega).\n\\end{align}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/later_test1.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = later_test()\n    t.later_test01()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func later_test01(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\begin{array}{lr}\\mbox{\\textcolor{Blue}{Russian}}&\\mbox{\\textcolor{Melon}{Greek}}\\\\\\mbox{ПРИВЕТ МИР}&\\mbox{ΓΕΙΆ ΚΌΣΜΟ}\\\\\\mbox{привет мир}&\\mbox{γειά κόσμο}\\\\\\mathbf{\\mbox{привет мир}}&\\mathbf{\\mbox{γειά κόσμο}}\\\\\\mathit{\\mbox{привет мир}}&\\mathit{\\mbox{γειά κόσμο}}\\\\\\mathsf{\\mbox{привет мир}}&\\mathsf{\\mbox{γειά κόσμο}}\\\\\\mathtt{\\mbox{привет мир}}&\\mathtt{\\mbox{γειά κόσμο}}\\\\\\mathbf{\\mathit{\\mbox{привет мир}}}&\\mathbf{\\mathit{\\mbox{γειά κόσμο}}}\\\\\\mathbf{\\mathsf{\\mbox{привет мир}}}&\\mathbf{\\mathsf{\\mbox{γειά κόσμο}}}\\\\\\mathsf{\\mathit{\\mbox{привет мир}}}&\\mathsf{\\mathit{\\mbox{γειά κόσμο}}}\\\\&\\\\\\mbox{\\textcolor{Salmon}{Bulgarian}}&\\mbox{\\textcolor{Tan}{Serbian}}\\\\\\mbox{здравей свят}&\\mbox{Хелло уорлд}\\\\&\\\\\\mbox{\\textcolor{Turquoise}{Bielorussian}}&\\mbox{\\textcolor{LimeGreen}{Ukrainian}}\\\\\\mbox{прывітаньне Свет}&\\mbox{привіт світ}\\\\\\end{array}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/later_test10.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = later_test()\n    t.later_test010()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func later_test010(): Unit { //中文问题\n\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\begin{array}{c}\n  a,b \\in R^{+} \\\\\n  \\Rightarrow \\frac{a+b}{{2}}\\ge \\sqrt{ab} \\\\\n  \\left( \\text{当且仅当}a=b\\text{时取“}=\\text{”号}\\right)\n\\end{array}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n        var arr = r.toBitmap(g2)\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/later_test11.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = later_test()\n    t.later_test011()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func later_test011(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\left.\\begin{matrix}\n  m \\subset \\alpha ,n \\subset \\alpha ,m \\cap n=P \\\\\n  a \\perp m,a \\perp n\n\\end{matrix}\\right\\}\\Rightarrow a \\perp \\alpha\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n        var arr = r.toBitmap(g2)\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/later_test12.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = later_test()\n    t.later_test012()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func later_test012(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\begin{array}{c}\n  H_{n}=\\frac{n}{\\sum \\limits_{i=1}^{n}\\frac{1}{x_{i}}}= \\frac{n}{\\frac{1}{x_{1}}+ \\frac{1}{x_{2}}+ \\cdots + \\frac{1}{x_{n}}} \\\\ G_{n}=\\sqrt[n]{\\prod \\limits_{i=1}^{n}x_{i}}= \\sqrt[n]{x_{1}x_{2}\\cdots x_{n}} \\\\ A_{n}=\\frac{1}{n}\\sum \\limits_{i=1}^{n}x_{i}=\\frac{x_{1}+ x_{2}+ \\cdots + x_{n}}{n} \\\\ Q_{n}=\\sqrt{\\sum \\limits_{i=1}^{n}x_{i}^{2}}= \\sqrt{\\frac{x_{1}^{2}+ x_{2}^{2}+ \\cdots + x_{n}^{2}}{n}} \\\\ H_{n}\\leq G_{n}\\leq A_{n}\\leq Q_{n}\n\\end{array}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n        var arr = r.toBitmap(g2)\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/later_test13.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = later_test()\n    t.later_test013()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func later_test013(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\mathbf{V}_1 \\times \\mathbf{V}_2 =\n\\begin{vmatrix}\n  \\mathbf{i}& \\mathbf{j}& \\mathbf{k} \\\\\n  \\frac{\\partial X}{\\partial u}& \\frac{\\partial Y}{\\partial u}& 0 \\\\\n  \\frac{\\partial X}{\\partial v}& \\frac{\\partial Y}{\\partial v}& 0 \\\\\n\\end{vmatrix}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n        var arr = r.toBitmap(g2)\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/later_test14.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = later_test()\n    t.later_test014()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func later_test014(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\frac{\\sin A}{a}=\\frac{\\sin B}{b}=\\frac{\\sin C}{c}=\\frac{1}{2R}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n        var arr = r.toBitmap(g2)\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/later_test15.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = later_test()\n    t.later_test015()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func later_test015(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\begin{array}{c}\n  S= \\binom{N}{n},A_{k}=\\binom{M}{k}\\cdot \\binom{N-M}{n-k} \\\\\n  P\\left ( A_{k}\\right ) = \\frac{\\binom{M}{k}\\cdot \\binom{N-M}{n-k}}{\\binom{N}{n}}\n\\end{array}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n        var arr = r.toBitmap(g2)\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/later_test16.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = later_test()\n    t.later_test016()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func later_test016(): Unit { //中文问题\n\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\begin{array}{c}\n  \\text{若}\\left \\{a_{n}\\right \\}、\\left \\{b_{n}\\right \\}\\text{为等差数列}, \\\\\n  \\text{则}\\left \\{a_{n}+ b_{n}\\right \\}\\text{为等差数列}\n\\end{array}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n        var arr = r.toBitmap(g2)\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/later_test17.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = later_test()\n    t.later_test017()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func later_test017(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\begin{array}{l}\n  \\nabla \\cdot \\mathbf{E} =\\cfrac{\\rho}{\\varepsilon _0}  \\\\\n  \\nabla \\cdot \\mathbf{B} = 0 \\\\\n  \\nabla \\times  \\mathbf{E} = -\\cfrac{\\partial \\mathbf{B}}{\\partial t }  \\\\\n  \\nabla \\times  \\mathbf{B} = \\mu _0\\mathbf{J} + \\mu _0\\varepsilon_0 \\cfrac{\\partial \\mathbf{E}}{\\partial t }\n\\end{array}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n        var arr = r.toBitmap(g2)\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/later_test18.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = later_test()\n    t.later_test018()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func later_test018(): Unit { //中文问题\n\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\begin{array}{c}\n  \\text{直角三角形中,直角边长a,b,斜边边长c} \\\\\n  a^{2}+b^{2}=c^{2}\n\\end{array}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n        var arr = r.toBitmap(g2)\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/later_test2.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = later_test()\n    t.later_test02()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func later_test02(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\begin{array}{l}\\forall\\varepsilon\\in\\mathbb{R}_+^*\\ \\exists\\eta>0\\ |x-x_0|\\leq\\eta\\Longrightarrow|f(x)-f(x_0)|\\leq\\varepsilon\\\\\\det\\begin{bmatrix}a_{11}&a_{12}&\\cdots&a_{1n}\\\\a_{21}&\\ddots&&\\vdots\\\\\\vdots&&\\ddots&\\vdots\\\\a_{n1}&\\cdots&\\cdots&a_{nn}\\end{bmatrix}\\overset{\\mathrm{def}}{=}\\sum_{\\sigma\\in\\mathfrak{S}_n}\\varepsilon(\\sigma)\\prod_{k=1}^n a_{k\\sigma(k)}\\\\\\sideset{_\\alpha^\\beta}{_\\gamma^\\delta}{\\begin{pmatrix}a&b\\\\c&d\\end{pmatrix}}\\\\\\int_0^\\infty{x^{2n} e^{-a x^2}\\,dx} = \\frac{2n-1}{2a} \\int_0^\\infty{x^{2(n-1)} e^{-a x^2}\\,dx} = \\frac{(2n-1)!!}{2^{n+1}} \\sqrt{\\frac{\\pi}{a^{2n+1}}}\\\\\\int_a^b{f(x)\\,dx} = (b - a) \\sum\\limits_{n = 1}^\\infty  {\\sum\\limits_{m = 1}^{2^n  - 1} {\\left( { - 1} \\right)^{m + 1} } } 2^{ - n} f(a + m\\left( {b - a} \\right)2^{-n} )\\\\\\int_{-\\pi}^{\\pi} \\sin(\\alpha x) \\sin^n(\\beta x) dx = \\textstyle{\\left \\{ \\begin{array}{cc} (-1)^{(n+1)/2} (-1)^m \\frac{2 \\pi}{2^n} \\binom{n}{m} & n \\mbox{ odd},\\ \\alpha = \\beta (2m-n) \\\\ 0 & \\mbox{otherwise} \\\\ \\end{array} \\right .}\\\\L = \\int_a^b \\sqrt{ \\left|\\sum_{i,j=1}^ng_{ij}(\\gamma(t))\\left(\\frac{d}{dt}x^i\\circ\\gamma(t)\\right)\\left(\\frac{d}{dt}x^j\\circ\\gamma(t)\\right)\\right|}\\,dt\\\\\\begin{array}{rl} s &= \\int_a^b\\left\\|\\frac{d}{dt}\\vec{r}\\,(u(t),v(t))\\right\\|\\,dt \\\\ &= \\int_a^b \\sqrt{u'(t)^2\\,\\vec{r}_u\\cdot\\vec{r}_u + 2u'(t)v'(t)\\, \\vec{r}_u\\cdot\\vec{r}_v+ v'(t)^2\\,\\vec{r}_v\\cdot\\vec{r}_v}\\,\\,\\, dt. \\end{array}\\\\\\end{array}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/later_test3.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = later_test()\n    t.later_test03()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func later_test03(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n    \\definecolor{gris}{gray}{0.9}\\definecolor{noir}{rgb}{0,0,0}\\definecolor{bleu}{rgb}{0,0,1}\\newcommand{\\pa}{\\left|}\\begin{array}{c}\\JLaTeXMath\\\\\\begin{split} &Тепловой\\ поток\\ \\mathrm{Тепловой\\ поток}\\ \\mathtt{Тепловой\\ поток}\\\\ &\\boldsymbol{\\mathrm{Тепловой\\ поток}}\\ \\mathsf{Тепловой\\ поток}\\\\|I_2| &= \\pa\\int_0^T\\psi(t)\\left\\{ u(a,t)-\\int_{\\gamma(t)}^a \\frac{d\\theta}{k} (\\theta,t) \\int_a^\\theta c(\\xi) u_t (\\xi,t)\\,d\\xi\\right\\}dt\\right|\\\\&\\le C_6 \\Bigg|\\pa f \\int_\\Omega \\pa\\widetilde{S}^{-1,0}_{a,-} W_2(\\Omega, \\Gamma_1)\\right|\\ \\right|\\left| |u|\\overset{\\circ}{\\to} W_2^{\\widetilde{A}}(\\Omega;\\Gamma_r,T)\\right|\\Bigg|\\\\&\\\\&\\textcolor{magenta}{\\mathrm{Produit\\ avec\\ Java\\ et\\ \\LaTeX\\ par\\ }\\mathscr{C}\\mathcal{A}\\mathfrak{L}\\mathbf{I}\\mathtt{X}\\mathbb{T}\\mathsf{E}}\\\\&\\begin{pmatrix}\\alpha&\\beta&\\gamma&\\delta\\\\\\aleph&\\beth&\\gimel&\\daleth\\\\\\mathfrak{A}&\\mathfrak{B}&\\mathfrak{C}&\\mathfrak{D}\\\\\\boldsymbol{\\mathfrak{a}}&\\boldsymbol{\\mathfrak{b}}&\\boldsymbol{\\mathfrak{c}}&\\boldsymbol{\\mathfrak{d}}\\end{pmatrix}\\quad{(a+b)}^{\\frac{n}{2}}=\\sqrt{\\sum_{k=0}^n\\tbinom{n}{k}a^kb^{n-k}}\\quad \\Biggl(\\biggl(\\Bigl(\\bigl(()\\bigr)\\Bigr)\\biggr)\\Biggr)\\\\&\\forall\\varepsilon\\in\\mathbb{R}_+^*\\ \\exists\\eta>0\\ |x-x_0|\\leq\\eta\\Longrightarrow|f(x)-f(x_0)|\\leq\\varepsilon\\\\&\\det\\begin{bmatrix}a_{11}&a_{12}&\\cdots&a_{1n}\\\\a_{21}&\\ddots&&\\vdots\\\\\\vdots&&\\ddots&\\vdots\\\\a_{n1}&\\cdots&\\cdots&a_{nn}\\end{bmatrix}\\overset{\\mathrm{def}}{=}\\sum_{\\sigma\\in\\mathfrak{S}_n}\\varepsilon(\\sigma)\\prod_{k=1}^n a_{k\\sigma(k)}\\\\&\\Delta f(x,y)=\\frac{\\partial^2f}{\\partial x^2}+\\frac{\\partial^2f}{\\partial y^2}\\qquad\\qquad \\fcolorbox{noir}{gris}{n!\\underset{n\\rightarrow+\\infty}{\\sim} {\\left(\\frac{n}{e}\\right)}^n\\sqrt{2\\pi n}}\\\\&\\sideset{_\\alpha^\\beta}{_\\gamma^\\delta}{\\begin{pmatrix}a&b\\\\c&d\\end{pmatrix}}\\xrightarrow[T]{n\\pm i-j}\\sideset{^t}{}A\\xleftarrow{\\overrightarrow{u}\\wedge\\overrightarrow{v}}\\underleftrightarrow{\\iint_{\\mathds{R}^2}e^{-\\left(x^2+y^2\\right)}\\,\\mathrm{d}x\\mathrm{d}y}\\end{split}\\\\\\rotatebox{30}{\\sum_{n=1}^{+\\infty}}\\quad\\mbox{Mirror rorriM}\\reflectbox{\\mbox{Mirror rorriM}}\\end{array}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/later_test4.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = later_test()\n    t.later_test04()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func later_test04(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\begin{array}{|c|c|c|c|}\n\\multicolumn{4}{c}{\\shadowbox{\\text{\\Huge An image from the \\LaTeX3 project}}}\\cr\n\\hline\n\\text{Left}\\includegraphics{src/test/resources/lion.png}\\text{Right} & \\text{Left}\\includegraphics[width=3cm,interpolation=bicubic]{src/test/resources/lion.png}\\text{Right} & \\text{Left}\\includegraphics[angle=45,width=3cm]{src/test/resources/lion.png}\\text{Right} & \\text{Left}\\includegraphics[angle=160]{src/test/resources/lion.png}\\text{Right} \\cr\n\\hline\n\\text{\\backslash includegraphics\\{src/test/resources/lion.png\\}} & \\text{\\backslash includegraphics[width=3cm,interpolation=bicubic]\\{lion.png\\}} & \\text{\\backslash includegraphics[angle=45,width=3cm]\\{lion.png\\}} & \\text{\\backslash includegraphics[angle=160]\\{lion.png\\}}\\cr\n\\hline\n\\end{array}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/later_test5.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = later_test()\n    t.later_test05()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func later_test05(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\begin{array}{|c|l|||r|c|}\\hline\\text{Matrix}&\\multicolumn{2}{|c|}{\\text{Multicolumns}}&\\text{Font sizes commands}\\cr\\hline\\begin{pmatrix}\\alpha_{11}&\\cdots&\\alpha_{1n}\\cr\\hdotsfor{3}\\cr\\alpha_{n1}&\\cdots&\\alpha_{nn}\\end{pmatrix}&\\Large \\text{Large Right}&\\small \\text{small Left}&\\tiny \\text{tiny Tiny}\\cr\\hline\\multicolumn{4}{|c|}{\\Huge \\text{Huge Multicolumns}}\\cr\\hline\\end{array}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/later_test6.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = later_test()\n    t.later_test06()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func later_test06(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\begin{array}{cc}\\fbox{\\text{A framed box with \\textdbend}}&\\shadowbox{\\text{A shadowed box}}\\cr\\doublebox{\\text{A double framed box}}&\\ovalbox{\\text{An oval framed box}}\\cr\\end{array}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/later_test7.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = later_test()\n    t.later_test07()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func later_test07(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\mbox{abc abc abc abc abc abc abc abc abc abc abc abc abc abc\\\\abc abc abc abc abc abc abc\\\\abc abc abc abc abc abc abc}\\\\1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/later_test8.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = later_test()\n    t.later_test08()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func later_test08(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\text{A long division \\longdiv{12345}{13}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/later_test9.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = later_test()\n    t.later_test09()\n    return ret\n}\n\n@Test\npublic class c_test_test {\n    @TestCase\n    func later_test09(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n{a \\bangle b} {c \\brace d} {e \\brack f} {g \\choose h}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/test1.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = test()\n    t.test1()\n    return ret\n}\n\n@Test\npublic class test {\n    @TestCase\n    func test1(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\sideset{^\\backprime}{'}\n\\sum_{x=1}^{\\infty} x\n\\sideset{a_1^2}{}\\sum_{x=1}^\\infty x_0\n\\\\\n\\sideset{_\\text{left bottom}'''}{_{\\text{right bottom}}'''}\n\\sum_{\\text{quite long text}}^\\infty x\n\\\\\n\\sideset{}{'}\n\\sum_{n<k,\\;\\text{$n$ odd}} nE_n\n\\\\\n\\sideset{}{'}\n\\sum^{n<k,\\;\\text{$n$ odd}} nE_n\n\\\\\nM_x''' M'''_x M^{'''}_x M_x{'''} M^{\\prime\\backprime}\n\"###\n        var r = latex.parse(str, 1000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/test2.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = test()\n    t.test2()\n    return ret\n}\n\n@Test\npublic class test {\n    @TestCase\n    func test2(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\sideset{^\\backprime}{'}\n\\sum_{x=1}^{\\infty} x\n\\sideset{a_1^2}{}\\sum_{x=1}^\\infty x_0\n\\\\\n\\sideset{_\\text{left bottom}'''}{_{\\text{right bottom}}'''}\n\\sum_{\\text{quite long text}}^\\infty x\n\\\\\n\\sideset{}{'}\n\\sum_{n<k,\\;\\text{$n$ odd}} nE_n\n\\\\\n\\sideset{}{'}\n\\sum^{n<k,\\;\\text{$n$ odd}} nE_n\n\\\\\nM_x''' M'''_x M^{'''}_x M_x{'''} M^{\\prime\\backprime}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/test3.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = test()\n    t.test3()\n    return ret\n}\n\n@Test\npublic class test {\n    @TestCase\n    func test3(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\sideset{^\\backprime}{'}\n\\sum_{x=1}^{\\infty} x\n\\sideset{a_1^2}{}\\sum_{x=1}^\\infty x_0\n\\\\\n\\sideset{_\\text{left bottom}'''}{_{\\text{right bottom}}'''}\n\\sum_{\\text{quite long text}}^\\infty x\n\\\\\n\\sideset{}{'}\n\\sum_{n<k,\\;\\text{$n$ odd}} nE_n\n\\\\\n\\sideset{}{'}\n\\sum^{n<k,\\;\\text{$n$ odd}} nE_n\n\\\\\nM_x''' M'''_x M^{'''}_x M_x{'''} M^{\\prime\\backprime}\n\"###\n        var r = latex.parse(str, 2000000000, 80.0, 100.0, 0xFF000005)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/test4.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = test()\n    t.test4()\n    return ret\n}\n\n@Test\npublic class test {\n    @TestCase\n    func test4(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\sideset{^\\backprime}{'}\n\\sum_{x=1}^{\\infty} x\n\\sideset{a_1^2}{}\\sum_{x=1}^\\infty x_0\n\\\\\n\\sideset{_\\text{left bottom}'''}{_{\\text{right bottom}}'''}\n\\sum_{\\text{quite long text}}^\\infty x\n\\\\\n\\sideset{}{'}\n\\sum_{n<k,\\;\\text{$n$ odd}} nE_n\n\\\\\n\\sideset{}{'}\n\\sum^{n<k,\\;\\text{$n$ odd}} nE_n\n\\\\\nM_x''' M'''_x M^{'''}_x M_x{'''} M^{\\prime\\backprime}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/test5.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = test()\n    t.test5()\n    return ret\n}\n\n@Test\npublic class test {\n    @TestCase\n    func test5(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\sideset{^\\backprime}{'}\n\\sum_{x=1}^{\\infty} x\n\\sideset{a_1^2}{}\\sum_{x=1}^\\infty x_0\n\\\\\n\\sideset{_\\text{left bottom}'''}{_{\\text{right bottom}}'''}\n\\sum_{\\text{quite long text}}^\\infty x\n\\\\\n\\sideset{}{'}\n\\sum_{n<k,\\;\\text{$n$ odd}} nE_n\n\\\\\n\\sideset{}{'}\n\\sum^{n<k,\\;\\text{$n$ odd}} nE_n\n\\\\\nM_x''' M'''_x M^{'''}_x M_x{'''} M^{\\prime\\backprime}\n\"###\n        var r = latex.parse(str, 2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/test6.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = test()\n    t.test6()\n    return ret\n}\n\n@Test\npublic class test {\n    @TestCase\n    func test6(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\sideset{^\\backprime}{'}\n\\sum_{x=1}^{\\infty} x\n\\sideset{a_1^2}{}\\sum_{x=1}^\\infty x_0\n\\\\\n\\sideset{_\\text{left bottom}'''}{_{\\text{right bottom}}'''}\n\\sum_{\\text{quite long text}}^\\infty x\n\\\\\n\\sideset{}{'}\n\\sum_{n<k,\\;\\text{$n$ odd}} nE_n\n\\\\\n\\sideset{}{'}\n\\sum^{n<k,\\;\\text{$n$ odd}} nE_n\n\\\\\nM_x''' M'''_x M^{'''}_x M_x{'''} M^{\\prime\\backprime}\n\"###\n        var r = latex.parse(str, -2000000000, 40.0, 10.0, 0xFF000000)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/test7.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = test()\n    t.test7()\n    return ret\n}\n\n@Test\npublic class test {\n    @TestCase\n    func test7(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\sideset{^\\backprime}{'}\n\\sum_{x=1}^{\\infty} x\n\\sideset{a_1^2}{}\\sum_{x=1}^\\infty x_0\n\\\\\n\\sideset{_\\text{left bottom}'''}{_{\\text{right bottom}}'''}\n\\sum_{\\text{quite long text}}^\\infty x\n\\\\\n\\sideset{}{'}\n\\sum_{n<k,\\;\\text{$n$ odd}} nE_n\n\\\\\n\\sideset{}{'}\n\\sum^{n<k,\\;\\text{$n$ odd}} nE_n\n\\\\\nM_x''' M'''_x M^{'''}_x M_x{'''} M^{\\prime\\backprime}\n\"###\n        var color1: UInt32 = 0xffff0000\n        var r = latex.parse(str, 1000000000, 40.0, 10.0, color1)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n\n        var arr = r.toBitmap(g2)\n\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/test8.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = test()\n    t.test8()\n    return ret\n}\n\n@Test\npublic class test {\n    @TestCase\n    func test8(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\\sideset{^\\backprime}{'}\n\\sum_{x=1}^{\\infty} x\n\\sideset{a_1^2}{}\\sum_{x=1}^\\infty x_0\n\\\\\n\\sideset{_\\text{left bottom}'''}{_{\\text{right bottom}}'''}\n\\sum_{\\text{quite long text}}^\\infty x\n\\\\\n\\sideset{}{'}\n\\sum_{n<k,\\;\\text{$n$ odd}} nE_n\n\\\\\n\\sideset{}{'}\n\\sum^{n<k,\\;\\text{$n$ odd}} nE_n\n\\\\\nM_x''' M'''_x M^{'''}_x M_x{'''} M^{\\prime\\backprime}\n\"###\n        var color1: UInt32 = 0xffff0000\n        var r = latex.parse(str, 10, 40.0, 10.0, color1)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n        var arr = r.toBitmap(g2)\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/formula-ffi/test/LLT/test9.cj",
    "content": "// EXEC: cjc %import-path %L %l %f\n// EXEC: ./main\n\nimport formula.*\nimport std.unittest.*\nimport std.collection.*\nimport std.fs.*\nimport std.unittest.*\nimport std.unittest.testmacro.*\n\nmain(): Int64 {\n    var ret = 0\n    var t = test()\n    t.test9()\n    return ret\n}\n\n@Test\npublic class test {\n    @TestCase\n    func test9(): Unit {\n        var latex = LaTeX(\"res\")\n        var str = ###\"\n\"###\n        var color1: UInt32 = 0xffff0000\n        var r = latex.parse(str, 10, 40.0, 10.0, color1)\n        var w = r.getWidth()\n        var h = r.getHeight()\n        println(w)\n        println(h)\n        var g2 = Graphic2D(r, COLOR_FORMAT_BGRA_8888)\n        r.draw(g2, 0xFFFFFFFF)\n        var arr = r.toBitmap(g2)\n        var file: File = File(\"test.bmp\", OpenOption.CreateOrTruncate(false))\n        file.write(arr)\n        file.close()\n    }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/napi_init.cpp",
    "content": "#include \"napi/native_api.h\"\n#include \"latex_ffi.h\"\n#include \"graphic_ohos_ffi.h\"\n#include \"render_ffi.h\"\n\n#include \"hilog/log.h\"\n#undef LOG_DOMAIN\n#undef LOG_TAG\n#define LOG_DOMAIN 0x3200  // Global domain macro, identifying the business domain\n#define LOG_TAG \"libLatex\" // Global tag macro, identifying module log tags\n\n#define LATEX_MAX_BUFFER_SIZE 4096\n\nstatic napi_value getLatex(napi_env env, napi_callback_info info) {\n    size_t argc = 5;\n    napi_value args[5] = {nullptr};\n    char latex[LATEX_MAX_BUFFER_SIZE];\n\n    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);\n\n    size_t data_Size;\n    napi_get_value_string_utf8(env, args[0], latex, LATEX_MAX_BUFFER_SIZE, &data_Size);\n\n    double value0;\n    napi_get_value_double(env, args[1], &value0);\n\n    double value1;\n    napi_get_value_double(env, args[2], &value1);\n\n    double value2;\n    napi_get_value_double(env, args[3], &value2);\n\n    uint32_t font_color;\n    napi_get_value_uint32(env, args[4], &font_color);\n\n    auto r = LaTeX_parse(latex, value0, value1, value2, font_color);\n\n    int h = TeXRender_getHeight(r);\n    int w = TeXRender_getWidth(r);\n    int text_size = TeXRender_getTextSize(r);\n    auto bitmap = initGraphics2D_ffi(w + (text_size / 9.0) + 1, h + (text_size / 9.0) + 1,\n                                     COLOR_FORMAT_BGRA_8888); // COLOR_FORMAT_BGRA_8888 COLOR_FORMAT_RGB_565\n\n    TeXRender_draw(r, bitmap, 0, 0, 0x00FFFFFF);\n\n    auto out = TeXRender_toBitmap(r, bitmap, COLOR_FORMAT_BGRA_8888);\n\n    char *data = nullptr;\n    napi_value result = nullptr;\n    napi_create_buffer_copy(env, out.len, out.data, reinterpret_cast<void **>(&data), &result);\n\n    return result;\n}\n\nstatic napi_value initLatex(napi_env env, napi_callback_info info) {\n    size_t argc = 1;\n    napi_value args[1] = {nullptr};\n    char res[LATEX_MAX_BUFFER_SIZE];\n\n    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);\n\n    size_t data_Size;\n    napi_get_value_string_utf8(env, args[0], res, LATEX_MAX_BUFFER_SIZE, &data_Size);\n    \n//    LaTeX_init(\"/data/storage/el1/bundle/latex/resources/resfile/res\");\n    LaTeX_init(res);\n\n    napi_value result = nullptr;\n    uint32_t ret = 10;\n    napi_create_uint32(env, ret, &result);\n\n    return result;\n}\n\nEXTERN_C_START\nstatic napi_value Init(napi_env env, napi_value exports) {\n    napi_property_descriptor desc[] = {\n        {\"getLatex\", nullptr, getLatex, nullptr, nullptr, nullptr, napi_default, nullptr},\n        {\"initLatex\", nullptr, initLatex, nullptr, nullptr, nullptr, napi_default, nullptr},\n        \n    };\n    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);\n\n    return exports;\n}\nEXTERN_C_END\n\nstatic napi_module demoModule = {\n    .nm_version = 1,\n    .nm_flags = 0,\n    .nm_filename = nullptr,\n    .nm_register_func = Init,\n    .nm_modname = \"latexentry\",\n    .nm_priv = ((void *)0),\n    .reserved = {0},\n};\n\nextern \"C\" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/types/liblatexentry/Index.d.ts",
    "content": "export const getLatex: (latex:string,width:number,fontsize:number,lineSpace:number,fontcolor:number) => ArrayBuffer;\nexport const initLatex:(res:string)=>number;"
  },
  {
    "path": "HarmonyOS/markdown/src/main/cpp/types/liblatexentry/oh-package.json5",
    "content": "{\n  \"name\": \"liblatexentry.so\",\n  \"types\": \"./Index.d.ts\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Please describe the basic information.\"\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/engine/base.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { IEngine, Engine, EEngine } from './engine';\nimport {\n  AstService, CodeService, ContextService,\n  HtmlService, ImageService,\n  EventService, CssService, MathService,\n} from '../service';\nimport { ThemeService } from '../theme';\nimport { RenderService } from '../render';\n\ninterface IBaseEngine extends IEngine {}\nexport class BaseEngine extends Engine<IBaseEngine> {\n  readonly type: EEngine = EEngine.Base;\n  constructor(option?: IBaseEngine) {\n    super(option);\n    [\n      new AstService(this),\n      new CodeService(this),\n      new ContextService(this),\n      new HtmlService(this),\n      new ImageService(this),\n      new ThemeService(this),\n      new RenderService(this),\n      new EventService(this),\n      new CssService(this),\n      new MathService(this),\n    ].forEach(ele => this.services.set(ele.type, ele));\n  }\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/engine/engine.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { type Service, EService } from './service';\nimport type {\n  AstService, CodeService, ContextService,\n  HtmlService, ImageService,\n  EventService, CssService, MathService,\n} from '../service';\nimport type { ThemeService } from '../theme';\nimport type { RenderService } from '../render';\n\nexport enum EEngine {\n  Unknown = 'unknown',\n  Base = 'base',\n  Global = 'global',\n}\nexport interface IEngine {}\nexport abstract class Engine <\n  Option extends IEngine = IEngine\n> {\n  readonly type: EEngine = EEngine.Unknown;\n  readonly option?: Option;\n  protected services: Map<EService, Service> = new Map();\n  constructor(option?: Option) {\n    this.option = option;\n  }\n  service<T extends Service = Service>(type: EService): T | undefined {\n    return this.services.get(type) as T;\n  }\n\n  get ast() {\n    return this.service<AstService>(EService.AST);\n  }\n  get code() {\n    return this.service<CodeService>(EService.Code);\n  }\n  get ctx() {\n    return this.service<ContextService>(EService.CTX);\n  }\n  get html() {\n    return this.service<HtmlService>(EService.HTML);\n  }\n  get image() {\n    return this.service<ImageService>(EService.Image);\n  }\n  get theme() {\n    return this.service<ThemeService>(EService.Theme);\n  }\n  get render() {\n    return this.service<RenderService>(EService.Render);\n  }\n  get event() {\n    return this.service<EventService>(EService.Event);\n  }\n  get css() {\n    return this.service<CssService>(EService.CSS);\n  }\n  get math() {\n    return this.service<MathService>(EService.Math);\n  }\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/engine/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport * from './base';\nexport * from './engine';\nexport * from './plugin';\nexport * from './service';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/engine/plugin.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport abstract class Plugin {}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/engine/service.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport type { Plugin } from './plugin';\nimport type { Engine } from './engine';\n\nexport enum EService {\n  AST = 'ast',\n  Code = 'code',\n  CTX = 'ctx',\n  HTML = 'html',\n  Image = 'image',\n  Latex = 'latex',\n  Theme = 'theme',\n  File = 'file',\n  Render = 'render',\n  Event = 'event',\n  Typing = 'typing',\n  CSS = 'css',\n  Math = 'math',\n}\nexport abstract class Service {\n  readonly engine?: WeakRef<Engine>;\n  constructor(engine?: Engine) {\n    this.engine = engine ? new WeakRef(engine) : undefined;\n  }\n  abstract readonly type: EService;\n  abstract add<T extends Plugin>(plugin: T): void;\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport * from './service';\nexport * from './theme';\nexport * from './util';\nexport * from './engine';\nexport * from './markdown';\nexport * from './render';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/markdown.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { Engine, BaseEngine } from './engine';\nimport { newLog, K_COMPONENT, IMDArea, MDArea, EMarkdownMode, EMarkdownMainBotEvent } from './util';\nimport { Program, type Node } from './service/ast/node';\nimport {\n  type ITextComponentSelectionChangeEvent,\n  type ITextComponentEvent, type ITextComponentSelectionOption,\n  type ITableComponentActionClickEvent, type IContentBoxBar,\n  type ITableComponentEvent,\n  type ICodeComponentEvent, type ICodeComponentActionClickEvent,\n  Typing, ITypingUpdateData,\n  TextContentController,\n  FragmentComponent, FragmentComponentController,\n} from './render';\nimport { type ITheme } from './theme';\n\nconst log = newLog('Markdown');\n\n@ComponentV2\nexport struct Markdown {\n  private static gid: number = 0;\n  private static createGid(): number {\n    return Markdown.gid++;\n  }\n  readonly ID: number = Markdown.createGid();\n\n  @Param content: string = '';\n  @Param @Once controller: MarkdownController = new MarkdownController({});\n  @Param @Once engine: Engine = new BaseEngine();\n  @Param @Once mode: EMarkdownMode = EMarkdownMode.Normal;\n  @Param @Once area: IMDArea = {};\n\n  @Event onMarkdownBeforeAboutToAppear: Callback<IMarkdownEvent>;\n  @Event onMarkdownAfterAboutToAppear: Callback<IMarkdownEvent>;\n  @Event onMarkdownBeforeAboutToDisappear: Callback<IMarkdownEvent>;\n  @Event onMarkdownAfterAboutToDisappear: Callback<IMarkdownEvent>;\n  @Event onMarkdownBeforeAboutToReuse: Callback<IMarkdownEvent>;\n  @Event onMarkdownAfterAboutToReuse: Callback<IMarkdownEvent>;\n  @Event onMarkdownBeforeAboutToRecycle: Callback<IMarkdownEvent>;\n  @Event onMarkdownAfterAboutToRecycle: Callback<IMarkdownEvent>;\n  @Event onMarkdownAreaChange: Callback<IMarkdownAreaChangeEvent>;\n  @Event onMarkdownNodeClick: Callback<IMarkdownNodeClickEvent>;\n  @Event onMarkdownTextComponentSelectionOption: Callback<IMarkdownTextComponentSelectionOptionEvent, ITextComponentSelectionOption>;\n  @Event onMarkdownTextComponentSelectionChange: Callback<IMarkdownTextComponentSelectionChangeEvent>;\n  @Event onMarkdownTableComponentActionClick: Callback<IMarkdownTableComponentActionClickEvent>;\n  @Event onMarkdownTableComponentContentBoxBar: Callback<IMarkdownTableComponentBarOptionEvent, IContentBoxBar | undefined>;\n  @Event onMarkdownCodeComponentActionClick: Callback<IMarkdownCodeComponentActionClickEvent>;\n  @Event onMarkdownCodeComponentContentBoxBar: Callback<IMarkdownCodeComponentBarOptionEvent, IContentBoxBar | undefined>;\n  @Event onMarkdownTypingReady: Callback<IMarkdownEvent>;\n  @Event onMarkdownTypingCompleted: Callback<IMarkdownEvent>;\n\n  @Local program?: Program;\n  @Provider(K_COMPONENT.THEME) theme: ITheme = this.engine.theme!.theme;\n  @Provider(K_COMPONENT.SHARED_ENGINE) sharedEngine: Engine = this.engine;\n\n  private fragmentController: FragmentComponentController = new FragmentComponentController({});\n  private fragmentComponentTypingReady: boolean = false;\n  private uiArea?: Area;\n  private mainBotScrolling: boolean = false;\n  private parser: MarkdownParser = new MarkdownParser(this.engine);\n  private typingUpdateDataList: ITypingUpdateData<string>[] = [];\n  private typingUpdateData?: ITypingUpdateData<string>;\n\n  @Monitor('area') _onMarkdownAreaChange(monitor: IMonitor) {\n    const value = monitor.value<IMDArea>();\n    if (MDArea.isEmpty(value?.before) && this.mode === EMarkdownMode.Normal) {\n      this.parser.parse(this.content).then(program => {\n        this.program = program;\n      }).catch((e: Error) => {\n        log.w(`${this.ID} can not parse content after area not empty. parse failed: ${e?.message}`)\n      });\n    }\n  }\n  @Monitor('content') onContentChange(monitor: IMonitor) {\n    const value = monitor.value<string>();\n    log.i(`${this.ID} onContentChange now: ${value?.now} before: ${value?.before}`);\n    if (this.mode === EMarkdownMode.Normal) {\n      this.parser.parse(value?.now || '').then(program => {\n        this.program = program;\n      }).catch((e: Error) => {\n        log.w(`${this.ID} can not parse content after content changed. parse failed: ${e?.message}`)\n      });\n    }\n  }\n  private bindController() {\n    this.sharedEngine.ctx!.typing = () => ({\n      speed: this.controller.typingSpeed,\n      step: this.controller.typingStep,\n      rootController: new WeakRef(this.controller.typing),\n      more: this.controller.typingMore,\n    });\n    this.sharedEngine.ctx!.textContentController = () => {\n      return this.controller.textContentController;\n    }\n    this.controller.textContentController.isHit = (_type, event) => {\n      return MDArea.isAreaContainFinger(this.uiArea, event.fingerList.slice().pop());\n    };\n    this.controller.typing.should = () => {\n      return this.mode === EMarkdownMode.Typing;\n    };\n    this.controller.typing.processing = () => {\n      return this.fragmentController.typing.processing();\n    };\n    this.controller.typing.completed = () => {\n      return this.fragmentController.typing.completed();\n    };\n    this.controller.typing.pause = () => {\n      return this.fragmentController.typing.pause();\n    };\n    this.controller.typing.resume = () => {\n      return this.fragmentController.typing.resume();\n    }\n    this.controller.typing.stop = () => {\n      return this.fragmentController.typing.stop();\n    };\n\n    this.controller.typing.update = (content, mode, hasMore) => {\n      log.i(`${this.ID} update typing content: ${JSON.stringify(content)}, mode: ${mode}, hasMore: ${hasMore}`);\n      if (this.mode !== EMarkdownMode.Typing) {\n        log.w(`${this.ID} current mode(${this.mode}) is not typing, can not update typing content`);\n        return;\n      }\n      if (!this.fragmentComponentTypingReady) {\n        log.w(`${this.ID} fragment component typing not ready, skip update typing content: ${content}`);\n      }\n      if (typeof content === 'string') {\n        log.i(`${this.ID} pick typing content: ${JSON.stringify(content)}, mode: ${mode}, hasMore: ${hasMore}`);\n        this.typingUpdateDataList.push({ content, mode, hasMore });\n        this.typingUpdate();\n      }\n    };\n  }\n  private typingUpdate() {\n    if (this.mainBotScrolling) {\n      log.i(`${this.ID} skip typing update while scrolling.`);\n      return;\n    }\n    if (this.typingUpdateData) {\n      log.i(`${this.ID} skip typing update while processing. mode: ${this.typingUpdateData.mode}, hasMore: ${this.typingUpdateData.hasMore}, content: ${this.typingUpdateData.content}`);\n      return;\n    }\n    const data = this.typingUpdateDataList.slice().pop();\n    if (data) {\n      this.typingUpdateData = data;\n      this.parser.parse(data.content).then(program => {\n        log.i(`${this.ID} will update typing content after parse. node: ${program.document.hash}, mode: ${data.mode}, hasMore: ${data.hasMore} content: ${data.content}`);\n        this.fragmentController.typing.update(program.document, data.mode);\n      }).catch((e: Error) => {\n        log.w(`${this.ID} can not update typing content after parse. parse failed: ${e?.message}`);\n        this.onTypingFinish(true);\n      });\n    }\n  }\n  private onTypingFinish(hasError?: boolean) {\n    const equal = (a?: ITypingUpdateData<string>, b?: ITypingUpdateData<string>): boolean => {\n      return !!(a?.mode === b?.mode && a?.hasMore === b?.hasMore && a?.content === b?.content);\n    };\n    const data = this.typingUpdateDataList.slice().pop();\n    const last = this.typingUpdateData\n    this.typingUpdateData = undefined;\n    if (equal(data, last)) {\n      log.i(`${this.ID} emit typing finish event. mode: ${data?.mode}, hasMore: ${data?.hasMore}, hasError: ${!!hasError} content: ${data?.content}`);\n      this.typingUpdateDataList = [];\n      this.onMarkdownTypingCompleted({});\n    } else {\n      log.i(`${this.ID} last content is not same as last typing update content, skip emit typing finish event. hasError: ${!!hasError}`);\n      this.typingUpdate();\n    }\n  }\n  private onMainBotScrollBegin = () => {\n    log.i(`${this.ID} onMainBotScrollBegin, try to pause typing`);\n    this.mainBotScrolling = true;\n    this.controller.typing.pause();\n  }\n  private onMainBotScrollEnd = () => {\n    log.i(`${this.ID} onMainBotScrollEnd, try to resume typing`);\n    this.mainBotScrolling = false;\n    this.controller.typing.resume();\n    this.typingUpdate();\n  }\n  private onMainBotStopTyping = () => {\n    log.i(`${this.ID} onMainBotStopTyping, try to stop typing`);\n    this.controller.typing.stop();\n  }\n\n  aboutToAppear(): void {\n    log.i(`${this.ID} before aboutToAppear`);\n    this.onMarkdownBeforeAboutToAppear({});\n    this.engine.ctx!.ctx = this.getUIContext();\n    this.engine.ctx!.markdownMode = () => this.mode;\n    this.bindController();\n\n    this.engine.event!.onClick = data => {\n      this.onMarkdownNodeClick({ node: data.node, event: data.event });\n    };\n    this.engine.event!.onTextComponentSelectionChange = event => {\n      this.onMarkdownTextComponentSelectionChange({ textEvent: event });\n    };\n    this.engine.event!.onTextComponentSelectionOption = event => {\n      return this.onMarkdownTextComponentSelectionOption({ textEvent: event }) ?? {};\n    };\n    this.engine.event!.onTableComponentActionClick = event => {\n      this.onMarkdownTableComponentActionClick({ tableEvent: event });\n    };\n    this.engine.event!.onTableComponentBarOption = event => {\n      return this.onMarkdownTableComponentContentBoxBar({ tableEvent: event });\n    };\n    this.engine.event!.onCodeComponentActionClick = event => {\n      this.onMarkdownCodeComponentActionClick({ codeEvent: event });\n    };\n    this.engine.event!.onCodeComponentBarOption = event => {\n      return this.onMarkdownCodeComponentContentBoxBar({ codeEvent: event });\n    };\n    if (!MDArea.isEmpty(this.area)) {\n      this.parser.parse(this.content).then(program => {\n        this.program = program;\n      }).catch((e: Error) => {\n        log.w(`${this.ID} can not parse content while aboutToAppear. parse failed: ${e?.message}`);\n      });\n    }\n\n    getContext(this)?.eventHub?.on(EMarkdownMainBotEvent.ScrollBegin, this.onMainBotScrollBegin);\n    getContext(this)?.eventHub?.on(EMarkdownMainBotEvent.ScrollEnd, this.onMainBotScrollEnd);\n    getContext(this)?.eventHub?.on(EMarkdownMainBotEvent.StopTyping, this.onMainBotStopTyping);\n\n    this.onMarkdownAfterAboutToAppear({});\n\n    log.i(`${this.ID} after aboutToAppear`);\n  }\n  aboutToDisappear(): void {\n    log.i(`${this.ID} before aboutToDisappear`);\n    this.onMarkdownBeforeAboutToDisappear({});\n    getContext(this)?.eventHub?.off(EMarkdownMainBotEvent.ScrollBegin, this.onMainBotScrollBegin);\n    getContext(this)?.eventHub?.off(EMarkdownMainBotEvent.ScrollEnd, this.onMainBotScrollEnd);\n    getContext(this)?.eventHub?.off(EMarkdownMainBotEvent.StopTyping, this.onMainBotStopTyping);\n    this.onMarkdownAfterAboutToDisappear({});\n    log.i(`${this.ID} after aboutToDisappear`);\n  }\n  aboutToReuse(): void {\n    log.i(`${this.ID} before aboutToReuse`);\n    this.onMarkdownBeforeAboutToReuse({});\n    this.onMarkdownAfterAboutToReuse({});\n    log.i(`${this.ID} after aboutToReuse`);\n  }\n  aboutToRecycle(): void {\n    log.i(`${this.ID} before aboutToRecycle`);\n    this.onMarkdownBeforeAboutToRecycle({});\n    this.onMarkdownAfterAboutToRecycle({});\n    log.i(`${this.ID} after aboutToRecycle`);\n  }\n\n  build() {\n    if (MDArea.isEmpty(this.area)) {\n      Row()\n        .width('100%')\n        .onAreaChange((oldValue, newValue) => {\n          this.uiArea = newValue;\n          this.area = MDArea.area(newValue);\n          this.onMarkdownAreaChange({ oldValue, newValue });\n        })\n    } else {\n      Stack({ alignContent: Alignment.TopStart }) {\n        FragmentComponent({\n          node: this.program?.document, area: this.area, controller: this.fragmentController,\n          onFragmentComponentAfterAboutToAppear: () => {\n            this.fragmentComponentTypingReady = true;\n            log.i(`${this.ID} on typing will ready`);\n            this.onMarkdownTypingReady({});\n            log.i(`${this.ID} on typing did ready`);\n          },\n          onFragmentComponentBeforeAboutToDisappear: () => {\n            this.fragmentComponentTypingReady = false;\n          },\n          onFragmentComponentTypingFinish: () => this.onTypingFinish(),\n        })\n      }\n      .position({ x: 0, y: 0 })\n      .zIndex(0)\n      .width('100%')\n      .onAreaChange((oldValue, newValue) => {\n        if (oldValue?.width !== newValue?.width || oldValue?.height !== newValue?.height) {\n          const desc = (area: Area) => `{ w: ${area.width}, h: ${area.height}, p: (${area.position.x}, ${area.position.y}), gp: (${area.globalPosition.x}, ${area.globalPosition.y}) }`;\n          log.i(`${this.ID} onAreaChange new ${desc(newValue)} old ${desc(oldValue)}`);\n        }\n        this.uiArea = newValue;\n        this.area = MDArea.area(newValue);\n        this.onMarkdownAreaChange({ oldValue, newValue });\n      })\n    }\n  }\n}\n\nconst log2 = newLog('MarkdownParser');\n\nclass MarkdownParser {\n  private static gid: number = 0;\n  readonly ID: number = MarkdownParser.gid++;\n  private count: number = 0;\n  private engine: Engine;\n  lastContent?: string;\n  constructor(engine: Engine) {\n    this.engine = engine;\n  }\n  async parse(content: string): Promise<Program> {\n    this.lastContent = content;\n    try {\n      this.count++;\n      log2.i(`${this.ID} drop parse task. count: ${this.count} content: ${JSON.stringify(content)}`);\n      const result = (await this.engine.ast!.parse(content));\n      log2.i(`${this.ID} parse content success: document hash: ${result.program.document.hash} document children: ${result.program.document.children.length} content: ${JSON.stringify(result.content)} `);\n      this.count--;\n      return result.program;\n    } catch (e) {\n      this.count--;\n      throw Error(`${e?.message}`);\n    }\n  }\n  get processing(): boolean {\n    return this.count > 0;\n  }\n}\n\ninterface IMarkdownController {\n  /**\n   * @note units: ms\n   * @default 25\n   */\n  typingSpeed?: number;\n  /**\n   * @default 1\n   */\n  typingStep?: number;\n  /**\n   * tail message while stop typing, eg ...\n   */\n  typingMore?: string;\n}\nexport class MarkdownController {\n  private option: IMarkdownController;\n  private listener: Record<string, IMarkdownEventCallback[]> = {};\n  readonly typing: Typing = new Typing();\n  readonly textContentController: TextContentController = new TextContentController();\n  constructor(option: IMarkdownController) {\n    this.option = option;\n  }\n  set typingSpeed(value: number | undefined) {\n    log.i(`set typingSpeed ${value}`);\n    this.option.typingSpeed = value;\n  }\n  get typingSpeed(): number | undefined {\n    return this.option.typingSpeed;\n  }\n  set typingStep(value: number | undefined) {\n    log.i(`set typingStep ${value}`);\n    this.option.typingStep = value;\n  }\n  get typingStep(): number | undefined {\n    return this.option.typingStep;\n  }\n  get typingMore(): string | undefined {\n    return this.option.typingMore;\n  }\n  on<T, V = void>(name: string, callback: Callback<T, V>) {\n    if (!this.listener[name]) {\n      this.listener[name] = [];\n    }\n    this.listener[name].push({ type: EMarkdownEventCallback.On, callback });\n    return this;\n  }\n  once<T, V = void>(name: string, callback: Callback<T, V>) {\n    if (!this.listener[name]) {\n      this.listener[name] = [];\n    }\n    this.listener[name].push({ type: EMarkdownEventCallback.Once, callback });\n    return this;\n  }\n  emit<T, V = void>(name: string, event: T): V {\n    let result: V = undefined as V;\n    this.listener[name]?.forEach(ele => {\n      result = (ele.callback as Callback<T, V>)(event);\n      if (ele.type === EMarkdownEventCallback.Once) {\n        this.off(name, (ele.callback as Callback<T, V>));\n      }\n    });\n    return result;\n  }\n  off<T, V = void>(name: string, callback?: Callback<T, V>) {\n    if (callback) {\n      this.listener[name] = this.listener[name].filter(ele => ele.callback !== callback);\n    } else {\n      this.listener[name] = [];\n    }\n    return this;\n  }\n}\nenum EMarkdownEventCallback {\n  On = 'on',\n  Once = 'once',\n}\ninterface IMarkdownEventCallback {\n  type: EMarkdownEventCallback;\n  callback: Function;\n}\n\nexport interface IMarkdownEvent {\n}\nexport interface IMarkdownAreaChangeEvent extends IMarkdownEvent {\n  oldValue: Area;\n  newValue: Area;\n}\nexport interface IMarkdownNodeClickEvent extends IMarkdownEvent {\n  node: Node;\n  event: ClickEvent;\n}\nexport interface IMarkdownTextComponentSelectionOptionEvent extends IMarkdownEvent {\n  textEvent: ITextComponentEvent;\n}\nexport interface IMarkdownTextComponentSelectionChangeEvent extends IMarkdownEvent {\n  textEvent: ITextComponentSelectionChangeEvent;\n}\nexport interface IMarkdownTableComponentActionClickEvent extends IMarkdownEvent {\n  tableEvent: ITableComponentActionClickEvent;\n}\nexport interface IMarkdownTableComponentBarOptionEvent extends IMarkdownEvent {\n  tableEvent: ITableComponentEvent;\n}\nexport interface IMarkdownCodeComponentActionClickEvent extends IMarkdownEvent {\n  codeEvent: ICodeComponentActionClickEvent;\n}\nexport interface IMarkdownCodeComponentBarOptionEvent extends IMarkdownEvent {\n  codeEvent: ICodeComponentEvent;\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/render/component/builder.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { StyledEmbed, EStyledEmbedBuilder } from '../styled';\nimport { TableComponent } from './table';\nimport { CodeComponent } from './code';\nimport { ImageGalleryComponent } from './image-gallery';\n\n@Builder\nexport function buildComponent(builder: StyledEmbed) {\n  if (builder.embedOption.builderType === EStyledEmbedBuilder.Table) {\n    TableComponent({\n      styledEmbed: builder,\n    })\n  } else if (builder.embedOption.builderType === EStyledEmbedBuilder.Code) {\n    CodeComponent({\n      styledEmbed: builder,\n    })\n  } else if (builder.embedOption.builderType === EStyledEmbedBuilder.ImageGallery) {\n    ImageGalleryComponent({\n      styledEmbed: builder,\n    })\n  }\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/render/component/code.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { K_COMPONENT, newLog, IMDArea, MDArea, MDMargin } from '../../util';\nimport { Engine, BaseEngine } from '../../engine';\nimport { ITheme } from '../../theme';\nimport { StyledEmbed } from '../styled';\nimport { ENode, Code } from '../../service/ast/node';\nimport { EmbedComponent } from './embed';\nimport { ContentBoxComponent, ContentBoxBar, type IContentBoxAction, IContentBoxBar } from './content-box';\n\nconst log = newLog('CodeComponent');\n\n@ComponentV2\nexport struct CodeComponent {\n  private _gid: number = CodeComponent.getGID();\n  private static gid: number = 0;\n  private static getGID() {\n    return CodeComponent.gid++;\n  }\n  get ID() {\n    return this._gid;\n  }\n\n  @Require @Param @Once styledEmbed: StyledEmbed;\n\n  @Consumer(K_COMPONENT.THEME) theme: ITheme = {};\n  @Consumer(K_COMPONENT.SHARED_ENGINE) sharedEngine: Engine = new BaseEngine();\n\n  private bridge: CodeComponentBridge = new CodeComponentBridge({\n    styledEmbed: () => this.styledEmbed,\n    codeContent: () => this.node?.content,\n  });\n\n  private barOption?: IContentBoxBar;\n  private currentArea?: IMDArea;\n\n  private get node() {\n    const node = this.styledEmbed.node;\n    if (!node || !node.is(ENode.Code)) {\n      log.e(`current embed node is not table: ${node?.type}`);\n      return undefined;\n    }\n    return node as Code;\n  }\n\n  aboutToAppear(): void {\n    this.styledEmbed.embedController.updateEmbed = embed => {\n      if (embed?.option.styled.node?.hash !== this.styledEmbed?.option.styled.node?.hash) {\n        this.styledEmbed = embed;\n      }\n    };\n    this.styledEmbed.embedController.currentArea = () => {\n      return this.currentArea;\n    };\n    this.barOption = this.sharedEngine.event!.invokeCodeBarOption({ bridge: this.bridge });\n  }\n\n  build() {\n    ContentBoxComponent({\n      content: () => { this.CodeContent() },\n      bar: {\n        title: this.node?.language || '',\n        actions: this.barOption?.actions ?? [\n          ContentBoxBar.copyAction(undefined, this.sharedEngine),\n          // ContentBoxBar.openAction(undefined, this.sharedEngine),\n        ],\n      },\n      onActionClick: (action, event) => {\n        this.sharedEngine.event!.invokeCodeActionClick({ bridge: this.bridge, action, event });\n      },\n    })\n      .position(this.styledEmbed?.position)\n      .onAreaChange((oldValue, newValue) => {\n        this.currentArea = MDArea.area(newValue);\n        if (!MDArea.mdAreaEqual(MDArea.area(oldValue), MDArea.area(newValue))) {\n          this.styledEmbed?.componentAreaChange(oldValue, newValue);\n        }\n      })\n      .visibility(this.styledEmbed?.position !== undefined ? Visibility.Visible : Visibility.Hidden)\n      .width(this.styledEmbed?.initMetrics.width)\n  }\n  @Builder\n  CodeContent() {\n    Row() {\n      EmbedComponent({\n        node: this.node?.styledContent,\n        area: {},\n      })\n        .constraintSize({ minWidth: '100%' })\n    }\n    .padding(this.theme.contentBox?.barMargin ? MDMargin.lengthMargin(this.theme.contentBox?.barMargin) : undefined)\n  }\n}\n\ninterface ICodeComponentBridge {\n  styledEmbed: () => StyledEmbed,\n  codeContent: () => string | undefined;\n}\nexport class CodeComponentBridge {\n  private option: ICodeComponentBridge;\n  constructor(option: ICodeComponentBridge) {\n    this.option = option;\n  }\n  get styledEmbed() {\n    return this.option.styledEmbed();\n  }\n  get codeContent() {\n    return this.option.codeContent();\n  }\n}\nexport interface ICodeComponentEvent {\n  bridge: CodeComponentBridge;\n}\nexport interface ICodeComponentActionClickEvent extends ICodeComponentEvent {\n  action: IContentBoxAction,\n  event: ClickEvent,\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/render/component/content-box.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { K_COMPONENT, MDLength, MDMargin } from '../../util';\nimport { Engine } from '../../engine';\nimport { ITheme } from '../../theme';\nimport { image } from '@kit.ImageKit';\n\n@ComponentV2\nexport struct ContentBoxComponent {\n  @Consumer(K_COMPONENT.THEME) theme: ITheme = {};\n  @BuilderParam content: () => void;\n  @Require @Param bar: IContentBoxBar;\n  @Event onActionClick?: (action: IContentBoxAction, event: ClickEvent) => void = undefined;\n\n  private scroller: Scroller = new Scroller();\n\n  aboutToAppear(): void {\n  }\n\n  build() {\n    Column() {\n      //  bar\n      Row() {\n        Text(this.bar.title)\n          .fontColor(this.theme.contentBox?.barFont?.fontColor)\n          .fontSize(this.theme.contentBox?.barFont?.fontSize?.value)\n          .fontWeight(this.theme.contentBox?.barFont?.fontWeight)\n          .margin(this.theme.contentBox?.barMargin ? MDMargin.lengthMargin(this.theme.contentBox?.barMargin) : undefined)\n        Row() {\n          ForEach(this.bar.actions ?? [], (action: IContentBoxAction) => {\n            Image(action.icon)\n              .width(MDLength.metrics2length(this.theme.contentBox?.barActionIconWidth ?? MDLength.vp(0)))\n              .height(MDLength.metrics2length(this.theme.contentBox?.barActionIconHeight ?? MDLength.vp(0)))\n              .margin({ left: 10 })\n              .onClick(event => this.onActionClick?.(action, event))\n          })\n        }\n        .margin(this.theme.contentBox?.barMargin ? MDMargin.lengthMargin(this.theme.contentBox?.barMargin) : undefined)\n        .justifyContent(FlexAlign.SpaceBetween)\n      }\n      .width('100%')\n      .justifyContent(FlexAlign.SpaceBetween)\n      .backgroundColor(this.theme.contentBox?.barBackgroundColor)\n      .border({\n        radius: {\n          topLeft: this.theme.contentBox?.border?.radius?.value ? this.theme.contentBox?.border?.radius?.value - 1 : undefined,\n          topRight: this.theme.contentBox?.border?.radius?.value ? this.theme.contentBox?.border?.radius?.value - 1 : undefined,\n        },\n      })\n      .clip(true)\n\n      //  content\n      Scroll(this.scroller) {\n        this.content()\n      }\n      .scrollable(ScrollDirection.Horizontal)\n    }\n    .border({\n      width: MDLength.metrics2length(this.theme.contentBox?.border?.width ?? MDLength.vp(0)),\n      color: this.theme.contentBox?.border?.color,\n      radius: MDLength.metrics2length(this.theme.contentBox?.border?.radius ?? MDLength.vp(0)),\n      style: BorderStyle.Solid,\n    })\n    .clip(true)\n  }\n}\nexport interface IContentBoxBar {\n  title?: string;\n  actions?: IContentBoxAction[];\n}\nexport interface IContentBoxAction {\n  icon?: image.PixelMap;\n  tag?: string | EContentBoxAction;\n}\nexport enum EContentBoxAction {\n  Open = 'open',\n  Copy = 'copy',\n}\nexport abstract class ContentBoxBar {\n  static openAction(option?: IContentBoxAction, engine?: Engine): IContentBoxAction {\n    return {\n      icon: option?.icon ?? engine?.image?.load('icon_open.png')?.createPixelMapSync(),\n      tag: option?.tag ?? EContentBoxAction.Open,\n    };\n  }\n  static copyAction(option?: IContentBoxAction, engine?: Engine): IContentBoxAction {\n    return {\n      icon: option?.icon ?? engine?.image?.load('icon_copy.png')?.createPixelMapSync(),\n      tag: option?.tag ?? EContentBoxAction.Copy,\n    };\n  }\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/render/component/embed.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { Node } from '../../service/ast/node';\nimport { newLog, K_COMPONENT, IMDArea, MDArea } from '../../util';\nimport {\n  Styled, StyledObject, StyledEmbed, EStyledObject, type StyledValue,\n  EStyledObjectEvent, IStyledObjectAppendEvent, type IStyledObjectReplaceStyleEvent,\n  StyledTextValue, EStyledEmbedBuilder,\n} from '../styled';\nimport type { ITheme } from '../../theme';\nimport { Engine, BaseEngine } from '../../engine';\nimport { buildComponent } from './builder';\nimport { TextComponent, TextComponentController } from './text';\nimport {\n  ETypingMode, ETypingEvent, Typing,\n  type ITypingPauseEvent, type ITypingResumeEvent, type ITypingFinishEvent\n} from '../typing';\n\nconst log = newLog('EmbedComponent');\n\n@ComponentV2\nexport struct EmbedComponent {\n  static _gid: number = 0;\n  static gid() {\n    return EmbedComponent._gid++;\n  }\n  private gid: number = EmbedComponent.gid();\n  get ID() {\n    return this.gid;\n  }\n\n  @Param node?: Node = undefined;\n  @Require @Param @Once area: IMDArea = {};\n  @Param @Once styles?: StyledValue[] = undefined;\n  @Param @Once controller?: EmbedComponentController = undefined;\n\n  private textComponentController = new TextComponentController({});\n  @Local content: StyledObject = StyledObject.empty();\n  @Local layers: StyledEmbed[] = [];\n\n  @Event onEmbedComponentBeforeAboutToAppear: Callback<IEmbedComponentEvent>;\n  @Event onEmbedComponentAfterAboutToAppear: Callback<IEmbedComponentEvent>;\n  @Event onEmbedComponentBeforeAboutToDisappear: Callback<IEmbedComponentEvent>;\n  @Event onEmbedComponentAfterAboutToDisappear: Callback<IEmbedComponentEvent>;\n\n  @Consumer(K_COMPONENT.THEME) theme: ITheme = {};\n  @Consumer(K_COMPONENT.SHARED_ENGINE) sharedEngine: Engine = new BaseEngine();\n\n  private bindController() {\n    if (this.controller) {\n      this.controller.typing.ctx = () => this.sharedEngine.ctx;\n      this.controller.typing.update = (content, mode) => {\n        if (!(content instanceof Node)) {\n          return;\n        }\n        this.controller!.typing.mode = () => mode;\n        if (mode === ETypingMode.Update) {\n          this.attach4update(mode, content);\n        } else {\n          this.attach4typing(mode, content);\n        }\n      };\n    }\n  }\n\n  @Monitor('node') onNodeChange(monitor: IMonitor) {\n    const node = monitor.value<Node>();\n    if (node) {\n      if (node.now?.hash !== node.before?.hash) {\n        this.attach4normal(node.now);\n      }\n    } else {\n      this.layers = [];\n      this.content = StyledObject.empty();\n    }\n  }\n  private attach4normal(node?: Node) {\n    if (!node) {\n      return;\n    }\n    this.layers = [];\n    const content = StyledObject.root(this.area, this.styles)\n      .on<IStyledObjectAppendEvent>(EStyledObjectEvent.DidAppend, event => {\n        if (event.target.type === EStyledObject.Embed) {\n          const embed = event.target as StyledEmbed;\n          this.layers.push(embed);\n        }\n      })\n      .on<IStyledObjectReplaceStyleEvent>(EStyledObjectEvent.DidReplaceStyle, () => {\n        this.textComponentController.refresh();\n      });\n\n    Styled.create({\n      node,\n    })?.build({\n      theme: this.theme,\n      engine: this.sharedEngine,\n      didCreateStyled: (styled) => {\n        content.attach(styled);\n      },\n    });\n    this.content = content;\n  }\n  private attach4update(mode: ETypingMode, node?: Node) {\n    if (!node) {\n      this.layers = [];\n      this.content = StyledObject.empty();\n      return;\n    }\n    const currentLayers: Record<string, StyledEmbed> = {};\n    const content = StyledObject.root(this.area, this.styles)\n      .on<IStyledObjectAppendEvent>(EStyledObjectEvent.DidAppend, event => {\n        if (event.target.type === EStyledObject.Embed) {\n          const embed = event.target as StyledEmbed;\n          let existedIndex: number | undefined = undefined;\n          let existed: StyledEmbed | undefined = undefined;\n          this.layers.forEach((ele, index) => {\n            if (ele.likelyKey === embed.likelyKey) {\n              existedIndex = index;\n              existed = ele;\n            }\n          });\n          if (existed !== undefined && existedIndex !== undefined) {\n            embed.reuse(existed);\n            (existed as StyledEmbed).embedController.updateEmbed(embed);\n          } else {\n            this.layers.push(embed);\n          }\n          currentLayers[embed.likelyKey] = embed;\n        }\n      })\n      .on<IStyledObjectReplaceStyleEvent>(EStyledObjectEvent.DidReplaceStyle, () => {\n        this.textComponentController.refresh();\n      });\n    const likelyUtil = new EmbedComponentLikelyUtil();\n    Styled.create({\n      node,\n    })?.build({\n      theme: this.theme,\n      engine: this.sharedEngine,\n      didCreateStyled: (styled) => {\n        if (styled.type === EStyledObject.Embed) {\n          const embed = styled as StyledEmbed;\n          embed.likelyKey = `${embed.embedOption.builderType}_${likelyUtil.index(embed.embedOption.builderType)}`;\n        }\n        content.attach(styled);\n      },\n    });\n    this.content = content;\n    do {\n      //  clear unused layers\n      let index = 0;\n      while (index < this.layers.length) {\n        const embed = this.layers[index];\n        const current = currentLayers[embed.likelyKey];\n        if (current) {\n          this.layers.splice(index, 1, current);\n        } else {\n          this.layers.splice(index, 1);\n        }\n        index++;\n      }\n    } while (0);\n  }\n  private attach4typing(mode: ETypingMode, node?: Node) {\n    if (!this.controller) {\n      return;\n    }\n    const targetContent = StyledObject.root(this.area, this.styles)\n      .on<IStyledObjectReplaceStyleEvent>(EStyledObjectEvent.DidReplaceStyle, (event) => {\n        if (!event.spanStyle) {\n          //  empty style event only posted from image-span image source changed\n          this.textComponentController.refresh();\n        }\n      });\n    Styled.create({\n      node,\n    })?.build({\n      theme: this.theme,\n      engine: this.sharedEngine,\n      didCreateStyled: (styled) => {\n        targetContent.attach(styled);\n      },\n    });\n\n    let offset: number = 0;\n    if (mode === ETypingMode.Begin) {\n      this.layers = [];\n    } else {\n      offset = Math.min(this.content.length, targetContent.length);\n    }\n    const step = this.controller.typing.step;\n    const speed = this.controller.typing.speed;\n    const currentLayers: Record<string, StyledEmbed> = {};\n\n    const hasMore = (): boolean => {\n      return !!(this.controller?.typing.more) && !(offset >= targetContent.length);\n    };\n    this.controller!.typing.typingTimer.onDidStop = () => {\n      if (hasMore()) {\n        this.content.attach(StyledObject.more(\n          this.controller?.typing.more || '',\n          [new StyledTextValue(this.theme.document?.more)],\n        ));\n        this.textComponentController.refresh();\n      }\n    }\n    this.controller!.typing.typingTimer.onWillResume = () => {};\n    this.controller!.typing.typingTimer.onDidStop = () => {};\n    this.controller!.typing.completed = () => offset >= targetContent.length;\n\n    log.i(`${this.ID} attach for typing, mode: ${mode} offset: ${offset} targetLength: ${targetContent.length} step: ${step} speed: ${speed}`);\n\n    const currentContent = StyledObject.root(this.area, this.styles)\n      .on<IStyledObjectAppendEvent>(EStyledObjectEvent.DidAppend, event => {\n        if (event.target.type === EStyledObject.Embed) {\n          const embed = event.target as StyledEmbed;\n          let existedIndex: number | undefined = undefined;\n          let existed: StyledEmbed | undefined = undefined;\n          this.layers.forEach((ele, index) => {\n            if (ele.likelyKey === embed.likelyKey) {\n              existedIndex = index;\n              existed = ele;\n            }\n          });\n          if (existed !== undefined && existedIndex !== undefined) {\n            embed.reuse(existed);\n            (existed as StyledEmbed).embedController.updateEmbed(embed);\n          } else {\n            this.layers.push(embed);\n          }\n          currentLayers[embed.likelyKey] = embed;\n        }\n      })\n      .on<IStyledObjectReplaceStyleEvent>(EStyledObjectEvent.DidReplaceStyle, () => {\n        this.textComponentController.refresh();\n      });\n    const likelyUtil = new EmbedComponentLikelyUtil();\n\n    this.controller?.typing.typingTimer.start(() => {\n\n      offset = Math.min(offset + step, targetContent.length);\n\n      log.i(`${this.ID} typing onStep, offset: ${offset}`);\n\n      if (offset > 0) {\n        targetContent.subStyledObjects(currentContent.length, offset - currentContent.length).forEach(ele => {\n          if (ele.object instanceof StyledObject) {\n            if (ele.object.type === EStyledObject.Embed) {\n              const embed = ele.object as StyledEmbed;\n              embed.likelyKey = `${embed.embedOption.builderType}_${likelyUtil.index(embed.embedOption.builderType)}`;\n            }\n          }\n          currentContent.attach(ele.object);\n        });\n        this.content = currentContent;\n        this.textComponentController.refresh();\n      }\n      do {\n        //  clear unused layers\n        let index = 0;\n        while (index < this.layers.length) {\n          const embed = this.layers[index];\n          const current = currentLayers[embed.likelyKey];\n          if (current) {\n            this.layers.splice(index, 1, current);\n          } else {\n            this.layers.splice(index, 1);\n          }\n          index++;\n        }\n      } while (0);\n\n      if (offset >= targetContent.length) {\n        log.i(`${this.ID} typing onFinish, offset: ${offset}`);\n        this.controller?.typing.typingTimer.reset();\n        //  notify finish\n        this.controller?.typing.emit<ITypingFinishEvent>(ETypingEvent.Finish, {});\n      }\n    }, speed);\n  }\n  private onRootTypingPause = (_e: ITypingPauseEvent) => {\n    this.controller?.typing.pause();\n  }\n  private onRootTypingResume = (_e: ITypingResumeEvent) => {\n    this.controller?.typing.resume();\n  }\n  aboutToAppear(): void {\n    log.i(`aboutToAppear node: ${JSON.stringify(this.node?.summary)}`);\n    this.onEmbedComponentBeforeAboutToAppear({ controller: this.controller });\n    this.sharedEngine.ctx!.typing().rootController?.deref()?.on<ITypingPauseEvent>(ETypingEvent.Pause, this.onRootTypingPause);\n    this.sharedEngine.ctx!.typing().rootController?.deref()?.on<ITypingResumeEvent>(ETypingEvent.Resume, this.onRootTypingResume);\n    this.bindController();\n    this.attach4normal(this.node);\n    this.onEmbedComponentAfterAboutToAppear({ controller: this.controller });\n  }\n  aboutToDisappear(): void {\n    log.i(`aboutToDisappear node: ${JSON.stringify(this.node?.summary)}`);\n    this.onEmbedComponentBeforeAboutToDisappear({ controller: this.controller });\n    this.sharedEngine.ctx!.typing().rootController?.deref()?.off(ETypingEvent.Pause, this.onRootTypingPause);\n    this.sharedEngine.ctx!.typing().rootController?.deref()?.off(ETypingEvent.Resume, this.onRootTypingResume);\n    this.onEmbedComponentAfterAboutToDisappear({ controller: this.controller });\n  }\n\n  build() {\n    Stack({ alignContent: Alignment.TopStart }) {\n      //  text content\n      TextComponent({\n        content: this.content, componentController: this.textComponentController,\n      })\n      //  overlay span\n      ForEach(this.layers, (layer: StyledEmbed) => {\n        buildComponent(layer);\n      }, (layer: StyledEmbed) => layer.likelyKey)\n    }\n  }\n}\n\nexport class EmbedComponentController {\n  readonly typing: Typing = new Typing();\n}\nexport interface IEmbedComponentEvent {\n  controller?: EmbedComponentController;\n}\n\nclass EmbedComponentLikelyUtil {\n  private indexStore: Map<EStyledEmbedBuilder, number> = new Map();\n  index(builderType: EStyledEmbedBuilder): number {\n    let index = this.indexStore.get(builderType);\n    if (index === undefined) {\n      index = 0;\n      this.indexStore.set(builderType, index);\n    } else {\n      index++;\n      this.indexStore.set(builderType, index);\n    }\n    return index;\n  }\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/render/component/fragment.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { newLog, IMDArea, K_COMPONENT, MDArea } from '../../util';\nimport { Engine, BaseEngine } from '../../engine';\nimport { ITheme } from '../../theme';\nimport { EmbedComponent, EmbedComponentController } from './embed';\nimport { Typing, ITypingUpdateData, ITypingFinishEvent, ETypingMode, ETypingEvent } from '../typing';\nimport { Node } from '../../service/ast';\n\nconst log = newLog('FragmentComponent');\n\n@ComponentV2\nexport struct FragmentComponent {\n  private static gid: number = 0;\n  private static getGid() {\n    return FragmentComponent.gid++;\n  }\n  readonly ID: number = FragmentComponent.getGid();\n\n  @Param node?: Node = undefined;\n  @Param @Once controller: FragmentComponentController = new FragmentComponentController({});\n  @Require @Param area: IMDArea = {};\n\n  @Consumer(K_COMPONENT.THEME) theme: ITheme = {};\n  @Consumer(K_COMPONENT.SHARED_ENGINE) sharedEngine: Engine = new BaseEngine();\n\n  @Local fragments: Fragment[] = [];\n\n  @Event onFragmentComponentBeforeAboutToAppear: Callback<IFragmentComponentEvent>;\n  @Event onFragmentComponentAfterAboutToAppear: Callback<IFragmentComponentEvent>;\n  @Event onFragmentComponentBeforeAboutToDisappear: Callback<IFragmentComponentEvent>;\n  @Event onFragmentComponentAfterAboutToDisappear: Callback<IFragmentComponentEvent>;\n  @Event onFragmentComponentTypingFinish: Callback<IFragmentComponentEvent>;\n\n  private dirtyTypingUpdateData?: IFragmentUpdateData;\n\n  @Monitor('node') onNodeChange(monitor: IMonitor) {\n    const node = monitor.value<Node>()?.now;\n    this.attach4normal(node);\n  }\n  private dequeueFragment(index: number, node?: Node) {\n    let fragment = this.fragments.slice(index, index + 1).pop();\n    if (fragment) {\n      fragment.option.likelyKey = Fragment.likelyKey(index, node);\n      fragment.option.node = node;\n    } else {\n      fragment = new Fragment({ likelyKey: Fragment.likelyKey(index, node), node });\n      fragment.embedController.typing.on<ITypingFinishEvent>(ETypingEvent.Finish, e => {\n        this.onEmbedControllerTypingFinish(e);\n      });\n      this.fragments.push(fragment);\n    }\n    return fragment;\n  }\n  private get fragment() {\n    return this.fragments.slice().pop();\n  }\n\n  aboutToAppear(): void {\n    this.onFragmentComponentBeforeAboutToAppear?.({});\n    this.bindController();\n    if (this.node) {\n      this.attach4normal(this.node);\n    }\n    this.onFragmentComponentAfterAboutToAppear?.({});\n  }\n  aboutToDisappear(): void {\n    this.onFragmentComponentBeforeAboutToDisappear?.({});\n    this.onFragmentComponentAfterAboutToDisappear?.({});\n  }\n  private bindController() {\n    this.controller.typing.processing = () => {\n      if (this.dirtyTypingUpdateData) {\n        return true;\n      }\n      return !!this.fragment?.embedController.typing.processing();\n    }\n    this.controller.typing.completed = () => {\n      if (this.dirtyTypingUpdateData) {\n        return false;\n      }\n      const fragment = this.fragment;\n      return fragment ? !!fragment.embedController.typing.completed() : true;\n    }\n    this.controller.typing.pause = () => {\n      return this.fragment?.embedController.typing.pause();\n    }\n    this.controller.typing.resume = () => {\n      return this.fragment?.embedController.typing.resume();\n    }\n    this.controller.typing.stop = () => {\n      return this.fragment?.embedController.typing.stop();\n    }\n    this.controller.typing.update = (node, mode, hasMore) => {\n      if (node instanceof Node) {\n        log.i(`${this.ID} update typing mode: ${mode}, hasMore: ${hasMore}, node: ${node.hash}`);\n        this.dirtyTypingUpdateData = { content: node, mode, hasMore, nodes: node.children };\n        if (mode === ETypingMode.Begin) {\n          this.fragments = [];\n        }\n        this.attach4typing();\n      } else {\n        log.w(`${this.ID} can not update content, node(${typeof node}) is not instance of Node`);\n      }\n    }\n  }\n  private attach4normal(node?: Node) {\n    if (node) {\n      const fragments: Fragment[] = [];\n      if (!!this.sharedEngine.ctx?.fragmentEnable) {\n        node.children.forEach((ele, index) => {\n          fragments.push(this.dequeueFragment(index, ele));\n        });\n      } else {\n        fragments.push(this.dequeueFragment(0, node));\n      }\n      this.fragments = fragments;\n    } else {\n      this.fragments = [];\n    }\n  }\n  private attach4typing() {\n    if (!!this.fragment?.embedController.typing.processing()) {\n      log.i(`${this.ID} fragment ${this.fragment?.ID} typing processing, will retry after finish`);\n      return;\n    }\n    if (!this.dirtyTypingUpdateData) {\n      log.w(`${this.ID} no dirty typing update data`);\n      return;\n    }\n    if (!!this.sharedEngine.ctx?.fragmentEnable) {\n      const targets = this.dirtyTypingUpdateData.content.children;\n      if (targets.length > 0 && this.fragments.length === 0) {\n        this.dequeueFragment(0);\n        log.i(`${this.ID} first fragment, will dequeue: ${this.fragments.length}`);\n      }\n      if (targets.length < this.fragments.length) {\n        log.w(`${this.ID} targets length less than fragments length, unexpected unintended refresh: targets(${targets.length}), fragments(${this.fragments.length})`);\n      }\n      const count = Math.min(targets.length, this.fragments.length);\n      log.i(`${this.ID} update fragments: ${this.fragments.length}, targets: ${targets.length}, min count: ${count}`);\n      const isLast = (index: number) => (index === count - 1);\n      for (let index = 0; index < count; index++) {\n        const fragment = this.fragments[index];\n        const target = targets[index];\n        if (fragment.updateData?.content.hash === target.hash) {\n          if (isLast(index)) {\n            log.i(`${this.ID} fragment ${fragment.ID} no change, skip update and will force emit fragment typing finish`);\n            this.onEmbedControllerTypingFinish({});\n          } else {\n            log.i(`${this.ID} fragment ${fragment.ID} no change, skip update`);\n          }\n          continue;\n        }\n        if (isLast(index)) {\n          fragment.update(target, this.dirtyTypingUpdateData.mode, this.dirtyTypingUpdateData.hasMore);\n        } else {\n          fragment.update(target, ETypingMode.Update, this.dirtyTypingUpdateData.hasMore);\n        }\n      }\n      this.fragments = this.fragments.slice(0, count);\n      log.i(`${this.ID} after update fragments: ${this.fragments.length} targets: ${targets.length}`)\n    } else {\n      const fragment = this.dequeueFragment(0);\n      fragment.update(this.dirtyTypingUpdateData.content, this.dirtyTypingUpdateData.mode, this.dirtyTypingUpdateData.hasMore);\n      if (this.fragments.length > 1) {\n        this.fragments = [fragment];\n      }\n    }\n  }\n  private onEmbedControllerTypingFinish = (_e: ITypingFinishEvent) => {\n    log.i(`${this.ID} receive embed typing finish event`);\n    if (this.dirtyTypingUpdateData) {\n      const targets = this.dirtyTypingUpdateData.content.children;\n      if (this.fragments.length === targets.length) {\n        let allDone = true;\n        this.fragments.forEach((fragment, index) => {\n          const target = targets[index];\n          if (fragment.updateData?.content.hash !== target.hash) {\n            allDone = false;\n          }\n        });\n        if (allDone) {\n          log.i(`${this.ID} all fragments typing finish. emit onFragmentComponentTypingFinish`);\n          this.dirtyTypingUpdateData = undefined;\n          this.onFragmentComponentTypingFinish?.({});\n          return;\n        } else {\n          log.i(`${this.ID} some fragments changed, need update`);\n          this.attach4typing();\n        }\n      } else {\n        log.i(`${this.ID} typing next fragment. fragments: ${this.fragments.length}, targets: ${targets.length}`);\n        this.dequeueFragment(this.fragments.length);\n        this.attach4typing();\n      }\n    } else {\n      log.w(`${this.ID} no dirty typing update data, ignore finish event`);\n    }\n  }\n\n  build() {\n    Column() {\n      ForEach(this.fragments, (fragment: Fragment) => {\n        EmbedComponent({\n          node: fragment.node, controller: fragment.embedController, area: this.area,\n          onEmbedComponentAfterAboutToAppear: () => {\n            log.i(`${this.ID} fragment ${fragment.ID} typing ready`);\n            fragment.typingReady = true;\n          },\n          onEmbedComponentBeforeAboutToDisappear: () => {\n            fragment.typingReady = false;\n          },\n        })\n          .width('100%')\n      }, (fragment: Fragment) => `${fragment.likelyKey}_${fragment.ID}`)\n    }\n  }\n}\n\nconst log2 = newLog('Fragment');\n\ninterface IFragment {\n  likelyKey: string;\n  node?: Node;\n}\nclass Fragment {\n  private static gid: number = 0;\n  private static getGid() {\n    return Fragment.gid++;\n  }\n  readonly ID: number = Fragment.getGid();\n  readonly embedController: EmbedComponentController = new EmbedComponentController();\n  readonly option: IFragment;\n  updateData?: ITypingUpdateData<Node>;\n\n  private _typingReady: boolean = false;\n\n  constructor(option: IFragment) {\n    this.option = option;\n  }\n  get typingReady() {\n    return this._typingReady;\n  }\n  set typingReady(value: boolean) {\n    this._typingReady = value;\n    if (value && this.updateData) {\n      log2.i(`${this.ID} typing ready, retry update node: ${this.updateData.content.hash}, mode: ${this.updateData.mode}, hasMore: ${this}`);\n      this.embedController.typing.update(this.updateData.content, this.updateData.mode, this.updateData.hasMore);\n    }\n  }\n  update(node: Node, mode: ETypingMode, hasMore?: boolean) {\n    log2.i(`${this.ID} will update node: ${node.hash}, mode: ${mode}, hasMore: ${hasMore}`)\n    this.updateData = { content: node, mode, hasMore };\n    if (this.typingReady) {\n      this.embedController.typing.update(node, mode, hasMore);\n    } else {\n      log2.i(`${this.ID} typing not ready, will update after ready`);\n    }\n  }\n  get node() {\n    return this.option.node;\n  }\n  get likelyKey() {\n    return this.option.likelyKey;\n  }\n  static likelyKey(index: number, node?: Node) {\n    return `fragment-${index}-${node?.hash}`;\n  }\n}\n\ninterface IFragmentUpdateData extends ITypingUpdateData<Node> {\n  nodes: Node[];\n}\n\ninterface IFragmentComponentController {}\nexport class FragmentComponentController {\n  readonly option: IFragmentComponentController;\n  readonly typing: Typing = new Typing();\n  constructor(option: IFragmentComponentController) {\n    this.option = option;\n  }\n}\nexport interface IFragmentComponentEvent {}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/render/component/image-gallery.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { K_COMPONENT } from '../../util';\nimport { Engine, BaseEngine } from '../../engine';\nimport { ITheme } from '../../theme';\nimport { StyledEmbed } from '../styled';\n\n@ComponentV2\nexport struct ImageGalleryComponent {\n  @Require @Param styledEmbed: StyledEmbed;\n\n  @Consumer(K_COMPONENT.THEME) theme: ITheme = {};\n  @Consumer(K_COMPONENT.SHARED_ENGINE) sharedEngine: Engine = new BaseEngine();\n\n  private scroller: Scroller = new Scroller();\n\n  build() {\n    Scroll(this.scroller) {\n    }\n\n    .position(this.styledEmbed?.position)\n\n    .scrollable(ScrollDirection.Horizontal)\n    .border({ width: '2px', color: 0x28333333, style: BorderStyle.Solid, radius: '24px' })\n    .clipContent(ContentClipMode.CONTENT_ONLY)\n    .onAreaChange((oldValue, newValue) => {\n      this.styledEmbed?.componentAreaChange(oldValue, newValue);\n    })\n  }\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/render/component/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport * from './table';\nexport * from './embed';;\nexport * from './builder';\nexport * from './text';\nexport * from './code';\nexport * from './image-gallery';\nexport * from './content-box';\nexport * from './fragment';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/render/component/table.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { K_COMPONENT, MDLength, IMDArea, newLog, MDMargin, MDArea } from '../../util';\nimport { Engine, BaseEngine } from '../../engine';\nimport { ITheme } from '../../theme';\nimport {\n  StyledEmbed, StyledTextValue, type StyledValue,\n} from '../styled';\nimport { ENode, TableItem, ETableItem } from '../../service/ast/node';\nimport { EmbedComponent } from './embed';\nimport { ContentBoxComponent, ContentBoxBar, type IContentBoxAction, IContentBoxBar } from './content-box';\n\nconst log = newLog('TableComponent');\nconst log2 = newLog('FSTableComponent');\n\n@ComponentV2\nexport struct FSTableComponent {\n  private static gid: number = 0;\n  private static createGid() {\n    return FSTableComponent.gid++;\n  }\n  readonly ID: number = FSTableComponent.createGid();\n\n  @Require @Param @Once styledEmbed: StyledEmbed;\n  @Require @Param @Once engine: Engine = new BaseEngine();\n\n  @Provider(K_COMPONENT.THEME) theme: ITheme = this.engine.theme!.theme;\n  @Provider(K_COMPONENT.SHARED_ENGINE) sharedEngine: Engine = this.engine;\n\n  @Local table: DSTable = new DSTable();\n  @Local ready: boolean = false\n  @Local uiArea?: Area;\n\n  @Monitor('uiArea') onUIAreaChange(monitor: IMonitor) {\n    const value = monitor.value<Area>();\n    if (value?.before === undefined && value?.now !== undefined) {\n      this.reload();\n    }\n  }\n\n  private get node() {\n    const node = this.styledEmbed.node;\n    if (!node || !node.is(ENode.Table)) {\n      log2.e(`current embed node is not table: ${node?.type}`);\n      return undefined;\n    }\n    return node;\n  }\n\n  private reload() {\n    const tableNode = this.node;\n    if (tableNode) {\n      log2.d(`component ${this.ID} table ${this.table.ID} reload start: ${JSON.stringify(this.table.summary)}`);\n      const dequeueRow = (rowIndex: number, rowItem: TableItem) => {\n        let row = this.table.rows.slice(rowIndex, rowIndex + 1).pop();\n        if (!row) {\n          row = new DSTableRow(rowItem, this.table);\n          this.table.rows.push(row);\n        } else {\n          row.node = new WeakRef(rowItem);\n        }\n        return row;\n      };\n      const dequeueCell = (rowIndex: number, cellIndex: number, rowItem: TableItem, cellItem: TableItem) => {\n        const row = dequeueRow(rowIndex, rowItem);\n        let cell = row.cells.slice(cellIndex, cellIndex + 1).pop();\n        if (!cell) {\n          cell = new DSTableCell(row, cellItem, this.table);\n          row.cells.push(cell);\n        } else {\n          cell.node = new WeakRef(cellItem);\n        }\n        return cell;\n      };\n\n      const rows: TableItem[] = [];\n      tableNode.children.forEach(child => {\n        //  thead | tbody\n        child.children.forEach(item => {\n          //  tr\n          rows.push(item as TableItem);\n        });\n      });\n      rows.forEach((row, rowIndex) => {\n        dequeueRow(rowIndex, row as TableItem);\n        row.children.forEach((cell, cellIndex) => {\n          dequeueCell(rowIndex, cellIndex, row as TableItem, cell as TableItem);\n        });\n      });\n\n      log2.d(`component ${this.ID} table ${this.table.ID} reload end: ${JSON.stringify(this.table.summary)}`);\n    }\n  }\n  build() {\n    Row() {\n      this.FSTableContent()\n    }\n    .height(\"100%\")\n    .width(\"100%\")\n    .onAreaChange((_oldValue, newValue) => {\n      this.uiArea = newValue;\n      if (newValue.height < newValue.width) {\n        this.ready = true\n      }\n    })\n  }\n  @Builder\n  FSTableContent() {\n    List() {\n      ForEach(this.table.rows, (row: DSTableRow) => {\n        if (row.parent?.itemType === ETableItem.Head) {\n          //  Table TH\n          ListItem() {\n            this.FSTableRow({ row, styles: [new StyledTextValue(this.theme.table?.headerFont)] })\n          }\n          .backgroundColor(this.theme.table?.headerBackgroundColor)\n        } else {\n          //  Table TD\n          ListItem() {\n            this.FSTableRow({ row, styles: [new StyledTextValue(this.theme.table?.contentFont)] })\n          }\n        }\n      }, (row: DSTableRow) => row.likelyKey)\n    }\n  }\n  @Builder\n  FSTableRow(data: ITableRowData) {\n    Row() {\n      ForEach(data.row.cells, (cell: DSTableCell) => {\n        Row() {\n          Scroll() {\n            EmbedComponent({\n              node: cell.node?.deref(),\n              area: { width: this.theme.table?.cellMaxWidth },\n              styles: data.styles,\n            })\n              .constraintSize(cell.constraintSize(this.uiArea ? MDArea.area(this.uiArea) : undefined, this.theme))\n              .onAreaChange((oldValue, newValue) => {\n                if (MDArea.mdAreaEqual(MDArea.area(oldValue), MDArea.area(newValue))) {\n                  return;\n                }\n                cell.table?.deref()?.cellAreaChange(cell, oldValue, newValue);\n              })\n          }\n          .align(Alignment.TopStart)\n          .scrollable(ScrollDirection.None)\n          .constraintSize({ minWidth: cell.width, minHeight: cell.height })\n        }\n        .padding(this.theme.contentBox?.barMargin ? MDMargin.lengthMargin(this.theme.contentBox?.barMargin) : undefined)\n        .borderWidth(cell.borderWidth(this.theme))\n        .borderColor(this.theme.contentBox?.border?.color)\n      }, (cell: DSTableCell) => cell.likelyKey)\n    }\n  }\n}\n\n@ComponentV2\nexport struct TableComponent {\n  private static gid: number = 0;\n  private static createGid() {\n    return TableComponent.gid++;\n  }\n  readonly ID: number = TableComponent.createGid();\n\n  @Consumer(K_COMPONENT.THEME) theme: ITheme = {};\n  @Consumer(K_COMPONENT.SHARED_ENGINE) sharedEngine: Engine = new BaseEngine();\n\n  @Require @Param @Once styledEmbed: StyledEmbed;\n  @Local table: DSTable = new DSTable();\n\n  @Monitor('styledEmbed') onStyledEmbedChange(monitor: IMonitor) {\n    const embed = monitor.value<StyledEmbed>();\n    if (embed?.before || embed?.now) {\n      if (embed?.before?.option.styled.node?.hash !== embed?.now?.option.styled.node?.hash) {\n        this.reload();\n      }\n    }\n  }\n\n  private bridge: TableComponentBridge = new TableComponentBridge({\n    styledEmbed: () => this.styledEmbed,\n  });\n\n  private barOption?: IContentBoxBar;\n  private currentArea?: IMDArea;\n\n  private get node() {\n    const node = this.styledEmbed.node;\n    if (!node || !node.is(ENode.Table)) {\n      log.e(`component ${this.ID} current embed node is not table: ${node?.type}`);\n      return undefined;\n    }\n    return node;\n  }\n  private reload() {\n    const tableNode = this.node;\n    if (tableNode) {\n      log.i(`component ${this.ID} table ${this.table.ID} reload start: ${JSON.stringify(this.table.summary)}`);\n      const dequeueRow = (rowIndex: number, rowItem: TableItem) => {\n        let row = this.table.rows.slice(rowIndex, rowIndex + 1).pop();\n        if (!row) {\n          row = new DSTableRow(rowItem, this.table);\n          this.table.rows.push(row);\n        } else {\n          row.node = new WeakRef(rowItem);\n        }\n        return row;\n      };\n      const dequeueCell = (rowIndex: number, cellIndex: number, rowItem: TableItem, cellItem: TableItem) => {\n        const row = dequeueRow(rowIndex, rowItem);\n        let cell = row.cells.slice(cellIndex, cellIndex + 1).pop();\n        if (!cell) {\n          cell = new DSTableCell(row, cellItem, this.table);\n          row.cells.push(cell);\n        } else {\n          cell.node = new WeakRef(cellItem);\n        }\n        return cell;\n      };\n\n      const rows: TableItem[] = [];\n      tableNode.children.forEach(child => {\n        //  thead | tbody\n        child.children.forEach(item => {\n          //  tr\n          rows.push(item as TableItem);\n        });\n      });\n      rows.forEach((row, rowIndex) => {\n        dequeueRow(rowIndex, row as TableItem);\n        row.children.forEach((cell, cellIndex) => {\n          dequeueCell(rowIndex, cellIndex, row as TableItem, cell as TableItem);\n        });\n      });\n\n      log.i(`component ${this.ID} table ${this.table.ID} reload end: ${JSON.stringify(this.table.summary)}`);\n    }\n  }\n  aboutToAppear(): void {\n    this.styledEmbed.embedController.updateEmbed = embed => {\n      this.styledEmbed = embed;\n    };\n    this.styledEmbed.embedController.currentArea = () => {\n      return this.currentArea;\n    };\n    this.barOption = this.sharedEngine.event!.invokeTableBarOption({ bridge: this.bridge });\n    this.reload();\n  }\n\n  build() {\n    ContentBoxComponent({\n      content: () => { this.TableContent() },\n      bar: {\n        title: this.barOption?.title ?? '表格',\n        actions: this.barOption?.actions ?? [\n          // ContentBoxBar.copyAction(undefined, this.sharedEngine),\n          ContentBoxBar.openAction(undefined, this.sharedEngine),\n        ],\n      },\n      onActionClick: (action, event) => {\n        this.sharedEngine.event!.invokeTableActionClick({\n          bridge: this.bridge,\n          action, event,\n        });\n      },\n    })\n      .position(this.styledEmbed?.position)\n      .onAreaChange((oldValue, newValue) => {\n        this.currentArea = MDArea.area(newValue);\n        if (!MDArea.mdAreaEqual(MDArea.area(oldValue), MDArea.area(newValue))) {\n          this.styledEmbed?.componentAreaChange(oldValue, newValue);\n        }\n        this.table.onAreaChange(oldValue, newValue);\n        // log.i(`component ${this.ID} table ${this.table.ID} AreaChange (${newValue.width},${newValue.height}) ${JSON.stringify(this.table.summary)}`);\n      })\n      .visibility(this.table.ready ? Visibility.Visible : Visibility.Hidden)\n      .width(this.styledEmbed?.initMetrics.width)\n  }\n\n  @Builder\n  TableContent() {\n    List() {\n      ForEach(this.table.rows, (row: DSTableRow) => {\n        if (row.parent?.itemType === ETableItem.Head) {\n          //  Table TH\n          ListItem() {\n            this.TableRow({ row, styles: [new StyledTextValue(this.theme.table?.headerFont)] })\n          }\n          .backgroundColor(this.theme.table?.headerBackgroundColor)\n        } else {\n          //  Table TD\n          ListItem() {\n            this.TableRow({ row, styles: [new StyledTextValue(this.theme.table?.contentFont)] })\n          }\n        }\n      }, (row: DSTableRow) => row.likelyKey)\n    }\n  }\n  @Builder\n  TableRow(data: ITableRowData) {\n    Row() {\n      ForEach(data.row.cells, (cell: DSTableCell) => {\n        Row() {\n          Scroll() {\n            EmbedComponent({\n              node: cell.node?.deref(),\n              area: { width: this.theme.table?.cellMaxWidth },\n              styles: data.styles,\n            })\n              .constraintSize(cell.constraintSize(this.styledEmbed.blockArea, this.theme))\n              .onAreaChange((oldValue, newValue) => {\n                if (MDArea.mdAreaEqual(MDArea.area(oldValue), MDArea.area(newValue))) {\n                  return;\n                }\n                cell.table?.deref()?.cellAreaChange(cell, oldValue, newValue);\n                // log.i(`component ${this.ID} table ${this.table.ID} Cell ${cell.likelyKey} ${cell.ID} t ${cell.table?.deref()?.ID} AreaChange (${newValue.width},${newValue.height}) ${JSON.stringify(cell.summary)}`);\n              })\n          }\n          .align(Alignment.TopStart)\n          .scrollable(ScrollDirection.None)\n          .constraintSize({ minWidth: cell.width, minHeight: cell.height })\n        }\n        .padding(this.theme.contentBox?.barMargin ? MDMargin.lengthMargin(this.theme.contentBox?.barMargin) : undefined)\n        .borderWidth(cell.borderWidth(this.theme))\n        .borderColor(this.theme.contentBox?.border?.color)\n      }, (cell: DSTableCell) => cell.likelyKey)\n    }\n  }\n}\ninterface ITableRowData {\n  row: DSTableRow;\n  styles?: StyledValue[];\n}\n\n/**\n * DataSource for Table\n */\n\n@ObservedV2\nclass DSTable {\n  private static gid: number = 0;\n  private static createGID() {\n    return DSTable.gid++;\n  }\n  readonly ID: number = DSTable.createGID();\n\n  @Trace rows: DSTableRow[] = [];\n  @Trace ready: boolean = false;\n\n  cellAreaChange(cell: DSTableCell, _oldValue: Area, newValue: Area) {\n    //  re-layout row\n    do {\n      let maxHeight: Length = newValue.height;\n      cell.row.deref()?.cells.forEach(ele => {\n        if (ele.height !== undefined && ele.height > maxHeight) {\n          maxHeight = ele.height;\n        }\n      });\n      cell.row.deref()?.cells.forEach(ele => {\n        if (ele.height !== undefined && ele.height !== maxHeight) {\n          ele.height = maxHeight;\n        }\n      });\n      if (cell.height === undefined) {\n        cell.height = maxHeight;\n      }\n      log.i(`ds table ${this.ID} relayout row maxHeight ${maxHeight} cell ${cell.ID} ${cell.likelyKey}`);\n    } while (0);\n    //  re-layout column\n    do {\n      let maxWidth: Length = newValue.width;\n      const index = cell.index;\n      if (index !== undefined) {\n        this.rows.forEach(row => {\n          if (row.cells.length > index) {\n            const column = row.cells[index];\n            if (column.width !== undefined && column.width > maxWidth) {\n              maxWidth = column.width;\n            }\n          }\n        });\n        this.rows.forEach(row => {\n          if (row.cells.length > index) {\n            const column = row.cells[index];\n            if (column.width !== undefined && column.width !== maxWidth) {\n              column.width = maxWidth;\n            }\n          }\n        });\n        if (cell.width === undefined) {\n          cell.width = maxWidth;\n        }\n        log.i(`ds table ${this.ID} relayout column maxWidth ${maxWidth} cell ${cell.ID} ${cell.likelyKey}`);\n      }\n    } while (0);\n  }\n  onAreaChange(_oldValue: Area, _newValue: Area) {\n    let allCellReady: boolean = true;\n    this.rows.forEach(row => {\n      row.cells.forEach(cell => {\n        if (cell.width === undefined || cell.height === undefined) {\n          allCellReady = false;\n        }\n      });\n    });\n    if (this.ready !== allCellReady) {\n      if (this.ready === false) {\n        this.ready = allCellReady;\n      }\n    }\n  }\n  get summary(): IDSTableMeta {\n    return {\n      id: this.ID,\n      rows: this.rows.map(ele => ele.summary),\n      ready: this.ready,\n    };\n  }\n}\n\n@ObservedV2\nclass DSTableRow {\n  private static gid: number = 0;\n  private static createGID() {\n    return DSTableRow.gid++;\n  }\n  readonly ID: number = DSTableRow.createGID();\n\n  @Trace cells: DSTableCell[] = [];\n  table?: WeakRef<DSTable>;\n  node?: WeakRef<TableItem>;\n  constructor(node?: TableItem, table?: DSTable) {\n    if (node) {\n      this.node = new WeakRef(node);\n    }\n    if (table) {\n      this.table = new WeakRef(table);\n    }\n  }\n  get index(): number | undefined {\n    return this.table?.deref()?.rows.indexOf(this);\n  }\n  get parent(): TableItem | undefined {\n    const parent = this.node?.deref()?.parent?.deref();\n    if (parent?.is(ENode.TableItem)) {\n      return parent as TableItem;\n    }\n    return undefined;\n  }\n  get summary(): IDSTableRowMeta {\n    return {\n      id: this.ID,\n      index: this.index,\n      cells: this.cells.map(ele => ele.summary),\n    };\n  }\n  get likelyKey(): string | undefined {\n    return `row:${this.index}`;\n  }\n}\ntype DSTableCellRef = string;\n@ObservedV2\nclass DSTableCell {\n  private static gid: number = 0;\n  private static createGID() {\n    return DSTableCell.gid++;\n  }\n  readonly ID: number = DSTableCell.createGID();\n\n  @Trace node?: WeakRef<TableItem>;\n  table?: WeakRef<DSTable>;\n  row: WeakRef<DSTableRow>;\n\n  @Trace width?: Length;\n  @Trace height?: Length;\n\n  constructor(row: DSTableRow, node?: TableItem, table?: DSTable) {\n    this.row = new WeakRef(row);\n    if (node) {\n      this.node = new WeakRef(node);\n    }\n    if (table) {\n      this.table = new WeakRef(table);\n    }\n  }\n  isEmpty() {\n    return !this.node;\n  }\n  constraintSize(area?: IMDArea, theme?: ITheme): ConstraintSizeOptions {\n    const length = this.row.deref()?.cells.length ?? 0;\n    const marginWidth = MDLength.vp(\n      (theme?.contentBox?.barMargin?.left?.value ?? 0) +\n        (theme?.contentBox?.barMargin?.right?.value ?? 0)\n    )\n    const borderWidth = MDLength.vp(theme?.contentBox?.border?.width?.value ?? 0);\n    //  border_count = cell_left ( length - 1 ) + table_left_right ( 1 + 1 ) = length + 1\n    let width = MDLength.vp((area?.width?.value ?? 0) - marginWidth.value * length - borderWidth.value * (length + 1));\n    let minWidth: LengthMetrics = MDLength.vp(width.value / (length || 1));\n    let maxWidth: LengthMetrics = this.index === 0 ?\n      theme?.table?.cellMaxWidth4First ?? MDLength.vp(0) :\n      theme?.table?.cellMaxWidth ?? MDLength.vp(0);\n    maxWidth = MDLength.vp(maxWidth.value - marginWidth.value - borderWidth.value);\n    if (maxWidth.value < minWidth.value) {\n      maxWidth = minWidth;\n    }\n    if (length === 1) {\n      return {\n        minWidth: minWidth.value > 0 ? MDLength.metrics2length(minWidth) : undefined,\n      };\n    } else {\n      return {\n        maxWidth: maxWidth.value > 0 ? MDLength.metrics2length(maxWidth) : undefined,\n        minWidth: minWidth.value > 0 ? MDLength.metrics2length(minWidth) : undefined,\n      };\n    }\n  }\n  borderWidth(theme?: ITheme): EdgeWidths {\n    const width = MDLength.metrics2length(\n      theme?.contentBox?.border?.width ??\n      MDLength.vp(0)\n    );\n    return {\n      top: width,\n      left: this.index !== 0 ? width : undefined,\n    };\n  }\n  get index(): number | undefined {\n    return this.row.deref()?.cells.indexOf(this);\n  }\n  get summary(): IDSTableCellMeta {\n    return {\n      id: this.ID,\n      index: this.index,\n      width: this.width,\n      height: this.height,\n    };\n  }\n  get ref(): DSTableCellRef {\n    return `${this.row.deref()?.index ?? -1}:${this.index ?? -1}`;\n  }\n  get likelyKey(): string | undefined {\n    return `row:${this.row?.deref()?.index}_cell:${this.index}`;\n  }\n}\n\ninterface IDSTableMeta {\n  id: number;\n  rows: IDSTableRowMeta[];\n  ready: boolean;\n}\ninterface IDSTableRowMeta {\n  id: number;\n  index?: number;\n  cells: IDSTableCellMeta[];\n}\ninterface IDSTableCellMeta {\n  id: number;\n  index?: number;\n  width?: Length;\n  height?: Length;\n}\n\n/**\n * Event\n */\n\ninterface ITableComponentBridge {\n  styledEmbed: () => StyledEmbed,\n}\nexport class TableComponentBridge {\n  private option: ITableComponentBridge;\n  constructor(option: ITableComponentBridge) {\n    this.option = option;\n  }\n  get styledEmbed() {\n    return this.option.styledEmbed();\n  }\n}\nexport interface ITableComponentEvent {\n  bridge: TableComponentBridge;\n}\nexport interface ITableComponentActionClickEvent extends ITableComponentEvent {\n  action: IContentBoxAction,\n  event: ClickEvent,\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/render/component/text.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { newLog, K_COMPONENT, MDArea } from '../../util';\nimport { Engine, BaseEngine } from '../../engine';\nimport { StyledController, type StyledObject } from '../styled';\n\nconst log = newLog('TextComponent');\n\n@ComponentV2\nexport struct TextComponent {\n  private static gid: number = 0;\n  private static getGID(): number {\n    return TextComponent.gid++;\n  }\n  private ID: number = TextComponent.getGID();\n  private textID: string = `fluid-markdown-text-component-${this.ID}`;\n\n  private styledController: TextController = new StyledController();\n  @Local selectionStart: number = -1;\n  @Local selectionEnd: number = -1;\n\n  private selectionOption: ITextComponentSelectionOption = {};\n  private selectionGesture: Map<ETextSelectionGesture, GestureEvent> = new Map();\n\n  @Event onTextComponentBeforeAboutToAppear: Callback<ITextComponentEvent>;\n  @Event onTextComponentAfterAboutToAppear: Callback<ITextComponentEvent>;\n\n  @Param componentController: TextComponentController = new TextComponentController({});\n  @Require @Param content: StyledObject;\n  @Consumer(K_COMPONENT.SHARED_ENGINE) sharedEngine: Engine = new BaseEngine();\n  @Monitor('content') onContentChange(monitor: IMonitor) {\n    const value = monitor.value<StyledString>();\n    if (value) {\n      log.i(`${this.ID} update content: ${value.now.length}`);\n      this.styledController.setStyledString(value.now);\n    }\n  }\n\n  private onCtxContentControllerClearSelection = (): void => {\n    this.componentController.select(-1, -1);\n  }\n  private onCtxContentControllerShouldSelectGesture = (e: ITextComponentControllerShouldSelectGestureEvent)\n    : ITextComponentControllerShouldSelectGestureResult | undefined => {\n    if (this.selectionGesture.get(e.type)) {\n      try {\n        const info = this.getUIContext().getComponentUtils().getRectangleById(this.textID);\n        const area: Area = {\n          width: info.size.width,\n          height: info.size.height,\n          position: { x: info.localOffset.x, y: info.localOffset.y },\n          globalPosition: { x: info.windowOffset.x, y: info.windowOffset.y },\n        };\n        if (MDArea.isAreaContainFinger(area, e.event.fingerList.slice().pop())) {\n          return {\n            componentController: this.componentController,\n            ID: this.ID,\n          };\n        }\n      } catch (e) {\n        log.e(`getRectangleById error: ${e?.message}`);\n      }\n    }\n    return undefined;\n  }\n\n  aboutToAppear(): void {\n    this.componentController.select = (start, end) => {\n      this.selectionStart = start;\n      this.selectionEnd = end;\n    };\n    this.componentController.selectGesture = type => {\n      const event = this.selectionGesture.get(type);\n      if (event) {\n        const finger = event.fingerList.slice(0, 1).pop();\n        if (finger) {\n          const offset = this.styledController.getLayoutManager().getGlyphPositionAtCoordinate(finger.localX, finger.localY).position;\n          const range = this.content.nearbyParagraph(offset);\n          if (range && range.start !== undefined && range.end !== undefined) {\n            this.componentController.select(range.start, range.end);\n          } else {\n            log.w('selection with gesture. but range not found');\n          }\n        } else {\n          log.w('selection with gesture. but finger not found');\n        }\n      } else {\n        log.w('selection with gesture. but event not found');\n      }\n    };\n    this.componentController.refresh = () => {\n      log.i(`${this.ID} refresh content: ${this.content.length}`);\n      this.styledController.setStyledString(this.content);\n    };\n    this.sharedEngine.ctx!.textContentController()?.on<undefined>(ETextComponentControllerEvent.ClearSelection, this.onCtxContentControllerClearSelection);\n    this.sharedEngine.ctx!.textContentController()?.on(ETextComponentControllerEvent.ShouldSelectGesture, this.onCtxContentControllerShouldSelectGesture);\n    this.onTextComponentBeforeAboutToAppear({});\n    this.selectionOption = this.sharedEngine.event!.invokeTextSelectionOption({});\n    this.styledController.setStyledString(this.content);\n    this.onTextComponentAfterAboutToAppear({});\n  }\n  aboutToDisappear(): void {\n    this.sharedEngine.ctx!.textContentController()?.off<undefined>(ETextComponentControllerEvent.ClearSelection, this.onCtxContentControllerClearSelection);\n    this.sharedEngine.ctx!.textContentController()?.off(ETextComponentControllerEvent.ShouldSelectGesture, this.onCtxContentControllerShouldSelectGesture);\n  }\n  @Builder TextContent() {\n    Text(undefined, { controller: this.styledController })\n      .id(this.textID)\n      .wordBreak(WordBreak.BREAK_ALL)\n      .draggable(false)\n      .selection(this.selectionStart, this.selectionEnd)\n      .copyOption(this.selectionOption.enableSelection ? CopyOptions.InApp : CopyOptions.None)\n      .bindSelectionMenu(\n        TextSpanType.MIXED,\n        this.selectionOption.bindSelectionMenuBuilder,\n        TextResponseType.SELECT,\n        this.selectionOption.bindSelectionMenuOptions,\n      )\n      .editMenuOptions(this.selectionOption.editSelectionMenuOptions)\n      .onTextSelectionChange((start, end) => {\n        this.selectionStart = start;\n        this.selectionEnd = end;\n        this.sharedEngine.event!.invokeTextSelectionChange({\n          start, end,\n          content: (() => {\n            try {\n              return this.content.getString().substring(start, end);\n            } catch (e) {\n              return undefined;\n            }\n          })(),\n        });\n      })\n  }\n  build() {\n    if (this.selectionOption.ignoreInternal) {\n      Row() {\n        this.TextContent()\n      }\n      .parallelGesture(\n        GestureGroup(\n          GestureMode.Parallel,\n          TapGesture({ count: 1 }).onAction(_e => {\n            //  ignore internal tap gesture\n          }),\n          TapGesture({ count: 2 }).onAction(e => {\n            this.selectionGesture.set(ETextSelectionGesture.DoubleTap, e);\n          }),\n          LongPressGesture().onAction(e => {\n            this.selectionGesture.set(ETextSelectionGesture.LongPress, e)\n          }),\n        ),\n        GestureMask.IgnoreInternal,\n      )\n    } else {\n      this.TextContent()\n    }\n  }\n}\n\nexport enum ETextSelectionGesture {\n  DoubleTap = 'double_tap',\n  LongPress = 'long_press',\n}\ninterface ITextComponentController {}\nexport class TextComponentController {\n  private option: ITextComponentController;\n  constructor(option: ITextComponentController) {\n    this.option = option;\n  }\n  select: (start: number, end: number) => void = () => {};\n  selectGesture: (type: ETextSelectionGesture, event?: GestureEvent) => void = () => {};\n  refresh: () => void = () => {};\n}\nexport interface ITextComponentEvent {\n}\nexport interface ITextComponentSelectionChangeEvent extends ITextComponentEvent {\n  start: number,\n  end: number,\n  content?: string;\n}\nexport interface ITextComponentSelectionOption {\n  enableSelection?: boolean,\n  bindSelectionMenuBuilder?: CustomBuilder,\n  bindSelectionMenuOptions?: SelectionMenuOptions,\n  editSelectionMenuOptions?: EditMenuOptions,\n  ignoreInternal?: boolean,\n}\nexport class TextContentController {\n  private listener: Record<string, Function[]> = {};\n  on<T, V = void>(name: string, callback: Callback<T, V>) {\n    if (!this.listener[name]) {\n      this.listener[name] = [];\n    }\n    this.listener[name].push(callback);\n    return this;\n  }\n  emit<T, V = void>(name: string, event: T): V[] {\n    let results: V[] = [];\n    this.listener[name]?.forEach(ele => {\n      results.push((ele as Callback<T, V>)(event));\n    });\n    return results;\n  }\n  off<T, V = void>(name: string, callback?: Callback<T, V>) {\n    if (callback) {\n      this.listener[name] = this.listener[name].filter(ele => ele !== callback);\n    } else {\n      this.listener[name] = [];\n    }\n    return this;\n  }\n  clearSelection() {\n    this.emit(ETextComponentControllerEvent.ClearSelection, undefined);\n  }\n  selectGesture(type: ETextSelectionGesture, event: GestureEvent) {\n    const result = this.emit<ITextComponentControllerShouldSelectGestureEvent, ITextComponentControllerShouldSelectGestureResult | undefined>(\n      ETextComponentControllerEvent.ShouldSelectGesture,\n      { type, event },\n    );\n    const textComponent = (result.filter(ele => ele !== undefined) as ITextComponentControllerShouldSelectGestureResult[])\n      .slice().sort((a, b) => a.ID - b.ID)\n      .pop();\n    if (textComponent) {\n      textComponent.componentController.selectGesture(type, event);\n    }\n  }\n  isHit: (type: ETextSelectionGesture, event: GestureEvent) => boolean = () => false;\n}\nenum ETextComponentControllerEvent {\n  ClearSelection = 'clear_selection',\n  ShouldSelectGesture = 'should_select_gesture',\n}\ninterface ITextComponentControllerShouldSelectGestureEvent {\n  type: ETextSelectionGesture,\n  event: GestureEvent,\n}\ninterface ITextComponentControllerShouldSelectGestureResult {\n  componentController: TextComponentController,\n  ID: number;\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/render/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport * from './component';\nexport * from './styled';\nexport * from './service';\nexport * from './typing';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/render/service.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { Service, EService, Plugin } from '../engine';\nimport type { Styled, IStyledBuild } from './styled';\nimport { newLog } from '../util';\n\nconst log = newLog('RenderService');\n\nexport class RenderService extends Service {\n  readonly type: EService = EService.Render;\n  private plugins: RenderServicePlugin[] = [];\n  add<T extends Plugin = RenderServicePlugin>(plugin: T): void {\n    if (plugin instanceof RenderServicePlugin) {\n      this.plugins.push(plugin);\n    } else {\n      log.e(`add plugin error, not RenderServicePlugin`);\n    }\n  }\n  styledBuildingPlugin(styled: Styled, buildOption: IStyledBuild): RenderServicePlugin<IRenderPluginStyledBuilding> | undefined {\n    for (const ele of this.plugins) {\n      if (ele.type === ERenderPlugin.StyledBuilding) {\n        const plugin = ele as RenderServicePlugin<IRenderPluginStyledBuilding>;\n        if (plugin.handler.should(styled, buildOption)) {\n          return plugin;\n        }\n      }\n    }\n    return undefined;\n  }\n}\n\nexport enum ERenderPlugin {\n  Unknown = 'unknown',\n  StyledBuilding = 'styled_building',\n}\nexport interface IRenderPlugin {}\nexport interface IRenderPluginStyledBuilding extends IRenderPlugin {\n  should: (styled: Styled, buildOption: IStyledBuild) => boolean;\n  building: (styled: Styled, buildOption: IStyledBuild) => void;\n}\nexport abstract class RenderServicePlugin <\n  T extends IRenderPlugin = IRenderPlugin\n> extends Plugin {\n  abstract readonly type: ERenderPlugin;\n  abstract readonly handler: T;\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/render/styled/build-in.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { IStyled, IStyledOption, IStyledBuild, StyledSpan, StyledImageSpan, StyledMathSpan } from './styled';\nimport { StyledObject, EStyledObjectEvent, IStyledObjectAttachEvent, IStyledObjectReplaceStyleEvent, EStyledObjectMark } from './styled-object';\nimport { StyledEmbed, EStyledEmbedBuilder, StyledEmbedController } from './styled-embed';\nimport {\n  StyledBaselineOffsetValue,\n  StyledDecorationValue,\n  StyledGestureValue,\n  StyledLetterSpacingValue,\n  StyledLineHeightValue,\n  StyledParagraphValue,\n  StyledTextValue,\n  StyledBackgroundColorValue,\n} from './styled-value';\nimport {\n  Node, ENode, ELayout, EListItem,\n  Document, Heading, LineBreak, Link,\n  FootnoteRef, Code, ListItem, Emoji,\n  HtmlTag, Image, Math as MathNode,\n  StyledContent, List, Fragment, EHtmlTag,\n} from '../../service/ast/node';\nimport { drawing } from '@kit.ArkGraphics2D';\nimport { HeadingLevelStyling } from '../../theme';\nimport { MDLength, newLog, MDColor } from '../../util';\nimport { LengthMetrics, Rect } from '@kit.ArkUI';\nimport OhosGText from '@ohos.graphics.text';\nimport type { IImageServiceRequest } from '../../service/image';\n\nconst log = newLog('Styled');\n\nexport abstract class Styled implements IStyled {\n  readonly option: IStyledOption;\n  constructor(option: IStyledOption) {\n    this.option = option;\n  }\n  abstract get node(): Node | undefined;\n  build(option: IStyledBuild): void {\n    do {\n      const anchor = StyledObject.begin({ styled: this }, undefined, EStyledObjectMark.BuildBegin);\n      option.didCreateStyled(anchor);\n      option.willBuild?.(anchor);\n    } while (0);\n    if (this.node?.layout === ELayout.Block) {\n      option.didCreateStyled(StyledObject.begin({ styled: this }));\n    }\n    const hook = option.engine.render?.styledBuildingPlugin(this, option);\n    if (hook) {\n      hook.handler.building(this, option);\n    } else {\n      this.building(option);\n    }\n    if (this.node?.layout === ELayout.Block) {\n      this.break(option);\n      option.didCreateStyled(StyledObject.end({ styled: this }));\n    }\n    do {\n      const anchor = StyledObject.end({ styled: this }, undefined, EStyledObjectMark.BuildEnd);\n      option.didCreateStyled(anchor);\n      option.didBuild?.(anchor);\n    } while (0);\n  }\n  protected abstract building(option: IStyledBuild): void;\n  private break(option: IStyledBuild) {\n    if (!this.node?.hidden && this.node?.next) {\n      const types = [\n        ENode.Paragraph, ENode.Heading,\n        ENode.Quote, ENode.ListItem, ENode.List,\n        ENode.Code, ENode.Table,\n      ];\n      if (types.indexOf(this.node?.type) !== -1) {\n        option.didCreateStyled(StyledObject.break({ styled: this }));\n      }\n    }\n  }\n  static create(option: IStyledOption): Styled | undefined {\n    if (option.node?.is(ENode.Fragment)) {\n      return new FragmentStyled(option);\n    } else if (option.node?.is(ENode.Document)) {\n      return new DocumentStyled(option);\n    } else if (option.node?.is(ENode.Paragraph)) {\n      return new ParagraphStyled(option);\n    } else if (option.node?.is(ENode.ThematicBreak)) {\n      return new ThematicBreakStyled(option);\n    } else if (option.node?.is(ENode.Heading)) {\n      return new HeadingStyled(option);\n    } else if (option.node?.is(ENode.Quote)) {\n      return new QuoteStyled(option);\n    } else if (option.node?.is(ENode.Code)) {\n      return new CodeStyled(option);\n    } else if (option.node?.is(ENode.Table)) {\n      return new TableStyled(option);\n    } else if (option.node?.is(ENode.TableItem)) {\n      return new TableItemStyled(option);\n    } else if (option.node?.is(ENode.List)) {\n      return new ListStyled(option);\n    } else if (option.node?.is(ENode.ListItem)) {\n      return new ListItemStyled(option);\n    } else if (option.node?.is(ENode.HtmlTag)) {\n      return new HtmlTagStyled(option);\n    } else if (option.node?.is(ENode.Math)) {\n      return new MathStyled(option);\n    } else if (option.node?.is(ENode.Text)) {\n      return new TextStyled(option);\n    } else if (option.node?.is(ENode.LineBreak)) {\n      return new LineBreakStyled(option);\n    } else if (option.node?.is(ENode.Emoji)) {\n      return new EmojiStyled(option);\n    } else if (option.node?.is(ENode.Strong)) {\n      return new StrongStyled(option);\n    } else if (option.node?.is(ENode.Emphasis)) {\n      return new EmphasisStyled(option);\n    } else if (option.node?.is(ENode.StrikeThrough)) {\n      return new StrikeThroughStyled(option);\n    } else if (option.node?.is(ENode.Image)) {\n      return new ImageStyled(option);\n    } else if (option.node?.is(ENode.Link)) {\n      return new LinkStyled(option);\n    } else if (option.node?.is(ENode.FootnoteRef)) {\n      return new FootnoteRefStyled(option);\n    } else if (option.node?.is(ENode.FootnoteDef)) {\n      return new FootnoteDefStyled(option);\n    } else if (option.node?.is(ENode.Superscript) || option.node?.is(ENode.Subscript)) {\n      return new SuxScriptStyled(option);\n    } else if (option.node?.is(ENode.Inline)) {\n      return new InlineStyled(option);\n    } else if (option.node?.is(ENode.StyledContent)) {\n      return new StyledContentStyled(option);\n    }\n    return undefined;\n  }\n}\nclass FragmentStyled extends Styled {\n  get node() {\n    return this.option.node as (Fragment | undefined);\n  }\n  protected building(option: IStyledBuild): void {\n    if (!!option.engine.ctx?.fragmentEnable) {\n      DocumentStyled.building(this, option);\n    } else {\n      this.node?.children?.forEach(node => {\n        Styled.create({ node })?.build(option);\n      });\n    }\n  }\n}\nclass DocumentStyled extends Styled {\n  get node() {\n    return this.option.node as (Document | undefined);\n  }\n  building(option: IStyledBuild) {\n    if (!!option.engine.ctx?.fragmentEnable) {\n      this.node?.children?.forEach(node => {\n        Styled.create({ node })?.build(option);\n      });\n    } else {\n      DocumentStyled.building(this, option);\n    }\n  }\n  static building(that: Styled, option: IStyledBuild) {\n    const group = StyledObject.group({ styled: that }, [\n      new StyledLetterSpacingValue(option.theme.document?.letterSpacing),\n      new StyledBaselineOffsetValue(option.theme.document?.baselineOffset),\n      new StyledLineHeightValue(option.theme.document?.lineHeight),\n      new StyledTextValue(option.theme.document?.font),\n    ]);\n    option.didCreateStyled(group);\n\n    for (const node of (that.node?.children ?? [])) {\n      Styled.create({ node })?.build({\n        theme: option.theme,\n        engine: option.engine,\n        didCreateStyled: styled => {\n          group.attach(styled);\n        },\n      });\n    }\n  }\n}\nclass ParagraphStyled extends Styled {\n  get node() {\n    return this.option.node as (Node | undefined);\n  }\n  building(option: IStyledBuild) {\n    if (this.node?.hidden) {\n      //  忽略本级paragraph，直接透传至父级处理\n      for (const node of (this.node?.children ?? [])) {\n        Styled.create({ node })?.build(option);\n      }\n    } else {\n      const group = StyledObject.group({ styled: this });\n      option.didCreateStyled(group);\n      for (const node of (this.node?.children ?? [])) {\n        Styled.create({ node })?.build({\n          theme: option.theme,\n          engine: option.engine,\n          didCreateStyled: styled => {\n            group.attach(styled);\n          },\n        });\n      }\n    }\n  }\n}\nclass ThematicBreakStyled extends Styled {\n  get node() {\n    return this.option.node as (Node | undefined);\n  }\n  building(option: IStyledBuild) {\n    const group = StyledObject.group({ styled: this });\n    option.didCreateStyled(group);\n\n    group.attach(new StyledObject(\n      { styled: this },\n      new StyledSpan({\n        onMeasure: (_span, _measureInfo) => {\n          const width: number = group.blockArea?.width?.value ?? 0;\n          const height: number = MDLength.vp(option.theme.thematicBreak?.lineHeight?.height?.value ?? 0).value;\n          return { width, height };\n        },\n        onDraw: (span, context, drawInfo) => {\n          const metrics = span.metrics;\n          const brush = new drawing.Brush();\n          brush.setColor(MDColor.makeColorFromResourceColor(option.theme.thematicBreak?.lineColor ?? Color.Black));\n          context.canvas.attachBrush(brush);\n          context.canvas.drawRect({\n            left: drawInfo.x,\n            top: drawInfo.baseline - MDLength.vp2px(metrics.height ?? 0).value/2*0.9,\n            right: MDLength.vp2px(metrics.width).value,\n            bottom: drawInfo.baseline + MDLength.vp2px(metrics.height ?? 0).value/2*0.9,\n          });\n          context.canvas.detachBrush();\n        },\n      }),\n    ));\n  }\n}\nclass HeadingStyled extends Styled {\n  get node() {\n    return this.option.node as (Heading | undefined);\n  }\n  building(option: IStyledBuild) {\n    let level: HeadingLevelStyling | undefined = undefined;\n    if (this.node?.level === 1) {\n      level = option.theme.heading?.h1;\n    } else if (this.node?.level === 2) {\n      level = option.theme.heading?.h2;\n    } else if (this.node?.level === 3) {\n      level = option.theme.heading?.h3;\n    } else if (this.node?.level === 4) {\n      level = option.theme.heading?.h4;\n    } else if (this.node?.level === 5) {\n      level = option.theme.heading?.h5;\n    } else if (this.node?.level === 6) {\n      level = option.theme.heading?.h6;\n    }\n    const group = StyledObject.group({ styled: this }, [\n      new StyledTextValue(level?.font),\n      new StyledLineHeightValue(level?.lineHeight),\n    ]);\n    option.didCreateStyled(group);\n\n    for (const node of (this.node?.children ?? [])) {\n      Styled.create({ node })?.build({\n        theme: option.theme,\n        engine: option.engine,\n        didCreateStyled: styled => {\n          group.attach(styled);\n        },\n      });\n    }\n  }\n}\nclass QuoteStyled extends Styled {\n  get node() {\n    return this.option.node as (Node | undefined);\n  }\n  building(option: IStyledBuild) {\n    const group = StyledObject.group({ styled: this }, [\n      new StyledTextValue(option.theme.quote?.font),\n      new StyledParagraphValue(option.theme.quote?.contentParagraph),\n    ]);\n    option.didCreateStyled(group);\n\n    let edgeOffset: number = 0;\n    let lastOffset: number = 0;\n    let lastLength: number = 0;\n    group.attach(\n      new StyledObject(\n        { styled: this },\n        new StyledSpan({\n          onMeasure: (_span, _measureInfo) => {\n            return { width: 0 };\n          },\n          onDraw: (_span, context, drawInfo) => {\n            const rects = group.getRectsForRange(\n              { start: edgeOffset, end: lastOffset + lastLength },\n              OhosGText.RectWidthStyle.TIGHT, OhosGText.RectHeightStyle.TIGHT,\n            );\n            if (rects && rects.length > 0) {\n              const bottom = rects[rects.length - 1].rect.bottom;\n              const brush = new drawing.Brush();\n              brush.setColor(MDColor.makeColorFromResourceColor(option.theme.quote?.edgeColor ?? Color.Gray));\n              context.canvas.attachBrush(brush);\n              const left: number = drawInfo.x - MDLength.vp2px((option.theme.quote?.contentParagraph?.leadingMargin as LengthMetrics)?.value ?? 0).value;\n              const right: number = left + MDLength.vp2px(option.theme.quote?.edgeWidth?.value ?? 0).value;\n              context.canvas.drawRect({\n                left, right,\n                top: drawInfo.lineTop, bottom: bottom,\n              })\n              context.canvas.detachBrush();\n            }\n          },\n        }),\n      ).on<IStyledObjectAttachEvent>(EStyledObjectEvent.DidAttachTo, event => {\n        edgeOffset = event.current.offset;\n      })\n    );\n\n    for (const node of (this.node?.children ?? [])) {\n      Styled.create({ node })?.build({\n        theme: option.theme,\n        engine: option.engine,\n        didCreateStyled: styled => {\n          group.attach(styled);\n          // lastOffset = styled.offset;\n          // lastLength = styled.length;\n        },\n        didBuild: anchor => {\n          lastOffset = anchor.offset;\n          lastLength = anchor.length;\n        },\n      });\n    }\n  }\n}\nclass CodeStyled extends Styled {\n  get node() {\n    return this.option.node as (Code | undefined);\n  }\n  building(option: IStyledBuild) {\n    const code = this.node;\n    if (code) {\n      if (code.layout === ELayout.Inline) {\n        CodeStyled.buildingInline(this, option, code.content);\n      } else {\n        this.buildingBlock(code, option);\n      }\n    }\n  }\n  buildingBlock(code: Code, option: IStyledBuild) {\n    if (code.styledContent) {\n      // option.didCreateStyled(code.styled as StyledObject);\n      const group = StyledObject.group({ styled: this });\n      option.didCreateStyled(group);\n      group.attach(new StyledEmbed(\n        { styled: this },\n        {\n          initMetrics: { width: group.blockArea?.width?.value ?? 0 },\n          builderType: EStyledEmbedBuilder.Code,\n          embedController: new StyledEmbedController(),\n          theme: option.theme,\n        },\n      ));\n    }\n  }\n  static buildingInline(that: Styled, option: IStyledBuild, content?: string | Node) {\n    if (content) {\n      const group = StyledObject.group({ styled: that });\n      option.didCreateStyled(group);\n      group.attach(new StyledObject({ styled: that }, ' ', [\n        new StyledBackgroundColorValue({\n          color: option.theme.inlineCode?.background?.color,\n          radiuses: {\n            topLeft: option.theme.inlineCode?.background?.radius,\n            bottomLeft: option.theme.inlineCode?.background?.radius,\n          },\n        }),\n      ]));\n      if (typeof content === 'string') {\n        group.attach(new StyledObject({ styled: that }, content, [\n          new StyledBackgroundColorValue({\n            color: option.theme.inlineCode?.background?.color,\n          }),\n        ]));\n      } else {\n        const contentGroup = StyledObject.group({ styled: that }, [\n          new StyledBackgroundColorValue({\n            color: option.theme.inlineCode?.background?.color,\n          }),\n        ]);\n        group.attach(contentGroup);\n        for (const node of (content.children ?? [])) {\n          Styled.create({ node })?.build({\n            theme: option.theme,\n            engine: option.engine,\n            didCreateStyled: styled => {\n              contentGroup.attach(styled);\n            },\n          });\n        }\n      }\n      group.attach(new StyledObject({ styled: that }, ' ', [\n        new StyledBackgroundColorValue({\n          color: option.theme.inlineCode?.background?.color,\n          radiuses: {\n            topRight: option.theme.inlineCode?.background?.radius,\n            bottomRight: option.theme.inlineCode?.background?.radius,\n          },\n        }),\n      ]));\n    }\n  }\n}\nclass TableStyled extends Styled {\n  get node() {\n    return this.option.node as (Node | undefined);\n  }\n  building(option: IStyledBuild) {\n    const group = StyledObject.group({ styled: this });\n    option.didCreateStyled(group);\n    group.attach(new StyledEmbed(\n      { styled: this },\n      {\n        initMetrics: { width: group.blockArea?.width?.value ?? 0 },\n        builderType: EStyledEmbedBuilder.Table,\n        embedController: new StyledEmbedController(),\n        theme: option.theme,\n      },\n    ));\n    // group.attach(StyledObject.break({ styled: this }));\n  }\n}\nclass TableItemStyled extends Styled {\n  get node() {\n    return this.option.node as (Node | undefined);\n  }\n  building(option: IStyledBuild) {\n    const group = StyledObject.group({ styled: this });\n    option.didCreateStyled(group);\n    for (const node of (this.node?.children ?? [])) {\n      Styled.create({ node })?.build({\n        theme: option.theme,\n        engine: option.engine,\n        didCreateStyled: styled => {\n          group.attach(styled);\n        },\n      });\n    }\n  }\n}\nclass ListStyled extends Styled {\n  get node() {\n    return this.option.node as (List | undefined);\n  }\n  building(option: IStyledBuild) {\n    const group = StyledObject.group({ styled: this }, [\n      new StyledParagraphValue(\n        this.node?.isTop ? option.theme.listItem?.contentTopParagraph : option.theme.listItem?.contentParagraph\n      ),\n    ]);\n    option.didCreateStyled(group);\n\n    for (const node of (this.node?.children ?? [])) {\n      Styled.create({ node })?.build({\n        theme: option.theme,\n        engine: option.engine,\n        didCreateStyled: styled => {\n          group.attach(styled);\n        },\n      });\n    }\n  }\n}\nclass ListItemStyled extends Styled {\n  get node() {\n    return this.option.node as (ListItem | undefined);\n  }\n  get content() {\n    const first = this.node?.first?.deref();\n    return first?.is(ENode.Paragraph) ? first : undefined;\n  }\n  get list() {\n    const last = this.node?.last?.deref();\n    return last?.is(ENode.List) ? last : undefined;\n  }\n  get isTop() {\n    return !!(this.node?.parentList?.isTop);\n  }\n  get inQuote() {\n    let isIn: boolean = false;\n    let parent = this.node?.parent?.deref();\n    while (parent) {\n      if (parent.is(ENode.Quote)) {\n        isIn = true;\n        break;\n      }\n      parent = parent.parent?.deref();\n    }\n    return isIn;\n  }\n  building(option: IStyledBuild) {\n    const item = StyledObject.group({ styled: this });\n    option.didCreateStyled(item);\n\n    const inQuote = this.inQuote;\n\n    do {\n      //  FIXME: why the first item in quote can NOT FOLLOW PARAGRAPH LEADING MARGIN?\n      const leading = (option.theme.listItem?.contentTopParagraph?.leadingMargin as LengthMetrics)?.value ?? 0;\n      if (inQuote && this.isTop && !this.node?.prev?.deref() && leading) {\n        item.attach(new StyledObject({ styled: this }, new StyledSpan({\n          onMeasure: (_span, _measureInfo) => {\n            return { width: leading };\n          },\n        })));\n      }\n    } while (0);\n\n    const obj = new StyledObject({ styled: this }, new StyledSpan({\n      onMeasure: (_span, _measureInfo) => {\n        return { width: 0 };\n      },\n      onDraw: (_span, context, drawInfo) => {\n        const textStyle = obj.cascadedStyle<TextStyle>(StyledStringKey.FONT);\n\n        if (this.node?.itemType === EListItem.CheckBox) {\n          const width = MDLength.vp2px(option.theme.listItem?.taskFlagWidth?.value ?? 0).value;\n          const left = drawInfo.x - width;\n          const top = drawInfo.baseline - width;\n          const inset = (rect: Rect): Rect => {\n            const v = MDLength.vp2px(1).value;\n            return {\n              left: rect.left + v,\n              top: rect.top + v,\n              right: rect.right - v,\n              bottom: rect.bottom - v,\n            };\n          };\n          let rect: Rect = {\n            left, top,\n            right: left + width,\n            bottom: top + width,\n          };\n          const color = inQuote ? textStyle?.fontColor : option.theme.listItem?.taskFlagColor;\n          do {\n            const brush = new drawing.Brush();\n            brush.setColor(MDColor.makeColorFromResourceColor(color ?? Color.Black));\n            context.canvas.attachBrush(brush);\n            context.canvas.drawRect(rect);\n            context.canvas.detachBrush();\n          } while (0);\n          do {\n            rect = inset(rect);\n            const brush = new drawing.Brush();\n            brush.setColor(MDColor.makeColorFromResourceColor(Color.White));\n            context.canvas.attachBrush(brush);\n            context.canvas.drawRect(rect);\n            context.canvas.detachBrush();\n          } while (0);\n          if (this.node?.checked) {\n            rect = inset(rect);\n            const brush = new drawing.Brush();\n            brush.setColor(MDColor.makeColorFromResourceColor(color ?? Color.Black));\n            context.canvas.attachBrush(brush);\n            context.canvas.drawRect(rect);\n            context.canvas.detachBrush();\n          }\n        } else {\n          const isTop = this.isTop && !inQuote;\n          const leading = isTop ? option.theme.listItem?.contentTopParagraph : option.theme.listItem?.contentParagraph;\n\n          const width = MDLength.vp2px((leading?.leadingMargin as LengthMetrics)?.value ?? 0).value;\n          if (width <= 0) {\n            return;\n          }\n          const x: number = drawInfo.x - width;\n\n          const topBoxWidth = MDLength.vp2px(option.theme.listItem?.contentTopBoxWidth?.value ?? 0).value;\n          const topBoxTop = drawInfo.baseline - topBoxWidth * 8 / 9;\n          const topBoxRect: Rect = {\n            left: x, right: x + topBoxWidth, top: topBoxTop, bottom: topBoxTop + topBoxWidth,\n          };\n          if (this.node?.itemType === EListItem.Ordered) {\n            const label = this.node?.info || '';\n            if (isTop) {\n              do {\n                const boxRadius = MDLength.vp2px(option.theme.listItem?.contentTopBoxRadius?.value ?? 0).value;\n                const brush = new drawing.Brush();\n                brush.setColor(MDColor.makeColorFromResourceColor(option.theme.listItem?.contentTopBoxBackgroundColor ?? Color.White));\n                context.canvas.attachBrush(brush);\n                context.canvas.drawRoundRect(new drawing.RoundRect(topBoxRect, boxRadius, boxRadius));\n                context.canvas.detachBrush();\n              } while (0);\n              do {\n                const textSize = option.engine.ctx?.measureTextSize({\n                  textContent: label,\n                  textStyle: new StyledTextValue(option.theme.listItem?.contentTopBoxFont).value,\n                });\n                const textX = topBoxRect.left + (topBoxRect.right - topBoxRect.left - (textSize?.width as number ?? 0)) / 2;\n                const textY = drawInfo.baseline - (option.theme.listItem?.contentTopBoxFont?.fontSize?.value ?? 0) * 2 / 5;\n                const font = new drawing.Font();\n                font.setSize(MDLength.vp2px(option.theme.listItem?.contentTopBoxFont?.fontSize?.value ?? 0).value);\n                const pen = new drawing.Pen();\n                pen.setStrokeWidth(1);\n                pen.setColor(MDColor.makeColorFromResourceColor(option.theme.listItem?.contentTopBoxFont?.fontColor ?? Color.Black));\n                context.canvas.attachPen(pen);\n                const brush = new drawing.Brush();\n                brush.setColor(MDColor.makeColorFromResourceColor(option.theme.listItem?.contentTopBoxFont?.fontColor ?? Color.Black));\n                context.canvas.attachBrush(brush);\n                const blob = drawing.TextBlob.makeFromString(label, font);\n                context.canvas.drawTextBlob(blob, textX, textY);\n                context.canvas.detachBrush();\n                context.canvas.detachPen();\n              } while (0);\n            } else {\n              const font = new drawing.Font();\n              font.setSize(MDLength.vp2px(textStyle?.fontSize as number ?? 0).value);\n              const pen = new drawing.Pen();\n              pen.setStrokeWidth(1);\n              pen.setColor(MDColor.makeColorFromResourceColor(textStyle?.fontColor ?? Color.Black));\n              context.canvas.attachPen(pen);\n              const brush = new drawing.Brush();\n              brush.setColor(MDColor.makeColorFromResourceColor(textStyle?.fontColor ?? Color.Black));\n              context.canvas.attachBrush(brush);\n              const blob = drawing.TextBlob.makeFromString(`${label}.`, font);\n              context.canvas.drawTextBlob(blob, x, drawInfo.baseline);\n              context.canvas.detachBrush();\n              context.canvas.detachPen();\n            }\n          } else if (this.node?.itemType === EListItem.Bullet) {\n            if (isTop) {\n              const badgeWidth = MDLength.vp2px(option.theme.listItem?.contentTopBadgeWidth?.value ?? 0).value ?? 0;\n              const brush = new drawing.Brush();\n              brush.setColor(MDColor.makeColorFromResourceColor(option.theme.listItem?.contentTopBadgeBackgroundColor ?? Color.Black));\n              context.canvas.attachBrush(brush);\n              context.canvas.drawCircle(\n                topBoxRect.left + (topBoxRect.right - topBoxRect.left)/2,\n                topBoxRect.top + (topBoxRect.bottom - topBoxRect.top)/2,\n                badgeWidth / 2,\n              );\n              context.canvas.detachBrush();\n            } else {\n              const color = inQuote ? textStyle?.fontColor : option.theme.listItem?.contentBadgeBackgroundColor;\n              const leading = MDLength.vp2px((option.theme.listItem?.contentParagraph?.leadingMargin as LengthMetrics)?.value ?? 0).value;\n              const badgeWidth = MDLength.vp2px(option.theme.listItem?.contentBadgeWidth?.value ?? 0).value ?? 0;\n              const brush = new drawing.Brush();\n              brush.setColor(MDColor.makeColorFromResourceColor(color ?? Color.Black));\n              context.canvas.attachBrush(brush);\n              context.canvas.drawCircle(\n                drawInfo.x - leading + badgeWidth,\n                drawInfo.baseline - badgeWidth,\n                badgeWidth / 2,\n              );\n              context.canvas.detachBrush();\n            }\n          }\n        }\n      }\n    }));\n    item.attach(obj);\n\n    for (const node of (this.node?.children ?? [])) {\n      Styled.create({ node })?.build({\n        theme: option.theme,\n        engine: option.engine,\n        didCreateStyled: styled => {\n          item.attach(styled);\n        },\n      });\n    }\n  }\n}\nclass HtmlTagStyled extends Styled {\n  get node() {\n    return this.option.node as (HtmlTag | undefined);\n  }\n  building(option: IStyledBuild) {\n    if (this.node?.tagName === EHtmlTag.Sup) {\n      this.buildingSux(option, false);\n    } else if (this.node?.tagName === EHtmlTag.Sub) {\n      this.buildingSux(option, true);\n    } else if (this.node?.tagName === EHtmlTag.U) {\n      this.buildingU(option);\n    } else if (this.node?.tagName === EHtmlTag.Br) {\n      this.buildingBr(option);\n    } else if (this.node?.tagName === EHtmlTag.S) {\n      this.buildingS(option);\n    } else if (this.node?.tagName === EHtmlTag.Del) {\n      this.buildingDel(option);\n    } else if (this.node?.tagName === EHtmlTag.Mark) {\n      this.buildingMark(option);\n    } else if (this.node?.tagName === EHtmlTag.Span) {\n      this.buildingSpan(option);\n    } else if (this.node?.tagName === EHtmlTag.Cite) {\n      this.buildingCite(option);\n    } else if (this.node?.tagName === EHtmlTag.Font) {\n      this.buildingFont(option);\n    } else if (this.node?.tagName === EHtmlTag.Img) {\n      this.buildingImg(option);\n    } else if (this.node?.tagName === EHtmlTag.A) {\n      this.buildingA(option);\n    } else if (this.node?.tagName === EHtmlTag.Icon) {\n      this.buildingIcon(option);\n    } else if (this.node?.tagName === EHtmlTag.Div) {\n      this.buildingSpan(option);\n    }\n  }\n  private buildingIcon(option: IStyledBuild) {\n    const src = this.node?.attributes?.find(ele => ele.name === 'src')?.value;\n    if (src && typeof src === 'string') {\n      const group = StyledObject.group({ styled: this });\n      option.didCreateStyled(group);\n\n      const request: IImageServiceRequest = { url: src };\n      const imageObject = new StyledObject(\n        { styled: this },\n        new StyledImageSpan({\n          buildOption: option,\n          request,\n          onImageSourceRequested: () => {\n            imageObject.root?.deref()?.emit<IStyledObjectReplaceStyleEvent>(EStyledObjectEvent.DidReplaceStyle, {});\n          },\n          onMeasure: (span: StyledImageSpan, _measureInfo) => {\n            const imageSource = span.imageSource;\n            if (!imageSource) {\n              return { width: 0 };\n            }\n            const textStyle = imageObject.cascadedStyle<TextStyle>(StyledStringKey.FONT);\n            const fontSize = textStyle?.fontSize ?? option.theme.document?.font?.fontSize?.value ?? 0;\n            const imgHeight: number = MDLength.vp2px(fontSize).value;\n            const imageInfo = imageSource.getImageInfoSync();\n            const imgWidth: number = imageInfo.size.width * imgHeight / (imageInfo.size.height ?? 1);\n            return { width: MDLength.px2vp(imgWidth).value, height: MDLength.px2vp(imgHeight).value };\n          },\n          onDraw: (span: StyledImageSpan, context, drawInfo) => {\n            const imageSource = span.imageSource;\n            if (imageSource) {\n              const canvas = context.canvas;\n              const pixelMap = imageSource.createPixelMapSync();\n              const top = drawInfo.baseline - MDLength.vp2px(span.metrics.height ?? 0).value * 8 / 9;\n              canvas.drawImageRect(pixelMap, {\n                left: drawInfo.x,\n                top,\n                right: drawInfo.x + MDLength.vp2px(span.metrics.width).value,\n                bottom: top + MDLength.vp2px(span.metrics.height ?? 0).value,\n              });\n              pixelMap.release();\n            }\n          },\n        }),\n      );\n      group.attach(imageObject);\n    }\n  }\n  private buildingA(option: IStyledBuild) {\n    const href = this.node?.attributes?.find(ele => ele.name === 'href')?.value;\n    LinkStyled.building(this, option, typeof href === 'string' ? href : undefined);\n  }\n  private buildingImg(option: IStyledBuild) {\n    const src = this.node?.attributes?.find(ele => ele.name === 'src')?.value;\n    const alt = this.node?.attributes?.find(ele => ele.name === 'alt')?.value;\n    if (src && typeof src === 'string') {\n      ImageStyled.building(this, option, src, typeof alt === 'string' ? alt : undefined);\n    }\n  }\n  private buildingFont(option: IStyledBuild) {\n    //  color like: #fff | red | rgb(255, 0, 0) | rgba(255, 0, 0, 0.5)\n    const color = this.node?.attributes?.find(ele => ele.name === 'color')?.value;\n    const group = StyledObject.group({ styled: this }, [new StyledTextValue({\n      fontColor: (typeof color === 'string') ? color : undefined,\n    })]);\n    option.didCreateStyled(group);\n    for (const node of (this.node?.children ?? [])) {\n      Styled.create({ node })?.build({\n        theme: option.theme,\n        engine: option.engine,\n        didCreateStyled: styled => {\n          group.attach(styled);\n        },\n      });\n    }\n  }\n  private buildingCite(option: IStyledBuild) {\n    EmphasisStyled.building(this, option);\n  }\n  private buildingSpan(option: IStyledBuild) {\n    const group = StyledObject.group({ styled: this });\n    option.didCreateStyled(group);\n    for (const node of (this.node?.children ?? [])) {\n      Styled.create({ node })?.build({\n        theme: option.theme,\n        engine: option.engine,\n        didCreateStyled: styled => {\n          group.attach(styled);\n        },\n      });\n    }\n  }\n  private buildingMark(option: IStyledBuild) {\n    CodeStyled.buildingInline(this, option, this.node);\n  }\n  private buildingDel(option: IStyledBuild) {\n    StrikeThroughStyled.building(this, option);\n  }\n  private buildingS(option: IStyledBuild) {\n    StrikeThroughStyled.building(this, option);\n  }\n  private buildingBr(option: IStyledBuild) {\n    LineBreakStyled.building(this, option);\n  }\n  private buildingSux(option: IStyledBuild, isSubscript: boolean) {\n    if (this.node) {\n      const content = this.node.first?.deref();\n      if (content && content.is(ENode.Text)) {\n        SuxScriptStyled.building(this, isSubscript, option, content.content);\n      }\n    }\n  }\n  private buildingU(option: IStyledBuild) {\n    if (this.node) {\n      let u_offset: number = 0;\n      let end_offset: number = 0;\n      let end_length: number = 0;\n      const u = new StyledObject({ styled: this }, new StyledSpan({\n        onMeasure: (_span, _measureInfo) => {\n          return { width: 0 };\n        },\n        onDraw: (_span, context, _drawInfo) => {\n          const rects = u.getRectsForRange(\n            { start: u_offset, end: end_offset + end_length },\n            OhosGText.RectWidthStyle.TIGHT, OhosGText.RectHeightStyle.TIGHT,\n          );\n          if (rects) {\n            const brush = new drawing.Brush();\n            brush.setColor(MDColor.makeColorFromResourceColor(option.theme.underline?.markColor ?? Color.Black));\n            context.canvas.attachBrush(brush);\n            rects.forEach(ele => {\n              context.canvas.drawRect({\n                left: ele.rect.left,\n                right: ele.rect.right,\n                top: ele.rect.bottom - MDLength.vp2px(option.theme.underline?.markHeight?.value ?? 0).value,\n                bottom: ele.rect.bottom,\n              });\n            });\n            context.canvas.detachBrush();\n          }\n        },\n      }));\n      option.didCreateStyled(u);\n      u_offset = u.offset;\n\n      for (const node of (this.node?.children ?? [])) {\n        Styled.create({ node })?.build({\n          theme: option.theme,\n          engine: option.engine,\n          didCreateStyled: styled => {\n            u.attach(styled);\n          },\n          didBuild: anchor => {\n            end_offset = anchor.offset;\n            end_length = anchor.length;\n          },\n        });\n      }\n    }\n  }\n}\nclass MathStyled extends Styled {\n  get node() {\n    return this.option.node as (MathNode | undefined);\n  }\n  building(option: IStyledBuild) {\n    const group = StyledObject.group({ styled: this });\n    option.didCreateStyled(group);\n\n    const anchor = StyledObject.empty();\n    group.attach(anchor);\n    const font = anchor.cascadedStyle<TextStyle>(StyledStringKey.FONT);\n\n    const mathObject = new StyledObject(\n      { styled: this },\n      new StyledMathSpan({\n        buildOption: option,\n        request: {\n          content:  this.node?.content || '',\n          hash: this.node?.mathHash,\n          fontSize: vp2px(font?.fontSize),\n          fontColor: font?.fontColor ? MDColor.toHex(font?.fontColor) : undefined,\n        },\n        onResourceLoaded: (_span) => {\n          mathObject.root?.deref()?.emit<IStyledObjectReplaceStyleEvent>(EStyledObjectEvent.DidReplaceStyle, {});\n        },\n        onMeasure: (span, _measureInfo) => {\n          if (span.imageSource) {\n            const imageInfo = span.imageSource.getImageInfoSync();\n            let width: number = MDLength.px2vp(imageInfo.size.width).value;\n            const widthMax = group.blockArea?.width?.value ?? width;\n            width = widthMax < width ? widthMax : width;\n            const height = MDLength.px2vp(imageInfo.size.height).value * width / (MDLength.px2vp(imageInfo.size.width).value || 1);\n            return { width,  height };\n          }\n          return { width: 0 };\n        },\n        onDraw: (span, context, drawInfo) => {\n          if (span.imageSource) {\n            const width = MDLength.vp2px(span.metrics.width).value;\n            const height = MDLength.vp2px(span.metrics.height ?? 0).value;\n            const baseline = drawInfo.baseline + height * 2/9;\n            const pixelMap = span.imageSource.createPixelMapSync();\n            context.canvas.drawImageRect(pixelMap, {\n              left: drawInfo.x,\n              top: baseline - height,\n              right: drawInfo.x + width,\n              bottom: baseline,\n            });\n            pixelMap.release();\n          }\n        },\n      }),\n    );\n\n    group.attach(mathObject);\n  }\n}\nclass TextStyled extends Styled {\n  get node() {\n    return this.option.node as (Node | undefined);\n  }\n  building(option: IStyledBuild) {\n    option.didCreateStyled(new StyledObject({ styled: this }, this.node?.content ?? ''));\n  }\n}\nclass LineBreakStyled extends Styled {\n  get node() {\n    return this.option.node as (LineBreak | undefined);\n  }\n  building(option: IStyledBuild) {\n    LineBreakStyled.building(this, option);\n  }\n  static building(that: Styled, option: IStyledBuild) {\n    option.didCreateStyled(StyledObject.break({ styled: that }));\n  }\n}\nclass EmojiStyled extends Styled {\n  get node() {\n    return this.option.node as (Emoji | undefined);\n  }\n  building(option: IStyledBuild) {\n    option.didCreateStyled(new StyledObject(\n      { styled: this },\n      this.node?.content ?? ''\n    ));\n  }\n}\nclass StrongStyled extends Styled {\n  get node() {\n    return this.option.node as (Node | undefined);\n  }\n  building(option: IStyledBuild) {\n    const group = StyledObject.group({ styled: this }, [\n      new StyledTextValue(option.theme.strong?.font),\n    ]);\n    option.didCreateStyled(group);\n\n    for (const node of (this.node?.children ?? [])) {\n      Styled.create({ node })?.build({\n        theme: option.theme,\n        engine: option.engine,\n        didCreateStyled: styled => {\n          group.attach(styled);\n        },\n      });\n    }\n  }\n}\nclass EmphasisStyled extends Styled {\n  get node() {\n    return this.option.node as (Node | undefined);\n  }\n  building(option: IStyledBuild) {\n    EmphasisStyled.building(this, option);\n  }\n  static building(that: Styled, option: IStyledBuild) {\n    const group = StyledObject.group({ styled: that }, [\n      new StyledTextValue(option.theme.emphasis?.font),\n    ]);\n    option.didCreateStyled(group);\n\n    for (const node of (that.node?.children ?? [])) {\n      Styled.create({ node })?.build({\n        theme: option.theme,\n        engine: option.engine,\n        didCreateStyled: styled => {\n          group.attach(styled);\n        },\n      });\n    }\n  }\n}\nclass StrikeThroughStyled extends Styled {\n  get node() {\n    return this.option.node as (Node | undefined);\n  }\n  building(option: IStyledBuild) {\n    StrikeThroughStyled.building(this, option);\n  }\n  static building(that: Styled, option: IStyledBuild) {\n    const group = StyledObject.group({ styled: that }, [\n      new StyledDecorationValue(option.theme.strikeThrough?.decoration),\n    ]);\n    option.didCreateStyled(group);\n\n    for (const node of (that.node?.children ?? [])) {\n      Styled.create({ node })?.build({\n        theme: option.theme,\n        engine: option.engine,\n        didCreateStyled: styled => {\n          group.attach(styled);\n        },\n      });\n    }\n  }\n}\nclass ImageStyled extends Styled {\n  get node() {\n    return this.option.node as (Image | undefined);\n  }\n  building(option: IStyledBuild) {\n    if (!this.node?.src) {\n      log.w(`image build failed. src is empty. nodeId: ${this.node?.id}`);\n      return;\n    }\n    ImageStyled.building(this, option, this.node?.src, this.node?.alt);\n  }\n  static building(that: Styled, option: IStyledBuild, src: string, _alt?: string) {\n    const group = StyledObject.group({ styled: that }, [\n      new StyledGestureValue({\n        onClick: event => {\n          option.engine.event?.invokeClickGesture(that.node!, event);\n        },\n      }),\n    ]);\n    option.didCreateStyled(group);\n\n    const request: IImageServiceRequest = { url: src };\n    const imageObject = new StyledObject(\n      { styled: that },\n      new StyledImageSpan({\n        buildOption: option,\n        request,\n        onImageSourceRequested: () => {\n          imageObject.root?.deref()?.emit<IStyledObjectReplaceStyleEvent>(EStyledObjectEvent.DidReplaceStyle, {});\n        },\n        onMeasure: (span: StyledImageSpan, _measureInfo) => {\n          const imageSource = span.imageSource;\n          if (!imageSource) {\n            return { width: 0 };\n          }\n          const maxWidth = MDLength.vp2px(group.blockArea?.width?.value ?? 0).value;\n          const maxHeight = MDLength.vp2px(option.theme.image?.maxHeight?.value ?? 0).value;\n          const imageInfo = imageSource.getImageInfoSync();\n          let width = Math.min(maxWidth, imageInfo.size.width);\n          let height = imageInfo.size.height * width / (imageInfo.size.width ?? 1);\n          if (height > maxHeight) {\n            width = maxHeight * width / (height ?? 1);\n            height = maxHeight;\n          }\n          return { width: MDLength.px2vp(width).value, height: MDLength.px2vp(height).value };\n        },\n        onDraw: (span: StyledImageSpan, context, drawInfo) => {\n          const imageSource = span.imageSource;\n          if (imageSource) {\n            const canvas = context.canvas;\n            const pixelMap = imageSource.createPixelMapSync();\n            canvas.drawImageRect(pixelMap, {\n              left: drawInfo.x,\n              top: drawInfo.lineTop,\n              right: drawInfo.x + MDLength.vp2px(span.metrics.width).value,\n              bottom: drawInfo.lineTop + MDLength.vp2px(span.metrics.height ?? 0).value,\n            });\n            pixelMap.release();\n          }\n        },\n      }),\n    );\n    group.attach(imageObject);\n  }\n}\nclass LinkStyled extends Styled {\n  get node() {\n    return this.option.node as (Link | undefined);\n  }\n  building(option: IStyledBuild) {\n    if (this.node && this.node.is(ENode.Link)) {\n      LinkStyled.building(this, option, this.node?.href);\n    }\n  }\n  static building(that: Styled, option: IStyledBuild, _href?: string) {\n    if (that.node) {\n      const group = StyledObject.group({ styled: that }, [\n        new StyledTextValue(option.theme.link?.font),\n        new StyledGestureValue({\n          onClick: event => {\n            option.engine.event?.invokeClickGesture(that.node!, event);\n          },\n        }),\n      ]);\n      option.didCreateStyled(group);\n\n      for (const node of (that.node?.children ?? [])) {\n        Styled.create({ node })?.build({\n          theme: option.theme,\n          engine: option.engine,\n          didCreateStyled: styled => {\n            group.attach(styled);\n          },\n        });\n      }\n\n      const icon = new StyledObject({ styled: that }, new StyledSpan({\n        onMeasure: (_span, _measureInfo) => {\n          return {\n            width: option.theme.link?.iconSize?.width?.value ?? 0,\n            height: option.theme.link?.iconSize?.height?.value,\n          };\n        },\n        onDraw: (span, context, drawInfo) => {\n          const canvas = context.canvas;\n          const image = option.engine.image?.load('icon_link.png');\n          if (image) {\n            const top = drawInfo.baseline - MDLength.vp2px(span.metrics.height ?? 0).value;\n            const imageRect: Rect = {\n              top,\n              left: drawInfo.x,\n              right: drawInfo.x + MDLength.vp2px(span.metrics.width).value,\n              bottom: top + MDLength.vp2px(span.metrics.height ?? 0).value,\n            };\n            const imagePixel = image.createPixelMapSync();\n            canvas.save();\n            canvas.drawImageRect(imagePixel, imageRect);\n            canvas.restore();\n            imagePixel.release();\n            image.release();\n          }\n        },\n      }));\n      group.attach(icon);\n    }\n  }\n}\nclass FootnoteRefStyled extends Styled {\n  get node() {\n    return this.option.node as (FootnoteRef | undefined);\n  }\n  building(option: IStyledBuild) {\n    FootnoteRefStyled.building(this, this.node?.label ?? '', option, this.node);\n  }\n  static building(styled: IStyled, text: string, option: IStyledBuild, node?: Node) {\n    const obj = new StyledObject(\n      { styled },\n      new StyledSpan({\n        onMeasure: (_span, _measureInfo) => {\n          const width: number = option.theme.footnoteRef?.minSize?.width?.value ?? 0;\n          const height: number = option.theme.footnoteRef?.minSize?.height?.value ?? 0;\n          return { width, height };\n        },\n        onDraw: (_span, context, drawInfo) => {\n          const canvas = context.canvas;\n\n          const textValue = obj.cascadedStyle<TextStyle>(StyledStringKey.FONT);\n          const fontSize = textValue?.fontSize ?? 0;\n\n          //  bg badge\n          do {\n            const offset = MDLength.vp2px(MDLength.baselineOffsetVP(fontSize).value);\n\n            const brush = new drawing.Brush();\n            brush.setColor(MDColor.makeColorFromResourceColor(option.theme.footnoteRef?.background?.color ?? Color.Black));\n            canvas.attachBrush(brush);\n            const radius = MDLength.vp2px(option.theme.footnoteRef?.minSize?.width?.value ?? 0).value/2;\n            const x = drawInfo.x + radius;\n            const y = drawInfo.baseline + offset.value - radius;\n            canvas.drawCircle(x, y, radius);\n            canvas.detachBrush();\n          } while (0);\n          //  text content\n          do {\n            if (text.length === 0) {\n              break;\n            }\n            const offset = MDLength.vp2px(MDLength.baselineOffsetVP(fontSize, 1/9).value);\n\n            const textStyle = obj.cascadedStyle<TextStyle>(StyledStringKey.FONT);\n            const size = option.engine.ctx?.measureTextSize({\n              textContent: text,\n              textStyle,\n            });\n            const x = drawInfo.x + (MDLength.vp2px(option.theme.footnoteRef?.minSize?.width?.value ?? 0).value - (size?.width as number ?? 0))/2;\n            const font = new drawing.Font();\n            font.setSize(MDLength.vp2px(textStyle?.fontSize ?? 0).value);\n            const brush = new drawing.Brush();\n            brush.setColor(MDColor.makeColorFromResourceColor(textStyle?.fontColor ?? Color.Black));\n            const blob = drawing.TextBlob.makeFromString(text, font);\n            canvas.attachBrush(brush);\n            canvas.drawTextBlob(blob, x, drawInfo.baseline - offset.value);\n            canvas.detachBrush();\n          } while (0);\n        },\n      }),\n      [\n        new StyledTextValue(option.theme.footnoteRef?.font),\n        new StyledGestureValue({\n          onClick: event => {\n            if (node) {\n              option.engine.event?.invokeClickGesture(node, event);\n            }\n          },\n        }),\n      ]\n    );\n    option.didCreateStyled(obj);\n  }\n}\nclass FootnoteDefStyled extends Styled {\n  get node() {\n    return this.option.node as (Node | undefined);\n  }\n  building(option: IStyledBuild) {\n\n  }\n}\nclass SuxScriptStyled extends Styled {\n  get node() {\n    return this.option.node as (Node | undefined);\n  }\n  get content() {\n    const node = this.node;\n    if (node) {\n      const first = node.first?.deref();\n      if (first && first.is(ENode.Text)) {\n        return first.content;\n      }\n    }\n    return undefined;\n  }\n  get isSubscript() {\n    return !!(this.node?.is(ENode.Subscript));\n  }\n  building(option: IStyledBuild) {\n    SuxScriptStyled.building(this, this.isSubscript, option, this.content);\n  }\n  static building(\n    that: IStyled, isSubscript: boolean,\n    option: IStyledBuild, content?: string\n  ) {\n    //  FIXME: span的letterSpacing需要修复\n    let contentSize: SizeOptions = {};\n    const obj = new StyledObject(\n      { styled: that },\n      new StyledSpan({\n        onMeasure: (_span, _measureInfo) => {\n          if (content) {\n            contentSize = option.engine.ctx?.measureTextSize({\n              textContent: content,\n              textStyle: obj.cascadedStyle<TextStyle>(StyledStringKey.FONT),\n            }) ?? {};\n            return { width: MDLength.px2vp((contentSize.width as number ?? 0)).value };\n          }\n          return { width: 0 };\n        },\n        onDraw: (_span, context, drawInfo) => {\n          if (content) {\n            const textStyle = obj.cascadedStyle<TextStyle>(StyledStringKey.FONT);\n            do {\n              const font = new drawing.Font();\n              font.setSize(MDLength.vp2px(textStyle?.fontSize ?? 0).value);\n              const brush = new drawing.Brush();\n              brush.setColor(MDColor.makeColorFromResourceColor(textStyle?.fontColor ?? Color.Black));\n              const blob = drawing.TextBlob.makeFromString(content, font);\n              const y = isSubscript ?\n                drawInfo.baseline + (contentSize.height as number ?? 0)/2*0.9 :\n                drawInfo.baseline - (contentSize.height as number ?? 0)/2*0.9\n              context.canvas.attachBrush(brush);\n              context.canvas.drawTextBlob(blob, drawInfo.x, y);\n              context.canvas.detachBrush();\n            } while (0);\n          }\n        },\n      }),\n      [\n        new StyledTextValue(isSubscript ?\n          option.theme.subscript?.font :\n          option.theme.superscript?.font),\n      ]\n    );\n    option.didCreateStyled(obj);\n  }\n}\nclass StyledContentStyled extends Styled {\n  get node() {\n    return this.option.node as (StyledContent | undefined);\n  }\n  building(option: IStyledBuild) {\n    if (this.node && this.node.styled) {\n      option.didCreateStyled(this.node.styled as StyledObject);\n    }\n  }\n}\nclass InlineStyled extends Styled {\n  get node() {\n    return this.option.node as (Node | undefined);\n  }\n  building(option: IStyledBuild) {\n    const group = StyledObject.group({ styled: this });\n    option.didCreateStyled(group);\n    for (const node of (this.node?.children ?? [])) {\n      Styled.create({ node })?.build({\n        theme: option.theme,\n        engine: option.engine,\n        didCreateStyled: styled => {\n          group.attach(styled);\n        },\n      });\n    }\n  }\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/render/styled/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { Styled } from './build-in';\n\nexport * from './styled';\nexport * from './styled-object';\nexport * from './styled-value';\nexport * from './styled-controller';\nexport * from './styled-embed';\nexport { Styled };"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/render/styled/styled-controller.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { StyledUserBridgeValue } from './styled-value';\nimport { newLog } from '../../util';\n\nconst log = newLog('StyledController');\n\nexport class StyledController extends TextController {\n  setStyledString(value: StyledString): void {\n    try {\n      if (value.length > 0) {\n        const styled = value.getStyles(0, value.length, StyledStringKey.USER_DATA)\n          .filter(ele => (ele.styledValue instanceof StyledUserBridgeValue))\n          .map(ele => (ele.styledValue as StyledUserBridgeValue).object?.deref())\n          .pop();\n        styled?.currentRoot?.bindTextController(this);\n      }\n    } catch (e) {\n      log.e(`setStyledString exception: ${e?.message}`);\n    }\n    super.setStyledString(value);\n  }\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/render/styled/styled-embed.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { StyledObject, IStyledObject, EStyledObject } from './styled-object';\nimport { StyledValue } from './styled-value';\nimport { StyledSpan } from './styled';\nimport { MDLength, IMDArea, newLog, MDArea } from '../../util';\nimport { ITheme } from '../../theme';\n\nconst log = newLog('StyledEmbed');\n\nexport interface IStyledEmbed {\n  initMetrics: CustomSpanMetrics;\n  builderType: EStyledEmbedBuilder;\n  embedController: StyledEmbedController;\n  theme: ITheme;\n}\n@ObservedV2\nexport class StyledEmbed extends StyledObject {\n  readonly type: EStyledObject = EStyledObject.Embed;\n  readonly embedOption: IStyledEmbed;\n  readonly initMetrics: CustomSpanMetrics;\n  likelyKey: string;\n  @Trace position?: Position;\n\n  constructor(option: IStyledObject, embedOption: IStyledEmbed, styles?: StyledValue[]) {\n    const metrics = embedOption.initMetrics;\n    super(\n      option,\n      new StyledSpan({\n        onMeasure: (_span, _measureInfo) => {\n          return metrics;\n        },\n        onDraw: (span, _context, drawInfo) => {\n          const position: Position = {\n            x: MDLength.metrics2length(MDLength.px2vp(drawInfo.x)),\n            y: MDLength.metrics2length(MDLength.px2vp(drawInfo.lineTop - MDLength.vp2px(embedOption.theme.document?.blockSpace?.value ?? 0).value)),\n          };\n          const _area: IMDArea = {\n            width: MDLength.vp(metrics.width),\n            height: metrics.height !== undefined ? MDLength.vp(metrics.height) : undefined,\n          };\n          log.i(`${this.id} init position(${this.position?.x}, ${this.position?.y}) area(${span.metrics.width}, ${span.metrics.height})`);\n          this.position = position;\n          this.area = _area;\n        },\n      }),\n      styles,\n    );\n    this.embedOption = embedOption;\n    this.initMetrics = metrics;\n    this.likelyKey = `${this.embedOption.builderType}_${this.option.styled.node?.id}`;\n  }\n  set area(area: IMDArea | undefined) {\n    this._area = area;\n    if (this.attached) {\n      this.root?.deref()?.replaceStyle({\n        start: this.offset, length: this.length,\n        styledKey: StyledStringKey.CUSTOM_SPAN,\n        styledValue: new StyledSpan({\n          onMeasure: (_span, _measureInfo) => {\n            if (MDArea.isEmpty(this._area)) {\n              return this.embedOption.initMetrics;\n            } else {\n              return MDArea.area2metrics(this._area ?? {});\n            }\n          },\n          onDraw: (span, _context, drawInfo) => {\n            const position: Position = {\n              x: MDLength.metrics2length(MDLength.px2vp(drawInfo.x)),\n              y: MDLength.metrics2length(MDLength.px2vp(drawInfo.lineTop - (MDLength.vp2px(this.embedOption.theme.document?.blockSpace?.value ?? 0).value))),\n            };\n            log.i(`${this.id} update position(${this.position?.x}, ${this.position?.y}) area(${span.metrics.width}, ${span.metrics.height})`);\n            this.position = position;\n          },\n        }),\n      });\n    }\n  }\n  get embedController() {\n    return this.embedOption.embedController;\n  }\n  fork(): StyledEmbed {\n    const embed = new StyledEmbed(this.option, {\n      initMetrics: MDArea.isEmpty(this.area) ? this.initMetrics : MDArea.area2metrics(this.area!),\n      builderType: this.embedOption.builderType,\n      embedController: this.embedController,\n      theme: this.embedOption.theme,\n    }, this.styleValues);\n    return embed;\n  }\n  reuse(embed: StyledEmbed) {\n    const position = embed.position;\n    const area = embed.embedOption.embedController.currentArea();\n    log.i(`${this.id} reuse position(${this.position?.x}, ${this.position?.y}) area(${this.area?.width?.value}, ${this.area?.height?.value}`);\n    this.position = position;\n    this.embedOption.embedController = embed.embedOption.embedController;\n    this.area = area;\n  }\n  componentAreaChange(_oldValue: Area, newValue: Area) {\n    if (!this.attached) {\n      log.w('StyledEmbed not attached');\n      return;\n    }\n    this.area = MDArea.area(newValue);\n  }\n}\nexport enum EStyledEmbedBuilder {\n  Table = 'table',\n  Code = 'code',\n  ImageGallery = 'image-gallery',\n}\nexport class StyledEmbedController {\n  readonly ID: number = StyledEmbedController.getGID();\n  private static gid: number = 0;\n  private static getGID() {\n    return StyledEmbedController.gid++;\n  }\n  updateEmbed: (embed: StyledEmbed) => void = () => {};\n  currentArea: () => IMDArea | undefined = () => undefined;\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/render/styled/styled-object.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { IStyled, StyledSpan } from './styled';\nimport { log, IMDArea, MDLength } from '../../util';\nimport {\n  StyledValue, EStyledValue, StyledParagraphValue,\n  StyledUserBridgeValue,\n} from './styled-value';\nimport Sys from '@ohos.deviceInfo';\n\nlog.tag('StyledObject', true);\n\nexport interface IStyledObject {\n  styled: IStyled;\n  mark?: EStyledObjectMark;\n}\nexport enum EStyledObjectMark {\n  Unknown = 'unknown',\n  BlockBegin = 'block-begin',\n  BlockEnd = 'block-end',\n  BuildBegin = 'build-begin',\n  BuildEnd = 'build-end',\n  Group = 'group',\n  Break = 'break',\n  Root = 'root',\n  Empty = 'empty',\n  Anchor = 'anchor',\n  More = 'more',\n  Text = 'text',\n  Invalid = 'invalid',\n}\ntype EStyledObjectBeginMark = EStyledObjectMark.BlockBegin | EStyledObjectMark.BuildBegin;\ntype EStyledObjectEndMark = EStyledObjectMark.BlockEnd | EStyledObjectMark.BuildEnd;\nexport enum EStyledObject {\n  Normal = 'normal',\n  Embed = 'embed',\n}\ntype StyledObjectContent = string | ImageAttachment | StyledSpan;\nexport class StyledObject extends MutableStyledString {\n  private _id: number = StyledObject._getID();\n  private static _gid: number = 0;\n  private static _getID() {\n    return StyledObject._gid++;\n  }\n  get id() {\n    return this._id;\n  }\n  readonly type: EStyledObject = EStyledObject.Normal;\n  root?: WeakRef<StyledObject>;\n  private owner?: WeakRef<StyledObject>;\n  protected styleValues: StyledValue[] = [];\n  private _offset: number = 0;\n  private _attached: boolean = false;\n  private value: StyledObjectContent;\n  readonly option: IStyledObject;\n  private _controller?: WeakRef<TextController>;\n  private _listener: Record<string, Function[]> = {};\n  protected _area?: IMDArea;\n\n  constructor(option: IStyledObject, value: StyledObjectContent, styles?: StyledValue[]) {\n    super(value);\n    this.value = value;\n    this.option = option;\n    this.styleValues = styles?.filter(ele => !ele.empty) ?? [];\n\n    this.on<IStyledObjectAttachEvent>(EStyledObjectEvent.WillAttachTo, event => {\n      if (event.current.value instanceof CustomSpan) {\n        event.current.owner?.deref()?.attach(StyledObject.anchor());\n      }\n    });\n  }\n  fork(): StyledObject {\n    return new StyledObject(this.option, this.value, this.styleValues);\n  }\n  on<T, V = void>(name: string, callback: Callback<T, V>) {\n    if (!this._listener[name]) {\n      this._listener[name] = [];\n    }\n    this._listener[name].push(callback);\n    return this;\n  }\n  emit<T, V = void>(name: string, event: T): V {\n    let result: V = undefined as V;\n    this._listener[name]?.forEach(ele => {\n      result = (ele as Callback<T, V>)(event);\n    });\n    return result;\n  }\n  set area(area: IMDArea | undefined) {\n    this._area = area;\n  }\n  get area() {\n    return this._area;\n  }\n  get node() {\n    return this.option.styled.node;\n  }\n  get offset() {\n    return this._offset;\n  }\n  private get canAttach() {\n    if (this.option.mark === EStyledObjectMark.Root) {\n      return true;\n    }\n    if (this.root?.deref()) {\n      return true;\n    }\n    return false;\n  }\n  attach(other: StyledObject | StyledString) {\n    const root = this.root ?? new WeakRef(this);\n    if (other instanceof StyledObject) {\n      if (!this.canAttach) {\n        throw Error('current object should be attached first');\n      }\n      other.owner = new WeakRef(this);\n      other.root = root;\n\n      this.emit<IStyledObjectAttachEvent>(EStyledObjectEvent.WillAttach, { current: this, target: other });\n      other.emit<IStyledObjectAttachEvent>(EStyledObjectEvent.WillAttachTo, { current: other, target: this });\n\n      other._offset = this.root?.deref()?.length ?? this.length;\n      root.deref()?.appendStyledString(other);\n\n      other.accept();\n      other._attached = true;\n\n      other.emit<IStyledObjectAttachEvent>(EStyledObjectEvent.DidAttachTo, { current: other, target: this });\n      this.emit<IStyledObjectAttachEvent>(EStyledObjectEvent.DidAttach, { current: this, target: other });\n\n      root.deref()?.emit<IStyledObjectAppendEvent>(EStyledObjectEvent.DidAppend, { target: other });\n    } else {\n      root.deref()?.appendStyledString(other);\n    }\n  }\n  get attached() {\n    return this._attached;\n  }\n  private accept() {\n    const owner = this.owner?.deref();\n    if (!owner) {\n      return;\n    }\n    const styles = owner.styleValues.map(ele => ele.copy());\n    for (const style of this.styleValues) {\n      const exists = styles.filter(ele => ele.type === style.type);\n      if (exists.length > 0) {\n        exists.forEach(ele => ele.cascade(style));\n      } else {\n        styles.push(style);\n      }\n    }\n    this.styleValues = styles;\n\n    if (this.length === 0) {\n      return;\n    }\n    styles.forEach(ele => {\n      this.root?.deref()?.setStyle({\n        start: this._offset, length: this.length,\n        styledKey: ele.key, styledValue: ele.value,\n      });\n    });\n\n    do {\n      const value = new StyledUserBridgeValue(this);\n      this.root?.deref()?.setStyle({\n        start: this._offset, length: this.length,\n        styledKey: value.key, styledValue: value,\n      });\n    } while (0);\n  }\n  cascadedStyle<T = StyledStringValue>(key: StyledStringKey): T | undefined {\n    return this.root?.deref()?.getStyles(this._offset, this.length, key).slice().shift()?.styledValue as T | undefined;\n  }\n  get blockArea(): IMDArea | undefined {\n    const area = this.area ?? this.root?.deref()?.area;\n    if (area) {\n      let leadingMargin: number = 0;\n      this.styleValues.filter(ele => ele.type === EStyledValue.Paragraph).forEach(ele => {\n        const paragraphValue = ele as StyledParagraphValue;\n        const paragraph = paragraphValue.value;\n        if (paragraph.leadingMargin) {\n          if (typeof paragraph.leadingMargin === 'number') {\n            leadingMargin = paragraph.leadingMargin as number;\n          } else {\n            //  FIXME: need LeadingMarginPlaceholder ?\n          }\n        }\n      });\n      if (leadingMargin > 0) {\n        //  NOTE: Length as number\n        return {\n          width: MDLength.vp((area.width?.value as number ?? 0) - leadingMargin),\n          height: area.height,\n        };\n      }\n      return area;\n    }\n    return undefined;\n  }\n  get currentRoot() {\n    return this.root?.deref();\n  }\n  bindTextController(controller: TextController) {\n    this._controller = new WeakRef(controller);\n  }\n  get textController() {\n    return this.root?.deref()?._controller?.deref() ?? this._controller?.deref();\n  }\n  get mark(): EStyledObjectMark {\n    return this.option.mark || EStyledObjectMark.Unknown;\n  }\n  getRectsForRange(range: TextRange, widthStyle: RectWidthStyle, heightStyle: RectHeightStyle): Array<TextBox> {\n    if (Sys.sdkApiVersion >= 14) {\n      const layoutManager = this.textController?.getLayoutManager();\n      if (layoutManager) {\n        return layoutManager.getRectsForRange(range, widthStyle, heightStyle);\n      }\n    }\n    return [];\n  }\n  nearbyParagraph(offset: number): TextRange | undefined {\n    const length = this.length;\n    if (length > 0 && offset < length) {\n      const isBreaker = (str?: StyledString) => {\n        if (str) {\n          return ['\\n', '\\r', '\\t'].indexOf(str.getString()) !== -1;\n        }\n        return true;\n      }\n      const picker = (cursor: number) => {\n        try {\n          return this.subStyledString(cursor, 1);\n        } catch (e) {\n          return undefined;\n        }\n      };\n      let start: number = offset;\n      do {\n        let cursor = offset;\n        do {\n          cursor -= 1;\n        } while (!isBreaker(picker(cursor)));\n        start = cursor + 1;\n      } while (0);\n      let end: number = offset;\n      do {\n        let cursor = offset;\n        do {\n          cursor += 1;\n        } while (!isBreaker(picker(cursor)));\n        end = cursor - 1;\n      } while (0);\n      return { start, end }\n    }\n    return undefined;\n  }\n  subStyledObjects(start: number, length: number): IStyledSubObject[] {\n    try {\n      const bridgeStyles = this.getStyles(start, length, StyledStringKey.USER_DATA).filter(ele => {\n        return ele.styledValue instanceof StyledUserBridgeValue;\n      });\n      return bridgeStyles.map<IStyledSubObject>(ele => {\n        const object = (ele.styledValue as StyledUserBridgeValue).object.deref();\n        if (object && object.type === EStyledObject.Embed) {\n          return {\n            object: object.fork(),\n            real: object,\n          };\n        }\n        const hasHighSurrogateTail = (text: string) => {\n          if (text.length === 0) {\n            return false;\n          }\n          const code = text.charCodeAt(text.length - 1);\n          return code >= 0xD800 && code <= 0xDBFF;\n        }\n        let revise: number = 0\n        const currentString = this.getString();\n        while (hasHighSurrogateTail(currentString.substring(ele.start, ele.start + ele.length + revise))) {\n          revise++;\n        }\n        return {\n          object: this.subStyledString(ele.start, ele.length + revise),\n          real: object,\n        };\n      });\n    } catch (e) {\n      log.w(`subStyledObjects exception. ${e?.message}`);\n      return [];\n    }\n  }\n  replaceStyle(spanStyle: SpanStyle): void {\n    try {\n      super.replaceStyle(spanStyle);\n      this.emit<IStyledObjectReplaceStyleEvent>(\n        EStyledObjectEvent.DidReplaceStyle,\n        { current: this, spanStyle },\n      );\n    } catch (e) {\n      log.w(`replaceStyle exception. ${e?.message}`);\n    }\n  }\n  setStyle(spanStyle: SpanStyle): void {\n    try {\n      super.setStyle(spanStyle);\n    } catch (e) {\n      log.e(`set style exception: ${e?.message}`);\n    }\n  }\n  getStyles(start: number, length: number, styledKey?: StyledStringKey | undefined): SpanStyle[] {\n    try {\n      return super.getStyles(start, length, styledKey);\n    } catch (e) {\n      log.w(`get styles exception. ${e?.message}`);\n      return [];\n    }\n  }\n\n  static begin(option: IStyledObject, styles?: StyledValue[], mark: EStyledObjectBeginMark = EStyledObjectMark.BlockBegin): StyledObject {\n    return new StyledObject({\n      styled: option.styled, mark,\n    }, '', styles);\n  }\n  static end(option: IStyledObject, styles?: StyledValue[], mark: EStyledObjectEndMark = EStyledObjectMark.BlockEnd): StyledObject {\n    return new StyledObject({\n      styled: option.styled, mark,\n    }, '', styles);\n  }\n  static group(option: IStyledObject, styles?: StyledValue[]): StyledObject {\n    return new StyledObject({\n      styled: option.styled,\n      mark: EStyledObjectMark.Group,\n    }, '', styles);\n  }\n  static break(option: IStyledObject, styles?: StyledValue[]): StyledObject {\n    return new StyledObject({\n      styled: option.styled,\n      mark: EStyledObjectMark.Break,\n    }, '\\n', styles);\n  }\n  static root(area?: IMDArea, styles?: StyledValue[]): StyledObject {\n    const object = new StyledObject({\n      styled: { option: {} },\n      mark: EStyledObjectMark.Root,\n    }, '', styles);\n    object.area = area;\n    return object;\n  }\n  static empty(styles?: StyledValue[]) {\n    return new StyledObject({\n      styled: { option: {} },\n      mark: EStyledObjectMark.Empty,\n    }, '\\u200B', styles);\n  }\n  static anchor(styles?: StyledValue[]) {\n    return new StyledObject({\n      styled: { option: {} },\n      mark: EStyledObjectMark.Anchor,\n    }, '\\u200B', styles);\n  }\n  static more(content: string, styles?: StyledValue[]) {\n    return new StyledObject({\n      styled: { option: {} },\n      mark: EStyledObjectMark.More,\n    }, content, styles);\n  }\n  static text(content: string, styles?: StyledValue[]) {\n    return new StyledObject({\n      styled: { option: {} },\n      mark: EStyledObjectMark.Text,\n    }, content, styles);\n  }\n  static invalid(styles?: StyledValue[]) {\n    return new StyledObject({\n      styled: { option: {} },\n      mark: EStyledObjectMark.Invalid,\n    }, '\\u200B', styles);\n  }\n}\nexport enum EStyledObjectEvent {\n  WillAttach = 'will_attach',       //  CURRENT will attach TARGET    => CURRENT will bind TARGET\n  DidAttach = 'did_attach',         //  CURRENT did attach TARGET     => CURRENT did bind TARGET\n  WillAttachTo = 'will_attach_to',  //  CURRENT will attach to TARGET => TARGET will bind CURRENT\n  DidAttachTo = 'did_attach_to',    //  CURRENT did attach to TARGET  => TARGET did bind CURRENT\n\n  DidAppend = 'did_append',         //  CURRENT did append TARGET\n\n  DidReplaceStyle = 'did_replace_style',\n\n  GetArea = 'get_area',\n}\nexport interface IStyledObjectAttachEvent {\n  current: StyledObject;\n  target: StyledObject;\n}\nexport interface IStyledObjectAppendEvent {\n  target: StyledObject;\n}\nexport interface IStyledObjectReplaceStyleEvent {\n  current?: StyledObject;\n  spanStyle?: SpanStyle;\n}\ninterface IStyledSubObject {\n  object: StyledObject | StyledString,\n  real?: StyledObject,\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/render/styled/styled-value.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { LengthMetrics } from \"@kit.ArkUI\";\nimport { MDLength } from '../../util';\nimport type { StyledObject } from './styled-object';\nimport Sys from '@ohos.deviceInfo';\n\nexport enum EStyledValue {\n  Text = 'text',\n  Decoration = 'decoration',\n  BaselineOffset = 'baselineOffset',\n  LetterSpacing = 'letterSpacing',\n  TextShadow = 'textShadow',\n  Gesture = 'gesture',\n  ImageAttachment = 'imageAttachment',\n  Paragraph = 'paragraph',\n  LineHeight = 'lineHeight',\n  CustomSpan = 'customSpan',\n  BackgroundColor = 'backgroundColor',\n\n  UserBridge = 'userBridge',\n}\nexport abstract class StyledValue {\n  abstract readonly type: EStyledValue;\n  abstract readonly key: StyledStringKey;\n  abstract readonly value: StyledStringValue;\n  abstract cascade(value: StyledValue): void;\n  abstract copy(): StyledValue;\n  abstract get empty(): boolean;\n}\nexport interface IStyledTextValue extends TextStyleInterface {}\nexport class StyledTextValue extends StyledValue {\n  readonly type = EStyledValue.Text;\n  readonly key = StyledStringKey.FONT;\n  private _option: IStyledTextValue;\n  constructor(option: IStyledTextValue = {}) {\n    super();\n    this._option = option;\n  }\n  get option() {\n    return this._option;\n  }\n  get value() {\n    return new TextStyle(this._option);\n  }\n  cascade(value: StyledTextValue) {\n    if (!(value instanceof StyledTextValue)) {\n      return;\n    }\n    this._option.fontColor = value._option.fontColor ?? this._option.fontColor;\n    this._option.fontSize = value._option.fontSize ?? this._option.fontSize;\n    this._option.fontWeight = value._option.fontWeight ?? this._option.fontWeight;\n    this._option.fontFamily = value._option.fontFamily ?? this._option.fontFamily;\n    this._option.fontStyle = value._option.fontStyle ?? this._option.fontStyle;\n  }\n  copy(): StyledValue {\n    return new StyledTextValue({\n      fontColor: this._option.fontColor,\n      fontSize: this._option.fontSize,\n      fontWeight: this._option.fontWeight,\n      fontFamily: this._option.fontFamily,\n      fontStyle: this._option.fontStyle,\n    });\n  }\n  get empty() {\n    return Object.keys(this._option).length > 0 ? false : true;\n  }\n}\nexport interface IStyledDecorationValue {\n  type?: TextDecorationType;\n  color?: ResourceColor;\n  style?: TextDecorationStyle;\n}\nexport class StyledDecorationValue extends StyledValue {\n  readonly type = EStyledValue.Decoration;\n  readonly key = StyledStringKey.DECORATION;\n  private _option: IStyledDecorationValue;\n  constructor(option: IStyledDecorationValue = {}) {\n    super();\n    this._option = option;\n  }\n  get option() {\n    return this._option;\n  }\n  get value() {\n    return new DecorationStyle({\n      style: this._option.style,\n      type: this._option.type ?? TextDecorationType.None,\n      color: this._option.color,\n    });\n  }\n  cascade(value: StyledDecorationValue) {\n    if (!(value instanceof StyledDecorationValue)) {\n      return;\n    }\n    this._option.type = value._option.type ?? this._option.type;\n    this._option.color = value._option.color ?? this._option.color;\n    this._option.style = value._option.style ?? this._option.style;\n  }\n  copy(): StyledValue {\n    return new StyledDecorationValue({\n      type: this._option.type,\n      color: this._option.color,\n      style: this._option.style,\n    });\n  }\n  get empty() {\n    return Object.keys(this._option).length > 0 ? false : true;\n  }\n}\nexport interface IStyledBaselineOffsetValue {\n  offset?: LengthMetrics;\n}\nexport class StyledBaselineOffsetValue extends StyledValue {\n  readonly type = EStyledValue.BaselineOffset;\n  readonly key = StyledStringKey.BASELINE_OFFSET;\n  private _option: IStyledBaselineOffsetValue;\n  constructor(option: IStyledBaselineOffsetValue = {}) {\n    super();\n    this._option = option;\n  }\n  get option() {\n    return this._option;\n  }\n  get value() {\n    return new BaselineOffsetStyle(this._option.offset ?? LengthMetrics.vp(0));\n  }\n  cascade(value: StyledBaselineOffsetValue) {\n    if (!(value instanceof StyledBaselineOffsetValue)) {\n      return;\n    }\n    this._option.offset = value._option.offset ?? this._option.offset;\n  }\n  copy(): StyledValue {\n    return new StyledBaselineOffsetValue({\n      offset: this._option.offset,\n    });\n  }\n  get empty() {\n    return Object.keys(this._option).length > 0 ? false : true;\n  }\n}\nexport interface IStyledLetterSpacingValue {\n  spacing?: LengthMetrics;\n}\nexport class StyledLetterSpacingValue extends StyledValue {\n  readonly type = EStyledValue.LetterSpacing;\n  readonly key = StyledStringKey.LETTER_SPACING;\n  private _option: IStyledLetterSpacingValue;\n  constructor(option: IStyledLetterSpacingValue = {}) {\n    super();\n    this._option = option;\n  }\n  get option() {\n    return this._option;\n  }\n  get value() {\n    return new LetterSpacingStyle(this._option.spacing ?? LengthMetrics.vp(0));\n  }\n  cascade(value: StyledLetterSpacingValue) {\n    if (!(value instanceof StyledLetterSpacingValue)) {\n      return;\n    }\n    this._option.spacing = value._option.spacing ?? this._option.spacing;\n  }\n  copy(): StyledValue {\n    return new StyledLetterSpacingValue({\n      spacing: this._option.spacing,\n    });\n  }\n  get empty() {\n    return Object.keys(this._option).length > 0 ? false : true;\n  }\n}\nexport interface IStyledTextShadowValue {\n  radius?: number | Resource;\n  type?: ShadowType;\n  color?: Color | string | Resource | ColoringStrategy;\n  offsetX?: number | Resource;\n  offsetY?: number | Resource;\n  fill?: boolean;\n}\nexport class StyledTextShadowValue extends StyledValue {\n  readonly type = EStyledValue.TextShadow;\n  readonly key = StyledStringKey.TEXT_SHADOW;\n  private _option: IStyledTextShadowValue;\n  constructor(option: IStyledTextShadowValue = {}) {\n    super();\n    this._option = option;\n  }\n  get option() {\n    return this._option;\n  }\n  get value() {\n    return new TextShadowStyle({\n      radius: this._option.radius ?? 0,\n      type: this._option.type,\n      color: this._option.color,\n      offsetX: this._option.offsetX,\n      offsetY: this._option.offsetY,\n      fill: this._option.fill,\n    });\n  }\n  cascade(value: StyledTextShadowValue) {\n    if (!(value instanceof StyledTextShadowValue)) {\n      return;\n    }\n    this._option.radius = value._option.radius ?? this._option.radius;\n    this._option.type = value._option.type ?? this._option.type;\n    this._option.color = value._option.color ?? this._option.color;\n    this._option.offsetX = value._option.offsetX ?? this._option.offsetX;\n    this._option.offsetY = value._option.offsetY ?? this._option.offsetY;\n    this._option.fill = value._option.fill ?? this._option.fill;\n  }\n  copy(): StyledValue {\n    return new StyledTextShadowValue({\n      radius: this._option.radius,\n      type: this._option.type,\n      color: this._option.color,\n      offsetX: this._option.offsetX,\n      offsetY: this._option.offsetY,\n      fill: this._option.fill,\n    });\n  }\n  get empty() {\n    return Object.keys(this._option).length > 0 ? false : true;\n  }\n}\nexport interface IStyledGestureValue extends GestureStyleInterface {}\nexport class StyledGestureValue extends StyledValue {\n  readonly type = EStyledValue.Gesture;\n  readonly key = StyledStringKey.GESTURE;\n  private _option: IStyledGestureValue;\n  constructor(option: IStyledGestureValue = {}) {\n    super();\n    this._option = option;\n  }\n  get option() {\n    return this._option;\n  }\n  get value() {\n    return new GestureStyle(this._option);\n  }\n  cascade(value: StyledGestureValue) {\n    if (!(value instanceof StyledGestureValue)) {\n      return;\n    }\n    this._option.onClick = value._option.onClick ?? this._option.onClick;\n    this._option.onLongPress = value._option.onLongPress ?? this._option.onLongPress;\n  }\n  copy(): StyledValue {\n    return new StyledGestureValue({\n      onClick: this._option.onClick,\n      onLongPress: this._option.onLongPress,\n    });\n  }\n  get empty() {\n    return Object.keys(this._option).length > 0 ? false : true;\n  }\n}\nexport interface IStyledImageAttachmentValue {\n  value?: PixelMap;\n  size?: SizeOptions;\n  verticalAlign?: ImageSpanAlignment;\n  objectFit?: ImageFit;\n  layoutStyle?: ImageAttachmentLayoutStyle;\n}\nexport class StyledImageAttachmentValue extends StyledValue {\n  readonly type = EStyledValue.ImageAttachment;\n  readonly key = StyledStringKey.IMAGE;\n  private _option: IStyledImageAttachmentValue;\n  constructor(option: IStyledImageAttachmentValue = {}) {\n    super();\n    this._option = option;\n  }\n  get option() {\n    return this._option;\n  }\n  get value() {\n    return new ImageAttachment(this._option.value ? {\n      value: this._option.value,\n      size: this._option.size,\n      verticalAlign: this._option.verticalAlign,\n      objectFit: this._option.objectFit,\n      layoutStyle: this._option.layoutStyle,\n    } : undefined);\n  }\n  cascade(value: StyledImageAttachmentValue) {\n    if (!(value instanceof StyledImageAttachmentValue)) {\n      return;\n    }\n    this._option.value = value._option.value ?? this._option.value;\n    this._option.size = value._option.size ?? this._option.size;\n    this._option.verticalAlign = value._option.verticalAlign ?? this._option.verticalAlign;\n    this._option.objectFit = value._option.objectFit ?? this._option.objectFit;\n    this._option.layoutStyle = value._option.layoutStyle ?? this._option.layoutStyle;\n  }\n  copy(): StyledValue {\n    return new StyledImageAttachmentValue({\n      value: this._option.value,\n      size: this._option.size,\n      verticalAlign: this._option.verticalAlign,\n      objectFit: this._option.objectFit,\n      layoutStyle: this._option.layoutStyle,\n    });\n  }\n  get empty() {\n    return Object.keys(this._option).length > 0 ? false : true;\n  }\n}\nexport interface IStyledParagraphValue extends ParagraphStyleInterface {}\nexport class StyledParagraphValue extends StyledValue {\n  readonly type = EStyledValue.Paragraph;\n  readonly key = StyledStringKey.PARAGRAPH_STYLE;\n  private _option: IStyledParagraphValue;\n  constructor(option: IStyledParagraphValue = {}) {\n    super();\n    this._option = option;\n  }\n  get option() {\n    return this._option;\n  }\n  get value() {\n    return new ParagraphStyle(this._option);\n  }\n  cascade(value: StyledParagraphValue) {\n    if (!(value instanceof StyledParagraphValue)) {\n      return;\n    }\n    this._option.textAlign = value._option.textAlign ?? this._option.textAlign;\n    this._option.textIndent = value._option.textIndent ?? this._option.textIndent;\n    this._option.maxLines = value._option.maxLines ?? this._option.maxLines;\n    this._option.overflow = value._option.overflow ?? this._option.overflow;\n    this._option.wordBreak = value._option.wordBreak ?? this._option.wordBreak;\n    if (value._option.leadingMargin && value._option.leadingMargin instanceof LengthMetrics) {\n      if (this._option.leadingMargin && this._option.leadingMargin instanceof LengthMetrics) {\n        this._option.leadingMargin = MDLength.vp(this._option.leadingMargin.value + value._option.leadingMargin.value);\n      } else {\n        this._option.leadingMargin = value._option.leadingMargin;\n      }\n    }\n  }\n  copy(): StyledValue {\n    return new StyledParagraphValue({\n      textAlign: this._option.textAlign,\n      textIndent: this._option.textIndent,\n      maxLines: this._option.maxLines,\n      overflow: this._option.overflow,\n      wordBreak: this._option.wordBreak,\n      leadingMargin: this._option.leadingMargin,\n    });\n  }\n  get empty() {\n    return Object.keys(this._option).length > 0 ? false : true;\n  }\n}\nexport interface IStyledLineHeightValue {\n  height?: LengthMetrics;\n}\nexport class StyledLineHeightValue extends StyledValue {\n  readonly type = EStyledValue.LineHeight;\n  readonly key = StyledStringKey.LINE_HEIGHT;\n  private _option: IStyledLineHeightValue;\n  constructor(option: IStyledLineHeightValue = {}) {\n    super();\n    this._option = option;\n  }\n  get option() {\n    return this._option;\n  }\n  get value() {\n    return new LineHeightStyle(this._option.height ?? LengthMetrics.vp(0));\n  }\n  cascade(value: StyledLineHeightValue) {\n    if (!(value instanceof StyledLineHeightValue)) {\n      return;\n    }\n    this._option.height = value._option.height ?? this._option.height;\n  }\n  copy(): StyledValue {\n    return new StyledLineHeightValue({\n      height: this._option.height,\n    });\n  }\n  get empty() {\n    return Object.keys(this._option).length > 0 ? false : true;\n  }\n}\nexport interface IStyledCustomSpanValue {\n  span: CustomSpan;\n}\nexport class StyledCustomSpanValue extends StyledValue {\n  readonly type = EStyledValue.CustomSpan;\n  readonly key = StyledStringKey.CUSTOM_SPAN;\n  private _option: IStyledCustomSpanValue;\n  constructor(option: IStyledCustomSpanValue) {\n    super();\n    this._option = option;\n  }\n  get option() {\n    return this._option;\n  }\n  get value() {\n    return this._option.span;\n  }\n  cascade(value: StyledCustomSpanValue) {\n    if (!(value instanceof StyledCustomSpanValue)) {\n      return;\n    }\n    this._option.span = value._option.span ?? this._option.span;\n  }\n  copy(): StyledValue {\n    return new StyledCustomSpanValue({\n      span: this._option.span,\n    });\n  }\n  get empty() {\n    return Object.keys(this._option).length > 0 ? false : true;\n  }\n}\nexport interface IStyledBackgroundRadiuses {\n  topLeft?: LengthMetrics;\n  topRight?: LengthMetrics;\n  bottomLeft?: LengthMetrics;\n  bottomRight?: LengthMetrics;\n}\nexport interface IStyledBackgroundValue {\n  color?: ResourceColor;\n  radius?: LengthMetrics;\n  radiuses?: IStyledBackgroundRadiuses;\n}\nexport class StyledBackgroundColorValue extends StyledValue {\n  readonly type = EStyledValue.BackgroundColor;\n  readonly key = Sys.sdkApiVersion >= 14 ? StyledStringKey.BACKGROUND_COLOR : StyledStringKey.USER_DATA;\n  private _option: IStyledBackgroundValue;\n  constructor(option: IStyledBackgroundValue = {}) {\n    super();\n    this._option = option;\n  }\n  get option() {\n    return this._option;\n  }\n  get value() {\n    if (Sys.sdkApiVersion >= 14) {\n      if (this._option.radius) {\n        return new BackgroundColorStyle({\n          color: this._option.color,\n          radius: this._option.radius?.value,\n        });\n      }\n      if (this._option.radiuses) {\n        return new BackgroundColorStyle({\n          color: this._option.color,\n          radius: {\n            topLeft: this._option.radiuses.topLeft?.value,\n            topRight: this._option.radiuses.topRight?.value,\n            bottomLeft: this._option.radiuses.bottomLeft?.value,\n            bottomRight: this._option.radiuses.bottomRight?.value,\n          },\n        });\n      }\n      return new BackgroundColorStyle({\n        color: this._option.color,\n      });\n    } else {\n      return new StyledInvalidValue();\n    }\n  }\n  cascade(value: StyledBackgroundColorValue) {\n    if (!(value instanceof StyledBackgroundColorValue)) {\n      return;\n    }\n    this._option.color = value._option.color ?? this._option.color;\n    this._option.radius = value._option.radius ?? this._option.radius;\n    this._option.radiuses = value._option.radiuses ?? this._option.radiuses;\n  }\n  copy(): StyledValue {\n    return new StyledBackgroundColorValue({\n      color: this._option.color,\n      radius: this._option.radius,\n      radiuses: this._option.radiuses,\n    });\n  }\n  get empty() {\n    return Object.keys(this._option).length > 0 ? false : true;\n  }\n}\nexport abstract class StyledDataSpan extends UserDataSpan {\n  abstract readonly type: EStyledValue;\n  readonly key: StyledStringKey = StyledStringKey.USER_DATA;\n}\nexport class StyledUserBridgeValue extends StyledDataSpan {\n  readonly type: EStyledValue = EStyledValue.UserBridge;\n  readonly object: WeakRef<StyledObject>;\n  constructor(object: StyledObject) {\n    super();\n    this.object = new WeakRef(object);\n  }\n}\nclass StyledInvalidValue extends UserDataSpan {\n  private message: string = 'invalid-styled-value';\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/render/styled/styled.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport type { Node } from '../../service/ast/node';\nimport type { StyledObject } from './styled-object';\nimport type { ITheme } from '../../theme';\nimport type { Engine } from '../../engine';\nimport Image from '@ohos.multimedia.image';\nimport type { IImageServiceRequest, IMathServiceRequest } from '../../service';\nimport { newLog } from '../../util';\n\nconst log = newLog('Styled');\n\nexport interface IStyled {\n  readonly option: IStyledOption;\n  readonly node?: Node;\n}\nexport interface IStyledOption {\n  node?: Node;\n}\nexport interface IStyledBuild {\n  readonly theme: ITheme;\n  readonly engine: Engine;\n  didCreateStyled: (styled: StyledObject) => void;\n  willBuild?: (anchor: StyledObject) => void;\n  didBuild?: (anchor: StyledObject) => void;\n}\n\nexport interface IStyledSpan<T = StyledSpan> {\n  onMeasure?: (\n    span: T,\n    measureInfo: CustomSpanMeasureInfo\n  ) => CustomSpanMetrics;\n  onDraw?: (\n    span: T,\n    context: DrawContext,\n    drawInfo: CustomSpanDrawInfo\n  ) => void;\n}\nexport class StyledSpan extends CustomSpan {\n  protected option: IStyledSpan;\n  protected _metrics: CustomSpanMetrics = { width: 0, height: 0 };\n  constructor(option: IStyledSpan) {\n    super();\n    this.option = option;\n  }\n  get metrics() {\n    return this._metrics;\n  }\n  onMeasure(measureInfo: CustomSpanMeasureInfo): CustomSpanMetrics {\n    if (this.option.onMeasure) {\n      this._metrics = this.option.onMeasure(this, measureInfo);\n    }\n    return this.metrics;\n  }\n  onDraw(context: DrawContext, drawInfo: CustomSpanDrawInfo): void {\n    if (this.option.onDraw) {\n      this.option.onDraw(this, context, drawInfo);\n    }\n  }\n}\nexport interface IStyledImageSpan<T = StyledImageSpan> extends IStyledSpan<T> {\n  buildOption: IStyledBuild;\n  request: IImageServiceRequest;\n  onImageSourceRequested: (span: T) => void;\n}\nexport class StyledImageSpan extends StyledSpan {\n  imageSource?: Image.ImageSource;\n  constructor(option: IStyledImageSpan) {\n    super(option);\n    const request = option.request;\n    this.imageSource = option.buildOption.engine.image?.cache(request)?.imageSource;\n    if (!this.imageSource) {\n      option.buildOption.engine.image?.post(request).then(resp => {\n        if (resp.imageSource) {\n          this.imageSource = resp.imageSource;\n          option.onImageSourceRequested(this);\n        } else {\n          log.w(`image span response invalid. url: ${request.url}`);\n        }\n      }).catch((e: Error) => {\n        log.w(`image span request error: ${e.message} url: ${request.url}`);\n      });\n    }\n  }\n}\nexport interface IStyledMathSpan extends IStyledSpan<StyledMathSpan> {\n  buildOption: IStyledBuild;\n  request: IMathServiceRequest;\n  onResourceLoaded: (span: StyledMathSpan) => void;\n}\nexport class StyledMathSpan extends StyledSpan {\n  imageSource?: Image.ImageSource;\n  constructor(option: IStyledMathSpan) {\n    super(option);\n    this.imageSource = option.buildOption.engine.math?.cache(option.request);\n    if (!this.imageSource) {\n      option.buildOption.engine.math?.generate(option.request).then(v => {\n        if (v.image) {\n          this.imageSource = v.image;\n          option.onResourceLoaded(this);\n        } else {\n          log.w(`math span generate invalid image source. content: ${option.request.content}, errorMessage: ${v.errorMessage}`);\n        }\n      }).catch((e: Error) => {\n        log.w(`math span generate error: ${e.message} content: ${option.request.content}`);\n      });\n    }\n  }\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/render/typing/controller.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { TypingTimer, ETypingTimerState } from './timer';\nimport type { ContextService } from '../../service';\nimport type { Node } from '../../service/ast';\n\nexport enum ETypingMode {\n  Begin = 'begin',\n  Append = 'append',\n  End = 'end',\n  Update = 'update',\n}\nexport interface ITyping {\n  /**\n   * @note units: ms\n   * @default 100\n   */\n  speed?: number;\n  /**\n   * @default 1\n   */\n  step?: number;\n  rootController?: WeakRef<Typing>;\n  more?: string;\n}\nexport class Typing {\n  private listener: Record<string, ITypingEventCallback[]> = {};\n  readonly typingTimer: TypingTimer = new TypingTimer();\n\n  get speed(): number {\n    return this.ctx()?.typing()?.speed ?? 25;\n  }\n  get step(): number {\n    return this.ctx()?.typing()?.step ?? 1;\n  }\n  get more(): string | undefined {\n    return this.ctx()?.typing()?.more;\n  }\n\n  ctx: () => ContextService | undefined = () => (undefined);\n  should: () => boolean = () => (true);\n  mode: () => ETypingMode = () => (ETypingMode.Begin);\n  update: <T = string | Node>(content: T, mode: ETypingMode, hasMore?: boolean) => void = () => {};\n  completed: () => boolean = () => false;\n  processing: () => boolean = () => {\n    return this.typingTimer.processing;\n  };\n  timerState: () => ETypingTimerState = () => (this.typingTimer.state);\n  pause: () => void = () => {\n    if (this.should()) {\n      this.typingTimer.pause();\n      this.emit<ITypingPauseEvent>(ETypingEvent.Pause, {});\n    }\n  };\n  resume: () => void = () => {\n    if (this.should()) {\n      this.typingTimer.resume();\n      this.emit<ITypingResumeEvent>(ETypingEvent.Resume, {});\n    }\n  };\n  stop: () => void = () => {\n    if (this.should()) {\n      this.typingTimer.stop();\n      this.emit<ITypingStopEvent>(ETypingEvent.Stop, {});\n    }\n  }\n\n  on<T, V = void>(name: string, callback: Callback<T, V>) {\n    if (!this.listener[name]) {\n      this.listener[name] = [];\n    }\n    this.listener[name].push({ type: ETypingEventCallback.On, callback });\n    return this;\n  }\n  once<T, V = void>(name: string, callback: Callback<T, V>) {\n    if (!this.listener[name]) {\n      this.listener[name] = [];\n    }\n    this.listener[name].push({ type: ETypingEventCallback.Once, callback });\n    return this;\n  }\n  emit<T, V = void>(name: string, event: T): V {\n    let result: V = undefined as V;\n    this.listener[name]?.forEach(ele => {\n      result = (ele.callback as Callback<T, V>)(event);\n      if (ele.type === ETypingEventCallback.Once) {\n        this.off(name, (ele.callback as Callback<T, V>));\n      }\n    });\n    return result;\n  }\n  off<T, V = void>(name: string, callback?: Callback<T, V>) {\n    if (callback) {\n      this.listener[name] = this.listener[name].filter(ele => ele.callback !== callback);\n    } else {\n      this.listener[name] = [];\n    }\n    return this;\n  }\n}\nenum ETypingEventCallback {\n  On = 'on',\n  Once = 'once',\n}\ninterface ITypingEventCallback {\n  type: ETypingEventCallback;\n  callback: Function;\n}\nexport enum ETypingEvent {\n  Pause = 'pause',\n  Resume = 'resume',\n  Stop = 'stop',\n  Finish = 'finish',\n}\nexport interface ITypingUpdateData<T = string | Node> {\n  content: T;\n  mode: ETypingMode;\n  hasMore?: boolean;\n}\nexport interface ITypingPauseEvent {}\nexport interface ITypingResumeEvent {}\nexport interface ITypingStopEvent {}\nexport interface ITypingFinishEvent {}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/render/typing/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport * from './controller';\nexport * from './timer';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/render/typing/timer.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { newLog } from '../../util';\n\nconst log = newLog('TypingTimer');\n\nexport class TypingTimer {\n  private static gid: number = 0;\n  private static createGid() {\n    return ++TypingTimer.gid;\n  }\n  readonly ID = TypingTimer.createGid();\n  private timer?: number;\n  private handler?: Callback<void>;\n  private interval?: number;\n  state: ETypingTimerState = ETypingTimerState.Unknown;\n  onDidPause?: Callback<void>;\n  onDidStop?: Callback<void>;\n  onWillResume?: Callback<void>;\n\n  start(handler: Callback<void>, interval: number) {\n    if (this.state === ETypingTimerState.Paused || this.state === ETypingTimerState.Stopped) {\n      log.i(`${this.ID} skip start as state is ${this.state}`);\n      return;\n    }\n    log.i(`${this.ID} invoke start`);\n    if (this.timer !== undefined) {\n      clearInterval(this.timer);\n    }\n    this.handler = handler;\n    this.interval = interval;\n    this.timer = setInterval(handler, interval);\n  }\n  pause() {\n    if (this.state === ETypingTimerState.Stopped) {\n      log.i(`${this.ID} skip pause as state is ${this.state}`);\n      return;\n    }\n    log.i(`${this.ID} invoke pause`);\n    if (this.timer !== undefined) {\n      this.state = ETypingTimerState.Paused;\n      clearInterval(this.timer);\n      this.timer = undefined;\n      this.onDidPause?.();\n    }\n  }\n  resume() {\n    if (this.state === ETypingTimerState.Stopped) {\n      log.i(`${this.ID} skip resume as state is ${this.state}`);\n      return;\n    }\n    if (this.timer !== undefined) {\n      log.i(`${this.ID} skip resume as timer is not undefined`);\n      return;\n    }\n    log.i(`${this.ID} invoke resume`);\n    this.state = ETypingTimerState.Resumed;\n    this.onWillResume?.();\n    if (this.handler && this.interval !== undefined) {\n      this.timer = setInterval(this.handler, this.interval);\n    }\n  }\n  stop() {\n    log.i(`${this.ID} invoke stop`);\n    this.state = ETypingTimerState.Stopped;\n    if (this.timer !== undefined) {\n      clearInterval(this.timer);\n      this.timer = undefined;\n    }\n    this.handler = undefined;\n    this.interval = undefined;\n    this.onDidStop?.();\n  }\n  reset() {\n    log.i(`${this.ID} invoke reset`);\n    // this.state = ETypingTimerState.Unknown;  //  keep state\n    if (this.timer !== undefined) {\n      clearInterval(this.timer);\n      this.timer = undefined;\n    }\n    this.handler = undefined;\n    this.interval = undefined;\n  }\n  get processing(): boolean {\n    return this.timer !== undefined;\n  }\n}\n\nexport enum ETypingTimerState {\n  Unknown = 0,\n  Paused = 1 << 0,\n  Resumed = 1 << 1,\n  Stopped = 1 << 2,\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport * from './service';\nexport * from './node';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/markdown-it/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/**\n * markdown-it\n * @home   : https://github.com/markdown-it/markdown-it\n * @branch : master\n * @commit : 0fe7ccb4b7f30236fb05f623be6924961d296d3d\n */\nimport markdown, { config } from './src/markdown-it';\n\nexport * from './src/types';\nexport { markdown, config };\nexport * from './plugin';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/markdown-it/plugin/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport plugin_footnote from './markdown-it-footnote';\nimport plugin_emoji from './markdown-it-emoji';\nimport plugin_sub from './markdown-it-sub';\nimport plugin_sup from './markdown-it-sup';\nimport plugin_taskList from './markdown-it-task-lists';\nimport plugin_katex from './vscode-markdown-it-katex';\n\nexport const plugins = [\n  plugin_footnote, plugin_emoji, plugin_sub, plugin_sup, plugin_taskList, plugin_katex\n]\nexport { plugin_footnote, plugin_emoji, plugin_sub, plugin_sup, plugin_taskList, plugin_katex }\n\nexport * from './vscode-markdown-it-katex';\nexport * from './markdown-it-task-lists';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/markdown-it/plugin/markdown-it-emoji/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/**\n * markdown-it-emoji\n * @home   : https://github.com/markdown-it/markdown-it-emoji\n * @branch : master\n * @commit : bdd07260f080e4d3d812928f3eb0b00883e4e71b\n */\n\nimport full from './markdown-it-emoji';\nimport bare from './markdown-it-emoji-bare';\nimport light from './markdown-it-emoji-light';\n\nexport { bare, light };\nexport default full;"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/markdown-it/plugin/markdown-it-emoji/markdown-it-emoji-bare.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n\n/*! markdown-it-emoji 3.0.0 https://github.com/markdown-it/markdown-it-emoji @license MIT */\nfunction emoji_html (tokens, idx /*, options, env */) {\n  return tokens[idx].content\n}\n\n// Emojies & shortcuts replacement logic.\n//\n// Note: In theory, it could be faster to parse :smile: in inline chain and\n// leave only shortcuts here. But, who care...\n//\nfunction create_rule (md, emojies, shortcuts, scanRE, replaceRE) {\n  const arrayReplaceAt = md.utils.arrayReplaceAt;\n  const ucm = md.utils.lib.ucmicro;\n  const has = md.utils.has;\n  const ZPCc = new RegExp([ucm.Z.source, ucm.P.source, ucm.Cc.source].join('|'));\n\n  function splitTextToken (text, level, Token) {\n    let last_pos = 0;\n    const nodes = [];\n\n    text.replace(replaceRE, function (match, offset, src) {\n      let emoji_name;\n      // Validate emoji name\n      if (has(shortcuts, match)) {\n        // replace shortcut with full name\n        emoji_name = shortcuts[match];\n\n        // Don't allow letters before any shortcut (as in no \":/\" in http://)\n        if (offset > 0 && !ZPCc.test(src[offset - 1])) return\n\n        // Don't allow letters after any shortcut\n        if (offset + match.length < src.length && !ZPCc.test(src[offset + match.length])) {\n          return\n        }\n      } else {\n        emoji_name = match.slice(1, -1);\n      }\n\n      // Add new tokens to pending list\n      if (offset > last_pos) {\n        const token = new Token('text', '', 0);\n        token.content = text.slice(last_pos, offset);\n        nodes.push(token);\n      }\n\n      const token = new Token('emoji', '', 0);\n      token.markup = emoji_name;\n      token.content = emojies[emoji_name];\n      nodes.push(token);\n\n      last_pos = offset + match.length;\n    });\n\n    if (last_pos < text.length) {\n      const token = new Token('text', '', 0);\n      token.content = text.slice(last_pos);\n      nodes.push(token);\n    }\n\n    return nodes\n  }\n\n  return function emoji_replace (state) {\n    let token;\n    const blockTokens = state.tokens;\n    let autolinkLevel = 0;\n\n    for (let j = 0, l = blockTokens.length; j < l; j++) {\n      if (blockTokens[j].type !== 'inline') { continue }\n      let tokens = blockTokens[j].children;\n\n      // We scan from the end, to keep position when new tags added.\n      // Use reversed logic in links start/end match\n      for (let i = tokens.length - 1; i >= 0; i--) {\n        token = tokens[i];\n\n        if (token.type === 'link_open' || token.type === 'link_close') {\n          if (token.info === 'auto') { autolinkLevel -= token.nesting; }\n        }\n\n        if (token.type === 'text' && autolinkLevel === 0 && scanRE.test(token.content)) {\n          // replace current node\n          blockTokens[j].children = tokens = arrayReplaceAt(\n            tokens, i, splitTextToken(token.content, token.level, state.Token)\n          );\n        }\n      }\n    }\n  }\n}\n\n// Convert input options to more useable format\n// and compile search regexp\n\nfunction quoteRE (str) {\n  return str.replace(/[.?*+^$[\\]\\\\(){}|-]/g, '\\\\$&')\n}\n\nfunction normalize_opts (options) {\n  let emojies = options.defs;\n\n  // Filter emojies by whitelist, if needed\n  if (options.enabled.length) {\n    emojies = Object.keys(emojies).reduce((acc, key) => {\n      if (options.enabled.indexOf(key) >= 0) acc[key] = emojies[key];\n      return acc\n    }, {});\n  }\n\n  // Flatten shortcuts to simple object: { alias: emoji_name }\n  const shortcuts = Object.keys(options.shortcuts).reduce((acc, key) => {\n    // Skip aliases for filtered emojies, to reduce regexp\n    if (!emojies[key]) return acc\n\n    if (Array.isArray(options.shortcuts[key])) {\n      options.shortcuts[key].forEach(alias => { acc[alias] = key; });\n      return acc\n    }\n\n    acc[options.shortcuts[key]] = key;\n    return acc\n  }, {});\n\n  const keys = Object.keys(emojies);\n  let names;\n\n  // If no definitions are given, return empty regex to avoid replacements with 'undefined'.\n  if (keys.length === 0) {\n    names = '^$';\n  } else {\n    // Compile regexp\n    names = keys\n      .map(name => { return `:${name}:` })\n      .concat(Object.keys(shortcuts))\n      .sort()\n      .reverse()\n      .map(name => { return quoteRE(name) })\n      .join('|');\n  }\n  const scanRE = RegExp(names);\n  const replaceRE = RegExp(names, 'g');\n\n  return {\n    defs: emojies,\n    shortcuts,\n    scanRE,\n    replaceRE\n  }\n}\n\nfunction emoji_plugin (md, options) {\n  const defaults = {\n    defs: {},\n    shortcuts: {},\n    enabled: []\n  };\n\n  const opts = normalize_opts(md.utils.assign({}, defaults, options || {}));\n\n  md.renderer.rules.emoji = emoji_html;\n\n  md.core.ruler.after(\n    'linkify',\n    'emoji',\n    create_rule(md, opts.defs, opts.shortcuts, opts.scanRE, opts.replaceRE)\n  );\n}\n\nexport { emoji_plugin as default };\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/markdown-it/plugin/markdown-it-emoji/markdown-it-emoji-light.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n\n/*! markdown-it-emoji 3.0.0 https://github.com/markdown-it/markdown-it-emoji @license MIT */\n// Generated, don't edit\nvar emojies_defs = {\n  \"grinning\": \"😀\",\n  \"smiley\": \"😃\",\n  \"smile\": \"😄\",\n  \"grin\": \"😁\",\n  \"laughing\": \"😆\",\n  \"satisfied\": \"😆\",\n  \"sweat_smile\": \"😅\",\n  \"joy\": \"😂\",\n  \"wink\": \"😉\",\n  \"blush\": \"😊\",\n  \"innocent\": \"😇\",\n  \"heart_eyes\": \"😍\",\n  \"kissing_heart\": \"😘\",\n  \"kissing\": \"😗\",\n  \"kissing_closed_eyes\": \"😚\",\n  \"kissing_smiling_eyes\": \"😙\",\n  \"yum\": \"😋\",\n  \"stuck_out_tongue\": \"😛\",\n  \"stuck_out_tongue_winking_eye\": \"😜\",\n  \"stuck_out_tongue_closed_eyes\": \"😝\",\n  \"neutral_face\": \"😐\",\n  \"expressionless\": \"😑\",\n  \"no_mouth\": \"😶\",\n  \"smirk\": \"😏\",\n  \"unamused\": \"😒\",\n  \"relieved\": \"😌\",\n  \"pensive\": \"😔\",\n  \"sleepy\": \"😪\",\n  \"sleeping\": \"😴\",\n  \"mask\": \"😷\",\n  \"dizzy_face\": \"😵\",\n  \"sunglasses\": \"😎\",\n  \"confused\": \"😕\",\n  \"worried\": \"😟\",\n  \"open_mouth\": \"😮\",\n  \"hushed\": \"😯\",\n  \"astonished\": \"😲\",\n  \"flushed\": \"😳\",\n  \"frowning\": \"😦\",\n  \"anguished\": \"😧\",\n  \"fearful\": \"😨\",\n  \"cold_sweat\": \"😰\",\n  \"disappointed_relieved\": \"😥\",\n  \"cry\": \"😢\",\n  \"sob\": \"😭\",\n  \"scream\": \"😱\",\n  \"confounded\": \"😖\",\n  \"persevere\": \"😣\",\n  \"disappointed\": \"😞\",\n  \"sweat\": \"😓\",\n  \"weary\": \"😩\",\n  \"tired_face\": \"😫\",\n  \"rage\": \"😡\",\n  \"pout\": \"😡\",\n  \"angry\": \"😠\",\n  \"smiling_imp\": \"😈\",\n  \"smiley_cat\": \"😺\",\n  \"smile_cat\": \"😸\",\n  \"joy_cat\": \"😹\",\n  \"heart_eyes_cat\": \"😻\",\n  \"smirk_cat\": \"😼\",\n  \"kissing_cat\": \"😽\",\n  \"scream_cat\": \"🙀\",\n  \"crying_cat_face\": \"😿\",\n  \"pouting_cat\": \"😾\",\n  \"heart\": \"❤️\",\n  \"hand\": \"✋\",\n  \"raised_hand\": \"✋\",\n  \"v\": \"✌️\",\n  \"point_up\": \"☝️\",\n  \"fist_raised\": \"✊\",\n  \"fist\": \"✊\",\n  \"monkey_face\": \"🐵\",\n  \"cat\": \"🐱\",\n  \"cow\": \"🐮\",\n  \"mouse\": \"🐭\",\n  \"coffee\": \"☕\",\n  \"hotsprings\": \"♨️\",\n  \"anchor\": \"⚓\",\n  \"airplane\": \"✈️\",\n  \"hourglass\": \"⌛\",\n  \"watch\": \"⌚\",\n  \"sunny\": \"☀️\",\n  \"star\": \"⭐\",\n  \"cloud\": \"☁️\",\n  \"umbrella\": \"☔\",\n  \"zap\": \"⚡\",\n  \"snowflake\": \"❄️\",\n  \"sparkles\": \"✨\",\n  \"black_joker\": \"🃏\",\n  \"mahjong\": \"🀄\",\n  \"phone\": \"☎️\",\n  \"telephone\": \"☎️\",\n  \"envelope\": \"✉️\",\n  \"pencil2\": \"✏️\",\n  \"black_nib\": \"✒️\",\n  \"scissors\": \"✂️\",\n  \"wheelchair\": \"♿\",\n  \"warning\": \"⚠️\",\n  \"aries\": \"♈\",\n  \"taurus\": \"♉\",\n  \"gemini\": \"♊\",\n  \"cancer\": \"♋\",\n  \"leo\": \"♌\",\n  \"virgo\": \"♍\",\n  \"libra\": \"♎\",\n  \"scorpius\": \"♏\",\n  \"sagittarius\": \"♐\",\n  \"capricorn\": \"♑\",\n  \"aquarius\": \"♒\",\n  \"pisces\": \"♓\",\n  \"heavy_multiplication_x\": \"✖️\",\n  \"heavy_plus_sign\": \"➕\",\n  \"heavy_minus_sign\": \"➖\",\n  \"heavy_division_sign\": \"➗\",\n  \"bangbang\": \"‼️\",\n  \"interrobang\": \"⁉️\",\n  \"question\": \"❓\",\n  \"grey_question\": \"❔\",\n  \"grey_exclamation\": \"❕\",\n  \"exclamation\": \"❗\",\n  \"heavy_exclamation_mark\": \"❗\",\n  \"wavy_dash\": \"〰️\",\n  \"recycle\": \"♻️\",\n  \"white_check_mark\": \"✅\",\n  \"ballot_box_with_check\": \"☑️\",\n  \"heavy_check_mark\": \"✔️\",\n  \"x\": \"❌\",\n  \"negative_squared_cross_mark\": \"❎\",\n  \"curly_loop\": \"➰\",\n  \"loop\": \"➿\",\n  \"part_alternation_mark\": \"〽️\",\n  \"eight_spoked_asterisk\": \"✳️\",\n  \"eight_pointed_black_star\": \"✴️\",\n  \"sparkle\": \"❇️\",\n  \"copyright\": \"©️\",\n  \"registered\": \"®️\",\n  \"tm\": \"™️\",\n  \"information_source\": \"ℹ️\",\n  \"m\": \"Ⓜ️\",\n  \"black_circle\": \"⚫\",\n  \"white_circle\": \"⚪\",\n  \"black_large_square\": \"⬛\",\n  \"white_large_square\": \"⬜\",\n  \"black_medium_square\": \"◼️\",\n  \"white_medium_square\": \"◻️\",\n  \"black_medium_small_square\": \"◾\",\n  \"white_medium_small_square\": \"◽\",\n  \"black_small_square\": \"▪️\",\n  \"white_small_square\": \"▫️\"\n};\n\n// Emoticons -> Emoji mapping.\n//\n// (!) Some patterns skipped, to avoid collisions\n// without increase matcher complicity. Than can change in future.\n//\n// Places to look for more emoticons info:\n//\n// - http://en.wikipedia.org/wiki/List_of_emoticons#Western\n// - https://github.com/wooorm/emoticon/blob/master/Support.md\n// - http://factoryjoe.com/projects/emoticons/\n//\n\n/* eslint-disable key-spacing */\n\nvar emojies_shortcuts = {\n  angry:            ['>:(', '>:-('],\n  blush:            [':\")', ':-\")'],\n  broken_heart:     ['</3', '<\\\\3'],\n  // :\\ and :-\\ not used because of conflict with markdown escaping\n  confused:         [':/', ':-/'], // twemoji shows question\n  cry:              [\":'(\", \":'-(\", ':,(', ':,-('],\n  frowning:         [':(', ':-('],\n  heart:            ['<3'],\n  imp:              [']:(', ']:-('],\n  innocent:         ['o:)', 'O:)', 'o:-)', 'O:-)', '0:)', '0:-)'],\n  joy:              [\":')\", \":'-)\", ':,)', ':,-)', \":'D\", \":'-D\", ':,D', ':,-D'],\n  kissing:          [':*', ':-*'],\n  laughing:         ['x-)', 'X-)'],\n  neutral_face:     [':|', ':-|'],\n  open_mouth:       [':o', ':-o', ':O', ':-O'],\n  rage:             [':@', ':-@'],\n  smile:            [':D', ':-D'],\n  smiley:           [':)', ':-)'],\n  smiling_imp:      [']:)', ']:-)'],\n  sob:              [\":,'(\", \":,'-(\", ';(', ';-('],\n  stuck_out_tongue: [':P', ':-P'],\n  sunglasses:       ['8-)', 'B-)'],\n  sweat:            [',:(', ',:-('],\n  sweat_smile:      [',:)', ',:-)'],\n  unamused:         [':s', ':-S', ':z', ':-Z', ':$', ':-$'],\n  wink:             [';)', ';-)']\n};\n\nfunction emoji_html (tokens, idx /*, options, env */) {\n  return tokens[idx].content\n}\n\n// Emojies & shortcuts replacement logic.\n//\n// Note: In theory, it could be faster to parse :smile: in inline chain and\n// leave only shortcuts here. But, who care...\n//\nfunction create_rule (md, emojies, shortcuts, scanRE, replaceRE) {\n  const arrayReplaceAt = md.utils.arrayReplaceAt;\n  const ucm = md.utils.lib.ucmicro;\n  const has = md.utils.has;\n  const ZPCc = new RegExp([ucm.Z.source, ucm.P.source, ucm.Cc.source].join('|'));\n\n  function splitTextToken (text, level, Token) {\n    let last_pos = 0;\n    const nodes = [];\n\n    text.replace(replaceRE, function (match, offset, src) {\n      let emoji_name;\n      // Validate emoji name\n      if (has(shortcuts, match)) {\n        // replace shortcut with full name\n        emoji_name = shortcuts[match];\n\n        // Don't allow letters before any shortcut (as in no \":/\" in http://)\n        if (offset > 0 && !ZPCc.test(src[offset - 1])) return\n\n        // Don't allow letters after any shortcut\n        if (offset + match.length < src.length && !ZPCc.test(src[offset + match.length])) {\n          return\n        }\n      } else {\n        emoji_name = match.slice(1, -1);\n      }\n\n      // Add new tokens to pending list\n      if (offset > last_pos) {\n        const token = new Token('text', '', 0);\n        token.content = text.slice(last_pos, offset);\n        nodes.push(token);\n      }\n\n      const token = new Token('emoji', '', 0);\n      token.markup = emoji_name;\n      token.content = emojies[emoji_name];\n      nodes.push(token);\n\n      last_pos = offset + match.length;\n    });\n\n    if (last_pos < text.length) {\n      const token = new Token('text', '', 0);\n      token.content = text.slice(last_pos);\n      nodes.push(token);\n    }\n\n    return nodes\n  }\n\n  return function emoji_replace (state) {\n    let token;\n    const blockTokens = state.tokens;\n    let autolinkLevel = 0;\n\n    for (let j = 0, l = blockTokens.length; j < l; j++) {\n      if (blockTokens[j].type !== 'inline') { continue }\n      let tokens = blockTokens[j].children;\n\n      // We scan from the end, to keep position when new tags added.\n      // Use reversed logic in links start/end match\n      for (let i = tokens.length - 1; i >= 0; i--) {\n        token = tokens[i];\n\n        if (token.type === 'link_open' || token.type === 'link_close') {\n          if (token.info === 'auto') { autolinkLevel -= token.nesting; }\n        }\n\n        if (token.type === 'text' && autolinkLevel === 0 && scanRE.test(token.content)) {\n          // replace current node\n          blockTokens[j].children = tokens = arrayReplaceAt(\n            tokens, i, splitTextToken(token.content, token.level, state.Token)\n          );\n        }\n      }\n    }\n  }\n}\n\n// Convert input options to more useable format\n// and compile search regexp\n\nfunction quoteRE (str) {\n  return str.replace(/[.?*+^$[\\]\\\\(){}|-]/g, '\\\\$&')\n}\n\nfunction normalize_opts (options) {\n  let emojies = options.defs;\n\n  // Filter emojies by whitelist, if needed\n  if (options.enabled.length) {\n    emojies = Object.keys(emojies).reduce((acc, key) => {\n      if (options.enabled.indexOf(key) >= 0) acc[key] = emojies[key];\n      return acc\n    }, {});\n  }\n\n  // Flatten shortcuts to simple object: { alias: emoji_name }\n  const shortcuts = Object.keys(options.shortcuts).reduce((acc, key) => {\n    // Skip aliases for filtered emojies, to reduce regexp\n    if (!emojies[key]) return acc\n\n    if (Array.isArray(options.shortcuts[key])) {\n      options.shortcuts[key].forEach(alias => { acc[alias] = key; });\n      return acc\n    }\n\n    acc[options.shortcuts[key]] = key;\n    return acc\n  }, {});\n\n  const keys = Object.keys(emojies);\n  let names;\n\n  // If no definitions are given, return empty regex to avoid replacements with 'undefined'.\n  if (keys.length === 0) {\n    names = '^$';\n  } else {\n    // Compile regexp\n    names = keys\n      .map(name => { return `:${name}:` })\n      .concat(Object.keys(shortcuts))\n      .sort()\n      .reverse()\n      .map(name => { return quoteRE(name) })\n      .join('|');\n  }\n  const scanRE = RegExp(names);\n  const replaceRE = RegExp(names, 'g');\n\n  return {\n    defs: emojies,\n    shortcuts,\n    scanRE,\n    replaceRE\n  }\n}\n\nfunction emoji_plugin$1 (md, options) {\n  const defaults = {\n    defs: {},\n    shortcuts: {},\n    enabled: []\n  };\n\n  const opts = normalize_opts(md.utils.assign({}, defaults, options || {}));\n\n  md.renderer.rules.emoji = emoji_html;\n\n  md.core.ruler.after(\n    'linkify',\n    'emoji',\n    create_rule(md, opts.defs, opts.shortcuts, opts.scanRE, opts.replaceRE)\n  );\n}\n\nfunction emoji_plugin (md, options) {\n  const defaults = {\n    defs: emojies_defs,\n    shortcuts: emojies_shortcuts,\n    enabled: []\n  };\n\n  const opts = md.utils.assign({}, defaults, options || {});\n\n  emoji_plugin$1(md, opts);\n}\n\nexport { emoji_plugin as default };\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/markdown-it/plugin/markdown-it-emoji/markdown-it-emoji.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n\n/*! markdown-it-emoji 3.0.0 https://github.com/markdown-it/markdown-it-emoji @license MIT */\n// Generated, don't edit\nvar emojies_defs = {\n  \"100\": \"💯\",\n  \"911\": \"🚨\",\n  \"1234\": \"🔢\",\n  \"grinning\": \"😀\",\n  \"smiley\": \"😃\",\n  \"smile\": \"😄\",\n  \"grin\": \"😁\",\n  \"laughing\": \"😆\",\n  \"satisfied\": \"😆\",\n  \"sweat_smile\": \"😅\",\n  \"rofl\": \"🤣\",\n  \"joy\": \"😂\",\n  \"slightly_smiling_face\": \"🙂\",\n  \"upside_down_face\": \"🙃\",\n  \"melting_face\": \"🫠\",\n  \"wink\": \"😉\",\n  \"blush\": \"😊\",\n  \"innocent\": \"😇\",\n  \"smiling_face_with_three_hearts\": \"🥰\",\n  \"heart_eyes\": \"😍\",\n  \"star_struck\": \"🤩\",\n  \"kissing_heart\": \"😘\",\n  \"kissing\": \"😗\",\n  \"relaxed\": \"☺️\",\n  \"kissing_closed_eyes\": \"😚\",\n  \"kissing_smiling_eyes\": \"😙\",\n  \"smiling_face_with_tear\": \"🥲\",\n  \"yum\": \"😋\",\n  \"stuck_out_tongue\": \"😛\",\n  \"stuck_out_tongue_winking_eye\": \"😜\",\n  \"zany_face\": \"🤪\",\n  \"stuck_out_tongue_closed_eyes\": \"😝\",\n  \"money_mouth_face\": \"🤑\",\n  \"hugs\": \"🤗\",\n  \"hand_over_mouth\": \"🤭\",\n  \"face_with_open_eyes_and_hand_over_mouth\": \"🫢\",\n  \"face_with_peeking_eye\": \"🫣\",\n  \"shushing_face\": \"🤫\",\n  \"thinking\": \"🤔\",\n  \"saluting_face\": \"🫡\",\n  \"zipper_mouth_face\": \"🤐\",\n  \"raised_eyebrow\": \"🤨\",\n  \"neutral_face\": \"😐\",\n  \"expressionless\": \"😑\",\n  \"no_mouth\": \"😶\",\n  \"dotted_line_face\": \"🫥\",\n  \"face_in_clouds\": \"😶‍🌫️\",\n  \"smirk\": \"😏\",\n  \"unamused\": \"😒\",\n  \"roll_eyes\": \"🙄\",\n  \"grimacing\": \"😬\",\n  \"face_exhaling\": \"😮‍💨\",\n  \"lying_face\": \"🤥\",\n  \"shaking_face\": \"🫨\",\n  \"relieved\": \"😌\",\n  \"pensive\": \"😔\",\n  \"sleepy\": \"😪\",\n  \"drooling_face\": \"🤤\",\n  \"sleeping\": \"😴\",\n  \"mask\": \"😷\",\n  \"face_with_thermometer\": \"🤒\",\n  \"face_with_head_bandage\": \"🤕\",\n  \"nauseated_face\": \"🤢\",\n  \"vomiting_face\": \"🤮\",\n  \"sneezing_face\": \"🤧\",\n  \"hot_face\": \"🥵\",\n  \"cold_face\": \"🥶\",\n  \"woozy_face\": \"🥴\",\n  \"dizzy_face\": \"😵\",\n  \"face_with_spiral_eyes\": \"😵‍💫\",\n  \"exploding_head\": \"🤯\",\n  \"cowboy_hat_face\": \"🤠\",\n  \"partying_face\": \"🥳\",\n  \"disguised_face\": \"🥸\",\n  \"sunglasses\": \"😎\",\n  \"nerd_face\": \"🤓\",\n  \"monocle_face\": \"🧐\",\n  \"confused\": \"😕\",\n  \"face_with_diagonal_mouth\": \"🫤\",\n  \"worried\": \"😟\",\n  \"slightly_frowning_face\": \"🙁\",\n  \"frowning_face\": \"☹️\",\n  \"open_mouth\": \"😮\",\n  \"hushed\": \"😯\",\n  \"astonished\": \"😲\",\n  \"flushed\": \"😳\",\n  \"pleading_face\": \"🥺\",\n  \"face_holding_back_tears\": \"🥹\",\n  \"frowning\": \"😦\",\n  \"anguished\": \"😧\",\n  \"fearful\": \"😨\",\n  \"cold_sweat\": \"😰\",\n  \"disappointed_relieved\": \"😥\",\n  \"cry\": \"😢\",\n  \"sob\": \"😭\",\n  \"scream\": \"😱\",\n  \"confounded\": \"😖\",\n  \"persevere\": \"😣\",\n  \"disappointed\": \"😞\",\n  \"sweat\": \"😓\",\n  \"weary\": \"😩\",\n  \"tired_face\": \"😫\",\n  \"yawning_face\": \"🥱\",\n  \"triumph\": \"😤\",\n  \"rage\": \"😡\",\n  \"pout\": \"😡\",\n  \"angry\": \"😠\",\n  \"cursing_face\": \"🤬\",\n  \"smiling_imp\": \"😈\",\n  \"imp\": \"👿\",\n  \"skull\": \"💀\",\n  \"skull_and_crossbones\": \"☠️\",\n  \"hankey\": \"💩\",\n  \"poop\": \"💩\",\n  \"shit\": \"💩\",\n  \"clown_face\": \"🤡\",\n  \"japanese_ogre\": \"👹\",\n  \"japanese_goblin\": \"👺\",\n  \"ghost\": \"👻\",\n  \"alien\": \"👽\",\n  \"space_invader\": \"👾\",\n  \"robot\": \"🤖\",\n  \"smiley_cat\": \"😺\",\n  \"smile_cat\": \"😸\",\n  \"joy_cat\": \"😹\",\n  \"heart_eyes_cat\": \"😻\",\n  \"smirk_cat\": \"😼\",\n  \"kissing_cat\": \"😽\",\n  \"scream_cat\": \"🙀\",\n  \"crying_cat_face\": \"😿\",\n  \"pouting_cat\": \"😾\",\n  \"see_no_evil\": \"🙈\",\n  \"hear_no_evil\": \"🙉\",\n  \"speak_no_evil\": \"🙊\",\n  \"love_letter\": \"💌\",\n  \"cupid\": \"💘\",\n  \"gift_heart\": \"💝\",\n  \"sparkling_heart\": \"💖\",\n  \"heartpulse\": \"💗\",\n  \"heartbeat\": \"💓\",\n  \"revolving_hearts\": \"💞\",\n  \"two_hearts\": \"💕\",\n  \"heart_decoration\": \"💟\",\n  \"heavy_heart_exclamation\": \"❣️\",\n  \"broken_heart\": \"💔\",\n  \"heart_on_fire\": \"❤️‍🔥\",\n  \"mending_heart\": \"❤️‍🩹\",\n  \"heart\": \"❤️\",\n  \"pink_heart\": \"🩷\",\n  \"orange_heart\": \"🧡\",\n  \"yellow_heart\": \"💛\",\n  \"green_heart\": \"💚\",\n  \"blue_heart\": \"💙\",\n  \"light_blue_heart\": \"🩵\",\n  \"purple_heart\": \"💜\",\n  \"brown_heart\": \"🤎\",\n  \"black_heart\": \"🖤\",\n  \"grey_heart\": \"🩶\",\n  \"white_heart\": \"🤍\",\n  \"kiss\": \"💋\",\n  \"anger\": \"💢\",\n  \"boom\": \"💥\",\n  \"collision\": \"💥\",\n  \"dizzy\": \"💫\",\n  \"sweat_drops\": \"💦\",\n  \"dash\": \"💨\",\n  \"hole\": \"🕳️\",\n  \"speech_balloon\": \"💬\",\n  \"eye_speech_bubble\": \"👁️‍🗨️\",\n  \"left_speech_bubble\": \"🗨️\",\n  \"right_anger_bubble\": \"🗯️\",\n  \"thought_balloon\": \"💭\",\n  \"zzz\": \"💤\",\n  \"wave\": \"👋\",\n  \"raised_back_of_hand\": \"🤚\",\n  \"raised_hand_with_fingers_splayed\": \"🖐️\",\n  \"hand\": \"✋\",\n  \"raised_hand\": \"✋\",\n  \"vulcan_salute\": \"🖖\",\n  \"rightwards_hand\": \"🫱\",\n  \"leftwards_hand\": \"🫲\",\n  \"palm_down_hand\": \"🫳\",\n  \"palm_up_hand\": \"🫴\",\n  \"leftwards_pushing_hand\": \"🫷\",\n  \"rightwards_pushing_hand\": \"🫸\",\n  \"ok_hand\": \"👌\",\n  \"pinched_fingers\": \"🤌\",\n  \"pinching_hand\": \"🤏\",\n  \"v\": \"✌️\",\n  \"crossed_fingers\": \"🤞\",\n  \"hand_with_index_finger_and_thumb_crossed\": \"🫰\",\n  \"love_you_gesture\": \"🤟\",\n  \"metal\": \"🤘\",\n  \"call_me_hand\": \"🤙\",\n  \"point_left\": \"👈\",\n  \"point_right\": \"👉\",\n  \"point_up_2\": \"👆\",\n  \"middle_finger\": \"🖕\",\n  \"fu\": \"🖕\",\n  \"point_down\": \"👇\",\n  \"point_up\": \"☝️\",\n  \"index_pointing_at_the_viewer\": \"🫵\",\n  \"+1\": \"👍\",\n  \"thumbsup\": \"👍\",\n  \"-1\": \"👎\",\n  \"thumbsdown\": \"👎\",\n  \"fist_raised\": \"✊\",\n  \"fist\": \"✊\",\n  \"fist_oncoming\": \"👊\",\n  \"facepunch\": \"👊\",\n  \"punch\": \"👊\",\n  \"fist_left\": \"🤛\",\n  \"fist_right\": \"🤜\",\n  \"clap\": \"👏\",\n  \"raised_hands\": \"🙌\",\n  \"heart_hands\": \"🫶\",\n  \"open_hands\": \"👐\",\n  \"palms_up_together\": \"🤲\",\n  \"handshake\": \"🤝\",\n  \"pray\": \"🙏\",\n  \"writing_hand\": \"✍️\",\n  \"nail_care\": \"💅\",\n  \"selfie\": \"🤳\",\n  \"muscle\": \"💪\",\n  \"mechanical_arm\": \"🦾\",\n  \"mechanical_leg\": \"🦿\",\n  \"leg\": \"🦵\",\n  \"foot\": \"🦶\",\n  \"ear\": \"👂\",\n  \"ear_with_hearing_aid\": \"🦻\",\n  \"nose\": \"👃\",\n  \"brain\": \"🧠\",\n  \"anatomical_heart\": \"🫀\",\n  \"lungs\": \"🫁\",\n  \"tooth\": \"🦷\",\n  \"bone\": \"🦴\",\n  \"eyes\": \"👀\",\n  \"eye\": \"👁️\",\n  \"tongue\": \"👅\",\n  \"lips\": \"👄\",\n  \"biting_lip\": \"🫦\",\n  \"baby\": \"👶\",\n  \"child\": \"🧒\",\n  \"boy\": \"👦\",\n  \"girl\": \"👧\",\n  \"adult\": \"🧑\",\n  \"blond_haired_person\": \"👱\",\n  \"man\": \"👨\",\n  \"bearded_person\": \"🧔\",\n  \"man_beard\": \"🧔‍♂️\",\n  \"woman_beard\": \"🧔‍♀️\",\n  \"red_haired_man\": \"👨‍🦰\",\n  \"curly_haired_man\": \"👨‍🦱\",\n  \"white_haired_man\": \"👨‍🦳\",\n  \"bald_man\": \"👨‍🦲\",\n  \"woman\": \"👩\",\n  \"red_haired_woman\": \"👩‍🦰\",\n  \"person_red_hair\": \"🧑‍🦰\",\n  \"curly_haired_woman\": \"👩‍🦱\",\n  \"person_curly_hair\": \"🧑‍🦱\",\n  \"white_haired_woman\": \"👩‍🦳\",\n  \"person_white_hair\": \"🧑‍🦳\",\n  \"bald_woman\": \"👩‍🦲\",\n  \"person_bald\": \"🧑‍🦲\",\n  \"blond_haired_woman\": \"👱‍♀️\",\n  \"blonde_woman\": \"👱‍♀️\",\n  \"blond_haired_man\": \"👱‍♂️\",\n  \"older_adult\": \"🧓\",\n  \"older_man\": \"👴\",\n  \"older_woman\": \"👵\",\n  \"frowning_person\": \"🙍\",\n  \"frowning_man\": \"🙍‍♂️\",\n  \"frowning_woman\": \"🙍‍♀️\",\n  \"pouting_face\": \"🙎\",\n  \"pouting_man\": \"🙎‍♂️\",\n  \"pouting_woman\": \"🙎‍♀️\",\n  \"no_good\": \"🙅\",\n  \"no_good_man\": \"🙅‍♂️\",\n  \"ng_man\": \"🙅‍♂️\",\n  \"no_good_woman\": \"🙅‍♀️\",\n  \"ng_woman\": \"🙅‍♀️\",\n  \"ok_person\": \"🙆\",\n  \"ok_man\": \"🙆‍♂️\",\n  \"ok_woman\": \"🙆‍♀️\",\n  \"tipping_hand_person\": \"💁\",\n  \"information_desk_person\": \"💁\",\n  \"tipping_hand_man\": \"💁‍♂️\",\n  \"sassy_man\": \"💁‍♂️\",\n  \"tipping_hand_woman\": \"💁‍♀️\",\n  \"sassy_woman\": \"💁‍♀️\",\n  \"raising_hand\": \"🙋\",\n  \"raising_hand_man\": \"🙋‍♂️\",\n  \"raising_hand_woman\": \"🙋‍♀️\",\n  \"deaf_person\": \"🧏\",\n  \"deaf_man\": \"🧏‍♂️\",\n  \"deaf_woman\": \"🧏‍♀️\",\n  \"bow\": \"🙇\",\n  \"bowing_man\": \"🙇‍♂️\",\n  \"bowing_woman\": \"🙇‍♀️\",\n  \"facepalm\": \"🤦\",\n  \"man_facepalming\": \"🤦‍♂️\",\n  \"woman_facepalming\": \"🤦‍♀️\",\n  \"shrug\": \"🤷\",\n  \"man_shrugging\": \"🤷‍♂️\",\n  \"woman_shrugging\": \"🤷‍♀️\",\n  \"health_worker\": \"🧑‍⚕️\",\n  \"man_health_worker\": \"👨‍⚕️\",\n  \"woman_health_worker\": \"👩‍⚕️\",\n  \"student\": \"🧑‍🎓\",\n  \"man_student\": \"👨‍🎓\",\n  \"woman_student\": \"👩‍🎓\",\n  \"teacher\": \"🧑‍🏫\",\n  \"man_teacher\": \"👨‍🏫\",\n  \"woman_teacher\": \"👩‍🏫\",\n  \"judge\": \"🧑‍⚖️\",\n  \"man_judge\": \"👨‍⚖️\",\n  \"woman_judge\": \"👩‍⚖️\",\n  \"farmer\": \"🧑‍🌾\",\n  \"man_farmer\": \"👨‍🌾\",\n  \"woman_farmer\": \"👩‍🌾\",\n  \"cook\": \"🧑‍🍳\",\n  \"man_cook\": \"👨‍🍳\",\n  \"woman_cook\": \"👩‍🍳\",\n  \"mechanic\": \"🧑‍🔧\",\n  \"man_mechanic\": \"👨‍🔧\",\n  \"woman_mechanic\": \"👩‍🔧\",\n  \"factory_worker\": \"🧑‍🏭\",\n  \"man_factory_worker\": \"👨‍🏭\",\n  \"woman_factory_worker\": \"👩‍🏭\",\n  \"office_worker\": \"🧑‍💼\",\n  \"man_office_worker\": \"👨‍💼\",\n  \"woman_office_worker\": \"👩‍💼\",\n  \"scientist\": \"🧑‍🔬\",\n  \"man_scientist\": \"👨‍🔬\",\n  \"woman_scientist\": \"👩‍🔬\",\n  \"technologist\": \"🧑‍💻\",\n  \"man_technologist\": \"👨‍💻\",\n  \"woman_technologist\": \"👩‍💻\",\n  \"singer\": \"🧑‍🎤\",\n  \"man_singer\": \"👨‍🎤\",\n  \"woman_singer\": \"👩‍🎤\",\n  \"artist\": \"🧑‍🎨\",\n  \"man_artist\": \"👨‍🎨\",\n  \"woman_artist\": \"👩‍🎨\",\n  \"pilot\": \"🧑‍✈️\",\n  \"man_pilot\": \"👨‍✈️\",\n  \"woman_pilot\": \"👩‍✈️\",\n  \"astronaut\": \"🧑‍🚀\",\n  \"man_astronaut\": \"👨‍🚀\",\n  \"woman_astronaut\": \"👩‍🚀\",\n  \"firefighter\": \"🧑‍🚒\",\n  \"man_firefighter\": \"👨‍🚒\",\n  \"woman_firefighter\": \"👩‍🚒\",\n  \"police_officer\": \"👮\",\n  \"cop\": \"👮\",\n  \"policeman\": \"👮‍♂️\",\n  \"policewoman\": \"👮‍♀️\",\n  \"detective\": \"🕵️\",\n  \"male_detective\": \"🕵️‍♂️\",\n  \"female_detective\": \"🕵️‍♀️\",\n  \"guard\": \"💂\",\n  \"guardsman\": \"💂‍♂️\",\n  \"guardswoman\": \"💂‍♀️\",\n  \"ninja\": \"🥷\",\n  \"construction_worker\": \"👷\",\n  \"construction_worker_man\": \"👷‍♂️\",\n  \"construction_worker_woman\": \"👷‍♀️\",\n  \"person_with_crown\": \"🫅\",\n  \"prince\": \"🤴\",\n  \"princess\": \"👸\",\n  \"person_with_turban\": \"👳\",\n  \"man_with_turban\": \"👳‍♂️\",\n  \"woman_with_turban\": \"👳‍♀️\",\n  \"man_with_gua_pi_mao\": \"👲\",\n  \"woman_with_headscarf\": \"🧕\",\n  \"person_in_tuxedo\": \"🤵\",\n  \"man_in_tuxedo\": \"🤵‍♂️\",\n  \"woman_in_tuxedo\": \"🤵‍♀️\",\n  \"person_with_veil\": \"👰\",\n  \"man_with_veil\": \"👰‍♂️\",\n  \"woman_with_veil\": \"👰‍♀️\",\n  \"bride_with_veil\": \"👰‍♀️\",\n  \"pregnant_woman\": \"🤰\",\n  \"pregnant_man\": \"🫃\",\n  \"pregnant_person\": \"🫄\",\n  \"breast_feeding\": \"🤱\",\n  \"woman_feeding_baby\": \"👩‍🍼\",\n  \"man_feeding_baby\": \"👨‍🍼\",\n  \"person_feeding_baby\": \"🧑‍🍼\",\n  \"angel\": \"👼\",\n  \"santa\": \"🎅\",\n  \"mrs_claus\": \"🤶\",\n  \"mx_claus\": \"🧑‍🎄\",\n  \"superhero\": \"🦸\",\n  \"superhero_man\": \"🦸‍♂️\",\n  \"superhero_woman\": \"🦸‍♀️\",\n  \"supervillain\": \"🦹\",\n  \"supervillain_man\": \"🦹‍♂️\",\n  \"supervillain_woman\": \"🦹‍♀️\",\n  \"mage\": \"🧙\",\n  \"mage_man\": \"🧙‍♂️\",\n  \"mage_woman\": \"🧙‍♀️\",\n  \"fairy\": \"🧚\",\n  \"fairy_man\": \"🧚‍♂️\",\n  \"fairy_woman\": \"🧚‍♀️\",\n  \"vampire\": \"🧛\",\n  \"vampire_man\": \"🧛‍♂️\",\n  \"vampire_woman\": \"🧛‍♀️\",\n  \"merperson\": \"🧜\",\n  \"merman\": \"🧜‍♂️\",\n  \"mermaid\": \"🧜‍♀️\",\n  \"elf\": \"🧝\",\n  \"elf_man\": \"🧝‍♂️\",\n  \"elf_woman\": \"🧝‍♀️\",\n  \"genie\": \"🧞\",\n  \"genie_man\": \"🧞‍♂️\",\n  \"genie_woman\": \"🧞‍♀️\",\n  \"zombie\": \"🧟\",\n  \"zombie_man\": \"🧟‍♂️\",\n  \"zombie_woman\": \"🧟‍♀️\",\n  \"troll\": \"🧌\",\n  \"massage\": \"💆\",\n  \"massage_man\": \"💆‍♂️\",\n  \"massage_woman\": \"💆‍♀️\",\n  \"haircut\": \"💇\",\n  \"haircut_man\": \"💇‍♂️\",\n  \"haircut_woman\": \"💇‍♀️\",\n  \"walking\": \"🚶\",\n  \"walking_man\": \"🚶‍♂️\",\n  \"walking_woman\": \"🚶‍♀️\",\n  \"standing_person\": \"🧍\",\n  \"standing_man\": \"🧍‍♂️\",\n  \"standing_woman\": \"🧍‍♀️\",\n  \"kneeling_person\": \"🧎\",\n  \"kneeling_man\": \"🧎‍♂️\",\n  \"kneeling_woman\": \"🧎‍♀️\",\n  \"person_with_probing_cane\": \"🧑‍🦯\",\n  \"man_with_probing_cane\": \"👨‍🦯\",\n  \"woman_with_probing_cane\": \"👩‍🦯\",\n  \"person_in_motorized_wheelchair\": \"🧑‍🦼\",\n  \"man_in_motorized_wheelchair\": \"👨‍🦼\",\n  \"woman_in_motorized_wheelchair\": \"👩‍🦼\",\n  \"person_in_manual_wheelchair\": \"🧑‍🦽\",\n  \"man_in_manual_wheelchair\": \"👨‍🦽\",\n  \"woman_in_manual_wheelchair\": \"👩‍🦽\",\n  \"runner\": \"🏃\",\n  \"running\": \"🏃\",\n  \"running_man\": \"🏃‍♂️\",\n  \"running_woman\": \"🏃‍♀️\",\n  \"woman_dancing\": \"💃\",\n  \"dancer\": \"💃\",\n  \"man_dancing\": \"🕺\",\n  \"business_suit_levitating\": \"🕴️\",\n  \"dancers\": \"👯\",\n  \"dancing_men\": \"👯‍♂️\",\n  \"dancing_women\": \"👯‍♀️\",\n  \"sauna_person\": \"🧖\",\n  \"sauna_man\": \"🧖‍♂️\",\n  \"sauna_woman\": \"🧖‍♀️\",\n  \"climbing\": \"🧗\",\n  \"climbing_man\": \"🧗‍♂️\",\n  \"climbing_woman\": \"🧗‍♀️\",\n  \"person_fencing\": \"🤺\",\n  \"horse_racing\": \"🏇\",\n  \"skier\": \"⛷️\",\n  \"snowboarder\": \"🏂\",\n  \"golfing\": \"🏌️\",\n  \"golfing_man\": \"🏌️‍♂️\",\n  \"golfing_woman\": \"🏌️‍♀️\",\n  \"surfer\": \"🏄\",\n  \"surfing_man\": \"🏄‍♂️\",\n  \"surfing_woman\": \"🏄‍♀️\",\n  \"rowboat\": \"🚣\",\n  \"rowing_man\": \"🚣‍♂️\",\n  \"rowing_woman\": \"🚣‍♀️\",\n  \"swimmer\": \"🏊\",\n  \"swimming_man\": \"🏊‍♂️\",\n  \"swimming_woman\": \"🏊‍♀️\",\n  \"bouncing_ball_person\": \"⛹️\",\n  \"bouncing_ball_man\": \"⛹️‍♂️\",\n  \"basketball_man\": \"⛹️‍♂️\",\n  \"bouncing_ball_woman\": \"⛹️‍♀️\",\n  \"basketball_woman\": \"⛹️‍♀️\",\n  \"weight_lifting\": \"🏋️\",\n  \"weight_lifting_man\": \"🏋️‍♂️\",\n  \"weight_lifting_woman\": \"🏋️‍♀️\",\n  \"bicyclist\": \"🚴\",\n  \"biking_man\": \"🚴‍♂️\",\n  \"biking_woman\": \"🚴‍♀️\",\n  \"mountain_bicyclist\": \"🚵\",\n  \"mountain_biking_man\": \"🚵‍♂️\",\n  \"mountain_biking_woman\": \"🚵‍♀️\",\n  \"cartwheeling\": \"🤸\",\n  \"man_cartwheeling\": \"🤸‍♂️\",\n  \"woman_cartwheeling\": \"🤸‍♀️\",\n  \"wrestling\": \"🤼\",\n  \"men_wrestling\": \"🤼‍♂️\",\n  \"women_wrestling\": \"🤼‍♀️\",\n  \"water_polo\": \"🤽\",\n  \"man_playing_water_polo\": \"🤽‍♂️\",\n  \"woman_playing_water_polo\": \"🤽‍♀️\",\n  \"handball_person\": \"🤾\",\n  \"man_playing_handball\": \"🤾‍♂️\",\n  \"woman_playing_handball\": \"🤾‍♀️\",\n  \"juggling_person\": \"🤹\",\n  \"man_juggling\": \"🤹‍♂️\",\n  \"woman_juggling\": \"🤹‍♀️\",\n  \"lotus_position\": \"🧘\",\n  \"lotus_position_man\": \"🧘‍♂️\",\n  \"lotus_position_woman\": \"🧘‍♀️\",\n  \"bath\": \"🛀\",\n  \"sleeping_bed\": \"🛌\",\n  \"people_holding_hands\": \"🧑‍🤝‍🧑\",\n  \"two_women_holding_hands\": \"👭\",\n  \"couple\": \"👫\",\n  \"two_men_holding_hands\": \"👬\",\n  \"couplekiss\": \"💏\",\n  \"couplekiss_man_woman\": \"👩‍❤️‍💋‍👨\",\n  \"couplekiss_man_man\": \"👨‍❤️‍💋‍👨\",\n  \"couplekiss_woman_woman\": \"👩‍❤️‍💋‍👩\",\n  \"couple_with_heart\": \"💑\",\n  \"couple_with_heart_woman_man\": \"👩‍❤️‍👨\",\n  \"couple_with_heart_man_man\": \"👨‍❤️‍👨\",\n  \"couple_with_heart_woman_woman\": \"👩‍❤️‍👩\",\n  \"family\": \"👪\",\n  \"family_man_woman_boy\": \"👨‍👩‍👦\",\n  \"family_man_woman_girl\": \"👨‍👩‍👧\",\n  \"family_man_woman_girl_boy\": \"👨‍👩‍👧‍👦\",\n  \"family_man_woman_boy_boy\": \"👨‍👩‍👦‍👦\",\n  \"family_man_woman_girl_girl\": \"👨‍👩‍👧‍👧\",\n  \"family_man_man_boy\": \"👨‍👨‍👦\",\n  \"family_man_man_girl\": \"👨‍👨‍👧\",\n  \"family_man_man_girl_boy\": \"👨‍👨‍👧‍👦\",\n  \"family_man_man_boy_boy\": \"👨‍👨‍👦‍👦\",\n  \"family_man_man_girl_girl\": \"👨‍👨‍👧‍👧\",\n  \"family_woman_woman_boy\": \"👩‍👩‍👦\",\n  \"family_woman_woman_girl\": \"👩‍👩‍👧\",\n  \"family_woman_woman_girl_boy\": \"👩‍👩‍👧‍👦\",\n  \"family_woman_woman_boy_boy\": \"👩‍👩‍👦‍👦\",\n  \"family_woman_woman_girl_girl\": \"👩‍👩‍👧‍👧\",\n  \"family_man_boy\": \"👨‍👦\",\n  \"family_man_boy_boy\": \"👨‍👦‍👦\",\n  \"family_man_girl\": \"👨‍👧\",\n  \"family_man_girl_boy\": \"👨‍👧‍👦\",\n  \"family_man_girl_girl\": \"👨‍👧‍👧\",\n  \"family_woman_boy\": \"👩‍👦\",\n  \"family_woman_boy_boy\": \"👩‍👦‍👦\",\n  \"family_woman_girl\": \"👩‍👧\",\n  \"family_woman_girl_boy\": \"👩‍👧‍👦\",\n  \"family_woman_girl_girl\": \"👩‍👧‍👧\",\n  \"speaking_head\": \"🗣️\",\n  \"bust_in_silhouette\": \"👤\",\n  \"busts_in_silhouette\": \"👥\",\n  \"people_hugging\": \"🫂\",\n  \"footprints\": \"👣\",\n  \"monkey_face\": \"🐵\",\n  \"monkey\": \"🐒\",\n  \"gorilla\": \"🦍\",\n  \"orangutan\": \"🦧\",\n  \"dog\": \"🐶\",\n  \"dog2\": \"🐕\",\n  \"guide_dog\": \"🦮\",\n  \"service_dog\": \"🐕‍🦺\",\n  \"poodle\": \"🐩\",\n  \"wolf\": \"🐺\",\n  \"fox_face\": \"🦊\",\n  \"raccoon\": \"🦝\",\n  \"cat\": \"🐱\",\n  \"cat2\": \"🐈\",\n  \"black_cat\": \"🐈‍⬛\",\n  \"lion\": \"🦁\",\n  \"tiger\": \"🐯\",\n  \"tiger2\": \"🐅\",\n  \"leopard\": \"🐆\",\n  \"horse\": \"🐴\",\n  \"moose\": \"🫎\",\n  \"donkey\": \"🫏\",\n  \"racehorse\": \"🐎\",\n  \"unicorn\": \"🦄\",\n  \"zebra\": \"🦓\",\n  \"deer\": \"🦌\",\n  \"bison\": \"🦬\",\n  \"cow\": \"🐮\",\n  \"ox\": \"🐂\",\n  \"water_buffalo\": \"🐃\",\n  \"cow2\": \"🐄\",\n  \"pig\": \"🐷\",\n  \"pig2\": \"🐖\",\n  \"boar\": \"🐗\",\n  \"pig_nose\": \"🐽\",\n  \"ram\": \"🐏\",\n  \"sheep\": \"🐑\",\n  \"goat\": \"🐐\",\n  \"dromedary_camel\": \"🐪\",\n  \"camel\": \"🐫\",\n  \"llama\": \"🦙\",\n  \"giraffe\": \"🦒\",\n  \"elephant\": \"🐘\",\n  \"mammoth\": \"🦣\",\n  \"rhinoceros\": \"🦏\",\n  \"hippopotamus\": \"🦛\",\n  \"mouse\": \"🐭\",\n  \"mouse2\": \"🐁\",\n  \"rat\": \"🐀\",\n  \"hamster\": \"🐹\",\n  \"rabbit\": \"🐰\",\n  \"rabbit2\": \"🐇\",\n  \"chipmunk\": \"🐿️\",\n  \"beaver\": \"🦫\",\n  \"hedgehog\": \"🦔\",\n  \"bat\": \"🦇\",\n  \"bear\": \"🐻\",\n  \"polar_bear\": \"🐻‍❄️\",\n  \"koala\": \"🐨\",\n  \"panda_face\": \"🐼\",\n  \"sloth\": \"🦥\",\n  \"otter\": \"🦦\",\n  \"skunk\": \"🦨\",\n  \"kangaroo\": \"🦘\",\n  \"badger\": \"🦡\",\n  \"feet\": \"🐾\",\n  \"paw_prints\": \"🐾\",\n  \"turkey\": \"🦃\",\n  \"chicken\": \"🐔\",\n  \"rooster\": \"🐓\",\n  \"hatching_chick\": \"🐣\",\n  \"baby_chick\": \"🐤\",\n  \"hatched_chick\": \"🐥\",\n  \"bird\": \"🐦\",\n  \"penguin\": \"🐧\",\n  \"dove\": \"🕊️\",\n  \"eagle\": \"🦅\",\n  \"duck\": \"🦆\",\n  \"swan\": \"🦢\",\n  \"owl\": \"🦉\",\n  \"dodo\": \"🦤\",\n  \"feather\": \"🪶\",\n  \"flamingo\": \"🦩\",\n  \"peacock\": \"🦚\",\n  \"parrot\": \"🦜\",\n  \"wing\": \"🪽\",\n  \"black_bird\": \"🐦‍⬛\",\n  \"goose\": \"🪿\",\n  \"frog\": \"🐸\",\n  \"crocodile\": \"🐊\",\n  \"turtle\": \"🐢\",\n  \"lizard\": \"🦎\",\n  \"snake\": \"🐍\",\n  \"dragon_face\": \"🐲\",\n  \"dragon\": \"🐉\",\n  \"sauropod\": \"🦕\",\n  \"t-rex\": \"🦖\",\n  \"whale\": \"🐳\",\n  \"whale2\": \"🐋\",\n  \"dolphin\": \"🐬\",\n  \"flipper\": \"🐬\",\n  \"seal\": \"🦭\",\n  \"fish\": \"🐟\",\n  \"tropical_fish\": \"🐠\",\n  \"blowfish\": \"🐡\",\n  \"shark\": \"🦈\",\n  \"octopus\": \"🐙\",\n  \"shell\": \"🐚\",\n  \"coral\": \"🪸\",\n  \"jellyfish\": \"🪼\",\n  \"snail\": \"🐌\",\n  \"butterfly\": \"🦋\",\n  \"bug\": \"🐛\",\n  \"ant\": \"🐜\",\n  \"bee\": \"🐝\",\n  \"honeybee\": \"🐝\",\n  \"beetle\": \"🪲\",\n  \"lady_beetle\": \"🐞\",\n  \"cricket\": \"🦗\",\n  \"cockroach\": \"🪳\",\n  \"spider\": \"🕷️\",\n  \"spider_web\": \"🕸️\",\n  \"scorpion\": \"🦂\",\n  \"mosquito\": \"🦟\",\n  \"fly\": \"🪰\",\n  \"worm\": \"🪱\",\n  \"microbe\": \"🦠\",\n  \"bouquet\": \"💐\",\n  \"cherry_blossom\": \"🌸\",\n  \"white_flower\": \"💮\",\n  \"lotus\": \"🪷\",\n  \"rosette\": \"🏵️\",\n  \"rose\": \"🌹\",\n  \"wilted_flower\": \"🥀\",\n  \"hibiscus\": \"🌺\",\n  \"sunflower\": \"🌻\",\n  \"blossom\": \"🌼\",\n  \"tulip\": \"🌷\",\n  \"hyacinth\": \"🪻\",\n  \"seedling\": \"🌱\",\n  \"potted_plant\": \"🪴\",\n  \"evergreen_tree\": \"🌲\",\n  \"deciduous_tree\": \"🌳\",\n  \"palm_tree\": \"🌴\",\n  \"cactus\": \"🌵\",\n  \"ear_of_rice\": \"🌾\",\n  \"herb\": \"🌿\",\n  \"shamrock\": \"☘️\",\n  \"four_leaf_clover\": \"🍀\",\n  \"maple_leaf\": \"🍁\",\n  \"fallen_leaf\": \"🍂\",\n  \"leaves\": \"🍃\",\n  \"empty_nest\": \"🪹\",\n  \"nest_with_eggs\": \"🪺\",\n  \"mushroom\": \"🍄\",\n  \"grapes\": \"🍇\",\n  \"melon\": \"🍈\",\n  \"watermelon\": \"🍉\",\n  \"tangerine\": \"🍊\",\n  \"orange\": \"🍊\",\n  \"mandarin\": \"🍊\",\n  \"lemon\": \"🍋\",\n  \"banana\": \"🍌\",\n  \"pineapple\": \"🍍\",\n  \"mango\": \"🥭\",\n  \"apple\": \"🍎\",\n  \"green_apple\": \"🍏\",\n  \"pear\": \"🍐\",\n  \"peach\": \"🍑\",\n  \"cherries\": \"🍒\",\n  \"strawberry\": \"🍓\",\n  \"blueberries\": \"🫐\",\n  \"kiwi_fruit\": \"🥝\",\n  \"tomato\": \"🍅\",\n  \"olive\": \"🫒\",\n  \"coconut\": \"🥥\",\n  \"avocado\": \"🥑\",\n  \"eggplant\": \"🍆\",\n  \"potato\": \"🥔\",\n  \"carrot\": \"🥕\",\n  \"corn\": \"🌽\",\n  \"hot_pepper\": \"🌶️\",\n  \"bell_pepper\": \"🫑\",\n  \"cucumber\": \"🥒\",\n  \"leafy_green\": \"🥬\",\n  \"broccoli\": \"🥦\",\n  \"garlic\": \"🧄\",\n  \"onion\": \"🧅\",\n  \"peanuts\": \"🥜\",\n  \"beans\": \"🫘\",\n  \"chestnut\": \"🌰\",\n  \"ginger_root\": \"🫚\",\n  \"pea_pod\": \"🫛\",\n  \"bread\": \"🍞\",\n  \"croissant\": \"🥐\",\n  \"baguette_bread\": \"🥖\",\n  \"flatbread\": \"🫓\",\n  \"pretzel\": \"🥨\",\n  \"bagel\": \"🥯\",\n  \"pancakes\": \"🥞\",\n  \"waffle\": \"🧇\",\n  \"cheese\": \"🧀\",\n  \"meat_on_bone\": \"🍖\",\n  \"poultry_leg\": \"🍗\",\n  \"cut_of_meat\": \"🥩\",\n  \"bacon\": \"🥓\",\n  \"hamburger\": \"🍔\",\n  \"fries\": \"🍟\",\n  \"pizza\": \"🍕\",\n  \"hotdog\": \"🌭\",\n  \"sandwich\": \"🥪\",\n  \"taco\": \"🌮\",\n  \"burrito\": \"🌯\",\n  \"tamale\": \"🫔\",\n  \"stuffed_flatbread\": \"🥙\",\n  \"falafel\": \"🧆\",\n  \"egg\": \"🥚\",\n  \"fried_egg\": \"🍳\",\n  \"shallow_pan_of_food\": \"🥘\",\n  \"stew\": \"🍲\",\n  \"fondue\": \"🫕\",\n  \"bowl_with_spoon\": \"🥣\",\n  \"green_salad\": \"🥗\",\n  \"popcorn\": \"🍿\",\n  \"butter\": \"🧈\",\n  \"salt\": \"🧂\",\n  \"canned_food\": \"🥫\",\n  \"bento\": \"🍱\",\n  \"rice_cracker\": \"🍘\",\n  \"rice_ball\": \"🍙\",\n  \"rice\": \"🍚\",\n  \"curry\": \"🍛\",\n  \"ramen\": \"🍜\",\n  \"spaghetti\": \"🍝\",\n  \"sweet_potato\": \"🍠\",\n  \"oden\": \"🍢\",\n  \"sushi\": \"🍣\",\n  \"fried_shrimp\": \"🍤\",\n  \"fish_cake\": \"🍥\",\n  \"moon_cake\": \"🥮\",\n  \"dango\": \"🍡\",\n  \"dumpling\": \"🥟\",\n  \"fortune_cookie\": \"🥠\",\n  \"takeout_box\": \"🥡\",\n  \"crab\": \"🦀\",\n  \"lobster\": \"🦞\",\n  \"shrimp\": \"🦐\",\n  \"squid\": \"🦑\",\n  \"oyster\": \"🦪\",\n  \"icecream\": \"🍦\",\n  \"shaved_ice\": \"🍧\",\n  \"ice_cream\": \"🍨\",\n  \"doughnut\": \"🍩\",\n  \"cookie\": \"🍪\",\n  \"birthday\": \"🎂\",\n  \"cake\": \"🍰\",\n  \"cupcake\": \"🧁\",\n  \"pie\": \"🥧\",\n  \"chocolate_bar\": \"🍫\",\n  \"candy\": \"🍬\",\n  \"lollipop\": \"🍭\",\n  \"custard\": \"🍮\",\n  \"honey_pot\": \"🍯\",\n  \"baby_bottle\": \"🍼\",\n  \"milk_glass\": \"🥛\",\n  \"coffee\": \"☕\",\n  \"teapot\": \"🫖\",\n  \"tea\": \"🍵\",\n  \"sake\": \"🍶\",\n  \"champagne\": \"🍾\",\n  \"wine_glass\": \"🍷\",\n  \"cocktail\": \"🍸\",\n  \"tropical_drink\": \"🍹\",\n  \"beer\": \"🍺\",\n  \"beers\": \"🍻\",\n  \"clinking_glasses\": \"🥂\",\n  \"tumbler_glass\": \"🥃\",\n  \"pouring_liquid\": \"🫗\",\n  \"cup_with_straw\": \"🥤\",\n  \"bubble_tea\": \"🧋\",\n  \"beverage_box\": \"🧃\",\n  \"mate\": \"🧉\",\n  \"ice_cube\": \"🧊\",\n  \"chopsticks\": \"🥢\",\n  \"plate_with_cutlery\": \"🍽️\",\n  \"fork_and_knife\": \"🍴\",\n  \"spoon\": \"🥄\",\n  \"hocho\": \"🔪\",\n  \"knife\": \"🔪\",\n  \"jar\": \"🫙\",\n  \"amphora\": \"🏺\",\n  \"earth_africa\": \"🌍\",\n  \"earth_americas\": \"🌎\",\n  \"earth_asia\": \"🌏\",\n  \"globe_with_meridians\": \"🌐\",\n  \"world_map\": \"🗺️\",\n  \"japan\": \"🗾\",\n  \"compass\": \"🧭\",\n  \"mountain_snow\": \"🏔️\",\n  \"mountain\": \"⛰️\",\n  \"volcano\": \"🌋\",\n  \"mount_fuji\": \"🗻\",\n  \"camping\": \"🏕️\",\n  \"beach_umbrella\": \"🏖️\",\n  \"desert\": \"🏜️\",\n  \"desert_island\": \"🏝️\",\n  \"national_park\": \"🏞️\",\n  \"stadium\": \"🏟️\",\n  \"classical_building\": \"🏛️\",\n  \"building_construction\": \"🏗️\",\n  \"bricks\": \"🧱\",\n  \"rock\": \"🪨\",\n  \"wood\": \"🪵\",\n  \"hut\": \"🛖\",\n  \"houses\": \"🏘️\",\n  \"derelict_house\": \"🏚️\",\n  \"house\": \"🏠\",\n  \"house_with_garden\": \"🏡\",\n  \"office\": \"🏢\",\n  \"post_office\": \"🏣\",\n  \"european_post_office\": \"🏤\",\n  \"hospital\": \"🏥\",\n  \"bank\": \"🏦\",\n  \"hotel\": \"🏨\",\n  \"love_hotel\": \"🏩\",\n  \"convenience_store\": \"🏪\",\n  \"school\": \"🏫\",\n  \"department_store\": \"🏬\",\n  \"factory\": \"🏭\",\n  \"japanese_castle\": \"🏯\",\n  \"european_castle\": \"🏰\",\n  \"wedding\": \"💒\",\n  \"tokyo_tower\": \"🗼\",\n  \"statue_of_liberty\": \"🗽\",\n  \"church\": \"⛪\",\n  \"mosque\": \"🕌\",\n  \"hindu_temple\": \"🛕\",\n  \"synagogue\": \"🕍\",\n  \"shinto_shrine\": \"⛩️\",\n  \"kaaba\": \"🕋\",\n  \"fountain\": \"⛲\",\n  \"tent\": \"⛺\",\n  \"foggy\": \"🌁\",\n  \"night_with_stars\": \"🌃\",\n  \"cityscape\": \"🏙️\",\n  \"sunrise_over_mountains\": \"🌄\",\n  \"sunrise\": \"🌅\",\n  \"city_sunset\": \"🌆\",\n  \"city_sunrise\": \"🌇\",\n  \"bridge_at_night\": \"🌉\",\n  \"hotsprings\": \"♨️\",\n  \"carousel_horse\": \"🎠\",\n  \"playground_slide\": \"🛝\",\n  \"ferris_wheel\": \"🎡\",\n  \"roller_coaster\": \"🎢\",\n  \"barber\": \"💈\",\n  \"circus_tent\": \"🎪\",\n  \"steam_locomotive\": \"🚂\",\n  \"railway_car\": \"🚃\",\n  \"bullettrain_side\": \"🚄\",\n  \"bullettrain_front\": \"🚅\",\n  \"train2\": \"🚆\",\n  \"metro\": \"🚇\",\n  \"light_rail\": \"🚈\",\n  \"station\": \"🚉\",\n  \"tram\": \"🚊\",\n  \"monorail\": \"🚝\",\n  \"mountain_railway\": \"🚞\",\n  \"train\": \"🚋\",\n  \"bus\": \"🚌\",\n  \"oncoming_bus\": \"🚍\",\n  \"trolleybus\": \"🚎\",\n  \"minibus\": \"🚐\",\n  \"ambulance\": \"🚑\",\n  \"fire_engine\": \"🚒\",\n  \"police_car\": \"🚓\",\n  \"oncoming_police_car\": \"🚔\",\n  \"taxi\": \"🚕\",\n  \"oncoming_taxi\": \"🚖\",\n  \"car\": \"🚗\",\n  \"red_car\": \"🚗\",\n  \"oncoming_automobile\": \"🚘\",\n  \"blue_car\": \"🚙\",\n  \"pickup_truck\": \"🛻\",\n  \"truck\": \"🚚\",\n  \"articulated_lorry\": \"🚛\",\n  \"tractor\": \"🚜\",\n  \"racing_car\": \"🏎️\",\n  \"motorcycle\": \"🏍️\",\n  \"motor_scooter\": \"🛵\",\n  \"manual_wheelchair\": \"🦽\",\n  \"motorized_wheelchair\": \"🦼\",\n  \"auto_rickshaw\": \"🛺\",\n  \"bike\": \"🚲\",\n  \"kick_scooter\": \"🛴\",\n  \"skateboard\": \"🛹\",\n  \"roller_skate\": \"🛼\",\n  \"busstop\": \"🚏\",\n  \"motorway\": \"🛣️\",\n  \"railway_track\": \"🛤️\",\n  \"oil_drum\": \"🛢️\",\n  \"fuelpump\": \"⛽\",\n  \"wheel\": \"🛞\",\n  \"rotating_light\": \"🚨\",\n  \"traffic_light\": \"🚥\",\n  \"vertical_traffic_light\": \"🚦\",\n  \"stop_sign\": \"🛑\",\n  \"construction\": \"🚧\",\n  \"anchor\": \"⚓\",\n  \"ring_buoy\": \"🛟\",\n  \"boat\": \"⛵\",\n  \"sailboat\": \"⛵\",\n  \"canoe\": \"🛶\",\n  \"speedboat\": \"🚤\",\n  \"passenger_ship\": \"🛳️\",\n  \"ferry\": \"⛴️\",\n  \"motor_boat\": \"🛥️\",\n  \"ship\": \"🚢\",\n  \"airplane\": \"✈️\",\n  \"small_airplane\": \"🛩️\",\n  \"flight_departure\": \"🛫\",\n  \"flight_arrival\": \"🛬\",\n  \"parachute\": \"🪂\",\n  \"seat\": \"💺\",\n  \"helicopter\": \"🚁\",\n  \"suspension_railway\": \"🚟\",\n  \"mountain_cableway\": \"🚠\",\n  \"aerial_tramway\": \"🚡\",\n  \"artificial_satellite\": \"🛰️\",\n  \"rocket\": \"🚀\",\n  \"flying_saucer\": \"🛸\",\n  \"bellhop_bell\": \"🛎️\",\n  \"luggage\": \"🧳\",\n  \"hourglass\": \"⌛\",\n  \"hourglass_flowing_sand\": \"⏳\",\n  \"watch\": \"⌚\",\n  \"alarm_clock\": \"⏰\",\n  \"stopwatch\": \"⏱️\",\n  \"timer_clock\": \"⏲️\",\n  \"mantelpiece_clock\": \"🕰️\",\n  \"clock12\": \"🕛\",\n  \"clock1230\": \"🕧\",\n  \"clock1\": \"🕐\",\n  \"clock130\": \"🕜\",\n  \"clock2\": \"🕑\",\n  \"clock230\": \"🕝\",\n  \"clock3\": \"🕒\",\n  \"clock330\": \"🕞\",\n  \"clock4\": \"🕓\",\n  \"clock430\": \"🕟\",\n  \"clock5\": \"🕔\",\n  \"clock530\": \"🕠\",\n  \"clock6\": \"🕕\",\n  \"clock630\": \"🕡\",\n  \"clock7\": \"🕖\",\n  \"clock730\": \"🕢\",\n  \"clock8\": \"🕗\",\n  \"clock830\": \"🕣\",\n  \"clock9\": \"🕘\",\n  \"clock930\": \"🕤\",\n  \"clock10\": \"🕙\",\n  \"clock1030\": \"🕥\",\n  \"clock11\": \"🕚\",\n  \"clock1130\": \"🕦\",\n  \"new_moon\": \"🌑\",\n  \"waxing_crescent_moon\": \"🌒\",\n  \"first_quarter_moon\": \"🌓\",\n  \"moon\": \"🌔\",\n  \"waxing_gibbous_moon\": \"🌔\",\n  \"full_moon\": \"🌕\",\n  \"waning_gibbous_moon\": \"🌖\",\n  \"last_quarter_moon\": \"🌗\",\n  \"waning_crescent_moon\": \"🌘\",\n  \"crescent_moon\": \"🌙\",\n  \"new_moon_with_face\": \"🌚\",\n  \"first_quarter_moon_with_face\": \"🌛\",\n  \"last_quarter_moon_with_face\": \"🌜\",\n  \"thermometer\": \"🌡️\",\n  \"sunny\": \"☀️\",\n  \"full_moon_with_face\": \"🌝\",\n  \"sun_with_face\": \"🌞\",\n  \"ringed_planet\": \"🪐\",\n  \"star\": \"⭐\",\n  \"star2\": \"🌟\",\n  \"stars\": \"🌠\",\n  \"milky_way\": \"🌌\",\n  \"cloud\": \"☁️\",\n  \"partly_sunny\": \"⛅\",\n  \"cloud_with_lightning_and_rain\": \"⛈️\",\n  \"sun_behind_small_cloud\": \"🌤️\",\n  \"sun_behind_large_cloud\": \"🌥️\",\n  \"sun_behind_rain_cloud\": \"🌦️\",\n  \"cloud_with_rain\": \"🌧️\",\n  \"cloud_with_snow\": \"🌨️\",\n  \"cloud_with_lightning\": \"🌩️\",\n  \"tornado\": \"🌪️\",\n  \"fog\": \"🌫️\",\n  \"wind_face\": \"🌬️\",\n  \"cyclone\": \"🌀\",\n  \"rainbow\": \"🌈\",\n  \"closed_umbrella\": \"🌂\",\n  \"open_umbrella\": \"☂️\",\n  \"umbrella\": \"☔\",\n  \"parasol_on_ground\": \"⛱️\",\n  \"zap\": \"⚡\",\n  \"snowflake\": \"❄️\",\n  \"snowman_with_snow\": \"☃️\",\n  \"snowman\": \"⛄\",\n  \"comet\": \"☄️\",\n  \"fire\": \"🔥\",\n  \"droplet\": \"💧\",\n  \"ocean\": \"🌊\",\n  \"jack_o_lantern\": \"🎃\",\n  \"christmas_tree\": \"🎄\",\n  \"fireworks\": \"🎆\",\n  \"sparkler\": \"🎇\",\n  \"firecracker\": \"🧨\",\n  \"sparkles\": \"✨\",\n  \"balloon\": \"🎈\",\n  \"tada\": \"🎉\",\n  \"confetti_ball\": \"🎊\",\n  \"tanabata_tree\": \"🎋\",\n  \"bamboo\": \"🎍\",\n  \"dolls\": \"🎎\",\n  \"flags\": \"🎏\",\n  \"wind_chime\": \"🎐\",\n  \"rice_scene\": \"🎑\",\n  \"red_envelope\": \"🧧\",\n  \"ribbon\": \"🎀\",\n  \"gift\": \"🎁\",\n  \"reminder_ribbon\": \"🎗️\",\n  \"tickets\": \"🎟️\",\n  \"ticket\": \"🎫\",\n  \"medal_military\": \"🎖️\",\n  \"trophy\": \"🏆\",\n  \"medal_sports\": \"🏅\",\n  \"1st_place_medal\": \"🥇\",\n  \"2nd_place_medal\": \"🥈\",\n  \"3rd_place_medal\": \"🥉\",\n  \"soccer\": \"⚽\",\n  \"baseball\": \"⚾\",\n  \"softball\": \"🥎\",\n  \"basketball\": \"🏀\",\n  \"volleyball\": \"🏐\",\n  \"football\": \"🏈\",\n  \"rugby_football\": \"🏉\",\n  \"tennis\": \"🎾\",\n  \"flying_disc\": \"🥏\",\n  \"bowling\": \"🎳\",\n  \"cricket_game\": \"🏏\",\n  \"field_hockey\": \"🏑\",\n  \"ice_hockey\": \"🏒\",\n  \"lacrosse\": \"🥍\",\n  \"ping_pong\": \"🏓\",\n  \"badminton\": \"🏸\",\n  \"boxing_glove\": \"🥊\",\n  \"martial_arts_uniform\": \"🥋\",\n  \"goal_net\": \"🥅\",\n  \"golf\": \"⛳\",\n  \"ice_skate\": \"⛸️\",\n  \"fishing_pole_and_fish\": \"🎣\",\n  \"diving_mask\": \"🤿\",\n  \"running_shirt_with_sash\": \"🎽\",\n  \"ski\": \"🎿\",\n  \"sled\": \"🛷\",\n  \"curling_stone\": \"🥌\",\n  \"dart\": \"🎯\",\n  \"yo_yo\": \"🪀\",\n  \"kite\": \"🪁\",\n  \"gun\": \"🔫\",\n  \"8ball\": \"🎱\",\n  \"crystal_ball\": \"🔮\",\n  \"magic_wand\": \"🪄\",\n  \"video_game\": \"🎮\",\n  \"joystick\": \"🕹️\",\n  \"slot_machine\": \"🎰\",\n  \"game_die\": \"🎲\",\n  \"jigsaw\": \"🧩\",\n  \"teddy_bear\": \"🧸\",\n  \"pinata\": \"🪅\",\n  \"mirror_ball\": \"🪩\",\n  \"nesting_dolls\": \"🪆\",\n  \"spades\": \"♠️\",\n  \"hearts\": \"♥️\",\n  \"diamonds\": \"♦️\",\n  \"clubs\": \"♣️\",\n  \"chess_pawn\": \"♟️\",\n  \"black_joker\": \"🃏\",\n  \"mahjong\": \"🀄\",\n  \"flower_playing_cards\": \"🎴\",\n  \"performing_arts\": \"🎭\",\n  \"framed_picture\": \"🖼️\",\n  \"art\": \"🎨\",\n  \"thread\": \"🧵\",\n  \"sewing_needle\": \"🪡\",\n  \"yarn\": \"🧶\",\n  \"knot\": \"🪢\",\n  \"eyeglasses\": \"👓\",\n  \"dark_sunglasses\": \"🕶️\",\n  \"goggles\": \"🥽\",\n  \"lab_coat\": \"🥼\",\n  \"safety_vest\": \"🦺\",\n  \"necktie\": \"👔\",\n  \"shirt\": \"👕\",\n  \"tshirt\": \"👕\",\n  \"jeans\": \"👖\",\n  \"scarf\": \"🧣\",\n  \"gloves\": \"🧤\",\n  \"coat\": \"🧥\",\n  \"socks\": \"🧦\",\n  \"dress\": \"👗\",\n  \"kimono\": \"👘\",\n  \"sari\": \"🥻\",\n  \"one_piece_swimsuit\": \"🩱\",\n  \"swim_brief\": \"🩲\",\n  \"shorts\": \"🩳\",\n  \"bikini\": \"👙\",\n  \"womans_clothes\": \"👚\",\n  \"folding_hand_fan\": \"🪭\",\n  \"purse\": \"👛\",\n  \"handbag\": \"👜\",\n  \"pouch\": \"👝\",\n  \"shopping\": \"🛍️\",\n  \"school_satchel\": \"🎒\",\n  \"thong_sandal\": \"🩴\",\n  \"mans_shoe\": \"👞\",\n  \"shoe\": \"👞\",\n  \"athletic_shoe\": \"👟\",\n  \"hiking_boot\": \"🥾\",\n  \"flat_shoe\": \"🥿\",\n  \"high_heel\": \"👠\",\n  \"sandal\": \"👡\",\n  \"ballet_shoes\": \"🩰\",\n  \"boot\": \"👢\",\n  \"hair_pick\": \"🪮\",\n  \"crown\": \"👑\",\n  \"womans_hat\": \"👒\",\n  \"tophat\": \"🎩\",\n  \"mortar_board\": \"🎓\",\n  \"billed_cap\": \"🧢\",\n  \"military_helmet\": \"🪖\",\n  \"rescue_worker_helmet\": \"⛑️\",\n  \"prayer_beads\": \"📿\",\n  \"lipstick\": \"💄\",\n  \"ring\": \"💍\",\n  \"gem\": \"💎\",\n  \"mute\": \"🔇\",\n  \"speaker\": \"🔈\",\n  \"sound\": \"🔉\",\n  \"loud_sound\": \"🔊\",\n  \"loudspeaker\": \"📢\",\n  \"mega\": \"📣\",\n  \"postal_horn\": \"📯\",\n  \"bell\": \"🔔\",\n  \"no_bell\": \"🔕\",\n  \"musical_score\": \"🎼\",\n  \"musical_note\": \"🎵\",\n  \"notes\": \"🎶\",\n  \"studio_microphone\": \"🎙️\",\n  \"level_slider\": \"🎚️\",\n  \"control_knobs\": \"🎛️\",\n  \"microphone\": \"🎤\",\n  \"headphones\": \"🎧\",\n  \"radio\": \"📻\",\n  \"saxophone\": \"🎷\",\n  \"accordion\": \"🪗\",\n  \"guitar\": \"🎸\",\n  \"musical_keyboard\": \"🎹\",\n  \"trumpet\": \"🎺\",\n  \"violin\": \"🎻\",\n  \"banjo\": \"🪕\",\n  \"drum\": \"🥁\",\n  \"long_drum\": \"🪘\",\n  \"maracas\": \"🪇\",\n  \"flute\": \"🪈\",\n  \"iphone\": \"📱\",\n  \"calling\": \"📲\",\n  \"phone\": \"☎️\",\n  \"telephone\": \"☎️\",\n  \"telephone_receiver\": \"📞\",\n  \"pager\": \"📟\",\n  \"fax\": \"📠\",\n  \"battery\": \"🔋\",\n  \"low_battery\": \"🪫\",\n  \"electric_plug\": \"🔌\",\n  \"computer\": \"💻\",\n  \"desktop_computer\": \"🖥️\",\n  \"printer\": \"🖨️\",\n  \"keyboard\": \"⌨️\",\n  \"computer_mouse\": \"🖱️\",\n  \"trackball\": \"🖲️\",\n  \"minidisc\": \"💽\",\n  \"floppy_disk\": \"💾\",\n  \"cd\": \"💿\",\n  \"dvd\": \"📀\",\n  \"abacus\": \"🧮\",\n  \"movie_camera\": \"🎥\",\n  \"film_strip\": \"🎞️\",\n  \"film_projector\": \"📽️\",\n  \"clapper\": \"🎬\",\n  \"tv\": \"📺\",\n  \"camera\": \"📷\",\n  \"camera_flash\": \"📸\",\n  \"video_camera\": \"📹\",\n  \"vhs\": \"📼\",\n  \"mag\": \"🔍\",\n  \"mag_right\": \"🔎\",\n  \"candle\": \"🕯️\",\n  \"bulb\": \"💡\",\n  \"flashlight\": \"🔦\",\n  \"izakaya_lantern\": \"🏮\",\n  \"lantern\": \"🏮\",\n  \"diya_lamp\": \"🪔\",\n  \"notebook_with_decorative_cover\": \"📔\",\n  \"closed_book\": \"📕\",\n  \"book\": \"📖\",\n  \"open_book\": \"📖\",\n  \"green_book\": \"📗\",\n  \"blue_book\": \"📘\",\n  \"orange_book\": \"📙\",\n  \"books\": \"📚\",\n  \"notebook\": \"📓\",\n  \"ledger\": \"📒\",\n  \"page_with_curl\": \"📃\",\n  \"scroll\": \"📜\",\n  \"page_facing_up\": \"📄\",\n  \"newspaper\": \"📰\",\n  \"newspaper_roll\": \"🗞️\",\n  \"bookmark_tabs\": \"📑\",\n  \"bookmark\": \"🔖\",\n  \"label\": \"🏷️\",\n  \"moneybag\": \"💰\",\n  \"coin\": \"🪙\",\n  \"yen\": \"💴\",\n  \"dollar\": \"💵\",\n  \"euro\": \"💶\",\n  \"pound\": \"💷\",\n  \"money_with_wings\": \"💸\",\n  \"credit_card\": \"💳\",\n  \"receipt\": \"🧾\",\n  \"chart\": \"💹\",\n  \"envelope\": \"✉️\",\n  \"email\": \"📧\",\n  \"e-mail\": \"📧\",\n  \"incoming_envelope\": \"📨\",\n  \"envelope_with_arrow\": \"📩\",\n  \"outbox_tray\": \"📤\",\n  \"inbox_tray\": \"📥\",\n  \"package\": \"📦\",\n  \"mailbox\": \"📫\",\n  \"mailbox_closed\": \"📪\",\n  \"mailbox_with_mail\": \"📬\",\n  \"mailbox_with_no_mail\": \"📭\",\n  \"postbox\": \"📮\",\n  \"ballot_box\": \"🗳️\",\n  \"pencil2\": \"✏️\",\n  \"black_nib\": \"✒️\",\n  \"fountain_pen\": \"🖋️\",\n  \"pen\": \"🖊️\",\n  \"paintbrush\": \"🖌️\",\n  \"crayon\": \"🖍️\",\n  \"memo\": \"📝\",\n  \"pencil\": \"📝\",\n  \"briefcase\": \"💼\",\n  \"file_folder\": \"📁\",\n  \"open_file_folder\": \"📂\",\n  \"card_index_dividers\": \"🗂️\",\n  \"date\": \"📅\",\n  \"calendar\": \"📆\",\n  \"spiral_notepad\": \"🗒️\",\n  \"spiral_calendar\": \"🗓️\",\n  \"card_index\": \"📇\",\n  \"chart_with_upwards_trend\": \"📈\",\n  \"chart_with_downwards_trend\": \"📉\",\n  \"bar_chart\": \"📊\",\n  \"clipboard\": \"📋\",\n  \"pushpin\": \"📌\",\n  \"round_pushpin\": \"📍\",\n  \"paperclip\": \"📎\",\n  \"paperclips\": \"🖇️\",\n  \"straight_ruler\": \"📏\",\n  \"triangular_ruler\": \"📐\",\n  \"scissors\": \"✂️\",\n  \"card_file_box\": \"🗃️\",\n  \"file_cabinet\": \"🗄️\",\n  \"wastebasket\": \"🗑️\",\n  \"lock\": \"🔒\",\n  \"unlock\": \"🔓\",\n  \"lock_with_ink_pen\": \"🔏\",\n  \"closed_lock_with_key\": \"🔐\",\n  \"key\": \"🔑\",\n  \"old_key\": \"🗝️\",\n  \"hammer\": \"🔨\",\n  \"axe\": \"🪓\",\n  \"pick\": \"⛏️\",\n  \"hammer_and_pick\": \"⚒️\",\n  \"hammer_and_wrench\": \"🛠️\",\n  \"dagger\": \"🗡️\",\n  \"crossed_swords\": \"⚔️\",\n  \"bomb\": \"💣\",\n  \"boomerang\": \"🪃\",\n  \"bow_and_arrow\": \"🏹\",\n  \"shield\": \"🛡️\",\n  \"carpentry_saw\": \"🪚\",\n  \"wrench\": \"🔧\",\n  \"screwdriver\": \"🪛\",\n  \"nut_and_bolt\": \"🔩\",\n  \"gear\": \"⚙️\",\n  \"clamp\": \"🗜️\",\n  \"balance_scale\": \"⚖️\",\n  \"probing_cane\": \"🦯\",\n  \"link\": \"🔗\",\n  \"chains\": \"⛓️\",\n  \"hook\": \"🪝\",\n  \"toolbox\": \"🧰\",\n  \"magnet\": \"🧲\",\n  \"ladder\": \"🪜\",\n  \"alembic\": \"⚗️\",\n  \"test_tube\": \"🧪\",\n  \"petri_dish\": \"🧫\",\n  \"dna\": \"🧬\",\n  \"microscope\": \"🔬\",\n  \"telescope\": \"🔭\",\n  \"satellite\": \"📡\",\n  \"syringe\": \"💉\",\n  \"drop_of_blood\": \"🩸\",\n  \"pill\": \"💊\",\n  \"adhesive_bandage\": \"🩹\",\n  \"crutch\": \"🩼\",\n  \"stethoscope\": \"🩺\",\n  \"x_ray\": \"🩻\",\n  \"door\": \"🚪\",\n  \"elevator\": \"🛗\",\n  \"mirror\": \"🪞\",\n  \"window\": \"🪟\",\n  \"bed\": \"🛏️\",\n  \"couch_and_lamp\": \"🛋️\",\n  \"chair\": \"🪑\",\n  \"toilet\": \"🚽\",\n  \"plunger\": \"🪠\",\n  \"shower\": \"🚿\",\n  \"bathtub\": \"🛁\",\n  \"mouse_trap\": \"🪤\",\n  \"razor\": \"🪒\",\n  \"lotion_bottle\": \"🧴\",\n  \"safety_pin\": \"🧷\",\n  \"broom\": \"🧹\",\n  \"basket\": \"🧺\",\n  \"roll_of_paper\": \"🧻\",\n  \"bucket\": \"🪣\",\n  \"soap\": \"🧼\",\n  \"bubbles\": \"🫧\",\n  \"toothbrush\": \"🪥\",\n  \"sponge\": \"🧽\",\n  \"fire_extinguisher\": \"🧯\",\n  \"shopping_cart\": \"🛒\",\n  \"smoking\": \"🚬\",\n  \"coffin\": \"⚰️\",\n  \"headstone\": \"🪦\",\n  \"funeral_urn\": \"⚱️\",\n  \"nazar_amulet\": \"🧿\",\n  \"hamsa\": \"🪬\",\n  \"moyai\": \"🗿\",\n  \"placard\": \"🪧\",\n  \"identification_card\": \"🪪\",\n  \"atm\": \"🏧\",\n  \"put_litter_in_its_place\": \"🚮\",\n  \"potable_water\": \"🚰\",\n  \"wheelchair\": \"♿\",\n  \"mens\": \"🚹\",\n  \"womens\": \"🚺\",\n  \"restroom\": \"🚻\",\n  \"baby_symbol\": \"🚼\",\n  \"wc\": \"🚾\",\n  \"passport_control\": \"🛂\",\n  \"customs\": \"🛃\",\n  \"baggage_claim\": \"🛄\",\n  \"left_luggage\": \"🛅\",\n  \"warning\": \"⚠️\",\n  \"children_crossing\": \"🚸\",\n  \"no_entry\": \"⛔\",\n  \"no_entry_sign\": \"🚫\",\n  \"no_bicycles\": \"🚳\",\n  \"no_smoking\": \"🚭\",\n  \"do_not_litter\": \"🚯\",\n  \"non-potable_water\": \"🚱\",\n  \"no_pedestrians\": \"🚷\",\n  \"no_mobile_phones\": \"📵\",\n  \"underage\": \"🔞\",\n  \"radioactive\": \"☢️\",\n  \"biohazard\": \"☣️\",\n  \"arrow_up\": \"⬆️\",\n  \"arrow_upper_right\": \"↗️\",\n  \"arrow_right\": \"➡️\",\n  \"arrow_lower_right\": \"↘️\",\n  \"arrow_down\": \"⬇️\",\n  \"arrow_lower_left\": \"↙️\",\n  \"arrow_left\": \"⬅️\",\n  \"arrow_upper_left\": \"↖️\",\n  \"arrow_up_down\": \"↕️\",\n  \"left_right_arrow\": \"↔️\",\n  \"leftwards_arrow_with_hook\": \"↩️\",\n  \"arrow_right_hook\": \"↪️\",\n  \"arrow_heading_up\": \"⤴️\",\n  \"arrow_heading_down\": \"⤵️\",\n  \"arrows_clockwise\": \"🔃\",\n  \"arrows_counterclockwise\": \"🔄\",\n  \"back\": \"🔙\",\n  \"end\": \"🔚\",\n  \"on\": \"🔛\",\n  \"soon\": \"🔜\",\n  \"top\": \"🔝\",\n  \"place_of_worship\": \"🛐\",\n  \"atom_symbol\": \"⚛️\",\n  \"om\": \"🕉️\",\n  \"star_of_david\": \"✡️\",\n  \"wheel_of_dharma\": \"☸️\",\n  \"yin_yang\": \"☯️\",\n  \"latin_cross\": \"✝️\",\n  \"orthodox_cross\": \"☦️\",\n  \"star_and_crescent\": \"☪️\",\n  \"peace_symbol\": \"☮️\",\n  \"menorah\": \"🕎\",\n  \"six_pointed_star\": \"🔯\",\n  \"khanda\": \"🪯\",\n  \"aries\": \"♈\",\n  \"taurus\": \"♉\",\n  \"gemini\": \"♊\",\n  \"cancer\": \"♋\",\n  \"leo\": \"♌\",\n  \"virgo\": \"♍\",\n  \"libra\": \"♎\",\n  \"scorpius\": \"♏\",\n  \"sagittarius\": \"♐\",\n  \"capricorn\": \"♑\",\n  \"aquarius\": \"♒\",\n  \"pisces\": \"♓\",\n  \"ophiuchus\": \"⛎\",\n  \"twisted_rightwards_arrows\": \"🔀\",\n  \"repeat\": \"🔁\",\n  \"repeat_one\": \"🔂\",\n  \"arrow_forward\": \"▶️\",\n  \"fast_forward\": \"⏩\",\n  \"next_track_button\": \"⏭️\",\n  \"play_or_pause_button\": \"⏯️\",\n  \"arrow_backward\": \"◀️\",\n  \"rewind\": \"⏪\",\n  \"previous_track_button\": \"⏮️\",\n  \"arrow_up_small\": \"🔼\",\n  \"arrow_double_up\": \"⏫\",\n  \"arrow_down_small\": \"🔽\",\n  \"arrow_double_down\": \"⏬\",\n  \"pause_button\": \"⏸️\",\n  \"stop_button\": \"⏹️\",\n  \"record_button\": \"⏺️\",\n  \"eject_button\": \"⏏️\",\n  \"cinema\": \"🎦\",\n  \"low_brightness\": \"🔅\",\n  \"high_brightness\": \"🔆\",\n  \"signal_strength\": \"📶\",\n  \"wireless\": \"🛜\",\n  \"vibration_mode\": \"📳\",\n  \"mobile_phone_off\": \"📴\",\n  \"female_sign\": \"♀️\",\n  \"male_sign\": \"♂️\",\n  \"transgender_symbol\": \"⚧️\",\n  \"heavy_multiplication_x\": \"✖️\",\n  \"heavy_plus_sign\": \"➕\",\n  \"heavy_minus_sign\": \"➖\",\n  \"heavy_division_sign\": \"➗\",\n  \"heavy_equals_sign\": \"🟰\",\n  \"infinity\": \"♾️\",\n  \"bangbang\": \"‼️\",\n  \"interrobang\": \"⁉️\",\n  \"question\": \"❓\",\n  \"grey_question\": \"❔\",\n  \"grey_exclamation\": \"❕\",\n  \"exclamation\": \"❗\",\n  \"heavy_exclamation_mark\": \"❗\",\n  \"wavy_dash\": \"〰️\",\n  \"currency_exchange\": \"💱\",\n  \"heavy_dollar_sign\": \"💲\",\n  \"medical_symbol\": \"⚕️\",\n  \"recycle\": \"♻️\",\n  \"fleur_de_lis\": \"⚜️\",\n  \"trident\": \"🔱\",\n  \"name_badge\": \"📛\",\n  \"beginner\": \"🔰\",\n  \"o\": \"⭕\",\n  \"white_check_mark\": \"✅\",\n  \"ballot_box_with_check\": \"☑️\",\n  \"heavy_check_mark\": \"✔️\",\n  \"x\": \"❌\",\n  \"negative_squared_cross_mark\": \"❎\",\n  \"curly_loop\": \"➰\",\n  \"loop\": \"➿\",\n  \"part_alternation_mark\": \"〽️\",\n  \"eight_spoked_asterisk\": \"✳️\",\n  \"eight_pointed_black_star\": \"✴️\",\n  \"sparkle\": \"❇️\",\n  \"copyright\": \"©️\",\n  \"registered\": \"®️\",\n  \"tm\": \"™️\",\n  \"hash\": \"#️⃣\",\n  \"asterisk\": \"*️⃣\",\n  \"zero\": \"0️⃣\",\n  \"one\": \"1️⃣\",\n  \"two\": \"2️⃣\",\n  \"three\": \"3️⃣\",\n  \"four\": \"4️⃣\",\n  \"five\": \"5️⃣\",\n  \"six\": \"6️⃣\",\n  \"seven\": \"7️⃣\",\n  \"eight\": \"8️⃣\",\n  \"nine\": \"9️⃣\",\n  \"keycap_ten\": \"🔟\",\n  \"capital_abcd\": \"🔠\",\n  \"abcd\": \"🔡\",\n  \"symbols\": \"🔣\",\n  \"abc\": \"🔤\",\n  \"a\": \"🅰️\",\n  \"ab\": \"🆎\",\n  \"b\": \"🅱️\",\n  \"cl\": \"🆑\",\n  \"cool\": \"🆒\",\n  \"free\": \"🆓\",\n  \"information_source\": \"ℹ️\",\n  \"id\": \"🆔\",\n  \"m\": \"Ⓜ️\",\n  \"new\": \"🆕\",\n  \"ng\": \"🆖\",\n  \"o2\": \"🅾️\",\n  \"ok\": \"🆗\",\n  \"parking\": \"🅿️\",\n  \"sos\": \"🆘\",\n  \"up\": \"🆙\",\n  \"vs\": \"🆚\",\n  \"koko\": \"🈁\",\n  \"sa\": \"🈂️\",\n  \"ideograph_advantage\": \"🉐\",\n  \"accept\": \"🉑\",\n  \"congratulations\": \"㊗️\",\n  \"secret\": \"㊙️\",\n  \"u6e80\": \"🈵\",\n  \"red_circle\": \"🔴\",\n  \"orange_circle\": \"🟠\",\n  \"yellow_circle\": \"🟡\",\n  \"green_circle\": \"🟢\",\n  \"large_blue_circle\": \"🔵\",\n  \"purple_circle\": \"🟣\",\n  \"brown_circle\": \"🟤\",\n  \"black_circle\": \"⚫\",\n  \"white_circle\": \"⚪\",\n  \"red_square\": \"🟥\",\n  \"orange_square\": \"🟧\",\n  \"yellow_square\": \"🟨\",\n  \"green_square\": \"🟩\",\n  \"blue_square\": \"🟦\",\n  \"purple_square\": \"🟪\",\n  \"brown_square\": \"🟫\",\n  \"black_large_square\": \"⬛\",\n  \"white_large_square\": \"⬜\",\n  \"black_medium_square\": \"◼️\",\n  \"white_medium_square\": \"◻️\",\n  \"black_medium_small_square\": \"◾\",\n  \"white_medium_small_square\": \"◽\",\n  \"black_small_square\": \"▪️\",\n  \"white_small_square\": \"▫️\",\n  \"large_orange_diamond\": \"🔶\",\n  \"large_blue_diamond\": \"🔷\",\n  \"small_orange_diamond\": \"🔸\",\n  \"small_blue_diamond\": \"🔹\",\n  \"small_red_triangle\": \"🔺\",\n  \"small_red_triangle_down\": \"🔻\",\n  \"diamond_shape_with_a_dot_inside\": \"💠\",\n  \"radio_button\": \"🔘\",\n  \"white_square_button\": \"🔳\",\n  \"black_square_button\": \"🔲\",\n  \"checkered_flag\": \"🏁\",\n  \"triangular_flag_on_post\": \"🚩\",\n  \"crossed_flags\": \"🎌\",\n  \"black_flag\": \"🏴\",\n  \"white_flag\": \"🏳️\",\n  \"rainbow_flag\": \"🏳️‍🌈\",\n  \"transgender_flag\": \"🏳️‍⚧️\",\n  \"pirate_flag\": \"🏴‍☠️\",\n  \"ascension_island\": \"🇦🇨\",\n  \"andorra\": \"🇦🇩\",\n  \"united_arab_emirates\": \"🇦🇪\",\n  \"afghanistan\": \"🇦🇫\",\n  \"antigua_barbuda\": \"🇦🇬\",\n  \"anguilla\": \"🇦🇮\",\n  \"albania\": \"🇦🇱\",\n  \"armenia\": \"🇦🇲\",\n  \"angola\": \"🇦🇴\",\n  \"antarctica\": \"🇦🇶\",\n  \"argentina\": \"🇦🇷\",\n  \"american_samoa\": \"🇦🇸\",\n  \"austria\": \"🇦🇹\",\n  \"australia\": \"🇦🇺\",\n  \"aruba\": \"🇦🇼\",\n  \"aland_islands\": \"🇦🇽\",\n  \"azerbaijan\": \"🇦🇿\",\n  \"bosnia_herzegovina\": \"🇧🇦\",\n  \"barbados\": \"🇧🇧\",\n  \"bangladesh\": \"🇧🇩\",\n  \"belgium\": \"🇧🇪\",\n  \"burkina_faso\": \"🇧🇫\",\n  \"bulgaria\": \"🇧🇬\",\n  \"bahrain\": \"🇧🇭\",\n  \"burundi\": \"🇧🇮\",\n  \"benin\": \"🇧🇯\",\n  \"st_barthelemy\": \"🇧🇱\",\n  \"bermuda\": \"🇧🇲\",\n  \"brunei\": \"🇧🇳\",\n  \"bolivia\": \"🇧🇴\",\n  \"caribbean_netherlands\": \"🇧🇶\",\n  \"brazil\": \"🇧🇷\",\n  \"bahamas\": \"🇧🇸\",\n  \"bhutan\": \"🇧🇹\",\n  \"bouvet_island\": \"🇧🇻\",\n  \"botswana\": \"🇧🇼\",\n  \"belarus\": \"🇧🇾\",\n  \"belize\": \"🇧🇿\",\n  \"canada\": \"🇨🇦\",\n  \"cocos_islands\": \"🇨🇨\",\n  \"congo_kinshasa\": \"🇨🇩\",\n  \"central_african_republic\": \"🇨🇫\",\n  \"congo_brazzaville\": \"🇨🇬\",\n  \"switzerland\": \"🇨🇭\",\n  \"cote_divoire\": \"🇨🇮\",\n  \"cook_islands\": \"🇨🇰\",\n  \"chile\": \"🇨🇱\",\n  \"cameroon\": \"🇨🇲\",\n  \"cn\": \"🇨🇳\",\n  \"colombia\": \"🇨🇴\",\n  \"clipperton_island\": \"🇨🇵\",\n  \"costa_rica\": \"🇨🇷\",\n  \"cuba\": \"🇨🇺\",\n  \"cape_verde\": \"🇨🇻\",\n  \"curacao\": \"🇨🇼\",\n  \"christmas_island\": \"🇨🇽\",\n  \"cyprus\": \"🇨🇾\",\n  \"czech_republic\": \"🇨🇿\",\n  \"de\": \"🇩🇪\",\n  \"diego_garcia\": \"🇩🇬\",\n  \"djibouti\": \"🇩🇯\",\n  \"denmark\": \"🇩🇰\",\n  \"dominica\": \"🇩🇲\",\n  \"dominican_republic\": \"🇩🇴\",\n  \"algeria\": \"🇩🇿\",\n  \"ceuta_melilla\": \"🇪🇦\",\n  \"ecuador\": \"🇪🇨\",\n  \"estonia\": \"🇪🇪\",\n  \"egypt\": \"🇪🇬\",\n  \"western_sahara\": \"🇪🇭\",\n  \"eritrea\": \"🇪🇷\",\n  \"es\": \"🇪🇸\",\n  \"ethiopia\": \"🇪🇹\",\n  \"eu\": \"🇪🇺\",\n  \"european_union\": \"🇪🇺\",\n  \"finland\": \"🇫🇮\",\n  \"fiji\": \"🇫🇯\",\n  \"falkland_islands\": \"🇫🇰\",\n  \"micronesia\": \"🇫🇲\",\n  \"faroe_islands\": \"🇫🇴\",\n  \"fr\": \"🇫🇷\",\n  \"gabon\": \"🇬🇦\",\n  \"gb\": \"🇬🇧\",\n  \"uk\": \"🇬🇧\",\n  \"grenada\": \"🇬🇩\",\n  \"georgia\": \"🇬🇪\",\n  \"french_guiana\": \"🇬🇫\",\n  \"guernsey\": \"🇬🇬\",\n  \"ghana\": \"🇬🇭\",\n  \"gibraltar\": \"🇬🇮\",\n  \"greenland\": \"🇬🇱\",\n  \"gambia\": \"🇬🇲\",\n  \"guinea\": \"🇬🇳\",\n  \"guadeloupe\": \"🇬🇵\",\n  \"equatorial_guinea\": \"🇬🇶\",\n  \"greece\": \"🇬🇷\",\n  \"south_georgia_south_sandwich_islands\": \"🇬🇸\",\n  \"guatemala\": \"🇬🇹\",\n  \"guam\": \"🇬🇺\",\n  \"guinea_bissau\": \"🇬🇼\",\n  \"guyana\": \"🇬🇾\",\n  \"hong_kong\": \"🇭🇰\",\n  \"heard_mcdonald_islands\": \"🇭🇲\",\n  \"honduras\": \"🇭🇳\",\n  \"croatia\": \"🇭🇷\",\n  \"haiti\": \"🇭🇹\",\n  \"hungary\": \"🇭🇺\",\n  \"canary_islands\": \"🇮🇨\",\n  \"indonesia\": \"🇮🇩\",\n  \"ireland\": \"🇮🇪\",\n  \"israel\": \"🇮🇱\",\n  \"isle_of_man\": \"🇮🇲\",\n  \"india\": \"🇮🇳\",\n  \"british_indian_ocean_territory\": \"🇮🇴\",\n  \"iraq\": \"🇮🇶\",\n  \"iran\": \"🇮🇷\",\n  \"iceland\": \"🇮🇸\",\n  \"it\": \"🇮🇹\",\n  \"jersey\": \"🇯🇪\",\n  \"jamaica\": \"🇯🇲\",\n  \"jordan\": \"🇯🇴\",\n  \"jp\": \"🇯🇵\",\n  \"kenya\": \"🇰🇪\",\n  \"kyrgyzstan\": \"🇰🇬\",\n  \"cambodia\": \"🇰🇭\",\n  \"kiribati\": \"🇰🇮\",\n  \"comoros\": \"🇰🇲\",\n  \"st_kitts_nevis\": \"🇰🇳\",\n  \"north_korea\": \"🇰🇵\",\n  \"kr\": \"🇰🇷\",\n  \"kuwait\": \"🇰🇼\",\n  \"cayman_islands\": \"🇰🇾\",\n  \"kazakhstan\": \"🇰🇿\",\n  \"laos\": \"🇱🇦\",\n  \"lebanon\": \"🇱🇧\",\n  \"st_lucia\": \"🇱🇨\",\n  \"liechtenstein\": \"🇱🇮\",\n  \"sri_lanka\": \"🇱🇰\",\n  \"liberia\": \"🇱🇷\",\n  \"lesotho\": \"🇱🇸\",\n  \"lithuania\": \"🇱🇹\",\n  \"luxembourg\": \"🇱🇺\",\n  \"latvia\": \"🇱🇻\",\n  \"libya\": \"🇱🇾\",\n  \"morocco\": \"🇲🇦\",\n  \"monaco\": \"🇲🇨\",\n  \"moldova\": \"🇲🇩\",\n  \"montenegro\": \"🇲🇪\",\n  \"st_martin\": \"🇲🇫\",\n  \"madagascar\": \"🇲🇬\",\n  \"marshall_islands\": \"🇲🇭\",\n  \"macedonia\": \"🇲🇰\",\n  \"mali\": \"🇲🇱\",\n  \"myanmar\": \"🇲🇲\",\n  \"mongolia\": \"🇲🇳\",\n  \"macau\": \"🇲🇴\",\n  \"northern_mariana_islands\": \"🇲🇵\",\n  \"martinique\": \"🇲🇶\",\n  \"mauritania\": \"🇲🇷\",\n  \"montserrat\": \"🇲🇸\",\n  \"malta\": \"🇲🇹\",\n  \"mauritius\": \"🇲🇺\",\n  \"maldives\": \"🇲🇻\",\n  \"malawi\": \"🇲🇼\",\n  \"mexico\": \"🇲🇽\",\n  \"malaysia\": \"🇲🇾\",\n  \"mozambique\": \"🇲🇿\",\n  \"namibia\": \"🇳🇦\",\n  \"new_caledonia\": \"🇳🇨\",\n  \"niger\": \"🇳🇪\",\n  \"norfolk_island\": \"🇳🇫\",\n  \"nigeria\": \"🇳🇬\",\n  \"nicaragua\": \"🇳🇮\",\n  \"netherlands\": \"🇳🇱\",\n  \"norway\": \"🇳🇴\",\n  \"nepal\": \"🇳🇵\",\n  \"nauru\": \"🇳🇷\",\n  \"niue\": \"🇳🇺\",\n  \"new_zealand\": \"🇳🇿\",\n  \"oman\": \"🇴🇲\",\n  \"panama\": \"🇵🇦\",\n  \"peru\": \"🇵🇪\",\n  \"french_polynesia\": \"🇵🇫\",\n  \"papua_new_guinea\": \"🇵🇬\",\n  \"philippines\": \"🇵🇭\",\n  \"pakistan\": \"🇵🇰\",\n  \"poland\": \"🇵🇱\",\n  \"st_pierre_miquelon\": \"🇵🇲\",\n  \"pitcairn_islands\": \"🇵🇳\",\n  \"puerto_rico\": \"🇵🇷\",\n  \"palestinian_territories\": \"🇵🇸\",\n  \"portugal\": \"🇵🇹\",\n  \"palau\": \"🇵🇼\",\n  \"paraguay\": \"🇵🇾\",\n  \"qatar\": \"🇶🇦\",\n  \"reunion\": \"🇷🇪\",\n  \"romania\": \"🇷🇴\",\n  \"serbia\": \"🇷🇸\",\n  \"ru\": \"🇷🇺\",\n  \"rwanda\": \"🇷🇼\",\n  \"saudi_arabia\": \"🇸🇦\",\n  \"solomon_islands\": \"🇸🇧\",\n  \"seychelles\": \"🇸🇨\",\n  \"sudan\": \"🇸🇩\",\n  \"sweden\": \"🇸🇪\",\n  \"singapore\": \"🇸🇬\",\n  \"st_helena\": \"🇸🇭\",\n  \"slovenia\": \"🇸🇮\",\n  \"svalbard_jan_mayen\": \"🇸🇯\",\n  \"slovakia\": \"🇸🇰\",\n  \"sierra_leone\": \"🇸🇱\",\n  \"san_marino\": \"🇸🇲\",\n  \"senegal\": \"🇸🇳\",\n  \"somalia\": \"🇸🇴\",\n  \"suriname\": \"🇸🇷\",\n  \"south_sudan\": \"🇸🇸\",\n  \"sao_tome_principe\": \"🇸🇹\",\n  \"el_salvador\": \"🇸🇻\",\n  \"sint_maarten\": \"🇸🇽\",\n  \"syria\": \"🇸🇾\",\n  \"swaziland\": \"🇸🇿\",\n  \"tristan_da_cunha\": \"🇹🇦\",\n  \"turks_caicos_islands\": \"🇹🇨\",\n  \"chad\": \"🇹🇩\",\n  \"french_southern_territories\": \"🇹🇫\",\n  \"togo\": \"🇹🇬\",\n  \"thailand\": \"🇹🇭\",\n  \"tajikistan\": \"🇹🇯\",\n  \"tokelau\": \"🇹🇰\",\n  \"timor_leste\": \"🇹🇱\",\n  \"turkmenistan\": \"🇹🇲\",\n  \"tunisia\": \"🇹🇳\",\n  \"tonga\": \"🇹🇴\",\n  \"tr\": \"🇹🇷\",\n  \"trinidad_tobago\": \"🇹🇹\",\n  \"tuvalu\": \"🇹🇻\",\n  \"taiwan\": \"🇹🇼\",\n  \"tanzania\": \"🇹🇿\",\n  \"ukraine\": \"🇺🇦\",\n  \"uganda\": \"🇺🇬\",\n  \"us_outlying_islands\": \"🇺🇲\",\n  \"united_nations\": \"🇺🇳\",\n  \"us\": \"🇺🇸\",\n  \"uruguay\": \"🇺🇾\",\n  \"uzbekistan\": \"🇺🇿\",\n  \"vatican_city\": \"🇻🇦\",\n  \"st_vincent_grenadines\": \"🇻🇨\",\n  \"venezuela\": \"🇻🇪\",\n  \"british_virgin_islands\": \"🇻🇬\",\n  \"us_virgin_islands\": \"🇻🇮\",\n  \"vietnam\": \"🇻🇳\",\n  \"vanuatu\": \"🇻🇺\",\n  \"wallis_futuna\": \"🇼🇫\",\n  \"samoa\": \"🇼🇸\",\n  \"kosovo\": \"🇽🇰\",\n  \"yemen\": \"🇾🇪\",\n  \"mayotte\": \"🇾🇹\",\n  \"south_africa\": \"🇿🇦\",\n  \"zambia\": \"🇿🇲\",\n  \"zimbabwe\": \"🇿🇼\",\n  \"england\": \"🏴󠁧󠁢󠁥󠁮󠁧󠁿\",\n  \"scotland\": \"🏴󠁧󠁢󠁳󠁣󠁴󠁿\",\n  \"wales\": \"🏴󠁧󠁢󠁷󠁬󠁳󠁿\",\n  \"accessibility\": \"♿\",\n  \"achoo\": \"🤧\",\n  \"airport\": \"🛄\",\n  \"alphabet\": \"🔤\",\n  \"amazed\": \"😲\",\n  \"america\": \"🇺🇸\",\n  \"announcement\": \"📢\",\n  \"annoyed\": \"😠\",\n  \"applause\": \"👏\",\n  \"approve\": \"👍\",\n  \"archery\": \"🏹\",\n  \"attack\": \"👊\",\n  \"aubergine\": \"🍆\",\n  \"autumn\": \"🍂\",\n  \"award\": \"🏆\",\n  \"bag\": \"👜\",\n  \"bags\": \"🛍️\",\n  \"bang\": \"❗\",\n  \"barf\": \"🤢\",\n  \"bawling\": \"😭\",\n  \"beach\": \"🐚\",\n  \"beauty\": \"💅\",\n  \"bicep\": \"💪\",\n  \"bicycle\": \"🚲\",\n  \"billiards\": \"🎱\",\n  \"blind\": \"🙈\",\n  \"block\": \"🚫\",\n  \"blow\": \"💨\",\n  \"blown\": \"🤯\",\n  \"bottle\": \"🍾\",\n  \"bouldering\": \"🧗\",\n  \"breakfast\": \"🍳\",\n  \"british\": \"🇬🇧\",\n  \"bronze\": \"🥉\",\n  \"bubbly\": \"🍾\",\n  \"bunny\": \"👯\",\n  \"burger\": \"🍔\",\n  \"burma\": \"🇲🇲\",\n  \"burn\": \"🔥\",\n  \"bury\": \"👎\",\n  \"business\": \"👨‍💼\",\n  \"cafe\": \"☕\",\n  \"call\": \"📲\",\n  \"celebration\": \"🥳\",\n  \"cheers\": \"🥂\",\n  \"chef\": \"👨‍🍳\",\n  \"china\": \"🇨🇳\",\n  \"chocolates\": \"💝\",\n  \"chop\": \"🔪\",\n  \"christmas\": \"🎅\",\n  \"cigarette\": \"🚬\",\n  \"classy\": \"🎩\",\n  \"coder\": \"👨‍💻\",\n  \"cold\": \"❄️\",\n  \"college\": \"🎓\",\n  \"comment\": \"💬\",\n  \"console\": \"🎮\",\n  \"contest\": \"🏆\",\n  \"controller\": \"🎮\",\n  \"crap\": \"💩\",\n  \"cream\": \"💰\",\n  \"cruise\": \"🛳️\",\n  \"crush\": \"😍\",\n  \"cut\": \"🔪\",\n  \"cutlery\": \"🍴\",\n  \"dad\": \"👨\",\n  \"danger\": \"💀\",\n  \"dead\": \"💀\",\n  \"deaf\": \"🙉\",\n  \"deal\": \"🤝\",\n  \"denied\": \"🙅\",\n  \"design\": \"🎨\",\n  \"desktop\": \"💻\",\n  \"dessert\": \"🍰\",\n  \"devil\": \"😈\",\n  \"diamond\": \"💎\",\n  \"dice\": \"🎲\",\n  \"dining\": \"🍽️\",\n  \"dinner\": \"🍽️\",\n  \"dinosaur\": \"🦕\",\n  \"directory\": \"📁\",\n  \"disapprove\": \"👎\",\n  \"disco\": \"🪩\",\n  \"disgusted\": \"🤢\",\n  \"doctor\": \"👨‍⚕️\",\n  \"document\": \"📜\",\n  \"drama\": \"🎭\",\n  \"dread\": \"🫠\",\n  \"drink\": \"🍸\",\n  \"drinks\": \"🍻\",\n  \"earphones\": \"🎧\",\n  \"education\": \"🎓\",\n  \"emergency\": \"🚨\",\n  \"engaged\": \"💍\",\n  \"environment\": \"♻️\",\n  \"espresso\": \"☕\",\n  \"evil\": \"😈\",\n  \"exercise\": \"🏃\",\n  \"explode\": \"💥\",\n  \"fast\": \"💨\",\n  \"father\": \"👨\",\n  \"festival\": \"🎆\",\n  \"film\": \"🎥\",\n  \"finish\": \"🏁\",\n  \"flag\": \"🇩🇪\",\n  \"flex\": \"💪\",\n  \"flight\": \"✈️\",\n  \"flirt\": \"😉\",\n  \"flower\": \"🌸\",\n  \"flowers\": \"💐\",\n  \"forbidden\": \"🚫\",\n  \"formal\": \"👔\",\n  \"fortune\": \"🔮\",\n  \"foul\": \"🤬\",\n  \"france\": \"🇫🇷\",\n  \"freezing\": \"🥶\",\n  \"french\": \"🇫🇷\",\n  \"fresh\": \"🆕\",\n  \"fruit\": \"🍌\",\n  \"funeral\": \"⚰️\",\n  \"fungus\": \"🍄\",\n  \"gambling\": \"🎲\",\n  \"game\": \"👾\",\n  \"gasp\": \"🫢\",\n  \"geek\": \"🤓\",\n  \"germ\": \"🦠\",\n  \"germany\": \"🇩🇪\",\n  \"girls\": \"👩\",\n  \"glasses\": \"🤓\",\n  \"global\": \"🌐\",\n  \"globe\": \"🌍\",\n  \"gold\": \"🏅\",\n  \"goodbye\": \"👋\",\n  \"goofy\": \"🤪\",\n  \"graduation\": \"👨‍🎓\",\n  \"graph\": \"📈\",\n  \"gratitude\": \"🥹\",\n  \"green\": \"🍵\",\n  \"groggy\": \"🥴\",\n  \"groom\": \"🤵\",\n  \"group\": \"👥\",\n  \"gym\": \"🏋️\",\n  \"haha\": \"😃\",\n  \"halloween\": \"👻\",\n  \"halt\": \"🙅\",\n  \"happy\": \"😀\",\n  \"hat\": \"🎩\",\n  \"health\": \"💉\",\n  \"hear\": \"👂\",\n  \"heat\": \"🥵\",\n  \"helmet\": \"👷\",\n  \"help\": \"🆘\",\n  \"highfive\": \"✋\",\n  \"hijab\": \"🧕\",\n  \"home\": \"👪\",\n  \"honk\": \"🪿\",\n  \"hooray\": \"🙌\",\n  \"hope\": \"🙏\",\n  \"hopeful\": \"🤞\",\n  \"horns\": \"😈\",\n  \"horror\": \"😱\",\n  \"hot\": \"😅\",\n  \"hurt\": \"🤕\",\n  \"hush\": \"🤐\",\n  \"ice\": \"🥶\",\n  \"idea\": \"💡\",\n  \"ignore\": \"🙈\",\n  \"ill\": \"😷\",\n  \"impressed\": \"😮\",\n  \"incoming\": \"📲\",\n  \"information\": \"💁‍♂️\",\n  \"international\": \"🌍\",\n  \"investigate\": \"🔬\",\n  \"invisible\": \"🫥\",\n  \"italy\": \"🇮🇹\",\n  \"ivory\": \"🇨🇮\",\n  \"justice\": \"👨‍⚖️\",\n  \"karl\": \"🌁\",\n  \"keeling\": \"🇨🇨\",\n  \"king\": \"👑\",\n  \"korea\": \"🇰🇷\",\n  \"laboratory\": \"🔬\",\n  \"laugh\": \"😄\",\n  \"launch\": \"🚀\",\n  \"law\": \"👮\",\n  \"leaf\": \"🍃\",\n  \"letter\": \"✉️\",\n  \"letters\": \"🔠\",\n  \"liar\": \"🤥\",\n  \"library\": \"📚\",\n  \"lick\": \"😋\",\n  \"life preserver\": \"🛟\",\n  \"light\": \"💡\",\n  \"lightning\": \"⚡\",\n  \"limit\": \"⛔\",\n  \"listen\": \"👂\",\n  \"location\": \"📌\",\n  \"lol\": \"🤣\",\n  \"look\": \"👀\",\n  \"love\": \"🥰\",\n  \"luck\": \"🤞\",\n  \"mad\": \"😠\",\n  \"makeup\": \"💄\",\n  \"manicure\": \"💅\",\n  \"marathon\": \"🏃\",\n  \"marriage\": \"🤵\",\n  \"meat\": \"🍗\",\n  \"medicine\": \"💊\",\n  \"meditation\": \"🧘\",\n  \"meh\": \"😐\",\n  \"metrics\": \"📈\",\n  \"milestone\": \"🏁\",\n  \"milk\": \"🍼\",\n  \"mind\": \"🤯\",\n  \"mobile\": \"📱\",\n  \"money\": \"💵\",\n  \"monster\": \"👹\",\n  \"morning\": \"⏰\",\n  \"movie\": \"🎦\",\n  \"mule\": \"🫏\",\n  \"music\": \"🎶\",\n  \"mustache\": \"👨\",\n  \"needle\": \"💉\",\n  \"nervous\": \"😟\",\n  \"newborn\": \"👶\",\n  \"night\": \"🌙\",\n  \"noodle\": \"🍜\",\n  \"note\": \"📝\",\n  \"notification\": \"🔔\",\n  \"number\": \"#️⃣\",\n  \"numbers\": \"🔢\",\n  \"nurse\": \"👨‍⚕️\",\n  \"nursing\": \"🤱\",\n  \"off\": \"🔕\",\n  \"oops\": \"😨\",\n  \"orbit\": \"🛰️\",\n  \"paella\": \"🥘\",\n  \"paint\": \"🎨\",\n  \"painter\": \"👨‍🎨\",\n  \"pants\": \"👖\",\n  \"parents\": \"👪\",\n  \"party\": \"🎂\",\n  \"password\": \"🔑\",\n  \"pasta\": \"🍝\",\n  \"peace\": \"✌️\",\n  \"perfect\": \"💯\",\n  \"pet\": \"🐶\",\n  \"phew\": \"😥\",\n  \"photo\": \"📷\",\n  \"piano\": \"🎹\",\n  \"pirate\": \"☠️\",\n  \"plant\": \"🌱\",\n  \"play\": \"🎮\",\n  \"please\": \"🙏\",\n  \"pleased\": \"😄\",\n  \"podcast\": \"🎙️\",\n  \"poison\": \"💀\",\n  \"pool\": \"🎱\",\n  \"power\": \"✊\",\n  \"praise\": \"👏\",\n  \"prank\": \"😜\",\n  \"present\": \"🎁\",\n  \"press\": \"📰\",\n  \"pride\": \"🏳️‍🌈\",\n  \"private\": \"🔒\",\n  \"professor\": \"👨‍🏫\",\n  \"prosper\": \"🖖\",\n  \"proud\": \"😊\",\n  \"puppy\": \"🥺\",\n  \"queen\": \"👑\",\n  \"quiet\": \"🤭\",\n  \"rain\": \"🌂\",\n  \"recorder\": \"🪈\",\n  \"research\": \"👨‍🔬\",\n  \"respect\": \"🫡\",\n  \"retro\": \"👾\",\n  \"return\": \"↩️\",\n  \"rich\": \"🤑\",\n  \"rockstar\": \"👨‍🎤\",\n  \"royal\": \"🤴\",\n  \"russia\": \"🇷🇺\",\n  \"sad\": \"😢\",\n  \"sarcasm\": \"🫠\",\n  \"save\": \"💾\",\n  \"scared\": \"😨\",\n  \"schedule\": \"📅\",\n  \"science\": \"🔬\",\n  \"score\": \"💯\",\n  \"screen\": \"💻\",\n  \"sea\": \"🐳\",\n  \"search\": \"🔍\",\n  \"security\": \"🔒\",\n  \"see\": \"👀\",\n  \"semaphore\": \"🚦\",\n  \"sensu\": \"🪭\",\n  \"shaker\": \"🪇\",\n  \"shiny\": \"✨\",\n  \"shipping\": \"📦\",\n  \"shock\": \"🫢\",\n  \"shocked\": \"😨\",\n  \"shoot\": \"🔫\",\n  \"shuffle\": \"🔀\",\n  \"sick\": \"😷\",\n  \"signal\": \"📡\",\n  \"silence\": \"🤫\",\n  \"silly\": \"😜\",\n  \"silver\": \"🥈\",\n  \"sing\": \"🎤\",\n  \"skating\": \"⛸️\",\n  \"skyline\": \"🏙️\",\n  \"sleuth\": \"🕵️\",\n  \"slow\": \"🐢\",\n  \"smartphone\": \"📱\",\n  \"smell\": \"👃\",\n  \"smug\": \"😏\",\n  \"sneaker\": \"👟\",\n  \"spa\": \"💆\",\n  \"space\": \"👨‍🚀\",\n  \"spain\": \"🇪🇸\",\n  \"speechless\": \"😯\",\n  \"speed\": \"🐎\",\n  \"spicy\": \"🌶️\",\n  \"spock\": \"🖖\",\n  \"sport\": \"👟\",\n  \"sports\": \"⚽\",\n  \"spring\": \"🌸\",\n  \"stats\": \"📊\",\n  \"steamy\": \"🧖\",\n  \"stone\": \"🗿\",\n  \"stop\": \"✋\",\n  \"strong\": \"💪\",\n  \"struggling\": \"😣\",\n  \"stunned\": \"😧\",\n  \"subscription\": \"💳\",\n  \"summer\": \"🍹\",\n  \"surprise\": \"😮\",\n  \"suspicious\": \"🤨\",\n  \"sweating\": \"🥵\",\n  \"sweet\": \"🍬\",\n  \"swirl\": \"🌀\",\n  \"sync\": \"🔄\",\n  \"tag\": \"🏷️\",\n  \"target\": \"🎯\",\n  \"taste\": \"👅\",\n  \"team\": \"👥\",\n  \"tear\": \"😢\",\n  \"tears\": \"😂\",\n  \"tempura\": \"🍤\",\n  \"thanks\": \"🙇\",\n  \"thanksgiving\": \"🦃\",\n  \"theater\": \"🎭\",\n  \"thunder\": \"⚡\",\n  \"time\": \"⌛\",\n  \"tired\": \"😪\",\n  \"toast\": \"🍞\",\n  \"tool\": \"🔨\",\n  \"tracks\": \"👣\",\n  \"trademark\": \"™️\",\n  \"trash\": \"🗑️\",\n  \"travel\": \"🗺️\",\n  \"u5272\": \"🈹\",\n  \"u5408\": \"🈴\",\n  \"u55b6\": \"🈺\",\n  \"u6307\": \"🈯\",\n  \"u6708\": \"🈷️\",\n  \"u6709\": \"🈶\",\n  \"u7121\": \"🈚\",\n  \"u7533\": \"🈸\",\n  \"u7981\": \"🈲\",\n  \"u7a7a\": \"🈳\",\n  \"ufo\": \"👽\",\n  \"united\": \"🇺🇸\",\n  \"university\": \"🎓\",\n  \"upset\": \"😫\",\n  \"user\": \"👤\",\n  \"users\": \"👥\",\n  \"vacation\": \"🍹\",\n  \"victory\": \"✌️\",\n  \"video\": \"🎥\",\n  \"volume\": \"🔇\",\n  \"wacky\": \"🤪\",\n  \"water\": \"💦\",\n  \"weapon\": \"🔫\",\n  \"weather\": \"☀️\",\n  \"whew\": \"😌\",\n  \"whine\": \"😫\",\n  \"whisky\": \"🥃\",\n  \"whoops\": \"🤭\",\n  \"wifi\": \"📶\",\n  \"wind\": \"💨\",\n  \"winner\": \"🏆\",\n  \"winter\": \"❄️\",\n  \"wip\": \"🚧\",\n  \"wish\": \"🙏\",\n  \"wizard\": \"🧙\",\n  \"workout\": \"💦\",\n  \"world\": \"🌍\",\n  \"wow\": \"😮\",\n  \"yes\": \"🆗\",\n  \"zoom\": \"🔍\"\n};\n\n// Emoticons -> Emoji mapping.\n//\n// (!) Some patterns skipped, to avoid collisions\n// without increase matcher complicity. Than can change in future.\n//\n// Places to look for more emoticons info:\n//\n// - http://en.wikipedia.org/wiki/List_of_emoticons#Western\n// - https://github.com/wooorm/emoticon/blob/master/Support.md\n// - http://factoryjoe.com/projects/emoticons/\n//\n\n/* eslint-disable key-spacing */\n\nvar emojies_shortcuts = {\n  angry:            ['>:(', '>:-('],\n  blush:            [':\")', ':-\")'],\n  broken_heart:     ['</3', '<\\\\3'],\n  // :\\ and :-\\ not used because of conflict with markdown escaping\n  confused:         [':/', ':-/'], // twemoji shows question\n  cry:              [\":'(\", \":'-(\", ':,(', ':,-('],\n  frowning:         [':(', ':-('],\n  heart:            ['<3'],\n  imp:              [']:(', ']:-('],\n  innocent:         ['o:)', 'O:)', 'o:-)', 'O:-)', '0:)', '0:-)'],\n  joy:              [\":')\", \":'-)\", ':,)', ':,-)', \":'D\", \":'-D\", ':,D', ':,-D'],\n  kissing:          [':*', ':-*'],\n  laughing:         ['x-)', 'X-)'],\n  neutral_face:     [':|', ':-|'],\n  open_mouth:       [':o', ':-o', ':O', ':-O'],\n  rage:             [':@', ':-@'],\n  smile:            [':D', ':-D'],\n  smiley:           [':)', ':-)'],\n  smiling_imp:      [']:)', ']:-)'],\n  sob:              [\":,'(\", \":,'-(\", ';(', ';-('],\n  stuck_out_tongue: [':P', ':-P'],\n  sunglasses:       ['8-)', 'B-)'],\n  sweat:            [',:(', ',:-('],\n  sweat_smile:      [',:)', ',:-)'],\n  unamused:         [':s', ':-S', ':z', ':-Z', ':$', ':-$'],\n  wink:             [';)', ';-)']\n};\n\nfunction emoji_html (tokens, idx /*, options, env */) {\n  return tokens[idx].content\n}\n\n// Emojies & shortcuts replacement logic.\n//\n// Note: In theory, it could be faster to parse :smile: in inline chain and\n// leave only shortcuts here. But, who care...\n//\nfunction create_rule (md, emojies, shortcuts, scanRE, replaceRE) {\n  const arrayReplaceAt = md.utils.arrayReplaceAt;\n  const ucm = md.utils.lib.ucmicro;\n  const has = md.utils.has;\n  const ZPCc = new RegExp([ucm.Z.source, ucm.P.source, ucm.Cc.source].join('|'));\n\n  function splitTextToken (text, level, Token) {\n    let last_pos = 0;\n    const nodes = [];\n\n    text.replace(replaceRE, function (match, offset, src) {\n      let emoji_name;\n      // Validate emoji name\n      if (has(shortcuts, match)) {\n        // replace shortcut with full name\n        emoji_name = shortcuts[match];\n\n        // Don't allow letters before any shortcut (as in no \":/\" in http://)\n        if (offset > 0 && !ZPCc.test(src[offset - 1])) return\n\n        // Don't allow letters after any shortcut\n        if (offset + match.length < src.length && !ZPCc.test(src[offset + match.length])) {\n          return\n        }\n      } else {\n        emoji_name = match.slice(1, -1);\n      }\n\n      // Add new tokens to pending list\n      if (offset > last_pos) {\n        const token = new Token('text', '', 0);\n        token.content = text.slice(last_pos, offset);\n        nodes.push(token);\n      }\n\n      const token = new Token('emoji', '', 0);\n      token.markup = emoji_name;\n      token.content = emojies[emoji_name];\n      nodes.push(token);\n\n      last_pos = offset + match.length;\n    });\n\n    if (last_pos < text.length) {\n      const token = new Token('text', '', 0);\n      token.content = text.slice(last_pos);\n      nodes.push(token);\n    }\n\n    return nodes\n  }\n\n  return function emoji_replace (state) {\n    let token;\n    const blockTokens = state.tokens;\n    let autolinkLevel = 0;\n\n    for (let j = 0, l = blockTokens.length; j < l; j++) {\n      if (blockTokens[j].type !== 'inline') { continue }\n      let tokens = blockTokens[j].children;\n\n      // We scan from the end, to keep position when new tags added.\n      // Use reversed logic in links start/end match\n      for (let i = tokens.length - 1; i >= 0; i--) {\n        token = tokens[i];\n\n        if (token.type === 'link_open' || token.type === 'link_close') {\n          if (token.info === 'auto') { autolinkLevel -= token.nesting; }\n        }\n\n        if (token.type === 'text' && autolinkLevel === 0 && scanRE.test(token.content)) {\n          // replace current node\n          blockTokens[j].children = tokens = arrayReplaceAt(\n            tokens, i, splitTextToken(token.content, token.level, state.Token)\n          );\n        }\n      }\n    }\n  }\n}\n\n// Convert input options to more useable format\n// and compile search regexp\n\nfunction quoteRE (str) {\n  return str.replace(/[.?*+^$[\\]\\\\(){}|-]/g, '\\\\$&')\n}\n\nfunction normalize_opts (options) {\n  let emojies = options.defs;\n\n  // Filter emojies by whitelist, if needed\n  if (options.enabled.length) {\n    emojies = Object.keys(emojies).reduce((acc, key) => {\n      if (options.enabled.indexOf(key) >= 0) acc[key] = emojies[key];\n      return acc\n    }, {});\n  }\n\n  // Flatten shortcuts to simple object: { alias: emoji_name }\n  const shortcuts = Object.keys(options.shortcuts).reduce((acc, key) => {\n    // Skip aliases for filtered emojies, to reduce regexp\n    if (!emojies[key]) return acc\n\n    if (Array.isArray(options.shortcuts[key])) {\n      options.shortcuts[key].forEach(alias => { acc[alias] = key; });\n      return acc\n    }\n\n    acc[options.shortcuts[key]] = key;\n    return acc\n  }, {});\n\n  const keys = Object.keys(emojies);\n  let names;\n\n  // If no definitions are given, return empty regex to avoid replacements with 'undefined'.\n  if (keys.length === 0) {\n    names = '^$';\n  } else {\n    // Compile regexp\n    names = keys\n      .map(name => { return `:${name}:` })\n      .concat(Object.keys(shortcuts))\n      .sort()\n      .reverse()\n      .map(name => { return quoteRE(name) })\n      .join('|');\n  }\n  const scanRE = RegExp(names);\n  const replaceRE = RegExp(names, 'g');\n\n  return {\n    defs: emojies,\n    shortcuts,\n    scanRE,\n    replaceRE\n  }\n}\n\nfunction emoji_plugin$1 (md, options) {\n  const defaults = {\n    defs: {},\n    shortcuts: {},\n    enabled: []\n  };\n\n  const opts = normalize_opts(md.utils.assign({}, defaults, options || {}));\n\n  md.renderer.rules.emoji = emoji_html;\n\n  md.core.ruler.after(\n    'linkify',\n    'emoji',\n    create_rule(md, opts.defs, opts.shortcuts, opts.scanRE, opts.replaceRE)\n  );\n}\n\nfunction emoji_plugin (md, options) {\n  const defaults = {\n    defs: emojies_defs,\n    shortcuts: emojies_shortcuts,\n    enabled: []\n  };\n\n  const opts = md.utils.assign({}, defaults, options || {});\n\n  emoji_plugin$1(md, opts);\n}\n\nexport { emoji_plugin as default };\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/markdown-it/plugin/markdown-it-footnote/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/**\n * markdown-it-footnote\n * @home   : https://github.com/markdown-it/markdown-it-footnote\n * @branch : master\n * @commit : fe6c169c72b9f4d6656b10aa449128456f5a990e\n */\n\nimport plugin from './markdown-it-footnote';\nexport default plugin;"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/markdown-it/plugin/markdown-it-footnote/markdown-it-footnote.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/*! markdown-it-footnote 4.0.0 https://github.com/markdown-it/markdown-it-footnote @license MIT */\n// Process footnotes\n/// /////////////////////////////////////////////////////////////////////////////\n// Renderer partials\nfunction render_footnote_anchor_name(tokens, idx, options, env /*, slf */) {\n    const n = Number(tokens[idx].meta.id + 1).toString();\n    let prefix = \"\";\n    if (typeof env.docId === \"string\") prefix = `-${env.docId}-`;\n    return prefix + n;\n}\n\nfunction render_footnote_caption(tokens, idx /*, options, env, slf */) {\n    let n = Number(tokens[idx].meta.id + 1).toString();\n    if (tokens[idx].meta.subId > 0) n += `:${tokens[idx].meta.subId}`;\n    return `[${n}]`;\n}\n\nfunction render_footnote_ref(tokens, idx, options, env, slf) {\n    const id = slf.rules.footnote_anchor_name(tokens, idx, options, env, slf);\n    const caption = slf.rules.footnote_caption(tokens, idx, options, env, slf);\n    let refid = id;\n    if (tokens[idx].meta.subId > 0) refid += `:${tokens[idx].meta.subId}`;\n    return `<sup class=\"footnote-ref\"><a href=\"#fn${id}\" id=\"fnref${refid}\">${caption}</a></sup>`;\n}\n\nfunction render_footnote_block_open(tokens, idx, options) {\n    return (options.xhtmlOut ? '<hr class=\"footnotes-sep\" />\\n' : '<hr class=\"footnotes-sep\">\\n') + '<section class=\"footnotes\">\\n' + '<ol class=\"footnotes-list\">\\n';\n}\n\nfunction render_footnote_block_close() {\n    return \"</ol>\\n</section>\\n\";\n}\n\nfunction render_footnote_open(tokens, idx, options, env, slf) {\n    let id = slf.rules.footnote_anchor_name(tokens, idx, options, env, slf);\n    if (tokens[idx].meta.subId > 0) id += `:${tokens[idx].meta.subId}`;\n    return `<li id=\"fn${id}\" class=\"footnote-item\">`;\n}\n\nfunction render_footnote_close() {\n    return \"</li>\\n\";\n}\n\nfunction render_footnote_anchor(tokens, idx, options, env, slf) {\n    let id = slf.rules.footnote_anchor_name(tokens, idx, options, env, slf);\n    if (tokens[idx].meta.subId > 0) id += `:${tokens[idx].meta.subId}`\n    /* ↩ with escape code to prevent display as Apple Emoji on iOS */;\n    return ` <a href=\"#fnref${id}\" class=\"footnote-backref\">\\u21a9\\ufe0e</a>`;\n}\n\nfunction footnote_plugin(md) {\n    const parseLinkLabel = md.helpers.parseLinkLabel;\n    const isSpace = md.utils.isSpace;\n    md.renderer.rules.footnote_ref = render_footnote_ref;\n    md.renderer.rules.footnote_block_open = render_footnote_block_open;\n    md.renderer.rules.footnote_block_close = render_footnote_block_close;\n    md.renderer.rules.footnote_open = render_footnote_open;\n    md.renderer.rules.footnote_close = render_footnote_close;\n    md.renderer.rules.footnote_anchor = render_footnote_anchor;\n    // helpers (only used in other rules, no tokens are attached to those)\n    md.renderer.rules.footnote_caption = render_footnote_caption;\n    md.renderer.rules.footnote_anchor_name = render_footnote_anchor_name;\n    // Process footnote block definition\n    function footnote_def(state, startLine, endLine, silent) {\n        const start = state.bMarks[startLine] + state.tShift[startLine];\n        const max = state.eMarks[startLine];\n        // line should be at least 5 chars - \"[^x]:\"\n        if (start + 4 > max) return false;\n        if (state.src.charCodeAt(start) !== 91 /* [ */) return false;\n        if (state.src.charCodeAt(start + 1) !== 94 /* ^ */) return false;\n        let pos;\n        for (pos = start + 2; pos < max; pos++) {\n            if (state.src.charCodeAt(pos) === 32) return false;\n            if (state.src.charCodeAt(pos) === 93 /* ] */) {\n                break;\n            }\n        }\n        if (pos === start + 2) return false;\n        // no empty footnote labels\n        if (pos + 1 >= max || state.src.charCodeAt(++pos) !== 58 /* : */) return false;\n        if (silent) return true;\n        pos++;\n        if (!state.env.footnotes) state.env.footnotes = {};\n        if (!state.env.footnotes.refs) state.env.footnotes.refs = {};\n        const label = state.src.slice(start + 2, pos - 2);\n        state.env.footnotes.refs[`:${label}`] = -1;\n        const token_fref_o = new state.Token(\"footnote_reference_open\", \"\", 1);\n        token_fref_o.meta = {\n            label: label\n        };\n        token_fref_o.level = state.level++;\n        state.tokens.push(token_fref_o);\n        const oldBMark = state.bMarks[startLine];\n        const oldTShift = state.tShift[startLine];\n        const oldSCount = state.sCount[startLine];\n        const oldParentType = state.parentType;\n        const posAfterColon = pos;\n        const initial = state.sCount[startLine] + pos - (state.bMarks[startLine] + state.tShift[startLine]);\n        let offset = initial;\n        while (pos < max) {\n            const ch = state.src.charCodeAt(pos);\n            if (isSpace(ch)) {\n                if (ch === 9) {\n                    offset += 4 - offset % 4;\n                } else {\n                    offset++;\n                }\n            } else {\n                break;\n            }\n            pos++;\n        }\n        state.tShift[startLine] = pos - posAfterColon;\n        state.sCount[startLine] = offset - initial;\n        state.bMarks[startLine] = posAfterColon;\n        state.blkIndent += 4;\n        state.parentType = \"footnote\";\n        if (state.sCount[startLine] < state.blkIndent) {\n            state.sCount[startLine] += state.blkIndent;\n        }\n        state.md.block.tokenize(state, startLine, endLine, true);\n        state.parentType = oldParentType;\n        state.blkIndent -= 4;\n        state.tShift[startLine] = oldTShift;\n        state.sCount[startLine] = oldSCount;\n        state.bMarks[startLine] = oldBMark;\n        const token_fref_c = new state.Token(\"footnote_reference_close\", \"\", -1);\n        token_fref_c.level = --state.level;\n        state.tokens.push(token_fref_c);\n        return true;\n    }\n    // Process inline footnotes (^[...])\n    function footnote_inline(state, silent) {\n        const max = state.posMax;\n        const start = state.pos;\n        if (start + 2 >= max) return false;\n        if (state.src.charCodeAt(start) !== 94 /* ^ */) return false;\n        if (state.src.charCodeAt(start + 1) !== 91 /* [ */) return false;\n        const labelStart = start + 2;\n        const labelEnd = parseLinkLabel(state, start + 1);\n        // parser failed to find ']', so it's not a valid note\n        if (labelEnd < 0) return false;\n        // We found the end of the link, and know for a fact it's a valid link;\n        // so all that's left to do is to call tokenizer.\n\n        if (!silent) {\n            if (!state.env.footnotes) state.env.footnotes = {};\n            if (!state.env.footnotes.list) state.env.footnotes.list = [];\n            const footnoteId = state.env.footnotes.list.length;\n            const tokens = [];\n            state.md.inline.parse(state.src.slice(labelStart, labelEnd), state.md, state.env, tokens);\n            const token = state.push(\"footnote_ref\", \"\", 0);\n            token.meta = {\n                id: footnoteId\n            };\n            state.env.footnotes.list[footnoteId] = {\n                content: state.src.slice(labelStart, labelEnd),\n                tokens: tokens\n            };\n        }\n        state.pos = labelEnd + 1;\n        state.posMax = max;\n        return true;\n    }\n    // Process footnote references ([^...])\n    function footnote_ref(state, silent) {\n        const max = state.posMax;\n        const start = state.pos;\n        // should be at least 4 chars - \"[^x]\"\n        if (start + 3 > max) return false;\n        if (!state.env.footnotes || !state.env.footnotes.refs) return false;\n        if (state.src.charCodeAt(start) !== 91 /* [ */) return false;\n        if (state.src.charCodeAt(start + 1) !== 94 /* ^ */) return false;\n        let pos;\n        for (pos = start + 2; pos < max; pos++) {\n            if (state.src.charCodeAt(pos) === 32) return false;\n            if (state.src.charCodeAt(pos) === 10) return false;\n            if (state.src.charCodeAt(pos) === 93 /* ] */) {\n                break;\n            }\n        }\n        if (pos === start + 2) return false;\n        // no empty footnote labels\n        if (pos >= max) return false;\n        pos++;\n        const label = state.src.slice(start + 2, pos - 1);\n        if (typeof state.env.footnotes.refs[`:${label}`] === \"undefined\") return false;\n        if (!silent) {\n            if (!state.env.footnotes.list) state.env.footnotes.list = [];\n            let footnoteId;\n            if (state.env.footnotes.refs[`:${label}`] < 0) {\n                footnoteId = state.env.footnotes.list.length;\n                state.env.footnotes.list[footnoteId] = {\n                    label: label,\n                    count: 0\n                };\n                state.env.footnotes.refs[`:${label}`] = footnoteId;\n            } else {\n                footnoteId = state.env.footnotes.refs[`:${label}`];\n            }\n            const footnoteSubId = state.env.footnotes.list[footnoteId].count;\n            state.env.footnotes.list[footnoteId].count++;\n            const token = state.push(\"footnote_ref\", \"\", 0);\n            token.meta = {\n                id: footnoteId,\n                subId: footnoteSubId,\n                label: label\n            };\n        }\n        state.pos = pos;\n        state.posMax = max;\n        return true;\n    }\n    // Glue footnote tokens to end of token stream\n    function footnote_tail(state) {\n        let tokens;\n        let current;\n        let currentLabel;\n        let insideRef = false;\n        const refTokens = {};\n        if (!state.env.footnotes) {\n            return;\n        }\n        state.tokens = state.tokens.filter(function(tok) {\n            if (tok.type === \"footnote_reference_open\") {\n                insideRef = true;\n                current = [];\n                currentLabel = tok.meta.label;\n                return false;\n            }\n            if (tok.type === \"footnote_reference_close\") {\n                insideRef = false;\n                // prepend ':' to avoid conflict with Object.prototype members\n                refTokens[\":\" + currentLabel] = current;\n                return false;\n            }\n            if (insideRef) {\n                current.push(tok);\n            }\n            return !insideRef;\n        });\n        if (!state.env.footnotes.list) {\n            return;\n        }\n        const list = state.env.footnotes.list;\n        state.tokens.push(new state.Token(\"footnote_block_open\", \"\", 1));\n        for (let i = 0, l = list.length; i < l; i++) {\n            const token_fo = new state.Token(\"footnote_open\", \"\", 1);\n            token_fo.meta = {\n                id: i,\n                label: list[i].label\n            };\n            state.tokens.push(token_fo);\n            if (list[i].tokens) {\n                tokens = [];\n                const token_po = new state.Token(\"paragraph_open\", \"p\", 1);\n                token_po.block = true;\n                tokens.push(token_po);\n                const token_i = new state.Token(\"inline\", \"\", 0);\n                token_i.children = list[i].tokens;\n                token_i.content = list[i].content;\n                tokens.push(token_i);\n                const token_pc = new state.Token(\"paragraph_close\", \"p\", -1);\n                token_pc.block = true;\n                tokens.push(token_pc);\n            } else if (list[i].label) {\n                tokens = refTokens[`:${list[i].label}`];\n            }\n            if (tokens) state.tokens = state.tokens.concat(tokens);\n            let lastParagraph;\n            if (state.tokens[state.tokens.length - 1].type === \"paragraph_close\") {\n                lastParagraph = state.tokens.pop();\n            } else {\n                lastParagraph = null;\n            }\n            const t = list[i].count > 0 ? list[i].count : 1;\n            for (let j = 0; j < t; j++) {\n                const token_a = new state.Token(\"footnote_anchor\", \"\", 0);\n                token_a.meta = {\n                    id: i,\n                    subId: j,\n                    label: list[i].label\n                };\n                state.tokens.push(token_a);\n            }\n            if (lastParagraph) {\n                state.tokens.push(lastParagraph);\n            }\n            state.tokens.push(new state.Token(\"footnote_close\", \"\", -1));\n        }\n        state.tokens.push(new state.Token(\"footnote_block_close\", \"\", -1));\n    }\n    md.block.ruler.before(\"reference\", \"footnote_def\", footnote_def, {\n        alt: [ \"paragraph\", \"reference\" ]\n    });\n    md.inline.ruler.after(\"image\", \"footnote_inline\", footnote_inline);\n    md.inline.ruler.after(\"footnote_inline\", \"footnote_ref\", footnote_ref);\n    md.core.ruler.after(\"inline\", \"footnote_tail\", footnote_tail);\n}\n\nexport { footnote_plugin as default };\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/markdown-it/plugin/markdown-it-sub/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/**\n * markdown-it-sub\n * @home   : https://github.com/markdown-it/markdown-it-sub\n * @branch : master\n * @commit : 422e93885b3c611234d602aa795f3d75a62cc93e\n */\n\nimport plugin from './markdown-it-sub';\nexport default plugin;"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/markdown-it/plugin/markdown-it-sub/markdown-it-sub.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/*! markdown-it-sub 2.0.0 https://github.com/markdown-it/markdown-it-sub @license MIT */\n// Process ~subscript~\n// same as UNESCAPE_MD_RE plus a space\nconst UNESCAPE_RE = /\\\\([ \\\\!\"#$%&'()*+,./:;<=>?@[\\]^_`{|}~-])/g;\n\nfunction subscript(state, silent) {\n  const max = state.posMax;\n  const start = state.pos;\n  if (state.src.charCodeAt(start) !== 126 /* ~ */) {\n    return false;\n  }\n  if (silent) {\n    return false;\n  }\n // don't run any pairs in validation mode\n    if (start + 2 >= max) {\n    return false;\n  }\n  state.pos = start + 1;\n  let found = false;\n  while (state.pos < max) {\n    if (state.src.charCodeAt(state.pos) === 126 /* ~ */) {\n      found = true;\n      break;\n    }\n    state.md.inline.skipToken(state);\n  }\n  if (!found || start + 1 === state.pos) {\n    state.pos = start;\n    return false;\n  }\n  const content = state.src.slice(start + 1, state.pos);\n  // don't allow unescaped spaces/newlines inside\n    if (content.match(/(^|[^\\\\])(\\\\\\\\)*\\s/)) {\n    state.pos = start;\n    return false;\n  }\n  // found!\n    state.posMax = state.pos;\n  state.pos = start + 1;\n  // Earlier we checked !silent, but this implementation does not need it\n    const token_so = state.push(\"sub_open\", \"sub\", 1);\n  token_so.markup = \"~\";\n  const token_t = state.push(\"text\", \"\", 0);\n  token_t.content = content.replace(UNESCAPE_RE, \"$1\");\n  const token_sc = state.push(\"sub_close\", \"sub\", -1);\n  token_sc.markup = \"~\";\n  state.pos = state.posMax + 1;\n  state.posMax = max;\n  return true;\n}\n\nfunction sub_plugin(md) {\n  md.inline.ruler.after(\"emphasis\", \"sub\", subscript);\n}\n\nexport { sub_plugin as default };\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/markdown-it/plugin/markdown-it-sup/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/**\n * markdown-it-sup\n * @home   : https://github.com/markdown-it/markdown-it-sup\n * @branch : master\n * @commit : 7a644d5276afa0229b569a8e8b789aa6f6325c1d\n */\n\nimport plugin from './markdown-it-sup';\nexport default plugin;"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/markdown-it/plugin/markdown-it-sup/markdown-it-sup.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/*! markdown-it-sup 2.0.0 https://github.com/markdown-it/markdown-it-sup @license MIT */\n// Process ^superscript^\n// same as UNESCAPE_MD_RE plus a space\nconst UNESCAPE_RE = /\\\\([ \\\\!\"#$%&'()*+,./:;<=>?@[\\]^_`{|}~-])/g;\n\nfunction superscript(state, silent) {\n  const max = state.posMax;\n  const start = state.pos;\n  if (state.src.charCodeAt(start) !== 94 /* ^ */) {\n    return false;\n  }\n  if (silent) {\n    return false;\n  }\n // don't run any pairs in validation mode\n    if (start + 2 >= max) {\n    return false;\n  }\n  state.pos = start + 1;\n  let found = false;\n  while (state.pos < max) {\n    if (state.src.charCodeAt(state.pos) === 94 /* ^ */) {\n      found = true;\n      break;\n    }\n    state.md.inline.skipToken(state);\n  }\n  if (!found || start + 1 === state.pos) {\n    state.pos = start;\n    return false;\n  }\n  const content = state.src.slice(start + 1, state.pos);\n  // don't allow unescaped spaces/newlines inside\n    if (content.match(/(^|[^\\\\])(\\\\\\\\)*\\s/)) {\n    state.pos = start;\n    return false;\n  }\n  // found!\n    state.posMax = state.pos;\n  state.pos = start + 1;\n  // Earlier we checked !silent, but this implementation does not need it\n    const token_so = state.push(\"sup_open\", \"sup\", 1);\n  token_so.markup = \"^\";\n  const token_t = state.push(\"text\", \"\", 0);\n  token_t.content = content.replace(UNESCAPE_RE, \"$1\");\n  const token_sc = state.push(\"sup_close\", \"sup\", -1);\n  token_sc.markup = \"^\";\n  state.pos = state.posMax + 1;\n  state.posMax = max;\n  return true;\n}\n\nfunction sup_plugin(md) {\n  md.inline.ruler.after(\"emphasis\", \"sup\", superscript);\n}\n\nexport { sup_plugin as default };\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/markdown-it/plugin/markdown-it-task-lists/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/**\n * markdown-it-task-lists\n * @home   : https://github.com/revin/markdown-it-task-lists\n * @branch : master\n * @commit : 1e68dd719b9c68be65fdb74f5c5e6d94d214447e\n */\n\nimport plugin from './markdown-it-task-lists';\nexport default plugin;\nexport interface IPluginTaskListOption {\n  enabled?: boolean;\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/markdown-it/plugin/markdown-it-task-lists/markdown-it-task-lists.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/*! markdown-it-task-lists 2.1.1 https://github.com/[object Object] @license ISC */\n// Markdown-it plugin to render GitHub-style task lists; see\n// https://github.com/blog/1375-task-lists-in-gfm-issues-pulls-comments\n// https://github.com/blog/1825-task-lists-in-all-markdown-documents\nvar disableCheckboxes = true;\n\nvar useLabelWrapper = false;\n\nvar useLabelAfter = false;\n\nfunction _plugin(md, options) {\n  if (options) {\n    disableCheckboxes = !options.enabled;\n    useLabelWrapper = !!options.label;\n    useLabelAfter = !!options.labelAfter;\n  }\n  md.core.ruler.after(\"inline\", \"github-task-lists\", function(state) {\n    var tokens = state.tokens;\n    for (var i = 2; i < tokens.length; i++) {\n      if (isTodoItem(tokens, i)) {\n        todoify(tokens[i], state.Token);\n        attrSet(tokens[i - 2], \"class\", \"task-list-item\" + (!disableCheckboxes ? \" enabled\" : \"\"));\n        attrSet(tokens[parentToken(tokens, i - 2)], \"class\", \"contains-task-list\");\n      }\n    }\n  });\n};\n\nfunction attrSet(token, name, value) {\n  var index = token.attrIndex(name);\n  var attr = [ name, value ];\n  if (index < 0) {\n    token.attrPush(attr);\n  } else {\n    token.attrs[index] = attr;\n  }\n}\n\nfunction parentToken(tokens, index) {\n  var targetLevel = tokens[index].level - 1;\n  for (var i = index - 1; i >= 0; i--) {\n    if (tokens[i].level === targetLevel) {\n      return i;\n    }\n  }\n  return -1;\n}\n\nfunction isTodoItem(tokens, index) {\n  return isInline(tokens[index]) && isParagraph(tokens[index - 1]) && isListItem(tokens[index - 2]) && startsWithTodoMarkdown(tokens[index]);\n}\n\nfunction todoify(token, TokenConstructor) {\n  token.children.unshift(makeCheckbox(token, TokenConstructor));\n  token.children[1].content = token.children[1].content.slice(3);\n  token.content = token.content.slice(3);\n  if (useLabelWrapper) {\n    if (useLabelAfter) {\n      token.children.pop();\n      // Use large random number as id property of the checkbox.\n            var id = \"task-item-\" + Math.ceil(Math.random() * (1e4 * 1e3) - 1e3);\n      token.children[0].content = token.children[0].content.slice(0, -1) + ' id=\"' + id + '\">';\n      token.children.push(afterLabel(token.content, id, TokenConstructor));\n    } else {\n      token.children.unshift(beginLabel(TokenConstructor));\n      token.children.push(endLabel(TokenConstructor));\n    }\n  }\n}\n\nfunction makeCheckbox(token, TokenConstructor) {\n  var checkbox = new TokenConstructor(\"html_inline\", \"\", 0);\n  var disabledAttr = disableCheckboxes ? ' disabled=\"\" ' : \"\";\n  if (token.content.indexOf(\"[ ] \") === 0) {\n    checkbox.content = '<input class=\"task-list-item-checkbox\"' + disabledAttr + 'type=\"checkbox\" />';\n  } else if (token.content.indexOf(\"[x] \") === 0 || token.content.indexOf(\"[X] \") === 0) {\n    checkbox.content = '<input class=\"task-list-item-checkbox\" checked=\"\"' + disabledAttr + 'type=\"checkbox\" />';\n  }\n  return checkbox;\n}\n\n// these next two functions are kind of hacky; probably should really be a\n// true block-level token with .tag=='label'\nfunction beginLabel(TokenConstructor) {\n  var token = new TokenConstructor(\"html_inline\", \"\", 0);\n  token.content = \"<label>\";\n  return token;\n}\n\nfunction endLabel(TokenConstructor) {\n  var token = new TokenConstructor(\"html_inline\", \"\", 0);\n  token.content = \"</label>\";\n  return token;\n}\n\nfunction afterLabel(content, id, TokenConstructor) {\n  var token = new TokenConstructor(\"html_inline\", \"\", 0);\n  token.content = '<label class=\"task-list-item-label\" for=\"' + id + '\">' + content + \"</label>\";\n  token.attrs = [ {\n    for: id\n  } ];\n  return token;\n}\n\nfunction isInline(token) {\n  return token.type === \"inline\";\n}\n\nfunction isParagraph(token) {\n  return token.type === \"paragraph_open\";\n}\n\nfunction isListItem(token) {\n  return token.type === \"list_item_open\";\n}\n\nfunction startsWithTodoMarkdown(token) {\n  // leading whitespace in a list item is already trimmed off by markdown-it\n  return token.content.indexOf(\"[ ] \") === 0 || token.content.indexOf(\"[x] \") === 0 || token.content.indexOf(\"[X] \") === 0;\n}\n\nexport { _plugin as default };"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/markdown-it/plugin/vscode-markdown-it-katex/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/**\n * vscode-markdown-it-katex\n * @home   : https://github.com/microsoft/vscode-markdown-it-katex\n * @branch : master\n * @commit : efd01d8e61b4aca4d8b1489d15dd29f641663119\n */\n\nimport plugin from './vscode-markdown-it-katex';\nexport default plugin;\n\nexport interface IPluginKatexOption {\n  throwOnError?: boolean;\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/markdown-it/plugin/vscode-markdown-it-katex/vscode-markdown-it-katex.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n\"use strict\";\n// var __importDefault = (this && this.__importDefault) || function (mod) {\n//     return (mod && mod.__esModule) ? mod : { \"default\": mod };\n// };\n// Object.defineProperty(exports, \"__esModule\", { value: true });\n// const katex_1 = __importDefault(require(\"katex\"));\n/**\n * Test if potential opening or closing delimiter\n */\nfunction isValidInlineDelim(state, pos) {\n    const prevChar = state.src[pos - 1];\n    const char = state.src[pos];\n    const nextChar = state.src[pos + 1];\n    if (char !== '$') {\n        return { can_open: false, can_close: false };\n    }\n    let canOpen = false;\n    let canClose = false;\n    if (prevChar !== '$' && prevChar !== '\\\\' && (prevChar === undefined || isWhitespace(prevChar) || !isWordCharacterOrNumber(prevChar))) {\n        canOpen = true;\n    }\n    if (nextChar !== '$' && (nextChar == undefined || isWhitespace(nextChar) || !isWordCharacterOrNumber(nextChar))) {\n        canClose = true;\n    }\n    return { can_open: canOpen, can_close: canClose };\n}\nfunction isWhitespace(char) {\n    return /^\\s$/u.test(char);\n}\nfunction isWordCharacterOrNumber(char) {\n    return /^[\\w\\d]$/u.test(char);\n}\nfunction isValidBlockDelim(state, pos) {\n    const prevChar = state.src[pos - 1];\n    const char = state.src[pos];\n    const nextChar = state.src[pos + 1];\n    const nextCharPlus1 = state.src[pos + 2];\n    if (char === '$'\n        && prevChar !== '$' && prevChar !== '\\\\'\n        && nextChar === '$'\n        && nextCharPlus1 !== '$') {\n        return { can_open: true, can_close: true };\n    }\n    return { can_open: false, can_close: false };\n}\nfunction inlineMath(state, silent) {\n    if (state.src[state.pos] !== \"$\") {\n        return false;\n    }\n    const lastToken = state.tokens.at(-1);\n    if (lastToken?.type === 'html_inline') {\n        // We may be inside of inside of inline html\n        if (/^<\\w+.+[^/]>$/.test(lastToken.content)) {\n            return false;\n        }\n    }\n    let res = isValidInlineDelim(state, state.pos);\n    if (!res.can_open) {\n        if (!silent) {\n            state.pending += \"$\";\n        }\n        state.pos += 1;\n        return true;\n    }\n    // First check for and bypass all properly escaped delimieters\n    // This loop will assume that the first leading backtick can not\n    // be the first character in state.src, which is known since\n    // we have found an opening delimieter already.\n    let start = state.pos + 1;\n    let match = start;\n    let pos;\n    while ((match = state.src.indexOf(\"$\", match)) !== -1) {\n        // Found potential $, look for escapes, pos will point to\n        // first non escape when complete\n        pos = match - 1;\n        while (state.src[pos] === \"\\\\\") {\n            pos -= 1;\n        }\n        // Even number of escapes, potential closing delimiter found\n        if (((match - pos) % 2) == 1) {\n            break;\n        }\n        match += 1;\n    }\n    // No closing delimter found.  Consume $ and continue.\n    if (match === -1) {\n        if (!silent) {\n            state.pending += \"$\";\n        }\n        state.pos = start;\n        return true;\n    }\n    // Check if we have empty content, ie: $$.  Do not parse.\n    if (match - start === 0) {\n        if (!silent) {\n            state.pending += \"$$\";\n        }\n        state.pos = start + 1;\n        return true;\n    }\n    // Check for valid closing delimiter\n    res = isValidInlineDelim(state, match);\n    if (!res.can_close) {\n        if (!silent) {\n            state.pending += \"$\";\n        }\n        state.pos = start;\n        return true;\n    }\n    if (!silent) {\n        const token = state.push('math_inline', 'math', 0);\n        token.markup = \"$\";\n        token.content = state.src.slice(start, match);\n    }\n    state.pos = match + 1;\n    return true;\n}\nfunction blockMath(state, start, end, silent) {\n    return false  //disabled\n\n    let found = false;\n    let pos = state.bMarks[start] + state.tShift[start];\n    let max = state.eMarks[start];\n    if (pos + 2 > max) {\n        return false;\n    }\n    if (state.src.slice(pos, pos + 2) !== '$$') {\n        return false;\n    }\n    pos += 2;\n    let firstLine = state.src.slice(pos, max);\n    // Check for single line expressions such as `$$x$$`\n    const endIndexes = [...firstLine.matchAll(/\\$\\$/g)];\n    if (endIndexes.length === 1 && endIndexes[0].index === firstLine.length - 2) {\n        // Fake inline expression such as `$$x$$`\n        // We actually want to treat this as a block instead of inline\n        firstLine = firstLine.trim().slice(0, -2);\n        found = true;\n    }\n    else if (endIndexes.length > 1) {\n        // Multiple $$ in the first line, so this is not a block\n        // Should be treated as inline instead\n        return false;\n    }\n    if (silent) {\n        return true;\n    }\n    let lastLine;\n    let next;\n    let lastPos;\n    for (next = start; !found;) {\n        next++;\n        if (next >= end) {\n            break;\n        }\n        pos = state.bMarks[next] + state.tShift[next];\n        max = state.eMarks[next];\n        if (pos < max && state.tShift[next] < state.blkIndent) {\n            // non-empty line with negative indent should stop the list:\n            break;\n        }\n        if (state.src.slice(pos, max).trim().slice(-2) === '$$') {\n            lastPos = state.src.slice(0, max).lastIndexOf('$$');\n            lastLine = state.src.slice(pos, lastPos);\n            found = true;\n        }\n        else if (state.src.slice(pos, max).trim().includes('$$')) {\n            lastPos = state.src.slice(0, max).trim().indexOf('$$');\n            lastLine = state.src.slice(pos, lastPos);\n            found = true;\n        }\n    }\n    state.line = next + 1;\n    const token = state.push('math_block', 'math', 0);\n    token.block = true;\n    token.content = (firstLine && firstLine.trim() ? firstLine + '\\n' : '')\n        + state.getLines(start + 1, next, state.tShift[start], true)\n        + (lastLine && lastLine.trim() ? lastLine : '');\n    token.map = [start, state.line];\n    token.markup = '$$';\n    return true;\n}\nfunction blockBareMath(state, start, end, silent) {\n    return false  //disabled\n\n    const startPos = state.bMarks[start] + state.tShift[start];\n    const startMax = state.eMarks[start];\n    const firstLine = state.src.slice(startPos, startMax);\n    const beginMatch = firstLine.match(/^\\s*\\\\begin\\s*\\{([^{}]+)\\}/);\n    if (!beginMatch) {\n        return false;\n    }\n    if (start > 0) {\n        // Previous line must be blank for bare blocks. There are instead handled by inlineBareBlock\n        const previousStart = state.bMarks[start - 1] + state.tShift[start - 1];\n        const previousEnd = state.eMarks[start - 1];\n        const previousLine = state.src.slice(previousStart, previousEnd);\n        if (!/^\\s*$/.test(previousLine)) {\n            return false;\n        }\n    }\n    if (silent) {\n        return true;\n    }\n    const beginEndStack = [];\n    let next = start;\n    let lastLine;\n    let found = false;\n    outer: for (; !found; next++) {\n        if (next >= end) {\n            break;\n        }\n        const pos = state.bMarks[next] + state.tShift[next];\n        const max = state.eMarks[next];\n        if (pos < max && state.tShift[next] < state.blkIndent) {\n            // non-empty line with negative indent should stop the list:\n            break;\n        }\n        const line = state.src.slice(pos, max);\n        for (const match of line.matchAll(/(\\\\begin|\\\\end)\\s*\\{([^{}]+)\\}/g)) {\n            if (match[1] === '\\\\begin') {\n                beginEndStack.push(match[2].trim());\n            }\n            else if (match[1] === '\\\\end') {\n                beginEndStack.pop();\n                if (!beginEndStack.length) {\n                    lastLine = state.src.slice(pos, max);\n                    found = true;\n                    break outer;\n                }\n            }\n        }\n    }\n    state.line = next + 1;\n    const token = state.push('math_block', 'math', 0);\n    token.block = true;\n    token.content = (state.getLines(start, next, state.tShift[start], true) + (lastLine ?? '')).trim();\n    token.map = [start, state.line];\n    token.markup = '$$';\n    return true;\n}\nfunction inlineMathBlock(state, silent) {\n    var start, match, token, res, pos;\n    if (state.src.slice(state.pos, state.pos + 2) !== \"$$\") {\n        return false;\n    }\n    res = isValidBlockDelim(state, state.pos);\n    if (!res.can_open) {\n        if (!silent) {\n            state.pending += \"$$\";\n        }\n        state.pos += 2;\n        return true;\n    }\n    // First check for and bypass all properly escaped delimieters\n    // This loop will assume that the first leading backtick can not\n    // be the first character in state.src, which is known since\n    // we have found an opening delimieter already.\n    start = state.pos + 2;\n    match = start;\n    while ((match = state.src.indexOf(\"$$\", match)) !== -1) {\n        // Found potential $$, look for escapes, pos will point to\n        // first non escape when complete\n        pos = match - 1;\n        while (state.src[pos] === \"\\\\\") {\n            pos -= 1;\n        }\n        // Even number of escapes, potential closing delimiter found\n        if (((match - pos) % 2) == 1) {\n            break;\n        }\n        match += 2;\n    }\n    // No closing delimter found.  Consume $$ and continue.\n    if (match === -1) {\n        if (!silent) {\n            state.pending += \"$$\";\n        }\n        state.pos = start;\n        return true;\n    }\n    // Check if we have empty content, ie: $$$$.  Do not parse.\n    if (match - start === 0) {\n        if (!silent) {\n            state.pending += \"$$$$\";\n        }\n        state.pos = start + 2;\n        return true;\n    }\n    // Check for valid closing delimiter\n    res = isValidBlockDelim(state, match);\n    if (!res.can_close) {\n        if (!silent) {\n            state.pending += \"$$\";\n        }\n        state.pos = start;\n        return true;\n    }\n    if (!silent) {\n        token = state.push('math_block', 'math', 0);\n        token.block = true;\n        token.markup = \"$$\";\n        token.content = state.src.slice(start, match);\n    }\n    state.pos = match + 2;\n    return true;\n}\nfunction inlineBareBlock(state, silent) {\n    const text = state.src.slice(state.pos);\n    // Make sure this is not a normal bare block\n    if (!/^\\n\\\\begin/.test(text)) {\n        return false;\n    }\n    state.pos += 1;\n    if (silent) {\n        return true;\n    }\n    const lines = text.split(/\\n/g).slice(1);\n    let foundLine;\n    const beginEndStack = [];\n    outer: for (var i = 0; i < lines.length; ++i) {\n        const line = lines[i];\n        for (const match of line.matchAll(/(\\\\begin|\\\\end)\\s*\\{([^{}]+)\\}/g)) {\n            if (match[1] === '\\\\begin') {\n                beginEndStack.push(match[2].trim());\n            }\n            else if (match[1] === '\\\\end') {\n                beginEndStack.pop();\n                if (!beginEndStack.length) {\n                    foundLine = i;\n                    break outer;\n                }\n            }\n        }\n    }\n    if (typeof foundLine === 'undefined') {\n        return false;\n    }\n    const endIndex = lines.slice(0, foundLine + 1).reduce((p, c) => p + c.length, 0) + foundLine + 1;\n    const token = state.push('math_inline_bare_block', 'math', 0);\n    token.block = true;\n    token.markup = \"$$\";\n    token.content = text.slice(1, endIndex);\n    state.pos = state.pos + endIndex;\n    return true;\n}\n// For any html block that contains math, replace the html block token with new tokens that separate out\n// the html blocks from the math\nfunction handleMathInHtml(state, mathType, mathMarkup, mathRegex) {\n    const tokens = state.tokens;\n    for (let index = tokens.length - 1; index >= 0; index--) {\n        const currentToken = tokens[index];\n        const newTokens = [];\n        if (currentToken.type !== \"html_block\") {\n            continue;\n        }\n        const content = currentToken.content;\n        // Process for each math referenced within the html block\n        for (const match of content.matchAll(mathRegex)) {\n            if (!match.groups) {\n                continue;\n            }\n            const html_before_math = match.groups.html_before_math;\n            const math = match.groups.math;\n            const html_after_math = match.groups.html_after_math;\n            if (html_before_math) {\n                newTokens.push({ ...currentToken, type: \"html_block\", map: null, content: html_before_math });\n            }\n            if (math) {\n                newTokens.push({\n                    ...currentToken,\n                    type: mathType,\n                    map: null,\n                    content: math,\n                    markup: mathMarkup,\n                    block: true,\n                    tag: \"math\",\n                });\n            }\n            if (html_after_math) {\n                newTokens.push({ ...currentToken, type: \"html_block\", map: null, content: html_after_math });\n            }\n        }\n        // Replace the original html_block token with the newly expanded tokens\n        if (newTokens.length > 0) {\n            tokens.splice(index, 1, ...newTokens);\n        }\n    }\n    return true;\n}\nfunction escapeHtml(unsafe) {\n    return unsafe\n        .replace(/&/g, \"&amp;\")\n        .replace(/</g, \"&lt;\")\n        .replace(/>/g, \"&gt;\")\n        .replace(/\"/g, \"&quot;\")\n        .replace(/'/g, \"&#039;\");\n}\nfunction default_1(md, options) {\n    // const katex = options?.katex ?? katex_1.default;\n    const katex = options?.katex;\n    const enableBareBlocks = options?.enableBareBlocks;\n    const enableMathBlockInHtml = options?.enableMathBlockInHtml;\n    const enableMathInlineInHtml = options?.enableMathInlineInHtml;\n    const enableFencedBlocks = options?.enableFencedBlocks;\n    // #region Parsing\n    md.inline.ruler.after('escape', 'math_inline', inlineMath);\n    md.inline.ruler.after('escape', 'math_inline_block', inlineMathBlock);\n    if (enableBareBlocks) {\n        md.inline.ruler.before('text', 'math_inline_bare_block', inlineBareBlock);\n    }\n    md.block.ruler.after('blockquote', 'math_block', (state, start, end, silent) => {\n        if (enableBareBlocks && blockBareMath(state, start, end, silent)) {\n            return true;\n        }\n        return blockMath(state, start, end, silent);\n    }, {\n        alt: ['paragraph', 'reference', 'blockquote', 'list']\n    });\n    // Regex to capture any html prior to math block, the math block (single or multi line), and any html after the math block\n    const math_block_within_html_regex = /(?<html_before_math>[\\s\\S]*?)\\$\\$(?<math>[\\s\\S]+?)\\$\\$(?<html_after_math>(?:(?!\\$\\$[\\s\\S]+?\\$\\$)[\\s\\S])*)/gm;\n    // Regex to capture any html prior to math inline, the math inline (single line), and any html after the math inline\n    const math_inline_within_html_regex = /(?<html_before_math>[\\s\\S]*?)\\$(?<math>.*?)\\$(?<html_after_math>(?:(?!\\$.*?\\$)[\\s\\S])*)/gm;\n    if (enableMathBlockInHtml) {\n        md.core.ruler.push(\"math_block_in_html_block\", (state) => {\n            return handleMathInHtml(state, \"math_block\", \"$$\", math_block_within_html_regex);\n        });\n    }\n    if (enableMathInlineInHtml) {\n        md.core.ruler.push(\"math_inline_in_html_block\", (state) => {\n            return handleMathInHtml(state, \"math_inline\", \"$\", math_inline_within_html_regex);\n        });\n    }\n    // #endregion\n    // #region Rendering\n    const katexInline = (latex) => {\n        const displayMode = /\\\\begin\\{(align|equation|gather|cd|alignat)\\}/ig.test(latex);\n        try {\n            return katex.renderToString(latex, { ...options, displayMode });\n        }\n        catch (error) {\n            if (options?.throwOnError) {\n                console.log(error);\n            }\n            return `<span class=\"katex-error\" title=\"${escapeHtml(latex)}\">${escapeHtml(error + '')}</span>`;\n        }\n    };\n    const inlineRenderer = (tokens, idx) => {\n        const content = tokens[idx].content;\n        // To support expression like $`1+1 = 2`$, check if the the expression has leading and trailing \"`\".\n        const hasBacktick = content.length > 2 && content[0] === \"`\" && content[content.length - 1] === \"`\";\n        const sanitized = hasBacktick ? content.slice(1, -1) : content;\n        return katexInline(sanitized);\n    };\n    const katexBlockRenderer = (latex) => {\n        try {\n            return `<p class=\"katex-block\">${katex.renderToString(latex, { ...options, displayMode: true })}</p>`;\n        }\n        catch (error) {\n            if (options?.throwOnError) {\n                console.log(error);\n            }\n            return `<p class=\"katex-block katex-error\" title=\"${escapeHtml(latex)}\">${escapeHtml(error + '')}</p>`;\n        }\n    };\n    const blockRenderer = (tokens, idx) => {\n        return katexBlockRenderer(tokens[idx].content) + '\\n';\n    };\n    md.renderer.rules.math_inline = inlineRenderer;\n    md.renderer.rules.math_inline_block = blockRenderer;\n    md.renderer.rules.math_inline_bare_block = blockRenderer;\n    md.renderer.rules.math_block = blockRenderer;\n    if (enableFencedBlocks) {\n        const mathLanguageId = 'math';\n        const originalFenceRenderer = md.renderer.rules.fence;\n        md.renderer.rules.fence = function (tokens, idx, options, env, self) {\n            const token = tokens[idx];\n            if (token.info.trim().toLowerCase() === mathLanguageId && enableFencedBlocks) {\n                return katexBlockRenderer(token.content) + '\\n';\n            }\n            else {\n                return originalFenceRenderer?.call(this, tokens, idx, options, env, self) || '';\n            }\n        };\n    }\n    // #endregion\n}\n// exports.default = default_1;\nexport { default_1 as default }\n;\n//# sourceMappingURL=index.js.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/markdown-it/src/markdown-it.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/*! markdown-it 14.1.0 https://github.com/markdown-it/markdown-it @license MIT */\n/* eslint-disable no-bitwise */\nconst decodeCache = {};\n\nfunction getDecodeCache(exclude) {\n  let cache = decodeCache[exclude];\n  if (cache) {\n    return cache;\n  }\n  cache = decodeCache[exclude] = [];\n  for (let i = 0; i < 128; i++) {\n    const ch = String.fromCharCode(i);\n    cache.push(ch);\n  }\n  for (let i = 0; i < exclude.length; i++) {\n    const ch = exclude.charCodeAt(i);\n    cache[ch] = \"%\" + (\"0\" + ch.toString(16).toUpperCase()).slice(-2);\n  }\n  return cache;\n}\n\n// Decode percent-encoded string.\n\nfunction decode$1(string, exclude) {\n  if (typeof exclude !== \"string\") {\n    exclude = decode$1.defaultChars;\n  }\n  const cache = getDecodeCache(exclude);\n  return string.replace(/(%[a-f0-9]{2})+/gi, function(seq) {\n    let result = \"\";\n    for (let i = 0, l = seq.length; i < l; i += 3) {\n      const b1 = parseInt(seq.slice(i + 1, i + 3), 16);\n      if (b1 < 128) {\n        result += cache[b1];\n        continue;\n      }\n      if ((b1 & 224) === 192 && i + 3 < l) {\n        // 110xxxxx 10xxxxxx\n        const b2 = parseInt(seq.slice(i + 4, i + 6), 16);\n        if ((b2 & 192) === 128) {\n          const chr = b1 << 6 & 1984 | b2 & 63;\n          if (chr < 128) {\n            result += \"\\ufffd\\ufffd\";\n          } else {\n            result += String.fromCharCode(chr);\n          }\n          i += 3;\n          continue;\n        }\n      }\n      if ((b1 & 240) === 224 && i + 6 < l) {\n        // 1110xxxx 10xxxxxx 10xxxxxx\n        const b2 = parseInt(seq.slice(i + 4, i + 6), 16);\n        const b3 = parseInt(seq.slice(i + 7, i + 9), 16);\n        if ((b2 & 192) === 128 && (b3 & 192) === 128) {\n          const chr = b1 << 12 & 61440 | b2 << 6 & 4032 | b3 & 63;\n          if (chr < 2048 || chr >= 55296 && chr <= 57343) {\n            result += \"\\ufffd\\ufffd\\ufffd\";\n          } else {\n            result += String.fromCharCode(chr);\n          }\n          i += 6;\n          continue;\n        }\n      }\n      if ((b1 & 248) === 240 && i + 9 < l) {\n        // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx\n        const b2 = parseInt(seq.slice(i + 4, i + 6), 16);\n        const b3 = parseInt(seq.slice(i + 7, i + 9), 16);\n        const b4 = parseInt(seq.slice(i + 10, i + 12), 16);\n        if ((b2 & 192) === 128 && (b3 & 192) === 128 && (b4 & 192) === 128) {\n          let chr = b1 << 18 & 1835008 | b2 << 12 & 258048 | b3 << 6 & 4032 | b4 & 63;\n          if (chr < 65536 || chr > 1114111) {\n            result += \"\\ufffd\\ufffd\\ufffd\\ufffd\";\n          } else {\n            chr -= 65536;\n            result += String.fromCharCode(55296 + (chr >> 10), 56320 + (chr & 1023));\n          }\n          i += 9;\n          continue;\n        }\n      }\n      result += \"\\ufffd\";\n    }\n    return result;\n  });\n}\n\ndecode$1.defaultChars = \";/?:@&=+$,#\";\n\ndecode$1.componentChars = \"\";\n\nconst encodeCache = {};\n\n// Create a lookup array where anything but characters in `chars` string\n// and alphanumeric chars is percent-encoded.\n\nfunction getEncodeCache(exclude) {\n  let cache = encodeCache[exclude];\n  if (cache) {\n    return cache;\n  }\n  cache = encodeCache[exclude] = [];\n  for (let i = 0; i < 128; i++) {\n    const ch = String.fromCharCode(i);\n    if (/^[0-9a-z]$/i.test(ch)) {\n      // always allow unencoded alphanumeric characters\n      cache.push(ch);\n    } else {\n      cache.push(\"%\" + (\"0\" + i.toString(16).toUpperCase()).slice(-2));\n    }\n  }\n  for (let i = 0; i < exclude.length; i++) {\n    cache[exclude.charCodeAt(i)] = exclude[i];\n  }\n  return cache;\n}\n\n// Encode unsafe characters with percent-encoding, skipping already\n// encoded sequences.\n\n//  - string       - string to encode\n//  - exclude      - list of characters to ignore (in addition to a-zA-Z0-9)\n//  - keepEscaped  - don't encode '%' in a correct escape sequence (default: true)\n\nfunction encode$1(string, exclude, keepEscaped) {\n  if (typeof exclude !== \"string\") {\n    // encode(string, keepEscaped)\n    keepEscaped = exclude;\n    exclude = encode$1.defaultChars;\n  }\n  if (typeof keepEscaped === \"undefined\") {\n    keepEscaped = true;\n  }\n  const cache = getEncodeCache(exclude);\n  let result = \"\";\n  for (let i = 0, l = string.length; i < l; i++) {\n    const code = string.charCodeAt(i);\n    if (keepEscaped && code === 37 /* % */ && i + 2 < l) {\n      if (/^[0-9a-f]{2}$/i.test(string.slice(i + 1, i + 3))) {\n        result += string.slice(i, i + 3);\n        i += 2;\n        continue;\n      }\n    }\n    if (code < 128) {\n      result += cache[code];\n      continue;\n    }\n    if (code >= 55296 && code <= 57343) {\n      if (code >= 55296 && code <= 56319 && i + 1 < l) {\n        const nextCode = string.charCodeAt(i + 1);\n        if (nextCode >= 56320 && nextCode <= 57343) {\n          result += encodeURIComponent(string[i] + string[i + 1]);\n          i++;\n          continue;\n        }\n      }\n      result += \"%EF%BF%BD\";\n      continue;\n    }\n    result += encodeURIComponent(string[i]);\n  }\n  return result;\n}\n\nencode$1.defaultChars = \";/?:@&=+$,-_.!~*'()#\";\n\nencode$1.componentChars = \"-_.!~*'()\";\n\nfunction format(url) {\n  let result = \"\";\n  result += url.protocol || \"\";\n  result += url.slashes ? \"//\" : \"\";\n  result += url.auth ? url.auth + \"@\" : \"\";\n  if (url.hostname && url.hostname.indexOf(\":\") !== -1) {\n    // ipv6 address\n    result += \"[\" + url.hostname + \"]\";\n  } else {\n    result += url.hostname || \"\";\n  }\n  result += url.port ? \":\" + url.port : \"\";\n  result += url.pathname || \"\";\n  result += url.search || \"\";\n  result += url.hash || \"\";\n  return result;\n}\n\n// Copyright Joyent, Inc. and other Node contributors.\n\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// Changes from joyent/node:\n\n// 1. No leading slash in paths,\n//    e.g. in `url.parse('http://foo?bar')` pathname is ``, not `/`\n\n// 2. Backslashes are not replaced with slashes,\n//    so `http:\\\\example.org\\` is treated like a relative path\n\n// 3. Trailing colon is treated like a part of the path,\n//    i.e. in `http://example.org:foo` pathname is `:foo`\n\n// 4. Nothing is URL-encoded in the resulting object,\n//    (in joyent/node some chars in auth and paths are encoded)\n\n// 5. `url.parse()` does not have `parseQueryString` argument\n\n// 6. Removed extraneous result properties: `host`, `path`, `query`, etc.,\n//    which can be constructed using other parts of the url.\n\nfunction Url() {\n  this.protocol = null;\n  this.slashes = null;\n  this.auth = null;\n  this.port = null;\n  this.hostname = null;\n  this.hash = null;\n  this.search = null;\n  this.pathname = null;\n}\n\n// Reference: RFC 3986, RFC 1808, RFC 2396\n// define these here so at least they only have to be\n// compiled once on the first module load.\nconst protocolPattern = /^([a-z0-9.+-]+:)/i;\n\nconst portPattern = /:[0-9]*$/;\n\n// Special case for a simple path URL\n/* eslint-disable-next-line no-useless-escape */ const simplePathPattern = /^(\\/\\/?(?!\\/)[^\\?\\s]*)(\\?[^\\s]*)?$/;\n\n// RFC 2396: characters reserved for delimiting URLs.\n// We actually just auto-escape these.\nconst delims = [ \"<\", \">\", '\"', \"`\", \" \", \"\\r\", \"\\n\", \"\\t\" ];\n\n// RFC 2396: characters not allowed for various reasons.\nconst unwise = [ \"{\", \"}\", \"|\", \"\\\\\", \"^\", \"`\" ].concat(delims);\n\n// Allowed by RFCs, but cause of XSS attacks.  Always escape these.\nconst autoEscape = [ \"'\" ].concat(unwise);\n\n// Characters that are never ever allowed in a hostname.\n// Note that any invalid chars are also handled, but these\n// are the ones that are *expected* to be seen, so we fast-path\n// them.\nconst nonHostChars = [ \"%\", \"/\", \"?\", \";\", \"#\" ].concat(autoEscape);\n\nconst hostEndingChars = [ \"/\", \"?\", \"#\" ];\n\nconst hostnameMaxLen = 255;\n\nconst hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/;\n\nconst hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/;\n\n// protocols that can allow \"unsafe\" and \"unwise\" chars.\n// protocols that never have a hostname.\nconst hostlessProtocol = {\n  javascript: true,\n  \"javascript:\": true\n};\n\n// protocols that always contain a // bit.\nconst slashedProtocol = {\n  http: true,\n  https: true,\n  ftp: true,\n  gopher: true,\n  file: true,\n  \"http:\": true,\n  \"https:\": true,\n  \"ftp:\": true,\n  \"gopher:\": true,\n  \"file:\": true\n};\n\nfunction urlParse(url, slashesDenoteHost) {\n  if (url && url instanceof Url) return url;\n  const u = new Url;\n  u.parse(url, slashesDenoteHost);\n  return u;\n}\n\nUrl.prototype.parse = function(url, slashesDenoteHost) {\n  let lowerProto, hec, slashes;\n  let rest = url;\n  // trim before proceeding.\n  // This is to support parse stuff like \"  http://foo.com  \\n\"\n    rest = rest.trim();\n  if (!slashesDenoteHost && url.split(\"#\").length === 1) {\n    // Try fast path regexp\n    const simplePath = simplePathPattern.exec(rest);\n    if (simplePath) {\n      this.pathname = simplePath[1];\n      if (simplePath[2]) {\n        this.search = simplePath[2];\n      }\n      return this;\n    }\n  }\n  let proto = protocolPattern.exec(rest);\n  if (proto) {\n    proto = proto[0];\n    lowerProto = proto.toLowerCase();\n    this.protocol = proto;\n    rest = rest.substr(proto.length);\n  }\n  // figure out if it's got a host\n  // user@server is *always* interpreted as a hostname, and url\n  // resolution will treat //foo/bar as host=foo,path=bar because that's\n  // how the browser resolves relative URLs.\n  /* eslint-disable-next-line no-useless-escape */  if (slashesDenoteHost || proto || rest.match(/^\\/\\/[^@\\/]+@[^@\\/]+/)) {\n    slashes = rest.substr(0, 2) === \"//\";\n    if (slashes && !(proto && hostlessProtocol[proto])) {\n      rest = rest.substr(2);\n      this.slashes = true;\n    }\n  }\n  if (!hostlessProtocol[proto] && (slashes || proto && !slashedProtocol[proto])) {\n    // there's a hostname.\n    // the first instance of /, ?, ;, or # ends the host.\n    // If there is an @ in the hostname, then non-host chars *are* allowed\n    // to the left of the last @ sign, unless some host-ending character\n    // comes *before* the @-sign.\n    // URLs are obnoxious.\n    // ex:\n    // http://a@b@c/ => user:a@b host:c\n    // http://a@b?@c => user:a host:c path:/?@c\n    // v0.12 TODO(isaacs): This is not quite how Chrome does things.\n    // Review our test case against browsers more comprehensively.\n    // find the first instance of any hostEndingChars\n    let hostEnd = -1;\n    for (let i = 0; i < hostEndingChars.length; i++) {\n      hec = rest.indexOf(hostEndingChars[i]);\n      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) {\n        hostEnd = hec;\n      }\n    }\n    // at this point, either we have an explicit point where the\n    // auth portion cannot go past, or the last @ char is the decider.\n        let auth, atSign;\n    if (hostEnd === -1) {\n      // atSign can be anywhere.\n      atSign = rest.lastIndexOf(\"@\");\n    } else {\n      // atSign must be in auth portion.\n      // http://a@b/c@d => host:b auth:a path:/c@d\n      atSign = rest.lastIndexOf(\"@\", hostEnd);\n    }\n    // Now we have a portion which is definitely the auth.\n    // Pull that off.\n        if (atSign !== -1) {\n      auth = rest.slice(0, atSign);\n      rest = rest.slice(atSign + 1);\n      this.auth = auth;\n    }\n    // the host is the remaining to the left of the first non-host char\n        hostEnd = -1;\n    for (let i = 0; i < nonHostChars.length; i++) {\n      hec = rest.indexOf(nonHostChars[i]);\n      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) {\n        hostEnd = hec;\n      }\n    }\n    // if we still have not hit it, then the entire thing is a host.\n        if (hostEnd === -1) {\n      hostEnd = rest.length;\n    }\n    if (rest[hostEnd - 1] === \":\") {\n      hostEnd--;\n    }\n    const host = rest.slice(0, hostEnd);\n    rest = rest.slice(hostEnd);\n    // pull out port.\n        this.parseHost(host);\n    // we've indicated that there is a hostname,\n    // so even if it's empty, it has to be present.\n        this.hostname = this.hostname || \"\";\n    // if hostname begins with [ and ends with ]\n    // assume that it's an IPv6 address.\n        const ipv6Hostname = this.hostname[0] === \"[\" && this.hostname[this.hostname.length - 1] === \"]\";\n    // validate a little.\n        if (!ipv6Hostname) {\n      const hostparts = this.hostname.split(/\\./);\n      for (let i = 0, l = hostparts.length; i < l; i++) {\n        const part = hostparts[i];\n        if (!part) {\n          continue;\n        }\n        if (!part.match(hostnamePartPattern)) {\n          let newpart = \"\";\n          for (let j = 0, k = part.length; j < k; j++) {\n            if (part.charCodeAt(j) > 127) {\n              // we replace non-ASCII char with a temporary placeholder\n              // we need this to make sure size of hostname is not\n              // broken by replacing non-ASCII by nothing\n              newpart += \"x\";\n            } else {\n              newpart += part[j];\n            }\n          }\n          // we test again with ASCII char only\n                    if (!newpart.match(hostnamePartPattern)) {\n            const validParts = hostparts.slice(0, i);\n            const notHost = hostparts.slice(i + 1);\n            const bit = part.match(hostnamePartStart);\n            if (bit) {\n              validParts.push(bit[1]);\n              notHost.unshift(bit[2]);\n            }\n            if (notHost.length) {\n              rest = notHost.join(\".\") + rest;\n            }\n            this.hostname = validParts.join(\".\");\n            break;\n          }\n        }\n      }\n    }\n    if (this.hostname.length > hostnameMaxLen) {\n      this.hostname = \"\";\n    }\n    // strip [ and ] from the hostname\n    // the host field still retains them, though\n        if (ipv6Hostname) {\n      this.hostname = this.hostname.substr(1, this.hostname.length - 2);\n    }\n  }\n  // chop off from the tail first.\n    const hash = rest.indexOf(\"#\");\n  if (hash !== -1) {\n    // got a fragment string.\n    this.hash = rest.substr(hash);\n    rest = rest.slice(0, hash);\n  }\n  const qm = rest.indexOf(\"?\");\n  if (qm !== -1) {\n    this.search = rest.substr(qm);\n    rest = rest.slice(0, qm);\n  }\n  if (rest) {\n    this.pathname = rest;\n  }\n  if (slashedProtocol[lowerProto] && this.hostname && !this.pathname) {\n    this.pathname = \"\";\n  }\n  return this;\n};\n\nUrl.prototype.parseHost = function(host) {\n  let port = portPattern.exec(host);\n  if (port) {\n    port = port[0];\n    if (port !== \":\") {\n      this.port = port.substr(1);\n    }\n    host = host.substr(0, host.length - port.length);\n  }\n  if (host) {\n    this.hostname = host;\n  }\n};\n\nvar mdurl =  Object.freeze({\n  __proto__: null,\n  decode: decode$1,\n  encode: encode$1,\n  format: format,\n  parse: urlParse\n});\n\nvar Any = /[\\0-\\uD7FF\\uE000-\\uFFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]/;\n\nvar Cc = /[\\0-\\x1F\\x7F-\\x9F]/;\n\nvar regex$1 = /[\\xAD\\u0600-\\u0605\\u061C\\u06DD\\u070F\\u0890\\u0891\\u08E2\\u180E\\u200B-\\u200F\\u202A-\\u202E\\u2060-\\u2064\\u2066-\\u206F\\uFEFF\\uFFF9-\\uFFFB]|\\uD804[\\uDCBD\\uDCCD]|\\uD80D[\\uDC30-\\uDC3F]|\\uD82F[\\uDCA0-\\uDCA3]|\\uD834[\\uDD73-\\uDD7A]|\\uDB40[\\uDC01\\uDC20-\\uDC7F]/;\n\nvar P = /[!-#%-\\*,-\\/:;\\?@\\[-\\]_\\{\\}\\xA1\\xA7\\xAB\\xB6\\xB7\\xBB\\xBF\\u037E\\u0387\\u055A-\\u055F\\u0589\\u058A\\u05BE\\u05C0\\u05C3\\u05C6\\u05F3\\u05F4\\u0609\\u060A\\u060C\\u060D\\u061B\\u061D-\\u061F\\u066A-\\u066D\\u06D4\\u0700-\\u070D\\u07F7-\\u07F9\\u0830-\\u083E\\u085E\\u0964\\u0965\\u0970\\u09FD\\u0A76\\u0AF0\\u0C77\\u0C84\\u0DF4\\u0E4F\\u0E5A\\u0E5B\\u0F04-\\u0F12\\u0F14\\u0F3A-\\u0F3D\\u0F85\\u0FD0-\\u0FD4\\u0FD9\\u0FDA\\u104A-\\u104F\\u10FB\\u1360-\\u1368\\u1400\\u166E\\u169B\\u169C\\u16EB-\\u16ED\\u1735\\u1736\\u17D4-\\u17D6\\u17D8-\\u17DA\\u1800-\\u180A\\u1944\\u1945\\u1A1E\\u1A1F\\u1AA0-\\u1AA6\\u1AA8-\\u1AAD\\u1B5A-\\u1B60\\u1B7D\\u1B7E\\u1BFC-\\u1BFF\\u1C3B-\\u1C3F\\u1C7E\\u1C7F\\u1CC0-\\u1CC7\\u1CD3\\u2010-\\u2027\\u2030-\\u2043\\u2045-\\u2051\\u2053-\\u205E\\u207D\\u207E\\u208D\\u208E\\u2308-\\u230B\\u2329\\u232A\\u2768-\\u2775\\u27C5\\u27C6\\u27E6-\\u27EF\\u2983-\\u2998\\u29D8-\\u29DB\\u29FC\\u29FD\\u2CF9-\\u2CFC\\u2CFE\\u2CFF\\u2D70\\u2E00-\\u2E2E\\u2E30-\\u2E4F\\u2E52-\\u2E5D\\u3001-\\u3003\\u3008-\\u3011\\u3014-\\u301F\\u3030\\u303D\\u30A0\\u30FB\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA673\\uA67E\\uA6F2-\\uA6F7\\uA874-\\uA877\\uA8CE\\uA8CF\\uA8F8-\\uA8FA\\uA8FC\\uA92E\\uA92F\\uA95F\\uA9C1-\\uA9CD\\uA9DE\\uA9DF\\uAA5C-\\uAA5F\\uAADE\\uAADF\\uAAF0\\uAAF1\\uABEB\\uFD3E\\uFD3F\\uFE10-\\uFE19\\uFE30-\\uFE52\\uFE54-\\uFE61\\uFE63\\uFE68\\uFE6A\\uFE6B\\uFF01-\\uFF03\\uFF05-\\uFF0A\\uFF0C-\\uFF0F\\uFF1A\\uFF1B\\uFF1F\\uFF20\\uFF3B-\\uFF3D\\uFF3F\\uFF5B\\uFF5D\\uFF5F-\\uFF65]|\\uD800[\\uDD00-\\uDD02\\uDF9F\\uDFD0]|\\uD801\\uDD6F|\\uD802[\\uDC57\\uDD1F\\uDD3F\\uDE50-\\uDE58\\uDE7F\\uDEF0-\\uDEF6\\uDF39-\\uDF3F\\uDF99-\\uDF9C]|\\uD803[\\uDEAD\\uDF55-\\uDF59\\uDF86-\\uDF89]|\\uD804[\\uDC47-\\uDC4D\\uDCBB\\uDCBC\\uDCBE-\\uDCC1\\uDD40-\\uDD43\\uDD74\\uDD75\\uDDC5-\\uDDC8\\uDDCD\\uDDDB\\uDDDD-\\uDDDF\\uDE38-\\uDE3D\\uDEA9]|\\uD805[\\uDC4B-\\uDC4F\\uDC5A\\uDC5B\\uDC5D\\uDCC6\\uDDC1-\\uDDD7\\uDE41-\\uDE43\\uDE60-\\uDE6C\\uDEB9\\uDF3C-\\uDF3E]|\\uD806[\\uDC3B\\uDD44-\\uDD46\\uDDE2\\uDE3F-\\uDE46\\uDE9A-\\uDE9C\\uDE9E-\\uDEA2\\uDF00-\\uDF09]|\\uD807[\\uDC41-\\uDC45\\uDC70\\uDC71\\uDEF7\\uDEF8\\uDF43-\\uDF4F\\uDFFF]|\\uD809[\\uDC70-\\uDC74]|\\uD80B[\\uDFF1\\uDFF2]|\\uD81A[\\uDE6E\\uDE6F\\uDEF5\\uDF37-\\uDF3B\\uDF44]|\\uD81B[\\uDE97-\\uDE9A\\uDFE2]|\\uD82F\\uDC9F|\\uD836[\\uDE87-\\uDE8B]|\\uD83A[\\uDD5E\\uDD5F]/;\n\nvar regex = /[\\$\\+<->\\^`\\|~\\xA2-\\xA6\\xA8\\xA9\\xAC\\xAE-\\xB1\\xB4\\xB8\\xD7\\xF7\\u02C2-\\u02C5\\u02D2-\\u02DF\\u02E5-\\u02EB\\u02ED\\u02EF-\\u02FF\\u0375\\u0384\\u0385\\u03F6\\u0482\\u058D-\\u058F\\u0606-\\u0608\\u060B\\u060E\\u060F\\u06DE\\u06E9\\u06FD\\u06FE\\u07F6\\u07FE\\u07FF\\u0888\\u09F2\\u09F3\\u09FA\\u09FB\\u0AF1\\u0B70\\u0BF3-\\u0BFA\\u0C7F\\u0D4F\\u0D79\\u0E3F\\u0F01-\\u0F03\\u0F13\\u0F15-\\u0F17\\u0F1A-\\u0F1F\\u0F34\\u0F36\\u0F38\\u0FBE-\\u0FC5\\u0FC7-\\u0FCC\\u0FCE\\u0FCF\\u0FD5-\\u0FD8\\u109E\\u109F\\u1390-\\u1399\\u166D\\u17DB\\u1940\\u19DE-\\u19FF\\u1B61-\\u1B6A\\u1B74-\\u1B7C\\u1FBD\\u1FBF-\\u1FC1\\u1FCD-\\u1FCF\\u1FDD-\\u1FDF\\u1FED-\\u1FEF\\u1FFD\\u1FFE\\u2044\\u2052\\u207A-\\u207C\\u208A-\\u208C\\u20A0-\\u20C0\\u2100\\u2101\\u2103-\\u2106\\u2108\\u2109\\u2114\\u2116-\\u2118\\u211E-\\u2123\\u2125\\u2127\\u2129\\u212E\\u213A\\u213B\\u2140-\\u2144\\u214A-\\u214D\\u214F\\u218A\\u218B\\u2190-\\u2307\\u230C-\\u2328\\u232B-\\u2426\\u2440-\\u244A\\u249C-\\u24E9\\u2500-\\u2767\\u2794-\\u27C4\\u27C7-\\u27E5\\u27F0-\\u2982\\u2999-\\u29D7\\u29DC-\\u29FB\\u29FE-\\u2B73\\u2B76-\\u2B95\\u2B97-\\u2BFF\\u2CE5-\\u2CEA\\u2E50\\u2E51\\u2E80-\\u2E99\\u2E9B-\\u2EF3\\u2F00-\\u2FD5\\u2FF0-\\u2FFF\\u3004\\u3012\\u3013\\u3020\\u3036\\u3037\\u303E\\u303F\\u309B\\u309C\\u3190\\u3191\\u3196-\\u319F\\u31C0-\\u31E3\\u31EF\\u3200-\\u321E\\u322A-\\u3247\\u3250\\u3260-\\u327F\\u328A-\\u32B0\\u32C0-\\u33FF\\u4DC0-\\u4DFF\\uA490-\\uA4C6\\uA700-\\uA716\\uA720\\uA721\\uA789\\uA78A\\uA828-\\uA82B\\uA836-\\uA839\\uAA77-\\uAA79\\uAB5B\\uAB6A\\uAB6B\\uFB29\\uFBB2-\\uFBC2\\uFD40-\\uFD4F\\uFDCF\\uFDFC-\\uFDFF\\uFE62\\uFE64-\\uFE66\\uFE69\\uFF04\\uFF0B\\uFF1C-\\uFF1E\\uFF3E\\uFF40\\uFF5C\\uFF5E\\uFFE0-\\uFFE6\\uFFE8-\\uFFEE\\uFFFC\\uFFFD]|\\uD800[\\uDD37-\\uDD3F\\uDD79-\\uDD89\\uDD8C-\\uDD8E\\uDD90-\\uDD9C\\uDDA0\\uDDD0-\\uDDFC]|\\uD802[\\uDC77\\uDC78\\uDEC8]|\\uD805\\uDF3F|\\uD807[\\uDFD5-\\uDFF1]|\\uD81A[\\uDF3C-\\uDF3F\\uDF45]|\\uD82F\\uDC9C|\\uD833[\\uDF50-\\uDFC3]|\\uD834[\\uDC00-\\uDCF5\\uDD00-\\uDD26\\uDD29-\\uDD64\\uDD6A-\\uDD6C\\uDD83\\uDD84\\uDD8C-\\uDDA9\\uDDAE-\\uDDEA\\uDE00-\\uDE41\\uDE45\\uDF00-\\uDF56]|\\uD835[\\uDEC1\\uDEDB\\uDEFB\\uDF15\\uDF35\\uDF4F\\uDF6F\\uDF89\\uDFA9\\uDFC3]|\\uD836[\\uDC00-\\uDDFF\\uDE37-\\uDE3A\\uDE6D-\\uDE74\\uDE76-\\uDE83\\uDE85\\uDE86]|\\uD838[\\uDD4F\\uDEFF]|\\uD83B[\\uDCAC\\uDCB0\\uDD2E\\uDEF0\\uDEF1]|\\uD83C[\\uDC00-\\uDC2B\\uDC30-\\uDC93\\uDCA0-\\uDCAE\\uDCB1-\\uDCBF\\uDCC1-\\uDCCF\\uDCD1-\\uDCF5\\uDD0D-\\uDDAD\\uDDE6-\\uDE02\\uDE10-\\uDE3B\\uDE40-\\uDE48\\uDE50\\uDE51\\uDE60-\\uDE65\\uDF00-\\uDFFF]|\\uD83D[\\uDC00-\\uDED7\\uDEDC-\\uDEEC\\uDEF0-\\uDEFC\\uDF00-\\uDF76\\uDF7B-\\uDFD9\\uDFE0-\\uDFEB\\uDFF0]|\\uD83E[\\uDC00-\\uDC0B\\uDC10-\\uDC47\\uDC50-\\uDC59\\uDC60-\\uDC87\\uDC90-\\uDCAD\\uDCB0\\uDCB1\\uDD00-\\uDE53\\uDE60-\\uDE6D\\uDE70-\\uDE7C\\uDE80-\\uDE88\\uDE90-\\uDEBD\\uDEBF-\\uDEC5\\uDECE-\\uDEDB\\uDEE0-\\uDEE8\\uDEF0-\\uDEF8\\uDF00-\\uDF92\\uDF94-\\uDFCA]/;\n\nvar Z = /[ \\xA0\\u1680\\u2000-\\u200A\\u2028\\u2029\\u202F\\u205F\\u3000]/;\n\nvar ucmicro =  Object.freeze({\n  __proto__: null,\n  Any: Any,\n  Cc: Cc,\n  Cf: regex$1,\n  P: P,\n  S: regex,\n  Z: Z\n});\n\n// Generated using scripts/write-decode-map.ts\nvar htmlDecodeTree = new Uint16Array(\n// prettier-ignore\n'\\u1d41<\\xd5\\u0131\\u028a\\u049d\\u057b\\u05d0\\u0675\\u06de\\u07a2\\u07d6\\u080f\\u0a4a\\u0a91\\u0da1\\u0e6d\\u0f09\\u0f26\\u10ca\\u1228\\u12e1\\u1415\\u149d\\u14c3\\u14df\\u1525\\0\\0\\0\\0\\0\\0\\u156b\\u16cd\\u198d\\u1c12\\u1ddd\\u1f7e\\u2060\\u21b0\\u228d\\u23c0\\u23fb\\u2442\\u2824\\u2912\\u2d08\\u2e48\\u2fce\\u3016\\u32ba\\u3639\\u37ac\\u38fe\\u3a28\\u3a71\\u3ae0\\u3b2e\\u0800EMabcfglmnoprstu\\\\bfms\\x7f\\x84\\x8b\\x90\\x95\\x98\\xa6\\xb3\\xb9\\xc8\\xcflig\\u803b\\xc6\\u40c6P\\u803b&\\u4026cute\\u803b\\xc1\\u40c1reve;\\u4102\\u0100iyx}rc\\u803b\\xc2\\u40c2;\\u4410r;\\uc000\\ud835\\udd04rave\\u803b\\xc0\\u40c0pha;\\u4391acr;\\u4100d;\\u6a53\\u0100gp\\x9d\\xa1on;\\u4104f;\\uc000\\ud835\\udd38plyFunction;\\u6061ing\\u803b\\xc5\\u40c5\\u0100cs\\xbe\\xc3r;\\uc000\\ud835\\udc9cign;\\u6254ilde\\u803b\\xc3\\u40c3ml\\u803b\\xc4\\u40c4\\u0400aceforsu\\xe5\\xfb\\xfe\\u0117\\u011c\\u0122\\u0127\\u012a\\u0100cr\\xea\\xf2kslash;\\u6216\\u0176\\xf6\\xf8;\\u6ae7ed;\\u6306y;\\u4411\\u0180crt\\u0105\\u010b\\u0114ause;\\u6235noullis;\\u612ca;\\u4392r;\\uc000\\ud835\\udd05pf;\\uc000\\ud835\\udd39eve;\\u42d8c\\xf2\\u0113mpeq;\\u624e\\u0700HOacdefhilorsu\\u014d\\u0151\\u0156\\u0180\\u019e\\u01a2\\u01b5\\u01b7\\u01ba\\u01dc\\u0215\\u0273\\u0278\\u027ecy;\\u4427PY\\u803b\\xa9\\u40a9\\u0180cpy\\u015d\\u0162\\u017aute;\\u4106\\u0100;i\\u0167\\u0168\\u62d2talDifferentialD;\\u6145leys;\\u612d\\u0200aeio\\u0189\\u018e\\u0194\\u0198ron;\\u410cdil\\u803b\\xc7\\u40c7rc;\\u4108nint;\\u6230ot;\\u410a\\u0100dn\\u01a7\\u01adilla;\\u40b8terDot;\\u40b7\\xf2\\u017fi;\\u43a7rcle\\u0200DMPT\\u01c7\\u01cb\\u01d1\\u01d6ot;\\u6299inus;\\u6296lus;\\u6295imes;\\u6297o\\u0100cs\\u01e2\\u01f8kwiseContourIntegral;\\u6232eCurly\\u0100DQ\\u0203\\u020foubleQuote;\\u601duote;\\u6019\\u0200lnpu\\u021e\\u0228\\u0247\\u0255on\\u0100;e\\u0225\\u0226\\u6237;\\u6a74\\u0180git\\u022f\\u0236\\u023aruent;\\u6261nt;\\u622fourIntegral;\\u622e\\u0100fr\\u024c\\u024e;\\u6102oduct;\\u6210nterClockwiseContourIntegral;\\u6233oss;\\u6a2fcr;\\uc000\\ud835\\udc9ep\\u0100;C\\u0284\\u0285\\u62d3ap;\\u624d\\u0580DJSZacefios\\u02a0\\u02ac\\u02b0\\u02b4\\u02b8\\u02cb\\u02d7\\u02e1\\u02e6\\u0333\\u048d\\u0100;o\\u0179\\u02a5trahd;\\u6911cy;\\u4402cy;\\u4405cy;\\u440f\\u0180grs\\u02bf\\u02c4\\u02c7ger;\\u6021r;\\u61a1hv;\\u6ae4\\u0100ay\\u02d0\\u02d5ron;\\u410e;\\u4414l\\u0100;t\\u02dd\\u02de\\u6207a;\\u4394r;\\uc000\\ud835\\udd07\\u0100af\\u02eb\\u0327\\u0100cm\\u02f0\\u0322ritical\\u0200ADGT\\u0300\\u0306\\u0316\\u031ccute;\\u40b4o\\u0174\\u030b\\u030d;\\u42d9bleAcute;\\u42ddrave;\\u4060ilde;\\u42dcond;\\u62c4ferentialD;\\u6146\\u0470\\u033d\\0\\0\\0\\u0342\\u0354\\0\\u0405f;\\uc000\\ud835\\udd3b\\u0180;DE\\u0348\\u0349\\u034d\\u40a8ot;\\u60dcqual;\\u6250ble\\u0300CDLRUV\\u0363\\u0372\\u0382\\u03cf\\u03e2\\u03f8ontourIntegra\\xec\\u0239o\\u0274\\u0379\\0\\0\\u037b\\xbb\\u0349nArrow;\\u61d3\\u0100eo\\u0387\\u03a4ft\\u0180ART\\u0390\\u0396\\u03a1rrow;\\u61d0ightArrow;\\u61d4e\\xe5\\u02cang\\u0100LR\\u03ab\\u03c4eft\\u0100AR\\u03b3\\u03b9rrow;\\u67f8ightArrow;\\u67faightArrow;\\u67f9ight\\u0100AT\\u03d8\\u03derrow;\\u61d2ee;\\u62a8p\\u0241\\u03e9\\0\\0\\u03efrrow;\\u61d1ownArrow;\\u61d5erticalBar;\\u6225n\\u0300ABLRTa\\u0412\\u042a\\u0430\\u045e\\u047f\\u037crrow\\u0180;BU\\u041d\\u041e\\u0422\\u6193ar;\\u6913pArrow;\\u61f5reve;\\u4311eft\\u02d2\\u043a\\0\\u0446\\0\\u0450ightVector;\\u6950eeVector;\\u695eector\\u0100;B\\u0459\\u045a\\u61bdar;\\u6956ight\\u01d4\\u0467\\0\\u0471eeVector;\\u695fector\\u0100;B\\u047a\\u047b\\u61c1ar;\\u6957ee\\u0100;A\\u0486\\u0487\\u62a4rrow;\\u61a7\\u0100ct\\u0492\\u0497r;\\uc000\\ud835\\udc9frok;\\u4110\\u0800NTacdfglmopqstux\\u04bd\\u04c0\\u04c4\\u04cb\\u04de\\u04e2\\u04e7\\u04ee\\u04f5\\u0521\\u052f\\u0536\\u0552\\u055d\\u0560\\u0565G;\\u414aH\\u803b\\xd0\\u40d0cute\\u803b\\xc9\\u40c9\\u0180aiy\\u04d2\\u04d7\\u04dcron;\\u411arc\\u803b\\xca\\u40ca;\\u442dot;\\u4116r;\\uc000\\ud835\\udd08rave\\u803b\\xc8\\u40c8ement;\\u6208\\u0100ap\\u04fa\\u04fecr;\\u4112ty\\u0253\\u0506\\0\\0\\u0512mallSquare;\\u65fberySmallSquare;\\u65ab\\u0100gp\\u0526\\u052aon;\\u4118f;\\uc000\\ud835\\udd3csilon;\\u4395u\\u0100ai\\u053c\\u0549l\\u0100;T\\u0542\\u0543\\u6a75ilde;\\u6242librium;\\u61cc\\u0100ci\\u0557\\u055ar;\\u6130m;\\u6a73a;\\u4397ml\\u803b\\xcb\\u40cb\\u0100ip\\u056a\\u056fsts;\\u6203onentialE;\\u6147\\u0280cfios\\u0585\\u0588\\u058d\\u05b2\\u05ccy;\\u4424r;\\uc000\\ud835\\udd09lled\\u0253\\u0597\\0\\0\\u05a3mallSquare;\\u65fcerySmallSquare;\\u65aa\\u0370\\u05ba\\0\\u05bf\\0\\0\\u05c4f;\\uc000\\ud835\\udd3dAll;\\u6200riertrf;\\u6131c\\xf2\\u05cb\\u0600JTabcdfgorst\\u05e8\\u05ec\\u05ef\\u05fa\\u0600\\u0612\\u0616\\u061b\\u061d\\u0623\\u066c\\u0672cy;\\u4403\\u803b>\\u403emma\\u0100;d\\u05f7\\u05f8\\u4393;\\u43dcreve;\\u411e\\u0180eiy\\u0607\\u060c\\u0610dil;\\u4122rc;\\u411c;\\u4413ot;\\u4120r;\\uc000\\ud835\\udd0a;\\u62d9pf;\\uc000\\ud835\\udd3eeater\\u0300EFGLST\\u0635\\u0644\\u064e\\u0656\\u065b\\u0666qual\\u0100;L\\u063e\\u063f\\u6265ess;\\u62dbullEqual;\\u6267reater;\\u6aa2ess;\\u6277lantEqual;\\u6a7eilde;\\u6273cr;\\uc000\\ud835\\udca2;\\u626b\\u0400Aacfiosu\\u0685\\u068b\\u0696\\u069b\\u069e\\u06aa\\u06be\\u06caRDcy;\\u442a\\u0100ct\\u0690\\u0694ek;\\u42c7;\\u405eirc;\\u4124r;\\u610clbertSpace;\\u610b\\u01f0\\u06af\\0\\u06b2f;\\u610dizontalLine;\\u6500\\u0100ct\\u06c3\\u06c5\\xf2\\u06a9rok;\\u4126mp\\u0144\\u06d0\\u06d8ownHum\\xf0\\u012fqual;\\u624f\\u0700EJOacdfgmnostu\\u06fa\\u06fe\\u0703\\u0707\\u070e\\u071a\\u071e\\u0721\\u0728\\u0744\\u0778\\u078b\\u078f\\u0795cy;\\u4415lig;\\u4132cy;\\u4401cute\\u803b\\xcd\\u40cd\\u0100iy\\u0713\\u0718rc\\u803b\\xce\\u40ce;\\u4418ot;\\u4130r;\\u6111rave\\u803b\\xcc\\u40cc\\u0180;ap\\u0720\\u072f\\u073f\\u0100cg\\u0734\\u0737r;\\u412ainaryI;\\u6148lie\\xf3\\u03dd\\u01f4\\u0749\\0\\u0762\\u0100;e\\u074d\\u074e\\u622c\\u0100gr\\u0753\\u0758ral;\\u622bsection;\\u62c2isible\\u0100CT\\u076c\\u0772omma;\\u6063imes;\\u6062\\u0180gpt\\u077f\\u0783\\u0788on;\\u412ef;\\uc000\\ud835\\udd40a;\\u4399cr;\\u6110ilde;\\u4128\\u01eb\\u079a\\0\\u079ecy;\\u4406l\\u803b\\xcf\\u40cf\\u0280cfosu\\u07ac\\u07b7\\u07bc\\u07c2\\u07d0\\u0100iy\\u07b1\\u07b5rc;\\u4134;\\u4419r;\\uc000\\ud835\\udd0dpf;\\uc000\\ud835\\udd41\\u01e3\\u07c7\\0\\u07ccr;\\uc000\\ud835\\udca5rcy;\\u4408kcy;\\u4404\\u0380HJacfos\\u07e4\\u07e8\\u07ec\\u07f1\\u07fd\\u0802\\u0808cy;\\u4425cy;\\u440cppa;\\u439a\\u0100ey\\u07f6\\u07fbdil;\\u4136;\\u441ar;\\uc000\\ud835\\udd0epf;\\uc000\\ud835\\udd42cr;\\uc000\\ud835\\udca6\\u0580JTaceflmost\\u0825\\u0829\\u082c\\u0850\\u0863\\u09b3\\u09b8\\u09c7\\u09cd\\u0a37\\u0a47cy;\\u4409\\u803b<\\u403c\\u0280cmnpr\\u0837\\u083c\\u0841\\u0844\\u084dute;\\u4139bda;\\u439bg;\\u67ealacetrf;\\u6112r;\\u619e\\u0180aey\\u0857\\u085c\\u0861ron;\\u413ddil;\\u413b;\\u441b\\u0100fs\\u0868\\u0970t\\u0500ACDFRTUVar\\u087e\\u08a9\\u08b1\\u08e0\\u08e6\\u08fc\\u092f\\u095b\\u0390\\u096a\\u0100nr\\u0883\\u088fgleBracket;\\u67e8row\\u0180;BR\\u0899\\u089a\\u089e\\u6190ar;\\u61e4ightArrow;\\u61c6eiling;\\u6308o\\u01f5\\u08b7\\0\\u08c3bleBracket;\\u67e6n\\u01d4\\u08c8\\0\\u08d2eeVector;\\u6961ector\\u0100;B\\u08db\\u08dc\\u61c3ar;\\u6959loor;\\u630aight\\u0100AV\\u08ef\\u08f5rrow;\\u6194ector;\\u694e\\u0100er\\u0901\\u0917e\\u0180;AV\\u0909\\u090a\\u0910\\u62a3rrow;\\u61a4ector;\\u695aiangle\\u0180;BE\\u0924\\u0925\\u0929\\u62b2ar;\\u69cfqual;\\u62b4p\\u0180DTV\\u0937\\u0942\\u094cownVector;\\u6951eeVector;\\u6960ector\\u0100;B\\u0956\\u0957\\u61bfar;\\u6958ector\\u0100;B\\u0965\\u0966\\u61bcar;\\u6952ight\\xe1\\u039cs\\u0300EFGLST\\u097e\\u098b\\u0995\\u099d\\u09a2\\u09adqualGreater;\\u62daullEqual;\\u6266reater;\\u6276ess;\\u6aa1lantEqual;\\u6a7dilde;\\u6272r;\\uc000\\ud835\\udd0f\\u0100;e\\u09bd\\u09be\\u62d8ftarrow;\\u61daidot;\\u413f\\u0180npw\\u09d4\\u0a16\\u0a1bg\\u0200LRlr\\u09de\\u09f7\\u0a02\\u0a10eft\\u0100AR\\u09e6\\u09ecrrow;\\u67f5ightArrow;\\u67f7ightArrow;\\u67f6eft\\u0100ar\\u03b3\\u0a0aight\\xe1\\u03bfight\\xe1\\u03caf;\\uc000\\ud835\\udd43er\\u0100LR\\u0a22\\u0a2ceftArrow;\\u6199ightArrow;\\u6198\\u0180cht\\u0a3e\\u0a40\\u0a42\\xf2\\u084c;\\u61b0rok;\\u4141;\\u626a\\u0400acefiosu\\u0a5a\\u0a5d\\u0a60\\u0a77\\u0a7c\\u0a85\\u0a8b\\u0a8ep;\\u6905y;\\u441c\\u0100dl\\u0a65\\u0a6fiumSpace;\\u605flintrf;\\u6133r;\\uc000\\ud835\\udd10nusPlus;\\u6213pf;\\uc000\\ud835\\udd44c\\xf2\\u0a76;\\u439c\\u0480Jacefostu\\u0aa3\\u0aa7\\u0aad\\u0ac0\\u0b14\\u0b19\\u0d91\\u0d97\\u0d9ecy;\\u440acute;\\u4143\\u0180aey\\u0ab4\\u0ab9\\u0aberon;\\u4147dil;\\u4145;\\u441d\\u0180gsw\\u0ac7\\u0af0\\u0b0eative\\u0180MTV\\u0ad3\\u0adf\\u0ae8ediumSpace;\\u600bhi\\u0100cn\\u0ae6\\u0ad8\\xeb\\u0ad9eryThi\\xee\\u0ad9ted\\u0100GL\\u0af8\\u0b06reaterGreate\\xf2\\u0673essLes\\xf3\\u0a48Line;\\u400ar;\\uc000\\ud835\\udd11\\u0200Bnpt\\u0b22\\u0b28\\u0b37\\u0b3areak;\\u6060BreakingSpace;\\u40a0f;\\u6115\\u0680;CDEGHLNPRSTV\\u0b55\\u0b56\\u0b6a\\u0b7c\\u0ba1\\u0beb\\u0c04\\u0c5e\\u0c84\\u0ca6\\u0cd8\\u0d61\\u0d85\\u6aec\\u0100ou\\u0b5b\\u0b64ngruent;\\u6262pCap;\\u626doubleVerticalBar;\\u6226\\u0180lqx\\u0b83\\u0b8a\\u0b9bement;\\u6209ual\\u0100;T\\u0b92\\u0b93\\u6260ilde;\\uc000\\u2242\\u0338ists;\\u6204reater\\u0380;EFGLST\\u0bb6\\u0bb7\\u0bbd\\u0bc9\\u0bd3\\u0bd8\\u0be5\\u626fqual;\\u6271ullEqual;\\uc000\\u2267\\u0338reater;\\uc000\\u226b\\u0338ess;\\u6279lantEqual;\\uc000\\u2a7e\\u0338ilde;\\u6275ump\\u0144\\u0bf2\\u0bfdownHump;\\uc000\\u224e\\u0338qual;\\uc000\\u224f\\u0338e\\u0100fs\\u0c0a\\u0c27tTriangle\\u0180;BE\\u0c1a\\u0c1b\\u0c21\\u62eaar;\\uc000\\u29cf\\u0338qual;\\u62ecs\\u0300;EGLST\\u0c35\\u0c36\\u0c3c\\u0c44\\u0c4b\\u0c58\\u626equal;\\u6270reater;\\u6278ess;\\uc000\\u226a\\u0338lantEqual;\\uc000\\u2a7d\\u0338ilde;\\u6274ested\\u0100GL\\u0c68\\u0c79reaterGreater;\\uc000\\u2aa2\\u0338essLess;\\uc000\\u2aa1\\u0338recedes\\u0180;ES\\u0c92\\u0c93\\u0c9b\\u6280qual;\\uc000\\u2aaf\\u0338lantEqual;\\u62e0\\u0100ei\\u0cab\\u0cb9verseElement;\\u620cghtTriangle\\u0180;BE\\u0ccb\\u0ccc\\u0cd2\\u62ebar;\\uc000\\u29d0\\u0338qual;\\u62ed\\u0100qu\\u0cdd\\u0d0cuareSu\\u0100bp\\u0ce8\\u0cf9set\\u0100;E\\u0cf0\\u0cf3\\uc000\\u228f\\u0338qual;\\u62e2erset\\u0100;E\\u0d03\\u0d06\\uc000\\u2290\\u0338qual;\\u62e3\\u0180bcp\\u0d13\\u0d24\\u0d4eset\\u0100;E\\u0d1b\\u0d1e\\uc000\\u2282\\u20d2qual;\\u6288ceeds\\u0200;EST\\u0d32\\u0d33\\u0d3b\\u0d46\\u6281qual;\\uc000\\u2ab0\\u0338lantEqual;\\u62e1ilde;\\uc000\\u227f\\u0338erset\\u0100;E\\u0d58\\u0d5b\\uc000\\u2283\\u20d2qual;\\u6289ilde\\u0200;EFT\\u0d6e\\u0d6f\\u0d75\\u0d7f\\u6241qual;\\u6244ullEqual;\\u6247ilde;\\u6249erticalBar;\\u6224cr;\\uc000\\ud835\\udca9ilde\\u803b\\xd1\\u40d1;\\u439d\\u0700Eacdfgmoprstuv\\u0dbd\\u0dc2\\u0dc9\\u0dd5\\u0ddb\\u0de0\\u0de7\\u0dfc\\u0e02\\u0e20\\u0e22\\u0e32\\u0e3f\\u0e44lig;\\u4152cute\\u803b\\xd3\\u40d3\\u0100iy\\u0dce\\u0dd3rc\\u803b\\xd4\\u40d4;\\u441eblac;\\u4150r;\\uc000\\ud835\\udd12rave\\u803b\\xd2\\u40d2\\u0180aei\\u0dee\\u0df2\\u0df6cr;\\u414cga;\\u43a9cron;\\u439fpf;\\uc000\\ud835\\udd46enCurly\\u0100DQ\\u0e0e\\u0e1aoubleQuote;\\u601cuote;\\u6018;\\u6a54\\u0100cl\\u0e27\\u0e2cr;\\uc000\\ud835\\udcaaash\\u803b\\xd8\\u40d8i\\u016c\\u0e37\\u0e3cde\\u803b\\xd5\\u40d5es;\\u6a37ml\\u803b\\xd6\\u40d6er\\u0100BP\\u0e4b\\u0e60\\u0100ar\\u0e50\\u0e53r;\\u603eac\\u0100ek\\u0e5a\\u0e5c;\\u63deet;\\u63b4arenthesis;\\u63dc\\u0480acfhilors\\u0e7f\\u0e87\\u0e8a\\u0e8f\\u0e92\\u0e94\\u0e9d\\u0eb0\\u0efcrtialD;\\u6202y;\\u441fr;\\uc000\\ud835\\udd13i;\\u43a6;\\u43a0usMinus;\\u40b1\\u0100ip\\u0ea2\\u0eadncareplan\\xe5\\u069df;\\u6119\\u0200;eio\\u0eb9\\u0eba\\u0ee0\\u0ee4\\u6abbcedes\\u0200;EST\\u0ec8\\u0ec9\\u0ecf\\u0eda\\u627aqual;\\u6aaflantEqual;\\u627cilde;\\u627eme;\\u6033\\u0100dp\\u0ee9\\u0eeeuct;\\u620fortion\\u0100;a\\u0225\\u0ef9l;\\u621d\\u0100ci\\u0f01\\u0f06r;\\uc000\\ud835\\udcab;\\u43a8\\u0200Ufos\\u0f11\\u0f16\\u0f1b\\u0f1fOT\\u803b\"\\u4022r;\\uc000\\ud835\\udd14pf;\\u611acr;\\uc000\\ud835\\udcac\\u0600BEacefhiorsu\\u0f3e\\u0f43\\u0f47\\u0f60\\u0f73\\u0fa7\\u0faa\\u0fad\\u1096\\u10a9\\u10b4\\u10bearr;\\u6910G\\u803b\\xae\\u40ae\\u0180cnr\\u0f4e\\u0f53\\u0f56ute;\\u4154g;\\u67ebr\\u0100;t\\u0f5c\\u0f5d\\u61a0l;\\u6916\\u0180aey\\u0f67\\u0f6c\\u0f71ron;\\u4158dil;\\u4156;\\u4420\\u0100;v\\u0f78\\u0f79\\u611cerse\\u0100EU\\u0f82\\u0f99\\u0100lq\\u0f87\\u0f8eement;\\u620builibrium;\\u61cbpEquilibrium;\\u696fr\\xbb\\u0f79o;\\u43a1ght\\u0400ACDFTUVa\\u0fc1\\u0feb\\u0ff3\\u1022\\u1028\\u105b\\u1087\\u03d8\\u0100nr\\u0fc6\\u0fd2gleBracket;\\u67e9row\\u0180;BL\\u0fdc\\u0fdd\\u0fe1\\u6192ar;\\u61e5eftArrow;\\u61c4eiling;\\u6309o\\u01f5\\u0ff9\\0\\u1005bleBracket;\\u67e7n\\u01d4\\u100a\\0\\u1014eeVector;\\u695dector\\u0100;B\\u101d\\u101e\\u61c2ar;\\u6955loor;\\u630b\\u0100er\\u102d\\u1043e\\u0180;AV\\u1035\\u1036\\u103c\\u62a2rrow;\\u61a6ector;\\u695biangle\\u0180;BE\\u1050\\u1051\\u1055\\u62b3ar;\\u69d0qual;\\u62b5p\\u0180DTV\\u1063\\u106e\\u1078ownVector;\\u694feeVector;\\u695cector\\u0100;B\\u1082\\u1083\\u61bear;\\u6954ector\\u0100;B\\u1091\\u1092\\u61c0ar;\\u6953\\u0100pu\\u109b\\u109ef;\\u611dndImplies;\\u6970ightarrow;\\u61db\\u0100ch\\u10b9\\u10bcr;\\u611b;\\u61b1leDelayed;\\u69f4\\u0680HOacfhimoqstu\\u10e4\\u10f1\\u10f7\\u10fd\\u1119\\u111e\\u1151\\u1156\\u1161\\u1167\\u11b5\\u11bb\\u11bf\\u0100Cc\\u10e9\\u10eeHcy;\\u4429y;\\u4428FTcy;\\u442ccute;\\u415a\\u0280;aeiy\\u1108\\u1109\\u110e\\u1113\\u1117\\u6abcron;\\u4160dil;\\u415erc;\\u415c;\\u4421r;\\uc000\\ud835\\udd16ort\\u0200DLRU\\u112a\\u1134\\u113e\\u1149ownArrow\\xbb\\u041eeftArrow\\xbb\\u089aightArrow\\xbb\\u0fddpArrow;\\u6191gma;\\u43a3allCircle;\\u6218pf;\\uc000\\ud835\\udd4a\\u0272\\u116d\\0\\0\\u1170t;\\u621aare\\u0200;ISU\\u117b\\u117c\\u1189\\u11af\\u65a1ntersection;\\u6293u\\u0100bp\\u118f\\u119eset\\u0100;E\\u1197\\u1198\\u628fqual;\\u6291erset\\u0100;E\\u11a8\\u11a9\\u6290qual;\\u6292nion;\\u6294cr;\\uc000\\ud835\\udcaear;\\u62c6\\u0200bcmp\\u11c8\\u11db\\u1209\\u120b\\u0100;s\\u11cd\\u11ce\\u62d0et\\u0100;E\\u11cd\\u11d5qual;\\u6286\\u0100ch\\u11e0\\u1205eeds\\u0200;EST\\u11ed\\u11ee\\u11f4\\u11ff\\u627bqual;\\u6ab0lantEqual;\\u627dilde;\\u627fTh\\xe1\\u0f8c;\\u6211\\u0180;es\\u1212\\u1213\\u1223\\u62d1rset\\u0100;E\\u121c\\u121d\\u6283qual;\\u6287et\\xbb\\u1213\\u0580HRSacfhiors\\u123e\\u1244\\u1249\\u1255\\u125e\\u1271\\u1276\\u129f\\u12c2\\u12c8\\u12d1ORN\\u803b\\xde\\u40deADE;\\u6122\\u0100Hc\\u124e\\u1252cy;\\u440by;\\u4426\\u0100bu\\u125a\\u125c;\\u4009;\\u43a4\\u0180aey\\u1265\\u126a\\u126fron;\\u4164dil;\\u4162;\\u4422r;\\uc000\\ud835\\udd17\\u0100ei\\u127b\\u1289\\u01f2\\u1280\\0\\u1287efore;\\u6234a;\\u4398\\u0100cn\\u128e\\u1298kSpace;\\uc000\\u205f\\u200aSpace;\\u6009lde\\u0200;EFT\\u12ab\\u12ac\\u12b2\\u12bc\\u623cqual;\\u6243ullEqual;\\u6245ilde;\\u6248pf;\\uc000\\ud835\\udd4bipleDot;\\u60db\\u0100ct\\u12d6\\u12dbr;\\uc000\\ud835\\udcafrok;\\u4166\\u0ae1\\u12f7\\u130e\\u131a\\u1326\\0\\u132c\\u1331\\0\\0\\0\\0\\0\\u1338\\u133d\\u1377\\u1385\\0\\u13ff\\u1404\\u140a\\u1410\\u0100cr\\u12fb\\u1301ute\\u803b\\xda\\u40dar\\u0100;o\\u1307\\u1308\\u619fcir;\\u6949r\\u01e3\\u1313\\0\\u1316y;\\u440eve;\\u416c\\u0100iy\\u131e\\u1323rc\\u803b\\xdb\\u40db;\\u4423blac;\\u4170r;\\uc000\\ud835\\udd18rave\\u803b\\xd9\\u40d9acr;\\u416a\\u0100di\\u1341\\u1369er\\u0100BP\\u1348\\u135d\\u0100ar\\u134d\\u1350r;\\u405fac\\u0100ek\\u1357\\u1359;\\u63dfet;\\u63b5arenthesis;\\u63ddon\\u0100;P\\u1370\\u1371\\u62c3lus;\\u628e\\u0100gp\\u137b\\u137fon;\\u4172f;\\uc000\\ud835\\udd4c\\u0400ADETadps\\u1395\\u13ae\\u13b8\\u13c4\\u03e8\\u13d2\\u13d7\\u13f3rrow\\u0180;BD\\u1150\\u13a0\\u13a4ar;\\u6912ownArrow;\\u61c5ownArrow;\\u6195quilibrium;\\u696eee\\u0100;A\\u13cb\\u13cc\\u62a5rrow;\\u61a5own\\xe1\\u03f3er\\u0100LR\\u13de\\u13e8eftArrow;\\u6196ightArrow;\\u6197i\\u0100;l\\u13f9\\u13fa\\u43d2on;\\u43a5ing;\\u416ecr;\\uc000\\ud835\\udcb0ilde;\\u4168ml\\u803b\\xdc\\u40dc\\u0480Dbcdefosv\\u1427\\u142c\\u1430\\u1433\\u143e\\u1485\\u148a\\u1490\\u1496ash;\\u62abar;\\u6aeby;\\u4412ash\\u0100;l\\u143b\\u143c\\u62a9;\\u6ae6\\u0100er\\u1443\\u1445;\\u62c1\\u0180bty\\u144c\\u1450\\u147aar;\\u6016\\u0100;i\\u144f\\u1455cal\\u0200BLST\\u1461\\u1465\\u146a\\u1474ar;\\u6223ine;\\u407ceparator;\\u6758ilde;\\u6240ThinSpace;\\u600ar;\\uc000\\ud835\\udd19pf;\\uc000\\ud835\\udd4dcr;\\uc000\\ud835\\udcb1dash;\\u62aa\\u0280cefos\\u14a7\\u14ac\\u14b1\\u14b6\\u14bcirc;\\u4174dge;\\u62c0r;\\uc000\\ud835\\udd1apf;\\uc000\\ud835\\udd4ecr;\\uc000\\ud835\\udcb2\\u0200fios\\u14cb\\u14d0\\u14d2\\u14d8r;\\uc000\\ud835\\udd1b;\\u439epf;\\uc000\\ud835\\udd4fcr;\\uc000\\ud835\\udcb3\\u0480AIUacfosu\\u14f1\\u14f5\\u14f9\\u14fd\\u1504\\u150f\\u1514\\u151a\\u1520cy;\\u442fcy;\\u4407cy;\\u442ecute\\u803b\\xdd\\u40dd\\u0100iy\\u1509\\u150drc;\\u4176;\\u442br;\\uc000\\ud835\\udd1cpf;\\uc000\\ud835\\udd50cr;\\uc000\\ud835\\udcb4ml;\\u4178\\u0400Hacdefos\\u1535\\u1539\\u153f\\u154b\\u154f\\u155d\\u1560\\u1564cy;\\u4416cute;\\u4179\\u0100ay\\u1544\\u1549ron;\\u417d;\\u4417ot;\\u417b\\u01f2\\u1554\\0\\u155boWidt\\xe8\\u0ad9a;\\u4396r;\\u6128pf;\\u6124cr;\\uc000\\ud835\\udcb5\\u0be1\\u1583\\u158a\\u1590\\0\\u15b0\\u15b6\\u15bf\\0\\0\\0\\0\\u15c6\\u15db\\u15eb\\u165f\\u166d\\0\\u1695\\u169b\\u16b2\\u16b9\\0\\u16becute\\u803b\\xe1\\u40e1reve;\\u4103\\u0300;Ediuy\\u159c\\u159d\\u15a1\\u15a3\\u15a8\\u15ad\\u623e;\\uc000\\u223e\\u0333;\\u623frc\\u803b\\xe2\\u40e2te\\u80bb\\xb4\\u0306;\\u4430lig\\u803b\\xe6\\u40e6\\u0100;r\\xb2\\u15ba;\\uc000\\ud835\\udd1erave\\u803b\\xe0\\u40e0\\u0100ep\\u15ca\\u15d6\\u0100fp\\u15cf\\u15d4sym;\\u6135\\xe8\\u15d3ha;\\u43b1\\u0100ap\\u15dfc\\u0100cl\\u15e4\\u15e7r;\\u4101g;\\u6a3f\\u0264\\u15f0\\0\\0\\u160a\\u0280;adsv\\u15fa\\u15fb\\u15ff\\u1601\\u1607\\u6227nd;\\u6a55;\\u6a5clope;\\u6a58;\\u6a5a\\u0380;elmrsz\\u1618\\u1619\\u161b\\u161e\\u163f\\u164f\\u1659\\u6220;\\u69a4e\\xbb\\u1619sd\\u0100;a\\u1625\\u1626\\u6221\\u0461\\u1630\\u1632\\u1634\\u1636\\u1638\\u163a\\u163c\\u163e;\\u69a8;\\u69a9;\\u69aa;\\u69ab;\\u69ac;\\u69ad;\\u69ae;\\u69aft\\u0100;v\\u1645\\u1646\\u621fb\\u0100;d\\u164c\\u164d\\u62be;\\u699d\\u0100pt\\u1654\\u1657h;\\u6222\\xbb\\xb9arr;\\u637c\\u0100gp\\u1663\\u1667on;\\u4105f;\\uc000\\ud835\\udd52\\u0380;Eaeiop\\u12c1\\u167b\\u167d\\u1682\\u1684\\u1687\\u168a;\\u6a70cir;\\u6a6f;\\u624ad;\\u624bs;\\u4027rox\\u0100;e\\u12c1\\u1692\\xf1\\u1683ing\\u803b\\xe5\\u40e5\\u0180cty\\u16a1\\u16a6\\u16a8r;\\uc000\\ud835\\udcb6;\\u402amp\\u0100;e\\u12c1\\u16af\\xf1\\u0288ilde\\u803b\\xe3\\u40e3ml\\u803b\\xe4\\u40e4\\u0100ci\\u16c2\\u16c8onin\\xf4\\u0272nt;\\u6a11\\u0800Nabcdefiklnoprsu\\u16ed\\u16f1\\u1730\\u173c\\u1743\\u1748\\u1778\\u177d\\u17e0\\u17e6\\u1839\\u1850\\u170d\\u193d\\u1948\\u1970ot;\\u6aed\\u0100cr\\u16f6\\u171ek\\u0200ceps\\u1700\\u1705\\u170d\\u1713ong;\\u624cpsilon;\\u43f6rime;\\u6035im\\u0100;e\\u171a\\u171b\\u623dq;\\u62cd\\u0176\\u1722\\u1726ee;\\u62bded\\u0100;g\\u172c\\u172d\\u6305e\\xbb\\u172drk\\u0100;t\\u135c\\u1737brk;\\u63b6\\u0100oy\\u1701\\u1741;\\u4431quo;\\u601e\\u0280cmprt\\u1753\\u175b\\u1761\\u1764\\u1768aus\\u0100;e\\u010a\\u0109ptyv;\\u69b0s\\xe9\\u170cno\\xf5\\u0113\\u0180ahw\\u176f\\u1771\\u1773;\\u43b2;\\u6136een;\\u626cr;\\uc000\\ud835\\udd1fg\\u0380costuvw\\u178d\\u179d\\u17b3\\u17c1\\u17d5\\u17db\\u17de\\u0180aiu\\u1794\\u1796\\u179a\\xf0\\u0760rc;\\u65efp\\xbb\\u1371\\u0180dpt\\u17a4\\u17a8\\u17adot;\\u6a00lus;\\u6a01imes;\\u6a02\\u0271\\u17b9\\0\\0\\u17becup;\\u6a06ar;\\u6605riangle\\u0100du\\u17cd\\u17d2own;\\u65bdp;\\u65b3plus;\\u6a04e\\xe5\\u1444\\xe5\\u14adarow;\\u690d\\u0180ako\\u17ed\\u1826\\u1835\\u0100cn\\u17f2\\u1823k\\u0180lst\\u17fa\\u05ab\\u1802ozenge;\\u69ebriangle\\u0200;dlr\\u1812\\u1813\\u1818\\u181d\\u65b4own;\\u65beeft;\\u65c2ight;\\u65b8k;\\u6423\\u01b1\\u182b\\0\\u1833\\u01b2\\u182f\\0\\u1831;\\u6592;\\u65914;\\u6593ck;\\u6588\\u0100eo\\u183e\\u184d\\u0100;q\\u1843\\u1846\\uc000=\\u20e5uiv;\\uc000\\u2261\\u20e5t;\\u6310\\u0200ptwx\\u1859\\u185e\\u1867\\u186cf;\\uc000\\ud835\\udd53\\u0100;t\\u13cb\\u1863om\\xbb\\u13cctie;\\u62c8\\u0600DHUVbdhmptuv\\u1885\\u1896\\u18aa\\u18bb\\u18d7\\u18db\\u18ec\\u18ff\\u1905\\u190a\\u1910\\u1921\\u0200LRlr\\u188e\\u1890\\u1892\\u1894;\\u6557;\\u6554;\\u6556;\\u6553\\u0280;DUdu\\u18a1\\u18a2\\u18a4\\u18a6\\u18a8\\u6550;\\u6566;\\u6569;\\u6564;\\u6567\\u0200LRlr\\u18b3\\u18b5\\u18b7\\u18b9;\\u655d;\\u655a;\\u655c;\\u6559\\u0380;HLRhlr\\u18ca\\u18cb\\u18cd\\u18cf\\u18d1\\u18d3\\u18d5\\u6551;\\u656c;\\u6563;\\u6560;\\u656b;\\u6562;\\u655fox;\\u69c9\\u0200LRlr\\u18e4\\u18e6\\u18e8\\u18ea;\\u6555;\\u6552;\\u6510;\\u650c\\u0280;DUdu\\u06bd\\u18f7\\u18f9\\u18fb\\u18fd;\\u6565;\\u6568;\\u652c;\\u6534inus;\\u629flus;\\u629eimes;\\u62a0\\u0200LRlr\\u1919\\u191b\\u191d\\u191f;\\u655b;\\u6558;\\u6518;\\u6514\\u0380;HLRhlr\\u1930\\u1931\\u1933\\u1935\\u1937\\u1939\\u193b\\u6502;\\u656a;\\u6561;\\u655e;\\u653c;\\u6524;\\u651c\\u0100ev\\u0123\\u1942bar\\u803b\\xa6\\u40a6\\u0200ceio\\u1951\\u1956\\u195a\\u1960r;\\uc000\\ud835\\udcb7mi;\\u604fm\\u0100;e\\u171a\\u171cl\\u0180;bh\\u1968\\u1969\\u196b\\u405c;\\u69c5sub;\\u67c8\\u016c\\u1974\\u197el\\u0100;e\\u1979\\u197a\\u6022t\\xbb\\u197ap\\u0180;Ee\\u012f\\u1985\\u1987;\\u6aae\\u0100;q\\u06dc\\u06db\\u0ce1\\u19a7\\0\\u19e8\\u1a11\\u1a15\\u1a32\\0\\u1a37\\u1a50\\0\\0\\u1ab4\\0\\0\\u1ac1\\0\\0\\u1b21\\u1b2e\\u1b4d\\u1b52\\0\\u1bfd\\0\\u1c0c\\u0180cpr\\u19ad\\u19b2\\u19ddute;\\u4107\\u0300;abcds\\u19bf\\u19c0\\u19c4\\u19ca\\u19d5\\u19d9\\u6229nd;\\u6a44rcup;\\u6a49\\u0100au\\u19cf\\u19d2p;\\u6a4bp;\\u6a47ot;\\u6a40;\\uc000\\u2229\\ufe00\\u0100eo\\u19e2\\u19e5t;\\u6041\\xee\\u0693\\u0200aeiu\\u19f0\\u19fb\\u1a01\\u1a05\\u01f0\\u19f5\\0\\u19f8s;\\u6a4don;\\u410ddil\\u803b\\xe7\\u40e7rc;\\u4109ps\\u0100;s\\u1a0c\\u1a0d\\u6a4cm;\\u6a50ot;\\u410b\\u0180dmn\\u1a1b\\u1a20\\u1a26il\\u80bb\\xb8\\u01adptyv;\\u69b2t\\u8100\\xa2;e\\u1a2d\\u1a2e\\u40a2r\\xe4\\u01b2r;\\uc000\\ud835\\udd20\\u0180cei\\u1a3d\\u1a40\\u1a4dy;\\u4447ck\\u0100;m\\u1a47\\u1a48\\u6713ark\\xbb\\u1a48;\\u43c7r\\u0380;Ecefms\\u1a5f\\u1a60\\u1a62\\u1a6b\\u1aa4\\u1aaa\\u1aae\\u65cb;\\u69c3\\u0180;el\\u1a69\\u1a6a\\u1a6d\\u42c6q;\\u6257e\\u0261\\u1a74\\0\\0\\u1a88rrow\\u0100lr\\u1a7c\\u1a81eft;\\u61baight;\\u61bb\\u0280RSacd\\u1a92\\u1a94\\u1a96\\u1a9a\\u1a9f\\xbb\\u0f47;\\u64c8st;\\u629birc;\\u629aash;\\u629dnint;\\u6a10id;\\u6aefcir;\\u69c2ubs\\u0100;u\\u1abb\\u1abc\\u6663it\\xbb\\u1abc\\u02ec\\u1ac7\\u1ad4\\u1afa\\0\\u1b0aon\\u0100;e\\u1acd\\u1ace\\u403a\\u0100;q\\xc7\\xc6\\u026d\\u1ad9\\0\\0\\u1ae2a\\u0100;t\\u1ade\\u1adf\\u402c;\\u4040\\u0180;fl\\u1ae8\\u1ae9\\u1aeb\\u6201\\xee\\u1160e\\u0100mx\\u1af1\\u1af6ent\\xbb\\u1ae9e\\xf3\\u024d\\u01e7\\u1afe\\0\\u1b07\\u0100;d\\u12bb\\u1b02ot;\\u6a6dn\\xf4\\u0246\\u0180fry\\u1b10\\u1b14\\u1b17;\\uc000\\ud835\\udd54o\\xe4\\u0254\\u8100\\xa9;s\\u0155\\u1b1dr;\\u6117\\u0100ao\\u1b25\\u1b29rr;\\u61b5ss;\\u6717\\u0100cu\\u1b32\\u1b37r;\\uc000\\ud835\\udcb8\\u0100bp\\u1b3c\\u1b44\\u0100;e\\u1b41\\u1b42\\u6acf;\\u6ad1\\u0100;e\\u1b49\\u1b4a\\u6ad0;\\u6ad2dot;\\u62ef\\u0380delprvw\\u1b60\\u1b6c\\u1b77\\u1b82\\u1bac\\u1bd4\\u1bf9arr\\u0100lr\\u1b68\\u1b6a;\\u6938;\\u6935\\u0270\\u1b72\\0\\0\\u1b75r;\\u62dec;\\u62dfarr\\u0100;p\\u1b7f\\u1b80\\u61b6;\\u693d\\u0300;bcdos\\u1b8f\\u1b90\\u1b96\\u1ba1\\u1ba5\\u1ba8\\u622arcap;\\u6a48\\u0100au\\u1b9b\\u1b9ep;\\u6a46p;\\u6a4aot;\\u628dr;\\u6a45;\\uc000\\u222a\\ufe00\\u0200alrv\\u1bb5\\u1bbf\\u1bde\\u1be3rr\\u0100;m\\u1bbc\\u1bbd\\u61b7;\\u693cy\\u0180evw\\u1bc7\\u1bd4\\u1bd8q\\u0270\\u1bce\\0\\0\\u1bd2re\\xe3\\u1b73u\\xe3\\u1b75ee;\\u62ceedge;\\u62cfen\\u803b\\xa4\\u40a4earrow\\u0100lr\\u1bee\\u1bf3eft\\xbb\\u1b80ight\\xbb\\u1bbde\\xe4\\u1bdd\\u0100ci\\u1c01\\u1c07onin\\xf4\\u01f7nt;\\u6231lcty;\\u632d\\u0980AHabcdefhijlorstuwz\\u1c38\\u1c3b\\u1c3f\\u1c5d\\u1c69\\u1c75\\u1c8a\\u1c9e\\u1cac\\u1cb7\\u1cfb\\u1cff\\u1d0d\\u1d7b\\u1d91\\u1dab\\u1dbb\\u1dc6\\u1dcdr\\xf2\\u0381ar;\\u6965\\u0200glrs\\u1c48\\u1c4d\\u1c52\\u1c54ger;\\u6020eth;\\u6138\\xf2\\u1133h\\u0100;v\\u1c5a\\u1c5b\\u6010\\xbb\\u090a\\u016b\\u1c61\\u1c67arow;\\u690fa\\xe3\\u0315\\u0100ay\\u1c6e\\u1c73ron;\\u410f;\\u4434\\u0180;ao\\u0332\\u1c7c\\u1c84\\u0100gr\\u02bf\\u1c81r;\\u61catseq;\\u6a77\\u0180glm\\u1c91\\u1c94\\u1c98\\u803b\\xb0\\u40b0ta;\\u43b4ptyv;\\u69b1\\u0100ir\\u1ca3\\u1ca8sht;\\u697f;\\uc000\\ud835\\udd21ar\\u0100lr\\u1cb3\\u1cb5\\xbb\\u08dc\\xbb\\u101e\\u0280aegsv\\u1cc2\\u0378\\u1cd6\\u1cdc\\u1ce0m\\u0180;os\\u0326\\u1cca\\u1cd4nd\\u0100;s\\u0326\\u1cd1uit;\\u6666amma;\\u43ddin;\\u62f2\\u0180;io\\u1ce7\\u1ce8\\u1cf8\\u40f7de\\u8100\\xf7;o\\u1ce7\\u1cf0ntimes;\\u62c7n\\xf8\\u1cf7cy;\\u4452c\\u026f\\u1d06\\0\\0\\u1d0arn;\\u631eop;\\u630d\\u0280lptuw\\u1d18\\u1d1d\\u1d22\\u1d49\\u1d55lar;\\u4024f;\\uc000\\ud835\\udd55\\u0280;emps\\u030b\\u1d2d\\u1d37\\u1d3d\\u1d42q\\u0100;d\\u0352\\u1d33ot;\\u6251inus;\\u6238lus;\\u6214quare;\\u62a1blebarwedg\\xe5\\xfan\\u0180adh\\u112e\\u1d5d\\u1d67ownarrow\\xf3\\u1c83arpoon\\u0100lr\\u1d72\\u1d76ef\\xf4\\u1cb4igh\\xf4\\u1cb6\\u0162\\u1d7f\\u1d85karo\\xf7\\u0f42\\u026f\\u1d8a\\0\\0\\u1d8ern;\\u631fop;\\u630c\\u0180cot\\u1d98\\u1da3\\u1da6\\u0100ry\\u1d9d\\u1da1;\\uc000\\ud835\\udcb9;\\u4455l;\\u69f6rok;\\u4111\\u0100dr\\u1db0\\u1db4ot;\\u62f1i\\u0100;f\\u1dba\\u1816\\u65bf\\u0100ah\\u1dc0\\u1dc3r\\xf2\\u0429a\\xf2\\u0fa6angle;\\u69a6\\u0100ci\\u1dd2\\u1dd5y;\\u445fgrarr;\\u67ff\\u0900Dacdefglmnopqrstux\\u1e01\\u1e09\\u1e19\\u1e38\\u0578\\u1e3c\\u1e49\\u1e61\\u1e7e\\u1ea5\\u1eaf\\u1ebd\\u1ee1\\u1f2a\\u1f37\\u1f44\\u1f4e\\u1f5a\\u0100Do\\u1e06\\u1d34o\\xf4\\u1c89\\u0100cs\\u1e0e\\u1e14ute\\u803b\\xe9\\u40e9ter;\\u6a6e\\u0200aioy\\u1e22\\u1e27\\u1e31\\u1e36ron;\\u411br\\u0100;c\\u1e2d\\u1e2e\\u6256\\u803b\\xea\\u40ealon;\\u6255;\\u444dot;\\u4117\\u0100Dr\\u1e41\\u1e45ot;\\u6252;\\uc000\\ud835\\udd22\\u0180;rs\\u1e50\\u1e51\\u1e57\\u6a9aave\\u803b\\xe8\\u40e8\\u0100;d\\u1e5c\\u1e5d\\u6a96ot;\\u6a98\\u0200;ils\\u1e6a\\u1e6b\\u1e72\\u1e74\\u6a99nters;\\u63e7;\\u6113\\u0100;d\\u1e79\\u1e7a\\u6a95ot;\\u6a97\\u0180aps\\u1e85\\u1e89\\u1e97cr;\\u4113ty\\u0180;sv\\u1e92\\u1e93\\u1e95\\u6205et\\xbb\\u1e93p\\u01001;\\u1e9d\\u1ea4\\u0133\\u1ea1\\u1ea3;\\u6004;\\u6005\\u6003\\u0100gs\\u1eaa\\u1eac;\\u414bp;\\u6002\\u0100gp\\u1eb4\\u1eb8on;\\u4119f;\\uc000\\ud835\\udd56\\u0180als\\u1ec4\\u1ece\\u1ed2r\\u0100;s\\u1eca\\u1ecb\\u62d5l;\\u69e3us;\\u6a71i\\u0180;lv\\u1eda\\u1edb\\u1edf\\u43b5on\\xbb\\u1edb;\\u43f5\\u0200csuv\\u1eea\\u1ef3\\u1f0b\\u1f23\\u0100io\\u1eef\\u1e31rc\\xbb\\u1e2e\\u0269\\u1ef9\\0\\0\\u1efb\\xed\\u0548ant\\u0100gl\\u1f02\\u1f06tr\\xbb\\u1e5dess\\xbb\\u1e7a\\u0180aei\\u1f12\\u1f16\\u1f1als;\\u403dst;\\u625fv\\u0100;D\\u0235\\u1f20D;\\u6a78parsl;\\u69e5\\u0100Da\\u1f2f\\u1f33ot;\\u6253rr;\\u6971\\u0180cdi\\u1f3e\\u1f41\\u1ef8r;\\u612fo\\xf4\\u0352\\u0100ah\\u1f49\\u1f4b;\\u43b7\\u803b\\xf0\\u40f0\\u0100mr\\u1f53\\u1f57l\\u803b\\xeb\\u40ebo;\\u60ac\\u0180cip\\u1f61\\u1f64\\u1f67l;\\u4021s\\xf4\\u056e\\u0100eo\\u1f6c\\u1f74ctatio\\xee\\u0559nential\\xe5\\u0579\\u09e1\\u1f92\\0\\u1f9e\\0\\u1fa1\\u1fa7\\0\\0\\u1fc6\\u1fcc\\0\\u1fd3\\0\\u1fe6\\u1fea\\u2000\\0\\u2008\\u205allingdotse\\xf1\\u1e44y;\\u4444male;\\u6640\\u0180ilr\\u1fad\\u1fb3\\u1fc1lig;\\u8000\\ufb03\\u0269\\u1fb9\\0\\0\\u1fbdg;\\u8000\\ufb00ig;\\u8000\\ufb04;\\uc000\\ud835\\udd23lig;\\u8000\\ufb01lig;\\uc000fj\\u0180alt\\u1fd9\\u1fdc\\u1fe1t;\\u666dig;\\u8000\\ufb02ns;\\u65b1of;\\u4192\\u01f0\\u1fee\\0\\u1ff3f;\\uc000\\ud835\\udd57\\u0100ak\\u05bf\\u1ff7\\u0100;v\\u1ffc\\u1ffd\\u62d4;\\u6ad9artint;\\u6a0d\\u0100ao\\u200c\\u2055\\u0100cs\\u2011\\u2052\\u03b1\\u201a\\u2030\\u2038\\u2045\\u2048\\0\\u2050\\u03b2\\u2022\\u2025\\u2027\\u202a\\u202c\\0\\u202e\\u803b\\xbd\\u40bd;\\u6153\\u803b\\xbc\\u40bc;\\u6155;\\u6159;\\u615b\\u01b3\\u2034\\0\\u2036;\\u6154;\\u6156\\u02b4\\u203e\\u2041\\0\\0\\u2043\\u803b\\xbe\\u40be;\\u6157;\\u615c5;\\u6158\\u01b6\\u204c\\0\\u204e;\\u615a;\\u615d8;\\u615el;\\u6044wn;\\u6322cr;\\uc000\\ud835\\udcbb\\u0880Eabcdefgijlnorstv\\u2082\\u2089\\u209f\\u20a5\\u20b0\\u20b4\\u20f0\\u20f5\\u20fa\\u20ff\\u2103\\u2112\\u2138\\u0317\\u213e\\u2152\\u219e\\u0100;l\\u064d\\u2087;\\u6a8c\\u0180cmp\\u2090\\u2095\\u209dute;\\u41f5ma\\u0100;d\\u209c\\u1cda\\u43b3;\\u6a86reve;\\u411f\\u0100iy\\u20aa\\u20aerc;\\u411d;\\u4433ot;\\u4121\\u0200;lqs\\u063e\\u0642\\u20bd\\u20c9\\u0180;qs\\u063e\\u064c\\u20c4lan\\xf4\\u0665\\u0200;cdl\\u0665\\u20d2\\u20d5\\u20e5c;\\u6aa9ot\\u0100;o\\u20dc\\u20dd\\u6a80\\u0100;l\\u20e2\\u20e3\\u6a82;\\u6a84\\u0100;e\\u20ea\\u20ed\\uc000\\u22db\\ufe00s;\\u6a94r;\\uc000\\ud835\\udd24\\u0100;g\\u0673\\u061bmel;\\u6137cy;\\u4453\\u0200;Eaj\\u065a\\u210c\\u210e\\u2110;\\u6a92;\\u6aa5;\\u6aa4\\u0200Eaes\\u211b\\u211d\\u2129\\u2134;\\u6269p\\u0100;p\\u2123\\u2124\\u6a8arox\\xbb\\u2124\\u0100;q\\u212e\\u212f\\u6a88\\u0100;q\\u212e\\u211bim;\\u62e7pf;\\uc000\\ud835\\udd58\\u0100ci\\u2143\\u2146r;\\u610am\\u0180;el\\u066b\\u214e\\u2150;\\u6a8e;\\u6a90\\u8300>;cdlqr\\u05ee\\u2160\\u216a\\u216e\\u2173\\u2179\\u0100ci\\u2165\\u2167;\\u6aa7r;\\u6a7aot;\\u62d7Par;\\u6995uest;\\u6a7c\\u0280adels\\u2184\\u216a\\u2190\\u0656\\u219b\\u01f0\\u2189\\0\\u218epro\\xf8\\u209er;\\u6978q\\u0100lq\\u063f\\u2196les\\xf3\\u2088i\\xed\\u066b\\u0100en\\u21a3\\u21adrtneqq;\\uc000\\u2269\\ufe00\\xc5\\u21aa\\u0500Aabcefkosy\\u21c4\\u21c7\\u21f1\\u21f5\\u21fa\\u2218\\u221d\\u222f\\u2268\\u227dr\\xf2\\u03a0\\u0200ilmr\\u21d0\\u21d4\\u21d7\\u21dbrs\\xf0\\u1484f\\xbb\\u2024il\\xf4\\u06a9\\u0100dr\\u21e0\\u21e4cy;\\u444a\\u0180;cw\\u08f4\\u21eb\\u21efir;\\u6948;\\u61adar;\\u610firc;\\u4125\\u0180alr\\u2201\\u220e\\u2213rts\\u0100;u\\u2209\\u220a\\u6665it\\xbb\\u220alip;\\u6026con;\\u62b9r;\\uc000\\ud835\\udd25s\\u0100ew\\u2223\\u2229arow;\\u6925arow;\\u6926\\u0280amopr\\u223a\\u223e\\u2243\\u225e\\u2263rr;\\u61fftht;\\u623bk\\u0100lr\\u2249\\u2253eftarrow;\\u61a9ightarrow;\\u61aaf;\\uc000\\ud835\\udd59bar;\\u6015\\u0180clt\\u226f\\u2274\\u2278r;\\uc000\\ud835\\udcbdas\\xe8\\u21f4rok;\\u4127\\u0100bp\\u2282\\u2287ull;\\u6043hen\\xbb\\u1c5b\\u0ae1\\u22a3\\0\\u22aa\\0\\u22b8\\u22c5\\u22ce\\0\\u22d5\\u22f3\\0\\0\\u22f8\\u2322\\u2367\\u2362\\u237f\\0\\u2386\\u23aa\\u23b4cute\\u803b\\xed\\u40ed\\u0180;iy\\u0771\\u22b0\\u22b5rc\\u803b\\xee\\u40ee;\\u4438\\u0100cx\\u22bc\\u22bfy;\\u4435cl\\u803b\\xa1\\u40a1\\u0100fr\\u039f\\u22c9;\\uc000\\ud835\\udd26rave\\u803b\\xec\\u40ec\\u0200;ino\\u073e\\u22dd\\u22e9\\u22ee\\u0100in\\u22e2\\u22e6nt;\\u6a0ct;\\u622dfin;\\u69dcta;\\u6129lig;\\u4133\\u0180aop\\u22fe\\u231a\\u231d\\u0180cgt\\u2305\\u2308\\u2317r;\\u412b\\u0180elp\\u071f\\u230f\\u2313in\\xe5\\u078ear\\xf4\\u0720h;\\u4131f;\\u62b7ed;\\u41b5\\u0280;cfot\\u04f4\\u232c\\u2331\\u233d\\u2341are;\\u6105in\\u0100;t\\u2338\\u2339\\u621eie;\\u69dddo\\xf4\\u2319\\u0280;celp\\u0757\\u234c\\u2350\\u235b\\u2361al;\\u62ba\\u0100gr\\u2355\\u2359er\\xf3\\u1563\\xe3\\u234darhk;\\u6a17rod;\\u6a3c\\u0200cgpt\\u236f\\u2372\\u2376\\u237by;\\u4451on;\\u412ff;\\uc000\\ud835\\udd5aa;\\u43b9uest\\u803b\\xbf\\u40bf\\u0100ci\\u238a\\u238fr;\\uc000\\ud835\\udcben\\u0280;Edsv\\u04f4\\u239b\\u239d\\u23a1\\u04f3;\\u62f9ot;\\u62f5\\u0100;v\\u23a6\\u23a7\\u62f4;\\u62f3\\u0100;i\\u0777\\u23aelde;\\u4129\\u01eb\\u23b8\\0\\u23bccy;\\u4456l\\u803b\\xef\\u40ef\\u0300cfmosu\\u23cc\\u23d7\\u23dc\\u23e1\\u23e7\\u23f5\\u0100iy\\u23d1\\u23d5rc;\\u4135;\\u4439r;\\uc000\\ud835\\udd27ath;\\u4237pf;\\uc000\\ud835\\udd5b\\u01e3\\u23ec\\0\\u23f1r;\\uc000\\ud835\\udcbfrcy;\\u4458kcy;\\u4454\\u0400acfghjos\\u240b\\u2416\\u2422\\u2427\\u242d\\u2431\\u2435\\u243bppa\\u0100;v\\u2413\\u2414\\u43ba;\\u43f0\\u0100ey\\u241b\\u2420dil;\\u4137;\\u443ar;\\uc000\\ud835\\udd28reen;\\u4138cy;\\u4445cy;\\u445cpf;\\uc000\\ud835\\udd5ccr;\\uc000\\ud835\\udcc0\\u0b80ABEHabcdefghjlmnoprstuv\\u2470\\u2481\\u2486\\u248d\\u2491\\u250e\\u253d\\u255a\\u2580\\u264e\\u265e\\u2665\\u2679\\u267d\\u269a\\u26b2\\u26d8\\u275d\\u2768\\u278b\\u27c0\\u2801\\u2812\\u0180art\\u2477\\u247a\\u247cr\\xf2\\u09c6\\xf2\\u0395ail;\\u691barr;\\u690e\\u0100;g\\u0994\\u248b;\\u6a8bar;\\u6962\\u0963\\u24a5\\0\\u24aa\\0\\u24b1\\0\\0\\0\\0\\0\\u24b5\\u24ba\\0\\u24c6\\u24c8\\u24cd\\0\\u24f9ute;\\u413amptyv;\\u69b4ra\\xee\\u084cbda;\\u43bbg\\u0180;dl\\u088e\\u24c1\\u24c3;\\u6991\\xe5\\u088e;\\u6a85uo\\u803b\\xab\\u40abr\\u0400;bfhlpst\\u0899\\u24de\\u24e6\\u24e9\\u24eb\\u24ee\\u24f1\\u24f5\\u0100;f\\u089d\\u24e3s;\\u691fs;\\u691d\\xeb\\u2252p;\\u61abl;\\u6939im;\\u6973l;\\u61a2\\u0180;ae\\u24ff\\u2500\\u2504\\u6aabil;\\u6919\\u0100;s\\u2509\\u250a\\u6aad;\\uc000\\u2aad\\ufe00\\u0180abr\\u2515\\u2519\\u251drr;\\u690crk;\\u6772\\u0100ak\\u2522\\u252cc\\u0100ek\\u2528\\u252a;\\u407b;\\u405b\\u0100es\\u2531\\u2533;\\u698bl\\u0100du\\u2539\\u253b;\\u698f;\\u698d\\u0200aeuy\\u2546\\u254b\\u2556\\u2558ron;\\u413e\\u0100di\\u2550\\u2554il;\\u413c\\xec\\u08b0\\xe2\\u2529;\\u443b\\u0200cqrs\\u2563\\u2566\\u256d\\u257da;\\u6936uo\\u0100;r\\u0e19\\u1746\\u0100du\\u2572\\u2577har;\\u6967shar;\\u694bh;\\u61b2\\u0280;fgqs\\u258b\\u258c\\u0989\\u25f3\\u25ff\\u6264t\\u0280ahlrt\\u2598\\u25a4\\u25b7\\u25c2\\u25e8rrow\\u0100;t\\u0899\\u25a1a\\xe9\\u24f6arpoon\\u0100du\\u25af\\u25b4own\\xbb\\u045ap\\xbb\\u0966eftarrows;\\u61c7ight\\u0180ahs\\u25cd\\u25d6\\u25derrow\\u0100;s\\u08f4\\u08a7arpoon\\xf3\\u0f98quigarro\\xf7\\u21f0hreetimes;\\u62cb\\u0180;qs\\u258b\\u0993\\u25falan\\xf4\\u09ac\\u0280;cdgs\\u09ac\\u260a\\u260d\\u261d\\u2628c;\\u6aa8ot\\u0100;o\\u2614\\u2615\\u6a7f\\u0100;r\\u261a\\u261b\\u6a81;\\u6a83\\u0100;e\\u2622\\u2625\\uc000\\u22da\\ufe00s;\\u6a93\\u0280adegs\\u2633\\u2639\\u263d\\u2649\\u264bppro\\xf8\\u24c6ot;\\u62d6q\\u0100gq\\u2643\\u2645\\xf4\\u0989gt\\xf2\\u248c\\xf4\\u099bi\\xed\\u09b2\\u0180ilr\\u2655\\u08e1\\u265asht;\\u697c;\\uc000\\ud835\\udd29\\u0100;E\\u099c\\u2663;\\u6a91\\u0161\\u2669\\u2676r\\u0100du\\u25b2\\u266e\\u0100;l\\u0965\\u2673;\\u696alk;\\u6584cy;\\u4459\\u0280;acht\\u0a48\\u2688\\u268b\\u2691\\u2696r\\xf2\\u25c1orne\\xf2\\u1d08ard;\\u696bri;\\u65fa\\u0100io\\u269f\\u26a4dot;\\u4140ust\\u0100;a\\u26ac\\u26ad\\u63b0che\\xbb\\u26ad\\u0200Eaes\\u26bb\\u26bd\\u26c9\\u26d4;\\u6268p\\u0100;p\\u26c3\\u26c4\\u6a89rox\\xbb\\u26c4\\u0100;q\\u26ce\\u26cf\\u6a87\\u0100;q\\u26ce\\u26bbim;\\u62e6\\u0400abnoptwz\\u26e9\\u26f4\\u26f7\\u271a\\u272f\\u2741\\u2747\\u2750\\u0100nr\\u26ee\\u26f1g;\\u67ecr;\\u61fdr\\xeb\\u08c1g\\u0180lmr\\u26ff\\u270d\\u2714eft\\u0100ar\\u09e6\\u2707ight\\xe1\\u09f2apsto;\\u67fcight\\xe1\\u09fdparrow\\u0100lr\\u2725\\u2729ef\\xf4\\u24edight;\\u61ac\\u0180afl\\u2736\\u2739\\u273dr;\\u6985;\\uc000\\ud835\\udd5dus;\\u6a2dimes;\\u6a34\\u0161\\u274b\\u274fst;\\u6217\\xe1\\u134e\\u0180;ef\\u2757\\u2758\\u1800\\u65cange\\xbb\\u2758ar\\u0100;l\\u2764\\u2765\\u4028t;\\u6993\\u0280achmt\\u2773\\u2776\\u277c\\u2785\\u2787r\\xf2\\u08a8orne\\xf2\\u1d8car\\u0100;d\\u0f98\\u2783;\\u696d;\\u600eri;\\u62bf\\u0300achiqt\\u2798\\u279d\\u0a40\\u27a2\\u27ae\\u27bbquo;\\u6039r;\\uc000\\ud835\\udcc1m\\u0180;eg\\u09b2\\u27aa\\u27ac;\\u6a8d;\\u6a8f\\u0100bu\\u252a\\u27b3o\\u0100;r\\u0e1f\\u27b9;\\u601arok;\\u4142\\u8400<;cdhilqr\\u082b\\u27d2\\u2639\\u27dc\\u27e0\\u27e5\\u27ea\\u27f0\\u0100ci\\u27d7\\u27d9;\\u6aa6r;\\u6a79re\\xe5\\u25f2mes;\\u62c9arr;\\u6976uest;\\u6a7b\\u0100Pi\\u27f5\\u27f9ar;\\u6996\\u0180;ef\\u2800\\u092d\\u181b\\u65c3r\\u0100du\\u2807\\u280dshar;\\u694ahar;\\u6966\\u0100en\\u2817\\u2821rtneqq;\\uc000\\u2268\\ufe00\\xc5\\u281e\\u0700Dacdefhilnopsu\\u2840\\u2845\\u2882\\u288e\\u2893\\u28a0\\u28a5\\u28a8\\u28da\\u28e2\\u28e4\\u0a83\\u28f3\\u2902Dot;\\u623a\\u0200clpr\\u284e\\u2852\\u2863\\u287dr\\u803b\\xaf\\u40af\\u0100et\\u2857\\u2859;\\u6642\\u0100;e\\u285e\\u285f\\u6720se\\xbb\\u285f\\u0100;s\\u103b\\u2868to\\u0200;dlu\\u103b\\u2873\\u2877\\u287bow\\xee\\u048cef\\xf4\\u090f\\xf0\\u13d1ker;\\u65ae\\u0100oy\\u2887\\u288cmma;\\u6a29;\\u443cash;\\u6014asuredangle\\xbb\\u1626r;\\uc000\\ud835\\udd2ao;\\u6127\\u0180cdn\\u28af\\u28b4\\u28c9ro\\u803b\\xb5\\u40b5\\u0200;acd\\u1464\\u28bd\\u28c0\\u28c4s\\xf4\\u16a7ir;\\u6af0ot\\u80bb\\xb7\\u01b5us\\u0180;bd\\u28d2\\u1903\\u28d3\\u6212\\u0100;u\\u1d3c\\u28d8;\\u6a2a\\u0163\\u28de\\u28e1p;\\u6adb\\xf2\\u2212\\xf0\\u0a81\\u0100dp\\u28e9\\u28eeels;\\u62a7f;\\uc000\\ud835\\udd5e\\u0100ct\\u28f8\\u28fdr;\\uc000\\ud835\\udcc2pos\\xbb\\u159d\\u0180;lm\\u2909\\u290a\\u290d\\u43bctimap;\\u62b8\\u0c00GLRVabcdefghijlmoprstuvw\\u2942\\u2953\\u297e\\u2989\\u2998\\u29da\\u29e9\\u2a15\\u2a1a\\u2a58\\u2a5d\\u2a83\\u2a95\\u2aa4\\u2aa8\\u2b04\\u2b07\\u2b44\\u2b7f\\u2bae\\u2c34\\u2c67\\u2c7c\\u2ce9\\u0100gt\\u2947\\u294b;\\uc000\\u22d9\\u0338\\u0100;v\\u2950\\u0bcf\\uc000\\u226b\\u20d2\\u0180elt\\u295a\\u2972\\u2976ft\\u0100ar\\u2961\\u2967rrow;\\u61cdightarrow;\\u61ce;\\uc000\\u22d8\\u0338\\u0100;v\\u297b\\u0c47\\uc000\\u226a\\u20d2ightarrow;\\u61cf\\u0100Dd\\u298e\\u2993ash;\\u62afash;\\u62ae\\u0280bcnpt\\u29a3\\u29a7\\u29ac\\u29b1\\u29ccla\\xbb\\u02deute;\\u4144g;\\uc000\\u2220\\u20d2\\u0280;Eiop\\u0d84\\u29bc\\u29c0\\u29c5\\u29c8;\\uc000\\u2a70\\u0338d;\\uc000\\u224b\\u0338s;\\u4149ro\\xf8\\u0d84ur\\u0100;a\\u29d3\\u29d4\\u666el\\u0100;s\\u29d3\\u0b38\\u01f3\\u29df\\0\\u29e3p\\u80bb\\xa0\\u0b37mp\\u0100;e\\u0bf9\\u0c00\\u0280aeouy\\u29f4\\u29fe\\u2a03\\u2a10\\u2a13\\u01f0\\u29f9\\0\\u29fb;\\u6a43on;\\u4148dil;\\u4146ng\\u0100;d\\u0d7e\\u2a0aot;\\uc000\\u2a6d\\u0338p;\\u6a42;\\u443dash;\\u6013\\u0380;Aadqsx\\u0b92\\u2a29\\u2a2d\\u2a3b\\u2a41\\u2a45\\u2a50rr;\\u61d7r\\u0100hr\\u2a33\\u2a36k;\\u6924\\u0100;o\\u13f2\\u13f0ot;\\uc000\\u2250\\u0338ui\\xf6\\u0b63\\u0100ei\\u2a4a\\u2a4ear;\\u6928\\xed\\u0b98ist\\u0100;s\\u0ba0\\u0b9fr;\\uc000\\ud835\\udd2b\\u0200Eest\\u0bc5\\u2a66\\u2a79\\u2a7c\\u0180;qs\\u0bbc\\u2a6d\\u0be1\\u0180;qs\\u0bbc\\u0bc5\\u2a74lan\\xf4\\u0be2i\\xed\\u0bea\\u0100;r\\u0bb6\\u2a81\\xbb\\u0bb7\\u0180Aap\\u2a8a\\u2a8d\\u2a91r\\xf2\\u2971rr;\\u61aear;\\u6af2\\u0180;sv\\u0f8d\\u2a9c\\u0f8c\\u0100;d\\u2aa1\\u2aa2\\u62fc;\\u62facy;\\u445a\\u0380AEadest\\u2ab7\\u2aba\\u2abe\\u2ac2\\u2ac5\\u2af6\\u2af9r\\xf2\\u2966;\\uc000\\u2266\\u0338rr;\\u619ar;\\u6025\\u0200;fqs\\u0c3b\\u2ace\\u2ae3\\u2aeft\\u0100ar\\u2ad4\\u2ad9rro\\xf7\\u2ac1ightarro\\xf7\\u2a90\\u0180;qs\\u0c3b\\u2aba\\u2aealan\\xf4\\u0c55\\u0100;s\\u0c55\\u2af4\\xbb\\u0c36i\\xed\\u0c5d\\u0100;r\\u0c35\\u2afei\\u0100;e\\u0c1a\\u0c25i\\xe4\\u0d90\\u0100pt\\u2b0c\\u2b11f;\\uc000\\ud835\\udd5f\\u8180\\xac;in\\u2b19\\u2b1a\\u2b36\\u40acn\\u0200;Edv\\u0b89\\u2b24\\u2b28\\u2b2e;\\uc000\\u22f9\\u0338ot;\\uc000\\u22f5\\u0338\\u01e1\\u0b89\\u2b33\\u2b35;\\u62f7;\\u62f6i\\u0100;v\\u0cb8\\u2b3c\\u01e1\\u0cb8\\u2b41\\u2b43;\\u62fe;\\u62fd\\u0180aor\\u2b4b\\u2b63\\u2b69r\\u0200;ast\\u0b7b\\u2b55\\u2b5a\\u2b5flle\\xec\\u0b7bl;\\uc000\\u2afd\\u20e5;\\uc000\\u2202\\u0338lint;\\u6a14\\u0180;ce\\u0c92\\u2b70\\u2b73u\\xe5\\u0ca5\\u0100;c\\u0c98\\u2b78\\u0100;e\\u0c92\\u2b7d\\xf1\\u0c98\\u0200Aait\\u2b88\\u2b8b\\u2b9d\\u2ba7r\\xf2\\u2988rr\\u0180;cw\\u2b94\\u2b95\\u2b99\\u619b;\\uc000\\u2933\\u0338;\\uc000\\u219d\\u0338ghtarrow\\xbb\\u2b95ri\\u0100;e\\u0ccb\\u0cd6\\u0380chimpqu\\u2bbd\\u2bcd\\u2bd9\\u2b04\\u0b78\\u2be4\\u2bef\\u0200;cer\\u0d32\\u2bc6\\u0d37\\u2bc9u\\xe5\\u0d45;\\uc000\\ud835\\udcc3ort\\u026d\\u2b05\\0\\0\\u2bd6ar\\xe1\\u2b56m\\u0100;e\\u0d6e\\u2bdf\\u0100;q\\u0d74\\u0d73su\\u0100bp\\u2beb\\u2bed\\xe5\\u0cf8\\xe5\\u0d0b\\u0180bcp\\u2bf6\\u2c11\\u2c19\\u0200;Ees\\u2bff\\u2c00\\u0d22\\u2c04\\u6284;\\uc000\\u2ac5\\u0338et\\u0100;e\\u0d1b\\u2c0bq\\u0100;q\\u0d23\\u2c00c\\u0100;e\\u0d32\\u2c17\\xf1\\u0d38\\u0200;Ees\\u2c22\\u2c23\\u0d5f\\u2c27\\u6285;\\uc000\\u2ac6\\u0338et\\u0100;e\\u0d58\\u2c2eq\\u0100;q\\u0d60\\u2c23\\u0200gilr\\u2c3d\\u2c3f\\u2c45\\u2c47\\xec\\u0bd7lde\\u803b\\xf1\\u40f1\\xe7\\u0c43iangle\\u0100lr\\u2c52\\u2c5ceft\\u0100;e\\u0c1a\\u2c5a\\xf1\\u0c26ight\\u0100;e\\u0ccb\\u2c65\\xf1\\u0cd7\\u0100;m\\u2c6c\\u2c6d\\u43bd\\u0180;es\\u2c74\\u2c75\\u2c79\\u4023ro;\\u6116p;\\u6007\\u0480DHadgilrs\\u2c8f\\u2c94\\u2c99\\u2c9e\\u2ca3\\u2cb0\\u2cb6\\u2cd3\\u2ce3ash;\\u62adarr;\\u6904p;\\uc000\\u224d\\u20d2ash;\\u62ac\\u0100et\\u2ca8\\u2cac;\\uc000\\u2265\\u20d2;\\uc000>\\u20d2nfin;\\u69de\\u0180Aet\\u2cbd\\u2cc1\\u2cc5rr;\\u6902;\\uc000\\u2264\\u20d2\\u0100;r\\u2cca\\u2ccd\\uc000<\\u20d2ie;\\uc000\\u22b4\\u20d2\\u0100At\\u2cd8\\u2cdcrr;\\u6903rie;\\uc000\\u22b5\\u20d2im;\\uc000\\u223c\\u20d2\\u0180Aan\\u2cf0\\u2cf4\\u2d02rr;\\u61d6r\\u0100hr\\u2cfa\\u2cfdk;\\u6923\\u0100;o\\u13e7\\u13e5ear;\\u6927\\u1253\\u1a95\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\u2d2d\\0\\u2d38\\u2d48\\u2d60\\u2d65\\u2d72\\u2d84\\u1b07\\0\\0\\u2d8d\\u2dab\\0\\u2dc8\\u2dce\\0\\u2ddc\\u2e19\\u2e2b\\u2e3e\\u2e43\\u0100cs\\u2d31\\u1a97ute\\u803b\\xf3\\u40f3\\u0100iy\\u2d3c\\u2d45r\\u0100;c\\u1a9e\\u2d42\\u803b\\xf4\\u40f4;\\u443e\\u0280abios\\u1aa0\\u2d52\\u2d57\\u01c8\\u2d5alac;\\u4151v;\\u6a38old;\\u69bclig;\\u4153\\u0100cr\\u2d69\\u2d6dir;\\u69bf;\\uc000\\ud835\\udd2c\\u036f\\u2d79\\0\\0\\u2d7c\\0\\u2d82n;\\u42dbave\\u803b\\xf2\\u40f2;\\u69c1\\u0100bm\\u2d88\\u0df4ar;\\u69b5\\u0200acit\\u2d95\\u2d98\\u2da5\\u2da8r\\xf2\\u1a80\\u0100ir\\u2d9d\\u2da0r;\\u69beoss;\\u69bbn\\xe5\\u0e52;\\u69c0\\u0180aei\\u2db1\\u2db5\\u2db9cr;\\u414dga;\\u43c9\\u0180cdn\\u2dc0\\u2dc5\\u01cdron;\\u43bf;\\u69b6pf;\\uc000\\ud835\\udd60\\u0180ael\\u2dd4\\u2dd7\\u01d2r;\\u69b7rp;\\u69b9\\u0380;adiosv\\u2dea\\u2deb\\u2dee\\u2e08\\u2e0d\\u2e10\\u2e16\\u6228r\\xf2\\u1a86\\u0200;efm\\u2df7\\u2df8\\u2e02\\u2e05\\u6a5dr\\u0100;o\\u2dfe\\u2dff\\u6134f\\xbb\\u2dff\\u803b\\xaa\\u40aa\\u803b\\xba\\u40bagof;\\u62b6r;\\u6a56lope;\\u6a57;\\u6a5b\\u0180clo\\u2e1f\\u2e21\\u2e27\\xf2\\u2e01ash\\u803b\\xf8\\u40f8l;\\u6298i\\u016c\\u2e2f\\u2e34de\\u803b\\xf5\\u40f5es\\u0100;a\\u01db\\u2e3as;\\u6a36ml\\u803b\\xf6\\u40f6bar;\\u633d\\u0ae1\\u2e5e\\0\\u2e7d\\0\\u2e80\\u2e9d\\0\\u2ea2\\u2eb9\\0\\0\\u2ecb\\u0e9c\\0\\u2f13\\0\\0\\u2f2b\\u2fbc\\0\\u2fc8r\\u0200;ast\\u0403\\u2e67\\u2e72\\u0e85\\u8100\\xb6;l\\u2e6d\\u2e6e\\u40b6le\\xec\\u0403\\u0269\\u2e78\\0\\0\\u2e7bm;\\u6af3;\\u6afdy;\\u443fr\\u0280cimpt\\u2e8b\\u2e8f\\u2e93\\u1865\\u2e97nt;\\u4025od;\\u402eil;\\u6030enk;\\u6031r;\\uc000\\ud835\\udd2d\\u0180imo\\u2ea8\\u2eb0\\u2eb4\\u0100;v\\u2ead\\u2eae\\u43c6;\\u43d5ma\\xf4\\u0a76ne;\\u660e\\u0180;tv\\u2ebf\\u2ec0\\u2ec8\\u43c0chfork\\xbb\\u1ffd;\\u43d6\\u0100au\\u2ecf\\u2edfn\\u0100ck\\u2ed5\\u2eddk\\u0100;h\\u21f4\\u2edb;\\u610e\\xf6\\u21f4s\\u0480;abcdemst\\u2ef3\\u2ef4\\u1908\\u2ef9\\u2efd\\u2f04\\u2f06\\u2f0a\\u2f0e\\u402bcir;\\u6a23ir;\\u6a22\\u0100ou\\u1d40\\u2f02;\\u6a25;\\u6a72n\\u80bb\\xb1\\u0e9dim;\\u6a26wo;\\u6a27\\u0180ipu\\u2f19\\u2f20\\u2f25ntint;\\u6a15f;\\uc000\\ud835\\udd61nd\\u803b\\xa3\\u40a3\\u0500;Eaceinosu\\u0ec8\\u2f3f\\u2f41\\u2f44\\u2f47\\u2f81\\u2f89\\u2f92\\u2f7e\\u2fb6;\\u6ab3p;\\u6ab7u\\xe5\\u0ed9\\u0100;c\\u0ece\\u2f4c\\u0300;acens\\u0ec8\\u2f59\\u2f5f\\u2f66\\u2f68\\u2f7eppro\\xf8\\u2f43urlye\\xf1\\u0ed9\\xf1\\u0ece\\u0180aes\\u2f6f\\u2f76\\u2f7approx;\\u6ab9qq;\\u6ab5im;\\u62e8i\\xed\\u0edfme\\u0100;s\\u2f88\\u0eae\\u6032\\u0180Eas\\u2f78\\u2f90\\u2f7a\\xf0\\u2f75\\u0180dfp\\u0eec\\u2f99\\u2faf\\u0180als\\u2fa0\\u2fa5\\u2faalar;\\u632eine;\\u6312urf;\\u6313\\u0100;t\\u0efb\\u2fb4\\xef\\u0efbrel;\\u62b0\\u0100ci\\u2fc0\\u2fc5r;\\uc000\\ud835\\udcc5;\\u43c8ncsp;\\u6008\\u0300fiopsu\\u2fda\\u22e2\\u2fdf\\u2fe5\\u2feb\\u2ff1r;\\uc000\\ud835\\udd2epf;\\uc000\\ud835\\udd62rime;\\u6057cr;\\uc000\\ud835\\udcc6\\u0180aeo\\u2ff8\\u3009\\u3013t\\u0100ei\\u2ffe\\u3005rnion\\xf3\\u06b0nt;\\u6a16st\\u0100;e\\u3010\\u3011\\u403f\\xf1\\u1f19\\xf4\\u0f14\\u0a80ABHabcdefhilmnoprstux\\u3040\\u3051\\u3055\\u3059\\u30e0\\u310e\\u312b\\u3147\\u3162\\u3172\\u318e\\u3206\\u3215\\u3224\\u3229\\u3258\\u326e\\u3272\\u3290\\u32b0\\u32b7\\u0180art\\u3047\\u304a\\u304cr\\xf2\\u10b3\\xf2\\u03ddail;\\u691car\\xf2\\u1c65ar;\\u6964\\u0380cdenqrt\\u3068\\u3075\\u3078\\u307f\\u308f\\u3094\\u30cc\\u0100eu\\u306d\\u3071;\\uc000\\u223d\\u0331te;\\u4155i\\xe3\\u116emptyv;\\u69b3g\\u0200;del\\u0fd1\\u3089\\u308b\\u308d;\\u6992;\\u69a5\\xe5\\u0fd1uo\\u803b\\xbb\\u40bbr\\u0580;abcfhlpstw\\u0fdc\\u30ac\\u30af\\u30b7\\u30b9\\u30bc\\u30be\\u30c0\\u30c3\\u30c7\\u30cap;\\u6975\\u0100;f\\u0fe0\\u30b4s;\\u6920;\\u6933s;\\u691e\\xeb\\u225d\\xf0\\u272el;\\u6945im;\\u6974l;\\u61a3;\\u619d\\u0100ai\\u30d1\\u30d5il;\\u691ao\\u0100;n\\u30db\\u30dc\\u6236al\\xf3\\u0f1e\\u0180abr\\u30e7\\u30ea\\u30eer\\xf2\\u17e5rk;\\u6773\\u0100ak\\u30f3\\u30fdc\\u0100ek\\u30f9\\u30fb;\\u407d;\\u405d\\u0100es\\u3102\\u3104;\\u698cl\\u0100du\\u310a\\u310c;\\u698e;\\u6990\\u0200aeuy\\u3117\\u311c\\u3127\\u3129ron;\\u4159\\u0100di\\u3121\\u3125il;\\u4157\\xec\\u0ff2\\xe2\\u30fa;\\u4440\\u0200clqs\\u3134\\u3137\\u313d\\u3144a;\\u6937dhar;\\u6969uo\\u0100;r\\u020e\\u020dh;\\u61b3\\u0180acg\\u314e\\u315f\\u0f44l\\u0200;ips\\u0f78\\u3158\\u315b\\u109cn\\xe5\\u10bbar\\xf4\\u0fa9t;\\u65ad\\u0180ilr\\u3169\\u1023\\u316esht;\\u697d;\\uc000\\ud835\\udd2f\\u0100ao\\u3177\\u3186r\\u0100du\\u317d\\u317f\\xbb\\u047b\\u0100;l\\u1091\\u3184;\\u696c\\u0100;v\\u318b\\u318c\\u43c1;\\u43f1\\u0180gns\\u3195\\u31f9\\u31fcht\\u0300ahlrst\\u31a4\\u31b0\\u31c2\\u31d8\\u31e4\\u31eerrow\\u0100;t\\u0fdc\\u31ada\\xe9\\u30c8arpoon\\u0100du\\u31bb\\u31bfow\\xee\\u317ep\\xbb\\u1092eft\\u0100ah\\u31ca\\u31d0rrow\\xf3\\u0feaarpoon\\xf3\\u0551ightarrows;\\u61c9quigarro\\xf7\\u30cbhreetimes;\\u62ccg;\\u42daingdotse\\xf1\\u1f32\\u0180ahm\\u320d\\u3210\\u3213r\\xf2\\u0feaa\\xf2\\u0551;\\u600foust\\u0100;a\\u321e\\u321f\\u63b1che\\xbb\\u321fmid;\\u6aee\\u0200abpt\\u3232\\u323d\\u3240\\u3252\\u0100nr\\u3237\\u323ag;\\u67edr;\\u61fer\\xeb\\u1003\\u0180afl\\u3247\\u324a\\u324er;\\u6986;\\uc000\\ud835\\udd63us;\\u6a2eimes;\\u6a35\\u0100ap\\u325d\\u3267r\\u0100;g\\u3263\\u3264\\u4029t;\\u6994olint;\\u6a12ar\\xf2\\u31e3\\u0200achq\\u327b\\u3280\\u10bc\\u3285quo;\\u603ar;\\uc000\\ud835\\udcc7\\u0100bu\\u30fb\\u328ao\\u0100;r\\u0214\\u0213\\u0180hir\\u3297\\u329b\\u32a0re\\xe5\\u31f8mes;\\u62cai\\u0200;efl\\u32aa\\u1059\\u1821\\u32ab\\u65b9tri;\\u69celuhar;\\u6968;\\u611e\\u0d61\\u32d5\\u32db\\u32df\\u332c\\u3338\\u3371\\0\\u337a\\u33a4\\0\\0\\u33ec\\u33f0\\0\\u3428\\u3448\\u345a\\u34ad\\u34b1\\u34ca\\u34f1\\0\\u3616\\0\\0\\u3633cute;\\u415bqu\\xef\\u27ba\\u0500;Eaceinpsy\\u11ed\\u32f3\\u32f5\\u32ff\\u3302\\u330b\\u330f\\u331f\\u3326\\u3329;\\u6ab4\\u01f0\\u32fa\\0\\u32fc;\\u6ab8on;\\u4161u\\xe5\\u11fe\\u0100;d\\u11f3\\u3307il;\\u415frc;\\u415d\\u0180Eas\\u3316\\u3318\\u331b;\\u6ab6p;\\u6abaim;\\u62e9olint;\\u6a13i\\xed\\u1204;\\u4441ot\\u0180;be\\u3334\\u1d47\\u3335\\u62c5;\\u6a66\\u0380Aacmstx\\u3346\\u334a\\u3357\\u335b\\u335e\\u3363\\u336drr;\\u61d8r\\u0100hr\\u3350\\u3352\\xeb\\u2228\\u0100;o\\u0a36\\u0a34t\\u803b\\xa7\\u40a7i;\\u403bwar;\\u6929m\\u0100in\\u3369\\xf0nu\\xf3\\xf1t;\\u6736r\\u0100;o\\u3376\\u2055\\uc000\\ud835\\udd30\\u0200acoy\\u3382\\u3386\\u3391\\u33a0rp;\\u666f\\u0100hy\\u338b\\u338fcy;\\u4449;\\u4448rt\\u026d\\u3399\\0\\0\\u339ci\\xe4\\u1464ara\\xec\\u2e6f\\u803b\\xad\\u40ad\\u0100gm\\u33a8\\u33b4ma\\u0180;fv\\u33b1\\u33b2\\u33b2\\u43c3;\\u43c2\\u0400;deglnpr\\u12ab\\u33c5\\u33c9\\u33ce\\u33d6\\u33de\\u33e1\\u33e6ot;\\u6a6a\\u0100;q\\u12b1\\u12b0\\u0100;E\\u33d3\\u33d4\\u6a9e;\\u6aa0\\u0100;E\\u33db\\u33dc\\u6a9d;\\u6a9fe;\\u6246lus;\\u6a24arr;\\u6972ar\\xf2\\u113d\\u0200aeit\\u33f8\\u3408\\u340f\\u3417\\u0100ls\\u33fd\\u3404lsetm\\xe9\\u336ahp;\\u6a33parsl;\\u69e4\\u0100dl\\u1463\\u3414e;\\u6323\\u0100;e\\u341c\\u341d\\u6aaa\\u0100;s\\u3422\\u3423\\u6aac;\\uc000\\u2aac\\ufe00\\u0180flp\\u342e\\u3433\\u3442tcy;\\u444c\\u0100;b\\u3438\\u3439\\u402f\\u0100;a\\u343e\\u343f\\u69c4r;\\u633ff;\\uc000\\ud835\\udd64a\\u0100dr\\u344d\\u0402es\\u0100;u\\u3454\\u3455\\u6660it\\xbb\\u3455\\u0180csu\\u3460\\u3479\\u349f\\u0100au\\u3465\\u346fp\\u0100;s\\u1188\\u346b;\\uc000\\u2293\\ufe00p\\u0100;s\\u11b4\\u3475;\\uc000\\u2294\\ufe00u\\u0100bp\\u347f\\u348f\\u0180;es\\u1197\\u119c\\u3486et\\u0100;e\\u1197\\u348d\\xf1\\u119d\\u0180;es\\u11a8\\u11ad\\u3496et\\u0100;e\\u11a8\\u349d\\xf1\\u11ae\\u0180;af\\u117b\\u34a6\\u05b0r\\u0165\\u34ab\\u05b1\\xbb\\u117car\\xf2\\u1148\\u0200cemt\\u34b9\\u34be\\u34c2\\u34c5r;\\uc000\\ud835\\udcc8tm\\xee\\xf1i\\xec\\u3415ar\\xe6\\u11be\\u0100ar\\u34ce\\u34d5r\\u0100;f\\u34d4\\u17bf\\u6606\\u0100an\\u34da\\u34edight\\u0100ep\\u34e3\\u34eapsilo\\xee\\u1ee0h\\xe9\\u2eafs\\xbb\\u2852\\u0280bcmnp\\u34fb\\u355e\\u1209\\u358b\\u358e\\u0480;Edemnprs\\u350e\\u350f\\u3511\\u3515\\u351e\\u3523\\u352c\\u3531\\u3536\\u6282;\\u6ac5ot;\\u6abd\\u0100;d\\u11da\\u351aot;\\u6ac3ult;\\u6ac1\\u0100Ee\\u3528\\u352a;\\u6acb;\\u628alus;\\u6abfarr;\\u6979\\u0180eiu\\u353d\\u3552\\u3555t\\u0180;en\\u350e\\u3545\\u354bq\\u0100;q\\u11da\\u350feq\\u0100;q\\u352b\\u3528m;\\u6ac7\\u0100bp\\u355a\\u355c;\\u6ad5;\\u6ad3c\\u0300;acens\\u11ed\\u356c\\u3572\\u3579\\u357b\\u3326ppro\\xf8\\u32faurlye\\xf1\\u11fe\\xf1\\u11f3\\u0180aes\\u3582\\u3588\\u331bppro\\xf8\\u331aq\\xf1\\u3317g;\\u666a\\u0680123;Edehlmnps\\u35a9\\u35ac\\u35af\\u121c\\u35b2\\u35b4\\u35c0\\u35c9\\u35d5\\u35da\\u35df\\u35e8\\u35ed\\u803b\\xb9\\u40b9\\u803b\\xb2\\u40b2\\u803b\\xb3\\u40b3;\\u6ac6\\u0100os\\u35b9\\u35bct;\\u6abeub;\\u6ad8\\u0100;d\\u1222\\u35c5ot;\\u6ac4s\\u0100ou\\u35cf\\u35d2l;\\u67c9b;\\u6ad7arr;\\u697bult;\\u6ac2\\u0100Ee\\u35e4\\u35e6;\\u6acc;\\u628blus;\\u6ac0\\u0180eiu\\u35f4\\u3609\\u360ct\\u0180;en\\u121c\\u35fc\\u3602q\\u0100;q\\u1222\\u35b2eq\\u0100;q\\u35e7\\u35e4m;\\u6ac8\\u0100bp\\u3611\\u3613;\\u6ad4;\\u6ad6\\u0180Aan\\u361c\\u3620\\u362drr;\\u61d9r\\u0100hr\\u3626\\u3628\\xeb\\u222e\\u0100;o\\u0a2b\\u0a29war;\\u692alig\\u803b\\xdf\\u40df\\u0be1\\u3651\\u365d\\u3660\\u12ce\\u3673\\u3679\\0\\u367e\\u36c2\\0\\0\\0\\0\\0\\u36db\\u3703\\0\\u3709\\u376c\\0\\0\\0\\u3787\\u0272\\u3656\\0\\0\\u365bget;\\u6316;\\u43c4r\\xeb\\u0e5f\\u0180aey\\u3666\\u366b\\u3670ron;\\u4165dil;\\u4163;\\u4442lrec;\\u6315r;\\uc000\\ud835\\udd31\\u0200eiko\\u3686\\u369d\\u36b5\\u36bc\\u01f2\\u368b\\0\\u3691e\\u01004f\\u1284\\u1281a\\u0180;sv\\u3698\\u3699\\u369b\\u43b8ym;\\u43d1\\u0100cn\\u36a2\\u36b2k\\u0100as\\u36a8\\u36aeppro\\xf8\\u12c1im\\xbb\\u12acs\\xf0\\u129e\\u0100as\\u36ba\\u36ae\\xf0\\u12c1rn\\u803b\\xfe\\u40fe\\u01ec\\u031f\\u36c6\\u22e7es\\u8180\\xd7;bd\\u36cf\\u36d0\\u36d8\\u40d7\\u0100;a\\u190f\\u36d5r;\\u6a31;\\u6a30\\u0180eps\\u36e1\\u36e3\\u3700\\xe1\\u2a4d\\u0200;bcf\\u0486\\u36ec\\u36f0\\u36f4ot;\\u6336ir;\\u6af1\\u0100;o\\u36f9\\u36fc\\uc000\\ud835\\udd65rk;\\u6ada\\xe1\\u3362rime;\\u6034\\u0180aip\\u370f\\u3712\\u3764d\\xe5\\u1248\\u0380adempst\\u3721\\u374d\\u3740\\u3751\\u3757\\u375c\\u375fngle\\u0280;dlqr\\u3730\\u3731\\u3736\\u3740\\u3742\\u65b5own\\xbb\\u1dbbeft\\u0100;e\\u2800\\u373e\\xf1\\u092e;\\u625cight\\u0100;e\\u32aa\\u374b\\xf1\\u105aot;\\u65ecinus;\\u6a3alus;\\u6a39b;\\u69cdime;\\u6a3bezium;\\u63e2\\u0180cht\\u3772\\u377d\\u3781\\u0100ry\\u3777\\u377b;\\uc000\\ud835\\udcc9;\\u4446cy;\\u445brok;\\u4167\\u0100io\\u378b\\u378ex\\xf4\\u1777head\\u0100lr\\u3797\\u37a0eftarro\\xf7\\u084fightarrow\\xbb\\u0f5d\\u0900AHabcdfghlmoprstuw\\u37d0\\u37d3\\u37d7\\u37e4\\u37f0\\u37fc\\u380e\\u381c\\u3823\\u3834\\u3851\\u385d\\u386b\\u38a9\\u38cc\\u38d2\\u38ea\\u38f6r\\xf2\\u03edar;\\u6963\\u0100cr\\u37dc\\u37e2ute\\u803b\\xfa\\u40fa\\xf2\\u1150r\\u01e3\\u37ea\\0\\u37edy;\\u445eve;\\u416d\\u0100iy\\u37f5\\u37farc\\u803b\\xfb\\u40fb;\\u4443\\u0180abh\\u3803\\u3806\\u380br\\xf2\\u13adlac;\\u4171a\\xf2\\u13c3\\u0100ir\\u3813\\u3818sht;\\u697e;\\uc000\\ud835\\udd32rave\\u803b\\xf9\\u40f9\\u0161\\u3827\\u3831r\\u0100lr\\u382c\\u382e\\xbb\\u0957\\xbb\\u1083lk;\\u6580\\u0100ct\\u3839\\u384d\\u026f\\u383f\\0\\0\\u384arn\\u0100;e\\u3845\\u3846\\u631cr\\xbb\\u3846op;\\u630fri;\\u65f8\\u0100al\\u3856\\u385acr;\\u416b\\u80bb\\xa8\\u0349\\u0100gp\\u3862\\u3866on;\\u4173f;\\uc000\\ud835\\udd66\\u0300adhlsu\\u114b\\u3878\\u387d\\u1372\\u3891\\u38a0own\\xe1\\u13b3arpoon\\u0100lr\\u3888\\u388cef\\xf4\\u382digh\\xf4\\u382fi\\u0180;hl\\u3899\\u389a\\u389c\\u43c5\\xbb\\u13faon\\xbb\\u389aparrows;\\u61c8\\u0180cit\\u38b0\\u38c4\\u38c8\\u026f\\u38b6\\0\\0\\u38c1rn\\u0100;e\\u38bc\\u38bd\\u631dr\\xbb\\u38bdop;\\u630eng;\\u416fri;\\u65f9cr;\\uc000\\ud835\\udcca\\u0180dir\\u38d9\\u38dd\\u38e2ot;\\u62f0lde;\\u4169i\\u0100;f\\u3730\\u38e8\\xbb\\u1813\\u0100am\\u38ef\\u38f2r\\xf2\\u38a8l\\u803b\\xfc\\u40fcangle;\\u69a7\\u0780ABDacdeflnoprsz\\u391c\\u391f\\u3929\\u392d\\u39b5\\u39b8\\u39bd\\u39df\\u39e4\\u39e8\\u39f3\\u39f9\\u39fd\\u3a01\\u3a20r\\xf2\\u03f7ar\\u0100;v\\u3926\\u3927\\u6ae8;\\u6ae9as\\xe8\\u03e1\\u0100nr\\u3932\\u3937grt;\\u699c\\u0380eknprst\\u34e3\\u3946\\u394b\\u3952\\u395d\\u3964\\u3996app\\xe1\\u2415othin\\xe7\\u1e96\\u0180hir\\u34eb\\u2ec8\\u3959op\\xf4\\u2fb5\\u0100;h\\u13b7\\u3962\\xef\\u318d\\u0100iu\\u3969\\u396dgm\\xe1\\u33b3\\u0100bp\\u3972\\u3984setneq\\u0100;q\\u397d\\u3980\\uc000\\u228a\\ufe00;\\uc000\\u2acb\\ufe00setneq\\u0100;q\\u398f\\u3992\\uc000\\u228b\\ufe00;\\uc000\\u2acc\\ufe00\\u0100hr\\u399b\\u399fet\\xe1\\u369ciangle\\u0100lr\\u39aa\\u39afeft\\xbb\\u0925ight\\xbb\\u1051y;\\u4432ash\\xbb\\u1036\\u0180elr\\u39c4\\u39d2\\u39d7\\u0180;be\\u2dea\\u39cb\\u39cfar;\\u62bbq;\\u625alip;\\u62ee\\u0100bt\\u39dc\\u1468a\\xf2\\u1469r;\\uc000\\ud835\\udd33tr\\xe9\\u39aesu\\u0100bp\\u39ef\\u39f1\\xbb\\u0d1c\\xbb\\u0d59pf;\\uc000\\ud835\\udd67ro\\xf0\\u0efbtr\\xe9\\u39b4\\u0100cu\\u3a06\\u3a0br;\\uc000\\ud835\\udccb\\u0100bp\\u3a10\\u3a18n\\u0100Ee\\u3980\\u3a16\\xbb\\u397en\\u0100Ee\\u3992\\u3a1e\\xbb\\u3990igzag;\\u699a\\u0380cefoprs\\u3a36\\u3a3b\\u3a56\\u3a5b\\u3a54\\u3a61\\u3a6airc;\\u4175\\u0100di\\u3a40\\u3a51\\u0100bg\\u3a45\\u3a49ar;\\u6a5fe\\u0100;q\\u15fa\\u3a4f;\\u6259erp;\\u6118r;\\uc000\\ud835\\udd34pf;\\uc000\\ud835\\udd68\\u0100;e\\u1479\\u3a66at\\xe8\\u1479cr;\\uc000\\ud835\\udccc\\u0ae3\\u178e\\u3a87\\0\\u3a8b\\0\\u3a90\\u3a9b\\0\\0\\u3a9d\\u3aa8\\u3aab\\u3aaf\\0\\0\\u3ac3\\u3ace\\0\\u3ad8\\u17dc\\u17dftr\\xe9\\u17d1r;\\uc000\\ud835\\udd35\\u0100Aa\\u3a94\\u3a97r\\xf2\\u03c3r\\xf2\\u09f6;\\u43be\\u0100Aa\\u3aa1\\u3aa4r\\xf2\\u03b8r\\xf2\\u09eba\\xf0\\u2713is;\\u62fb\\u0180dpt\\u17a4\\u3ab5\\u3abe\\u0100fl\\u3aba\\u17a9;\\uc000\\ud835\\udd69im\\xe5\\u17b2\\u0100Aa\\u3ac7\\u3acar\\xf2\\u03cer\\xf2\\u0a01\\u0100cq\\u3ad2\\u17b8r;\\uc000\\ud835\\udccd\\u0100pt\\u17d6\\u3adcr\\xe9\\u17d4\\u0400acefiosu\\u3af0\\u3afd\\u3b08\\u3b0c\\u3b11\\u3b15\\u3b1b\\u3b21c\\u0100uy\\u3af6\\u3afbte\\u803b\\xfd\\u40fd;\\u444f\\u0100iy\\u3b02\\u3b06rc;\\u4177;\\u444bn\\u803b\\xa5\\u40a5r;\\uc000\\ud835\\udd36cy;\\u4457pf;\\uc000\\ud835\\udd6acr;\\uc000\\ud835\\udcce\\u0100cm\\u3b26\\u3b29y;\\u444el\\u803b\\xff\\u40ff\\u0500acdefhiosw\\u3b42\\u3b48\\u3b54\\u3b58\\u3b64\\u3b69\\u3b6d\\u3b74\\u3b7a\\u3b80cute;\\u417a\\u0100ay\\u3b4d\\u3b52ron;\\u417e;\\u4437ot;\\u417c\\u0100et\\u3b5d\\u3b61tr\\xe6\\u155fa;\\u43b6r;\\uc000\\ud835\\udd37cy;\\u4436grarr;\\u61ddpf;\\uc000\\ud835\\udd6bcr;\\uc000\\ud835\\udccf\\u0100jn\\u3b85\\u3b87;\\u600dj;\\u600c'.split(\"\").map(c => c.charCodeAt(0)));\n\n// Generated using scripts/write-decode-map.ts\nvar xmlDecodeTree = new Uint16Array(\n// prettier-ignore\n\"\\u0200aglq\\t\\x15\\x18\\x1b\\u026d\\x0f\\0\\0\\x12p;\\u4026os;\\u4027t;\\u403et;\\u403cuot;\\u4022\".split(\"\").map(c => c.charCodeAt(0)));\n\n// Adapted from https://github.com/mathiasbynens/he/blob/36afe179392226cf1b6ccdb16ebbb7a5a844d93a/src/he.js#L106-L134\nvar _a;\n\nconst decodeMap = new Map([ [ 0, 65533 ], \n// C1 Unicode control character reference replacements\n[ 128, 8364 ], [ 130, 8218 ], [ 131, 402 ], [ 132, 8222 ], [ 133, 8230 ], [ 134, 8224 ], [ 135, 8225 ], [ 136, 710 ], [ 137, 8240 ], [ 138, 352 ], [ 139, 8249 ], [ 140, 338 ], [ 142, 381 ], [ 145, 8216 ], [ 146, 8217 ], [ 147, 8220 ], [ 148, 8221 ], [ 149, 8226 ], [ 150, 8211 ], [ 151, 8212 ], [ 152, 732 ], [ 153, 8482 ], [ 154, 353 ], [ 155, 8250 ], [ 156, 339 ], [ 158, 382 ], [ 159, 376 ] ]);\n\n/**\n * Polyfill for `String.fromCodePoint`. It is used to create a string from a Unicode code point.\n */ const fromCodePoint$1 = \n// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, node/no-unsupported-features/es-builtins\n(_a = String.fromCodePoint) !== null && _a !== void 0 ? _a : function(codePoint) {\n  let output = \"\";\n  if (codePoint > 65535) {\n    codePoint -= 65536;\n    output += String.fromCharCode(codePoint >>> 10 & 1023 | 55296);\n    codePoint = 56320 | codePoint & 1023;\n  }\n  output += String.fromCharCode(codePoint);\n  return output;\n};\n\n/**\n * Replace the given code point with a replacement character if it is a\n * surrogate or is outside the valid range. Otherwise return the code\n * point unchanged.\n */ function replaceCodePoint(codePoint) {\n  var _a;\n  if (codePoint >= 55296 && codePoint <= 57343 || codePoint > 1114111) {\n    return 65533;\n  }\n  return (_a = decodeMap.get(codePoint)) !== null && _a !== void 0 ? _a : codePoint;\n}\n\nvar CharCodes;\n\n(function(CharCodes) {\n  CharCodes[CharCodes[\"NUM\"] = 35] = \"NUM\";\n  CharCodes[CharCodes[\"SEMI\"] = 59] = \"SEMI\";\n  CharCodes[CharCodes[\"EQUALS\"] = 61] = \"EQUALS\";\n  CharCodes[CharCodes[\"ZERO\"] = 48] = \"ZERO\";\n  CharCodes[CharCodes[\"NINE\"] = 57] = \"NINE\";\n  CharCodes[CharCodes[\"LOWER_A\"] = 97] = \"LOWER_A\";\n  CharCodes[CharCodes[\"LOWER_F\"] = 102] = \"LOWER_F\";\n  CharCodes[CharCodes[\"LOWER_X\"] = 120] = \"LOWER_X\";\n  CharCodes[CharCodes[\"LOWER_Z\"] = 122] = \"LOWER_Z\";\n  CharCodes[CharCodes[\"UPPER_A\"] = 65] = \"UPPER_A\";\n  CharCodes[CharCodes[\"UPPER_F\"] = 70] = \"UPPER_F\";\n  CharCodes[CharCodes[\"UPPER_Z\"] = 90] = \"UPPER_Z\";\n})(CharCodes || (CharCodes = {}));\n\n/** Bit that needs to be set to convert an upper case ASCII character to lower case */ const TO_LOWER_BIT = 32;\n\nvar BinTrieFlags;\n\n(function(BinTrieFlags) {\n  BinTrieFlags[BinTrieFlags[\"VALUE_LENGTH\"] = 49152] = \"VALUE_LENGTH\";\n  BinTrieFlags[BinTrieFlags[\"BRANCH_LENGTH\"] = 16256] = \"BRANCH_LENGTH\";\n  BinTrieFlags[BinTrieFlags[\"JUMP_TABLE\"] = 127] = \"JUMP_TABLE\";\n})(BinTrieFlags || (BinTrieFlags = {}));\n\nfunction isNumber(code) {\n  return code >= CharCodes.ZERO && code <= CharCodes.NINE;\n}\n\nfunction isHexadecimalCharacter(code) {\n  return code >= CharCodes.UPPER_A && code <= CharCodes.UPPER_F || code >= CharCodes.LOWER_A && code <= CharCodes.LOWER_F;\n}\n\nfunction isAsciiAlphaNumeric(code) {\n  return code >= CharCodes.UPPER_A && code <= CharCodes.UPPER_Z || code >= CharCodes.LOWER_A && code <= CharCodes.LOWER_Z || isNumber(code);\n}\n\n/**\n * Checks if the given character is a valid end character for an entity in an attribute.\n *\n * Attribute values that aren't terminated properly aren't parsed, and shouldn't lead to a parser error.\n * See the example in https://html.spec.whatwg.org/multipage/parsing.html#named-character-reference-state\n */ function isEntityInAttributeInvalidEnd(code) {\n  return code === CharCodes.EQUALS || isAsciiAlphaNumeric(code);\n}\n\nvar EntityDecoderState;\n\n(function(EntityDecoderState) {\n  EntityDecoderState[EntityDecoderState[\"EntityStart\"] = 0] = \"EntityStart\";\n  EntityDecoderState[EntityDecoderState[\"NumericStart\"] = 1] = \"NumericStart\";\n  EntityDecoderState[EntityDecoderState[\"NumericDecimal\"] = 2] = \"NumericDecimal\";\n  EntityDecoderState[EntityDecoderState[\"NumericHex\"] = 3] = \"NumericHex\";\n  EntityDecoderState[EntityDecoderState[\"NamedEntity\"] = 4] = \"NamedEntity\";\n})(EntityDecoderState || (EntityDecoderState = {}));\n\nvar DecodingMode;\n\n(function(DecodingMode) {\n  /** Entities in text nodes that can end with any character. */\n  DecodingMode[DecodingMode[\"Legacy\"] = 0] = \"Legacy\";\n  /** Only allow entities terminated with a semicolon. */  DecodingMode[DecodingMode[\"Strict\"] = 1] = \"Strict\";\n  /** Entities in attributes have limitations on ending characters. */  DecodingMode[DecodingMode[\"Attribute\"] = 2] = \"Attribute\";\n})(DecodingMode || (DecodingMode = {}));\n\n/**\n * Token decoder with support of writing partial entities.\n */ class EntityDecoder {\n  constructor(/** The tree used to decode entities. */\n  decodeTree, \n  /**\n   * The function that is called when a codepoint is decoded.\n   *\n   * For multi-byte named entities, this will be called multiple times,\n   * with the second codepoint, and the same `consumed` value.\n   *\n   * @param codepoint The decoded codepoint.\n   * @param consumed The number of bytes consumed by the decoder.\n   */\n  emitCodePoint, /** An object that is used to produce errors. */\n  errors) {\n    this.decodeTree = decodeTree;\n    this.emitCodePoint = emitCodePoint;\n    this.errors = errors;\n    /** The current state of the decoder. */    this.state = EntityDecoderState.EntityStart;\n    /** Characters that were consumed while parsing an entity. */    this.consumed = 1;\n    /**\n     * The result of the entity.\n     *\n     * Either the result index of a numeric entity, or the codepoint of a\n     * numeric entity.\n     */    this.result = 0;\n    /** The current index in the decode tree. */    this.treeIndex = 0;\n    /** The number of characters that were consumed in excess. */    this.excess = 1;\n    /** The mode in which the decoder is operating. */    this.decodeMode = DecodingMode.Strict;\n  }\n  /** Resets the instance to make it reusable. */  startEntity(decodeMode) {\n    this.decodeMode = decodeMode;\n    this.state = EntityDecoderState.EntityStart;\n    this.result = 0;\n    this.treeIndex = 0;\n    this.excess = 1;\n    this.consumed = 1;\n  }\n  /**\n   * Write an entity to the decoder. This can be called multiple times with partial entities.\n   * If the entity is incomplete, the decoder will return -1.\n   *\n   * Mirrors the implementation of `getDecoder`, but with the ability to stop decoding if the\n   * entity is incomplete, and resume when the next string is written.\n   *\n   * @param string The string containing the entity (or a continuation of the entity).\n   * @param offset The offset at which the entity begins. Should be 0 if this is not the first call.\n   * @returns The number of characters that were consumed, or -1 if the entity is incomplete.\n   */  write(str, offset) {\n    switch (this.state) {\n     case EntityDecoderState.EntityStart:\n      {\n        if (str.charCodeAt(offset) === CharCodes.NUM) {\n          this.state = EntityDecoderState.NumericStart;\n          this.consumed += 1;\n          return this.stateNumericStart(str, offset + 1);\n        }\n        this.state = EntityDecoderState.NamedEntity;\n        return this.stateNamedEntity(str, offset);\n      }\n\n     case EntityDecoderState.NumericStart:\n      {\n        return this.stateNumericStart(str, offset);\n      }\n\n     case EntityDecoderState.NumericDecimal:\n      {\n        return this.stateNumericDecimal(str, offset);\n      }\n\n     case EntityDecoderState.NumericHex:\n      {\n        return this.stateNumericHex(str, offset);\n      }\n\n     case EntityDecoderState.NamedEntity:\n      {\n        return this.stateNamedEntity(str, offset);\n      }\n    }\n  }\n  /**\n   * Switches between the numeric decimal and hexadecimal states.\n   *\n   * Equivalent to the `Numeric character reference state` in the HTML spec.\n   *\n   * @param str The string containing the entity (or a continuation of the entity).\n   * @param offset The current offset.\n   * @returns The number of characters that were consumed, or -1 if the entity is incomplete.\n   */  stateNumericStart(str, offset) {\n    if (offset >= str.length) {\n      return -1;\n    }\n    if ((str.charCodeAt(offset) | TO_LOWER_BIT) === CharCodes.LOWER_X) {\n      this.state = EntityDecoderState.NumericHex;\n      this.consumed += 1;\n      return this.stateNumericHex(str, offset + 1);\n    }\n    this.state = EntityDecoderState.NumericDecimal;\n    return this.stateNumericDecimal(str, offset);\n  }\n  addToNumericResult(str, start, end, base) {\n    if (start !== end) {\n      const digitCount = end - start;\n      this.result = this.result * Math.pow(base, digitCount) + parseInt(str.substr(start, digitCount), base);\n      this.consumed += digitCount;\n    }\n  }\n  /**\n   * Parses a hexadecimal numeric entity.\n   *\n   * Equivalent to the `Hexademical character reference state` in the HTML spec.\n   *\n   * @param str The string containing the entity (or a continuation of the entity).\n   * @param offset The current offset.\n   * @returns The number of characters that were consumed, or -1 if the entity is incomplete.\n   */  stateNumericHex(str, offset) {\n    const startIdx = offset;\n    while (offset < str.length) {\n      const char = str.charCodeAt(offset);\n      if (isNumber(char) || isHexadecimalCharacter(char)) {\n        offset += 1;\n      } else {\n        this.addToNumericResult(str, startIdx, offset, 16);\n        return this.emitNumericEntity(char, 3);\n      }\n    }\n    this.addToNumericResult(str, startIdx, offset, 16);\n    return -1;\n  }\n  /**\n   * Parses a decimal numeric entity.\n   *\n   * Equivalent to the `Decimal character reference state` in the HTML spec.\n   *\n   * @param str The string containing the entity (or a continuation of the entity).\n   * @param offset The current offset.\n   * @returns The number of characters that were consumed, or -1 if the entity is incomplete.\n   */  stateNumericDecimal(str, offset) {\n    const startIdx = offset;\n    while (offset < str.length) {\n      const char = str.charCodeAt(offset);\n      if (isNumber(char)) {\n        offset += 1;\n      } else {\n        this.addToNumericResult(str, startIdx, offset, 10);\n        return this.emitNumericEntity(char, 2);\n      }\n    }\n    this.addToNumericResult(str, startIdx, offset, 10);\n    return -1;\n  }\n  /**\n   * Validate and emit a numeric entity.\n   *\n   * Implements the logic from the `Hexademical character reference start\n   * state` and `Numeric character reference end state` in the HTML spec.\n   *\n   * @param lastCp The last code point of the entity. Used to see if the\n   *               entity was terminated with a semicolon.\n   * @param expectedLength The minimum number of characters that should be\n   *                       consumed. Used to validate that at least one digit\n   *                       was consumed.\n   * @returns The number of characters that were consumed.\n   */  emitNumericEntity(lastCp, expectedLength) {\n    var _a;\n    // Ensure we consumed at least one digit.\n        if (this.consumed <= expectedLength) {\n      (_a = this.errors) === null || _a === void 0 ? void 0 : _a.absenceOfDigitsInNumericCharacterReference(this.consumed);\n      return 0;\n    }\n    // Figure out if this is a legit end of the entity\n        if (lastCp === CharCodes.SEMI) {\n      this.consumed += 1;\n    } else if (this.decodeMode === DecodingMode.Strict) {\n      return 0;\n    }\n    this.emitCodePoint(replaceCodePoint(this.result), this.consumed);\n    if (this.errors) {\n      if (lastCp !== CharCodes.SEMI) {\n        this.errors.missingSemicolonAfterCharacterReference();\n      }\n      this.errors.validateNumericCharacterReference(this.result);\n    }\n    return this.consumed;\n  }\n  /**\n   * Parses a named entity.\n   *\n   * Equivalent to the `Named character reference state` in the HTML spec.\n   *\n   * @param str The string containing the entity (or a continuation of the entity).\n   * @param offset The current offset.\n   * @returns The number of characters that were consumed, or -1 if the entity is incomplete.\n   */  stateNamedEntity(str, offset) {\n    const {decodeTree: decodeTree} = this;\n    let current = decodeTree[this.treeIndex];\n    // The mask is the number of bytes of the value, including the current byte.\n        let valueLength = (current & BinTrieFlags.VALUE_LENGTH) >> 14;\n    for (;offset < str.length; offset++, this.excess++) {\n      const char = str.charCodeAt(offset);\n      this.treeIndex = determineBranch(decodeTree, current, this.treeIndex + Math.max(1, valueLength), char);\n      if (this.treeIndex < 0) {\n        return this.result === 0 || \n        // If we are parsing an attribute\n        this.decodeMode === DecodingMode.Attribute && (\n        // We shouldn't have consumed any characters after the entity,\n        valueLength === 0 || \n        // And there should be no invalid characters.\n        isEntityInAttributeInvalidEnd(char)) ? 0 : this.emitNotTerminatedNamedEntity();\n      }\n      current = decodeTree[this.treeIndex];\n      valueLength = (current & BinTrieFlags.VALUE_LENGTH) >> 14;\n      // If the branch is a value, store it and continue\n            if (valueLength !== 0) {\n        // If the entity is terminated by a semicolon, we are done.\n        if (char === CharCodes.SEMI) {\n          return this.emitNamedEntityData(this.treeIndex, valueLength, this.consumed + this.excess);\n        }\n        // If we encounter a non-terminated (legacy) entity while parsing strictly, then ignore it.\n                if (this.decodeMode !== DecodingMode.Strict) {\n          this.result = this.treeIndex;\n          this.consumed += this.excess;\n          this.excess = 0;\n        }\n      }\n    }\n    return -1;\n  }\n  /**\n   * Emit a named entity that was not terminated with a semicolon.\n   *\n   * @returns The number of characters consumed.\n   */  emitNotTerminatedNamedEntity() {\n    var _a;\n    const {result: result, decodeTree: decodeTree} = this;\n    const valueLength = (decodeTree[result] & BinTrieFlags.VALUE_LENGTH) >> 14;\n    this.emitNamedEntityData(result, valueLength, this.consumed);\n    (_a = this.errors) === null || _a === void 0 ? void 0 : _a.missingSemicolonAfterCharacterReference();\n    return this.consumed;\n  }\n  /**\n   * Emit a named entity.\n   *\n   * @param result The index of the entity in the decode tree.\n   * @param valueLength The number of bytes in the entity.\n   * @param consumed The number of characters consumed.\n   *\n   * @returns The number of characters consumed.\n   */  emitNamedEntityData(result, valueLength, consumed) {\n    const {decodeTree: decodeTree} = this;\n    this.emitCodePoint(valueLength === 1 ? decodeTree[result] & ~BinTrieFlags.VALUE_LENGTH : decodeTree[result + 1], consumed);\n    if (valueLength === 3) {\n      // For multi-byte values, we need to emit the second byte.\n      this.emitCodePoint(decodeTree[result + 2], consumed);\n    }\n    return consumed;\n  }\n  /**\n   * Signal to the parser that the end of the input was reached.\n   *\n   * Remaining data will be emitted and relevant errors will be produced.\n   *\n   * @returns The number of characters consumed.\n   */  end() {\n    var _a;\n    switch (this.state) {\n     case EntityDecoderState.NamedEntity:\n      {\n        // Emit a named entity if we have one.\n        return this.result !== 0 && (this.decodeMode !== DecodingMode.Attribute || this.result === this.treeIndex) ? this.emitNotTerminatedNamedEntity() : 0;\n      }\n\n      // Otherwise, emit a numeric entity if we have one.\n           case EntityDecoderState.NumericDecimal:\n      {\n        return this.emitNumericEntity(0, 2);\n      }\n\n     case EntityDecoderState.NumericHex:\n      {\n        return this.emitNumericEntity(0, 3);\n      }\n\n     case EntityDecoderState.NumericStart:\n      {\n        (_a = this.errors) === null || _a === void 0 ? void 0 : _a.absenceOfDigitsInNumericCharacterReference(this.consumed);\n        return 0;\n      }\n\n     case EntityDecoderState.EntityStart:\n      {\n        // Return 0 if we have no entity.\n        return 0;\n      }\n    }\n  }\n}\n\n/**\n * Creates a function that decodes entities in a string.\n *\n * @param decodeTree The decode tree.\n * @returns A function that decodes entities in a string.\n */ function getDecoder(decodeTree) {\n  let ret = \"\";\n  const decoder = new EntityDecoder(decodeTree, str => ret += fromCodePoint$1(str));\n  return function decodeWithTrie(str, decodeMode) {\n    let lastIndex = 0;\n    let offset = 0;\n    while ((offset = str.indexOf(\"&\", offset)) >= 0) {\n      ret += str.slice(lastIndex, offset);\n      decoder.startEntity(decodeMode);\n      const len = decoder.write(str, \n      // Skip the \"&\"\n      offset + 1);\n      if (len < 0) {\n        lastIndex = offset + decoder.end();\n        break;\n      }\n      lastIndex = offset + len;\n      // If `len` is 0, skip the current `&` and continue.\n            offset = len === 0 ? lastIndex + 1 : lastIndex;\n    }\n    const result = ret + str.slice(lastIndex);\n    // Make sure we don't keep a reference to the final string.\n        ret = \"\";\n    return result;\n  };\n}\n\n/**\n * Determines the branch of the current node that is taken given the current\n * character. This function is used to traverse the trie.\n *\n * @param decodeTree The trie.\n * @param current The current node.\n * @param nodeIdx The index right after the current node and its value.\n * @param char The current character.\n * @returns The index of the next node, or -1 if no branch is taken.\n */ function determineBranch(decodeTree, current, nodeIdx, char) {\n  const branchCount = (current & BinTrieFlags.BRANCH_LENGTH) >> 7;\n  const jumpOffset = current & BinTrieFlags.JUMP_TABLE;\n  // Case 1: Single branch encoded in jump offset\n    if (branchCount === 0) {\n    return jumpOffset !== 0 && char === jumpOffset ? nodeIdx : -1;\n  }\n  // Case 2: Multiple branches encoded in jump table\n    if (jumpOffset) {\n    const value = char - jumpOffset;\n    return value < 0 || value >= branchCount ? -1 : decodeTree[nodeIdx + value] - 1;\n  }\n  // Case 3: Multiple branches encoded in dictionary\n  // Binary search for the character.\n    let lo = nodeIdx;\n  let hi = lo + branchCount - 1;\n  while (lo <= hi) {\n    const mid = lo + hi >>> 1;\n    const midVal = decodeTree[mid];\n    if (midVal < char) {\n      lo = mid + 1;\n    } else if (midVal > char) {\n      hi = mid - 1;\n    } else {\n      return decodeTree[mid + branchCount];\n    }\n  }\n  return -1;\n}\n\nconst htmlDecoder = getDecoder(htmlDecodeTree);\n\ngetDecoder(xmlDecodeTree);\n\n/**\n * Decodes an HTML string.\n *\n * @param str The string to decode.\n * @param mode The decoding mode.\n * @returns The decoded string.\n */ function decodeHTML(str, mode = DecodingMode.Legacy) {\n  return htmlDecoder(str, mode);\n}\n\n// Utilities\n\nfunction _class$1(obj) {\n  return Object.prototype.toString.call(obj);\n}\n\nfunction isString$1(obj) {\n  return _class$1(obj) === \"[object String]\";\n}\n\nconst _hasOwnProperty = Object.prototype.hasOwnProperty;\n\nfunction has(object, key) {\n  return _hasOwnProperty.call(object, key);\n}\n\n// Merge objects\n\nfunction assign$1(obj /* from1, from2, from3, ... */) {\n  const sources = Array.prototype.slice.call(arguments, 1);\n  sources.forEach(function(source) {\n    if (!source) {\n      return;\n    }\n    if (typeof source !== \"object\") {\n      throw new TypeError(source + \"must be object\");\n    }\n    Object.keys(source).forEach(function(key) {\n      obj[key] = source[key];\n    });\n  });\n  return obj;\n}\n\n// Remove element from array and put another array at those position.\n// Useful for some operations with tokens\nfunction arrayReplaceAt(src, pos, newElements) {\n  return [].concat(src.slice(0, pos), newElements, src.slice(pos + 1));\n}\n\nfunction isValidEntityCode(c) {\n  /* eslint no-bitwise:0 */\n  // broken sequence\n  if (c >= 55296 && c <= 57343) {\n    return false;\n  }\n  // never used\n    if (c >= 64976 && c <= 65007) {\n    return false;\n  }\n  if ((c & 65535) === 65535 || (c & 65535) === 65534) {\n    return false;\n  }\n  // control codes\n    if (c >= 0 && c <= 8) {\n    return false;\n  }\n  if (c === 11) {\n    return false;\n  }\n  if (c >= 14 && c <= 31) {\n    return false;\n  }\n  if (c >= 127 && c <= 159) {\n    return false;\n  }\n  // out of range\n    if (c > 1114111) {\n    return false;\n  }\n  return true;\n}\n\nfunction fromCodePoint(c) {\n  /* eslint no-bitwise:0 */\n  if (c > 65535) {\n    c -= 65536;\n    const surrogate1 = 55296 + (c >> 10);\n    const surrogate2 = 56320 + (c & 1023);\n    return String.fromCharCode(surrogate1, surrogate2);\n  }\n  return String.fromCharCode(c);\n}\n\nconst UNESCAPE_MD_RE = /\\\\([!\"#$%&'()*+,\\-./:;<=>?@[\\\\\\]^_`{|}~])/g;\n\nconst ENTITY_RE = /&([a-z#][a-z0-9]{1,31});/gi;\n\nconst UNESCAPE_ALL_RE = new RegExp(UNESCAPE_MD_RE.source + \"|\" + ENTITY_RE.source, \"gi\");\n\nconst DIGITAL_ENTITY_TEST_RE = /^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))$/i;\n\nfunction replaceEntityPattern(match, name) {\n  if (name.charCodeAt(0) === 35 /* # */ && DIGITAL_ENTITY_TEST_RE.test(name)) {\n    const code = name[1].toLowerCase() === \"x\" ? parseInt(name.slice(2), 16) : parseInt(name.slice(1), 10);\n    if (isValidEntityCode(code)) {\n      return fromCodePoint(code);\n    }\n    return match;\n  }\n  const decoded = decodeHTML(match);\n  if (decoded !== match) {\n    return decoded;\n  }\n  return match;\n}\n\n/* function replaceEntities(str) {\n  if (str.indexOf('&') < 0) { return str; }\n\n  return str.replace(ENTITY_RE, replaceEntityPattern);\n} */ function unescapeMd(str) {\n  if (str.indexOf(\"\\\\\") < 0) {\n    return str;\n  }\n  return str.replace(UNESCAPE_MD_RE, \"$1\");\n}\n\nfunction unescapeAll(str) {\n  if (str.indexOf(\"\\\\\") < 0 && str.indexOf(\"&\") < 0) {\n    return str;\n  }\n  return str.replace(UNESCAPE_ALL_RE, function(match, escaped, entity) {\n    if (escaped) {\n      return escaped;\n    }\n    return replaceEntityPattern(match, entity);\n  });\n}\n\nconst HTML_ESCAPE_TEST_RE = /[&<>\"]/;\n\nconst HTML_ESCAPE_REPLACE_RE = /[&<>\"]/g;\n\nconst HTML_REPLACEMENTS = {\n  \"&\": \"&amp;\",\n  \"<\": \"&lt;\",\n  \">\": \"&gt;\",\n  '\"': \"&quot;\"\n};\n\nfunction replaceUnsafeChar(ch) {\n  return HTML_REPLACEMENTS[ch];\n}\n\nfunction escapeHtml(str) {\n  if (HTML_ESCAPE_TEST_RE.test(str)) {\n    return str.replace(HTML_ESCAPE_REPLACE_RE, replaceUnsafeChar);\n  }\n  return str;\n}\n\nconst REGEXP_ESCAPE_RE = /[.?*+^$[\\]\\\\(){}|-]/g;\n\nfunction escapeRE$1(str) {\n  return str.replace(REGEXP_ESCAPE_RE, \"\\\\$&\");\n}\n\nfunction isSpace(code) {\n  switch (code) {\n   case 9:\n   case 32:\n    return true;\n  }\n  return false;\n}\n\n// Zs (unicode class) || [\\t\\f\\v\\r\\n]\nfunction isWhiteSpace(code) {\n  if (code >= 8192 && code <= 8202) {\n    return true;\n  }\n  switch (code) {\n   case 9:\n // \\t\n       case 10:\n // \\n\n       case 11:\n // \\v\n       case 12:\n // \\f\n       case 13:\n // \\r\n       case 32:\n   case 160:\n   case 5760:\n   case 8239:\n   case 8287:\n   case 12288:\n    return true;\n  }\n  return false;\n}\n\n/* eslint-disable max-len */\n// Currently without astral characters support.\nfunction isPunctChar(ch) {\n  return P.test(ch) || regex.test(ch);\n}\n\n// Markdown ASCII punctuation characters.\n\n// !, \", #, $, %, &, ', (, ), *, +, ,, -, ., /, :, ;, <, =, >, ?, @, [, \\, ], ^, _, `, {, |, }, or ~\n// http://spec.commonmark.org/0.15/#ascii-punctuation-character\n\n// Don't confuse with unicode punctuation !!! It lacks some chars in ascii range.\n\nfunction isMdAsciiPunct(ch) {\n  switch (ch) {\n   case 33 /* ! */ :\n   case 34 /* \" */ :\n   case 35 /* # */ :\n   case 36 /* $ */ :\n   case 37 /* % */ :\n   case 38 /* & */ :\n   case 39 /* ' */ :\n   case 40 /* ( */ :\n   case 41 /* ) */ :\n   case 42 /* * */ :\n   case 43 /* + */ :\n   case 44 /* , */ :\n   case 45 /* - */ :\n   case 46 /* . */ :\n   case 47 /* / */ :\n   case 58 /* : */ :\n   case 59 /* ; */ :\n   case 60 /* < */ :\n   case 61 /* = */ :\n   case 62 /* > */ :\n   case 63 /* ? */ :\n   case 64 /* @ */ :\n   case 91 /* [ */ :\n   case 92 /* \\ */ :\n   case 93 /* ] */ :\n   case 94 /* ^ */ :\n   case 95 /* _ */ :\n   case 96 /* ` */ :\n   case 123 /* { */ :\n   case 124 /* | */ :\n   case 125 /* } */ :\n   case 126 /* ~ */ :\n    return true;\n\n   default:\n    return false;\n  }\n}\n\n// Hepler to unify [reference labels].\n\nfunction normalizeReference(str) {\n  // Trim and collapse whitespace\n  str = str.trim().replace(/\\s+/g, \" \");\n  // In node v10 'ẞ'.toLowerCase() === 'Ṿ', which is presumed to be a bug\n  // fixed in v12 (couldn't find any details).\n  \n  // So treat this one as a special case\n  // (remove this when node v10 is no longer supported).\n  \n    if (\"\\u1e9e\".toLowerCase() === \"\\u1e7e\") {\n    str = str.replace(/\\u1e9e/g, \"\\xdf\");\n  }\n  // .toLowerCase().toUpperCase() should get rid of all differences\n  // between letter variants.\n  \n  // Simple .toLowerCase() doesn't normalize 125 code points correctly,\n  // and .toUpperCase doesn't normalize 6 of them (list of exceptions:\n  // İ, ϴ, ẞ, Ω, K, Å - those are already uppercased, but have differently\n  // uppercased versions).\n  \n  // Here's an example showing how it happens. Lets take greek letter omega:\n  // uppercase U+0398 (Θ), U+03f4 (ϴ) and lowercase U+03b8 (θ), U+03d1 (ϑ)\n  \n  // Unicode entries:\n  // 0398;GREEK CAPITAL LETTER THETA;Lu;0;L;;;;;N;;;;03B8;\n  // 03B8;GREEK SMALL LETTER THETA;Ll;0;L;;;;;N;;;0398;;0398\n  // 03D1;GREEK THETA SYMBOL;Ll;0;L;<compat> 03B8;;;;N;GREEK SMALL LETTER SCRIPT THETA;;0398;;0398\n  // 03F4;GREEK CAPITAL THETA SYMBOL;Lu;0;L;<compat> 0398;;;;N;;;;03B8;\n  \n  // Case-insensitive comparison should treat all of them as equivalent.\n  \n  // But .toLowerCase() doesn't change ϑ (it's already lowercase),\n  // and .toUpperCase() doesn't change ϴ (already uppercase).\n  \n  // Applying first lower then upper case normalizes any character:\n  // '\\u0398\\u03f4\\u03b8\\u03d1'.toLowerCase().toUpperCase() === '\\u0398\\u0398\\u0398\\u0398'\n  \n  // Note: this is equivalent to unicode case folding; unicode normalization\n  // is a different step that is not required here.\n  \n  // Final result should be uppercased, because it's later stored in an object\n  // (this avoid a conflict with Object.prototype members,\n  // most notably, `__proto__`)\n  \n    return str.toLowerCase().toUpperCase();\n}\n\n// Re-export libraries commonly used in both markdown-it and its plugins,\n// so plugins won't have to depend on them explicitly, which reduces their\n// bundled size (e.g. a browser build).\n\nconst lib = {\n  mdurl: mdurl,\n  ucmicro: ucmicro\n};\n\nvar utils =  Object.freeze({\n  __proto__: null,\n  arrayReplaceAt: arrayReplaceAt,\n  assign: assign$1,\n  escapeHtml: escapeHtml,\n  escapeRE: escapeRE$1,\n  fromCodePoint: fromCodePoint,\n  has: has,\n  isMdAsciiPunct: isMdAsciiPunct,\n  isPunctChar: isPunctChar,\n  isSpace: isSpace,\n  isString: isString$1,\n  isValidEntityCode: isValidEntityCode,\n  isWhiteSpace: isWhiteSpace,\n  lib: lib,\n  normalizeReference: normalizeReference,\n  unescapeAll: unescapeAll,\n  unescapeMd: unescapeMd\n});\n\n// Parse link label\n\n// this function assumes that first character (\"[\") already matches;\n// returns the end of the label\n\nfunction parseLinkLabel(state, start, disableNested) {\n  let level, found, marker, prevPos;\n  const max = state.posMax;\n  const oldPos = state.pos;\n  state.pos = start + 1;\n  level = 1;\n  while (state.pos < max) {\n    marker = state.src.charCodeAt(state.pos);\n    if (marker === 93 /* ] */) {\n      level--;\n      if (level === 0) {\n        found = true;\n        break;\n      }\n    }\n    prevPos = state.pos;\n    state.md.inline.skipToken(state);\n    if (marker === 91 /* [ */) {\n      if (prevPos === state.pos - 1) {\n        // increase level if we find text `[`, which is not a part of any token\n        level++;\n      } else if (disableNested) {\n        state.pos = oldPos;\n        return -1;\n      }\n    }\n  }\n  let labelEnd = -1;\n  if (found) {\n    labelEnd = state.pos;\n  }\n  // restore old state\n    state.pos = oldPos;\n  return labelEnd;\n}\n\n// Parse link destination\n\nfunction parseLinkDestination(str, start, max) {\n  let code;\n  let pos = start;\n  const result = {\n    ok: false,\n    pos: 0,\n    str: \"\"\n  };\n  if (str.charCodeAt(pos) === 60 /* < */) {\n    pos++;\n    while (pos < max) {\n      code = str.charCodeAt(pos);\n      if (code === 10 /* \\n */) {\n        return result;\n      }\n      if (code === 60 /* < */) {\n        return result;\n      }\n      if (code === 62 /* > */) {\n        result.pos = pos + 1;\n        result.str = unescapeAll(str.slice(start + 1, pos));\n        result.ok = true;\n        return result;\n      }\n      if (code === 92 /* \\ */ && pos + 1 < max) {\n        pos += 2;\n        continue;\n      }\n      pos++;\n    }\n    // no closing '>'\n        return result;\n  }\n  // this should be ... } else { ... branch\n    let level = 0;\n  while (pos < max) {\n    code = str.charCodeAt(pos);\n    if (code === 32) {\n      break;\n    }\n    // ascii control characters\n        if (code < 32 || code === 127) {\n      break;\n    }\n    if (code === 92 /* \\ */ && pos + 1 < max) {\n      if (str.charCodeAt(pos + 1) === 32) {\n        break;\n      }\n      pos += 2;\n      continue;\n    }\n    if (code === 40 /* ( */) {\n      level++;\n      if (level > 32) {\n        return result;\n      }\n    }\n    if (code === 41 /* ) */) {\n      if (level === 0) {\n        break;\n      }\n      level--;\n    }\n    pos++;\n  }\n  if (start === pos) {\n    return result;\n  }\n  if (level !== 0) {\n    return result;\n  }\n  result.str = unescapeAll(str.slice(start, pos));\n  result.pos = pos;\n  result.ok = true;\n  return result;\n}\n\n// Parse link title\n\n// Parse link title within `str` in [start, max] range,\n// or continue previous parsing if `prev_state` is defined (equal to result of last execution).\n\nfunction parseLinkTitle(str, start, max, prev_state) {\n  let code;\n  let pos = start;\n  const state = {\n    // if `true`, this is a valid link title\n    ok: false,\n    // if `true`, this link can be continued on the next line\n    can_continue: false,\n    // if `ok`, it's the position of the first character after the closing marker\n    pos: 0,\n    // if `ok`, it's the unescaped title\n    str: \"\",\n    // expected closing marker character code\n    marker: 0\n  };\n  if (prev_state) {\n    // this is a continuation of a previous parseLinkTitle call on the next line,\n    // used in reference links only\n    state.str = prev_state.str;\n    state.marker = prev_state.marker;\n  } else {\n    if (pos >= max) {\n      return state;\n    }\n    let marker = str.charCodeAt(pos);\n    if (marker !== 34 /* \" */ && marker !== 39 /* ' */ && marker !== 40 /* ( */) {\n      return state;\n    }\n    start++;\n    pos++;\n    // if opening marker is \"(\", switch it to closing marker \")\"\n        if (marker === 40) {\n      marker = 41;\n    }\n    state.marker = marker;\n  }\n  while (pos < max) {\n    code = str.charCodeAt(pos);\n    if (code === state.marker) {\n      state.pos = pos + 1;\n      state.str += unescapeAll(str.slice(start, pos));\n      state.ok = true;\n      return state;\n    } else if (code === 40 /* ( */ && state.marker === 41 /* ) */) {\n      return state;\n    } else if (code === 92 /* \\ */ && pos + 1 < max) {\n      pos++;\n    }\n    pos++;\n  }\n  // no closing marker found, but this link title may continue on the next line (for references)\n    state.can_continue = true;\n  state.str += unescapeAll(str.slice(start, pos));\n  return state;\n}\n\n// Just a shortcut for bulk export\nvar helpers =  Object.freeze({\n  __proto__: null,\n  parseLinkDestination: parseLinkDestination,\n  parseLinkLabel: parseLinkLabel,\n  parseLinkTitle: parseLinkTitle\n});\n\n/**\n * class Renderer\n *\n * Generates HTML from parsed token stream. Each instance has independent\n * copy of rules. Those can be rewritten with ease. Also, you can add new\n * rules if you create plugin and adds new token types.\n **/ const default_rules = {};\n\ndefault_rules.code_inline = function(tokens, idx, options, env, slf) {\n  const token = tokens[idx];\n  return \"<code\" + slf.renderAttrs(token) + \">\" + escapeHtml(token.content) + \"</code>\";\n};\n\ndefault_rules.code_block = function(tokens, idx, options, env, slf) {\n  const token = tokens[idx];\n  return \"<pre\" + slf.renderAttrs(token) + \"><code>\" + escapeHtml(tokens[idx].content) + \"</code></pre>\\n\";\n};\n\ndefault_rules.fence = function(tokens, idx, options, env, slf) {\n  const token = tokens[idx];\n  const info = token.info ? unescapeAll(token.info).trim() : \"\";\n  let langName = \"\";\n  let langAttrs = \"\";\n  if (info) {\n    const arr = info.split(/(\\s+)/g);\n    langName = arr[0];\n    langAttrs = arr.slice(2).join(\"\");\n  }\n  let highlighted;\n  if (options.highlight) {\n    highlighted = options.highlight(token.content, langName, langAttrs) || escapeHtml(token.content);\n  } else {\n    highlighted = escapeHtml(token.content);\n  }\n  if (highlighted.indexOf(\"<pre\") === 0) {\n    return highlighted + \"\\n\";\n  }\n  // If language exists, inject class gently, without modifying original token.\n  // May be, one day we will add .deepClone() for token and simplify this part, but\n  // now we prefer to keep things local.\n    if (info) {\n    const i = token.attrIndex(\"class\");\n    const tmpAttrs = token.attrs ? token.attrs.slice() : [];\n    if (i < 0) {\n      tmpAttrs.push([ \"class\", options.langPrefix + langName ]);\n    } else {\n      tmpAttrs[i] = tmpAttrs[i].slice();\n      tmpAttrs[i][1] += \" \" + options.langPrefix + langName;\n    }\n    // Fake token just to render attributes\n        const tmpToken = {\n      attrs: tmpAttrs\n    };\n    return `<pre><code${slf.renderAttrs(tmpToken)}>${highlighted}</code></pre>\\n`;\n  }\n  return `<pre><code${slf.renderAttrs(token)}>${highlighted}</code></pre>\\n`;\n};\n\ndefault_rules.image = function(tokens, idx, options, env, slf) {\n  const token = tokens[idx];\n  // \"alt\" attr MUST be set, even if empty. Because it's mandatory and\n  // should be placed on proper position for tests.\n  \n  // Replace content with actual value\n    token.attrs[token.attrIndex(\"alt\")][1] = slf.renderInlineAsText(token.children, options, env);\n  return slf.renderToken(tokens, idx, options);\n};\n\ndefault_rules.hardbreak = function(tokens, idx, options /*, env */) {\n  return options.xhtmlOut ? \"<br />\\n\" : \"<br>\\n\";\n};\n\ndefault_rules.softbreak = function(tokens, idx, options /*, env */) {\n  return options.breaks ? options.xhtmlOut ? \"<br />\\n\" : \"<br>\\n\" : \"\\n\";\n};\n\ndefault_rules.text = function(tokens, idx /*, options, env */) {\n  return escapeHtml(tokens[idx].content);\n};\n\ndefault_rules.html_block = function(tokens, idx /*, options, env */) {\n  return tokens[idx].content;\n};\n\ndefault_rules.html_inline = function(tokens, idx /*, options, env */) {\n  return tokens[idx].content;\n};\n\n/**\n * new Renderer()\n *\n * Creates new [[Renderer]] instance and fill [[Renderer#rules]] with defaults.\n **/ function Renderer() {\n  /**\n   * Renderer#rules -> Object\n   *\n   * Contains render rules for tokens. Can be updated and extended.\n   *\n   * ##### Example\n   *\n   * ```javascript\n   * var md = require('markdown-it')();\n   *\n   * md.renderer.rules.strong_open  = function () { return '<b>'; };\n   * md.renderer.rules.strong_close = function () { return '</b>'; };\n   *\n   * var result = md.renderInline(...);\n   * ```\n   *\n   * Each rule is called as independent static function with fixed signature:\n   *\n   * ```javascript\n   * function my_token_render(tokens, idx, options, env, renderer) {\n   *   // ...\n   *   return renderedHTML;\n   * }\n   * ```\n   *\n   * See [source code](https://github.com/markdown-it/markdown-it/blob/master/lib/renderer.mjs)\n   * for more details and examples.\n   **/\n  this.rules = assign$1({}, default_rules);\n}\n\n/**\n * Renderer.renderAttrs(token) -> String\n *\n * Render token attributes to string.\n **/ Renderer.prototype.renderAttrs = function renderAttrs(token) {\n  let i, l, result;\n  if (!token.attrs) {\n    return \"\";\n  }\n  result = \"\";\n  for (i = 0, l = token.attrs.length; i < l; i++) {\n    result += \" \" + escapeHtml(token.attrs[i][0]) + '=\"' + escapeHtml(token.attrs[i][1]) + '\"';\n  }\n  return result;\n};\n\n/**\n * Renderer.renderToken(tokens, idx, options) -> String\n * - tokens (Array): list of tokens\n * - idx (Numbed): token index to render\n * - options (Object): params of parser instance\n *\n * Default token renderer. Can be overriden by custom function\n * in [[Renderer#rules]].\n **/ Renderer.prototype.renderToken = function renderToken(tokens, idx, options) {\n  const token = tokens[idx];\n  let result = \"\";\n  // Tight list paragraphs\n    if (token.hidden) {\n    return \"\";\n  }\n  // Insert a newline between hidden paragraph and subsequent opening\n  // block-level tag.\n  \n  // For example, here we should insert a newline before blockquote:\n  //  - a\n  //    >\n  \n    if (token.block && token.nesting !== -1 && idx && tokens[idx - 1].hidden) {\n    result += \"\\n\";\n  }\n  // Add token name, e.g. `<img`\n    result += (token.nesting === -1 ? \"</\" : \"<\") + token.tag;\n  // Encode attributes, e.g. `<img src=\"foo\"`\n    result += this.renderAttrs(token);\n  // Add a slash for self-closing tags, e.g. `<img src=\"foo\" /`\n    if (token.nesting === 0 && options.xhtmlOut) {\n    result += \" /\";\n  }\n  // Check if we need to add a newline after this tag\n    let needLf = false;\n  if (token.block) {\n    needLf = true;\n    if (token.nesting === 1) {\n      if (idx + 1 < tokens.length) {\n        const nextToken = tokens[idx + 1];\n        if (nextToken.type === \"inline\" || nextToken.hidden) {\n          // Block-level tag containing an inline tag.\n          needLf = false;\n        } else if (nextToken.nesting === -1 && nextToken.tag === token.tag) {\n          // Opening tag + closing tag of the same type. E.g. `<li></li>`.\n          needLf = false;\n        }\n      }\n    }\n  }\n  result += needLf ? \">\\n\" : \">\";\n  return result;\n};\n\n/**\n * Renderer.renderInline(tokens, options, env) -> String\n * - tokens (Array): list on block tokens to render\n * - options (Object): params of parser instance\n * - env (Object): additional data from parsed input (references, for example)\n *\n * The same as [[Renderer.render]], but for single token of `inline` type.\n **/ Renderer.prototype.renderInline = function(tokens, options, env) {\n  let result = \"\";\n  const rules = this.rules;\n  for (let i = 0, len = tokens.length; i < len; i++) {\n    const type = tokens[i].type;\n    if (typeof rules[type] !== \"undefined\") {\n      result += rules[type](tokens, i, options, env, this);\n    } else {\n      result += this.renderToken(tokens, i, options);\n    }\n  }\n  return result;\n};\n\n/** internal\n * Renderer.renderInlineAsText(tokens, options, env) -> String\n * - tokens (Array): list on block tokens to render\n * - options (Object): params of parser instance\n * - env (Object): additional data from parsed input (references, for example)\n *\n * Special kludge for image `alt` attributes to conform CommonMark spec.\n * Don't try to use it! Spec requires to show `alt` content with stripped markup,\n * instead of simple escaping.\n **/ Renderer.prototype.renderInlineAsText = function(tokens, options, env) {\n  let result = \"\";\n  for (let i = 0, len = tokens.length; i < len; i++) {\n    switch (tokens[i].type) {\n     case \"text\":\n      result += tokens[i].content;\n      break;\n\n     case \"image\":\n      result += this.renderInlineAsText(tokens[i].children, options, env);\n      break;\n\n     case \"html_inline\":\n     case \"html_block\":\n      result += tokens[i].content;\n      break;\n\n     case \"softbreak\":\n     case \"hardbreak\":\n      result += \"\\n\";\n      break;\n      // all other tokens are skipped\n        }\n  }\n  return result;\n};\n\n/**\n * Renderer.render(tokens, options, env) -> String\n * - tokens (Array): list on block tokens to render\n * - options (Object): params of parser instance\n * - env (Object): additional data from parsed input (references, for example)\n *\n * Takes token stream and generates HTML. Probably, you will never need to call\n * this method directly.\n **/ Renderer.prototype.render = function(tokens, options, env) {\n  let result = \"\";\n  const rules = this.rules;\n  for (let i = 0, len = tokens.length; i < len; i++) {\n    const type = tokens[i].type;\n    if (type === \"inline\") {\n      result += this.renderInline(tokens[i].children, options, env);\n    } else if (typeof rules[type] !== \"undefined\") {\n      result += rules[type](tokens, i, options, env, this);\n    } else {\n      result += this.renderToken(tokens, i, options, env);\n    }\n  }\n  return result;\n};\n\n/**\n * class Ruler\n *\n * Helper class, used by [[MarkdownIt#core]], [[MarkdownIt#block]] and\n * [[MarkdownIt#inline]] to manage sequences of functions (rules):\n *\n * - keep rules in defined order\n * - assign the name to each rule\n * - enable/disable rules\n * - add/replace rules\n * - allow assign rules to additional named chains (in the same)\n * - cacheing lists of active rules\n *\n * You will not need use this class directly until write plugins. For simple\n * rules control use [[MarkdownIt.disable]], [[MarkdownIt.enable]] and\n * [[MarkdownIt.use]].\n **/\n/**\n * new Ruler()\n **/ function Ruler() {\n  // List of added rules. Each element is:\n  // {\n  //   name: XXX,\n  //   enabled: Boolean,\n  //   fn: Function(),\n  //   alt: [ name2, name3 ]\n  // }\n  this.__rules__ = [];\n  // Cached rule chains.\n  \n  // First level - chain name, '' for default.\n  // Second level - diginal anchor for fast filtering by charcodes.\n  \n    this.__cache__ = null;\n}\n\n// Helper methods, should not be used directly\n// Find rule index by name\n\nRuler.prototype.__find__ = function(name) {\n  for (let i = 0; i < this.__rules__.length; i++) {\n    if (this.__rules__[i].name === name) {\n      return i;\n    }\n  }\n  return -1;\n};\n\n// Build rules lookup cache\n\nRuler.prototype.__compile__ = function() {\n  const self = this;\n  const chains = [ \"\" ];\n  // collect unique names\n    self.__rules__.forEach(function(rule) {\n    if (!rule.enabled) {\n      return;\n    }\n    rule.alt.forEach(function(altName) {\n      if (chains.indexOf(altName) < 0) {\n        chains.push(altName);\n      }\n    });\n  });\n  self.__cache__ = {};\n  chains.forEach(function(chain) {\n    self.__cache__[chain] = [];\n    self.__rules__.forEach(function(rule) {\n      if (!rule.enabled) {\n        return;\n      }\n      if (chain && rule.alt.indexOf(chain) < 0) {\n        return;\n      }\n      self.__cache__[chain].push(rule.fn);\n    });\n  });\n};\n\n/**\n * Ruler.at(name, fn [, options])\n * - name (String): rule name to replace.\n * - fn (Function): new rule function.\n * - options (Object): new rule options (not mandatory).\n *\n * Replace rule by name with new function & options. Throws error if name not\n * found.\n *\n * ##### Options:\n *\n * - __alt__ - array with names of \"alternate\" chains.\n *\n * ##### Example\n *\n * Replace existing typographer replacement rule with new one:\n *\n * ```javascript\n * var md = require('markdown-it')();\n *\n * md.core.ruler.at('replacements', function replace(state) {\n *   //...\n * });\n * ```\n **/ Ruler.prototype.at = function(name, fn, options) {\n  const index = this.__find__(name);\n  const opt = options || {};\n  if (index === -1) {\n    throw new Error(\"Parser rule not found: \" + name);\n  }\n  this.__rules__[index].fn = fn;\n  this.__rules__[index].alt = opt.alt || [];\n  this.__cache__ = null;\n};\n\n/**\n * Ruler.before(beforeName, ruleName, fn [, options])\n * - beforeName (String): new rule will be added before this one.\n * - ruleName (String): name of added rule.\n * - fn (Function): rule function.\n * - options (Object): rule options (not mandatory).\n *\n * Add new rule to chain before one with given name. See also\n * [[Ruler.after]], [[Ruler.push]].\n *\n * ##### Options:\n *\n * - __alt__ - array with names of \"alternate\" chains.\n *\n * ##### Example\n *\n * ```javascript\n * var md = require('markdown-it')();\n *\n * md.block.ruler.before('paragraph', 'my_rule', function replace(state) {\n *   //...\n * });\n * ```\n **/ Ruler.prototype.before = function(beforeName, ruleName, fn, options) {\n  const index = this.__find__(beforeName);\n  const opt = options || {};\n  if (index === -1) {\n    throw new Error(\"Parser rule not found: \" + beforeName);\n  }\n  this.__rules__.splice(index, 0, {\n    name: ruleName,\n    enabled: true,\n    fn: fn,\n    alt: opt.alt || []\n  });\n  this.__cache__ = null;\n};\n\n/**\n * Ruler.after(afterName, ruleName, fn [, options])\n * - afterName (String): new rule will be added after this one.\n * - ruleName (String): name of added rule.\n * - fn (Function): rule function.\n * - options (Object): rule options (not mandatory).\n *\n * Add new rule to chain after one with given name. See also\n * [[Ruler.before]], [[Ruler.push]].\n *\n * ##### Options:\n *\n * - __alt__ - array with names of \"alternate\" chains.\n *\n * ##### Example\n *\n * ```javascript\n * var md = require('markdown-it')();\n *\n * md.inline.ruler.after('text', 'my_rule', function replace(state) {\n *   //...\n * });\n * ```\n **/ Ruler.prototype.after = function(afterName, ruleName, fn, options) {\n  const index = this.__find__(afterName);\n  const opt = options || {};\n  if (index === -1) {\n    throw new Error(\"Parser rule not found: \" + afterName);\n  }\n  this.__rules__.splice(index + 1, 0, {\n    name: ruleName,\n    enabled: true,\n    fn: fn,\n    alt: opt.alt || []\n  });\n  this.__cache__ = null;\n};\n\n/**\n * Ruler.push(ruleName, fn [, options])\n * - ruleName (String): name of added rule.\n * - fn (Function): rule function.\n * - options (Object): rule options (not mandatory).\n *\n * Push new rule to the end of chain. See also\n * [[Ruler.before]], [[Ruler.after]].\n *\n * ##### Options:\n *\n * - __alt__ - array with names of \"alternate\" chains.\n *\n * ##### Example\n *\n * ```javascript\n * var md = require('markdown-it')();\n *\n * md.core.ruler.push('my_rule', function replace(state) {\n *   //...\n * });\n * ```\n **/ Ruler.prototype.push = function(ruleName, fn, options) {\n  const opt = options || {};\n  this.__rules__.push({\n    name: ruleName,\n    enabled: true,\n    fn: fn,\n    alt: opt.alt || []\n  });\n  this.__cache__ = null;\n};\n\n/**\n * Ruler.enable(list [, ignoreInvalid]) -> Array\n * - list (String|Array): list of rule names to enable.\n * - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found.\n *\n * Enable rules with given names. If any rule name not found - throw Error.\n * Errors can be disabled by second param.\n *\n * Returns list of found rule names (if no exception happened).\n *\n * See also [[Ruler.disable]], [[Ruler.enableOnly]].\n **/ Ruler.prototype.enable = function(list, ignoreInvalid) {\n  if (!Array.isArray(list)) {\n    list = [ list ];\n  }\n  const result = [];\n  // Search by name and enable\n    list.forEach(function(name) {\n    const idx = this.__find__(name);\n    if (idx < 0) {\n      if (ignoreInvalid) {\n        return;\n      }\n      throw new Error(\"Rules manager: invalid rule name \" + name);\n    }\n    this.__rules__[idx].enabled = true;\n    result.push(name);\n  }, this);\n  this.__cache__ = null;\n  return result;\n};\n\n/**\n * Ruler.enableOnly(list [, ignoreInvalid])\n * - list (String|Array): list of rule names to enable (whitelist).\n * - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found.\n *\n * Enable rules with given names, and disable everything else. If any rule name\n * not found - throw Error. Errors can be disabled by second param.\n *\n * See also [[Ruler.disable]], [[Ruler.enable]].\n **/ Ruler.prototype.enableOnly = function(list, ignoreInvalid) {\n  if (!Array.isArray(list)) {\n    list = [ list ];\n  }\n  this.__rules__.forEach(function(rule) {\n    rule.enabled = false;\n  });\n  this.enable(list, ignoreInvalid);\n};\n\n/**\n * Ruler.disable(list [, ignoreInvalid]) -> Array\n * - list (String|Array): list of rule names to disable.\n * - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found.\n *\n * Disable rules with given names. If any rule name not found - throw Error.\n * Errors can be disabled by second param.\n *\n * Returns list of found rule names (if no exception happened).\n *\n * See also [[Ruler.enable]], [[Ruler.enableOnly]].\n **/ Ruler.prototype.disable = function(list, ignoreInvalid) {\n  if (!Array.isArray(list)) {\n    list = [ list ];\n  }\n  const result = [];\n  // Search by name and disable\n    list.forEach(function(name) {\n    const idx = this.__find__(name);\n    if (idx < 0) {\n      if (ignoreInvalid) {\n        return;\n      }\n      throw new Error(\"Rules manager: invalid rule name \" + name);\n    }\n    this.__rules__[idx].enabled = false;\n    result.push(name);\n  }, this);\n  this.__cache__ = null;\n  return result;\n};\n\n/**\n * Ruler.getRules(chainName) -> Array\n *\n * Return array of active functions (rules) for given chain name. It analyzes\n * rules configuration, compiles caches if not exists and returns result.\n *\n * Default chain name is `''` (empty string). It can't be skipped. That's\n * done intentionally, to keep signature monomorphic for high speed.\n **/ Ruler.prototype.getRules = function(chainName) {\n  if (this.__cache__ === null) {\n    this.__compile__();\n  }\n  // Chain can be empty, if rules disabled. But we still have to return Array.\n    return this.__cache__[chainName] || [];\n};\n\n// Token class\n/**\n * class Token\n **/\n/**\n * new Token(type, tag, nesting)\n *\n * Create new token and fill passed properties.\n **/ function Token(type, tag, nesting) {\n  /**\n   * Token#type -> String\n   *\n   * Type of the token (string, e.g. \"paragraph_open\")\n   **/\n  this.type = type;\n  /**\n   * Token#tag -> String\n   *\n   * html tag name, e.g. \"p\"\n   **/  this.tag = tag;\n  /**\n   * Token#attrs -> Array\n   *\n   * Html attributes. Format: `[ [ name1, value1 ], [ name2, value2 ] ]`\n   **/  this.attrs = null;\n  /**\n   * Token#map -> Array\n   *\n   * Source map info. Format: `[ line_begin, line_end ]`\n   **/  this.map = null;\n  /**\n   * Token#nesting -> Number\n   *\n   * Level change (number in {-1, 0, 1} set), where:\n   *\n   * -  `1` means the tag is opening\n   * -  `0` means the tag is self-closing\n   * - `-1` means the tag is closing\n   **/  this.nesting = nesting;\n  /**\n   * Token#level -> Number\n   *\n   * nesting level, the same as `state.level`\n   **/  this.level = 0;\n  /**\n   * Token#children -> Array\n   *\n   * An array of child nodes (inline and img tokens)\n   **/  this.children = null;\n  /**\n   * Token#content -> String\n   *\n   * In a case of self-closing tag (code, html, fence, etc.),\n   * it has contents of this tag.\n   **/  this.content = \"\";\n  /**\n   * Token#markup -> String\n   *\n   * '*' or '_' for emphasis, fence string for fence, etc.\n   **/  this.markup = \"\";\n  /**\n   * Token#info -> String\n   *\n   * Additional information:\n   *\n   * - Info string for \"fence\" tokens\n   * - The value \"auto\" for autolink \"link_open\" and \"link_close\" tokens\n   * - The string value of the item marker for ordered-list \"list_item_open\" tokens\n   **/  this.info = \"\";\n  /**\n   * Token#meta -> Object\n   *\n   * A place for plugins to store an arbitrary data\n   **/  this.meta = null;\n  /**\n   * Token#block -> Boolean\n   *\n   * True for block-level tokens, false for inline tokens.\n   * Used in renderer to calculate line breaks\n   **/  this.block = false;\n  /**\n   * Token#hidden -> Boolean\n   *\n   * If it's true, ignore this element when rendering. Used for tight lists\n   * to hide paragraphs.\n   **/  this.hidden = false;\n}\n\n/**\n * Token.attrIndex(name) -> Number\n *\n * Search attribute index by name.\n **/ Token.prototype.attrIndex = function attrIndex(name) {\n  if (!this.attrs) {\n    return -1;\n  }\n  const attrs = this.attrs;\n  for (let i = 0, len = attrs.length; i < len; i++) {\n    if (attrs[i][0] === name) {\n      return i;\n    }\n  }\n  return -1;\n};\n\n/**\n * Token.attrPush(attrData)\n *\n * Add `[ name, value ]` attribute to list. Init attrs if necessary\n **/ Token.prototype.attrPush = function attrPush(attrData) {\n  if (this.attrs) {\n    this.attrs.push(attrData);\n  } else {\n    this.attrs = [ attrData ];\n  }\n};\n\n/**\n * Token.attrSet(name, value)\n *\n * Set `name` attribute to `value`. Override old value if exists.\n **/ Token.prototype.attrSet = function attrSet(name, value) {\n  const idx = this.attrIndex(name);\n  const attrData = [ name, value ];\n  if (idx < 0) {\n    this.attrPush(attrData);\n  } else {\n    this.attrs[idx] = attrData;\n  }\n};\n\n/**\n * Token.attrGet(name)\n *\n * Get the value of attribute `name`, or null if it does not exist.\n **/ Token.prototype.attrGet = function attrGet(name) {\n  const idx = this.attrIndex(name);\n  let value = null;\n  if (idx >= 0) {\n    value = this.attrs[idx][1];\n  }\n  return value;\n};\n\n/**\n * Token.attrJoin(name, value)\n *\n * Join value to existing attribute via space. Or create new attribute if not\n * exists. Useful to operate with token classes.\n **/ Token.prototype.attrJoin = function attrJoin(name, value) {\n  const idx = this.attrIndex(name);\n  if (idx < 0) {\n    this.attrPush([ name, value ]);\n  } else {\n    this.attrs[idx][1] = this.attrs[idx][1] + \" \" + value;\n  }\n};\n\n// Core state object\n\nfunction StateCore(src, md, env) {\n  this.src = src;\n  this.env = env;\n  this.tokens = [];\n  this.inlineMode = false;\n  this.md = md;\n // link to parser instance\n}\n\n// re-export Token class to use in core rules\nStateCore.prototype.Token = Token;\n\n// Normalize input string\n// https://spec.commonmark.org/0.29/#line-ending\nconst NEWLINES_RE = /\\r\\n?|\\n/g;\n\nconst NULL_RE = /\\0/g;\n\nfunction normalize(state) {\n  let str;\n  // Normalize newlines\n    str = state.src.replace(NEWLINES_RE, \"\\n\");\n  // Replace NULL characters\n    str = str.replace(NULL_RE, \"\\ufffd\");\n  state.src = str;\n}\n\nfunction block(state) {\n  let token;\n  if (state.inlineMode) {\n    token = new state.Token(\"inline\", \"\", 0);\n    token.content = state.src;\n    token.map = [ 0, 1 ];\n    token.children = [];\n    state.tokens.push(token);\n  } else {\n    state.md.block.parse(state.src, state.md, state.env, state.tokens);\n  }\n}\n\nfunction inline(state) {\n  const tokens = state.tokens;\n  // Parse inlines\n    for (let i = 0, l = tokens.length; i < l; i++) {\n    const tok = tokens[i];\n    if (tok.type === \"inline\") {\n      state.md.inline.parse(tok.content, state.md, state.env, tok.children);\n    }\n  }\n}\n\n// Replace link-like texts with link nodes.\n\n// Currently restricted by `md.validateLink()` to http/https/ftp\n\nfunction isLinkOpen$1(str) {\n  return /^<a[>\\s]/i.test(str);\n}\n\nfunction isLinkClose$1(str) {\n  return /^<\\/a\\s*>/i.test(str);\n}\n\nfunction linkify$1(state) {\n  const blockTokens = state.tokens;\n  if (!state.md.options.linkify) {\n    return;\n  }\n  for (let j = 0, l = blockTokens.length; j < l; j++) {\n    if (blockTokens[j].type !== \"inline\" || !state.md.linkify.pretest(blockTokens[j].content)) {\n      continue;\n    }\n    let tokens = blockTokens[j].children;\n    let htmlLinkLevel = 0;\n    // We scan from the end, to keep position when new tags added.\n    // Use reversed logic in links start/end match\n        for (let i = tokens.length - 1; i >= 0; i--) {\n      const currentToken = tokens[i];\n      // Skip content of markdown links\n            if (currentToken.type === \"link_close\") {\n        i--;\n        while (tokens[i].level !== currentToken.level && tokens[i].type !== \"link_open\") {\n          i--;\n        }\n        continue;\n      }\n      // Skip content of html tag links\n            if (currentToken.type === \"html_inline\") {\n        if (isLinkOpen$1(currentToken.content) && htmlLinkLevel > 0) {\n          htmlLinkLevel--;\n        }\n        if (isLinkClose$1(currentToken.content)) {\n          htmlLinkLevel++;\n        }\n      }\n      if (htmlLinkLevel > 0) {\n        continue;\n      }\n      if (currentToken.type === \"text\" && state.md.linkify.test(currentToken.content)) {\n        const text = currentToken.content;\n        let links = state.md.linkify.match(text);\n        // Now split string to nodes\n                const nodes = [];\n        let level = currentToken.level;\n        let lastPos = 0;\n        // forbid escape sequence at the start of the string,\n        // this avoids http\\://example.com/ from being linkified as\n        // http:<a href=\"//example.com/\">//example.com/</a>\n                if (links.length > 0 && links[0].index === 0 && i > 0 && tokens[i - 1].type === \"text_special\") {\n          links = links.slice(1);\n        }\n        for (let ln = 0; ln < links.length; ln++) {\n          const url = links[ln].url;\n          const fullUrl = state.md.normalizeLink(url);\n          if (!state.md.validateLink(fullUrl)) {\n            continue;\n          }\n          let urlText = links[ln].text;\n          // Linkifier might send raw hostnames like \"example.com\", where url\n          // starts with domain name. So we prepend http:// in those cases,\n          // and remove it afterwards.\n          \n                    if (!links[ln].schema) {\n            urlText = state.md.normalizeLinkText(\"http://\" + urlText).replace(/^http:\\/\\//, \"\");\n          } else if (links[ln].schema === \"mailto:\" && !/^mailto:/i.test(urlText)) {\n            urlText = state.md.normalizeLinkText(\"mailto:\" + urlText).replace(/^mailto:/, \"\");\n          } else {\n            urlText = state.md.normalizeLinkText(urlText);\n          }\n          const pos = links[ln].index;\n          if (pos > lastPos) {\n            const token = new state.Token(\"text\", \"\", 0);\n            token.content = text.slice(lastPos, pos);\n            token.level = level;\n            nodes.push(token);\n          }\n          const token_o = new state.Token(\"link_open\", \"a\", 1);\n          token_o.attrs = [ [ \"href\", fullUrl ] ];\n          token_o.level = level++;\n          token_o.markup = \"linkify\";\n          token_o.info = \"auto\";\n          nodes.push(token_o);\n          const token_t = new state.Token(\"text\", \"\", 0);\n          token_t.content = urlText;\n          token_t.level = level;\n          nodes.push(token_t);\n          const token_c = new state.Token(\"link_close\", \"a\", -1);\n          token_c.level = --level;\n          token_c.markup = \"linkify\";\n          token_c.info = \"auto\";\n          nodes.push(token_c);\n          lastPos = links[ln].lastIndex;\n        }\n        if (lastPos < text.length) {\n          const token = new state.Token(\"text\", \"\", 0);\n          token.content = text.slice(lastPos);\n          token.level = level;\n          nodes.push(token);\n        }\n        // replace current node\n                blockTokens[j].children = tokens = arrayReplaceAt(tokens, i, nodes);\n      }\n    }\n  }\n}\n\n// Simple typographic replacements\n\n// (c) (C) → ©\n// (tm) (TM) → ™\n// (r) (R) → ®\n// +- → ±\n// ... → … (also ?.... → ?.., !.... → !..)\n// ???????? → ???, !!!!! → !!!, `,,` → `,`\n// -- → &ndash;, --- → &mdash;\n\n// TODO:\n// - fractionals 1/2, 1/4, 3/4 -> ½, ¼, ¾\n// - multiplications 2 x 4 -> 2 × 4\nconst RARE_RE = /\\+-|\\.\\.|\\?\\?\\?\\?|!!!!|,,|--/;\n\n// Workaround for phantomjs - need regex without /g flag,\n// or root check will fail every second time\nconst SCOPED_ABBR_TEST_RE = /\\((c|tm|r)\\)/i;\n\nconst SCOPED_ABBR_RE = /\\((c|tm|r)\\)/gi;\n\nconst SCOPED_ABBR = {\n  c: \"\\xa9\",\n  r: \"\\xae\",\n  tm: \"\\u2122\"\n};\n\nfunction replaceFn(match, name) {\n  return SCOPED_ABBR[name.toLowerCase()];\n}\n\nfunction replace_scoped(inlineTokens) {\n  let inside_autolink = 0;\n  for (let i = inlineTokens.length - 1; i >= 0; i--) {\n    const token = inlineTokens[i];\n    if (token.type === \"text\" && !inside_autolink) {\n      token.content = token.content.replace(SCOPED_ABBR_RE, replaceFn);\n    }\n    if (token.type === \"link_open\" && token.info === \"auto\") {\n      inside_autolink--;\n    }\n    if (token.type === \"link_close\" && token.info === \"auto\") {\n      inside_autolink++;\n    }\n  }\n}\n\nfunction replace_rare(inlineTokens) {\n  let inside_autolink = 0;\n  for (let i = inlineTokens.length - 1; i >= 0; i--) {\n    const token = inlineTokens[i];\n    if (token.type === \"text\" && !inside_autolink) {\n      if (RARE_RE.test(token.content)) {\n        token.content = token.content.replace(/\\+-/g, \"\\xb1\").replace(/\\.{2,}/g, \"\\u2026\").replace(/([?!])\\u2026/g, \"$1..\").replace(/([?!]){4,}/g, \"$1$1$1\").replace(/,{2,}/g, \",\").replace(/(^|[^-])---(?=[^-]|$)/gm, \"$1\\u2014\").replace(/(^|\\s)--(?=\\s|$)/gm, \"$1\\u2013\").replace(/(^|[^-\\s])--(?=[^-\\s]|$)/gm, \"$1\\u2013\");\n      }\n    }\n    if (token.type === \"link_open\" && token.info === \"auto\") {\n      inside_autolink--;\n    }\n    if (token.type === \"link_close\" && token.info === \"auto\") {\n      inside_autolink++;\n    }\n  }\n}\n\nfunction replace(state) {\n  let blkIdx;\n  if (!state.md.options.typographer) {\n    return;\n  }\n  for (blkIdx = state.tokens.length - 1; blkIdx >= 0; blkIdx--) {\n    if (state.tokens[blkIdx].type !== \"inline\") {\n      continue;\n    }\n    if (SCOPED_ABBR_TEST_RE.test(state.tokens[blkIdx].content)) {\n      replace_scoped(state.tokens[blkIdx].children);\n    }\n    if (RARE_RE.test(state.tokens[blkIdx].content)) {\n      replace_rare(state.tokens[blkIdx].children);\n    }\n  }\n}\n\n// Convert straight quotation marks to typographic ones\n\nconst QUOTE_TEST_RE = /['\"]/;\n\nconst QUOTE_RE = /['\"]/g;\n\nconst APOSTROPHE = \"\\u2019\";\n\n /* ’ */ function replaceAt(str, index, ch) {\n  return str.slice(0, index) + ch + str.slice(index + 1);\n}\n\nfunction process_inlines(tokens, state) {\n  let j;\n  const stack = [];\n  for (let i = 0; i < tokens.length; i++) {\n    const token = tokens[i];\n    const thisLevel = tokens[i].level;\n    for (j = stack.length - 1; j >= 0; j--) {\n      if (stack[j].level <= thisLevel) {\n        break;\n      }\n    }\n    stack.length = j + 1;\n    if (token.type !== \"text\") {\n      continue;\n    }\n    let text = token.content;\n    let pos = 0;\n    let max = text.length;\n    /* eslint no-labels:0,block-scoped-var:0 */    OUTER: while (pos < max) {\n      QUOTE_RE.lastIndex = pos;\n      const t = QUOTE_RE.exec(text);\n      if (!t) {\n        break;\n      }\n      let canOpen = true;\n      let canClose = true;\n      pos = t.index + 1;\n      const isSingle = t[0] === \"'\";\n      // Find previous character,\n      // default to space if it's the beginning of the line\n      \n            let lastChar = 32;\n      if (t.index - 1 >= 0) {\n        lastChar = text.charCodeAt(t.index - 1);\n      } else {\n        for (j = i - 1; j >= 0; j--) {\n          if (tokens[j].type === \"softbreak\" || tokens[j].type === \"hardbreak\") break;\n // lastChar defaults to 0x20\n                    if (!tokens[j].content) continue;\n // should skip all tokens except 'text', 'html_inline' or 'code_inline'\n                    lastChar = tokens[j].content.charCodeAt(tokens[j].content.length - 1);\n          break;\n        }\n      }\n      // Find next character,\n      // default to space if it's the end of the line\n      \n            let nextChar = 32;\n      if (pos < max) {\n        nextChar = text.charCodeAt(pos);\n      } else {\n        for (j = i + 1; j < tokens.length; j++) {\n          if (tokens[j].type === \"softbreak\" || tokens[j].type === \"hardbreak\") break;\n // nextChar defaults to 0x20\n                    if (!tokens[j].content) continue;\n // should skip all tokens except 'text', 'html_inline' or 'code_inline'\n                    nextChar = tokens[j].content.charCodeAt(0);\n          break;\n        }\n      }\n      const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar));\n      const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar));\n      const isLastWhiteSpace = isWhiteSpace(lastChar);\n      const isNextWhiteSpace = isWhiteSpace(nextChar);\n      if (isNextWhiteSpace) {\n        canOpen = false;\n      } else if (isNextPunctChar) {\n        if (!(isLastWhiteSpace || isLastPunctChar)) {\n          canOpen = false;\n        }\n      }\n      if (isLastWhiteSpace) {\n        canClose = false;\n      } else if (isLastPunctChar) {\n        if (!(isNextWhiteSpace || isNextPunctChar)) {\n          canClose = false;\n        }\n      }\n      if (nextChar === 34 /* \" */ && t[0] === '\"') {\n        if (lastChar >= 48 /* 0 */ && lastChar <= 57 /* 9 */) {\n          // special case: 1\"\" - count first quote as an inch\n          canClose = canOpen = false;\n        }\n      }\n      if (canOpen && canClose) {\n        // Replace quotes in the middle of punctuation sequence, but not\n        // in the middle of the words, i.e.:\n        // 1. foo \" bar \" baz - not replaced\n        // 2. foo-\"-bar-\"-baz - replaced\n        // 3. foo\"bar\"baz     - not replaced\n        canOpen = isLastPunctChar;\n        canClose = isNextPunctChar;\n      }\n      if (!canOpen && !canClose) {\n        // middle of word\n        if (isSingle) {\n          token.content = replaceAt(token.content, t.index, APOSTROPHE);\n        }\n        continue;\n      }\n      if (canClose) {\n        // this could be a closing quote, rewind the stack to get a match\n        for (j = stack.length - 1; j >= 0; j--) {\n          let item = stack[j];\n          if (stack[j].level < thisLevel) {\n            break;\n          }\n          if (item.single === isSingle && stack[j].level === thisLevel) {\n            item = stack[j];\n            let openQuote;\n            let closeQuote;\n            if (isSingle) {\n              openQuote = state.md.options.quotes[2];\n              closeQuote = state.md.options.quotes[3];\n            } else {\n              openQuote = state.md.options.quotes[0];\n              closeQuote = state.md.options.quotes[1];\n            }\n            // replace token.content *before* tokens[item.token].content,\n            // because, if they are pointing at the same token, replaceAt\n            // could mess up indices when quote length != 1\n                        token.content = replaceAt(token.content, t.index, closeQuote);\n            tokens[item.token].content = replaceAt(tokens[item.token].content, item.pos, openQuote);\n            pos += closeQuote.length - 1;\n            if (item.token === i) {\n              pos += openQuote.length - 1;\n            }\n            text = token.content;\n            max = text.length;\n            stack.length = j;\n            continue OUTER;\n          }\n        }\n      }\n      if (canOpen) {\n        stack.push({\n          token: i,\n          pos: t.index,\n          single: isSingle,\n          level: thisLevel\n        });\n      } else if (canClose && isSingle) {\n        token.content = replaceAt(token.content, t.index, APOSTROPHE);\n      }\n    }\n  }\n}\n\nfunction smartquotes(state) {\n  /* eslint max-depth:0 */\n  if (!state.md.options.typographer) {\n    return;\n  }\n  for (let blkIdx = state.tokens.length - 1; blkIdx >= 0; blkIdx--) {\n    if (state.tokens[blkIdx].type !== \"inline\" || !QUOTE_TEST_RE.test(state.tokens[blkIdx].content)) {\n      continue;\n    }\n    process_inlines(state.tokens[blkIdx].children, state);\n  }\n}\n\n// Join raw text tokens with the rest of the text\n\n// This is set as a separate rule to provide an opportunity for plugins\n// to run text replacements after text join, but before escape join.\n\n// For example, `\\:)` shouldn't be replaced with an emoji.\n\nfunction text_join(state) {\n  let curr, last;\n  const blockTokens = state.tokens;\n  const l = blockTokens.length;\n  for (let j = 0; j < l; j++) {\n    if (blockTokens[j].type !== \"inline\") continue;\n    const tokens = blockTokens[j].children;\n    const max = tokens.length;\n    for (curr = 0; curr < max; curr++) {\n      if (tokens[curr].type === \"text_special\") {\n        tokens[curr].type = \"text\";\n      }\n    }\n    for (curr = last = 0; curr < max; curr++) {\n      if (tokens[curr].type === \"text\" && curr + 1 < max && tokens[curr + 1].type === \"text\") {\n        // collapse two adjacent text nodes\n        tokens[curr + 1].content = tokens[curr].content + tokens[curr + 1].content;\n      } else {\n        if (curr !== last) {\n          tokens[last] = tokens[curr];\n        }\n        last++;\n      }\n    }\n    if (curr !== last) {\n      tokens.length = last;\n    }\n  }\n}\n\n/** internal\n * class Core\n *\n * Top-level rules executor. Glues block/inline parsers and does intermediate\n * transformations.\n **/ const _rules$2 = [ [ \"normalize\", normalize ], [ \"block\", block ], [ \"inline\", inline ], [ \"linkify\", linkify$1 ], [ \"replacements\", replace ], [ \"smartquotes\", smartquotes ], \n// `text_join` finds `text_special` tokens (for escape sequences)\n// and joins them with the rest of the text\n[ \"text_join\", text_join ] ];\n\n/**\n * new Core()\n **/ function Core() {\n  /**\n   * Core#ruler -> Ruler\n   *\n   * [[Ruler]] instance. Keep configuration of core rules.\n   **/\n  this.ruler = new Ruler;\n  for (let i = 0; i < _rules$2.length; i++) {\n    this.ruler.push(_rules$2[i][0], _rules$2[i][1]);\n  }\n}\n\n/**\n * Core.process(state)\n *\n * Executes core chain rules.\n **/ Core.prototype.process = function(state) {\n  const rules = this.ruler.getRules(\"\");\n  for (let i = 0, l = rules.length; i < l; i++) {\n    rules[i](state);\n  }\n};\n\nCore.prototype.State = StateCore;\n\n// Parser state class\nfunction StateBlock(src, md, env, tokens) {\n  this.src = src;\n  // link to parser instance\n    this.md = md;\n  this.env = env;\n  \n  // Internal state vartiables\n  \n    this.tokens = tokens;\n  this.bMarks = [];\n // line begin offsets for fast jumps\n    this.eMarks = [];\n // line end offsets for fast jumps\n    this.tShift = [];\n // offsets of the first non-space characters (tabs not expanded)\n    this.sCount = [];\n // indents for each line (tabs expanded)\n  // An amount of virtual spaces (tabs expanded) between beginning\n  // of each line (bMarks) and real beginning of that line.\n  \n  // It exists only as a hack because blockquotes override bMarks\n  // losing information in the process.\n  \n  // It's used only when expanding tabs, you can think about it as\n  // an initial tab length, e.g. bsCount=21 applied to string `\\t123`\n  // means first tab should be expanded to 4-21%4 === 3 spaces.\n  \n    this.bsCount = [];\n  // block parser variables\n  // required block content indent (for example, if we are\n  // inside a list, it would be positioned after list marker)\n    this.blkIndent = 0;\n  this.line = 0;\n // line index in src\n    this.lineMax = 0;\n // lines count\n    this.tight = false;\n // loose/tight mode for lists\n    this.ddIndent = -1;\n // indent of the current dd block (-1 if there isn't any)\n    this.listIndent = -1;\n // indent of the current list block (-1 if there isn't any)\n  // can be 'blockquote', 'list', 'root', 'paragraph' or 'reference'\n  // used in lists to determine if they interrupt a paragraph\n    this.parentType = \"root\";\n  this.level = 0;\n  // Create caches\n  // Generate markers.\n    const s = this.src;\n  for (let start = 0, pos = 0, indent = 0, offset = 0, len = s.length, indent_found = false; pos < len; pos++) {\n    const ch = s.charCodeAt(pos);\n    if (!indent_found) {\n      if (isSpace(ch)) {\n        indent++;\n        if (ch === 9) {\n          offset += 4 - offset % 4;\n        } else {\n          offset++;\n        }\n        continue;\n      } else {\n        indent_found = true;\n      }\n    }\n    if (ch === 10 || pos === len - 1) {\n      if (ch !== 10) {\n        pos++;\n      }\n      this.bMarks.push(start);\n      this.eMarks.push(pos);\n      this.tShift.push(indent);\n      this.sCount.push(offset);\n      this.bsCount.push(0);\n      indent_found = false;\n      indent = 0;\n      offset = 0;\n      start = pos + 1;\n    }\n  }\n  // Push fake entry to simplify cache bounds checks\n    this.bMarks.push(s.length);\n  this.eMarks.push(s.length);\n  this.tShift.push(0);\n  this.sCount.push(0);\n  this.bsCount.push(0);\n  this.lineMax = this.bMarks.length - 1;\n // don't count last fake line\n}\n\n// Push new token to \"stream\".\n\nStateBlock.prototype.push = function(type, tag, nesting) {\n  const token = new Token(type, tag, nesting);\n  token.block = true;\n  if (nesting < 0) this.level--;\n // closing tag\n    token.level = this.level;\n  if (nesting > 0) this.level++;\n // opening tag\n    this.tokens.push(token);\n  return token;\n};\n\nStateBlock.prototype.isEmpty = function isEmpty(line) {\n  return this.bMarks[line] + this.tShift[line] >= this.eMarks[line];\n};\n\nStateBlock.prototype.skipEmptyLines = function skipEmptyLines(from) {\n  for (let max = this.lineMax; from < max; from++) {\n    if (this.bMarks[from] + this.tShift[from] < this.eMarks[from]) {\n      break;\n    }\n  }\n  return from;\n};\n\n// Skip spaces from given position.\nStateBlock.prototype.skipSpaces = function skipSpaces(pos) {\n  for (let max = this.src.length; pos < max; pos++) {\n    const ch = this.src.charCodeAt(pos);\n    if (!isSpace(ch)) {\n      break;\n    }\n  }\n  return pos;\n};\n\n// Skip spaces from given position in reverse.\nStateBlock.prototype.skipSpacesBack = function skipSpacesBack(pos, min) {\n  if (pos <= min) {\n    return pos;\n  }\n  while (pos > min) {\n    if (!isSpace(this.src.charCodeAt(--pos))) {\n      return pos + 1;\n    }\n  }\n  return pos;\n};\n\n// Skip char codes from given position\nStateBlock.prototype.skipChars = function skipChars(pos, code) {\n  for (let max = this.src.length; pos < max; pos++) {\n    if (this.src.charCodeAt(pos) !== code) {\n      break;\n    }\n  }\n  return pos;\n};\n\n// Skip char codes reverse from given position - 1\nStateBlock.prototype.skipCharsBack = function skipCharsBack(pos, code, min) {\n  if (pos <= min) {\n    return pos;\n  }\n  while (pos > min) {\n    if (code !== this.src.charCodeAt(--pos)) {\n      return pos + 1;\n    }\n  }\n  return pos;\n};\n\n// cut lines range from source.\nStateBlock.prototype.getLines = function getLines(begin, end, indent, keepLastLF) {\n  if (begin >= end) {\n    return \"\";\n  }\n  const queue = new Array(end - begin);\n  for (let i = 0, line = begin; line < end; line++, i++) {\n    let lineIndent = 0;\n    const lineStart = this.bMarks[line];\n    let first = lineStart;\n    let last;\n    if (line + 1 < end || keepLastLF) {\n      // No need for bounds check because we have fake entry on tail.\n      last = this.eMarks[line] + 1;\n    } else {\n      last = this.eMarks[line];\n    }\n    while (first < last && lineIndent < indent) {\n      const ch = this.src.charCodeAt(first);\n      if (isSpace(ch)) {\n        if (ch === 9) {\n          lineIndent += 4 - (lineIndent + this.bsCount[line]) % 4;\n        } else {\n          lineIndent++;\n        }\n      } else if (first - lineStart < this.tShift[line]) {\n        // patched tShift masked characters to look like spaces (blockquotes, list markers)\n        lineIndent++;\n      } else {\n        break;\n      }\n      first++;\n    }\n    if (lineIndent > indent) {\n      // partially expanding tabs in code blocks, e.g '\\t\\tfoobar'\n      // with indent=2 becomes '  \\tfoobar'\n      queue[i] = new Array(lineIndent - indent + 1).join(\" \") + this.src.slice(first, last);\n    } else {\n      queue[i] = this.src.slice(first, last);\n    }\n  }\n  return queue.join(\"\");\n};\n\n// re-export Token class to use in block rules\nStateBlock.prototype.Token = Token;\n\n// GFM table, https://github.github.com/gfm/#tables-extension-\n// Limit the amount of empty autocompleted cells in a table,\n// see https://github.com/markdown-it/markdown-it/issues/1000,\n\n// Both pulldown-cmark and commonmark-hs limit the number of cells this way to ~200k.\n// We set it to 65k, which can expand user input by a factor of x370\n// (256x256 square is 1.8kB expanded into 650kB).\nconst MAX_AUTOCOMPLETED_CELLS = 65536;\n\nfunction getLine(state, line) {\n  const pos = state.bMarks[line] + state.tShift[line];\n  const max = state.eMarks[line];\n  return state.src.slice(pos, max);\n}\n\nfunction escapedSplit(str) {\n  const result = [];\n  const max = str.length;\n  let pos = 0;\n  let ch = str.charCodeAt(pos);\n  let isEscaped = false;\n  let lastPos = 0;\n  let current = \"\";\n  while (pos < max) {\n    if (ch === 124 /* | */) {\n      if (!isEscaped) {\n        // pipe separating cells, '|'\n        result.push(current + str.substring(lastPos, pos));\n        current = \"\";\n        lastPos = pos + 1;\n      } else {\n        // escaped pipe, '\\|'\n        current += str.substring(lastPos, pos - 1);\n        lastPos = pos;\n      }\n    }\n    isEscaped = ch === 92 /* \\ */;\n    pos++;\n    ch = str.charCodeAt(pos);\n  }\n  result.push(current + str.substring(lastPos));\n  return result;\n}\n\nfunction table(state, startLine, endLine, silent) {\n  // should have at least two lines\n  if (startLine + 2 > endLine) {\n    return false;\n  }\n  let nextLine = startLine + 1;\n  if (state.sCount[nextLine] < state.blkIndent) {\n    return false;\n  }\n  // if it's indented more than 3 spaces, it should be a code block\n    if (state.sCount[nextLine] - state.blkIndent >= 4) {\n    return false;\n  }\n  // first character of the second line should be '|', '-', ':',\n  // and no other characters are allowed but spaces;\n  // basically, this is the equivalent of /^[-:|][-:|\\s]*$/ regexp\n    let pos = state.bMarks[nextLine] + state.tShift[nextLine];\n  if (pos >= state.eMarks[nextLine]) {\n    return false;\n  }\n  const firstCh = state.src.charCodeAt(pos++);\n  if (firstCh !== 124 /* | */ && firstCh !== 45 /* - */ && firstCh !== 58 /* : */) {\n    return false;\n  }\n  if (pos >= state.eMarks[nextLine]) {\n    return false;\n  }\n  const secondCh = state.src.charCodeAt(pos++);\n  if (secondCh !== 124 /* | */ && secondCh !== 45 /* - */ && secondCh !== 58 /* : */ && !isSpace(secondCh)) {\n    return false;\n  }\n  // if first character is '-', then second character must not be a space\n  // (due to parsing ambiguity with list)\n    if (firstCh === 45 /* - */ && isSpace(secondCh)) {\n    return false;\n  }\n  while (pos < state.eMarks[nextLine]) {\n    const ch = state.src.charCodeAt(pos);\n    if (ch !== 124 /* | */ && ch !== 45 /* - */ && ch !== 58 /* : */ && !isSpace(ch)) {\n      return false;\n    }\n    pos++;\n  }\n  let lineText = getLine(state, startLine + 1);\n  let columns = lineText.split(\"|\");\n  const aligns = [];\n  for (let i = 0; i < columns.length; i++) {\n    const t = columns[i].trim();\n    if (!t) {\n      // allow empty columns before and after table, but not in between columns;\n      // e.g. allow ` |---| `, disallow ` ---||--- `\n      if (i === 0 || i === columns.length - 1) {\n        continue;\n      } else {\n        return false;\n      }\n    }\n    if (!/^:?-+:?$/.test(t)) {\n      return false;\n    }\n    if (t.charCodeAt(t.length - 1) === 58 /* : */) {\n      aligns.push(t.charCodeAt(0) === 58 /* : */ ? \"center\" : \"right\");\n    } else if (t.charCodeAt(0) === 58 /* : */) {\n      aligns.push(\"left\");\n    } else {\n      aligns.push(\"\");\n    }\n  }\n  lineText = getLine(state, startLine).trim();\n  if (lineText.indexOf(\"|\") === -1) {\n    return false;\n  }\n  if (state.sCount[startLine] - state.blkIndent >= 4) {\n    return false;\n  }\n  columns = escapedSplit(lineText);\n  if (columns.length && columns[0] === \"\") columns.shift();\n  if (columns.length && columns[columns.length - 1] === \"\") columns.pop();\n  // header row will define an amount of columns in the entire table,\n  // and align row should be exactly the same (the rest of the rows can differ)\n    const columnCount = columns.length;\n  if (columnCount === 0 || columnCount !== aligns.length) {\n    return false;\n  }\n  if (silent) {\n    return true;\n  }\n  const oldParentType = state.parentType;\n  state.parentType = \"table\";\n  // use 'blockquote' lists for termination because it's\n  // the most similar to tables\n    const terminatorRules = state.md.block.ruler.getRules(\"blockquote\");\n  const token_to = state.push(\"table_open\", \"table\", 1);\n  const tableLines = [ startLine, 0 ];\n  token_to.map = tableLines;\n  const token_tho = state.push(\"thead_open\", \"thead\", 1);\n  token_tho.map = [ startLine, startLine + 1 ];\n  const token_htro = state.push(\"tr_open\", \"tr\", 1);\n  token_htro.map = [ startLine, startLine + 1 ];\n  for (let i = 0; i < columns.length; i++) {\n    const token_ho = state.push(\"th_open\", \"th\", 1);\n    if (aligns[i]) {\n      token_ho.attrs = [ [ \"style\", \"text-align:\" + aligns[i] ] ];\n    }\n    const token_il = state.push(\"inline\", \"\", 0);\n    token_il.content = columns[i].trim();\n    token_il.children = [];\n    state.push(\"th_close\", \"th\", -1);\n  }\n  state.push(\"tr_close\", \"tr\", -1);\n  state.push(\"thead_close\", \"thead\", -1);\n  let tbodyLines;\n  let autocompletedCells = 0;\n  for (nextLine = startLine + 2; nextLine < endLine; nextLine++) {\n    if (state.sCount[nextLine] < state.blkIndent) {\n      break;\n    }\n    let terminate = false;\n    for (let i = 0, l = terminatorRules.length; i < l; i++) {\n      if (terminatorRules[i](state, nextLine, endLine, true)) {\n        terminate = true;\n        break;\n      }\n    }\n    if (terminate) {\n      break;\n    }\n    lineText = getLine(state, nextLine).trim();\n    if (!lineText) {\n      break;\n    }\n    if (state.sCount[nextLine] - state.blkIndent >= 4) {\n      break;\n    }\n    columns = escapedSplit(lineText);\n    if (columns.length && columns[0] === \"\") columns.shift();\n    if (columns.length && columns[columns.length - 1] === \"\") columns.pop();\n    // note: autocomplete count can be negative if user specifies more columns than header,\n    // but that does not affect intended use (which is limiting expansion)\n        autocompletedCells += columnCount - columns.length;\n    if (autocompletedCells > MAX_AUTOCOMPLETED_CELLS) {\n      break;\n    }\n    if (nextLine === startLine + 2) {\n      const token_tbo = state.push(\"tbody_open\", \"tbody\", 1);\n      token_tbo.map = tbodyLines = [ startLine + 2, 0 ];\n    }\n    const token_tro = state.push(\"tr_open\", \"tr\", 1);\n    token_tro.map = [ nextLine, nextLine + 1 ];\n    for (let i = 0; i < columnCount; i++) {\n      const token_tdo = state.push(\"td_open\", \"td\", 1);\n      if (aligns[i]) {\n        token_tdo.attrs = [ [ \"style\", \"text-align:\" + aligns[i] ] ];\n      }\n      const token_il = state.push(\"inline\", \"\", 0);\n      token_il.content = columns[i] ? columns[i].trim() : \"\";\n      token_il.children = [];\n      state.push(\"td_close\", \"td\", -1);\n    }\n    state.push(\"tr_close\", \"tr\", -1);\n  }\n  if (tbodyLines) {\n    state.push(\"tbody_close\", \"tbody\", -1);\n    tbodyLines[1] = nextLine;\n  }\n  state.push(\"table_close\", \"table\", -1);\n  tableLines[1] = nextLine;\n  state.parentType = oldParentType;\n  state.line = nextLine;\n  return true;\n}\n\n// Code block (4 spaces padded)\nfunction code(state, startLine, endLine /*, silent */) {\n  if (state.sCount[startLine] - state.blkIndent < 4) {\n    return false;\n  }\n  let nextLine = startLine + 1;\n  let last = nextLine;\n  while (nextLine < endLine) {\n    if (state.isEmpty(nextLine)) {\n      nextLine++;\n      continue;\n    }\n    if (state.sCount[nextLine] - state.blkIndent >= 4) {\n      nextLine++;\n      last = nextLine;\n      continue;\n    }\n    break;\n  }\n  state.line = last;\n  const token = state.push(\"code_block\", \"code\", 0);\n  token.content = state.getLines(startLine, last, 4 + state.blkIndent, false) + \"\\n\";\n  token.map = [ startLine, state.line ];\n  return true;\n}\n\n// fences (``` lang, ~~~ lang)\nfunction fence(state, startLine, endLine, silent) {\n  let pos = state.bMarks[startLine] + state.tShift[startLine];\n  let max = state.eMarks[startLine];\n  // if it's indented more than 3 spaces, it should be a code block\n    if (state.sCount[startLine] - state.blkIndent >= 4) {\n    return false;\n  }\n  if (pos + 3 > max) {\n    return false;\n  }\n  const marker = state.src.charCodeAt(pos);\n  if (marker !== 126 /* ~ */ && marker !== 96 /* ` */) {\n    return false;\n  }\n  // scan marker length\n    let mem = pos;\n  pos = state.skipChars(pos, marker);\n  let len = pos - mem;\n  if (len < 3) {\n    return false;\n  }\n  const markup = state.src.slice(mem, pos);\n  const params = state.src.slice(pos, max);\n  if (marker === 96 /* ` */) {\n    if (params.indexOf(String.fromCharCode(marker)) >= 0) {\n      return false;\n    }\n  }\n  // Since start is found, we can report success here in validation mode\n    if (silent) {\n    return true;\n  }\n  // search end of block\n    let nextLine = startLine;\n  let haveEndMarker = false;\n  for (;;) {\n    nextLine++;\n    if (nextLine >= endLine) {\n      // unclosed block should be autoclosed by end of document.\n      // also block seems to be autoclosed by end of parent\n      break;\n    }\n    pos = mem = state.bMarks[nextLine] + state.tShift[nextLine];\n    max = state.eMarks[nextLine];\n    if (pos < max && state.sCount[nextLine] < state.blkIndent) {\n      // non-empty line with negative indent should stop the list:\n      // - ```\n      //  test\n      break;\n    }\n    if (state.src.charCodeAt(pos) !== marker) {\n      continue;\n    }\n    if (state.sCount[nextLine] - state.blkIndent >= 4) {\n      // closing fence should be indented less than 4 spaces\n      continue;\n    }\n    pos = state.skipChars(pos, marker);\n    // closing code fence must be at least as long as the opening one\n        if (pos - mem < len) {\n      continue;\n    }\n    // make sure tail has spaces only\n        pos = state.skipSpaces(pos);\n    if (pos < max) {\n      continue;\n    }\n    haveEndMarker = true;\n    // found!\n        break;\n  }\n  // If a fence has heading spaces, they should be removed from its inner block\n    len = state.sCount[startLine];\n  state.line = nextLine + (haveEndMarker ? 1 : 0);\n  const token = state.push(\"fence\", \"code\", 0);\n  token.info = params;\n  token.content = state.getLines(startLine + 1, nextLine, len, true);\n  token.markup = markup;\n  token.map = [ startLine, state.line ];\n  return true;\n}\n\n// Block quotes\nfunction blockquote(state, startLine, endLine, silent) {\n  let pos = state.bMarks[startLine] + state.tShift[startLine];\n  let max = state.eMarks[startLine];\n  const oldLineMax = state.lineMax;\n  // if it's indented more than 3 spaces, it should be a code block\n    if (state.sCount[startLine] - state.blkIndent >= 4) {\n    return false;\n  }\n  // check the block quote marker\n    if (state.src.charCodeAt(pos) !== 62 /* > */) {\n    return false;\n  }\n  // we know that it's going to be a valid blockquote,\n  // so no point trying to find the end of it in silent mode\n    if (silent) {\n    return true;\n  }\n  const oldBMarks = [];\n  const oldBSCount = [];\n  const oldSCount = [];\n  const oldTShift = [];\n  const terminatorRules = state.md.block.ruler.getRules(\"blockquote\");\n  const oldParentType = state.parentType;\n  state.parentType = \"blockquote\";\n  let lastLineEmpty = false;\n  let nextLine;\n  // Search the end of the block\n  \n  // Block ends with either:\n  //  1. an empty line outside:\n  //     ```\n  //     > test\n  \n  //     ```\n  //  2. an empty line inside:\n  //     ```\n  //     >\n  //     test\n  //     ```\n  //  3. another tag:\n  //     ```\n  //     > test\n  //      - - -\n  //     ```\n    for (nextLine = startLine; nextLine < endLine; nextLine++) {\n    // check if it's outdented, i.e. it's inside list item and indented\n    // less than said list item:\n    // ```\n    // 1. anything\n    //    > current blockquote\n    // 2. checking this line\n    // ```\n    const isOutdented = state.sCount[nextLine] < state.blkIndent;\n    pos = state.bMarks[nextLine] + state.tShift[nextLine];\n    max = state.eMarks[nextLine];\n    if (pos >= max) {\n      // Case 1: line is not inside the blockquote, and this line is empty.\n      break;\n    }\n    if (state.src.charCodeAt(pos++) === 62 /* > */ && !isOutdented) {\n      // This line is inside the blockquote.\n      // set offset past spaces and \">\"\n      let initial = state.sCount[nextLine] + 1;\n      let spaceAfterMarker;\n      let adjustTab;\n      // skip one optional space after '>'\n            if (state.src.charCodeAt(pos) === 32 /* space */) {\n        // ' >   test '\n        //     ^ -- position start of line here:\n        pos++;\n        initial++;\n        adjustTab = false;\n        spaceAfterMarker = true;\n      } else if (state.src.charCodeAt(pos) === 9 /* tab */) {\n        spaceAfterMarker = true;\n        if ((state.bsCount[nextLine] + initial) % 4 === 3) {\n          // '  >\\t  test '\n          //       ^ -- position start of line here (tab has width===1)\n          pos++;\n          initial++;\n          adjustTab = false;\n        } else {\n          // ' >\\t  test '\n          //    ^ -- position start of line here + shift bsCount slightly\n          //         to make extra space appear\n          adjustTab = true;\n        }\n      } else {\n        spaceAfterMarker = false;\n      }\n      let offset = initial;\n      oldBMarks.push(state.bMarks[nextLine]);\n      state.bMarks[nextLine] = pos;\n      while (pos < max) {\n        const ch = state.src.charCodeAt(pos);\n        if (isSpace(ch)) {\n          if (ch === 9) {\n            offset += 4 - (offset + state.bsCount[nextLine] + (adjustTab ? 1 : 0)) % 4;\n          } else {\n            offset++;\n          }\n        } else {\n          break;\n        }\n        pos++;\n      }\n      lastLineEmpty = pos >= max;\n      oldBSCount.push(state.bsCount[nextLine]);\n      state.bsCount[nextLine] = state.sCount[nextLine] + 1 + (spaceAfterMarker ? 1 : 0);\n      oldSCount.push(state.sCount[nextLine]);\n      state.sCount[nextLine] = offset - initial;\n      oldTShift.push(state.tShift[nextLine]);\n      state.tShift[nextLine] = pos - state.bMarks[nextLine];\n      continue;\n    }\n    // Case 2: line is not inside the blockquote, and the last line was empty.\n        if (lastLineEmpty) {\n      break;\n    }\n    // Case 3: another tag found.\n        let terminate = false;\n    for (let i = 0, l = terminatorRules.length; i < l; i++) {\n      if (terminatorRules[i](state, nextLine, endLine, true)) {\n        terminate = true;\n        break;\n      }\n    }\n    if (terminate) {\n      // Quirk to enforce \"hard termination mode\" for paragraphs;\n      // normally if you call `tokenize(state, startLine, nextLine)`,\n      // paragraphs will look below nextLine for paragraph continuation,\n      // but if blockquote is terminated by another tag, they shouldn't\n      state.lineMax = nextLine;\n      if (state.blkIndent !== 0) {\n        // state.blkIndent was non-zero, we now set it to zero,\n        // so we need to re-calculate all offsets to appear as\n        // if indent wasn't changed\n        oldBMarks.push(state.bMarks[nextLine]);\n        oldBSCount.push(state.bsCount[nextLine]);\n        oldTShift.push(state.tShift[nextLine]);\n        oldSCount.push(state.sCount[nextLine]);\n        state.sCount[nextLine] -= state.blkIndent;\n      }\n      break;\n    }\n    oldBMarks.push(state.bMarks[nextLine]);\n    oldBSCount.push(state.bsCount[nextLine]);\n    oldTShift.push(state.tShift[nextLine]);\n    oldSCount.push(state.sCount[nextLine]);\n    // A negative indentation means that this is a paragraph continuation\n    \n        state.sCount[nextLine] = -1;\n  }\n  const oldIndent = state.blkIndent;\n  state.blkIndent = 0;\n  const token_o = state.push(\"blockquote_open\", \"blockquote\", 1);\n  token_o.markup = \">\";\n  const lines = [ startLine, 0 ];\n  token_o.map = lines;\n  state.md.block.tokenize(state, startLine, nextLine);\n  const token_c = state.push(\"blockquote_close\", \"blockquote\", -1);\n  token_c.markup = \">\";\n  state.lineMax = oldLineMax;\n  state.parentType = oldParentType;\n  lines[1] = state.line;\n  // Restore original tShift; this might not be necessary since the parser\n  // has already been here, but just to make sure we can do that.\n    for (let i = 0; i < oldTShift.length; i++) {\n    state.bMarks[i + startLine] = oldBMarks[i];\n    state.tShift[i + startLine] = oldTShift[i];\n    state.sCount[i + startLine] = oldSCount[i];\n    state.bsCount[i + startLine] = oldBSCount[i];\n  }\n  state.blkIndent = oldIndent;\n  return true;\n}\n\n// Horizontal rule\nfunction hr(state, startLine, endLine, silent) {\n  const max = state.eMarks[startLine];\n  // if it's indented more than 3 spaces, it should be a code block\n    if (state.sCount[startLine] - state.blkIndent >= 4) {\n    return false;\n  }\n  let pos = state.bMarks[startLine] + state.tShift[startLine];\n  const marker = state.src.charCodeAt(pos++);\n  // Check hr marker\n    if (marker !== 42 /* * */ && marker !== 45 /* - */ && marker !== 95 /* _ */) {\n    return false;\n  }\n  // markers can be mixed with spaces, but there should be at least 3 of them\n    let cnt = 1;\n  while (pos < max) {\n    const ch = state.src.charCodeAt(pos++);\n    if (ch !== marker && !isSpace(ch)) {\n      return false;\n    }\n    if (ch === marker) {\n      cnt++;\n    }\n  }\n  if (cnt < 3) {\n    return false;\n  }\n  if (silent) {\n    return true;\n  }\n  state.line = startLine + 1;\n  const token = state.push(\"hr\", \"hr\", 0);\n  token.map = [ startLine, state.line ];\n  token.markup = Array(cnt + 1).join(String.fromCharCode(marker));\n  return true;\n}\n\n// Lists\n// Search `[-+*][\\n ]`, returns next pos after marker on success\n// or -1 on fail.\nfunction skipBulletListMarker(state, startLine) {\n  const max = state.eMarks[startLine];\n  let pos = state.bMarks[startLine] + state.tShift[startLine];\n  const marker = state.src.charCodeAt(pos++);\n  // Check bullet\n    if (marker !== 42 /* * */ && marker !== 45 /* - */ && marker !== 43 /* + */) {\n    return -1;\n  }\n  if (pos < max) {\n    const ch = state.src.charCodeAt(pos);\n    if (!isSpace(ch)) {\n      // \" -test \" - is not a list item\n      return -1;\n    }\n  }\n  return pos;\n}\n\n// Search `\\d+[.)][\\n ]`, returns next pos after marker on success\n// or -1 on fail.\nfunction skipOrderedListMarker(state, startLine) {\n  const start = state.bMarks[startLine] + state.tShift[startLine];\n  const max = state.eMarks[startLine];\n  let pos = start;\n  // List marker should have at least 2 chars (digit + dot)\n    if (pos + 1 >= max) {\n    return -1;\n  }\n  let ch = state.src.charCodeAt(pos++);\n  if (ch < 48 /* 0 */ || ch > 57 /* 9 */) {\n    return -1;\n  }\n  for (;;) {\n    // EOL -> fail\n    if (pos >= max) {\n      return -1;\n    }\n    ch = state.src.charCodeAt(pos++);\n    if (ch >= 48 /* 0 */ && ch <= 57 /* 9 */) {\n      // List marker should have no more than 9 digits\n      // (prevents integer overflow in browsers)\n      if (pos - start >= 10) {\n        return -1;\n      }\n      continue;\n    }\n    // found valid marker\n        if (ch === 41 /* ) */ || ch === 46 /* . */) {\n      break;\n    }\n    return -1;\n  }\n  if (pos < max) {\n    ch = state.src.charCodeAt(pos);\n    if (!isSpace(ch)) {\n      // \" 1.test \" - is not a list item\n      return -1;\n    }\n  }\n  return pos;\n}\n\nfunction markTightParagraphs(state, idx) {\n  const level = state.level + 2;\n  for (let i = idx + 2, l = state.tokens.length - 2; i < l; i++) {\n    if (state.tokens[i].level === level && state.tokens[i].type === \"paragraph_open\") {\n      state.tokens[i + 2].hidden = true;\n      state.tokens[i].hidden = true;\n      i += 2;\n    }\n  }\n}\n\nfunction list(state, startLine, endLine, silent) {\n  let max, pos, start, token;\n  let nextLine = startLine;\n  let tight = true;\n  // if it's indented more than 3 spaces, it should be a code block\n    if (state.sCount[nextLine] - state.blkIndent >= 4) {\n    return false;\n  }\n  // Special case:\n  //  - item 1\n  //   - item 2\n  //    - item 3\n  //     - item 4\n  //      - this one is a paragraph continuation\n    if (state.listIndent >= 0 && state.sCount[nextLine] - state.listIndent >= 4 && state.sCount[nextLine] < state.blkIndent) {\n    return false;\n  }\n  let isTerminatingParagraph = false;\n  // limit conditions when list can interrupt\n  // a paragraph (validation mode only)\n    if (silent && state.parentType === \"paragraph\") {\n    // Next list item should still terminate previous list item;\n    // This code can fail if plugins use blkIndent as well as lists,\n    // but I hope the spec gets fixed long before that happens.\n    if (state.sCount[nextLine] >= state.blkIndent) {\n      isTerminatingParagraph = true;\n    }\n  }\n  // Detect list type and position after marker\n    let isOrdered;\n  let markerValue;\n  let posAfterMarker;\n  if ((posAfterMarker = skipOrderedListMarker(state, nextLine)) >= 0) {\n    isOrdered = true;\n    start = state.bMarks[nextLine] + state.tShift[nextLine];\n    markerValue = Number(state.src.slice(start, posAfterMarker - 1));\n    // If we're starting a new ordered list right after\n    // a paragraph, it should start with 1.\n        if (isTerminatingParagraph && markerValue !== 1) return false;\n  } else if ((posAfterMarker = skipBulletListMarker(state, nextLine)) >= 0) {\n    isOrdered = false;\n  } else {\n    return false;\n  }\n  // If we're starting a new unordered list right after\n  // a paragraph, first line should not be empty.\n    if (isTerminatingParagraph) {\n    if (state.skipSpaces(posAfterMarker) >= state.eMarks[nextLine]) return false;\n  }\n  // For validation mode we can terminate immediately\n    if (silent) {\n    return true;\n  }\n  // We should terminate list on style change. Remember first one to compare.\n    const markerCharCode = state.src.charCodeAt(posAfterMarker - 1);\n  // Start list\n    const listTokIdx = state.tokens.length;\n  if (isOrdered) {\n    token = state.push(\"ordered_list_open\", \"ol\", 1);\n    if (markerValue !== 1) {\n      token.attrs = [ [ \"start\", markerValue ] ];\n    }\n  } else {\n    token = state.push(\"bullet_list_open\", \"ul\", 1);\n  }\n  const listLines = [ nextLine, 0 ];\n  token.map = listLines;\n  token.markup = String.fromCharCode(markerCharCode);\n  \n  // Iterate list items\n  \n    let prevEmptyEnd = false;\n  const terminatorRules = state.md.block.ruler.getRules(\"list\");\n  const oldParentType = state.parentType;\n  state.parentType = \"list\";\n  while (nextLine < endLine) {\n    pos = posAfterMarker;\n    max = state.eMarks[nextLine];\n    const initial = state.sCount[nextLine] + posAfterMarker - (state.bMarks[nextLine] + state.tShift[nextLine]);\n    let offset = initial;\n    while (pos < max) {\n      const ch = state.src.charCodeAt(pos);\n      if (ch === 9) {\n        offset += 4 - (offset + state.bsCount[nextLine]) % 4;\n      } else if (ch === 32) {\n        offset++;\n      } else {\n        break;\n      }\n      pos++;\n    }\n    const contentStart = pos;\n    let indentAfterMarker;\n    if (contentStart >= max) {\n      // trimming space in \"-    \\n  3\" case, indent is 1 here\n      indentAfterMarker = 1;\n    } else {\n      indentAfterMarker = offset - initial;\n    }\n    // If we have more than 4 spaces, the indent is 1\n    // (the rest is just indented code block)\n        if (indentAfterMarker > 4) {\n      indentAfterMarker = 1;\n    }\n    // \"  -  test\"\n    //  ^^^^^ - calculating total length of this thing\n        const indent = initial + indentAfterMarker;\n    // Run subparser & write tokens\n        token = state.push(\"list_item_open\", \"li\", 1);\n    token.markup = String.fromCharCode(markerCharCode);\n    const itemLines = [ nextLine, 0 ];\n    token.map = itemLines;\n    if (isOrdered) {\n      token.info = state.src.slice(start, posAfterMarker - 1);\n    }\n    // change current state, then restore it after parser subcall\n        const oldTight = state.tight;\n    const oldTShift = state.tShift[nextLine];\n    const oldSCount = state.sCount[nextLine];\n    //  - example list\n    // ^ listIndent position will be here\n    //   ^ blkIndent position will be here\n    \n        const oldListIndent = state.listIndent;\n    state.listIndent = state.blkIndent;\n    state.blkIndent = indent;\n    state.tight = true;\n    state.tShift[nextLine] = contentStart - state.bMarks[nextLine];\n    state.sCount[nextLine] = offset;\n    if (contentStart >= max && state.isEmpty(nextLine + 1)) {\n      // workaround for this case\n      // (list item is empty, list terminates before \"foo\"):\n      // ~~~~~~~~\n      //   -\n      //     foo\n      // ~~~~~~~~\n      state.line = Math.min(state.line + 2, endLine);\n    } else {\n      state.md.block.tokenize(state, nextLine, endLine, true);\n    }\n    // If any of list item is tight, mark list as tight\n        if (!state.tight || prevEmptyEnd) {\n      tight = false;\n    }\n    // Item become loose if finish with empty line,\n    // but we should filter last element, because it means list finish\n        prevEmptyEnd = state.line - nextLine > 1 && state.isEmpty(state.line - 1);\n    state.blkIndent = state.listIndent;\n    state.listIndent = oldListIndent;\n    state.tShift[nextLine] = oldTShift;\n    state.sCount[nextLine] = oldSCount;\n    state.tight = oldTight;\n    token = state.push(\"list_item_close\", \"li\", -1);\n    token.markup = String.fromCharCode(markerCharCode);\n    nextLine = state.line;\n    itemLines[1] = nextLine;\n    if (nextLine >= endLine) {\n      break;\n    }\n    \n    // Try to check if list is terminated or continued.\n    \n        if (state.sCount[nextLine] < state.blkIndent) {\n      break;\n    }\n    // if it's indented more than 3 spaces, it should be a code block\n        if (state.sCount[nextLine] - state.blkIndent >= 4) {\n      break;\n    }\n    // fail if terminating block found\n        let terminate = false;\n    for (let i = 0, l = terminatorRules.length; i < l; i++) {\n      if (terminatorRules[i](state, nextLine, endLine, true)) {\n        terminate = true;\n        break;\n      }\n    }\n    if (terminate) {\n      break;\n    }\n    // fail if list has another type\n        if (isOrdered) {\n      posAfterMarker = skipOrderedListMarker(state, nextLine);\n      if (posAfterMarker < 0) {\n        break;\n      }\n      start = state.bMarks[nextLine] + state.tShift[nextLine];\n    } else {\n      posAfterMarker = skipBulletListMarker(state, nextLine);\n      if (posAfterMarker < 0) {\n        break;\n      }\n    }\n    if (markerCharCode !== state.src.charCodeAt(posAfterMarker - 1)) {\n      break;\n    }\n  }\n  // Finalize list\n    if (isOrdered) {\n    token = state.push(\"ordered_list_close\", \"ol\", -1);\n  } else {\n    token = state.push(\"bullet_list_close\", \"ul\", -1);\n  }\n  token.markup = String.fromCharCode(markerCharCode);\n  listLines[1] = nextLine;\n  state.line = nextLine;\n  state.parentType = oldParentType;\n  // mark paragraphs tight if needed\n    if (tight) {\n    markTightParagraphs(state, listTokIdx);\n  }\n  return true;\n}\n\nfunction reference(state, startLine, _endLine, silent) {\n  let pos = state.bMarks[startLine] + state.tShift[startLine];\n  let max = state.eMarks[startLine];\n  let nextLine = startLine + 1;\n  // if it's indented more than 3 spaces, it should be a code block\n    if (state.sCount[startLine] - state.blkIndent >= 4) {\n    return false;\n  }\n  if (state.src.charCodeAt(pos) !== 91 /* [ */) {\n    return false;\n  }\n  function getNextLine(nextLine) {\n    const endLine = state.lineMax;\n    if (nextLine >= endLine || state.isEmpty(nextLine)) {\n      // empty line or end of input\n      return null;\n    }\n    let isContinuation = false;\n    // this would be a code block normally, but after paragraph\n    // it's considered a lazy continuation regardless of what's there\n        if (state.sCount[nextLine] - state.blkIndent > 3) {\n      isContinuation = true;\n    }\n    // quirk for blockquotes, this line should already be checked by that rule\n        if (state.sCount[nextLine] < 0) {\n      isContinuation = true;\n    }\n    if (!isContinuation) {\n      const terminatorRules = state.md.block.ruler.getRules(\"reference\");\n      const oldParentType = state.parentType;\n      state.parentType = \"reference\";\n      // Some tags can terminate paragraph without empty line.\n            let terminate = false;\n      for (let i = 0, l = terminatorRules.length; i < l; i++) {\n        if (terminatorRules[i](state, nextLine, endLine, true)) {\n          terminate = true;\n          break;\n        }\n      }\n      state.parentType = oldParentType;\n      if (terminate) {\n        // terminated by another block\n        return null;\n      }\n    }\n    const pos = state.bMarks[nextLine] + state.tShift[nextLine];\n    const max = state.eMarks[nextLine];\n    // max + 1 explicitly includes the newline\n        return state.src.slice(pos, max + 1);\n  }\n  let str = state.src.slice(pos, max + 1);\n  max = str.length;\n  let labelEnd = -1;\n  for (pos = 1; pos < max; pos++) {\n    const ch = str.charCodeAt(pos);\n    if (ch === 91 /* [ */) {\n      return false;\n    } else if (ch === 93 /* ] */) {\n      labelEnd = pos;\n      break;\n    } else if (ch === 10 /* \\n */) {\n      const lineContent = getNextLine(nextLine);\n      if (lineContent !== null) {\n        str += lineContent;\n        max = str.length;\n        nextLine++;\n      }\n    } else if (ch === 92 /* \\ */) {\n      pos++;\n      if (pos < max && str.charCodeAt(pos) === 10) {\n        const lineContent = getNextLine(nextLine);\n        if (lineContent !== null) {\n          str += lineContent;\n          max = str.length;\n          nextLine++;\n        }\n      }\n    }\n  }\n  if (labelEnd < 0 || str.charCodeAt(labelEnd + 1) !== 58 /* : */) {\n    return false;\n  }\n  // [label]:   destination   'title'\n  //         ^^^ skip optional whitespace here\n    for (pos = labelEnd + 2; pos < max; pos++) {\n    const ch = str.charCodeAt(pos);\n    if (ch === 10) {\n      const lineContent = getNextLine(nextLine);\n      if (lineContent !== null) {\n        str += lineContent;\n        max = str.length;\n        nextLine++;\n      }\n    } else if (isSpace(ch)) ; else {\n      break;\n    }\n  }\n  // [label]:   destination   'title'\n  //            ^^^^^^^^^^^ parse this\n    const destRes = state.md.helpers.parseLinkDestination(str, pos, max);\n  if (!destRes.ok) {\n    return false;\n  }\n  const href = state.md.normalizeLink(destRes.str);\n  if (!state.md.validateLink(href)) {\n    return false;\n  }\n  pos = destRes.pos;\n  // save cursor state, we could require to rollback later\n    const destEndPos = pos;\n  const destEndLineNo = nextLine;\n  // [label]:   destination   'title'\n  //                       ^^^ skipping those spaces\n    const start = pos;\n  for (;pos < max; pos++) {\n    const ch = str.charCodeAt(pos);\n    if (ch === 10) {\n      const lineContent = getNextLine(nextLine);\n      if (lineContent !== null) {\n        str += lineContent;\n        max = str.length;\n        nextLine++;\n      }\n    } else if (isSpace(ch)) ; else {\n      break;\n    }\n  }\n  // [label]:   destination   'title'\n  //                          ^^^^^^^ parse this\n    let titleRes = state.md.helpers.parseLinkTitle(str, pos, max);\n  while (titleRes.can_continue) {\n    const lineContent = getNextLine(nextLine);\n    if (lineContent === null) break;\n    str += lineContent;\n    pos = max;\n    max = str.length;\n    nextLine++;\n    titleRes = state.md.helpers.parseLinkTitle(str, pos, max, titleRes);\n  }\n  let title;\n  if (pos < max && start !== pos && titleRes.ok) {\n    title = titleRes.str;\n    pos = titleRes.pos;\n  } else {\n    title = \"\";\n    pos = destEndPos;\n    nextLine = destEndLineNo;\n  }\n  // skip trailing spaces until the rest of the line\n    while (pos < max) {\n    const ch = str.charCodeAt(pos);\n    if (!isSpace(ch)) {\n      break;\n    }\n    pos++;\n  }\n  if (pos < max && str.charCodeAt(pos) !== 10) {\n    if (title) {\n      // garbage at the end of the line after title,\n      // but it could still be a valid reference if we roll back\n      title = \"\";\n      pos = destEndPos;\n      nextLine = destEndLineNo;\n      while (pos < max) {\n        const ch = str.charCodeAt(pos);\n        if (!isSpace(ch)) {\n          break;\n        }\n        pos++;\n      }\n    }\n  }\n  if (pos < max && str.charCodeAt(pos) !== 10) {\n    // garbage at the end of the line\n    return false;\n  }\n  const label = normalizeReference(str.slice(1, labelEnd));\n  if (!label) {\n    // CommonMark 0.20 disallows empty labels\n    return false;\n  }\n  // Reference can not terminate anything. This check is for safety only.\n  /* istanbul ignore if */  if (silent) {\n    return true;\n  }\n  if (typeof state.env.references === \"undefined\") {\n    state.env.references = {};\n  }\n  if (typeof state.env.references[label] === \"undefined\") {\n    state.env.references[label] = {\n      title: title,\n      href: href\n    };\n  }\n  state.line = nextLine;\n  return true;\n}\n\n// List of valid html blocks names, according to commonmark spec\n// https://spec.commonmark.org/0.30/#html-blocks\nvar block_names = [ \"address\", \"article\", \"aside\", \"base\", \"basefont\", \"blockquote\", \"body\", \"caption\", \"center\", \"col\", \"colgroup\", \"dd\", \"details\", \"dialog\", \"dir\", \"div\", \"dl\", \"dt\", \"fieldset\", \"figcaption\", \"figure\", \"footer\", \"form\", \"frame\", \"frameset\", \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\", \"head\", \"header\", \"hr\", \"html\", \"iframe\", \"legend\", \"li\", \"link\", \"main\", \"menu\", \"menuitem\", \"nav\", \"noframes\", \"ol\", \"optgroup\", \"option\", \"p\", \"param\", \"search\", \"section\", \"summary\", \"table\", \"tbody\", \"td\", \"tfoot\", \"th\", \"thead\", \"title\", \"tr\", \"track\", \"ul\" ];\n\n// Regexps to match html elements\nconst attr_name = \"[a-zA-Z_:][a-zA-Z0-9:._-]*\";\n\nconst unquoted = \"[^\\\"'=<>`\\\\x00-\\\\x20]+\";\n\nconst single_quoted = \"'[^']*'\";\n\nconst double_quoted = '\"[^\"]*\"';\n\nconst attr_value = \"(?:\" + unquoted + \"|\" + single_quoted + \"|\" + double_quoted + \")\";\n\nconst attribute = \"(?:\\\\s+\" + attr_name + \"(?:\\\\s*=\\\\s*\" + attr_value + \")?)\";\n\nconst open_tag = \"<[A-Za-z][A-Za-z0-9\\\\-]*\" + attribute + \"*\\\\s*\\\\/?>\";\n\nconst close_tag = \"<\\\\/[A-Za-z][A-Za-z0-9\\\\-]*\\\\s*>\";\n\nconst comment = \"\\x3c!---?>|\\x3c!--(?:[^-]|-[^-]|--[^>])*--\\x3e\";\n\nconst processing = \"<[?][\\\\s\\\\S]*?[?]>\";\n\nconst declaration = \"<![A-Za-z][^>]*>\";\n\nconst cdata = \"<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?\\\\]\\\\]>\";\n\nconst HTML_TAG_RE = new RegExp(\"^(?:\" + open_tag + \"|\" + close_tag + \"|\" + comment + \"|\" + processing + \"|\" + declaration + \"|\" + cdata + \")\");\n\nconst HTML_OPEN_CLOSE_TAG_RE = new RegExp(\"^(?:\" + open_tag + \"|\" + close_tag + \")\");\n\n// HTML block\n// An array of opening and corresponding closing sequences for html tags,\n// last argument defines whether it can terminate a paragraph or not\n\nconst HTML_SEQUENCES = [ [ /^<(script|pre|style|textarea)(?=(\\s|>|$))/i, /<\\/(script|pre|style|textarea)>/i, true ], [ /^<!--/, /-->/, true ], [ /^<\\?/, /\\?>/, true ], [ /^<![A-Z]/, />/, true ], [ /^<!\\[CDATA\\[/, /\\]\\]>/, true ], [ new RegExp(\"^</?(\" + block_names.join(\"|\") + \")(?=(\\\\s|/?>|$))\", \"i\"), /^$/, true ], [ new RegExp(HTML_OPEN_CLOSE_TAG_RE.source + \"\\\\s*$\"), /^$/, false ] ];\n\nfunction html_block(state, startLine, endLine, silent) {\n  let pos = state.bMarks[startLine] + state.tShift[startLine];\n  let max = state.eMarks[startLine];\n  // if it's indented more than 3 spaces, it should be a code block\n    if (state.sCount[startLine] - state.blkIndent >= 4) {\n    return false;\n  }\n  if (!state.md.options.html) {\n    return false;\n  }\n  if (state.src.charCodeAt(pos) !== 60 /* < */) {\n    return false;\n  }\n  let lineText = state.src.slice(pos, max);\n  let i = 0;\n  for (;i < HTML_SEQUENCES.length; i++) {\n    if (HTML_SEQUENCES[i][0].test(lineText)) {\n      break;\n    }\n  }\n  if (i === HTML_SEQUENCES.length) {\n    return false;\n  }\n  if (silent) {\n    // true if this sequence can be a terminator, false otherwise\n    return HTML_SEQUENCES[i][2];\n  }\n  let nextLine = startLine + 1;\n  // If we are here - we detected HTML block.\n  // Let's roll down till block end.\n    if (!HTML_SEQUENCES[i][1].test(lineText)) {\n    for (;nextLine < endLine; nextLine++) {\n      if (state.sCount[nextLine] < state.blkIndent) {\n        break;\n      }\n      pos = state.bMarks[nextLine] + state.tShift[nextLine];\n      max = state.eMarks[nextLine];\n      lineText = state.src.slice(pos, max);\n      if (HTML_SEQUENCES[i][1].test(lineText)) {\n        if (lineText.length !== 0) {\n          nextLine++;\n        }\n        break;\n      }\n    }\n  }\n  state.line = nextLine;\n  const token = state.push(\"html_block\", \"\", 0);\n  token.map = [ startLine, nextLine ];\n  token.content = state.getLines(startLine, nextLine, state.blkIndent, true);\n  return true;\n}\n\n// heading (#, ##, ...)\nfunction heading(state, startLine, endLine, silent) {\n  let pos = state.bMarks[startLine] + state.tShift[startLine];\n  let max = state.eMarks[startLine];\n  // if it's indented more than 3 spaces, it should be a code block\n    if (state.sCount[startLine] - state.blkIndent >= 4) {\n    return false;\n  }\n  let ch = state.src.charCodeAt(pos);\n  if (ch !== 35 /* # */ || pos >= max) {\n    return false;\n  }\n  // count heading level\n    let level = 1;\n  ch = state.src.charCodeAt(++pos);\n  while (ch === 35 /* # */ && pos < max && level <= 6) {\n    level++;\n    ch = state.src.charCodeAt(++pos);\n  }\n  if (level > 6 || pos < max && !isSpace(ch)) {\n    return false;\n  }\n  if (silent) {\n    return true;\n  }\n  // Let's cut tails like '    ###  ' from the end of string\n    max = state.skipSpacesBack(max, pos);\n  const tmp = state.skipCharsBack(max, 35, pos);\n // #\n    if (tmp > pos && isSpace(state.src.charCodeAt(tmp - 1))) {\n    max = tmp;\n  }\n  state.line = startLine + 1;\n  const token_o = state.push(\"heading_open\", \"h\" + String(level), 1);\n  token_o.markup = \"########\".slice(0, level);\n  token_o.map = [ startLine, state.line ];\n  const token_i = state.push(\"inline\", \"\", 0);\n  token_i.content = state.src.slice(pos, max).trim();\n  token_i.map = [ startLine, state.line ];\n  token_i.children = [];\n  const token_c = state.push(\"heading_close\", \"h\" + String(level), -1);\n  token_c.markup = \"########\".slice(0, level);\n  return true;\n}\n\n// lheading (---, ===)\nfunction lheading(state, startLine, endLine /*, silent */) {\n  const terminatorRules = state.md.block.ruler.getRules(\"paragraph\");\n  // if it's indented more than 3 spaces, it should be a code block\n    if (state.sCount[startLine] - state.blkIndent >= 4) {\n    return false;\n  }\n  const oldParentType = state.parentType;\n  state.parentType = \"paragraph\";\n // use paragraph to match terminatorRules\n  // jump line-by-line until empty one or EOF\n    let level = 0;\n  let marker;\n  let nextLine = startLine + 1;\n  for (;nextLine < endLine && !state.isEmpty(nextLine); nextLine++) {\n    // this would be a code block normally, but after paragraph\n    // it's considered a lazy continuation regardless of what's there\n    if (state.sCount[nextLine] - state.blkIndent > 3) {\n      continue;\n    }\n    \n    // Check for underline in setext header\n    \n        if (state.sCount[nextLine] >= state.blkIndent) {\n      let pos = state.bMarks[nextLine] + state.tShift[nextLine];\n      const max = state.eMarks[nextLine];\n      if (pos < max) {\n        marker = state.src.charCodeAt(pos);\n        if (marker === 45 /* - */ || marker === 61 /* = */) {\n          pos = state.skipChars(pos, marker);\n          pos = state.skipSpaces(pos);\n          if (pos >= max) {\n            level = marker === 61 /* = */ ? 1 : 2;\n            break;\n          }\n        }\n      }\n    }\n    // quirk for blockquotes, this line should already be checked by that rule\n        if (state.sCount[nextLine] < 0) {\n      continue;\n    }\n    // Some tags can terminate paragraph without empty line.\n        let terminate = false;\n    for (let i = 0, l = terminatorRules.length; i < l; i++) {\n      if (terminatorRules[i](state, nextLine, endLine, true)) {\n        terminate = true;\n        break;\n      }\n    }\n    if (terminate) {\n      break;\n    }\n  }\n  if (!level) {\n    // Didn't find valid underline\n    return false;\n  }\n  const content = state.getLines(startLine, nextLine, state.blkIndent, false).trim();\n  state.line = nextLine + 1;\n  const token_o = state.push(\"heading_open\", \"h\" + String(level), 1);\n  token_o.markup = String.fromCharCode(marker);\n  token_o.map = [ startLine, state.line ];\n  const token_i = state.push(\"inline\", \"\", 0);\n  token_i.content = content;\n  token_i.map = [ startLine, state.line - 1 ];\n  token_i.children = [];\n  const token_c = state.push(\"heading_close\", \"h\" + String(level), -1);\n  token_c.markup = String.fromCharCode(marker);\n  state.parentType = oldParentType;\n  return true;\n}\n\n// Paragraph\nfunction paragraph(state, startLine, endLine) {\n  const terminatorRules = state.md.block.ruler.getRules(\"paragraph\");\n  const oldParentType = state.parentType;\n  let nextLine = startLine + 1;\n  state.parentType = \"paragraph\";\n  // jump line-by-line until empty one or EOF\n    for (;nextLine < endLine && !state.isEmpty(nextLine); nextLine++) {\n    // this would be a code block normally, but after paragraph\n    // it's considered a lazy continuation regardless of what's there\n    if (state.sCount[nextLine] - state.blkIndent > 3) {\n      continue;\n    }\n    // quirk for blockquotes, this line should already be checked by that rule\n        if (state.sCount[nextLine] < 0) {\n      continue;\n    }\n    // Some tags can terminate paragraph without empty line.\n        let terminate = false;\n    for (let i = 0, l = terminatorRules.length; i < l; i++) {\n      if (terminatorRules[i](state, nextLine, endLine, true)) {\n        terminate = true;\n        break;\n      }\n    }\n    if (terminate) {\n      break;\n    }\n  }\n  const content = state.getLines(startLine, nextLine, state.blkIndent, false).trim();\n  state.line = nextLine;\n  const token_o = state.push(\"paragraph_open\", \"p\", 1);\n  token_o.map = [ startLine, state.line ];\n  const token_i = state.push(\"inline\", \"\", 0);\n  token_i.content = content;\n  token_i.map = [ startLine, state.line ];\n  token_i.children = [];\n  state.push(\"paragraph_close\", \"p\", -1);\n  state.parentType = oldParentType;\n  return true;\n}\n\n/** internal\n * class ParserBlock\n *\n * Block-level tokenizer.\n **/ const _rules$1 = [ \n// First 2 params - rule name & source. Secondary array - list of rules,\n// which can be terminated by this one.\n[ \"table\", table, [ \"paragraph\", \"reference\" ] ], [ \"code\", code ], [ \"fence\", fence, [ \"paragraph\", \"reference\", \"blockquote\", \"list\" ] ], [ \"blockquote\", blockquote, [ \"paragraph\", \"reference\", \"blockquote\", \"list\" ] ], [ \"hr\", hr, [ \"paragraph\", \"reference\", \"blockquote\", \"list\" ] ], [ \"list\", list, [ \"paragraph\", \"reference\", \"blockquote\" ] ], [ \"reference\", reference ], [ \"html_block\", html_block, [ \"paragraph\", \"reference\", \"blockquote\" ] ], [ \"heading\", heading, [ \"paragraph\", \"reference\", \"blockquote\" ] ], [ \"lheading\", lheading ], [ \"paragraph\", paragraph ] ];\n\n/**\n * new ParserBlock()\n **/ function ParserBlock() {\n  /**\n   * ParserBlock#ruler -> Ruler\n   *\n   * [[Ruler]] instance. Keep configuration of block rules.\n   **/\n  this.ruler = new Ruler;\n  for (let i = 0; i < _rules$1.length; i++) {\n    this.ruler.push(_rules$1[i][0], _rules$1[i][1], {\n      alt: (_rules$1[i][2] || []).slice()\n    });\n  }\n}\n\n// Generate tokens for input range\n\nParserBlock.prototype.tokenize = function(state, startLine, endLine) {\n  const rules = this.ruler.getRules(\"\");\n  const len = rules.length;\n  const maxNesting = state.md.options.maxNesting;\n  let line = startLine;\n  let hasEmptyLines = false;\n  while (line < endLine) {\n    state.line = line = state.skipEmptyLines(line);\n    if (line >= endLine) {\n      break;\n    }\n    // Termination condition for nested calls.\n    // Nested calls currently used for blockquotes & lists\n        if (state.sCount[line] < state.blkIndent) {\n      break;\n    }\n    // If nesting level exceeded - skip tail to the end. That's not ordinary\n    // situation and we should not care about content.\n        if (state.level >= maxNesting) {\n      state.line = endLine;\n      break;\n    }\n    // Try all possible rules.\n    // On success, rule should:\n    \n    // - update `state.line`\n    // - update `state.tokens`\n    // - return true\n        const prevLine = state.line;\n    let ok = false;\n    for (let i = 0; i < len; i++) {\n      ok = rules[i](state, line, endLine, false);\n      if (ok) {\n        if (prevLine >= state.line) {\n          throw new Error(\"block rule didn't increment state.line\");\n        }\n        break;\n      }\n    }\n    // this can only happen if user disables paragraph rule\n        if (!ok) throw new Error(\"none of the block rules matched\");\n    // set state.tight if we had an empty line before current tag\n    // i.e. latest empty line should not count\n        state.tight = !hasEmptyLines;\n    // paragraph might \"eat\" one newline after it in nested lists\n        if (state.isEmpty(state.line - 1)) {\n      hasEmptyLines = true;\n    }\n    line = state.line;\n    if (line < endLine && state.isEmpty(line)) {\n      hasEmptyLines = true;\n      line++;\n      state.line = line;\n    }\n  }\n};\n\n/**\n * ParserBlock.parse(str, md, env, outTokens)\n *\n * Process input string and push block tokens into `outTokens`\n **/ ParserBlock.prototype.parse = function(src, md, env, outTokens) {\n  if (!src) {\n    return;\n  }\n  const state = new this.State(src, md, env, outTokens);\n  this.tokenize(state, state.line, state.lineMax);\n};\n\nParserBlock.prototype.State = StateBlock;\n\n// Inline parser state\nfunction StateInline(src, md, env, outTokens) {\n  this.src = src;\n  this.env = env;\n  this.md = md;\n  this.tokens = outTokens;\n  this.tokens_meta = Array(outTokens.length);\n  this.pos = 0;\n  this.posMax = this.src.length;\n  this.level = 0;\n  this.pending = \"\";\n  this.pendingLevel = 0;\n  // Stores { start: end } pairs. Useful for backtrack\n  // optimization of pairs parse (emphasis, strikes).\n    this.cache = {};\n  // List of emphasis-like delimiters for current tag\n    this.delimiters = [];\n  // Stack of delimiter lists for upper level tags\n    this._prev_delimiters = [];\n  // backtick length => last seen position\n    this.backticks = {};\n  this.backticksScanned = false;\n  // Counter used to disable inline linkify-it execution\n  // inside <a> and markdown links\n    this.linkLevel = 0;\n}\n\n// Flush pending text\n\nStateInline.prototype.pushPending = function() {\n  const token = new Token(\"text\", \"\", 0);\n  token.content = this.pending;\n  token.level = this.pendingLevel;\n  this.tokens.push(token);\n  this.pending = \"\";\n  return token;\n};\n\n// Push new token to \"stream\".\n// If pending text exists - flush it as text token\n\nStateInline.prototype.push = function(type, tag, nesting) {\n  if (this.pending) {\n    this.pushPending();\n  }\n  const token = new Token(type, tag, nesting);\n  let token_meta = null;\n  if (nesting < 0) {\n    // closing tag\n    this.level--;\n    this.delimiters = this._prev_delimiters.pop();\n  }\n  token.level = this.level;\n  if (nesting > 0) {\n    // opening tag\n    this.level++;\n    this._prev_delimiters.push(this.delimiters);\n    this.delimiters = [];\n    token_meta = {\n      delimiters: this.delimiters\n    };\n  }\n  this.pendingLevel = this.level;\n  this.tokens.push(token);\n  this.tokens_meta.push(token_meta);\n  return token;\n};\n\n// Scan a sequence of emphasis-like markers, and determine whether\n// it can start an emphasis sequence or end an emphasis sequence.\n\n//  - start - position to scan from (it should point at a valid marker);\n//  - canSplitWord - determine if these markers can be found inside a word\n\nStateInline.prototype.scanDelims = function(start, canSplitWord) {\n  const max = this.posMax;\n  const marker = this.src.charCodeAt(start);\n  // treat beginning of the line as a whitespace\n    const lastChar = start > 0 ? this.src.charCodeAt(start - 1) : 32;\n  let pos = start;\n  while (pos < max && this.src.charCodeAt(pos) === marker) {\n    pos++;\n  }\n  const count = pos - start;\n  // treat end of the line as a whitespace\n    const nextChar = pos < max ? this.src.charCodeAt(pos) : 32;\n  const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar));\n  const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar));\n  const isLastWhiteSpace = isWhiteSpace(lastChar);\n  const isNextWhiteSpace = isWhiteSpace(nextChar);\n  const left_flanking = !isNextWhiteSpace && (!isNextPunctChar || isLastWhiteSpace || isLastPunctChar);\n  const right_flanking = !isLastWhiteSpace && (!isLastPunctChar || isNextWhiteSpace || isNextPunctChar);\n  const can_open = left_flanking && (canSplitWord || !right_flanking || isLastPunctChar);\n  const can_close = right_flanking && (canSplitWord || !left_flanking || isNextPunctChar);\n  return {\n    can_open: can_open,\n    can_close: can_close,\n    length: count\n  };\n};\n\n// re-export Token class to use in block rules\nStateInline.prototype.Token = Token;\n\n// Skip text characters for text token, place those to pending buffer\n// and increment current pos\n// Rule to skip pure text\n// '{}$%@~+=:' reserved for extentions\n// !, \", #, $, %, &, ', (, ), *, +, ,, -, ., /, :, ;, <, =, >, ?, @, [, \\, ], ^, _, `, {, |, }, or ~\n// !!!! Don't confuse with \"Markdown ASCII Punctuation\" chars\n// http://spec.commonmark.org/0.15/#ascii-punctuation-character\nfunction isTerminatorChar(ch) {\n  switch (ch) {\n   case 10 /* \\n */ :\n   case 33 /* ! */ :\n   case 35 /* # */ :\n   case 36 /* $ */ :\n   case 37 /* % */ :\n   case 38 /* & */ :\n   case 42 /* * */ :\n   case 43 /* + */ :\n   case 45 /* - */ :\n   case 58 /* : */ :\n   case 60 /* < */ :\n   case 61 /* = */ :\n   case 62 /* > */ :\n   case 64 /* @ */ :\n   case 91 /* [ */ :\n   case 92 /* \\ */ :\n   case 93 /* ] */ :\n   case 94 /* ^ */ :\n   case 95 /* _ */ :\n   case 96 /* ` */ :\n   case 123 /* { */ :\n   case 125 /* } */ :\n   case 126 /* ~ */ :\n    return true;\n\n   default:\n    return false;\n  }\n}\n\nfunction text(state, silent) {\n  let pos = state.pos;\n  while (pos < state.posMax && !isTerminatorChar(state.src.charCodeAt(pos))) {\n    pos++;\n  }\n  if (pos === state.pos) {\n    return false;\n  }\n  if (!silent) {\n    state.pending += state.src.slice(state.pos, pos);\n  }\n  state.pos = pos;\n  return true;\n}\n\n// Alternative implementation, for memory.\n\n// It costs 10% of performance, but allows extend terminators list, if place it\n// to `ParserInline` property. Probably, will switch to it sometime, such\n// flexibility required.\n/*\nvar TERMINATOR_RE = /[\\n!#$%&*+\\-:<=>@[\\\\\\]^_`{}~]/;\n\nmodule.exports = function text(state, silent) {\n  var pos = state.pos,\n      idx = state.src.slice(pos).search(TERMINATOR_RE);\n\n  // first char is terminator -> empty text\n  if (idx === 0) { return false; }\n\n  // no terminator -> text till end of string\n  if (idx < 0) {\n    if (!silent) { state.pending += state.src.slice(pos); }\n    state.pos = state.src.length;\n    return true;\n  }\n\n  if (!silent) { state.pending += state.src.slice(pos, pos + idx); }\n\n  state.pos += idx;\n\n  return true;\n}; */\n// Process links like https://example.org/\n// RFC3986: scheme = ALPHA *( ALPHA / DIGIT / \"+\" / \"-\" / \".\" )\nconst SCHEME_RE = /(?:^|[^a-z0-9.+-])([a-z][a-z0-9.+-]*)$/i;\n\nfunction linkify(state, silent) {\n  if (!state.md.options.linkify) return false;\n  if (state.linkLevel > 0) return false;\n  const pos = state.pos;\n  const max = state.posMax;\n  if (pos + 3 > max) return false;\n  if (state.src.charCodeAt(pos) !== 58 /* : */) return false;\n  if (state.src.charCodeAt(pos + 1) !== 47 /* / */) return false;\n  if (state.src.charCodeAt(pos + 2) !== 47 /* / */) return false;\n  const match = state.pending.match(SCHEME_RE);\n  if (!match) return false;\n  const proto = match[1];\n  const link = state.md.linkify.matchAtStart(state.src.slice(pos - proto.length));\n  if (!link) return false;\n  let url = link.url;\n  // invalid link, but still detected by linkify somehow;\n  // need to check to prevent infinite loop below\n    if (url.length <= proto.length) return false;\n  // disallow '*' at the end of the link (conflicts with emphasis)\n    url = url.replace(/\\*+$/, \"\");\n  const fullUrl = state.md.normalizeLink(url);\n  if (!state.md.validateLink(fullUrl)) return false;\n  if (!silent) {\n    state.pending = state.pending.slice(0, -proto.length);\n    const token_o = state.push(\"link_open\", \"a\", 1);\n    token_o.attrs = [ [ \"href\", fullUrl ] ];\n    token_o.markup = \"linkify\";\n    token_o.info = \"auto\";\n    const token_t = state.push(\"text\", \"\", 0);\n    token_t.content = state.md.normalizeLinkText(url);\n    const token_c = state.push(\"link_close\", \"a\", -1);\n    token_c.markup = \"linkify\";\n    token_c.info = \"auto\";\n  }\n  state.pos += url.length - proto.length;\n  return true;\n}\n\n// Proceess '\\n'\nfunction newline(state, silent) {\n  let pos = state.pos;\n  if (state.src.charCodeAt(pos) !== 10 /* \\n */) {\n    return false;\n  }\n  const pmax = state.pending.length - 1;\n  const max = state.posMax;\n  // '  \\n' -> hardbreak\n  // Lookup in pending chars is bad practice! Don't copy to other rules!\n  // Pending string is stored in concat mode, indexed lookups will cause\n  // convertion to flat mode.\n    if (!silent) {\n    if (pmax >= 0 && state.pending.charCodeAt(pmax) === 32) {\n      if (pmax >= 1 && state.pending.charCodeAt(pmax - 1) === 32) {\n        // Find whitespaces tail of pending chars.\n        let ws = pmax - 1;\n        while (ws >= 1 && state.pending.charCodeAt(ws - 1) === 32) ws--;\n        state.pending = state.pending.slice(0, ws);\n        state.push(\"hardbreak\", \"br\", 0);\n      } else {\n        state.pending = state.pending.slice(0, -1);\n        state.push(\"softbreak\", \"br\", 0);\n      }\n    } else {\n      state.push(\"softbreak\", \"br\", 0);\n    }\n  }\n  pos++;\n  // skip heading spaces for next line\n    while (pos < max && isSpace(state.src.charCodeAt(pos))) {\n    pos++;\n  }\n  state.pos = pos;\n  return true;\n}\n\n// Process escaped chars and hardbreaks\nconst ESCAPED = [];\n\nfor (let i = 0; i < 256; i++) {\n  ESCAPED.push(0);\n}\n\n\"\\\\!\\\"#$%&'()*+,./:;<=>?@[]^_`{|}~-\".split(\"\").forEach(function(ch) {\n  ESCAPED[ch.charCodeAt(0)] = 1;\n});\n\nfunction escape(state, silent) {\n  let pos = state.pos;\n  const max = state.posMax;\n  if (state.src.charCodeAt(pos) !== 92 /* \\ */) return false;\n  pos++;\n  // '\\' at the end of the inline block\n    if (pos >= max) return false;\n  let ch1 = state.src.charCodeAt(pos);\n  if (ch1 === 10) {\n    if (!silent) {\n      state.push(\"hardbreak\", \"br\", 0);\n    }\n    pos++;\n    // skip leading whitespaces from next line\n        while (pos < max) {\n      ch1 = state.src.charCodeAt(pos);\n      if (!isSpace(ch1)) break;\n      pos++;\n    }\n    state.pos = pos;\n    return true;\n  }\n  let escapedStr = state.src[pos];\n  if (ch1 >= 55296 && ch1 <= 56319 && pos + 1 < max) {\n    const ch2 = state.src.charCodeAt(pos + 1);\n    if (ch2 >= 56320 && ch2 <= 57343) {\n      escapedStr += state.src[pos + 1];\n      pos++;\n    }\n  }\n  const origStr = \"\\\\\" + escapedStr;\n  if (!silent) {\n    const token = state.push(\"text_special\", \"\", 0);\n    if (ch1 < 256 && ESCAPED[ch1] !== 0) {\n      token.content = escapedStr;\n    } else {\n      token.content = origStr;\n    }\n    token.markup = origStr;\n    token.info = \"escape\";\n  }\n  state.pos = pos + 1;\n  return true;\n}\n\n// Parse backticks\nfunction backtick(state, silent) {\n  let pos = state.pos;\n  const ch = state.src.charCodeAt(pos);\n  if (ch !== 96 /* ` */) {\n    return false;\n  }\n  const start = pos;\n  pos++;\n  const max = state.posMax;\n  // scan marker length\n    while (pos < max && state.src.charCodeAt(pos) === 96 /* ` */) {\n    pos++;\n  }\n  const marker = state.src.slice(start, pos);\n  const openerLength = marker.length;\n  if (state.backticksScanned && (state.backticks[openerLength] || 0) <= start) {\n    if (!silent) state.pending += marker;\n    state.pos += openerLength;\n    return true;\n  }\n  let matchEnd = pos;\n  let matchStart;\n  // Nothing found in the cache, scan until the end of the line (or until marker is found)\n    while ((matchStart = state.src.indexOf(\"`\", matchEnd)) !== -1) {\n    matchEnd = matchStart + 1;\n    // scan marker length\n        while (matchEnd < max && state.src.charCodeAt(matchEnd) === 96 /* ` */) {\n      matchEnd++;\n    }\n    const closerLength = matchEnd - matchStart;\n    if (closerLength === openerLength) {\n      // Found matching closer length.\n      if (!silent) {\n        const token = state.push(\"code_inline\", \"code\", 0);\n        token.markup = marker;\n        token.content = state.src.slice(pos, matchStart).replace(/\\n/g, \" \").replace(/^ (.+) $/, \"$1\");\n      }\n      state.pos = matchEnd;\n      return true;\n    }\n    // Some different length found, put it in cache as upper limit of where closer can be found\n        state.backticks[closerLength] = matchStart;\n  }\n  // Scanned through the end, didn't find anything\n    state.backticksScanned = true;\n  if (!silent) state.pending += marker;\n  state.pos += openerLength;\n  return true;\n}\n\n// ~~strike through~~\n\n// Insert each marker as a separate text token, and add it to delimiter list\n\nfunction strikethrough_tokenize(state, silent) {\n  const start = state.pos;\n  const marker = state.src.charCodeAt(start);\n  if (silent) {\n    return false;\n  }\n  if (marker !== 126 /* ~ */) {\n    return false;\n  }\n  const scanned = state.scanDelims(state.pos, true);\n  let len = scanned.length;\n  const ch = String.fromCharCode(marker);\n  if (len < 2) {\n    return false;\n  }\n  let token;\n  if (len % 2) {\n    token = state.push(\"text\", \"\", 0);\n    token.content = ch;\n    len--;\n  }\n  for (let i = 0; i < len; i += 2) {\n    token = state.push(\"text\", \"\", 0);\n    token.content = ch + ch;\n    state.delimiters.push({\n      marker: marker,\n      length: 0,\n      // disable \"rule of 3\" length checks meant for emphasis\n      token: state.tokens.length - 1,\n      end: -1,\n      open: scanned.can_open,\n      close: scanned.can_close\n    });\n  }\n  state.pos += scanned.length;\n  return true;\n}\n\nfunction postProcess$1(state, delimiters) {\n  let token;\n  const loneMarkers = [];\n  const max = delimiters.length;\n  for (let i = 0; i < max; i++) {\n    const startDelim = delimiters[i];\n    if (startDelim.marker !== 126 /* ~ */) {\n      continue;\n    }\n    if (startDelim.end === -1) {\n      continue;\n    }\n    const endDelim = delimiters[startDelim.end];\n    token = state.tokens[startDelim.token];\n    token.type = \"s_open\";\n    token.tag = \"s\";\n    token.nesting = 1;\n    token.markup = \"~~\";\n    token.content = \"\";\n    token = state.tokens[endDelim.token];\n    token.type = \"s_close\";\n    token.tag = \"s\";\n    token.nesting = -1;\n    token.markup = \"~~\";\n    token.content = \"\";\n    if (state.tokens[endDelim.token - 1].type === \"text\" && state.tokens[endDelim.token - 1].content === \"~\") {\n      loneMarkers.push(endDelim.token - 1);\n    }\n  }\n  // If a marker sequence has an odd number of characters, it's splitted\n  // like this: `~~~~~` -> `~` + `~~` + `~~`, leaving one marker at the\n  // start of the sequence.\n  \n  // So, we have to move all those markers after subsequent s_close tags.\n  \n    while (loneMarkers.length) {\n    const i = loneMarkers.pop();\n    let j = i + 1;\n    while (j < state.tokens.length && state.tokens[j].type === \"s_close\") {\n      j++;\n    }\n    j--;\n    if (i !== j) {\n      token = state.tokens[j];\n      state.tokens[j] = state.tokens[i];\n      state.tokens[i] = token;\n    }\n  }\n}\n\n// Walk through delimiter list and replace text tokens with tags\n\nfunction strikethrough_postProcess(state) {\n  const tokens_meta = state.tokens_meta;\n  const max = state.tokens_meta.length;\n  postProcess$1(state, state.delimiters);\n  for (let curr = 0; curr < max; curr++) {\n    if (tokens_meta[curr] && tokens_meta[curr].delimiters) {\n      postProcess$1(state, tokens_meta[curr].delimiters);\n    }\n  }\n}\n\nvar r_strikethrough = {\n  tokenize: strikethrough_tokenize,\n  postProcess: strikethrough_postProcess\n};\n\n// Process *this* and _that_\n\n// Insert each marker as a separate text token, and add it to delimiter list\n\nfunction emphasis_tokenize(state, silent) {\n  const start = state.pos;\n  const marker = state.src.charCodeAt(start);\n  if (silent) {\n    return false;\n  }\n  if (marker !== 95 /* _ */ && marker !== 42 /* * */) {\n    return false;\n  }\n  const scanned = state.scanDelims(state.pos, marker === 42);\n  for (let i = 0; i < scanned.length; i++) {\n    const token = state.push(\"text\", \"\", 0);\n    token.content = String.fromCharCode(marker);\n    state.delimiters.push({\n      // Char code of the starting marker (number).\n      marker: marker,\n      // Total length of these series of delimiters.\n      length: scanned.length,\n      // A position of the token this delimiter corresponds to.\n      token: state.tokens.length - 1,\n      // If this delimiter is matched as a valid opener, `end` will be\n      // equal to its position, otherwise it's `-1`.\n      end: -1,\n      // Boolean flags that determine if this delimiter could open or close\n      // an emphasis.\n      open: scanned.can_open,\n      close: scanned.can_close\n    });\n  }\n  state.pos += scanned.length;\n  return true;\n}\n\nfunction postProcess(state, delimiters) {\n  const max = delimiters.length;\n  for (let i = max - 1; i >= 0; i--) {\n    const startDelim = delimiters[i];\n    if (startDelim.marker !== 95 /* _ */ && startDelim.marker !== 42 /* * */) {\n      continue;\n    }\n    // Process only opening markers\n        if (startDelim.end === -1) {\n      continue;\n    }\n    const endDelim = delimiters[startDelim.end];\n    // If the previous delimiter has the same marker and is adjacent to this one,\n    // merge those into one strong delimiter.\n    \n    // `<em><em>whatever</em></em>` -> `<strong>whatever</strong>`\n    \n        const isStrong = i > 0 && delimiters[i - 1].end === startDelim.end + 1 && \n    // check that first two markers match and adjacent\n    delimiters[i - 1].marker === startDelim.marker && delimiters[i - 1].token === startDelim.token - 1 && \n    // check that last two markers are adjacent (we can safely assume they match)\n    delimiters[startDelim.end + 1].token === endDelim.token + 1;\n    const ch = String.fromCharCode(startDelim.marker);\n    const token_o = state.tokens[startDelim.token];\n    token_o.type = isStrong ? \"strong_open\" : \"em_open\";\n    token_o.tag = isStrong ? \"strong\" : \"em\";\n    token_o.nesting = 1;\n    token_o.markup = isStrong ? ch + ch : ch;\n    token_o.content = \"\";\n    const token_c = state.tokens[endDelim.token];\n    token_c.type = isStrong ? \"strong_close\" : \"em_close\";\n    token_c.tag = isStrong ? \"strong\" : \"em\";\n    token_c.nesting = -1;\n    token_c.markup = isStrong ? ch + ch : ch;\n    token_c.content = \"\";\n    if (isStrong) {\n      state.tokens[delimiters[i - 1].token].content = \"\";\n      state.tokens[delimiters[startDelim.end + 1].token].content = \"\";\n      i--;\n    }\n  }\n}\n\n// Walk through delimiter list and replace text tokens with tags\n\nfunction emphasis_post_process(state) {\n  const tokens_meta = state.tokens_meta;\n  const max = state.tokens_meta.length;\n  postProcess(state, state.delimiters);\n  for (let curr = 0; curr < max; curr++) {\n    if (tokens_meta[curr] && tokens_meta[curr].delimiters) {\n      postProcess(state, tokens_meta[curr].delimiters);\n    }\n  }\n}\n\nvar r_emphasis = {\n  tokenize: emphasis_tokenize,\n  postProcess: emphasis_post_process\n};\n\n// Process [link](<to> \"stuff\")\nfunction link(state, silent) {\n  let code, label, res, ref;\n  let href = \"\";\n  let title = \"\";\n  let start = state.pos;\n  let parseReference = true;\n  if (state.src.charCodeAt(state.pos) !== 91 /* [ */) {\n    return false;\n  }\n  const oldPos = state.pos;\n  const max = state.posMax;\n  const labelStart = state.pos + 1;\n  const labelEnd = state.md.helpers.parseLinkLabel(state, state.pos, true);\n  // parser failed to find ']', so it's not a valid link\n    if (labelEnd < 0) {\n    return false;\n  }\n  let pos = labelEnd + 1;\n  if (pos < max && state.src.charCodeAt(pos) === 40 /* ( */) {\n    // Inline link\n    // might have found a valid shortcut link, disable reference parsing\n    parseReference = false;\n    // [link](  <href>  \"title\"  )\n    //        ^^ skipping these spaces\n        pos++;\n    for (;pos < max; pos++) {\n      code = state.src.charCodeAt(pos);\n      if (!isSpace(code) && code !== 10) {\n        break;\n      }\n    }\n    if (pos >= max) {\n      return false;\n    }\n    // [link](  <href>  \"title\"  )\n    //          ^^^^^^ parsing link destination\n        start = pos;\n    res = state.md.helpers.parseLinkDestination(state.src, pos, state.posMax);\n    if (res.ok) {\n      href = state.md.normalizeLink(res.str);\n      if (state.md.validateLink(href)) {\n        pos = res.pos;\n      } else {\n        href = \"\";\n      }\n      // [link](  <href>  \"title\"  )\n      //                ^^ skipping these spaces\n            start = pos;\n      for (;pos < max; pos++) {\n        code = state.src.charCodeAt(pos);\n        if (!isSpace(code) && code !== 10) {\n          break;\n        }\n      }\n      // [link](  <href>  \"title\"  )\n      //                  ^^^^^^^ parsing link title\n            res = state.md.helpers.parseLinkTitle(state.src, pos, state.posMax);\n      if (pos < max && start !== pos && res.ok) {\n        title = res.str;\n        pos = res.pos;\n        // [link](  <href>  \"title\"  )\n        //                         ^^ skipping these spaces\n                for (;pos < max; pos++) {\n          code = state.src.charCodeAt(pos);\n          if (!isSpace(code) && code !== 10) {\n            break;\n          }\n        }\n      }\n    }\n    if (pos >= max || state.src.charCodeAt(pos) !== 41 /* ) */) {\n      // parsing a valid shortcut link failed, fallback to reference\n      parseReference = true;\n    }\n    pos++;\n  }\n  if (parseReference) {\n    // Link reference\n    if (typeof state.env.references === \"undefined\") {\n      return false;\n    }\n    if (pos < max && state.src.charCodeAt(pos) === 91 /* [ */) {\n      start = pos + 1;\n      pos = state.md.helpers.parseLinkLabel(state, pos);\n      if (pos >= 0) {\n        label = state.src.slice(start, pos++);\n      } else {\n        pos = labelEnd + 1;\n      }\n    } else {\n      pos = labelEnd + 1;\n    }\n    // covers label === '' and label === undefined\n    // (collapsed reference link and shortcut reference link respectively)\n        if (!label) {\n      label = state.src.slice(labelStart, labelEnd);\n    }\n    ref = state.env.references[normalizeReference(label)];\n    if (!ref) {\n      state.pos = oldPos;\n      return false;\n    }\n    href = ref.href;\n    title = ref.title;\n  }\n  \n  // We found the end of the link, and know for a fact it's a valid link;\n  // so all that's left to do is to call tokenizer.\n  \n    if (!silent) {\n    state.pos = labelStart;\n    state.posMax = labelEnd;\n    const token_o = state.push(\"link_open\", \"a\", 1);\n    const attrs = [ [ \"href\", href ] ];\n    token_o.attrs = attrs;\n    if (title) {\n      attrs.push([ \"title\", title ]);\n    }\n    state.linkLevel++;\n    state.md.inline.tokenize(state);\n    state.linkLevel--;\n    state.push(\"link_close\", \"a\", -1);\n  }\n  state.pos = pos;\n  state.posMax = max;\n  return true;\n}\n\n// Process ![image](<src> \"title\")\nfunction image(state, silent) {\n  let code, content, label, pos, ref, res, title, start;\n  let href = \"\";\n  const oldPos = state.pos;\n  const max = state.posMax;\n  if (state.src.charCodeAt(state.pos) !== 33 /* ! */) {\n    return false;\n  }\n  if (state.src.charCodeAt(state.pos + 1) !== 91 /* [ */) {\n    return false;\n  }\n  const labelStart = state.pos + 2;\n  const labelEnd = state.md.helpers.parseLinkLabel(state, state.pos + 1, false);\n  // parser failed to find ']', so it's not a valid link\n    if (labelEnd < 0) {\n    return false;\n  }\n  pos = labelEnd + 1;\n  if (pos < max && state.src.charCodeAt(pos) === 40 /* ( */) {\n    // Inline link\n    // [link](  <href>  \"title\"  )\n    //        ^^ skipping these spaces\n    pos++;\n    for (;pos < max; pos++) {\n      code = state.src.charCodeAt(pos);\n      if (!isSpace(code) && code !== 10) {\n        break;\n      }\n    }\n    if (pos >= max) {\n      return false;\n    }\n    // [link](  <href>  \"title\"  )\n    //          ^^^^^^ parsing link destination\n        start = pos;\n    res = state.md.helpers.parseLinkDestination(state.src, pos, state.posMax);\n    if (res.ok) {\n      href = state.md.normalizeLink(res.str);\n      if (state.md.validateLink(href)) {\n        pos = res.pos;\n      } else {\n        href = \"\";\n      }\n    }\n    // [link](  <href>  \"title\"  )\n    //                ^^ skipping these spaces\n        start = pos;\n    for (;pos < max; pos++) {\n      code = state.src.charCodeAt(pos);\n      if (!isSpace(code) && code !== 10) {\n        break;\n      }\n    }\n    // [link](  <href>  \"title\"  )\n    //                  ^^^^^^^ parsing link title\n        res = state.md.helpers.parseLinkTitle(state.src, pos, state.posMax);\n    if (pos < max && start !== pos && res.ok) {\n      title = res.str;\n      pos = res.pos;\n      // [link](  <href>  \"title\"  )\n      //                         ^^ skipping these spaces\n            for (;pos < max; pos++) {\n        code = state.src.charCodeAt(pos);\n        if (!isSpace(code) && code !== 10) {\n          break;\n        }\n      }\n    } else {\n      title = \"\";\n    }\n    if (pos >= max || state.src.charCodeAt(pos) !== 41 /* ) */) {\n      state.pos = oldPos;\n      return false;\n    }\n    pos++;\n  } else {\n    // Link reference\n    if (typeof state.env.references === \"undefined\") {\n      return false;\n    }\n    if (pos < max && state.src.charCodeAt(pos) === 91 /* [ */) {\n      start = pos + 1;\n      pos = state.md.helpers.parseLinkLabel(state, pos);\n      if (pos >= 0) {\n        label = state.src.slice(start, pos++);\n      } else {\n        pos = labelEnd + 1;\n      }\n    } else {\n      pos = labelEnd + 1;\n    }\n    // covers label === '' and label === undefined\n    // (collapsed reference link and shortcut reference link respectively)\n        if (!label) {\n      label = state.src.slice(labelStart, labelEnd);\n    }\n    ref = state.env.references[normalizeReference(label)];\n    if (!ref) {\n      state.pos = oldPos;\n      return false;\n    }\n    href = ref.href;\n    title = ref.title;\n  }\n  \n  // We found the end of the link, and know for a fact it's a valid link;\n  // so all that's left to do is to call tokenizer.\n  \n    if (!silent) {\n    content = state.src.slice(labelStart, labelEnd);\n    const tokens = [];\n    state.md.inline.parse(content, state.md, state.env, tokens);\n    const token = state.push(\"image\", \"img\", 0);\n    const attrs = [ [ \"src\", href ], [ \"alt\", \"\" ] ];\n    token.attrs = attrs;\n    token.children = tokens;\n    token.content = content;\n    if (title) {\n      attrs.push([ \"title\", title ]);\n    }\n  }\n  state.pos = pos;\n  state.posMax = max;\n  return true;\n}\n\n// Process autolinks '<protocol:...>'\n/* eslint max-len:0 */ const EMAIL_RE = /^([a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)$/;\n\n/* eslint-disable-next-line no-control-regex */ const AUTOLINK_RE = /^([a-zA-Z][a-zA-Z0-9+.-]{1,31}):([^<>\\x00-\\x20]*)$/;\n\nfunction autolink(state, silent) {\n  let pos = state.pos;\n  if (state.src.charCodeAt(pos) !== 60 /* < */) {\n    return false;\n  }\n  const start = state.pos;\n  const max = state.posMax;\n  for (;;) {\n    if (++pos >= max) return false;\n    const ch = state.src.charCodeAt(pos);\n    if (ch === 60 /* < */) return false;\n    if (ch === 62 /* > */) break;\n  }\n  const url = state.src.slice(start + 1, pos);\n  if (AUTOLINK_RE.test(url)) {\n    const fullUrl = state.md.normalizeLink(url);\n    if (!state.md.validateLink(fullUrl)) {\n      return false;\n    }\n    if (!silent) {\n      const token_o = state.push(\"link_open\", \"a\", 1);\n      token_o.attrs = [ [ \"href\", fullUrl ] ];\n      token_o.markup = \"autolink\";\n      token_o.info = \"auto\";\n      const token_t = state.push(\"text\", \"\", 0);\n      token_t.content = state.md.normalizeLinkText(url);\n      const token_c = state.push(\"link_close\", \"a\", -1);\n      token_c.markup = \"autolink\";\n      token_c.info = \"auto\";\n    }\n    state.pos += url.length + 2;\n    return true;\n  }\n  if (EMAIL_RE.test(url)) {\n    const fullUrl = state.md.normalizeLink(\"mailto:\" + url);\n    if (!state.md.validateLink(fullUrl)) {\n      return false;\n    }\n    if (!silent) {\n      const token_o = state.push(\"link_open\", \"a\", 1);\n      token_o.attrs = [ [ \"href\", fullUrl ] ];\n      token_o.markup = \"autolink\";\n      token_o.info = \"auto\";\n      const token_t = state.push(\"text\", \"\", 0);\n      token_t.content = state.md.normalizeLinkText(url);\n      const token_c = state.push(\"link_close\", \"a\", -1);\n      token_c.markup = \"autolink\";\n      token_c.info = \"auto\";\n    }\n    state.pos += url.length + 2;\n    return true;\n  }\n  return false;\n}\n\n// Process html tags\nfunction isLinkOpen(str) {\n  return /^<a[>\\s]/i.test(str);\n}\n\nfunction isLinkClose(str) {\n  return /^<\\/a\\s*>/i.test(str);\n}\n\nfunction isLetter(ch) {\n  /* eslint no-bitwise:0 */\n  const lc = ch | 32;\n // to lower case\n    return lc >= 97 /* a */ && lc <= 122 /* z */;\n}\n\nfunction html_inline(state, silent) {\n  if (!state.md.options.html) {\n    return false;\n  }\n  // Check start\n    const max = state.posMax;\n  const pos = state.pos;\n  if (state.src.charCodeAt(pos) !== 60 /* < */ || pos + 2 >= max) {\n    return false;\n  }\n  // Quick fail on second char\n    const ch = state.src.charCodeAt(pos + 1);\n  if (ch !== 33 /* ! */ && ch !== 63 /* ? */ && ch !== 47 /* / */ && !isLetter(ch)) {\n    return false;\n  }\n  const match = state.src.slice(pos).match(HTML_TAG_RE);\n  if (!match) {\n    return false;\n  }\n  if (!silent) {\n    const token = state.push(\"html_inline\", \"\", 0);\n    token.content = match[0];\n    if (isLinkOpen(token.content)) state.linkLevel++;\n    if (isLinkClose(token.content)) state.linkLevel--;\n  }\n  state.pos += match[0].length;\n  return true;\n}\n\n// Process html entity - &#123;, &#xAF;, &quot;, ...\nconst DIGITAL_RE = /^&#((?:x[a-f0-9]{1,6}|[0-9]{1,7}));/i;\n\nconst NAMED_RE = /^&([a-z][a-z0-9]{1,31});/i;\n\nfunction entity(state, silent) {\n  const pos = state.pos;\n  const max = state.posMax;\n  if (state.src.charCodeAt(pos) !== 38 /* & */) return false;\n  if (pos + 1 >= max) return false;\n  const ch = state.src.charCodeAt(pos + 1);\n  if (ch === 35 /* # */) {\n    const match = state.src.slice(pos).match(DIGITAL_RE);\n    if (match) {\n      if (!silent) {\n        const code = match[1][0].toLowerCase() === \"x\" ? parseInt(match[1].slice(1), 16) : parseInt(match[1], 10);\n        const token = state.push(\"text_special\", \"\", 0);\n        token.content = isValidEntityCode(code) ? fromCodePoint(code) : fromCodePoint(65533);\n        token.markup = match[0];\n        token.info = \"entity\";\n      }\n      state.pos += match[0].length;\n      return true;\n    }\n  } else {\n    const match = state.src.slice(pos).match(NAMED_RE);\n    if (match) {\n      const decoded = decodeHTML(match[0]);\n      if (decoded !== match[0]) {\n        if (!silent) {\n          const token = state.push(\"text_special\", \"\", 0);\n          token.content = decoded;\n          token.markup = match[0];\n          token.info = \"entity\";\n        }\n        state.pos += match[0].length;\n        return true;\n      }\n    }\n  }\n  return false;\n}\n\n// For each opening emphasis-like marker find a matching closing one\n\nfunction processDelimiters(delimiters) {\n  const openersBottom = {};\n  const max = delimiters.length;\n  if (!max) return;\n  // headerIdx is the first delimiter of the current (where closer is) delimiter run\n    let headerIdx = 0;\n  let lastTokenIdx = -2;\n // needs any value lower than -1\n    const jumps = [];\n  for (let closerIdx = 0; closerIdx < max; closerIdx++) {\n    const closer = delimiters[closerIdx];\n    jumps.push(0);\n    // markers belong to same delimiter run if:\n    //  - they have adjacent tokens\n    //  - AND markers are the same\n    \n        if (delimiters[headerIdx].marker !== closer.marker || lastTokenIdx !== closer.token - 1) {\n      headerIdx = closerIdx;\n    }\n    lastTokenIdx = closer.token;\n    // Length is only used for emphasis-specific \"rule of 3\",\n    // if it's not defined (in strikethrough or 3rd party plugins),\n    // we can default it to 0 to disable those checks.\n    \n        closer.length = closer.length || 0;\n    if (!closer.close) continue;\n    // Previously calculated lower bounds (previous fails)\n    // for each marker, each delimiter length modulo 3,\n    // and for whether this closer can be an opener;\n    // https://github.com/commonmark/cmark/commit/34250e12ccebdc6372b8b49c44fab57c72443460\n    /* eslint-disable-next-line no-prototype-builtins */    if (!openersBottom.hasOwnProperty(closer.marker)) {\n      openersBottom[closer.marker] = [ -1, -1, -1, -1, -1, -1 ];\n    }\n    const minOpenerIdx = openersBottom[closer.marker][(closer.open ? 3 : 0) + closer.length % 3];\n    let openerIdx = headerIdx - jumps[headerIdx] - 1;\n    let newMinOpenerIdx = openerIdx;\n    for (;openerIdx > minOpenerIdx; openerIdx -= jumps[openerIdx] + 1) {\n      const opener = delimiters[openerIdx];\n      if (opener.marker !== closer.marker) continue;\n      if (opener.open && opener.end < 0) {\n        let isOddMatch = false;\n        // from spec:\n        \n        // If one of the delimiters can both open and close emphasis, then the\n        // sum of the lengths of the delimiter runs containing the opening and\n        // closing delimiters must not be a multiple of 3 unless both lengths\n        // are multiples of 3.\n        \n                if (opener.close || closer.open) {\n          if ((opener.length + closer.length) % 3 === 0) {\n            if (opener.length % 3 !== 0 || closer.length % 3 !== 0) {\n              isOddMatch = true;\n            }\n          }\n        }\n        if (!isOddMatch) {\n          // If previous delimiter cannot be an opener, we can safely skip\n          // the entire sequence in future checks. This is required to make\n          // sure algorithm has linear complexity (see *_*_*_*_*_... case).\n          const lastJump = openerIdx > 0 && !delimiters[openerIdx - 1].open ? jumps[openerIdx - 1] + 1 : 0;\n          jumps[closerIdx] = closerIdx - openerIdx + lastJump;\n          jumps[openerIdx] = lastJump;\n          closer.open = false;\n          opener.end = closerIdx;\n          opener.close = false;\n          newMinOpenerIdx = -1;\n          // treat next token as start of run,\n          // it optimizes skips in **<...>**a**<...>** pathological case\n                    lastTokenIdx = -2;\n          break;\n        }\n      }\n    }\n    if (newMinOpenerIdx !== -1) {\n      // If match for this delimiter run failed, we want to set lower bound for\n      // future lookups. This is required to make sure algorithm has linear\n      // complexity.\n      // See details here:\n      // https://github.com/commonmark/cmark/issues/178#issuecomment-270417442\n      openersBottom[closer.marker][(closer.open ? 3 : 0) + (closer.length || 0) % 3] = newMinOpenerIdx;\n    }\n  }\n}\n\nfunction link_pairs(state) {\n  const tokens_meta = state.tokens_meta;\n  const max = state.tokens_meta.length;\n  processDelimiters(state.delimiters);\n  for (let curr = 0; curr < max; curr++) {\n    if (tokens_meta[curr] && tokens_meta[curr].delimiters) {\n      processDelimiters(tokens_meta[curr].delimiters);\n    }\n  }\n}\n\n// Clean up tokens after emphasis and strikethrough postprocessing:\n// merge adjacent text nodes into one and re-calculate all token levels\n\n// This is necessary because initially emphasis delimiter markers (*, _, ~)\n// are treated as their own separate text tokens. Then emphasis rule either\n// leaves them as text (needed to merge with adjacent text) or turns them\n// into opening/closing tags (which messes up levels inside).\n\nfunction fragments_join(state) {\n  let curr, last;\n  let level = 0;\n  const tokens = state.tokens;\n  const max = state.tokens.length;\n  for (curr = last = 0; curr < max; curr++) {\n    // re-calculate levels after emphasis/strikethrough turns some text nodes\n    // into opening/closing tags\n    if (tokens[curr].nesting < 0) level--;\n // closing tag\n        tokens[curr].level = level;\n    if (tokens[curr].nesting > 0) level++;\n // opening tag\n        if (tokens[curr].type === \"text\" && curr + 1 < max && tokens[curr + 1].type === \"text\") {\n      // collapse two adjacent text nodes\n      tokens[curr + 1].content = tokens[curr].content + tokens[curr + 1].content;\n    } else {\n      if (curr !== last) {\n        tokens[last] = tokens[curr];\n      }\n      last++;\n    }\n  }\n  if (curr !== last) {\n    tokens.length = last;\n  }\n}\n\n/** internal\n * class ParserInline\n *\n * Tokenizes paragraph content.\n **/\n// Parser rules\nconst _rules = [ [ \"text\", text ], [ \"linkify\", linkify ], [ \"newline\", newline ], [ \"escape\", escape ], [ \"backticks\", backtick ], [ \"strikethrough\", r_strikethrough.tokenize ], [ \"emphasis\", r_emphasis.tokenize ], [ \"link\", link ], [ \"image\", image ], [ \"autolink\", autolink ], [ \"html_inline\", html_inline ], [ \"entity\", entity ] ];\n\n// `rule2` ruleset was created specifically for emphasis/strikethrough\n// post-processing and may be changed in the future.\n\n// Don't use this for anything except pairs (plugins working with `balance_pairs`).\n\nconst _rules2 = [ [ \"balance_pairs\", link_pairs ], [ \"strikethrough\", r_strikethrough.postProcess ], [ \"emphasis\", r_emphasis.postProcess ], \n// rules for pairs separate '**' into its own text tokens, which may be left unused,\n// rule below merges unused segments back with the rest of the text\n[ \"fragments_join\", fragments_join ] ];\n\n/**\n * new ParserInline()\n **/ function ParserInline() {\n  /**\n   * ParserInline#ruler -> Ruler\n   *\n   * [[Ruler]] instance. Keep configuration of inline rules.\n   **/\n  this.ruler = new Ruler;\n  for (let i = 0; i < _rules.length; i++) {\n    this.ruler.push(_rules[i][0], _rules[i][1]);\n  }\n  /**\n   * ParserInline#ruler2 -> Ruler\n   *\n   * [[Ruler]] instance. Second ruler used for post-processing\n   * (e.g. in emphasis-like rules).\n   **/  this.ruler2 = new Ruler;\n  for (let i = 0; i < _rules2.length; i++) {\n    this.ruler2.push(_rules2[i][0], _rules2[i][1]);\n  }\n}\n\n// Skip single token by running all rules in validation mode;\n// returns `true` if any rule reported success\n\nParserInline.prototype.skipToken = function(state) {\n  const pos = state.pos;\n  const rules = this.ruler.getRules(\"\");\n  const len = rules.length;\n  const maxNesting = state.md.options.maxNesting;\n  const cache = state.cache;\n  if (typeof cache[pos] !== \"undefined\") {\n    state.pos = cache[pos];\n    return;\n  }\n  let ok = false;\n  if (state.level < maxNesting) {\n    for (let i = 0; i < len; i++) {\n      // Increment state.level and decrement it later to limit recursion.\n      // It's harmless to do here, because no tokens are created. But ideally,\n      // we'd need a separate private state variable for this purpose.\n      state.level++;\n      ok = rules[i](state, true);\n      state.level--;\n      if (ok) {\n        if (pos >= state.pos) {\n          throw new Error(\"inline rule didn't increment state.pos\");\n        }\n        break;\n      }\n    }\n  } else {\n    // Too much nesting, just skip until the end of the paragraph.\n    // NOTE: this will cause links to behave incorrectly in the following case,\n    //       when an amount of `[` is exactly equal to `maxNesting + 1`:\n    //       [[[[[[[[[[[[[[[[[[[[[foo]()\n    // TODO: remove this workaround when CM standard will allow nested links\n    //       (we can replace it by preventing links from being parsed in\n    //       validation mode)\n    state.pos = state.posMax;\n  }\n  if (!ok) {\n    state.pos++;\n  }\n  cache[pos] = state.pos;\n};\n\n// Generate tokens for input range\n\nParserInline.prototype.tokenize = function(state) {\n  const rules = this.ruler.getRules(\"\");\n  const len = rules.length;\n  const end = state.posMax;\n  const maxNesting = state.md.options.maxNesting;\n  while (state.pos < end) {\n    // Try all possible rules.\n    // On success, rule should:\n    // - update `state.pos`\n    // - update `state.tokens`\n    // - return true\n    const prevPos = state.pos;\n    let ok = false;\n    if (state.level < maxNesting) {\n      for (let i = 0; i < len; i++) {\n        ok = rules[i](state, false);\n        if (ok) {\n          if (prevPos >= state.pos) {\n            throw new Error(\"inline rule didn't increment state.pos\");\n          }\n          break;\n        }\n      }\n    }\n    if (ok) {\n      if (state.pos >= end) {\n        break;\n      }\n      continue;\n    }\n    state.pending += state.src[state.pos++];\n  }\n  if (state.pending) {\n    state.pushPending();\n  }\n};\n\n/**\n * ParserInline.parse(str, md, env, outTokens)\n *\n * Process input string and push inline tokens into `outTokens`\n **/ ParserInline.prototype.parse = function(str, md, env, outTokens) {\n  const state = new this.State(str, md, env, outTokens);\n  this.tokenize(state);\n  const rules = this.ruler2.getRules(\"\");\n  const len = rules.length;\n  for (let i = 0; i < len; i++) {\n    rules[i](state);\n  }\n};\n\nParserInline.prototype.State = StateInline;\n\nfunction reFactory(opts) {\n  const re = {};\n  opts = opts || {};\n  re.src_Any = Any.source;\n  re.src_Cc = Cc.source;\n  re.src_Z = Z.source;\n  re.src_P = P.source;\n  // \\p{\\Z\\P\\Cc\\CF} (white spaces + control + format + punctuation)\n    re.src_ZPCc = [ re.src_Z, re.src_P, re.src_Cc ].join(\"|\");\n  // \\p{\\Z\\Cc} (white spaces + control)\n    re.src_ZCc = [ re.src_Z, re.src_Cc ].join(\"|\");\n  // Experimental. List of chars, completely prohibited in links\n  // because can separate it from other part of text\n    const text_separators = \"[><\\uff5c]\";\n  // All possible word characters (everything without punctuation, spaces & controls)\n  // Defined via punctuation & spaces to save space\n  // Should be something like \\p{\\L\\N\\S\\M} (\\w but without `_`)\n    re.src_pseudo_letter = \"(?:(?!\" + text_separators + \"|\" + re.src_ZPCc + \")\" + re.src_Any + \")\";\n  // The same as abothe but without [0-9]\n  // var src_pseudo_letter_non_d = '(?:(?![0-9]|' + src_ZPCc + ')' + src_Any + ')';\n    re.src_ip4 = \"(?:(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\";\n  // Prohibit any of \"@/[]()\" in user/pass to avoid wrong domain fetch.\n    re.src_auth = \"(?:(?:(?!\" + re.src_ZCc + \"|[@/\\\\[\\\\]()]).)+@)?\";\n  re.src_port = \"(?::(?:6(?:[0-4]\\\\d{3}|5(?:[0-4]\\\\d{2}|5(?:[0-2]\\\\d|3[0-5])))|[1-5]?\\\\d{1,4}))?\";\n  re.src_host_terminator = \"(?=$|\" + text_separators + \"|\" + re.src_ZPCc + \")\" + \"(?!\" + (opts[\"---\"] ? \"-(?!--)|\" : \"-|\") + \"_|:\\\\d|\\\\.-|\\\\.(?!$|\" + re.src_ZPCc + \"))\";\n  re.src_path = \"(?:\" + \"[/?#]\" + \"(?:\" + \"(?!\" + re.src_ZCc + \"|\" + text_separators + \"|[()[\\\\]{}.,\\\"'?!\\\\-;]).|\" + \"\\\\[(?:(?!\" + re.src_ZCc + \"|\\\\]).)*\\\\]|\" + \"\\\\((?:(?!\" + re.src_ZCc + \"|[)]).)*\\\\)|\" + \"\\\\{(?:(?!\" + re.src_ZCc + \"|[}]).)*\\\\}|\" + '\\\\\"(?:(?!' + re.src_ZCc + '|[\"]).)+\\\\\"|' + \"\\\\'(?:(?!\" + re.src_ZCc + \"|[']).)+\\\\'|\" + \n  // allow `I'm_king` if no pair found\n  \"\\\\'(?=\" + re.src_pseudo_letter + \"|[-])|\" + \n  // google has many dots in \"google search\" links (#66, #81).\n  // github has ... in commit range links,\n  // Restrict to\n  // - english\n  // - percent-encoded\n  // - parts of file path\n  // - params separator\n  // until more examples found.\n  \"\\\\.{2,}[a-zA-Z0-9%/&]|\" + \"\\\\.(?!\" + re.src_ZCc + \"|[.]|$)|\" + (opts[\"---\"] ? \"\\\\-(?!--(?:[^-]|$))(?:-*)|\" : \"\\\\-+|\") + \n  // allow `,,,` in paths\n  \",(?!\" + re.src_ZCc + \"|$)|\" + \n  // allow `;` if not followed by space-like char\n  \";(?!\" + re.src_ZCc + \"|$)|\" + \n  // allow `!!!` in paths, but not at the end\n  \"\\\\!+(?!\" + re.src_ZCc + \"|[!]|$)|\" + \"\\\\?(?!\" + re.src_ZCc + \"|[?]|$)\" + \")+\" + \"|\\\\/\" + \")?\";\n  // Allow anything in markdown spec, forbid quote (\") at the first position\n  // because emails enclosed in quotes are far more common\n    re.src_email_name = '[\\\\-;:&=\\\\+\\\\$,\\\\.a-zA-Z0-9_][\\\\-;:&=\\\\+\\\\$,\\\\\"\\\\.a-zA-Z0-9_]*';\n  re.src_xn = \"xn--[a-z0-9\\\\-]{1,59}\";\n  // More to read about domain names\n  // http://serverfault.com/questions/638260/\n    re.src_domain_root = \n  // Allow letters & digits (http://test1)\n  \"(?:\" + re.src_xn + \"|\" + re.src_pseudo_letter + \"{1,63}\" + \")\";\n  re.src_domain = \"(?:\" + re.src_xn + \"|\" + \"(?:\" + re.src_pseudo_letter + \")\" + \"|\" + \"(?:\" + re.src_pseudo_letter + \"(?:-|\" + re.src_pseudo_letter + \"){0,61}\" + re.src_pseudo_letter + \")\" + \")\";\n  re.src_host = \"(?:\" + \n  // Don't need IP check, because digits are already allowed in normal domain names\n  //   src_ip4 +\n  // '|' +\n  \"(?:(?:(?:\" + re.src_domain + \")\\\\.)*\" + re.src_domain /* _root */ + \")\" + \")\";\n  re.tpl_host_fuzzy = \"(?:\" + re.src_ip4 + \"|\" + \"(?:(?:(?:\" + re.src_domain + \")\\\\.)+(?:%TLDS%))\" + \")\";\n  re.tpl_host_no_ip_fuzzy = \"(?:(?:(?:\" + re.src_domain + \")\\\\.)+(?:%TLDS%))\";\n  re.src_host_strict = re.src_host + re.src_host_terminator;\n  re.tpl_host_fuzzy_strict = re.tpl_host_fuzzy + re.src_host_terminator;\n  re.src_host_port_strict = re.src_host + re.src_port + re.src_host_terminator;\n  re.tpl_host_port_fuzzy_strict = re.tpl_host_fuzzy + re.src_port + re.src_host_terminator;\n  re.tpl_host_port_no_ip_fuzzy_strict = re.tpl_host_no_ip_fuzzy + re.src_port + re.src_host_terminator;\n  \n  // Main rules\n  \n  // Rude test fuzzy links by host, for quick deny\n    re.tpl_host_fuzzy_test = \"localhost|www\\\\.|\\\\.\\\\d{1,3}\\\\.|(?:\\\\.(?:%TLDS%)(?:\" + re.src_ZPCc + \"|>|$))\";\n  re.tpl_email_fuzzy = \"(^|\" + text_separators + '|\"|\\\\(|' + re.src_ZCc + \")\" + \"(\" + re.src_email_name + \"@\" + re.tpl_host_fuzzy_strict + \")\";\n  re.tpl_link_fuzzy = \n  // Fuzzy link can't be prepended with .:/\\- and non punctuation.\n  // but can start with > (markdown blockquote)\n  \"(^|(?![.:/\\\\-_@])(?:[$+<=>^`|\\uff5c]|\" + re.src_ZPCc + \"))\" + \"((?![$+<=>^`|\\uff5c])\" + re.tpl_host_port_fuzzy_strict + re.src_path + \")\";\n  re.tpl_link_no_ip_fuzzy = \n  // Fuzzy link can't be prepended with .:/\\- and non punctuation.\n  // but can start with > (markdown blockquote)\n  \"(^|(?![.:/\\\\-_@])(?:[$+<=>^`|\\uff5c]|\" + re.src_ZPCc + \"))\" + \"((?![$+<=>^`|\\uff5c])\" + re.tpl_host_port_no_ip_fuzzy_strict + re.src_path + \")\";\n  return re;\n}\n\n// Helpers\n\n// Merge objects\n\nfunction assign(obj /* from1, from2, from3, ... */) {\n  const sources = Array.prototype.slice.call(arguments, 1);\n  sources.forEach(function(source) {\n    if (!source) {\n      return;\n    }\n    Object.keys(source).forEach(function(key) {\n      obj[key] = source[key];\n    });\n  });\n  return obj;\n}\n\nfunction _class(obj) {\n  return Object.prototype.toString.call(obj);\n}\n\nfunction isString(obj) {\n  return _class(obj) === \"[object String]\";\n}\n\nfunction isObject(obj) {\n  return _class(obj) === \"[object Object]\";\n}\n\nfunction isRegExp(obj) {\n  return _class(obj) === \"[object RegExp]\";\n}\n\nfunction isFunction(obj) {\n  return _class(obj) === \"[object Function]\";\n}\n\nfunction escapeRE(str) {\n  return str.replace(/[.?*+^$[\\]\\\\(){}|-]/g, \"\\\\$&\");\n}\n\n\nconst defaultOptions = {\n  fuzzyLink: true,\n  fuzzyEmail: true,\n  fuzzyIP: false\n};\n\nfunction isOptionsObj(obj) {\n  return Object.keys(obj || {}).reduce(function(acc, k) {\n    /* eslint-disable-next-line no-prototype-builtins */\n    return acc || defaultOptions.hasOwnProperty(k);\n  }, false);\n}\n\nconst defaultSchemas = {\n  \"http:\": {\n    validate: function(text, pos, self) {\n      const tail = text.slice(pos);\n      if (!self.re.http) {\n        // compile lazily, because \"host\"-containing variables can change on tlds update.\n        self.re.http = new RegExp(\"^\\\\/\\\\/\" + self.re.src_auth + self.re.src_host_port_strict + self.re.src_path, \"i\");\n      }\n      if (self.re.http.test(tail)) {\n        return tail.match(self.re.http)[0].length;\n      }\n      return 0;\n    }\n  },\n  \"https:\": \"http:\",\n  \"ftp:\": \"http:\",\n  \"//\": {\n    validate: function(text, pos, self) {\n      const tail = text.slice(pos);\n      if (!self.re.no_http) {\n        // compile lazily, because \"host\"-containing variables can change on tlds update.\n        self.re.no_http = new RegExp(\"^\" + self.re.src_auth + \n        // Don't allow single-level domains, because of false positives like '//test'\n        // with code comments\n        \"(?:localhost|(?:(?:\" + self.re.src_domain + \")\\\\.)+\" + self.re.src_domain_root + \")\" + self.re.src_port + self.re.src_host_terminator + self.re.src_path, \"i\");\n      }\n      if (self.re.no_http.test(tail)) {\n        // should not be `://` & `///`, that protects from errors in protocol name\n        if (pos >= 3 && text[pos - 3] === \":\") {\n          return 0;\n        }\n        if (pos >= 3 && text[pos - 3] === \"/\") {\n          return 0;\n        }\n        return tail.match(self.re.no_http)[0].length;\n      }\n      return 0;\n    }\n  },\n  \"mailto:\": {\n    validate: function(text, pos, self) {\n      const tail = text.slice(pos);\n      if (!self.re.mailto) {\n        self.re.mailto = new RegExp(\"^\" + self.re.src_email_name + \"@\" + self.re.src_host_strict, \"i\");\n      }\n      if (self.re.mailto.test(tail)) {\n        return tail.match(self.re.mailto)[0].length;\n      }\n      return 0;\n    }\n  }\n};\n\n// RE pattern for 2-character tlds (autogenerated by ./support/tlds_2char_gen.js)\n/* eslint-disable-next-line max-len */ const tlds_2ch_src_re = \"a[cdefgilmnoqrstuwxz]|b[abdefghijmnorstvwyz]|c[acdfghiklmnoruvwxyz]|d[ejkmoz]|e[cegrstu]|f[ijkmor]|g[abdefghilmnpqrstuwy]|h[kmnrtu]|i[delmnoqrst]|j[emop]|k[eghimnprwyz]|l[abcikrstuvy]|m[acdeghklmnopqrstuvwxyz]|n[acefgilopruz]|om|p[aefghklmnrstwy]|qa|r[eosuw]|s[abcdeghijklmnortuvxyz]|t[cdfghjklmnortvwz]|u[agksyz]|v[aceginu]|w[fs]|y[et]|z[amw]\";\n\n// DON'T try to make PRs with changes. Extend TLDs with LinkifyIt.tlds() instead\nconst tlds_default = \"biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|\\u0440\\u0444\".split(\"|\");\n\nfunction resetScanCache(self) {\n  self.__index__ = -1;\n  self.__text_cache__ = \"\";\n}\n\nfunction createValidator(re) {\n  return function(text, pos) {\n    const tail = text.slice(pos);\n    if (re.test(tail)) {\n      return tail.match(re)[0].length;\n    }\n    return 0;\n  };\n}\n\nfunction createNormalizer() {\n  return function(match, self) {\n    self.normalize(match);\n  };\n}\n\n// Schemas compiler. Build regexps.\n\nfunction compile(self) {\n  // Load & clone RE patterns.\n  const re = self.re = reFactory(self.__opts__);\n  // Define dynamic patterns\n    const tlds = self.__tlds__.slice();\n  self.onCompile();\n  if (!self.__tlds_replaced__) {\n    tlds.push(tlds_2ch_src_re);\n  }\n  tlds.push(re.src_xn);\n  re.src_tlds = tlds.join(\"|\");\n  function untpl(tpl) {\n    return tpl.replace(\"%TLDS%\", re.src_tlds);\n  }\n  re.email_fuzzy = RegExp(untpl(re.tpl_email_fuzzy), \"i\");\n  re.link_fuzzy = RegExp(untpl(re.tpl_link_fuzzy), \"i\");\n  re.link_no_ip_fuzzy = RegExp(untpl(re.tpl_link_no_ip_fuzzy), \"i\");\n  re.host_fuzzy_test = RegExp(untpl(re.tpl_host_fuzzy_test), \"i\");\n  \n  // Compile each schema\n  \n    const aliases = [];\n  self.__compiled__ = {};\n // Reset compiled data\n    function schemaError(name, val) {\n    throw new Error('(LinkifyIt) Invalid schema \"' + name + '\": ' + val);\n  }\n  Object.keys(self.__schemas__).forEach(function(name) {\n    const val = self.__schemas__[name];\n    // skip disabled methods\n        if (val === null) {\n      return;\n    }\n    const compiled = {\n      validate: null,\n      link: null\n    };\n    self.__compiled__[name] = compiled;\n    if (isObject(val)) {\n      if (isRegExp(val.validate)) {\n        compiled.validate = createValidator(val.validate);\n      } else if (isFunction(val.validate)) {\n        compiled.validate = val.validate;\n      } else {\n        schemaError(name, val);\n      }\n      if (isFunction(val.normalize)) {\n        compiled.normalize = val.normalize;\n      } else if (!val.normalize) {\n        compiled.normalize = createNormalizer();\n      } else {\n        schemaError(name, val);\n      }\n      return;\n    }\n    if (isString(val)) {\n      aliases.push(name);\n      return;\n    }\n    schemaError(name, val);\n  });\n  \n  // Compile postponed aliases\n  \n    aliases.forEach(function(alias) {\n    if (!self.__compiled__[self.__schemas__[alias]]) {\n      // Silently fail on missed schemas to avoid errons on disable.\n      // schemaError(alias, self.__schemas__[alias]);\n      return;\n    }\n    self.__compiled__[alias].validate = self.__compiled__[self.__schemas__[alias]].validate;\n    self.__compiled__[alias].normalize = self.__compiled__[self.__schemas__[alias]].normalize;\n  });\n  \n  // Fake record for guessed links\n  \n    self.__compiled__[\"\"] = {\n    validate: null,\n    normalize: createNormalizer()\n  };\n  \n  // Build schema condition\n  \n    const slist = Object.keys(self.__compiled__).filter(function(name) {\n    // Filter disabled & fake schemas\n    return name.length > 0 && self.__compiled__[name];\n  }).map(escapeRE).join(\"|\");\n  // (?!_) cause 1.5x slowdown\n    self.re.schema_test = RegExp(\"(^|(?!_)(?:[><\\uff5c]|\" + re.src_ZPCc + \"))(\" + slist + \")\", \"i\");\n  self.re.schema_search = RegExp(\"(^|(?!_)(?:[><\\uff5c]|\" + re.src_ZPCc + \"))(\" + slist + \")\", \"ig\");\n  self.re.schema_at_start = RegExp(\"^\" + self.re.schema_search.source, \"i\");\n  self.re.pretest = RegExp(\"(\" + self.re.schema_test.source + \")|(\" + self.re.host_fuzzy_test.source + \")|@\", \"i\");\n  \n  // Cleanup\n  \n    resetScanCache(self);\n}\n\n/**\n * class Match\n *\n * Match result. Single element of array, returned by [[LinkifyIt#match]]\n **/ function Match(self, shift) {\n  const start = self.__index__;\n  const end = self.__last_index__;\n  const text = self.__text_cache__.slice(start, end);\n  /**\n   * Match#schema -> String\n   *\n   * Prefix (protocol) for matched string.\n   **/  this.schema = self.__schema__.toLowerCase();\n  /**\n   * Match#index -> Number\n   *\n   * First position of matched string.\n   **/  this.index = start + shift;\n  /**\n   * Match#lastIndex -> Number\n   *\n   * Next position after matched string.\n   **/  this.lastIndex = end + shift;\n  /**\n   * Match#raw -> String\n   *\n   * Matched string.\n   **/  this.raw = text;\n  /**\n   * Match#text -> String\n   *\n   * Notmalized text of matched string.\n   **/  this.text = text;\n  /**\n   * Match#url -> String\n   *\n   * Normalized url of matched string.\n   **/  this.url = text;\n}\n\nfunction createMatch(self, shift) {\n  const match = new Match(self, shift);\n  self.__compiled__[match.schema].normalize(match, self);\n  return match;\n}\n\n/**\n * class LinkifyIt\n **/\n/**\n * new LinkifyIt(schemas, options)\n * - schemas (Object): Optional. Additional schemas to validate (prefix/validator)\n * - options (Object): { fuzzyLink|fuzzyEmail|fuzzyIP: true|false }\n *\n * Creates new linkifier instance with optional additional schemas.\n * Can be called without `new` keyword for convenience.\n *\n * By default understands:\n *\n * - `http(s)://...` , `ftp://...`, `mailto:...` & `//...` links\n * - \"fuzzy\" links and emails (example.com, foo@bar.com).\n *\n * `schemas` is an object, where each key/value describes protocol/rule:\n *\n * - __key__ - link prefix (usually, protocol name with `:` at the end, `skype:`\n *   for example). `linkify-it` makes shure that prefix is not preceeded with\n *   alphanumeric char and symbols. Only whitespaces and punctuation allowed.\n * - __value__ - rule to check tail after link prefix\n *   - _String_ - just alias to existing rule\n *   - _Object_\n *     - _validate_ - validator function (should return matched length on success),\n *       or `RegExp`.\n *     - _normalize_ - optional function to normalize text & url of matched result\n *       (for example, for @twitter mentions).\n *\n * `options`:\n *\n * - __fuzzyLink__ - recognige URL-s without `http(s):` prefix. Default `true`.\n * - __fuzzyIP__ - allow IPs in fuzzy links above. Can conflict with some texts\n *   like version numbers. Default `false`.\n * - __fuzzyEmail__ - recognize emails without `mailto:` prefix.\n *\n **/ function LinkifyIt(schemas, options) {\n  if (!(this instanceof LinkifyIt)) {\n    return new LinkifyIt(schemas, options);\n  }\n  if (!options) {\n    if (isOptionsObj(schemas)) {\n      options = schemas;\n      schemas = {};\n    }\n  }\n  this.__opts__ = assign({}, defaultOptions, options);\n  // Cache last tested result. Used to skip repeating steps on next `match` call.\n    this.__index__ = -1;\n  this.__last_index__ = -1;\n // Next scan position\n    this.__schema__ = \"\";\n  this.__text_cache__ = \"\";\n  this.__schemas__ = assign({}, defaultSchemas, schemas);\n  this.__compiled__ = {};\n  this.__tlds__ = tlds_default;\n  this.__tlds_replaced__ = false;\n  this.re = {};\n  compile(this);\n}\n\n/** chainable\n * LinkifyIt#add(schema, definition)\n * - schema (String): rule name (fixed pattern prefix)\n * - definition (String|RegExp|Object): schema definition\n *\n * Add new rule definition. See constructor description for details.\n **/ LinkifyIt.prototype.add = function add(schema, definition) {\n  this.__schemas__[schema] = definition;\n  compile(this);\n  return this;\n};\n\n/** chainable\n * LinkifyIt#set(options)\n * - options (Object): { fuzzyLink|fuzzyEmail|fuzzyIP: true|false }\n *\n * Set recognition options for links without schema.\n **/ LinkifyIt.prototype.set = function set(options) {\n  this.__opts__ = assign(this.__opts__, options);\n  return this;\n};\n\n/**\n * LinkifyIt#test(text) -> Boolean\n *\n * Searches linkifiable pattern and returns `true` on success or `false` on fail.\n **/ LinkifyIt.prototype.test = function test(text) {\n  // Reset scan cache\n  this.__text_cache__ = text;\n  this.__index__ = -1;\n  if (!text.length) {\n    return false;\n  }\n  let m, ml, me, len, shift, next, re, tld_pos, at_pos;\n  // try to scan for link with schema - that's the most simple rule\n    if (this.re.schema_test.test(text)) {\n    re = this.re.schema_search;\n    re.lastIndex = 0;\n    while ((m = re.exec(text)) !== null) {\n      len = this.testSchemaAt(text, m[2], re.lastIndex);\n      if (len) {\n        this.__schema__ = m[2];\n        this.__index__ = m.index + m[1].length;\n        this.__last_index__ = m.index + m[0].length + len;\n        break;\n      }\n    }\n  }\n  if (this.__opts__.fuzzyLink && this.__compiled__[\"http:\"]) {\n    // guess schemaless links\n    tld_pos = text.search(this.re.host_fuzzy_test);\n    if (tld_pos >= 0) {\n      // if tld is located after found link - no need to check fuzzy pattern\n      if (this.__index__ < 0 || tld_pos < this.__index__) {\n        if ((ml = text.match(this.__opts__.fuzzyIP ? this.re.link_fuzzy : this.re.link_no_ip_fuzzy)) !== null) {\n          shift = ml.index + ml[1].length;\n          if (this.__index__ < 0 || shift < this.__index__) {\n            this.__schema__ = \"\";\n            this.__index__ = shift;\n            this.__last_index__ = ml.index + ml[0].length;\n          }\n        }\n      }\n    }\n  }\n  if (this.__opts__.fuzzyEmail && this.__compiled__[\"mailto:\"]) {\n    // guess schemaless emails\n    at_pos = text.indexOf(\"@\");\n    if (at_pos >= 0) {\n      // We can't skip this check, because this cases are possible:\n      // 192.168.1.1@gmail.com, my.in@example.com\n      if ((me = text.match(this.re.email_fuzzy)) !== null) {\n        shift = me.index + me[1].length;\n        next = me.index + me[0].length;\n        if (this.__index__ < 0 || shift < this.__index__ || shift === this.__index__ && next > this.__last_index__) {\n          this.__schema__ = \"mailto:\";\n          this.__index__ = shift;\n          this.__last_index__ = next;\n        }\n      }\n    }\n  }\n  return this.__index__ >= 0;\n};\n\n/**\n * LinkifyIt#pretest(text) -> Boolean\n *\n * Very quick check, that can give false positives. Returns true if link MAY BE\n * can exists. Can be used for speed optimization, when you need to check that\n * link NOT exists.\n **/ LinkifyIt.prototype.pretest = function pretest(text) {\n  return this.re.pretest.test(text);\n};\n\n/**\n * LinkifyIt#testSchemaAt(text, name, position) -> Number\n * - text (String): text to scan\n * - name (String): rule (schema) name\n * - position (Number): text offset to check from\n *\n * Similar to [[LinkifyIt#test]] but checks only specific protocol tail exactly\n * at given position. Returns length of found pattern (0 on fail).\n **/ LinkifyIt.prototype.testSchemaAt = function testSchemaAt(text, schema, pos) {\n  // If not supported schema check requested - terminate\n  if (!this.__compiled__[schema.toLowerCase()]) {\n    return 0;\n  }\n  return this.__compiled__[schema.toLowerCase()].validate(text, pos, this);\n};\n\n/**\n * LinkifyIt#match(text) -> Array|null\n *\n * Returns array of found link descriptions or `null` on fail. We strongly\n * recommend to use [[LinkifyIt#test]] first, for best speed.\n *\n * ##### Result match description\n *\n * - __schema__ - link schema, can be empty for fuzzy links, or `//` for\n *   protocol-neutral  links.\n * - __index__ - offset of matched text\n * - __lastIndex__ - index of next char after mathch end\n * - __raw__ - matched text\n * - __text__ - normalized text\n * - __url__ - link, generated from matched text\n **/ LinkifyIt.prototype.match = function match(text) {\n  const result = [];\n  let shift = 0;\n  // Try to take previous element from cache, if .test() called before\n    if (this.__index__ >= 0 && this.__text_cache__ === text) {\n    result.push(createMatch(this, shift));\n    shift = this.__last_index__;\n  }\n  // Cut head if cache was used\n    let tail = shift ? text.slice(shift) : text;\n  // Scan string until end reached\n    while (this.test(tail)) {\n    result.push(createMatch(this, shift));\n    tail = tail.slice(this.__last_index__);\n    shift += this.__last_index__;\n  }\n  if (result.length) {\n    return result;\n  }\n  return null;\n};\n\n/**\n * LinkifyIt#matchAtStart(text) -> Match|null\n *\n * Returns fully-formed (not fuzzy) link if it starts at the beginning\n * of the string, and null otherwise.\n **/ LinkifyIt.prototype.matchAtStart = function matchAtStart(text) {\n  // Reset scan cache\n  this.__text_cache__ = text;\n  this.__index__ = -1;\n  if (!text.length) return null;\n  const m = this.re.schema_at_start.exec(text);\n  if (!m) return null;\n  const len = this.testSchemaAt(text, m[2], m[0].length);\n  if (!len) return null;\n  this.__schema__ = m[2];\n  this.__index__ = m.index + m[1].length;\n  this.__last_index__ = m.index + m[0].length + len;\n  return createMatch(this, 0);\n};\n\n/** chainable\n * LinkifyIt#tlds(list [, keepOld]) -> this\n * - list (Array): list of tlds\n * - keepOld (Boolean): merge with current list if `true` (`false` by default)\n *\n * Load (or merge) new tlds list. Those are user for fuzzy links (without prefix)\n * to avoid false positives. By default this algorythm used:\n *\n * - hostname with any 2-letter root zones are ok.\n * - biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|рф\n *   are ok.\n * - encoded (`xn--...`) root zones are ok.\n *\n * If list is replaced, then exact match for 2-chars root zones will be checked.\n **/ LinkifyIt.prototype.tlds = function tlds(list, keepOld) {\n  list = Array.isArray(list) ? list : [ list ];\n  if (!keepOld) {\n    this.__tlds__ = list.slice();\n    this.__tlds_replaced__ = true;\n    compile(this);\n    return this;\n  }\n  this.__tlds__ = this.__tlds__.concat(list).sort().filter(function(el, idx, arr) {\n    return el !== arr[idx - 1];\n  }).reverse();\n  compile(this);\n  return this;\n};\n\n/**\n * LinkifyIt#normalize(match)\n *\n * Default normalizer (if schema does not define it's own).\n **/ LinkifyIt.prototype.normalize = function normalize(match) {\n  // Do minimal possible changes by default. Need to collect feedback prior\n  // to move forward https://github.com/markdown-it/linkify-it/issues/1\n  if (!match.schema) {\n    match.url = \"http://\" + match.url;\n  }\n  if (match.schema === \"mailto:\" && !/^mailto:/i.test(match.url)) {\n    match.url = \"mailto:\" + match.url;\n  }\n};\n\n/**\n * LinkifyIt#onCompile()\n *\n * Override to modify basic RegExp-s.\n **/ LinkifyIt.prototype.onCompile = function onCompile() {};\n\n/** Highest positive signed 32-bit float value */ const maxInt = 2147483647;\n\n // aka. 0x7FFFFFFF or 2^31-1\n/** Bootstring parameters */ const base = 36;\n\nconst tMin = 1;\n\nconst tMax = 26;\n\nconst skew = 38;\n\nconst damp = 700;\n\nconst initialBias = 72;\n\nconst initialN = 128;\n\n // 0x80\nconst delimiter = \"-\";\n\n // '\\x2D'\n/** Regular expressions */ const regexPunycode = /^xn--/;\n\nconst regexNonASCII = /[^\\0-\\x7F]/;\n\n // Note: U+007F DEL is excluded too.\nconst regexSeparators = /[\\x2E\\u3002\\uFF0E\\uFF61]/g;\n\n // RFC 3490 separators\n/** Error messages */ const errors = {\n  overflow: \"Overflow: input needs wider integers to process\",\n  \"not-basic\": \"Illegal input >= 0x80 (not a basic code point)\",\n  \"invalid-input\": \"Invalid input\"\n};\n\n/** Convenience shortcuts */ const baseMinusTMin = base - tMin;\n\nconst floor = Math.floor;\n\nconst stringFromCharCode = String.fromCharCode;\n\n/*--------------------------------------------------------------------------*/\n/**\n * A generic error utility function.\n * @private\n * @param {String} type The error type.\n * @returns {Error} Throws a `RangeError` with the applicable error message.\n */ function error(type) {\n  throw new RangeError(errors[type]);\n}\n\n/**\n * A generic `Array#map` utility function.\n * @private\n * @param {Array} array The array to iterate over.\n * @param {Function} callback The function that gets called for every array\n * item.\n * @returns {Array} A new array of values returned by the callback function.\n */ function map(array, callback) {\n  const result = [];\n  let length = array.length;\n  while (length--) {\n    result[length] = callback(array[length]);\n  }\n  return result;\n}\n\n/**\n * A simple `Array#map`-like wrapper to work with domain name strings or email\n * addresses.\n * @private\n * @param {String} domain The domain name or email address.\n * @param {Function} callback The function that gets called for every\n * character.\n * @returns {String} A new string of characters returned by the callback\n * function.\n */ function mapDomain(domain, callback) {\n  const parts = domain.split(\"@\");\n  let result = \"\";\n  if (parts.length > 1) {\n    // In email addresses, only the domain name should be punycoded. Leave\n    // the local part (i.e. everything up to `@`) intact.\n    result = parts[0] + \"@\";\n    domain = parts[1];\n  }\n  // Avoid `split(regex)` for IE8 compatibility. See #17.\n    domain = domain.replace(regexSeparators, \".\");\n  const labels = domain.split(\".\");\n  const encoded = map(labels, callback).join(\".\");\n  return result + encoded;\n}\n\n/**\n * Creates an array containing the numeric code points of each Unicode\n * character in the string. While JavaScript uses UCS-2 internally,\n * this function will convert a pair of surrogate halves (each of which\n * UCS-2 exposes as separate characters) into a single code point,\n * matching UTF-16.\n * @see `punycode.ucs2.encode`\n * @see <https://mathiasbynens.be/notes/javascript-encoding>\n * @memberOf punycode.ucs2\n * @name decode\n * @param {String} string The Unicode input string (UCS-2).\n * @returns {Array} The new array of code points.\n */ function ucs2decode(string) {\n  const output = [];\n  let counter = 0;\n  const length = string.length;\n  while (counter < length) {\n    const value = string.charCodeAt(counter++);\n    if (value >= 55296 && value <= 56319 && counter < length) {\n      // It's a high surrogate, and there is a next character.\n      const extra = string.charCodeAt(counter++);\n      if ((extra & 64512) == 56320) {\n        // Low surrogate.\n        output.push(((value & 1023) << 10) + (extra & 1023) + 65536);\n      } else {\n        // It's an unmatched surrogate; only append this code unit, in case the\n        // next code unit is the high surrogate of a surrogate pair.\n        output.push(value);\n        counter--;\n      }\n    } else {\n      output.push(value);\n    }\n  }\n  return output;\n}\n\n/**\n * Creates a string based on an array of numeric code points.\n * @see `punycode.ucs2.decode`\n * @memberOf punycode.ucs2\n * @name encode\n * @param {Array} codePoints The array of numeric code points.\n * @returns {String} The new Unicode string (UCS-2).\n */ const ucs2encode = codePoints => String.fromCodePoint(...codePoints);\n\n/**\n * Converts a basic code point into a digit/integer.\n * @see `digitToBasic()`\n * @private\n * @param {Number} codePoint The basic numeric code point value.\n * @returns {Number} The numeric value of a basic code point (for use in\n * representing integers) in the range `0` to `base - 1`, or `base` if\n * the code point does not represent a value.\n */ const basicToDigit = function(codePoint) {\n  if (codePoint >= 48 && codePoint < 58) {\n    return 26 + (codePoint - 48);\n  }\n  if (codePoint >= 65 && codePoint < 91) {\n    return codePoint - 65;\n  }\n  if (codePoint >= 97 && codePoint < 123) {\n    return codePoint - 97;\n  }\n  return base;\n};\n\n/**\n * Converts a digit/integer into a basic code point.\n * @see `basicToDigit()`\n * @private\n * @param {Number} digit The numeric value of a basic code point.\n * @returns {Number} The basic code point whose value (when used for\n * representing integers) is `digit`, which needs to be in the range\n * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is\n * used; else, the lowercase form is used. The behavior is undefined\n * if `flag` is non-zero and `digit` has no uppercase form.\n */ const digitToBasic = function(digit, flag) {\n  //  0..25 map to ASCII a..z or A..Z\n  // 26..35 map to ASCII 0..9\n  return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);\n};\n\n/**\n * Bias adaptation function as per section 3.4 of RFC 3492.\n * https://tools.ietf.org/html/rfc3492#section-3.4\n * @private\n */ const adapt = function(delta, numPoints, firstTime) {\n  let k = 0;\n  delta = firstTime ? floor(delta / damp) : delta >> 1;\n  delta += floor(delta / numPoints);\n  for (;delta > baseMinusTMin * tMax >> 1; k += base) {\n    delta = floor(delta / baseMinusTMin);\n  }\n  return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));\n};\n\n/**\n * Converts a Punycode string of ASCII-only symbols to a string of Unicode\n * symbols.\n * @memberOf punycode\n * @param {String} input The Punycode string of ASCII-only symbols.\n * @returns {String} The resulting string of Unicode symbols.\n */ const decode = function(input) {\n  // Don't use UCS-2.\n  const output = [];\n  const inputLength = input.length;\n  let i = 0;\n  let n = initialN;\n  let bias = initialBias;\n  // Handle the basic code points: let `basic` be the number of input code\n  // points before the last delimiter, or `0` if there is none, then copy\n  // the first basic code points to the output.\n    let basic = input.lastIndexOf(delimiter);\n  if (basic < 0) {\n    basic = 0;\n  }\n  for (let j = 0; j < basic; ++j) {\n    // if it's not a basic code point\n    if (input.charCodeAt(j) >= 128) {\n      error(\"not-basic\");\n    }\n    output.push(input.charCodeAt(j));\n  }\n  // Main decoding loop: start just after the last delimiter if any basic code\n  // points were copied; start at the beginning otherwise.\n    for (let index = basic > 0 ? basic + 1 : 0; index < inputLength; ) {\n    // `index` is the index of the next character to be consumed.\n    // Decode a generalized variable-length integer into `delta`,\n    // which gets added to `i`. The overflow checking is easier\n    // if we increase `i` as we go, then subtract off its starting\n    // value at the end to obtain `delta`.\n    const oldi = i;\n    for (let w = 1, k = base; ;k += base) {\n      if (index >= inputLength) {\n        error(\"invalid-input\");\n      }\n      const digit = basicToDigit(input.charCodeAt(index++));\n      if (digit >= base) {\n        error(\"invalid-input\");\n      }\n      if (digit > floor((maxInt - i) / w)) {\n        error(\"overflow\");\n      }\n      i += digit * w;\n      const t = k <= bias ? tMin : k >= bias + tMax ? tMax : k - bias;\n      if (digit < t) {\n        break;\n      }\n      const baseMinusT = base - t;\n      if (w > floor(maxInt / baseMinusT)) {\n        error(\"overflow\");\n      }\n      w *= baseMinusT;\n    }\n    const out = output.length + 1;\n    bias = adapt(i - oldi, out, oldi == 0);\n    // `i` was supposed to wrap around from `out` to `0`,\n    // incrementing `n` each time, so we'll fix that now:\n        if (floor(i / out) > maxInt - n) {\n      error(\"overflow\");\n    }\n    n += floor(i / out);\n    i %= out;\n    // Insert `n` at position `i` of the output.\n        output.splice(i++, 0, n);\n  }\n  return String.fromCodePoint(...output);\n};\n\n/**\n * Converts a string of Unicode symbols (e.g. a domain name label) to a\n * Punycode string of ASCII-only symbols.\n * @memberOf punycode\n * @param {String} input The string of Unicode symbols.\n * @returns {String} The resulting Punycode string of ASCII-only symbols.\n */ const encode = function(input) {\n  const output = [];\n  // Convert the input in UCS-2 to an array of Unicode code points.\n    input = ucs2decode(input);\n  // Cache the length.\n    const inputLength = input.length;\n  // Initialize the state.\n    let n = initialN;\n  let delta = 0;\n  let bias = initialBias;\n  // Handle the basic code points.\n    for (const currentValue of input) {\n    if (currentValue < 128) {\n      output.push(stringFromCharCode(currentValue));\n    }\n  }\n  const basicLength = output.length;\n  let handledCPCount = basicLength;\n  // `handledCPCount` is the number of code points that have been handled;\n  // `basicLength` is the number of basic code points.\n  // Finish the basic string with a delimiter unless it's empty.\n    if (basicLength) {\n    output.push(delimiter);\n  }\n  // Main encoding loop:\n    while (handledCPCount < inputLength) {\n    // All non-basic code points < n have been handled already. Find the next\n    // larger one:\n    let m = maxInt;\n    for (const currentValue of input) {\n      if (currentValue >= n && currentValue < m) {\n        m = currentValue;\n      }\n    }\n    // Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,\n    // but guard against overflow.\n        const handledCPCountPlusOne = handledCPCount + 1;\n    if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {\n      error(\"overflow\");\n    }\n    delta += (m - n) * handledCPCountPlusOne;\n    n = m;\n    for (const currentValue of input) {\n      if (currentValue < n && ++delta > maxInt) {\n        error(\"overflow\");\n      }\n      if (currentValue === n) {\n        // Represent delta as a generalized variable-length integer.\n        let q = delta;\n        for (let k = base; ;k += base) {\n          const t = k <= bias ? tMin : k >= bias + tMax ? tMax : k - bias;\n          if (q < t) {\n            break;\n          }\n          const qMinusT = q - t;\n          const baseMinusT = base - t;\n          output.push(stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)));\n          q = floor(qMinusT / baseMinusT);\n        }\n        output.push(stringFromCharCode(digitToBasic(q, 0)));\n        bias = adapt(delta, handledCPCountPlusOne, handledCPCount === basicLength);\n        delta = 0;\n        ++handledCPCount;\n      }\n    }\n    ++delta;\n    ++n;\n  }\n  return output.join(\"\");\n};\n\n/**\n * Converts a Punycode string representing a domain name or an email address\n * to Unicode. Only the Punycoded parts of the input will be converted, i.e.\n * it doesn't matter if you call it on a string that has already been\n * converted to Unicode.\n * @memberOf punycode\n * @param {String} input The Punycoded domain name or email address to\n * convert to Unicode.\n * @returns {String} The Unicode representation of the given Punycode\n * string.\n */ const toUnicode = function(input) {\n  return mapDomain(input, function(string) {\n    return regexPunycode.test(string) ? decode(string.slice(4).toLowerCase()) : string;\n  });\n};\n\n/**\n * Converts a Unicode string representing a domain name or an email address to\n * Punycode. Only the non-ASCII parts of the domain name will be converted,\n * i.e. it doesn't matter if you call it with a domain that's already in\n * ASCII.\n * @memberOf punycode\n * @param {String} input The domain name or email address to convert, as a\n * Unicode string.\n * @returns {String} The Punycode representation of the given domain name or\n * email address.\n */ const toASCII = function(input) {\n  return mapDomain(input, function(string) {\n    return regexNonASCII.test(string) ? \"xn--\" + encode(string) : string;\n  });\n};\n\n/*--------------------------------------------------------------------------*/\n/** Define the public API */ const punycode = {\n  /**\n   * A string representing the current Punycode.js version number.\n   * @memberOf punycode\n   * @type String\n   */\n  version: \"2.3.1\",\n  /**\n   * An object of methods to convert from JavaScript's internal character\n   * representation (UCS-2) to Unicode code points, and back.\n   * @see <https://mathiasbynens.be/notes/javascript-encoding>\n   * @memberOf punycode\n   * @type Object\n   */\n  ucs2: {\n    decode: ucs2decode,\n    encode: ucs2encode\n  },\n  decode: decode,\n  encode: encode,\n  toASCII: toASCII,\n  toUnicode: toUnicode\n};\n\n// markdown-it default options\nvar cfg_default = {\n  options: {\n    // Enable HTML tags in source\n    html: false,\n    // Use '/' to close single tags (<br />)\n    xhtmlOut: false,\n    // Convert '\\n' in paragraphs into <br>\n    breaks: false,\n    // CSS language prefix for fenced blocks\n    langPrefix: \"language-\",\n    // autoconvert URL-like texts to links\n    linkify: false,\n    // Enable some language-neutral replacements + quotes beautification\n    typographer: false,\n    // Double + single quotes replacement pairs, when typographer enabled,\n    // and smartquotes on. Could be either a String or an Array.\n    // For example, you can use '«»„“' for Russian, '„“‚‘' for German,\n    // and ['«\\xA0', '\\xA0»', '‹\\xA0', '\\xA0›'] for French (including nbsp).\n    quotes: \"\\u201c\\u201d\\u2018\\u2019\",\n    /* “”‘’ */\n    // Highlighter function. Should return escaped HTML,\n    // or '' if the source string is not changed and should be escaped externaly.\n    // If result starts with <pre... internal wrapper is skipped.\n    // function (/*str, lang*/) { return ''; }\n    highlight: null,\n    // Internal protection, recursion limit\n    maxNesting: 100\n  },\n  components: {\n    core: {},\n    block: {},\n    inline: {}\n  }\n};\n\n// \"Zero\" preset, with nothing enabled. Useful for manual configuring of simple\n// modes. For example, to parse bold/italic only.\nvar cfg_zero = {\n  options: {\n    // Enable HTML tags in source\n    html: false,\n    // Use '/' to close single tags (<br />)\n    xhtmlOut: false,\n    // Convert '\\n' in paragraphs into <br>\n    breaks: false,\n    // CSS language prefix for fenced blocks\n    langPrefix: \"language-\",\n    // autoconvert URL-like texts to links\n    linkify: false,\n    // Enable some language-neutral replacements + quotes beautification\n    typographer: false,\n    // Double + single quotes replacement pairs, when typographer enabled,\n    // and smartquotes on. Could be either a String or an Array.\n    // For example, you can use '«»„“' for Russian, '„“‚‘' for German,\n    // and ['«\\xA0', '\\xA0»', '‹\\xA0', '\\xA0›'] for French (including nbsp).\n    quotes: \"\\u201c\\u201d\\u2018\\u2019\",\n    /* “”‘’ */\n    // Highlighter function. Should return escaped HTML,\n    // or '' if the source string is not changed and should be escaped externaly.\n    // If result starts with <pre... internal wrapper is skipped.\n    // function (/*str, lang*/) { return ''; }\n    highlight: null,\n    // Internal protection, recursion limit\n    maxNesting: 20\n  },\n  components: {\n    core: {\n      rules: [ \"normalize\", \"block\", \"inline\", \"text_join\" ]\n    },\n    block: {\n      rules: [ \"paragraph\" ]\n    },\n    inline: {\n      rules: [ \"text\" ],\n      rules2: [ \"balance_pairs\", \"fragments_join\" ]\n    }\n  }\n};\n\n// Commonmark default options\nvar cfg_commonmark = {\n  options: {\n    // Enable HTML tags in source\n    html: true,\n    // Use '/' to close single tags (<br />)\n    xhtmlOut: true,\n    // Convert '\\n' in paragraphs into <br>\n    breaks: false,\n    // CSS language prefix for fenced blocks\n    langPrefix: \"language-\",\n    // autoconvert URL-like texts to links\n    linkify: false,\n    // Enable some language-neutral replacements + quotes beautification\n    typographer: false,\n    // Double + single quotes replacement pairs, when typographer enabled,\n    // and smartquotes on. Could be either a String or an Array.\n    // For example, you can use '«»„“' for Russian, '„“‚‘' for German,\n    // and ['«\\xA0', '\\xA0»', '‹\\xA0', '\\xA0›'] for French (including nbsp).\n    quotes: \"\\u201c\\u201d\\u2018\\u2019\",\n    /* “”‘’ */\n    // Highlighter function. Should return escaped HTML,\n    // or '' if the source string is not changed and should be escaped externaly.\n    // If result starts with <pre... internal wrapper is skipped.\n    // function (/*str, lang*/) { return ''; }\n    highlight: null,\n    // Internal protection, recursion limit\n    maxNesting: 20\n  },\n  components: {\n    core: {\n      rules: [ \"normalize\", \"block\", \"inline\", \"text_join\" ]\n    },\n    block: {\n      rules: [ \"blockquote\", \"code\", \"fence\", \"heading\", \"hr\", \"html_block\", \"lheading\", \"list\", \"reference\", \"paragraph\" ]\n    },\n    inline: {\n      rules: [ \"autolink\", \"backticks\", \"emphasis\", \"entity\", \"escape\", \"html_inline\", \"image\", \"link\", \"newline\", \"text\" ],\n      rules2: [ \"balance_pairs\", \"emphasis\", \"fragments_join\" ]\n    }\n  }\n};\n\n// Main parser class\nconst config = {\n  default: cfg_default,\n  zero: cfg_zero,\n  commonmark: cfg_commonmark\n};\n\n// This validator can prohibit more than really needed to prevent XSS. It's a\n// tradeoff to keep code simple and to be secure by default.\n\n// If you need different setup - override validator method as you wish. Or\n// replace it with dummy function and use external sanitizer.\n\nconst BAD_PROTO_RE = /^(vbscript|javascript|file|data):/;\n\nconst GOOD_DATA_RE = /^data:image\\/(gif|png|jpeg|webp);/;\n\nfunction validateLink(url) {\n  // url should be normalized at this point, and existing entities are decoded\n  const str = url.trim().toLowerCase();\n  return BAD_PROTO_RE.test(str) ? GOOD_DATA_RE.test(str) : true;\n}\n\nconst RECODE_HOSTNAME_FOR = [ \"http:\", \"https:\", \"mailto:\" ];\n\nfunction normalizeLink(url) {\n  const parsed = urlParse(url, true);\n  if (parsed.hostname) {\n    // Encode hostnames in urls like:\n    // `http://host/`, `https://host/`, `mailto:user@host`, `//host/`\n    // We don't encode unknown schemas, because it's likely that we encode\n    // something we shouldn't (e.g. `skype:name` treated as `skype:host`)\n    if (!parsed.protocol || RECODE_HOSTNAME_FOR.indexOf(parsed.protocol) >= 0) {\n      try {\n        parsed.hostname = punycode.toASCII(parsed.hostname);\n      } catch (er) {}\n    }\n  }\n  return encode$1(format(parsed));\n}\n\nfunction normalizeLinkText(url) {\n  const parsed = urlParse(url, true);\n  if (parsed.hostname) {\n    // Encode hostnames in urls like:\n    // `http://host/`, `https://host/`, `mailto:user@host`, `//host/`\n    // We don't encode unknown schemas, because it's likely that we encode\n    // something we shouldn't (e.g. `skype:name` treated as `skype:host`)\n    if (!parsed.protocol || RECODE_HOSTNAME_FOR.indexOf(parsed.protocol) >= 0) {\n      try {\n        parsed.hostname = punycode.toUnicode(parsed.hostname);\n      } catch (er) {}\n    }\n  }\n  // add '%' to exclude list because of https://github.com/markdown-it/markdown-it/issues/720\n    return decode$1(format(parsed), decode$1.defaultChars + \"%\");\n}\n\n/**\n * class MarkdownIt\n *\n * Main parser/renderer class.\n *\n * ##### Usage\n *\n * ```javascript\n * // node.js, \"classic\" way:\n * var MarkdownIt = require('markdown-it'),\n *     md = new MarkdownIt();\n * var result = md.render('# markdown-it rulezz!');\n *\n * // node.js, the same, but with sugar:\n * var md = require('markdown-it')();\n * var result = md.render('# markdown-it rulezz!');\n *\n * // browser without AMD, added to \"window\" on script load\n * // Note, there are no dash.\n * var md = window.markdownit();\n * var result = md.render('# markdown-it rulezz!');\n * ```\n *\n * Single line rendering, without paragraph wrap:\n *\n * ```javascript\n * var md = require('markdown-it')();\n * var result = md.renderInline('__markdown-it__ rulezz!');\n * ```\n **/\n/**\n * new MarkdownIt([presetName, options])\n * - presetName (String): optional, `commonmark` / `zero`\n * - options (Object)\n *\n * Creates parser instanse with given config. Can be called without `new`.\n *\n * ##### presetName\n *\n * MarkdownIt provides named presets as a convenience to quickly\n * enable/disable active syntax rules and options for common use cases.\n *\n * - [\"commonmark\"](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/commonmark.mjs) -\n *   configures parser to strict [CommonMark](http://commonmark.org/) mode.\n * - [default](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/default.mjs) -\n *   similar to GFM, used when no preset name given. Enables all available rules,\n *   but still without html, typographer & autolinker.\n * - [\"zero\"](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/zero.mjs) -\n *   all rules disabled. Useful to quickly setup your config via `.enable()`.\n *   For example, when you need only `bold` and `italic` markup and nothing else.\n *\n * ##### options:\n *\n * - __html__ - `false`. Set `true` to enable HTML tags in source. Be careful!\n *   That's not safe! You may need external sanitizer to protect output from XSS.\n *   It's better to extend features via plugins, instead of enabling HTML.\n * - __xhtmlOut__ - `false`. Set `true` to add '/' when closing single tags\n *   (`<br />`). This is needed only for full CommonMark compatibility. In real\n *   world you will need HTML output.\n * - __breaks__ - `false`. Set `true` to convert `\\n` in paragraphs into `<br>`.\n * - __langPrefix__ - `language-`. CSS language class prefix for fenced blocks.\n *   Can be useful for external highlighters.\n * - __linkify__ - `false`. Set `true` to autoconvert URL-like text to links.\n * - __typographer__  - `false`. Set `true` to enable [some language-neutral\n *   replacement](https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/replacements.mjs) +\n *   quotes beautification (smartquotes).\n * - __quotes__ - `“”‘’`, String or Array. Double + single quotes replacement\n *   pairs, when typographer enabled and smartquotes on. For example, you can\n *   use `'«»„“'` for Russian, `'„“‚‘'` for German, and\n *   `['«\\xA0', '\\xA0»', '‹\\xA0', '\\xA0›']` for French (including nbsp).\n * - __highlight__ - `null`. Highlighter function for fenced code blocks.\n *   Highlighter `function (str, lang)` should return escaped HTML. It can also\n *   return empty string if the source was not changed and should be escaped\n *   externaly. If result starts with <pre... internal wrapper is skipped.\n *\n * ##### Example\n *\n * ```javascript\n * // commonmark mode\n * var md = require('markdown-it')('commonmark');\n *\n * // default mode\n * var md = require('markdown-it')();\n *\n * // enable everything\n * var md = require('markdown-it')({\n *   html: true,\n *   linkify: true,\n *   typographer: true\n * });\n * ```\n *\n * ##### Syntax highlighting\n *\n * ```js\n * var hljs = require('highlight.js') // https://highlightjs.org/\n *\n * var md = require('markdown-it')({\n *   highlight: function (str, lang) {\n *     if (lang && hljs.getLanguage(lang)) {\n *       try {\n *         return hljs.highlight(str, { language: lang, ignoreIllegals: true }).value;\n *       } catch (__) {}\n *     }\n *\n *     return ''; // use external default escaping\n *   }\n * });\n * ```\n *\n * Or with full wrapper override (if you need assign class to `<pre>` or `<code>`):\n *\n * ```javascript\n * var hljs = require('highlight.js') // https://highlightjs.org/\n *\n * // Actual default values\n * var md = require('markdown-it')({\n *   highlight: function (str, lang) {\n *     if (lang && hljs.getLanguage(lang)) {\n *       try {\n *         return '<pre><code class=\"hljs\">' +\n *                hljs.highlight(str, { language: lang, ignoreIllegals: true }).value +\n *                '</code></pre>';\n *       } catch (__) {}\n *     }\n *\n *     return '<pre><code class=\"hljs\">' + md.utils.escapeHtml(str) + '</code></pre>';\n *   }\n * });\n * ```\n *\n **/ function MarkdownIt(presetName, options) {\n  if (!(this instanceof MarkdownIt)) {\n    return new MarkdownIt(presetName, options);\n  }\n  if (!options) {\n    if (!isString$1(presetName)) {\n      options = presetName || {};\n      presetName = \"default\";\n    }\n  }\n  /**\n   * MarkdownIt#inline -> ParserInline\n   *\n   * Instance of [[ParserInline]]. You may need it to add new rules when\n   * writing plugins. For simple rules control use [[MarkdownIt.disable]] and\n   * [[MarkdownIt.enable]].\n   **/  this.inline = new ParserInline;\n  /**\n   * MarkdownIt#block -> ParserBlock\n   *\n   * Instance of [[ParserBlock]]. You may need it to add new rules when\n   * writing plugins. For simple rules control use [[MarkdownIt.disable]] and\n   * [[MarkdownIt.enable]].\n   **/  this.block = new ParserBlock;\n  /**\n   * MarkdownIt#core -> Core\n   *\n   * Instance of [[Core]] chain executor. You may need it to add new rules when\n   * writing plugins. For simple rules control use [[MarkdownIt.disable]] and\n   * [[MarkdownIt.enable]].\n   **/  this.core = new Core;\n  /**\n   * MarkdownIt#renderer -> Renderer\n   *\n   * Instance of [[Renderer]]. Use it to modify output look. Or to add rendering\n   * rules for new token types, generated by plugins.\n   *\n   * ##### Example\n   *\n   * ```javascript\n   * var md = require('markdown-it')();\n   *\n   * function myToken(tokens, idx, options, env, self) {\n   *   //...\n   *   return result;\n   * };\n   *\n   * md.renderer.rules['my_token'] = myToken\n   * ```\n   *\n   * See [[Renderer]] docs and [source code](https://github.com/markdown-it/markdown-it/blob/master/lib/renderer.mjs).\n   **/  this.renderer = new Renderer;\n  /**\n   * MarkdownIt#linkify -> LinkifyIt\n   *\n   * [linkify-it](https://github.com/markdown-it/linkify-it) instance.\n   * Used by [linkify](https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/linkify.mjs)\n   * rule.\n   **/  this.linkify = new LinkifyIt;\n  /**\n   * MarkdownIt#validateLink(url) -> Boolean\n   *\n   * Link validation function. CommonMark allows too much in links. By default\n   * we disable `javascript:`, `vbscript:`, `file:` schemas, and almost all `data:...` schemas\n   * except some embedded image types.\n   *\n   * You can change this behaviour:\n   *\n   * ```javascript\n   * var md = require('markdown-it')();\n   * // enable everything\n   * md.validateLink = function () { return true; }\n   * ```\n   **/  this.validateLink = validateLink;\n  /**\n   * MarkdownIt#normalizeLink(url) -> String\n   *\n   * Function used to encode link url to a machine-readable format,\n   * which includes url-encoding, punycode, etc.\n   **/  this.normalizeLink = normalizeLink;\n  /**\n   * MarkdownIt#normalizeLinkText(url) -> String\n   *\n   * Function used to decode link url to a human-readable format`\n   **/  this.normalizeLinkText = normalizeLinkText;\n  // Expose utils & helpers for easy acces from plugins\n  /**\n   * MarkdownIt#utils -> utils\n   *\n   * Assorted utility functions, useful to write plugins. See details\n   * [here](https://github.com/markdown-it/markdown-it/blob/master/lib/common/utils.mjs).\n   **/  this.utils = utils;\n  /**\n   * MarkdownIt#helpers -> helpers\n   *\n   * Link components parser functions, useful to write plugins. See details\n   * [here](https://github.com/markdown-it/markdown-it/blob/master/lib/helpers).\n   **/  this.helpers = assign$1({}, helpers);\n  this.options = {};\n  this.configure(presetName);\n  if (options) {\n    this.set(options);\n  }\n}\n\n/** chainable\n * MarkdownIt.set(options)\n *\n * Set parser options (in the same format as in constructor). Probably, you\n * will never need it, but you can change options after constructor call.\n *\n * ##### Example\n *\n * ```javascript\n * var md = require('markdown-it')()\n *             .set({ html: true, breaks: true })\n *             .set({ typographer, true });\n * ```\n *\n * __Note:__ To achieve the best possible performance, don't modify a\n * `markdown-it` instance options on the fly. If you need multiple configurations\n * it's best to create multiple instances and initialize each with separate\n * config.\n **/ MarkdownIt.prototype.set = function(options) {\n  assign$1(this.options, options);\n  return this;\n};\n\n/** chainable, internal\n * MarkdownIt.configure(presets)\n *\n * Batch load of all options and compenent settings. This is internal method,\n * and you probably will not need it. But if you will - see available presets\n * and data structure [here](https://github.com/markdown-it/markdown-it/tree/master/lib/presets)\n *\n * We strongly recommend to use presets instead of direct config loads. That\n * will give better compatibility with next versions.\n **/ MarkdownIt.prototype.configure = function(presets) {\n  const self = this;\n  if (isString$1(presets)) {\n    const presetName = presets;\n    presets = config[presetName];\n    if (!presets) {\n      throw new Error('Wrong `markdown-it` preset \"' + presetName + '\", check name');\n    }\n  }\n  if (!presets) {\n    throw new Error(\"Wrong `markdown-it` preset, can't be empty\");\n  }\n  if (presets.options) {\n    self.set(presets.options);\n  }\n  if (presets.components) {\n    Object.keys(presets.components).forEach(function(name) {\n      if (presets.components[name].rules) {\n        self[name].ruler.enableOnly(presets.components[name].rules);\n      }\n      if (presets.components[name].rules2) {\n        self[name].ruler2.enableOnly(presets.components[name].rules2);\n      }\n    });\n  }\n  return this;\n};\n\n/** chainable\n * MarkdownIt.enable(list, ignoreInvalid)\n * - list (String|Array): rule name or list of rule names to enable\n * - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found.\n *\n * Enable list or rules. It will automatically find appropriate components,\n * containing rules with given names. If rule not found, and `ignoreInvalid`\n * not set - throws exception.\n *\n * ##### Example\n *\n * ```javascript\n * var md = require('markdown-it')()\n *             .enable(['sub', 'sup'])\n *             .disable('smartquotes');\n * ```\n **/ MarkdownIt.prototype.enable = function(list, ignoreInvalid) {\n  let result = [];\n  if (!Array.isArray(list)) {\n    list = [ list ];\n  }\n  [ \"core\", \"block\", \"inline\" ].forEach(function(chain) {\n    result = result.concat(this[chain].ruler.enable(list, true));\n  }, this);\n  result = result.concat(this.inline.ruler2.enable(list, true));\n  const missed = list.filter(function(name) {\n    return result.indexOf(name) < 0;\n  });\n  if (missed.length && !ignoreInvalid) {\n    throw new Error(\"MarkdownIt. Failed to enable unknown rule(s): \" + missed);\n  }\n  return this;\n};\n\n/** chainable\n * MarkdownIt.disable(list, ignoreInvalid)\n * - list (String|Array): rule name or list of rule names to disable.\n * - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found.\n *\n * The same as [[MarkdownIt.enable]], but turn specified rules off.\n **/ MarkdownIt.prototype.disable = function(list, ignoreInvalid) {\n  let result = [];\n  if (!Array.isArray(list)) {\n    list = [ list ];\n  }\n  [ \"core\", \"block\", \"inline\" ].forEach(function(chain) {\n    result = result.concat(this[chain].ruler.disable(list, true));\n  }, this);\n  result = result.concat(this.inline.ruler2.disable(list, true));\n  const missed = list.filter(function(name) {\n    return result.indexOf(name) < 0;\n  });\n  if (missed.length && !ignoreInvalid) {\n    throw new Error(\"MarkdownIt. Failed to disable unknown rule(s): \" + missed);\n  }\n  return this;\n};\n\n/** chainable\n * MarkdownIt.use(plugin, params)\n *\n * Load specified plugin with given params into current parser instance.\n * It's just a sugar to call `plugin(md, params)` with curring.\n *\n * ##### Example\n *\n * ```javascript\n * var iterator = require('markdown-it-for-inline');\n * var md = require('markdown-it')()\n *             .use(iterator, 'foo_replace', 'text', function (tokens, idx) {\n *               tokens[idx].content = tokens[idx].content.replace(/foo/g, 'bar');\n *             });\n * ```\n **/ MarkdownIt.prototype.use = function(plugin /*, params, ... */) {\n  const args = [ this ].concat(Array.prototype.slice.call(arguments, 1));\n  plugin.apply(plugin, args);\n  return this;\n};\n\n/** internal\n * MarkdownIt.parse(src, env) -> Array\n * - src (String): source string\n * - env (Object): environment sandbox\n *\n * Parse input string and return list of block tokens (special token type\n * \"inline\" will contain list of inline tokens). You should not call this\n * method directly, until you write custom renderer (for example, to produce\n * AST).\n *\n * `env` is used to pass data between \"distributed\" rules and return additional\n * metadata like reference info, needed for the renderer. It also can be used to\n * inject data in specific cases. Usually, you will be ok to pass `{}`,\n * and then pass updated object to renderer.\n **/ MarkdownIt.prototype.parse = function(src, env) {\n  if (typeof src !== \"string\") {\n    throw new Error(\"Input data should be a String\");\n  }\n  const state = new this.core.State(src, this, env);\n  this.core.process(state);\n  return state.tokens;\n};\n\n/**\n * MarkdownIt.render(src [, env]) -> String\n * - src (String): source string\n * - env (Object): environment sandbox\n *\n * Render markdown string into html. It does all magic for you :).\n *\n * `env` can be used to inject additional metadata (`{}` by default).\n * But you will not need it with high probability. See also comment\n * in [[MarkdownIt.parse]].\n **/ MarkdownIt.prototype.render = function(src, env) {\n  env = env || {};\n  return this.renderer.render(this.parse(src, env), this.options, env);\n};\n\n/** internal\n * MarkdownIt.parseInline(src, env) -> Array\n * - src (String): source string\n * - env (Object): environment sandbox\n *\n * The same as [[MarkdownIt.parse]] but skip all block rules. It returns the\n * block tokens list with the single `inline` element, containing parsed inline\n * tokens in `children` property. Also updates `env` object.\n **/ MarkdownIt.prototype.parseInline = function(src, env) {\n  const state = new this.core.State(src, this, env);\n  state.inlineMode = true;\n  this.core.process(state);\n  return state.tokens;\n};\n\n/**\n * MarkdownIt.renderInline(src [, env]) -> String\n * - src (String): source string\n * - env (Object): environment sandbox\n *\n * Similar to [[MarkdownIt.render]] but for single paragraph content. Result\n * will NOT be wrapped into `<p>` tags.\n **/ MarkdownIt.prototype.renderInline = function(src, env) {\n  env = env || {};\n  return this.renderer.render(this.parseInline(src, env), this.options, env);\n};\n\nexport { MarkdownIt as default, config };\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/markdown-it/src/token.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport const tokens = [\n  \"blockquote_open\",\n  \"paragraph_open\",\n  \"inline\",\n  \"text\",\n  \"softbreak\",\n  \"paragraph_close\",\n  \"blockquote_close\",\n  \"fence\",\n  \"code_inline\",\n  \"hr\",\n  \"emoji\",\n  \"em_open\",\n  \"em_close\",\n  \"footnote_ref\",\n  \"heading_open\",\n  \"heading_close\",\n  \"image\",\n  \"link_open\",\n  \"link_close\",\n  \"bullet_list_open\",\n  \"list_item_open\",\n  \"list_item_close\",\n  \"bullet_list_close\",\n  \"ordered_list_open\",\n  \"ordered_list_close\",\n  \"s_open\",\n  \"s_close\",\n  \"strong_open\",\n  \"strong_close\",\n  \"table_open\",\n  \"thead_open\",\n  \"tr_open\",\n  \"th_open\",\n  \"th_close\",\n  \"tr_close\",\n  \"thead_close\",\n  \"tbody_open\",\n  \"td_open\",\n  \"td_close\",\n  \"tbody_close\",\n  \"table_close\",\n  \"html_inline\",\n  \"code_block\",\n  \"hardbreak\",\n  \"sub_open\",\n  \"sub_close\",\n  \"sup_open\",\n  \"sup_close\",\n  \"footnote_block_open\",\n  \"footnote_open\",\n  \"footnote_anchor\",\n  \"footnote_close\",\n  \"footnote_block_close\"\n]"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/markdown-it/src/types.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n// import LinkifyIt = require(\"linkify-it\");\n// import mdurl = require(\"mdurl\");\n// import ucmicro = require(\"uc.micro\");\n\ntype Any = string | number | boolean | null | undefined | object;\n\n// lib/token.mjs\n\ninterface Token {\n  /**\n   * Type of the token, e.g. \"paragraph_open\"\n   */\n  type: string;\n\n  /**\n   * HTML tag name, e.g. \"p\"\n   */\n  tag: string;\n\n  /**\n   * HTML attributes. Format: `[ [ name1, value1 ], [ name2, value2 ] ]`\n   */\n  attrs: Array<[string, string]> | null;\n\n  /**\n   * Source map info. Format: `[ line_begin, line_end ]`\n   */\n  map: [number, number] | null;\n\n  /**\n   * Level change (number in {-1, 0, 1} set), where:\n   *\n   * -  `1` means the tag is opening\n   * -  `0` means the tag is self-closing\n   * - `-1` means the tag is closing\n   */\n  nesting: MarkdownItNS.Token.Nesting;\n\n  /**\n   * Nesting level, the same as `state.level`\n   */\n  level: number;\n\n  /**\n   * An array of child nodes (inline and img tokens)\n   */\n  children: Token[] | null;\n\n  /**\n   * In a case of self-closing tag (code, html, fence, etc.),\n   * it has contents of MarkdownIt tag.\n   */\n  content: string;\n\n  /**\n   * '*' or '_' for emphasis, fence string for fence, etc.\n   */\n  markup: string;\n\n  /**\n   * - Info string for \"fence\" tokens\n   * - The value \"auto\" for autolink \"link_open\" and \"link_close\" tokens\n   * - The string value of the item marker for ordered-list \"list_item_open\" tokens\n   */\n  info: string;\n\n  /**\n   * A place for plugins to store an arbitrary data\n   */\n  meta: Any;\n\n  /**\n   * True for block-level tokens, false for inline tokens.\n   * Used in renderer to calculate line breaks\n   */\n  block: boolean;\n\n  /**\n   * If it's true, ignore MarkdownIt element when rendering. Used for tight lists\n   * to hide paragraphs.\n   */\n  hidden: boolean;\n\n  /**\n   * Search attribute index by name.\n   */\n  attrIndex(name: string): number;\n\n  /**\n   * Add `[ name, value ]` attribute to list. Init attrs if necessary\n   */\n  attrPush(attrData: [string, string]): void;\n\n  /**\n   * Set `name` attribute to `value`. Override old value if exists.\n   */\n  attrSet(name: string, value: string): void;\n\n  /**\n   * Get the value of attribute `name`, or null if it does not exist.\n   */\n  attrGet(name: string): string | null;\n\n  /**\n   * Join value to existing attribute via space. Or create new attribute if not\n   * exists. Useful to operate with token classes.\n   */\n  attrJoin(name: string, value: string): void;\n}\n\ntype Token_ = Token;\n\n// lib/renderer.mjs\n\ninterface Renderer {\n  /**\n   * Contains render rules for tokens. Can be updated and extended.\n   *\n   * ##### Example\n   *\n   * ```javascript\n   * var md = require('markdown-it')();\n   *\n   * md.renderer.rules.strong_open  = function () { return '<b>'; };\n   * md.renderer.rules.strong_close = function () { return '</b>'; };\n   *\n   * var result = md.renderInline(...);\n   * ```\n   *\n   * Each rule is called as independent static function with fixed signature:\n   *\n   * ```javascript\n   * function my_token_render(tokens, idx, options, env, renderer) {\n   *   // ...\n   *   return renderedHTML;\n   * }\n   * ```\n   *\n   * @see https://github.com/markdown-it/markdown-it/blob/master/lib/renderer.mjs\n   */\n  rules: MarkdownItNS.Renderer.RenderRuleRecord;\n\n  /**\n   * Render token attributes to string.\n   */\n  renderAttrs(token: Token): string;\n\n  /**\n   * Default token renderer. Can be overriden by custom function\n   * in {@link Renderer#rules}.\n   *\n   * @param tokens list of tokens\n   * @param idx token index to render\n   * @param options params of parser instance\n   */\n  renderToken(tokens: Token[], idx: number, options: MarkdownItNS.Options): string;\n\n  /**\n   * The same as {@link Renderer.render}, but for single token of `inline` type.\n   *\n   * @param tokens list of block tokens to render\n   * @param options params of parser instance\n   * @param env additional data from parsed input (references, for example)\n   */\n  renderInline(tokens: Token[], options: MarkdownItNS.Options, env: Any): string;\n\n  /**\n   * Special kludge for image `alt` attributes to conform CommonMark spec.\n   * Don't try to use it! Spec requires to show `alt` content with stripped markup,\n   * instead of simple escaping.\n   *\n   * @param tokens list of block tokens to render\n   * @param options params of parser instance\n   * @param env additional data from parsed input (references, for example)\n   */\n  renderInlineAsText(tokens: Token[], options: MarkdownItNS.Options, env: Any): string;\n\n  /**\n   * Takes token stream and generates HTML. Probably, you will never need to call\n   * MarkdownIt method directly.\n   *\n   * @param tokens list of block tokens to render\n   * @param options params of parser instance\n   * @param env additional data from parsed input (references, for example)\n   */\n  render(tokens: Token[], options: MarkdownItNS.Options, env: Any): string;\n}\n\ntype Renderer_ = Renderer;\n\n// lib/ruler.mjs\n\n/**\n * Helper class, used by {@link MarkdownIt#core}, {@link MarkdownIt#block} and\n * {@link MarkdownIt#inline} to manage sequences of functions (rules):\n *\n * - keep rules in defined order\n * - assign the name to each rule\n * - enable/disable rules\n * - add/replace rules\n * - allow assign rules to additional named chains (in the same)\n * - caching lists of active rules\n *\n * You will not need use MarkdownIt class directly until write plugins. For simple\n * rules control use {@link MarkdownItNS disable}, {@link MarkdownItNS enable} and\n * {@link MarkdownItNS use}.\n */\ninterface  Ruler<T> {\n  /**\n   * Replace rule by name with new function & options. Throws error if name not\n   * found.\n   *\n   * ##### Example\n   *\n   * Replace existing typographer replacement rule with new one:\n   *\n   * ```javascript\n   * var md = require('markdown-it')();\n   *\n   * md.core.ruler.at('replacements', function replace(state) {\n   *   //...\n   * });\n   * ```\n   *\n   * @param name rule name to replace.\n   * @param fn new rule function.\n   * @param options new rule options (not mandatory).\n   */\n  at(name: string, fn: T, options?: MarkdownItNS.Ruler.RuleOptions): void;\n\n  /**\n   * Add new rule to chain before one with given name.\n   *\n   * ##### Example\n   *\n   * ```javascript\n   * var md = require('markdown-it')();\n   *\n   * md.block.ruler.before('paragraph', 'my_rule', function replace(state) {\n   *   //...\n   * });\n   * ```\n   *\n   * @see {@link Ruler.after}, {@link Ruler.push}\n   *\n   * @param beforeName new rule will be added before MarkdownIt one.\n   * @param ruleName name of added rule.\n   * @param fn rule function.\n   * @param options rule options (not mandatory).\n   */\n  before(beforeName: string, ruleName: string, fn: T, options?: MarkdownItNS.Ruler.RuleOptions): void;\n\n  /**\n   * Add new rule to chain after one with given name.\n   *\n   * ##### Example\n   *\n   * ```javascript\n   * var md = require('markdown-it')();\n   *\n   * md.inline.ruler.after('text', 'my_rule', function replace(state) {\n   *   //...\n   * });\n   * ```\n   *\n   * @see {@link Ruler.before}, {@link Ruler.push}\n   *\n   * @param afterName new rule will be added after MarkdownIt one.\n   * @param ruleName name of added rule.\n   * @param fn rule function.\n   * @param options rule options (not mandatory).\n   */\n  after(afterName: string, ruleName: string, fn: T, options?: MarkdownItNS.Ruler.RuleOptions): void;\n\n  /**\n   * Push new rule to the end of chain.\n   *\n   * ##### Example\n   *\n   * ```javascript\n   * var md = require('markdown-it')();\n   *\n   * md.core.ruler.push('my_rule', function replace(state) {\n   *   //...\n   * });\n   * ```\n   *\n   * @see {@link Ruler.before}, {@link Ruler.after}\n   *\n   * @param ruleName name of added rule.\n   * @param fn rule function.\n   * @param options rule options (not mandatory).\n   */\n  push(ruleName: string, fn: T, options?: MarkdownItNS.Ruler.RuleOptions): void;\n\n  /**\n   * Enable rules with given names. If Any rule name not found - throw Error.\n   * Errors can be disabled by second param.\n   *\n   * Returns list of found rule names (if no exception happened).\n   *\n   * @see {@link Ruler.disable}, {@link Ruler.enableOnly}\n   *\n   * @param list list of rule names to enable.\n   * @param ignoreInvalid set `true` to ignore errors when rule not found.\n   */\n  enable(list: string | string[], ignoreInvalid?: boolean): string[];\n\n  /**\n   * Enable rules with given names, and disable everything else. If Any rule name\n   * not found - throw Error. Errors can be disabled by second param.\n   *\n   * @see {@link Ruler.disable}, {@link Ruler.enable}\n   *\n   * @param list list of rule names to enable (whitelist).\n   * @param ignoreInvalid set `true` to ignore errors when rule not found.\n   */\n  enableOnly(list: string | string[], ignoreInvalid?: boolean): void;\n\n  /**\n   * Disable rules with given names. If Any rule name not found - throw Error.\n   * Errors can be disabled by second param.\n   *\n   * Returns list of found rule names (if no exception happened).\n   *\n   * @see {@link Ruler.enable}, {@link Ruler.enableOnly}\n   *\n   * @param list list of rule names to disable.\n   * @param ignoreInvalid set `true` to ignore errors when rule not found.\n   */\n  disable(list: string | string[], ignoreInvalid?: boolean): string[];\n\n  /**\n   * Return array of active functions (rules) for given chain name. It analyzes\n   * rules configuration, compiles caches if not exists and returns result.\n   *\n   * Default chain name is `''` (empty string). It can't be skipped. That's\n   * done intentionally, to keep signature monomorphic for high speed.\n   */\n  getRules(chainName: string): T[];\n}\n\ntype Ruler_<T> = Ruler<T>;\n\n// lib/rules_core/state_core.mjs\n\ninterface StateCore {\n  src: string;\n  env: Any;\n  tokens: Token[];\n  inlineMode: boolean;\n\n  /**\n   * link to parser instance\n   */\n  md: MarkdownIt;\n\n  // Token: typeof Token;\n}\n\ntype StateCore_ = StateCore;\n\n// lib/rules_block/state_block.mjs\n\ninterface StateBlock {\n  src: string;\n\n  /**\n   * link to parser instance\n   */\n  md: MarkdownIt;\n\n  env: Any;\n\n  //\n  // Internal state vartiables\n  //\n\n  tokens: Token[];\n\n  /**\n   * line begin offsets for fast jumps\n   */\n  bMarks: number[];\n  /**\n   * line end offsets for fast jumps\n   */\n  eMarks: number[];\n  /**\n   * offsets of the first non-space characters (tabs not expanded)\n   */\n  tShift: number[];\n  /**\n   * indents for each line (tabs expanded)\n   */\n  sCount: number[];\n\n  /**\n   * An amount of virtual spaces (tabs expanded) between beginning\n   * of each line (bMarks) and real beginning of that line.\n   *\n   * It exists only as a hack because blockquotes override bMarks\n   * losing information in the process.\n   *\n   * It's used only when expanding tabs, you can think about it as\n   * an initial tab length, e.g. bsCount=21 applied to string `\\t123`\n   * means first tab should be expanded to 4-21%4 === 3 spaces.\n   */\n  bsCount: number[];\n\n  // block parser variables\n\n  /**\n   * required block content indent (for example, if we are\n   * inside a list, it would be positioned after list marker)\n   */\n  blkIndent: number;\n  /**\n   * line index in src\n   */\n  line: number;\n  /**\n   * lines count\n   */\n  lineMax: number;\n  /**\n   * loose/tight mode for lists\n   */\n  tight: boolean;\n  /**\n   * indent of the current dd block (-1 if there isn't Any)\n   */\n  ddIndent: number;\n  /**\n   * indent of the current list block (-1 if there isn't Any)\n   */\n  listIndent: number;\n\n  /**\n   * used in lists to determine if they interrupt a paragraph\n   */\n  parentType: MarkdownItNS.StateBlock.ParentType;\n\n  level: number;\n\n  /**\n   * Push new token to \"stream\".\n   */\n  push(type: string, tag: string, nesting: MarkdownItNS.Token.Nesting): Token;\n\n  isEmpty(line: number): boolean;\n\n  skipEmptyLines(from: number): number;\n\n  /**\n   * Skip spaces from given position.\n   */\n  skipSpaces(pos: number): number;\n\n  /**\n   * Skip spaces from given position in reverse.\n   */\n  skipSpacesBack(pos: number, min: number): number;\n\n  /**\n   * Skip char codes from given position\n   */\n  skipChars(pos: number, code: number): number;\n\n  /**\n   * Skip char codes reverse from given position - 1\n   */\n  skipCharsBack(pos: number, code: number, min: number): number;\n\n  /**\n   * cut lines range from source.\n   */\n  getLines(begin: number, end: number, indent: number, keepLastLF: boolean): string;\n\n  // Token: typeof Token;\n}\n\ntype StateBlock_ = StateBlock;\n\n// lib/rules_inline/state_inline.mjs\n\ninterface StateInline {\n  src: string;\n  env: Any;\n  md: MarkdownIt;\n  tokens: Token[];\n  tokens_meta: Array<MarkdownItNS.StateInline.TokenMeta | null>;\n\n  pos: number;\n  posMax: number;\n  level: number;\n  pending: string;\n  pendingLevel: number;\n\n  /**\n   * Stores { start: end } pairs. Useful for backtrack\n   * optimization of pairs parse (emphasis, strikes).\n   */\n  cache: Any;\n\n  /**\n   * List of emphasis-like delimiters for current tag\n   */\n  delimiters: MarkdownItNS.StateInline.Delimiter[];\n\n  // Stack of delimiter lists for upper level tags\n  // _prev_delimiters: StateInline.Delimiter[][];\n\n  /**\n   * Flush pending text\n   */\n  pushPending(): Token;\n\n  /**\n   * Push new token to \"stream\".\n   * If pending text exists - flush it as text token\n   */\n  push(type: string, tag: string, nesting: MarkdownItNS.Token.Nesting): Token;\n\n  /**\n   * Scan a sequence of emphasis-like markers, and determine whether\n   * it can start an emphasis sequence or end an emphasis sequence.\n   *\n   * @param start position to scan from (it should point at a valid marker)\n   * @param canSplitWord determine if these markers can be found inside a word\n   */\n  scanDelims(start: number, canSplitWord: boolean): MarkdownItNS.StateInline.Scanned;\n\n  // Token: typeof Token;\n}\n\ntype StateInline_ = StateInline;\n\n// lib/parser_core.mjs\n\ninterface Core {\n  /**\n   * {@link Ruler} instance. Keep configuration of core rules.\n   */\n  ruler: Ruler<MarkdownItNS.Core.RuleCore>;\n\n  /**\n   * Executes core chain rules.\n   */\n  process(state: StateCore): void;\n\n  // State: typeof StateCore;\n}\n\ntype Core_ = Core;\n\n// lib/parser_block.mjs\n\ninterface ParserBlock {\n  /**\n   * {@link Ruler} instance. Keep configuration of block rules.\n   */\n  ruler: Ruler<MarkdownItNS.ParserBlock.RuleBlock>;\n\n  /**\n   * Generate tokens for input range\n   */\n  tokenize(state: StateBlock, startLine: number, endLine: number): void;\n\n  /**\n   * Process input string and push block tokens into `outTokens`\n   */\n  parse(str: string, md: MarkdownIt, env: Any, outTokens: Token[]): void;\n\n  // State: typeof StateBlock;\n}\n\ntype ParserBlock_ = ParserBlock;\n\n// lib/parser_inline.mjs\n\ninterface ParserInline {\n  /**\n   * {@link Ruler} instance. Keep configuration of inline rules.\n   */\n  ruler: Ruler<MarkdownItNS.ParserInline.RuleInline>;\n\n  /**\n   * {@link Ruler} instance. Second ruler used for post-processing\n   * (e.g. in emphasis-like rules).\n   */\n  ruler2: Ruler<MarkdownItNS.ParserInline.RuleInline2>;\n\n  /**\n   * Skip single token by running all rules in validation mode;\n   * returns `true` if Any rule reported success\n   */\n  skipToken(state: StateInline): void;\n\n  /**\n   * Generate tokens for input range\n   */\n  tokenize(state: StateInline): void;\n\n  /**\n   * Process input string and push inline tokens into `outTokens`\n   */\n  parse(str: string, md: MarkdownIt, env: Any, outTokens: Token[]): void;\n\n  // State: typeof StateInline;\n}\n\ntype ParserInline_ = ParserInline;\n\ndeclare namespace MarkdownItNS {\n  // lib/common/utils.mjs\n\n  interface Utils {\n    // lib: {\n    //   mdurl: typeof mdurl;\n    //   ucmicro: Any;\n    // };\n\n    /**\n     * Merge objects\n     */\n    assign(obj: Any, ...from: Any[]): Any;\n\n    // isString(obj: Any): obj is string;\n\n    has(obj: Any, key: keyof Any): boolean;\n\n    unescapeMd(str: string): string;\n\n    unescapeAll(str: string): string;\n\n    isValidEntityCode(c: number): boolean;\n\n    fromCodePoint(c: number): string;\n\n    escapeHtml(str: string): string;\n\n    /**\n     * Remove element from array and put another array at those position.\n     * Useful for some operations with tokens\n     */\n    arrayReplaceAt<T>(src: T[], pos: number, newElements: T[]): T[];\n\n    isSpace(code: number): boolean;\n\n    /**\n     * Zs (unicode class) || [\\t\\f\\v\\r\\n]\n     */\n    isWhiteSpace(code: number): boolean;\n\n    /**\n     * Markdown ASCII punctuation characters.\n     *\n     * !, \", #, $, %, &, ', (, ), *, +, ,, -, ., /, :, ;, <, =, >, ?, @, [, \\, ], ^, _, `, {, |, }, or ~\n     *\n     * Don't confuse with unicode punctuation !!! It lacks some chars in ascii range.\n     *\n     * @see http://spec.commonmark.org/0.15/#ascii-punctuation-character\n     */\n    isMdAsciiPunct(code: number): boolean;\n\n    /**\n     * Currently without astral characters support.\n     */\n    isPunctChar(ch: string): boolean;\n\n    escapeRE(str: string): string;\n\n    /**\n     * Helper to unify [reference labels].\n     */\n    normalizeReference(str: string): string;\n  }\n\n  // lib/helpers/index.mjs\n\n  interface ParseLinkDestinationResult {\n    ok: boolean;\n    pos: number;\n    str: string;\n  }\n\n  interface ParseLinkTitleResult {\n    /**\n     * if `true`, MarkdownIt is a valid link title\n     */\n    ok: boolean;\n    /**\n     * if `true`, MarkdownIt link can be continued on the next line\n     */\n    can_continue: boolean;\n    /**\n     * if `ok`, it's the position of the first character after the closing marker\n     */\n    pos: number;\n    /**\n     * if `ok`, it's the unescaped title\n     */\n    str: string;\n    /**\n     * expected closing marker character code\n     */\n    marker: number;\n  }\n\n  interface Helpers {\n    // lib/helpers/parse_link_label.mjs\n\n    parseLinkLabel(state: StateInline, start: number, disableNested?: boolean): number;\n\n    // lib/helpers/parse_link_destination.mjs\n\n    parseLinkDestination(str: string, start: number, max: number): ParseLinkDestinationResult;\n\n    // lib/helpers/parse_link_title.mjs\n\n    parseLinkTitle(\n      str: string,\n      start: number,\n      max: number,\n      prev_state?: ParseLinkTitleResult,\n    ): ParseLinkTitleResult;\n  }\n\n  /**\n   * MarkdownIt provides named presets as a convenience to quickly\n   * enable/disable active syntax rules and options for common use cases.\n   *\n   * - [\"commonmark\"](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/commonmark.js) -\n   *   configures parser to strict [CommonMark](http://commonmark.org/) mode.\n   * - [default](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/default.js) -\n   *   similar to GFM, used when no preset name given. Enables all available rules,\n   *   but still without html, typographer & autolinker.\n   * - [\"zero\"](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/zero.js) -\n   *   all rules disabled. Useful to quickly setup your config via `.enable()`.\n   *   For example, when you need only `bold` and `italic` markup and nothing else.\n   */\n  type PresetName = \"default\" | \"zero\" | \"commonmark\";\n\n  interface Options {\n    /**\n     * Set `true` to enable HTML tags in source. Be careful!\n     * That's not safe! You may need external sanitizer to protect output from XSS.\n     * It's better to extend features via plugins, instead of enabling HTML.\n     * @default false\n     */\n    html?: boolean | undefined;\n\n    /**\n     * Set `true` to add '/' when closing single tags\n     * (`<br />`). This is needed only for full CommonMark compatibility. In real\n     * world you will need HTML output.\n     * @default false\n     */\n    xhtmlOut?: boolean | undefined;\n\n    /**\n     * Set `true` to convert `\\n` in paragraphs into `<br>`.\n     * @default false\n     */\n    breaks?: boolean | undefined;\n\n    /**\n     * CSS language class prefix for fenced blocks.\n     * Can be useful for external highlighters.\n     * @default 'language-'\n     */\n    langPrefix?: string | undefined;\n\n    /**\n     * Set `true` to autoconvert URL-like text to links.\n     * @default false\n     */\n    linkify?: boolean | undefined;\n\n    /**\n     * Set `true` to enable [some language-neutral replacement](https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/replacements.js) +\n     * quotes beautification (smartquotes).\n     * @default false\n     */\n    typographer?: boolean | undefined;\n\n    /**\n     * Double + single quotes replacement\n     * pairs, when typographer enabled and smartquotes on. For example, you can\n     * use `'«»„“'` for Russian, `'„“‚‘'` for German, and\n     * `['«\\xA0', '\\xA0»', '‹\\xA0', '\\xA0›']` for French (including nbsp).\n     * @default '“”‘’'\n     */\n    quotes?: string | string[];\n\n    /**\n     * Highlighter function for fenced code blocks.\n     * Highlighter `function (str, lang, attrs)` should return escaped HTML. It can\n     * also return empty string if the source was not changed and should be escaped\n     * externally. If result starts with <pre... internal wrapper is skipped.\n     * @default null\n     */\n    highlight?: ((str: string, lang: string, attrs: string) => string) | null | undefined;\n  }\n\n  // lib/token.mjs\n\n  type Token = Token_;\n  namespace Token {\n    type Nesting = 1 | 0 | -1;\n  }\n\n  // lib/renderer.mjs\n\n  type Renderer = Renderer_;\n  namespace Renderer {\n    type RenderRule = (tokens: Token[], idx: number, options: Options, env: Any, self: Renderer) => string;\n\n    interface RenderRuleRecord {\n      // [type: string]: RenderRule | undefined;\n      code_inline?: RenderRule | undefined;\n      code_block?: RenderRule | undefined;\n      fence?: RenderRule | undefined;\n      image?: RenderRule | undefined;\n      hardbreak?: RenderRule | undefined;\n      softbreak?: RenderRule | undefined;\n      text?: RenderRule | undefined;\n      html_block?: RenderRule | undefined;\n      html_inline?: RenderRule | undefined;\n    }\n  }\n\n  // lib/ruler.mjs\n\n  type Ruler<T> = Ruler_<T>;\n  namespace Ruler {\n    interface RuleOptions {\n      /**\n       * array with names of \"alternate\" chains.\n       */\n      alt: string[];\n    }\n  }\n\n  // lib/rules_core/state_core.mjs\n\n  type StateCore = StateCore_;\n\n  // lib/rules_block/state_block.mjs\n\n  type StateBlock = StateBlock_;\n  namespace StateBlock {\n    type ParentType = \"blockquote\" | \"list\" | \"root\" | \"paragraph\" | \"reference\";\n  }\n\n  // lib/rules_inline/state_inline.mjs\n\n  type StateInline = StateInline_;\n  namespace StateInline {\n    interface Scanned {\n      can_open: boolean;\n      can_close: boolean;\n      length: number;\n    }\n\n    interface Delimiter {\n      marker: number;\n      length: number;\n      token: number;\n      end: number;\n      open: boolean;\n      close: boolean;\n    }\n\n    interface TokenMeta {\n      delimiters: Delimiter[];\n    }\n  }\n\n  // lib/parser_core.mjs\n\n  type Core = Core_;\n  namespace Core {\n    type RuleCore = (state: StateCore) => void;\n  }\n\n  // lib/parser_block.mjs\n\n  type ParserBlock = ParserBlock_;\n  namespace ParserBlock {\n    type RuleBlock = (state: StateBlock, startLine: number, endLine: number, silent: boolean) => boolean;\n  }\n\n  // lib/parser_inline.mjs\n\n  type ParserInline = ParserInline_;\n  namespace ParserInline {\n    type RuleInline = (state: StateInline, silent: boolean) => boolean;\n    type RuleInline2 = (state: StateInline) => boolean;\n  }\n\n  type PluginSimple = (md: MarkdownIt) => void;\n  type PluginWithOptions<T = Any> = (md: MarkdownIt, options?: T) => void;\n  type PluginWithParams = (md: MarkdownIt, ...params: Any[]) => void;\n}\n\n// interface MarkdownItConstructor {\n//   new(): MarkdownIt;\n//   new(presetName: MarkdownItNS.PresetName, options?: MarkdownItNS.Options): MarkdownIt;\n//   new(options: MarkdownItNS.Options): MarkdownIt;\n//   (): MarkdownIt;\n//   (presetName: MarkdownItNS.PresetName, options?: MarkdownItNS.Options): MarkdownIt;\n//   (options: MarkdownItNS.Options): MarkdownIt;\n// }\n\ninterface MarkdownIt {\n  /**\n   * Instance of {@link ParserInline}. You may need it to add new rules when\n   * writing plugins. For simple rules control use {@link MarkdownItNS.disable} and\n   * {@link MarkdownItNS.enable}.\n   */\n  readonly inline: ParserInline;\n\n  /**\n   * Instance of {@link ParserBlock}. You may need it to add new rules when\n   * writing plugins. For simple rules control use {@link MarkdownItNS.disable} and\n   * {@link MarkdownItNS.enable}.\n   */\n  readonly block: ParserBlock;\n\n  /**\n   * Instance of {@link Core} chain executor. You may need it to add new rules when\n   * writing plugins. For simple rules control use {@link MarkdownItNS.disable} and\n   * {@link MarkdownItNS.enable}.\n   */\n  readonly core: Core;\n\n  /**\n   * Instance of {@link Renderer}. Use it to modify output look. Or to add rendering\n   * rules for new token types, generated by plugins.\n   *\n   * ##### Example\n   *\n   * ```javascript\n   * var md = require('markdown-it')();\n   *\n   * function myToken(tokens, idx, options, env, self) {\n   *   //...\n   *   return result;\n   * };\n   *\n   * md.renderer.rules['my_token'] = myToken\n   * ```\n   *\n   * See {@link Renderer} docs and [source code](https://github.com/markdown-it/markdown-it/blob/master/lib/renderer.js).\n   */\n  readonly renderer: Renderer;\n\n  /**\n   * [linkify-it](https://github.com/markdown-it/linkify-it) instance.\n   * Used by [linkify](https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/linkify.js)\n   * rule.\n   */\n  // readonly linkify: LinkifyIt;\n\n  /**\n   * Link validation function. CommonMark allows too much in links. By default\n   * we disable `javascript:`, `vbscript:`, `file:` schemas, and almost all `data:...` schemas\n   * except some embedded image types.\n   *\n   * You can change MarkdownIt behaviour:\n   *\n   * ```javascript\n   * var md = require('markdown-it')();\n   * // enable everything\n   * md.validateLink = function () { return true; }\n   * ```\n   */\n  validateLink(url: string): boolean;\n\n  /**\n   * Function used to encode link url to a machine-readable format,\n   * which includes url-encoding, punycode, etc.\n   */\n  normalizeLink(url: string): string;\n\n  /**\n   * Function used to decode link url to a human-readable format`\n   */\n  normalizeLinkText(url: string): string;\n\n  readonly utils: MarkdownItNS.Utils;\n\n  readonly helpers: MarkdownItNS.Helpers;\n\n  readonly options: MarkdownItNS.Options;\n\n  /**\n   * *chainable*\n   *\n   * Set parser options (in the same format as in constructor). Probably, you\n   * will never need it, but you can change options after constructor call.\n   *\n   * ##### Example\n   *\n   * ```javascript\n   * var md = require('markdown-it')()\n   *             .set({ html: true, breaks: true })\n   *             .set({ typographer: true });\n   * ```\n   *\n   * __Note:__ To achieve the best possible performance, don't modify a\n   * `markdown-it` instance options on the fly. If you need multiple configurations\n   * it's best to create multiple instances and initialize each with separate\n   * config.\n   */\n  set(options: MarkdownItNS.Options): MarkdownIt;\n\n  /**\n   * *chainable*, *internal*\n   *\n   * Batch load of all options and compenent settings. This is internal method,\n   * and you probably will not need it. But if you with - see available presets\n   * and data structure [here](https://github.com/markdown-it/markdown-it/tree/master/lib/presets)\n   *\n   * We strongly recommend to use presets instead of direct config loads. That\n   * will give better compatibility with next versions.\n   */\n  configure(presets: MarkdownItNS.PresetName): MarkdownIt;\n\n  /**\n   * *chainable*\n   *\n   * Enable list or rules. It will automatically find appropriate components,\n   * containing rules with given names. If rule not found, and `ignoreInvalid`\n   * not set - throws exception.\n   *\n   * ##### Example\n   *\n   * ```javascript\n   * var md = require('markdown-it')()\n   *             .enable(['sub', 'sup'])\n   *             .disable('smartquotes');\n   * ```\n   *\n   * @param list rule name or list of rule names to enable\n   * @param ignoreInvalid set `true` to ignore errors when rule not found.\n   */\n  enable(list: string | string[], ignoreInvalid?: boolean): MarkdownIt;\n\n  /**\n   * *chainable*\n   *\n   * The same as {@link MarkdownItNS.enable}, but turn specified rules off.\n   *\n   * @param list rule name or list of rule names to disable.\n   * @param ignoreInvalid set `true` to ignore errors when rule not found.\n   */\n  disable(list: string | string[], ignoreInvalid?: boolean): MarkdownIt;\n\n  /**\n   * *chainable*\n   *\n   * Load specified plugin with given params into current parser instance.\n   * It's just a sugar to call `plugin(md, params)` with curring.\n   *\n   * ##### Example\n   *\n   * ```javascript\n   * var iterator = require('markdown-it-for-inline');\n   * var md = require('markdown-it')()\n   *             .use(iterator, 'foo_replace', 'text', function (tokens, idx) {\n   *               tokens[idx].content = tokens[idx].content.replace(/foo/g, 'bar');\n   *             });\n   * ```\n   */\n  use(plugin: MarkdownItNS.PluginSimple): MarkdownIt;\n  use<T = Any>(plugin: MarkdownItNS.PluginWithOptions<T>, options?: T): MarkdownIt;\n  use(plugin: MarkdownItNS.PluginWithParams, ...params: Any[]): MarkdownIt;\n\n  /**\n   * *internal*\n   *\n   * Parse input string and returns list of block tokens (special token type\n   * \"inline\" will contain list of inline tokens). You should not call MarkdownIt\n   * method directly, until you write custom renderer (for example, to produce\n   * AST).\n   *\n   * `env` is used to pass data between \"distributed\" rules and return additional\n   * metadata like reference info, needed for the renderer. It also can be used to\n   * inject data in specific cases. Usually, you will be ok to pass `{}`,\n   * and then pass updated object to renderer.\n   *\n   * @param src source string\n   * @param env environment sandbox\n   */\n  parse(src: string, env: Any): Token[];\n\n  /**\n   * Render markdown string into html. It does all magic for you :).\n   *\n   * `env` can be used to inject additional metadata (`{}` by default).\n   * But you will not need it with high probability. See also comment\n   * in {@link MarkdownItNS.parse}.\n   *\n   * @param src source string\n   * @param env environment sandbox\n   */\n  render(src: string, env?: Any): string;\n\n  /**\n   * *internal*\n   *\n   * The same as {@link MarkdownItNS.parse} but skip all block rules. It returns the\n   * block tokens list with the single `inline` element, containing parsed inline\n   * tokens in `children` property. Also updates `env` object.\n   *\n   * @param src source string\n   * @param env environment sandbox\n   */\n  parseInline(src: string, env: Any): Token[];\n\n  /**\n   * Similar to {@link MarkdownItNS.render} but for single paragraph content. Result\n   * will NOT be wrapped into `<p>` tags.\n   *\n   * @param src source string\n   * @param env environment sandbox\n   */\n  renderInline(src: string, env?: Any): string;\n}\n\n/**\n * Main parser/renderer class.\n *\n * ##### Usage\n *\n * ```javascript\n * // node.js, \"classic\" way:\n * var MarkdownIt = require('markdown-it'),\n *     md = new MarkdownIt();\n * var result = md.render('# markdown-it rulezz!');\n *\n * // node.js, the same, but with sugar:\n * var md = require('markdown-it')();\n * var result = md.render('# markdown-it rulezz!');\n *\n * // browser without AMD, added to \"window\" on script load\n * // Note, there are no dash.\n * var md = window.markdownit();\n * var result = md.render('# markdown-it rulezz!');\n * ```\n *\n * Single line rendering, without paragraph wrap:\n *\n * ```javascript\n * var md = require('markdown-it')();\n * var result = md.renderInline('__markdown-it__ rulezz!');\n * ```\n *\n * ##### Example\n *\n * ```javascript\n * // commonmark mode\n * var md = require('markdown-it')('commonmark');\n *\n * // default mode\n * var md = require('markdown-it')();\n *\n * // enable everything\n * var md = require('markdown-it')({\n *   html: true,\n *   linkify: true,\n *   typographer: true\n * });\n * ```\n *\n * ##### Syntax highlighting\n *\n * ```js\n * var hljs = require('highlight.js') // https://highlightjs.org/\n *\n * var md = require('markdown-it')({\n *   highlight: function (str, lang) {\n *     if (lang && hljs.getLanguage(lang)) {\n *       try {\n *         return hljs.highlight(lang, str, true).value;\n *       } catch (__) {}\n *     }\n *\n *     return ''; // use external default escaping\n *   }\n * });\n * ```\n *\n * Or with full wrapper override (if you need assign class to `<pre>`):\n *\n * ```javascript\n * var hljs = require('highlight.js') // https://highlightjs.org/\n *\n * // Actual default values\n * var md = require('markdown-it')({\n *   highlight: function (str, lang) {\n *     if (lang && hljs.getLanguage(lang)) {\n *       try {\n *         return '<pre class=\"hljs\"><code>' +\n *                hljs.highlight(lang, str, true).value +\n *                '</code></pre>';\n *       } catch (__) {}\n *     }\n *\n *     return '<pre class=\"hljs\"><code>' + md.utils.escapeHtml(str) + '</code></pre>';\n *   }\n * });\n * ```\n */\n// declare const MarkdownIt: MarkdownItConstructor;\n//\n// export = MarkdownIt;\n\ninterface Component {\n  rules: string[],\n}\ninterface ComponentMap {\n  core?: Component,\n  block?: Component,\n  inline?: Component,\n}\ninterface Config {\n  components: ComponentMap,\n}\n\nexport {\n  MarkdownIt,\n  Token,\n  Renderer,\n  StateCore,\n  StateBlock,\n  StateInline,\n  Ruler,\n  Core,\n  ParserBlock,\n  ParserInline,\n\n  Config,\n};"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/node/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport * from './models';\nexport * from './program';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/node/models.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { Event, MDUuid } from '../../../util';\nimport type { Token } from '../markdown-it';\n\nexport enum ENode {\n  Unknown = 'unknown',\n\n  Document = 'document',\n\n  Paragraph = 'paragraph',\n  ThematicBreak = 'thematic-break',\n  Heading = 'heading',\n  Quote = 'quote',\n  Code = 'code',\n  Table = 'table',\n  TableItem = 'table-item',\n  List = 'list',\n  ListItem = 'list-item',\n  HtmlTag = 'html-tag',\n  Math = 'math',\n\n  Text = 'text',\n  LineBreak = 'line-break',\n  Emoji = 'emoji',\n  Strong = 'strong',\n  Emphasis = 'emphasis',\n  StrikeThrough = 'strike-through',\n  Image = 'image',\n  Link = 'link',\n  FootnoteRef = 'footnote-ref',\n  FootnoteDef = 'footnote-def',\n  Superscript = 'sup',\n  Subscript = 'sub',\n\n  Inline = 'inline',\n\n  StyledContent = 'styled-content',\n  Fragment = 'fragment',\n}\n\nexport enum ELayout {\n  Unknown = 'unknown',\n  Inline = 'inline',\n  Block = 'block',\n}\nexport enum ELineBreak {\n  Unknown = 'unknown',\n  Soft = 'soft',\n  Hard = 'hard',\n}\nexport enum EList {\n  Unknown = 'unknown',\n  Bullet = 'bullet',\n  Ordered = 'ordered',\n  Task = 'task',\n}\nexport enum EListItem {\n  Unknown = 'unknown',\n  Ordered = 'ordered',\n  Bullet = 'bullet',\n  CheckBox = 'check-box',\n}\nexport enum ETableItem {\n  Unknown = 'unknown',\n  Head = 'head',\n  Body = 'body',\n  TR = 'tr', //  table row\n  TD = 'td', //  table body cell\n  TH = 'th', //  table head cell\n}\nexport enum EAlignment {\n  Unknown = 'unknown',\n  Left = 'left',\n  Center = 'center',\n  Right = 'right',\n}\nexport enum EState {\n  Unknown = 'unknown',\n  Open = 'open',\n  Close = 'close',\n  SelfClose = 'self-close',\n}\n\nexport interface ILocation {\n  readonly lineBegin: number,\n  readonly lineEnd: number,\n}\nconst EmptyLocation: ILocation = { lineBegin: -1, lineEnd: -1 };\nexport interface IAttribute {\n  readonly name: string,\n  readonly value?: string | number | boolean,\n}\nexport interface IVisitor {\n  on: (node: Node) => boolean,\n  filter?: (node: Node) => boolean,\n}\ninterface IVisitorAsync {\n  on: (node: Node) => Promise<boolean>,\n  filter?: (node: Node) => Promise<boolean>,\n}\n\ninterface INode {\n  type?: ENode,\n  layout?: ELayout,\n  content?: string,\n  hidden?: boolean,\n}\ninterface INodeSummary {\n  id?: number,\n  type?: ENode,\n  layout?: ELayout,\n  content?: string,\n  attributes?: IAttribute[],\n  children?: INodeSummary[],\n  hidden?: boolean,\n  hash?: string,\n}\nexport class Node extends Event {\n  readonly id: number = Node.getID();\n  type: ENode = ENode.Unknown;\n  layout: ELayout = ELayout.Unknown;\n  location: ILocation = EmptyLocation;\n  attributes: IAttribute[] = [];\n  content?: string;\n  state: EState = EState.Unknown;\n  hidden: boolean = false;\n\n  parent?: WeakRef<Node>;\n  first?: WeakRef<Node>;\n  last?: WeakRef<Node>;\n  prev?: WeakRef<Node>;\n  next?: WeakRef<Node>;\n\n  token?: Token;\n\n  private _hash?: string;\n  get hash() {\n    return this._hash;\n  }\n  createHash(): string | undefined {\n    const hashList: string[] = [];\n    //  this\n    do {\n      const hash = this.createThisHash();\n      if (hash) {\n        hashList.push(hash);\n      }\n    } while (0);\n    //  children\n    do {\n      const hash = this.first?.deref()?.createHash();\n      if (hash) {\n        hashList.push(hash);\n      }\n    } while (0);\n    //  brother\n    do {\n      const hash = this.next?.deref()?.createHash();\n      if (hash) {\n        hashList.push(hash);\n      }\n    } while (0);\n    this._hash = hashList.length > 0 ? MDUuid.md5(hashList.join('_')) : undefined;\n    return this._hash;\n  }\n  protected createThisHash(): string | undefined {\n    const content = `${\n      this.id\n    }${\n      this.type\n    }${\n      this.layout\n    }${\n      this.attributes.map(ele => ([ele.name, ele.value].join(''))).join('')\n    }${\n      this.content\n    }${\n      this.hidden\n    }`;\n    return MDUuid.md5(content);\n  }\n\n  constructor(option?: INode) {\n    super();\n    if (option?.type) {\n      this.type = option.type;\n    }\n    if (option?.layout) {\n      this.layout = option.layout;\n    }\n    if (option?.content) {\n      this.content = option.content;\n    }\n  }\n\n  is(type: ENode) {\n    return this.type === type;\n  }\n  weak() {\n    return new WeakRef(this);\n  }\n  stringify() {\n    return JSON.stringify({\n      id: this.id,\n      type: this.type,\n      level: this.layout,\n      location: JSON.stringify(this.location),\n      attributes: JSON.stringify(this.attributes),\n    });\n  }\n  append(node: Node) {\n    if (!this.canAppend(node)) {\n      return;\n    }\n    this.emit('will-append-node', node);\n    this.unbind(node);\n    node.parent = this.weak();\n    const last = this.last?.deref();\n    if (last) {\n      last.next = node.weak();\n      node.prev = last.weak();\n    } else {\n      const first = this.first?.deref();\n      if (first) {\n        first.next = node.weak();\n        node.prev = first.weak();\n      } else {\n        this.first = node.weak();\n      }\n    }\n    this.last = node.weak();\n    this.emit('did-append-node', node);\n  }\n  remove(node: Node) {\n    if (!this.canRemove(node)) {\n      return;\n    }\n    this.emit('will-remove-node', node);\n    this.unbind(node);\n    this.emit('did-remove-node', node);\n  }\n  insert(node: Node, anchor: Node, before: boolean = true) {\n    if (!this.canInsert(node, anchor, before)) {\n      return;\n    }\n    if (!before) {\n      //  目前仅支持 before 插入\n      return;\n    }\n    this.emit('will-insert-node', node);\n    this.unbind(node);\n    node.parent = this.weak();\n    const prev = anchor.prev?.deref();\n    if (prev) {\n      prev.next = node.weak();\n      node.prev = prev.weak();\n      node.next = anchor.weak();\n      anchor.prev = node.weak();\n    } else {\n      this.first = node.weak();\n      node.next = anchor.weak();\n      anchor.prev = node.weak();\n    }\n    this.emit('did-insert-node', node);\n  }\n  private canAppend(node: Node) {\n    return node ? true : false;\n  }\n  private canRemove(node: Node) {\n    if (!node) {\n      return false;\n    }\n    if (node.parent?.deref() !== this) {\n      return false;\n    }\n    return true;\n  }\n  private canInsert(node: Node, anchor: Node, before: boolean = true) {\n    if (!node || !anchor) {\n      return false;\n    }\n    if (!before) {\n      return false;\n    }\n    if (anchor.parent?.deref() !== this) {\n      return false;\n    }\n    return true;\n  }\n  private unbind(node?: Node) {\n    if (!node) {\n      return;\n    }\n    const prev = node?.prev?.deref();\n    const next = node?.next?.deref();\n    const parent = node?.parent?.deref();\n    if (parent) {\n      if (parent.first?.deref() === node) {\n        parent.first = next?.weak();\n      }\n      if (parent.last?.deref() === node) {\n        parent.last = prev?.weak();\n      }\n      node.parent = undefined;\n    }\n    if (prev) {\n      prev.next = next?.weak();\n      node.prev = undefined;\n    }\n    if (next) {\n      next.prev = prev?.weak();\n      node.next = undefined;\n    }\n  }\n  get children(): Node[] {\n    const nodes: Node[] = [];\n    let node = this.first?.deref();\n    if (node) {\n      nodes.push(node);\n    }\n    do {\n      node = node?.next?.deref();\n      if (node) {\n        nodes.push(node);\n      }\n    } while (node && this.last?.deref() && node !== this.last?.deref());\n    return nodes;\n  }\n  get summary(): INodeSummary {\n    return {\n      id: this.id,\n      type: this.type,\n      layout: this.layout,\n      content: this.content,\n      attributes: this.attributes,\n      hidden: this.hidden,\n      hash: this.hash,\n      children: this.children.map((node) => node.summary),\n    };\n  }\n  get document(): Document | undefined {\n    if (this instanceof Document) {\n      return this;\n    }\n    let parent = this.parent?.deref();\n    do {\n      if (parent instanceof Document) {\n        return parent;\n      }\n      parent = parent?.parent?.deref();\n    } while (parent);\n    return undefined;\n  }\n  private static gid: number = 0;\n  private static getID() {\n    return Node.gid++;\n  }\n  static resetID() {\n    Node.gid = 0;\n  }\n  static traverseSelf(node?: Node, visitor?: IVisitor) {\n    if (!node || !visitor) {\n      return;\n    }\n    let canNext = true;\n    if (visitor.filter) {\n      if (visitor.filter(node)) {\n        canNext = visitor.on(node);\n      }\n    } else {\n      canNext = visitor.on(node);\n    }\n    if (!canNext) {\n      return;\n    }\n    //  children\n    const first = node.first?.deref();\n    if (first) {\n      Node.traverse(first, visitor);\n    }\n  }\n  static traverse(node?: Node, visitor?: IVisitor) {\n    if (!node || !visitor) {\n      return;\n    }\n    let canNext = true;\n    if (visitor.filter) {\n      if (visitor.filter(node)) {\n        canNext = visitor.on(node);\n      }\n    } else {\n      canNext = visitor.on(node);\n    }\n    if (!canNext) {\n      return;\n    }\n    //  children\n    const first = node.first?.deref();\n    if (first) {\n      Node.traverse(first, visitor);\n    }\n    //  brother\n    const next = node.next?.deref();\n    if (next) {\n      Node.traverse(next, visitor);\n    }\n  }\n  static async traverseAsync(node?: Node, visitor?: IVisitorAsync) {\n    if (!node || !visitor) {\n      return;\n    }\n    let canNext = true;\n    if (visitor.filter) {\n      if (await visitor.filter(node)) {\n        canNext = await visitor.on(node);\n      }\n    } else {\n      canNext = await visitor.on(node);\n    }\n    if (!canNext) {\n      return;\n    }\n    //  children\n    const first = node.first?.deref();\n    if (first) {\n      await Node.traverseAsync(first, visitor);\n    }\n    //  brother\n    const next = node.next?.deref();\n    if (next) {\n      await Node.traverseAsync(next, visitor);\n    }\n  }\n}\n\ninterface IHeadingSummary extends INodeSummary {\n  level?: number,\n}\nexport class Heading extends Node {\n  readonly type: ENode = ENode.Heading;\n  readonly layout: ELayout = ELayout.Block;\n  level: number = 0;\n  get summary(): IHeadingSummary {\n    const summary = super.summary as IHeadingSummary;\n    summary.level = this.level;\n    return summary;\n  }\n  protected createThisHash(): string | undefined {\n    const content = `${\n      super.createThisHash()\n    }${\n      this.level\n    }`;\n    return MDUuid.md5(content);\n  }\n}\ninterface ICodeSummary extends INodeSummary {\n  language?: string,\n}\nexport class Code extends Node {\n  readonly type: ENode = ENode.Code;\n  language?: string;\n  get summary(): ICodeSummary {\n    const summary = super.summary as ICodeSummary;\n    summary.language = this.language;\n    return summary;\n  }\n  protected createThisHash(): string | undefined {\n    const content = `${\n     super.createThisHash()\n    }${\n      this.language\n    }`;\n    return MDUuid.md5(content);\n  }\n  get styledContent() {\n    const first = this.first?.deref();\n    return first?.is(ENode.StyledContent) ? first as StyledContent : undefined;\n  }\n}\ninterface IListSummary extends INodeSummary {\n  isTop?: boolean,\n  listType?: EList,\n}\nexport class List extends Node {\n  readonly type: ENode = ENode.List;\n  readonly layout: ELayout = ELayout.Block;\n  listType: EList = EList.Unknown;\n  get isTop() {\n    return this.parent?.deref()?.is(ENode.ListItem) ? false : true;\n  }\n  get summary(): IListSummary {\n    const summary = super.summary as IListSummary;\n    summary.isTop = this.isTop;\n    summary.listType = this.listType;\n    return summary;\n  }\n  protected createThisHash(): string | undefined {\n    const content = `${\n      super.createThisHash()\n    }${\n      this.listType\n    }`;\n    return MDUuid.md5(content);\n  }\n}\ninterface IListItemSummary extends INodeSummary {\n  itemType?: EListItem,\n  index?: number,\n  checked?: boolean,\n  info?: string,\n}\nexport class ListItem extends Node {\n  readonly type: ENode = ENode.ListItem;\n  readonly layout: ELayout = ELayout.Block;\n  itemType: EListItem = EListItem.Unknown;\n  index: number = -1;\n  checked: boolean = false;\n  info?: string;\n  get parentList() {\n    if (this.parent?.deref()?.is(ENode.List)) {\n      return this.parent?.deref() as List;\n    }\n    return undefined;\n  }\n  get summary(): IListItemSummary {\n    const summary = super.summary as IListItemSummary;\n    summary.itemType = this.itemType;\n    summary.index = this.index;\n    summary.checked = this.checked;\n    summary.info = this.info;\n    return summary;\n  }\n  protected createThisHash(): string | undefined {\n    const content = `${\n      super.createThisHash()\n    }${\n      this.itemType\n    }${\n      this.index\n    }${\n      this.checked\n    }`;\n    return MDUuid.md5(content);\n  }\n  static isCheckNode(node?: Node) {\n    if (node?.type === ENode.HtmlTag && node?.layout === ELayout.Inline) {\n      return /<input([\\s\\S]*)type=\"checkbox\"/.test(node.content || '');\n    }\n    return false;\n  }\n}\ninterface ITableItemSummary extends INodeSummary {\n  itemType?: ETableItem,\n  align?: EAlignment,\n}\nexport class TableItem extends Node {\n  readonly type: ENode = ENode.TableItem;\n  readonly layout: ELayout = ELayout.Block;\n  itemType: ETableItem = ETableItem.Unknown;\n  align: EAlignment = EAlignment.Left;\n  get summary(): ITableItemSummary {\n    const summary = super.summary as ITableItemSummary;\n    summary.itemType = this.itemType;\n    summary.align = this.align;\n    return summary;\n  }\n  protected createThisHash(): string | undefined {\n    const content = `${\n      super.createThisHash()\n    }${\n      this.itemType\n    }${\n      this.align\n    }`;\n    return MDUuid.md5(content);\n  }\n}\ninterface IImageSummary extends INodeSummary {\n  src?: string,\n  alt?: string,\n}\nexport class Image extends Node {\n  readonly type: ENode = ENode.Image;\n  readonly layout: ELayout = ELayout.Inline;\n  src?: string;\n  alt?: string;\n  get summary(): IImageSummary {\n    const summary = super.summary as IImageSummary;\n    summary.src = this.src;\n    summary.alt = this.alt;\n    return summary;\n  }\n  protected createThisHash(): string | undefined {\n    const content = `${\n      super.createThisHash()\n    }${\n      this.src\n    }${\n      this.alt\n    }`;\n    return MDUuid.md5(content);\n  }\n}\ninterface ILinkSummary extends INodeSummary {\n  href?: string,\n}\nexport class Link extends Node {\n  readonly type: ENode = ENode.Link;\n  readonly layout: ELayout = ELayout.Inline;\n  href?: string;\n  get summary(): ILinkSummary {\n    const summary = super.summary as ILinkSummary;\n    summary.href = this.href;\n    return summary;\n  }\n  protected createThisHash(): string | undefined {\n    const content = `${\n      super.createThisHash()\n    }${\n      this.href\n    }`;\n    return MDUuid.md5(content);\n  }\n}\ninterface IFootnoteRefSummary extends INodeSummary {\n  footnoteId?: number,\n  label?: string,\n}\nexport class FootnoteRef extends Node {\n  readonly type: ENode = ENode.FootnoteRef;\n  readonly layout: ELayout = ELayout.Inline;\n  footnoteId?: number;\n  label?: string;\n  def?: WeakRef<FootnoteDef>;\n  get summary(): IFootnoteRefSummary {\n    const summary = super.summary as IFootnoteRefSummary;\n    summary.footnoteId = this.footnoteId;\n    summary.label = this.label;\n    return summary;\n  }\n  protected createThisHash(): string | undefined {\n    const content = `${\n      super.createThisHash()\n    }${\n      this.footnoteId\n    }${\n      this.label\n    }${\n      this.def?.deref()?.id\n    }`;\n    return MDUuid.md5(content);\n  }\n}\ninterface IFootnoteDefSummary extends INodeSummary {\n  footnoteId?: number,\n  label?: string,\n}\nexport class FootnoteDef extends Node {\n  readonly type: ENode = ENode.FootnoteDef;\n  readonly layout: ELayout = ELayout.Block;\n  footnoteId?: number;\n  label?: string;\n  // refs?: WeakRef<FootnoteRef>[];\n  get summary(): IFootnoteDefSummary {\n    const summary = super.summary as IFootnoteDefSummary;\n    summary.footnoteId = this.footnoteId;\n    summary.label = this.label;\n    return summary;\n  }\n  protected createThisHash(): string | undefined {\n    const content = `${\n      super.createThisHash()\n    }${\n      this.footnoteId\n    }${\n      this.label\n    }`;\n    return MDUuid.md5(content);\n  }\n}\ninterface ILineBreakSummary extends INodeSummary {\n  lineBreakType?: ELineBreak,\n}\nexport class LineBreak extends Node {\n  readonly type: ENode = ENode.LineBreak;\n  readonly layout: ELayout = ELayout.Inline;\n  lineBreakType: ELineBreak = ELineBreak.Unknown;\n  get summary(): ILineBreakSummary {\n    const summary = super.summary as ILineBreakSummary;\n    summary.lineBreakType = this.lineBreakType;\n    return summary;\n  }\n  protected createThisHash(): string | undefined {\n    const content = `${\n      super.createThisHash()\n    }${\n      this.lineBreakType\n    }`;\n    return MDUuid.md5(content);\n  }\n}\ninterface IEmojiSummary extends INodeSummary {\n  markup?: string,\n}\nexport class Emoji extends Node {\n  readonly type: ENode = ENode.Emoji;\n  readonly layout: ELayout = ELayout.Inline;\n  markup?: string;\n  get summary(): IEmojiSummary {\n    const summary = super.summary as IEmojiSummary;\n    summary.markup = this.markup;\n    return summary;\n  }\n  protected createThisHash(): string | undefined {\n    const content = `${\n      super.createThisHash()\n    }${\n      this.markup\n    }`;\n    return MDUuid.md5(content);\n  }\n}\nexport enum EHtmlTag {\n  Sup = 'sup',\n  Sub = 'sub',\n  U = 'u',\n  Br = 'br',\n  S = 's',\n  Del = 'del',\n  Mark = 'mark',\n  Span = 'span',\n  Cite = 'cite',\n  Font = 'font',\n  Img = 'img',\n  A = 'a',\n  Icon = 'icon',\n  Div = 'div',\n}\ninterface IHtmlTagSummary extends INodeSummary {\n  tagName?: string,\n}\nexport class HtmlTag extends Node {\n  readonly type: ENode = ENode.HtmlTag;\n  readonly layout: ELayout = ELayout.Inline;\n  tagName?: string;\n  get summary(): IHtmlTagSummary {\n    const summary = super.summary as IHtmlTagSummary;\n    summary.tagName = this.tagName;\n    return summary;\n  }\n}\ninterface IMathSummary extends INodeSummary {\n  mathHash?: string,\n}\nexport class Math extends Node {\n  readonly type: ENode = ENode.Math;\n  mathHash?: string;\n  get summary(): IMathSummary {\n    const summary = super.summary as IMathSummary;\n    summary.mathHash = this.mathHash;\n    return summary;\n  }\n  protected createThisHash(): string | undefined {\n    this.mathHash = MDUuid.md5(this.content || '');\n    return super.createThisHash();\n  }\n}\ninterface IStyledContent extends INodeSummary {\n}\nexport class StyledContent extends Node {\n  readonly type: ENode = ENode.StyledContent;\n  styled?: StyledString;\n  get summary(): IStyledContent {\n    const summary = super.summary as IStyledContent;\n    return summary;\n  }\n  protected createThisHash(): string | undefined {\n    const content = `${\n      super.createThisHash()\n    }${\n      this.styled?.getString()\n    }`;\n    return MDUuid.md5(content);\n  }\n}\ninterface IDocumentSummary extends INodeSummary {\n}\nexport class Document extends Node {\n  readonly type: ENode = ENode.Document;\n  readonly layout: ELayout = ELayout.Block;\n  readonly footnoteRefs: WeakRef<FootnoteRef>[] = [];\n  readonly footnoteDefs: WeakRef<FootnoteDef>[] = [];\n  readonly tokens?: Token[];\n  constructor(tokens?: Token[]) {\n    super();\n    this.tokens = tokens;\n  }\n  get summary(): IDocumentSummary {\n    const summary = super.summary as IDocumentSummary;\n    return summary;\n  }\n  protected createThisHash(): string | undefined {\n    const content = `${\n      super.createThisHash()\n    }${\n      this.footnoteRefs.map(ele => ele.deref()?.id).join('')\n    }${\n      this.footnoteDefs.map(ele => ele.deref()?.id).join('')\n    }`;\n    return MDUuid.md5(content);\n  }\n}\nexport class Fragment extends Node {\n  readonly type: ENode = ENode.Fragment;\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/node/plugin/build-in.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { ENodeEvent, INodePayload, INodeResult, NodePlugin, INodeContext } from './plugin';\nimport { Code,\n  EAlignment,\n  ELayout,\n  ELineBreak,\n  EList, EListItem,\n  Emoji,\n  ENode,\n  EState,\n  ETableItem,\n  FootnoteDef,\n  FootnoteRef,\n  Heading,\n  HtmlTag,\n  Image,\n  LineBreak,\n  Math,\n  Link, List, ListItem, Node,\n  TableItem } from '../models';\n\nclass QuotePlugin extends NodePlugin {\n  readonly name = 'quote';\n  should(payload?: INodePayload, _?: INodeContext) {\n    if (payload?.event === ENodeEvent.Create && payload?.token?.type === 'blockquote') {\n      return true;\n    }\n    return false;\n  }\n  on(payload?: INodePayload, _?: INodeContext): INodeResult | undefined {\n    if (payload?.event === ENodeEvent.Create) {\n      return { node: new Node({ type: ENode.Quote, layout: ELayout.Block }) };\n    }\n    return undefined;\n  }\n}\nclass HeadingPlugin extends NodePlugin {\n  readonly name = 'heading';\n  should(payload?: INodePayload, _?: INodeContext) {\n    if (payload?.event === ENodeEvent.Create && payload?.token?.type === 'heading') {\n      return true;\n    }\n    return false;\n  }\n  on(payload?: INodePayload, _?: INodeContext): INodeResult | undefined {\n    if (payload?.event === ENodeEvent.Create) {\n      const node = new Heading();\n      const level = parseInt(payload?.token?.token?.tag?.substring(1) || '');\n      if (!isNaN(level)) {\n        node.level = level;\n      }\n      return { node };\n    }\n    return undefined;\n  }\n}\nclass ParagraphPlugin extends NodePlugin {\n  readonly name = 'paragraph';\n  should(payload?: INodePayload, _?: INodeContext) {\n    if (payload?.event === ENodeEvent.Create && payload?.token?.type === 'paragraph') {\n      return true;\n    }\n    if (payload?.event === ENodeEvent.DidFill && payload?.node?.type === ENode.Paragraph) {\n      return true;\n    }\n    return false;\n  }\n  on(payload?: INodePayload, _?: INodeContext): INodeResult | undefined {\n    if (payload?.event === ENodeEvent.Create) {\n      return { node: new Node({ type: ENode.Paragraph, layout: ELayout.Block, hidden: payload?.token?.token?.hidden }) };\n    }\n    return undefined;\n  }\n}\nclass CodePlugin extends NodePlugin {\n  readonly name = 'code';\n  should(payload?: INodePayload, _?: INodeContext) {\n    if (payload?.event === ENodeEvent.Create) {\n      if (payload?.token?.type === 'code_block' ||\n          payload?.token?.type === 'fence' ||\n          payload?.token?.type === 'code_inline') {\n        return true;\n      }\n    }\n    return false;\n  }\n  on(payload?: INodePayload, _?: INodeContext): INodeResult | undefined {\n    if (payload?.event === ENodeEvent.Create) {\n      const node = new Code({\n        layout: payload?.token?.type === 'code_inline' ? ELayout.Inline : ELayout.Block,\n        content: payload?.token?.token.content,\n      });\n      node.language = payload?.token?.token.info;\n      return { node }\n    }\n    return undefined;\n  }\n}\nclass ThematicBreakPlugin extends NodePlugin {\n  readonly name = 'thematic_break';\n  should(payload?: INodePayload, _?: INodeContext) {\n    if (payload?.event === ENodeEvent.Create && payload?.token?.type === 'hr') {\n      return true;\n    }\n    return false;\n  }\n  on(payload?: INodePayload, _?: INodeContext): INodeResult | undefined {\n    if (payload?.event === ENodeEvent.Create) {\n      return { node: new Node({ type: ENode.ThematicBreak, layout: ELayout.Block }) };\n    }\n    return undefined;\n  }\n}\nclass ListPlugin extends NodePlugin {\n  readonly name = 'list';\n  should(payload?: INodePayload, _?: INodeContext) {\n    if (payload?.event === ENodeEvent.Create) {\n      if (payload?.token?.type === 'bullet_list' ||\n          payload?.token?.type === 'ordered_list') {\n        return true;\n      }\n    }\n    if (payload?.event === ENodeEvent.DidFill) {\n      if (payload?.node?.type === ENode.List) {\n        return true;\n      }\n    }\n    return false;\n  }\n  on(payload?: INodePayload, _?: INodeContext): INodeResult | undefined {\n    if (payload?.event === ENodeEvent.Create) {\n      const node = new List();\n      if (payload?.token?.type === 'ordered_list') {\n        node.listType = EList.Ordered;\n      } else if (payload?.token?.type === 'bullet_list') {\n        const task = payload?.token?.token.attrs?.filter(ele => {\n          if (ele.length > 1) {\n            if (ele[0] === 'class' && /contains-task-list/.test(ele[1])) {\n              return true;\n            }\n          }\n          return false;\n        });\n        if (task && task.length > 0) {\n          node.listType = EList.Task;\n        } else {\n          node.listType = EList.Bullet;\n        }\n      }\n      return { node }\n    }\n    if (payload?.event === ENodeEvent.DidFill) {\n      if (payload?.node?.type === ENode.List) {\n        const listType = (payload?.node as List).listType;\n        (payload.node as List).children.filter(ele => {\n          return ele.type === ENode.ListItem;\n        }).forEach((ele, index) => {\n          (ele as ListItem).index = index;\n          if ((ele as ListItem).itemType === EListItem.Unknown) {\n            if (listType === EList.Bullet) {\n              (ele as ListItem).itemType = EListItem.Bullet;\n            } else if (listType === EList.Ordered) {\n              (ele as ListItem).itemType = EListItem.Ordered;\n            }\n          }\n        });\n      }\n    }\n    return undefined;\n  }\n}\nclass ListItemPlugin extends NodePlugin {\n  readonly name = 'list_item';\n  should(payload?: INodePayload, _?: INodeContext) {\n    if (payload?.event === ENodeEvent.Create && payload?.token?.type === 'list_item') {\n      return true;\n    }\n    if (payload?.event === ENodeEvent.DidFill && payload?.node?.type === ENode.ListItem) {\n      return true;\n    }\n    return false;\n  }\n  on(payload?: INodePayload, _?: INodeContext): INodeResult | undefined {\n    if (payload?.event === ENodeEvent.Create) {\n      const node = new ListItem();\n      node.info = payload?.token?.token.info;\n      const checkbox = payload?.token?.token.attrs?.filter(ele => {\n        if (ele.length > 1) {\n          if (ele[0] === 'class' && /task-list-item([\\s\\S]*)enabled/.test(ele[1])) {\n            return true;\n          }\n        }\n        return false;\n      });\n      if (checkbox && checkbox.length > 0) {\n        node.itemType = EListItem.CheckBox;\n      }\n      return { node };\n    }\n    if (payload?.event === ENodeEvent.DidFill && (payload?.node as ListItem)?.itemType === EListItem.CheckBox) {\n      if (payload?.node?.first?.deref()?.first?.deref()?.type === ENode.Inline) {\n        const inline = payload?.node?.first?.deref()?.first?.deref();\n        if (ListItem.isCheckNode(inline?.first?.deref())) {\n          (payload?.node as ListItem).checked = /checked=\"\"/.test(inline?.first?.deref()?.content || '');\n        }\n      }\n    }\n    return undefined;\n  }\n}\nclass TablePlugin extends NodePlugin {\n  readonly name = 'table';\n  should(payload?: INodePayload, _?: INodeContext) {\n    if (payload?.event === ENodeEvent.Create && payload?.token?.type === 'table') {\n      return true;\n    }\n    return false;\n  }\n  on(payload?: INodePayload, _?: INodeContext): INodeResult | undefined {\n    if (payload?.event === ENodeEvent.Create) {\n      return { node: new Node({ type: ENode.Table, layout: ELayout.Block }) };\n    }\n    return undefined;\n  }\n}\nclass TableItemPlugin extends NodePlugin {\n  readonly name = 'table_item';\n  should(payload?: INodePayload, _?: INodeContext) {\n    if (payload?.event === ENodeEvent.Create) {\n      if (payload?.token?.type === 'thead' ||\n          payload?.token?.type === 'tbody' ||\n          payload?.token?.type === 'tr' ||\n          payload?.token?.type === 'td' ||\n          payload?.token?.type === 'th') {\n        return true;\n      }\n    }\n    return false;\n  }\n  on(payload?: INodePayload, _?: INodeContext): INodeResult | undefined {\n    if (payload?.event === ENodeEvent.Create) {\n      const node = new TableItem();\n      if (payload?.token?.type === 'thead') {\n        node.itemType = ETableItem.Head;\n      } else if (payload?.token?.type === 'tbody') {\n        node.itemType = ETableItem.Body;\n      } else if (payload?.token?.type === 'tr') {\n        node.itemType = ETableItem.TR;\n      } else if (payload?.token?.type === 'td') {\n        node.itemType = ETableItem.TD;\n      } else if (payload?.token?.type === 'th') {\n        node.itemType = ETableItem.TH;\n      }\n      if (payload?.token?.type === 'td' ||\n          payload?.token?.type === 'th') {\n        payload?.token?.token.attrs?.forEach(ele => {\n          const name = ele.length > 0 ? ele[0] : undefined;\n          const value = ele.length > 1 ? ele[1] : undefined;\n          if (name === 'style') {\n            if (/text-align( *):( *)left/.test(value || '')) {\n              node.align = EAlignment.Left;\n            } else if (/text-align( *):( *)center/.test(value || '')) {\n              node.align = EAlignment.Center;\n            } else if (/text-align( *):( *)right/.test(value || '')) {\n              node.align = EAlignment.Right;\n            }\n          }\n        })\n      }\n      return { node }\n    }\n    return undefined;\n  }\n}\nclass ImagePlugin extends NodePlugin {\n  readonly name = 'image';\n  should(payload?: INodePayload, _?: INodeContext) {\n    if (payload?.event === ENodeEvent.Create && payload?.token?.type === 'image') {\n      return true;\n    }\n    return false;\n  }\n  on(payload?: INodePayload, _?: INodeContext): INodeResult | undefined {\n    if (payload?.event === ENodeEvent.Create) {\n      const node = new Image();\n      payload?.token?.token.attrs?.forEach(attr => {\n        const name = attr.length > 0 ? attr[0] : undefined;\n        const value = attr.length > 1 ? attr[1] : undefined;\n        if (name === 'src') {\n          node.src = value;\n        } else if (name === 'alt') {\n          node.alt = value;\n        }\n      });\n      return { node };\n    }\n    return undefined;\n  }\n}\nclass LinkPlugin extends NodePlugin {\n  readonly name = 'link';\n  should(payload?: INodePayload, _?: INodeContext) {\n    if (payload?.event === ENodeEvent.Create && payload?.token?.type === 'link') {\n      return true;\n    }\n    return false;\n  }\n  on(payload?: INodePayload, _?: INodeContext): INodeResult | undefined {\n    if (payload?.event === ENodeEvent.Create) {\n      const node = new Link();\n      payload?.token?.token.attrs?.forEach(attr => {\n        const name = attr.length > 0 ? attr[0] : undefined;\n        const value = attr.length > 1 ? attr[1] : undefined;\n        if (name === 'href') {\n          node.href = value;\n        }\n      });\n      return { node };\n    }\n    return undefined;\n  }\n}\nclass StrongPlugin extends NodePlugin {\n  readonly name = 'strong';\n  should(payload?: INodePayload, _?: INodeContext) {\n    if (payload?.event === ENodeEvent.Create && payload?.token?.type === 'strong') {\n      return true;\n    }\n    return false;\n  }\n  on(payload?: INodePayload, _?: INodeContext): INodeResult | undefined {\n    if (payload?.event === ENodeEvent.Create) {\n      return { node: new Node({ type: ENode.Strong, layout: ELayout.Inline }) };\n    }\n    return undefined;\n  }\n}\nclass EmphasisPlugin extends NodePlugin {\n  readonly name = 'emphasis';\n  should(payload?: INodePayload, _?: INodeContext) {\n    if (payload?.event === ENodeEvent.Create && payload?.token?.type === 'em') {\n      return true;\n    }\n    return false;\n  }\n  on(payload?: INodePayload, _?: INodeContext): INodeResult | undefined {\n    if (payload?.event === ENodeEvent.Create) {\n      return { node: new Node({ type: ENode.Emphasis, layout: ELayout.Inline }) };\n    }\n    return undefined;\n  }\n}\nclass StrikeThroughPlugin extends NodePlugin {\n  readonly name = 'strike_through';\n  should(payload?: INodePayload, _?: INodeContext) {\n    if (payload?.event === ENodeEvent.Create && payload?.token?.type === 's') {\n      return true;\n    }\n    return false;\n  }\n  on(payload?: INodePayload, _?: INodeContext): INodeResult | undefined {\n    if (payload?.event === ENodeEvent.Create) {\n      return { node: new Node({ type: ENode.StrikeThrough, layout: ELayout.Inline }) };\n    }\n    return undefined;\n  }\n}\nclass ScriptPlugin extends NodePlugin {\n  readonly name = 'script';\n  should(payload?: INodePayload, _?: INodeContext) {\n    if (payload?.event === ENodeEvent.Create) {\n      if (payload?.token?.type === 'sub' ||\n          payload?.token?.type === 'sup') {\n        return true;\n      }\n    }\n    return false;\n  }\n  on(payload?: INodePayload, _?: INodeContext): INodeResult | undefined {\n    if (payload?.event === ENodeEvent.Create) {\n      return { node: new Node({\n        layout: ELayout.Inline,\n        type: payload?.token?.type === 'sub' ? ENode.Subscript : ENode.Superscript\n      }) };\n    }\n    return undefined;\n  }\n}\nclass TextPlugin extends NodePlugin {\n  readonly name = 'text';\n  should(payload?: INodePayload, _?: INodeContext) {\n    if (payload?.event === ENodeEvent.Create && payload?.token?.type === 'text') {\n      return true;\n    }\n    return false;\n  }\n  on(payload?: INodePayload, _?: INodeContext): INodeResult | undefined {\n    if (payload?.event === ENodeEvent.Create) {\n      return { node: new Node({\n        type: ENode.Text, layout: ELayout.Inline, content: payload?.token?.token.content\n      }) };\n    }\n    return undefined;\n  }\n}\nclass BreakPlugin extends NodePlugin {\n  readonly name = 'break';\n  should(payload?: INodePayload, _?: INodeContext) {\n    if (payload?.event === ENodeEvent.Create) {\n      if (payload?.token?.type === 'softbreak' ||\n          payload?.token?.type === 'hardbreak') {\n        return true;\n      }\n    }\n    return false;\n  }\n  on(payload?: INodePayload, _?: INodeContext): INodeResult | undefined {\n    if (payload?.event === ENodeEvent.Create) {\n      const node = new LineBreak();\n      node.lineBreakType = payload?.token?.type === 'softbreak' ? ELineBreak.Soft : ELineBreak.Hard;\n      return { node };\n    }\n    return undefined;\n  }\n}\nclass FootnotePlugin extends NodePlugin {\n  readonly name = 'footnote';\n  should(payload?: INodePayload, _?: INodeContext) {\n    if (payload?.event === ENodeEvent.Create) {\n      //  footnote_block footnote_anchor 类型均忽略，仅通过 footnote_ref、footnote 创建REF、DEF\n      if (payload?.token?.type === 'footnote_ref') {\n        return true;\n      }\n      if (payload?.token?.type === 'footnote') {\n        return true;\n      }\n    }\n    return false;\n  }\n  on(payload?: INodePayload, _?: INodeContext): INodeResult | undefined {\n    if (payload?.event === ENodeEvent.Create) {\n      if (payload?.token?.type === 'footnote_ref') {\n        const node = new FootnoteRef();\n        node.footnoteId = (payload?.token?.token.meta as IAnyTokenMeta)?.id;\n        node.label = (payload?.token?.token.meta as IAnyTokenMeta)?.label;\n        return { node };\n      }\n      if (payload?.token?.type === 'footnote') {\n        const node = new FootnoteDef();\n        node.footnoteId = (payload?.token?.token.meta as IAnyTokenMeta)?.id;\n        node.label = (payload?.token?.token.meta as IAnyTokenMeta)?.label;\n        return { node };\n      }\n    }\n    return undefined;\n  }\n}\nclass EmojiPlugin extends NodePlugin {\n  readonly name = 'emoji';\n  should(payload?: INodePayload, _?: INodeContext) {\n    if (payload?.event === ENodeEvent.Create && payload?.token?.type === 'emoji') {\n      return true;\n    }\n    return false;\n  }\n  on(payload?: INodePayload, _?: INodeContext): INodeResult | undefined {\n    if (payload?.event === ENodeEvent.Create) {\n      const node = new Emoji({ content: payload?.token?.token.content });\n      node.markup = payload?.token?.token.markup;\n      return { node };\n    }\n    return undefined;\n  }\n}\nclass HtmlTagPlugin extends NodePlugin {\n  readonly name = 'html-tag';\n  should(payload?: INodePayload, _?: INodeContext) {\n    if (payload?.event === ENodeEvent.Create && payload?.token?.type === 'html_inline') {\n      return true;\n    }\n    return false;\n  }\n  on(payload?: INodePayload, _?: INodeContext): INodeResult | undefined {\n    if (payload?.event === ENodeEvent.Create) {\n      const node = new HtmlTag({ content: payload?.token?.token.content });\n      if (/<\\//.test(node.content || '')) {\n        node.state = EState.Close;\n      } else if (/<([\\s\\S]*)\\/>/.test(node.content || '')) {\n        node.state = EState.SelfClose;\n      } else if (HtmlTagPlugin.isVoidElement(node.content || '')) {\n        node.state = EState.SelfClose;\n      } else if (/<([\\s\\S]*)>/.test(node.content || '')) {\n        node.state = EState.Open;\n      }\n      if (node.state !== EState.Close) {\n        const html = this.engine()?.deref()?.html;\n        const doc = html?.parse(payload?.token?.token.content ?? '');\n        if (doc) {\n          const element = html?.toElement(doc.firstChild);\n          if (element) {\n            node.tagName = element.tagName;\n            element.attributes.forEach(ele => node.attributes.push({\n              name: ele.name,\n              value: ele.value,\n            }));\n          }\n        }\n      }\n      return { node };\n    }\n    return undefined;\n  }\n  static isVoidElement(content: string) {\n    const names: string[] = [\n      'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\n      'link', 'meta', 'param', 'source', 'track', 'wbr', 'icon',\n    ];\n    return RegExp(`<(${names.join('|')})([\\\\s\\\\S]*)/?>$`).test(content);\n  }\n}\nclass MathPlugin extends NodePlugin {\n  readonly name = 'math';\n  should(payload?: INodePayload, _?: INodeContext) {\n    if (payload?.event === ENodeEvent.Create &&\n      (payload?.token?.type === 'math_inline' ||\n        payload?.token?.type === 'math_block'))\n    {\n      return true;\n    }\n    return false;\n  }\n  on(payload?: INodePayload, _?: INodeContext): INodeResult | undefined {\n    if (payload?.event === ENodeEvent.Create) {\n      return {\n        node: new Math({\n          layout: payload.token?.token.block ? ELayout.Block : ELayout.Inline,\n          content: payload?.token?.token.content,\n        }),\n      }\n    }\n    return undefined;\n  }\n}\nclass InlinePlugin extends NodePlugin {\n  readonly name = 'inline';\n  should(payload?: INodePayload, _?: INodeContext) {\n    if (payload?.event === ENodeEvent.Create && payload?.token?.type === 'inline') {\n      return true;\n    }\n    return false;\n  }\n  on(payload?: INodePayload, _?: INodeContext): INodeResult | undefined {\n    if (payload?.event === ENodeEvent.Create) {\n      return { node: new Node({ type: ENode.Inline, layout: ELayout.Block }) };\n    }\n    return undefined;\n  }\n}\nclass DocumentPlugin extends NodePlugin {\n  readonly name = 'document';\n  should(payload?: INodePayload, _?: INodeContext) {\n    if (payload?.event === ENodeEvent.DidFill ||\n        payload?.event === ENodeEvent.DidAppend) {\n      if (payload?.node?.type === ENode.FootnoteRef ||\n          payload?.node?.type === ENode.FootnoteDef) {\n        return true;\n      }\n    }\n    return false;\n  }\n  on(payload?: INodePayload, context?: INodeContext): INodeResult | undefined {\n    if (payload?.event === ENodeEvent.DidAppend && context?.program?.document) {\n      if (payload?.node?.type === ENode.FootnoteRef) {\n        const ref = payload?.node as FootnoteRef;\n        context?.program?.document.footnoteRefs.push(new WeakRef(ref));\n      }\n      if (payload?.node?.type === ENode.FootnoteDef) {\n        const def = payload?.node as FootnoteDef;\n        context?.program?.document.footnoteDefs.push(new WeakRef(def));\n      }\n      return undefined;\n    }\n    if (payload?.event === ENodeEvent.DidFill && context?.program?.document) {\n      if (payload?.node?.type === ENode.FootnoteRef) {\n        const ref = payload?.node as FootnoteRef;\n        for (const def of context?.program?.document.footnoteDefs || []) {\n          if (def.deref()?.footnoteId === ref.footnoteId) {\n            ref.def = new WeakRef(def.deref() as FootnoteDef);\n            break;  // ref 只关联一个 def\n          }\n        }\n      }\n      if (payload?.node?.type === ENode.FootnoteDef) {\n        const def = payload?.node as FootnoteDef;\n        for (const ref of context?.program?.document.footnoteRefs || []) {\n          if (ref.deref()?.footnoteId === def.footnoteId) {\n            (ref.deref() as FootnoteRef).def = new WeakRef(def);\n            // break; def 可能关联多个 ref\n          }\n        }\n      }\n      return undefined;\n    }\n    return undefined;\n  }\n}\n\nexport const plugins = (): NodePlugin[] => {\n  return [\n    new DocumentPlugin(),\n    new QuotePlugin(),\n    new HeadingPlugin(),\n    new ParagraphPlugin(),\n    new CodePlugin(),\n    new ThematicBreakPlugin(),\n    new ListPlugin(),\n    new ListItemPlugin(),\n    new TablePlugin(),\n    new TableItemPlugin(),\n    new ImagePlugin(),\n    new LinkPlugin(),\n    new StrongPlugin(),\n    new EmphasisPlugin(),\n    new StrikeThroughPlugin(),\n    new ScriptPlugin(),\n    new TextPlugin(),\n    new BreakPlugin(),\n    new FootnotePlugin(),\n    new EmojiPlugin(),\n    new HtmlTagPlugin(),\n    new InlinePlugin(),\n    new MathPlugin(),\n  ];\n}\n\ninterface IAnyTokenMeta {\n  id?: number,\n  label?: string,\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/node/plugin/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport * from './plugin';\nexport * as BuildIn from './build-in';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/node/plugin/plugin.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport type { Node } from '../models';\nimport { Token } from '../../markdown-it';\nimport type { Program } from '../program';\nimport type { Engine } from '../../../../engine';\n\nexport enum EPlugin {\n  Unknown = 'unknown',\n  Node = 'node',\n}\nexport abstract class Plugin <\nP extends IPayload = IPayload,\nR extends IResult = IResult,\nC extends IContext = IContext,\n> {\n  readonly id: number = Plugin.gid();\n  abstract readonly type: EPlugin;\n  abstract readonly name: string;\n  abstract should(payload?: P, context?: C): boolean;\n  abstract on(payload?: P, context?: C): undefined | R;\n  emit(payload?: P, context?: C) {\n    if (!this.should(payload, context)) {\n      return undefined;\n    }\n    return this.on(payload, context);\n  }\n\n  private static _gid: number = 0;\n  private static gid() {\n    return Plugin._gid++;\n  }\n}\nexport interface IPayload {}\nexport interface IContext {}\nexport interface IResult {}\n\nexport enum ENodeEvent {\n  // @summary 节点创建\n  Create = 'create',\n  // @summary 节点添加到父节点完成\n  DidAppend = 'did-append',\n  // @summary 节点将要填充子节点\n  WillFill = 'will-fill',\n  // @summary 节点填充子节点完成\n  DidFill = 'did-fill',\n}\nexport interface INodeContext extends IContext {\n  program: Program;\n}\nexport interface INodePayload extends IPayload {\n  event?: ENodeEvent;\n  // @summary ENodeEvent.Create 时填充\n  token?: FatToken;\n  // @summary ENodeEvent.WillFill | ENodeEvent.DidFill 时填充\n  node?: Node;\n}\nexport interface INodeResult extends IResult {\n  // @summary ENodeEvent.Create 时填充\n  node?: Node;\n}\nexport abstract class NodePlugin extends Plugin<INodePayload, INodeResult, INodeContext> {\n  readonly type: EPlugin = EPlugin.Node;\n  engine: () => WeakRef<Engine> | undefined = () => undefined;\n  static fatToken(token: Token) {\n    return new FatToken(token);\n  }\n}\nclass FatToken {\n  readonly token: Token;\n  readonly type: string;\n  constructor(token: Token) {\n    this.token = token;\n    this.type = token.type.replace('_open', '').replace('_close', '');\n  }\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/node/program.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { Token } from '../markdown-it';\nimport * as M from './models';\nimport { ENodeEvent, NodePlugin, BuildIn } from './plugin';\nimport type { Engine } from '../../../engine';\n\ninterface IProgram {\n  engine: () => WeakRef<Engine> | undefined;\n}\nexport class Program {\n  nodes: M.Node[] = [];\n  private stacks: M.Node[] = [];\n  private option: IProgram;\n  readonly document: M.Document;\n  private nodePlugins: NodePlugin[] = BuildIn.plugins();\n\n  constructor(tokens: Token[], option: IProgram) {\n    this.option = option;\n    this.nodePlugins.forEach(ele => {\n      ele.engine = () => {\n        return this.option.engine();\n      };\n    });\n\n    M.Node.resetID();\n    this.document = new M.Document(tokens);\n\n    this.push(this.document);\n    const meet = (token: Token) => {\n      const node = this.create(token);\n      if (node) {\n\n        this.nodes.push(node);\n        node.on<M.Node>('did-remove-node', _node => {\n          if (_node) {\n            this.nodes = this.nodes.filter(ele => ele !== _node);\n          }\n        });\n\n        if (token.nesting === 1) {  //  open\n          this.append(node);\n          this.push(node);\n        } else if (token.nesting === -1) {  //  close\n          this.pop();\n        } else if (node.state === M.EState.Open) {\n          this.append(node);\n          this.push(node);\n        } else if (node.state === M.EState.Close) {\n          this.pop();\n        } else {\n          this.append(node);\n        }\n\n        if (token.children) {\n          this.push(node);\n          token.children?.forEach(ele => {\n            meet(ele);\n          });\n          this.pop();\n        }\n      }\n    };\n    tokens.forEach(ele => {\n      meet(ele);\n    });\n    this.pop();\n  }\n  private append(node: M.Node) {\n    this.current.append(node);\n    this.nodePlugins.forEach(ele => {\n      ele.emit({ event: ENodeEvent.DidAppend, node }, { program: this });\n    });\n  }\n  private push(node: M.Node) {\n    this.nodePlugins.forEach(ele => {\n      ele.emit({ event: ENodeEvent.WillFill, node }, { program: this });\n    });\n    this.stacks.push(node);\n  }\n  private pop() {\n    const node = this.stacks.pop();\n    this.nodePlugins.forEach(ele => {\n      ele.emit({ event: ENodeEvent.DidFill, node }, { program: this });\n    });\n  }\n  get current(): M.Node {\n    return this.stacks[this.stacks.length - 1];\n  }\n  private create(token: Token): M.Node | undefined {\n    const fatToken = NodePlugin.fatToken(token);\n    let node: M.Node | undefined = undefined;\n    for (const ele of this.nodePlugins) {\n      const _node = ele.emit({\n        event: ENodeEvent.Create,\n        token: fatToken,\n      }, {\n        program: this,\n      })?.node;\n      if (_node) {\n        node = _node;\n        break;\n      }\n    }\n    if (node) {\n      node.token = token;\n    }\n    return node;\n  }\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ast/service.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport {\n  type MarkdownIt, markdown,\n  plugin_footnote, plugin_emoji, plugin_sub, plugin_sup, plugin_taskList, plugin_katex,\n  type IPluginKatexOption, type IPluginTaskListOption, type Token,\n} from './markdown-it';\nimport { Program, Node, ENode, ELayout, Code, StyledContent, Fragment } from './node';\nimport { EService, Service } from '../../engine/service';\nimport { Plugin } from '../../engine/plugin';\nimport type { Engine } from '../../engine';\nimport { CssService } from '../css';\nimport type { Declaration, Rule } from '../css/csstree';\nimport { newLog } from '../../util';\n\nconst log = newLog('AstService');\n\ninterface IResult {\n  program: Program;\n  content?: string;\n}\n\nexport class AstService extends Service {\n  private static gid: number = 0;\n  readonly ID: number = AstService.gid++;\n  readonly type: EService = EService.AST;\n  private tail: Promise<IResult | void> = Promise.resolve();\n  private count: number = 0;\n  private plugins: AstServicePlugin[] = [];\n  private markdown_it: MarkdownIt;\n  constructor(engine?: Engine) {\n    super(engine);\n    const markdown_it = new markdown() as MarkdownIt;\n    markdown_it.set({ html: true });\n    markdown_it.disable(['html_block']);  // only support inline html\n\n    const plugins = [\n      plugin_footnote,\n      plugin_emoji,\n      plugin_sub,\n      plugin_sup,\n    ];\n    plugins.forEach(ele => markdown_it.use(ele));\n\n    markdown_it.use<IPluginTaskListOption>(plugin_taskList, { enabled: true });\n    markdown_it.use<IPluginKatexOption>(plugin_katex, { throwOnError: false });\n    this.markdown_it = markdown_it;\n  }\n  add<T extends Plugin = AstServicePlugin>(plugin: T): void {\n    if (plugin instanceof AstServicePlugin) {\n      this.plugins.push(plugin);\n    } else {\n      log.e(`${this.ID} add plugin error, not AstServicePlugin`);\n    }\n  }\n  private get parsePlugin(): AstServicePlugin<IAstPluginParse> | undefined {\n    return this.plugins.filter(ele => ele.type === EAstPlugin.Parse).pop();\n  }\n  parse(content: string): Promise<IResult> {\n    this.count++;\n    const tail = this.tail.then(async () => {\n      this.parsePlugin?.handler?.willParse?.(content);\n\n      const tokens = this.markdown_it.parse(content, new Object());\n      const program = new Program(tokens, {\n        engine: () => this.engine,\n      });\n      this.prepareFragment(program);\n      program.document.createHash();\n      this.prepareCodeBlock(program);\n\n      const result: IResult = { program, content };\n\n      this.parsePlugin?.handler?.didParse?.(result);\n\n      return result;\n    }).finally(() => {\n      this.count--;\n    });\n    this.tail = tail;\n    return tail;\n  }\n  get processing(): boolean {\n    return this.count > 0;\n  }\n  toHtml(node: Node): string {\n    const tokens: Token[] = [];\n    const document = node.document;\n    if (document) {\n      const startToken = node.token;\n      const endToken = node.next?.deref()?.token;\n      const pick = (from: number, list: Token[]) => {\n        for (let index = from; index < list.length; index++) {\n          if (list[index] === endToken) {\n            break;\n          }\n          tokens.push(list[index]);\n        }\n      };\n      const traver = (list: Token[]): boolean => {\n        for (let index = 0; index < list.length; index++) {\n          const token = list[index];\n          if (token === startToken) {\n            pick(index, list);\n            return true;\n          } else {\n            if (traver(token.children || [])) {\n              return true;\n            }\n          }\n        }\n        return false;\n      }\n      if (startToken) {\n        traver(document.tokens || []);\n      }\n    }\n    return this.markdown_it.renderer.render(tokens, this.markdown_it.options, new Object());\n  }\n  private prepareFragment(program: Program) {\n    if (!this.engine?.deref()?.ctx?.fragmentEnable) {\n      log.i(`${this.ID} ast fragment is disabled`);\n      return;\n    }\n    const blockMax = Number(this.engine?.deref()?.ctx?.fragmentBlockMax) || 10;\n    const ignoreNodes: ENode[] = [ ENode.FootnoteDef ];\n    log.i(`${this.ID} will prepare ast fragment. blockMax: ${this.engine?.deref()?.ctx?.fragmentBlockMax}`);\n    const fragments: Fragment[] = [];\n    const dequeue = () => {\n      let fragment = fragments.slice(-1).pop();\n      if (!fragment) {\n        fragment = new Fragment();\n        fragments.push(fragment);\n      } else {\n        let blockCount: number = 0;\n        let child = fragment.first?.deref();\n        while (child) {\n          if (child.layout === ELayout.Block && !ignoreNodes.includes(child.type)) {\n            blockCount++;\n          }\n          child = child.next?.deref();\n        }\n        if (blockCount >= blockMax) {\n          fragment = new Fragment();\n          fragments.push(fragment);\n        }\n      }\n      return fragment;\n    };\n    let node = program.document.first?.deref();\n    while (node) {\n      const fragment = dequeue();\n      fragment.append(node);\n      node = program.document.first?.deref();\n    }\n    fragments.forEach(ele => {\n      program.document.append(ele);\n    });\n    log.i(`${this.ID} did prepare ast fragment. fragments: ${fragments.length}`);\n  }\n  private prepareCodeBlock(program: Program) {\n    const codes: Code[] = [];\n    Node.traverse(program.document, {\n      on: node => {\n        codes.push(node as Code);\n        return true;\n      },\n      filter: node => {\n        return node.type === ENode.Code && node.layout === ELayout.Block;\n      },\n    });\n    for (const code of codes) {\n      if (code.content) {\n        const page = this.engine?.deref()?.code?.parse4page(code.content, { language: code.language || '' });\n        if (page) {\n          const html = this.engine?.deref()?.html?.parse(page);\n          const css = this.engine?.deref()?.code?.css;\n          if (html && css) {\n            this.engine?.deref()?.html?.traverse(html, {\n              on: htmlNode => {\n                const element = this.engine?.deref()?.html?.toElement(htmlNode);\n                if (element) {\n                  const cls = element.attribs['class']?.split(' ').filter(ele => ele.length > 0) || [];\n                  if (cls && cls.length > 0) {\n                    let style = element.attribs['style'] ? `${element.attribs['style']};` : '';\n                    CssService.findAll<Rule>(css, rule => {\n                      return rule.type === 'Rule';\n                    }).forEach(rule => {\n                      const matched = CssService.find(rule.prelude, prelude => {\n                        if (prelude.type === 'ClassSelector') {\n                          return cls.indexOf(prelude.name) !== -1;\n                        }\n                        return false;\n                      });\n                      if (matched) {\n                        CssService.findAll<Declaration>(rule.block, block => {\n                          return block.type === 'Declaration';\n                        }).forEach(declaration => {\n                          style = `${style} ${declaration.property}: ${CssService.generate(declaration.value)};`;\n                        });\n                      }\n                    });\n                    if (style.length > 0) {\n                      element.attribs['style'] = `${style} font-size: 13;`;\n                    }\n                  }\n                }\n                return true;\n              },\n            });\n            const adapted = this.engine?.deref()?.html?.render(html);\n            if (adapted && adapted.length > 0) {\n              const styled = new StyledContent();\n              styled.createHash();\n              styled.styled = this.engine?.deref()?.code?.styledFromHtml(adapted);\n              program.nodes.push(styled);\n              code.append(styled);\n            }\n          }\n        }\n      }\n    }\n  }\n}\n\nexport interface IFragment {\n  enable?: boolean;\n  blockMax?: number;\n}\n\nexport enum EAstPlugin {\n  Unknown = 'unknown',\n  Parse = 'parse',\n}\nexport interface IAstPlugin {}\nexport interface IAstPluginParse extends IAstPlugin {\n  willParse?: (content: string) => void;\n  didParse?: (result: IResult) => void;\n}\nexport abstract class AstServicePlugin <\n  T extends IAstPlugin = IAstPlugin,\n> extends Plugin {\n  abstract readonly type: EAstPlugin;\n  abstract readonly handler: T;\n}\n\n// export { Program, Node };"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/code/highlightjs/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/**\n * highlight.js\n * @home   : https://github.com/highlightjs/highlight.js\n * @branch : master\n * @commit : 5697ae5187746c24732e62cd625f3f83004a44ce\n */\n\nimport type { HL } from './src/types';\nimport { hljs } from './src/highlight';\n\nconst hl: HL = hljs;\nexport { hl };\nexport * from './src/types';\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/code/highlightjs/src/highlight.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/*!\n  Highlight.js v11.11.1 (git: 5697ae5187)\n  (c) 2006-2025 Josh Goebel <hello@joshgoebel.com> and other contributors\n  License: BSD-3-Clause\n */\nvar hljs = (function () {\n  'use strict';\n\n  /* eslint-disable no-multi-assign */\n\n  function deepFreeze(obj) {\n    if (obj instanceof Map) {\n      obj.clear =\n        obj.delete =\n        obj.set =\n          function () {\n            throw new Error('map is read-only');\n          };\n    } else if (obj instanceof Set) {\n      obj.add =\n        obj.clear =\n        obj.delete =\n          function () {\n            throw new Error('set is read-only');\n          };\n    }\n\n    // Freeze self\n    Object.freeze(obj);\n\n    Object.getOwnPropertyNames(obj).forEach((name) => {\n      const prop = obj[name];\n      const type = typeof prop;\n\n      // Freeze prop if it is an object or function and also not already frozen\n      if ((type === 'object' || type === 'function') && !Object.isFrozen(prop)) {\n        deepFreeze(prop);\n      }\n    });\n\n    return obj;\n  }\n\n  /** @typedef {import('highlight.js').CallbackResponse} CallbackResponse */\n  /** @typedef {import('highlight.js').CompiledMode} CompiledMode */\n  /** @implements CallbackResponse */\n\n  class Response {\n    /**\n     * @param {CompiledMode} mode\n     */\n    constructor(mode) {\n      // eslint-disable-next-line no-undefined\n      if (mode.data === undefined) mode.data = {};\n\n      this.data = mode.data;\n      this.isMatchIgnored = false;\n    }\n\n    ignoreMatch() {\n      this.isMatchIgnored = true;\n    }\n  }\n\n  /**\n   * @param {string} value\n   * @returns {string}\n   */\n  function escapeHTML(value) {\n    return value\n      .replace(/&/g, '&amp;')\n      .replace(/</g, '&lt;')\n      .replace(/>/g, '&gt;')\n      .replace(/\"/g, '&quot;')\n      .replace(/'/g, '&#x27;');\n  }\n\n  /**\n   * performs a shallow merge of multiple objects into one\n   *\n   * @template T\n   * @param {T} original\n   * @param {Record<string,any>[]} objects\n   * @returns {T} a single new object\n   */\n  function inherit$1(original, ...objects) {\n    /** @type Record<string,any> */\n    const result = Object.create(null);\n\n    for (const key in original) {\n      result[key] = original[key];\n    }\n    objects.forEach(function(obj) {\n      for (const key in obj) {\n        result[key] = obj[key];\n      }\n    });\n    return /** @type {T} */ (result);\n  }\n\n  /**\n   * @typedef {object} Renderer\n   * @property {(text: string) => void} addText\n   * @property {(node: Node) => void} openNode\n   * @property {(node: Node) => void} closeNode\n   * @property {() => string} value\n   */\n\n  /** @typedef {{scope?: string, language?: string, sublanguage?: boolean}} Node */\n  /** @typedef {{walk: (r: Renderer) => void}} Tree */\n  /** */\n\n  const SPAN_CLOSE = '</span>';\n\n  /**\n   * Determines if a node needs to be wrapped in <span>\n   *\n   * @param {Node} node */\n  const emitsWrappingTags = (node) => {\n    // rarely we can have a sublanguage where language is undefined\n    // TODO: track down why\n    return !!node.scope;\n  };\n\n  /**\n   *\n   * @param {string} name\n   * @param {{prefix:string}} options\n   */\n  const scopeToCSSClass = (name, { prefix }) => {\n    // sub-language\n    if (name.startsWith(\"language:\")) {\n      return name.replace(\"language:\", \"language-\");\n    }\n    // tiered scope: comment.line\n    if (name.includes(\".\")) {\n      const pieces = name.split(\".\");\n      return [\n        `${prefix}${pieces.shift()}`,\n        ...(pieces.map((x, i) => `${x}${\"_\".repeat(i + 1)}`))\n      ].join(\" \");\n    }\n    // simple scope\n    return `${prefix}${name}`;\n  };\n\n  /** @type {Renderer} */\n  class HTMLRenderer {\n    /**\n     * Creates a new HTMLRenderer\n     *\n     * @param {Tree} parseTree - the parse tree (must support `walk` API)\n     * @param {{classPrefix: string}} options\n     */\n    constructor(parseTree, options) {\n      this.buffer = \"\";\n      this.classPrefix = options.classPrefix;\n      parseTree.walk(this);\n    }\n\n    /**\n     * Adds texts to the output stream\n     *\n     * @param {string} text */\n    addText(text) {\n      this.buffer += escapeHTML(text);\n    }\n\n    /**\n     * Adds a node open to the output stream (if needed)\n     *\n     * @param {Node} node */\n    openNode(node) {\n      if (!emitsWrappingTags(node)) return;\n\n      const className = scopeToCSSClass(node.scope,\n        { prefix: this.classPrefix });\n      this.span(className);\n    }\n\n    /**\n     * Adds a node close to the output stream (if needed)\n     *\n     * @param {Node} node */\n    closeNode(node) {\n      if (!emitsWrappingTags(node)) return;\n\n      this.buffer += SPAN_CLOSE;\n    }\n\n    /**\n     * returns the accumulated buffer\n    */\n    value() {\n      return this.buffer;\n    }\n\n    // helpers\n\n    /**\n     * Builds a span element\n     *\n     * @param {string} className */\n    span(className) {\n      this.buffer += `<span class=\"${className}\">`;\n    }\n  }\n\n  /** @typedef {{scope?: string, language?: string, children: Node[]} | string} Node */\n  /** @typedef {{scope?: string, language?: string, children: Node[]} } DataNode */\n  /** @typedef {import('highlight.js').Emitter} Emitter */\n  /**  */\n\n  /** @returns {DataNode} */\n  const newNode = (opts = {}) => {\n    /** @type DataNode */\n    const result = { children: [] };\n    Object.assign(result, opts);\n    return result;\n  };\n\n  class TokenTree {\n    constructor() {\n      /** @type DataNode */\n      this.rootNode = newNode();\n      this.stack = [this.rootNode];\n    }\n\n    get top() {\n      return this.stack[this.stack.length - 1];\n    }\n\n    get root() { return this.rootNode; }\n\n    /** @param {Node} node */\n    add(node) {\n      this.top.children.push(node);\n    }\n\n    /** @param {string} scope */\n    openNode(scope) {\n      /** @type Node */\n      const node = newNode({ scope });\n      this.add(node);\n      this.stack.push(node);\n    }\n\n    closeNode() {\n      if (this.stack.length > 1) {\n        return this.stack.pop();\n      }\n      // eslint-disable-next-line no-undefined\n      return undefined;\n    }\n\n    closeAllNodes() {\n      while (this.closeNode());\n    }\n\n    toJSON() {\n      return JSON.stringify(this.rootNode, null, 4);\n    }\n\n    /**\n     * @typedef { import(\"./html_renderer\").Renderer } Renderer\n     * @param {Renderer} builder\n     */\n    walk(builder) {\n      // this does not\n      return this.constructor._walk(builder, this.rootNode);\n      // this works\n      // return TokenTree._walk(builder, this.rootNode);\n    }\n\n    /**\n     * @param {Renderer} builder\n     * @param {Node} node\n     */\n    static _walk(builder, node) {\n      if (typeof node === \"string\") {\n        builder.addText(node);\n      } else if (node.children) {\n        builder.openNode(node);\n        node.children.forEach((child) => this._walk(builder, child));\n        builder.closeNode(node);\n      }\n      return builder;\n    }\n\n    /**\n     * @param {Node} node\n     */\n    static _collapse(node) {\n      if (typeof node === \"string\") return;\n      if (!node.children) return;\n\n      if (node.children.every(el => typeof el === \"string\")) {\n        // node.text = node.children.join(\"\");\n        // delete node.children;\n        node.children = [node.children.join(\"\")];\n      } else {\n        node.children.forEach((child) => {\n          TokenTree._collapse(child);\n        });\n      }\n    }\n  }\n\n  /**\n    Currently this is all private API, but this is the minimal API necessary\n    that an Emitter must implement to fully support the parser.\n\n    Minimal interface:\n\n    - addText(text)\n    - __addSublanguage(emitter, subLanguageName)\n    - startScope(scope)\n    - endScope()\n    - finalize()\n    - toHTML()\n\n  */\n\n  /**\n   * @implements {Emitter}\n   */\n  class TokenTreeEmitter extends TokenTree {\n    /**\n     * @param {*} options\n     */\n    constructor(options) {\n      super();\n      this.options = options;\n    }\n\n    /**\n     * @param {string} text\n     */\n    addText(text) {\n      if (text === \"\") { return; }\n\n      this.add(text);\n    }\n\n    /** @param {string} scope */\n    startScope(scope) {\n      this.openNode(scope);\n    }\n\n    endScope() {\n      this.closeNode();\n    }\n\n    /**\n     * @param {Emitter & {root: DataNode}} emitter\n     * @param {string} name\n     */\n    __addSublanguage(emitter, name) {\n      /** @type DataNode */\n      const node = emitter.root;\n      if (name) node.scope = `language:${name}`;\n\n      this.add(node);\n    }\n\n    toHTML() {\n      const renderer = new HTMLRenderer(this, this.options);\n      return renderer.value();\n    }\n\n    finalize() {\n      this.closeAllNodes();\n      return true;\n    }\n  }\n\n  /**\n   * @param {string} value\n   * @returns {RegExp}\n   * */\n\n  /**\n   * @param {RegExp | string } re\n   * @returns {string}\n   */\n  function source(re) {\n    if (!re) return null;\n    if (typeof re === \"string\") return re;\n\n    return re.source;\n  }\n\n  /**\n   * @param {RegExp | string } re\n   * @returns {string}\n   */\n  function lookahead(re) {\n    return concat('(?=', re, ')');\n  }\n\n  /**\n   * @param {RegExp | string } re\n   * @returns {string}\n   */\n  function anyNumberOfTimes(re) {\n    return concat('(?:', re, ')*');\n  }\n\n  /**\n   * @param {RegExp | string } re\n   * @returns {string}\n   */\n  function optional(re) {\n    return concat('(?:', re, ')?');\n  }\n\n  /**\n   * @param {...(RegExp | string) } args\n   * @returns {string}\n   */\n  function concat(...args) {\n    const joined = args.map((x) => source(x)).join(\"\");\n    return joined;\n  }\n\n  /**\n   * @param { Array<string | RegExp | Object> } args\n   * @returns {object}\n   */\n  function stripOptionsFromArgs(args) {\n    const opts = args[args.length - 1];\n\n    if (typeof opts === 'object' && opts.constructor === Object) {\n      args.splice(args.length - 1, 1);\n      return opts;\n    } else {\n      return {};\n    }\n  }\n\n  /** @typedef { {capture?: boolean} } RegexEitherOptions */\n\n  /**\n   * Any of the passed expresssions may match\n   *\n   * Creates a huge this | this | that | that match\n   * @param {(RegExp | string)[] | [...(RegExp | string)[], RegexEitherOptions]} args\n   * @returns {string}\n   */\n  function either(...args) {\n    /** @type { object & {capture?: boolean} }  */\n    const opts = stripOptionsFromArgs(args);\n    const joined = '('\n      + (opts.capture ? \"\" : \"?:\")\n      + args.map((x) => source(x)).join(\"|\") + \")\";\n    return joined;\n  }\n\n  /**\n   * @param {RegExp | string} re\n   * @returns {number}\n   */\n  function countMatchGroups(re) {\n    return (new RegExp(re.toString() + '|')).exec('').length - 1;\n  }\n\n  /**\n   * Does lexeme start with a regular expression match at the beginning\n   * @param {RegExp} re\n   * @param {string} lexeme\n   */\n  function startsWith(re, lexeme) {\n    const match = re && re.exec(lexeme);\n    return match && match.index === 0;\n  }\n\n  // BACKREF_RE matches an open parenthesis or backreference. To avoid\n  // an incorrect parse, it additionally matches the following:\n  // - [...] elements, where the meaning of parentheses and escapes change\n  // - other escape sequences, so we do not misparse escape sequences as\n  //   interesting elements\n  // - non-matching or lookahead parentheses, which do not capture. These\n  //   follow the '(' with a '?'.\n  const BACKREF_RE = /\\[(?:[^\\\\\\]]|\\\\.)*\\]|\\(\\??|\\\\([1-9][0-9]*)|\\\\./;\n\n  // **INTERNAL** Not intended for outside usage\n  // join logically computes regexps.join(separator), but fixes the\n  // backreferences so they continue to match.\n  // it also places each individual regular expression into it's own\n  // match group, keeping track of the sequencing of those match groups\n  // is currently an exercise for the caller. :-)\n  /**\n   * @param {(string | RegExp)[]} regexps\n   * @param {{joinWith: string}} opts\n   * @returns {string}\n   */\n  function _rewriteBackreferences(regexps, { joinWith }) {\n    let numCaptures = 0;\n\n    return regexps.map((regex) => {\n      numCaptures += 1;\n      const offset = numCaptures;\n      let re = source(regex);\n      let out = '';\n\n      while (re.length > 0) {\n        const match = BACKREF_RE.exec(re);\n        if (!match) {\n          out += re;\n          break;\n        }\n        out += re.substring(0, match.index);\n        re = re.substring(match.index + match[0].length);\n        if (match[0][0] === '\\\\' && match[1]) {\n          // Adjust the backreference.\n          out += '\\\\' + String(Number(match[1]) + offset);\n        } else {\n          out += match[0];\n          if (match[0] === '(') {\n            numCaptures++;\n          }\n        }\n      }\n      return out;\n    }).map(re => `(${re})`).join(joinWith);\n  }\n\n  /** @typedef {import('highlight.js').Mode} Mode */\n  /** @typedef {import('highlight.js').ModeCallback} ModeCallback */\n\n  // Common regexps\n  const MATCH_NOTHING_RE = /\\b\\B/;\n  const IDENT_RE$1 = '[a-zA-Z]\\\\w*';\n  const UNDERSCORE_IDENT_RE = '[a-zA-Z_]\\\\w*';\n  const NUMBER_RE = '\\\\b\\\\d+(\\\\.\\\\d+)?';\n  const C_NUMBER_RE = '(-?)(\\\\b0[xX][a-fA-F0-9]+|(\\\\b\\\\d+(\\\\.\\\\d*)?|\\\\.\\\\d+)([eE][-+]?\\\\d+)?)'; // 0x..., 0..., decimal, float\n  const BINARY_NUMBER_RE = '\\\\b(0b[01]+)'; // 0b...\n  const RE_STARTERS_RE = '!|!=|!==|%|%=|&|&&|&=|\\\\*|\\\\*=|\\\\+|\\\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\\\?|\\\\[|\\\\{|\\\\(|\\\\^|\\\\^=|\\\\||\\\\|=|\\\\|\\\\||~';\n\n  /**\n  * @param { Partial<Mode> & {binary?: string | RegExp} } opts\n  */\n  const SHEBANG = (opts = {}) => {\n    const beginShebang = /^#![ ]*\\//;\n    if (opts.binary) {\n      opts.begin = concat(\n        beginShebang,\n        /.*\\b/,\n        opts.binary,\n        /\\b.*/);\n    }\n    return inherit$1({\n      scope: 'meta',\n      begin: beginShebang,\n      end: /$/,\n      relevance: 0,\n      /** @type {ModeCallback} */\n      \"on:begin\": (m, resp) => {\n        if (m.index !== 0) resp.ignoreMatch();\n      }\n    }, opts);\n  };\n\n  // Common modes\n  const BACKSLASH_ESCAPE = {\n    begin: '\\\\\\\\[\\\\s\\\\S]', relevance: 0\n  };\n  const APOS_STRING_MODE = {\n    scope: 'string',\n    begin: '\\'',\n    end: '\\'',\n    illegal: '\\\\n',\n    contains: [BACKSLASH_ESCAPE]\n  };\n  const QUOTE_STRING_MODE = {\n    scope: 'string',\n    begin: '\"',\n    end: '\"',\n    illegal: '\\\\n',\n    contains: [BACKSLASH_ESCAPE]\n  };\n  const PHRASAL_WORDS_MODE = {\n    begin: /\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b/\n  };\n  /**\n   * Creates a comment mode\n   *\n   * @param {string | RegExp} begin\n   * @param {string | RegExp} end\n   * @param {Mode | {}} [modeOptions]\n   * @returns {Partial<Mode>}\n   */\n  const COMMENT = function(begin, end, modeOptions = {}) {\n    const mode = inherit$1(\n      {\n        scope: 'comment',\n        begin,\n        end,\n        contains: []\n      },\n      modeOptions\n    );\n    mode.contains.push({\n      scope: 'doctag',\n      // hack to avoid the space from being included. the space is necessary to\n      // match here to prevent the plain text rule below from gobbling up doctags\n      begin: '[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)',\n      end: /(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,\n      excludeBegin: true,\n      relevance: 0\n    });\n    const ENGLISH_WORD = either(\n      // list of common 1 and 2 letter words in English\n      \"I\",\n      \"a\",\n      \"is\",\n      \"so\",\n      \"us\",\n      \"to\",\n      \"at\",\n      \"if\",\n      \"in\",\n      \"it\",\n      \"on\",\n      // note: this is not an exhaustive list of contractions, just popular ones\n      /[A-Za-z]+['](d|ve|re|ll|t|s|n)/, // contractions - can't we'd they're let's, etc\n      /[A-Za-z]+[-][a-z]+/, // `no-way`, etc.\n      /[A-Za-z][a-z]{2,}/ // allow capitalized words at beginning of sentences\n    );\n    // looking like plain text, more likely to be a comment\n    mode.contains.push(\n      {\n        // TODO: how to include \", (, ) without breaking grammars that use these for\n        // comment delimiters?\n        // begin: /[ ]+([()\"]?([A-Za-z'-]{3,}|is|a|I|so|us|[tT][oO]|at|if|in|it|on)[.]?[()\":]?([.][ ]|[ ]|\\))){3}/\n        // ---\n\n        // this tries to find sequences of 3 english words in a row (without any\n        // \"programming\" type syntax) this gives us a strong signal that we've\n        // TRULY found a comment - vs perhaps scanning with the wrong language.\n        // It's possible to find something that LOOKS like the start of the\n        // comment - but then if there is no readable text - good chance it is a\n        // false match and not a comment.\n        //\n        // for a visual example please see:\n        // https://github.com/highlightjs/highlight.js/issues/2827\n\n        begin: concat(\n          /[ ]+/, // necessary to prevent us gobbling up doctags like /* @author Bob Mcgill */\n          '(',\n          ENGLISH_WORD,\n          /[.]?[:]?([.][ ]|[ ])/,\n          '){3}') // look for 3 words in a row\n      }\n    );\n    return mode;\n  };\n  const C_LINE_COMMENT_MODE = COMMENT('//', '$');\n  const C_BLOCK_COMMENT_MODE = COMMENT('/\\\\*', '\\\\*/');\n  const HASH_COMMENT_MODE = COMMENT('#', '$');\n  const NUMBER_MODE = {\n    scope: 'number',\n    begin: NUMBER_RE,\n    relevance: 0\n  };\n  const C_NUMBER_MODE = {\n    scope: 'number',\n    begin: C_NUMBER_RE,\n    relevance: 0\n  };\n  const BINARY_NUMBER_MODE = {\n    scope: 'number',\n    begin: BINARY_NUMBER_RE,\n    relevance: 0\n  };\n  const REGEXP_MODE = {\n    scope: \"regexp\",\n    begin: /\\/(?=[^/\\n]*\\/)/,\n    end: /\\/[gimuy]*/,\n    contains: [\n      BACKSLASH_ESCAPE,\n      {\n        begin: /\\[/,\n        end: /\\]/,\n        relevance: 0,\n        contains: [BACKSLASH_ESCAPE]\n      }\n    ]\n  };\n  const TITLE_MODE = {\n    scope: 'title',\n    begin: IDENT_RE$1,\n    relevance: 0\n  };\n  const UNDERSCORE_TITLE_MODE = {\n    scope: 'title',\n    begin: UNDERSCORE_IDENT_RE,\n    relevance: 0\n  };\n  const METHOD_GUARD = {\n    // excludes method names from keyword processing\n    begin: '\\\\.\\\\s*' + UNDERSCORE_IDENT_RE,\n    relevance: 0\n  };\n\n  /**\n   * Adds end same as begin mechanics to a mode\n   *\n   * Your mode must include at least a single () match group as that first match\n   * group is what is used for comparison\n   * @param {Partial<Mode>} mode\n   */\n  const END_SAME_AS_BEGIN = function(mode) {\n    return Object.assign(mode,\n      {\n        /** @type {ModeCallback} */\n        'on:begin': (m, resp) => { resp.data._beginMatch = m[1]; },\n        /** @type {ModeCallback} */\n        'on:end': (m, resp) => { if (resp.data._beginMatch !== m[1]) resp.ignoreMatch(); }\n      });\n  };\n\n  var MODES$1 = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    APOS_STRING_MODE: APOS_STRING_MODE,\n    BACKSLASH_ESCAPE: BACKSLASH_ESCAPE,\n    BINARY_NUMBER_MODE: BINARY_NUMBER_MODE,\n    BINARY_NUMBER_RE: BINARY_NUMBER_RE,\n    COMMENT: COMMENT,\n    C_BLOCK_COMMENT_MODE: C_BLOCK_COMMENT_MODE,\n    C_LINE_COMMENT_MODE: C_LINE_COMMENT_MODE,\n    C_NUMBER_MODE: C_NUMBER_MODE,\n    C_NUMBER_RE: C_NUMBER_RE,\n    END_SAME_AS_BEGIN: END_SAME_AS_BEGIN,\n    HASH_COMMENT_MODE: HASH_COMMENT_MODE,\n    IDENT_RE: IDENT_RE$1,\n    MATCH_NOTHING_RE: MATCH_NOTHING_RE,\n    METHOD_GUARD: METHOD_GUARD,\n    NUMBER_MODE: NUMBER_MODE,\n    NUMBER_RE: NUMBER_RE,\n    PHRASAL_WORDS_MODE: PHRASAL_WORDS_MODE,\n    QUOTE_STRING_MODE: QUOTE_STRING_MODE,\n    REGEXP_MODE: REGEXP_MODE,\n    RE_STARTERS_RE: RE_STARTERS_RE,\n    SHEBANG: SHEBANG,\n    TITLE_MODE: TITLE_MODE,\n    UNDERSCORE_IDENT_RE: UNDERSCORE_IDENT_RE,\n    UNDERSCORE_TITLE_MODE: UNDERSCORE_TITLE_MODE\n  });\n\n  /**\n  @typedef {import('highlight.js').CallbackResponse} CallbackResponse\n  @typedef {import('highlight.js').CompilerExt} CompilerExt\n  */\n\n  // Grammar extensions / plugins\n  // See: https://github.com/highlightjs/highlight.js/issues/2833\n\n  // Grammar extensions allow \"syntactic sugar\" to be added to the grammar modes\n  // without requiring any underlying changes to the compiler internals.\n\n  // `compileMatch` being the perfect small example of now allowing a grammar\n  // author to write `match` when they desire to match a single expression rather\n  // than being forced to use `begin`.  The extension then just moves `match` into\n  // `begin` when it runs.  Ie, no features have been added, but we've just made\n  // the experience of writing (and reading grammars) a little bit nicer.\n\n  // ------\n\n  // TODO: We need negative look-behind support to do this properly\n  /**\n   * Skip a match if it has a preceding dot\n   *\n   * This is used for `beginKeywords` to prevent matching expressions such as\n   * `bob.keyword.do()`. The mode compiler automatically wires this up as a\n   * special _internal_ 'on:begin' callback for modes with `beginKeywords`\n   * @param {RegExpMatchArray} match\n   * @param {CallbackResponse} response\n   */\n  function skipIfHasPrecedingDot(match, response) {\n    const before = match.input[match.index - 1];\n    if (before === \".\") {\n      response.ignoreMatch();\n    }\n  }\n\n  /**\n   *\n   * @type {CompilerExt}\n   */\n  function scopeClassName(mode, _parent) {\n    // eslint-disable-next-line no-undefined\n    if (mode.className !== undefined) {\n      mode.scope = mode.className;\n      delete mode.className;\n    }\n  }\n\n  /**\n   * `beginKeywords` syntactic sugar\n   * @type {CompilerExt}\n   */\n  function beginKeywords(mode, parent) {\n    if (!parent) return;\n    if (!mode.beginKeywords) return;\n\n    // for languages with keywords that include non-word characters checking for\n    // a word boundary is not sufficient, so instead we check for a word boundary\n    // or whitespace - this does no harm in any case since our keyword engine\n    // doesn't allow spaces in keywords anyways and we still check for the boundary\n    // first\n    mode.begin = '\\\\b(' + mode.beginKeywords.split(' ').join('|') + ')(?!\\\\.)(?=\\\\b|\\\\s)';\n    mode.__beforeBegin = skipIfHasPrecedingDot;\n    mode.keywords = mode.keywords || mode.beginKeywords;\n    delete mode.beginKeywords;\n\n    // prevents double relevance, the keywords themselves provide\n    // relevance, the mode doesn't need to double it\n    // eslint-disable-next-line no-undefined\n    if (mode.relevance === undefined) mode.relevance = 0;\n  }\n\n  /**\n   * Allow `illegal` to contain an array of illegal values\n   * @type {CompilerExt}\n   */\n  function compileIllegal(mode, _parent) {\n    if (!Array.isArray(mode.illegal)) return;\n\n    mode.illegal = either(...mode.illegal);\n  }\n\n  /**\n   * `match` to match a single expression for readability\n   * @type {CompilerExt}\n   */\n  function compileMatch(mode, _parent) {\n    if (!mode.match) return;\n    if (mode.begin || mode.end) throw new Error(\"begin & end are not supported with match\");\n\n    mode.begin = mode.match;\n    delete mode.match;\n  }\n\n  /**\n   * provides the default 1 relevance to all modes\n   * @type {CompilerExt}\n   */\n  function compileRelevance(mode, _parent) {\n    // eslint-disable-next-line no-undefined\n    if (mode.relevance === undefined) mode.relevance = 1;\n  }\n\n  // allow beforeMatch to act as a \"qualifier\" for the match\n  // the full match begin must be [beforeMatch][begin]\n  const beforeMatchExt = (mode, parent) => {\n    if (!mode.beforeMatch) return;\n    // starts conflicts with endsParent which we need to make sure the child\n    // rule is not matched multiple times\n    if (mode.starts) throw new Error(\"beforeMatch cannot be used with starts\");\n\n    const originalMode = Object.assign({}, mode);\n    Object.keys(mode).forEach((key) => { delete mode[key]; });\n\n    mode.keywords = originalMode.keywords;\n    mode.begin = concat(originalMode.beforeMatch, lookahead(originalMode.begin));\n    mode.starts = {\n      relevance: 0,\n      contains: [\n        Object.assign(originalMode, { endsParent: true })\n      ]\n    };\n    mode.relevance = 0;\n\n    delete originalMode.beforeMatch;\n  };\n\n  // keywords that should have no default relevance value\n  const COMMON_KEYWORDS = [\n    'of',\n    'and',\n    'for',\n    'in',\n    'not',\n    'or',\n    'if',\n    'then',\n    'parent', // common variable name\n    'list', // common variable name\n    'value' // common variable name\n  ];\n\n  const DEFAULT_KEYWORD_SCOPE = \"keyword\";\n\n  /**\n   * Given raw keywords from a language definition, compile them.\n   *\n   * @param {string | Record<string,string|string[]> | Array<string>} rawKeywords\n   * @param {boolean} caseInsensitive\n   */\n  function compileKeywords(rawKeywords, caseInsensitive, scopeName = DEFAULT_KEYWORD_SCOPE) {\n    /** @type {import(\"highlight.js/private\").KeywordDict} */\n    const compiledKeywords = Object.create(null);\n\n    // input can be a string of keywords, an array of keywords, or a object with\n    // named keys representing scopeName (which can then point to a string or array)\n    if (typeof rawKeywords === 'string') {\n      compileList(scopeName, rawKeywords.split(\" \"));\n    } else if (Array.isArray(rawKeywords)) {\n      compileList(scopeName, rawKeywords);\n    } else {\n      Object.keys(rawKeywords).forEach(function(scopeName) {\n        // collapse all our objects back into the parent object\n        Object.assign(\n          compiledKeywords,\n          compileKeywords(rawKeywords[scopeName], caseInsensitive, scopeName)\n        );\n      });\n    }\n    return compiledKeywords;\n\n    // ---\n\n    /**\n     * Compiles an individual list of keywords\n     *\n     * Ex: \"for if when while|5\"\n     *\n     * @param {string} scopeName\n     * @param {Array<string>} keywordList\n     */\n    function compileList(scopeName, keywordList) {\n      if (caseInsensitive) {\n        keywordList = keywordList.map(x => x.toLowerCase());\n      }\n      keywordList.forEach(function(keyword) {\n        const pair = keyword.split('|');\n        compiledKeywords[pair[0]] = [scopeName, scoreForKeyword(pair[0], pair[1])];\n      });\n    }\n  }\n\n  /**\n   * Returns the proper score for a given keyword\n   *\n   * Also takes into account comment keywords, which will be scored 0 UNLESS\n   * another score has been manually assigned.\n   * @param {string} keyword\n   * @param {string} [providedScore]\n   */\n  function scoreForKeyword(keyword, providedScore) {\n    // manual scores always win over common keywords\n    // so you can force a score of 1 if you really insist\n    if (providedScore) {\n      return Number(providedScore);\n    }\n\n    return commonKeyword(keyword) ? 0 : 1;\n  }\n\n  /**\n   * Determines if a given keyword is common or not\n   *\n   * @param {string} keyword */\n  function commonKeyword(keyword) {\n    return COMMON_KEYWORDS.includes(keyword.toLowerCase());\n  }\n\n  /*\n\n  For the reasoning behind this please see:\n  https://github.com/highlightjs/highlight.js/issues/2880#issuecomment-747275419\n\n  */\n\n  /**\n   * @type {Record<string, boolean>}\n   */\n  const seenDeprecations = {};\n\n  /**\n   * @param {string} message\n   */\n  const error = (message) => {\n    console.error(message);\n  };\n\n  /**\n   * @param {string} message\n   * @param {any} args\n   */\n  const warn = (message, ...args) => {\n    console.log(`WARN: ${message}`, ...args);\n  };\n\n  /**\n   * @param {string} version\n   * @param {string} message\n   */\n  const deprecated = (version, message) => {\n    if (seenDeprecations[`${version}/${message}`]) return;\n\n    console.log(`Deprecated as of ${version}. ${message}`);\n    seenDeprecations[`${version}/${message}`] = true;\n  };\n\n  /* eslint-disable no-throw-literal */\n\n  /**\n  @typedef {import('highlight.js').CompiledMode} CompiledMode\n  */\n\n  const MultiClassError = new Error();\n\n  /**\n   * Renumbers labeled scope names to account for additional inner match\n   * groups that otherwise would break everything.\n   *\n   * Lets say we 3 match scopes:\n   *\n   *   { 1 => ..., 2 => ..., 3 => ... }\n   *\n   * So what we need is a clean match like this:\n   *\n   *   (a)(b)(c) => [ \"a\", \"b\", \"c\" ]\n   *\n   * But this falls apart with inner match groups:\n   *\n   * (a)(((b)))(c) => [\"a\", \"b\", \"b\", \"b\", \"c\" ]\n   *\n   * Our scopes are now \"out of alignment\" and we're repeating `b` 3 times.\n   * What needs to happen is the numbers are remapped:\n   *\n   *   { 1 => ..., 2 => ..., 5 => ... }\n   *\n   * We also need to know that the ONLY groups that should be output\n   * are 1, 2, and 5.  This function handles this behavior.\n   *\n   * @param {CompiledMode} mode\n   * @param {Array<RegExp | string>} regexes\n   * @param {{key: \"beginScope\"|\"endScope\"}} opts\n   */\n  function remapScopeNames(mode, regexes, { key }) {\n    let offset = 0;\n    const scopeNames = mode[key];\n    /** @type Record<number,boolean> */\n    const emit = {};\n    /** @type Record<number,string> */\n    const positions = {};\n\n    for (let i = 1; i <= regexes.length; i++) {\n      positions[i + offset] = scopeNames[i];\n      emit[i + offset] = true;\n      offset += countMatchGroups(regexes[i - 1]);\n    }\n    // we use _emit to keep track of which match groups are \"top-level\" to avoid double\n    // output from inside match groups\n    mode[key] = positions;\n    mode[key]._emit = emit;\n    mode[key]._multi = true;\n  }\n\n  /**\n   * @param {CompiledMode} mode\n   */\n  function beginMultiClass(mode) {\n    if (!Array.isArray(mode.begin)) return;\n\n    if (mode.skip || mode.excludeBegin || mode.returnBegin) {\n      error(\"skip, excludeBegin, returnBegin not compatible with beginScope: {}\");\n      throw MultiClassError;\n    }\n\n    if (typeof mode.beginScope !== \"object\" || mode.beginScope === null) {\n      error(\"beginScope must be object\");\n      throw MultiClassError;\n    }\n\n    remapScopeNames(mode, mode.begin, { key: \"beginScope\" });\n    mode.begin = _rewriteBackreferences(mode.begin, { joinWith: \"\" });\n  }\n\n  /**\n   * @param {CompiledMode} mode\n   */\n  function endMultiClass(mode) {\n    if (!Array.isArray(mode.end)) return;\n\n    if (mode.skip || mode.excludeEnd || mode.returnEnd) {\n      error(\"skip, excludeEnd, returnEnd not compatible with endScope: {}\");\n      throw MultiClassError;\n    }\n\n    if (typeof mode.endScope !== \"object\" || mode.endScope === null) {\n      error(\"endScope must be object\");\n      throw MultiClassError;\n    }\n\n    remapScopeNames(mode, mode.end, { key: \"endScope\" });\n    mode.end = _rewriteBackreferences(mode.end, { joinWith: \"\" });\n  }\n\n  /**\n   * this exists only to allow `scope: {}` to be used beside `match:`\n   * Otherwise `beginScope` would necessary and that would look weird\n\n    {\n      match: [ /def/, /\\w+/ ]\n      scope: { 1: \"keyword\" , 2: \"title\" }\n    }\n\n   * @param {CompiledMode} mode\n   */\n  function scopeSugar(mode) {\n    if (mode.scope && typeof mode.scope === \"object\" && mode.scope !== null) {\n      mode.beginScope = mode.scope;\n      delete mode.scope;\n    }\n  }\n\n  /**\n   * @param {CompiledMode} mode\n   */\n  function MultiClass(mode) {\n    scopeSugar(mode);\n\n    if (typeof mode.beginScope === \"string\") {\n      mode.beginScope = { _wrap: mode.beginScope };\n    }\n    if (typeof mode.endScope === \"string\") {\n      mode.endScope = { _wrap: mode.endScope };\n    }\n\n    beginMultiClass(mode);\n    endMultiClass(mode);\n  }\n\n  /**\n  @typedef {import('highlight.js').Mode} Mode\n  @typedef {import('highlight.js').CompiledMode} CompiledMode\n  @typedef {import('highlight.js').Language} Language\n  @typedef {import('highlight.js').HLJSPlugin} HLJSPlugin\n  @typedef {import('highlight.js').CompiledLanguage} CompiledLanguage\n  */\n\n  // compilation\n\n  /**\n   * Compiles a language definition result\n   *\n   * Given the raw result of a language definition (Language), compiles this so\n   * that it is ready for highlighting code.\n   * @param {Language} language\n   * @returns {CompiledLanguage}\n   */\n  function compileLanguage(language) {\n    /**\n     * Builds a regex with the case sensitivity of the current language\n     *\n     * @param {RegExp | string} value\n     * @param {boolean} [global]\n     */\n    function langRe(value, global) {\n      return new RegExp(\n        source(value),\n        'm'\n        + (language.case_insensitive ? 'i' : '')\n        + (language.unicodeRegex ? 'u' : '')\n        + (global ? 'g' : '')\n      );\n    }\n\n    /**\n      Stores multiple regular expressions and allows you to quickly search for\n      them all in a string simultaneously - returning the first match.  It does\n      this by creating a huge (a|b|c) regex - each individual item wrapped with ()\n      and joined by `|` - using match groups to track position.  When a match is\n      found checking which position in the array has content allows us to figure\n      out which of the original regexes / match groups triggered the match.\n\n      The match object itself (the result of `Regex.exec`) is returned but also\n      enhanced by merging in any meta-data that was registered with the regex.\n      This is how we keep track of which mode matched, and what type of rule\n      (`illegal`, `begin`, end, etc).\n    */\n    class MultiRegex {\n      constructor() {\n        this.matchIndexes = {};\n        // @ts-ignore\n        this.regexes = [];\n        this.matchAt = 1;\n        this.position = 0;\n      }\n\n      // @ts-ignore\n      addRule(re, opts) {\n        opts.position = this.position++;\n        // @ts-ignore\n        this.matchIndexes[this.matchAt] = opts;\n        this.regexes.push([opts, re]);\n        this.matchAt += countMatchGroups(re) + 1;\n      }\n\n      compile() {\n        if (this.regexes.length === 0) {\n          // avoids the need to check length every time exec is called\n          // @ts-ignore\n          this.exec = () => null;\n        }\n        const terminators = this.regexes.map(el => el[1]);\n        this.matcherRe = langRe(_rewriteBackreferences(terminators, { joinWith: '|' }), true);\n        this.lastIndex = 0;\n      }\n\n      /** @param {string} s */\n      exec(s) {\n        this.matcherRe.lastIndex = this.lastIndex;\n        const match = this.matcherRe.exec(s);\n        if (!match) { return null; }\n\n        // eslint-disable-next-line no-undefined\n        const i = match.findIndex((el, i) => i > 0 && el !== undefined);\n        // @ts-ignore\n        const matchData = this.matchIndexes[i];\n        // trim off any earlier non-relevant match groups (ie, the other regex\n        // match groups that make up the multi-matcher)\n        match.splice(0, i);\n\n        return Object.assign(match, matchData);\n      }\n    }\n\n    /*\n      Created to solve the key deficiently with MultiRegex - there is no way to\n      test for multiple matches at a single location.  Why would we need to do\n      that?  In the future a more dynamic engine will allow certain matches to be\n      ignored.  An example: if we matched say the 3rd regex in a large group but\n      decided to ignore it - we'd need to started testing again at the 4th\n      regex... but MultiRegex itself gives us no real way to do that.\n\n      So what this class creates MultiRegexs on the fly for whatever search\n      position they are needed.\n\n      NOTE: These additional MultiRegex objects are created dynamically.  For most\n      grammars most of the time we will never actually need anything more than the\n      first MultiRegex - so this shouldn't have too much overhead.\n\n      Say this is our search group, and we match regex3, but wish to ignore it.\n\n        regex1 | regex2 | regex3 | regex4 | regex5    ' ie, startAt = 0\n\n      What we need is a new MultiRegex that only includes the remaining\n      possibilities:\n\n        regex4 | regex5                               ' ie, startAt = 3\n\n      This class wraps all that complexity up in a simple API... `startAt` decides\n      where in the array of expressions to start doing the matching. It\n      auto-increments, so if a match is found at position 2, then startAt will be\n      set to 3.  If the end is reached startAt will return to 0.\n\n      MOST of the time the parser will be setting startAt manually to 0.\n    */\n    class ResumableMultiRegex {\n      constructor() {\n        // @ts-ignore\n        this.rules = [];\n        // @ts-ignore\n        this.multiRegexes = [];\n        this.count = 0;\n\n        this.lastIndex = 0;\n        this.regexIndex = 0;\n      }\n\n      // @ts-ignore\n      getMatcher(index) {\n        if (this.multiRegexes[index]) return this.multiRegexes[index];\n\n        const matcher = new MultiRegex();\n        this.rules.slice(index).forEach(([re, opts]) => matcher.addRule(re, opts));\n        matcher.compile();\n        this.multiRegexes[index] = matcher;\n        return matcher;\n      }\n\n      resumingScanAtSamePosition() {\n        return this.regexIndex !== 0;\n      }\n\n      considerAll() {\n        this.regexIndex = 0;\n      }\n\n      // @ts-ignore\n      addRule(re, opts) {\n        this.rules.push([re, opts]);\n        if (opts.type === \"begin\") this.count++;\n      }\n\n      /** @param {string} s */\n      exec(s) {\n        const m = this.getMatcher(this.regexIndex);\n        m.lastIndex = this.lastIndex;\n        let result = m.exec(s);\n\n        // The following is because we have no easy way to say \"resume scanning at the\n        // existing position but also skip the current rule ONLY\". What happens is\n        // all prior rules are also skipped which can result in matching the wrong\n        // thing. Example of matching \"booger\":\n\n        // our matcher is [string, \"booger\", number]\n        //\n        // ....booger....\n\n        // if \"booger\" is ignored then we'd really need a regex to scan from the\n        // SAME position for only: [string, number] but ignoring \"booger\" (if it\n        // was the first match), a simple resume would scan ahead who knows how\n        // far looking only for \"number\", ignoring potential string matches (or\n        // future \"booger\" matches that might be valid.)\n\n        // So what we do: We execute two matchers, one resuming at the same\n        // position, but the second full matcher starting at the position after:\n\n        //     /--- resume first regex match here (for [number])\n        //     |/---- full match here for [string, \"booger\", number]\n        //     vv\n        // ....booger....\n\n        // Which ever results in a match first is then used. So this 3-4 step\n        // process essentially allows us to say \"match at this position, excluding\n        // a prior rule that was ignored\".\n        //\n        // 1. Match \"booger\" first, ignore. Also proves that [string] does non match.\n        // 2. Resume matching for [number]\n        // 3. Match at index + 1 for [string, \"booger\", number]\n        // 4. If #2 and #3 result in matches, which came first?\n        if (this.resumingScanAtSamePosition()) {\n          if (result && result.index === this.lastIndex) ; else { // use the second matcher result\n            const m2 = this.getMatcher(0);\n            m2.lastIndex = this.lastIndex + 1;\n            result = m2.exec(s);\n          }\n        }\n\n        if (result) {\n          this.regexIndex += result.position + 1;\n          if (this.regexIndex === this.count) {\n            // wrap-around to considering all matches again\n            this.considerAll();\n          }\n        }\n\n        return result;\n      }\n    }\n\n    /**\n     * Given a mode, builds a huge ResumableMultiRegex that can be used to walk\n     * the content and find matches.\n     *\n     * @param {CompiledMode} mode\n     * @returns {ResumableMultiRegex}\n     */\n    function buildModeRegex(mode) {\n      const mm = new ResumableMultiRegex();\n\n      mode.contains.forEach(term => mm.addRule(term.begin, { rule: term, type: \"begin\" }));\n\n      if (mode.terminatorEnd) {\n        mm.addRule(mode.terminatorEnd, { type: \"end\" });\n      }\n      if (mode.illegal) {\n        mm.addRule(mode.illegal, { type: \"illegal\" });\n      }\n\n      return mm;\n    }\n\n    /** skip vs abort vs ignore\n     *\n     * @skip   - The mode is still entered and exited normally (and contains rules apply),\n     *           but all content is held and added to the parent buffer rather than being\n     *           output when the mode ends.  Mostly used with `sublanguage` to build up\n     *           a single large buffer than can be parsed by sublanguage.\n     *\n     *             - The mode begin ands ends normally.\n     *             - Content matched is added to the parent mode buffer.\n     *             - The parser cursor is moved forward normally.\n     *\n     * @abort  - A hack placeholder until we have ignore.  Aborts the mode (as if it\n     *           never matched) but DOES NOT continue to match subsequent `contains`\n     *           modes.  Abort is bad/suboptimal because it can result in modes\n     *           farther down not getting applied because an earlier rule eats the\n     *           content but then aborts.\n     *\n     *             - The mode does not begin.\n     *             - Content matched by `begin` is added to the mode buffer.\n     *             - The parser cursor is moved forward accordingly.\n     *\n     * @ignore - Ignores the mode (as if it never matched) and continues to match any\n     *           subsequent `contains` modes.  Ignore isn't technically possible with\n     *           the current parser implementation.\n     *\n     *             - The mode does not begin.\n     *             - Content matched by `begin` is ignored.\n     *             - The parser cursor is not moved forward.\n     */\n\n    /**\n     * Compiles an individual mode\n     *\n     * This can raise an error if the mode contains certain detectable known logic\n     * issues.\n     * @param {Mode} mode\n     * @param {CompiledMode | null} [parent]\n     * @returns {CompiledMode | never}\n     */\n    function compileMode(mode, parent) {\n      const cmode = /** @type CompiledMode */ (mode);\n      if (mode.isCompiled) return cmode;\n\n      [\n        scopeClassName,\n        // do this early so compiler extensions generally don't have to worry about\n        // the distinction between match/begin\n        compileMatch,\n        MultiClass,\n        beforeMatchExt\n      ].forEach(ext => ext(mode, parent));\n\n      language.compilerExtensions.forEach(ext => ext(mode, parent));\n\n      // __beforeBegin is considered private API, internal use only\n      mode.__beforeBegin = null;\n\n      [\n        beginKeywords,\n        // do this later so compiler extensions that come earlier have access to the\n        // raw array if they wanted to perhaps manipulate it, etc.\n        compileIllegal,\n        // default to 1 relevance if not specified\n        compileRelevance\n      ].forEach(ext => ext(mode, parent));\n\n      mode.isCompiled = true;\n\n      let keywordPattern = null;\n      if (typeof mode.keywords === \"object\" && mode.keywords.$pattern) {\n        // we need a copy because keywords might be compiled multiple times\n        // so we can't go deleting $pattern from the original on the first\n        // pass\n        mode.keywords = Object.assign({}, mode.keywords);\n        keywordPattern = mode.keywords.$pattern;\n        delete mode.keywords.$pattern;\n      }\n      keywordPattern = keywordPattern || /\\w+/;\n\n      if (mode.keywords) {\n        mode.keywords = compileKeywords(mode.keywords, language.case_insensitive);\n      }\n\n      cmode.keywordPatternRe = langRe(keywordPattern, true);\n\n      if (parent) {\n        if (!mode.begin) mode.begin = /\\B|\\b/;\n        cmode.beginRe = langRe(cmode.begin);\n        if (!mode.end && !mode.endsWithParent) mode.end = /\\B|\\b/;\n        if (mode.end) cmode.endRe = langRe(cmode.end);\n        cmode.terminatorEnd = source(cmode.end) || '';\n        if (mode.endsWithParent && parent.terminatorEnd) {\n          cmode.terminatorEnd += (mode.end ? '|' : '') + parent.terminatorEnd;\n        }\n      }\n      if (mode.illegal) cmode.illegalRe = langRe(/** @type {RegExp | string} */ (mode.illegal));\n      if (!mode.contains) mode.contains = [];\n\n      mode.contains = [].concat(...mode.contains.map(function(c) {\n        return expandOrCloneMode(c === 'self' ? mode : c);\n      }));\n      mode.contains.forEach(function(c) { compileMode(/** @type Mode */ (c), cmode); });\n\n      if (mode.starts) {\n        compileMode(mode.starts, parent);\n      }\n\n      cmode.matcher = buildModeRegex(cmode);\n      return cmode;\n    }\n\n    if (!language.compilerExtensions) language.compilerExtensions = [];\n\n    // self is not valid at the top-level\n    if (language.contains && language.contains.includes('self')) {\n      throw new Error(\"ERR: contains `self` is not supported at the top-level of a language.  See documentation.\");\n    }\n\n    // we need a null object, which inherit will guarantee\n    language.classNameAliases = inherit$1(language.classNameAliases || {});\n\n    return compileMode(/** @type Mode */ (language));\n  }\n\n  /**\n   * Determines if a mode has a dependency on it's parent or not\n   *\n   * If a mode does have a parent dependency then often we need to clone it if\n   * it's used in multiple places so that each copy points to the correct parent,\n   * where-as modes without a parent can often safely be re-used at the bottom of\n   * a mode chain.\n   *\n   * @param {Mode | null} mode\n   * @returns {boolean} - is there a dependency on the parent?\n   * */\n  function dependencyOnParent(mode) {\n    if (!mode) return false;\n\n    return mode.endsWithParent || dependencyOnParent(mode.starts);\n  }\n\n  /**\n   * Expands a mode or clones it if necessary\n   *\n   * This is necessary for modes with parental dependenceis (see notes on\n   * `dependencyOnParent`) and for nodes that have `variants` - which must then be\n   * exploded into their own individual modes at compile time.\n   *\n   * @param {Mode} mode\n   * @returns {Mode | Mode[]}\n   * */\n  function expandOrCloneMode(mode) {\n    if (mode.variants && !mode.cachedVariants) {\n      mode.cachedVariants = mode.variants.map(function(variant) {\n        return inherit$1(mode, { variants: null }, variant);\n      });\n    }\n\n    // EXPAND\n    // if we have variants then essentially \"replace\" the mode with the variants\n    // this happens in compileMode, where this function is called from\n    if (mode.cachedVariants) {\n      return mode.cachedVariants;\n    }\n\n    // CLONE\n    // if we have dependencies on parents then we need a unique\n    // instance of ourselves, so we can be reused with many\n    // different parents without issue\n    if (dependencyOnParent(mode)) {\n      return inherit$1(mode, { starts: mode.starts ? inherit$1(mode.starts) : null });\n    }\n\n    if (Object.isFrozen(mode)) {\n      return inherit$1(mode);\n    }\n\n    // no special dependency issues, just return ourselves\n    return mode;\n  }\n\n  var version = \"11.11.1\";\n\n  class HTMLInjectionError extends Error {\n    constructor(reason, html) {\n      super(reason);\n      this.name = \"HTMLInjectionError\";\n      this.html = html;\n    }\n  }\n\n  /*\n  Syntax highlighting with language autodetection.\n  https://highlightjs.org/\n  */\n\n\n\n  /**\n  @typedef {import('highlight.js').Mode} Mode\n  @typedef {import('highlight.js').CompiledMode} CompiledMode\n  @typedef {import('highlight.js').CompiledScope} CompiledScope\n  @typedef {import('highlight.js').Language} Language\n  @typedef {import('highlight.js').HLJSApi} HLJSApi\n  @typedef {import('highlight.js').HLJSPlugin} HLJSPlugin\n  @typedef {import('highlight.js').PluginEvent} PluginEvent\n  @typedef {import('highlight.js').HLJSOptions} HLJSOptions\n  @typedef {import('highlight.js').LanguageFn} LanguageFn\n  @typedef {import('highlight.js').HighlightedHTMLElement} HighlightedHTMLElement\n  @typedef {import('highlight.js').BeforeHighlightContext} BeforeHighlightContext\n  @typedef {import('highlight.js/private').MatchType} MatchType\n  @typedef {import('highlight.js/private').KeywordData} KeywordData\n  @typedef {import('highlight.js/private').EnhancedMatch} EnhancedMatch\n  @typedef {import('highlight.js/private').AnnotatedError} AnnotatedError\n  @typedef {import('highlight.js').AutoHighlightResult} AutoHighlightResult\n  @typedef {import('highlight.js').HighlightOptions} HighlightOptions\n  @typedef {import('highlight.js').HighlightResult} HighlightResult\n  */\n\n\n  const escape = escapeHTML;\n  const inherit = inherit$1;\n  const NO_MATCH = Symbol(\"nomatch\");\n  const MAX_KEYWORD_HITS = 7;\n\n  /**\n   * @param {any} hljs - object that is extended (legacy)\n   * @returns {HLJSApi}\n   */\n  const HLJS = function(hljs) {\n    // Global internal variables used within the highlight.js library.\n    /** @type {Record<string, Language>} */\n    const languages = Object.create(null);\n    /** @type {Record<string, string>} */\n    const aliases = Object.create(null);\n    /** @type {HLJSPlugin[]} */\n    const plugins = [];\n\n    // safe/production mode - swallows more errors, tries to keep running\n    // even if a single syntax or parse hits a fatal error\n    let SAFE_MODE = true;\n    const LANGUAGE_NOT_FOUND = \"Could not find the language '{}', did you forget to load/include a language module?\";\n    /** @type {Language} */\n    const PLAINTEXT_LANGUAGE = { disableAutodetect: true, name: 'Plain text', contains: [] };\n\n    // Global options used when within external APIs. This is modified when\n    // calling the `hljs.configure` function.\n    /** @type HLJSOptions */\n    let options = {\n      ignoreUnescapedHTML: false,\n      throwUnescapedHTML: false,\n      noHighlightRe: /^(no-?highlight)$/i,\n      languageDetectRe: /\\blang(?:uage)?-([\\w-]+)\\b/i,\n      classPrefix: 'hljs-',\n      cssSelector: 'pre code',\n      languages: null,\n      // beta configuration options, subject to change, welcome to discuss\n      // https://github.com/highlightjs/highlight.js/issues/1086\n      __emitter: TokenTreeEmitter\n    };\n\n    /* Utility functions */\n\n    /**\n     * Tests a language name to see if highlighting should be skipped\n     * @param {string} languageName\n     */\n    function shouldNotHighlight(languageName) {\n      return options.noHighlightRe.test(languageName);\n    }\n\n    /**\n     * @param {HighlightedHTMLElement} block - the HTML element to determine language for\n     */\n    function blockLanguage(block) {\n      let classes = block.className + ' ';\n\n      classes += block.parentNode ? block.parentNode.className : '';\n\n      // language-* takes precedence over non-prefixed class names.\n      const match = options.languageDetectRe.exec(classes);\n      if (match) {\n        const language = getLanguage(match[1]);\n        if (!language) {\n          warn(LANGUAGE_NOT_FOUND.replace(\"{}\", match[1]));\n          warn(\"Falling back to no-highlight mode for this block.\", block);\n        }\n        return language ? match[1] : 'no-highlight';\n      }\n\n      return classes\n        .split(/\\s+/)\n        .find((_class) => shouldNotHighlight(_class) || getLanguage(_class));\n    }\n\n    /**\n     * Core highlighting function.\n     *\n     * OLD API\n     * highlight(lang, code, ignoreIllegals, continuation)\n     *\n     * NEW API\n     * highlight(code, {lang, ignoreIllegals})\n     *\n     * @param {string} codeOrLanguageName - the language to use for highlighting\n     * @param {string | HighlightOptions} optionsOrCode - the code to highlight\n     * @param {boolean} [ignoreIllegals] - whether to ignore illegal matches, default is to bail\n     *\n     * @returns {HighlightResult} Result - an object that represents the result\n     * @property {string} language - the language name\n     * @property {number} relevance - the relevance score\n     * @property {string} value - the highlighted HTML code\n     * @property {string} code - the original raw code\n     * @property {CompiledMode} top - top of the current mode stack\n     * @property {boolean} illegal - indicates whether any illegal matches were found\n    */\n    function highlight(codeOrLanguageName, optionsOrCode, ignoreIllegals) {\n      let code = \"\";\n      let languageName = \"\";\n      if (typeof optionsOrCode === \"object\") {\n        code = codeOrLanguageName;\n        ignoreIllegals = optionsOrCode.ignoreIllegals;\n        languageName = optionsOrCode.language;\n      } else {\n        // old API\n        deprecated(\"10.7.0\", \"highlight(lang, code, ...args) has been deprecated.\");\n        deprecated(\"10.7.0\", \"Please use highlight(code, options) instead.\\nhttps://github.com/highlightjs/highlight.js/issues/2277\");\n        languageName = codeOrLanguageName;\n        code = optionsOrCode;\n      }\n\n      // https://github.com/highlightjs/highlight.js/issues/3149\n      // eslint-disable-next-line no-undefined\n      if (ignoreIllegals === undefined) { ignoreIllegals = true; }\n\n      /** @type {BeforeHighlightContext} */\n      const context = {\n        code,\n        language: languageName\n      };\n      // the plugin can change the desired language or the code to be highlighted\n      // just be changing the object it was passed\n      fire(\"before:highlight\", context);\n\n      // a before plugin can usurp the result completely by providing it's own\n      // in which case we don't even need to call highlight\n      const result = context.result\n        ? context.result\n        : _highlight(context.language, context.code, ignoreIllegals);\n\n      result.code = context.code;\n      // the plugin can change anything in result to suite it\n      fire(\"after:highlight\", result);\n\n      return result;\n    }\n\n    /**\n     * private highlight that's used internally and does not fire callbacks\n     *\n     * @param {string} languageName - the language to use for highlighting\n     * @param {string} codeToHighlight - the code to highlight\n     * @param {boolean?} [ignoreIllegals] - whether to ignore illegal matches, default is to bail\n     * @param {CompiledMode?} [continuation] - current continuation mode, if any\n     * @returns {HighlightResult} - result of the highlight operation\n    */\n    function _highlight(languageName, codeToHighlight, ignoreIllegals, continuation) {\n      const keywordHits = Object.create(null);\n\n      /**\n       * Return keyword data if a match is a keyword\n       * @param {CompiledMode} mode - current mode\n       * @param {string} matchText - the textual match\n       * @returns {KeywordData | false}\n       */\n      function keywordData(mode, matchText) {\n        return mode.keywords[matchText];\n      }\n\n      function processKeywords() {\n        if (!top.keywords) {\n          emitter.addText(modeBuffer);\n          return;\n        }\n\n        let lastIndex = 0;\n        top.keywordPatternRe.lastIndex = 0;\n        let match = top.keywordPatternRe.exec(modeBuffer);\n        let buf = \"\";\n\n        while (match) {\n          buf += modeBuffer.substring(lastIndex, match.index);\n          const word = language.case_insensitive ? match[0].toLowerCase() : match[0];\n          const data = keywordData(top, word);\n          if (data) {\n            const [kind, keywordRelevance] = data;\n            emitter.addText(buf);\n            buf = \"\";\n\n            keywordHits[word] = (keywordHits[word] || 0) + 1;\n            if (keywordHits[word] <= MAX_KEYWORD_HITS) relevance += keywordRelevance;\n            if (kind.startsWith(\"_\")) {\n              // _ implied for relevance only, do not highlight\n              // by applying a class name\n              buf += match[0];\n            } else {\n              const cssClass = language.classNameAliases[kind] || kind;\n              emitKeyword(match[0], cssClass);\n            }\n          } else {\n            buf += match[0];\n          }\n          lastIndex = top.keywordPatternRe.lastIndex;\n          match = top.keywordPatternRe.exec(modeBuffer);\n        }\n        buf += modeBuffer.substring(lastIndex);\n        emitter.addText(buf);\n      }\n\n      function processSubLanguage() {\n        if (modeBuffer === \"\") return;\n        /** @type HighlightResult */\n        let result = null;\n\n        if (typeof top.subLanguage === 'string') {\n          if (!languages[top.subLanguage]) {\n            emitter.addText(modeBuffer);\n            return;\n          }\n          result = _highlight(top.subLanguage, modeBuffer, true, continuations[top.subLanguage]);\n          continuations[top.subLanguage] = /** @type {CompiledMode} */ (result._top);\n        } else {\n          result = highlightAuto(modeBuffer, top.subLanguage.length ? top.subLanguage : null);\n        }\n\n        // Counting embedded language score towards the host language may be disabled\n        // with zeroing the containing mode relevance. Use case in point is Markdown that\n        // allows XML everywhere and makes every XML snippet to have a much larger Markdown\n        // score.\n        if (top.relevance > 0) {\n          relevance += result.relevance;\n        }\n        emitter.__addSublanguage(result._emitter, result.language);\n      }\n\n      function processBuffer() {\n        if (top.subLanguage != null) {\n          processSubLanguage();\n        } else {\n          processKeywords();\n        }\n        modeBuffer = '';\n      }\n\n      /**\n       * @param {string} text\n       * @param {string} scope\n       */\n      function emitKeyword(keyword, scope) {\n        if (keyword === \"\") return;\n\n        emitter.startScope(scope);\n        emitter.addText(keyword);\n        emitter.endScope();\n      }\n\n      /**\n       * @param {CompiledScope} scope\n       * @param {RegExpMatchArray} match\n       */\n      function emitMultiClass(scope, match) {\n        let i = 1;\n        const max = match.length - 1;\n        while (i <= max) {\n          if (!scope._emit[i]) { i++; continue; }\n          const klass = language.classNameAliases[scope[i]] || scope[i];\n          const text = match[i];\n          if (klass) {\n            emitKeyword(text, klass);\n          } else {\n            modeBuffer = text;\n            processKeywords();\n            modeBuffer = \"\";\n          }\n          i++;\n        }\n      }\n\n      /**\n       * @param {CompiledMode} mode - new mode to start\n       * @param {RegExpMatchArray} match\n       */\n      function startNewMode(mode, match) {\n        if (mode.scope && typeof mode.scope === \"string\") {\n          emitter.openNode(language.classNameAliases[mode.scope] || mode.scope);\n        }\n        if (mode.beginScope) {\n          // beginScope just wraps the begin match itself in a scope\n          if (mode.beginScope._wrap) {\n            emitKeyword(modeBuffer, language.classNameAliases[mode.beginScope._wrap] || mode.beginScope._wrap);\n            modeBuffer = \"\";\n          } else if (mode.beginScope._multi) {\n            // at this point modeBuffer should just be the match\n            emitMultiClass(mode.beginScope, match);\n            modeBuffer = \"\";\n          }\n        }\n\n        top = Object.create(mode, { parent: { value: top } });\n        return top;\n      }\n\n      /**\n       * @param {CompiledMode } mode - the mode to potentially end\n       * @param {RegExpMatchArray} match - the latest match\n       * @param {string} matchPlusRemainder - match plus remainder of content\n       * @returns {CompiledMode | void} - the next mode, or if void continue on in current mode\n       */\n      function endOfMode(mode, match, matchPlusRemainder) {\n        let matched = startsWith(mode.endRe, matchPlusRemainder);\n\n        if (matched) {\n          if (mode[\"on:end\"]) {\n            const resp = new Response(mode);\n            mode[\"on:end\"](match, resp);\n            if (resp.isMatchIgnored) matched = false;\n          }\n\n          if (matched) {\n            while (mode.endsParent && mode.parent) {\n              mode = mode.parent;\n            }\n            return mode;\n          }\n        }\n        // even if on:end fires an `ignore` it's still possible\n        // that we might trigger the end node because of a parent mode\n        if (mode.endsWithParent) {\n          return endOfMode(mode.parent, match, matchPlusRemainder);\n        }\n      }\n\n      /**\n       * Handle matching but then ignoring a sequence of text\n       *\n       * @param {string} lexeme - string containing full match text\n       */\n      function doIgnore(lexeme) {\n        if (top.matcher.regexIndex === 0) {\n          // no more regexes to potentially match here, so we move the cursor forward one\n          // space\n          modeBuffer += lexeme[0];\n          return 1;\n        } else {\n          // no need to move the cursor, we still have additional regexes to try and\n          // match at this very spot\n          resumeScanAtSamePosition = true;\n          return 0;\n        }\n      }\n\n      /**\n       * Handle the start of a new potential mode match\n       *\n       * @param {EnhancedMatch} match - the current match\n       * @returns {number} how far to advance the parse cursor\n       */\n      function doBeginMatch(match) {\n        const lexeme = match[0];\n        const newMode = match.rule;\n\n        const resp = new Response(newMode);\n        // first internal before callbacks, then the public ones\n        const beforeCallbacks = [newMode.__beforeBegin, newMode[\"on:begin\"]];\n        for (const cb of beforeCallbacks) {\n          if (!cb) continue;\n          cb(match, resp);\n          if (resp.isMatchIgnored) return doIgnore(lexeme);\n        }\n\n        if (newMode.skip) {\n          modeBuffer += lexeme;\n        } else {\n          if (newMode.excludeBegin) {\n            modeBuffer += lexeme;\n          }\n          processBuffer();\n          if (!newMode.returnBegin && !newMode.excludeBegin) {\n            modeBuffer = lexeme;\n          }\n        }\n        startNewMode(newMode, match);\n        return newMode.returnBegin ? 0 : lexeme.length;\n      }\n\n      /**\n       * Handle the potential end of mode\n       *\n       * @param {RegExpMatchArray} match - the current match\n       */\n      function doEndMatch(match) {\n        const lexeme = match[0];\n        const matchPlusRemainder = codeToHighlight.substring(match.index);\n\n        const endMode = endOfMode(top, match, matchPlusRemainder);\n        if (!endMode) { return NO_MATCH; }\n\n        const origin = top;\n        if (top.endScope && top.endScope._wrap) {\n          processBuffer();\n          emitKeyword(lexeme, top.endScope._wrap);\n        } else if (top.endScope && top.endScope._multi) {\n          processBuffer();\n          emitMultiClass(top.endScope, match);\n        } else if (origin.skip) {\n          modeBuffer += lexeme;\n        } else {\n          if (!(origin.returnEnd || origin.excludeEnd)) {\n            modeBuffer += lexeme;\n          }\n          processBuffer();\n          if (origin.excludeEnd) {\n            modeBuffer = lexeme;\n          }\n        }\n        do {\n          if (top.scope) {\n            emitter.closeNode();\n          }\n          if (!top.skip && !top.subLanguage) {\n            relevance += top.relevance;\n          }\n          top = top.parent;\n        } while (top !== endMode.parent);\n        if (endMode.starts) {\n          startNewMode(endMode.starts, match);\n        }\n        return origin.returnEnd ? 0 : lexeme.length;\n      }\n\n      function processContinuations() {\n        const list = [];\n        for (let current = top; current !== language; current = current.parent) {\n          if (current.scope) {\n            list.unshift(current.scope);\n          }\n        }\n        list.forEach(item => emitter.openNode(item));\n      }\n\n      /** @type {{type?: MatchType, index?: number, rule?: Mode}}} */\n      let lastMatch = {};\n\n      /**\n       *  Process an individual match\n       *\n       * @param {string} textBeforeMatch - text preceding the match (since the last match)\n       * @param {EnhancedMatch} [match] - the match itself\n       */\n      function processLexeme(textBeforeMatch, match) {\n        const lexeme = match && match[0];\n\n        // add non-matched text to the current mode buffer\n        modeBuffer += textBeforeMatch;\n\n        if (lexeme == null) {\n          processBuffer();\n          return 0;\n        }\n\n        // we've found a 0 width match and we're stuck, so we need to advance\n        // this happens when we have badly behaved rules that have optional matchers to the degree that\n        // sometimes they can end up matching nothing at all\n        // Ref: https://github.com/highlightjs/highlight.js/issues/2140\n        if (lastMatch.type === \"begin\" && match.type === \"end\" && lastMatch.index === match.index && lexeme === \"\") {\n          // spit the \"skipped\" character that our regex choked on back into the output sequence\n          modeBuffer += codeToHighlight.slice(match.index, match.index + 1);\n          if (!SAFE_MODE) {\n            /** @type {AnnotatedError} */\n            const err = new Error(`0 width match regex (${languageName})`);\n            err.languageName = languageName;\n            err.badRule = lastMatch.rule;\n            throw err;\n          }\n          return 1;\n        }\n        lastMatch = match;\n\n        if (match.type === \"begin\") {\n          return doBeginMatch(match);\n        } else if (match.type === \"illegal\" && !ignoreIllegals) {\n          // illegal match, we do not continue processing\n          /** @type {AnnotatedError} */\n          const err = new Error('Illegal lexeme \"' + lexeme + '\" for mode \"' + (top.scope || '<unnamed>') + '\"');\n          err.mode = top;\n          throw err;\n        } else if (match.type === \"end\") {\n          const processed = doEndMatch(match);\n          if (processed !== NO_MATCH) {\n            return processed;\n          }\n        }\n\n        // edge case for when illegal matches $ (end of line/text) which is technically\n        // a 0 width match but not a begin/end match so it's not caught by the\n        // first handler (when `ignoreIllegals` is true)\n        if (match.type === \"illegal\" && lexeme === \"\") {\n          if (match.index === codeToHighlight.length) ; else {\n            // matched literal `\\n` (with `$`) so we must manually add the newline\n            // itself to the modeBuffer so it is not lost when we advance the cursor\n            modeBuffer += \"\\n\";\n          }\n          return 1;\n        }\n\n        // infinite loops are BAD, this is a last ditch catch all. if we have a\n        // decent number of iterations yet our index (cursor position in our\n        // parsing) still 3x behind our index then something is very wrong\n        // so we bail\n        if (iterations > 100000 && iterations > match.index * 3) {\n          const err = new Error('potential infinite loop, way more iterations than matches');\n          throw err;\n        }\n\n        /*\n        Why might be find ourselves here?  An potential end match that was\n        triggered but could not be completed.  IE, `doEndMatch` returned NO_MATCH.\n        (this could be because a callback requests the match be ignored, etc)\n\n        This causes no real harm other than stopping a few times too many.\n        */\n\n        modeBuffer += lexeme;\n        return lexeme.length;\n      }\n\n      const language = getLanguage(languageName);\n      if (!language) {\n        error(LANGUAGE_NOT_FOUND.replace(\"{}\", languageName));\n        throw new Error('Unknown language: \"' + languageName + '\"');\n      }\n\n      const md = compileLanguage(language);\n      let result = '';\n      /** @type {CompiledMode} */\n      let top = continuation || md;\n      /** @type Record<string,CompiledMode> */\n      const continuations = {}; // keep continuations for sub-languages\n      const emitter = new options.__emitter(options);\n      processContinuations();\n      let modeBuffer = '';\n      let relevance = 0;\n      let index = 0;\n      let iterations = 0;\n      let resumeScanAtSamePosition = false;\n\n      try {\n        if (!language.__emitTokens) {\n          top.matcher.considerAll();\n\n          for (;;) {\n            iterations++;\n            if (resumeScanAtSamePosition) {\n              // only regexes not matched previously will now be\n              // considered for a potential match\n              resumeScanAtSamePosition = false;\n            } else {\n              top.matcher.considerAll();\n            }\n            top.matcher.lastIndex = index;\n\n            const match = top.matcher.exec(codeToHighlight);\n            // console.log(\"match\", match[0], match.rule && match.rule.begin)\n\n            if (!match) break;\n\n            const beforeMatch = codeToHighlight.substring(index, match.index);\n            const processedCount = processLexeme(beforeMatch, match);\n            index = match.index + processedCount;\n          }\n          processLexeme(codeToHighlight.substring(index));\n        } else {\n          language.__emitTokens(codeToHighlight, emitter);\n        }\n\n        emitter.finalize();\n        result = emitter.toHTML();\n\n        return {\n          language: languageName,\n          value: result,\n          relevance,\n          illegal: false,\n          _emitter: emitter,\n          _top: top\n        };\n      } catch (err) {\n        if (err.message && err.message.includes('Illegal')) {\n          return {\n            language: languageName,\n            value: escape(codeToHighlight),\n            illegal: true,\n            relevance: 0,\n            _illegalBy: {\n              message: err.message,\n              index,\n              context: codeToHighlight.slice(index - 100, index + 100),\n              mode: err.mode,\n              resultSoFar: result\n            },\n            _emitter: emitter\n          };\n        } else if (SAFE_MODE) {\n          return {\n            language: languageName,\n            value: escape(codeToHighlight),\n            illegal: false,\n            relevance: 0,\n            errorRaised: err,\n            _emitter: emitter,\n            _top: top\n          };\n        } else {\n          throw err;\n        }\n      }\n    }\n\n    /**\n     * returns a valid highlight result, without actually doing any actual work,\n     * auto highlight starts with this and it's possible for small snippets that\n     * auto-detection may not find a better match\n     * @param {string} code\n     * @returns {HighlightResult}\n     */\n    function justTextHighlightResult(code) {\n      const result = {\n        value: escape(code),\n        illegal: false,\n        relevance: 0,\n        _top: PLAINTEXT_LANGUAGE,\n        _emitter: new options.__emitter(options)\n      };\n      result._emitter.addText(code);\n      return result;\n    }\n\n    /**\n    Highlighting with language detection. Accepts a string with the code to\n    highlight. Returns an object with the following properties:\n\n    - language (detected language)\n    - relevance (int)\n    - value (an HTML string with highlighting markup)\n    - secondBest (object with the same structure for second-best heuristically\n      detected language, may be absent)\n\n      @param {string} code\n      @param {Array<string>} [languageSubset]\n      @returns {AutoHighlightResult}\n    */\n    function highlightAuto(code, languageSubset) {\n      languageSubset = languageSubset || options.languages || Object.keys(languages);\n      const plaintext = justTextHighlightResult(code);\n\n      const results = languageSubset.filter(getLanguage).filter(autoDetection).map(name =>\n        _highlight(name, code, false)\n      );\n      results.unshift(plaintext); // plaintext is always an option\n\n      const sorted = results.sort((a, b) => {\n        // sort base on relevance\n        if (a.relevance !== b.relevance) return b.relevance - a.relevance;\n\n        // always award the tie to the base language\n        // ie if C++ and Arduino are tied, it's more likely to be C++\n        if (a.language && b.language) {\n          if (getLanguage(a.language).supersetOf === b.language) {\n            return 1;\n          } else if (getLanguage(b.language).supersetOf === a.language) {\n            return -1;\n          }\n        }\n\n        // otherwise say they are equal, which has the effect of sorting on\n        // relevance while preserving the original ordering - which is how ties\n        // have historically been settled, ie the language that comes first always\n        // wins in the case of a tie\n        return 0;\n      });\n\n      const [best, secondBest] = sorted;\n\n      /** @type {AutoHighlightResult} */\n      const result = best;\n      result.secondBest = secondBest;\n\n      return result;\n    }\n\n    /**\n     * Builds new class name for block given the language name\n     *\n     * @param {HTMLElement} element\n     * @param {string} [currentLang]\n     * @param {string} [resultLang]\n     */\n    function updateClassName(element, currentLang, resultLang) {\n      const language = (currentLang && aliases[currentLang]) || resultLang;\n\n      element.classList.add(\"hljs\");\n      element.classList.add(`language-${language}`);\n    }\n\n    /**\n     * Applies highlighting to a DOM node containing code.\n     *\n     * @param {HighlightedHTMLElement} element - the HTML element to highlight\n    */\n    function highlightElement(element) {\n      /** @type HTMLElement */\n      let node = null;\n      const language = blockLanguage(element);\n\n      if (shouldNotHighlight(language)) return;\n\n      fire(\"before:highlightElement\",\n        { el: element, language });\n\n      if (element.dataset.highlighted) {\n        console.log(\"Element previously highlighted. To highlight again, first unset `dataset.highlighted`.\", element);\n        return;\n      }\n\n      // we should be all text, no child nodes (unescaped HTML) - this is possibly\n      // an HTML injection attack - it's likely too late if this is already in\n      // production (the code has likely already done its damage by the time\n      // we're seeing it)... but we yell loudly about this so that hopefully it's\n      // more likely to be caught in development before making it to production\n      if (element.children.length > 0) {\n        if (!options.ignoreUnescapedHTML) {\n          console.warn(\"One of your code blocks includes unescaped HTML. This is a potentially serious security risk.\");\n          console.warn(\"https://github.com/highlightjs/highlight.js/wiki/security\");\n          console.warn(\"The element with unescaped HTML:\");\n          console.warn(element);\n        }\n        if (options.throwUnescapedHTML) {\n          const err = new HTMLInjectionError(\n            \"One of your code blocks includes unescaped HTML.\",\n            element.innerHTML\n          );\n          throw err;\n        }\n      }\n\n      node = element;\n      const text = node.textContent;\n      const result = language ? highlight(text, { language, ignoreIllegals: true }) : highlightAuto(text);\n\n      element.innerHTML = result.value;\n      element.dataset.highlighted = \"yes\";\n      updateClassName(element, language, result.language);\n      element.result = {\n        language: result.language,\n        // TODO: remove with version 11.0\n        re: result.relevance,\n        relevance: result.relevance\n      };\n      if (result.secondBest) {\n        element.secondBest = {\n          language: result.secondBest.language,\n          relevance: result.secondBest.relevance\n        };\n      }\n\n      fire(\"after:highlightElement\", { el: element, result, text });\n    }\n\n    /**\n     * Updates highlight.js global options with the passed options\n     *\n     * @param {Partial<HLJSOptions>} userOptions\n     */\n    function configure(userOptions) {\n      options = inherit(options, userOptions);\n    }\n\n    // TODO: remove v12, deprecated\n    const initHighlighting = () => {\n      highlightAll();\n      deprecated(\"10.6.0\", \"initHighlighting() deprecated.  Use highlightAll() now.\");\n    };\n\n    // TODO: remove v12, deprecated\n    function initHighlightingOnLoad() {\n      highlightAll();\n      deprecated(\"10.6.0\", \"initHighlightingOnLoad() deprecated.  Use highlightAll() now.\");\n    }\n\n    let wantsHighlight = false;\n\n    /**\n     * auto-highlights all pre>code elements on the page\n     */\n    function highlightAll() {\n      function boot() {\n        // if a highlight was requested before DOM was loaded, do now\n        highlightAll();\n      }\n\n      // if we are called too early in the loading process\n      if (document.readyState === \"loading\") {\n        // make sure the event listener is only added once\n        if (!wantsHighlight) {\n          window.addEventListener('DOMContentLoaded', boot, false);\n        }\n        wantsHighlight = true;\n        return;\n      }\n\n      const blocks = document.querySelectorAll(options.cssSelector);\n      blocks.forEach(highlightElement);\n    }\n\n    /**\n     * Register a language grammar module\n     *\n     * @param {string} languageName\n     * @param {LanguageFn} languageDefinition\n     */\n    function registerLanguage(languageName, languageDefinition) {\n      let lang = null;\n      try {\n        lang = languageDefinition(hljs);\n      } catch (error$1) {\n        error(\"Language definition for '{}' could not be registered.\".replace(\"{}\", languageName));\n        // hard or soft error\n        if (!SAFE_MODE) { throw error$1; } else { error(error$1); }\n        // languages that have serious errors are replaced with essentially a\n        // \"plaintext\" stand-in so that the code blocks will still get normal\n        // css classes applied to them - and one bad language won't break the\n        // entire highlighter\n        lang = PLAINTEXT_LANGUAGE;\n      }\n      // give it a temporary name if it doesn't have one in the meta-data\n      if (!lang.name) lang.name = languageName;\n      languages[languageName] = lang;\n      lang.rawDefinition = languageDefinition.bind(null, hljs);\n\n      if (lang.aliases) {\n        registerAliases(lang.aliases, { languageName });\n      }\n    }\n\n    /**\n     * Remove a language grammar module\n     *\n     * @param {string} languageName\n     */\n    function unregisterLanguage(languageName) {\n      delete languages[languageName];\n      for (const alias of Object.keys(aliases)) {\n        if (aliases[alias] === languageName) {\n          delete aliases[alias];\n        }\n      }\n    }\n\n    /**\n     * @returns {string[]} List of language internal names\n     */\n    function listLanguages() {\n      return Object.keys(languages);\n    }\n\n    /**\n     * @param {string} name - name of the language to retrieve\n     * @returns {Language | undefined}\n     */\n    function getLanguage(name) {\n      name = (name || '').toLowerCase();\n      return languages[name] || languages[aliases[name]];\n    }\n\n    /**\n     *\n     * @param {string|string[]} aliasList - single alias or list of aliases\n     * @param {{languageName: string}} opts\n     */\n    function registerAliases(aliasList, { languageName }) {\n      if (typeof aliasList === 'string') {\n        aliasList = [aliasList];\n      }\n      aliasList.forEach(alias => { aliases[alias.toLowerCase()] = languageName; });\n    }\n\n    /**\n     * Determines if a given language has auto-detection enabled\n     * @param {string} name - name of the language\n     */\n    function autoDetection(name) {\n      const lang = getLanguage(name);\n      return lang && !lang.disableAutodetect;\n    }\n\n    /**\n     * Upgrades the old highlightBlock plugins to the new\n     * highlightElement API\n     * @param {HLJSPlugin} plugin\n     */\n    function upgradePluginAPI(plugin) {\n      // TODO: remove with v12\n      if (plugin[\"before:highlightBlock\"] && !plugin[\"before:highlightElement\"]) {\n        plugin[\"before:highlightElement\"] = (data) => {\n          plugin[\"before:highlightBlock\"](\n            Object.assign({ block: data.el }, data)\n          );\n        };\n      }\n      if (plugin[\"after:highlightBlock\"] && !plugin[\"after:highlightElement\"]) {\n        plugin[\"after:highlightElement\"] = (data) => {\n          plugin[\"after:highlightBlock\"](\n            Object.assign({ block: data.el }, data)\n          );\n        };\n      }\n    }\n\n    /**\n     * @param {HLJSPlugin} plugin\n     */\n    function addPlugin(plugin) {\n      upgradePluginAPI(plugin);\n      plugins.push(plugin);\n    }\n\n    /**\n     * @param {HLJSPlugin} plugin\n     */\n    function removePlugin(plugin) {\n      const index = plugins.indexOf(plugin);\n      if (index !== -1) {\n        plugins.splice(index, 1);\n      }\n    }\n\n    /**\n     *\n     * @param {PluginEvent} event\n     * @param {any} args\n     */\n    function fire(event, args) {\n      const cb = event;\n      plugins.forEach(function(plugin) {\n        if (plugin[cb]) {\n          plugin[cb](args);\n        }\n      });\n    }\n\n    /**\n     * DEPRECATED\n     * @param {HighlightedHTMLElement} el\n     */\n    function deprecateHighlightBlock(el) {\n      deprecated(\"10.7.0\", \"highlightBlock will be removed entirely in v12.0\");\n      deprecated(\"10.7.0\", \"Please use highlightElement now.\");\n\n      return highlightElement(el);\n    }\n\n    /* Interface definition */\n    Object.assign(hljs, {\n      highlight,\n      highlightAuto,\n      highlightAll,\n      highlightElement,\n      // TODO: Remove with v12 API\n      highlightBlock: deprecateHighlightBlock,\n      configure,\n      initHighlighting,\n      initHighlightingOnLoad,\n      registerLanguage,\n      unregisterLanguage,\n      listLanguages,\n      getLanguage,\n      registerAliases,\n      autoDetection,\n      inherit,\n      addPlugin,\n      removePlugin\n    });\n\n    hljs.debugMode = function() { SAFE_MODE = false; };\n    hljs.safeMode = function() { SAFE_MODE = true; };\n    hljs.versionString = version;\n\n    hljs.regex = {\n      concat: concat,\n      lookahead: lookahead,\n      either: either,\n      optional: optional,\n      anyNumberOfTimes: anyNumberOfTimes\n    };\n\n    for (const key in MODES$1) {\n      // @ts-ignore\n      if (typeof MODES$1[key] === \"object\") {\n        // @ts-ignore\n        deepFreeze(MODES$1[key]);\n      }\n    }\n\n    // merge all the modes/regexes into our main object\n    Object.assign(hljs, MODES$1);\n\n    return hljs;\n  };\n\n  // Other names for the variable may break build script\n  const highlight = HLJS({});\n\n  // returns a new instance of the highlighter to be used for extensions\n  // check https://github.com/wooorm/lowlight/issues/47\n  highlight.newInstance = () => HLJS({});\n\n  /*\n  Language: Bash\n  Author: vah <vahtenberg@gmail.com>\n  Contributrors: Benjamin Pannell <contact@sierrasoftworks.com>\n  Website: https://www.gnu.org/software/bash/\n  Category: common, scripting\n  */\n\n  /** @type LanguageFn */\n  function bash(hljs) {\n    const regex = hljs.regex;\n    const VAR = {};\n    const BRACED_VAR = {\n      begin: /\\$\\{/,\n      end: /\\}/,\n      contains: [\n        \"self\",\n        {\n          begin: /:-/,\n          contains: [ VAR ]\n        } // default values\n      ]\n    };\n    Object.assign(VAR, {\n      className: 'variable',\n      variants: [\n        { begin: regex.concat(/\\$[\\w\\d#@][\\w\\d_]*/,\n          // negative look-ahead tries to avoid matching patterns that are not\n          // Perl at all like $ident$, @ident@, etc.\n          `(?![\\\\w\\\\d])(?![$])`) },\n        BRACED_VAR\n      ]\n    });\n\n    const SUBST = {\n      className: 'subst',\n      begin: /\\$\\(/,\n      end: /\\)/,\n      contains: [ hljs.BACKSLASH_ESCAPE ]\n    };\n    const COMMENT = hljs.inherit(\n      hljs.COMMENT(),\n      {\n        match: [\n          /(^|\\s)/,\n          /#.*$/\n        ],\n        scope: {\n          2: 'comment'\n        }\n      }\n    );\n    const HERE_DOC = {\n      begin: /<<-?\\s*(?=\\w+)/,\n      starts: { contains: [\n        hljs.END_SAME_AS_BEGIN({\n          begin: /(\\w+)/,\n          end: /(\\w+)/,\n          className: 'string'\n        })\n      ] }\n    };\n    const QUOTE_STRING = {\n      className: 'string',\n      begin: /\"/,\n      end: /\"/,\n      contains: [\n        hljs.BACKSLASH_ESCAPE,\n        VAR,\n        SUBST\n      ]\n    };\n    SUBST.contains.push(QUOTE_STRING);\n    const ESCAPED_QUOTE = {\n      match: /\\\\\"/\n    };\n    const APOS_STRING = {\n      className: 'string',\n      begin: /'/,\n      end: /'/\n    };\n    const ESCAPED_APOS = {\n      match: /\\\\'/\n    };\n    const ARITHMETIC = {\n      begin: /\\$?\\(\\(/,\n      end: /\\)\\)/,\n      contains: [\n        {\n          begin: /\\d+#[0-9a-f]+/,\n          className: \"number\"\n        },\n        hljs.NUMBER_MODE,\n        VAR\n      ]\n    };\n    const SH_LIKE_SHELLS = [\n      \"fish\",\n      \"bash\",\n      \"zsh\",\n      \"sh\",\n      \"csh\",\n      \"ksh\",\n      \"tcsh\",\n      \"dash\",\n      \"scsh\",\n    ];\n    const KNOWN_SHEBANG = hljs.SHEBANG({\n      binary: `(${SH_LIKE_SHELLS.join(\"|\")})`,\n      relevance: 10\n    });\n    const FUNCTION = {\n      className: 'function',\n      begin: /\\w[\\w\\d_]*\\s*\\(\\s*\\)\\s*\\{/,\n      returnBegin: true,\n      contains: [ hljs.inherit(hljs.TITLE_MODE, { begin: /\\w[\\w\\d_]*/ }) ],\n      relevance: 0\n    };\n\n    const KEYWORDS = [\n      \"if\",\n      \"then\",\n      \"else\",\n      \"elif\",\n      \"fi\",\n      \"time\",\n      \"for\",\n      \"while\",\n      \"until\",\n      \"in\",\n      \"do\",\n      \"done\",\n      \"case\",\n      \"esac\",\n      \"coproc\",\n      \"function\",\n      \"select\"\n    ];\n\n    const LITERALS = [\n      \"true\",\n      \"false\"\n    ];\n\n    // to consume paths to prevent keyword matches inside them\n    const PATH_MODE = { match: /(\\/[a-z._-]+)+/ };\n\n    // http://www.gnu.org/software/bash/manual/html_node/Shell-Builtin-Commands.html\n    const SHELL_BUILT_INS = [\n      \"break\",\n      \"cd\",\n      \"continue\",\n      \"eval\",\n      \"exec\",\n      \"exit\",\n      \"export\",\n      \"getopts\",\n      \"hash\",\n      \"pwd\",\n      \"readonly\",\n      \"return\",\n      \"shift\",\n      \"test\",\n      \"times\",\n      \"trap\",\n      \"umask\",\n      \"unset\"\n    ];\n\n    const BASH_BUILT_INS = [\n      \"alias\",\n      \"bind\",\n      \"builtin\",\n      \"caller\",\n      \"command\",\n      \"declare\",\n      \"echo\",\n      \"enable\",\n      \"help\",\n      \"let\",\n      \"local\",\n      \"logout\",\n      \"mapfile\",\n      \"printf\",\n      \"read\",\n      \"readarray\",\n      \"source\",\n      \"sudo\",\n      \"type\",\n      \"typeset\",\n      \"ulimit\",\n      \"unalias\"\n    ];\n\n    const ZSH_BUILT_INS = [\n      \"autoload\",\n      \"bg\",\n      \"bindkey\",\n      \"bye\",\n      \"cap\",\n      \"chdir\",\n      \"clone\",\n      \"comparguments\",\n      \"compcall\",\n      \"compctl\",\n      \"compdescribe\",\n      \"compfiles\",\n      \"compgroups\",\n      \"compquote\",\n      \"comptags\",\n      \"comptry\",\n      \"compvalues\",\n      \"dirs\",\n      \"disable\",\n      \"disown\",\n      \"echotc\",\n      \"echoti\",\n      \"emulate\",\n      \"fc\",\n      \"fg\",\n      \"float\",\n      \"functions\",\n      \"getcap\",\n      \"getln\",\n      \"history\",\n      \"integer\",\n      \"jobs\",\n      \"kill\",\n      \"limit\",\n      \"log\",\n      \"noglob\",\n      \"popd\",\n      \"print\",\n      \"pushd\",\n      \"pushln\",\n      \"rehash\",\n      \"sched\",\n      \"setcap\",\n      \"setopt\",\n      \"stat\",\n      \"suspend\",\n      \"ttyctl\",\n      \"unfunction\",\n      \"unhash\",\n      \"unlimit\",\n      \"unsetopt\",\n      \"vared\",\n      \"wait\",\n      \"whence\",\n      \"where\",\n      \"which\",\n      \"zcompile\",\n      \"zformat\",\n      \"zftp\",\n      \"zle\",\n      \"zmodload\",\n      \"zparseopts\",\n      \"zprof\",\n      \"zpty\",\n      \"zregexparse\",\n      \"zsocket\",\n      \"zstyle\",\n      \"ztcp\"\n    ];\n\n    const GNU_CORE_UTILS = [\n      \"chcon\",\n      \"chgrp\",\n      \"chown\",\n      \"chmod\",\n      \"cp\",\n      \"dd\",\n      \"df\",\n      \"dir\",\n      \"dircolors\",\n      \"ln\",\n      \"ls\",\n      \"mkdir\",\n      \"mkfifo\",\n      \"mknod\",\n      \"mktemp\",\n      \"mv\",\n      \"realpath\",\n      \"rm\",\n      \"rmdir\",\n      \"shred\",\n      \"sync\",\n      \"touch\",\n      \"truncate\",\n      \"vdir\",\n      \"b2sum\",\n      \"base32\",\n      \"base64\",\n      \"cat\",\n      \"cksum\",\n      \"comm\",\n      \"csplit\",\n      \"cut\",\n      \"expand\",\n      \"fmt\",\n      \"fold\",\n      \"head\",\n      \"join\",\n      \"md5sum\",\n      \"nl\",\n      \"numfmt\",\n      \"od\",\n      \"paste\",\n      \"ptx\",\n      \"pr\",\n      \"sha1sum\",\n      \"sha224sum\",\n      \"sha256sum\",\n      \"sha384sum\",\n      \"sha512sum\",\n      \"shuf\",\n      \"sort\",\n      \"split\",\n      \"sum\",\n      \"tac\",\n      \"tail\",\n      \"tr\",\n      \"tsort\",\n      \"unexpand\",\n      \"uniq\",\n      \"wc\",\n      \"arch\",\n      \"basename\",\n      \"chroot\",\n      \"date\",\n      \"dirname\",\n      \"du\",\n      \"echo\",\n      \"env\",\n      \"expr\",\n      \"factor\",\n      // \"false\", // keyword literal already\n      \"groups\",\n      \"hostid\",\n      \"id\",\n      \"link\",\n      \"logname\",\n      \"nice\",\n      \"nohup\",\n      \"nproc\",\n      \"pathchk\",\n      \"pinky\",\n      \"printenv\",\n      \"printf\",\n      \"pwd\",\n      \"readlink\",\n      \"runcon\",\n      \"seq\",\n      \"sleep\",\n      \"stat\",\n      \"stdbuf\",\n      \"stty\",\n      \"tee\",\n      \"test\",\n      \"timeout\",\n      // \"true\", // keyword literal already\n      \"tty\",\n      \"uname\",\n      \"unlink\",\n      \"uptime\",\n      \"users\",\n      \"who\",\n      \"whoami\",\n      \"yes\"\n    ];\n\n    return {\n      name: 'Bash',\n      aliases: [\n        'sh',\n        'zsh'\n      ],\n      keywords: {\n        $pattern: /\\b[a-z][a-z0-9._-]+\\b/,\n        keyword: KEYWORDS,\n        literal: LITERALS,\n        built_in: [\n          ...SHELL_BUILT_INS,\n          ...BASH_BUILT_INS,\n          // Shell modifiers\n          \"set\",\n          \"shopt\",\n          ...ZSH_BUILT_INS,\n          ...GNU_CORE_UTILS\n        ]\n      },\n      contains: [\n        KNOWN_SHEBANG, // to catch known shells and boost relevancy\n        hljs.SHEBANG(), // to catch unknown shells but still highlight the shebang\n        FUNCTION,\n        ARITHMETIC,\n        COMMENT,\n        HERE_DOC,\n        PATH_MODE,\n        QUOTE_STRING,\n        ESCAPED_QUOTE,\n        APOS_STRING,\n        ESCAPED_APOS,\n        VAR\n      ]\n    };\n  }\n\n  /*\n  Language: C\n  Category: common, system\n  Website: https://en.wikipedia.org/wiki/C_(programming_language)\n  */\n\n  /** @type LanguageFn */\n  function c(hljs) {\n    const regex = hljs.regex;\n    // added for historic reasons because `hljs.C_LINE_COMMENT_MODE` does\n    // not include such support nor can we be sure all the grammars depending\n    // on it would desire this behavior\n    const C_LINE_COMMENT_MODE = hljs.COMMENT('//', '$', { contains: [ { begin: /\\\\\\n/ } ] });\n    const DECLTYPE_AUTO_RE = 'decltype\\\\(auto\\\\)';\n    const NAMESPACE_RE = '[a-zA-Z_]\\\\w*::';\n    const TEMPLATE_ARGUMENT_RE = '<[^<>]+>';\n    const FUNCTION_TYPE_RE = '('\n      + DECLTYPE_AUTO_RE + '|'\n      + regex.optional(NAMESPACE_RE)\n      + '[a-zA-Z_]\\\\w*' + regex.optional(TEMPLATE_ARGUMENT_RE)\n    + ')';\n\n\n    const TYPES = {\n      className: 'type',\n      variants: [\n        { begin: '\\\\b[a-z\\\\d_]*_t\\\\b' },\n        { match: /\\batomic_[a-z]{3,6}\\b/ }\n      ]\n\n    };\n\n    // https://en.cppreference.com/w/cpp/language/escape\n    // \\\\ \\x \\xFF \\u2837 \\u00323747 \\374\n    const CHARACTER_ESCAPES = '\\\\\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\\\S)';\n    const STRINGS = {\n      className: 'string',\n      variants: [\n        {\n          begin: '(u8?|U|L)?\"',\n          end: '\"',\n          illegal: '\\\\n',\n          contains: [ hljs.BACKSLASH_ESCAPE ]\n        },\n        {\n          begin: '(u8?|U|L)?\\'(' + CHARACTER_ESCAPES + \"|.)\",\n          end: '\\'',\n          illegal: '.'\n        },\n        hljs.END_SAME_AS_BEGIN({\n          begin: /(?:u8?|U|L)?R\"([^()\\\\ ]{0,16})\\(/,\n          end: /\\)([^()\\\\ ]{0,16})\"/\n        })\n      ]\n    };\n\n    const NUMBERS = {\n      className: 'number',\n      variants: [\n        { match: /\\b(0b[01']+)/ },  \n        { match: /(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)((ll|LL|l|L)(u|U)?|(u|U)(ll|LL|l|L)?|f|F|b|B)/ },  \n        { match: /(-?)\\b(0[xX][a-fA-F0-9]+(?:'[a-fA-F0-9]+)*(?:\\.[a-fA-F0-9]*(?:'[a-fA-F0-9]*)*)?(?:[pP][-+]?[0-9]+)?(l|L)?(u|U)?)/ },  \n        { match: /(-?)\\b\\d+(?:'\\d+)*(?:\\.\\d*(?:'\\d*)*)?(?:[eE][-+]?\\d+)?/ }  \n    ],\n      relevance: 0\n    };  \n    \n    const PREPROCESSOR = {\n      className: 'meta',\n      begin: /#\\s*[a-z]+\\b/,\n      end: /$/,\n      keywords: { keyword:\n          'if else elif endif define undef warning error line '\n          + 'pragma _Pragma ifdef ifndef elifdef elifndef include' },\n      contains: [\n        {\n          begin: /\\\\\\n/,\n          relevance: 0\n        },\n        hljs.inherit(STRINGS, { className: 'string' }),\n        {\n          className: 'string',\n          begin: /<.*?>/\n        },\n        C_LINE_COMMENT_MODE,\n        hljs.C_BLOCK_COMMENT_MODE\n      ]\n    };\n\n    const TITLE_MODE = {\n      className: 'title',\n      begin: regex.optional(NAMESPACE_RE) + hljs.IDENT_RE,\n      relevance: 0\n    };\n\n    const FUNCTION_TITLE = regex.optional(NAMESPACE_RE) + hljs.IDENT_RE + '\\\\s*\\\\(';\n\n    const C_KEYWORDS = [\n      \"asm\",\n      \"auto\",\n      \"break\",\n      \"case\",\n      \"continue\",\n      \"default\",\n      \"do\",\n      \"else\",\n      \"enum\",\n      \"extern\",\n      \"for\",\n      \"fortran\",\n      \"goto\",\n      \"if\",\n      \"inline\",\n      \"register\",\n      \"restrict\",\n      \"return\",\n      \"sizeof\",\n      \"typeof\",\n      \"typeof_unqual\",\n      \"struct\",\n      \"switch\",\n      \"typedef\",\n      \"union\",\n      \"volatile\",\n      \"while\",\n      \"_Alignas\",\n      \"_Alignof\",\n      \"_Atomic\",\n      \"_Generic\",\n      \"_Noreturn\",\n      \"_Static_assert\",\n      \"_Thread_local\",\n      // aliases\n      \"alignas\",\n      \"alignof\",\n      \"noreturn\",\n      \"static_assert\",\n      \"thread_local\",\n      // not a C keyword but is, for all intents and purposes, treated exactly like one.\n      \"_Pragma\"\n    ];\n\n    const C_TYPES = [\n      \"float\",\n      \"double\",\n      \"signed\",\n      \"unsigned\",\n      \"int\",\n      \"short\",\n      \"long\",\n      \"char\",\n      \"void\",\n      \"_Bool\",\n      \"_BitInt\",\n      \"_Complex\",\n      \"_Imaginary\",\n      \"_Decimal32\",\n      \"_Decimal64\",\n      \"_Decimal96\",\n      \"_Decimal128\",\n      \"_Decimal64x\",\n      \"_Decimal128x\",\n      \"_Float16\",\n      \"_Float32\",\n      \"_Float64\",\n      \"_Float128\",\n      \"_Float32x\",\n      \"_Float64x\",\n      \"_Float128x\",\n      // modifiers\n      \"const\",\n      \"static\",\n      \"constexpr\",\n      // aliases\n      \"complex\",\n      \"bool\",\n      \"imaginary\"\n    ];\n\n    const KEYWORDS = {\n      keyword: C_KEYWORDS,\n      type: C_TYPES,\n      literal: 'true false NULL',\n      // TODO: apply hinting work similar to what was done in cpp.js\n      built_in: 'std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream '\n        + 'auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set '\n        + 'unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos '\n        + 'asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp '\n        + 'fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper '\n        + 'isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow '\n        + 'printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp '\n        + 'strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan '\n        + 'vfprintf vprintf vsprintf endl initializer_list unique_ptr',\n    };\n\n    const EXPRESSION_CONTAINS = [\n      PREPROCESSOR,\n      TYPES,\n      C_LINE_COMMENT_MODE,\n      hljs.C_BLOCK_COMMENT_MODE,\n      NUMBERS,\n      STRINGS\n    ];\n\n    const EXPRESSION_CONTEXT = {\n      // This mode covers expression context where we can't expect a function\n      // definition and shouldn't highlight anything that looks like one:\n      // `return some()`, `else if()`, `(x*sum(1, 2))`\n      variants: [\n        {\n          begin: /=/,\n          end: /;/\n        },\n        {\n          begin: /\\(/,\n          end: /\\)/\n        },\n        {\n          beginKeywords: 'new throw return else',\n          end: /;/\n        }\n      ],\n      keywords: KEYWORDS,\n      contains: EXPRESSION_CONTAINS.concat([\n        {\n          begin: /\\(/,\n          end: /\\)/,\n          keywords: KEYWORDS,\n          contains: EXPRESSION_CONTAINS.concat([ 'self' ]),\n          relevance: 0\n        }\n      ]),\n      relevance: 0\n    };\n\n    const FUNCTION_DECLARATION = {\n      begin: '(' + FUNCTION_TYPE_RE + '[\\\\*&\\\\s]+)+' + FUNCTION_TITLE,\n      returnBegin: true,\n      end: /[{;=]/,\n      excludeEnd: true,\n      keywords: KEYWORDS,\n      illegal: /[^\\w\\s\\*&:<>.]/,\n      contains: [\n        { // to prevent it from being confused as the function title\n          begin: DECLTYPE_AUTO_RE,\n          keywords: KEYWORDS,\n          relevance: 0\n        },\n        {\n          begin: FUNCTION_TITLE,\n          returnBegin: true,\n          contains: [ hljs.inherit(TITLE_MODE, { className: \"title.function\" }) ],\n          relevance: 0\n        },\n        // allow for multiple declarations, e.g.:\n        // extern void f(int), g(char);\n        {\n          relevance: 0,\n          match: /,/\n        },\n        {\n          className: 'params',\n          begin: /\\(/,\n          end: /\\)/,\n          keywords: KEYWORDS,\n          relevance: 0,\n          contains: [\n            C_LINE_COMMENT_MODE,\n            hljs.C_BLOCK_COMMENT_MODE,\n            STRINGS,\n            NUMBERS,\n            TYPES,\n            // Count matching parentheses.\n            {\n              begin: /\\(/,\n              end: /\\)/,\n              keywords: KEYWORDS,\n              relevance: 0,\n              contains: [\n                'self',\n                C_LINE_COMMENT_MODE,\n                hljs.C_BLOCK_COMMENT_MODE,\n                STRINGS,\n                NUMBERS,\n                TYPES\n              ]\n            }\n          ]\n        },\n        TYPES,\n        C_LINE_COMMENT_MODE,\n        hljs.C_BLOCK_COMMENT_MODE,\n        PREPROCESSOR\n      ]\n    };\n\n    return {\n      name: \"C\",\n      aliases: [ 'h' ],\n      keywords: KEYWORDS,\n      // Until differentiations are added between `c` and `cpp`, `c` will\n      // not be auto-detected to avoid auto-detect conflicts between C and C++\n      disableAutodetect: true,\n      illegal: '</',\n      contains: [].concat(\n        EXPRESSION_CONTEXT,\n        FUNCTION_DECLARATION,\n        EXPRESSION_CONTAINS,\n        [\n          PREPROCESSOR,\n          {\n            begin: hljs.IDENT_RE + '::',\n            keywords: KEYWORDS\n          },\n          {\n            className: 'class',\n            beginKeywords: 'enum class struct union',\n            end: /[{;:<>=]/,\n            contains: [\n              { beginKeywords: \"final class struct\" },\n              hljs.TITLE_MODE\n            ]\n          }\n        ]),\n      exports: {\n        preprocessor: PREPROCESSOR,\n        strings: STRINGS,\n        keywords: KEYWORDS\n      }\n    };\n  }\n\n  /*\n  Language: C++\n  Category: common, system\n  Website: https://isocpp.org\n  */\n\n  /** @type LanguageFn */\n  function cpp(hljs) {\n    const regex = hljs.regex;\n    // added for historic reasons because `hljs.C_LINE_COMMENT_MODE` does\n    // not include such support nor can we be sure all the grammars depending\n    // on it would desire this behavior\n    const C_LINE_COMMENT_MODE = hljs.COMMENT('//', '$', { contains: [ { begin: /\\\\\\n/ } ] });\n    const DECLTYPE_AUTO_RE = 'decltype\\\\(auto\\\\)';\n    const NAMESPACE_RE = '[a-zA-Z_]\\\\w*::';\n    const TEMPLATE_ARGUMENT_RE = '<[^<>]+>';\n    const FUNCTION_TYPE_RE = '(?!struct)('\n      + DECLTYPE_AUTO_RE + '|'\n      + regex.optional(NAMESPACE_RE)\n      + '[a-zA-Z_]\\\\w*' + regex.optional(TEMPLATE_ARGUMENT_RE)\n    + ')';\n\n    const CPP_PRIMITIVE_TYPES = {\n      className: 'type',\n      begin: '\\\\b[a-z\\\\d_]*_t\\\\b'\n    };\n\n    // https://en.cppreference.com/w/cpp/language/escape\n    // \\\\ \\x \\xFF \\u2837 \\u00323747 \\374\n    const CHARACTER_ESCAPES = '\\\\\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\\\S)';\n    const STRINGS = {\n      className: 'string',\n      variants: [\n        {\n          begin: '(u8?|U|L)?\"',\n          end: '\"',\n          illegal: '\\\\n',\n          contains: [ hljs.BACKSLASH_ESCAPE ]\n        },\n        {\n          begin: '(u8?|U|L)?\\'(' + CHARACTER_ESCAPES + '|.)',\n          end: '\\'',\n          illegal: '.'\n        },\n        hljs.END_SAME_AS_BEGIN({\n          begin: /(?:u8?|U|L)?R\"([^()\\\\ ]{0,16})\\(/,\n          end: /\\)([^()\\\\ ]{0,16})\"/\n        })\n      ]\n    };\n\n    const NUMBERS = {\n      className: 'number',\n      variants: [\n        // Floating-point literal.\n        { begin:\n          \"[+-]?(?:\" // Leading sign.\n            // Decimal.\n            + \"(?:\"\n              +\"[0-9](?:'?[0-9])*\\\\.(?:[0-9](?:'?[0-9])*)?\"\n              + \"|\\\\.[0-9](?:'?[0-9])*\"\n            + \")(?:[Ee][+-]?[0-9](?:'?[0-9])*)?\"\n            + \"|[0-9](?:'?[0-9])*[Ee][+-]?[0-9](?:'?[0-9])*\"\n            // Hexadecimal.\n            + \"|0[Xx](?:\"\n              +\"[0-9A-Fa-f](?:'?[0-9A-Fa-f])*(?:\\\\.(?:[0-9A-Fa-f](?:'?[0-9A-Fa-f])*)?)?\"\n              + \"|\\\\.[0-9A-Fa-f](?:'?[0-9A-Fa-f])*\"\n            + \")[Pp][+-]?[0-9](?:'?[0-9])*\"\n          + \")(?:\" // Literal suffixes.\n            + \"[Ff](?:16|32|64|128)?\"\n            + \"|(BF|bf)16\"\n            + \"|[Ll]\"\n            + \"|\" // Literal suffix is optional.\n          + \")\"\n        },\n        // Integer literal.\n        { begin:\n          \"[+-]?\\\\b(?:\" // Leading sign.\n            + \"0[Bb][01](?:'?[01])*\" // Binary.\n            + \"|0[Xx][0-9A-Fa-f](?:'?[0-9A-Fa-f])*\" // Hexadecimal.\n            + \"|0(?:'?[0-7])*\" // Octal or just a lone zero.\n            + \"|[1-9](?:'?[0-9])*\" // Decimal.\n          + \")(?:\" // Literal suffixes.\n            + \"[Uu](?:LL?|ll?)\"\n            + \"|[Uu][Zz]?\"\n            + \"|(?:LL?|ll?)[Uu]?\"\n            + \"|[Zz][Uu]\"\n            + \"|\" // Literal suffix is optional.\n          + \")\"\n          // Note: there are user-defined literal suffixes too, but perhaps having the custom suffix not part of the\n          // literal highlight actually makes it stand out more.\n        }\n      ],\n      relevance: 0\n    };\n\n    const PREPROCESSOR = {\n      className: 'meta',\n      begin: /#\\s*[a-z]+\\b/,\n      end: /$/,\n      keywords: { keyword:\n          'if else elif endif define undef warning error line '\n          + 'pragma _Pragma ifdef ifndef include' },\n      contains: [\n        {\n          begin: /\\\\\\n/,\n          relevance: 0\n        },\n        hljs.inherit(STRINGS, { className: 'string' }),\n        {\n          className: 'string',\n          begin: /<.*?>/\n        },\n        C_LINE_COMMENT_MODE,\n        hljs.C_BLOCK_COMMENT_MODE\n      ]\n    };\n\n    const TITLE_MODE = {\n      className: 'title',\n      begin: regex.optional(NAMESPACE_RE) + hljs.IDENT_RE,\n      relevance: 0\n    };\n\n    const FUNCTION_TITLE = regex.optional(NAMESPACE_RE) + hljs.IDENT_RE + '\\\\s*\\\\(';\n\n    // https://en.cppreference.com/w/cpp/keyword\n    const RESERVED_KEYWORDS = [\n      'alignas',\n      'alignof',\n      'and',\n      'and_eq',\n      'asm',\n      'atomic_cancel',\n      'atomic_commit',\n      'atomic_noexcept',\n      'auto',\n      'bitand',\n      'bitor',\n      'break',\n      'case',\n      'catch',\n      'class',\n      'co_await',\n      'co_return',\n      'co_yield',\n      'compl',\n      'concept',\n      'const_cast|10',\n      'consteval',\n      'constexpr',\n      'constinit',\n      'continue',\n      'decltype',\n      'default',\n      'delete',\n      'do',\n      'dynamic_cast|10',\n      'else',\n      'enum',\n      'explicit',\n      'export',\n      'extern',\n      'false',\n      'final',\n      'for',\n      'friend',\n      'goto',\n      'if',\n      'import',\n      'inline',\n      'module',\n      'mutable',\n      'namespace',\n      'new',\n      'noexcept',\n      'not',\n      'not_eq',\n      'nullptr',\n      'operator',\n      'or',\n      'or_eq',\n      'override',\n      'private',\n      'protected',\n      'public',\n      'reflexpr',\n      'register',\n      'reinterpret_cast|10',\n      'requires',\n      'return',\n      'sizeof',\n      'static_assert',\n      'static_cast|10',\n      'struct',\n      'switch',\n      'synchronized',\n      'template',\n      'this',\n      'thread_local',\n      'throw',\n      'transaction_safe',\n      'transaction_safe_dynamic',\n      'true',\n      'try',\n      'typedef',\n      'typeid',\n      'typename',\n      'union',\n      'using',\n      'virtual',\n      'volatile',\n      'while',\n      'xor',\n      'xor_eq'\n    ];\n\n    // https://en.cppreference.com/w/cpp/keyword\n    const RESERVED_TYPES = [\n      'bool',\n      'char',\n      'char16_t',\n      'char32_t',\n      'char8_t',\n      'double',\n      'float',\n      'int',\n      'long',\n      'short',\n      'void',\n      'wchar_t',\n      'unsigned',\n      'signed',\n      'const',\n      'static'\n    ];\n\n    const TYPE_HINTS = [\n      'any',\n      'auto_ptr',\n      'barrier',\n      'binary_semaphore',\n      'bitset',\n      'complex',\n      'condition_variable',\n      'condition_variable_any',\n      'counting_semaphore',\n      'deque',\n      'false_type',\n      'flat_map',\n      'flat_set',\n      'future',\n      'imaginary',\n      'initializer_list',\n      'istringstream',\n      'jthread',\n      'latch',\n      'lock_guard',\n      'multimap',\n      'multiset',\n      'mutex',\n      'optional',\n      'ostringstream',\n      'packaged_task',\n      'pair',\n      'promise',\n      'priority_queue',\n      'queue',\n      'recursive_mutex',\n      'recursive_timed_mutex',\n      'scoped_lock',\n      'set',\n      'shared_future',\n      'shared_lock',\n      'shared_mutex',\n      'shared_timed_mutex',\n      'shared_ptr',\n      'stack',\n      'string_view',\n      'stringstream',\n      'timed_mutex',\n      'thread',\n      'true_type',\n      'tuple',\n      'unique_lock',\n      'unique_ptr',\n      'unordered_map',\n      'unordered_multimap',\n      'unordered_multiset',\n      'unordered_set',\n      'variant',\n      'vector',\n      'weak_ptr',\n      'wstring',\n      'wstring_view'\n    ];\n\n    const FUNCTION_HINTS = [\n      'abort',\n      'abs',\n      'acos',\n      'apply',\n      'as_const',\n      'asin',\n      'atan',\n      'atan2',\n      'calloc',\n      'ceil',\n      'cerr',\n      'cin',\n      'clog',\n      'cos',\n      'cosh',\n      'cout',\n      'declval',\n      'endl',\n      'exchange',\n      'exit',\n      'exp',\n      'fabs',\n      'floor',\n      'fmod',\n      'forward',\n      'fprintf',\n      'fputs',\n      'free',\n      'frexp',\n      'fscanf',\n      'future',\n      'invoke',\n      'isalnum',\n      'isalpha',\n      'iscntrl',\n      'isdigit',\n      'isgraph',\n      'islower',\n      'isprint',\n      'ispunct',\n      'isspace',\n      'isupper',\n      'isxdigit',\n      'labs',\n      'launder',\n      'ldexp',\n      'log',\n      'log10',\n      'make_pair',\n      'make_shared',\n      'make_shared_for_overwrite',\n      'make_tuple',\n      'make_unique',\n      'malloc',\n      'memchr',\n      'memcmp',\n      'memcpy',\n      'memset',\n      'modf',\n      'move',\n      'pow',\n      'printf',\n      'putchar',\n      'puts',\n      'realloc',\n      'scanf',\n      'sin',\n      'sinh',\n      'snprintf',\n      'sprintf',\n      'sqrt',\n      'sscanf',\n      'std',\n      'stderr',\n      'stdin',\n      'stdout',\n      'strcat',\n      'strchr',\n      'strcmp',\n      'strcpy',\n      'strcspn',\n      'strlen',\n      'strncat',\n      'strncmp',\n      'strncpy',\n      'strpbrk',\n      'strrchr',\n      'strspn',\n      'strstr',\n      'swap',\n      'tan',\n      'tanh',\n      'terminate',\n      'to_underlying',\n      'tolower',\n      'toupper',\n      'vfprintf',\n      'visit',\n      'vprintf',\n      'vsprintf'\n    ];\n\n    const LITERALS = [\n      'NULL',\n      'false',\n      'nullopt',\n      'nullptr',\n      'true'\n    ];\n\n    // https://en.cppreference.com/w/cpp/keyword\n    const BUILT_IN = [ '_Pragma' ];\n\n    const CPP_KEYWORDS = {\n      type: RESERVED_TYPES,\n      keyword: RESERVED_KEYWORDS,\n      literal: LITERALS,\n      built_in: BUILT_IN,\n      _type_hints: TYPE_HINTS\n    };\n\n    const FUNCTION_DISPATCH = {\n      className: 'function.dispatch',\n      relevance: 0,\n      keywords: {\n        // Only for relevance, not highlighting.\n        _hint: FUNCTION_HINTS },\n      begin: regex.concat(\n        /\\b/,\n        `(?!${RESERVED_KEYWORDS.join('|')})`,\n        hljs.IDENT_RE,\n        regex.lookahead(/(<[^<>]+>|)\\s*\\(/))\n    };\n\n    const EXPRESSION_CONTAINS = [\n      FUNCTION_DISPATCH,\n      PREPROCESSOR,\n      CPP_PRIMITIVE_TYPES,\n      C_LINE_COMMENT_MODE,\n      hljs.C_BLOCK_COMMENT_MODE,\n      NUMBERS,\n      STRINGS\n    ];\n\n    const EXPRESSION_CONTEXT = {\n      // This mode covers expression context where we can't expect a function\n      // definition and shouldn't highlight anything that looks like one:\n      // `return some()`, `else if()`, `(x*sum(1, 2))`\n      variants: [\n        {\n          begin: /=/,\n          end: /;/\n        },\n        {\n          begin: /\\(/,\n          end: /\\)/\n        },\n        {\n          beginKeywords: 'new throw return else',\n          end: /;/\n        }\n      ],\n      keywords: CPP_KEYWORDS,\n      contains: EXPRESSION_CONTAINS.concat([\n        {\n          begin: /\\(/,\n          end: /\\)/,\n          keywords: CPP_KEYWORDS,\n          contains: EXPRESSION_CONTAINS.concat([ 'self' ]),\n          relevance: 0\n        }\n      ]),\n      relevance: 0\n    };\n\n    const FUNCTION_DECLARATION = {\n      className: 'function',\n      begin: '(' + FUNCTION_TYPE_RE + '[\\\\*&\\\\s]+)+' + FUNCTION_TITLE,\n      returnBegin: true,\n      end: /[{;=]/,\n      excludeEnd: true,\n      keywords: CPP_KEYWORDS,\n      illegal: /[^\\w\\s\\*&:<>.]/,\n      contains: [\n        { // to prevent it from being confused as the function title\n          begin: DECLTYPE_AUTO_RE,\n          keywords: CPP_KEYWORDS,\n          relevance: 0\n        },\n        {\n          begin: FUNCTION_TITLE,\n          returnBegin: true,\n          contains: [ TITLE_MODE ],\n          relevance: 0\n        },\n        // needed because we do not have look-behind on the below rule\n        // to prevent it from grabbing the final : in a :: pair\n        {\n          begin: /::/,\n          relevance: 0\n        },\n        // initializers\n        {\n          begin: /:/,\n          endsWithParent: true,\n          contains: [\n            STRINGS,\n            NUMBERS\n          ]\n        },\n        // allow for multiple declarations, e.g.:\n        // extern void f(int), g(char);\n        {\n          relevance: 0,\n          match: /,/\n        },\n        {\n          className: 'params',\n          begin: /\\(/,\n          end: /\\)/,\n          keywords: CPP_KEYWORDS,\n          relevance: 0,\n          contains: [\n            C_LINE_COMMENT_MODE,\n            hljs.C_BLOCK_COMMENT_MODE,\n            STRINGS,\n            NUMBERS,\n            CPP_PRIMITIVE_TYPES,\n            // Count matching parentheses.\n            {\n              begin: /\\(/,\n              end: /\\)/,\n              keywords: CPP_KEYWORDS,\n              relevance: 0,\n              contains: [\n                'self',\n                C_LINE_COMMENT_MODE,\n                hljs.C_BLOCK_COMMENT_MODE,\n                STRINGS,\n                NUMBERS,\n                CPP_PRIMITIVE_TYPES\n              ]\n            }\n          ]\n        },\n        CPP_PRIMITIVE_TYPES,\n        C_LINE_COMMENT_MODE,\n        hljs.C_BLOCK_COMMENT_MODE,\n        PREPROCESSOR\n      ]\n    };\n\n    return {\n      name: 'C++',\n      aliases: [\n        'cc',\n        'c++',\n        'h++',\n        'hpp',\n        'hh',\n        'hxx',\n        'cxx'\n      ],\n      keywords: CPP_KEYWORDS,\n      illegal: '</',\n      classNameAliases: { 'function.dispatch': 'built_in' },\n      contains: [].concat(\n        EXPRESSION_CONTEXT,\n        FUNCTION_DECLARATION,\n        FUNCTION_DISPATCH,\n        EXPRESSION_CONTAINS,\n        [\n          PREPROCESSOR,\n          { // containers: ie, `vector <int> rooms (9);`\n            begin: '\\\\b(deque|list|queue|priority_queue|pair|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array|tuple|optional|variant|function|flat_map|flat_set)\\\\s*<(?!<)',\n            end: '>',\n            keywords: CPP_KEYWORDS,\n            contains: [\n              'self',\n              CPP_PRIMITIVE_TYPES\n            ]\n          },\n          {\n            begin: hljs.IDENT_RE + '::',\n            keywords: CPP_KEYWORDS\n          },\n          {\n            match: [\n              // extra complexity to deal with `enum class` and `enum struct`\n              /\\b(?:enum(?:\\s+(?:class|struct))?|class|struct|union)/,\n              /\\s+/,\n              /\\w+/\n            ],\n            className: {\n              1: 'keyword',\n              3: 'title.class'\n            }\n          }\n        ])\n    };\n  }\n\n  /*\n  Language: C#\n  Author: Jason Diamond <jason@diamond.name>\n  Contributor: Nicolas LLOBERA <nllobera@gmail.com>, Pieter Vantorre <pietervantorre@gmail.com>, David Pine <david.pine@microsoft.com>\n  Website: https://docs.microsoft.com/dotnet/csharp/\n  Category: common\n  */\n\n  /** @type LanguageFn */\n  function csharp(hljs) {\n    const BUILT_IN_KEYWORDS = [\n      'bool',\n      'byte',\n      'char',\n      'decimal',\n      'delegate',\n      'double',\n      'dynamic',\n      'enum',\n      'float',\n      'int',\n      'long',\n      'nint',\n      'nuint',\n      'object',\n      'sbyte',\n      'short',\n      'string',\n      'ulong',\n      'uint',\n      'ushort'\n    ];\n    const FUNCTION_MODIFIERS = [\n      'public',\n      'private',\n      'protected',\n      'static',\n      'internal',\n      'protected',\n      'abstract',\n      'async',\n      'extern',\n      'override',\n      'unsafe',\n      'virtual',\n      'new',\n      'sealed',\n      'partial'\n    ];\n    const LITERAL_KEYWORDS = [\n      'default',\n      'false',\n      'null',\n      'true'\n    ];\n    const NORMAL_KEYWORDS = [\n      'abstract',\n      'as',\n      'base',\n      'break',\n      'case',\n      'catch',\n      'class',\n      'const',\n      'continue',\n      'do',\n      'else',\n      'event',\n      'explicit',\n      'extern',\n      'finally',\n      'fixed',\n      'for',\n      'foreach',\n      'goto',\n      'if',\n      'implicit',\n      'in',\n      'interface',\n      'internal',\n      'is',\n      'lock',\n      'namespace',\n      'new',\n      'operator',\n      'out',\n      'override',\n      'params',\n      'private',\n      'protected',\n      'public',\n      'readonly',\n      'record',\n      'ref',\n      'return',\n      'scoped',\n      'sealed',\n      'sizeof',\n      'stackalloc',\n      'static',\n      'struct',\n      'switch',\n      'this',\n      'throw',\n      'try',\n      'typeof',\n      'unchecked',\n      'unsafe',\n      'using',\n      'virtual',\n      'void',\n      'volatile',\n      'while'\n    ];\n    const CONTEXTUAL_KEYWORDS = [\n      'add',\n      'alias',\n      'and',\n      'ascending',\n      'args',\n      'async',\n      'await',\n      'by',\n      'descending',\n      'dynamic',\n      'equals',\n      'file',\n      'from',\n      'get',\n      'global',\n      'group',\n      'init',\n      'into',\n      'join',\n      'let',\n      'nameof',\n      'not',\n      'notnull',\n      'on',\n      'or',\n      'orderby',\n      'partial',\n      'record',\n      'remove',\n      'required',\n      'scoped',\n      'select',\n      'set',\n      'unmanaged',\n      'value|0',\n      'var',\n      'when',\n      'where',\n      'with',\n      'yield'\n    ];\n\n    const KEYWORDS = {\n      keyword: NORMAL_KEYWORDS.concat(CONTEXTUAL_KEYWORDS),\n      built_in: BUILT_IN_KEYWORDS,\n      literal: LITERAL_KEYWORDS\n    };\n    const TITLE_MODE = hljs.inherit(hljs.TITLE_MODE, { begin: '[a-zA-Z](\\\\.?\\\\w)*' });\n    const NUMBERS = {\n      className: 'number',\n      variants: [\n        { begin: '\\\\b(0b[01\\']+)' },\n        { begin: '(-?)\\\\b([\\\\d\\']+(\\\\.[\\\\d\\']*)?|\\\\.[\\\\d\\']+)(u|U|l|L|ul|UL|f|F|b|B)' },\n        { begin: '(-?)(\\\\b0[xX][a-fA-F0-9\\'_]+|(\\\\b[\\\\d\\'_]+(\\\\.[\\\\d\\'_]*)?|\\\\.[\\\\d\\'_]+)([eE][-+]?[\\\\d\\'_]+)?)' }\n      ],\n      relevance: 0\n    };\n    const RAW_STRING = {\n      className: 'string',\n      begin: /\"\"\"(\"*)(?!\")(.|\\n)*?\"\"\"\\1/,\n      relevance: 1\n    };\n    const VERBATIM_STRING = {\n      className: 'string',\n      begin: '@\"',\n      end: '\"',\n      contains: [ { begin: '\"\"' } ]\n    };\n    const VERBATIM_STRING_NO_LF = hljs.inherit(VERBATIM_STRING, { illegal: /\\n/ });\n    const SUBST = {\n      className: 'subst',\n      begin: /\\{/,\n      end: /\\}/,\n      keywords: KEYWORDS\n    };\n    const SUBST_NO_LF = hljs.inherit(SUBST, { illegal: /\\n/ });\n    const INTERPOLATED_STRING = {\n      className: 'string',\n      begin: /\\$\"/,\n      end: '\"',\n      illegal: /\\n/,\n      contains: [\n        { begin: /\\{\\{/ },\n        { begin: /\\}\\}/ },\n        hljs.BACKSLASH_ESCAPE,\n        SUBST_NO_LF\n      ]\n    };\n    const INTERPOLATED_VERBATIM_STRING = {\n      className: 'string',\n      begin: /\\$@\"/,\n      end: '\"',\n      contains: [\n        { begin: /\\{\\{/ },\n        { begin: /\\}\\}/ },\n        { begin: '\"\"' },\n        SUBST\n      ]\n    };\n    const INTERPOLATED_VERBATIM_STRING_NO_LF = hljs.inherit(INTERPOLATED_VERBATIM_STRING, {\n      illegal: /\\n/,\n      contains: [\n        { begin: /\\{\\{/ },\n        { begin: /\\}\\}/ },\n        { begin: '\"\"' },\n        SUBST_NO_LF\n      ]\n    });\n    SUBST.contains = [\n      INTERPOLATED_VERBATIM_STRING,\n      INTERPOLATED_STRING,\n      VERBATIM_STRING,\n      hljs.APOS_STRING_MODE,\n      hljs.QUOTE_STRING_MODE,\n      NUMBERS,\n      hljs.C_BLOCK_COMMENT_MODE\n    ];\n    SUBST_NO_LF.contains = [\n      INTERPOLATED_VERBATIM_STRING_NO_LF,\n      INTERPOLATED_STRING,\n      VERBATIM_STRING_NO_LF,\n      hljs.APOS_STRING_MODE,\n      hljs.QUOTE_STRING_MODE,\n      NUMBERS,\n      hljs.inherit(hljs.C_BLOCK_COMMENT_MODE, { illegal: /\\n/ })\n    ];\n    const STRING = { variants: [\n      RAW_STRING,\n      INTERPOLATED_VERBATIM_STRING,\n      INTERPOLATED_STRING,\n      VERBATIM_STRING,\n      hljs.APOS_STRING_MODE,\n      hljs.QUOTE_STRING_MODE\n    ] };\n\n    const GENERIC_MODIFIER = {\n      begin: \"<\",\n      end: \">\",\n      contains: [\n        { beginKeywords: \"in out\" },\n        TITLE_MODE\n      ]\n    };\n    const TYPE_IDENT_RE = hljs.IDENT_RE + '(<' + hljs.IDENT_RE + '(\\\\s*,\\\\s*' + hljs.IDENT_RE + ')*>)?(\\\\[\\\\])?';\n    const AT_IDENTIFIER = {\n      // prevents expressions like `@class` from incorrect flagging\n      // `class` as a keyword\n      begin: \"@\" + hljs.IDENT_RE,\n      relevance: 0\n    };\n\n    return {\n      name: 'C#',\n      aliases: [\n        'cs',\n        'c#'\n      ],\n      keywords: KEYWORDS,\n      illegal: /::/,\n      contains: [\n        hljs.COMMENT(\n          '///',\n          '$',\n          {\n            returnBegin: true,\n            contains: [\n              {\n                className: 'doctag',\n                variants: [\n                  {\n                    begin: '///',\n                    relevance: 0\n                  },\n                  { begin: '<!--|-->' },\n                  {\n                    begin: '</?',\n                    end: '>'\n                  }\n                ]\n              }\n            ]\n          }\n        ),\n        hljs.C_LINE_COMMENT_MODE,\n        hljs.C_BLOCK_COMMENT_MODE,\n        {\n          className: 'meta',\n          begin: '#',\n          end: '$',\n          keywords: { keyword: 'if else elif endif define undef warning error line region endregion pragma checksum' }\n        },\n        STRING,\n        NUMBERS,\n        {\n          beginKeywords: 'class interface',\n          relevance: 0,\n          end: /[{;=]/,\n          illegal: /[^\\s:,]/,\n          contains: [\n            { beginKeywords: \"where class\" },\n            TITLE_MODE,\n            GENERIC_MODIFIER,\n            hljs.C_LINE_COMMENT_MODE,\n            hljs.C_BLOCK_COMMENT_MODE\n          ]\n        },\n        {\n          beginKeywords: 'namespace',\n          relevance: 0,\n          end: /[{;=]/,\n          illegal: /[^\\s:]/,\n          contains: [\n            TITLE_MODE,\n            hljs.C_LINE_COMMENT_MODE,\n            hljs.C_BLOCK_COMMENT_MODE\n          ]\n        },\n        {\n          beginKeywords: 'record',\n          relevance: 0,\n          end: /[{;=]/,\n          illegal: /[^\\s:]/,\n          contains: [\n            TITLE_MODE,\n            GENERIC_MODIFIER,\n            hljs.C_LINE_COMMENT_MODE,\n            hljs.C_BLOCK_COMMENT_MODE\n          ]\n        },\n        {\n          // [Attributes(\"\")]\n          className: 'meta',\n          begin: '^\\\\s*\\\\[(?=[\\\\w])',\n          excludeBegin: true,\n          end: '\\\\]',\n          excludeEnd: true,\n          contains: [\n            {\n              className: 'string',\n              begin: /\"/,\n              end: /\"/\n            }\n          ]\n        },\n        {\n          // Expression keywords prevent 'keyword Name(...)' from being\n          // recognized as a function definition\n          beginKeywords: 'new return throw await else',\n          relevance: 0\n        },\n        {\n          className: 'function',\n          begin: '(' + TYPE_IDENT_RE + '\\\\s+)+' + hljs.IDENT_RE + '\\\\s*(<[^=]+>\\\\s*)?\\\\(',\n          returnBegin: true,\n          end: /\\s*[{;=]/,\n          excludeEnd: true,\n          keywords: KEYWORDS,\n          contains: [\n            // prevents these from being highlighted `title`\n            {\n              beginKeywords: FUNCTION_MODIFIERS.join(\" \"),\n              relevance: 0\n            },\n            {\n              begin: hljs.IDENT_RE + '\\\\s*(<[^=]+>\\\\s*)?\\\\(',\n              returnBegin: true,\n              contains: [\n                hljs.TITLE_MODE,\n                GENERIC_MODIFIER\n              ],\n              relevance: 0\n            },\n            { match: /\\(\\)/ },\n            {\n              className: 'params',\n              begin: /\\(/,\n              end: /\\)/,\n              excludeBegin: true,\n              excludeEnd: true,\n              keywords: KEYWORDS,\n              relevance: 0,\n              contains: [\n                STRING,\n                NUMBERS,\n                hljs.C_BLOCK_COMMENT_MODE\n              ]\n            },\n            hljs.C_LINE_COMMENT_MODE,\n            hljs.C_BLOCK_COMMENT_MODE\n          ]\n        },\n        AT_IDENTIFIER\n      ]\n    };\n  }\n\n  const MODES = (hljs) => {\n    return {\n      IMPORTANT: {\n        scope: 'meta',\n        begin: '!important'\n      },\n      BLOCK_COMMENT: hljs.C_BLOCK_COMMENT_MODE,\n      HEXCOLOR: {\n        scope: 'number',\n        begin: /#(([0-9a-fA-F]{3,4})|(([0-9a-fA-F]{2}){3,4}))\\b/\n      },\n      UNICODE_RANGE: {\n        scope: 'number',\n        begin: /\\b[Uu]\\+[0-9A-Fa-f][0-9A-Fa-f?]{0,4}(-[0-9A-Fa-f][0-9A-Fa-f]{0,4})?/\n      },\n      FUNCTION_DISPATCH: {\n        className: \"built_in\",\n        begin: /[\\w-]+(?=\\()/\n      },\n      ATTRIBUTE_SELECTOR_MODE: {\n        scope: 'selector-attr',\n        begin: /\\[/,\n        end: /\\]/,\n        illegal: '$',\n        contains: [\n          hljs.APOS_STRING_MODE,\n          hljs.QUOTE_STRING_MODE\n        ]\n      },\n      CSS_NUMBER_MODE: {\n        scope: 'number',\n        begin: hljs.NUMBER_RE + '(' +\n          '%|em|ex|ch|rem' +\n          '|vw|vh|vmin|vmax' +\n          '|cm|mm|in|pt|pc|px' +\n          '|deg|grad|rad|turn' +\n          '|s|ms' +\n          '|Hz|kHz' +\n          '|dpi|dpcm|dppx' +\n          ')?',\n        relevance: 0\n      },\n      CSS_VARIABLE: {\n        className: \"attr\",\n        begin: /--[A-Za-z_][A-Za-z0-9_-]*/\n      }\n    };\n  };\n\n  const HTML_TAGS = [\n    'a',\n    'abbr',\n    'address',\n    'article',\n    'aside',\n    'audio',\n    'b',\n    'blockquote',\n    'body',\n    'button',\n    'canvas',\n    'caption',\n    'cite',\n    'code',\n    'dd',\n    'del',\n    'details',\n    'dfn',\n    'div',\n    'dl',\n    'dt',\n    'em',\n    'fieldset',\n    'figcaption',\n    'figure',\n    'footer',\n    'form',\n    'h1',\n    'h2',\n    'h3',\n    'h4',\n    'h5',\n    'h6',\n    'header',\n    'hgroup',\n    'html',\n    'i',\n    'iframe',\n    'img',\n    'input',\n    'ins',\n    'kbd',\n    'label',\n    'legend',\n    'li',\n    'main',\n    'mark',\n    'menu',\n    'nav',\n    'object',\n    'ol',\n    'optgroup',\n    'option',\n    'p',\n    'picture',\n    'q',\n    'quote',\n    'samp',\n    'section',\n    'select',\n    'source',\n    'span',\n    'strong',\n    'summary',\n    'sup',\n    'table',\n    'tbody',\n    'td',\n    'textarea',\n    'tfoot',\n    'th',\n    'thead',\n    'time',\n    'tr',\n    'ul',\n    'var',\n    'video'\n  ];\n\n  const SVG_TAGS = [\n    'defs',\n    'g',\n    'marker',\n    'mask',\n    'pattern',\n    'svg',\n    'switch',\n    'symbol',\n    'feBlend',\n    'feColorMatrix',\n    'feComponentTransfer',\n    'feComposite',\n    'feConvolveMatrix',\n    'feDiffuseLighting',\n    'feDisplacementMap',\n    'feFlood',\n    'feGaussianBlur',\n    'feImage',\n    'feMerge',\n    'feMorphology',\n    'feOffset',\n    'feSpecularLighting',\n    'feTile',\n    'feTurbulence',\n    'linearGradient',\n    'radialGradient',\n    'stop',\n    'circle',\n    'ellipse',\n    'image',\n    'line',\n    'path',\n    'polygon',\n    'polyline',\n    'rect',\n    'text',\n    'use',\n    'textPath',\n    'tspan',\n    'foreignObject',\n    'clipPath'\n  ];\n\n  const TAGS = [\n    ...HTML_TAGS,\n    ...SVG_TAGS,\n  ];\n\n  // Sorting, then reversing makes sure longer attributes/elements like\n  // `font-weight` are matched fully instead of getting false positives on say `font`\n\n  const MEDIA_FEATURES = [\n    'any-hover',\n    'any-pointer',\n    'aspect-ratio',\n    'color',\n    'color-gamut',\n    'color-index',\n    'device-aspect-ratio',\n    'device-height',\n    'device-width',\n    'display-mode',\n    'forced-colors',\n    'grid',\n    'height',\n    'hover',\n    'inverted-colors',\n    'monochrome',\n    'orientation',\n    'overflow-block',\n    'overflow-inline',\n    'pointer',\n    'prefers-color-scheme',\n    'prefers-contrast',\n    'prefers-reduced-motion',\n    'prefers-reduced-transparency',\n    'resolution',\n    'scan',\n    'scripting',\n    'update',\n    'width',\n    // TODO: find a better solution?\n    'min-width',\n    'max-width',\n    'min-height',\n    'max-height'\n  ].sort().reverse();\n\n  // https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes\n  const PSEUDO_CLASSES = [\n    'active',\n    'any-link',\n    'blank',\n    'checked',\n    'current',\n    'default',\n    'defined',\n    'dir', // dir()\n    'disabled',\n    'drop',\n    'empty',\n    'enabled',\n    'first',\n    'first-child',\n    'first-of-type',\n    'fullscreen',\n    'future',\n    'focus',\n    'focus-visible',\n    'focus-within',\n    'has', // has()\n    'host', // host or host()\n    'host-context', // host-context()\n    'hover',\n    'indeterminate',\n    'in-range',\n    'invalid',\n    'is', // is()\n    'lang', // lang()\n    'last-child',\n    'last-of-type',\n    'left',\n    'link',\n    'local-link',\n    'not', // not()\n    'nth-child', // nth-child()\n    'nth-col', // nth-col()\n    'nth-last-child', // nth-last-child()\n    'nth-last-col', // nth-last-col()\n    'nth-last-of-type', //nth-last-of-type()\n    'nth-of-type', //nth-of-type()\n    'only-child',\n    'only-of-type',\n    'optional',\n    'out-of-range',\n    'past',\n    'placeholder-shown',\n    'read-only',\n    'read-write',\n    'required',\n    'right',\n    'root',\n    'scope',\n    'target',\n    'target-within',\n    'user-invalid',\n    'valid',\n    'visited',\n    'where' // where()\n  ].sort().reverse();\n\n  // https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements\n  const PSEUDO_ELEMENTS = [\n    'after',\n    'backdrop',\n    'before',\n    'cue',\n    'cue-region',\n    'first-letter',\n    'first-line',\n    'grammar-error',\n    'marker',\n    'part',\n    'placeholder',\n    'selection',\n    'slotted',\n    'spelling-error'\n  ].sort().reverse();\n\n  const ATTRIBUTES = [\n    'accent-color',\n    'align-content',\n    'align-items',\n    'align-self',\n    'alignment-baseline',\n    'all',\n    'anchor-name',\n    'animation',\n    'animation-composition',\n    'animation-delay',\n    'animation-direction',\n    'animation-duration',\n    'animation-fill-mode',\n    'animation-iteration-count',\n    'animation-name',\n    'animation-play-state',\n    'animation-range',\n    'animation-range-end',\n    'animation-range-start',\n    'animation-timeline',\n    'animation-timing-function',\n    'appearance',\n    'aspect-ratio',\n    'backdrop-filter',\n    'backface-visibility',\n    'background',\n    'background-attachment',\n    'background-blend-mode',\n    'background-clip',\n    'background-color',\n    'background-image',\n    'background-origin',\n    'background-position',\n    'background-position-x',\n    'background-position-y',\n    'background-repeat',\n    'background-size',\n    'baseline-shift',\n    'block-size',\n    'border',\n    'border-block',\n    'border-block-color',\n    'border-block-end',\n    'border-block-end-color',\n    'border-block-end-style',\n    'border-block-end-width',\n    'border-block-start',\n    'border-block-start-color',\n    'border-block-start-style',\n    'border-block-start-width',\n    'border-block-style',\n    'border-block-width',\n    'border-bottom',\n    'border-bottom-color',\n    'border-bottom-left-radius',\n    'border-bottom-right-radius',\n    'border-bottom-style',\n    'border-bottom-width',\n    'border-collapse',\n    'border-color',\n    'border-end-end-radius',\n    'border-end-start-radius',\n    'border-image',\n    'border-image-outset',\n    'border-image-repeat',\n    'border-image-slice',\n    'border-image-source',\n    'border-image-width',\n    'border-inline',\n    'border-inline-color',\n    'border-inline-end',\n    'border-inline-end-color',\n    'border-inline-end-style',\n    'border-inline-end-width',\n    'border-inline-start',\n    'border-inline-start-color',\n    'border-inline-start-style',\n    'border-inline-start-width',\n    'border-inline-style',\n    'border-inline-width',\n    'border-left',\n    'border-left-color',\n    'border-left-style',\n    'border-left-width',\n    'border-radius',\n    'border-right',\n    'border-right-color',\n    'border-right-style',\n    'border-right-width',\n    'border-spacing',\n    'border-start-end-radius',\n    'border-start-start-radius',\n    'border-style',\n    'border-top',\n    'border-top-color',\n    'border-top-left-radius',\n    'border-top-right-radius',\n    'border-top-style',\n    'border-top-width',\n    'border-width',\n    'bottom',\n    'box-align',\n    'box-decoration-break',\n    'box-direction',\n    'box-flex',\n    'box-flex-group',\n    'box-lines',\n    'box-ordinal-group',\n    'box-orient',\n    'box-pack',\n    'box-shadow',\n    'box-sizing',\n    'break-after',\n    'break-before',\n    'break-inside',\n    'caption-side',\n    'caret-color',\n    'clear',\n    'clip',\n    'clip-path',\n    'clip-rule',\n    'color',\n    'color-interpolation',\n    'color-interpolation-filters',\n    'color-profile',\n    'color-rendering',\n    'color-scheme',\n    'column-count',\n    'column-fill',\n    'column-gap',\n    'column-rule',\n    'column-rule-color',\n    'column-rule-style',\n    'column-rule-width',\n    'column-span',\n    'column-width',\n    'columns',\n    'contain',\n    'contain-intrinsic-block-size',\n    'contain-intrinsic-height',\n    'contain-intrinsic-inline-size',\n    'contain-intrinsic-size',\n    'contain-intrinsic-width',\n    'container',\n    'container-name',\n    'container-type',\n    'content',\n    'content-visibility',\n    'counter-increment',\n    'counter-reset',\n    'counter-set',\n    'cue',\n    'cue-after',\n    'cue-before',\n    'cursor',\n    'cx',\n    'cy',\n    'direction',\n    'display',\n    'dominant-baseline',\n    'empty-cells',\n    'enable-background',\n    'field-sizing',\n    'fill',\n    'fill-opacity',\n    'fill-rule',\n    'filter',\n    'flex',\n    'flex-basis',\n    'flex-direction',\n    'flex-flow',\n    'flex-grow',\n    'flex-shrink',\n    'flex-wrap',\n    'float',\n    'flood-color',\n    'flood-opacity',\n    'flow',\n    'font',\n    'font-display',\n    'font-family',\n    'font-feature-settings',\n    'font-kerning',\n    'font-language-override',\n    'font-optical-sizing',\n    'font-palette',\n    'font-size',\n    'font-size-adjust',\n    'font-smooth',\n    'font-smoothing',\n    'font-stretch',\n    'font-style',\n    'font-synthesis',\n    'font-synthesis-position',\n    'font-synthesis-small-caps',\n    'font-synthesis-style',\n    'font-synthesis-weight',\n    'font-variant',\n    'font-variant-alternates',\n    'font-variant-caps',\n    'font-variant-east-asian',\n    'font-variant-emoji',\n    'font-variant-ligatures',\n    'font-variant-numeric',\n    'font-variant-position',\n    'font-variation-settings',\n    'font-weight',\n    'forced-color-adjust',\n    'gap',\n    'glyph-orientation-horizontal',\n    'glyph-orientation-vertical',\n    'grid',\n    'grid-area',\n    'grid-auto-columns',\n    'grid-auto-flow',\n    'grid-auto-rows',\n    'grid-column',\n    'grid-column-end',\n    'grid-column-start',\n    'grid-gap',\n    'grid-row',\n    'grid-row-end',\n    'grid-row-start',\n    'grid-template',\n    'grid-template-areas',\n    'grid-template-columns',\n    'grid-template-rows',\n    'hanging-punctuation',\n    'height',\n    'hyphenate-character',\n    'hyphenate-limit-chars',\n    'hyphens',\n    'icon',\n    'image-orientation',\n    'image-rendering',\n    'image-resolution',\n    'ime-mode',\n    'initial-letter',\n    'initial-letter-align',\n    'inline-size',\n    'inset',\n    'inset-area',\n    'inset-block',\n    'inset-block-end',\n    'inset-block-start',\n    'inset-inline',\n    'inset-inline-end',\n    'inset-inline-start',\n    'isolation',\n    'justify-content',\n    'justify-items',\n    'justify-self',\n    'kerning',\n    'left',\n    'letter-spacing',\n    'lighting-color',\n    'line-break',\n    'line-height',\n    'line-height-step',\n    'list-style',\n    'list-style-image',\n    'list-style-position',\n    'list-style-type',\n    'margin',\n    'margin-block',\n    'margin-block-end',\n    'margin-block-start',\n    'margin-bottom',\n    'margin-inline',\n    'margin-inline-end',\n    'margin-inline-start',\n    'margin-left',\n    'margin-right',\n    'margin-top',\n    'margin-trim',\n    'marker',\n    'marker-end',\n    'marker-mid',\n    'marker-start',\n    'marks',\n    'mask',\n    'mask-border',\n    'mask-border-mode',\n    'mask-border-outset',\n    'mask-border-repeat',\n    'mask-border-slice',\n    'mask-border-source',\n    'mask-border-width',\n    'mask-clip',\n    'mask-composite',\n    'mask-image',\n    'mask-mode',\n    'mask-origin',\n    'mask-position',\n    'mask-repeat',\n    'mask-size',\n    'mask-type',\n    'masonry-auto-flow',\n    'math-depth',\n    'math-shift',\n    'math-style',\n    'max-block-size',\n    'max-height',\n    'max-inline-size',\n    'max-width',\n    'min-block-size',\n    'min-height',\n    'min-inline-size',\n    'min-width',\n    'mix-blend-mode',\n    'nav-down',\n    'nav-index',\n    'nav-left',\n    'nav-right',\n    'nav-up',\n    'none',\n    'normal',\n    'object-fit',\n    'object-position',\n    'offset',\n    'offset-anchor',\n    'offset-distance',\n    'offset-path',\n    'offset-position',\n    'offset-rotate',\n    'opacity',\n    'order',\n    'orphans',\n    'outline',\n    'outline-color',\n    'outline-offset',\n    'outline-style',\n    'outline-width',\n    'overflow',\n    'overflow-anchor',\n    'overflow-block',\n    'overflow-clip-margin',\n    'overflow-inline',\n    'overflow-wrap',\n    'overflow-x',\n    'overflow-y',\n    'overlay',\n    'overscroll-behavior',\n    'overscroll-behavior-block',\n    'overscroll-behavior-inline',\n    'overscroll-behavior-x',\n    'overscroll-behavior-y',\n    'padding',\n    'padding-block',\n    'padding-block-end',\n    'padding-block-start',\n    'padding-bottom',\n    'padding-inline',\n    'padding-inline-end',\n    'padding-inline-start',\n    'padding-left',\n    'padding-right',\n    'padding-top',\n    'page',\n    'page-break-after',\n    'page-break-before',\n    'page-break-inside',\n    'paint-order',\n    'pause',\n    'pause-after',\n    'pause-before',\n    'perspective',\n    'perspective-origin',\n    'place-content',\n    'place-items',\n    'place-self',\n    'pointer-events',\n    'position',\n    'position-anchor',\n    'position-visibility',\n    'print-color-adjust',\n    'quotes',\n    'r',\n    'resize',\n    'rest',\n    'rest-after',\n    'rest-before',\n    'right',\n    'rotate',\n    'row-gap',\n    'ruby-align',\n    'ruby-position',\n    'scale',\n    'scroll-behavior',\n    'scroll-margin',\n    'scroll-margin-block',\n    'scroll-margin-block-end',\n    'scroll-margin-block-start',\n    'scroll-margin-bottom',\n    'scroll-margin-inline',\n    'scroll-margin-inline-end',\n    'scroll-margin-inline-start',\n    'scroll-margin-left',\n    'scroll-margin-right',\n    'scroll-margin-top',\n    'scroll-padding',\n    'scroll-padding-block',\n    'scroll-padding-block-end',\n    'scroll-padding-block-start',\n    'scroll-padding-bottom',\n    'scroll-padding-inline',\n    'scroll-padding-inline-end',\n    'scroll-padding-inline-start',\n    'scroll-padding-left',\n    'scroll-padding-right',\n    'scroll-padding-top',\n    'scroll-snap-align',\n    'scroll-snap-stop',\n    'scroll-snap-type',\n    'scroll-timeline',\n    'scroll-timeline-axis',\n    'scroll-timeline-name',\n    'scrollbar-color',\n    'scrollbar-gutter',\n    'scrollbar-width',\n    'shape-image-threshold',\n    'shape-margin',\n    'shape-outside',\n    'shape-rendering',\n    'speak',\n    'speak-as',\n    'src', // @font-face\n    'stop-color',\n    'stop-opacity',\n    'stroke',\n    'stroke-dasharray',\n    'stroke-dashoffset',\n    'stroke-linecap',\n    'stroke-linejoin',\n    'stroke-miterlimit',\n    'stroke-opacity',\n    'stroke-width',\n    'tab-size',\n    'table-layout',\n    'text-align',\n    'text-align-all',\n    'text-align-last',\n    'text-anchor',\n    'text-combine-upright',\n    'text-decoration',\n    'text-decoration-color',\n    'text-decoration-line',\n    'text-decoration-skip',\n    'text-decoration-skip-ink',\n    'text-decoration-style',\n    'text-decoration-thickness',\n    'text-emphasis',\n    'text-emphasis-color',\n    'text-emphasis-position',\n    'text-emphasis-style',\n    'text-indent',\n    'text-justify',\n    'text-orientation',\n    'text-overflow',\n    'text-rendering',\n    'text-shadow',\n    'text-size-adjust',\n    'text-transform',\n    'text-underline-offset',\n    'text-underline-position',\n    'text-wrap',\n    'text-wrap-mode',\n    'text-wrap-style',\n    'timeline-scope',\n    'top',\n    'touch-action',\n    'transform',\n    'transform-box',\n    'transform-origin',\n    'transform-style',\n    'transition',\n    'transition-behavior',\n    'transition-delay',\n    'transition-duration',\n    'transition-property',\n    'transition-timing-function',\n    'translate',\n    'unicode-bidi',\n    'unicode-range',\n    'user-modify',\n    'user-select',\n    'vector-effect',\n    'vertical-align',\n    'view-timeline',\n    'view-timeline-axis',\n    'view-timeline-inset',\n    'view-timeline-name',\n    'view-transition-name',\n    'visibility',\n    'voice-balance',\n    'voice-duration',\n    'voice-family',\n    'voice-pitch',\n    'voice-range',\n    'voice-rate',\n    'voice-stress',\n    'voice-volume',\n    'white-space',\n    'white-space-collapse',\n    'widows',\n    'width',\n    'will-change',\n    'word-break',\n    'word-spacing',\n    'word-wrap',\n    'writing-mode',\n    'x',\n    'y',\n    'z-index',\n    'zoom'\n  ].sort().reverse();\n\n  // some grammars use them all as a single group\n  const PSEUDO_SELECTORS = PSEUDO_CLASSES.concat(PSEUDO_ELEMENTS).sort().reverse();\n\n  /*\n  Language: CSS\n  Category: common, css, web\n  Website: https://developer.mozilla.org/en-US/docs/Web/CSS\n  */\n\n\n  /** @type LanguageFn */\n  function css(hljs) {\n    const regex = hljs.regex;\n    const modes = MODES(hljs);\n    const VENDOR_PREFIX = { begin: /-(webkit|moz|ms|o)-(?=[a-z])/ };\n    const AT_MODIFIERS = \"and or not only\";\n    const AT_PROPERTY_RE = /@-?\\w[\\w]*(-\\w+)*/; // @-webkit-keyframes\n    const IDENT_RE = '[a-zA-Z-][a-zA-Z0-9_-]*';\n    const STRINGS = [\n      hljs.APOS_STRING_MODE,\n      hljs.QUOTE_STRING_MODE\n    ];\n\n    return {\n      name: 'CSS',\n      case_insensitive: true,\n      illegal: /[=|'\\$]/,\n      keywords: { keyframePosition: \"from to\" },\n      classNameAliases: {\n        // for visual continuity with `tag {}` and because we\n        // don't have a great class for this?\n        keyframePosition: \"selector-tag\" },\n      contains: [\n        modes.BLOCK_COMMENT,\n        VENDOR_PREFIX,\n        // to recognize keyframe 40% etc which are outside the scope of our\n        // attribute value mode\n        modes.CSS_NUMBER_MODE,\n        {\n          className: 'selector-id',\n          begin: /#[A-Za-z0-9_-]+/,\n          relevance: 0\n        },\n        {\n          className: 'selector-class',\n          begin: '\\\\.' + IDENT_RE,\n          relevance: 0\n        },\n        modes.ATTRIBUTE_SELECTOR_MODE,\n        {\n          className: 'selector-pseudo',\n          variants: [\n            { begin: ':(' + PSEUDO_CLASSES.join('|') + ')' },\n            { begin: ':(:)?(' + PSEUDO_ELEMENTS.join('|') + ')' }\n          ]\n        },\n        // we may actually need this (12/2020)\n        // { // pseudo-selector params\n        //   begin: /\\(/,\n        //   end: /\\)/,\n        //   contains: [ hljs.CSS_NUMBER_MODE ]\n        // },\n        modes.CSS_VARIABLE,\n        {\n          className: 'attribute',\n          begin: '\\\\b(' + ATTRIBUTES.join('|') + ')\\\\b'\n        },\n        // attribute values\n        {\n          begin: /:/,\n          end: /[;}{]/,\n          contains: [\n            modes.BLOCK_COMMENT,\n            modes.HEXCOLOR,\n            modes.IMPORTANT,\n            modes.CSS_NUMBER_MODE,\n            modes.UNICODE_RANGE,\n            ...STRINGS,\n            // needed to highlight these as strings and to avoid issues with\n            // illegal characters that might be inside urls that would trigger the\n            // languages illegal stack\n            {\n              begin: /(url|data-uri)\\(/,\n              end: /\\)/,\n              relevance: 0, // from keywords\n              keywords: { built_in: \"url data-uri\" },\n              contains: [\n                ...STRINGS,\n                {\n                  className: \"string\",\n                  // any character other than `)` as in `url()` will be the start\n                  // of a string, which ends with `)` (from the parent mode)\n                  begin: /[^)]/,\n                  endsWithParent: true,\n                  excludeEnd: true\n                }\n              ]\n            },\n            modes.FUNCTION_DISPATCH\n          ]\n        },\n        {\n          begin: regex.lookahead(/@/),\n          end: '[{;]',\n          relevance: 0,\n          illegal: /:/, // break on Less variables @var: ...\n          contains: [\n            {\n              className: 'keyword',\n              begin: AT_PROPERTY_RE\n            },\n            {\n              begin: /\\s/,\n              endsWithParent: true,\n              excludeEnd: true,\n              relevance: 0,\n              keywords: {\n                $pattern: /[a-z-]+/,\n                keyword: AT_MODIFIERS,\n                attribute: MEDIA_FEATURES.join(\" \")\n              },\n              contains: [\n                {\n                  begin: /[a-z-]+(?=:)/,\n                  className: \"attribute\"\n                },\n                ...STRINGS,\n                modes.CSS_NUMBER_MODE\n              ]\n            }\n          ]\n        },\n        {\n          className: 'selector-tag',\n          begin: '\\\\b(' + TAGS.join('|') + ')\\\\b'\n        }\n      ]\n    };\n  }\n\n  /*\n  Language: Diff\n  Description: Unified and context diff\n  Author: Vasily Polovnyov <vast@whiteants.net>\n  Website: https://www.gnu.org/software/diffutils/\n  Category: common\n  */\n\n  /** @type LanguageFn */\n  function diff(hljs) {\n    const regex = hljs.regex;\n    return {\n      name: 'Diff',\n      aliases: [ 'patch' ],\n      contains: [\n        {\n          className: 'meta',\n          relevance: 10,\n          match: regex.either(\n            /^@@ +-\\d+,\\d+ +\\+\\d+,\\d+ +@@/, // @@ -1,2 +1,2 @@\n            /^@@ +-\\d+ +\\+\\d+,\\d+ +@@/,     // @@ -1 +1,2 @@\n            /^@@ +-\\d+,\\d+ +\\+\\d+ +@@/,     // @@ -1,2 +1 @@\n            /^@@ +-\\d+ +\\+\\d+ +@@/,         // @@ -1 +1 @@\n            /^\\*\\*\\* +\\d+,\\d+ +\\*\\*\\*\\*$/,\n            /^--- +\\d+,\\d+ +----$/\n          )\n        },\n        {\n          className: 'comment',\n          variants: [\n            {\n              begin: regex.either(\n                /Index: /,\n                /^index/,\n                /={3,}/,\n                /^-{3}/,\n                /^\\*{3} /,\n                /^\\+{3}/,\n                /^diff --git/\n              ),\n              end: /$/\n            },\n            { match: /^\\*{15}$/ }\n          ]\n        },\n        {\n          className: 'addition',\n          begin: /^\\+/,\n          end: /$/\n        },\n        {\n          className: 'deletion',\n          begin: /^-/,\n          end: /$/\n        },\n        {\n          className: 'addition',\n          begin: /^!/,\n          end: /$/\n        }\n      ]\n    };\n  }\n\n  /*\n  Language: Go\n  Author: Stephan Kountso aka StepLg <steplg@gmail.com>\n  Contributors: Evgeny Stepanischev <imbolk@gmail.com>\n  Description: Google go language (golang). For info about language\n  Website: http://golang.org/\n  Category: common, system\n  */\n\n  function go(hljs) {\n    const LITERALS = [\n      \"true\",\n      \"false\",\n      \"iota\",\n      \"nil\"\n    ];\n    const BUILT_INS = [\n      \"append\",\n      \"cap\",\n      \"close\",\n      \"complex\",\n      \"copy\",\n      \"imag\",\n      \"len\",\n      \"make\",\n      \"new\",\n      \"panic\",\n      \"print\",\n      \"println\",\n      \"real\",\n      \"recover\",\n      \"delete\"\n    ];\n    const TYPES = [\n      \"bool\",\n      \"byte\",\n      \"complex64\",\n      \"complex128\",\n      \"error\",\n      \"float32\",\n      \"float64\",\n      \"int8\",\n      \"int16\",\n      \"int32\",\n      \"int64\",\n      \"string\",\n      \"uint8\",\n      \"uint16\",\n      \"uint32\",\n      \"uint64\",\n      \"int\",\n      \"uint\",\n      \"uintptr\",\n      \"rune\"\n    ];\n    const KWS = [\n      \"break\",\n      \"case\",\n      \"chan\",\n      \"const\",\n      \"continue\",\n      \"default\",\n      \"defer\",\n      \"else\",\n      \"fallthrough\",\n      \"for\",\n      \"func\",\n      \"go\",\n      \"goto\",\n      \"if\",\n      \"import\",\n      \"interface\",\n      \"map\",\n      \"package\",\n      \"range\",\n      \"return\",\n      \"select\",\n      \"struct\",\n      \"switch\",\n      \"type\",\n      \"var\",\n    ];\n    const KEYWORDS = {\n      keyword: KWS,\n      type: TYPES,\n      literal: LITERALS,\n      built_in: BUILT_INS\n    };\n    return {\n      name: 'Go',\n      aliases: [ 'golang' ],\n      keywords: KEYWORDS,\n      illegal: '</',\n      contains: [\n        hljs.C_LINE_COMMENT_MODE,\n        hljs.C_BLOCK_COMMENT_MODE,\n        {\n          className: 'string',\n          variants: [\n            hljs.QUOTE_STRING_MODE,\n            hljs.APOS_STRING_MODE,\n            {\n              begin: '`',\n              end: '`'\n            }\n          ]\n        },\n        {\n          className: 'number',\n          variants: [\n            {\n              match: /-?\\b0[xX]\\.[a-fA-F0-9](_?[a-fA-F0-9])*[pP][+-]?\\d(_?\\d)*i?/, // hex without a present digit before . (making a digit afterwards required)\n              relevance: 0\n            },\n            {\n              match: /-?\\b0[xX](_?[a-fA-F0-9])+((\\.([a-fA-F0-9](_?[a-fA-F0-9])*)?)?[pP][+-]?\\d(_?\\d)*)?i?/, // hex with a present digit before . (making a digit afterwards optional)\n              relevance: 0\n            },\n            {\n              match: /-?\\b0[oO](_?[0-7])*i?/, // leading 0o octal\n              relevance: 0\n            },\n            {\n              match: /-?\\.\\d(_?\\d)*([eE][+-]?\\d(_?\\d)*)?i?/, // decimal without a present digit before . (making a digit afterwards required)\n              relevance: 0\n            },\n            {\n              match: /-?\\b\\d(_?\\d)*(\\.(\\d(_?\\d)*)?)?([eE][+-]?\\d(_?\\d)*)?i?/, // decimal with a present digit before . (making a digit afterwards optional)\n              relevance: 0\n            }\n          ]\n        },\n        { begin: /:=/ // relevance booster\n        },\n        {\n          className: 'function',\n          beginKeywords: 'func',\n          end: '\\\\s*(\\\\{|$)',\n          excludeEnd: true,\n          contains: [\n            hljs.TITLE_MODE,\n            {\n              className: 'params',\n              begin: /\\(/,\n              end: /\\)/,\n              endsParent: true,\n              keywords: KEYWORDS,\n              illegal: /[\"']/\n            }\n          ]\n        }\n      ]\n    };\n  }\n\n  /*\n   Language: GraphQL\n   Author: John Foster (GH jf990), and others\n   Description: GraphQL is a query language for APIs\n   Category: web, common\n  */\n\n  /** @type LanguageFn */\n  function graphql(hljs) {\n    const regex = hljs.regex;\n    const GQL_NAME = /[_A-Za-z][_0-9A-Za-z]*/;\n    return {\n      name: \"GraphQL\",\n      aliases: [ \"gql\" ],\n      case_insensitive: true,\n      disableAutodetect: false,\n      keywords: {\n        keyword: [\n          \"query\",\n          \"mutation\",\n          \"subscription\",\n          \"type\",\n          \"input\",\n          \"schema\",\n          \"directive\",\n          \"interface\",\n          \"union\",\n          \"scalar\",\n          \"fragment\",\n          \"enum\",\n          \"on\"\n        ],\n        literal: [\n          \"true\",\n          \"false\",\n          \"null\"\n        ]\n      },\n      contains: [\n        hljs.HASH_COMMENT_MODE,\n        hljs.QUOTE_STRING_MODE,\n        hljs.NUMBER_MODE,\n        {\n          scope: \"punctuation\",\n          match: /[.]{3}/,\n          relevance: 0\n        },\n        {\n          scope: \"punctuation\",\n          begin: /[\\!\\(\\)\\:\\=\\[\\]\\{\\|\\}]{1}/,\n          relevance: 0\n        },\n        {\n          scope: \"variable\",\n          begin: /\\$/,\n          end: /\\W/,\n          excludeEnd: true,\n          relevance: 0\n        },\n        {\n          scope: \"meta\",\n          match: /@\\w+/,\n          excludeEnd: true\n        },\n        {\n          scope: \"symbol\",\n          begin: regex.concat(GQL_NAME, regex.lookahead(/\\s*:/)),\n          relevance: 0\n        }\n      ],\n      illegal: [\n        /[;<']/,\n        /BEGIN/\n      ]\n    };\n  }\n\n  /*\n  Language: TOML, also INI\n  Description: TOML aims to be a minimal configuration file format that's easy to read due to obvious semantics.\n  Contributors: Guillaume Gomez <guillaume1.gomez@gmail.com>\n  Category: common, config\n  Website: https://github.com/toml-lang/toml\n  */\n\n  function ini(hljs) {\n    const regex = hljs.regex;\n    const NUMBERS = {\n      className: 'number',\n      relevance: 0,\n      variants: [\n        { begin: /([+-]+)?[\\d]+_[\\d_]+/ },\n        { begin: hljs.NUMBER_RE }\n      ]\n    };\n    const COMMENTS = hljs.COMMENT();\n    COMMENTS.variants = [\n      {\n        begin: /;/,\n        end: /$/\n      },\n      {\n        begin: /#/,\n        end: /$/\n      }\n    ];\n    const VARIABLES = {\n      className: 'variable',\n      variants: [\n        { begin: /\\$[\\w\\d\"][\\w\\d_]*/ },\n        { begin: /\\$\\{(.*?)\\}/ }\n      ]\n    };\n    const LITERALS = {\n      className: 'literal',\n      begin: /\\bon|off|true|false|yes|no\\b/\n    };\n    const STRINGS = {\n      className: \"string\",\n      contains: [ hljs.BACKSLASH_ESCAPE ],\n      variants: [\n        {\n          begin: \"'''\",\n          end: \"'''\",\n          relevance: 10\n        },\n        {\n          begin: '\"\"\"',\n          end: '\"\"\"',\n          relevance: 10\n        },\n        {\n          begin: '\"',\n          end: '\"'\n        },\n        {\n          begin: \"'\",\n          end: \"'\"\n        }\n      ]\n    };\n    const ARRAY = {\n      begin: /\\[/,\n      end: /\\]/,\n      contains: [\n        COMMENTS,\n        LITERALS,\n        VARIABLES,\n        STRINGS,\n        NUMBERS,\n        'self'\n      ],\n      relevance: 0\n    };\n\n    const BARE_KEY = /[A-Za-z0-9_-]+/;\n    const QUOTED_KEY_DOUBLE_QUOTE = /\"(\\\\\"|[^\"])*\"/;\n    const QUOTED_KEY_SINGLE_QUOTE = /'[^']*'/;\n    const ANY_KEY = regex.either(\n      BARE_KEY, QUOTED_KEY_DOUBLE_QUOTE, QUOTED_KEY_SINGLE_QUOTE\n    );\n    const DOTTED_KEY = regex.concat(\n      ANY_KEY, '(\\\\s*\\\\.\\\\s*', ANY_KEY, ')*',\n      regex.lookahead(/\\s*=\\s*[^#\\s]/)\n    );\n\n    return {\n      name: 'TOML, also INI',\n      aliases: [ 'toml' ],\n      case_insensitive: true,\n      illegal: /\\S/,\n      contains: [\n        COMMENTS,\n        {\n          className: 'section',\n          begin: /\\[+/,\n          end: /\\]+/\n        },\n        {\n          begin: DOTTED_KEY,\n          className: 'attr',\n          starts: {\n            end: /$/,\n            contains: [\n              COMMENTS,\n              ARRAY,\n              LITERALS,\n              VARIABLES,\n              STRINGS,\n              NUMBERS\n            ]\n          }\n        }\n      ]\n    };\n  }\n\n  // https://docs.oracle.com/javase/specs/jls/se15/html/jls-3.html#jls-3.10\n  var decimalDigits = '[0-9](_*[0-9])*';\n  var frac = `\\\\.(${decimalDigits})`;\n  var hexDigits = '[0-9a-fA-F](_*[0-9a-fA-F])*';\n  var NUMERIC = {\n    className: 'number',\n    variants: [\n      // DecimalFloatingPointLiteral\n      // including ExponentPart\n      { begin: `(\\\\b(${decimalDigits})((${frac})|\\\\.)?|(${frac}))` +\n        `[eE][+-]?(${decimalDigits})[fFdD]?\\\\b` },\n      // excluding ExponentPart\n      { begin: `\\\\b(${decimalDigits})((${frac})[fFdD]?\\\\b|\\\\.([fFdD]\\\\b)?)` },\n      { begin: `(${frac})[fFdD]?\\\\b` },\n      { begin: `\\\\b(${decimalDigits})[fFdD]\\\\b` },\n\n      // HexadecimalFloatingPointLiteral\n      { begin: `\\\\b0[xX]((${hexDigits})\\\\.?|(${hexDigits})?\\\\.(${hexDigits}))` +\n        `[pP][+-]?(${decimalDigits})[fFdD]?\\\\b` },\n\n      // DecimalIntegerLiteral\n      { begin: '\\\\b(0|[1-9](_*[0-9])*)[lL]?\\\\b' },\n\n      // HexIntegerLiteral\n      { begin: `\\\\b0[xX](${hexDigits})[lL]?\\\\b` },\n\n      // OctalIntegerLiteral\n      { begin: '\\\\b0(_*[0-7])*[lL]?\\\\b' },\n\n      // BinaryIntegerLiteral\n      { begin: '\\\\b0[bB][01](_*[01])*[lL]?\\\\b' },\n    ],\n    relevance: 0\n  };\n\n  /*\n  Language: Java\n  Author: Vsevolod Solovyov <vsevolod.solovyov@gmail.com>\n  Category: common, enterprise\n  Website: https://www.java.com/\n  */\n\n\n  /**\n   * Allows recursive regex expressions to a given depth\n   *\n   * ie: recurRegex(\"(abc~~~)\", /~~~/g, 2) becomes:\n   * (abc(abc(abc)))\n   *\n   * @param {string} re\n   * @param {RegExp} substitution (should be a g mode regex)\n   * @param {number} depth\n   * @returns {string}``\n   */\n  function recurRegex(re, substitution, depth) {\n    if (depth === -1) return \"\";\n\n    return re.replace(substitution, _ => {\n      return recurRegex(re, substitution, depth - 1);\n    });\n  }\n\n  /** @type LanguageFn */\n  function java(hljs) {\n    const regex = hljs.regex;\n    const JAVA_IDENT_RE = '[\\u00C0-\\u02B8a-zA-Z_$][\\u00C0-\\u02B8a-zA-Z_$0-9]*';\n    const GENERIC_IDENT_RE = JAVA_IDENT_RE\n      + recurRegex('(?:<' + JAVA_IDENT_RE + '~~~(?:\\\\s*,\\\\s*' + JAVA_IDENT_RE + '~~~)*>)?', /~~~/g, 2);\n    const MAIN_KEYWORDS = [\n      'synchronized',\n      'abstract',\n      'private',\n      'var',\n      'static',\n      'if',\n      'const ',\n      'for',\n      'while',\n      'strictfp',\n      'finally',\n      'protected',\n      'import',\n      'native',\n      'final',\n      'void',\n      'enum',\n      'else',\n      'break',\n      'transient',\n      'catch',\n      'instanceof',\n      'volatile',\n      'case',\n      'assert',\n      'package',\n      'default',\n      'public',\n      'try',\n      'switch',\n      'continue',\n      'throws',\n      'protected',\n      'public',\n      'private',\n      'module',\n      'requires',\n      'exports',\n      'do',\n      'sealed',\n      'yield',\n      'permits',\n      'goto',\n      'when'\n    ];\n\n    const BUILT_INS = [\n      'super',\n      'this'\n    ];\n\n    const LITERALS = [\n      'false',\n      'true',\n      'null'\n    ];\n\n    const TYPES = [\n      'char',\n      'boolean',\n      'long',\n      'float',\n      'int',\n      'byte',\n      'short',\n      'double'\n    ];\n\n    const KEYWORDS = {\n      keyword: MAIN_KEYWORDS,\n      literal: LITERALS,\n      type: TYPES,\n      built_in: BUILT_INS\n    };\n\n    const ANNOTATION = {\n      className: 'meta',\n      begin: '@' + JAVA_IDENT_RE,\n      contains: [\n        {\n          begin: /\\(/,\n          end: /\\)/,\n          contains: [ \"self\" ] // allow nested () inside our annotation\n        }\n      ]\n    };\n    const PARAMS = {\n      className: 'params',\n      begin: /\\(/,\n      end: /\\)/,\n      keywords: KEYWORDS,\n      relevance: 0,\n      contains: [ hljs.C_BLOCK_COMMENT_MODE ],\n      endsParent: true\n    };\n\n    return {\n      name: 'Java',\n      aliases: [ 'jsp' ],\n      keywords: KEYWORDS,\n      illegal: /<\\/|#/,\n      contains: [\n        hljs.COMMENT(\n          '/\\\\*\\\\*',\n          '\\\\*/',\n          {\n            relevance: 0,\n            contains: [\n              {\n                // eat up @'s in emails to prevent them to be recognized as doctags\n                begin: /\\w+@/,\n                relevance: 0\n              },\n              {\n                className: 'doctag',\n                begin: '@[A-Za-z]+'\n              }\n            ]\n          }\n        ),\n        // relevance boost\n        {\n          begin: /import java\\.[a-z]+\\./,\n          keywords: \"import\",\n          relevance: 2\n        },\n        hljs.C_LINE_COMMENT_MODE,\n        hljs.C_BLOCK_COMMENT_MODE,\n        {\n          begin: /\"\"\"/,\n          end: /\"\"\"/,\n          className: \"string\",\n          contains: [ hljs.BACKSLASH_ESCAPE ]\n        },\n        hljs.APOS_STRING_MODE,\n        hljs.QUOTE_STRING_MODE,\n        {\n          match: [\n            /\\b(?:class|interface|enum|extends|implements|new)/,\n            /\\s+/,\n            JAVA_IDENT_RE\n          ],\n          className: {\n            1: \"keyword\",\n            3: \"title.class\"\n          }\n        },\n        {\n          // Exceptions for hyphenated keywords\n          match: /non-sealed/,\n          scope: \"keyword\"\n        },\n        {\n          begin: [\n            regex.concat(/(?!else)/, JAVA_IDENT_RE),\n            /\\s+/,\n            JAVA_IDENT_RE,\n            /\\s+/,\n            /=(?!=)/\n          ],\n          className: {\n            1: \"type\",\n            3: \"variable\",\n            5: \"operator\"\n          }\n        },\n        {\n          begin: [\n            /record/,\n            /\\s+/,\n            JAVA_IDENT_RE\n          ],\n          className: {\n            1: \"keyword\",\n            3: \"title.class\"\n          },\n          contains: [\n            PARAMS,\n            hljs.C_LINE_COMMENT_MODE,\n            hljs.C_BLOCK_COMMENT_MODE\n          ]\n        },\n        {\n          // Expression keywords prevent 'keyword Name(...)' from being\n          // recognized as a function definition\n          beginKeywords: 'new throw return else',\n          relevance: 0\n        },\n        {\n          begin: [\n            '(?:' + GENERIC_IDENT_RE + '\\\\s+)',\n            hljs.UNDERSCORE_IDENT_RE,\n            /\\s*(?=\\()/\n          ],\n          className: { 2: \"title.function\" },\n          keywords: KEYWORDS,\n          contains: [\n            {\n              className: 'params',\n              begin: /\\(/,\n              end: /\\)/,\n              keywords: KEYWORDS,\n              relevance: 0,\n              contains: [\n                ANNOTATION,\n                hljs.APOS_STRING_MODE,\n                hljs.QUOTE_STRING_MODE,\n                NUMERIC,\n                hljs.C_BLOCK_COMMENT_MODE\n              ]\n            },\n            hljs.C_LINE_COMMENT_MODE,\n            hljs.C_BLOCK_COMMENT_MODE\n          ]\n        },\n        NUMERIC,\n        ANNOTATION\n      ]\n    };\n  }\n\n  const IDENT_RE = '[A-Za-z$_][0-9A-Za-z$_]*';\n  const EXTENDED_NUMBER_RE = '([-+]?)(\\\\b0[xX][a-fA-F0-9]+|(\\\\b\\\\d+(\\\\.\\\\d*)?|\\\\.\\\\d+)([eE][-+]?\\\\d+)?)|NaN|[-+]?Infinity'; // 0x..., 0..., decimal, float\n\n  const EXTENDED_NUMBER_MODE = {\n    scope: 'number',\n    match: EXTENDED_NUMBER_RE,\n    relevance: 0\n  };\n\n  const KEYWORDS = [\n    \"as\", // for exports\n    \"in\",\n    \"of\",\n    \"if\",\n    \"for\",\n    \"while\",\n    \"finally\",\n    \"var\",\n    \"new\",\n    \"function\",\n    \"do\",\n    \"return\",\n    \"void\",\n    \"else\",\n    \"break\",\n    \"catch\",\n    \"instanceof\",\n    \"with\",\n    \"throw\",\n    \"case\",\n    \"default\",\n    \"try\",\n    \"switch\",\n    \"continue\",\n    \"typeof\",\n    \"delete\",\n    \"let\",\n    \"yield\",\n    \"const\",\n    \"class\",\n    // JS handles these with a special rule\n    // \"get\",\n    // \"set\",\n    \"debugger\",\n    \"async\",\n    \"await\",\n    \"static\",\n    \"import\",\n    \"from\",\n    \"export\",\n    \"extends\",\n    // It's reached stage 3, which is \"recommended for implementation\":\n    \"using\"\n  ];\n  const LITERALS = [\n    \"true\",\n    \"false\",\n    \"null\",\n    \"undefined\",\n    \"NaN\",\n    \"Infinity\"\n  ];\n\n  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects\n  const TYPES = [\n    // Fundamental objects\n    \"Object\",\n    \"Function\",\n    \"Boolean\",\n    \"Symbol\",\n    // numbers and dates\n    \"Math\",\n    \"Date\",\n    \"Number\",\n    \"BigInt\",\n    // text\n    \"String\",\n    \"RegExp\",\n    // Indexed collections\n    \"Array\",\n    \"Float32Array\",\n    \"Float64Array\",\n    \"Int8Array\",\n    \"Uint8Array\",\n    \"Uint8ClampedArray\",\n    \"Int16Array\",\n    \"Int32Array\",\n    \"Uint16Array\",\n    \"Uint32Array\",\n    \"BigInt64Array\",\n    \"BigUint64Array\",\n    // Keyed collections\n    \"Set\",\n    \"Map\",\n    \"WeakSet\",\n    \"WeakMap\",\n    // Structured data\n    \"ArrayBuffer\",\n    \"SharedArrayBuffer\",\n    \"Atomics\",\n    \"DataView\",\n    \"JSON\",\n    // Control abstraction objects\n    \"Promise\",\n    \"Generator\",\n    \"GeneratorFunction\",\n    \"AsyncFunction\",\n    // Reflection\n    \"Reflect\",\n    \"Proxy\",\n    // Internationalization\n    \"Intl\",\n    // WebAssembly\n    \"WebAssembly\"\n  ];\n\n  const ERROR_TYPES = [\n    \"Error\",\n    \"EvalError\",\n    \"InternalError\",\n    \"RangeError\",\n    \"ReferenceError\",\n    \"SyntaxError\",\n    \"TypeError\",\n    \"URIError\"\n  ];\n\n  const BUILT_IN_GLOBALS = [\n    \"setInterval\",\n    \"setTimeout\",\n    \"clearInterval\",\n    \"clearTimeout\",\n\n    \"require\",\n    \"exports\",\n\n    \"eval\",\n    \"isFinite\",\n    \"isNaN\",\n    \"parseFloat\",\n    \"parseInt\",\n    \"decodeURI\",\n    \"decodeURIComponent\",\n    \"encodeURI\",\n    \"encodeURIComponent\",\n    \"escape\",\n    \"unescape\"\n  ];\n\n  const BUILT_IN_VARIABLES = [\n    \"arguments\",\n    \"this\",\n    \"super\",\n    \"console\",\n    \"window\",\n    \"document\",\n    \"localStorage\",\n    \"sessionStorage\",\n    \"module\",\n    \"global\" // Node.js\n  ];\n\n  const BUILT_INS = [].concat(\n    BUILT_IN_GLOBALS,\n    TYPES,\n    ERROR_TYPES\n  );\n\n  /*\n  Language: JavaScript\n  Description: JavaScript (JS) is a lightweight, interpreted, or just-in-time compiled programming language with first-class functions.\n  Category: common, scripting, web\n  Website: https://developer.mozilla.org/en-US/docs/Web/JavaScript\n  */\n\n\n  /** @type LanguageFn */\n  function javascript(hljs) {\n    const regex = hljs.regex;\n    /**\n     * Takes a string like \"<Booger\" and checks to see\n     * if we can find a matching \"</Booger\" later in the\n     * content.\n     * @param {RegExpMatchArray} match\n     * @param {{after:number}} param1\n     */\n    const hasClosingTag = (match, { after }) => {\n      const tag = \"</\" + match[0].slice(1);\n      const pos = match.input.indexOf(tag, after);\n      return pos !== -1;\n    };\n\n    const IDENT_RE$1 = IDENT_RE;\n    const FRAGMENT = {\n      begin: '<>',\n      end: '</>'\n    };\n    // to avoid some special cases inside isTrulyOpeningTag\n    const XML_SELF_CLOSING = /<[A-Za-z0-9\\\\._:-]+\\s*\\/>/;\n    const XML_TAG = {\n      begin: /<[A-Za-z0-9\\\\._:-]+/,\n      end: /\\/[A-Za-z0-9\\\\._:-]+>|\\/>/,\n      /**\n       * @param {RegExpMatchArray} match\n       * @param {CallbackResponse} response\n       */\n      isTrulyOpeningTag: (match, response) => {\n        const afterMatchIndex = match[0].length + match.index;\n        const nextChar = match.input[afterMatchIndex];\n        if (\n          // HTML should not include another raw `<` inside a tag\n          // nested type?\n          // `<Array<Array<number>>`, etc.\n          nextChar === \"<\" ||\n          // the , gives away that this is not HTML\n          // `<T, A extends keyof T, V>`\n          nextChar === \",\"\n          ) {\n          response.ignoreMatch();\n          return;\n        }\n\n        // `<something>`\n        // Quite possibly a tag, lets look for a matching closing tag...\n        if (nextChar === \">\") {\n          // if we cannot find a matching closing tag, then we\n          // will ignore it\n          if (!hasClosingTag(match, { after: afterMatchIndex })) {\n            response.ignoreMatch();\n          }\n        }\n\n        // `<blah />` (self-closing)\n        // handled by simpleSelfClosing rule\n\n        let m;\n        const afterMatch = match.input.substring(afterMatchIndex);\n\n        // some more template typing stuff\n        //  <T = any>(key?: string) => Modify<\n        if ((m = afterMatch.match(/^\\s*=/))) {\n          response.ignoreMatch();\n          return;\n        }\n\n        // `<From extends string>`\n        // technically this could be HTML, but it smells like a type\n        // NOTE: This is ugh, but added specifically for https://github.com/highlightjs/highlight.js/issues/3276\n        if ((m = afterMatch.match(/^\\s+extends\\s+/))) {\n          if (m.index === 0) {\n            response.ignoreMatch();\n            // eslint-disable-next-line no-useless-return\n            return;\n          }\n        }\n      }\n    };\n    const KEYWORDS$1 = {\n      $pattern: IDENT_RE,\n      keyword: KEYWORDS,\n      literal: LITERALS,\n      built_in: BUILT_INS,\n      \"variable.language\": BUILT_IN_VARIABLES\n    };\n\n    // https://tc39.es/ecma262/#sec-literals-numeric-literals\n    const decimalDigits = '[0-9](_?[0-9])*';\n    const frac = `\\\\.(${decimalDigits})`;\n    // DecimalIntegerLiteral, including Annex B NonOctalDecimalIntegerLiteral\n    // https://tc39.es/ecma262/#sec-additional-syntax-numeric-literals\n    const decimalInteger = `0|[1-9](_?[0-9])*|0[0-7]*[89][0-9]*`;\n    const NUMBER = {\n      className: 'number',\n      variants: [\n        // DecimalLiteral\n        { begin: `(\\\\b(${decimalInteger})((${frac})|\\\\.)?|(${frac}))` +\n          `[eE][+-]?(${decimalDigits})\\\\b` },\n        { begin: `\\\\b(${decimalInteger})\\\\b((${frac})\\\\b|\\\\.)?|(${frac})\\\\b` },\n\n        // DecimalBigIntegerLiteral\n        { begin: `\\\\b(0|[1-9](_?[0-9])*)n\\\\b` },\n\n        // NonDecimalIntegerLiteral\n        { begin: \"\\\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*n?\\\\b\" },\n        { begin: \"\\\\b0[bB][0-1](_?[0-1])*n?\\\\b\" },\n        { begin: \"\\\\b0[oO][0-7](_?[0-7])*n?\\\\b\" },\n\n        // LegacyOctalIntegerLiteral (does not include underscore separators)\n        // https://tc39.es/ecma262/#sec-additional-syntax-numeric-literals\n        { begin: \"\\\\b0[0-7]+n?\\\\b\" },\n      ],\n      relevance: 0\n    };\n\n    const SUBST = {\n      className: 'subst',\n      begin: '\\\\$\\\\{',\n      end: '\\\\}',\n      keywords: KEYWORDS$1,\n      contains: [] // defined later\n    };\n    const HTML_TEMPLATE = {\n      begin: '\\.?html`',\n      end: '',\n      starts: {\n        end: '`',\n        returnEnd: false,\n        contains: [\n          hljs.BACKSLASH_ESCAPE,\n          SUBST\n        ],\n        subLanguage: 'xml'\n      }\n    };\n    const CSS_TEMPLATE = {\n      begin: '\\.?css`',\n      end: '',\n      starts: {\n        end: '`',\n        returnEnd: false,\n        contains: [\n          hljs.BACKSLASH_ESCAPE,\n          SUBST\n        ],\n        subLanguage: 'css'\n      }\n    };\n    const GRAPHQL_TEMPLATE = {\n      begin: '\\.?gql`',\n      end: '',\n      starts: {\n        end: '`',\n        returnEnd: false,\n        contains: [\n          hljs.BACKSLASH_ESCAPE,\n          SUBST\n        ],\n        subLanguage: 'graphql'\n      }\n    };\n    const TEMPLATE_STRING = {\n      className: 'string',\n      begin: '`',\n      end: '`',\n      contains: [\n        hljs.BACKSLASH_ESCAPE,\n        SUBST\n      ]\n    };\n    const JSDOC_COMMENT = hljs.COMMENT(\n      /\\/\\*\\*(?!\\/)/,\n      '\\\\*/',\n      {\n        relevance: 0,\n        contains: [\n          {\n            begin: '(?=@[A-Za-z]+)',\n            relevance: 0,\n            contains: [\n              {\n                className: 'doctag',\n                begin: '@[A-Za-z]+'\n              },\n              {\n                className: 'type',\n                begin: '\\\\{',\n                end: '\\\\}',\n                excludeEnd: true,\n                excludeBegin: true,\n                relevance: 0\n              },\n              {\n                className: 'variable',\n                begin: IDENT_RE$1 + '(?=\\\\s*(-)|$)',\n                endsParent: true,\n                relevance: 0\n              },\n              // eat spaces (not newlines) so we can find\n              // types or variables\n              {\n                begin: /(?=[^\\n])\\s/,\n                relevance: 0\n              }\n            ]\n          }\n        ]\n      }\n    );\n    const COMMENT = {\n      className: \"comment\",\n      variants: [\n        JSDOC_COMMENT,\n        hljs.C_BLOCK_COMMENT_MODE,\n        hljs.C_LINE_COMMENT_MODE\n      ]\n    };\n    const SUBST_INTERNALS = [\n      hljs.APOS_STRING_MODE,\n      hljs.QUOTE_STRING_MODE,\n      HTML_TEMPLATE,\n      CSS_TEMPLATE,\n      GRAPHQL_TEMPLATE,\n      TEMPLATE_STRING,\n      // Skip numbers when they are part of a variable name\n      { match: /\\$\\d+/ },\n      NUMBER,\n      // This is intentional:\n      // See https://github.com/highlightjs/highlight.js/issues/3288\n      // hljs.REGEXP_MODE\n    ];\n    SUBST.contains = SUBST_INTERNALS\n      .concat({\n        // we need to pair up {} inside our subst to prevent\n        // it from ending too early by matching another }\n        begin: /\\{/,\n        end: /\\}/,\n        keywords: KEYWORDS$1,\n        contains: [\n          \"self\"\n        ].concat(SUBST_INTERNALS)\n      });\n    const SUBST_AND_COMMENTS = [].concat(COMMENT, SUBST.contains);\n    const PARAMS_CONTAINS = SUBST_AND_COMMENTS.concat([\n      // eat recursive parens in sub expressions\n      {\n        begin: /(\\s*)\\(/,\n        end: /\\)/,\n        keywords: KEYWORDS$1,\n        contains: [\"self\"].concat(SUBST_AND_COMMENTS)\n      }\n    ]);\n    const PARAMS = {\n      className: 'params',\n      // convert this to negative lookbehind in v12\n      begin: /(\\s*)\\(/, // to match the parms with\n      end: /\\)/,\n      excludeBegin: true,\n      excludeEnd: true,\n      keywords: KEYWORDS$1,\n      contains: PARAMS_CONTAINS\n    };\n\n    // ES6 classes\n    const CLASS_OR_EXTENDS = {\n      variants: [\n        // class Car extends vehicle\n        {\n          match: [\n            /class/,\n            /\\s+/,\n            IDENT_RE$1,\n            /\\s+/,\n            /extends/,\n            /\\s+/,\n            regex.concat(IDENT_RE$1, \"(\", regex.concat(/\\./, IDENT_RE$1), \")*\")\n          ],\n          scope: {\n            1: \"keyword\",\n            3: \"title.class\",\n            5: \"keyword\",\n            7: \"title.class.inherited\"\n          }\n        },\n        // class Car\n        {\n          match: [\n            /class/,\n            /\\s+/,\n            IDENT_RE$1\n          ],\n          scope: {\n            1: \"keyword\",\n            3: \"title.class\"\n          }\n        },\n\n      ]\n    };\n\n    const CLASS_REFERENCE = {\n      relevance: 0,\n      match:\n      regex.either(\n        // Hard coded exceptions\n        /\\bJSON/,\n        // Float32Array, OutT\n        /\\b[A-Z][a-z]+([A-Z][a-z]*|\\d)*/,\n        // CSSFactory, CSSFactoryT\n        /\\b[A-Z]{2,}([A-Z][a-z]+|\\d)+([A-Z][a-z]*)*/,\n        // FPs, FPsT\n        /\\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\\d)*([A-Z][a-z]*)*/,\n        // P\n        // single letters are not highlighted\n        // BLAH\n        // this will be flagged as a UPPER_CASE_CONSTANT instead\n      ),\n      className: \"title.class\",\n      keywords: {\n        _: [\n          // se we still get relevance credit for JS library classes\n          ...TYPES,\n          ...ERROR_TYPES\n        ]\n      }\n    };\n\n    const USE_STRICT = {\n      label: \"use_strict\",\n      className: 'meta',\n      relevance: 10,\n      begin: /^\\s*['\"]use (strict|asm)['\"]/\n    };\n\n    const FUNCTION_DEFINITION = {\n      variants: [\n        {\n          match: [\n            /function/,\n            /\\s+/,\n            IDENT_RE$1,\n            /(?=\\s*\\()/\n          ]\n        },\n        // anonymous function\n        {\n          match: [\n            /function/,\n            /\\s*(?=\\()/\n          ]\n        }\n      ],\n      className: {\n        1: \"keyword\",\n        3: \"title.function\"\n      },\n      label: \"func.def\",\n      contains: [ PARAMS ],\n      illegal: /%/\n    };\n\n    const UPPER_CASE_CONSTANT = {\n      relevance: 0,\n      match: /\\b[A-Z][A-Z_0-9]+\\b/,\n      className: \"variable.constant\"\n    };\n\n    function noneOf(list) {\n      return regex.concat(\"(?!\", list.join(\"|\"), \")\");\n    }\n\n    const FUNCTION_CALL = {\n      match: regex.concat(\n        /\\b/,\n        noneOf([\n          ...BUILT_IN_GLOBALS,\n          \"super\",\n          \"import\",\n          \"await\",\n        ].map(x => `${x}\\\\s*\\\\(`)),\n        IDENT_RE$1, regex.lookahead(/\\s*\\(/)),\n      className: \"title.function\",\n      relevance: 0\n    };\n\n    const PROPERTY_ACCESS = {\n      begin: regex.concat(/\\./, regex.lookahead(\n        regex.concat(IDENT_RE$1, /(?![0-9A-Za-z$_(])/)\n      )),\n      end: IDENT_RE$1,\n      excludeBegin: true,\n      keywords: \"prototype\",\n      className: \"property\",\n      relevance: 0\n    };\n\n    const GETTER_OR_SETTER = {\n      match: [\n        /get|set/,\n        /\\s+/,\n        IDENT_RE$1,\n        /(?=\\()/\n      ],\n      className: {\n        1: \"keyword\",\n        3: \"title.function\"\n      },\n      contains: [\n        { // eat to avoid empty params\n          begin: /\\(\\)/\n        },\n        PARAMS\n      ]\n    };\n\n    const FUNC_LEAD_IN_RE = '(\\\\(' +\n      '[^()]*(\\\\(' +\n      '[^()]*(\\\\(' +\n      '[^()]*' +\n      '\\\\)[^()]*)*' +\n      '\\\\)[^()]*)*' +\n      '\\\\)|' + hljs.UNDERSCORE_IDENT_RE + ')\\\\s*=>';\n\n    const FUNCTION_VARIABLE = {\n      match: [\n        /const|var|let/, /\\s+/,\n        IDENT_RE$1, /\\s*/,\n        /=\\s*/,\n        /(async\\s*)?/, // async is optional\n        regex.lookahead(FUNC_LEAD_IN_RE)\n      ],\n      keywords: \"async\",\n      className: {\n        1: \"keyword\",\n        3: \"title.function\"\n      },\n      contains: [\n        PARAMS\n      ]\n    };\n\n    return {\n      name: 'JavaScript',\n      aliases: ['js', 'jsx', 'mjs', 'cjs'],\n      keywords: KEYWORDS$1,\n      // this will be extended by TypeScript\n      exports: { PARAMS_CONTAINS, CLASS_REFERENCE },\n      illegal: /#(?![$_A-Za-z])/,\n      contains: [\n        hljs.SHEBANG({\n          label: \"shebang\",\n          binary: \"node\",\n          relevance: 5\n        }),\n        USE_STRICT,\n        hljs.APOS_STRING_MODE,\n        hljs.QUOTE_STRING_MODE,\n        HTML_TEMPLATE,\n        CSS_TEMPLATE,\n        GRAPHQL_TEMPLATE,\n        TEMPLATE_STRING,\n        COMMENT,\n        // Skip numbers when they are part of a variable name\n        { match: /\\$\\d+/ },\n        NUMBER,\n        CLASS_REFERENCE,\n        {\n          scope: 'attr',\n          match: IDENT_RE$1 + regex.lookahead(':'),\n          relevance: 0\n        },\n        FUNCTION_VARIABLE,\n        { // \"value\" container\n          begin: '(' + hljs.RE_STARTERS_RE + '|\\\\b(case|return|throw)\\\\b)\\\\s*',\n          keywords: 'return throw case',\n          relevance: 0,\n          contains: [\n            COMMENT,\n            hljs.REGEXP_MODE,\n            {\n              className: 'function',\n              // we have to count the parens to make sure we actually have the\n              // correct bounding ( ) before the =>.  There could be any number of\n              // sub-expressions inside also surrounded by parens.\n              begin: FUNC_LEAD_IN_RE,\n              returnBegin: true,\n              end: '\\\\s*=>',\n              contains: [\n                {\n                  className: 'params',\n                  variants: [\n                    {\n                      begin: hljs.UNDERSCORE_IDENT_RE,\n                      relevance: 0\n                    },\n                    {\n                      className: null,\n                      begin: /\\(\\s*\\)/,\n                      skip: true\n                    },\n                    {\n                      begin: /(\\s*)\\(/,\n                      end: /\\)/,\n                      excludeBegin: true,\n                      excludeEnd: true,\n                      keywords: KEYWORDS$1,\n                      contains: PARAMS_CONTAINS\n                    }\n                  ]\n                }\n              ]\n            },\n            { // could be a comma delimited list of params to a function call\n              begin: /,/,\n              relevance: 0\n            },\n            {\n              match: /\\s+/,\n              relevance: 0\n            },\n            { // JSX\n              variants: [\n                { begin: FRAGMENT.begin, end: FRAGMENT.end },\n                { match: XML_SELF_CLOSING },\n                {\n                  begin: XML_TAG.begin,\n                  // we carefully check the opening tag to see if it truly\n                  // is a tag and not a false positive\n                  'on:begin': XML_TAG.isTrulyOpeningTag,\n                  end: XML_TAG.end\n                }\n              ],\n              subLanguage: 'xml',\n              contains: [\n                {\n                  begin: XML_TAG.begin,\n                  end: XML_TAG.end,\n                  skip: true,\n                  contains: ['self']\n                }\n              ]\n            }\n          ],\n        },\n        FUNCTION_DEFINITION,\n        {\n          // prevent this from getting swallowed up by function\n          // since they appear \"function like\"\n          beginKeywords: \"while if switch catch for\"\n        },\n        {\n          // we have to count the parens to make sure we actually have the correct\n          // bounding ( ).  There could be any number of sub-expressions inside\n          // also surrounded by parens.\n          begin: '\\\\b(?!function)' + hljs.UNDERSCORE_IDENT_RE +\n            '\\\\(' + // first parens\n            '[^()]*(\\\\(' +\n              '[^()]*(\\\\(' +\n                '[^()]*' +\n              '\\\\)[^()]*)*' +\n            '\\\\)[^()]*)*' +\n            '\\\\)\\\\s*\\\\{', // end parens\n          returnBegin:true,\n          label: \"func.def\",\n          contains: [\n            PARAMS,\n            hljs.inherit(hljs.TITLE_MODE, { begin: IDENT_RE$1, className: \"title.function\" })\n          ]\n        },\n        // catch ... so it won't trigger the property rule below\n        {\n          match: /\\.\\.\\./,\n          relevance: 0\n        },\n        PROPERTY_ACCESS,\n        // hack: prevents detection of keywords in some circumstances\n        // .keyword()\n        // $keyword = x\n        {\n          match: '\\\\$' + IDENT_RE$1,\n          relevance: 0\n        },\n        {\n          match: [ /\\bconstructor(?=\\s*\\()/ ],\n          className: { 1: \"title.function\" },\n          contains: [ PARAMS ]\n        },\n        FUNCTION_CALL,\n        UPPER_CASE_CONSTANT,\n        CLASS_OR_EXTENDS,\n        GETTER_OR_SETTER,\n        {\n          match: /\\$[(.]/ // relevance booster for a pattern common to JS libs: `$(something)` and `$.something`\n        }\n      ]\n    };\n  }\n\n  /*\n  Language: JSON\n  Description: JSON (JavaScript Object Notation) is a lightweight data-interchange format.\n  Websites: http://www.json.org, https://www.json5.org\n  Category: common, protocols, web\n  */\n\n\n  function json(hljs) {\n    const ATTRIBUTE = {\n      className: 'attr',\n      begin: /((\"(\\\\.|[^\\\\\"\\r\\n])*\")|('(\\\\.|[^\\\\'\\r\\n])*'))(?=\\s*:)/,\n      relevance: 1.01\n    };\n    const PUNCTUATION = {\n      match: /[{}[\\],:]/,\n      className: \"punctuation\",\n      relevance: 0\n    };\n    const LITERALS = [\n      \"true\",\n      \"false\",\n      \"null\"\n    ];\n    // NOTE: normally we would rely on `keywords` for this but using a mode here allows us\n    // - to use the very tight `illegal: \\S` rule later to flag any other character\n    // - as illegal indicating that despite looking like JSON we do not truly have\n    // - JSON and thus improve false-positively greatly since JSON will try and claim\n    // - all sorts of JSON looking stuff\n    const LITERALS_MODE = {\n      scope: \"literal\",\n      beginKeywords: LITERALS.join(\" \"),\n    };\n\n    return {\n      name: 'JSON',\n      aliases: ['jsonc', 'json5'],\n      keywords:{\n        literal: LITERALS,\n      },\n      contains: [\n        ATTRIBUTE,\n        PUNCTUATION,\n        hljs.APOS_STRING_MODE,\n        hljs.QUOTE_STRING_MODE,\n        LITERALS_MODE,\n        EXTENDED_NUMBER_MODE,\n        hljs.C_LINE_COMMENT_MODE,\n        hljs.C_BLOCK_COMMENT_MODE\n      ],\n      illegal: '\\\\S'\n    };\n  }\n\n  /*\n   Language: Kotlin\n   Description: Kotlin is an OSS statically typed programming language that targets the JVM, Android, JavaScript and Native.\n   Author: Sergey Mashkov <cy6erGn0m@gmail.com>\n   Website: https://kotlinlang.org\n   Category: common\n   */\n\n\n  function kotlin(hljs) {\n    const KEYWORDS = {\n      keyword:\n        'abstract as val var vararg get set class object open private protected public noinline '\n        + 'crossinline dynamic final enum if else do while for when throw try catch finally '\n        + 'import package is in fun override companion reified inline lateinit init '\n        + 'interface annotation data sealed internal infix operator out by constructor super '\n        + 'tailrec where const inner suspend typealias external expect actual',\n      built_in:\n        'Byte Short Char Int Long Boolean Float Double Void Unit Nothing',\n      literal:\n        'true false null'\n    };\n    const KEYWORDS_WITH_LABEL = {\n      className: 'keyword',\n      begin: /\\b(break|continue|return|this)\\b/,\n      starts: { contains: [\n        {\n          className: 'symbol',\n          begin: /@\\w+/\n        }\n      ] }\n    };\n    const LABEL = {\n      className: 'symbol',\n      begin: hljs.UNDERSCORE_IDENT_RE + '@'\n    };\n\n    // for string templates\n    const SUBST = {\n      className: 'subst',\n      begin: /\\$\\{/,\n      end: /\\}/,\n      contains: [ hljs.C_NUMBER_MODE ]\n    };\n    const VARIABLE = {\n      className: 'variable',\n      begin: '\\\\$' + hljs.UNDERSCORE_IDENT_RE\n    };\n    const STRING = {\n      className: 'string',\n      variants: [\n        {\n          begin: '\"\"\"',\n          end: '\"\"\"(?=[^\"])',\n          contains: [\n            VARIABLE,\n            SUBST\n          ]\n        },\n        // Can't use built-in modes easily, as we want to use STRING in the meta\n        // context as 'meta-string' and there's no syntax to remove explicitly set\n        // classNames in built-in modes.\n        {\n          begin: '\\'',\n          end: '\\'',\n          illegal: /\\n/,\n          contains: [ hljs.BACKSLASH_ESCAPE ]\n        },\n        {\n          begin: '\"',\n          end: '\"',\n          illegal: /\\n/,\n          contains: [\n            hljs.BACKSLASH_ESCAPE,\n            VARIABLE,\n            SUBST\n          ]\n        }\n      ]\n    };\n    SUBST.contains.push(STRING);\n\n    const ANNOTATION_USE_SITE = {\n      className: 'meta',\n      begin: '@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\\\s*:(?:\\\\s*' + hljs.UNDERSCORE_IDENT_RE + ')?'\n    };\n    const ANNOTATION = {\n      className: 'meta',\n      begin: '@' + hljs.UNDERSCORE_IDENT_RE,\n      contains: [\n        {\n          begin: /\\(/,\n          end: /\\)/,\n          contains: [\n            hljs.inherit(STRING, { className: 'string' }),\n            \"self\"\n          ]\n        }\n      ]\n    };\n\n    // https://kotlinlang.org/docs/reference/whatsnew11.html#underscores-in-numeric-literals\n    // According to the doc above, the number mode of kotlin is the same as java 8,\n    // so the code below is copied from java.js\n    const KOTLIN_NUMBER_MODE = NUMERIC;\n    const KOTLIN_NESTED_COMMENT = hljs.COMMENT(\n      '/\\\\*', '\\\\*/',\n      { contains: [ hljs.C_BLOCK_COMMENT_MODE ] }\n    );\n    const KOTLIN_PAREN_TYPE = { variants: [\n      {\n        className: 'type',\n        begin: hljs.UNDERSCORE_IDENT_RE\n      },\n      {\n        begin: /\\(/,\n        end: /\\)/,\n        contains: [] // defined later\n      }\n    ] };\n    const KOTLIN_PAREN_TYPE2 = KOTLIN_PAREN_TYPE;\n    KOTLIN_PAREN_TYPE2.variants[1].contains = [ KOTLIN_PAREN_TYPE ];\n    KOTLIN_PAREN_TYPE.variants[1].contains = [ KOTLIN_PAREN_TYPE2 ];\n\n    return {\n      name: 'Kotlin',\n      aliases: [\n        'kt',\n        'kts'\n      ],\n      keywords: KEYWORDS,\n      contains: [\n        hljs.COMMENT(\n          '/\\\\*\\\\*',\n          '\\\\*/',\n          {\n            relevance: 0,\n            contains: [\n              {\n                className: 'doctag',\n                begin: '@[A-Za-z]+'\n              }\n            ]\n          }\n        ),\n        hljs.C_LINE_COMMENT_MODE,\n        KOTLIN_NESTED_COMMENT,\n        KEYWORDS_WITH_LABEL,\n        LABEL,\n        ANNOTATION_USE_SITE,\n        ANNOTATION,\n        {\n          className: 'function',\n          beginKeywords: 'fun',\n          end: '[(]|$',\n          returnBegin: true,\n          excludeEnd: true,\n          keywords: KEYWORDS,\n          relevance: 5,\n          contains: [\n            {\n              begin: hljs.UNDERSCORE_IDENT_RE + '\\\\s*\\\\(',\n              returnBegin: true,\n              relevance: 0,\n              contains: [ hljs.UNDERSCORE_TITLE_MODE ]\n            },\n            {\n              className: 'type',\n              begin: /</,\n              end: />/,\n              keywords: 'reified',\n              relevance: 0\n            },\n            {\n              className: 'params',\n              begin: /\\(/,\n              end: /\\)/,\n              endsParent: true,\n              keywords: KEYWORDS,\n              relevance: 0,\n              contains: [\n                {\n                  begin: /:/,\n                  end: /[=,\\/]/,\n                  endsWithParent: true,\n                  contains: [\n                    KOTLIN_PAREN_TYPE,\n                    hljs.C_LINE_COMMENT_MODE,\n                    KOTLIN_NESTED_COMMENT\n                  ],\n                  relevance: 0\n                },\n                hljs.C_LINE_COMMENT_MODE,\n                KOTLIN_NESTED_COMMENT,\n                ANNOTATION_USE_SITE,\n                ANNOTATION,\n                STRING,\n                hljs.C_NUMBER_MODE\n              ]\n            },\n            KOTLIN_NESTED_COMMENT\n          ]\n        },\n        {\n          begin: [\n            /class|interface|trait/,\n            /\\s+/,\n            hljs.UNDERSCORE_IDENT_RE\n          ],\n          beginScope: {\n            3: \"title.class\"\n          },\n          keywords: 'class interface trait',\n          end: /[:\\{(]|$/,\n          excludeEnd: true,\n          illegal: 'extends implements',\n          contains: [\n            { beginKeywords: 'public protected internal private constructor' },\n            hljs.UNDERSCORE_TITLE_MODE,\n            {\n              className: 'type',\n              begin: /</,\n              end: />/,\n              excludeBegin: true,\n              excludeEnd: true,\n              relevance: 0\n            },\n            {\n              className: 'type',\n              begin: /[,:]\\s*/,\n              end: /[<\\(,){\\s]|$/,\n              excludeBegin: true,\n              returnEnd: true\n            },\n            ANNOTATION_USE_SITE,\n            ANNOTATION\n          ]\n        },\n        STRING,\n        {\n          className: 'meta',\n          begin: \"^#!/usr/bin/env\",\n          end: '$',\n          illegal: '\\n'\n        },\n        KOTLIN_NUMBER_MODE\n      ]\n    };\n  }\n\n  /*\n  Language: Less\n  Description: It's CSS, with just a little more.\n  Author:   Max Mikhailov <seven.phases.max@gmail.com>\n  Website: http://lesscss.org\n  Category: common, css, web\n  */\n\n\n  /** @type LanguageFn */\n  function less(hljs) {\n    const modes = MODES(hljs);\n    const PSEUDO_SELECTORS$1 = PSEUDO_SELECTORS;\n\n    const AT_MODIFIERS = \"and or not only\";\n    const IDENT_RE = '[\\\\w-]+'; // yes, Less identifiers may begin with a digit\n    const INTERP_IDENT_RE = '(' + IDENT_RE + '|@\\\\{' + IDENT_RE + '\\\\})';\n\n    /* Generic Modes */\n\n    const RULES = []; const VALUE_MODES = []; // forward def. for recursive modes\n\n    const STRING_MODE = function(c) {\n      return {\n      // Less strings are not multiline (also include '~' for more consistent coloring of \"escaped\" strings)\n        className: 'string',\n        begin: '~?' + c + '.*?' + c\n      };\n    };\n\n    const IDENT_MODE = function(name, begin, relevance) {\n      return {\n        className: name,\n        begin: begin,\n        relevance: relevance\n      };\n    };\n\n    const AT_KEYWORDS = {\n      $pattern: /[a-z-]+/,\n      keyword: AT_MODIFIERS,\n      attribute: MEDIA_FEATURES.join(\" \")\n    };\n\n    const PARENS_MODE = {\n      // used only to properly balance nested parens inside mixin call, def. arg list\n      begin: '\\\\(',\n      end: '\\\\)',\n      contains: VALUE_MODES,\n      keywords: AT_KEYWORDS,\n      relevance: 0\n    };\n\n    // generic Less highlighter (used almost everywhere except selectors):\n    VALUE_MODES.push(\n      hljs.C_LINE_COMMENT_MODE,\n      hljs.C_BLOCK_COMMENT_MODE,\n      STRING_MODE(\"'\"),\n      STRING_MODE('\"'),\n      modes.CSS_NUMBER_MODE, // fixme: it does not include dot for numbers like .5em :(\n      {\n        begin: '(url|data-uri)\\\\(',\n        starts: {\n          className: 'string',\n          end: '[\\\\)\\\\n]',\n          excludeEnd: true\n        }\n      },\n      modes.UNICODE_RANGE,\n      modes.HEXCOLOR,\n      PARENS_MODE,\n      IDENT_MODE('variable', '@@?' + IDENT_RE, 10),\n      IDENT_MODE('variable', '@\\\\{' + IDENT_RE + '\\\\}'),\n      IDENT_MODE('built_in', '~?`[^`]*?`'), // inline javascript (or whatever host language) *multiline* string\n      { // @media features (it’s here to not duplicate things in AT_RULE_MODE with extra PARENS_MODE overriding):\n        className: 'attribute',\n        begin: IDENT_RE + '\\\\s*:',\n        end: ':',\n        returnBegin: true,\n        excludeEnd: true\n      },\n      modes.IMPORTANT,\n      { beginKeywords: 'and not' },\n      modes.FUNCTION_DISPATCH\n    );\n\n    const VALUE_WITH_RULESETS = VALUE_MODES.concat({\n      begin: /\\{/,\n      end: /\\}/,\n      contains: RULES\n    });\n\n    const MIXIN_GUARD_MODE = {\n      beginKeywords: 'when',\n      endsWithParent: true,\n      contains: [ { beginKeywords: 'and not' } ].concat(VALUE_MODES) // using this form to override VALUE’s 'function' match\n    };\n\n    /* Rule-Level Modes */\n\n    const RULE_MODE = {\n      begin: INTERP_IDENT_RE + '\\\\s*:',\n      returnBegin: true,\n      end: /[;}]/,\n      relevance: 0,\n      contains: [\n        { begin: /-(webkit|moz|ms|o)-/ },\n        modes.CSS_VARIABLE,\n        {\n          className: 'attribute',\n          begin: '\\\\b(' + ATTRIBUTES.join('|') + ')\\\\b',\n          end: /(?=:)/,\n          starts: {\n            endsWithParent: true,\n            illegal: '[<=$]',\n            relevance: 0,\n            contains: VALUE_MODES\n          }\n        }\n      ]\n    };\n\n    const AT_RULE_MODE = {\n      className: 'keyword',\n      begin: '@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\\\b',\n      starts: {\n        end: '[;{}]',\n        keywords: AT_KEYWORDS,\n        returnEnd: true,\n        contains: VALUE_MODES,\n        relevance: 0\n      }\n    };\n\n    // variable definitions and calls\n    const VAR_RULE_MODE = {\n      className: 'variable',\n      variants: [\n        // using more strict pattern for higher relevance to increase chances of Less detection.\n        // this is *the only* Less specific statement used in most of the sources, so...\n        // (we’ll still often loose to the css-parser unless there's '//' comment,\n        // simply because 1 variable just can't beat 99 properties :)\n        {\n          begin: '@' + IDENT_RE + '\\\\s*:',\n          relevance: 15\n        },\n        { begin: '@' + IDENT_RE }\n      ],\n      starts: {\n        end: '[;}]',\n        returnEnd: true,\n        contains: VALUE_WITH_RULESETS\n      }\n    };\n\n    const SELECTOR_MODE = {\n      // first parse unambiguous selectors (i.e. those not starting with tag)\n      // then fall into the scary lookahead-discriminator variant.\n      // this mode also handles mixin definitions and calls\n      variants: [\n        {\n          begin: '[\\\\.#:&\\\\[>]',\n          end: '[;{}]' // mixin calls end with ';'\n        },\n        {\n          begin: INTERP_IDENT_RE,\n          end: /\\{/\n        }\n      ],\n      returnBegin: true,\n      returnEnd: true,\n      illegal: '[<=\\'$\"]',\n      relevance: 0,\n      contains: [\n        hljs.C_LINE_COMMENT_MODE,\n        hljs.C_BLOCK_COMMENT_MODE,\n        MIXIN_GUARD_MODE,\n        IDENT_MODE('keyword', 'all\\\\b'),\n        IDENT_MODE('variable', '@\\\\{' + IDENT_RE + '\\\\}'), // otherwise it’s identified as tag\n\n        {\n          begin: '\\\\b(' + TAGS.join('|') + ')\\\\b',\n          className: 'selector-tag'\n        },\n        modes.CSS_NUMBER_MODE,\n        IDENT_MODE('selector-tag', INTERP_IDENT_RE, 0),\n        IDENT_MODE('selector-id', '#' + INTERP_IDENT_RE),\n        IDENT_MODE('selector-class', '\\\\.' + INTERP_IDENT_RE, 0),\n        IDENT_MODE('selector-tag', '&', 0),\n        modes.ATTRIBUTE_SELECTOR_MODE,\n        {\n          className: 'selector-pseudo',\n          begin: ':(' + PSEUDO_CLASSES.join('|') + ')'\n        },\n        {\n          className: 'selector-pseudo',\n          begin: ':(:)?(' + PSEUDO_ELEMENTS.join('|') + ')'\n        },\n        {\n          begin: /\\(/,\n          end: /\\)/,\n          relevance: 0,\n          contains: VALUE_WITH_RULESETS\n        }, // argument list of parametric mixins\n        { begin: '!important' }, // eat !important after mixin call or it will be colored as tag\n        modes.FUNCTION_DISPATCH\n      ]\n    };\n\n    const PSEUDO_SELECTOR_MODE = {\n      begin: IDENT_RE + ':(:)?' + `(${PSEUDO_SELECTORS$1.join('|')})`,\n      returnBegin: true,\n      contains: [ SELECTOR_MODE ]\n    };\n\n    RULES.push(\n      hljs.C_LINE_COMMENT_MODE,\n      hljs.C_BLOCK_COMMENT_MODE,\n      AT_RULE_MODE,\n      VAR_RULE_MODE,\n      PSEUDO_SELECTOR_MODE,\n      RULE_MODE,\n      SELECTOR_MODE,\n      MIXIN_GUARD_MODE,\n      modes.FUNCTION_DISPATCH\n    );\n\n    return {\n      name: 'Less',\n      case_insensitive: true,\n      illegal: '[=>\\'/<($\"]',\n      contains: RULES\n    };\n  }\n\n  /*\n  Language: Lua\n  Description: Lua is a powerful, efficient, lightweight, embeddable scripting language.\n  Author: Andrew Fedorov <dmmdrs@mail.ru>\n  Category: common, gaming, scripting\n  Website: https://www.lua.org\n  */\n\n  function lua(hljs) {\n    const OPENING_LONG_BRACKET = '\\\\[=*\\\\[';\n    const CLOSING_LONG_BRACKET = '\\\\]=*\\\\]';\n    const LONG_BRACKETS = {\n      begin: OPENING_LONG_BRACKET,\n      end: CLOSING_LONG_BRACKET,\n      contains: [ 'self' ]\n    };\n    const COMMENTS = [\n      hljs.COMMENT('--(?!' + OPENING_LONG_BRACKET + ')', '$'),\n      hljs.COMMENT(\n        '--' + OPENING_LONG_BRACKET,\n        CLOSING_LONG_BRACKET,\n        {\n          contains: [ LONG_BRACKETS ],\n          relevance: 10\n        }\n      )\n    ];\n    return {\n      name: 'Lua',\n      aliases: ['pluto'],\n      keywords: {\n        $pattern: hljs.UNDERSCORE_IDENT_RE,\n        literal: \"true false nil\",\n        keyword: \"and break do else elseif end for goto if in local not or repeat return then until while\",\n        built_in:\n          // Metatags and globals:\n          '_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len '\n          + '__gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert '\n          // Standard methods and properties:\n          + 'collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring '\n          + 'module next pairs pcall print rawequal rawget rawset require select setfenv '\n          + 'setmetatable tonumber tostring type unpack xpcall arg self '\n          // Library methods and properties (one line per library):\n          + 'coroutine resume yield status wrap create running debug getupvalue '\n          + 'debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv '\n          + 'io lines write close flush open output type read stderr stdin input stdout popen tmpfile '\n          + 'math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan '\n          + 'os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall '\n          + 'string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower '\n          + 'table setn insert getn foreachi maxn foreach concat sort remove'\n      },\n      contains: COMMENTS.concat([\n        {\n          className: 'function',\n          beginKeywords: 'function',\n          end: '\\\\)',\n          contains: [\n            hljs.inherit(hljs.TITLE_MODE, { begin: '([_a-zA-Z]\\\\w*\\\\.)*([_a-zA-Z]\\\\w*:)?[_a-zA-Z]\\\\w*' }),\n            {\n              className: 'params',\n              begin: '\\\\(',\n              endsWithParent: true,\n              contains: COMMENTS\n            }\n          ].concat(COMMENTS)\n        },\n        hljs.C_NUMBER_MODE,\n        hljs.APOS_STRING_MODE,\n        hljs.QUOTE_STRING_MODE,\n        {\n          className: 'string',\n          begin: OPENING_LONG_BRACKET,\n          end: CLOSING_LONG_BRACKET,\n          contains: [ LONG_BRACKETS ],\n          relevance: 5\n        }\n      ])\n    };\n  }\n\n  /*\n  Language: Makefile\n  Author: Ivan Sagalaev <maniac@softwaremaniacs.org>\n  Contributors: Joël Porquet <joel@porquet.org>\n  Website: https://www.gnu.org/software/make/manual/html_node/Introduction.html\n  Category: common, build-system\n  */\n\n  function makefile(hljs) {\n    /* Variables: simple (eg $(var)) and special (eg $@) */\n    const VARIABLE = {\n      className: 'variable',\n      variants: [\n        {\n          begin: '\\\\$\\\\(' + hljs.UNDERSCORE_IDENT_RE + '\\\\)',\n          contains: [ hljs.BACKSLASH_ESCAPE ]\n        },\n        { begin: /\\$[@%<?\\^\\+\\*]/ }\n      ]\n    };\n    /* Quoted string with variables inside */\n    const QUOTE_STRING = {\n      className: 'string',\n      begin: /\"/,\n      end: /\"/,\n      contains: [\n        hljs.BACKSLASH_ESCAPE,\n        VARIABLE\n      ]\n    };\n    /* Function: $(func arg,...) */\n    const FUNC = {\n      className: 'variable',\n      begin: /\\$\\([\\w-]+\\s/,\n      end: /\\)/,\n      keywords: { built_in:\n          'subst patsubst strip findstring filter filter-out sort '\n          + 'word wordlist firstword lastword dir notdir suffix basename '\n          + 'addsuffix addprefix join wildcard realpath abspath error warning '\n          + 'shell origin flavor foreach if or and call eval file value' },\n      contains: [ \n        VARIABLE,\n        QUOTE_STRING // Added QUOTE_STRING as they can be a part of functions\n      ]\n    };\n    /* Variable assignment */\n    const ASSIGNMENT = { begin: '^' + hljs.UNDERSCORE_IDENT_RE + '\\\\s*(?=[:+?]?=)' };\n    /* Meta targets (.PHONY) */\n    const META = {\n      className: 'meta',\n      begin: /^\\.PHONY:/,\n      end: /$/,\n      keywords: {\n        $pattern: /[\\.\\w]+/,\n        keyword: '.PHONY'\n      }\n    };\n    /* Targets */\n    const TARGET = {\n      className: 'section',\n      begin: /^[^\\s]+:/,\n      end: /$/,\n      contains: [ VARIABLE ]\n    };\n    return {\n      name: 'Makefile',\n      aliases: [\n        'mk',\n        'mak',\n        'make',\n      ],\n      keywords: {\n        $pattern: /[\\w-]+/,\n        keyword: 'define endef undefine ifdef ifndef ifeq ifneq else endif '\n        + 'include -include sinclude override export unexport private vpath'\n      },\n      contains: [\n        hljs.HASH_COMMENT_MODE,\n        VARIABLE,\n        QUOTE_STRING,\n        FUNC,\n        ASSIGNMENT,\n        META,\n        TARGET\n      ]\n    };\n  }\n\n  /*\n  Language: HTML, XML\n  Website: https://www.w3.org/XML/\n  Category: common, web\n  Audit: 2020\n  */\n\n  /** @type LanguageFn */\n  function xml(hljs) {\n    const regex = hljs.regex;\n    // XML names can have the following additional letters: https://www.w3.org/TR/xml/#NT-NameChar\n    // OTHER_NAME_CHARS = /[:\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]/;\n    // Element names start with NAME_START_CHAR followed by optional other Unicode letters, ASCII digits, hyphens, underscores, and periods\n    // const TAG_NAME_RE = regex.concat(/[A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD]/, regex.optional(/[A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*:/), /[A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*/);;\n    // const XML_IDENT_RE = /[A-Z_a-z:\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]+/;\n    // const TAG_NAME_RE = regex.concat(/[A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD]/, regex.optional(/[A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*:/), /[A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*/);\n    // however, to cater for performance and more Unicode support rely simply on the Unicode letter class\n    const TAG_NAME_RE = regex.concat(/[\\p{L}_]/u, regex.optional(/[\\p{L}0-9_.-]*:/u), /[\\p{L}0-9_.-]*/u);\n    const XML_IDENT_RE = /[\\p{L}0-9._:-]+/u;\n    const XML_ENTITIES = {\n      className: 'symbol',\n      begin: /&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/\n    };\n    const XML_META_KEYWORDS = {\n      begin: /\\s/,\n      contains: [\n        {\n          className: 'keyword',\n          begin: /#?[a-z_][a-z1-9_-]+/,\n          illegal: /\\n/\n        }\n      ]\n    };\n    const XML_META_PAR_KEYWORDS = hljs.inherit(XML_META_KEYWORDS, {\n      begin: /\\(/,\n      end: /\\)/\n    });\n    const APOS_META_STRING_MODE = hljs.inherit(hljs.APOS_STRING_MODE, { className: 'string' });\n    const QUOTE_META_STRING_MODE = hljs.inherit(hljs.QUOTE_STRING_MODE, { className: 'string' });\n    const TAG_INTERNALS = {\n      endsWithParent: true,\n      illegal: /</,\n      relevance: 0,\n      contains: [\n        {\n          className: 'attr',\n          begin: XML_IDENT_RE,\n          relevance: 0\n        },\n        {\n          begin: /=\\s*/,\n          relevance: 0,\n          contains: [\n            {\n              className: 'string',\n              endsParent: true,\n              variants: [\n                {\n                  begin: /\"/,\n                  end: /\"/,\n                  contains: [ XML_ENTITIES ]\n                },\n                {\n                  begin: /'/,\n                  end: /'/,\n                  contains: [ XML_ENTITIES ]\n                },\n                { begin: /[^\\s\"'=<>`]+/ }\n              ]\n            }\n          ]\n        }\n      ]\n    };\n    return {\n      name: 'HTML, XML',\n      aliases: [\n        'html',\n        'xhtml',\n        'rss',\n        'atom',\n        'xjb',\n        'xsd',\n        'xsl',\n        'plist',\n        'wsf',\n        'svg'\n      ],\n      case_insensitive: true,\n      unicodeRegex: true,\n      contains: [\n        {\n          className: 'meta',\n          begin: /<![a-z]/,\n          end: />/,\n          relevance: 10,\n          contains: [\n            XML_META_KEYWORDS,\n            QUOTE_META_STRING_MODE,\n            APOS_META_STRING_MODE,\n            XML_META_PAR_KEYWORDS,\n            {\n              begin: /\\[/,\n              end: /\\]/,\n              contains: [\n                {\n                  className: 'meta',\n                  begin: /<![a-z]/,\n                  end: />/,\n                  contains: [\n                    XML_META_KEYWORDS,\n                    XML_META_PAR_KEYWORDS,\n                    QUOTE_META_STRING_MODE,\n                    APOS_META_STRING_MODE\n                  ]\n                }\n              ]\n            }\n          ]\n        },\n        hljs.COMMENT(\n          /<!--/,\n          /-->/,\n          { relevance: 10 }\n        ),\n        {\n          begin: /<!\\[CDATA\\[/,\n          end: /\\]\\]>/,\n          relevance: 10\n        },\n        XML_ENTITIES,\n        // xml processing instructions\n        {\n          className: 'meta',\n          end: /\\?>/,\n          variants: [\n            {\n              begin: /<\\?xml/,\n              relevance: 10,\n              contains: [\n                QUOTE_META_STRING_MODE\n              ]\n            },\n            {\n              begin: /<\\?[a-z][a-z0-9]+/,\n            }\n          ]\n\n        },\n        {\n          className: 'tag',\n          /*\n          The lookahead pattern (?=...) ensures that 'begin' only matches\n          '<style' as a single word, followed by a whitespace or an\n          ending bracket.\n          */\n          begin: /<style(?=\\s|>)/,\n          end: />/,\n          keywords: { name: 'style' },\n          contains: [ TAG_INTERNALS ],\n          starts: {\n            end: /<\\/style>/,\n            returnEnd: true,\n            subLanguage: [\n              'css',\n              'xml'\n            ]\n          }\n        },\n        {\n          className: 'tag',\n          // See the comment in the <style tag about the lookahead pattern\n          begin: /<script(?=\\s|>)/,\n          end: />/,\n          keywords: { name: 'script' },\n          contains: [ TAG_INTERNALS ],\n          starts: {\n            end: /<\\/script>/,\n            returnEnd: true,\n            subLanguage: [\n              'javascript',\n              'handlebars',\n              'xml'\n            ]\n          }\n        },\n        // we need this for now for jSX\n        {\n          className: 'tag',\n          begin: /<>|<\\/>/\n        },\n        // open tag\n        {\n          className: 'tag',\n          begin: regex.concat(\n            /</,\n            regex.lookahead(regex.concat(\n              TAG_NAME_RE,\n              // <tag/>\n              // <tag>\n              // <tag ...\n              regex.either(/\\/>/, />/, /\\s/)\n            ))\n          ),\n          end: /\\/?>/,\n          contains: [\n            {\n              className: 'name',\n              begin: TAG_NAME_RE,\n              relevance: 0,\n              starts: TAG_INTERNALS\n            }\n          ]\n        },\n        // close tag\n        {\n          className: 'tag',\n          begin: regex.concat(\n            /<\\//,\n            regex.lookahead(regex.concat(\n              TAG_NAME_RE, />/\n            ))\n          ),\n          contains: [\n            {\n              className: 'name',\n              begin: TAG_NAME_RE,\n              relevance: 0\n            },\n            {\n              begin: />/,\n              relevance: 0,\n              endsParent: true\n            }\n          ]\n        }\n      ]\n    };\n  }\n\n  /*\n  Language: Markdown\n  Requires: xml.js\n  Author: John Crepezzi <john.crepezzi@gmail.com>\n  Website: https://daringfireball.net/projects/markdown/\n  Category: common, markup\n  */\n\n  function markdown(hljs) {\n    const regex = hljs.regex;\n    const INLINE_HTML = {\n      begin: /<\\/?[A-Za-z_]/,\n      end: '>',\n      subLanguage: 'xml',\n      relevance: 0\n    };\n    const HORIZONTAL_RULE = {\n      begin: '^[-\\\\*]{3,}',\n      end: '$'\n    };\n    const CODE = {\n      className: 'code',\n      variants: [\n        // TODO: fix to allow these to work with sublanguage also\n        { begin: '(`{3,})[^`](.|\\\\n)*?\\\\1`*[ ]*' },\n        { begin: '(~{3,})[^~](.|\\\\n)*?\\\\1~*[ ]*' },\n        // needed to allow markdown as a sublanguage to work\n        {\n          begin: '```',\n          end: '```+[ ]*$'\n        },\n        {\n          begin: '~~~',\n          end: '~~~+[ ]*$'\n        },\n        { begin: '`.+?`' },\n        {\n          begin: '(?=^( {4}|\\\\t))',\n          // use contains to gobble up multiple lines to allow the block to be whatever size\n          // but only have a single open/close tag vs one per line\n          contains: [\n            {\n              begin: '^( {4}|\\\\t)',\n              end: '(\\\\n)$'\n            }\n          ],\n          relevance: 0\n        }\n      ]\n    };\n    const LIST = {\n      className: 'bullet',\n      begin: '^[ \\t]*([*+-]|(\\\\d+\\\\.))(?=\\\\s+)',\n      end: '\\\\s+',\n      excludeEnd: true\n    };\n    const LINK_REFERENCE = {\n      begin: /^\\[[^\\n]+\\]:/,\n      returnBegin: true,\n      contains: [\n        {\n          className: 'symbol',\n          begin: /\\[/,\n          end: /\\]/,\n          excludeBegin: true,\n          excludeEnd: true\n        },\n        {\n          className: 'link',\n          begin: /:\\s*/,\n          end: /$/,\n          excludeBegin: true\n        }\n      ]\n    };\n    const URL_SCHEME = /[A-Za-z][A-Za-z0-9+.-]*/;\n    const LINK = {\n      variants: [\n        // too much like nested array access in so many languages\n        // to have any real relevance\n        {\n          begin: /\\[.+?\\]\\[.*?\\]/,\n          relevance: 0\n        },\n        // popular internet URLs\n        {\n          begin: /\\[.+?\\]\\(((data|javascript|mailto):|(?:http|ftp)s?:\\/\\/).*?\\)/,\n          relevance: 2\n        },\n        {\n          begin: regex.concat(/\\[.+?\\]\\(/, URL_SCHEME, /:\\/\\/.*?\\)/),\n          relevance: 2\n        },\n        // relative urls\n        {\n          begin: /\\[.+?\\]\\([./?&#].*?\\)/,\n          relevance: 1\n        },\n        // whatever else, lower relevance (might not be a link at all)\n        {\n          begin: /\\[.*?\\]\\(.*?\\)/,\n          relevance: 0\n        }\n      ],\n      returnBegin: true,\n      contains: [\n        {\n          // empty strings for alt or link text\n          match: /\\[(?=\\])/ },\n        {\n          className: 'string',\n          relevance: 0,\n          begin: '\\\\[',\n          end: '\\\\]',\n          excludeBegin: true,\n          returnEnd: true\n        },\n        {\n          className: 'link',\n          relevance: 0,\n          begin: '\\\\]\\\\(',\n          end: '\\\\)',\n          excludeBegin: true,\n          excludeEnd: true\n        },\n        {\n          className: 'symbol',\n          relevance: 0,\n          begin: '\\\\]\\\\[',\n          end: '\\\\]',\n          excludeBegin: true,\n          excludeEnd: true\n        }\n      ]\n    };\n    const BOLD = {\n      className: 'strong',\n      contains: [], // defined later\n      variants: [\n        {\n          begin: /_{2}(?!\\s)/,\n          end: /_{2}/\n        },\n        {\n          begin: /\\*{2}(?!\\s)/,\n          end: /\\*{2}/\n        }\n      ]\n    };\n    const ITALIC = {\n      className: 'emphasis',\n      contains: [], // defined later\n      variants: [\n        {\n          begin: /\\*(?![*\\s])/,\n          end: /\\*/\n        },\n        {\n          begin: /_(?![_\\s])/,\n          end: /_/,\n          relevance: 0\n        }\n      ]\n    };\n\n    // 3 level deep nesting is not allowed because it would create confusion\n    // in cases like `***testing***` because where we don't know if the last\n    // `***` is starting a new bold/italic or finishing the last one\n    const BOLD_WITHOUT_ITALIC = hljs.inherit(BOLD, { contains: [] });\n    const ITALIC_WITHOUT_BOLD = hljs.inherit(ITALIC, { contains: [] });\n    BOLD.contains.push(ITALIC_WITHOUT_BOLD);\n    ITALIC.contains.push(BOLD_WITHOUT_ITALIC);\n\n    let CONTAINABLE = [\n      INLINE_HTML,\n      LINK\n    ];\n\n    [\n      BOLD,\n      ITALIC,\n      BOLD_WITHOUT_ITALIC,\n      ITALIC_WITHOUT_BOLD\n    ].forEach(m => {\n      m.contains = m.contains.concat(CONTAINABLE);\n    });\n\n    CONTAINABLE = CONTAINABLE.concat(BOLD, ITALIC);\n\n    const HEADER = {\n      className: 'section',\n      variants: [\n        {\n          begin: '^#{1,6}',\n          end: '$',\n          contains: CONTAINABLE\n        },\n        {\n          begin: '(?=^.+?\\\\n[=-]{2,}$)',\n          contains: [\n            { begin: '^[=-]*$' },\n            {\n              begin: '^',\n              end: \"\\\\n\",\n              contains: CONTAINABLE\n            }\n          ]\n        }\n      ]\n    };\n\n    const BLOCKQUOTE = {\n      className: 'quote',\n      begin: '^>\\\\s+',\n      contains: CONTAINABLE,\n      end: '$'\n    };\n\n    const ENTITY = {\n      //https://spec.commonmark.org/0.31.2/#entity-references\n      scope: 'literal',\n      match: /&([a-zA-Z0-9]+|#[0-9]{1,7}|#[Xx][0-9a-fA-F]{1,6});/\n    };\n\n    return {\n      name: 'Markdown',\n      aliases: [\n        'md',\n        'mkdown',\n        'mkd'\n      ],\n      contains: [\n        HEADER,\n        INLINE_HTML,\n        LIST,\n        BOLD,\n        ITALIC,\n        BLOCKQUOTE,\n        CODE,\n        HORIZONTAL_RULE,\n        LINK,\n        LINK_REFERENCE,\n        ENTITY\n      ]\n    };\n  }\n\n  /*\n  Language: Objective-C\n  Author: Valerii Hiora <valerii.hiora@gmail.com>\n  Contributors: Angel G. Olloqui <angelgarcia.mail@gmail.com>, Matt Diephouse <matt@diephouse.com>, Andrew Farmer <ahfarmer@gmail.com>, Minh Nguyễn <mxn@1ec5.org>\n  Website: https://developer.apple.com/documentation/objectivec\n  Category: common\n  */\n\n  function objectivec(hljs) {\n    const API_CLASS = {\n      className: 'built_in',\n      begin: '\\\\b(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)\\\\w+'\n    };\n    const IDENTIFIER_RE = /[a-zA-Z@][a-zA-Z0-9_]*/;\n    const TYPES = [\n      \"int\",\n      \"float\",\n      \"char\",\n      \"unsigned\",\n      \"signed\",\n      \"short\",\n      \"long\",\n      \"double\",\n      \"wchar_t\",\n      \"unichar\",\n      \"void\",\n      \"bool\",\n      \"BOOL\",\n      \"id|0\",\n      \"_Bool\"\n    ];\n    const KWS = [\n      \"while\",\n      \"export\",\n      \"sizeof\",\n      \"typedef\",\n      \"const\",\n      \"struct\",\n      \"for\",\n      \"union\",\n      \"volatile\",\n      \"static\",\n      \"mutable\",\n      \"if\",\n      \"do\",\n      \"return\",\n      \"goto\",\n      \"enum\",\n      \"else\",\n      \"break\",\n      \"extern\",\n      \"asm\",\n      \"case\",\n      \"default\",\n      \"register\",\n      \"explicit\",\n      \"typename\",\n      \"switch\",\n      \"continue\",\n      \"inline\",\n      \"readonly\",\n      \"assign\",\n      \"readwrite\",\n      \"self\",\n      \"@synchronized\",\n      \"id\",\n      \"typeof\",\n      \"nonatomic\",\n      \"IBOutlet\",\n      \"IBAction\",\n      \"strong\",\n      \"weak\",\n      \"copy\",\n      \"in\",\n      \"out\",\n      \"inout\",\n      \"bycopy\",\n      \"byref\",\n      \"oneway\",\n      \"__strong\",\n      \"__weak\",\n      \"__block\",\n      \"__autoreleasing\",\n      \"@private\",\n      \"@protected\",\n      \"@public\",\n      \"@try\",\n      \"@property\",\n      \"@end\",\n      \"@throw\",\n      \"@catch\",\n      \"@finally\",\n      \"@autoreleasepool\",\n      \"@synthesize\",\n      \"@dynamic\",\n      \"@selector\",\n      \"@optional\",\n      \"@required\",\n      \"@encode\",\n      \"@package\",\n      \"@import\",\n      \"@defs\",\n      \"@compatibility_alias\",\n      \"__bridge\",\n      \"__bridge_transfer\",\n      \"__bridge_retained\",\n      \"__bridge_retain\",\n      \"__covariant\",\n      \"__contravariant\",\n      \"__kindof\",\n      \"_Nonnull\",\n      \"_Nullable\",\n      \"_Null_unspecified\",\n      \"__FUNCTION__\",\n      \"__PRETTY_FUNCTION__\",\n      \"__attribute__\",\n      \"getter\",\n      \"setter\",\n      \"retain\",\n      \"unsafe_unretained\",\n      \"nonnull\",\n      \"nullable\",\n      \"null_unspecified\",\n      \"null_resettable\",\n      \"class\",\n      \"instancetype\",\n      \"NS_DESIGNATED_INITIALIZER\",\n      \"NS_UNAVAILABLE\",\n      \"NS_REQUIRES_SUPER\",\n      \"NS_RETURNS_INNER_POINTER\",\n      \"NS_INLINE\",\n      \"NS_AVAILABLE\",\n      \"NS_DEPRECATED\",\n      \"NS_ENUM\",\n      \"NS_OPTIONS\",\n      \"NS_SWIFT_UNAVAILABLE\",\n      \"NS_ASSUME_NONNULL_BEGIN\",\n      \"NS_ASSUME_NONNULL_END\",\n      \"NS_REFINED_FOR_SWIFT\",\n      \"NS_SWIFT_NAME\",\n      \"NS_SWIFT_NOTHROW\",\n      \"NS_DURING\",\n      \"NS_HANDLER\",\n      \"NS_ENDHANDLER\",\n      \"NS_VALUERETURN\",\n      \"NS_VOIDRETURN\"\n    ];\n    const LITERALS = [\n      \"false\",\n      \"true\",\n      \"FALSE\",\n      \"TRUE\",\n      \"nil\",\n      \"YES\",\n      \"NO\",\n      \"NULL\"\n    ];\n    const BUILT_INS = [\n      \"dispatch_once_t\",\n      \"dispatch_queue_t\",\n      \"dispatch_sync\",\n      \"dispatch_async\",\n      \"dispatch_once\"\n    ];\n    const KEYWORDS = {\n      \"variable.language\": [\n        \"this\",\n        \"super\"\n      ],\n      $pattern: IDENTIFIER_RE,\n      keyword: KWS,\n      literal: LITERALS,\n      built_in: BUILT_INS,\n      type: TYPES\n    };\n    const CLASS_KEYWORDS = {\n      $pattern: IDENTIFIER_RE,\n      keyword: [\n        \"@interface\",\n        \"@class\",\n        \"@protocol\",\n        \"@implementation\"\n      ]\n    };\n    return {\n      name: 'Objective-C',\n      aliases: [\n        'mm',\n        'objc',\n        'obj-c',\n        'obj-c++',\n        'objective-c++'\n      ],\n      keywords: KEYWORDS,\n      illegal: '</',\n      contains: [\n        API_CLASS,\n        hljs.C_LINE_COMMENT_MODE,\n        hljs.C_BLOCK_COMMENT_MODE,\n        hljs.C_NUMBER_MODE,\n        hljs.QUOTE_STRING_MODE,\n        hljs.APOS_STRING_MODE,\n        {\n          className: 'string',\n          variants: [\n            {\n              begin: '@\"',\n              end: '\"',\n              illegal: '\\\\n',\n              contains: [ hljs.BACKSLASH_ESCAPE ]\n            }\n          ]\n        },\n        {\n          className: 'meta',\n          begin: /#\\s*[a-z]+\\b/,\n          end: /$/,\n          keywords: { keyword:\n              'if else elif endif define undef warning error line '\n              + 'pragma ifdef ifndef include' },\n          contains: [\n            {\n              begin: /\\\\\\n/,\n              relevance: 0\n            },\n            hljs.inherit(hljs.QUOTE_STRING_MODE, { className: 'string' }),\n            {\n              className: 'string',\n              begin: /<.*?>/,\n              end: /$/,\n              illegal: '\\\\n'\n            },\n            hljs.C_LINE_COMMENT_MODE,\n            hljs.C_BLOCK_COMMENT_MODE\n          ]\n        },\n        {\n          className: 'class',\n          begin: '(' + CLASS_KEYWORDS.keyword.join('|') + ')\\\\b',\n          end: /(\\{|$)/,\n          excludeEnd: true,\n          keywords: CLASS_KEYWORDS,\n          contains: [ hljs.UNDERSCORE_TITLE_MODE ]\n        },\n        {\n          begin: '\\\\.' + hljs.UNDERSCORE_IDENT_RE,\n          relevance: 0\n        }\n      ]\n    };\n  }\n\n  /*\n  Language: Perl\n  Author: Peter Leonov <gojpeg@yandex.ru>\n  Website: https://www.perl.org\n  Category: common\n  */\n\n  /** @type LanguageFn */\n  function perl(hljs) {\n    const regex = hljs.regex;\n    const KEYWORDS = [\n      'abs',\n      'accept',\n      'alarm',\n      'and',\n      'atan2',\n      'bind',\n      'binmode',\n      'bless',\n      'break',\n      'caller',\n      'chdir',\n      'chmod',\n      'chomp',\n      'chop',\n      'chown',\n      'chr',\n      'chroot',\n      'class',\n      'close',\n      'closedir',\n      'connect',\n      'continue',\n      'cos',\n      'crypt',\n      'dbmclose',\n      'dbmopen',\n      'defined',\n      'delete',\n      'die',\n      'do',\n      'dump',\n      'each',\n      'else',\n      'elsif',\n      'endgrent',\n      'endhostent',\n      'endnetent',\n      'endprotoent',\n      'endpwent',\n      'endservent',\n      'eof',\n      'eval',\n      'exec',\n      'exists',\n      'exit',\n      'exp',\n      'fcntl',\n      'field',\n      'fileno',\n      'flock',\n      'for',\n      'foreach',\n      'fork',\n      'format',\n      'formline',\n      'getc',\n      'getgrent',\n      'getgrgid',\n      'getgrnam',\n      'gethostbyaddr',\n      'gethostbyname',\n      'gethostent',\n      'getlogin',\n      'getnetbyaddr',\n      'getnetbyname',\n      'getnetent',\n      'getpeername',\n      'getpgrp',\n      'getpriority',\n      'getprotobyname',\n      'getprotobynumber',\n      'getprotoent',\n      'getpwent',\n      'getpwnam',\n      'getpwuid',\n      'getservbyname',\n      'getservbyport',\n      'getservent',\n      'getsockname',\n      'getsockopt',\n      'given',\n      'glob',\n      'gmtime',\n      'goto',\n      'grep',\n      'gt',\n      'hex',\n      'if',\n      'index',\n      'int',\n      'ioctl',\n      'join',\n      'keys',\n      'kill',\n      'last',\n      'lc',\n      'lcfirst',\n      'length',\n      'link',\n      'listen',\n      'local',\n      'localtime',\n      'log',\n      'lstat',\n      'lt',\n      'ma',\n      'map',\n      'method',\n      'mkdir',\n      'msgctl',\n      'msgget',\n      'msgrcv',\n      'msgsnd',\n      'my',\n      'ne',\n      'next',\n      'no',\n      'not',\n      'oct',\n      'open',\n      'opendir',\n      'or',\n      'ord',\n      'our',\n      'pack',\n      'package',\n      'pipe',\n      'pop',\n      'pos',\n      'print',\n      'printf',\n      'prototype',\n      'push',\n      'q|0',\n      'qq',\n      'quotemeta',\n      'qw',\n      'qx',\n      'rand',\n      'read',\n      'readdir',\n      'readline',\n      'readlink',\n      'readpipe',\n      'recv',\n      'redo',\n      'ref',\n      'rename',\n      'require',\n      'reset',\n      'return',\n      'reverse',\n      'rewinddir',\n      'rindex',\n      'rmdir',\n      'say',\n      'scalar',\n      'seek',\n      'seekdir',\n      'select',\n      'semctl',\n      'semget',\n      'semop',\n      'send',\n      'setgrent',\n      'sethostent',\n      'setnetent',\n      'setpgrp',\n      'setpriority',\n      'setprotoent',\n      'setpwent',\n      'setservent',\n      'setsockopt',\n      'shift',\n      'shmctl',\n      'shmget',\n      'shmread',\n      'shmwrite',\n      'shutdown',\n      'sin',\n      'sleep',\n      'socket',\n      'socketpair',\n      'sort',\n      'splice',\n      'split',\n      'sprintf',\n      'sqrt',\n      'srand',\n      'stat',\n      'state',\n      'study',\n      'sub',\n      'substr',\n      'symlink',\n      'syscall',\n      'sysopen',\n      'sysread',\n      'sysseek',\n      'system',\n      'syswrite',\n      'tell',\n      'telldir',\n      'tie',\n      'tied',\n      'time',\n      'times',\n      'tr',\n      'truncate',\n      'uc',\n      'ucfirst',\n      'umask',\n      'undef',\n      'unless',\n      'unlink',\n      'unpack',\n      'unshift',\n      'untie',\n      'until',\n      'use',\n      'utime',\n      'values',\n      'vec',\n      'wait',\n      'waitpid',\n      'wantarray',\n      'warn',\n      'when',\n      'while',\n      'write',\n      'x|0',\n      'xor',\n      'y|0'\n    ];\n\n    // https://perldoc.perl.org/perlre#Modifiers\n    const REGEX_MODIFIERS = /[dualxmsipngr]{0,12}/; // aa and xx are valid, making max length 12\n    const PERL_KEYWORDS = {\n      $pattern: /[\\w.]+/,\n      keyword: KEYWORDS.join(\" \")\n    };\n    const SUBST = {\n      className: 'subst',\n      begin: '[$@]\\\\{',\n      end: '\\\\}',\n      keywords: PERL_KEYWORDS\n    };\n    const METHOD = {\n      begin: /->\\{/,\n      end: /\\}/\n      // contains defined later\n    };\n    const ATTR = {\n      scope: 'attr',\n      match: /\\s+:\\s*\\w+(\\s*\\(.*?\\))?/,\n    };\n    const VAR = {\n      scope: 'variable',\n      variants: [\n        { begin: /\\$\\d/ },\n        { begin: regex.concat(\n          /[$%@](?!\")(\\^\\w\\b|#\\w+(::\\w+)*|\\{\\w+\\}|\\w+(::\\w*)*)/,\n          // negative look-ahead tries to avoid matching patterns that are not\n          // Perl at all like $ident$, @ident@, etc.\n          `(?![A-Za-z])(?![@$%])`\n          )\n        },\n        {\n          // Only $= is a special Perl variable and one can't declare @= or %=.\n          begin: /[$%@](?!\")[^\\s\\w{=]|\\$=/,\n          relevance: 0\n        }\n      ],\n      contains: [ ATTR ],\n    };\n    const NUMBER = {\n      className: 'number',\n      variants: [\n        // decimal numbers:\n        // include the case where a number starts with a dot (eg. .9), and\n        // the leading 0? avoids mixing the first and second match on 0.x cases\n        { match: /0?\\.[0-9][0-9_]+\\b/ },\n        // include the special versioned number (eg. v5.38)\n        { match: /\\bv?(0|[1-9][0-9_]*(\\.[0-9_]+)?|[1-9][0-9_]*)\\b/ },\n        // non-decimal numbers:\n        { match: /\\b0[0-7][0-7_]*\\b/ },\n        { match: /\\b0x[0-9a-fA-F][0-9a-fA-F_]*\\b/ },\n        { match: /\\b0b[0-1][0-1_]*\\b/ },\n      ],\n      relevance: 0\n    };\n    const STRING_CONTAINS = [\n      hljs.BACKSLASH_ESCAPE,\n      SUBST,\n      VAR\n    ];\n    const REGEX_DELIMS = [\n      /!/,\n      /\\//,\n      /\\|/,\n      /\\?/,\n      /'/,\n      /\"/, // valid but infrequent and weird\n      /#/ // valid but infrequent and weird\n    ];\n    /**\n     * @param {string|RegExp} prefix\n     * @param {string|RegExp} open\n     * @param {string|RegExp} close\n     */\n    const PAIRED_DOUBLE_RE = (prefix, open, close = '\\\\1') => {\n      const middle = (close === '\\\\1')\n        ? close\n        : regex.concat(close, open);\n      return regex.concat(\n        regex.concat(\"(?:\", prefix, \")\"),\n        open,\n        /(?:\\\\.|[^\\\\\\/])*?/,\n        middle,\n        /(?:\\\\.|[^\\\\\\/])*?/,\n        close,\n        REGEX_MODIFIERS\n      );\n    };\n    /**\n     * @param {string|RegExp} prefix\n     * @param {string|RegExp} open\n     * @param {string|RegExp} close\n     */\n    const PAIRED_RE = (prefix, open, close) => {\n      return regex.concat(\n        regex.concat(\"(?:\", prefix, \")\"),\n        open,\n        /(?:\\\\.|[^\\\\\\/])*?/,\n        close,\n        REGEX_MODIFIERS\n      );\n    };\n    const PERL_DEFAULT_CONTAINS = [\n      VAR,\n      hljs.HASH_COMMENT_MODE,\n      hljs.COMMENT(\n        /^=\\w/,\n        /=cut/,\n        { endsWithParent: true }\n      ),\n      METHOD,\n      {\n        className: 'string',\n        contains: STRING_CONTAINS,\n        variants: [\n          {\n            begin: 'q[qwxr]?\\\\s*\\\\(',\n            end: '\\\\)',\n            relevance: 5\n          },\n          {\n            begin: 'q[qwxr]?\\\\s*\\\\[',\n            end: '\\\\]',\n            relevance: 5\n          },\n          {\n            begin: 'q[qwxr]?\\\\s*\\\\{',\n            end: '\\\\}',\n            relevance: 5\n          },\n          {\n            begin: 'q[qwxr]?\\\\s*\\\\|',\n            end: '\\\\|',\n            relevance: 5\n          },\n          {\n            begin: 'q[qwxr]?\\\\s*<',\n            end: '>',\n            relevance: 5\n          },\n          {\n            begin: 'qw\\\\s+q',\n            end: 'q',\n            relevance: 5\n          },\n          {\n            begin: '\\'',\n            end: '\\'',\n            contains: [ hljs.BACKSLASH_ESCAPE ]\n          },\n          {\n            begin: '\"',\n            end: '\"'\n          },\n          {\n            begin: '`',\n            end: '`',\n            contains: [ hljs.BACKSLASH_ESCAPE ]\n          },\n          {\n            begin: /\\{\\w+\\}/,\n            relevance: 0\n          },\n          {\n            begin: '-?\\\\w+\\\\s*=>',\n            relevance: 0\n          }\n        ]\n      },\n      NUMBER,\n      { // regexp container\n        begin: '(\\\\/\\\\/|' + hljs.RE_STARTERS_RE + '|\\\\b(split|return|print|reverse|grep)\\\\b)\\\\s*',\n        keywords: 'split return print reverse grep',\n        relevance: 0,\n        contains: [\n          hljs.HASH_COMMENT_MODE,\n          {\n            className: 'regexp',\n            variants: [\n              // allow matching common delimiters\n              { begin: PAIRED_DOUBLE_RE(\"s|tr|y\", regex.either(...REGEX_DELIMS, { capture: true })) },\n              // and then paired delmis\n              { begin: PAIRED_DOUBLE_RE(\"s|tr|y\", \"\\\\(\", \"\\\\)\") },\n              { begin: PAIRED_DOUBLE_RE(\"s|tr|y\", \"\\\\[\", \"\\\\]\") },\n              { begin: PAIRED_DOUBLE_RE(\"s|tr|y\", \"\\\\{\", \"\\\\}\") }\n            ],\n            relevance: 2\n          },\n          {\n            className: 'regexp',\n            variants: [\n              {\n                // could be a comment in many languages so do not count\n                // as relevant\n                begin: /(m|qr)\\/\\//,\n                relevance: 0\n              },\n              // prefix is optional with /regex/\n              { begin: PAIRED_RE(\"(?:m|qr)?\", /\\//, /\\//) },\n              // allow matching common delimiters\n              { begin: PAIRED_RE(\"m|qr\", regex.either(...REGEX_DELIMS, { capture: true }), /\\1/) },\n              // allow common paired delmins\n              { begin: PAIRED_RE(\"m|qr\", /\\(/, /\\)/) },\n              { begin: PAIRED_RE(\"m|qr\", /\\[/, /\\]/) },\n              { begin: PAIRED_RE(\"m|qr\", /\\{/, /\\}/) }\n            ]\n          }\n        ]\n      },\n      {\n        className: 'function',\n        beginKeywords: 'sub method',\n        end: '(\\\\s*\\\\(.*?\\\\))?[;{]',\n        excludeEnd: true,\n        relevance: 5,\n        contains: [ hljs.TITLE_MODE, ATTR ]\n      },\n      {\n        className: 'class',\n        beginKeywords: 'class',\n        end: '[;{]',\n        excludeEnd: true,\n        relevance: 5,\n        contains: [ hljs.TITLE_MODE, ATTR, NUMBER ]\n      },\n      {\n        begin: '-\\\\w\\\\b',\n        relevance: 0\n      },\n      {\n        begin: \"^__DATA__$\",\n        end: \"^__END__$\",\n        subLanguage: 'mojolicious',\n        contains: [\n          {\n            begin: \"^@@.*\",\n            end: \"$\",\n            className: \"comment\"\n          }\n        ]\n      }\n    ];\n    SUBST.contains = PERL_DEFAULT_CONTAINS;\n    METHOD.contains = PERL_DEFAULT_CONTAINS;\n\n    return {\n      name: 'Perl',\n      aliases: [\n        'pl',\n        'pm'\n      ],\n      keywords: PERL_KEYWORDS,\n      contains: PERL_DEFAULT_CONTAINS\n    };\n  }\n\n  /*\n  Language: PHP\n  Author: Victor Karamzin <Victor.Karamzin@enterra-inc.com>\n  Contributors: Evgeny Stepanischev <imbolk@gmail.com>, Ivan Sagalaev <maniac@softwaremaniacs.org>\n  Website: https://www.php.net\n  Category: common\n  */\n\n  /**\n   * @param {HLJSApi} hljs\n   * @returns {LanguageDetail}\n   * */\n  function php(hljs) {\n    const regex = hljs.regex;\n    // negative look-ahead tries to avoid matching patterns that are not\n    // Perl at all like $ident$, @ident@, etc.\n    const NOT_PERL_ETC = /(?![A-Za-z0-9])(?![$])/;\n    const IDENT_RE = regex.concat(\n      /[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*/,\n      NOT_PERL_ETC);\n    // Will not detect camelCase classes\n    const PASCAL_CASE_CLASS_NAME_RE = regex.concat(\n      /(\\\\?[A-Z][a-z0-9_\\x7f-\\xff]+|\\\\?[A-Z]+(?=[A-Z][a-z0-9_\\x7f-\\xff])){1,}/,\n      NOT_PERL_ETC);\n    const UPCASE_NAME_RE = regex.concat(\n      /[A-Z]+/,\n      NOT_PERL_ETC);\n    const VARIABLE = {\n      scope: 'variable',\n      match: '\\\\$+' + IDENT_RE,\n    };\n    const PREPROCESSOR = {\n      scope: \"meta\",\n      variants: [\n        { begin: /<\\?php/, relevance: 10 }, // boost for obvious PHP\n        { begin: /<\\?=/ },\n        // less relevant per PSR-1 which says not to use short-tags\n        { begin: /<\\?/, relevance: 0.1 },\n        { begin: /\\?>/ } // end php tag\n      ]\n    };\n    const SUBST = {\n      scope: 'subst',\n      variants: [\n        { begin: /\\$\\w+/ },\n        {\n          begin: /\\{\\$/,\n          end: /\\}/\n        }\n      ]\n    };\n    const SINGLE_QUOTED = hljs.inherit(hljs.APOS_STRING_MODE, { illegal: null, });\n    const DOUBLE_QUOTED = hljs.inherit(hljs.QUOTE_STRING_MODE, {\n      illegal: null,\n      contains: hljs.QUOTE_STRING_MODE.contains.concat(SUBST),\n    });\n\n    const HEREDOC = {\n      begin: /<<<[ \\t]*(?:(\\w+)|\"(\\w+)\")\\n/,\n      end: /[ \\t]*(\\w+)\\b/,\n      contains: hljs.QUOTE_STRING_MODE.contains.concat(SUBST),\n      'on:begin': (m, resp) => { resp.data._beginMatch = m[1] || m[2]; },\n      'on:end': (m, resp) => { if (resp.data._beginMatch !== m[1]) resp.ignoreMatch(); },\n    };\n\n    const NOWDOC = hljs.END_SAME_AS_BEGIN({\n      begin: /<<<[ \\t]*'(\\w+)'\\n/,\n      end: /[ \\t]*(\\w+)\\b/,\n    });\n    // list of valid whitespaces because non-breaking space might be part of a IDENT_RE\n    const WHITESPACE = '[ \\t\\n]';\n    const STRING = {\n      scope: 'string',\n      variants: [\n        DOUBLE_QUOTED,\n        SINGLE_QUOTED,\n        HEREDOC,\n        NOWDOC\n      ]\n    };\n    const NUMBER = {\n      scope: 'number',\n      variants: [\n        { begin: `\\\\b0[bB][01]+(?:_[01]+)*\\\\b` }, // Binary w/ underscore support\n        { begin: `\\\\b0[oO][0-7]+(?:_[0-7]+)*\\\\b` }, // Octals w/ underscore support\n        { begin: `\\\\b0[xX][\\\\da-fA-F]+(?:_[\\\\da-fA-F]+)*\\\\b` }, // Hex w/ underscore support\n        // Decimals w/ underscore support, with optional fragments and scientific exponent (e) suffix.\n        { begin: `(?:\\\\b\\\\d+(?:_\\\\d+)*(\\\\.(?:\\\\d+(?:_\\\\d+)*))?|\\\\B\\\\.\\\\d+)(?:[eE][+-]?\\\\d+)?` }\n      ],\n      relevance: 0\n    };\n    const LITERALS = [\n      \"false\",\n      \"null\",\n      \"true\"\n    ];\n    const KWS = [\n      // Magic constants:\n      // <https://www.php.net/manual/en/language.constants.predefined.php>\n      \"__CLASS__\",\n      \"__DIR__\",\n      \"__FILE__\",\n      \"__FUNCTION__\",\n      \"__COMPILER_HALT_OFFSET__\",\n      \"__LINE__\",\n      \"__METHOD__\",\n      \"__NAMESPACE__\",\n      \"__TRAIT__\",\n      // Function that look like language construct or language construct that look like function:\n      // List of keywords that may not require parenthesis\n      \"die\",\n      \"echo\",\n      \"exit\",\n      \"include\",\n      \"include_once\",\n      \"print\",\n      \"require\",\n      \"require_once\",\n      // These are not language construct (function) but operate on the currently-executing function and can access the current symbol table\n      // 'compact extract func_get_arg func_get_args func_num_args get_called_class get_parent_class ' +\n      // Other keywords:\n      // <https://www.php.net/manual/en/reserved.php>\n      // <https://www.php.net/manual/en/language.types.type-juggling.php>\n      \"array\",\n      \"abstract\",\n      \"and\",\n      \"as\",\n      \"binary\",\n      \"bool\",\n      \"boolean\",\n      \"break\",\n      \"callable\",\n      \"case\",\n      \"catch\",\n      \"class\",\n      \"clone\",\n      \"const\",\n      \"continue\",\n      \"declare\",\n      \"default\",\n      \"do\",\n      \"double\",\n      \"else\",\n      \"elseif\",\n      \"empty\",\n      \"enddeclare\",\n      \"endfor\",\n      \"endforeach\",\n      \"endif\",\n      \"endswitch\",\n      \"endwhile\",\n      \"enum\",\n      \"eval\",\n      \"extends\",\n      \"final\",\n      \"finally\",\n      \"float\",\n      \"for\",\n      \"foreach\",\n      \"from\",\n      \"global\",\n      \"goto\",\n      \"if\",\n      \"implements\",\n      \"instanceof\",\n      \"insteadof\",\n      \"int\",\n      \"integer\",\n      \"interface\",\n      \"isset\",\n      \"iterable\",\n      \"list\",\n      \"match|0\",\n      \"mixed\",\n      \"new\",\n      \"never\",\n      \"object\",\n      \"or\",\n      \"private\",\n      \"protected\",\n      \"public\",\n      \"readonly\",\n      \"real\",\n      \"return\",\n      \"string\",\n      \"switch\",\n      \"throw\",\n      \"trait\",\n      \"try\",\n      \"unset\",\n      \"use\",\n      \"var\",\n      \"void\",\n      \"while\",\n      \"xor\",\n      \"yield\"\n    ];\n\n    const BUILT_INS = [\n      // Standard PHP library:\n      // <https://www.php.net/manual/en/book.spl.php>\n      \"Error|0\",\n      \"AppendIterator\",\n      \"ArgumentCountError\",\n      \"ArithmeticError\",\n      \"ArrayIterator\",\n      \"ArrayObject\",\n      \"AssertionError\",\n      \"BadFunctionCallException\",\n      \"BadMethodCallException\",\n      \"CachingIterator\",\n      \"CallbackFilterIterator\",\n      \"CompileError\",\n      \"Countable\",\n      \"DirectoryIterator\",\n      \"DivisionByZeroError\",\n      \"DomainException\",\n      \"EmptyIterator\",\n      \"ErrorException\",\n      \"Exception\",\n      \"FilesystemIterator\",\n      \"FilterIterator\",\n      \"GlobIterator\",\n      \"InfiniteIterator\",\n      \"InvalidArgumentException\",\n      \"IteratorIterator\",\n      \"LengthException\",\n      \"LimitIterator\",\n      \"LogicException\",\n      \"MultipleIterator\",\n      \"NoRewindIterator\",\n      \"OutOfBoundsException\",\n      \"OutOfRangeException\",\n      \"OuterIterator\",\n      \"OverflowException\",\n      \"ParentIterator\",\n      \"ParseError\",\n      \"RangeException\",\n      \"RecursiveArrayIterator\",\n      \"RecursiveCachingIterator\",\n      \"RecursiveCallbackFilterIterator\",\n      \"RecursiveDirectoryIterator\",\n      \"RecursiveFilterIterator\",\n      \"RecursiveIterator\",\n      \"RecursiveIteratorIterator\",\n      \"RecursiveRegexIterator\",\n      \"RecursiveTreeIterator\",\n      \"RegexIterator\",\n      \"RuntimeException\",\n      \"SeekableIterator\",\n      \"SplDoublyLinkedList\",\n      \"SplFileInfo\",\n      \"SplFileObject\",\n      \"SplFixedArray\",\n      \"SplHeap\",\n      \"SplMaxHeap\",\n      \"SplMinHeap\",\n      \"SplObjectStorage\",\n      \"SplObserver\",\n      \"SplPriorityQueue\",\n      \"SplQueue\",\n      \"SplStack\",\n      \"SplSubject\",\n      \"SplTempFileObject\",\n      \"TypeError\",\n      \"UnderflowException\",\n      \"UnexpectedValueException\",\n      \"UnhandledMatchError\",\n      // Reserved interfaces:\n      // <https://www.php.net/manual/en/reserved.interfaces.php>\n      \"ArrayAccess\",\n      \"BackedEnum\",\n      \"Closure\",\n      \"Fiber\",\n      \"Generator\",\n      \"Iterator\",\n      \"IteratorAggregate\",\n      \"Serializable\",\n      \"Stringable\",\n      \"Throwable\",\n      \"Traversable\",\n      \"UnitEnum\",\n      \"WeakReference\",\n      \"WeakMap\",\n      // Reserved classes:\n      // <https://www.php.net/manual/en/reserved.classes.php>\n      \"Directory\",\n      \"__PHP_Incomplete_Class\",\n      \"parent\",\n      \"php_user_filter\",\n      \"self\",\n      \"static\",\n      \"stdClass\"\n    ];\n\n    /** Dual-case keywords\n     *\n     * [\"then\",\"FILE\"] =>\n     *     [\"then\", \"THEN\", \"FILE\", \"file\"]\n     *\n     * @param {string[]} items */\n    const dualCase = (items) => {\n      /** @type string[] */\n      const result = [];\n      items.forEach(item => {\n        result.push(item);\n        if (item.toLowerCase() === item) {\n          result.push(item.toUpperCase());\n        } else {\n          result.push(item.toLowerCase());\n        }\n      });\n      return result;\n    };\n\n    const KEYWORDS = {\n      keyword: KWS,\n      literal: dualCase(LITERALS),\n      built_in: BUILT_INS,\n    };\n\n    /**\n     * @param {string[]} items */\n    const normalizeKeywords = (items) => {\n      return items.map(item => {\n        return item.replace(/\\|\\d+$/, \"\");\n      });\n    };\n\n    const CONSTRUCTOR_CALL = { variants: [\n      {\n        match: [\n          /new/,\n          regex.concat(WHITESPACE, \"+\"),\n          // to prevent built ins from being confused as the class constructor call\n          regex.concat(\"(?!\", normalizeKeywords(BUILT_INS).join(\"\\\\b|\"), \"\\\\b)\"),\n          PASCAL_CASE_CLASS_NAME_RE,\n        ],\n        scope: {\n          1: \"keyword\",\n          4: \"title.class\",\n        },\n      }\n    ] };\n\n    const CONSTANT_REFERENCE = regex.concat(IDENT_RE, \"\\\\b(?!\\\\()\");\n\n    const LEFT_AND_RIGHT_SIDE_OF_DOUBLE_COLON = { variants: [\n      {\n        match: [\n          regex.concat(\n            /::/,\n            regex.lookahead(/(?!class\\b)/)\n          ),\n          CONSTANT_REFERENCE,\n        ],\n        scope: { 2: \"variable.constant\", },\n      },\n      {\n        match: [\n          /::/,\n          /class/,\n        ],\n        scope: { 2: \"variable.language\", },\n      },\n      {\n        match: [\n          PASCAL_CASE_CLASS_NAME_RE,\n          regex.concat(\n            /::/,\n            regex.lookahead(/(?!class\\b)/)\n          ),\n          CONSTANT_REFERENCE,\n        ],\n        scope: {\n          1: \"title.class\",\n          3: \"variable.constant\",\n        },\n      },\n      {\n        match: [\n          PASCAL_CASE_CLASS_NAME_RE,\n          regex.concat(\n            \"::\",\n            regex.lookahead(/(?!class\\b)/)\n          ),\n        ],\n        scope: { 1: \"title.class\", },\n      },\n      {\n        match: [\n          PASCAL_CASE_CLASS_NAME_RE,\n          /::/,\n          /class/,\n        ],\n        scope: {\n          1: \"title.class\",\n          3: \"variable.language\",\n        },\n      }\n    ] };\n\n    const NAMED_ARGUMENT = {\n      scope: 'attr',\n      match: regex.concat(IDENT_RE, regex.lookahead(':'), regex.lookahead(/(?!::)/)),\n    };\n    const PARAMS_MODE = {\n      relevance: 0,\n      begin: /\\(/,\n      end: /\\)/,\n      keywords: KEYWORDS,\n      contains: [\n        NAMED_ARGUMENT,\n        VARIABLE,\n        LEFT_AND_RIGHT_SIDE_OF_DOUBLE_COLON,\n        hljs.C_BLOCK_COMMENT_MODE,\n        hljs.C_LINE_COMMENT_MODE,\n        hljs.HASH_COMMENT_MODE,\n        STRING,\n        NUMBER,\n        CONSTRUCTOR_CALL,\n      ],\n    };\n    const FUNCTION_INVOKE = {\n      relevance: 0,\n      match: [\n        /\\b/,\n        // to prevent keywords from being confused as the function title\n        regex.concat(\"(?!fn\\\\b|function\\\\b|\", normalizeKeywords(KWS).join(\"\\\\b|\"), \"|\", normalizeKeywords(BUILT_INS).join(\"\\\\b|\"), \"\\\\b)\"),\n        IDENT_RE,\n        regex.concat(WHITESPACE, \"*\"),\n        regex.lookahead(/(?=\\()/)\n      ],\n      scope: { 3: \"title.function.invoke\", },\n      contains: [ PARAMS_MODE ]\n    };\n    PARAMS_MODE.contains.push(FUNCTION_INVOKE);\n\n    const ATTRIBUTE_CONTAINS = [\n      NAMED_ARGUMENT,\n      LEFT_AND_RIGHT_SIDE_OF_DOUBLE_COLON,\n      hljs.C_BLOCK_COMMENT_MODE,\n      hljs.C_LINE_COMMENT_MODE,\n      hljs.HASH_COMMENT_MODE,\n      STRING,\n      NUMBER,\n      CONSTRUCTOR_CALL,\n    ];\n\n    const ATTRIBUTES = {\n      begin: regex.concat(/#\\[\\s*\\\\?/,\n        regex.either(\n          PASCAL_CASE_CLASS_NAME_RE,\n          UPCASE_NAME_RE\n        )\n      ),\n      beginScope: \"meta\",\n      end: /]/,\n      endScope: \"meta\",\n      keywords: {\n        literal: LITERALS,\n        keyword: [\n          'new',\n          'array',\n        ]\n      },\n      contains: [\n        {\n          begin: /\\[/,\n          end: /]/,\n          keywords: {\n            literal: LITERALS,\n            keyword: [\n              'new',\n              'array',\n            ]\n          },\n          contains: [\n            'self',\n            ...ATTRIBUTE_CONTAINS,\n          ]\n        },\n        ...ATTRIBUTE_CONTAINS,\n        {\n          scope: 'meta',\n          variants: [\n            { match: PASCAL_CASE_CLASS_NAME_RE },\n            { match: UPCASE_NAME_RE }\n          ]\n        }\n      ]\n    };\n\n    return {\n      case_insensitive: false,\n      keywords: KEYWORDS,\n      contains: [\n        ATTRIBUTES,\n        hljs.HASH_COMMENT_MODE,\n        hljs.COMMENT('//', '$'),\n        hljs.COMMENT(\n          '/\\\\*',\n          '\\\\*/',\n          { contains: [\n            {\n              scope: 'doctag',\n              match: '@[A-Za-z]+'\n            }\n          ] }\n        ),\n        {\n          match: /__halt_compiler\\(\\);/,\n          keywords: '__halt_compiler',\n          starts: {\n            scope: \"comment\",\n            end: hljs.MATCH_NOTHING_RE,\n            contains: [\n              {\n                match: /\\?>/,\n                scope: \"meta\",\n                endsParent: true\n              }\n            ]\n          }\n        },\n        PREPROCESSOR,\n        {\n          scope: 'variable.language',\n          match: /\\$this\\b/\n        },\n        VARIABLE,\n        FUNCTION_INVOKE,\n        LEFT_AND_RIGHT_SIDE_OF_DOUBLE_COLON,\n        {\n          match: [\n            /const/,\n            /\\s/,\n            IDENT_RE,\n          ],\n          scope: {\n            1: \"keyword\",\n            3: \"variable.constant\",\n          },\n        },\n        CONSTRUCTOR_CALL,\n        {\n          scope: 'function',\n          relevance: 0,\n          beginKeywords: 'fn function',\n          end: /[;{]/,\n          excludeEnd: true,\n          illegal: '[$%\\\\[]',\n          contains: [\n            { beginKeywords: 'use', },\n            hljs.UNDERSCORE_TITLE_MODE,\n            {\n              begin: '=>', // No markup, just a relevance booster\n              endsParent: true\n            },\n            {\n              scope: 'params',\n              begin: '\\\\(',\n              end: '\\\\)',\n              excludeBegin: true,\n              excludeEnd: true,\n              keywords: KEYWORDS,\n              contains: [\n                'self',\n                ATTRIBUTES,\n                VARIABLE,\n                LEFT_AND_RIGHT_SIDE_OF_DOUBLE_COLON,\n                hljs.C_BLOCK_COMMENT_MODE,\n                hljs.C_LINE_COMMENT_MODE,\n                hljs.HASH_COMMENT_MODE,\n                STRING,\n                NUMBER\n              ]\n            },\n          ]\n        },\n        {\n          scope: 'class',\n          variants: [\n            {\n              beginKeywords: \"enum\",\n              illegal: /[($\"]/\n            },\n            {\n              beginKeywords: \"class interface trait\",\n              illegal: /[:($\"]/\n            }\n          ],\n          relevance: 0,\n          end: /\\{/,\n          excludeEnd: true,\n          contains: [\n            { beginKeywords: 'extends implements' },\n            hljs.UNDERSCORE_TITLE_MODE\n          ]\n        },\n        // both use and namespace still use \"old style\" rules (vs multi-match)\n        // because the namespace name can include `\\` and we still want each\n        // element to be treated as its own *individual* title\n        {\n          beginKeywords: 'namespace',\n          relevance: 0,\n          end: ';',\n          illegal: /[.']/,\n          contains: [ hljs.inherit(hljs.UNDERSCORE_TITLE_MODE, { scope: \"title.class\" }) ]\n        },\n        {\n          beginKeywords: 'use',\n          relevance: 0,\n          end: ';',\n          contains: [\n            // TODO: title.function vs title.class\n            {\n              match: /\\b(as|const|function)\\b/,\n              scope: \"keyword\"\n            },\n            // TODO: could be title.class or title.function\n            hljs.UNDERSCORE_TITLE_MODE\n          ]\n        },\n        STRING,\n        NUMBER,\n      ]\n    };\n  }\n\n  /*\n  Language: PHP Template\n  Requires: xml.js, php.js\n  Author: Josh Goebel <hello@joshgoebel.com>\n  Website: https://www.php.net\n  Category: common\n  */\n\n  function phpTemplate(hljs) {\n    return {\n      name: \"PHP template\",\n      subLanguage: 'xml',\n      contains: [\n        {\n          begin: /<\\?(php|=)?/,\n          end: /\\?>/,\n          subLanguage: 'php',\n          contains: [\n            // We don't want the php closing tag ?> to close the PHP block when\n            // inside any of the following blocks:\n            {\n              begin: '/\\\\*',\n              end: '\\\\*/',\n              skip: true\n            },\n            {\n              begin: 'b\"',\n              end: '\"',\n              skip: true\n            },\n            {\n              begin: 'b\\'',\n              end: '\\'',\n              skip: true\n            },\n            hljs.inherit(hljs.APOS_STRING_MODE, {\n              illegal: null,\n              className: null,\n              contains: null,\n              skip: true\n            }),\n            hljs.inherit(hljs.QUOTE_STRING_MODE, {\n              illegal: null,\n              className: null,\n              contains: null,\n              skip: true\n            })\n          ]\n        }\n      ]\n    };\n  }\n\n  /*\n  Language: Plain text\n  Author: Egor Rogov (e.rogov@postgrespro.ru)\n  Description: Plain text without any highlighting.\n  Category: common\n  */\n\n  function plaintext(hljs) {\n    return {\n      name: 'Plain text',\n      aliases: [\n        'text',\n        'txt'\n      ],\n      disableAutodetect: true\n    };\n  }\n\n  /*\n  Language: Python\n  Description: Python is an interpreted, object-oriented, high-level programming language with dynamic semantics.\n  Website: https://www.python.org\n  Category: common\n  */\n\n  function python(hljs) {\n    const regex = hljs.regex;\n    const IDENT_RE = /[\\p{XID_Start}_]\\p{XID_Continue}*/u;\n    const RESERVED_WORDS = [\n      'and',\n      'as',\n      'assert',\n      'async',\n      'await',\n      'break',\n      'case',\n      'class',\n      'continue',\n      'def',\n      'del',\n      'elif',\n      'else',\n      'except',\n      'finally',\n      'for',\n      'from',\n      'global',\n      'if',\n      'import',\n      'in',\n      'is',\n      'lambda',\n      'match',\n      'nonlocal|10',\n      'not',\n      'or',\n      'pass',\n      'raise',\n      'return',\n      'try',\n      'while',\n      'with',\n      'yield'\n    ];\n\n    const BUILT_INS = [\n      '__import__',\n      'abs',\n      'all',\n      'any',\n      'ascii',\n      'bin',\n      'bool',\n      'breakpoint',\n      'bytearray',\n      'bytes',\n      'callable',\n      'chr',\n      'classmethod',\n      'compile',\n      'complex',\n      'delattr',\n      'dict',\n      'dir',\n      'divmod',\n      'enumerate',\n      'eval',\n      'exec',\n      'filter',\n      'float',\n      'format',\n      'frozenset',\n      'getattr',\n      'globals',\n      'hasattr',\n      'hash',\n      'help',\n      'hex',\n      'id',\n      'input',\n      'int',\n      'isinstance',\n      'issubclass',\n      'iter',\n      'len',\n      'list',\n      'locals',\n      'map',\n      'max',\n      'memoryview',\n      'min',\n      'next',\n      'object',\n      'oct',\n      'open',\n      'ord',\n      'pow',\n      'print',\n      'property',\n      'range',\n      'repr',\n      'reversed',\n      'round',\n      'set',\n      'setattr',\n      'slice',\n      'sorted',\n      'staticmethod',\n      'str',\n      'sum',\n      'super',\n      'tuple',\n      'type',\n      'vars',\n      'zip'\n    ];\n\n    const LITERALS = [\n      '__debug__',\n      'Ellipsis',\n      'False',\n      'None',\n      'NotImplemented',\n      'True'\n    ];\n\n    // https://docs.python.org/3/library/typing.html\n    // TODO: Could these be supplemented by a CamelCase matcher in certain\n    // contexts, leaving these remaining only for relevance hinting?\n    const TYPES = [\n      \"Any\",\n      \"Callable\",\n      \"Coroutine\",\n      \"Dict\",\n      \"List\",\n      \"Literal\",\n      \"Generic\",\n      \"Optional\",\n      \"Sequence\",\n      \"Set\",\n      \"Tuple\",\n      \"Type\",\n      \"Union\"\n    ];\n\n    const KEYWORDS = {\n      $pattern: /[A-Za-z]\\w+|__\\w+__/,\n      keyword: RESERVED_WORDS,\n      built_in: BUILT_INS,\n      literal: LITERALS,\n      type: TYPES\n    };\n\n    const PROMPT = {\n      className: 'meta',\n      begin: /^(>>>|\\.\\.\\.) /\n    };\n\n    const SUBST = {\n      className: 'subst',\n      begin: /\\{/,\n      end: /\\}/,\n      keywords: KEYWORDS,\n      illegal: /#/\n    };\n\n    const LITERAL_BRACKET = {\n      begin: /\\{\\{/,\n      relevance: 0\n    };\n\n    const STRING = {\n      className: 'string',\n      contains: [ hljs.BACKSLASH_ESCAPE ],\n      variants: [\n        {\n          begin: /([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?'''/,\n          end: /'''/,\n          contains: [\n            hljs.BACKSLASH_ESCAPE,\n            PROMPT\n          ],\n          relevance: 10\n        },\n        {\n          begin: /([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?\"\"\"/,\n          end: /\"\"\"/,\n          contains: [\n            hljs.BACKSLASH_ESCAPE,\n            PROMPT\n          ],\n          relevance: 10\n        },\n        {\n          begin: /([fF][rR]|[rR][fF]|[fF])'''/,\n          end: /'''/,\n          contains: [\n            hljs.BACKSLASH_ESCAPE,\n            PROMPT,\n            LITERAL_BRACKET,\n            SUBST\n          ]\n        },\n        {\n          begin: /([fF][rR]|[rR][fF]|[fF])\"\"\"/,\n          end: /\"\"\"/,\n          contains: [\n            hljs.BACKSLASH_ESCAPE,\n            PROMPT,\n            LITERAL_BRACKET,\n            SUBST\n          ]\n        },\n        {\n          begin: /([uU]|[rR])'/,\n          end: /'/,\n          relevance: 10\n        },\n        {\n          begin: /([uU]|[rR])\"/,\n          end: /\"/,\n          relevance: 10\n        },\n        {\n          begin: /([bB]|[bB][rR]|[rR][bB])'/,\n          end: /'/\n        },\n        {\n          begin: /([bB]|[bB][rR]|[rR][bB])\"/,\n          end: /\"/\n        },\n        {\n          begin: /([fF][rR]|[rR][fF]|[fF])'/,\n          end: /'/,\n          contains: [\n            hljs.BACKSLASH_ESCAPE,\n            LITERAL_BRACKET,\n            SUBST\n          ]\n        },\n        {\n          begin: /([fF][rR]|[rR][fF]|[fF])\"/,\n          end: /\"/,\n          contains: [\n            hljs.BACKSLASH_ESCAPE,\n            LITERAL_BRACKET,\n            SUBST\n          ]\n        },\n        hljs.APOS_STRING_MODE,\n        hljs.QUOTE_STRING_MODE\n      ]\n    };\n\n    // https://docs.python.org/3.9/reference/lexical_analysis.html#numeric-literals\n    const digitpart = '[0-9](_?[0-9])*';\n    const pointfloat = `(\\\\b(${digitpart}))?\\\\.(${digitpart})|\\\\b(${digitpart})\\\\.`;\n    // Whitespace after a number (or any lexical token) is needed only if its absence\n    // would change the tokenization\n    // https://docs.python.org/3.9/reference/lexical_analysis.html#whitespace-between-tokens\n    // We deviate slightly, requiring a word boundary or a keyword\n    // to avoid accidentally recognizing *prefixes* (e.g., `0` in `0x41` or `08` or `0__1`)\n    const lookahead = `\\\\b|${RESERVED_WORDS.join('|')}`;\n    const NUMBER = {\n      className: 'number',\n      relevance: 0,\n      variants: [\n        // exponentfloat, pointfloat\n        // https://docs.python.org/3.9/reference/lexical_analysis.html#floating-point-literals\n        // optionally imaginary\n        // https://docs.python.org/3.9/reference/lexical_analysis.html#imaginary-literals\n        // Note: no leading \\b because floats can start with a decimal point\n        // and we don't want to mishandle e.g. `fn(.5)`,\n        // no trailing \\b for pointfloat because it can end with a decimal point\n        // and we don't want to mishandle e.g. `0..hex()`; this should be safe\n        // because both MUST contain a decimal point and so cannot be confused with\n        // the interior part of an identifier\n        {\n          begin: `(\\\\b(${digitpart})|(${pointfloat}))[eE][+-]?(${digitpart})[jJ]?(?=${lookahead})`\n        },\n        {\n          begin: `(${pointfloat})[jJ]?`\n        },\n\n        // decinteger, bininteger, octinteger, hexinteger\n        // https://docs.python.org/3.9/reference/lexical_analysis.html#integer-literals\n        // optionally \"long\" in Python 2\n        // https://docs.python.org/2.7/reference/lexical_analysis.html#integer-and-long-integer-literals\n        // decinteger is optionally imaginary\n        // https://docs.python.org/3.9/reference/lexical_analysis.html#imaginary-literals\n        {\n          begin: `\\\\b([1-9](_?[0-9])*|0+(_?0)*)[lLjJ]?(?=${lookahead})`\n        },\n        {\n          begin: `\\\\b0[bB](_?[01])+[lL]?(?=${lookahead})`\n        },\n        {\n          begin: `\\\\b0[oO](_?[0-7])+[lL]?(?=${lookahead})`\n        },\n        {\n          begin: `\\\\b0[xX](_?[0-9a-fA-F])+[lL]?(?=${lookahead})`\n        },\n\n        // imagnumber (digitpart-based)\n        // https://docs.python.org/3.9/reference/lexical_analysis.html#imaginary-literals\n        {\n          begin: `\\\\b(${digitpart})[jJ](?=${lookahead})`\n        }\n      ]\n    };\n    const COMMENT_TYPE = {\n      className: \"comment\",\n      begin: regex.lookahead(/# type:/),\n      end: /$/,\n      keywords: KEYWORDS,\n      contains: [\n        { // prevent keywords from coloring `type`\n          begin: /# type:/\n        },\n        // comment within a datatype comment includes no keywords\n        {\n          begin: /#/,\n          end: /\\b\\B/,\n          endsWithParent: true\n        }\n      ]\n    };\n    const PARAMS = {\n      className: 'params',\n      variants: [\n        // Exclude params in functions without params\n        {\n          className: \"\",\n          begin: /\\(\\s*\\)/,\n          skip: true\n        },\n        {\n          begin: /\\(/,\n          end: /\\)/,\n          excludeBegin: true,\n          excludeEnd: true,\n          keywords: KEYWORDS,\n          contains: [\n            'self',\n            PROMPT,\n            NUMBER,\n            STRING,\n            hljs.HASH_COMMENT_MODE\n          ]\n        }\n      ]\n    };\n    SUBST.contains = [\n      STRING,\n      NUMBER,\n      PROMPT\n    ];\n\n    return {\n      name: 'Python',\n      aliases: [\n        'py',\n        'gyp',\n        'ipython'\n      ],\n      unicodeRegex: true,\n      keywords: KEYWORDS,\n      illegal: /(<\\/|\\?)|=>/,\n      contains: [\n        PROMPT,\n        NUMBER,\n        {\n          // very common convention\n          scope: 'variable.language',\n          match: /\\bself\\b/\n        },\n        {\n          // eat \"if\" prior to string so that it won't accidentally be\n          // labeled as an f-string\n          beginKeywords: \"if\",\n          relevance: 0\n        },\n        { match: /\\bor\\b/, scope: \"keyword\" },\n        STRING,\n        COMMENT_TYPE,\n        hljs.HASH_COMMENT_MODE,\n        {\n          match: [\n            /\\bdef/, /\\s+/,\n            IDENT_RE,\n          ],\n          scope: {\n            1: \"keyword\",\n            3: \"title.function\"\n          },\n          contains: [ PARAMS ]\n        },\n        {\n          variants: [\n            {\n              match: [\n                /\\bclass/, /\\s+/,\n                IDENT_RE, /\\s*/,\n                /\\(\\s*/, IDENT_RE,/\\s*\\)/\n              ],\n            },\n            {\n              match: [\n                /\\bclass/, /\\s+/,\n                IDENT_RE\n              ],\n            }\n          ],\n          scope: {\n            1: \"keyword\",\n            3: \"title.class\",\n            6: \"title.class.inherited\",\n          }\n        },\n        {\n          className: 'meta',\n          begin: /^[\\t ]*@/,\n          end: /(?=#)|$/,\n          contains: [\n            NUMBER,\n            PARAMS,\n            STRING\n          ]\n        }\n      ]\n    };\n  }\n\n  /*\n  Language: Python REPL\n  Requires: python.js\n  Author: Josh Goebel <hello@joshgoebel.com>\n  Category: common\n  */\n\n  function pythonRepl(hljs) {\n    return {\n      aliases: [ 'pycon' ],\n      contains: [\n        {\n          className: 'meta.prompt',\n          starts: {\n            // a space separates the REPL prefix from the actual code\n            // this is purely for cleaner HTML output\n            end: / |$/,\n            starts: {\n              end: '$',\n              subLanguage: 'python'\n            }\n          },\n          variants: [\n            { begin: /^>>>(?=[ ]|$)/ },\n            { begin: /^\\.\\.\\.(?=[ ]|$)/ }\n          ]\n        }\n      ]\n    };\n  }\n\n  /*\n  Language: R\n  Description: R is a free software environment for statistical computing and graphics.\n  Author: Joe Cheng <joe@rstudio.org>\n  Contributors: Konrad Rudolph <konrad.rudolph@gmail.com>\n  Website: https://www.r-project.org\n  Category: common,scientific\n  */\n\n  /** @type LanguageFn */\n  function r(hljs) {\n    const regex = hljs.regex;\n    // Identifiers in R cannot start with `_`, but they can start with `.` if it\n    // is not immediately followed by a digit.\n    // R also supports quoted identifiers, which are near-arbitrary sequences\n    // delimited by backticks (`…`), which may contain escape sequences. These are\n    // handled in a separate mode. See `test/markup/r/names.txt` for examples.\n    // FIXME: Support Unicode identifiers.\n    const IDENT_RE = /(?:(?:[a-zA-Z]|\\.[._a-zA-Z])[._a-zA-Z0-9]*)|\\.(?!\\d)/;\n    const NUMBER_TYPES_RE = regex.either(\n      // Special case: only hexadecimal binary powers can contain fractions\n      /0[xX][0-9a-fA-F]+\\.[0-9a-fA-F]*[pP][+-]?\\d+i?/,\n      // Hexadecimal numbers without fraction and optional binary power\n      /0[xX][0-9a-fA-F]+(?:[pP][+-]?\\d+)?[Li]?/,\n      // Decimal numbers\n      /(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+)?[Li]?/\n    );\n    const OPERATORS_RE = /[=!<>:]=|\\|\\||&&|:::?|<-|<<-|->>|->|\\|>|[-+*\\/?!$&|:<=>@^~]|\\*\\*/;\n    const PUNCTUATION_RE = regex.either(\n      /[()]/,\n      /[{}]/,\n      /\\[\\[/,\n      /[[\\]]/,\n      /\\\\/,\n      /,/\n    );\n\n    return {\n      name: 'R',\n\n      keywords: {\n        $pattern: IDENT_RE,\n        keyword:\n          'function if in break next repeat else for while',\n        literal:\n          'NULL NA TRUE FALSE Inf NaN NA_integer_|10 NA_real_|10 '\n          + 'NA_character_|10 NA_complex_|10',\n        built_in:\n          // Builtin constants\n          'LETTERS letters month.abb month.name pi T F '\n          // Primitive functions\n          // These are all the functions in `base` that are implemented as a\n          // `.Primitive`, minus those functions that are also keywords.\n          + 'abs acos acosh all any anyNA Arg as.call as.character '\n          + 'as.complex as.double as.environment as.integer as.logical '\n          + 'as.null.default as.numeric as.raw asin asinh atan atanh attr '\n          + 'attributes baseenv browser c call ceiling class Conj cos cosh '\n          + 'cospi cummax cummin cumprod cumsum digamma dim dimnames '\n          + 'emptyenv exp expression floor forceAndCall gamma gc.time '\n          + 'globalenv Im interactive invisible is.array is.atomic is.call '\n          + 'is.character is.complex is.double is.environment is.expression '\n          + 'is.finite is.function is.infinite is.integer is.language '\n          + 'is.list is.logical is.matrix is.na is.name is.nan is.null '\n          + 'is.numeric is.object is.pairlist is.raw is.recursive is.single '\n          + 'is.symbol lazyLoadDBfetch length lgamma list log max min '\n          + 'missing Mod names nargs nzchar oldClass on.exit pos.to.env '\n          + 'proc.time prod quote range Re rep retracemem return round '\n          + 'seq_along seq_len seq.int sign signif sin sinh sinpi sqrt '\n          + 'standardGeneric substitute sum switch tan tanh tanpi tracemem '\n          + 'trigamma trunc unclass untracemem UseMethod xtfrm',\n      },\n\n      contains: [\n        // Roxygen comments\n        hljs.COMMENT(\n          /#'/,\n          /$/,\n          { contains: [\n            {\n              // Handle `@examples` separately to cause all subsequent code\n              // until the next `@`-tag on its own line to be kept as-is,\n              // preventing highlighting. This code is example R code, so nested\n              // doctags shouldn’t be treated as such. See\n              // `test/markup/r/roxygen.txt` for an example.\n              scope: 'doctag',\n              match: /@examples/,\n              starts: {\n                end: regex.lookahead(regex.either(\n                  // end if another doc comment\n                  /\\n^#'\\s*(?=@[a-zA-Z]+)/,\n                  // or a line with no comment\n                  /\\n^(?!#')/\n                )),\n                endsParent: true\n              }\n            },\n            {\n              // Handle `@param` to highlight the parameter name following\n              // after.\n              scope: 'doctag',\n              begin: '@param',\n              end: /$/,\n              contains: [\n                {\n                  scope: 'variable',\n                  variants: [\n                    { match: IDENT_RE },\n                    { match: /`(?:\\\\.|[^`\\\\])+`/ }\n                  ],\n                  endsParent: true\n                }\n              ]\n            },\n            {\n              scope: 'doctag',\n              match: /@[a-zA-Z]+/\n            },\n            {\n              scope: 'keyword',\n              match: /\\\\[a-zA-Z]+/\n            }\n          ] }\n        ),\n\n        hljs.HASH_COMMENT_MODE,\n\n        {\n          scope: 'string',\n          contains: [ hljs.BACKSLASH_ESCAPE ],\n          variants: [\n            hljs.END_SAME_AS_BEGIN({\n              begin: /[rR]\"(-*)\\(/,\n              end: /\\)(-*)\"/\n            }),\n            hljs.END_SAME_AS_BEGIN({\n              begin: /[rR]\"(-*)\\{/,\n              end: /\\}(-*)\"/\n            }),\n            hljs.END_SAME_AS_BEGIN({\n              begin: /[rR]\"(-*)\\[/,\n              end: /\\](-*)\"/\n            }),\n            hljs.END_SAME_AS_BEGIN({\n              begin: /[rR]'(-*)\\(/,\n              end: /\\)(-*)'/\n            }),\n            hljs.END_SAME_AS_BEGIN({\n              begin: /[rR]'(-*)\\{/,\n              end: /\\}(-*)'/\n            }),\n            hljs.END_SAME_AS_BEGIN({\n              begin: /[rR]'(-*)\\[/,\n              end: /\\](-*)'/\n            }),\n            {\n              begin: '\"',\n              end: '\"',\n              relevance: 0\n            },\n            {\n              begin: \"'\",\n              end: \"'\",\n              relevance: 0\n            }\n          ],\n        },\n\n        // Matching numbers immediately following punctuation and operators is\n        // tricky since we need to look at the character ahead of a number to\n        // ensure the number is not part of an identifier, and we cannot use\n        // negative look-behind assertions. So instead we explicitly handle all\n        // possible combinations of (operator|punctuation), number.\n        // TODO: replace with negative look-behind when available\n        // { begin: /(?<![a-zA-Z0-9._])0[xX][0-9a-fA-F]+\\.[0-9a-fA-F]*[pP][+-]?\\d+i?/ },\n        // { begin: /(?<![a-zA-Z0-9._])0[xX][0-9a-fA-F]+([pP][+-]?\\d+)?[Li]?/ },\n        // { begin: /(?<![a-zA-Z0-9._])(\\d+(\\.\\d*)?|\\.\\d+)([eE][+-]?\\d+)?[Li]?/ }\n        {\n          relevance: 0,\n          variants: [\n            {\n              scope: {\n                1: 'operator',\n                2: 'number'\n              },\n              match: [\n                OPERATORS_RE,\n                NUMBER_TYPES_RE\n              ]\n            },\n            {\n              scope: {\n                1: 'operator',\n                2: 'number'\n              },\n              match: [\n                /%[^%]*%/,\n                NUMBER_TYPES_RE\n              ]\n            },\n            {\n              scope: {\n                1: 'punctuation',\n                2: 'number'\n              },\n              match: [\n                PUNCTUATION_RE,\n                NUMBER_TYPES_RE\n              ]\n            },\n            {\n              scope: { 2: 'number' },\n              match: [\n                /[^a-zA-Z0-9._]|^/, // not part of an identifier, or start of document\n                NUMBER_TYPES_RE\n              ]\n            }\n          ]\n        },\n\n        // Operators/punctuation when they're not directly followed by numbers\n        {\n          // Relevance boost for the most common assignment form.\n          scope: { 3: 'operator' },\n          match: [\n            IDENT_RE,\n            /\\s+/,\n            /<-/,\n            /\\s+/\n          ]\n        },\n\n        {\n          scope: 'operator',\n          relevance: 0,\n          variants: [\n            { match: OPERATORS_RE },\n            { match: /%[^%]*%/ }\n          ]\n        },\n\n        {\n          scope: 'punctuation',\n          relevance: 0,\n          match: PUNCTUATION_RE\n        },\n\n        {\n          // Escaped identifier\n          begin: '`',\n          end: '`',\n          contains: [ { begin: /\\\\./ } ]\n        }\n      ]\n    };\n  }\n\n  /*\n  Language: Ruby\n  Description: Ruby is a dynamic, open source programming language with a focus on simplicity and productivity.\n  Website: https://www.ruby-lang.org/\n  Author: Anton Kovalyov <anton@kovalyov.net>\n  Contributors: Peter Leonov <gojpeg@yandex.ru>, Vasily Polovnyov <vast@whiteants.net>, Loren Segal <lsegal@soen.ca>, Pascal Hurni <phi@ruby-reactive.org>, Cedric Sohrauer <sohrauer@googlemail.com>\n  Category: common, scripting\n  */\n\n  function ruby(hljs) {\n    const regex = hljs.regex;\n    const RUBY_METHOD_RE = '([a-zA-Z_]\\\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\\\*\\\\*|[-/+%^&*~`|]|\\\\[\\\\]=?)';\n    // TODO: move concepts like CAMEL_CASE into `modes.js`\n    const CLASS_NAME_RE = regex.either(\n      /\\b([A-Z]+[a-z0-9]+)+/,\n      // ends in caps\n      /\\b([A-Z]+[a-z0-9]+)+[A-Z]+/,\n    )\n    ;\n    const CLASS_NAME_WITH_NAMESPACE_RE = regex.concat(CLASS_NAME_RE, /(::\\w+)*/);\n    // very popular ruby built-ins that one might even assume\n    // are actual keywords (despite that not being the case)\n    const PSEUDO_KWS = [\n      \"include\",\n      \"extend\",\n      \"prepend\",\n      \"public\",\n      \"private\",\n      \"protected\",\n      \"raise\",\n      \"throw\"\n    ];\n    const RUBY_KEYWORDS = {\n      \"variable.constant\": [\n        \"__FILE__\",\n        \"__LINE__\",\n        \"__ENCODING__\"\n      ],\n      \"variable.language\": [\n        \"self\",\n        \"super\",\n      ],\n      keyword: [\n        \"alias\",\n        \"and\",\n        \"begin\",\n        \"BEGIN\",\n        \"break\",\n        \"case\",\n        \"class\",\n        \"defined\",\n        \"do\",\n        \"else\",\n        \"elsif\",\n        \"end\",\n        \"END\",\n        \"ensure\",\n        \"for\",\n        \"if\",\n        \"in\",\n        \"module\",\n        \"next\",\n        \"not\",\n        \"or\",\n        \"redo\",\n        \"require\",\n        \"rescue\",\n        \"retry\",\n        \"return\",\n        \"then\",\n        \"undef\",\n        \"unless\",\n        \"until\",\n        \"when\",\n        \"while\",\n        \"yield\",\n        ...PSEUDO_KWS\n      ],\n      built_in: [\n        \"proc\",\n        \"lambda\",\n        \"attr_accessor\",\n        \"attr_reader\",\n        \"attr_writer\",\n        \"define_method\",\n        \"private_constant\",\n        \"module_function\"\n      ],\n      literal: [\n        \"true\",\n        \"false\",\n        \"nil\"\n      ]\n    };\n    const YARDOCTAG = {\n      className: 'doctag',\n      begin: '@[A-Za-z]+'\n    };\n    const IRB_OBJECT = {\n      begin: '#<',\n      end: '>'\n    };\n    const COMMENT_MODES = [\n      hljs.COMMENT(\n        '#',\n        '$',\n        { contains: [ YARDOCTAG ] }\n      ),\n      hljs.COMMENT(\n        '^=begin',\n        '^=end',\n        {\n          contains: [ YARDOCTAG ],\n          relevance: 10\n        }\n      ),\n      hljs.COMMENT('^__END__', hljs.MATCH_NOTHING_RE)\n    ];\n    const SUBST = {\n      className: 'subst',\n      begin: /#\\{/,\n      end: /\\}/,\n      keywords: RUBY_KEYWORDS\n    };\n    const STRING = {\n      className: 'string',\n      contains: [\n        hljs.BACKSLASH_ESCAPE,\n        SUBST\n      ],\n      variants: [\n        {\n          begin: /'/,\n          end: /'/\n        },\n        {\n          begin: /\"/,\n          end: /\"/\n        },\n        {\n          begin: /`/,\n          end: /`/\n        },\n        {\n          begin: /%[qQwWx]?\\(/,\n          end: /\\)/\n        },\n        {\n          begin: /%[qQwWx]?\\[/,\n          end: /\\]/\n        },\n        {\n          begin: /%[qQwWx]?\\{/,\n          end: /\\}/\n        },\n        {\n          begin: /%[qQwWx]?</,\n          end: />/\n        },\n        {\n          begin: /%[qQwWx]?\\//,\n          end: /\\//\n        },\n        {\n          begin: /%[qQwWx]?%/,\n          end: /%/\n        },\n        {\n          begin: /%[qQwWx]?-/,\n          end: /-/\n        },\n        {\n          begin: /%[qQwWx]?\\|/,\n          end: /\\|/\n        },\n        // in the following expressions, \\B in the beginning suppresses recognition of ?-sequences\n        // where ? is the last character of a preceding identifier, as in: `func?4`\n        { begin: /\\B\\?(\\\\\\d{1,3})/ },\n        { begin: /\\B\\?(\\\\x[A-Fa-f0-9]{1,2})/ },\n        { begin: /\\B\\?(\\\\u\\{?[A-Fa-f0-9]{1,6}\\}?)/ },\n        { begin: /\\B\\?(\\\\M-\\\\C-|\\\\M-\\\\c|\\\\c\\\\M-|\\\\M-|\\\\C-\\\\M-)[\\x20-\\x7e]/ },\n        { begin: /\\B\\?\\\\(c|C-)[\\x20-\\x7e]/ },\n        { begin: /\\B\\?\\\\?\\S/ },\n        // heredocs\n        {\n          // this guard makes sure that we have an entire heredoc and not a false\n          // positive (auto-detect, etc.)\n          begin: regex.concat(\n            /<<[-~]?'?/,\n            regex.lookahead(/(\\w+)(?=\\W)[^\\n]*\\n(?:[^\\n]*\\n)*?\\s*\\1\\b/)\n          ),\n          contains: [\n            hljs.END_SAME_AS_BEGIN({\n              begin: /(\\w+)/,\n              end: /(\\w+)/,\n              contains: [\n                hljs.BACKSLASH_ESCAPE,\n                SUBST\n              ]\n            })\n          ]\n        }\n      ]\n    };\n\n    // Ruby syntax is underdocumented, but this grammar seems to be accurate\n    // as of version 2.7.2 (confirmed with (irb and `Ripper.sexp(...)`)\n    // https://docs.ruby-lang.org/en/2.7.0/doc/syntax/literals_rdoc.html#label-Numbers\n    const decimal = '[1-9](_?[0-9])*|0';\n    const digits = '[0-9](_?[0-9])*';\n    const NUMBER = {\n      className: 'number',\n      relevance: 0,\n      variants: [\n        // decimal integer/float, optionally exponential or rational, optionally imaginary\n        { begin: `\\\\b(${decimal})(\\\\.(${digits}))?([eE][+-]?(${digits})|r)?i?\\\\b` },\n\n        // explicit decimal/binary/octal/hexadecimal integer,\n        // optionally rational and/or imaginary\n        { begin: \"\\\\b0[dD][0-9](_?[0-9])*r?i?\\\\b\" },\n        { begin: \"\\\\b0[bB][0-1](_?[0-1])*r?i?\\\\b\" },\n        { begin: \"\\\\b0[oO][0-7](_?[0-7])*r?i?\\\\b\" },\n        { begin: \"\\\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*r?i?\\\\b\" },\n\n        // 0-prefixed implicit octal integer, optionally rational and/or imaginary\n        { begin: \"\\\\b0(_?[0-7])+r?i?\\\\b\" }\n      ]\n    };\n\n    const PARAMS = {\n      variants: [\n        {\n          match: /\\(\\)/,\n        },\n        {\n          className: 'params',\n          begin: /\\(/,\n          end: /(?=\\))/,\n          excludeBegin: true,\n          endsParent: true,\n          keywords: RUBY_KEYWORDS,\n        }\n      ]\n    };\n\n    const INCLUDE_EXTEND = {\n      match: [\n        /(include|extend)\\s+/,\n        CLASS_NAME_WITH_NAMESPACE_RE\n      ],\n      scope: {\n        2: \"title.class\"\n      },\n      keywords: RUBY_KEYWORDS\n    };\n\n    const CLASS_DEFINITION = {\n      variants: [\n        {\n          match: [\n            /class\\s+/,\n            CLASS_NAME_WITH_NAMESPACE_RE,\n            /\\s+<\\s+/,\n            CLASS_NAME_WITH_NAMESPACE_RE\n          ]\n        },\n        {\n          match: [\n            /\\b(class|module)\\s+/,\n            CLASS_NAME_WITH_NAMESPACE_RE\n          ]\n        }\n      ],\n      scope: {\n        2: \"title.class\",\n        4: \"title.class.inherited\"\n      },\n      keywords: RUBY_KEYWORDS\n    };\n\n    const UPPER_CASE_CONSTANT = {\n      relevance: 0,\n      match: /\\b[A-Z][A-Z_0-9]+\\b/,\n      className: \"variable.constant\"\n    };\n\n    const METHOD_DEFINITION = {\n      match: [\n        /def/, /\\s+/,\n        RUBY_METHOD_RE\n      ],\n      scope: {\n        1: \"keyword\",\n        3: \"title.function\"\n      },\n      contains: [\n        PARAMS\n      ]\n    };\n\n    const OBJECT_CREATION = {\n      relevance: 0,\n      match: [\n        CLASS_NAME_WITH_NAMESPACE_RE,\n        /\\.new[. (]/\n      ],\n      scope: {\n        1: \"title.class\"\n      }\n    };\n\n    // CamelCase\n    const CLASS_REFERENCE = {\n      relevance: 0,\n      match: CLASS_NAME_RE,\n      scope: \"title.class\"\n    };\n\n    const RUBY_DEFAULT_CONTAINS = [\n      STRING,\n      CLASS_DEFINITION,\n      INCLUDE_EXTEND,\n      OBJECT_CREATION,\n      UPPER_CASE_CONSTANT,\n      CLASS_REFERENCE,\n      METHOD_DEFINITION,\n      {\n        // swallow namespace qualifiers before symbols\n        begin: hljs.IDENT_RE + '::' },\n      {\n        className: 'symbol',\n        begin: hljs.UNDERSCORE_IDENT_RE + '(!|\\\\?)?:',\n        relevance: 0\n      },\n      {\n        className: 'symbol',\n        begin: ':(?!\\\\s)',\n        contains: [\n          STRING,\n          { begin: RUBY_METHOD_RE }\n        ],\n        relevance: 0\n      },\n      NUMBER,\n      {\n        // negative-look forward attempts to prevent false matches like:\n        // @ident@ or $ident$ that might indicate this is not ruby at all\n        className: \"variable\",\n        begin: '(\\\\$\\\\W)|((\\\\$|@@?)(\\\\w+))(?=[^@$?])' + `(?![A-Za-z])(?![@$?'])`\n      },\n      {\n        className: 'params',\n        begin: /\\|(?!=)/,\n        end: /\\|/,\n        excludeBegin: true,\n        excludeEnd: true,\n        relevance: 0, // this could be a lot of things (in other languages) other than params\n        keywords: RUBY_KEYWORDS\n      },\n      { // regexp container\n        begin: '(' + hljs.RE_STARTERS_RE + '|unless)\\\\s*',\n        keywords: 'unless',\n        contains: [\n          {\n            className: 'regexp',\n            contains: [\n              hljs.BACKSLASH_ESCAPE,\n              SUBST\n            ],\n            illegal: /\\n/,\n            variants: [\n              {\n                begin: '/',\n                end: '/[a-z]*'\n              },\n              {\n                begin: /%r\\{/,\n                end: /\\}[a-z]*/\n              },\n              {\n                begin: '%r\\\\(',\n                end: '\\\\)[a-z]*'\n              },\n              {\n                begin: '%r!',\n                end: '![a-z]*'\n              },\n              {\n                begin: '%r\\\\[',\n                end: '\\\\][a-z]*'\n              }\n            ]\n          }\n        ].concat(IRB_OBJECT, COMMENT_MODES),\n        relevance: 0\n      }\n    ].concat(IRB_OBJECT, COMMENT_MODES);\n\n    SUBST.contains = RUBY_DEFAULT_CONTAINS;\n    PARAMS.contains = RUBY_DEFAULT_CONTAINS;\n\n    // >>\n    // ?>\n    const SIMPLE_PROMPT = \"[>?]>\";\n    // irb(main):001:0>\n    const DEFAULT_PROMPT = \"[\\\\w#]+\\\\(\\\\w+\\\\):\\\\d+:\\\\d+[>*]\";\n    const RVM_PROMPT = \"(\\\\w+-)?\\\\d+\\\\.\\\\d+\\\\.\\\\d+(p\\\\d+)?[^\\\\d][^>]+>\";\n\n    const IRB_DEFAULT = [\n      {\n        begin: /^\\s*=>/,\n        starts: {\n          end: '$',\n          contains: RUBY_DEFAULT_CONTAINS\n        }\n      },\n      {\n        className: 'meta.prompt',\n        begin: '^(' + SIMPLE_PROMPT + \"|\" + DEFAULT_PROMPT + '|' + RVM_PROMPT + ')(?=[ ])',\n        starts: {\n          end: '$',\n          keywords: RUBY_KEYWORDS,\n          contains: RUBY_DEFAULT_CONTAINS\n        }\n      }\n    ];\n\n    COMMENT_MODES.unshift(IRB_OBJECT);\n\n    return {\n      name: 'Ruby',\n      aliases: [\n        'rb',\n        'gemspec',\n        'podspec',\n        'thor',\n        'irb'\n      ],\n      keywords: RUBY_KEYWORDS,\n      illegal: /\\/\\*/,\n      contains: [ hljs.SHEBANG({ binary: \"ruby\" }) ]\n        .concat(IRB_DEFAULT)\n        .concat(COMMENT_MODES)\n        .concat(RUBY_DEFAULT_CONTAINS)\n    };\n  }\n\n  /*\n  Language: Rust\n  Author: Andrey Vlasovskikh <andrey.vlasovskikh@gmail.com>\n  Contributors: Roman Shmatov <romanshmatov@gmail.com>, Kasper Andersen <kma_untrusted@protonmail.com>\n  Website: https://www.rust-lang.org\n  Category: common, system\n  */\n\n  /** @type LanguageFn */\n\n  function rust(hljs) {\n    const regex = hljs.regex;\n    // ============================================\n    // Added to support the r# keyword, which is a raw identifier in Rust.\n    const RAW_IDENTIFIER = /(r#)?/;\n    const UNDERSCORE_IDENT_RE = regex.concat(RAW_IDENTIFIER, hljs.UNDERSCORE_IDENT_RE);\n    const IDENT_RE = regex.concat(RAW_IDENTIFIER, hljs.IDENT_RE);\n    // ============================================\n    const FUNCTION_INVOKE = {\n      className: \"title.function.invoke\",\n      relevance: 0,\n      begin: regex.concat(\n        /\\b/,\n        /(?!let|for|while|if|else|match\\b)/,\n        IDENT_RE,\n        regex.lookahead(/\\s*\\(/))\n    };\n    const NUMBER_SUFFIX = '([ui](8|16|32|64|128|size)|f(32|64))\\?';\n    const KEYWORDS = [\n      \"abstract\",\n      \"as\",\n      \"async\",\n      \"await\",\n      \"become\",\n      \"box\",\n      \"break\",\n      \"const\",\n      \"continue\",\n      \"crate\",\n      \"do\",\n      \"dyn\",\n      \"else\",\n      \"enum\",\n      \"extern\",\n      \"false\",\n      \"final\",\n      \"fn\",\n      \"for\",\n      \"if\",\n      \"impl\",\n      \"in\",\n      \"let\",\n      \"loop\",\n      \"macro\",\n      \"match\",\n      \"mod\",\n      \"move\",\n      \"mut\",\n      \"override\",\n      \"priv\",\n      \"pub\",\n      \"ref\",\n      \"return\",\n      \"self\",\n      \"Self\",\n      \"static\",\n      \"struct\",\n      \"super\",\n      \"trait\",\n      \"true\",\n      \"try\",\n      \"type\",\n      \"typeof\",\n      \"union\",\n      \"unsafe\",\n      \"unsized\",\n      \"use\",\n      \"virtual\",\n      \"where\",\n      \"while\",\n      \"yield\"\n    ];\n    const LITERALS = [\n      \"true\",\n      \"false\",\n      \"Some\",\n      \"None\",\n      \"Ok\",\n      \"Err\"\n    ];\n    const BUILTINS = [\n      // functions\n      'drop ',\n      // traits\n      \"Copy\",\n      \"Send\",\n      \"Sized\",\n      \"Sync\",\n      \"Drop\",\n      \"Fn\",\n      \"FnMut\",\n      \"FnOnce\",\n      \"ToOwned\",\n      \"Clone\",\n      \"Debug\",\n      \"PartialEq\",\n      \"PartialOrd\",\n      \"Eq\",\n      \"Ord\",\n      \"AsRef\",\n      \"AsMut\",\n      \"Into\",\n      \"From\",\n      \"Default\",\n      \"Iterator\",\n      \"Extend\",\n      \"IntoIterator\",\n      \"DoubleEndedIterator\",\n      \"ExactSizeIterator\",\n      \"SliceConcatExt\",\n      \"ToString\",\n      // macros\n      \"assert!\",\n      \"assert_eq!\",\n      \"bitflags!\",\n      \"bytes!\",\n      \"cfg!\",\n      \"col!\",\n      \"concat!\",\n      \"concat_idents!\",\n      \"debug_assert!\",\n      \"debug_assert_eq!\",\n      \"env!\",\n      \"eprintln!\",\n      \"panic!\",\n      \"file!\",\n      \"format!\",\n      \"format_args!\",\n      \"include_bytes!\",\n      \"include_str!\",\n      \"line!\",\n      \"local_data_key!\",\n      \"module_path!\",\n      \"option_env!\",\n      \"print!\",\n      \"println!\",\n      \"select!\",\n      \"stringify!\",\n      \"try!\",\n      \"unimplemented!\",\n      \"unreachable!\",\n      \"vec!\",\n      \"write!\",\n      \"writeln!\",\n      \"macro_rules!\",\n      \"assert_ne!\",\n      \"debug_assert_ne!\"\n    ];\n    const TYPES = [\n      \"i8\",\n      \"i16\",\n      \"i32\",\n      \"i64\",\n      \"i128\",\n      \"isize\",\n      \"u8\",\n      \"u16\",\n      \"u32\",\n      \"u64\",\n      \"u128\",\n      \"usize\",\n      \"f32\",\n      \"f64\",\n      \"str\",\n      \"char\",\n      \"bool\",\n      \"Box\",\n      \"Option\",\n      \"Result\",\n      \"String\",\n      \"Vec\"\n    ];\n    return {\n      name: 'Rust',\n      aliases: [ 'rs' ],\n      keywords: {\n        $pattern: hljs.IDENT_RE + '!?',\n        type: TYPES,\n        keyword: KEYWORDS,\n        literal: LITERALS,\n        built_in: BUILTINS\n      },\n      illegal: '</',\n      contains: [\n        hljs.C_LINE_COMMENT_MODE,\n        hljs.COMMENT('/\\\\*', '\\\\*/', { contains: [ 'self' ] }),\n        hljs.inherit(hljs.QUOTE_STRING_MODE, {\n          begin: /b?\"/,\n          illegal: null\n        }),\n        {\n          className: 'symbol',\n          // negative lookahead to avoid matching `'`\n          begin: /'[a-zA-Z_][a-zA-Z0-9_]*(?!')/\n        },\n        {\n          scope: 'string',\n          variants: [\n            { begin: /b?r(#*)\"(.|\\n)*?\"\\1(?!#)/ },\n            {\n              begin: /b?'/,\n              end: /'/,\n              contains: [\n                {\n                  scope: \"char.escape\",\n                  match: /\\\\('|\\w|x\\w{2}|u\\w{4}|U\\w{8})/\n                }\n              ]\n            }\n          ]\n        },\n        {\n          className: 'number',\n          variants: [\n            { begin: '\\\\b0b([01_]+)' + NUMBER_SUFFIX },\n            { begin: '\\\\b0o([0-7_]+)' + NUMBER_SUFFIX },\n            { begin: '\\\\b0x([A-Fa-f0-9_]+)' + NUMBER_SUFFIX },\n            { begin: '\\\\b(\\\\d[\\\\d_]*(\\\\.[0-9_]+)?([eE][+-]?[0-9_]+)?)'\n                     + NUMBER_SUFFIX }\n          ],\n          relevance: 0\n        },\n        {\n          begin: [\n            /fn/,\n            /\\s+/,\n            UNDERSCORE_IDENT_RE\n          ],\n          className: {\n            1: \"keyword\",\n            3: \"title.function\"\n          }\n        },\n        {\n          className: 'meta',\n          begin: '#!?\\\\[',\n          end: '\\\\]',\n          contains: [\n            {\n              className: 'string',\n              begin: /\"/,\n              end: /\"/,\n              contains: [\n                hljs.BACKSLASH_ESCAPE\n              ]\n            }\n          ]\n        },\n        {\n          begin: [\n            /let/,\n            /\\s+/,\n            /(?:mut\\s+)?/,\n            UNDERSCORE_IDENT_RE\n          ],\n          className: {\n            1: \"keyword\",\n            3: \"keyword\",\n            4: \"variable\"\n          }\n        },\n        // must come before impl/for rule later\n        {\n          begin: [\n            /for/,\n            /\\s+/,\n            UNDERSCORE_IDENT_RE,\n            /\\s+/,\n            /in/\n          ],\n          className: {\n            1: \"keyword\",\n            3: \"variable\",\n            5: \"keyword\"\n          }\n        },\n        {\n          begin: [\n            /type/,\n            /\\s+/,\n            UNDERSCORE_IDENT_RE\n          ],\n          className: {\n            1: \"keyword\",\n            3: \"title.class\"\n          }\n        },\n        {\n          begin: [\n            /(?:trait|enum|struct|union|impl|for)/,\n            /\\s+/,\n            UNDERSCORE_IDENT_RE\n          ],\n          className: {\n            1: \"keyword\",\n            3: \"title.class\"\n          }\n        },\n        {\n          begin: hljs.IDENT_RE + '::',\n          keywords: {\n            keyword: \"Self\",\n            built_in: BUILTINS,\n            type: TYPES\n          }\n        },\n        {\n          className: \"punctuation\",\n          begin: '->'\n        },\n        FUNCTION_INVOKE\n      ]\n    };\n  }\n\n  /*\n  Language: SCSS\n  Description: Scss is an extension of the syntax of CSS.\n  Author: Kurt Emch <kurt@kurtemch.com>\n  Website: https://sass-lang.com\n  Category: common, css, web\n  */\n\n\n  /** @type LanguageFn */\n  function scss(hljs) {\n    const modes = MODES(hljs);\n    const PSEUDO_ELEMENTS$1 = PSEUDO_ELEMENTS;\n    const PSEUDO_CLASSES$1 = PSEUDO_CLASSES;\n\n    const AT_IDENTIFIER = '@[a-z-]+'; // @font-face\n    const AT_MODIFIERS = \"and or not only\";\n    const IDENT_RE = '[a-zA-Z-][a-zA-Z0-9_-]*';\n    const VARIABLE = {\n      className: 'variable',\n      begin: '(\\\\$' + IDENT_RE + ')\\\\b',\n      relevance: 0\n    };\n\n    return {\n      name: 'SCSS',\n      case_insensitive: true,\n      illegal: '[=/|\\']',\n      contains: [\n        hljs.C_LINE_COMMENT_MODE,\n        hljs.C_BLOCK_COMMENT_MODE,\n        // to recognize keyframe 40% etc which are outside the scope of our\n        // attribute value mode\n        modes.CSS_NUMBER_MODE,\n        {\n          className: 'selector-id',\n          begin: '#[A-Za-z0-9_-]+',\n          relevance: 0\n        },\n        {\n          className: 'selector-class',\n          begin: '\\\\.[A-Za-z0-9_-]+',\n          relevance: 0\n        },\n        modes.ATTRIBUTE_SELECTOR_MODE,\n        {\n          className: 'selector-tag',\n          begin: '\\\\b(' + TAGS.join('|') + ')\\\\b',\n          // was there, before, but why?\n          relevance: 0\n        },\n        {\n          className: 'selector-pseudo',\n          begin: ':(' + PSEUDO_CLASSES$1.join('|') + ')'\n        },\n        {\n          className: 'selector-pseudo',\n          begin: ':(:)?(' + PSEUDO_ELEMENTS$1.join('|') + ')'\n        },\n        VARIABLE,\n        { // pseudo-selector params\n          begin: /\\(/,\n          end: /\\)/,\n          contains: [ modes.CSS_NUMBER_MODE ]\n        },\n        modes.CSS_VARIABLE,\n        {\n          className: 'attribute',\n          begin: '\\\\b(' + ATTRIBUTES.join('|') + ')\\\\b'\n        },\n        { begin: '\\\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\\\b' },\n        {\n          begin: /:/,\n          end: /[;}{]/,\n          relevance: 0,\n          contains: [\n            modes.BLOCK_COMMENT,\n            VARIABLE,\n            modes.HEXCOLOR,\n            modes.CSS_NUMBER_MODE,\n            modes.UNICODE_RANGE,\n            hljs.QUOTE_STRING_MODE,\n            hljs.APOS_STRING_MODE,\n            modes.IMPORTANT,\n            modes.FUNCTION_DISPATCH\n          ]\n        },\n        // matching these here allows us to treat them more like regular CSS\n        // rules so everything between the {} gets regular rule highlighting,\n        // which is what we want for page and font-face\n        {\n          begin: '@(page|font-face)',\n          keywords: {\n            $pattern: AT_IDENTIFIER,\n            keyword: '@page @font-face'\n          }\n        },\n        {\n          begin: '@',\n          end: '[{;]',\n          returnBegin: true,\n          keywords: {\n            $pattern: /[a-z-]+/,\n            keyword: AT_MODIFIERS,\n            attribute: MEDIA_FEATURES.join(\" \")\n          },\n          contains: [\n            {\n              begin: AT_IDENTIFIER,\n              className: \"keyword\"\n            },\n            {\n              begin: /[a-z-]+(?=:)/,\n              className: \"attribute\"\n            },\n            VARIABLE,\n            hljs.QUOTE_STRING_MODE,\n            hljs.APOS_STRING_MODE,\n            modes.HEXCOLOR,\n            modes.CSS_NUMBER_MODE\n          ]\n        },\n        modes.FUNCTION_DISPATCH\n      ]\n    };\n  }\n\n  /*\n  Language: Shell Session\n  Requires: bash.js\n  Author: TSUYUSATO Kitsune <make.just.on@gmail.com>\n  Category: common\n  Audit: 2020\n  */\n\n  /** @type LanguageFn */\n  function shell(hljs) {\n    return {\n      name: 'Shell Session',\n      aliases: [\n        'console',\n        'shellsession'\n      ],\n      contains: [\n        {\n          className: 'meta.prompt',\n          // We cannot add \\s (spaces) in the regular expression otherwise it will be too broad and produce unexpected result.\n          // For instance, in the following example, it would match \"echo /path/to/home >\" as a prompt:\n          // echo /path/to/home > t.exe\n          begin: /^\\s{0,3}[/~\\w\\d[\\]()@-]*[>%$#][ ]?/,\n          starts: {\n            end: /[^\\\\](?=\\s*$)/,\n            subLanguage: 'bash'\n          }\n        }\n      ]\n    };\n  }\n\n  /*\n   Language: SQL\n   Website: https://en.wikipedia.org/wiki/SQL\n   Category: common, database\n   */\n\n  /*\n\n  Goals:\n\n  SQL is intended to highlight basic/common SQL keywords and expressions\n\n  - If pretty much every single SQL server includes supports, then it's a canidate.\n  - It is NOT intended to include tons of vendor specific keywords (Oracle, MySQL,\n    PostgreSQL) although the list of data types is purposely a bit more expansive.\n  - For more specific SQL grammars please see:\n    - PostgreSQL and PL/pgSQL - core\n    - T-SQL - https://github.com/highlightjs/highlightjs-tsql\n    - sql_more (core)\n\n   */\n\n  function sql(hljs) {\n    const regex = hljs.regex;\n    const COMMENT_MODE = hljs.COMMENT('--', '$');\n    const STRING = {\n      scope: 'string',\n      variants: [\n        {\n          begin: /'/,\n          end: /'/,\n          contains: [ { match: /''/ } ]\n        }\n      ]\n    };\n    const QUOTED_IDENTIFIER = {\n      begin: /\"/,\n      end: /\"/,\n      contains: [ { match: /\"\"/ } ]\n    };\n\n    const LITERALS = [\n      \"true\",\n      \"false\",\n      // Not sure it's correct to call NULL literal, and clauses like IS [NOT] NULL look strange that way.\n      // \"null\",\n      \"unknown\"\n    ];\n\n    const MULTI_WORD_TYPES = [\n      \"double precision\",\n      \"large object\",\n      \"with timezone\",\n      \"without timezone\"\n    ];\n\n    const TYPES = [\n      'bigint',\n      'binary',\n      'blob',\n      'boolean',\n      'char',\n      'character',\n      'clob',\n      'date',\n      'dec',\n      'decfloat',\n      'decimal',\n      'float',\n      'int',\n      'integer',\n      'interval',\n      'nchar',\n      'nclob',\n      'national',\n      'numeric',\n      'real',\n      'row',\n      'smallint',\n      'time',\n      'timestamp',\n      'varchar',\n      'varying', // modifier (character varying)\n      'varbinary'\n    ];\n\n    const NON_RESERVED_WORDS = [\n      \"add\",\n      \"asc\",\n      \"collation\",\n      \"desc\",\n      \"final\",\n      \"first\",\n      \"last\",\n      \"view\"\n    ];\n\n    // https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#reserved-word\n    const RESERVED_WORDS = [\n      \"abs\",\n      \"acos\",\n      \"all\",\n      \"allocate\",\n      \"alter\",\n      \"and\",\n      \"any\",\n      \"are\",\n      \"array\",\n      \"array_agg\",\n      \"array_max_cardinality\",\n      \"as\",\n      \"asensitive\",\n      \"asin\",\n      \"asymmetric\",\n      \"at\",\n      \"atan\",\n      \"atomic\",\n      \"authorization\",\n      \"avg\",\n      \"begin\",\n      \"begin_frame\",\n      \"begin_partition\",\n      \"between\",\n      \"bigint\",\n      \"binary\",\n      \"blob\",\n      \"boolean\",\n      \"both\",\n      \"by\",\n      \"call\",\n      \"called\",\n      \"cardinality\",\n      \"cascaded\",\n      \"case\",\n      \"cast\",\n      \"ceil\",\n      \"ceiling\",\n      \"char\",\n      \"char_length\",\n      \"character\",\n      \"character_length\",\n      \"check\",\n      \"classifier\",\n      \"clob\",\n      \"close\",\n      \"coalesce\",\n      \"collate\",\n      \"collect\",\n      \"column\",\n      \"commit\",\n      \"condition\",\n      \"connect\",\n      \"constraint\",\n      \"contains\",\n      \"convert\",\n      \"copy\",\n      \"corr\",\n      \"corresponding\",\n      \"cos\",\n      \"cosh\",\n      \"count\",\n      \"covar_pop\",\n      \"covar_samp\",\n      \"create\",\n      \"cross\",\n      \"cube\",\n      \"cume_dist\",\n      \"current\",\n      \"current_catalog\",\n      \"current_date\",\n      \"current_default_transform_group\",\n      \"current_path\",\n      \"current_role\",\n      \"current_row\",\n      \"current_schema\",\n      \"current_time\",\n      \"current_timestamp\",\n      \"current_path\",\n      \"current_role\",\n      \"current_transform_group_for_type\",\n      \"current_user\",\n      \"cursor\",\n      \"cycle\",\n      \"date\",\n      \"day\",\n      \"deallocate\",\n      \"dec\",\n      \"decimal\",\n      \"decfloat\",\n      \"declare\",\n      \"default\",\n      \"define\",\n      \"delete\",\n      \"dense_rank\",\n      \"deref\",\n      \"describe\",\n      \"deterministic\",\n      \"disconnect\",\n      \"distinct\",\n      \"double\",\n      \"drop\",\n      \"dynamic\",\n      \"each\",\n      \"element\",\n      \"else\",\n      \"empty\",\n      \"end\",\n      \"end_frame\",\n      \"end_partition\",\n      \"end-exec\",\n      \"equals\",\n      \"escape\",\n      \"every\",\n      \"except\",\n      \"exec\",\n      \"execute\",\n      \"exists\",\n      \"exp\",\n      \"external\",\n      \"extract\",\n      \"false\",\n      \"fetch\",\n      \"filter\",\n      \"first_value\",\n      \"float\",\n      \"floor\",\n      \"for\",\n      \"foreign\",\n      \"frame_row\",\n      \"free\",\n      \"from\",\n      \"full\",\n      \"function\",\n      \"fusion\",\n      \"get\",\n      \"global\",\n      \"grant\",\n      \"group\",\n      \"grouping\",\n      \"groups\",\n      \"having\",\n      \"hold\",\n      \"hour\",\n      \"identity\",\n      \"in\",\n      \"indicator\",\n      \"initial\",\n      \"inner\",\n      \"inout\",\n      \"insensitive\",\n      \"insert\",\n      \"int\",\n      \"integer\",\n      \"intersect\",\n      \"intersection\",\n      \"interval\",\n      \"into\",\n      \"is\",\n      \"join\",\n      \"json_array\",\n      \"json_arrayagg\",\n      \"json_exists\",\n      \"json_object\",\n      \"json_objectagg\",\n      \"json_query\",\n      \"json_table\",\n      \"json_table_primitive\",\n      \"json_value\",\n      \"lag\",\n      \"language\",\n      \"large\",\n      \"last_value\",\n      \"lateral\",\n      \"lead\",\n      \"leading\",\n      \"left\",\n      \"like\",\n      \"like_regex\",\n      \"listagg\",\n      \"ln\",\n      \"local\",\n      \"localtime\",\n      \"localtimestamp\",\n      \"log\",\n      \"log10\",\n      \"lower\",\n      \"match\",\n      \"match_number\",\n      \"match_recognize\",\n      \"matches\",\n      \"max\",\n      \"member\",\n      \"merge\",\n      \"method\",\n      \"min\",\n      \"minute\",\n      \"mod\",\n      \"modifies\",\n      \"module\",\n      \"month\",\n      \"multiset\",\n      \"national\",\n      \"natural\",\n      \"nchar\",\n      \"nclob\",\n      \"new\",\n      \"no\",\n      \"none\",\n      \"normalize\",\n      \"not\",\n      \"nth_value\",\n      \"ntile\",\n      \"null\",\n      \"nullif\",\n      \"numeric\",\n      \"octet_length\",\n      \"occurrences_regex\",\n      \"of\",\n      \"offset\",\n      \"old\",\n      \"omit\",\n      \"on\",\n      \"one\",\n      \"only\",\n      \"open\",\n      \"or\",\n      \"order\",\n      \"out\",\n      \"outer\",\n      \"over\",\n      \"overlaps\",\n      \"overlay\",\n      \"parameter\",\n      \"partition\",\n      \"pattern\",\n      \"per\",\n      \"percent\",\n      \"percent_rank\",\n      \"percentile_cont\",\n      \"percentile_disc\",\n      \"period\",\n      \"portion\",\n      \"position\",\n      \"position_regex\",\n      \"power\",\n      \"precedes\",\n      \"precision\",\n      \"prepare\",\n      \"primary\",\n      \"procedure\",\n      \"ptf\",\n      \"range\",\n      \"rank\",\n      \"reads\",\n      \"real\",\n      \"recursive\",\n      \"ref\",\n      \"references\",\n      \"referencing\",\n      \"regr_avgx\",\n      \"regr_avgy\",\n      \"regr_count\",\n      \"regr_intercept\",\n      \"regr_r2\",\n      \"regr_slope\",\n      \"regr_sxx\",\n      \"regr_sxy\",\n      \"regr_syy\",\n      \"release\",\n      \"result\",\n      \"return\",\n      \"returns\",\n      \"revoke\",\n      \"right\",\n      \"rollback\",\n      \"rollup\",\n      \"row\",\n      \"row_number\",\n      \"rows\",\n      \"running\",\n      \"savepoint\",\n      \"scope\",\n      \"scroll\",\n      \"search\",\n      \"second\",\n      \"seek\",\n      \"select\",\n      \"sensitive\",\n      \"session_user\",\n      \"set\",\n      \"show\",\n      \"similar\",\n      \"sin\",\n      \"sinh\",\n      \"skip\",\n      \"smallint\",\n      \"some\",\n      \"specific\",\n      \"specifictype\",\n      \"sql\",\n      \"sqlexception\",\n      \"sqlstate\",\n      \"sqlwarning\",\n      \"sqrt\",\n      \"start\",\n      \"static\",\n      \"stddev_pop\",\n      \"stddev_samp\",\n      \"submultiset\",\n      \"subset\",\n      \"substring\",\n      \"substring_regex\",\n      \"succeeds\",\n      \"sum\",\n      \"symmetric\",\n      \"system\",\n      \"system_time\",\n      \"system_user\",\n      \"table\",\n      \"tablesample\",\n      \"tan\",\n      \"tanh\",\n      \"then\",\n      \"time\",\n      \"timestamp\",\n      \"timezone_hour\",\n      \"timezone_minute\",\n      \"to\",\n      \"trailing\",\n      \"translate\",\n      \"translate_regex\",\n      \"translation\",\n      \"treat\",\n      \"trigger\",\n      \"trim\",\n      \"trim_array\",\n      \"true\",\n      \"truncate\",\n      \"uescape\",\n      \"union\",\n      \"unique\",\n      \"unknown\",\n      \"unnest\",\n      \"update\",\n      \"upper\",\n      \"user\",\n      \"using\",\n      \"value\",\n      \"values\",\n      \"value_of\",\n      \"var_pop\",\n      \"var_samp\",\n      \"varbinary\",\n      \"varchar\",\n      \"varying\",\n      \"versioning\",\n      \"when\",\n      \"whenever\",\n      \"where\",\n      \"width_bucket\",\n      \"window\",\n      \"with\",\n      \"within\",\n      \"without\",\n      \"year\",\n    ];\n\n    // these are reserved words we have identified to be functions\n    // and should only be highlighted in a dispatch-like context\n    // ie, array_agg(...), etc.\n    const RESERVED_FUNCTIONS = [\n      \"abs\",\n      \"acos\",\n      \"array_agg\",\n      \"asin\",\n      \"atan\",\n      \"avg\",\n      \"cast\",\n      \"ceil\",\n      \"ceiling\",\n      \"coalesce\",\n      \"corr\",\n      \"cos\",\n      \"cosh\",\n      \"count\",\n      \"covar_pop\",\n      \"covar_samp\",\n      \"cume_dist\",\n      \"dense_rank\",\n      \"deref\",\n      \"element\",\n      \"exp\",\n      \"extract\",\n      \"first_value\",\n      \"floor\",\n      \"json_array\",\n      \"json_arrayagg\",\n      \"json_exists\",\n      \"json_object\",\n      \"json_objectagg\",\n      \"json_query\",\n      \"json_table\",\n      \"json_table_primitive\",\n      \"json_value\",\n      \"lag\",\n      \"last_value\",\n      \"lead\",\n      \"listagg\",\n      \"ln\",\n      \"log\",\n      \"log10\",\n      \"lower\",\n      \"max\",\n      \"min\",\n      \"mod\",\n      \"nth_value\",\n      \"ntile\",\n      \"nullif\",\n      \"percent_rank\",\n      \"percentile_cont\",\n      \"percentile_disc\",\n      \"position\",\n      \"position_regex\",\n      \"power\",\n      \"rank\",\n      \"regr_avgx\",\n      \"regr_avgy\",\n      \"regr_count\",\n      \"regr_intercept\",\n      \"regr_r2\",\n      \"regr_slope\",\n      \"regr_sxx\",\n      \"regr_sxy\",\n      \"regr_syy\",\n      \"row_number\",\n      \"sin\",\n      \"sinh\",\n      \"sqrt\",\n      \"stddev_pop\",\n      \"stddev_samp\",\n      \"substring\",\n      \"substring_regex\",\n      \"sum\",\n      \"tan\",\n      \"tanh\",\n      \"translate\",\n      \"translate_regex\",\n      \"treat\",\n      \"trim\",\n      \"trim_array\",\n      \"unnest\",\n      \"upper\",\n      \"value_of\",\n      \"var_pop\",\n      \"var_samp\",\n      \"width_bucket\",\n    ];\n\n    // these functions can\n    const POSSIBLE_WITHOUT_PARENS = [\n      \"current_catalog\",\n      \"current_date\",\n      \"current_default_transform_group\",\n      \"current_path\",\n      \"current_role\",\n      \"current_schema\",\n      \"current_transform_group_for_type\",\n      \"current_user\",\n      \"session_user\",\n      \"system_time\",\n      \"system_user\",\n      \"current_time\",\n      \"localtime\",\n      \"current_timestamp\",\n      \"localtimestamp\"\n    ];\n\n    // those exist to boost relevance making these very\n    // \"SQL like\" keyword combos worth +1 extra relevance\n    const COMBOS = [\n      \"create table\",\n      \"insert into\",\n      \"primary key\",\n      \"foreign key\",\n      \"not null\",\n      \"alter table\",\n      \"add constraint\",\n      \"grouping sets\",\n      \"on overflow\",\n      \"character set\",\n      \"respect nulls\",\n      \"ignore nulls\",\n      \"nulls first\",\n      \"nulls last\",\n      \"depth first\",\n      \"breadth first\"\n    ];\n\n    const FUNCTIONS = RESERVED_FUNCTIONS;\n\n    const KEYWORDS = [\n      ...RESERVED_WORDS,\n      ...NON_RESERVED_WORDS\n    ].filter((keyword) => {\n      return !RESERVED_FUNCTIONS.includes(keyword);\n    });\n\n    const VARIABLE = {\n      scope: \"variable\",\n      match: /@[a-z0-9][a-z0-9_]*/,\n    };\n\n    const OPERATOR = {\n      scope: \"operator\",\n      match: /[-+*/=%^~]|&&?|\\|\\|?|!=?|<(?:=>?|<|>)?|>[>=]?/,\n      relevance: 0,\n    };\n\n    const FUNCTION_CALL = {\n      match: regex.concat(/\\b/, regex.either(...FUNCTIONS), /\\s*\\(/),\n      relevance: 0,\n      keywords: { built_in: FUNCTIONS }\n    };\n\n    // turns a multi-word keyword combo into a regex that doesn't\n    // care about extra whitespace etc.\n    // input: \"START QUERY\"\n    // output: /\\bSTART\\s+QUERY\\b/\n    function kws_to_regex(list) {\n      return regex.concat(\n        /\\b/,\n        regex.either(...list.map((kw) => {\n          return kw.replace(/\\s+/, \"\\\\s+\")\n        })),\n        /\\b/\n      )\n    }\n\n    const MULTI_WORD_KEYWORDS = {\n      scope: \"keyword\",\n      match: kws_to_regex(COMBOS),\n      relevance: 0,\n    };\n\n    // keywords with less than 3 letters are reduced in relevancy\n    function reduceRelevancy(list, {\n      exceptions, when\n    } = {}) {\n      const qualifyFn = when;\n      exceptions = exceptions || [];\n      return list.map((item) => {\n        if (item.match(/\\|\\d+$/) || exceptions.includes(item)) {\n          return item;\n        } else if (qualifyFn(item)) {\n          return `${item}|0`;\n        } else {\n          return item;\n        }\n      });\n    }\n\n    return {\n      name: 'SQL',\n      case_insensitive: true,\n      // does not include {} or HTML tags `</`\n      illegal: /[{}]|<\\//,\n      keywords: {\n        $pattern: /\\b[\\w\\.]+/,\n        keyword:\n          reduceRelevancy(KEYWORDS, { when: (x) => x.length < 3 }),\n        literal: LITERALS,\n        type: TYPES,\n        built_in: POSSIBLE_WITHOUT_PARENS\n      },\n      contains: [\n        {\n          scope: \"type\",\n          match: kws_to_regex(MULTI_WORD_TYPES)\n        },\n        MULTI_WORD_KEYWORDS,\n        FUNCTION_CALL,\n        VARIABLE,\n        STRING,\n        QUOTED_IDENTIFIER,\n        hljs.C_NUMBER_MODE,\n        hljs.C_BLOCK_COMMENT_MODE,\n        COMMENT_MODE,\n        OPERATOR\n      ]\n    };\n  }\n\n  const keywordWrapper = keyword => concat(\n    /\\b/,\n    keyword,\n    /\\w$/.test(keyword) ? /\\b/ : /\\B/\n  );\n\n  // Keywords that require a leading dot.\n  const dotKeywords = [\n    'Protocol', // contextual\n    'Type' // contextual\n  ].map(keywordWrapper);\n\n  // Keywords that may have a leading dot.\n  const optionalDotKeywords = [\n    'init',\n    'self'\n  ].map(keywordWrapper);\n\n  // should register as keyword, not type\n  const keywordTypes = [\n    'Any',\n    'Self'\n  ];\n\n  // Regular keywords and literals.\n  const keywords = [\n    // strings below will be fed into the regular `keywords` engine while regex\n    // will result in additional modes being created to scan for those keywords to\n    // avoid conflicts with other rules\n    'actor',\n    'any', // contextual\n    'associatedtype',\n    'async',\n    'await',\n    /as\\?/, // operator\n    /as!/, // operator\n    'as', // operator\n    'borrowing', // contextual\n    'break',\n    'case',\n    'catch',\n    'class',\n    'consume', // contextual\n    'consuming', // contextual\n    'continue',\n    'convenience', // contextual\n    'copy', // contextual\n    'default',\n    'defer',\n    'deinit',\n    'didSet', // contextual\n    'distributed',\n    'do',\n    'dynamic', // contextual\n    'each',\n    'else',\n    'enum',\n    'extension',\n    'fallthrough',\n    /fileprivate\\(set\\)/,\n    'fileprivate',\n    'final', // contextual\n    'for',\n    'func',\n    'get', // contextual\n    'guard',\n    'if',\n    'import',\n    'indirect', // contextual\n    'infix', // contextual\n    /init\\?/,\n    /init!/,\n    'inout',\n    /internal\\(set\\)/,\n    'internal',\n    'in',\n    'is', // operator\n    'isolated', // contextual\n    'nonisolated', // contextual\n    'lazy', // contextual\n    'let',\n    'macro',\n    'mutating', // contextual\n    'nonmutating', // contextual\n    /open\\(set\\)/, // contextual\n    'open', // contextual\n    'operator',\n    'optional', // contextual\n    'override', // contextual\n    'package',\n    'postfix', // contextual\n    'precedencegroup',\n    'prefix', // contextual\n    /private\\(set\\)/,\n    'private',\n    'protocol',\n    /public\\(set\\)/,\n    'public',\n    'repeat',\n    'required', // contextual\n    'rethrows',\n    'return',\n    'set', // contextual\n    'some', // contextual\n    'static',\n    'struct',\n    'subscript',\n    'super',\n    'switch',\n    'throws',\n    'throw',\n    /try\\?/, // operator\n    /try!/, // operator\n    'try', // operator\n    'typealias',\n    /unowned\\(safe\\)/, // contextual\n    /unowned\\(unsafe\\)/, // contextual\n    'unowned', // contextual\n    'var',\n    'weak', // contextual\n    'where',\n    'while',\n    'willSet' // contextual\n  ];\n\n  // NOTE: Contextual keywords are reserved only in specific contexts.\n  // Ideally, these should be matched using modes to avoid false positives.\n\n  // Literals.\n  const literals = [\n    'false',\n    'nil',\n    'true'\n  ];\n\n  // Keywords used in precedence groups.\n  const precedencegroupKeywords = [\n    'assignment',\n    'associativity',\n    'higherThan',\n    'left',\n    'lowerThan',\n    'none',\n    'right'\n  ];\n\n  // Keywords that start with a number sign (#).\n  // #(un)available is handled separately.\n  const numberSignKeywords = [\n    '#colorLiteral',\n    '#column',\n    '#dsohandle',\n    '#else',\n    '#elseif',\n    '#endif',\n    '#error',\n    '#file',\n    '#fileID',\n    '#fileLiteral',\n    '#filePath',\n    '#function',\n    '#if',\n    '#imageLiteral',\n    '#keyPath',\n    '#line',\n    '#selector',\n    '#sourceLocation',\n    '#warning'\n  ];\n\n  // Global functions in the Standard Library.\n  const builtIns$1 = [\n    'abs',\n    'all',\n    'any',\n    'assert',\n    'assertionFailure',\n    'debugPrint',\n    'dump',\n    'fatalError',\n    'getVaList',\n    'isKnownUniquelyReferenced',\n    'max',\n    'min',\n    'numericCast',\n    'pointwiseMax',\n    'pointwiseMin',\n    'precondition',\n    'preconditionFailure',\n    'print',\n    'readLine',\n    'repeatElement',\n    'sequence',\n    'stride',\n    'swap',\n    'swift_unboxFromSwiftValueWithType',\n    'transcode',\n    'type',\n    'unsafeBitCast',\n    'unsafeDowncast',\n    'withExtendedLifetime',\n    'withUnsafeMutablePointer',\n    'withUnsafePointer',\n    'withVaList',\n    'withoutActuallyEscaping',\n    'zip'\n  ];\n\n  // Valid first characters for operators.\n  const operatorHead = either(\n    /[/=\\-+!*%<>&|^~?]/,\n    /[\\u00A1-\\u00A7]/,\n    /[\\u00A9\\u00AB]/,\n    /[\\u00AC\\u00AE]/,\n    /[\\u00B0\\u00B1]/,\n    /[\\u00B6\\u00BB\\u00BF\\u00D7\\u00F7]/,\n    /[\\u2016-\\u2017]/,\n    /[\\u2020-\\u2027]/,\n    /[\\u2030-\\u203E]/,\n    /[\\u2041-\\u2053]/,\n    /[\\u2055-\\u205E]/,\n    /[\\u2190-\\u23FF]/,\n    /[\\u2500-\\u2775]/,\n    /[\\u2794-\\u2BFF]/,\n    /[\\u2E00-\\u2E7F]/,\n    /[\\u3001-\\u3003]/,\n    /[\\u3008-\\u3020]/,\n    /[\\u3030]/\n  );\n\n  // Valid characters for operators.\n  const operatorCharacter = either(\n    operatorHead,\n    /[\\u0300-\\u036F]/,\n    /[\\u1DC0-\\u1DFF]/,\n    /[\\u20D0-\\u20FF]/,\n    /[\\uFE00-\\uFE0F]/,\n    /[\\uFE20-\\uFE2F]/\n    // TODO: The following characters are also allowed, but the regex isn't supported yet.\n    // /[\\u{E0100}-\\u{E01EF}]/u\n  );\n\n  // Valid operator.\n  const operator = concat(operatorHead, operatorCharacter, '*');\n\n  // Valid first characters for identifiers.\n  const identifierHead = either(\n    /[a-zA-Z_]/,\n    /[\\u00A8\\u00AA\\u00AD\\u00AF\\u00B2-\\u00B5\\u00B7-\\u00BA]/,\n    /[\\u00BC-\\u00BE\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u00FF]/,\n    /[\\u0100-\\u02FF\\u0370-\\u167F\\u1681-\\u180D\\u180F-\\u1DBF]/,\n    /[\\u1E00-\\u1FFF]/,\n    /[\\u200B-\\u200D\\u202A-\\u202E\\u203F-\\u2040\\u2054\\u2060-\\u206F]/,\n    /[\\u2070-\\u20CF\\u2100-\\u218F\\u2460-\\u24FF\\u2776-\\u2793]/,\n    /[\\u2C00-\\u2DFF\\u2E80-\\u2FFF]/,\n    /[\\u3004-\\u3007\\u3021-\\u302F\\u3031-\\u303F\\u3040-\\uD7FF]/,\n    /[\\uF900-\\uFD3D\\uFD40-\\uFDCF\\uFDF0-\\uFE1F\\uFE30-\\uFE44]/,\n    /[\\uFE47-\\uFEFE\\uFF00-\\uFFFD]/ // Should be /[\\uFE47-\\uFFFD]/, but we have to exclude FEFF.\n    // The following characters are also allowed, but the regexes aren't supported yet.\n    // /[\\u{10000}-\\u{1FFFD}\\u{20000-\\u{2FFFD}\\u{30000}-\\u{3FFFD}\\u{40000}-\\u{4FFFD}]/u,\n    // /[\\u{50000}-\\u{5FFFD}\\u{60000-\\u{6FFFD}\\u{70000}-\\u{7FFFD}\\u{80000}-\\u{8FFFD}]/u,\n    // /[\\u{90000}-\\u{9FFFD}\\u{A0000-\\u{AFFFD}\\u{B0000}-\\u{BFFFD}\\u{C0000}-\\u{CFFFD}]/u,\n    // /[\\u{D0000}-\\u{DFFFD}\\u{E0000-\\u{EFFFD}]/u\n  );\n\n  // Valid characters for identifiers.\n  const identifierCharacter = either(\n    identifierHead,\n    /\\d/,\n    /[\\u0300-\\u036F\\u1DC0-\\u1DFF\\u20D0-\\u20FF\\uFE20-\\uFE2F]/\n  );\n\n  // Valid identifier.\n  const identifier = concat(identifierHead, identifierCharacter, '*');\n\n  // Valid type identifier.\n  const typeIdentifier = concat(/[A-Z]/, identifierCharacter, '*');\n\n  // Built-in attributes, which are highlighted as keywords.\n  // @available is handled separately.\n  // https://docs.swift.org/swift-book/documentation/the-swift-programming-language/attributes\n  const keywordAttributes = [\n    'attached',\n    'autoclosure',\n    concat(/convention\\(/, either('swift', 'block', 'c'), /\\)/),\n    'discardableResult',\n    'dynamicCallable',\n    'dynamicMemberLookup',\n    'escaping',\n    'freestanding',\n    'frozen',\n    'GKInspectable',\n    'IBAction',\n    'IBDesignable',\n    'IBInspectable',\n    'IBOutlet',\n    'IBSegueAction',\n    'inlinable',\n    'main',\n    'nonobjc',\n    'NSApplicationMain',\n    'NSCopying',\n    'NSManaged',\n    concat(/objc\\(/, identifier, /\\)/),\n    'objc',\n    'objcMembers',\n    'propertyWrapper',\n    'requires_stored_property_inits',\n    'resultBuilder',\n    'Sendable',\n    'testable',\n    'UIApplicationMain',\n    'unchecked',\n    'unknown',\n    'usableFromInline',\n    'warn_unqualified_access'\n  ];\n\n  // Contextual keywords used in @available and #(un)available.\n  const availabilityKeywords = [\n    'iOS',\n    'iOSApplicationExtension',\n    'macOS',\n    'macOSApplicationExtension',\n    'macCatalyst',\n    'macCatalystApplicationExtension',\n    'watchOS',\n    'watchOSApplicationExtension',\n    'tvOS',\n    'tvOSApplicationExtension',\n    'swift'\n  ];\n\n  /*\n  Language: Swift\n  Description: Swift is a general-purpose programming language built using a modern approach to safety, performance, and software design patterns.\n  Author: Steven Van Impe <steven.vanimpe@icloud.com>\n  Contributors: Chris Eidhof <chris@eidhof.nl>, Nate Cook <natecook@gmail.com>, Alexander Lichter <manniL@gmx.net>, Richard Gibson <gibson042@github>\n  Website: https://swift.org\n  Category: common, system\n  */\n\n\n  /** @type LanguageFn */\n  function swift(hljs) {\n    const WHITESPACE = {\n      match: /\\s+/,\n      relevance: 0\n    };\n    // https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID411\n    const BLOCK_COMMENT = hljs.COMMENT(\n      '/\\\\*',\n      '\\\\*/',\n      { contains: [ 'self' ] }\n    );\n    const COMMENTS = [\n      hljs.C_LINE_COMMENT_MODE,\n      BLOCK_COMMENT\n    ];\n\n    // https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID413\n    // https://docs.swift.org/swift-book/ReferenceManual/zzSummaryOfTheGrammar.html\n    const DOT_KEYWORD = {\n      match: [\n        /\\./,\n        either(...dotKeywords, ...optionalDotKeywords)\n      ],\n      className: { 2: \"keyword\" }\n    };\n    const KEYWORD_GUARD = {\n      // Consume .keyword to prevent highlighting properties and methods as keywords.\n      match: concat(/\\./, either(...keywords)),\n      relevance: 0\n    };\n    const PLAIN_KEYWORDS = keywords\n      .filter(kw => typeof kw === 'string')\n      .concat([ \"_|0\" ]); // seems common, so 0 relevance\n    const REGEX_KEYWORDS = keywords\n      .filter(kw => typeof kw !== 'string') // find regex\n      .concat(keywordTypes)\n      .map(keywordWrapper);\n    const KEYWORD = { variants: [\n      {\n        className: 'keyword',\n        match: either(...REGEX_KEYWORDS, ...optionalDotKeywords)\n      }\n    ] };\n    // find all the regular keywords\n    const KEYWORDS = {\n      $pattern: either(\n        /\\b\\w+/, // regular keywords\n        /#\\w+/ // number keywords\n      ),\n      keyword: PLAIN_KEYWORDS\n        .concat(numberSignKeywords),\n      literal: literals\n    };\n    const KEYWORD_MODES = [\n      DOT_KEYWORD,\n      KEYWORD_GUARD,\n      KEYWORD\n    ];\n\n    // https://github.com/apple/swift/tree/main/stdlib/public/core\n    const BUILT_IN_GUARD = {\n      // Consume .built_in to prevent highlighting properties and methods.\n      match: concat(/\\./, either(...builtIns$1)),\n      relevance: 0\n    };\n    const BUILT_IN = {\n      className: 'built_in',\n      match: concat(/\\b/, either(...builtIns$1), /(?=\\()/)\n    };\n    const BUILT_INS = [\n      BUILT_IN_GUARD,\n      BUILT_IN\n    ];\n\n    // https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID418\n    const OPERATOR_GUARD = {\n      // Prevent -> from being highlighting as an operator.\n      match: /->/,\n      relevance: 0\n    };\n    const OPERATOR = {\n      className: 'operator',\n      relevance: 0,\n      variants: [\n        { match: operator },\n        {\n          // dot-operator: only operators that start with a dot are allowed to use dots as\n          // characters (..., ...<, .*, etc). So there rule here is: a dot followed by one or more\n          // characters that may also include dots.\n          match: `\\\\.(\\\\.|${operatorCharacter})+` }\n      ]\n    };\n    const OPERATORS = [\n      OPERATOR_GUARD,\n      OPERATOR\n    ];\n\n    // https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#grammar_numeric-literal\n    // TODO: Update for leading `-` after lookbehind is supported everywhere\n    const decimalDigits = '([0-9]_*)+';\n    const hexDigits = '([0-9a-fA-F]_*)+';\n    const NUMBER = {\n      className: 'number',\n      relevance: 0,\n      variants: [\n        // decimal floating-point-literal (subsumes decimal-literal)\n        { match: `\\\\b(${decimalDigits})(\\\\.(${decimalDigits}))?` + `([eE][+-]?(${decimalDigits}))?\\\\b` },\n        // hexadecimal floating-point-literal (subsumes hexadecimal-literal)\n        { match: `\\\\b0x(${hexDigits})(\\\\.(${hexDigits}))?` + `([pP][+-]?(${decimalDigits}))?\\\\b` },\n        // octal-literal\n        { match: /\\b0o([0-7]_*)+\\b/ },\n        // binary-literal\n        { match: /\\b0b([01]_*)+\\b/ }\n      ]\n    };\n\n    // https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#grammar_string-literal\n    const ESCAPED_CHARACTER = (rawDelimiter = \"\") => ({\n      className: 'subst',\n      variants: [\n        { match: concat(/\\\\/, rawDelimiter, /[0\\\\tnr\"']/) },\n        { match: concat(/\\\\/, rawDelimiter, /u\\{[0-9a-fA-F]{1,8}\\}/) }\n      ]\n    });\n    const ESCAPED_NEWLINE = (rawDelimiter = \"\") => ({\n      className: 'subst',\n      match: concat(/\\\\/, rawDelimiter, /[\\t ]*(?:[\\r\\n]|\\r\\n)/)\n    });\n    const INTERPOLATION = (rawDelimiter = \"\") => ({\n      className: 'subst',\n      label: \"interpol\",\n      begin: concat(/\\\\/, rawDelimiter, /\\(/),\n      end: /\\)/\n    });\n    const MULTILINE_STRING = (rawDelimiter = \"\") => ({\n      begin: concat(rawDelimiter, /\"\"\"/),\n      end: concat(/\"\"\"/, rawDelimiter),\n      contains: [\n        ESCAPED_CHARACTER(rawDelimiter),\n        ESCAPED_NEWLINE(rawDelimiter),\n        INTERPOLATION(rawDelimiter)\n      ]\n    });\n    const SINGLE_LINE_STRING = (rawDelimiter = \"\") => ({\n      begin: concat(rawDelimiter, /\"/),\n      end: concat(/\"/, rawDelimiter),\n      contains: [\n        ESCAPED_CHARACTER(rawDelimiter),\n        INTERPOLATION(rawDelimiter)\n      ]\n    });\n    const STRING = {\n      className: 'string',\n      variants: [\n        MULTILINE_STRING(),\n        MULTILINE_STRING(\"#\"),\n        MULTILINE_STRING(\"##\"),\n        MULTILINE_STRING(\"###\"),\n        SINGLE_LINE_STRING(),\n        SINGLE_LINE_STRING(\"#\"),\n        SINGLE_LINE_STRING(\"##\"),\n        SINGLE_LINE_STRING(\"###\")\n      ]\n    };\n\n    const REGEXP_CONTENTS = [\n      hljs.BACKSLASH_ESCAPE,\n      {\n        begin: /\\[/,\n        end: /\\]/,\n        relevance: 0,\n        contains: [ hljs.BACKSLASH_ESCAPE ]\n      }\n    ];\n\n    const BARE_REGEXP_LITERAL = {\n      begin: /\\/[^\\s](?=[^/\\n]*\\/)/,\n      end: /\\//,\n      contains: REGEXP_CONTENTS\n    };\n\n    const EXTENDED_REGEXP_LITERAL = (rawDelimiter) => {\n      const begin = concat(rawDelimiter, /\\//);\n      const end = concat(/\\//, rawDelimiter);\n      return {\n        begin,\n        end,\n        contains: [\n          ...REGEXP_CONTENTS,\n          {\n            scope: \"comment\",\n            begin: `#(?!.*${end})`,\n            end: /$/,\n          },\n        ],\n      };\n    };\n\n    // https://docs.swift.org/swift-book/documentation/the-swift-programming-language/lexicalstructure/#Regular-Expression-Literals\n    const REGEXP = {\n      scope: \"regexp\",\n      variants: [\n        EXTENDED_REGEXP_LITERAL('###'),\n        EXTENDED_REGEXP_LITERAL('##'),\n        EXTENDED_REGEXP_LITERAL('#'),\n        BARE_REGEXP_LITERAL\n      ]\n    };\n\n    // https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID412\n    const QUOTED_IDENTIFIER = { match: concat(/`/, identifier, /`/) };\n    const IMPLICIT_PARAMETER = {\n      className: 'variable',\n      match: /\\$\\d+/\n    };\n    const PROPERTY_WRAPPER_PROJECTION = {\n      className: 'variable',\n      match: `\\\\$${identifierCharacter}+`\n    };\n    const IDENTIFIERS = [\n      QUOTED_IDENTIFIER,\n      IMPLICIT_PARAMETER,\n      PROPERTY_WRAPPER_PROJECTION\n    ];\n\n    // https://docs.swift.org/swift-book/ReferenceManual/Attributes.html\n    const AVAILABLE_ATTRIBUTE = {\n      match: /(@|#(un)?)available/,\n      scope: 'keyword',\n      starts: { contains: [\n        {\n          begin: /\\(/,\n          end: /\\)/,\n          keywords: availabilityKeywords,\n          contains: [\n            ...OPERATORS,\n            NUMBER,\n            STRING\n          ]\n        }\n      ] }\n    };\n\n    const KEYWORD_ATTRIBUTE = {\n      scope: 'keyword',\n      match: concat(/@/, either(...keywordAttributes), lookahead(either(/\\(/, /\\s+/))),\n    };\n\n    const USER_DEFINED_ATTRIBUTE = {\n      scope: 'meta',\n      match: concat(/@/, identifier)\n    };\n\n    const ATTRIBUTES = [\n      AVAILABLE_ATTRIBUTE,\n      KEYWORD_ATTRIBUTE,\n      USER_DEFINED_ATTRIBUTE\n    ];\n\n    // https://docs.swift.org/swift-book/ReferenceManual/Types.html\n    const TYPE = {\n      match: lookahead(/\\b[A-Z]/),\n      relevance: 0,\n      contains: [\n        { // Common Apple frameworks, for relevance boost\n          className: 'type',\n          match: concat(/(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)/, identifierCharacter, '+')\n        },\n        { // Type identifier\n          className: 'type',\n          match: typeIdentifier,\n          relevance: 0\n        },\n        { // Optional type\n          match: /[?!]+/,\n          relevance: 0\n        },\n        { // Variadic parameter\n          match: /\\.\\.\\./,\n          relevance: 0\n        },\n        { // Protocol composition\n          match: concat(/\\s+&\\s+/, lookahead(typeIdentifier)),\n          relevance: 0\n        }\n      ]\n    };\n    const GENERIC_ARGUMENTS = {\n      begin: /</,\n      end: />/,\n      keywords: KEYWORDS,\n      contains: [\n        ...COMMENTS,\n        ...KEYWORD_MODES,\n        ...ATTRIBUTES,\n        OPERATOR_GUARD,\n        TYPE\n      ]\n    };\n    TYPE.contains.push(GENERIC_ARGUMENTS);\n\n    // https://docs.swift.org/swift-book/ReferenceManual/Expressions.html#ID552\n    // Prevents element names from being highlighted as keywords.\n    const TUPLE_ELEMENT_NAME = {\n      match: concat(identifier, /\\s*:/),\n      keywords: \"_|0\",\n      relevance: 0\n    };\n    // Matches tuples as well as the parameter list of a function type.\n    const TUPLE = {\n      begin: /\\(/,\n      end: /\\)/,\n      relevance: 0,\n      keywords: KEYWORDS,\n      contains: [\n        'self',\n        TUPLE_ELEMENT_NAME,\n        ...COMMENTS,\n        REGEXP,\n        ...KEYWORD_MODES,\n        ...BUILT_INS,\n        ...OPERATORS,\n        NUMBER,\n        STRING,\n        ...IDENTIFIERS,\n        ...ATTRIBUTES,\n        TYPE\n      ]\n    };\n\n    const GENERIC_PARAMETERS = {\n      begin: /</,\n      end: />/,\n      keywords: 'repeat each',\n      contains: [\n        ...COMMENTS,\n        TYPE\n      ]\n    };\n    const FUNCTION_PARAMETER_NAME = {\n      begin: either(\n        lookahead(concat(identifier, /\\s*:/)),\n        lookahead(concat(identifier, /\\s+/, identifier, /\\s*:/))\n      ),\n      end: /:/,\n      relevance: 0,\n      contains: [\n        {\n          className: 'keyword',\n          match: /\\b_\\b/\n        },\n        {\n          className: 'params',\n          match: identifier\n        }\n      ]\n    };\n    const FUNCTION_PARAMETERS = {\n      begin: /\\(/,\n      end: /\\)/,\n      keywords: KEYWORDS,\n      contains: [\n        FUNCTION_PARAMETER_NAME,\n        ...COMMENTS,\n        ...KEYWORD_MODES,\n        ...OPERATORS,\n        NUMBER,\n        STRING,\n        ...ATTRIBUTES,\n        TYPE,\n        TUPLE\n      ],\n      endsParent: true,\n      illegal: /[\"']/\n    };\n    // https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID362\n    // https://docs.swift.org/swift-book/documentation/the-swift-programming-language/declarations/#Macro-Declaration\n    const FUNCTION_OR_MACRO = {\n      match: [\n        /(func|macro)/,\n        /\\s+/,\n        either(QUOTED_IDENTIFIER.match, identifier, operator)\n      ],\n      className: {\n        1: \"keyword\",\n        3: \"title.function\"\n      },\n      contains: [\n        GENERIC_PARAMETERS,\n        FUNCTION_PARAMETERS,\n        WHITESPACE\n      ],\n      illegal: [\n        /\\[/,\n        /%/\n      ]\n    };\n\n    // https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID375\n    // https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID379\n    const INIT_SUBSCRIPT = {\n      match: [\n        /\\b(?:subscript|init[?!]?)/,\n        /\\s*(?=[<(])/,\n      ],\n      className: { 1: \"keyword\" },\n      contains: [\n        GENERIC_PARAMETERS,\n        FUNCTION_PARAMETERS,\n        WHITESPACE\n      ],\n      illegal: /\\[|%/\n    };\n    // https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID380\n    const OPERATOR_DECLARATION = {\n      match: [\n        /operator/,\n        /\\s+/,\n        operator\n      ],\n      className: {\n        1: \"keyword\",\n        3: \"title\"\n      }\n    };\n\n    // https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID550\n    const PRECEDENCEGROUP = {\n      begin: [\n        /precedencegroup/,\n        /\\s+/,\n        typeIdentifier\n      ],\n      className: {\n        1: \"keyword\",\n        3: \"title\"\n      },\n      contains: [ TYPE ],\n      keywords: [\n        ...precedencegroupKeywords,\n        ...literals\n      ],\n      end: /}/\n    };\n\n    const CLASS_FUNC_DECLARATION = {\n      match: [\n        /class\\b/,          \n        /\\s+/,\n        /func\\b/,\n        /\\s+/,\n        /\\b[A-Za-z_][A-Za-z0-9_]*\\b/ \n      ],\n      scope: {\n        1: \"keyword\",\n        3: \"keyword\",\n        5: \"title.function\"\n      }\n    };\n\n    const CLASS_VAR_DECLARATION = {\n      match: [\n        /class\\b/,\n        /\\s+/,          \n        /var\\b/, \n      ],\n      scope: {\n        1: \"keyword\",\n        3: \"keyword\"\n      }\n    };\n\n    const TYPE_DECLARATION = {\n      begin: [\n        /(struct|protocol|class|extension|enum|actor)/,\n        /\\s+/,\n        identifier,\n        /\\s*/,\n      ],\n      beginScope: {\n        1: \"keyword\",\n        3: \"title.class\"\n      },\n      keywords: KEYWORDS,\n      contains: [\n        GENERIC_PARAMETERS,\n        ...KEYWORD_MODES,\n        {\n          begin: /:/,\n          end: /\\{/,\n          keywords: KEYWORDS,\n          contains: [\n            {\n              scope: \"title.class.inherited\",\n              match: typeIdentifier,\n            },\n            ...KEYWORD_MODES,\n          ],\n          relevance: 0,\n        },\n      ]\n    };\n\n    // Add supported submodes to string interpolation.\n    for (const variant of STRING.variants) {\n      const interpolation = variant.contains.find(mode => mode.label === \"interpol\");\n      // TODO: Interpolation can contain any expression, so there's room for improvement here.\n      interpolation.keywords = KEYWORDS;\n      const submodes = [\n        ...KEYWORD_MODES,\n        ...BUILT_INS,\n        ...OPERATORS,\n        NUMBER,\n        STRING,\n        ...IDENTIFIERS\n      ];\n      interpolation.contains = [\n        ...submodes,\n        {\n          begin: /\\(/,\n          end: /\\)/,\n          contains: [\n            'self',\n            ...submodes\n          ]\n        }\n      ];\n    }\n\n    return {\n      name: 'Swift',\n      keywords: KEYWORDS,\n      contains: [\n        ...COMMENTS,\n        FUNCTION_OR_MACRO,\n        INIT_SUBSCRIPT,\n        CLASS_FUNC_DECLARATION,\n        CLASS_VAR_DECLARATION,\n        TYPE_DECLARATION,\n        OPERATOR_DECLARATION,\n        PRECEDENCEGROUP,\n        {\n          beginKeywords: 'import',\n          end: /$/,\n          contains: [ ...COMMENTS ],\n          relevance: 0\n        },\n        REGEXP,\n        ...KEYWORD_MODES,\n        ...BUILT_INS,\n        ...OPERATORS,\n        NUMBER,\n        STRING,\n        ...IDENTIFIERS,\n        ...ATTRIBUTES,\n        TYPE,\n        TUPLE\n      ]\n    };\n  }\n\n  /*\n  Language: TypeScript\n  Author: Panu Horsmalahti <panu.horsmalahti@iki.fi>\n  Contributors: Ike Ku <dempfi@yahoo.com>\n  Description: TypeScript is a strict superset of JavaScript\n  Website: https://www.typescriptlang.org\n  Category: common, scripting\n  */\n\n\n  /** @type LanguageFn */\n  function typescript(hljs) {\n    const regex = hljs.regex;\n    const tsLanguage = javascript(hljs);\n\n    const IDENT_RE$1 = IDENT_RE;\n    const TYPES = [\n      \"any\",\n      \"void\",\n      \"number\",\n      \"boolean\",\n      \"string\",\n      \"object\",\n      \"never\",\n      \"symbol\",\n      \"bigint\",\n      \"unknown\"\n    ];\n    const NAMESPACE = {\n      begin: [\n        /namespace/,\n        /\\s+/,\n        hljs.IDENT_RE\n      ],\n      beginScope: {\n        1: \"keyword\",\n        3: \"title.class\"\n      }\n    };\n    const INTERFACE = {\n      beginKeywords: 'interface',\n      end: /\\{/,\n      excludeEnd: true,\n      keywords: {\n        keyword: 'interface extends',\n        built_in: TYPES\n      },\n      contains: [ tsLanguage.exports.CLASS_REFERENCE ]\n    };\n    const USE_STRICT = {\n      className: 'meta',\n      relevance: 10,\n      begin: /^\\s*['\"]use strict['\"]/\n    };\n    const TS_SPECIFIC_KEYWORDS = [\n      \"type\",\n      // \"namespace\",\n      \"interface\",\n      \"public\",\n      \"private\",\n      \"protected\",\n      \"implements\",\n      \"declare\",\n      \"abstract\",\n      \"readonly\",\n      \"enum\",\n      \"override\",\n      \"satisfies\"\n    ];\n    /*\n      namespace is a TS keyword but it's fine to use it as a variable name too.\n      const message = 'foo';\n      const namespace = 'bar';\n    */\n    const KEYWORDS$1 = {\n      $pattern: IDENT_RE,\n      keyword: KEYWORDS.concat(TS_SPECIFIC_KEYWORDS),\n      literal: LITERALS,\n      built_in: BUILT_INS.concat(TYPES),\n      \"variable.language\": BUILT_IN_VARIABLES\n    };\n\n    const DECORATOR = {\n      className: 'meta',\n      begin: '@' + IDENT_RE$1,\n    };\n\n    const swapMode = (mode, label, replacement) => {\n      const indx = mode.contains.findIndex(m => m.label === label);\n      if (indx === -1) { throw new Error(\"can not find mode to replace\"); }\n\n      mode.contains.splice(indx, 1, replacement);\n    };\n\n\n    // this should update anywhere keywords is used since\n    // it will be the same actual JS object\n    Object.assign(tsLanguage.keywords, KEYWORDS$1);\n\n    tsLanguage.exports.PARAMS_CONTAINS.push(DECORATOR);\n\n    // highlight the function params\n    const ATTRIBUTE_HIGHLIGHT = tsLanguage.contains.find(c => c.scope === \"attr\");\n\n    // take default attr rule and extend it to support optionals\n    const OPTIONAL_KEY_OR_ARGUMENT = Object.assign({},\n      ATTRIBUTE_HIGHLIGHT,\n      { match: regex.concat(IDENT_RE$1, regex.lookahead(/\\s*\\?:/)) }\n    );\n    tsLanguage.exports.PARAMS_CONTAINS.push([\n      tsLanguage.exports.CLASS_REFERENCE, // class reference for highlighting the params types\n      ATTRIBUTE_HIGHLIGHT, // highlight the params key\n      OPTIONAL_KEY_OR_ARGUMENT, // Added for optional property assignment highlighting\n    ]);\n\n    // Add the optional property assignment highlighting for objects or classes\n    tsLanguage.contains = tsLanguage.contains.concat([\n      DECORATOR,\n      NAMESPACE,\n      INTERFACE,\n      OPTIONAL_KEY_OR_ARGUMENT, // Added for optional property assignment highlighting\n    ]);\n\n    // TS gets a simpler shebang rule than JS\n    swapMode(tsLanguage, \"shebang\", hljs.SHEBANG());\n    // JS use strict rule purposely excludes `asm` which makes no sense\n    swapMode(tsLanguage, \"use_strict\", USE_STRICT);\n\n    const functionDeclaration = tsLanguage.contains.find(m => m.label === \"func.def\");\n    functionDeclaration.relevance = 0; // () => {} is more typical in TypeScript\n\n    Object.assign(tsLanguage, {\n      name: 'TypeScript',\n      aliases: [\n        'ts',\n        'tsx',\n        'mts',\n        'cts'\n      ]\n    });\n\n    return tsLanguage;\n  }\n\n  /*\n  Language: Visual Basic .NET\n  Description: Visual Basic .NET (VB.NET) is a multi-paradigm, object-oriented programming language, implemented on the .NET Framework.\n  Authors: Poren Chiang <ren.chiang@gmail.com>, Jan Pilzer\n  Website: https://docs.microsoft.com/dotnet/visual-basic/getting-started\n  Category: common\n  */\n\n  /** @type LanguageFn */\n  function vbnet(hljs) {\n    const regex = hljs.regex;\n    /**\n     * Character Literal\n     * Either a single character (\"a\"C) or an escaped double quote (\"\"\"\"C).\n     */\n    const CHARACTER = {\n      className: 'string',\n      begin: /\"(\"\"|[^/n])\"C\\b/\n    };\n\n    const STRING = {\n      className: 'string',\n      begin: /\"/,\n      end: /\"/,\n      illegal: /\\n/,\n      contains: [\n        {\n          // double quote escape\n          begin: /\"\"/ }\n      ]\n    };\n\n    /** Date Literals consist of a date, a time, or both separated by whitespace, surrounded by # */\n    const MM_DD_YYYY = /\\d{1,2}\\/\\d{1,2}\\/\\d{4}/;\n    const YYYY_MM_DD = /\\d{4}-\\d{1,2}-\\d{1,2}/;\n    const TIME_12H = /(\\d|1[012])(:\\d+){0,2} *(AM|PM)/;\n    const TIME_24H = /\\d{1,2}(:\\d{1,2}){1,2}/;\n    const DATE = {\n      className: 'literal',\n      variants: [\n        {\n          // #YYYY-MM-DD# (ISO-Date) or #M/D/YYYY# (US-Date)\n          begin: regex.concat(/# */, regex.either(YYYY_MM_DD, MM_DD_YYYY), / *#/) },\n        {\n          // #H:mm[:ss]# (24h Time)\n          begin: regex.concat(/# */, TIME_24H, / *#/) },\n        {\n          // #h[:mm[:ss]] A# (12h Time)\n          begin: regex.concat(/# */, TIME_12H, / *#/) },\n        {\n          // date plus time\n          begin: regex.concat(\n            /# */,\n            regex.either(YYYY_MM_DD, MM_DD_YYYY),\n            / +/,\n            regex.either(TIME_12H, TIME_24H),\n            / *#/\n          ) }\n      ]\n    };\n\n    const NUMBER = {\n      className: 'number',\n      relevance: 0,\n      variants: [\n        {\n          // Float\n          begin: /\\b\\d[\\d_]*((\\.[\\d_]+(E[+-]?[\\d_]+)?)|(E[+-]?[\\d_]+))[RFD@!#]?/ },\n        {\n          // Integer (base 10)\n          begin: /\\b\\d[\\d_]*((U?[SIL])|[%&])?/ },\n        {\n          // Integer (base 16)\n          begin: /&H[\\dA-F_]+((U?[SIL])|[%&])?/ },\n        {\n          // Integer (base 8)\n          begin: /&O[0-7_]+((U?[SIL])|[%&])?/ },\n        {\n          // Integer (base 2)\n          begin: /&B[01_]+((U?[SIL])|[%&])?/ }\n      ]\n    };\n\n    const LABEL = {\n      className: 'label',\n      begin: /^\\w+:/\n    };\n\n    const DOC_COMMENT = hljs.COMMENT(/'''/, /$/, { contains: [\n      {\n        className: 'doctag',\n        begin: /<\\/?/,\n        end: />/\n      }\n    ] });\n\n    const COMMENT = hljs.COMMENT(null, /$/, { variants: [\n      { begin: /'/ },\n      {\n        // TODO: Use multi-class for leading spaces\n        begin: /([\\t ]|^)REM(?=\\s)/ }\n    ] });\n\n    const DIRECTIVES = {\n      className: 'meta',\n      // TODO: Use multi-class for indentation once available\n      begin: /[\\t ]*#(const|disable|else|elseif|enable|end|externalsource|if|region)\\b/,\n      end: /$/,\n      keywords: { keyword:\n          'const disable else elseif enable end externalsource if region then' },\n      contains: [ COMMENT ]\n    };\n\n    return {\n      name: 'Visual Basic .NET',\n      aliases: [ 'vb' ],\n      case_insensitive: true,\n      classNameAliases: { label: 'symbol' },\n      keywords: {\n        keyword:\n          'addhandler alias aggregate ansi as async assembly auto binary by byref byval ' /* a-b */\n          + 'call case catch class compare const continue custom declare default delegate dim distinct do ' /* c-d */\n          + 'each equals else elseif end enum erase error event exit explicit finally for friend from function ' /* e-f */\n          + 'get global goto group handles if implements imports in inherits interface into iterator ' /* g-i */\n          + 'join key let lib loop me mid module mustinherit mustoverride mybase myclass ' /* j-m */\n          + 'namespace narrowing new next notinheritable notoverridable ' /* n */\n          + 'of off on operator option optional order overloads overridable overrides ' /* o */\n          + 'paramarray partial preserve private property protected public ' /* p */\n          + 'raiseevent readonly redim removehandler resume return ' /* r */\n          + 'select set shadows shared skip static step stop structure strict sub synclock ' /* s */\n          + 'take text then throw to try unicode until using when where while widening with withevents writeonly yield' /* t-y */,\n        built_in:\n          // Operators https://docs.microsoft.com/dotnet/visual-basic/language-reference/operators\n          'addressof and andalso await directcast gettype getxmlnamespace is isfalse isnot istrue like mod nameof new not or orelse trycast typeof xor '\n          // Type Conversion Functions https://docs.microsoft.com/dotnet/visual-basic/language-reference/functions/type-conversion-functions\n          + 'cbool cbyte cchar cdate cdbl cdec cint clng cobj csbyte cshort csng cstr cuint culng cushort',\n        type:\n          // Data types https://docs.microsoft.com/dotnet/visual-basic/language-reference/data-types\n          'boolean byte char date decimal double integer long object sbyte short single string uinteger ulong ushort',\n        literal: 'true false nothing'\n      },\n      illegal:\n        '//|\\\\{|\\\\}|endif|gosub|variant|wend|^\\\\$ ' /* reserved deprecated keywords */,\n      contains: [\n        CHARACTER,\n        STRING,\n        DATE,\n        NUMBER,\n        LABEL,\n        DOC_COMMENT,\n        COMMENT,\n        DIRECTIVES\n      ]\n    };\n  }\n\n  /*\n  Language: WebAssembly\n  Website: https://webassembly.org\n  Description:  Wasm is designed as a portable compilation target for programming languages, enabling deployment on the web for client and server applications.\n  Category: web, common\n  Audit: 2020\n  */\n\n  /** @type LanguageFn */\n  function wasm(hljs) {\n    hljs.regex;\n    const BLOCK_COMMENT = hljs.COMMENT(/\\(;/, /;\\)/);\n    BLOCK_COMMENT.contains.push(\"self\");\n    const LINE_COMMENT = hljs.COMMENT(/;;/, /$/);\n\n    const KWS = [\n      \"anyfunc\",\n      \"block\",\n      \"br\",\n      \"br_if\",\n      \"br_table\",\n      \"call\",\n      \"call_indirect\",\n      \"data\",\n      \"drop\",\n      \"elem\",\n      \"else\",\n      \"end\",\n      \"export\",\n      \"func\",\n      \"global.get\",\n      \"global.set\",\n      \"local.get\",\n      \"local.set\",\n      \"local.tee\",\n      \"get_global\",\n      \"get_local\",\n      \"global\",\n      \"if\",\n      \"import\",\n      \"local\",\n      \"loop\",\n      \"memory\",\n      \"memory.grow\",\n      \"memory.size\",\n      \"module\",\n      \"mut\",\n      \"nop\",\n      \"offset\",\n      \"param\",\n      \"result\",\n      \"return\",\n      \"select\",\n      \"set_global\",\n      \"set_local\",\n      \"start\",\n      \"table\",\n      \"tee_local\",\n      \"then\",\n      \"type\",\n      \"unreachable\"\n    ];\n\n    const FUNCTION_REFERENCE = {\n      begin: [\n        /(?:func|call|call_indirect)/,\n        /\\s+/,\n        /\\$[^\\s)]+/\n      ],\n      className: {\n        1: \"keyword\",\n        3: \"title.function\"\n      }\n    };\n\n    const ARGUMENT = {\n      className: \"variable\",\n      begin: /\\$[\\w_]+/\n    };\n\n    const PARENS = {\n      match: /(\\((?!;)|\\))+/,\n      className: \"punctuation\",\n      relevance: 0\n    };\n\n    const NUMBER = {\n      className: \"number\",\n      relevance: 0,\n      // borrowed from Prism, TODO: split out into variants\n      match: /[+-]?\\b(?:\\d(?:_?\\d)*(?:\\.\\d(?:_?\\d)*)?(?:[eE][+-]?\\d(?:_?\\d)*)?|0x[\\da-fA-F](?:_?[\\da-fA-F])*(?:\\.[\\da-fA-F](?:_?[\\da-fA-D])*)?(?:[pP][+-]?\\d(?:_?\\d)*)?)\\b|\\binf\\b|\\bnan(?::0x[\\da-fA-F](?:_?[\\da-fA-D])*)?\\b/\n    };\n\n    const TYPE = {\n      // look-ahead prevents us from gobbling up opcodes\n      match: /(i32|i64|f32|f64)(?!\\.)/,\n      className: \"type\"\n    };\n\n    const MATH_OPERATIONS = {\n      className: \"keyword\",\n      // borrowed from Prism, TODO: split out into variants\n      match: /\\b(f32|f64|i32|i64)(?:\\.(?:abs|add|and|ceil|clz|const|convert_[su]\\/i(?:32|64)|copysign|ctz|demote\\/f64|div(?:_[su])?|eqz?|extend_[su]\\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|nearest|neg?|or|popcnt|promote\\/f32|reinterpret\\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|store(?:8|16|32)?|sqrt|sub|trunc(?:_[su]\\/f(?:32|64))?|wrap\\/i64|xor))\\b/\n    };\n\n    const OFFSET_ALIGN = {\n      match: [\n        /(?:offset|align)/,\n        /\\s*/,\n        /=/\n      ],\n      className: {\n        1: \"keyword\",\n        3: \"operator\"\n      }\n    };\n\n    return {\n      name: 'WebAssembly',\n      keywords: {\n        $pattern: /[\\w.]+/,\n        keyword: KWS\n      },\n      contains: [\n        LINE_COMMENT,\n        BLOCK_COMMENT,\n        OFFSET_ALIGN,\n        ARGUMENT,\n        PARENS,\n        FUNCTION_REFERENCE,\n        hljs.QUOTE_STRING_MODE,\n        TYPE,\n        MATH_OPERATIONS,\n        NUMBER\n      ]\n    };\n  }\n\n  /*\n  Language: YAML\n  Description: Yet Another Markdown Language\n  Author: Stefan Wienert <stwienert@gmail.com>\n  Contributors: Carl Baxter <carl@cbax.tech>\n  Requires: ruby.js\n  Website: https://yaml.org\n  Category: common, config\n  */\n  function yaml(hljs) {\n    const LITERALS = 'true false yes no null';\n\n    // YAML spec allows non-reserved URI characters in tags.\n    const URI_CHARACTERS = '[\\\\w#;/?:@&=+$,.~*\\'()[\\\\]]+';\n\n    // Define keys as starting with a word character\n    // ...containing word chars, spaces, colons, forward-slashes, hyphens and periods\n    // ...and ending with a colon followed immediately by a space, tab or newline.\n    // The YAML spec allows for much more than this, but this covers most use-cases.\n    const KEY = {\n      className: 'attr',\n      variants: [\n        // added brackets support and special char support\n        { begin: /[\\w*@][\\w*@ :()\\./-]*:(?=[ \\t]|$)/ },\n        { // double quoted keys - with brackets and special char support\n          begin: /\"[\\w*@][\\w*@ :()\\./-]*\":(?=[ \\t]|$)/ },\n        { // single quoted keys - with brackets and special char support\n          begin: /'[\\w*@][\\w*@ :()\\./-]*':(?=[ \\t]|$)/ },\n      ]\n    };\n    \n    const TEMPLATE_VARIABLES = {\n      className: 'template-variable',\n      variants: [\n        { // jinja templates Ansible\n          begin: /\\{\\{/,\n          end: /\\}\\}/\n        },\n        { // Ruby i18n\n          begin: /%\\{/,\n          end: /\\}/\n        }\n      ]\n    };\n\n    const SINGLE_QUOTE_STRING = {\n      className: 'string',\n      relevance: 0,\n      begin: /'/,\n      end: /'/,\n      contains: [\n        {\n          match: /''/,\n          scope: 'char.escape',\n          relevance: 0\n        }\n      ]\n    };\n\n    const STRING = {\n      className: 'string',\n      relevance: 0,\n      variants: [\n        {\n          begin: /\"/,\n          end: /\"/\n        },\n        { begin: /\\S+/ }\n      ],\n      contains: [\n        hljs.BACKSLASH_ESCAPE,\n        TEMPLATE_VARIABLES\n      ]\n    };\n\n    // Strings inside of value containers (objects) can't contain braces,\n    // brackets, or commas\n    const CONTAINER_STRING = hljs.inherit(STRING, { variants: [\n      {\n        begin: /'/,\n        end: /'/,\n        contains: [\n          {\n            begin: /''/,\n            relevance: 0\n          }\n        ]\n      },\n      {\n        begin: /\"/,\n        end: /\"/\n      },\n      { begin: /[^\\s,{}[\\]]+/ }\n    ] });\n\n    const DATE_RE = '[0-9]{4}(-[0-9][0-9]){0,2}';\n    const TIME_RE = '([Tt \\\\t][0-9][0-9]?(:[0-9][0-9]){2})?';\n    const FRACTION_RE = '(\\\\.[0-9]*)?';\n    const ZONE_RE = '([ \\\\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?';\n    const TIMESTAMP = {\n      className: 'number',\n      begin: '\\\\b' + DATE_RE + TIME_RE + FRACTION_RE + ZONE_RE + '\\\\b'\n    };\n\n    const VALUE_CONTAINER = {\n      end: ',',\n      endsWithParent: true,\n      excludeEnd: true,\n      keywords: LITERALS,\n      relevance: 0\n    };\n    const OBJECT = {\n      begin: /\\{/,\n      end: /\\}/,\n      contains: [ VALUE_CONTAINER ],\n      illegal: '\\\\n',\n      relevance: 0\n    };\n    const ARRAY = {\n      begin: '\\\\[',\n      end: '\\\\]',\n      contains: [ VALUE_CONTAINER ],\n      illegal: '\\\\n',\n      relevance: 0\n    };\n\n    const MODES = [\n      KEY,\n      {\n        className: 'meta',\n        begin: '^---\\\\s*$',\n        relevance: 10\n      },\n      { // multi line string\n        // Blocks start with a | or > followed by a newline\n        //\n        // Indentation of subsequent lines must be the same to\n        // be considered part of the block\n        className: 'string',\n        begin: '[\\\\|>]([1-9]?[+-])?[ ]*\\\\n( +)[^ ][^\\\\n]*\\\\n(\\\\2[^\\\\n]+\\\\n?)*'\n      },\n      { // Ruby/Rails erb\n        begin: '<%[%=-]?',\n        end: '[%-]?%>',\n        subLanguage: 'ruby',\n        excludeBegin: true,\n        excludeEnd: true,\n        relevance: 0\n      },\n      { // named tags\n        className: 'type',\n        begin: '!\\\\w+!' + URI_CHARACTERS\n      },\n      // https://yaml.org/spec/1.2/spec.html#id2784064\n      { // verbatim tags\n        className: 'type',\n        begin: '!<' + URI_CHARACTERS + \">\"\n      },\n      { // primary tags\n        className: 'type',\n        begin: '!' + URI_CHARACTERS\n      },\n      { // secondary tags\n        className: 'type',\n        begin: '!!' + URI_CHARACTERS\n      },\n      { // fragment id &ref\n        className: 'meta',\n        begin: '&' + hljs.UNDERSCORE_IDENT_RE + '$'\n      },\n      { // fragment reference *ref\n        className: 'meta',\n        begin: '\\\\*' + hljs.UNDERSCORE_IDENT_RE + '$'\n      },\n      { // array listing\n        className: 'bullet',\n        // TODO: remove |$ hack when we have proper look-ahead support\n        begin: '-(?=[ ]|$)',\n        relevance: 0\n      },\n      hljs.HASH_COMMENT_MODE,\n      {\n        beginKeywords: LITERALS,\n        keywords: { literal: LITERALS }\n      },\n      TIMESTAMP,\n      // numbers are any valid C-style number that\n      // sit isolated from other words\n      {\n        className: 'number',\n        begin: hljs.C_NUMBER_RE + '\\\\b',\n        relevance: 0\n      },\n      OBJECT,\n      ARRAY,\n      SINGLE_QUOTE_STRING,\n      STRING\n    ];\n\n    const VALUE_MODES = [ ...MODES ];\n    VALUE_MODES.pop();\n    VALUE_MODES.push(CONTAINER_STRING);\n    VALUE_CONTAINER.contains = VALUE_MODES;\n\n    return {\n      name: 'YAML',\n      case_insensitive: true,\n      aliases: [ 'yml' ],\n      contains: MODES\n    };\n  }\n\n  var builtIns = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    grmr_bash: bash,\n    grmr_c: c,\n    grmr_cpp: cpp,\n    grmr_csharp: csharp,\n    grmr_css: css,\n    grmr_diff: diff,\n    grmr_go: go,\n    grmr_graphql: graphql,\n    grmr_ini: ini,\n    grmr_java: java,\n    grmr_javascript: javascript,\n    grmr_json: json,\n    grmr_kotlin: kotlin,\n    grmr_less: less,\n    grmr_lua: lua,\n    grmr_makefile: makefile,\n    grmr_markdown: markdown,\n    grmr_objectivec: objectivec,\n    grmr_perl: perl,\n    grmr_php: php,\n    grmr_php_template: phpTemplate,\n    grmr_plaintext: plaintext,\n    grmr_python: python,\n    grmr_python_repl: pythonRepl,\n    grmr_r: r,\n    grmr_ruby: ruby,\n    grmr_rust: rust,\n    grmr_scss: scss,\n    grmr_shell: shell,\n    grmr_sql: sql,\n    grmr_swift: swift,\n    grmr_typescript: typescript,\n    grmr_vbnet: vbnet,\n    grmr_wasm: wasm,\n    grmr_xml: xml,\n    grmr_yaml: yaml\n  });\n\n  const hljs = highlight;\n\n  for (const key of Object.keys(builtIns)) {\n    // our builtInLanguages Rollup plugin has to use `_` to allow identifiers to be\n    // compatible with `export` naming conventions, so we need to convert the\n    // identifiers back into the more typical dash style that we use for language\n    // naming via the API\n    const languageName = key.replace(\"grmr_\", \"\").replace(\"_\", \"-\");\n    hljs.registerLanguage(languageName, builtIns[key]);\n  }\n\n  return hljs;\n\n})();\n// if (typeof exports === 'object' && typeof module !== 'undefined') { module.exports = hljs; }\n\nexport { hljs };\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/code/highlightjs/src/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/code/highlightjs/src/types.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport interface HL {\n  highlightAuto(code: string): HighlightResult\n  highlight(code: string, options: HighlightOptions): HighlightResult\n  getLanguage(language: string): Language | undefined\n  addPlugin: (plugin: HLJSPlugin) => void\n  removePlugin: (plugin: HLJSPlugin) => void\n}\nexport interface Language {}\nexport interface HighlightOptions {\n  language: string\n  ignoreIllegals?: boolean\n}\nexport interface HighlightResult {\n  code?: string\n  relevance : number\n  value : string\n  language? : string\n  illegal : boolean\n  errorRaised? : Error\n}\nexport interface BeforeHighlightContext {\n  code: string,\n  language: string,\n  result?: HighlightResult\n}\nexport interface HLJSPlugin {\n  'after:highlight'?: (result: HighlightResult) => void,\n  'before:highlight'?: (context: BeforeHighlightContext) => void,\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/code/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport * from './service';\nexport * from './style';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/code/service.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { hl, type HighlightOptions, type HighlightResult } from './highlightjs';\nimport { EService, Service } from '../../engine/service';\nimport { Plugin } from '../../engine/plugin';\nimport { HIGHLIGHT_DEFAULT_CSS } from './style';\nimport { type CssNode  } from '../css';\n\nexport class CodeService extends Service {\n  private _css?: CssNode;\n  readonly type: EService = EService.Code;\n  add<T extends Plugin>(_plugin: T): void {\n  }\n  parse(content: string, option: HighlightOptions): HighlightResult | undefined {\n    try {\n      return hl.getLanguage(option.language || '') ? hl.highlight(content, option) : hl.highlightAuto(content);\n    } catch (e) {\n      return undefined;\n    }\n  }\n  parse4page(content: string, option: HighlightOptions): string | undefined {\n    const value = this.parse(content, option)?.value;\n    if (value) {\n      return `<span class=\"hljs\">${value}</span>`;\n    }\n    return undefined;\n  }\n  get css() {\n    if (!this._css) {\n      this._css = this.engine?.deref()?.css?.parse(HIGHLIGHT_DEFAULT_CSS).data;\n    }\n    return this._css;\n  }\n  styledFromHtml(content: string): StyledString | undefined {\n    return this.engine?.deref()?.html?.toStyled(content);\n  }\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/code/style.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport const HIGHLIGHT_DEFAULT_CSS = `\n/*!\n  Theme: Default\n  Description: Original highlight.js style\n  Author: (c) Ivan Sagalaev <maniac@softwaremaniacs.org>\n  Maintainer: @highlightjs/core-team\n  Website: https://highlightjs.org/\n  License: see project LICENSE\n  Touched: 2021\n*/pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#f3f3f3;color:#444}.hljs-comment{color:#697070}.hljs-punctuation,.hljs-tag{color:#444a}.hljs-tag .hljs-attr,.hljs-tag .hljs-name{color:#444}.hljs-attribute,.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-name,.hljs-selector-tag{font-weight:700}.hljs-deletion,.hljs-number,.hljs-quote,.hljs-selector-class,.hljs-selector-id,.hljs-string,.hljs-template-tag,.hljs-type{color:#800}.hljs-section,.hljs-title{color:#800;font-weight:700}.hljs-link,.hljs-operator,.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#ab5656}.hljs-literal{color:#695}.hljs-addition,.hljs-built_in,.hljs-bullet,.hljs-code{color:#397300}.hljs-meta{color:#1f7199}.hljs-meta .hljs-string{color:#38a}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}\n`;"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/css/csstree/csstree.rollup.esm.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n// CSS Syntax Module Level 3\n// https://www.w3.org/TR/css-syntax-3/\nconst EOF$1 = 0;                 // <EOF-token>\nconst Ident = 1;               // <ident-token>\nconst Function$1 = 2;            // <function-token>\nconst AtKeyword = 3;           // <at-keyword-token>\nconst Hash$1 = 4;                // <hash-token>\nconst String$2 = 5;              // <string-token>\nconst BadString = 6;           // <bad-string-token>\nconst Url$1 = 7;                 // <url-token>\nconst BadUrl = 8;              // <bad-url-token>\nconst Delim = 9;               // <delim-token>\nconst Number$2 = 10;             // <number-token>\nconst Percentage$1 = 11;         // <percentage-token>\nconst Dimension$1 = 12;          // <dimension-token>\nconst WhiteSpace$1 = 13;         // <whitespace-token>\nconst CDO$1 = 14;                // <CDO-token>\nconst CDC$1 = 15;                // <CDC-token>\nconst Colon = 16;              // <colon-token>     :\nconst Semicolon = 17;          // <semicolon-token> ;\nconst Comma = 18;              // <comma-token>     ,\nconst LeftSquareBracket = 19;  // <[-token>\nconst RightSquareBracket = 20; // <]-token>\nconst LeftParenthesis = 21;    // <(-token>\nconst RightParenthesis = 22;   // <)-token>\nconst LeftCurlyBracket = 23;   // <{-token>\nconst RightCurlyBracket = 24;  // <}-token>\nconst Comment$1 = 25;\n\nvar types = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    EOF: EOF$1,\n    Ident: Ident,\n    Function: Function$1,\n    AtKeyword: AtKeyword,\n    Hash: Hash$1,\n    String: String$2,\n    BadString: BadString,\n    Url: Url$1,\n    BadUrl: BadUrl,\n    Delim: Delim,\n    Number: Number$2,\n    Percentage: Percentage$1,\n    Dimension: Dimension$1,\n    WhiteSpace: WhiteSpace$1,\n    CDO: CDO$1,\n    CDC: CDC$1,\n    Colon: Colon,\n    Semicolon: Semicolon,\n    Comma: Comma,\n    LeftSquareBracket: LeftSquareBracket,\n    RightSquareBracket: RightSquareBracket,\n    LeftParenthesis: LeftParenthesis,\n    RightParenthesis: RightParenthesis,\n    LeftCurlyBracket: LeftCurlyBracket,\n    RightCurlyBracket: RightCurlyBracket,\n    Comment: Comment$1\n});\n\nconst EOF = 0;\n\n// https://drafts.csswg.org/css-syntax-3/\n// § 4.2. Definitions\n\n// digit\n// A code point between U+0030 DIGIT ZERO (0) and U+0039 DIGIT NINE (9).\nfunction isDigit(code) {\n    return code >= 0x0030 && code <= 0x0039;\n}\n\n// hex digit\n// A digit, or a code point between U+0041 LATIN CAPITAL LETTER A (A) and U+0046 LATIN CAPITAL LETTER F (F),\n// or a code point between U+0061 LATIN SMALL LETTER A (a) and U+0066 LATIN SMALL LETTER F (f).\nfunction isHexDigit(code) {\n    return (\n        isDigit(code) || // 0 .. 9\n        (code >= 0x0041 && code <= 0x0046) || // A .. F\n        (code >= 0x0061 && code <= 0x0066)    // a .. f\n    );\n}\n\n// uppercase letter\n// A code point between U+0041 LATIN CAPITAL LETTER A (A) and U+005A LATIN CAPITAL LETTER Z (Z).\nfunction isUppercaseLetter(code) {\n    return code >= 0x0041 && code <= 0x005A;\n}\n\n// lowercase letter\n// A code point between U+0061 LATIN SMALL LETTER A (a) and U+007A LATIN SMALL LETTER Z (z).\nfunction isLowercaseLetter(code) {\n    return code >= 0x0061 && code <= 0x007A;\n}\n\n// letter\n// An uppercase letter or a lowercase letter.\nfunction isLetter(code) {\n    return isUppercaseLetter(code) || isLowercaseLetter(code);\n}\n\n// non-ASCII code point\n// A code point with a value equal to or greater than U+0080 <control>.\n//\n// 2024-09-02: The latest spec narrows the range for non-ASCII characters (see https://github.com/csstree/csstree/issues/188).\n// However, all modern browsers support a wider range, and strictly following the latest spec could result\n// in some CSS being parsed incorrectly, even though it works in the browser. Therefore, this function adheres\n// to the previous, broader definition of non-ASCII characters.\nfunction isNonAscii(code) {\n    return code >= 0x0080;\n}\n\n// name-start code point\n// A letter, a non-ASCII code point, or U+005F LOW LINE (_).\nfunction isNameStart(code) {\n    return isLetter(code) || isNonAscii(code) || code === 0x005F;\n}\n\n// name code point\n// A name-start code point, a digit, or U+002D HYPHEN-MINUS (-).\nfunction isName(code) {\n    return isNameStart(code) || isDigit(code) || code === 0x002D;\n}\n\n// non-printable code point\n// A code point between U+0000 NULL and U+0008 BACKSPACE, or U+000B LINE TABULATION,\n// or a code point between U+000E SHIFT OUT and U+001F INFORMATION SEPARATOR ONE, or U+007F DELETE.\nfunction isNonPrintable(code) {\n    return (\n        (code >= 0x0000 && code <= 0x0008) ||\n        (code === 0x000B) ||\n        (code >= 0x000E && code <= 0x001F) ||\n        (code === 0x007F)\n    );\n}\n\n// newline\n// U+000A LINE FEED. Note that U+000D CARRIAGE RETURN and U+000C FORM FEED are not included in this definition,\n// as they are converted to U+000A LINE FEED during preprocessing.\n// TODO: we doesn't do a preprocessing, so check a code point for U+000D CARRIAGE RETURN and U+000C FORM FEED\nfunction isNewline(code) {\n    return code === 0x000A || code === 0x000D || code === 0x000C;\n}\n\n// whitespace\n// A newline, U+0009 CHARACTER TABULATION, or U+0020 SPACE.\nfunction isWhiteSpace(code) {\n    return isNewline(code) || code === 0x0020 || code === 0x0009;\n}\n\n// § 4.3.8. Check if two code points are a valid escape\nfunction isValidEscape(first, second) {\n    // If the first code point is not U+005C REVERSE SOLIDUS (\\), return false.\n    if (first !== 0x005C) {\n        return false;\n    }\n\n    // Otherwise, if the second code point is a newline or EOF, return false.\n    if (isNewline(second) || second === EOF) {\n        return false;\n    }\n\n    // Otherwise, return true.\n    return true;\n}\n\n// § 4.3.9. Check if three code points would start an identifier\nfunction isIdentifierStart(first, second, third) {\n    // Look at the first code point:\n\n    // U+002D HYPHEN-MINUS\n    if (first === 0x002D) {\n        // If the second code point is a name-start code point or a U+002D HYPHEN-MINUS,\n        // or the second and third code points are a valid escape, return true. Otherwise, return false.\n        return (\n            isNameStart(second) ||\n            second === 0x002D ||\n            isValidEscape(second, third)\n        );\n    }\n\n    // name-start code point\n    if (isNameStart(first)) {\n        // Return true.\n        return true;\n    }\n\n    // U+005C REVERSE SOLIDUS (\\)\n    if (first === 0x005C) {\n        // If the first and second code points are a valid escape, return true. Otherwise, return false.\n        return isValidEscape(first, second);\n    }\n\n    // anything else\n    // Return false.\n    return false;\n}\n\n// § 4.3.10. Check if three code points would start a number\nfunction isNumberStart(first, second, third) {\n    // Look at the first code point:\n\n    // U+002B PLUS SIGN (+)\n    // U+002D HYPHEN-MINUS (-)\n    if (first === 0x002B || first === 0x002D) {\n        // If the second code point is a digit, return true.\n        if (isDigit(second)) {\n            return 2;\n        }\n\n        // Otherwise, if the second code point is a U+002E FULL STOP (.)\n        // and the third code point is a digit, return true.\n        // Otherwise, return false.\n        return second === 0x002E && isDigit(third) ? 3 : 0;\n    }\n\n    // U+002E FULL STOP (.)\n    if (first === 0x002E) {\n        // If the second code point is a digit, return true. Otherwise, return false.\n        return isDigit(second) ? 2 : 0;\n    }\n\n    // digit\n    if (isDigit(first)) {\n        // Return true.\n        return 1;\n    }\n\n    // anything else\n    // Return false.\n    return 0;\n}\n\n//\n// Misc\n//\n\n// detect BOM (https://en.wikipedia.org/wiki/Byte_order_mark)\nfunction isBOM(code) {\n    // UTF-16BE\n    if (code === 0xFEFF) {\n        return 1;\n    }\n\n    // UTF-16LE\n    if (code === 0xFFFE) {\n        return 1;\n    }\n\n    return 0;\n}\n\n// Fast code category\n// Only ASCII code points has a special meaning, that's why we define a maps for 0..127 codes only\nconst CATEGORY = new Array(0x80);\nconst EofCategory = 0x80;\nconst WhiteSpaceCategory = 0x82;\nconst DigitCategory = 0x83;\nconst NameStartCategory = 0x84;\nconst NonPrintableCategory = 0x85;\n\nfor (let i = 0; i < CATEGORY.length; i++) {\n    CATEGORY[i] =\n        isWhiteSpace(i) && WhiteSpaceCategory ||\n        isDigit(i) && DigitCategory ||\n        isNameStart(i) && NameStartCategory ||\n        isNonPrintable(i) && NonPrintableCategory ||\n        i || EofCategory;\n}\n\nfunction charCodeCategory(code) {\n    return code < 0x80 ? CATEGORY[code] : NameStartCategory;\n}\n\nfunction getCharCode(source, offset) {\n    return offset < source.length ? source.charCodeAt(offset) : 0;\n}\n\nfunction getNewlineLength(source, offset, code) {\n    if (code === 13 /* \\r */ && getCharCode(source, offset + 1) === 10 /* \\n */) {\n        return 2;\n    }\n\n    return 1;\n}\n\nfunction cmpChar(testStr, offset, referenceCode) {\n    let code = testStr.charCodeAt(offset);\n\n    // code.toLowerCase() for A..Z\n    if (isUppercaseLetter(code)) {\n        code = code | 32;\n    }\n\n    return code === referenceCode;\n}\n\nfunction cmpStr(testStr, start, end, referenceStr) {\n    if (end - start !== referenceStr.length) {\n        return false;\n    }\n\n    if (start < 0 || end > testStr.length) {\n        return false;\n    }\n\n    for (let i = start; i < end; i++) {\n        const referenceCode = referenceStr.charCodeAt(i - start);\n        let testCode = testStr.charCodeAt(i);\n\n        // testCode.toLowerCase() for A..Z\n        if (isUppercaseLetter(testCode)) {\n            testCode = testCode | 32;\n        }\n\n        if (testCode !== referenceCode) {\n            return false;\n        }\n    }\n\n    return true;\n}\n\nfunction findWhiteSpaceStart(source, offset) {\n    for (; offset >= 0; offset--) {\n        if (!isWhiteSpace(source.charCodeAt(offset))) {\n            break;\n        }\n    }\n\n    return offset + 1;\n}\n\nfunction findWhiteSpaceEnd(source, offset) {\n    for (; offset < source.length; offset++) {\n        if (!isWhiteSpace(source.charCodeAt(offset))) {\n            break;\n        }\n    }\n\n    return offset;\n}\n\nfunction findDecimalNumberEnd(source, offset) {\n    for (; offset < source.length; offset++) {\n        if (!isDigit(source.charCodeAt(offset))) {\n            break;\n        }\n    }\n\n    return offset;\n}\n\n// § 4.3.7. Consume an escaped code point\nfunction consumeEscaped(source, offset) {\n    // It assumes that the U+005C REVERSE SOLIDUS (\\) has already been consumed and\n    // that the next input code point has already been verified to be part of a valid escape.\n    offset += 2;\n\n    // hex digit\n    if (isHexDigit(getCharCode(source, offset - 1))) {\n        // Consume as many hex digits as possible, but no more than 5.\n        // Note that this means 1-6 hex digits have been consumed in total.\n        for (const maxOffset = Math.min(source.length, offset + 5); offset < maxOffset; offset++) {\n            if (!isHexDigit(getCharCode(source, offset))) {\n                break;\n            }\n        }\n\n        // If the next input code point is whitespace, consume it as well.\n        const code = getCharCode(source, offset);\n        if (isWhiteSpace(code)) {\n            offset += getNewlineLength(source, offset, code);\n        }\n    }\n\n    return offset;\n}\n\n// §4.3.11. Consume a name\n// Note: This algorithm does not do the verification of the first few code points that are necessary\n// to ensure the returned code points would constitute an <ident-token>. If that is the intended use,\n// ensure that the stream starts with an identifier before calling this algorithm.\nfunction consumeName(source, offset) {\n    // Let result initially be an empty string.\n    // Repeatedly consume the next input code point from the stream:\n    for (; offset < source.length; offset++) {\n        const code = source.charCodeAt(offset);\n\n        // name code point\n        if (isName(code)) {\n            // Append the code point to result.\n            continue;\n        }\n\n        // the stream starts with a valid escape\n        if (isValidEscape(code, getCharCode(source, offset + 1))) {\n            // Consume an escaped code point. Append the returned code point to result.\n            offset = consumeEscaped(source, offset) - 1;\n            continue;\n        }\n\n        // anything else\n        // Reconsume the current input code point. Return result.\n        break;\n    }\n\n    return offset;\n}\n\n// §4.3.12. Consume a number\nfunction consumeNumber(source, offset) {\n    let code = source.charCodeAt(offset);\n\n    // 2. If the next input code point is U+002B PLUS SIGN (+) or U+002D HYPHEN-MINUS (-),\n    // consume it and append it to repr.\n    if (code === 0x002B || code === 0x002D) {\n        code = source.charCodeAt(offset += 1);\n    }\n\n    // 3. While the next input code point is a digit, consume it and append it to repr.\n    if (isDigit(code)) {\n        offset = findDecimalNumberEnd(source, offset + 1);\n        code = source.charCodeAt(offset);\n    }\n\n    // 4. If the next 2 input code points are U+002E FULL STOP (.) followed by a digit, then:\n    if (code === 0x002E && isDigit(source.charCodeAt(offset + 1))) {\n        // 4.1 Consume them.\n        // 4.2 Append them to repr.\n        offset += 2;\n\n        // 4.3 Set type to \"number\".\n        // TODO\n\n        // 4.4 While the next input code point is a digit, consume it and append it to repr.\n\n        offset = findDecimalNumberEnd(source, offset);\n    }\n\n    // 5. If the next 2 or 3 input code points are U+0045 LATIN CAPITAL LETTER E (E)\n    // or U+0065 LATIN SMALL LETTER E (e), ... , followed by a digit, then:\n    if (cmpChar(source, offset, 101 /* e */)) {\n        let sign = 0;\n        code = source.charCodeAt(offset + 1);\n\n        // ... optionally followed by U+002D HYPHEN-MINUS (-) or U+002B PLUS SIGN (+) ...\n        if (code === 0x002D || code === 0x002B) {\n            sign = 1;\n            code = source.charCodeAt(offset + 2);\n        }\n\n        // ... followed by a digit\n        if (isDigit(code)) {\n            // 5.1 Consume them.\n            // 5.2 Append them to repr.\n\n            // 5.3 Set type to \"number\".\n            // TODO\n\n            // 5.4 While the next input code point is a digit, consume it and append it to repr.\n            offset = findDecimalNumberEnd(source, offset + 1 + sign + 1);\n        }\n    }\n\n    return offset;\n}\n\n// § 4.3.14. Consume the remnants of a bad url\n// ... its sole use is to consume enough of the input stream to reach a recovery point\n// where normal tokenizing can resume.\nfunction consumeBadUrlRemnants(source, offset) {\n    // Repeatedly consume the next input code point from the stream:\n    for (; offset < source.length; offset++) {\n        const code = source.charCodeAt(offset);\n\n        // U+0029 RIGHT PARENTHESIS ())\n        // EOF\n        if (code === 0x0029) {\n            // Return.\n            offset++;\n            break;\n        }\n\n        if (isValidEscape(code, getCharCode(source, offset + 1))) {\n            // Consume an escaped code point.\n            // Note: This allows an escaped right parenthesis (\"\\)\") to be encountered\n            // without ending the <bad-url-token>. This is otherwise identical to\n            // the \"anything else\" clause.\n            offset = consumeEscaped(source, offset);\n        }\n    }\n\n    return offset;\n}\n\n// § 4.3.7. Consume an escaped code point\n// Note: This algorithm assumes that escaped is valid without leading U+005C REVERSE SOLIDUS (\\)\nfunction decodeEscaped(escaped) {\n    // Single char escaped that's not a hex digit\n    if (escaped.length === 1 && !isHexDigit(escaped.charCodeAt(0))) {\n        return escaped[0];\n    }\n\n    // Interpret the hex digits as a hexadecimal number.\n    let code = parseInt(escaped, 16);\n\n    if (\n        (code === 0) ||                       // If this number is zero,\n        (code >= 0xD800 && code <= 0xDFFF) || // or is for a surrogate,\n        (code > 0x10FFFF)                     // or is greater than the maximum allowed code point\n    ) {\n        // ... return U+FFFD REPLACEMENT CHARACTER\n        code = 0xFFFD;\n    }\n\n    // Otherwise, return the code point with that value.\n    return String.fromCodePoint(code);\n}\n\nvar tokenNames = [\n    'EOF-token',\n    'ident-token',\n    'function-token',\n    'at-keyword-token',\n    'hash-token',\n    'string-token',\n    'bad-string-token',\n    'url-token',\n    'bad-url-token',\n    'delim-token',\n    'number-token',\n    'percentage-token',\n    'dimension-token',\n    'whitespace-token',\n    'CDO-token',\n    'CDC-token',\n    'colon-token',\n    'semicolon-token',\n    'comma-token',\n    '[-token',\n    ']-token',\n    '(-token',\n    ')-token',\n    '{-token',\n    '}-token',\n    'comment-token'\n];\n\nconst MIN_SIZE = 16 * 1024;\n\nfunction adoptBuffer(buffer = null, size) {\n    if (buffer === null || buffer.length < size) {\n        return new Uint32Array(Math.max(size + 1024, MIN_SIZE));\n    }\n\n    return buffer;\n}\n\nconst N$4 = 10;\nconst F$2 = 12;\nconst R$2 = 13;\n\nfunction computeLinesAndColumns(host) {\n    const source = host.source;\n    const sourceLength = source.length;\n    const startOffset = source.length > 0 ? isBOM(source.charCodeAt(0)) : 0;\n    const lines = adoptBuffer(host.lines, sourceLength);\n    const columns = adoptBuffer(host.columns, sourceLength);\n    let line = host.startLine;\n    let column = host.startColumn;\n\n    for (let i = startOffset; i < sourceLength; i++) {\n        const code = source.charCodeAt(i);\n\n        lines[i] = line;\n        columns[i] = column++;\n\n        if (code === N$4 || code === R$2 || code === F$2) {\n            if (code === R$2 && i + 1 < sourceLength && source.charCodeAt(i + 1) === N$4) {\n                i++;\n                lines[i] = line;\n                columns[i] = column;\n            }\n\n            line++;\n            column = 1;\n        }\n    }\n\n    lines[sourceLength] = line;\n    columns[sourceLength] = column;\n\n    host.lines = lines;\n    host.columns = columns;\n    host.computed = true;\n}\n\nclass OffsetToLocation {\n    constructor(source, startOffset, startLine, startColumn) {\n        this.setSource(source, startOffset, startLine, startColumn);\n        this.lines = null;\n        this.columns = null;\n    }\n    setSource(source = '', startOffset = 0, startLine = 1, startColumn = 1) {\n        this.source = source;\n        this.startOffset = startOffset;\n        this.startLine = startLine;\n        this.startColumn = startColumn;\n        this.computed = false;\n    }\n    getLocation(offset, filename) {\n        if (!this.computed) {\n            computeLinesAndColumns(this);\n        }\n\n        return {\n            source: filename,\n            offset: this.startOffset + offset,\n            line: this.lines[offset],\n            column: this.columns[offset]\n        };\n    }\n    getLocationRange(start, end, filename) {\n        if (!this.computed) {\n            computeLinesAndColumns(this);\n        }\n\n        return {\n            source: filename,\n            start: {\n                offset: this.startOffset + start,\n                line: this.lines[start],\n                column: this.columns[start]\n            },\n            end: {\n                offset: this.startOffset + end,\n                line: this.lines[end],\n                column: this.columns[end]\n            }\n        };\n    }\n}\n\nconst OFFSET_MASK = 0x00FFFFFF;\nconst TYPE_SHIFT = 24;\nconst BLOCK_OPEN_TOKEN = 1;\nconst BLOCK_CLOSE_TOKEN = 2;\nconst balancePair$1 = new Uint8Array(32); // 32b of memory ought to be enough for anyone (any number of tokens)\nbalancePair$1[Function$1] = RightParenthesis;\nbalancePair$1[LeftParenthesis] = RightParenthesis;\nbalancePair$1[LeftSquareBracket] = RightSquareBracket;\nbalancePair$1[LeftCurlyBracket] = RightCurlyBracket;\n\nconst blockTokens = new Uint8Array(32);\nblockTokens[Function$1] = BLOCK_OPEN_TOKEN;\nblockTokens[LeftParenthesis] = BLOCK_OPEN_TOKEN;\nblockTokens[LeftSquareBracket] = BLOCK_OPEN_TOKEN;\nblockTokens[LeftCurlyBracket] = BLOCK_OPEN_TOKEN;\nblockTokens[RightParenthesis] = BLOCK_CLOSE_TOKEN;\nblockTokens[RightSquareBracket] = BLOCK_CLOSE_TOKEN;\nblockTokens[RightCurlyBracket] = BLOCK_CLOSE_TOKEN;\n\nfunction boundIndex(index, min, max) {\n    return index < min ? min : index > max ? max : index;\n}\n\nclass TokenStream {\n    constructor(source, tokenize) {\n        this.setSource(source, tokenize);\n    }\n    reset() {\n        this.eof = false;\n        this.tokenIndex = -1;\n        this.tokenType = 0;\n        this.tokenStart = this.firstCharOffset;\n        this.tokenEnd = this.firstCharOffset;\n    }\n    setSource(source = '', tokenize = () => {}) {\n        source = String(source || '');\n\n        const sourceLength = source.length;\n        const offsetAndType = adoptBuffer(this.offsetAndType, source.length + 1); // +1 because of eof-token\n        const balance = adoptBuffer(this.balance, source.length + 1);\n        let tokenCount = 0;\n        let firstCharOffset = -1;\n        let balanceCloseType = 0;\n        let balanceStart = source.length;\n\n        // capture buffers\n        this.offsetAndType = null;\n        this.balance = null;\n        balance.fill(0);\n\n        tokenize(source, (type, start, end) => {\n            const index = tokenCount++;\n\n            // type & offset\n            offsetAndType[index] = (type << TYPE_SHIFT) | end;\n\n            if (firstCharOffset === -1) {\n                firstCharOffset = start;\n            }\n\n            // balance\n            balance[index] = balanceStart;\n\n            if (type === balanceCloseType) {\n                const prevBalanceStart = balance[balanceStart];\n\n                // set reference to balance end for a block opener\n                balance[balanceStart] = index;\n\n                // pop state\n                balanceStart = prevBalanceStart;\n                balanceCloseType = balancePair$1[offsetAndType[prevBalanceStart] >> TYPE_SHIFT];\n            } else if (this.isBlockOpenerTokenType(type)) { // check for FunctionToken, <(-token>, <[-token> and <{-token>\n                // push state\n                balanceStart = index;\n                balanceCloseType = balancePair$1[type];\n            }\n        });\n\n        // finalize buffers\n        offsetAndType[tokenCount] = (EOF$1 << TYPE_SHIFT) | sourceLength; // <EOF-token>\n        balance[tokenCount] = tokenCount; // prevents false positive balance match with any token\n\n        // reverse references from balance start to end\n        // tokens\n        //   token:   a ( [ b c ] d e ) {\n        //   index:   0 1 2 3 4 5 6 7 8 9\n        // before\n        //   balance: 0 8 5 2 2 2 1 1 1 0\n        //            - > > < < < < < < -\n        // after\n        //   balance: 9 8 5 5 5 2 8 8 1 9\n        //            > > > > > < > > < >\n        for (let i = 0; i < tokenCount; i++) {\n            const balanceStart = balance[i];\n\n            if (balanceStart <= i) {\n                const balanceEnd = balance[balanceStart];\n\n                if (balanceEnd !== i) {\n                    balance[i] = balanceEnd;\n                }\n            } else if (balanceStart > tokenCount) {\n                balance[i] = tokenCount;\n            }\n        }\n\n        // balance[0] = tokenCount;\n\n        this.source = source;\n        this.firstCharOffset = firstCharOffset === -1 ? 0 : firstCharOffset;\n        this.tokenCount = tokenCount;\n        this.offsetAndType = offsetAndType;\n        this.balance = balance;\n\n        this.reset();\n        this.next();\n    }\n\n    lookupType(offset) {\n        offset += this.tokenIndex;\n\n        if (offset < this.tokenCount) {\n            return this.offsetAndType[offset] >> TYPE_SHIFT;\n        }\n\n        return EOF$1;\n    }\n    lookupTypeNonSC(idx) {\n        for (let offset = this.tokenIndex; offset < this.tokenCount; offset++) {\n            const tokenType = this.offsetAndType[offset] >> TYPE_SHIFT;\n\n            if (tokenType !== WhiteSpace$1 && tokenType !== Comment$1) {\n                if (idx-- === 0) {\n                    return tokenType;\n                }\n            }\n        }\n\n        return EOF$1;\n    }\n    lookupOffset(offset) {\n        offset += this.tokenIndex;\n\n        if (offset < this.tokenCount) {\n            return this.offsetAndType[offset - 1] & OFFSET_MASK;\n        }\n\n        return this.source.length;\n    }\n    lookupOffsetNonSC(idx) {\n        for (let offset = this.tokenIndex; offset < this.tokenCount; offset++) {\n            const tokenType = this.offsetAndType[offset] >> TYPE_SHIFT;\n\n            if (tokenType !== WhiteSpace$1 && tokenType !== Comment$1) {\n                if (idx-- === 0) {\n                    return offset - this.tokenIndex;\n                }\n            }\n        }\n\n        return EOF$1;\n    }\n    lookupValue(offset, referenceStr) {\n        offset += this.tokenIndex;\n\n        if (offset < this.tokenCount) {\n            return cmpStr(\n                this.source,\n                this.offsetAndType[offset - 1] & OFFSET_MASK,\n                this.offsetAndType[offset] & OFFSET_MASK,\n                referenceStr\n            );\n        }\n\n        return false;\n    }\n    getTokenStart(tokenIndex) {\n        if (tokenIndex === this.tokenIndex) {\n            return this.tokenStart;\n        }\n\n        if (tokenIndex > 0) {\n            return tokenIndex < this.tokenCount\n                ? this.offsetAndType[tokenIndex - 1] & OFFSET_MASK\n                : this.offsetAndType[this.tokenCount] & OFFSET_MASK;\n        }\n\n        return this.firstCharOffset;\n    }\n    getTokenEnd(tokenIndex) {\n        if (tokenIndex === this.tokenIndex) {\n            return this.tokenEnd;\n        }\n\n        return this.offsetAndType[boundIndex(tokenIndex, 0, this.tokenCount)] & OFFSET_MASK;\n    }\n    getTokenType(tokenIndex) {\n        if (tokenIndex === this.tokenIndex) {\n            return this.tokenType;\n        }\n\n        return this.offsetAndType[boundIndex(tokenIndex, 0, this.tokenCount)] >> TYPE_SHIFT;\n    }\n    substrToCursor(start) {\n        return this.source.substring(start, this.tokenStart);\n    }\n\n    isBlockOpenerTokenType(tokenType) {\n        return blockTokens[tokenType] === BLOCK_OPEN_TOKEN;\n    }\n    isBlockCloserTokenType(tokenType) {\n        return blockTokens[tokenType] === BLOCK_CLOSE_TOKEN;\n    }\n    getBlockTokenPairIndex(tokenIndex) {\n        const type = this.getTokenType(tokenIndex);\n\n        if (blockTokens[type] === 1) {\n            // block open token\n            const pairIndex = this.balance[tokenIndex];\n            const closeType = this.getTokenType(pairIndex);\n\n            return balancePair$1[type] === closeType ? pairIndex : -1;\n        } else if (blockTokens[type] === 2) {\n            // block close token\n            const pairIndex = this.balance[tokenIndex];\n            const openType = this.getTokenType(pairIndex);\n\n            return balancePair$1[openType] === type ? pairIndex : -1;\n        }\n\n        return -1;\n    }\n    isBalanceEdge(tokenIndex) {\n        return this.balance[this.tokenIndex] < tokenIndex;\n    }\n\n    isDelim(code, offset) {\n        if (offset) {\n            return (\n                this.lookupType(offset) === Delim &&\n                this.source.charCodeAt(this.lookupOffset(offset)) === code\n            );\n        }\n\n        return (\n            this.tokenType === Delim &&\n            this.source.charCodeAt(this.tokenStart) === code\n        );\n    }\n\n    skip(tokenCount) {\n        let next = this.tokenIndex + tokenCount;\n\n        if (next < this.tokenCount) {\n            this.tokenIndex = next;\n            this.tokenStart = this.offsetAndType[next - 1] & OFFSET_MASK;\n            next = this.offsetAndType[next];\n            this.tokenType = next >> TYPE_SHIFT;\n            this.tokenEnd = next & OFFSET_MASK;\n        } else {\n            this.tokenIndex = this.tokenCount;\n            this.next();\n        }\n    }\n    next() {\n        let next = this.tokenIndex + 1;\n\n        if (next < this.tokenCount) {\n            this.tokenIndex = next;\n            this.tokenStart = this.tokenEnd;\n            next = this.offsetAndType[next];\n            this.tokenType = next >> TYPE_SHIFT;\n            this.tokenEnd = next & OFFSET_MASK;\n        } else {\n            this.eof = true;\n            this.tokenIndex = this.tokenCount;\n            this.tokenType = EOF$1;\n            this.tokenStart = this.tokenEnd = this.source.length;\n        }\n    }\n    skipSC() {\n        while (this.tokenType === WhiteSpace$1 || this.tokenType === Comment$1) {\n            this.next();\n        }\n    }\n    skipUntilBalanced(startToken, stopConsume) {\n        let cursor = startToken;\n        let balanceEnd = 0;\n        let offset = 0;\n\n        loop:\n        for (; cursor < this.tokenCount; cursor++) {\n            balanceEnd = this.balance[cursor];\n\n            // stop scanning on balance edge that points to offset before start token\n            if (balanceEnd < startToken) {\n                break loop;\n            }\n\n            offset = cursor > 0 ? this.offsetAndType[cursor - 1] & OFFSET_MASK : this.firstCharOffset;\n\n            // check stop condition\n            switch (stopConsume(this.source.charCodeAt(offset))) {\n                case 1: // just stop\n                    break loop;\n\n                case 2: // stop & included\n                    cursor++;\n                    break loop;\n\n                default:\n                    // fast forward to the end of balanced block for an open block tokens\n                    if (this.isBlockOpenerTokenType(this.offsetAndType[cursor] >> TYPE_SHIFT)) {\n                        cursor = balanceEnd;\n                    }\n            }\n        }\n\n        this.skip(cursor - this.tokenIndex);\n    }\n\n    forEachToken(fn) {\n        for (let i = 0, offset = this.firstCharOffset; i < this.tokenCount; i++) {\n            const start = offset;\n            const item = this.offsetAndType[i];\n            const end = item & OFFSET_MASK;\n            const type = item >> TYPE_SHIFT;\n\n            offset = end;\n\n            fn(type, start, end, i);\n        }\n    }\n    dump() {\n        const tokens = new Array(this.tokenCount);\n\n        this.forEachToken((type, start, end, index) => {\n            tokens[index] = {\n                idx: index,\n                type: tokenNames[type],\n                chunk: this.source.substring(start, end),\n                balance: this.balance[index]\n            };\n        });\n\n        return tokens;\n    }\n}\n\nfunction tokenize$1(source, onToken) {\n    function getCharCode(offset) {\n        return offset < sourceLength ? source.charCodeAt(offset) : 0;\n    }\n\n    // § 4.3.3. Consume a numeric token\n    function consumeNumericToken() {\n        // Consume a number and let number be the result.\n        offset = consumeNumber(source, offset);\n\n        // If the next 3 input code points would start an identifier, then:\n        if (isIdentifierStart(getCharCode(offset), getCharCode(offset + 1), getCharCode(offset + 2))) {\n            // Create a <dimension-token> with the same value and type flag as number, and a unit set initially to the empty string.\n            // Consume a name. Set the <dimension-token>’s unit to the returned value.\n            // Return the <dimension-token>.\n            type = Dimension$1;\n            offset = consumeName(source, offset);\n            return;\n        }\n\n        // Otherwise, if the next input code point is U+0025 PERCENTAGE SIGN (%), consume it.\n        if (getCharCode(offset) === 0x0025) {\n            // Create a <percentage-token> with the same value as number, and return it.\n            type = Percentage$1;\n            offset++;\n            return;\n        }\n\n        // Otherwise, create a <number-token> with the same value and type flag as number, and return it.\n        type = Number$2;\n    }\n\n    // § 4.3.4. Consume an ident-like token\n    function consumeIdentLikeToken() {\n        const nameStartOffset = offset;\n\n        // Consume a name, and let string be the result.\n        offset = consumeName(source, offset);\n\n        // If string’s value is an ASCII case-insensitive match for \"url\",\n        // and the next input code point is U+0028 LEFT PARENTHESIS ((), consume it.\n        if (cmpStr(source, nameStartOffset, offset, 'url') && getCharCode(offset) === 0x0028) {\n            // While the next two input code points are whitespace, consume the next input code point.\n            offset = findWhiteSpaceEnd(source, offset + 1);\n\n            // If the next one or two input code points are U+0022 QUOTATION MARK (\"), U+0027 APOSTROPHE ('),\n            // or whitespace followed by U+0022 QUOTATION MARK (\") or U+0027 APOSTROPHE ('),\n            // then create a <function-token> with its value set to string and return it.\n            if (getCharCode(offset) === 0x0022 ||\n                getCharCode(offset) === 0x0027) {\n                type = Function$1;\n                offset = nameStartOffset + 4;\n                return;\n            }\n\n            // Otherwise, consume a url token, and return it.\n            consumeUrlToken();\n            return;\n        }\n\n        // Otherwise, if the next input code point is U+0028 LEFT PARENTHESIS ((), consume it.\n        // Create a <function-token> with its value set to string and return it.\n        if (getCharCode(offset) === 0x0028) {\n            type = Function$1;\n            offset++;\n            return;\n        }\n\n        // Otherwise, create an <ident-token> with its value set to string and return it.\n        type = Ident;\n    }\n\n    // § 4.3.5. Consume a string token\n    function consumeStringToken(endingCodePoint) {\n        // This algorithm may be called with an ending code point, which denotes the code point\n        // that ends the string. If an ending code point is not specified,\n        // the current input code point is used.\n        if (!endingCodePoint) {\n            endingCodePoint = getCharCode(offset++);\n        }\n\n        // Initially create a <string-token> with its value set to the empty string.\n        type = String$2;\n\n        // Repeatedly consume the next input code point from the stream:\n        for (; offset < source.length; offset++) {\n            const code = source.charCodeAt(offset);\n\n            switch (charCodeCategory(code)) {\n                // ending code point\n                case endingCodePoint:\n                    // Return the <string-token>.\n                    offset++;\n                    return;\n\n                    // EOF\n                    // case EofCategory:\n                    // This is a parse error. Return the <string-token>.\n                    // return;\n\n                // newline\n                case WhiteSpaceCategory:\n                    if (isNewline(code)) {\n                        // This is a parse error. Reconsume the current input code point,\n                        // create a <bad-string-token>, and return it.\n                        offset += getNewlineLength(source, offset, code);\n                        type = BadString;\n                        return;\n                    }\n                    break;\n\n                // U+005C REVERSE SOLIDUS (\\)\n                case 0x005C:\n                    // If the next input code point is EOF, do nothing.\n                    if (offset === source.length - 1) {\n                        break;\n                    }\n\n                    const nextCode = getCharCode(offset + 1);\n\n                    // Otherwise, if the next input code point is a newline, consume it.\n                    if (isNewline(nextCode)) {\n                        offset += getNewlineLength(source, offset + 1, nextCode);\n                    } else if (isValidEscape(code, nextCode)) {\n                        // Otherwise, (the stream starts with a valid escape) consume\n                        // an escaped code point and append the returned code point to\n                        // the <string-token>’s value.\n                        offset = consumeEscaped(source, offset) - 1;\n                    }\n                    break;\n\n                // anything else\n                // Append the current input code point to the <string-token>’s value.\n            }\n        }\n    }\n\n    // § 4.3.6. Consume a url token\n    // Note: This algorithm assumes that the initial \"url(\" has already been consumed.\n    // This algorithm also assumes that it’s being called to consume an \"unquoted\" value, like url(foo).\n    // A quoted value, like url(\"foo\"), is parsed as a <function-token>. Consume an ident-like token\n    // automatically handles this distinction; this algorithm shouldn’t be called directly otherwise.\n    function consumeUrlToken() {\n        // Initially create a <url-token> with its value set to the empty string.\n        type = Url$1;\n\n        // Consume as much whitespace as possible.\n        offset = findWhiteSpaceEnd(source, offset);\n\n        // Repeatedly consume the next input code point from the stream:\n        for (; offset < source.length; offset++) {\n            const code = source.charCodeAt(offset);\n\n            switch (charCodeCategory(code)) {\n                // U+0029 RIGHT PARENTHESIS ())\n                case 0x0029:\n                    // Return the <url-token>.\n                    offset++;\n                    return;\n\n                    // EOF\n                    // case EofCategory:\n                    // This is a parse error. Return the <url-token>.\n                    // return;\n\n                // whitespace\n                case WhiteSpaceCategory:\n                    // Consume as much whitespace as possible.\n                    offset = findWhiteSpaceEnd(source, offset);\n\n                    // If the next input code point is U+0029 RIGHT PARENTHESIS ()) or EOF,\n                    // consume it and return the <url-token>\n                    // (if EOF was encountered, this is a parse error);\n                    if (getCharCode(offset) === 0x0029 || offset >= source.length) {\n                        if (offset < source.length) {\n                            offset++;\n                        }\n                        return;\n                    }\n\n                    // otherwise, consume the remnants of a bad url, create a <bad-url-token>,\n                    // and return it.\n                    offset = consumeBadUrlRemnants(source, offset);\n                    type = BadUrl;\n                    return;\n\n                // U+0022 QUOTATION MARK (\")\n                // U+0027 APOSTROPHE (')\n                // U+0028 LEFT PARENTHESIS (()\n                // non-printable code point\n                case 0x0022:\n                case 0x0027:\n                case 0x0028:\n                case NonPrintableCategory:\n                    // This is a parse error. Consume the remnants of a bad url,\n                    // create a <bad-url-token>, and return it.\n                    offset = consumeBadUrlRemnants(source, offset);\n                    type = BadUrl;\n                    return;\n\n                // U+005C REVERSE SOLIDUS (\\)\n                case 0x005C:\n                    // If the stream starts with a valid escape, consume an escaped code point and\n                    // append the returned code point to the <url-token>’s value.\n                    if (isValidEscape(code, getCharCode(offset + 1))) {\n                        offset = consumeEscaped(source, offset) - 1;\n                        break;\n                    }\n\n                    // Otherwise, this is a parse error. Consume the remnants of a bad url,\n                    // create a <bad-url-token>, and return it.\n                    offset = consumeBadUrlRemnants(source, offset);\n                    type = BadUrl;\n                    return;\n\n                // anything else\n                // Append the current input code point to the <url-token>’s value.\n            }\n        }\n    }\n\n    // ensure source is a string\n    source = String(source || '');\n\n    const sourceLength = source.length;\n    let start = isBOM(getCharCode(0));\n    let offset = start;\n    let type;\n\n    // https://drafts.csswg.org/css-syntax-3/#consume-token\n    // § 4.3.1. Consume a token\n    while (offset < sourceLength) {\n        const code = source.charCodeAt(offset);\n\n        switch (charCodeCategory(code)) {\n            // whitespace\n            case WhiteSpaceCategory:\n                // Consume as much whitespace as possible. Return a <whitespace-token>.\n                type = WhiteSpace$1;\n                offset = findWhiteSpaceEnd(source, offset + 1);\n                break;\n\n            // U+0022 QUOTATION MARK (\")\n            case 0x0022:\n                // Consume a string token and return it.\n                consumeStringToken();\n                break;\n\n            // U+0023 NUMBER SIGN (#)\n            case 0x0023:\n                // If the next input code point is a name code point or the next two input code points are a valid escape, then:\n                if (isName(getCharCode(offset + 1)) || isValidEscape(getCharCode(offset + 1), getCharCode(offset + 2))) {\n                    // Create a <hash-token>.\n                    type = Hash$1;\n\n                    // If the next 3 input code points would start an identifier, set the <hash-token>’s type flag to \"id\".\n                    // if (isIdentifierStart(getCharCode(offset + 1), getCharCode(offset + 2), getCharCode(offset + 3))) {\n                    //     // TODO: set id flag\n                    // }\n\n                    // Consume a name, and set the <hash-token>’s value to the returned string.\n                    offset = consumeName(source, offset + 1);\n\n                    // Return the <hash-token>.\n                } else {\n                    // Otherwise, return a <delim-token> with its value set to the current input code point.\n                    type = Delim;\n                    offset++;\n                }\n\n                break;\n\n            // U+0027 APOSTROPHE (')\n            case 0x0027:\n                // Consume a string token and return it.\n                consumeStringToken();\n                break;\n\n            // U+0028 LEFT PARENTHESIS (()\n            case 0x0028:\n                // Return a <(-token>.\n                type = LeftParenthesis;\n                offset++;\n                break;\n\n            // U+0029 RIGHT PARENTHESIS ())\n            case 0x0029:\n                // Return a <)-token>.\n                type = RightParenthesis;\n                offset++;\n                break;\n\n            // U+002B PLUS SIGN (+)\n            case 0x002B:\n                // If the input stream starts with a number, ...\n                if (isNumberStart(code, getCharCode(offset + 1), getCharCode(offset + 2))) {\n                    // ... reconsume the current input code point, consume a numeric token, and return it.\n                    consumeNumericToken();\n                } else {\n                    // Otherwise, return a <delim-token> with its value set to the current input code point.\n                    type = Delim;\n                    offset++;\n                }\n                break;\n\n            // U+002C COMMA (,)\n            case 0x002C:\n                // Return a <comma-token>.\n                type = Comma;\n                offset++;\n                break;\n\n            // U+002D HYPHEN-MINUS (-)\n            case 0x002D:\n                // If the input stream starts with a number, reconsume the current input code point, consume a numeric token, and return it.\n                if (isNumberStart(code, getCharCode(offset + 1), getCharCode(offset + 2))) {\n                    consumeNumericToken();\n                } else {\n                    // Otherwise, if the next 2 input code points are U+002D HYPHEN-MINUS U+003E GREATER-THAN SIGN (->), consume them and return a <CDC-token>.\n                    if (getCharCode(offset + 1) === 0x002D &&\n                        getCharCode(offset + 2) === 0x003E) {\n                        type = CDC$1;\n                        offset = offset + 3;\n                    } else {\n                        // Otherwise, if the input stream starts with an identifier, ...\n                        if (isIdentifierStart(code, getCharCode(offset + 1), getCharCode(offset + 2))) {\n                            // ... reconsume the current input code point, consume an ident-like token, and return it.\n                            consumeIdentLikeToken();\n                        } else {\n                            // Otherwise, return a <delim-token> with its value set to the current input code point.\n                            type = Delim;\n                            offset++;\n                        }\n                    }\n                }\n                break;\n\n            // U+002E FULL STOP (.)\n            case 0x002E:\n                // If the input stream starts with a number, ...\n                if (isNumberStart(code, getCharCode(offset + 1), getCharCode(offset + 2))) {\n                    // ... reconsume the current input code point, consume a numeric token, and return it.\n                    consumeNumericToken();\n                } else {\n                    // Otherwise, return a <delim-token> with its value set to the current input code point.\n                    type = Delim;\n                    offset++;\n                }\n\n                break;\n\n            // U+002F SOLIDUS (/)\n            case 0x002F:\n                // If the next two input code point are U+002F SOLIDUS (/) followed by a U+002A ASTERISK (*),\n                if (getCharCode(offset + 1) === 0x002A) {\n                    // ... consume them and all following code points up to and including the first U+002A ASTERISK (*)\n                    // followed by a U+002F SOLIDUS (/), or up to an EOF code point.\n                    type = Comment$1;\n                    offset = source.indexOf('*/', offset + 2);\n                    offset = offset === -1 ? source.length : offset + 2;\n                } else {\n                    type = Delim;\n                    offset++;\n                }\n                break;\n\n            // U+003A COLON (:)\n            case 0x003A:\n                // Return a <colon-token>.\n                type = Colon;\n                offset++;\n                break;\n\n            // U+003B SEMICOLON (;)\n            case 0x003B:\n                // Return a <semicolon-token>.\n                type = Semicolon;\n                offset++;\n                break;\n\n            // U+003C LESS-THAN SIGN (<)\n            case 0x003C:\n                // If the next 3 input code points are U+0021 EXCLAMATION MARK U+002D HYPHEN-MINUS U+002D HYPHEN-MINUS (!--), ...\n                if (getCharCode(offset + 1) === 0x0021 &&\n                    getCharCode(offset + 2) === 0x002D &&\n                    getCharCode(offset + 3) === 0x002D) {\n                    // ... consume them and return a <CDO-token>.\n                    type = CDO$1;\n                    offset = offset + 4;\n                } else {\n                    // Otherwise, return a <delim-token> with its value set to the current input code point.\n                    type = Delim;\n                    offset++;\n                }\n\n                break;\n\n            // U+0040 COMMERCIAL AT (@)\n            case 0x0040:\n                // If the next 3 input code points would start an identifier, ...\n                if (isIdentifierStart(getCharCode(offset + 1), getCharCode(offset + 2), getCharCode(offset + 3))) {\n                    // ... consume a name, create an <at-keyword-token> with its value set to the returned value, and return it.\n                    type = AtKeyword;\n                    offset = consumeName(source, offset + 1);\n                } else {\n                    // Otherwise, return a <delim-token> with its value set to the current input code point.\n                    type = Delim;\n                    offset++;\n                }\n\n                break;\n\n            // U+005B LEFT SQUARE BRACKET ([)\n            case 0x005B:\n                // Return a <[-token>.\n                type = LeftSquareBracket;\n                offset++;\n                break;\n\n            // U+005C REVERSE SOLIDUS (\\)\n            case 0x005C:\n                // If the input stream starts with a valid escape, ...\n                if (isValidEscape(code, getCharCode(offset + 1))) {\n                    // ... reconsume the current input code point, consume an ident-like token, and return it.\n                    consumeIdentLikeToken();\n                } else {\n                    // Otherwise, this is a parse error. Return a <delim-token> with its value set to the current input code point.\n                    type = Delim;\n                    offset++;\n                }\n                break;\n\n            // U+005D RIGHT SQUARE BRACKET (])\n            case 0x005D:\n                // Return a <]-token>.\n                type = RightSquareBracket;\n                offset++;\n                break;\n\n            // U+007B LEFT CURLY BRACKET ({)\n            case 0x007B:\n                // Return a <{-token>.\n                type = LeftCurlyBracket;\n                offset++;\n                break;\n\n            // U+007D RIGHT CURLY BRACKET (})\n            case 0x007D:\n                // Return a <}-token>.\n                type = RightCurlyBracket;\n                offset++;\n                break;\n\n            // digit\n            case DigitCategory:\n                // Reconsume the current input code point, consume a numeric token, and return it.\n                consumeNumericToken();\n                break;\n\n            // name-start code point\n            case NameStartCategory:\n                // Reconsume the current input code point, consume an ident-like token, and return it.\n                consumeIdentLikeToken();\n                break;\n\n                // EOF\n                // case EofCategory:\n                // Return an <EOF-token>.\n                // break;\n\n            // anything else\n            default:\n                // Return a <delim-token> with its value set to the current input code point.\n                type = Delim;\n                offset++;\n        }\n\n        // put token to stream\n        onToken(type, start, start = offset);\n    }\n}\n\n//\n//                              list\n//                            ┌──────┐\n//             ┌──────────────┼─head │\n//             │              │ tail─┼──────────────┐\n//             │              └──────┘              │\n//             ▼                                    ▼\n//            item        item        item        item\n//          ┌──────┐    ┌──────┐    ┌──────┐    ┌──────┐\n//  null ◀──┼─prev │◀───┼─prev │◀───┼─prev │◀───┼─prev │\n//          │ next─┼───▶│ next─┼───▶│ next─┼───▶│ next─┼──▶ null\n//          ├──────┤    ├──────┤    ├──────┤    ├──────┤\n//          │ data │    │ data │    │ data │    │ data │\n//          └──────┘    └──────┘    └──────┘    └──────┘\n//\n\nlet releasedCursors = null;\n\nclass List {\n    static createItem(data) {\n        return {\n            prev: null,\n            next: null,\n            data\n        };\n    }\n\n    constructor() {\n        this.head = null;\n        this.tail = null;\n        this.cursor = null;\n    }\n    createItem(data) {\n        return List.createItem(data);\n    }\n\n    // cursor helpers\n    allocateCursor(prev, next) {\n        let cursor;\n\n        if (releasedCursors !== null) {\n            cursor = releasedCursors;\n            releasedCursors = releasedCursors.cursor;\n            cursor.prev = prev;\n            cursor.next = next;\n            cursor.cursor = this.cursor;\n        } else {\n            cursor = {\n                prev,\n                next,\n                cursor: this.cursor\n            };\n        }\n\n        this.cursor = cursor;\n\n        return cursor;\n    }\n    releaseCursor() {\n        const { cursor } = this;\n\n        this.cursor = cursor.cursor;\n        cursor.prev = null;\n        cursor.next = null;\n        cursor.cursor = releasedCursors;\n        releasedCursors = cursor;\n    }\n    updateCursors(prevOld, prevNew, nextOld, nextNew) {\n        let { cursor } = this;\n\n        while (cursor !== null) {\n            if (cursor.prev === prevOld) {\n                cursor.prev = prevNew;\n            }\n\n            if (cursor.next === nextOld) {\n                cursor.next = nextNew;\n            }\n\n            cursor = cursor.cursor;\n        }\n    }\n    *[Symbol.iterator]() {\n        for (let cursor = this.head; cursor !== null; cursor = cursor.next) {\n            yield cursor.data;\n        }\n    }\n\n    // getters\n    get size() {\n        let size = 0;\n\n        for (let cursor = this.head; cursor !== null; cursor = cursor.next) {\n            size++;\n        }\n\n        return size;\n    }\n    get isEmpty() {\n        return this.head === null;\n    }\n    get first() {\n        return this.head && this.head.data;\n    }\n    get last() {\n        return this.tail && this.tail.data;\n    }\n\n    // convertors\n    fromArray(array) {\n        let cursor = null;\n        this.head = null;\n\n        for (let data of array) {\n            const item = List.createItem(data);\n\n            if (cursor !== null) {\n                cursor.next = item;\n            } else {\n                this.head = item;\n            }\n\n            item.prev = cursor;\n            cursor = item;\n        }\n\n        this.tail = cursor;\n        return this;\n    }\n    toArray() {\n        return [...this];\n    }\n    toJSON() {\n        return [...this];\n    }\n\n    // array-like methods\n    forEach(fn, thisArg = this) {\n        // push cursor\n        const cursor = this.allocateCursor(null, this.head);\n\n        while (cursor.next !== null) {\n            const item = cursor.next;\n            cursor.next = item.next;\n            fn.call(thisArg, item.data, item, this);\n        }\n\n        // pop cursor\n        this.releaseCursor();\n    }\n    forEachRight(fn, thisArg = this) {\n        // push cursor\n        const cursor = this.allocateCursor(this.tail, null);\n\n        while (cursor.prev !== null) {\n            const item = cursor.prev;\n            cursor.prev = item.prev;\n            fn.call(thisArg, item.data, item, this);\n        }\n\n        // pop cursor\n        this.releaseCursor();\n    }\n    reduce(fn, initialValue, thisArg = this) {\n        // push cursor\n        let cursor = this.allocateCursor(null, this.head);\n        let acc = initialValue;\n        let item;\n\n        while (cursor.next !== null) {\n            item = cursor.next;\n            cursor.next = item.next;\n\n            acc = fn.call(thisArg, acc, item.data, item, this);\n        }\n\n        // pop cursor\n        this.releaseCursor();\n\n        return acc;\n    }\n    reduceRight(fn, initialValue, thisArg = this) {\n        // push cursor\n        let cursor = this.allocateCursor(this.tail, null);\n        let acc = initialValue;\n        let item;\n\n        while (cursor.prev !== null) {\n            item = cursor.prev;\n            cursor.prev = item.prev;\n\n            acc = fn.call(thisArg, acc, item.data, item, this);\n        }\n\n        // pop cursor\n        this.releaseCursor();\n\n        return acc;\n    }\n    some(fn, thisArg = this) {\n        for (let cursor = this.head; cursor !== null; cursor = cursor.next) {\n            if (fn.call(thisArg, cursor.data, cursor, this)) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n    map(fn, thisArg = this) {\n        const result = new List();\n\n        for (let cursor = this.head; cursor !== null; cursor = cursor.next) {\n            result.appendData(fn.call(thisArg, cursor.data, cursor, this));\n        }\n\n        return result;\n    }\n    filter(fn, thisArg = this) {\n        const result = new List();\n\n        for (let cursor = this.head; cursor !== null; cursor = cursor.next) {\n            if (fn.call(thisArg, cursor.data, cursor, this)) {\n                result.appendData(cursor.data);\n            }\n        }\n\n        return result;\n    }\n\n    nextUntil(start, fn, thisArg = this) {\n        if (start === null) {\n            return;\n        }\n\n        // push cursor\n        const cursor = this.allocateCursor(null, start);\n\n        while (cursor.next !== null) {\n            const item = cursor.next;\n            cursor.next = item.next;\n            if (fn.call(thisArg, item.data, item, this)) {\n                break;\n            }\n        }\n\n        // pop cursor\n        this.releaseCursor();\n    }\n    prevUntil(start, fn, thisArg = this) {\n        if (start === null) {\n            return;\n        }\n\n        // push cursor\n        const cursor = this.allocateCursor(start, null);\n\n        while (cursor.prev !== null) {\n            const item = cursor.prev;\n            cursor.prev = item.prev;\n            if (fn.call(thisArg, item.data, item, this)) {\n                break;\n            }\n        }\n\n        // pop cursor\n        this.releaseCursor();\n    }\n\n    // mutation\n    clear() {\n        this.head = null;\n        this.tail = null;\n    }\n    copy() {\n        const result = new List();\n\n        for (let data of this) {\n            result.appendData(data);\n        }\n\n        return result;\n    }\n    prepend(item) {\n        //      head\n        //    ^\n        // item\n        this.updateCursors(null, item, this.head, item);\n\n        // insert to the beginning of the list\n        if (this.head !== null) {\n            // new item <- first item\n            this.head.prev = item;\n            // new item -> first item\n            item.next = this.head;\n        } else {\n            // if list has no head, then it also has no tail\n            // in this case tail points to the new item\n            this.tail = item;\n        }\n\n        // head always points to new item\n        this.head = item;\n        return this;\n    }\n    prependData(data) {\n        return this.prepend(List.createItem(data));\n    }\n    append(item) {\n        return this.insert(item);\n    }\n    appendData(data) {\n        return this.insert(List.createItem(data));\n    }\n    insert(item, before = null) {\n        if (before !== null) {\n            // prev   before\n            //      ^\n            //     item\n            this.updateCursors(before.prev, item, before, item);\n\n            if (before.prev === null) {\n                // insert to the beginning of list\n                if (this.head !== before) {\n                    throw new Error('before doesn\\'t belong to list');\n                }\n                // since head points to before therefore list doesn't empty\n                // no need to check tail\n                this.head = item;\n                before.prev = item;\n                item.next = before;\n                this.updateCursors(null, item);\n            } else {\n                // insert between two items\n                before.prev.next = item;\n                item.prev = before.prev;\n                before.prev = item;\n                item.next = before;\n            }\n        } else {\n            // tail\n            //      ^\n            //      item\n            this.updateCursors(this.tail, item, null, item);\n\n            // insert to the ending of the list\n            if (this.tail !== null) {\n                // last item -> new item\n                this.tail.next = item;\n                // last item <- new item\n                item.prev = this.tail;\n            } else {\n                // if list has no tail, then it also has no head\n                // in this case head points to new item\n                this.head = item;\n            }\n\n            // tail always points to new item\n            this.tail = item;\n        }\n\n        return this;\n    }\n    insertData(data, before) {\n        return this.insert(List.createItem(data), before);\n    }\n    remove(item) {\n        //      item\n        //       ^\n        // prev     next\n        this.updateCursors(item, item.prev, item, item.next);\n\n        if (item.prev !== null) {\n            item.prev.next = item.next;\n        } else {\n            if (this.head !== item) {\n                throw new Error('item doesn\\'t belong to list');\n            }\n\n            this.head = item.next;\n        }\n\n        if (item.next !== null) {\n            item.next.prev = item.prev;\n        } else {\n            if (this.tail !== item) {\n                throw new Error('item doesn\\'t belong to list');\n            }\n\n            this.tail = item.prev;\n        }\n\n        item.prev = null;\n        item.next = null;\n\n        return item;\n    }\n    push(data) {\n        this.insert(List.createItem(data));\n    }\n    pop() {\n        return this.tail !== null ? this.remove(this.tail) : null;\n    }\n    unshift(data) {\n        this.prepend(List.createItem(data));\n    }\n    shift() {\n        return this.head !== null ? this.remove(this.head) : null;\n    }\n    prependList(list) {\n        return this.insertList(list, this.head);\n    }\n    appendList(list) {\n        return this.insertList(list);\n    }\n    insertList(list, before) {\n        // ignore empty lists\n        if (list.head === null) {\n            return this;\n        }\n\n        if (before !== undefined && before !== null) {\n            this.updateCursors(before.prev, list.tail, before, list.head);\n\n            // insert in the middle of dist list\n            if (before.prev !== null) {\n                // before.prev <-> list.head\n                before.prev.next = list.head;\n                list.head.prev = before.prev;\n            } else {\n                this.head = list.head;\n            }\n\n            before.prev = list.tail;\n            list.tail.next = before;\n        } else {\n            this.updateCursors(this.tail, list.tail, null, list.head);\n\n            // insert to end of the list\n            if (this.tail !== null) {\n                // if destination list has a tail, then it also has a head,\n                // but head doesn't change\n                // dest tail -> source head\n                this.tail.next = list.head;\n                // dest tail <- source head\n                list.head.prev = this.tail;\n            } else {\n                // if list has no a tail, then it also has no a head\n                // in this case points head to new item\n                this.head = list.head;\n            }\n\n            // tail always start point to new item\n            this.tail = list.tail;\n        }\n\n        list.head = null;\n        list.tail = null;\n        return this;\n    }\n    replace(oldItem, newItemOrList) {\n        if ('head' in newItemOrList) {\n            this.insertList(newItemOrList, oldItem);\n        } else {\n            this.insert(newItemOrList, oldItem);\n        }\n\n        this.remove(oldItem);\n    }\n}\n\nfunction createCustomError(name, message) {\n    // use Object.create(), because some VMs prevent setting line/column otherwise\n    // (iOS Safari 10 even throws an exception)\n    const error = Object.create(SyntaxError.prototype);\n    const errorStack = new Error();\n\n    return Object.assign(error, {\n        name,\n        message,\n        get stack() {\n            return (errorStack.stack || '').replace(/^(.+\\n){1,3}/, `${name}: ${message}\\n`);\n        }\n    });\n}\n\nconst MAX_LINE_LENGTH = 100;\nconst OFFSET_CORRECTION = 60;\nconst TAB_REPLACEMENT = '    ';\n\nfunction sourceFragment({ source, line, column, baseLine, baseColumn }, extraLines) {\n    function processLines(start, end) {\n        return lines\n            .slice(start, end)\n            .map((line, idx) =>\n                String(start + idx + 1).padStart(maxNumLength) + ' |' + line\n            ).join('\\n');\n    }\n\n    const prelines = '\\n'.repeat(Math.max(baseLine - 1, 0));\n    const precolumns = ' '.repeat(Math.max(baseColumn - 1, 0));\n    const lines = (prelines + precolumns + source).split(/\\r\\n?|\\n|\\f/);\n    const startLine = Math.max(1, line - extraLines) - 1;\n    const endLine = Math.min(line + extraLines, lines.length + 1);\n    const maxNumLength = Math.max(4, String(endLine).length) + 1;\n    let cutLeft = 0;\n\n    // column correction according to replaced tab before column\n    column += (TAB_REPLACEMENT.length - 1) * (lines[line - 1].substr(0, column - 1).match(/\\t/g) || []).length;\n\n    if (column > MAX_LINE_LENGTH) {\n        cutLeft = column - OFFSET_CORRECTION + 3;\n        column = OFFSET_CORRECTION - 2;\n    }\n\n    for (let i = startLine; i <= endLine; i++) {\n        if (i >= 0 && i < lines.length) {\n            lines[i] = lines[i].replace(/\\t/g, TAB_REPLACEMENT);\n            lines[i] =\n                (cutLeft > 0 && lines[i].length > cutLeft ? '\\u2026' : '') +\n                lines[i].substr(cutLeft, MAX_LINE_LENGTH - 2) +\n                (lines[i].length > cutLeft + MAX_LINE_LENGTH - 1 ? '\\u2026' : '');\n        }\n    }\n\n    return [\n        processLines(startLine, line),\n        new Array(column + maxNumLength + 2).join('-') + '^',\n        processLines(line, endLine)\n    ].filter(Boolean)\n        .join('\\n')\n        .replace(/^(\\s+\\d+\\s+\\|\\n)+/, '')\n        .replace(/\\n(\\s+\\d+\\s+\\|)+$/, '');\n}\n\nfunction SyntaxError$2(message, source, offset, line, column, baseLine = 1, baseColumn = 1) {\n    const error = Object.assign(createCustomError('SyntaxError', message), {\n        source,\n        offset,\n        line,\n        column,\n        sourceFragment(extraLines) {\n            return sourceFragment({ source, line, column, baseLine, baseColumn }, isNaN(extraLines) ? 0 : extraLines);\n        },\n        get formattedMessage() {\n            return (\n                `Parse error: ${message}\\n` +\n                sourceFragment({ source, line, column, baseLine, baseColumn }, 2)\n            );\n        }\n    });\n\n    return error;\n}\n\nfunction readSequence(recognizer) {\n    const children = this.createList();\n    let space = false;\n    const context = {\n        recognizer\n    };\n\n    while (!this.eof) {\n        switch (this.tokenType) {\n            case Comment$1:\n                this.next();\n                continue;\n\n            case WhiteSpace$1:\n                space = true;\n                this.next();\n                continue;\n        }\n\n        let child = recognizer.getNode.call(this, context);\n\n        if (child === undefined) {\n            break;\n        }\n\n        if (space) {\n            if (recognizer.onWhiteSpace) {\n                recognizer.onWhiteSpace.call(this, child, children, context);\n            }\n            space = false;\n        }\n\n        children.push(child);\n    }\n\n    if (space && recognizer.onWhiteSpace) {\n        recognizer.onWhiteSpace.call(this, null, children, context);\n    }\n\n    return children;\n}\n\nconst NOOP = () => {};\nconst EXCLAMATIONMARK$3 = 0x0021;  // U+0021 EXCLAMATION MARK (!)\nconst NUMBERSIGN$4 = 0x0023;       // U+0023 NUMBER SIGN (#)\nconst SEMICOLON = 0x003B;        // U+003B SEMICOLON (;)\nconst LEFTCURLYBRACKET$1 = 0x007B; // U+007B LEFT CURLY BRACKET ({)\nconst NULL = 0;\n\nfunction createParseContext(name) {\n    return function() {\n        return this[name]();\n    };\n}\n\nfunction fetchParseValues(dict) {\n    const result = Object.create(null);\n\n    for (const name of Object.keys(dict)) {\n        const item = dict[name];\n        const fn = item.parse || item;\n\n        if (fn) {\n            result[name] = fn;\n        }\n    }\n\n    return result;\n}\n\nfunction processConfig(config) {\n    const parseConfig = {\n        context: Object.create(null),\n        features: Object.assign(Object.create(null), config.features),\n        scope: Object.assign(Object.create(null), config.scope),\n        atrule: fetchParseValues(config.atrule),\n        pseudo: fetchParseValues(config.pseudo),\n        node: fetchParseValues(config.node)\n    };\n\n    for (const [name, context] of Object.entries(config.parseContext)) {\n        switch (typeof context) {\n            case 'function':\n                parseConfig.context[name] = context;\n                break;\n\n            case 'string':\n                parseConfig.context[name] = createParseContext(context);\n                break;\n        }\n    }\n\n    return {\n        config: parseConfig,\n        ...parseConfig,\n        ...parseConfig.node\n    };\n}\n\nfunction createParser(config) {\n    let source = '';\n    let filename = '<unknown>';\n    let needPositions = false;\n    let onParseError = NOOP;\n    let onParseErrorThrow = false;\n\n    const locationMap = new OffsetToLocation();\n    const parser = Object.assign(new TokenStream(), processConfig(config || {}), {\n        parseAtrulePrelude: true,\n        parseRulePrelude: true,\n        parseValue: true,\n        parseCustomProperty: false,\n\n        readSequence,\n\n        consumeUntilBalanceEnd: () => 0,\n        consumeUntilLeftCurlyBracket(code) {\n            return code === LEFTCURLYBRACKET$1 ? 1 : 0;\n        },\n        consumeUntilLeftCurlyBracketOrSemicolon(code) {\n            return code === LEFTCURLYBRACKET$1 || code === SEMICOLON ? 1 : 0;\n        },\n        consumeUntilExclamationMarkOrSemicolon(code) {\n            return code === EXCLAMATIONMARK$3 || code === SEMICOLON ? 1 : 0;\n        },\n        consumeUntilSemicolonIncluded(code) {\n            return code === SEMICOLON ? 2 : 0;\n        },\n\n        createList() {\n            return new List();\n        },\n        createSingleNodeList(node) {\n            return new List().appendData(node);\n        },\n        getFirstListNode(list) {\n            return list && list.first;\n        },\n        getLastListNode(list) {\n            return list && list.last;\n        },\n\n        parseWithFallback(consumer, fallback) {\n            const startIndex = this.tokenIndex;\n\n            try {\n                return consumer.call(this);\n            } catch (e) {\n                if (onParseErrorThrow) {\n                    throw e;\n                }\n\n                this.skip(startIndex - this.tokenIndex);\n                const fallbackNode = fallback.call(this);\n\n                onParseErrorThrow = true;\n                onParseError(e, fallbackNode);\n                onParseErrorThrow = false;\n\n                return fallbackNode;\n            }\n        },\n\n        lookupNonWSType(offset) {\n            let type;\n\n            do {\n                type = this.lookupType(offset++);\n                if (type !== WhiteSpace$1 && type !== Comment$1) {\n                    return type;\n                }\n            } while (type !== NULL);\n\n            return NULL;\n        },\n\n        charCodeAt(offset) {\n            return offset >= 0 && offset < source.length ? source.charCodeAt(offset) : 0;\n        },\n        substring(offsetStart, offsetEnd) {\n            return source.substring(offsetStart, offsetEnd);\n        },\n        substrToCursor(start) {\n            return this.source.substring(start, this.tokenStart);\n        },\n\n        cmpChar(offset, charCode) {\n            return cmpChar(source, offset, charCode);\n        },\n        cmpStr(offsetStart, offsetEnd, str) {\n            return cmpStr(source, offsetStart, offsetEnd, str);\n        },\n\n        consume(tokenType) {\n            const start = this.tokenStart;\n\n            this.eat(tokenType);\n\n            return this.substrToCursor(start);\n        },\n        consumeFunctionName() {\n            const name = source.substring(this.tokenStart, this.tokenEnd - 1);\n\n            this.eat(Function$1);\n\n            return name;\n        },\n        consumeNumber(type) {\n            const number = source.substring(this.tokenStart, consumeNumber(source, this.tokenStart));\n\n            this.eat(type);\n\n            return number;\n        },\n\n        eat(tokenType) {\n            if (this.tokenType !== tokenType) {\n                const tokenName = tokenNames[tokenType].slice(0, -6).replace(/-/g, ' ').replace(/^./, m => m.toUpperCase());\n                let message = `${/[[\\](){}]/.test(tokenName) ? `\"${tokenName}\"` : tokenName} is expected`;\n                let offset = this.tokenStart;\n\n                // tweak message and offset\n                switch (tokenType) {\n                    case Ident:\n                        // when identifier is expected but there is a function or url\n                        if (this.tokenType === Function$1 || this.tokenType === Url$1) {\n                            offset = this.tokenEnd - 1;\n                            message = 'Identifier is expected but function found';\n                        } else {\n                            message = 'Identifier is expected';\n                        }\n                        break;\n\n                    case Hash$1:\n                        if (this.isDelim(NUMBERSIGN$4)) {\n                            this.next();\n                            offset++;\n                            message = 'Name is expected';\n                        }\n                        break;\n\n                    case Percentage$1:\n                        if (this.tokenType === Number$2) {\n                            offset = this.tokenEnd;\n                            message = 'Percent sign is expected';\n                        }\n                        break;\n                }\n\n                this.error(message, offset);\n            }\n\n            this.next();\n        },\n        eatIdent(name) {\n            if (this.tokenType !== Ident || this.lookupValue(0, name) === false) {\n                this.error(`Identifier \"${name}\" is expected`);\n            }\n\n            this.next();\n        },\n        eatDelim(code) {\n            if (!this.isDelim(code)) {\n                this.error(`Delim \"${String.fromCharCode(code)}\" is expected`);\n            }\n\n            this.next();\n        },\n\n        getLocation(start, end) {\n            if (needPositions) {\n                return locationMap.getLocationRange(\n                    start,\n                    end,\n                    filename\n                );\n            }\n\n            return null;\n        },\n        getLocationFromList(list) {\n            if (needPositions) {\n                const head = this.getFirstListNode(list);\n                const tail = this.getLastListNode(list);\n                return locationMap.getLocationRange(\n                    head !== null ? head.loc.start.offset - locationMap.startOffset : this.tokenStart,\n                    tail !== null ? tail.loc.end.offset - locationMap.startOffset : this.tokenStart,\n                    filename\n                );\n            }\n\n            return null;\n        },\n\n        error(message, offset) {\n            const location = typeof offset !== 'undefined' && offset < source.length\n                ? locationMap.getLocation(offset)\n                : this.eof\n                    ? locationMap.getLocation(findWhiteSpaceStart(source, source.length - 1))\n                    : locationMap.getLocation(this.tokenStart);\n\n            throw new SyntaxError$2(\n                message || 'Unexpected input',\n                source,\n                location.offset,\n                location.line,\n                location.column,\n                locationMap.startLine,\n                locationMap.startColumn\n            );\n        }\n    });\n    const createTokenIterateAPI = () => ({\n        filename,\n        source,\n        tokenCount: parser.tokenCount,\n\n        getTokenType: (index) =>\n            parser.getTokenType(index),\n        getTokenTypeName: (index) =>\n            tokenNames[parser.getTokenType(index)],\n        getTokenStart: (index) =>\n            parser.getTokenStart(index),\n        getTokenEnd: (index) =>\n            parser.getTokenEnd(index),\n        getTokenValue: (index) =>\n            parser.source.substring(parser.getTokenStart(index), parser.getTokenEnd(index)),\n\n        substring: (start, end) =>\n            parser.source.substring(start, end),\n\n        balance: parser.balance.subarray(0, parser.tokenCount + 1),\n        isBlockOpenerTokenType: parser.isBlockOpenerTokenType,\n        isBlockCloserTokenType: parser.isBlockCloserTokenType,\n        getBlockTokenPairIndex: (index) =>\n            parser.getBlockTokenPairIndex(index),\n\n        getLocation: (offset) =>\n            locationMap.getLocation(offset, filename),\n        getRangeLocation: (start, end) =>\n            locationMap.getLocationRange(start, end, filename)\n    });\n\n    const parse = function(source_, options) {\n        source = source_;\n        options = options || {};\n\n        parser.setSource(source, tokenize$1);\n        locationMap.setSource(\n            source,\n            options.offset,\n            options.line,\n            options.column\n        );\n\n        filename = options.filename || '<unknown>';\n        needPositions = Boolean(options.positions);\n        onParseError = typeof options.onParseError === 'function' ? options.onParseError : NOOP;\n        onParseErrorThrow = false;\n\n        parser.parseAtrulePrelude = 'parseAtrulePrelude' in options ? Boolean(options.parseAtrulePrelude) : true;\n        parser.parseRulePrelude = 'parseRulePrelude' in options ? Boolean(options.parseRulePrelude) : true;\n        parser.parseValue = 'parseValue' in options ? Boolean(options.parseValue) : true;\n        parser.parseCustomProperty = 'parseCustomProperty' in options ? Boolean(options.parseCustomProperty) : false;\n\n        const { context = 'default', onComment, onToken } = options;\n\n        if (context in parser.context === false) {\n            throw new Error('Unknown context `' + context + '`');\n        }\n\n        if (Array.isArray(onToken)) {\n            parser.forEachToken((type, start, end) => {\n                onToken.push({ type, start, end });\n            });\n        } else if (typeof onToken === 'function') {\n            parser.forEachToken(onToken.bind(createTokenIterateAPI()));\n        }\n\n        if (typeof onComment === 'function') {\n            parser.forEachToken((type, start, end) => {\n                if (type === Comment$1) {\n                    const loc = parser.getLocation(start, end);\n                    const value = cmpStr(source, end - 2, end, '*/')\n                        ? source.slice(start + 2, end - 2)\n                        : source.slice(start + 2, end);\n\n                    onComment(value, loc);\n                }\n            });\n        }\n\n        const ast = parser.context[context].call(parser, options);\n\n        if (!parser.eof) {\n            parser.error();\n        }\n\n        return ast;\n    };\n\n    return Object.assign(parse, {\n        SyntaxError: SyntaxError$2,\n        config: parser.config\n    });\n}\n\nvar sourceMapGenerator = {};\n\nvar base64Vlq = {};\n\nvar base64 = {};\n\n/* -*- Mode: js; js-indent-level: 2; -*- */\n\nvar hasRequiredBase64;\n\nfunction requireBase64 () {\n\tif (hasRequiredBase64) return base64;\n\thasRequiredBase64 = 1;\n\t/*\n\t * Copyright 2011 Mozilla Foundation and contributors\n\t * Licensed under the New BSD license. See LICENSE or:\n\t * http://opensource.org/licenses/BSD-3-Clause\n\t */\n\n\tvar intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');\n\n\t/**\n\t * Encode an integer in the range of 0 to 63 to a single base 64 digit.\n\t */\n\tbase64.encode = function (number) {\n\t  if (0 <= number && number < intToCharMap.length) {\n\t    return intToCharMap[number];\n\t  }\n\t  throw new TypeError(\"Must be between 0 and 63: \" + number);\n\t};\n\n\t/**\n\t * Decode a single base 64 character code digit to an integer. Returns -1 on\n\t * failure.\n\t */\n\tbase64.decode = function (charCode) {\n\t  var bigA = 65;     // 'A'\n\t  var bigZ = 90;     // 'Z'\n\n\t  var littleA = 97;  // 'a'\n\t  var littleZ = 122; // 'z'\n\n\t  var zero = 48;     // '0'\n\t  var nine = 57;     // '9'\n\n\t  var plus = 43;     // '+'\n\t  var slash = 47;    // '/'\n\n\t  var littleOffset = 26;\n\t  var numberOffset = 52;\n\n\t  // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ\n\t  if (bigA <= charCode && charCode <= bigZ) {\n\t    return (charCode - bigA);\n\t  }\n\n\t  // 26 - 51: abcdefghijklmnopqrstuvwxyz\n\t  if (littleA <= charCode && charCode <= littleZ) {\n\t    return (charCode - littleA + littleOffset);\n\t  }\n\n\t  // 52 - 61: 0123456789\n\t  if (zero <= charCode && charCode <= nine) {\n\t    return (charCode - zero + numberOffset);\n\t  }\n\n\t  // 62: +\n\t  if (charCode == plus) {\n\t    return 62;\n\t  }\n\n\t  // 63: /\n\t  if (charCode == slash) {\n\t    return 63;\n\t  }\n\n\t  // Invalid base64 digit.\n\t  return -1;\n\t};\n\treturn base64;\n}\n\n/* -*- Mode: js; js-indent-level: 2; -*- */\n\nvar hasRequiredBase64Vlq;\n\nfunction requireBase64Vlq () {\n\tif (hasRequiredBase64Vlq) return base64Vlq;\n\thasRequiredBase64Vlq = 1;\n\t/*\n\t * Copyright 2011 Mozilla Foundation and contributors\n\t * Licensed under the New BSD license. See LICENSE or:\n\t * http://opensource.org/licenses/BSD-3-Clause\n\t *\n\t * Based on the Base 64 VLQ implementation in Closure Compiler:\n\t * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java\n\t *\n\t * Copyright 2011 The Closure Compiler Authors. All rights reserved.\n\t * Redistribution and use in source and binary forms, with or without\n\t * modification, are permitted provided that the following conditions are\n\t * met:\n\t *\n\t *  * Redistributions of source code must retain the above copyright\n\t *    notice, this list of conditions and the following disclaimer.\n\t *  * Redistributions in binary form must reproduce the above\n\t *    copyright notice, this list of conditions and the following\n\t *    disclaimer in the documentation and/or other materials provided\n\t *    with the distribution.\n\t *  * Neither the name of Google Inc. nor the names of its\n\t *    contributors may be used to endorse or promote products derived\n\t *    from this software without specific prior written permission.\n\t *\n\t * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\t * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n\t * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n\t * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n\t * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n\t * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n\t * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n\t * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n\t * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\t * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\t * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\t */\n\n\tvar base64 = requireBase64();\n\n\t// A single base 64 digit can contain 6 bits of data. For the base 64 variable\n\t// length quantities we use in the source map spec, the first bit is the sign,\n\t// the next four bits are the actual value, and the 6th bit is the\n\t// continuation bit. The continuation bit tells us whether there are more\n\t// digits in this value following this digit.\n\t//\n\t//   Continuation\n\t//   |    Sign\n\t//   |    |\n\t//   V    V\n\t//   101011\n\n\tvar VLQ_BASE_SHIFT = 5;\n\n\t// binary: 100000\n\tvar VLQ_BASE = 1 << VLQ_BASE_SHIFT;\n\n\t// binary: 011111\n\tvar VLQ_BASE_MASK = VLQ_BASE - 1;\n\n\t// binary: 100000\n\tvar VLQ_CONTINUATION_BIT = VLQ_BASE;\n\n\t/**\n\t * Converts from a two-complement value to a value where the sign bit is\n\t * placed in the least significant bit.  For example, as decimals:\n\t *   1 becomes 2 (10 binary), -1 becomes 3 (11 binary)\n\t *   2 becomes 4 (100 binary), -2 becomes 5 (101 binary)\n\t */\n\tfunction toVLQSigned(aValue) {\n\t  return aValue < 0\n\t    ? ((-aValue) << 1) + 1\n\t    : (aValue << 1) + 0;\n\t}\n\n\t/**\n\t * Converts to a two-complement value from a value where the sign bit is\n\t * placed in the least significant bit.  For example, as decimals:\n\t *   2 (10 binary) becomes 1, 3 (11 binary) becomes -1\n\t *   4 (100 binary) becomes 2, 5 (101 binary) becomes -2\n\t */\n\tfunction fromVLQSigned(aValue) {\n\t  var isNegative = (aValue & 1) === 1;\n\t  var shifted = aValue >> 1;\n\t  return isNegative\n\t    ? -shifted\n\t    : shifted;\n\t}\n\n\t/**\n\t * Returns the base 64 VLQ encoded value.\n\t */\n\tbase64Vlq.encode = function base64VLQ_encode(aValue) {\n\t  var encoded = \"\";\n\t  var digit;\n\n\t  var vlq = toVLQSigned(aValue);\n\n\t  do {\n\t    digit = vlq & VLQ_BASE_MASK;\n\t    vlq >>>= VLQ_BASE_SHIFT;\n\t    if (vlq > 0) {\n\t      // There are still more digits in this value, so we must make sure the\n\t      // continuation bit is marked.\n\t      digit |= VLQ_CONTINUATION_BIT;\n\t    }\n\t    encoded += base64.encode(digit);\n\t  } while (vlq > 0);\n\n\t  return encoded;\n\t};\n\n\t/**\n\t * Decodes the next base 64 VLQ value from the given string and returns the\n\t * value and the rest of the string via the out parameter.\n\t */\n\tbase64Vlq.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) {\n\t  var strLen = aStr.length;\n\t  var result = 0;\n\t  var shift = 0;\n\t  var continuation, digit;\n\n\t  do {\n\t    if (aIndex >= strLen) {\n\t      throw new Error(\"Expected more digits in base 64 VLQ value.\");\n\t    }\n\n\t    digit = base64.decode(aStr.charCodeAt(aIndex++));\n\t    if (digit === -1) {\n\t      throw new Error(\"Invalid base64 digit: \" + aStr.charAt(aIndex - 1));\n\t    }\n\n\t    continuation = !!(digit & VLQ_CONTINUATION_BIT);\n\t    digit &= VLQ_BASE_MASK;\n\t    result = result + (digit << shift);\n\t    shift += VLQ_BASE_SHIFT;\n\t  } while (continuation);\n\n\t  aOutParam.value = fromVLQSigned(result);\n\t  aOutParam.rest = aIndex;\n\t};\n\treturn base64Vlq;\n}\n\nvar util = {};\n\n/* -*- Mode: js; js-indent-level: 2; -*- */\n\nvar hasRequiredUtil;\n\nfunction requireUtil () {\n\tif (hasRequiredUtil) return util;\n\thasRequiredUtil = 1;\n\t(function (exports) {\n\t\t/*\n\t\t * Copyright 2011 Mozilla Foundation and contributors\n\t\t * Licensed under the New BSD license. See LICENSE or:\n\t\t * http://opensource.org/licenses/BSD-3-Clause\n\t\t */\n\n\t\t/**\n\t\t * This is a helper function for getting values from parameter/options\n\t\t * objects.\n\t\t *\n\t\t * @param args The object we are extracting values from\n\t\t * @param name The name of the property we are getting.\n\t\t * @param defaultValue An optional value to return if the property is missing\n\t\t * from the object. If this is not specified and the property is missing, an\n\t\t * error will be thrown.\n\t\t */\n\t\tfunction getArg(aArgs, aName, aDefaultValue) {\n\t\t  if (aName in aArgs) {\n\t\t    return aArgs[aName];\n\t\t  } else if (arguments.length === 3) {\n\t\t    return aDefaultValue;\n\t\t  } else {\n\t\t    throw new Error('\"' + aName + '\" is a required argument.');\n\t\t  }\n\t\t}\n\t\texports.getArg = getArg;\n\n\t\tvar urlRegexp = /^(?:([\\w+\\-.]+):)?\\/\\/(?:(\\w+:\\w+)@)?([\\w.-]*)(?::(\\d+))?(.*)$/;\n\t\tvar dataUrlRegexp = /^data:.+\\,.+$/;\n\n\t\tfunction urlParse(aUrl) {\n\t\t  var match = aUrl.match(urlRegexp);\n\t\t  if (!match) {\n\t\t    return null;\n\t\t  }\n\t\t  return {\n\t\t    scheme: match[1],\n\t\t    auth: match[2],\n\t\t    host: match[3],\n\t\t    port: match[4],\n\t\t    path: match[5]\n\t\t  };\n\t\t}\n\t\texports.urlParse = urlParse;\n\n\t\tfunction urlGenerate(aParsedUrl) {\n\t\t  var url = '';\n\t\t  if (aParsedUrl.scheme) {\n\t\t    url += aParsedUrl.scheme + ':';\n\t\t  }\n\t\t  url += '//';\n\t\t  if (aParsedUrl.auth) {\n\t\t    url += aParsedUrl.auth + '@';\n\t\t  }\n\t\t  if (aParsedUrl.host) {\n\t\t    url += aParsedUrl.host;\n\t\t  }\n\t\t  if (aParsedUrl.port) {\n\t\t    url += \":\" + aParsedUrl.port;\n\t\t  }\n\t\t  if (aParsedUrl.path) {\n\t\t    url += aParsedUrl.path;\n\t\t  }\n\t\t  return url;\n\t\t}\n\t\texports.urlGenerate = urlGenerate;\n\n\t\tvar MAX_CACHED_INPUTS = 32;\n\n\t\t/**\n\t\t * Takes some function `f(input) -> result` and returns a memoized version of\n\t\t * `f`.\n\t\t *\n\t\t * We keep at most `MAX_CACHED_INPUTS` memoized results of `f` alive. The\n\t\t * memoization is a dumb-simple, linear least-recently-used cache.\n\t\t */\n\t\tfunction lruMemoize(f) {\n\t\t  var cache = [];\n\n\t\t  return function(input) {\n\t\t    for (var i = 0; i < cache.length; i++) {\n\t\t      if (cache[i].input === input) {\n\t\t        var temp = cache[0];\n\t\t        cache[0] = cache[i];\n\t\t        cache[i] = temp;\n\t\t        return cache[0].result;\n\t\t      }\n\t\t    }\n\n\t\t    var result = f(input);\n\n\t\t    cache.unshift({\n\t\t      input,\n\t\t      result,\n\t\t    });\n\n\t\t    if (cache.length > MAX_CACHED_INPUTS) {\n\t\t      cache.pop();\n\t\t    }\n\n\t\t    return result;\n\t\t  };\n\t\t}\n\n\t\t/**\n\t\t * Normalizes a path, or the path portion of a URL:\n\t\t *\n\t\t * - Replaces consecutive slashes with one slash.\n\t\t * - Removes unnecessary '.' parts.\n\t\t * - Removes unnecessary '<dir>/..' parts.\n\t\t *\n\t\t * Based on code in the Node.js 'path' core module.\n\t\t *\n\t\t * @param aPath The path or url to normalize.\n\t\t */\n\t\tvar normalize = lruMemoize(function normalize(aPath) {\n\t\t  var path = aPath;\n\t\t  var url = urlParse(aPath);\n\t\t  if (url) {\n\t\t    if (!url.path) {\n\t\t      return aPath;\n\t\t    }\n\t\t    path = url.path;\n\t\t  }\n\t\t  var isAbsolute = exports.isAbsolute(path);\n\t\t  // Split the path into parts between `/` characters. This is much faster than\n\t\t  // using `.split(/\\/+/g)`.\n\t\t  var parts = [];\n\t\t  var start = 0;\n\t\t  var i = 0;\n\t\t  while (true) {\n\t\t    start = i;\n\t\t    i = path.indexOf(\"/\", start);\n\t\t    if (i === -1) {\n\t\t      parts.push(path.slice(start));\n\t\t      break;\n\t\t    } else {\n\t\t      parts.push(path.slice(start, i));\n\t\t      while (i < path.length && path[i] === \"/\") {\n\t\t        i++;\n\t\t      }\n\t\t    }\n\t\t  }\n\n\t\t  for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {\n\t\t    part = parts[i];\n\t\t    if (part === '.') {\n\t\t      parts.splice(i, 1);\n\t\t    } else if (part === '..') {\n\t\t      up++;\n\t\t    } else if (up > 0) {\n\t\t      if (part === '') {\n\t\t        // The first part is blank if the path is absolute. Trying to go\n\t\t        // above the root is a no-op. Therefore we can remove all '..' parts\n\t\t        // directly after the root.\n\t\t        parts.splice(i + 1, up);\n\t\t        up = 0;\n\t\t      } else {\n\t\t        parts.splice(i, 2);\n\t\t        up--;\n\t\t      }\n\t\t    }\n\t\t  }\n\t\t  path = parts.join('/');\n\n\t\t  if (path === '') {\n\t\t    path = isAbsolute ? '/' : '.';\n\t\t  }\n\n\t\t  if (url) {\n\t\t    url.path = path;\n\t\t    return urlGenerate(url);\n\t\t  }\n\t\t  return path;\n\t\t});\n\t\texports.normalize = normalize;\n\n\t\t/**\n\t\t * Joins two paths/URLs.\n\t\t *\n\t\t * @param aRoot The root path or URL.\n\t\t * @param aPath The path or URL to be joined with the root.\n\t\t *\n\t\t * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a\n\t\t *   scheme-relative URL: Then the scheme of aRoot, if any, is prepended\n\t\t *   first.\n\t\t * - Otherwise aPath is a path. If aRoot is a URL, then its path portion\n\t\t *   is updated with the result and aRoot is returned. Otherwise the result\n\t\t *   is returned.\n\t\t *   - If aPath is absolute, the result is aPath.\n\t\t *   - Otherwise the two paths are joined with a slash.\n\t\t * - Joining for example 'http://' and 'www.example.com' is also supported.\n\t\t */\n\t\tfunction join(aRoot, aPath) {\n\t\t  if (aRoot === \"\") {\n\t\t    aRoot = \".\";\n\t\t  }\n\t\t  if (aPath === \"\") {\n\t\t    aPath = \".\";\n\t\t  }\n\t\t  var aPathUrl = urlParse(aPath);\n\t\t  var aRootUrl = urlParse(aRoot);\n\t\t  if (aRootUrl) {\n\t\t    aRoot = aRootUrl.path || '/';\n\t\t  }\n\n\t\t  // `join(foo, '//www.example.org')`\n\t\t  if (aPathUrl && !aPathUrl.scheme) {\n\t\t    if (aRootUrl) {\n\t\t      aPathUrl.scheme = aRootUrl.scheme;\n\t\t    }\n\t\t    return urlGenerate(aPathUrl);\n\t\t  }\n\n\t\t  if (aPathUrl || aPath.match(dataUrlRegexp)) {\n\t\t    return aPath;\n\t\t  }\n\n\t\t  // `join('http://', 'www.example.com')`\n\t\t  if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {\n\t\t    aRootUrl.host = aPath;\n\t\t    return urlGenerate(aRootUrl);\n\t\t  }\n\n\t\t  var joined = aPath.charAt(0) === '/'\n\t\t    ? aPath\n\t\t    : normalize(aRoot.replace(/\\/+$/, '') + '/' + aPath);\n\n\t\t  if (aRootUrl) {\n\t\t    aRootUrl.path = joined;\n\t\t    return urlGenerate(aRootUrl);\n\t\t  }\n\t\t  return joined;\n\t\t}\n\t\texports.join = join;\n\n\t\texports.isAbsolute = function (aPath) {\n\t\t  return aPath.charAt(0) === '/' || urlRegexp.test(aPath);\n\t\t};\n\n\t\t/**\n\t\t * Make a path relative to a URL or another path.\n\t\t *\n\t\t * @param aRoot The root path or URL.\n\t\t * @param aPath The path or URL to be made relative to aRoot.\n\t\t */\n\t\tfunction relative(aRoot, aPath) {\n\t\t  if (aRoot === \"\") {\n\t\t    aRoot = \".\";\n\t\t  }\n\n\t\t  aRoot = aRoot.replace(/\\/$/, '');\n\n\t\t  // It is possible for the path to be above the root. In this case, simply\n\t\t  // checking whether the root is a prefix of the path won't work. Instead, we\n\t\t  // need to remove components from the root one by one, until either we find\n\t\t  // a prefix that fits, or we run out of components to remove.\n\t\t  var level = 0;\n\t\t  while (aPath.indexOf(aRoot + '/') !== 0) {\n\t\t    var index = aRoot.lastIndexOf(\"/\");\n\t\t    if (index < 0) {\n\t\t      return aPath;\n\t\t    }\n\n\t\t    // If the only part of the root that is left is the scheme (i.e. http://,\n\t\t    // file:///, etc.), one or more slashes (/), or simply nothing at all, we\n\t\t    // have exhausted all components, so the path is not relative to the root.\n\t\t    aRoot = aRoot.slice(0, index);\n\t\t    if (aRoot.match(/^([^\\/]+:\\/)?\\/*$/)) {\n\t\t      return aPath;\n\t\t    }\n\n\t\t    ++level;\n\t\t  }\n\n\t\t  // Make sure we add a \"../\" for each component we removed from the root.\n\t\t  return Array(level + 1).join(\"../\") + aPath.substr(aRoot.length + 1);\n\t\t}\n\t\texports.relative = relative;\n\n\t\tvar supportsNullProto = (function () {\n\t\t  var obj = Object.create(null);\n\t\t  return !('__proto__' in obj);\n\t\t}());\n\n\t\tfunction identity (s) {\n\t\t  return s;\n\t\t}\n\n\t\t/**\n\t\t * Because behavior goes wacky when you set `__proto__` on objects, we\n\t\t * have to prefix all the strings in our set with an arbitrary character.\n\t\t *\n\t\t * See https://github.com/mozilla/source-map/pull/31 and\n\t\t * https://github.com/mozilla/source-map/issues/30\n\t\t *\n\t\t * @param String aStr\n\t\t */\n\t\tfunction toSetString(aStr) {\n\t\t  if (isProtoString(aStr)) {\n\t\t    return '$' + aStr;\n\t\t  }\n\n\t\t  return aStr;\n\t\t}\n\t\texports.toSetString = supportsNullProto ? identity : toSetString;\n\n\t\tfunction fromSetString(aStr) {\n\t\t  if (isProtoString(aStr)) {\n\t\t    return aStr.slice(1);\n\t\t  }\n\n\t\t  return aStr;\n\t\t}\n\t\texports.fromSetString = supportsNullProto ? identity : fromSetString;\n\n\t\tfunction isProtoString(s) {\n\t\t  if (!s) {\n\t\t    return false;\n\t\t  }\n\n\t\t  var length = s.length;\n\n\t\t  if (length < 9 /* \"__proto__\".length */) {\n\t\t    return false;\n\t\t  }\n\n\t\t  if (s.charCodeAt(length - 1) !== 95  /* '_' */ ||\n\t\t      s.charCodeAt(length - 2) !== 95  /* '_' */ ||\n\t\t      s.charCodeAt(length - 3) !== 111 /* 'o' */ ||\n\t\t      s.charCodeAt(length - 4) !== 116 /* 't' */ ||\n\t\t      s.charCodeAt(length - 5) !== 111 /* 'o' */ ||\n\t\t      s.charCodeAt(length - 6) !== 114 /* 'r' */ ||\n\t\t      s.charCodeAt(length - 7) !== 112 /* 'p' */ ||\n\t\t      s.charCodeAt(length - 8) !== 95  /* '_' */ ||\n\t\t      s.charCodeAt(length - 9) !== 95  /* '_' */) {\n\t\t    return false;\n\t\t  }\n\n\t\t  for (var i = length - 10; i >= 0; i--) {\n\t\t    if (s.charCodeAt(i) !== 36 /* '$' */) {\n\t\t      return false;\n\t\t    }\n\t\t  }\n\n\t\t  return true;\n\t\t}\n\n\t\t/**\n\t\t * Comparator between two mappings where the original positions are compared.\n\t\t *\n\t\t * Optionally pass in `true` as `onlyCompareGenerated` to consider two\n\t\t * mappings with the same original source/line/column, but different generated\n\t\t * line and column the same. Useful when searching for a mapping with a\n\t\t * stubbed out mapping.\n\t\t */\n\t\tfunction compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {\n\t\t  var cmp = strcmp(mappingA.source, mappingB.source);\n\t\t  if (cmp !== 0) {\n\t\t    return cmp;\n\t\t  }\n\n\t\t  cmp = mappingA.originalLine - mappingB.originalLine;\n\t\t  if (cmp !== 0) {\n\t\t    return cmp;\n\t\t  }\n\n\t\t  cmp = mappingA.originalColumn - mappingB.originalColumn;\n\t\t  if (cmp !== 0 || onlyCompareOriginal) {\n\t\t    return cmp;\n\t\t  }\n\n\t\t  cmp = mappingA.generatedColumn - mappingB.generatedColumn;\n\t\t  if (cmp !== 0) {\n\t\t    return cmp;\n\t\t  }\n\n\t\t  cmp = mappingA.generatedLine - mappingB.generatedLine;\n\t\t  if (cmp !== 0) {\n\t\t    return cmp;\n\t\t  }\n\n\t\t  return strcmp(mappingA.name, mappingB.name);\n\t\t}\n\t\texports.compareByOriginalPositions = compareByOriginalPositions;\n\n\t\tfunction compareByOriginalPositionsNoSource(mappingA, mappingB, onlyCompareOriginal) {\n\t\t  var cmp;\n\n\t\t  cmp = mappingA.originalLine - mappingB.originalLine;\n\t\t  if (cmp !== 0) {\n\t\t    return cmp;\n\t\t  }\n\n\t\t  cmp = mappingA.originalColumn - mappingB.originalColumn;\n\t\t  if (cmp !== 0 || onlyCompareOriginal) {\n\t\t    return cmp;\n\t\t  }\n\n\t\t  cmp = mappingA.generatedColumn - mappingB.generatedColumn;\n\t\t  if (cmp !== 0) {\n\t\t    return cmp;\n\t\t  }\n\n\t\t  cmp = mappingA.generatedLine - mappingB.generatedLine;\n\t\t  if (cmp !== 0) {\n\t\t    return cmp;\n\t\t  }\n\n\t\t  return strcmp(mappingA.name, mappingB.name);\n\t\t}\n\t\texports.compareByOriginalPositionsNoSource = compareByOriginalPositionsNoSource;\n\n\t\t/**\n\t\t * Comparator between two mappings with deflated source and name indices where\n\t\t * the generated positions are compared.\n\t\t *\n\t\t * Optionally pass in `true` as `onlyCompareGenerated` to consider two\n\t\t * mappings with the same generated line and column, but different\n\t\t * source/name/original line and column the same. Useful when searching for a\n\t\t * mapping with a stubbed out mapping.\n\t\t */\n\t\tfunction compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) {\n\t\t  var cmp = mappingA.generatedLine - mappingB.generatedLine;\n\t\t  if (cmp !== 0) {\n\t\t    return cmp;\n\t\t  }\n\n\t\t  cmp = mappingA.generatedColumn - mappingB.generatedColumn;\n\t\t  if (cmp !== 0 || onlyCompareGenerated) {\n\t\t    return cmp;\n\t\t  }\n\n\t\t  cmp = strcmp(mappingA.source, mappingB.source);\n\t\t  if (cmp !== 0) {\n\t\t    return cmp;\n\t\t  }\n\n\t\t  cmp = mappingA.originalLine - mappingB.originalLine;\n\t\t  if (cmp !== 0) {\n\t\t    return cmp;\n\t\t  }\n\n\t\t  cmp = mappingA.originalColumn - mappingB.originalColumn;\n\t\t  if (cmp !== 0) {\n\t\t    return cmp;\n\t\t  }\n\n\t\t  return strcmp(mappingA.name, mappingB.name);\n\t\t}\n\t\texports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;\n\n\t\tfunction compareByGeneratedPositionsDeflatedNoLine(mappingA, mappingB, onlyCompareGenerated) {\n\t\t  var cmp = mappingA.generatedColumn - mappingB.generatedColumn;\n\t\t  if (cmp !== 0 || onlyCompareGenerated) {\n\t\t    return cmp;\n\t\t  }\n\n\t\t  cmp = strcmp(mappingA.source, mappingB.source);\n\t\t  if (cmp !== 0) {\n\t\t    return cmp;\n\t\t  }\n\n\t\t  cmp = mappingA.originalLine - mappingB.originalLine;\n\t\t  if (cmp !== 0) {\n\t\t    return cmp;\n\t\t  }\n\n\t\t  cmp = mappingA.originalColumn - mappingB.originalColumn;\n\t\t  if (cmp !== 0) {\n\t\t    return cmp;\n\t\t  }\n\n\t\t  return strcmp(mappingA.name, mappingB.name);\n\t\t}\n\t\texports.compareByGeneratedPositionsDeflatedNoLine = compareByGeneratedPositionsDeflatedNoLine;\n\n\t\tfunction strcmp(aStr1, aStr2) {\n\t\t  if (aStr1 === aStr2) {\n\t\t    return 0;\n\t\t  }\n\n\t\t  if (aStr1 === null) {\n\t\t    return 1; // aStr2 !== null\n\t\t  }\n\n\t\t  if (aStr2 === null) {\n\t\t    return -1; // aStr1 !== null\n\t\t  }\n\n\t\t  if (aStr1 > aStr2) {\n\t\t    return 1;\n\t\t  }\n\n\t\t  return -1;\n\t\t}\n\n\t\t/**\n\t\t * Comparator between two mappings with inflated source and name strings where\n\t\t * the generated positions are compared.\n\t\t */\n\t\tfunction compareByGeneratedPositionsInflated(mappingA, mappingB) {\n\t\t  var cmp = mappingA.generatedLine - mappingB.generatedLine;\n\t\t  if (cmp !== 0) {\n\t\t    return cmp;\n\t\t  }\n\n\t\t  cmp = mappingA.generatedColumn - mappingB.generatedColumn;\n\t\t  if (cmp !== 0) {\n\t\t    return cmp;\n\t\t  }\n\n\t\t  cmp = strcmp(mappingA.source, mappingB.source);\n\t\t  if (cmp !== 0) {\n\t\t    return cmp;\n\t\t  }\n\n\t\t  cmp = mappingA.originalLine - mappingB.originalLine;\n\t\t  if (cmp !== 0) {\n\t\t    return cmp;\n\t\t  }\n\n\t\t  cmp = mappingA.originalColumn - mappingB.originalColumn;\n\t\t  if (cmp !== 0) {\n\t\t    return cmp;\n\t\t  }\n\n\t\t  return strcmp(mappingA.name, mappingB.name);\n\t\t}\n\t\texports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;\n\n\t\t/**\n\t\t * Strip any JSON XSSI avoidance prefix from the string (as documented\n\t\t * in the source maps specification), and then parse the string as\n\t\t * JSON.\n\t\t */\n\t\tfunction parseSourceMapInput(str) {\n\t\t  return JSON.parse(str.replace(/^\\)]}'[^\\n]*\\n/, ''));\n\t\t}\n\t\texports.parseSourceMapInput = parseSourceMapInput;\n\n\t\t/**\n\t\t * Compute the URL of a source given the the source root, the source's\n\t\t * URL, and the source map's URL.\n\t\t */\n\t\tfunction computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {\n\t\t  sourceURL = sourceURL || '';\n\n\t\t  if (sourceRoot) {\n\t\t    // This follows what Chrome does.\n\t\t    if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {\n\t\t      sourceRoot += '/';\n\t\t    }\n\t\t    // The spec says:\n\t\t    //   Line 4: An optional source root, useful for relocating source\n\t\t    //   files on a server or removing repeated values in the\n\t\t    //   “sources” entry.  This value is prepended to the individual\n\t\t    //   entries in the “source” field.\n\t\t    sourceURL = sourceRoot + sourceURL;\n\t\t  }\n\n\t\t  // Historically, SourceMapConsumer did not take the sourceMapURL as\n\t\t  // a parameter.  This mode is still somewhat supported, which is why\n\t\t  // this code block is conditional.  However, it's preferable to pass\n\t\t  // the source map URL to SourceMapConsumer, so that this function\n\t\t  // can implement the source URL resolution algorithm as outlined in\n\t\t  // the spec.  This block is basically the equivalent of:\n\t\t  //    new URL(sourceURL, sourceMapURL).toString()\n\t\t  // ... except it avoids using URL, which wasn't available in the\n\t\t  // older releases of node still supported by this library.\n\t\t  //\n\t\t  // The spec says:\n\t\t  //   If the sources are not absolute URLs after prepending of the\n\t\t  //   “sourceRoot”, the sources are resolved relative to the\n\t\t  //   SourceMap (like resolving script src in a html document).\n\t\t  if (sourceMapURL) {\n\t\t    var parsed = urlParse(sourceMapURL);\n\t\t    if (!parsed) {\n\t\t      throw new Error(\"sourceMapURL could not be parsed\");\n\t\t    }\n\t\t    if (parsed.path) {\n\t\t      // Strip the last path component, but keep the \"/\".\n\t\t      var index = parsed.path.lastIndexOf('/');\n\t\t      if (index >= 0) {\n\t\t        parsed.path = parsed.path.substring(0, index + 1);\n\t\t      }\n\t\t    }\n\t\t    sourceURL = join(urlGenerate(parsed), sourceURL);\n\t\t  }\n\n\t\t  return normalize(sourceURL);\n\t\t}\n\t\texports.computeSourceURL = computeSourceURL; \n\t} (util));\n\treturn util;\n}\n\nvar arraySet = {};\n\n/* -*- Mode: js; js-indent-level: 2; -*- */\n\nvar hasRequiredArraySet;\n\nfunction requireArraySet () {\n\tif (hasRequiredArraySet) return arraySet;\n\thasRequiredArraySet = 1;\n\t/*\n\t * Copyright 2011 Mozilla Foundation and contributors\n\t * Licensed under the New BSD license. See LICENSE or:\n\t * http://opensource.org/licenses/BSD-3-Clause\n\t */\n\n\tvar util = requireUtil();\n\tvar has = Object.prototype.hasOwnProperty;\n\tvar hasNativeMap = typeof Map !== \"undefined\";\n\n\t/**\n\t * A data structure which is a combination of an array and a set. Adding a new\n\t * member is O(1), testing for membership is O(1), and finding the index of an\n\t * element is O(1). Removing elements from the set is not supported. Only\n\t * strings are supported for membership.\n\t */\n\tfunction ArraySet() {\n\t  this._array = [];\n\t  this._set = hasNativeMap ? new Map() : Object.create(null);\n\t}\n\n\t/**\n\t * Static method for creating ArraySet instances from an existing array.\n\t */\n\tArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {\n\t  var set = new ArraySet();\n\t  for (var i = 0, len = aArray.length; i < len; i++) {\n\t    set.add(aArray[i], aAllowDuplicates);\n\t  }\n\t  return set;\n\t};\n\n\t/**\n\t * Return how many unique items are in this ArraySet. If duplicates have been\n\t * added, than those do not count towards the size.\n\t *\n\t * @returns Number\n\t */\n\tArraySet.prototype.size = function ArraySet_size() {\n\t  return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;\n\t};\n\n\t/**\n\t * Add the given string to this set.\n\t *\n\t * @param String aStr\n\t */\n\tArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {\n\t  var sStr = hasNativeMap ? aStr : util.toSetString(aStr);\n\t  var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);\n\t  var idx = this._array.length;\n\t  if (!isDuplicate || aAllowDuplicates) {\n\t    this._array.push(aStr);\n\t  }\n\t  if (!isDuplicate) {\n\t    if (hasNativeMap) {\n\t      this._set.set(aStr, idx);\n\t    } else {\n\t      this._set[sStr] = idx;\n\t    }\n\t  }\n\t};\n\n\t/**\n\t * Is the given string a member of this set?\n\t *\n\t * @param String aStr\n\t */\n\tArraySet.prototype.has = function ArraySet_has(aStr) {\n\t  if (hasNativeMap) {\n\t    return this._set.has(aStr);\n\t  } else {\n\t    var sStr = util.toSetString(aStr);\n\t    return has.call(this._set, sStr);\n\t  }\n\t};\n\n\t/**\n\t * What is the index of the given string in the array?\n\t *\n\t * @param String aStr\n\t */\n\tArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {\n\t  if (hasNativeMap) {\n\t    var idx = this._set.get(aStr);\n\t    if (idx >= 0) {\n\t        return idx;\n\t    }\n\t  } else {\n\t    var sStr = util.toSetString(aStr);\n\t    if (has.call(this._set, sStr)) {\n\t      return this._set[sStr];\n\t    }\n\t  }\n\n\t  throw new Error('\"' + aStr + '\" is not in the set.');\n\t};\n\n\t/**\n\t * What is the element at the given index?\n\t *\n\t * @param Number aIdx\n\t */\n\tArraySet.prototype.at = function ArraySet_at(aIdx) {\n\t  if (aIdx >= 0 && aIdx < this._array.length) {\n\t    return this._array[aIdx];\n\t  }\n\t  throw new Error('No element indexed by ' + aIdx);\n\t};\n\n\t/**\n\t * Returns the array representation of this set (which has the proper indices\n\t * indicated by indexOf). Note that this is a copy of the internal array used\n\t * for storing the members so that no one can mess with internal state.\n\t */\n\tArraySet.prototype.toArray = function ArraySet_toArray() {\n\t  return this._array.slice();\n\t};\n\n\tarraySet.ArraySet = ArraySet;\n\treturn arraySet;\n}\n\nvar mappingList = {};\n\n/* -*- Mode: js; js-indent-level: 2; -*- */\n\nvar hasRequiredMappingList;\n\nfunction requireMappingList () {\n\tif (hasRequiredMappingList) return mappingList;\n\thasRequiredMappingList = 1;\n\t/*\n\t * Copyright 2014 Mozilla Foundation and contributors\n\t * Licensed under the New BSD license. See LICENSE or:\n\t * http://opensource.org/licenses/BSD-3-Clause\n\t */\n\n\tvar util = requireUtil();\n\n\t/**\n\t * Determine whether mappingB is after mappingA with respect to generated\n\t * position.\n\t */\n\tfunction generatedPositionAfter(mappingA, mappingB) {\n\t  // Optimized for most common case\n\t  var lineA = mappingA.generatedLine;\n\t  var lineB = mappingB.generatedLine;\n\t  var columnA = mappingA.generatedColumn;\n\t  var columnB = mappingB.generatedColumn;\n\t  return lineB > lineA || lineB == lineA && columnB >= columnA ||\n\t         util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0;\n\t}\n\n\t/**\n\t * A data structure to provide a sorted view of accumulated mappings in a\n\t * performance conscious manner. It trades a neglibable overhead in general\n\t * case for a large speedup in case of mappings being added in order.\n\t */\n\tfunction MappingList() {\n\t  this._array = [];\n\t  this._sorted = true;\n\t  // Serves as infimum\n\t  this._last = {generatedLine: -1, generatedColumn: 0};\n\t}\n\n\t/**\n\t * Iterate through internal items. This method takes the same arguments that\n\t * `Array.prototype.forEach` takes.\n\t *\n\t * NOTE: The order of the mappings is NOT guaranteed.\n\t */\n\tMappingList.prototype.unsortedForEach =\n\t  function MappingList_forEach(aCallback, aThisArg) {\n\t    this._array.forEach(aCallback, aThisArg);\n\t  };\n\n\t/**\n\t * Add the given source mapping.\n\t *\n\t * @param Object aMapping\n\t */\n\tMappingList.prototype.add = function MappingList_add(aMapping) {\n\t  if (generatedPositionAfter(this._last, aMapping)) {\n\t    this._last = aMapping;\n\t    this._array.push(aMapping);\n\t  } else {\n\t    this._sorted = false;\n\t    this._array.push(aMapping);\n\t  }\n\t};\n\n\t/**\n\t * Returns the flat, sorted array of mappings. The mappings are sorted by\n\t * generated position.\n\t *\n\t * WARNING: This method returns internal data without copying, for\n\t * performance. The return value must NOT be mutated, and should be treated as\n\t * an immutable borrow. If you want to take ownership, you must make your own\n\t * copy.\n\t */\n\tMappingList.prototype.toArray = function MappingList_toArray() {\n\t  if (!this._sorted) {\n\t    this._array.sort(util.compareByGeneratedPositionsInflated);\n\t    this._sorted = true;\n\t  }\n\t  return this._array;\n\t};\n\n\tmappingList.MappingList = MappingList;\n\treturn mappingList;\n}\n\n/* -*- Mode: js; js-indent-level: 2; -*- */\n\nvar hasRequiredSourceMapGenerator;\n\nfunction requireSourceMapGenerator () {\n\tif (hasRequiredSourceMapGenerator) return sourceMapGenerator;\n\thasRequiredSourceMapGenerator = 1;\n\t/*\n\t * Copyright 2011 Mozilla Foundation and contributors\n\t * Licensed under the New BSD license. See LICENSE or:\n\t * http://opensource.org/licenses/BSD-3-Clause\n\t */\n\n\tvar base64VLQ = requireBase64Vlq();\n\tvar util = requireUtil();\n\tvar ArraySet = requireArraySet().ArraySet;\n\tvar MappingList = requireMappingList().MappingList;\n\n\t/**\n\t * An instance of the SourceMapGenerator represents a source map which is\n\t * being built incrementally. You may pass an object with the following\n\t * properties:\n\t *\n\t *   - file: The filename of the generated source.\n\t *   - sourceRoot: A root for all relative URLs in this source map.\n\t */\n\tfunction SourceMapGenerator(aArgs) {\n\t  if (!aArgs) {\n\t    aArgs = {};\n\t  }\n\t  this._file = util.getArg(aArgs, 'file', null);\n\t  this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);\n\t  this._skipValidation = util.getArg(aArgs, 'skipValidation', false);\n\t  this._sources = new ArraySet();\n\t  this._names = new ArraySet();\n\t  this._mappings = new MappingList();\n\t  this._sourcesContents = null;\n\t}\n\n\tSourceMapGenerator.prototype._version = 3;\n\n\t/**\n\t * Creates a new SourceMapGenerator based on a SourceMapConsumer\n\t *\n\t * @param aSourceMapConsumer The SourceMap.\n\t */\n\tSourceMapGenerator.fromSourceMap =\n\t  function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {\n\t    var sourceRoot = aSourceMapConsumer.sourceRoot;\n\t    var generator = new SourceMapGenerator({\n\t      file: aSourceMapConsumer.file,\n\t      sourceRoot: sourceRoot\n\t    });\n\t    aSourceMapConsumer.eachMapping(function (mapping) {\n\t      var newMapping = {\n\t        generated: {\n\t          line: mapping.generatedLine,\n\t          column: mapping.generatedColumn\n\t        }\n\t      };\n\n\t      if (mapping.source != null) {\n\t        newMapping.source = mapping.source;\n\t        if (sourceRoot != null) {\n\t          newMapping.source = util.relative(sourceRoot, newMapping.source);\n\t        }\n\n\t        newMapping.original = {\n\t          line: mapping.originalLine,\n\t          column: mapping.originalColumn\n\t        };\n\n\t        if (mapping.name != null) {\n\t          newMapping.name = mapping.name;\n\t        }\n\t      }\n\n\t      generator.addMapping(newMapping);\n\t    });\n\t    aSourceMapConsumer.sources.forEach(function (sourceFile) {\n\t      var sourceRelative = sourceFile;\n\t      if (sourceRoot !== null) {\n\t        sourceRelative = util.relative(sourceRoot, sourceFile);\n\t      }\n\n\t      if (!generator._sources.has(sourceRelative)) {\n\t        generator._sources.add(sourceRelative);\n\t      }\n\n\t      var content = aSourceMapConsumer.sourceContentFor(sourceFile);\n\t      if (content != null) {\n\t        generator.setSourceContent(sourceFile, content);\n\t      }\n\t    });\n\t    return generator;\n\t  };\n\n\t/**\n\t * Add a single mapping from original source line and column to the generated\n\t * source's line and column for this source map being created. The mapping\n\t * object should have the following properties:\n\t *\n\t *   - generated: An object with the generated line and column positions.\n\t *   - original: An object with the original line and column positions.\n\t *   - source: The original source file (relative to the sourceRoot).\n\t *   - name: An optional original token name for this mapping.\n\t */\n\tSourceMapGenerator.prototype.addMapping =\n\t  function SourceMapGenerator_addMapping(aArgs) {\n\t    var generated = util.getArg(aArgs, 'generated');\n\t    var original = util.getArg(aArgs, 'original', null);\n\t    var source = util.getArg(aArgs, 'source', null);\n\t    var name = util.getArg(aArgs, 'name', null);\n\n\t    if (!this._skipValidation) {\n\t      this._validateMapping(generated, original, source, name);\n\t    }\n\n\t    if (source != null) {\n\t      source = String(source);\n\t      if (!this._sources.has(source)) {\n\t        this._sources.add(source);\n\t      }\n\t    }\n\n\t    if (name != null) {\n\t      name = String(name);\n\t      if (!this._names.has(name)) {\n\t        this._names.add(name);\n\t      }\n\t    }\n\n\t    this._mappings.add({\n\t      generatedLine: generated.line,\n\t      generatedColumn: generated.column,\n\t      originalLine: original != null && original.line,\n\t      originalColumn: original != null && original.column,\n\t      source: source,\n\t      name: name\n\t    });\n\t  };\n\n\t/**\n\t * Set the source content for a source file.\n\t */\n\tSourceMapGenerator.prototype.setSourceContent =\n\t  function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {\n\t    var source = aSourceFile;\n\t    if (this._sourceRoot != null) {\n\t      source = util.relative(this._sourceRoot, source);\n\t    }\n\n\t    if (aSourceContent != null) {\n\t      // Add the source content to the _sourcesContents map.\n\t      // Create a new _sourcesContents map if the property is null.\n\t      if (!this._sourcesContents) {\n\t        this._sourcesContents = Object.create(null);\n\t      }\n\t      this._sourcesContents[util.toSetString(source)] = aSourceContent;\n\t    } else if (this._sourcesContents) {\n\t      // Remove the source file from the _sourcesContents map.\n\t      // If the _sourcesContents map is empty, set the property to null.\n\t      delete this._sourcesContents[util.toSetString(source)];\n\t      if (Object.keys(this._sourcesContents).length === 0) {\n\t        this._sourcesContents = null;\n\t      }\n\t    }\n\t  };\n\n\t/**\n\t * Applies the mappings of a sub-source-map for a specific source file to the\n\t * source map being generated. Each mapping to the supplied source file is\n\t * rewritten using the supplied source map. Note: The resolution for the\n\t * resulting mappings is the minimium of this map and the supplied map.\n\t *\n\t * @param aSourceMapConsumer The source map to be applied.\n\t * @param aSourceFile Optional. The filename of the source file.\n\t *        If omitted, SourceMapConsumer's file property will be used.\n\t * @param aSourceMapPath Optional. The dirname of the path to the source map\n\t *        to be applied. If relative, it is relative to the SourceMapConsumer.\n\t *        This parameter is needed when the two source maps aren't in the same\n\t *        directory, and the source map to be applied contains relative source\n\t *        paths. If so, those relative source paths need to be rewritten\n\t *        relative to the SourceMapGenerator.\n\t */\n\tSourceMapGenerator.prototype.applySourceMap =\n\t  function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {\n\t    var sourceFile = aSourceFile;\n\t    // If aSourceFile is omitted, we will use the file property of the SourceMap\n\t    if (aSourceFile == null) {\n\t      if (aSourceMapConsumer.file == null) {\n\t        throw new Error(\n\t          'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' +\n\t          'or the source map\\'s \"file\" property. Both were omitted.'\n\t        );\n\t      }\n\t      sourceFile = aSourceMapConsumer.file;\n\t    }\n\t    var sourceRoot = this._sourceRoot;\n\t    // Make \"sourceFile\" relative if an absolute Url is passed.\n\t    if (sourceRoot != null) {\n\t      sourceFile = util.relative(sourceRoot, sourceFile);\n\t    }\n\t    // Applying the SourceMap can add and remove items from the sources and\n\t    // the names array.\n\t    var newSources = new ArraySet();\n\t    var newNames = new ArraySet();\n\n\t    // Find mappings for the \"sourceFile\"\n\t    this._mappings.unsortedForEach(function (mapping) {\n\t      if (mapping.source === sourceFile && mapping.originalLine != null) {\n\t        // Check if it can be mapped by the source map, then update the mapping.\n\t        var original = aSourceMapConsumer.originalPositionFor({\n\t          line: mapping.originalLine,\n\t          column: mapping.originalColumn\n\t        });\n\t        if (original.source != null) {\n\t          // Copy mapping\n\t          mapping.source = original.source;\n\t          if (aSourceMapPath != null) {\n\t            mapping.source = util.join(aSourceMapPath, mapping.source);\n\t          }\n\t          if (sourceRoot != null) {\n\t            mapping.source = util.relative(sourceRoot, mapping.source);\n\t          }\n\t          mapping.originalLine = original.line;\n\t          mapping.originalColumn = original.column;\n\t          if (original.name != null) {\n\t            mapping.name = original.name;\n\t          }\n\t        }\n\t      }\n\n\t      var source = mapping.source;\n\t      if (source != null && !newSources.has(source)) {\n\t        newSources.add(source);\n\t      }\n\n\t      var name = mapping.name;\n\t      if (name != null && !newNames.has(name)) {\n\t        newNames.add(name);\n\t      }\n\n\t    }, this);\n\t    this._sources = newSources;\n\t    this._names = newNames;\n\n\t    // Copy sourcesContents of applied map.\n\t    aSourceMapConsumer.sources.forEach(function (sourceFile) {\n\t      var content = aSourceMapConsumer.sourceContentFor(sourceFile);\n\t      if (content != null) {\n\t        if (aSourceMapPath != null) {\n\t          sourceFile = util.join(aSourceMapPath, sourceFile);\n\t        }\n\t        if (sourceRoot != null) {\n\t          sourceFile = util.relative(sourceRoot, sourceFile);\n\t        }\n\t        this.setSourceContent(sourceFile, content);\n\t      }\n\t    }, this);\n\t  };\n\n\t/**\n\t * A mapping can have one of the three levels of data:\n\t *\n\t *   1. Just the generated position.\n\t *   2. The Generated position, original position, and original source.\n\t *   3. Generated and original position, original source, as well as a name\n\t *      token.\n\t *\n\t * To maintain consistency, we validate that any new mapping being added falls\n\t * in to one of these categories.\n\t */\n\tSourceMapGenerator.prototype._validateMapping =\n\t  function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,\n\t                                              aName) {\n\t    // When aOriginal is truthy but has empty values for .line and .column,\n\t    // it is most likely a programmer error. In this case we throw a very\n\t    // specific error message to try to guide them the right way.\n\t    // For example: https://github.com/Polymer/polymer-bundler/pull/519\n\t    if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') {\n\t        throw new Error(\n\t            'original.line and original.column are not numbers -- you probably meant to omit ' +\n\t            'the original mapping entirely and only map the generated position. If so, pass ' +\n\t            'null for the original mapping instead of an object with empty or null values.'\n\t        );\n\t    }\n\n\t    if (aGenerated && 'line' in aGenerated && 'column' in aGenerated\n\t        && aGenerated.line > 0 && aGenerated.column >= 0\n\t        && !aOriginal && !aSource && !aName) {\n\t      // Case 1.\n\t      return;\n\t    }\n\t    else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated\n\t             && aOriginal && 'line' in aOriginal && 'column' in aOriginal\n\t             && aGenerated.line > 0 && aGenerated.column >= 0\n\t             && aOriginal.line > 0 && aOriginal.column >= 0\n\t             && aSource) {\n\t      // Cases 2 and 3.\n\t      return;\n\t    }\n\t    else {\n\t      throw new Error('Invalid mapping: ' + JSON.stringify({\n\t        generated: aGenerated,\n\t        source: aSource,\n\t        original: aOriginal,\n\t        name: aName\n\t      }));\n\t    }\n\t  };\n\n\t/**\n\t * Serialize the accumulated mappings in to the stream of base 64 VLQs\n\t * specified by the source map format.\n\t */\n\tSourceMapGenerator.prototype._serializeMappings =\n\t  function SourceMapGenerator_serializeMappings() {\n\t    var previousGeneratedColumn = 0;\n\t    var previousGeneratedLine = 1;\n\t    var previousOriginalColumn = 0;\n\t    var previousOriginalLine = 0;\n\t    var previousName = 0;\n\t    var previousSource = 0;\n\t    var result = '';\n\t    var next;\n\t    var mapping;\n\t    var nameIdx;\n\t    var sourceIdx;\n\n\t    var mappings = this._mappings.toArray();\n\t    for (var i = 0, len = mappings.length; i < len; i++) {\n\t      mapping = mappings[i];\n\t      next = '';\n\n\t      if (mapping.generatedLine !== previousGeneratedLine) {\n\t        previousGeneratedColumn = 0;\n\t        while (mapping.generatedLine !== previousGeneratedLine) {\n\t          next += ';';\n\t          previousGeneratedLine++;\n\t        }\n\t      }\n\t      else {\n\t        if (i > 0) {\n\t          if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {\n\t            continue;\n\t          }\n\t          next += ',';\n\t        }\n\t      }\n\n\t      next += base64VLQ.encode(mapping.generatedColumn\n\t                                 - previousGeneratedColumn);\n\t      previousGeneratedColumn = mapping.generatedColumn;\n\n\t      if (mapping.source != null) {\n\t        sourceIdx = this._sources.indexOf(mapping.source);\n\t        next += base64VLQ.encode(sourceIdx - previousSource);\n\t        previousSource = sourceIdx;\n\n\t        // lines are stored 0-based in SourceMap spec version 3\n\t        next += base64VLQ.encode(mapping.originalLine - 1\n\t                                   - previousOriginalLine);\n\t        previousOriginalLine = mapping.originalLine - 1;\n\n\t        next += base64VLQ.encode(mapping.originalColumn\n\t                                   - previousOriginalColumn);\n\t        previousOriginalColumn = mapping.originalColumn;\n\n\t        if (mapping.name != null) {\n\t          nameIdx = this._names.indexOf(mapping.name);\n\t          next += base64VLQ.encode(nameIdx - previousName);\n\t          previousName = nameIdx;\n\t        }\n\t      }\n\n\t      result += next;\n\t    }\n\n\t    return result;\n\t  };\n\n\tSourceMapGenerator.prototype._generateSourcesContent =\n\t  function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {\n\t    return aSources.map(function (source) {\n\t      if (!this._sourcesContents) {\n\t        return null;\n\t      }\n\t      if (aSourceRoot != null) {\n\t        source = util.relative(aSourceRoot, source);\n\t      }\n\t      var key = util.toSetString(source);\n\t      return Object.prototype.hasOwnProperty.call(this._sourcesContents, key)\n\t        ? this._sourcesContents[key]\n\t        : null;\n\t    }, this);\n\t  };\n\n\t/**\n\t * Externalize the source map.\n\t */\n\tSourceMapGenerator.prototype.toJSON =\n\t  function SourceMapGenerator_toJSON() {\n\t    var map = {\n\t      version: this._version,\n\t      sources: this._sources.toArray(),\n\t      names: this._names.toArray(),\n\t      mappings: this._serializeMappings()\n\t    };\n\t    if (this._file != null) {\n\t      map.file = this._file;\n\t    }\n\t    if (this._sourceRoot != null) {\n\t      map.sourceRoot = this._sourceRoot;\n\t    }\n\t    if (this._sourcesContents) {\n\t      map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);\n\t    }\n\n\t    return map;\n\t  };\n\n\t/**\n\t * Render the source map being generated to a string.\n\t */\n\tSourceMapGenerator.prototype.toString =\n\t  function SourceMapGenerator_toString() {\n\t    return JSON.stringify(this.toJSON());\n\t  };\n\n\tsourceMapGenerator.SourceMapGenerator = SourceMapGenerator;\n\treturn sourceMapGenerator;\n}\n\nvar sourceMapGeneratorExports = requireSourceMapGenerator();\n\nconst trackNodes = new Set(['Atrule', 'Selector', 'Declaration']);\n\nfunction generateSourceMap(handlers) {\n    const map = new sourceMapGeneratorExports.SourceMapGenerator();\n    const generated = {\n        line: 1,\n        column: 0\n    };\n    const original = {\n        line: 0, // should be zero to add first mapping\n        column: 0\n    };\n    const activatedGenerated = {\n        line: 1,\n        column: 0\n    };\n    const activatedMapping = {\n        generated: activatedGenerated\n    };\n    let line = 1;\n    let column = 0;\n    let sourceMappingActive = false;\n\n    const origHandlersNode = handlers.node;\n    handlers.node = function(node) {\n        if (node.loc && node.loc.start && trackNodes.has(node.type)) {\n            const nodeLine = node.loc.start.line;\n            const nodeColumn = node.loc.start.column - 1;\n\n            if (original.line !== nodeLine ||\n                original.column !== nodeColumn) {\n                original.line = nodeLine;\n                original.column = nodeColumn;\n\n                generated.line = line;\n                generated.column = column;\n\n                if (sourceMappingActive) {\n                    sourceMappingActive = false;\n                    if (generated.line !== activatedGenerated.line ||\n                        generated.column !== activatedGenerated.column) {\n                        map.addMapping(activatedMapping);\n                    }\n                }\n\n                sourceMappingActive = true;\n                map.addMapping({\n                    source: node.loc.source,\n                    original,\n                    generated\n                });\n            }\n        }\n\n        origHandlersNode.call(this, node);\n\n        if (sourceMappingActive && trackNodes.has(node.type)) {\n            activatedGenerated.line = line;\n            activatedGenerated.column = column;\n        }\n    };\n\n    const origHandlersEmit = handlers.emit;\n    handlers.emit = function(value, type, auto) {\n        for (let i = 0; i < value.length; i++) {\n            if (value.charCodeAt(i) === 10) { // \\n\n                line++;\n                column = 0;\n            } else {\n                column++;\n            }\n        }\n\n        origHandlersEmit(value, type, auto);\n    };\n\n    const origHandlersResult = handlers.result;\n    handlers.result = function() {\n        if (sourceMappingActive) {\n            map.addMapping(activatedMapping);\n        }\n\n        return {\n            css: origHandlersResult(),\n            map\n        };\n    };\n\n    return handlers;\n}\n\nconst PLUSSIGN$9 = 0x002B;    // U+002B PLUS SIGN (+)\nconst HYPHENMINUS$6 = 0x002D; // U+002D HYPHEN-MINUS (-)\n\nconst code = (type, value) => {\n    if (type === Delim) {\n        type = value;\n    }\n\n    if (typeof type === 'string') {\n        const charCode = type.charCodeAt(0);\n        return charCode > 0x7F ? 0x8000 : charCode << 8;\n    }\n\n    return type;\n};\n\n// https://www.w3.org/TR/css-syntax-3/#serialization\n// The only requirement for serialization is that it must \"round-trip\" with parsing,\n// that is, parsing the stylesheet must produce the same data structures as parsing,\n// serializing, and parsing again, except for consecutive <whitespace-token>s,\n// which may be collapsed into a single token.\n\nconst specPairs = [\n    [Ident, Ident],\n    [Ident, Function$1],\n    [Ident, Url$1],\n    [Ident, BadUrl],\n    [Ident, '-'],\n    [Ident, Number$2],\n    [Ident, Percentage$1],\n    [Ident, Dimension$1],\n    [Ident, CDC$1],\n    [Ident, LeftParenthesis],\n\n    [AtKeyword, Ident],\n    [AtKeyword, Function$1],\n    [AtKeyword, Url$1],\n    [AtKeyword, BadUrl],\n    [AtKeyword, '-'],\n    [AtKeyword, Number$2],\n    [AtKeyword, Percentage$1],\n    [AtKeyword, Dimension$1],\n    [AtKeyword, CDC$1],\n\n    [Hash$1, Ident],\n    [Hash$1, Function$1],\n    [Hash$1, Url$1],\n    [Hash$1, BadUrl],\n    [Hash$1, '-'],\n    [Hash$1, Number$2],\n    [Hash$1, Percentage$1],\n    [Hash$1, Dimension$1],\n    [Hash$1, CDC$1],\n\n    [Dimension$1, Ident],\n    [Dimension$1, Function$1],\n    [Dimension$1, Url$1],\n    [Dimension$1, BadUrl],\n    [Dimension$1, '-'],\n    [Dimension$1, Number$2],\n    [Dimension$1, Percentage$1],\n    [Dimension$1, Dimension$1],\n    [Dimension$1, CDC$1],\n\n    ['#', Ident],\n    ['#', Function$1],\n    ['#', Url$1],\n    ['#', BadUrl],\n    ['#', '-'],\n    ['#', Number$2],\n    ['#', Percentage$1],\n    ['#', Dimension$1],\n    ['#', CDC$1], // https://github.com/w3c/csswg-drafts/pull/6874\n\n    ['-', Ident],\n    ['-', Function$1],\n    ['-', Url$1],\n    ['-', BadUrl],\n    ['-', '-'],\n    ['-', Number$2],\n    ['-', Percentage$1],\n    ['-', Dimension$1],\n    ['-', CDC$1], // https://github.com/w3c/csswg-drafts/pull/6874\n\n    [Number$2, Ident],\n    [Number$2, Function$1],\n    [Number$2, Url$1],\n    [Number$2, BadUrl],\n    [Number$2, Number$2],\n    [Number$2, Percentage$1],\n    [Number$2, Dimension$1],\n    [Number$2, '%'],\n    [Number$2, CDC$1], // https://github.com/w3c/csswg-drafts/pull/6874\n\n    ['@', Ident],\n    ['@', Function$1],\n    ['@', Url$1],\n    ['@', BadUrl],\n    ['@', '-'],\n    ['@', CDC$1], // https://github.com/w3c/csswg-drafts/pull/6874\n\n    ['.', Number$2],\n    ['.', Percentage$1],\n    ['.', Dimension$1],\n\n    ['+', Number$2],\n    ['+', Percentage$1],\n    ['+', Dimension$1],\n\n    ['/', '*']\n];\n// validate with scripts/generate-safe\nconst safePairs = specPairs.concat([\n    [Ident, Hash$1],\n\n    [Dimension$1, Hash$1],\n\n    [Hash$1, Hash$1],\n\n    [AtKeyword, LeftParenthesis],\n    [AtKeyword, String$2],\n    [AtKeyword, Colon],\n\n    [Percentage$1, Percentage$1],\n    [Percentage$1, Dimension$1],\n    [Percentage$1, Function$1],\n    [Percentage$1, '-'],\n\n    [RightParenthesis, Ident],\n    [RightParenthesis, Function$1],\n    [RightParenthesis, Percentage$1],\n    [RightParenthesis, Dimension$1],\n    [RightParenthesis, Hash$1],\n    [RightParenthesis, '-']\n]);\n\nfunction createMap(pairs) {\n    const isWhiteSpaceRequired = new Set(\n        pairs.map(([prev, next]) => (code(prev) << 16 | code(next)))\n    );\n\n    return function(prevCode, type, value) {\n        const nextCode = code(type, value);\n        const nextCharCode = value.charCodeAt(0);\n        const emitWs =\n            (nextCharCode === HYPHENMINUS$6 &&\n                type !== Ident &&\n                type !== Function$1 &&\n                type !== CDC$1) ||\n            (nextCharCode === PLUSSIGN$9)\n                ? isWhiteSpaceRequired.has(prevCode << 16 | nextCharCode << 8)\n                : isWhiteSpaceRequired.has(prevCode << 16 | nextCode);\n\n        if (emitWs) {\n            this.emit(' ', WhiteSpace$1, true);\n        }\n\n        return nextCode;\n    };\n}\n\nconst spec = createMap(specPairs);\nconst safe = createMap(safePairs);\n\nvar tokenBefore = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    spec: spec,\n    safe: safe\n});\n\nconst REVERSESOLIDUS = 0x005c; // U+005C REVERSE SOLIDUS (\\)\n\nfunction processChildren(node, delimeter) {\n    if (typeof delimeter === 'function') {\n        let prev = null;\n\n        node.children.forEach(node => {\n            if (prev !== null) {\n                delimeter.call(this, prev);\n            }\n\n            this.node(node);\n            prev = node;\n        });\n\n        return;\n    }\n\n    node.children.forEach(this.node, this);\n}\n\nfunction processChunk(chunk) {\n    tokenize$1(chunk, (type, start, end) => {\n        this.token(type, chunk.slice(start, end));\n    });\n}\n\nfunction createGenerator(config) {\n    const types = new Map();\n\n    for (let [name, item] of Object.entries(config.node)) {\n        const fn = item.generate || item;\n\n        if (typeof fn === 'function') {\n            types.set(name, item.generate || item);\n        }\n    }\n\n    return function(node, options) {\n        let buffer = '';\n        let prevCode = 0;\n        let handlers = {\n            node(node) {\n                if (types.has(node.type)) {\n                    types.get(node.type).call(publicApi, node);\n                } else {\n                    throw new Error('Unknown node type: ' + node.type);\n                }\n            },\n            tokenBefore: safe,\n            token(type, value) {\n                prevCode = this.tokenBefore(prevCode, type, value);\n\n                this.emit(value, type, false);\n\n                if (type === Delim && value.charCodeAt(0) === REVERSESOLIDUS) {\n                    this.emit('\\n', WhiteSpace$1, true);\n                }\n            },\n            emit(value) {\n                buffer += value;\n            },\n            result() {\n                return buffer;\n            }\n        };\n\n        if (options) {\n            if (typeof options.decorator === 'function') {\n                handlers = options.decorator(handlers);\n            }\n\n            if (options.sourceMap) {\n                handlers = generateSourceMap(handlers);\n            }\n\n            if (options.mode in tokenBefore) {\n                handlers.tokenBefore = tokenBefore[options.mode];\n            }\n        }\n\n        const publicApi = {\n            node: (node) => handlers.node(node),\n            children: processChildren,\n            token: (type, value) => handlers.token(type, value),\n            tokenize: processChunk\n        };\n\n        handlers.node(node);\n\n        return handlers.result();\n    };\n}\n\nfunction createConvertor(walk) {\n    return {\n        fromPlainObject(ast) {\n            walk(ast, {\n                enter(node) {\n                    if (node.children && node.children instanceof List === false) {\n                        node.children = new List().fromArray(node.children);\n                    }\n                }\n            });\n\n            return ast;\n        },\n        toPlainObject(ast) {\n            walk(ast, {\n                leave(node) {\n                    if (node.children && node.children instanceof List) {\n                        node.children = node.children.toArray();\n                    }\n                }\n            });\n\n            return ast;\n        }\n    };\n}\n\nconst { hasOwnProperty: hasOwnProperty$3 } = Object.prototype;\nconst noop$2 = function() {};\n\nfunction ensureFunction$1(value) {\n    return typeof value === 'function' ? value : noop$2;\n}\n\nfunction invokeForType(fn, type) {\n    return function(node, item, list) {\n        if (node.type === type) {\n            fn.call(this, node, item, list);\n        }\n    };\n}\n\nfunction getWalkersFromStructure(name, nodeType) {\n    const structure = nodeType.structure;\n    const walkers = [];\n\n    for (const key in structure) {\n        if (hasOwnProperty$3.call(structure, key) === false) {\n            continue;\n        }\n\n        let fieldTypes = structure[key];\n        const walker = {\n            name: key,\n            type: false,\n            nullable: false\n        };\n\n        if (!Array.isArray(fieldTypes)) {\n            fieldTypes = [fieldTypes];\n        }\n\n        for (const fieldType of fieldTypes) {\n            if (fieldType === null) {\n                walker.nullable = true;\n            } else if (typeof fieldType === 'string') {\n                walker.type = 'node';\n            } else if (Array.isArray(fieldType)) {\n                walker.type = 'list';\n            }\n        }\n\n        if (walker.type) {\n            walkers.push(walker);\n        }\n    }\n\n    if (walkers.length) {\n        return {\n            context: nodeType.walkContext,\n            fields: walkers\n        };\n    }\n\n    return null;\n}\n\nfunction getTypesFromConfig(config) {\n    const types = {};\n\n    for (const name in config.node) {\n        if (hasOwnProperty$3.call(config.node, name)) {\n            const nodeType = config.node[name];\n\n            if (!nodeType.structure) {\n                throw new Error('Missed `structure` field in `' + name + '` node type definition');\n            }\n\n            types[name] = getWalkersFromStructure(name, nodeType);\n        }\n    }\n\n    return types;\n}\n\nfunction createTypeIterator(config, reverse) {\n    const fields = config.fields.slice();\n    const contextName = config.context;\n    const useContext = typeof contextName === 'string';\n\n    if (reverse) {\n        fields.reverse();\n    }\n\n    return function(node, context, walk, walkReducer) {\n        let prevContextValue;\n\n        if (useContext) {\n            prevContextValue = context[contextName];\n            context[contextName] = node;\n        }\n\n        for (const field of fields) {\n            const ref = node[field.name];\n\n            if (!field.nullable || ref) {\n                if (field.type === 'list') {\n                    const breakWalk = reverse\n                        ? ref.reduceRight(walkReducer, false)\n                        : ref.reduce(walkReducer, false);\n\n                    if (breakWalk) {\n                        return true;\n                    }\n                } else if (walk(ref)) {\n                    return true;\n                }\n            }\n        }\n\n        if (useContext) {\n            context[contextName] = prevContextValue;\n        }\n    };\n}\n\nfunction createFastTraveralMap({\n    StyleSheet,\n    Atrule,\n    Rule,\n    Block,\n    DeclarationList\n}) {\n    return {\n        Atrule: {\n            StyleSheet,\n            Atrule,\n            Rule,\n            Block\n        },\n        Rule: {\n            StyleSheet,\n            Atrule,\n            Rule,\n            Block\n        },\n        Declaration: {\n            StyleSheet,\n            Atrule,\n            Rule,\n            Block,\n            DeclarationList\n        }\n    };\n}\n\nfunction createWalker(config) {\n    const types = getTypesFromConfig(config);\n    const iteratorsNatural = {};\n    const iteratorsReverse = {};\n    const breakWalk = Symbol('break-walk');\n    const skipNode = Symbol('skip-node');\n\n    for (const name in types) {\n        if (hasOwnProperty$3.call(types, name) && types[name] !== null) {\n            iteratorsNatural[name] = createTypeIterator(types[name], false);\n            iteratorsReverse[name] = createTypeIterator(types[name], true);\n        }\n    }\n\n    const fastTraversalIteratorsNatural = createFastTraveralMap(iteratorsNatural);\n    const fastTraversalIteratorsReverse = createFastTraveralMap(iteratorsReverse);\n\n    const walk = function(root, options) {\n        function walkNode(node, item, list) {\n            const enterRet = enter.call(context, node, item, list);\n\n            if (enterRet === breakWalk) {\n                return true;\n            }\n\n            if (enterRet === skipNode) {\n                return false;\n            }\n\n            if (iterators.hasOwnProperty(node.type)) {\n                if (iterators[node.type](node, context, walkNode, walkReducer)) {\n                    return true;\n                }\n            }\n\n            if (leave.call(context, node, item, list) === breakWalk) {\n                return true;\n            }\n\n            return false;\n        }\n\n        let enter = noop$2;\n        let leave = noop$2;\n        let iterators = iteratorsNatural;\n        let walkReducer = (ret, data, item, list) => ret || walkNode(data, item, list);\n        const context = {\n            break: breakWalk,\n            skip: skipNode,\n\n            root,\n            stylesheet: null,\n            atrule: null,\n            atrulePrelude: null,\n            rule: null,\n            selector: null,\n            block: null,\n            declaration: null,\n            function: null\n        };\n\n        if (typeof options === 'function') {\n            enter = options;\n        } else if (options) {\n            enter = ensureFunction$1(options.enter);\n            leave = ensureFunction$1(options.leave);\n\n            if (options.reverse) {\n                iterators = iteratorsReverse;\n            }\n\n            if (options.visit) {\n                if (fastTraversalIteratorsNatural.hasOwnProperty(options.visit)) {\n                    iterators = options.reverse\n                        ? fastTraversalIteratorsReverse[options.visit]\n                        : fastTraversalIteratorsNatural[options.visit];\n                } else if (!types.hasOwnProperty(options.visit)) {\n                    throw new Error('Bad value `' + options.visit + '` for `visit` option (should be: ' + Object.keys(types).sort().join(', ') + ')');\n                }\n\n                enter = invokeForType(enter, options.visit);\n                leave = invokeForType(leave, options.visit);\n            }\n        }\n\n        if (enter === noop$2 && leave === noop$2) {\n            throw new Error('Neither `enter` nor `leave` walker handler is set or both aren\\'t a function');\n        }\n\n        walkNode(root);\n    };\n\n    walk.break = breakWalk;\n    walk.skip = skipNode;\n\n    walk.find = function(ast, fn) {\n        let found = null;\n\n        walk(ast, function(node, item, list) {\n            if (fn.call(this, node, item, list)) {\n                found = node;\n                return breakWalk;\n            }\n        });\n\n        return found;\n    };\n\n    walk.findLast = function(ast, fn) {\n        let found = null;\n\n        walk(ast, {\n            reverse: true,\n            enter(node, item, list) {\n                if (fn.call(this, node, item, list)) {\n                    found = node;\n                    return breakWalk;\n                }\n            }\n        });\n\n        return found;\n    };\n\n    walk.findAll = function(ast, fn) {\n        const found = [];\n\n        walk(ast, function(node, item, list) {\n            if (fn.call(this, node, item, list)) {\n                found.push(node);\n            }\n        });\n\n        return found;\n    };\n\n    return walk;\n}\n\nfunction noop$1(value) {\n    return value;\n}\n\nfunction generateMultiplier(multiplier) {\n    const { min, max, comma } = multiplier;\n\n    if (min === 0 && max === 0) {\n        return comma ? '#?' : '*';\n    }\n\n    if (min === 0 && max === 1) {\n        return '?';\n    }\n\n    if (min === 1 && max === 0) {\n        return comma ? '#' : '+';\n    }\n\n    if (min === 1 && max === 1) {\n        return '';\n    }\n\n    return (\n        (comma ? '#' : '') +\n        (min === max\n            ? '{' + min + '}'\n            : '{' + min + ',' + (max !== 0 ? max : '') + '}'\n        )\n    );\n}\n\nfunction generateTypeOpts(node) {\n    switch (node.type) {\n        case 'Range':\n            return (\n                ' [' +\n                (node.min === null ? '-∞' : node.min) +\n                ',' +\n                (node.max === null ? '∞' : node.max) +\n                ']'\n            );\n\n        default:\n            throw new Error('Unknown node type `' + node.type + '`');\n    }\n}\n\nfunction generateSequence(node, decorate, forceBraces, compact) {\n    const combinator = node.combinator === ' ' || compact ? node.combinator : ' ' + node.combinator + ' ';\n    const result = node.terms\n        .map(term => internalGenerate(term, decorate, forceBraces, compact))\n        .join(combinator);\n\n    if (node.explicit || forceBraces) {\n        return (compact || result[0] === ',' ? '[' : '[ ') + result + (compact ? ']' : ' ]');\n    }\n\n    return result;\n}\n\nfunction internalGenerate(node, decorate, forceBraces, compact) {\n    let result;\n\n    switch (node.type) {\n        case 'Group':\n            result =\n                generateSequence(node, decorate, forceBraces, compact) +\n                (node.disallowEmpty ? '!' : '');\n            break;\n\n        case 'Multiplier':\n            // return since node is a composition\n            return (\n                internalGenerate(node.term, decorate, forceBraces, compact) +\n                decorate(generateMultiplier(node), node)\n            );\n\n        case 'Boolean':\n            result = '<boolean-expr[' + internalGenerate(node.term, decorate, forceBraces, compact) + ']>';\n            break;\n\n        case 'Type':\n            result = '<' + node.name + (node.opts ? decorate(generateTypeOpts(node.opts), node.opts) : '') + '>';\n            break;\n\n        case 'Property':\n            result = '<\\'' + node.name + '\\'>';\n            break;\n\n        case 'Keyword':\n            result = node.name;\n            break;\n\n        case 'AtKeyword':\n            result = '@' + node.name;\n            break;\n\n        case 'Function':\n            result = node.name + '(';\n            break;\n\n        case 'String':\n        case 'Token':\n            result = node.value;\n            break;\n\n        case 'Comma':\n            result = ',';\n            break;\n\n        default:\n            throw new Error('Unknown node type `' + node.type + '`');\n    }\n\n    return decorate(result, node);\n}\n\nfunction generate$O(node, options) {\n    let decorate = noop$1;\n    let forceBraces = false;\n    let compact = false;\n\n    if (typeof options === 'function') {\n        decorate = options;\n    } else if (options) {\n        forceBraces = Boolean(options.forceBraces);\n        compact = Boolean(options.compact);\n        if (typeof options.decorate === 'function') {\n            decorate = options.decorate;\n        }\n    }\n\n    return internalGenerate(node, decorate, forceBraces, compact);\n}\n\nconst defaultLoc = { offset: 0, line: 1, column: 1 };\n\nfunction locateMismatch(matchResult, node) {\n    const tokens = matchResult.tokens;\n    const longestMatch = matchResult.longestMatch;\n    const mismatchNode = longestMatch < tokens.length ? tokens[longestMatch].node || null : null;\n    const badNode = mismatchNode !== node ? mismatchNode : null;\n    let mismatchOffset = 0;\n    let mismatchLength = 0;\n    let entries = 0;\n    let css = '';\n    let start;\n    let end;\n\n    for (let i = 0; i < tokens.length; i++) {\n        const token = tokens[i].value;\n\n        if (i === longestMatch) {\n            mismatchLength = token.length;\n            mismatchOffset = css.length;\n        }\n\n        if (badNode !== null && tokens[i].node === badNode) {\n            if (i <= longestMatch) {\n                entries++;\n            } else {\n                entries = 0;\n            }\n        }\n\n        css += token;\n    }\n\n    if (longestMatch === tokens.length || entries > 1) { // last\n        start = fromLoc(badNode || node, 'end') || buildLoc(defaultLoc, css);\n        end = buildLoc(start);\n    } else {\n        start = fromLoc(badNode, 'start') ||\n            buildLoc(fromLoc(node, 'start') || defaultLoc, css.slice(0, mismatchOffset));\n        end = fromLoc(badNode, 'end') ||\n            buildLoc(start, css.substr(mismatchOffset, mismatchLength));\n    }\n\n    return {\n        css,\n        mismatchOffset,\n        mismatchLength,\n        start,\n        end\n    };\n}\n\nfunction fromLoc(node, point) {\n    const value = node && node.loc && node.loc[point];\n\n    if (value) {\n        return 'line' in value ? buildLoc(value) : value;\n    }\n\n    return null;\n}\n\nfunction buildLoc({ offset, line, column }, extra) {\n    const loc = {\n        offset,\n        line,\n        column\n    };\n\n    if (extra) {\n        const lines = extra.split(/\\n|\\r\\n?|\\f/);\n\n        loc.offset += extra.length;\n        loc.line += lines.length - 1;\n        loc.column = lines.length === 1 ? loc.column + extra.length : lines.pop().length + 1;\n    }\n\n    return loc;\n}\n\nconst SyntaxReferenceError = function(type, referenceName) {\n    const error = createCustomError(\n        'SyntaxReferenceError',\n        type + (referenceName ? ' `' + referenceName + '`' : '')\n    );\n\n    error.reference = referenceName;\n\n    return error;\n};\n\nconst SyntaxMatchError = function(message, syntax, node, matchResult) {\n    const error = createCustomError('SyntaxMatchError', message);\n    const {\n        css,\n        mismatchOffset,\n        mismatchLength,\n        start,\n        end\n    } = locateMismatch(matchResult, node);\n\n    error.rawMessage = message;\n    error.syntax = syntax ? generate$O(syntax) : '<generic>';\n    error.css = css;\n    error.mismatchOffset = mismatchOffset;\n    error.mismatchLength = mismatchLength;\n    error.message = message + '\\n' +\n        '  syntax: ' + error.syntax + '\\n' +\n        '   value: ' + (css || '<empty string>') + '\\n' +\n        '  --------' + new Array(error.mismatchOffset + 1).join('-') + '^';\n\n    Object.assign(error, start);\n    error.loc = {\n        source: (node && node.loc && node.loc.source) || '<unknown>',\n        start,\n        end\n    };\n\n    return error;\n};\n\nconst keywords = new Map();\nconst properties = new Map();\nconst HYPHENMINUS$5 = 45; // '-'.charCodeAt()\n\nconst keyword = getKeywordDescriptor;\nconst property = getPropertyDescriptor;\nconst vendorPrefix = getVendorPrefix;\nfunction isCustomProperty(str, offset) {\n    offset = offset || 0;\n\n    return str.length - offset >= 2 &&\n           str.charCodeAt(offset) === HYPHENMINUS$5 &&\n           str.charCodeAt(offset + 1) === HYPHENMINUS$5;\n}\n\nfunction getVendorPrefix(str, offset) {\n    offset = offset || 0;\n\n    // verdor prefix should be at least 3 chars length\n    if (str.length - offset >= 3) {\n        // vendor prefix starts with hyper minus following non-hyper minus\n        if (str.charCodeAt(offset) === HYPHENMINUS$5 &&\n            str.charCodeAt(offset + 1) !== HYPHENMINUS$5) {\n            // vendor prefix should contain a hyper minus at the ending\n            const secondDashIndex = str.indexOf('-', offset + 2);\n\n            if (secondDashIndex !== -1) {\n                return str.substring(offset, secondDashIndex + 1);\n            }\n        }\n    }\n\n    return '';\n}\n\nfunction getKeywordDescriptor(keyword) {\n    if (keywords.has(keyword)) {\n        return keywords.get(keyword);\n    }\n\n    const name = keyword.toLowerCase();\n    let descriptor = keywords.get(name);\n\n    if (descriptor === undefined) {\n        const custom = isCustomProperty(name, 0);\n        const vendor = !custom ? getVendorPrefix(name, 0) : '';\n        descriptor = Object.freeze({\n            basename: name.substr(vendor.length),\n            name,\n            prefix: vendor,\n            vendor,\n            custom\n        });\n    }\n\n    keywords.set(keyword, descriptor);\n\n    return descriptor;\n}\n\nfunction getPropertyDescriptor(property) {\n    if (properties.has(property)) {\n        return properties.get(property);\n    }\n\n    let name = property;\n    let hack = property[0];\n\n    if (hack === '/') {\n        hack = property[1] === '/' ? '//' : '/';\n    } else if (hack !== '_' &&\n               hack !== '*' &&\n               hack !== '$' &&\n               hack !== '#' &&\n               hack !== '+' &&\n               hack !== '&') {\n        hack = '';\n    }\n\n    const custom = isCustomProperty(name, hack.length);\n\n    // re-use result when possible (the same as for lower case)\n    if (!custom) {\n        name = name.toLowerCase();\n        if (properties.has(name)) {\n            const descriptor = properties.get(name);\n            properties.set(property, descriptor);\n            return descriptor;\n        }\n    }\n\n    const vendor = !custom ? getVendorPrefix(name, hack.length) : '';\n    const prefix = name.substr(0, hack.length + vendor.length);\n    const descriptor = Object.freeze({\n        basename: name.substr(prefix.length),\n        name: name.substr(hack.length),\n        hack,\n        vendor,\n        prefix,\n        custom\n    });\n\n    properties.set(property, descriptor);\n\n    return descriptor;\n}\n\n// https://drafts.csswg.org/css-cascade-5/\nconst cssWideKeywords = [\n    'initial',\n    'inherit',\n    'unset',\n    'revert',\n    'revert-layer'\n];\n\nconst PLUSSIGN$8 = 0x002B;    // U+002B PLUS SIGN (+)\nconst HYPHENMINUS$4 = 0x002D; // U+002D HYPHEN-MINUS (-)\nconst N$3 = 0x006E;           // U+006E LATIN SMALL LETTER N (n)\nconst DISALLOW_SIGN$1 = true;\nconst ALLOW_SIGN$1 = false;\n\nfunction isDelim$1(token, code) {\n    return token !== null && token.type === Delim && token.value.charCodeAt(0) === code;\n}\n\nfunction skipSC(token, offset, getNextToken) {\n    while (token !== null && (token.type === WhiteSpace$1 || token.type === Comment$1)) {\n        token = getNextToken(++offset);\n    }\n\n    return offset;\n}\n\nfunction checkInteger$1(token, valueOffset, disallowSign, offset) {\n    if (!token) {\n        return 0;\n    }\n\n    const code = token.value.charCodeAt(valueOffset);\n\n    if (code === PLUSSIGN$8 || code === HYPHENMINUS$4) {\n        if (disallowSign) {\n            // Number sign is not allowed\n            return 0;\n        }\n        valueOffset++;\n    }\n\n    for (; valueOffset < token.value.length; valueOffset++) {\n        if (!isDigit(token.value.charCodeAt(valueOffset))) {\n            // Integer is expected\n            return 0;\n        }\n    }\n\n    return offset + 1;\n}\n\n// ... <signed-integer>\n// ... ['+' | '-'] <signless-integer>\nfunction consumeB$1(token, offset_, getNextToken) {\n    let sign = false;\n    let offset = skipSC(token, offset_, getNextToken);\n\n    token = getNextToken(offset);\n\n    if (token === null) {\n        return offset_;\n    }\n\n    if (token.type !== Number$2) {\n        if (isDelim$1(token, PLUSSIGN$8) || isDelim$1(token, HYPHENMINUS$4)) {\n            sign = true;\n            offset = skipSC(getNextToken(++offset), offset, getNextToken);\n            token = getNextToken(offset);\n\n            if (token === null || token.type !== Number$2) {\n                return 0;\n            }\n        } else {\n            return offset_;\n        }\n    }\n\n    if (!sign) {\n        const code = token.value.charCodeAt(0);\n        if (code !== PLUSSIGN$8 && code !== HYPHENMINUS$4) {\n            // Number sign is expected\n            return 0;\n        }\n    }\n\n    return checkInteger$1(token, sign ? 0 : 1, sign, offset);\n}\n\n// An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb\nfunction anPlusB(token, getNextToken) {\n    /* eslint-disable brace-style*/\n    let offset = 0;\n\n    if (!token) {\n        return 0;\n    }\n\n    // <integer>\n    if (token.type === Number$2) {\n        return checkInteger$1(token, 0, ALLOW_SIGN$1, offset); // b\n    }\n\n    // -n\n    // -n <signed-integer>\n    // -n ['+' | '-'] <signless-integer>\n    // -n- <signless-integer>\n    // <dashndashdigit-ident>\n    else if (token.type === Ident && token.value.charCodeAt(0) === HYPHENMINUS$4) {\n        // expect 1st char is N\n        if (!cmpChar(token.value, 1, N$3)) {\n            return 0;\n        }\n\n        switch (token.value.length) {\n            // -n\n            // -n <signed-integer>\n            // -n ['+' | '-'] <signless-integer>\n            case 2:\n                return consumeB$1(getNextToken(++offset), offset, getNextToken);\n\n            // -n- <signless-integer>\n            case 3:\n                if (token.value.charCodeAt(2) !== HYPHENMINUS$4) {\n                    return 0;\n                }\n\n                offset = skipSC(getNextToken(++offset), offset, getNextToken);\n                token = getNextToken(offset);\n\n                return checkInteger$1(token, 0, DISALLOW_SIGN$1, offset);\n\n            // <dashndashdigit-ident>\n            default:\n                if (token.value.charCodeAt(2) !== HYPHENMINUS$4) {\n                    return 0;\n                }\n\n                return checkInteger$1(token, 3, DISALLOW_SIGN$1, offset);\n        }\n    }\n\n    // '+'? n\n    // '+'? n <signed-integer>\n    // '+'? n ['+' | '-'] <signless-integer>\n    // '+'? n- <signless-integer>\n    // '+'? <ndashdigit-ident>\n    else if (token.type === Ident || (isDelim$1(token, PLUSSIGN$8) && getNextToken(offset + 1).type === Ident)) {\n        // just ignore a plus\n        if (token.type !== Ident) {\n            token = getNextToken(++offset);\n        }\n\n        if (token === null || !cmpChar(token.value, 0, N$3)) {\n            return 0;\n        }\n\n        switch (token.value.length) {\n            // '+'? n\n            // '+'? n <signed-integer>\n            // '+'? n ['+' | '-'] <signless-integer>\n            case 1:\n                return consumeB$1(getNextToken(++offset), offset, getNextToken);\n\n            // '+'? n- <signless-integer>\n            case 2:\n                if (token.value.charCodeAt(1) !== HYPHENMINUS$4) {\n                    return 0;\n                }\n\n                offset = skipSC(getNextToken(++offset), offset, getNextToken);\n                token = getNextToken(offset);\n\n                return checkInteger$1(token, 0, DISALLOW_SIGN$1, offset);\n\n            // '+'? <ndashdigit-ident>\n            default:\n                if (token.value.charCodeAt(1) !== HYPHENMINUS$4) {\n                    return 0;\n                }\n\n                return checkInteger$1(token, 2, DISALLOW_SIGN$1, offset);\n        }\n    }\n\n    // <ndashdigit-dimension>\n    // <ndash-dimension> <signless-integer>\n    // <n-dimension>\n    // <n-dimension> <signed-integer>\n    // <n-dimension> ['+' | '-'] <signless-integer>\n    else if (token.type === Dimension$1) {\n        let code = token.value.charCodeAt(0);\n        let sign = code === PLUSSIGN$8 || code === HYPHENMINUS$4 ? 1 : 0;\n        let i = sign;\n\n        for (; i < token.value.length; i++) {\n            if (!isDigit(token.value.charCodeAt(i))) {\n                break;\n            }\n        }\n\n        if (i === sign) {\n            // Integer is expected\n            return 0;\n        }\n\n        if (!cmpChar(token.value, i, N$3)) {\n            return 0;\n        }\n\n        // <n-dimension>\n        // <n-dimension> <signed-integer>\n        // <n-dimension> ['+' | '-'] <signless-integer>\n        if (i + 1 === token.value.length) {\n            return consumeB$1(getNextToken(++offset), offset, getNextToken);\n        } else {\n            if (token.value.charCodeAt(i + 1) !== HYPHENMINUS$4) {\n                return 0;\n            }\n\n            // <ndash-dimension> <signless-integer>\n            if (i + 2 === token.value.length) {\n                offset = skipSC(getNextToken(++offset), offset, getNextToken);\n                token = getNextToken(offset);\n\n                return checkInteger$1(token, 0, DISALLOW_SIGN$1, offset);\n            }\n            // <ndashdigit-dimension>\n            else {\n                return checkInteger$1(token, i + 2, DISALLOW_SIGN$1, offset);\n            }\n        }\n    }\n\n    return 0;\n}\n\nconst PLUSSIGN$7 = 0x002B;     // U+002B PLUS SIGN (+)\nconst HYPHENMINUS$3 = 0x002D;  // U+002D HYPHEN-MINUS (-)\nconst QUESTIONMARK$2 = 0x003F; // U+003F QUESTION MARK (?)\nconst U$1 = 0x0075;            // U+0075 LATIN SMALL LETTER U (u)\n\nfunction isDelim(token, code) {\n    return token !== null && token.type === Delim && token.value.charCodeAt(0) === code;\n}\n\nfunction startsWith$1(token, code) {\n    return token.value.charCodeAt(0) === code;\n}\n\nfunction hexSequence(token, offset, allowDash) {\n    let hexlen = 0;\n\n    for (let pos = offset; pos < token.value.length; pos++) {\n        const code = token.value.charCodeAt(pos);\n\n        if (code === HYPHENMINUS$3 && allowDash && hexlen !== 0) {\n            hexSequence(token, offset + hexlen + 1, false);\n            return 6; // dissallow following question marks\n        }\n\n        if (!isHexDigit(code)) {\n            return 0; // not a hex digit\n        }\n\n        if (++hexlen > 6) {\n            return 0; // too many hex digits\n        }    }\n\n    return hexlen;\n}\n\nfunction withQuestionMarkSequence(consumed, length, getNextToken) {\n    if (!consumed) {\n        return 0; // nothing consumed\n    }\n\n    while (isDelim(getNextToken(length), QUESTIONMARK$2)) {\n        if (++consumed > 6) {\n            return 0; // too many question marks\n        }\n\n        length++;\n    }\n\n    return length;\n}\n\n// https://drafts.csswg.org/css-syntax/#urange\n// Informally, the <urange> production has three forms:\n// U+0001\n//      Defines a range consisting of a single code point, in this case the code point \"1\".\n// U+0001-00ff\n//      Defines a range of codepoints between the first and the second value, in this case\n//      the range between \"1\" and \"ff\" (255 in decimal) inclusive.\n// U+00??\n//      Defines a range of codepoints where the \"?\" characters range over all hex digits,\n//      in this case defining the same as the value U+0000-00ff.\n// In each form, a maximum of 6 digits is allowed for each hexadecimal number (if you treat \"?\" as a hexadecimal digit).\n//\n// <urange> =\n//   u '+' <ident-token> '?'* |\n//   u <dimension-token> '?'* |\n//   u <number-token> '?'* |\n//   u <number-token> <dimension-token> |\n//   u <number-token> <number-token> |\n//   u '+' '?'+\nfunction urange(token, getNextToken) {\n    let length = 0;\n\n    // should start with `u` or `U`\n    if (token === null || token.type !== Ident || !cmpChar(token.value, 0, U$1)) {\n        return 0;\n    }\n\n    token = getNextToken(++length);\n    if (token === null) {\n        return 0;\n    }\n\n    // u '+' <ident-token> '?'*\n    // u '+' '?'+\n    if (isDelim(token, PLUSSIGN$7)) {\n        token = getNextToken(++length);\n        if (token === null) {\n            return 0;\n        }\n\n        if (token.type === Ident) {\n            // u '+' <ident-token> '?'*\n            return withQuestionMarkSequence(hexSequence(token, 0, true), ++length, getNextToken);\n        }\n\n        if (isDelim(token, QUESTIONMARK$2)) {\n            // u '+' '?'+\n            return withQuestionMarkSequence(1, ++length, getNextToken);\n        }\n\n        // Hex digit or question mark is expected\n        return 0;\n    }\n\n    // u <number-token> '?'*\n    // u <number-token> <dimension-token>\n    // u <number-token> <number-token>\n    if (token.type === Number$2) {\n        const consumedHexLength = hexSequence(token, 1, true);\n        if (consumedHexLength === 0) {\n            return 0;\n        }\n\n        token = getNextToken(++length);\n        if (token === null) {\n            // u <number-token> <eof>\n            return length;\n        }\n\n        if (token.type === Dimension$1 || token.type === Number$2) {\n            // u <number-token> <dimension-token>\n            // u <number-token> <number-token>\n            if (!startsWith$1(token, HYPHENMINUS$3) || !hexSequence(token, 1, false)) {\n                return 0;\n            }\n\n            return length + 1;\n        }\n\n        // u <number-token> '?'*\n        return withQuestionMarkSequence(consumedHexLength, length, getNextToken);\n    }\n\n    // u <dimension-token> '?'*\n    if (token.type === Dimension$1) {\n        return withQuestionMarkSequence(hexSequence(token, 1, true), ++length, getNextToken);\n    }\n\n    return 0;\n}\n\nconst calcFunctionNames = ['calc(', '-moz-calc(', '-webkit-calc('];\nconst balancePair = new Map([\n    [Function$1, RightParenthesis],\n    [LeftParenthesis, RightParenthesis],\n    [LeftSquareBracket, RightSquareBracket],\n    [LeftCurlyBracket, RightCurlyBracket]\n]);\n\n// safe char code getter\nfunction charCodeAt(str, index) {\n    return index < str.length ? str.charCodeAt(index) : 0;\n}\n\nfunction eqStr(actual, expected) {\n    return cmpStr(actual, 0, actual.length, expected);\n}\n\nfunction eqStrAny(actual, expected) {\n    for (let i = 0; i < expected.length; i++) {\n        if (eqStr(actual, expected[i])) {\n            return true;\n        }\n    }\n\n    return false;\n}\n\n// IE postfix hack, i.e. 123\\0 or 123px\\9\nfunction isPostfixIeHack(str, offset) {\n    if (offset !== str.length - 2) {\n        return false;\n    }\n\n    return (\n        charCodeAt(str, offset) === 0x005C &&  // U+005C REVERSE SOLIDUS (\\)\n        isDigit(charCodeAt(str, offset + 1))\n    );\n}\n\nfunction outOfRange(opts, value, numEnd) {\n    if (opts && opts.type === 'Range') {\n        const num = Number(\n            numEnd !== undefined && numEnd !== value.length\n                ? value.substr(0, numEnd)\n                : value\n        );\n\n        if (isNaN(num)) {\n            return true;\n        }\n\n        // FIXME: when opts.min is a string it's a dimension, skip a range validation\n        // for now since it requires a type covertation which is not implmented yet\n        if (opts.min !== null && num < opts.min && typeof opts.min !== 'string') {\n            return true;\n        }\n\n        // FIXME: when opts.max is a string it's a dimension, skip a range validation\n        // for now since it requires a type covertation which is not implmented yet\n        if (opts.max !== null && num > opts.max && typeof opts.max !== 'string') {\n            return true;\n        }\n    }\n\n    return false;\n}\n\nfunction consumeFunction(token, getNextToken) {\n    let balanceCloseType = 0;\n    let balanceStash = [];\n    let length = 0;\n\n    // balanced token consuming\n    scan:\n    do {\n        switch (token.type) {\n            case RightCurlyBracket:\n            case RightParenthesis:\n            case RightSquareBracket:\n                if (token.type !== balanceCloseType) {\n                    break scan;\n                }\n\n                balanceCloseType = balanceStash.pop();\n\n                if (balanceStash.length === 0) {\n                    length++;\n                    break scan;\n                }\n\n                break;\n\n            case Function$1:\n            case LeftParenthesis:\n            case LeftSquareBracket:\n            case LeftCurlyBracket:\n                balanceStash.push(balanceCloseType);\n                balanceCloseType = balancePair.get(token.type);\n                break;\n        }\n\n        length++;\n    } while (token = getNextToken(length));\n\n    return length;\n}\n\n// TODO: implement\n// can be used wherever <length>, <frequency>, <angle>, <time>, <percentage>, <number>, or <integer> values are allowed\n// https://drafts.csswg.org/css-values/#calc-notation\nfunction calc(next) {\n    return function(token, getNextToken, opts) {\n        if (token === null) {\n            return 0;\n        }\n\n        if (token.type === Function$1 && eqStrAny(token.value, calcFunctionNames)) {\n            return consumeFunction(token, getNextToken);\n        }\n\n        return next(token, getNextToken, opts);\n    };\n}\n\nfunction tokenType(expectedTokenType) {\n    return function(token) {\n        if (token === null || token.type !== expectedTokenType) {\n            return 0;\n        }\n\n        return 1;\n    };\n}\n\n// =========================\n// Complex types\n//\n\n// https://drafts.csswg.org/css-values-4/#custom-idents\n// 4.2. Author-defined Identifiers: the <custom-ident> type\n// Some properties accept arbitrary author-defined identifiers as a component value.\n// This generic data type is denoted by <custom-ident>, and represents any valid CSS identifier\n// that would not be misinterpreted as a pre-defined keyword in that property’s value definition.\n//\n// See also: https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident\nfunction customIdent(token) {\n    if (token === null || token.type !== Ident) {\n        return 0;\n    }\n\n    const name = token.value.toLowerCase();\n\n    // The CSS-wide keywords are not valid <custom-ident>s\n    if (eqStrAny(name, cssWideKeywords)) {\n        return 0;\n    }\n\n    // The default keyword is reserved and is also not a valid <custom-ident>\n    if (eqStr(name, 'default')) {\n        return 0;\n    }\n\n    // TODO: ignore property specific keywords (as described https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident)\n    // Specifications using <custom-ident> must specify clearly what other keywords\n    // are excluded from <custom-ident>, if any—for example by saying that any pre-defined keywords\n    // in that property’s value definition are excluded. Excluded keywords are excluded\n    // in all ASCII case permutations.\n\n    return 1;\n}\n\n// https://drafts.csswg.org/css-values-4/#dashed-idents\n// The <dashed-ident> production is a <custom-ident>, with all the case-sensitivity that implies,\n// with the additional restriction that it must start with two dashes (U+002D HYPHEN-MINUS).\nfunction dashedIdent(token) {\n    if (token === null || token.type !== Ident) {\n        return 0;\n    }\n\n    // ... must start with two dashes (U+002D HYPHEN-MINUS)\n    if (charCodeAt(token.value, 0) !== 0x002D || charCodeAt(token.value, 1) !== 0x002D) {\n        return 0;\n    }\n\n    return 1;\n}\n\n// https://drafts.csswg.org/css-variables/#typedef-custom-property-name\n// A custom property is any property whose name starts with two dashes (U+002D HYPHEN-MINUS), like --foo.\n// The <custom-property-name> production corresponds to this: it’s defined as any <dashed-ident>\n// (a valid identifier that starts with two dashes), except -- itself, which is reserved for future use by CSS.\nfunction customPropertyName(token) {\n    // ... it’s defined as any <dashed-ident>\n    if (!dashedIdent(token)) {\n        return 0;\n    }\n\n    // ... except -- itself, which is reserved for future use by CSS\n    if (token.value === '--') {\n        return 0;\n    }\n\n    return 1;\n}\n\n// https://drafts.csswg.org/css-color-4/#hex-notation\n// The syntax of a <hex-color> is a <hash-token> token whose value consists of 3, 4, 6, or 8 hexadecimal digits.\n// In other words, a hex color is written as a hash character, \"#\", followed by some number of digits 0-9 or\n// letters a-f (the case of the letters doesn’t matter - #00ff00 is identical to #00FF00).\nfunction hexColor(token) {\n    if (token === null || token.type !== Hash$1) {\n        return 0;\n    }\n\n    const length = token.value.length;\n\n    // valid values (length): #rgb (4), #rgba (5), #rrggbb (7), #rrggbbaa (9)\n    if (length !== 4 && length !== 5 && length !== 7 && length !== 9) {\n        return 0;\n    }\n\n    for (let i = 1; i < length; i++) {\n        if (!isHexDigit(charCodeAt(token.value, i))) {\n            return 0;\n        }\n    }\n\n    return 1;\n}\n\nfunction idSelector(token) {\n    if (token === null || token.type !== Hash$1) {\n        return 0;\n    }\n\n    if (!isIdentifierStart(charCodeAt(token.value, 1), charCodeAt(token.value, 2), charCodeAt(token.value, 3))) {\n        return 0;\n    }\n\n    return 1;\n}\n\n// https://drafts.csswg.org/css-syntax/#any-value\n// It represents the entirety of what a valid declaration can have as its value.\nfunction declarationValue(token, getNextToken) {\n    if (!token) {\n        return 0;\n    }\n\n    let balanceCloseType = 0;\n    let balanceStash = [];\n    let length = 0;\n\n    // The <declaration-value> production matches any sequence of one or more tokens,\n    // so long as the sequence does not contain ...\n    scan:\n    do {\n        switch (token.type) {\n            // ... <bad-string-token>, <bad-url-token>,\n            case BadString:\n            case BadUrl:\n                break scan;\n\n            // ... unmatched <)-token>, <]-token>, or <}-token>,\n            case RightCurlyBracket:\n            case RightParenthesis:\n            case RightSquareBracket:\n                if (token.type !== balanceCloseType) {\n                    break scan;\n                }\n\n                balanceCloseType = balanceStash.pop();\n                break;\n\n            // ... or top-level <semicolon-token> tokens\n            case Semicolon:\n                if (balanceCloseType === 0) {\n                    break scan;\n                }\n\n                break;\n\n            // ... or <delim-token> tokens with a value of \"!\"\n            case Delim:\n                if (balanceCloseType === 0 && token.value === '!') {\n                    break scan;\n                }\n\n                break;\n\n            case Function$1:\n            case LeftParenthesis:\n            case LeftSquareBracket:\n            case LeftCurlyBracket:\n                balanceStash.push(balanceCloseType);\n                balanceCloseType = balancePair.get(token.type);\n                break;\n        }\n\n        length++;\n    } while (token = getNextToken(length));\n\n    return length;\n}\n\n// https://drafts.csswg.org/css-syntax/#any-value\n// The <any-value> production is identical to <declaration-value>, but also\n// allows top-level <semicolon-token> tokens and <delim-token> tokens\n// with a value of \"!\". It represents the entirety of what valid CSS can be in any context.\nfunction anyValue(token, getNextToken) {\n    if (!token) {\n        return 0;\n    }\n\n    let balanceCloseType = 0;\n    let balanceStash = [];\n    let length = 0;\n\n    // The <any-value> production matches any sequence of one or more tokens,\n    // so long as the sequence ...\n    scan:\n    do {\n        switch (token.type) {\n            // ... does not contain <bad-string-token>, <bad-url-token>,\n            case BadString:\n            case BadUrl:\n                break scan;\n\n            // ... unmatched <)-token>, <]-token>, or <}-token>,\n            case RightCurlyBracket:\n            case RightParenthesis:\n            case RightSquareBracket:\n                if (token.type !== balanceCloseType) {\n                    break scan;\n                }\n\n                balanceCloseType = balanceStash.pop();\n                break;\n\n            case Function$1:\n            case LeftParenthesis:\n            case LeftSquareBracket:\n            case LeftCurlyBracket:\n                balanceStash.push(balanceCloseType);\n                balanceCloseType = balancePair.get(token.type);\n                break;\n        }\n\n        length++;\n    } while (token = getNextToken(length));\n\n    return length;\n}\n\n// =========================\n// Dimensions\n//\n\nfunction dimension(type) {\n    if (type) {\n        type = new Set(type);\n    }\n\n    return function(token, getNextToken, opts) {\n        if (token === null || token.type !== Dimension$1) {\n            return 0;\n        }\n\n        const numberEnd = consumeNumber(token.value, 0);\n\n        // check unit\n        if (type !== null) {\n            // check for IE postfix hack, i.e. 123px\\0 or 123px\\9\n            const reverseSolidusOffset = token.value.indexOf('\\\\', numberEnd);\n            const unit = reverseSolidusOffset === -1 || !isPostfixIeHack(token.value, reverseSolidusOffset)\n                ? token.value.substr(numberEnd)\n                : token.value.substring(numberEnd, reverseSolidusOffset);\n\n            if (type.has(unit.toLowerCase()) === false) {\n                return 0;\n            }\n        }\n\n        // check range if specified\n        if (outOfRange(opts, token.value, numberEnd)) {\n            return 0;\n        }\n\n        return 1;\n    };\n}\n\n// =========================\n// Percentage\n//\n\n// §5.5. Percentages: the <percentage> type\n// https://drafts.csswg.org/css-values-4/#percentages\nfunction percentage(token, getNextToken, opts) {\n    // ... corresponds to the <percentage-token> production\n    if (token === null || token.type !== Percentage$1) {\n        return 0;\n    }\n\n    // check range if specified\n    if (outOfRange(opts, token.value, token.value.length - 1)) {\n        return 0;\n    }\n\n    return 1;\n}\n\n// =========================\n// Numeric\n//\n\n// https://drafts.csswg.org/css-values-4/#numbers\n// The value <zero> represents a literal number with the value 0. Expressions that merely\n// evaluate to a <number> with the value 0 (for example, calc(0)) do not match <zero>;\n// only literal <number-token>s do.\nfunction zero(next) {\n    if (typeof next !== 'function') {\n        next = function() {\n            return 0;\n        };\n    }\n\n    return function(token, getNextToken, opts) {\n        if (token !== null && token.type === Number$2) {\n            if (Number(token.value) === 0) {\n                return 1;\n            }\n        }\n\n        return next(token, getNextToken, opts);\n    };\n}\n\n// § 5.3. Real Numbers: the <number> type\n// https://drafts.csswg.org/css-values-4/#numbers\n// Number values are denoted by <number>, and represent real numbers, possibly with a fractional component.\n// ... It corresponds to the <number-token> production\nfunction number(token, getNextToken, opts) {\n    if (token === null) {\n        return 0;\n    }\n\n    const numberEnd = consumeNumber(token.value, 0);\n    const isNumber = numberEnd === token.value.length;\n    if (!isNumber && !isPostfixIeHack(token.value, numberEnd)) {\n        return 0;\n    }\n\n    // check range if specified\n    if (outOfRange(opts, token.value, numberEnd)) {\n        return 0;\n    }\n\n    return 1;\n}\n\n// §5.2. Integers: the <integer> type\n// https://drafts.csswg.org/css-values-4/#integers\nfunction integer(token, getNextToken, opts) {\n    // ... corresponds to a subset of the <number-token> production\n    if (token === null || token.type !== Number$2) {\n        return 0;\n    }\n\n    // The first digit of an integer may be immediately preceded by `-` or `+` to indicate the integer’s sign.\n    let i = charCodeAt(token.value, 0) === 0x002B ||       // U+002B PLUS SIGN (+)\n            charCodeAt(token.value, 0) === 0x002D ? 1 : 0; // U+002D HYPHEN-MINUS (-)\n\n    // When written literally, an integer is one or more decimal digits 0 through 9 ...\n    for (; i < token.value.length; i++) {\n        if (!isDigit(charCodeAt(token.value, i))) {\n            return 0;\n        }\n    }\n\n    // check range if specified\n    if (outOfRange(opts, token.value, i)) {\n        return 0;\n    }\n\n    return 1;\n}\n\n// token types\nconst tokenTypes = {\n    'ident-token': tokenType(Ident),\n    'function-token': tokenType(Function$1),\n    'at-keyword-token': tokenType(AtKeyword),\n    'hash-token': tokenType(Hash$1),\n    'string-token': tokenType(String$2),\n    'bad-string-token': tokenType(BadString),\n    'url-token': tokenType(Url$1),\n    'bad-url-token': tokenType(BadUrl),\n    'delim-token': tokenType(Delim),\n    'number-token': tokenType(Number$2),\n    'percentage-token': tokenType(Percentage$1),\n    'dimension-token': tokenType(Dimension$1),\n    'whitespace-token': tokenType(WhiteSpace$1),\n    'CDO-token': tokenType(CDO$1),\n    'CDC-token': tokenType(CDC$1),\n    'colon-token': tokenType(Colon),\n    'semicolon-token': tokenType(Semicolon),\n    'comma-token': tokenType(Comma),\n    '[-token': tokenType(LeftSquareBracket),\n    ']-token': tokenType(RightSquareBracket),\n    '(-token': tokenType(LeftParenthesis),\n    ')-token': tokenType(RightParenthesis),\n    '{-token': tokenType(LeftCurlyBracket),\n    '}-token': tokenType(RightCurlyBracket)\n};\n\n// token production types\nconst productionTypes = {\n    // token type aliases\n    'string': tokenType(String$2),\n    'ident': tokenType(Ident),\n\n    // percentage\n    'percentage': calc(percentage),\n\n    // numeric\n    'zero': zero(),\n    'number': calc(number),\n    'integer': calc(integer),\n\n    // complex types\n    'custom-ident': customIdent,\n    'dashed-ident': dashedIdent,\n    'custom-property-name': customPropertyName,\n    'hex-color': hexColor,\n    'id-selector': idSelector, // element( <id-selector> )\n    'an-plus-b': anPlusB,\n    'urange': urange,\n    'declaration-value': declarationValue,\n    'any-value': anyValue\n};\n\n// dimensions types depend on units set\nfunction createDemensionTypes(units) {\n    const {\n        angle,\n        decibel,\n        frequency,\n        flex,\n        length,\n        resolution,\n        semitones,\n        time\n    } = units || {};\n\n    return {\n        'dimension': calc(dimension(null)),\n        'angle': calc(dimension(angle)),\n        'decibel': calc(dimension(decibel)),\n        'frequency': calc(dimension(frequency)),\n        'flex': calc(dimension(flex)),\n        'length': calc(zero(dimension(length))),\n        'resolution': calc(dimension(resolution)),\n        'semitones': calc(dimension(semitones)),\n        'time': calc(dimension(time))\n    };\n}\n\nfunction createGenericTypes(units) {\n    return {\n        ...tokenTypes,\n        ...productionTypes,\n        ...createDemensionTypes(units)\n    };\n}\n\nconst length = [\n    // absolute length units https://www.w3.org/TR/css-values-3/#lengths\n    'cm', 'mm', 'q', 'in', 'pt', 'pc', 'px',\n    // font-relative length units https://drafts.csswg.org/css-values-4/#font-relative-lengths\n    'em', 'rem',\n    'ex', 'rex',\n    'cap', 'rcap',\n    'ch', 'rch',\n    'ic', 'ric',\n    'lh', 'rlh',\n    // viewport-percentage lengths https://drafts.csswg.org/css-values-4/#viewport-relative-lengths\n    'vw', 'svw', 'lvw', 'dvw',\n    'vh', 'svh', 'lvh', 'dvh',\n    'vi', 'svi', 'lvi', 'dvi',\n    'vb', 'svb', 'lvb', 'dvb',\n    'vmin', 'svmin', 'lvmin', 'dvmin',\n    'vmax', 'svmax', 'lvmax', 'dvmax',\n    // container relative lengths https://drafts.csswg.org/css-contain-3/#container-lengths\n    'cqw', 'cqh', 'cqi', 'cqb', 'cqmin', 'cqmax'\n];\nconst angle = ['deg', 'grad', 'rad', 'turn'];    // https://www.w3.org/TR/css-values-3/#angles\nconst time = ['s', 'ms'];                        // https://www.w3.org/TR/css-values-3/#time\nconst frequency = ['hz', 'khz'];                 // https://www.w3.org/TR/css-values-3/#frequency\nconst resolution = ['dpi', 'dpcm', 'dppx', 'x']; // https://www.w3.org/TR/css-values-3/#resolution\nconst flex = ['fr'];                             // https://drafts.csswg.org/css-grid/#fr-unit\nconst decibel = ['db'];                          // https://www.w3.org/TR/css3-speech/#mixing-props-voice-volume\nconst semitones = ['st'];                        // https://www.w3.org/TR/css3-speech/#voice-props-voice-pitch\n\nvar units = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    length: length,\n    angle: angle,\n    time: time,\n    frequency: frequency,\n    resolution: resolution,\n    flex: flex,\n    decibel: decibel,\n    semitones: semitones\n});\n\nfunction SyntaxError$1(message, input, offset) {\n    return Object.assign(createCustomError('SyntaxError', message), {\n        input,\n        offset,\n        rawMessage: message,\n        message: message + '\\n' +\n            '  ' + input + '\\n' +\n            '--' + new Array((offset || input.length) + 1).join('-') + '^'\n    });\n}\n\nconst TAB$1 = 9;\nconst N$2 = 10;\nconst F$1 = 12;\nconst R$1 = 13;\nconst SPACE$3 = 32;\nconst NAME_CHAR = new Uint8Array(128).map((_, idx) =>\n    /[a-zA-Z0-9\\-]/.test(String.fromCharCode(idx)) ? 1 : 0\n);\n\nclass Scanner {\n    constructor(str) {\n        this.str = str;\n        this.pos = 0;\n    }\n\n    charCodeAt(pos) {\n        return pos < this.str.length ? this.str.charCodeAt(pos) : 0;\n    }\n    charCode() {\n        return this.charCodeAt(this.pos);\n    }\n    isNameCharCode(code = this.charCode()) {\n        return code < 128 && NAME_CHAR[code] === 1;\n    }\n    nextCharCode() {\n        return this.charCodeAt(this.pos + 1);\n    }\n    nextNonWsCode(pos) {\n        return this.charCodeAt(this.findWsEnd(pos));\n    }\n    skipWs() {\n        this.pos = this.findWsEnd(this.pos);\n    }\n    findWsEnd(pos) {\n        for (; pos < this.str.length; pos++) {\n            const code = this.str.charCodeAt(pos);\n            if (code !== R$1 && code !== N$2 && code !== F$1 && code !== SPACE$3 && code !== TAB$1) {\n                break;\n            }\n        }\n\n        return pos;\n    }\n    substringToPos(end) {\n        return this.str.substring(this.pos, this.pos = end);\n    }\n    eat(code) {\n        if (this.charCode() !== code) {\n            this.error('Expect `' + String.fromCharCode(code) + '`');\n        }\n\n        this.pos++;\n    }\n    peek() {\n        return this.pos < this.str.length ? this.str.charAt(this.pos++) : '';\n    }\n    error(message) {\n        throw new SyntaxError$1(message, this.str, this.pos);\n    }\n\n    scanSpaces() {\n        return this.substringToPos(this.findWsEnd(this.pos));\n    }\n    scanWord() {\n        let end = this.pos;\n\n        for (; end < this.str.length; end++) {\n            const code = this.str.charCodeAt(end);\n            if (code >= 128 || NAME_CHAR[code] === 0) {\n                break;\n            }\n        }\n\n        if (this.pos === end) {\n            this.error('Expect a keyword');\n        }\n\n        return this.substringToPos(end);\n    }\n    scanNumber() {\n        let end = this.pos;\n\n        for (; end < this.str.length; end++) {\n            const code = this.str.charCodeAt(end);\n\n            if (code < 48 || code > 57) {\n                break;\n            }\n        }\n\n        if (this.pos === end) {\n            this.error('Expect a number');\n        }\n\n        return this.substringToPos(end);\n    }\n    scanString() {\n        const end = this.str.indexOf('\\'', this.pos + 1);\n\n        if (end === -1) {\n            this.pos = this.str.length;\n            this.error('Expect an apostrophe');\n        }\n\n        return this.substringToPos(end + 1);\n    }\n}\n\nconst TAB = 9;\nconst N$1 = 10;\nconst F = 12;\nconst R = 13;\nconst SPACE$2 = 32;\nconst EXCLAMATIONMARK$2 = 33;    // !\nconst NUMBERSIGN$3 = 35;         // #\nconst AMPERSAND$5 = 38;          // &\nconst APOSTROPHE$2 = 39;         // '\nconst LEFTPARENTHESIS$2 = 40;    // (\nconst RIGHTPARENTHESIS$2 = 41;   // )\nconst ASTERISK$6 = 42;           // *\nconst PLUSSIGN$6 = 43;           // +\nconst COMMA = 44;              // ,\nconst HYPERMINUS = 45;         // -\nconst LESSTHANSIGN$1 = 60;       // <\nconst GREATERTHANSIGN$3 = 62;    // >\nconst QUESTIONMARK$1 = 63;       // ?\nconst COMMERCIALAT = 64;       // @\nconst LEFTSQUAREBRACKET = 91;  // [\nconst RIGHTSQUAREBRACKET = 93; // ]\nconst LEFTCURLYBRACKET = 123;  // {\nconst VERTICALLINE$3 = 124;      // |\nconst RIGHTCURLYBRACKET = 125; // }\nconst INFINITY = 8734;         // ∞\nconst COMBINATOR_PRECEDENCE = {\n    ' ': 1,\n    '&&': 2,\n    '||': 3,\n    '|': 4\n};\n\nfunction readMultiplierRange(scanner) {\n    let min = null;\n    let max = null;\n\n    scanner.eat(LEFTCURLYBRACKET);\n    scanner.skipWs();\n\n    min = scanner.scanNumber(scanner);\n    scanner.skipWs();\n\n    if (scanner.charCode() === COMMA) {\n        scanner.pos++;\n        scanner.skipWs();\n\n        if (scanner.charCode() !== RIGHTCURLYBRACKET) {\n            max = scanner.scanNumber(scanner);\n            scanner.skipWs();\n        }\n    } else {\n        max = min;\n    }\n\n    scanner.eat(RIGHTCURLYBRACKET);\n\n    return {\n        min: Number(min),\n        max: max ? Number(max) : 0\n    };\n}\n\nfunction readMultiplier(scanner) {\n    let range = null;\n    let comma = false;\n\n    switch (scanner.charCode()) {\n        case ASTERISK$6:\n            scanner.pos++;\n\n            range = {\n                min: 0,\n                max: 0\n            };\n\n            break;\n\n        case PLUSSIGN$6:\n            scanner.pos++;\n\n            range = {\n                min: 1,\n                max: 0\n            };\n\n            break;\n\n        case QUESTIONMARK$1:\n            scanner.pos++;\n\n            range = {\n                min: 0,\n                max: 1\n            };\n\n            break;\n\n        case NUMBERSIGN$3:\n            scanner.pos++;\n\n            comma = true;\n\n            if (scanner.charCode() === LEFTCURLYBRACKET) {\n                range = readMultiplierRange(scanner);\n            } else if (scanner.charCode() === QUESTIONMARK$1) {\n                // https://www.w3.org/TR/css-values-4/#component-multipliers\n                // > the # and ? multipliers may be stacked as #?\n                // In this case just treat \"#?\" as a single multiplier\n                // { min: 0, max: 0, comma: true }\n                scanner.pos++;\n                range = {\n                    min: 0,\n                    max: 0\n                };\n            } else {\n                range = {\n                    min: 1,\n                    max: 0\n                };\n            }\n\n            break;\n\n        case LEFTCURLYBRACKET:\n            range = readMultiplierRange(scanner);\n            break;\n\n        default:\n            return null;\n    }\n\n    return {\n        type: 'Multiplier',\n        comma,\n        min: range.min,\n        max: range.max,\n        term: null\n    };\n}\n\nfunction maybeMultiplied(scanner, node) {\n    const multiplier = readMultiplier(scanner);\n\n    if (multiplier !== null) {\n        multiplier.term = node;\n\n        // https://www.w3.org/TR/css-values-4/#component-multipliers\n        // > The + and # multipliers may be stacked as +#;\n        // Represent \"+#\" as nested multipliers:\n        // { ...<multiplier #>,\n        //   term: {\n        //     ...<multipler +>,\n        //     term: node\n        //   }\n        // }\n        if (scanner.charCode() === NUMBERSIGN$3 &&\n            scanner.charCodeAt(scanner.pos - 1) === PLUSSIGN$6) {\n            return maybeMultiplied(scanner, multiplier);\n        }\n\n        return multiplier;\n    }\n\n    return node;\n}\n\nfunction maybeToken(scanner) {\n    const ch = scanner.peek();\n\n    if (ch === '') {\n        return null;\n    }\n\n    return maybeMultiplied(scanner, {\n        type: 'Token',\n        value: ch\n    });\n}\n\nfunction readProperty$1(scanner) {\n    let name;\n\n    scanner.eat(LESSTHANSIGN$1);\n    scanner.eat(APOSTROPHE$2);\n\n    name = scanner.scanWord();\n\n    scanner.eat(APOSTROPHE$2);\n    scanner.eat(GREATERTHANSIGN$3);\n\n    return maybeMultiplied(scanner, {\n        type: 'Property',\n        name\n    });\n}\n\n// https://drafts.csswg.org/css-values-3/#numeric-ranges\n// 4.1. Range Restrictions and Range Definition Notation\n//\n// Range restrictions can be annotated in the numeric type notation using CSS bracketed\n// range notation—[min,max]—within the angle brackets, after the identifying keyword,\n// indicating a closed range between (and including) min and max.\n// For example, <integer [0, 10]> indicates an integer between 0 and 10, inclusive.\nfunction readTypeRange(scanner) {\n    // use null for Infinity to make AST format JSON serializable/deserializable\n    let min = null; // -Infinity\n    let max = null; // Infinity\n    let sign = 1;\n\n    scanner.eat(LEFTSQUAREBRACKET);\n\n    if (scanner.charCode() === HYPERMINUS) {\n        scanner.peek();\n        sign = -1;\n    }\n\n    if (sign == -1 && scanner.charCode() === INFINITY) {\n        scanner.peek();\n    } else {\n        min = sign * Number(scanner.scanNumber(scanner));\n\n        if (scanner.isNameCharCode()) {\n            min += scanner.scanWord();\n        }\n    }\n\n    scanner.skipWs();\n    scanner.eat(COMMA);\n    scanner.skipWs();\n\n    if (scanner.charCode() === INFINITY) {\n        scanner.peek();\n    } else {\n        sign = 1;\n\n        if (scanner.charCode() === HYPERMINUS) {\n            scanner.peek();\n            sign = -1;\n        }\n\n        max = sign * Number(scanner.scanNumber(scanner));\n\n        if (scanner.isNameCharCode()) {\n            max += scanner.scanWord();\n        }\n    }\n\n    scanner.eat(RIGHTSQUAREBRACKET);\n\n    return {\n        type: 'Range',\n        min,\n        max\n    };\n}\n\nfunction readType(scanner) {\n    let name;\n    let opts = null;\n\n    scanner.eat(LESSTHANSIGN$1);\n    name = scanner.scanWord();\n\n    // https://drafts.csswg.org/css-values-5/#boolean\n    if (name === 'boolean-expr') {\n        scanner.eat(LEFTSQUAREBRACKET);\n\n        const implicitGroup = readImplicitGroup(scanner, RIGHTSQUAREBRACKET);\n\n        scanner.eat(RIGHTSQUAREBRACKET);\n        scanner.eat(GREATERTHANSIGN$3);\n\n        return maybeMultiplied(scanner, {\n            type: 'Boolean',\n            term: implicitGroup.terms.length === 1\n                ? implicitGroup.terms[0]\n                : implicitGroup\n        });\n    }\n\n    if (scanner.charCode() === LEFTPARENTHESIS$2 &&\n        scanner.nextCharCode() === RIGHTPARENTHESIS$2) {\n        scanner.pos += 2;\n        name += '()';\n    }\n\n    if (scanner.charCodeAt(scanner.findWsEnd(scanner.pos)) === LEFTSQUAREBRACKET) {\n        scanner.skipWs();\n        opts = readTypeRange(scanner);\n    }\n\n    scanner.eat(GREATERTHANSIGN$3);\n\n    return maybeMultiplied(scanner, {\n        type: 'Type',\n        name,\n        opts\n    });\n}\n\nfunction readKeywordOrFunction(scanner) {\n    const name = scanner.scanWord();\n\n    if (scanner.charCode() === LEFTPARENTHESIS$2) {\n        scanner.pos++;\n\n        return {\n            type: 'Function',\n            name\n        };\n    }\n\n    return maybeMultiplied(scanner, {\n        type: 'Keyword',\n        name\n    });\n}\n\nfunction regroupTerms(terms, combinators) {\n    function createGroup(terms, combinator) {\n        return {\n            type: 'Group',\n            terms,\n            combinator,\n            disallowEmpty: false,\n            explicit: false\n        };\n    }\n\n    let combinator;\n\n    combinators = Object.keys(combinators)\n        .sort((a, b) => COMBINATOR_PRECEDENCE[a] - COMBINATOR_PRECEDENCE[b]);\n\n    while (combinators.length > 0) {\n        combinator = combinators.shift();\n\n        let i = 0;\n        let subgroupStart = 0;\n\n        for (; i < terms.length; i++) {\n            const term = terms[i];\n\n            if (term.type === 'Combinator') {\n                if (term.value === combinator) {\n                    if (subgroupStart === -1) {\n                        subgroupStart = i - 1;\n                    }\n                    terms.splice(i, 1);\n                    i--;\n                } else {\n                    if (subgroupStart !== -1 && i - subgroupStart > 1) {\n                        terms.splice(\n                            subgroupStart,\n                            i - subgroupStart,\n                            createGroup(terms.slice(subgroupStart, i), combinator)\n                        );\n                        i = subgroupStart + 1;\n                    }\n                    subgroupStart = -1;\n                }\n            }\n        }\n\n        if (subgroupStart !== -1 && combinators.length) {\n            terms.splice(\n                subgroupStart,\n                i - subgroupStart,\n                createGroup(terms.slice(subgroupStart, i), combinator)\n            );\n        }\n    }\n\n    return combinator;\n}\n\nfunction readImplicitGroup(scanner, stopCharCode) {\n    const combinators = Object.create(null);\n    const terms = [];\n    let token;\n    let prevToken = null;\n    let prevTokenPos = scanner.pos;\n\n    while (scanner.charCode() !== stopCharCode && (token = peek(scanner, stopCharCode))) {\n        if (token.type !== 'Spaces') {\n            if (token.type === 'Combinator') {\n                // check for combinator in group beginning and double combinator sequence\n                if (prevToken === null || prevToken.type === 'Combinator') {\n                    scanner.pos = prevTokenPos;\n                    scanner.error('Unexpected combinator');\n                }\n\n                combinators[token.value] = true;\n            } else if (prevToken !== null && prevToken.type !== 'Combinator') {\n                combinators[' '] = true;  // a b\n                terms.push({\n                    type: 'Combinator',\n                    value: ' '\n                });\n            }\n\n            terms.push(token);\n            prevToken = token;\n            prevTokenPos = scanner.pos;\n        }\n    }\n\n    // check for combinator in group ending\n    if (prevToken !== null && prevToken.type === 'Combinator') {\n        scanner.pos -= prevTokenPos;\n        scanner.error('Unexpected combinator');\n    }\n\n    return {\n        type: 'Group',\n        terms,\n        combinator: regroupTerms(terms, combinators) || ' ',\n        disallowEmpty: false,\n        explicit: false\n    };\n}\n\nfunction readGroup(scanner, stopCharCode) {\n    let result;\n\n    scanner.eat(LEFTSQUAREBRACKET);\n    result = readImplicitGroup(scanner, stopCharCode);\n    scanner.eat(RIGHTSQUAREBRACKET);\n\n    result.explicit = true;\n\n    if (scanner.charCode() === EXCLAMATIONMARK$2) {\n        scanner.pos++;\n        result.disallowEmpty = true;\n    }\n\n    return result;\n}\n\nfunction peek(scanner, stopCharCode) {\n    let code = scanner.charCode();\n\n    switch (code) {\n        case RIGHTSQUAREBRACKET:\n            // don't eat, stop scan a group\n            break;\n\n        case LEFTSQUAREBRACKET:\n            return maybeMultiplied(scanner, readGroup(scanner, stopCharCode));\n\n        case LESSTHANSIGN$1:\n            return scanner.nextCharCode() === APOSTROPHE$2\n                ? readProperty$1(scanner)\n                : readType(scanner);\n\n        case VERTICALLINE$3:\n            return {\n                type: 'Combinator',\n                value: scanner.substringToPos(\n                    scanner.pos + (scanner.nextCharCode() === VERTICALLINE$3 ? 2 : 1)\n                )\n            };\n\n        case AMPERSAND$5:\n            scanner.pos++;\n            scanner.eat(AMPERSAND$5);\n\n            return {\n                type: 'Combinator',\n                value: '&&'\n            };\n\n        case COMMA:\n            scanner.pos++;\n            return {\n                type: 'Comma'\n            };\n\n        case APOSTROPHE$2:\n            return maybeMultiplied(scanner, {\n                type: 'String',\n                value: scanner.scanString()\n            });\n\n        case SPACE$2:\n        case TAB:\n        case N$1:\n        case R:\n        case F:\n            return {\n                type: 'Spaces',\n                value: scanner.scanSpaces()\n            };\n\n        case COMMERCIALAT:\n            code = scanner.nextCharCode();\n\n            if (scanner.isNameCharCode(code)) {\n                scanner.pos++;\n                return {\n                    type: 'AtKeyword',\n                    name: scanner.scanWord()\n                };\n            }\n\n            return maybeToken(scanner);\n\n        case ASTERISK$6:\n        case PLUSSIGN$6:\n        case QUESTIONMARK$1:\n        case NUMBERSIGN$3:\n        case EXCLAMATIONMARK$2:\n            // prohibited tokens (used as a multiplier start)\n            break;\n\n        case LEFTCURLYBRACKET:\n            // LEFTCURLYBRACKET is allowed since mdn/data uses it w/o quoting\n            // check next char isn't a number, because it's likely a disjoined multiplier\n            code = scanner.nextCharCode();\n\n            if (code < 48 || code > 57) {\n                return maybeToken(scanner);\n            }\n\n            break;\n\n        default:\n            if (scanner.isNameCharCode(code)) {\n                return readKeywordOrFunction(scanner);\n            }\n\n            return maybeToken(scanner);\n    }\n}\n\nfunction parse$O(source) {\n    const scanner = new Scanner(source);\n    const result = readImplicitGroup(scanner);\n\n    if (scanner.pos !== source.length) {\n        scanner.error('Unexpected input');\n    }\n\n    // reduce redundant groups with single group term\n    if (result.terms.length === 1 && result.terms[0].type === 'Group') {\n        return result.terms[0];\n    }\n\n    return result;\n}\n\nconst noop = function() {};\n\nfunction ensureFunction(value) {\n    return typeof value === 'function' ? value : noop;\n}\n\nfunction walk$1(node, options, context) {\n    function walk(node) {\n        enter.call(context, node);\n\n        switch (node.type) {\n            case 'Group':\n                node.terms.forEach(walk);\n                break;\n\n            case 'Multiplier':\n            case 'Boolean':\n                walk(node.term);\n                break;\n\n            case 'Type':\n            case 'Property':\n            case 'Keyword':\n            case 'AtKeyword':\n            case 'Function':\n            case 'String':\n            case 'Token':\n            case 'Comma':\n                break;\n\n            default:\n                throw new Error('Unknown type: ' + node.type);\n        }\n\n        leave.call(context, node);\n    }\n\n    let enter = noop;\n    let leave = noop;\n\n    if (typeof options === 'function') {\n        enter = options;\n    } else if (options) {\n        enter = ensureFunction(options.enter);\n        leave = ensureFunction(options.leave);\n    }\n\n    if (enter === noop && leave === noop) {\n        throw new Error('Neither `enter` nor `leave` walker handler is set or both aren\\'t a function');\n    }\n\n    walk(node);\n}\n\nvar index = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    SyntaxError: SyntaxError$1,\n    generate: generate$O,\n    parse: parse$O,\n    walk: walk$1\n});\n\nconst astToTokens = {\n    decorator(handlers) {\n        const tokens = [];\n        let curNode = null;\n\n        return {\n            ...handlers,\n            node(node) {\n                const tmp = curNode;\n                curNode = node;\n                handlers.node.call(this, node);\n                curNode = tmp;\n            },\n            emit(value, type, auto) {\n                tokens.push({\n                    type,\n                    value,\n                    node: auto ? null : curNode\n                });\n            },\n            result() {\n                return tokens;\n            }\n        };\n    }\n};\n\nfunction stringToTokens(str) {\n    const tokens = [];\n\n    tokenize$1(str, (type, start, end) =>\n        tokens.push({\n            type,\n            value: str.slice(start, end),\n            node: null\n        })\n    );\n\n    return tokens;\n}\n\nfunction prepareTokens(value, syntax) {\n    if (typeof value === 'string') {\n        return stringToTokens(value);\n    }\n\n    return syntax.generate(value, astToTokens);\n}\n\nconst MATCH = { type: 'Match' };\nconst MISMATCH = { type: 'Mismatch' };\nconst DISALLOW_EMPTY = { type: 'DisallowEmpty' };\n\nconst LEFTPARENTHESIS$1 = 40;  // (\nconst RIGHTPARENTHESIS$1 = 41; // )\n\nfunction createCondition(match, thenBranch, elseBranch) {\n    // reduce node count\n    if (thenBranch === MATCH && elseBranch === MISMATCH) {\n        return match;\n    }\n\n    if (match === MATCH && thenBranch === MATCH && elseBranch === MATCH) {\n        return match;\n    }\n\n    if (match.type === 'If' && match.else === MISMATCH && thenBranch === MATCH) {\n        thenBranch = match.then;\n        match = match.match;\n    }\n\n    return {\n        type: 'If',\n        match,\n        then: thenBranch,\n        else: elseBranch\n    };\n}\n\nfunction isFunctionType(name) {\n    return (\n        name.length > 2 &&\n        name.charCodeAt(name.length - 2) === LEFTPARENTHESIS$1 &&\n        name.charCodeAt(name.length - 1) === RIGHTPARENTHESIS$1\n    );\n}\n\nfunction isEnumCapatible(term) {\n    return (\n        term.type === 'Keyword' ||\n        term.type === 'AtKeyword' ||\n        term.type === 'Function' ||\n        term.type === 'Type' && isFunctionType(term.name)\n    );\n}\n\nfunction groupNode(terms, combinator = ' ', explicit = false) {\n    return {\n        type: 'Group',\n        terms,\n        combinator,\n        disallowEmpty: false,\n        explicit\n    };\n}\n\nfunction replaceTypeInGraph(node, replacements, visited = new Set()) {\n    if (!visited.has(node)) {\n        visited.add(node);\n\n        switch (node.type) {\n            case 'If':\n                node.match = replaceTypeInGraph(node.match, replacements, visited);\n                node.then = replaceTypeInGraph(node.then, replacements, visited);\n                node.else = replaceTypeInGraph(node.else, replacements, visited);\n                break;\n\n            case 'Type':\n                return replacements[node.name] || node;\n        }\n    }\n\n    return node;\n}\n\nfunction buildGroupMatchGraph(combinator, terms, atLeastOneTermMatched) {\n    switch (combinator) {\n        case ' ': {\n            // Juxtaposing components means that all of them must occur, in the given order.\n            //\n            // a b c\n            // =\n            // match a\n            //   then match b\n            //     then match c\n            //       then MATCH\n            //       else MISMATCH\n            //     else MISMATCH\n            //   else MISMATCH\n            let result = MATCH;\n\n            for (let i = terms.length - 1; i >= 0; i--) {\n                const term = terms[i];\n\n                result = createCondition(\n                    term,\n                    result,\n                    MISMATCH\n                );\n            }\n            return result;\n        }\n\n        case '|': {\n            // A bar (|) separates two or more alternatives: exactly one of them must occur.\n            //\n            // a | b | c\n            // =\n            // match a\n            //   then MATCH\n            //   else match b\n            //     then MATCH\n            //     else match c\n            //       then MATCH\n            //       else MISMATCH\n\n            let result = MISMATCH;\n            let map = null;\n\n            for (let i = terms.length - 1; i >= 0; i--) {\n                let term = terms[i];\n\n                // reduce sequence of keywords into a Enum\n                if (isEnumCapatible(term)) {\n                    if (map === null && i > 0 && isEnumCapatible(terms[i - 1])) {\n                        map = Object.create(null);\n                        result = createCondition(\n                            {\n                                type: 'Enum',\n                                map\n                            },\n                            MATCH,\n                            result\n                        );\n                    }\n\n                    if (map !== null) {\n                        const key = (isFunctionType(term.name) ? term.name.slice(0, -1) : term.name).toLowerCase();\n                        if (key in map === false) {\n                            map[key] = term;\n                            continue;\n                        }\n                    }\n                }\n\n                map = null;\n\n                // create a new conditonal node\n                result = createCondition(\n                    term,\n                    MATCH,\n                    result\n                );\n            }\n            return result;\n        }\n\n        case '&&': {\n            // A double ampersand (&&) separates two or more components,\n            // all of which must occur, in any order.\n\n            // Use MatchOnce for groups with a large number of terms,\n            // since &&-groups produces at least N!-node trees\n            if (terms.length > 5) {\n                return {\n                    type: 'MatchOnce',\n                    terms,\n                    all: true\n                };\n            }\n\n            // Use a combination tree for groups with small number of terms\n            //\n            // a && b && c\n            // =\n            // match a\n            //   then [b && c]\n            //   else match b\n            //     then [a && c]\n            //     else match c\n            //       then [a && b]\n            //       else MISMATCH\n            //\n            // a && b\n            // =\n            // match a\n            //   then match b\n            //     then MATCH\n            //     else MISMATCH\n            //   else match b\n            //     then match a\n            //       then MATCH\n            //       else MISMATCH\n            //     else MISMATCH\n            let result = MISMATCH;\n\n            for (let i = terms.length - 1; i >= 0; i--) {\n                const term = terms[i];\n                let thenClause;\n\n                if (terms.length > 1) {\n                    thenClause = buildGroupMatchGraph(\n                        combinator,\n                        terms.filter(function(newGroupTerm) {\n                            return newGroupTerm !== term;\n                        }),\n                        false\n                    );\n                } else {\n                    thenClause = MATCH;\n                }\n\n                result = createCondition(\n                    term,\n                    thenClause,\n                    result\n                );\n            }\n            return result;\n        }\n\n        case '||': {\n            // A double bar (||) separates two or more options:\n            // one or more of them must occur, in any order.\n\n            // Use MatchOnce for groups with a large number of terms,\n            // since ||-groups produces at least N!-node trees\n            if (terms.length > 5) {\n                return {\n                    type: 'MatchOnce',\n                    terms,\n                    all: false\n                };\n            }\n\n            // Use a combination tree for groups with small number of terms\n            //\n            // a || b || c\n            // =\n            // match a\n            //   then [b || c]\n            //   else match b\n            //     then [a || c]\n            //     else match c\n            //       then [a || b]\n            //       else MISMATCH\n            //\n            // a || b\n            // =\n            // match a\n            //   then match b\n            //     then MATCH\n            //     else MATCH\n            //   else match b\n            //     then match a\n            //       then MATCH\n            //       else MATCH\n            //     else MISMATCH\n            let result = atLeastOneTermMatched ? MATCH : MISMATCH;\n\n            for (let i = terms.length - 1; i >= 0; i--) {\n                const term = terms[i];\n                let thenClause;\n\n                if (terms.length > 1) {\n                    thenClause = buildGroupMatchGraph(\n                        combinator,\n                        terms.filter(function(newGroupTerm) {\n                            return newGroupTerm !== term;\n                        }),\n                        true\n                    );\n                } else {\n                    thenClause = MATCH;\n                }\n\n                result = createCondition(\n                    term,\n                    thenClause,\n                    result\n                );\n            }\n            return result;\n        }\n    }\n}\n\nfunction buildMultiplierMatchGraph(node) {\n    let result = MATCH;\n    let matchTerm = buildMatchGraphInternal(node.term);\n\n    if (node.max === 0) {\n        // disable repeating of empty match to prevent infinite loop\n        matchTerm = createCondition(\n            matchTerm,\n            DISALLOW_EMPTY,\n            MISMATCH\n        );\n\n        // an occurrence count is not limited, make a cycle;\n        // to collect more terms on each following matching mismatch\n        result = createCondition(\n            matchTerm,\n            null, // will be a loop\n            MISMATCH\n        );\n\n        result.then = createCondition(\n            MATCH,\n            MATCH,\n            result // make a loop\n        );\n\n        if (node.comma) {\n            result.then.else = createCondition(\n                { type: 'Comma', syntax: node },\n                result,\n                MISMATCH\n            );\n        }\n    } else {\n        // create a match node chain for [min .. max] interval with optional matches\n        for (let i = node.min || 1; i <= node.max; i++) {\n            if (node.comma && result !== MATCH) {\n                result = createCondition(\n                    { type: 'Comma', syntax: node },\n                    result,\n                    MISMATCH\n                );\n            }\n\n            result = createCondition(\n                matchTerm,\n                createCondition(\n                    MATCH,\n                    MATCH,\n                    result\n                ),\n                MISMATCH\n            );\n        }\n    }\n\n    if (node.min === 0) {\n        // allow zero match\n        result = createCondition(\n            MATCH,\n            MATCH,\n            result\n        );\n    } else {\n        // create a match node chain to collect [0 ... min - 1] required matches\n        for (let i = 0; i < node.min - 1; i++) {\n            if (node.comma && result !== MATCH) {\n                result = createCondition(\n                    { type: 'Comma', syntax: node },\n                    result,\n                    MISMATCH\n                );\n            }\n\n            result = createCondition(\n                matchTerm,\n                result,\n                MISMATCH\n            );\n        }\n    }\n\n    return result;\n}\n\nfunction buildMatchGraphInternal(node) {\n    if (typeof node === 'function') {\n        return {\n            type: 'Generic',\n            fn: node\n        };\n    }\n\n    switch (node.type) {\n        case 'Group': {\n            let result = buildGroupMatchGraph(\n                node.combinator,\n                node.terms.map(buildMatchGraphInternal),\n                false\n            );\n\n            if (node.disallowEmpty) {\n                result = createCondition(\n                    result,\n                    DISALLOW_EMPTY,\n                    MISMATCH\n                );\n            }\n\n            return result;\n        }\n\n        case 'Multiplier':\n            return buildMultiplierMatchGraph(node);\n\n        // https://drafts.csswg.org/css-values-5/#boolean\n        case 'Boolean': {\n            const term = buildMatchGraphInternal(node.term);\n            // <boolean-expr[ <test> ]> = not <boolean-expr-group> | <boolean-expr-group> [ [ and <boolean-expr-group> ]* | [ or <boolean-expr-group> ]* ]\n            const matchNode = buildMatchGraphInternal(groupNode([\n                groupNode([\n                    { type: 'Keyword', name: 'not' },\n                    { type: 'Type', name: '!boolean-group' }\n                ]),\n                groupNode([\n                    { type: 'Type', name: '!boolean-group' },\n                    groupNode([\n                        { type: 'Multiplier', comma: false, min: 0, max: 0, term: groupNode([\n                            { type: 'Keyword', name: 'and' },\n                            { type: 'Type', name: '!boolean-group' }\n                        ]) },\n                        { type: 'Multiplier', comma: false, min: 0, max: 0, term: groupNode([\n                            { type: 'Keyword', name: 'or' },\n                            { type: 'Type', name: '!boolean-group' }\n                        ]) }\n                    ], '|')\n                ])\n            ], '|'));\n            // <boolean-expr-group> = <test> | ( <boolean-expr[ <test> ]> ) | <general-enclosed>\n            const booleanGroup = buildMatchGraphInternal(\n                groupNode([\n                    { type: 'Type', name: '!term' },\n                    groupNode([\n                        { type: 'Token', value: '(' },\n                        { type: 'Type', name: '!self' },\n                        { type: 'Token', value: ')' }\n                    ]),\n                    { type: 'Type', name: 'general-enclosed' }\n                ], '|')\n            );\n\n            replaceTypeInGraph(booleanGroup, { '!term': term, '!self': matchNode });\n            replaceTypeInGraph(matchNode, { '!boolean-group': booleanGroup });\n\n            return matchNode;\n        }\n\n        case 'Type':\n        case 'Property':\n            return {\n                type: node.type,\n                name: node.name,\n                syntax: node\n            };\n\n        case 'Keyword':\n            return {\n                type: node.type,\n                name: node.name.toLowerCase(),\n                syntax: node\n            };\n\n        case 'AtKeyword':\n            return {\n                type: node.type,\n                name: '@' + node.name.toLowerCase(),\n                syntax: node\n            };\n\n        case 'Function':\n            return {\n                type: node.type,\n                name: node.name.toLowerCase() + '(',\n                syntax: node\n            };\n\n        case 'String':\n            // convert a one char length String to a Token\n            if (node.value.length === 3) {\n                return {\n                    type: 'Token',\n                    value: node.value.charAt(1),\n                    syntax: node\n                };\n            }\n\n            // otherwise use it as is\n            return {\n                type: node.type,\n                value: node.value.substr(1, node.value.length - 2).replace(/\\\\'/g, '\\''),\n                syntax: node\n            };\n\n        case 'Token':\n            return {\n                type: node.type,\n                value: node.value,\n                syntax: node\n            };\n\n        case 'Comma':\n            return {\n                type: node.type,\n                syntax: node\n            };\n\n        default:\n            throw new Error('Unknown node type:', node.type);\n    }\n}\n\nfunction buildMatchGraph(syntaxTree, ref) {\n    if (typeof syntaxTree === 'string') {\n        syntaxTree = parse$O(syntaxTree);\n    }\n\n    return {\n        type: 'MatchGraph',\n        match: buildMatchGraphInternal(syntaxTree),\n        syntax: ref || null,\n        source: syntaxTree\n    };\n}\n\nconst { hasOwnProperty: hasOwnProperty$2 } = Object.prototype;\nconst STUB = 0;\nconst TOKEN = 1;\nconst OPEN_SYNTAX = 2;\nconst CLOSE_SYNTAX = 3;\n\nconst EXIT_REASON_MATCH = 'Match';\nconst EXIT_REASON_MISMATCH = 'Mismatch';\nconst EXIT_REASON_ITERATION_LIMIT = 'Maximum iteration number exceeded (please fill an issue on https://github.com/csstree/csstree/issues)';\n\nconst ITERATION_LIMIT = 15000;\n\nfunction reverseList(list) {\n    let prev = null;\n    let next = null;\n    let item = list;\n\n    while (item !== null) {\n        next = item.prev;\n        item.prev = prev;\n        prev = item;\n        item = next;\n    }\n\n    return prev;\n}\n\nfunction areStringsEqualCaseInsensitive(testStr, referenceStr) {\n    if (testStr.length !== referenceStr.length) {\n        return false;\n    }\n\n    for (let i = 0; i < testStr.length; i++) {\n        const referenceCode = referenceStr.charCodeAt(i);\n        let testCode = testStr.charCodeAt(i);\n\n        // testCode.toLowerCase() for U+0041 LATIN CAPITAL LETTER A (A) .. U+005A LATIN CAPITAL LETTER Z (Z).\n        if (testCode >= 0x0041 && testCode <= 0x005A) {\n            testCode = testCode | 32;\n        }\n\n        if (testCode !== referenceCode) {\n            return false;\n        }\n    }\n\n    return true;\n}\n\nfunction isContextEdgeDelim(token) {\n    if (token.type !== Delim) {\n        return false;\n    }\n\n    // Fix matching for unicode-range: U+30??, U+FF00-FF9F\n    // Probably we need to check out previous match instead\n    return token.value !== '?';\n}\n\nfunction isCommaContextStart(token) {\n    if (token === null) {\n        return true;\n    }\n\n    return (\n        token.type === Comma ||\n        token.type === Function$1 ||\n        token.type === LeftParenthesis ||\n        token.type === LeftSquareBracket ||\n        token.type === LeftCurlyBracket ||\n        isContextEdgeDelim(token)\n    );\n}\n\nfunction isCommaContextEnd(token) {\n    if (token === null) {\n        return true;\n    }\n\n    return (\n        token.type === RightParenthesis ||\n        token.type === RightSquareBracket ||\n        token.type === RightCurlyBracket ||\n        (token.type === Delim && token.value === '/')\n    );\n}\n\nfunction internalMatch(tokens, state, syntaxes) {\n    function moveToNextToken() {\n        do {\n            tokenIndex++;\n            token = tokenIndex < tokens.length ? tokens[tokenIndex] : null;\n        } while (token !== null && (token.type === WhiteSpace$1 || token.type === Comment$1));\n    }\n\n    function getNextToken(offset) {\n        const nextIndex = tokenIndex + offset;\n\n        return nextIndex < tokens.length ? tokens[nextIndex] : null;\n    }\n\n    function stateSnapshotFromSyntax(nextState, prev) {\n        return {\n            nextState,\n            matchStack,\n            syntaxStack,\n            thenStack,\n            tokenIndex,\n            prev\n        };\n    }\n\n    function pushThenStack(nextState) {\n        thenStack = {\n            nextState,\n            matchStack,\n            syntaxStack,\n            prev: thenStack\n        };\n    }\n\n    function pushElseStack(nextState) {\n        elseStack = stateSnapshotFromSyntax(nextState, elseStack);\n    }\n\n    function addTokenToMatch() {\n        matchStack = {\n            type: TOKEN,\n            syntax: state.syntax,\n            token,\n            prev: matchStack\n        };\n\n        moveToNextToken();\n        syntaxStash = null;\n\n        if (tokenIndex > longestMatch) {\n            longestMatch = tokenIndex;\n        }\n    }\n\n    function openSyntax() {\n        syntaxStack = {\n            syntax: state.syntax,\n            opts: state.syntax.opts || (syntaxStack !== null && syntaxStack.opts) || null,\n            prev: syntaxStack\n        };\n\n        matchStack = {\n            type: OPEN_SYNTAX,\n            syntax: state.syntax,\n            token: matchStack.token,\n            prev: matchStack\n        };\n    }\n\n    function closeSyntax() {\n        if (matchStack.type === OPEN_SYNTAX) {\n            matchStack = matchStack.prev;\n        } else {\n            matchStack = {\n                type: CLOSE_SYNTAX,\n                syntax: syntaxStack.syntax,\n                token: matchStack.token,\n                prev: matchStack\n            };\n        }\n\n        syntaxStack = syntaxStack.prev;\n    }\n\n    let syntaxStack = null;\n    let thenStack = null;\n    let elseStack = null;\n\n    // null – stashing allowed, nothing stashed\n    // false – stashing disabled, nothing stashed\n    // anithing else – fail stashable syntaxes, some syntax stashed\n    let syntaxStash = null;\n\n    let iterationCount = 0; // count iterations and prevent infinite loop\n    let exitReason = null;\n\n    let token = null;\n    let tokenIndex = -1;\n    let longestMatch = 0;\n    let matchStack = {\n        type: STUB,\n        syntax: null,\n        token: null,\n        prev: null\n    };\n\n    moveToNextToken();\n\n    while (exitReason === null && ++iterationCount < ITERATION_LIMIT) {\n        // function mapList(list, fn) {\n        //     const result = [];\n        //     while (list) {\n        //         result.unshift(fn(list));\n        //         list = list.prev;\n        //     }\n        //     return result;\n        // }\n        // console.log('--\\n',\n        //     '#' + iterationCount,\n        //     require('util').inspect({\n        //         match: mapList(matchStack, x => x.type === TOKEN ? x.token && x.token.value : x.syntax ? ({ [OPEN_SYNTAX]: '<', [CLOSE_SYNTAX]: '</' }[x.type] || x.type) + '!' + x.syntax.name : null),\n        //         token: token && token.value,\n        //         tokenIndex,\n        //         syntax: syntax.type + (syntax.id ? ' #' + syntax.id : '')\n        //     }, { depth: null })\n        // );\n        switch (state.type) {\n            case 'Match':\n                if (thenStack === null) {\n                    // turn to MISMATCH when some tokens left unmatched\n                    if (token !== null) {\n                        // doesn't mismatch if just one token left and it's an IE hack\n                        if (tokenIndex !== tokens.length - 1 || (token.value !== '\\\\0' && token.value !== '\\\\9')) {\n                            state = MISMATCH;\n                            break;\n                        }\n                    }\n\n                    // break the main loop, return a result - MATCH\n                    exitReason = EXIT_REASON_MATCH;\n                    break;\n                }\n\n                // go to next syntax (`then` branch)\n                state = thenStack.nextState;\n\n                // check match is not empty\n                if (state === DISALLOW_EMPTY) {\n                    if (thenStack.matchStack === matchStack) {\n                        state = MISMATCH;\n                        break;\n                    } else {\n                        state = MATCH;\n                    }\n                }\n\n                // close syntax if needed\n                while (thenStack.syntaxStack !== syntaxStack) {\n                    closeSyntax();\n                }\n\n                // pop stack\n                thenStack = thenStack.prev;\n                break;\n\n            case 'Mismatch':\n                // when some syntax is stashed\n                if (syntaxStash !== null && syntaxStash !== false) {\n                    // there is no else branches or a branch reduce match stack\n                    if (elseStack === null || tokenIndex > elseStack.tokenIndex) {\n                        // restore state from the stash\n                        elseStack = syntaxStash;\n                        syntaxStash = false; // disable stashing\n                    }\n                } else if (elseStack === null) {\n                    // no else branches -> break the main loop\n                    // return a result - MISMATCH\n                    exitReason = EXIT_REASON_MISMATCH;\n                    break;\n                }\n\n                // go to next syntax (`else` branch)\n                state = elseStack.nextState;\n\n                // restore all the rest stack states\n                thenStack = elseStack.thenStack;\n                syntaxStack = elseStack.syntaxStack;\n                matchStack = elseStack.matchStack;\n                tokenIndex = elseStack.tokenIndex;\n                token = tokenIndex < tokens.length ? tokens[tokenIndex] : null;\n\n                // pop stack\n                elseStack = elseStack.prev;\n                break;\n\n            case 'MatchGraph':\n                state = state.match;\n                break;\n\n            case 'If':\n                // IMPORTANT: else stack push must go first,\n                // since it stores the state of thenStack before changes\n                if (state.else !== MISMATCH) {\n                    pushElseStack(state.else);\n                }\n\n                if (state.then !== MATCH) {\n                    pushThenStack(state.then);\n                }\n\n                state = state.match;\n                break;\n\n            case 'MatchOnce':\n                state = {\n                    type: 'MatchOnceBuffer',\n                    syntax: state,\n                    index: 0,\n                    mask: 0\n                };\n                break;\n\n            case 'MatchOnceBuffer': {\n                const terms = state.syntax.terms;\n\n                if (state.index === terms.length) {\n                    // no matches at all or it's required all terms to be matched\n                    if (state.mask === 0 || state.syntax.all) {\n                        state = MISMATCH;\n                        break;\n                    }\n\n                    // a partial match is ok\n                    state = MATCH;\n                    break;\n                }\n\n                // all terms are matched\n                if (state.mask === (1 << terms.length) - 1) {\n                    state = MATCH;\n                    break;\n                }\n\n                for (; state.index < terms.length; state.index++) {\n                    const matchFlag = 1 << state.index;\n\n                    if ((state.mask & matchFlag) === 0) {\n                        // IMPORTANT: else stack push must go first,\n                        // since it stores the state of thenStack before changes\n                        pushElseStack(state);\n                        pushThenStack({\n                            type: 'AddMatchOnce',\n                            syntax: state.syntax,\n                            mask: state.mask | matchFlag\n                        });\n\n                        // match\n                        state = terms[state.index++];\n                        break;\n                    }\n                }\n                break;\n            }\n\n            case 'AddMatchOnce':\n                state = {\n                    type: 'MatchOnceBuffer',\n                    syntax: state.syntax,\n                    index: 0,\n                    mask: state.mask\n                };\n                break;\n\n            case 'Enum':\n                if (token !== null) {\n                    let name = token.value.toLowerCase();\n\n                    // drop \\0 and \\9 hack from keyword name\n                    if (name.indexOf('\\\\') !== -1) {\n                        name = name.replace(/\\\\[09].*$/, '');\n                    }\n\n                    if (hasOwnProperty$2.call(state.map, name)) {\n                        state = state.map[name];\n                        break;\n                    }\n                }\n\n                state = MISMATCH;\n                break;\n\n            case 'Generic': {\n                const opts = syntaxStack !== null ? syntaxStack.opts : null;\n                const lastTokenIndex = tokenIndex + Math.floor(state.fn(token, getNextToken, opts));\n\n                if (!isNaN(lastTokenIndex) && lastTokenIndex > tokenIndex) {\n                    while (tokenIndex < lastTokenIndex) {\n                        addTokenToMatch();\n                    }\n\n                    state = MATCH;\n                } else {\n                    state = MISMATCH;\n                }\n\n                break;\n            }\n\n            case 'Type':\n            case 'Property': {\n                const syntaxDict = state.type === 'Type' ? 'types' : 'properties';\n                const dictSyntax = hasOwnProperty$2.call(syntaxes, syntaxDict) ? syntaxes[syntaxDict][state.name] : null;\n\n                if (!dictSyntax || !dictSyntax.match) {\n                    throw new Error(\n                        'Bad syntax reference: ' +\n                        (state.type === 'Type'\n                            ? '<' + state.name + '>'\n                            : '<\\'' + state.name + '\\'>')\n                    );\n                }\n\n                // stash a syntax for types with low priority\n                if (syntaxStash !== false && token !== null && state.type === 'Type') {\n                    const lowPriorityMatching =\n                        // https://drafts.csswg.org/css-values-4/#custom-idents\n                        // When parsing positionally-ambiguous keywords in a property value, a <custom-ident> production\n                        // can only claim the keyword if no other unfulfilled production can claim it.\n                        (state.name === 'custom-ident' && token.type === Ident) ||\n\n                        // https://drafts.csswg.org/css-values-4/#lengths\n                        // ... if a `0` could be parsed as either a <number> or a <length> in a property (such as line-height),\n                        // it must parse as a <number>\n                        (state.name === 'length' && token.value === '0');\n\n                    if (lowPriorityMatching) {\n                        if (syntaxStash === null) {\n                            syntaxStash = stateSnapshotFromSyntax(state, elseStack);\n                        }\n\n                        state = MISMATCH;\n                        break;\n                    }\n                }\n\n                openSyntax();\n                state = dictSyntax.matchRef || dictSyntax.match;\n                break;\n            }\n\n            case 'Keyword': {\n                const name = state.name;\n\n                if (token !== null) {\n                    let keywordName = token.value;\n\n                    // drop \\0 and \\9 hack from keyword name\n                    if (keywordName.indexOf('\\\\') !== -1) {\n                        keywordName = keywordName.replace(/\\\\[09].*$/, '');\n                    }\n\n                    if (areStringsEqualCaseInsensitive(keywordName, name)) {\n                        addTokenToMatch();\n                        state = MATCH;\n                        break;\n                    }\n                }\n\n                state = MISMATCH;\n                break;\n            }\n\n            case 'AtKeyword':\n            case 'Function':\n                if (token !== null && areStringsEqualCaseInsensitive(token.value, state.name)) {\n                    addTokenToMatch();\n                    state = MATCH;\n                    break;\n                }\n\n                state = MISMATCH;\n                break;\n\n            case 'Token':\n                if (token !== null && token.value === state.value) {\n                    addTokenToMatch();\n                    state = MATCH;\n                    break;\n                }\n\n                state = MISMATCH;\n                break;\n\n            case 'Comma':\n                if (token !== null && token.type === Comma) {\n                    if (isCommaContextStart(matchStack.token)) {\n                        state = MISMATCH;\n                    } else {\n                        addTokenToMatch();\n                        state = isCommaContextEnd(token) ? MISMATCH : MATCH;\n                    }\n                } else {\n                    state = isCommaContextStart(matchStack.token) || isCommaContextEnd(token) ? MATCH : MISMATCH;\n                }\n\n                break;\n\n            case 'String':\n                let string = '';\n                let lastTokenIndex = tokenIndex;\n\n                for (; lastTokenIndex < tokens.length && string.length < state.value.length; lastTokenIndex++) {\n                    string += tokens[lastTokenIndex].value;\n                }\n\n                if (areStringsEqualCaseInsensitive(string, state.value)) {\n                    while (tokenIndex < lastTokenIndex) {\n                        addTokenToMatch();\n                    }\n\n                    state = MATCH;\n                } else {\n                    state = MISMATCH;\n                }\n\n                break;\n\n            default:\n                throw new Error('Unknown node type: ' + state.type);\n        }\n    }\n\n    switch (exitReason) {\n        case null:\n            console.warn('[csstree-match] BREAK after ' + ITERATION_LIMIT + ' iterations');\n            exitReason = EXIT_REASON_ITERATION_LIMIT;\n            matchStack = null;\n            break;\n\n        case EXIT_REASON_MATCH:\n            while (syntaxStack !== null) {\n                closeSyntax();\n            }\n            break;\n\n        default:\n            matchStack = null;\n    }\n\n    return {\n        tokens,\n        reason: exitReason,\n        iterations: iterationCount,\n        match: matchStack,\n        longestMatch\n    };\n}\n\nfunction matchAsTree(tokens, matchGraph, syntaxes) {\n    const matchResult = internalMatch(tokens, matchGraph, syntaxes || {});\n\n    if (matchResult.match === null) {\n        return matchResult;\n    }\n\n    let item = matchResult.match;\n    let host = matchResult.match = {\n        syntax: matchGraph.syntax || null,\n        match: []\n    };\n    const hostStack = [host];\n\n    // revert a list and start with 2nd item since 1st is a stub item\n    item = reverseList(item).prev;\n\n    // build a tree\n    while (item !== null) {\n        switch (item.type) {\n            case OPEN_SYNTAX:\n                host.match.push(host = {\n                    syntax: item.syntax,\n                    match: []\n                });\n                hostStack.push(host);\n                break;\n\n            case CLOSE_SYNTAX:\n                hostStack.pop();\n                host = hostStack[hostStack.length - 1];\n                break;\n\n            default:\n                host.match.push({\n                    syntax: item.syntax || null,\n                    token: item.token.value,\n                    node: item.token.node\n                });\n        }\n\n        item = item.prev;\n    }\n\n    return matchResult;\n}\n\nfunction getTrace(node) {\n    function shouldPutToTrace(syntax) {\n        if (syntax === null) {\n            return false;\n        }\n\n        return (\n            syntax.type === 'Type' ||\n            syntax.type === 'Property' ||\n            syntax.type === 'Keyword'\n        );\n    }\n\n    function hasMatch(matchNode) {\n        if (Array.isArray(matchNode.match)) {\n            // use for-loop for better perfomance\n            for (let i = 0; i < matchNode.match.length; i++) {\n                if (hasMatch(matchNode.match[i])) {\n                    if (shouldPutToTrace(matchNode.syntax)) {\n                        result.unshift(matchNode.syntax);\n                    }\n\n                    return true;\n                }\n            }\n        } else if (matchNode.node === node) {\n            result = shouldPutToTrace(matchNode.syntax)\n                ? [matchNode.syntax]\n                : [];\n\n            return true;\n        }\n\n        return false;\n    }\n\n    let result = null;\n\n    if (this.matched !== null) {\n        hasMatch(this.matched);\n    }\n\n    return result;\n}\n\nfunction isType(node, type) {\n    return testNode(this, node, match => match.type === 'Type' && match.name === type);\n}\n\nfunction isProperty(node, property) {\n    return testNode(this, node, match => match.type === 'Property' && match.name === property);\n}\n\nfunction isKeyword(node) {\n    return testNode(this, node, match => match.type === 'Keyword');\n}\n\nfunction testNode(match, node, fn) {\n    const trace = getTrace.call(match, node);\n\n    if (trace === null) {\n        return false;\n    }\n\n    return trace.some(fn);\n}\n\nvar trace = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    getTrace: getTrace,\n    isType: isType,\n    isProperty: isProperty,\n    isKeyword: isKeyword\n});\n\nfunction getFirstMatchNode(matchNode) {\n    if ('node' in matchNode) {\n        return matchNode.node;\n    }\n\n    return getFirstMatchNode(matchNode.match[0]);\n}\n\nfunction getLastMatchNode(matchNode) {\n    if ('node' in matchNode) {\n        return matchNode.node;\n    }\n\n    return getLastMatchNode(matchNode.match[matchNode.match.length - 1]);\n}\n\nfunction matchFragments(lexer, ast, match, type, name) {\n    function findFragments(matchNode) {\n        if (matchNode.syntax !== null &&\n            matchNode.syntax.type === type &&\n            matchNode.syntax.name === name) {\n            const start = getFirstMatchNode(matchNode);\n            const end = getLastMatchNode(matchNode);\n\n            lexer.syntax.walk(ast, function(node, item, list) {\n                if (node === start) {\n                    const nodes = new List();\n\n                    do {\n                        nodes.appendData(item.data);\n\n                        if (item.data === end) {\n                            break;\n                        }\n\n                        item = item.next;\n                    } while (item !== null);\n\n                    fragments.push({\n                        parent: list,\n                        nodes\n                    });\n                }\n            });\n        }\n\n        if (Array.isArray(matchNode.match)) {\n            matchNode.match.forEach(findFragments);\n        }\n    }\n\n    const fragments = [];\n\n    if (match.matched !== null) {\n        findFragments(match.matched);\n    }\n\n    return fragments;\n}\n\nconst { hasOwnProperty: hasOwnProperty$1 } = Object.prototype;\n\nfunction isValidNumber(value) {\n    // Number.isInteger(value) && value >= 0\n    return (\n        typeof value === 'number' &&\n        isFinite(value) &&\n        Math.floor(value) === value &&\n        value >= 0\n    );\n}\n\nfunction isValidLocation(loc) {\n    return (\n        Boolean(loc) &&\n        isValidNumber(loc.offset) &&\n        isValidNumber(loc.line) &&\n        isValidNumber(loc.column)\n    );\n}\n\nfunction createNodeStructureChecker(type, fields) {\n    return function checkNode(node, warn) {\n        if (!node || node.constructor !== Object) {\n            return warn(node, 'Type of node should be an Object');\n        }\n\n        for (let key in node) {\n            let valid = true;\n\n            if (hasOwnProperty$1.call(node, key) === false) {\n                continue;\n            }\n\n            if (key === 'type') {\n                if (node.type !== type) {\n                    warn(node, 'Wrong node type `' + node.type + '`, expected `' + type + '`');\n                }\n            } else if (key === 'loc') {\n                if (node.loc === null) {\n                    continue;\n                } else if (node.loc && node.loc.constructor === Object) {\n                    if (typeof node.loc.source !== 'string') {\n                        key += '.source';\n                    } else if (!isValidLocation(node.loc.start)) {\n                        key += '.start';\n                    } else if (!isValidLocation(node.loc.end)) {\n                        key += '.end';\n                    } else {\n                        continue;\n                    }\n                }\n\n                valid = false;\n            } else if (fields.hasOwnProperty(key)) {\n                valid = false;\n\n                for (let i = 0; !valid && i < fields[key].length; i++) {\n                    const fieldType = fields[key][i];\n\n                    switch (fieldType) {\n                        case String:\n                            valid = typeof node[key] === 'string';\n                            break;\n\n                        case Boolean:\n                            valid = typeof node[key] === 'boolean';\n                            break;\n\n                        case null:\n                            valid = node[key] === null;\n                            break;\n\n                        default:\n                            if (typeof fieldType === 'string') {\n                                valid = node[key] && node[key].type === fieldType;\n                            } else if (Array.isArray(fieldType)) {\n                                valid = node[key] instanceof List;\n                            }\n                    }\n                }\n            } else {\n                warn(node, 'Unknown field `' + key + '` for ' + type + ' node type');\n            }\n\n            if (!valid) {\n                warn(node, 'Bad value for `' + type + '.' + key + '`');\n            }\n        }\n\n        for (const key in fields) {\n            if (hasOwnProperty$1.call(fields, key) &&\n                hasOwnProperty$1.call(node, key) === false) {\n                warn(node, 'Field `' + type + '.' + key + '` is missed');\n            }\n        }\n    };\n}\n\nfunction genTypesList(fieldTypes, path) {\n    const docsTypes = [];\n\n    for (let i = 0; i < fieldTypes.length; i++) {\n        const fieldType = fieldTypes[i];\n        if (fieldType === String || fieldType === Boolean) {\n            docsTypes.push(fieldType.name.toLowerCase());\n        } else if (fieldType === null) {\n            docsTypes.push('null');\n        } else if (typeof fieldType === 'string') {\n            docsTypes.push(fieldType);\n        } else if (Array.isArray(fieldType)) {\n            docsTypes.push('List<' + (genTypesList(fieldType, path) || 'any') + '>'); // TODO: use type enum\n        } else {\n            throw new Error('Wrong value `' + fieldType + '` in `' + path + '` structure definition');\n        }\n    }\n\n    return docsTypes.join(' | ');\n}\n\nfunction processStructure(name, nodeType) {\n    const structure = nodeType.structure;\n    const fields = {\n        type: String,\n        loc: true\n    };\n    const docs = {\n        type: '\"' + name + '\"'\n    };\n\n    for (const key in structure) {\n        if (hasOwnProperty$1.call(structure, key) === false) {\n            continue;\n        }\n\n        const fieldTypes = fields[key] = Array.isArray(structure[key])\n            ? structure[key].slice()\n            : [structure[key]];\n\n        docs[key] = genTypesList(fieldTypes, name + '.' + key);\n    }\n\n    return {\n        docs,\n        check: createNodeStructureChecker(name, fields)\n    };\n}\n\nfunction getStructureFromConfig(config) {\n    const structure = {};\n\n    if (config.node) {\n        for (const name in config.node) {\n            if (hasOwnProperty$1.call(config.node, name)) {\n                const nodeType = config.node[name];\n\n                if (nodeType.structure) {\n                    structure[name] = processStructure(name, nodeType);\n                } else {\n                    throw new Error('Missed `structure` field in `' + name + '` node type definition');\n                }\n            }\n        }\n    }\n\n    return structure;\n}\n\nfunction dumpMapSyntax(map, compact, syntaxAsAst) {\n    const result = {};\n\n    for (const name in map) {\n        if (map[name].syntax) {\n            result[name] = syntaxAsAst\n                ? map[name].syntax\n                : generate$O(map[name].syntax, { compact });\n        }\n    }\n\n    return result;\n}\n\nfunction dumpAtruleMapSyntax(map, compact, syntaxAsAst) {\n    const result = {};\n\n    for (const [name, atrule] of Object.entries(map)) {\n        result[name] = {\n            prelude: atrule.prelude && (\n                syntaxAsAst\n                    ? atrule.prelude.syntax\n                    : generate$O(atrule.prelude.syntax, { compact })\n            ),\n            descriptors: atrule.descriptors && dumpMapSyntax(atrule.descriptors, compact, syntaxAsAst)\n        };\n    }\n\n    return result;\n}\n\nfunction valueHasVar(tokens) {\n    for (let i = 0; i < tokens.length; i++) {\n        if (tokens[i].value.toLowerCase() === 'var(') {\n            return true;\n        }\n    }\n\n    return false;\n}\n\nfunction syntaxHasTopLevelCommaMultiplier(syntax) {\n    const singleTerm = syntax.terms[0];\n\n    return (\n        syntax.explicit === false &&\n        syntax.terms.length === 1 &&\n        singleTerm.type === 'Multiplier' &&\n        singleTerm.comma === true\n    );\n}\n\nfunction buildMatchResult(matched, error, iterations) {\n    return {\n        matched,\n        iterations,\n        error,\n        ...trace\n    };\n}\n\nfunction matchSyntax(lexer, syntax, value, useCssWideKeywords) {\n    const tokens = prepareTokens(value, lexer.syntax);\n    let result;\n\n    if (valueHasVar(tokens)) {\n        return buildMatchResult(null, new Error('Matching for a tree with var() is not supported'));\n    }\n\n    if (useCssWideKeywords) {\n        result = matchAsTree(tokens, lexer.cssWideKeywordsSyntax, lexer);\n    }\n\n    if (!useCssWideKeywords || !result.match) {\n        result = matchAsTree(tokens, syntax.match, lexer);\n        if (!result.match) {\n            return buildMatchResult(\n                null,\n                new SyntaxMatchError(result.reason, syntax.syntax, value, result),\n                result.iterations\n            );\n        }\n    }\n\n    return buildMatchResult(result.match, null, result.iterations);\n}\n\nclass Lexer {\n    constructor(config, syntax, structure) {\n        this.cssWideKeywords = cssWideKeywords;\n        this.syntax = syntax;\n        this.generic = false;\n        this.units = { ...units };\n        this.atrules = Object.create(null);\n        this.properties = Object.create(null);\n        this.types = Object.create(null);\n        this.structure = structure || getStructureFromConfig(config);\n\n        if (config) {\n            if (config.cssWideKeywords) {\n                this.cssWideKeywords = config.cssWideKeywords;\n            }\n\n            if (config.units) {\n                for (const group of Object.keys(units)) {\n                    if (Array.isArray(config.units[group])) {\n                        this.units[group] = config.units[group];\n                    }\n                }\n            }\n\n            if (config.types) {\n                for (const [name, type] of Object.entries(config.types)) {\n                    this.addType_(name, type);\n                }\n            }\n\n            if (config.generic) {\n                this.generic = true;\n                for (const [name, value] of Object.entries(createGenericTypes(this.units))) {\n                    this.addType_(name, value);\n                }\n            }\n\n            if (config.atrules) {\n                for (const [name, atrule] of Object.entries(config.atrules)) {\n                    this.addAtrule_(name, atrule);\n                }\n            }\n\n            if (config.properties) {\n                for (const [name, property] of Object.entries(config.properties)) {\n                    this.addProperty_(name, property);\n                }\n            }\n        }\n\n        this.cssWideKeywordsSyntax = buildMatchGraph(this.cssWideKeywords.join(' |  '));\n    }\n\n    checkStructure(ast) {\n        function collectWarning(node, message) {\n            warns.push({ node, message });\n        }\n\n        const structure = this.structure;\n        const warns = [];\n\n        this.syntax.walk(ast, function(node) {\n            if (structure.hasOwnProperty(node.type)) {\n                structure[node.type].check(node, collectWarning);\n            } else {\n                collectWarning(node, 'Unknown node type `' + node.type + '`');\n            }\n        });\n\n        return warns.length ? warns : false;\n    }\n\n    createDescriptor(syntax, type, name, parent = null) {\n        const ref = {\n            type,\n            name\n        };\n        const descriptor = {\n            type,\n            name,\n            parent,\n            serializable: typeof syntax === 'string' || (syntax && typeof syntax.type === 'string'),\n            syntax: null,\n            match: null,\n            matchRef: null // used for properties when a syntax referenced as <'property'> in other syntax definitions\n        };\n\n        if (typeof syntax === 'function') {\n            descriptor.match = buildMatchGraph(syntax, ref);\n        } else {\n            if (typeof syntax === 'string') {\n                // lazy parsing on first access\n                Object.defineProperty(descriptor, 'syntax', {\n                    get() {\n                        Object.defineProperty(descriptor, 'syntax', {\n                            value: parse$O(syntax)\n                        });\n\n                        return descriptor.syntax;\n                    }\n                });\n            } else {\n                descriptor.syntax = syntax;\n            }\n\n            // lazy graph build on first access\n            Object.defineProperty(descriptor, 'match', {\n                get() {\n                    Object.defineProperty(descriptor, 'match', {\n                        value: buildMatchGraph(descriptor.syntax, ref)\n                    });\n\n                    return descriptor.match;\n                }\n            });\n\n            if (type === 'Property') {\n                Object.defineProperty(descriptor, 'matchRef', {\n                    get() {\n                        const syntax = descriptor.syntax;\n                        const value = syntaxHasTopLevelCommaMultiplier(syntax)\n                            ? buildMatchGraph({\n                                ...syntax,\n                                terms: [syntax.terms[0].term]\n                            }, ref)\n                            : null;\n\n                        Object.defineProperty(descriptor, 'matchRef', {\n                            value\n                        });\n\n                        return value;\n                    }\n                });\n            }\n        }\n\n        return descriptor;\n    }\n    addAtrule_(name, syntax) {\n        if (!syntax) {\n            return;\n        }\n\n        this.atrules[name] = {\n            type: 'Atrule',\n            name: name,\n            prelude: syntax.prelude ? this.createDescriptor(syntax.prelude, 'AtrulePrelude', name) : null,\n            descriptors: syntax.descriptors\n                ? Object.keys(syntax.descriptors).reduce(\n                    (map, descName) => {\n                        map[descName] = this.createDescriptor(syntax.descriptors[descName], 'AtruleDescriptor', descName, name);\n                        return map;\n                    },\n                    Object.create(null)\n                )\n                : null\n        };\n    }\n    addProperty_(name, syntax) {\n        if (!syntax) {\n            return;\n        }\n\n        this.properties[name] = this.createDescriptor(syntax, 'Property', name);\n    }\n    addType_(name, syntax) {\n        if (!syntax) {\n            return;\n        }\n\n        this.types[name] = this.createDescriptor(syntax, 'Type', name);\n    }\n\n    checkAtruleName(atruleName) {\n        if (!this.getAtrule(atruleName)) {\n            return new SyntaxReferenceError('Unknown at-rule', '@' + atruleName);\n        }\n    }\n    checkAtrulePrelude(atruleName, prelude) {\n        const error = this.checkAtruleName(atruleName);\n\n        if (error) {\n            return error;\n        }\n\n        const atrule = this.getAtrule(atruleName);\n\n        if (!atrule.prelude && prelude) {\n            return new SyntaxError('At-rule `@' + atruleName + '` should not contain a prelude');\n        }\n\n        if (atrule.prelude && !prelude) {\n            if (!matchSyntax(this, atrule.prelude, '', false).matched) {\n                return new SyntaxError('At-rule `@' + atruleName + '` should contain a prelude');\n            }\n        }\n    }\n    checkAtruleDescriptorName(atruleName, descriptorName) {\n        const error = this.checkAtruleName(atruleName);\n\n        if (error) {\n            return error;\n        }\n\n        const atrule = this.getAtrule(atruleName);\n        const descriptor = keyword(descriptorName);\n\n        if (!atrule.descriptors) {\n            return new SyntaxError('At-rule `@' + atruleName + '` has no known descriptors');\n        }\n\n        if (!atrule.descriptors[descriptor.name] &&\n            !atrule.descriptors[descriptor.basename]) {\n            return new SyntaxReferenceError('Unknown at-rule descriptor', descriptorName);\n        }\n    }\n    checkPropertyName(propertyName) {\n        if (!this.getProperty(propertyName)) {\n            return new SyntaxReferenceError('Unknown property', propertyName);\n        }\n    }\n\n    matchAtrulePrelude(atruleName, prelude) {\n        const error = this.checkAtrulePrelude(atruleName, prelude);\n\n        if (error) {\n            return buildMatchResult(null, error);\n        }\n\n        const atrule = this.getAtrule(atruleName);\n\n        if (!atrule.prelude) {\n            return buildMatchResult(null, null);\n        }\n\n        return matchSyntax(this, atrule.prelude, prelude || '', false);\n    }\n    matchAtruleDescriptor(atruleName, descriptorName, value) {\n        const error = this.checkAtruleDescriptorName(atruleName, descriptorName);\n\n        if (error) {\n            return buildMatchResult(null, error);\n        }\n\n        const atrule = this.getAtrule(atruleName);\n        const descriptor = keyword(descriptorName);\n\n        return matchSyntax(this, atrule.descriptors[descriptor.name] || atrule.descriptors[descriptor.basename], value, false);\n    }\n    matchDeclaration(node) {\n        if (node.type !== 'Declaration') {\n            return buildMatchResult(null, new Error('Not a Declaration node'));\n        }\n\n        return this.matchProperty(node.property, node.value);\n    }\n    matchProperty(propertyName, value) {\n        // don't match syntax for a custom property at the moment\n        if (property(propertyName).custom) {\n            return buildMatchResult(null, new Error('Lexer matching doesn\\'t applicable for custom properties'));\n        }\n\n        const error = this.checkPropertyName(propertyName);\n\n        if (error) {\n            return buildMatchResult(null, error);\n        }\n\n        return matchSyntax(this, this.getProperty(propertyName), value, true);\n    }\n    matchType(typeName, value) {\n        const typeSyntax = this.getType(typeName);\n\n        if (!typeSyntax) {\n            return buildMatchResult(null, new SyntaxReferenceError('Unknown type', typeName));\n        }\n\n        return matchSyntax(this, typeSyntax, value, false);\n    }\n    match(syntax, value) {\n        if (typeof syntax !== 'string' && (!syntax || !syntax.type)) {\n            return buildMatchResult(null, new SyntaxReferenceError('Bad syntax'));\n        }\n\n        if (typeof syntax === 'string' || !syntax.match) {\n            syntax = this.createDescriptor(syntax, 'Type', 'anonymous');\n        }\n\n        return matchSyntax(this, syntax, value, false);\n    }\n\n    findValueFragments(propertyName, value, type, name) {\n        return matchFragments(this, value, this.matchProperty(propertyName, value), type, name);\n    }\n    findDeclarationValueFragments(declaration, type, name) {\n        return matchFragments(this, declaration.value, this.matchDeclaration(declaration), type, name);\n    }\n    findAllFragments(ast, type, name) {\n        const result = [];\n\n        this.syntax.walk(ast, {\n            visit: 'Declaration',\n            enter: (declaration) => {\n                result.push.apply(result, this.findDeclarationValueFragments(declaration, type, name));\n            }\n        });\n\n        return result;\n    }\n\n    getAtrule(atruleName, fallbackBasename = true) {\n        const atrule = keyword(atruleName);\n        const atruleEntry = atrule.vendor && fallbackBasename\n            ? this.atrules[atrule.name] || this.atrules[atrule.basename]\n            : this.atrules[atrule.name];\n\n        return atruleEntry || null;\n    }\n    getAtrulePrelude(atruleName, fallbackBasename = true) {\n        const atrule = this.getAtrule(atruleName, fallbackBasename);\n\n        return atrule && atrule.prelude || null;\n    }\n    getAtruleDescriptor(atruleName, name) {\n        return this.atrules.hasOwnProperty(atruleName) && this.atrules.declarators\n            ? this.atrules[atruleName].declarators[name] || null\n            : null;\n    }\n    getProperty(propertyName, fallbackBasename = true) {\n        const property$1 = property(propertyName);\n        const propertyEntry = property$1.vendor && fallbackBasename\n            ? this.properties[property$1.name] || this.properties[property$1.basename]\n            : this.properties[property$1.name];\n\n        return propertyEntry || null;\n    }\n    getType(name) {\n        return hasOwnProperty.call(this.types, name) ? this.types[name] : null;\n    }\n\n    validate() {\n        function syntaxRef(name, isType) {\n            return isType ? `<${name}>` : `<'${name}'>`;\n        }\n\n        function validate(syntax, name, broken, descriptor) {\n            if (broken.has(name)) {\n                return broken.get(name);\n            }\n\n            broken.set(name, false);\n            if (descriptor.syntax !== null) {\n                walk$1(descriptor.syntax, function(node) {\n                    if (node.type !== 'Type' && node.type !== 'Property') {\n                        return;\n                    }\n\n                    const map = node.type === 'Type' ? syntax.types : syntax.properties;\n                    const brokenMap = node.type === 'Type' ? brokenTypes : brokenProperties;\n\n                    if (!hasOwnProperty.call(map, node.name)) {\n                        errors.push(`${syntaxRef(name, broken === brokenTypes)} used missed syntax definition ${syntaxRef(node.name, node.type === 'Type')}`);\n                        broken.set(name, true);\n                    } else if (validate(syntax, node.name, brokenMap, map[node.name])) {\n                        errors.push(`${syntaxRef(name, broken === brokenTypes)} used broken syntax definition ${syntaxRef(node.name, node.type === 'Type')}`);\n                        broken.set(name, true);\n                    }\n                }, this);\n            }\n        }\n\n        const errors = [];\n        let brokenTypes = new Map();\n        let brokenProperties = new Map();\n\n        for (const key in this.types) {\n            validate(this, key, brokenTypes, this.types[key]);\n        }\n\n        for (const key in this.properties) {\n            validate(this, key, brokenProperties, this.properties[key]);\n        }\n\n        const brokenTypesArray = [...brokenTypes.keys()].filter(name => brokenTypes.get(name));\n        const brokenPropertiesArray = [...brokenProperties.keys()].filter(name => brokenProperties.get(name));\n\n        if (brokenTypesArray.length || brokenPropertiesArray.length) {\n            return {\n                errors,\n                types: brokenTypesArray,\n                properties: brokenPropertiesArray\n            };\n        }\n\n        return null;\n    }\n    dump(syntaxAsAst, pretty) {\n        return {\n            generic: this.generic,\n            cssWideKeywords: this.cssWideKeywords,\n            units: this.units,\n            types: dumpMapSyntax(this.types, !pretty, syntaxAsAst),\n            properties: dumpMapSyntax(this.properties, !pretty, syntaxAsAst),\n            atrules: dumpAtruleMapSyntax(this.atrules, !pretty, syntaxAsAst)\n        };\n    }\n    toString() {\n        return JSON.stringify(this.dump());\n    }\n}\n\nfunction appendOrSet(a, b) {\n    if (typeof b === 'string' && /^\\s*\\|/.test(b)) {\n        return typeof a === 'string'\n            ? a + b\n            : b.replace(/^\\s*\\|\\s*/, '');\n    }\n\n    return b || null;\n}\n\nfunction extractProps(obj, props) {\n    const result = Object.create(null);\n\n    for (const prop of Object.keys(obj)) {\n        if (props.includes(prop)) {\n            result[prop] = obj[prop];\n        }\n    }\n\n    return result;\n}\n\nfunction mergeDicts(base, ext, fields) {\n    const result = { ...base };\n\n    for (const [key, props] of Object.entries(ext)) {\n        result[key] = {\n            ...result[key],\n            ...fields ? extractProps(props, fields) : props\n        };\n    }\n\n    return result;\n}\n\nfunction mix(dest, src) {\n    const result = { ...dest };\n\n    for (const [prop, value] of Object.entries(src)) {\n        switch (prop) {\n            case 'generic':\n                result[prop] = Boolean(value);\n                break;\n\n            case 'cssWideKeywords':\n                result[prop] = dest[prop]\n                    ? [...dest[prop], ...value]\n                    : value || [];\n                break;\n\n            case 'units':\n                result[prop] = { ...dest[prop] };\n                for (const [name, patch] of Object.entries(value)) {\n                    result[prop][name] = Array.isArray(patch) ? patch : [];\n                }\n                break;\n\n            case 'atrules':\n                result[prop] = { ...dest[prop] };\n\n                for (const [name, atrule] of Object.entries(value)) {\n                    const exists = result[prop][name] || {};\n                    const current = result[prop][name] = {\n                        prelude: exists.prelude || null,\n                        descriptors: {\n                            ...exists.descriptors\n                        }\n                    };\n\n                    if (!atrule) {\n                        continue;\n                    }\n\n                    current.prelude = atrule.prelude\n                        ? appendOrSet(current.prelude, atrule.prelude)\n                        : current.prelude || null;\n\n                    for (const [descriptorName, descriptorValue] of Object.entries(atrule.descriptors || {})) {\n                        current.descriptors[descriptorName] = descriptorValue\n                            ? appendOrSet(current.descriptors[descriptorName], descriptorValue)\n                            : null;\n                    }\n\n                    if (!Object.keys(current.descriptors).length) {\n                        current.descriptors = null;\n                    }\n                }\n                break;\n\n            case 'types':\n            case 'properties':\n                result[prop] = { ...dest[prop] };\n                for (const [name, syntax] of Object.entries(value)) {\n                    result[prop][name] = appendOrSet(result[prop][name], syntax);\n                }\n                break;\n\n            case 'parseContext':\n                result[prop] = {\n                    ...dest[prop],\n                    ...value\n                };\n                break;\n\n            case 'scope':\n            case 'features':\n                result[prop] = mergeDicts(dest[prop], value);\n                break;\n\n            case 'atrule':\n            case 'pseudo':\n                result[prop] = mergeDicts(dest[prop], value, ['parse']);\n                break;\n\n            case 'node':\n                result[prop] = mergeDicts(dest[prop], value, ['name', 'structure', 'parse', 'generate', 'walkContext']);\n                break;\n        }\n    }\n\n    return result;\n}\n\nfunction createSyntax(config) {\n    const parse = createParser(config);\n    const walk = createWalker(config);\n    const generate = createGenerator(config);\n    const { fromPlainObject, toPlainObject } = createConvertor(walk);\n\n    const syntax = {\n        lexer: null,\n        createLexer: config => new Lexer(config, syntax, syntax.lexer.structure),\n\n        tokenize: tokenize$1,\n        parse,\n        generate,\n\n        walk,\n        find: walk.find,\n        findLast: walk.findLast,\n        findAll: walk.findAll,\n\n        fromPlainObject,\n        toPlainObject,\n\n        fork(extension) {\n            const base = mix({}, config); // copy of config\n\n            return createSyntax(\n                typeof extension === 'function'\n                    ? extension(base) // TODO: remove Object.assign as second parameter\n                    : mix(base, extension)\n            );\n        }\n    };\n\n    syntax.lexer = new Lexer({\n        generic: config.generic,\n        cssWideKeywords: config.cssWideKeywords,\n        units: config.units,\n        types: config.types,\n        atrules: config.atrules,\n        properties: config.properties,\n        node: config.node\n    }, syntax);\n\n    return syntax;\n}\nvar createSyntax$1 = config => createSyntax(mix({}, config));\n\nvar definitions = {\n    \"generic\": true,\n    \"cssWideKeywords\": [\n        \"initial\",\n        \"inherit\",\n        \"unset\",\n        \"revert\",\n        \"revert-layer\"\n    ],\n    \"units\": {\n        \"angle\": [\n            \"deg\",\n            \"grad\",\n            \"rad\",\n            \"turn\"\n        ],\n        \"decibel\": [\n            \"db\"\n        ],\n        \"flex\": [\n            \"fr\"\n        ],\n        \"frequency\": [\n            \"hz\",\n            \"khz\"\n        ],\n        \"length\": [\n            \"cm\",\n            \"mm\",\n            \"q\",\n            \"in\",\n            \"pt\",\n            \"pc\",\n            \"px\",\n            \"em\",\n            \"rem\",\n            \"ex\",\n            \"rex\",\n            \"cap\",\n            \"rcap\",\n            \"ch\",\n            \"rch\",\n            \"ic\",\n            \"ric\",\n            \"lh\",\n            \"rlh\",\n            \"vw\",\n            \"svw\",\n            \"lvw\",\n            \"dvw\",\n            \"vh\",\n            \"svh\",\n            \"lvh\",\n            \"dvh\",\n            \"vi\",\n            \"svi\",\n            \"lvi\",\n            \"dvi\",\n            \"vb\",\n            \"svb\",\n            \"lvb\",\n            \"dvb\",\n            \"vmin\",\n            \"svmin\",\n            \"lvmin\",\n            \"dvmin\",\n            \"vmax\",\n            \"svmax\",\n            \"lvmax\",\n            \"dvmax\",\n            \"cqw\",\n            \"cqh\",\n            \"cqi\",\n            \"cqb\",\n            \"cqmin\",\n            \"cqmax\"\n        ],\n        \"resolution\": [\n            \"dpi\",\n            \"dpcm\",\n            \"dppx\",\n            \"x\"\n        ],\n        \"semitones\": [\n            \"st\"\n        ],\n        \"time\": [\n            \"s\",\n            \"ms\"\n        ]\n    },\n    \"types\": {\n        \"abs()\": \"abs( <calc-sum> )\",\n        \"absolute-size\": \"xx-small|x-small|small|medium|large|x-large|xx-large|xxx-large\",\n        \"acos()\": \"acos( <calc-sum> )\",\n        \"alpha-value\": \"<number>|<percentage>\",\n        \"an+b\": \"odd|even|<integer>|<n-dimension>|'+'? † n|-n|<ndashdigit-dimension>|'+'? † <ndashdigit-ident>|<dashndashdigit-ident>|<n-dimension> <signed-integer>|'+'? † n <signed-integer>|-n <signed-integer>|<ndash-dimension> <signless-integer>|'+'? † n- <signless-integer>|-n- <signless-integer>|<n-dimension> ['+'|'-'] <signless-integer>|'+'? † n ['+'|'-'] <signless-integer>|-n ['+'|'-'] <signless-integer>\",\n        \"anchor()\": \"anchor( <anchor-name>?&&<anchor-side> , <length-percentage>? )\",\n        \"anchor-name\": \"<dashed-ident>\",\n        \"anchor-side\": \"inside|outside|top|left|right|bottom|start|end|self-start|self-end|<percentage>|center\",\n        \"anchor-size\": \"width|height|block|inline|self-block|self-inline\",\n        \"anchor-size()\": \"anchor-size( [<anchor-name>||<anchor-size>]? , <length-percentage>? )\",\n        \"angle-percentage\": \"<angle>|<percentage>\",\n        \"angular-color-hint\": \"<angle-percentage>|<zero>\",\n        \"angular-color-stop\": \"<color> <color-stop-angle>?\",\n        \"angular-color-stop-list\": \"<angular-color-stop> , [<angular-color-hint>? , <angular-color-stop>]#?\",\n        \"animateable-feature\": \"scroll-position|contents|<custom-ident>\",\n        \"asin()\": \"asin( <calc-sum> )\",\n        \"atan()\": \"atan( <calc-sum> )\",\n        \"atan2()\": \"atan2( <calc-sum> , <calc-sum> )\",\n        \"attachment\": \"scroll|fixed|local\",\n        \"attr()\": \"attr( <attr-name> <type-or-unit>? [, <attr-fallback>]? )\",\n        \"attr-matcher\": \"['~'|'|'|'^'|'$'|'*']? '='\",\n        \"attr-modifier\": \"i|s\",\n        \"attribute-selector\": \"'[' <wq-name> ']'|'[' <wq-name> <attr-matcher> [<string-token>|<ident-token>] <attr-modifier>? ']'\",\n        \"auto-repeat\": \"repeat( [auto-fill|auto-fit] , [<line-names>? <fixed-size>]+ <line-names>? )\",\n        \"auto-track-list\": \"[<line-names>? [<fixed-size>|<fixed-repeat>]]* <line-names>? <auto-repeat> [<line-names>? [<fixed-size>|<fixed-repeat>]]* <line-names>?\",\n        \"axis\": \"block|inline|x|y\",\n        \"baseline-position\": \"[first|last]? baseline\",\n        \"basic-shape\": \"<inset()>|<xywh()>|<rect()>|<circle()>|<ellipse()>|<polygon()>|<path()>\",\n        \"basic-shape-rect\": \"<inset()>|<rect()>|<xywh()>\",\n        \"bg-clip\": \"<visual-box>|border-area|text\",\n        \"bg-image\": \"none|<image>\",\n        \"bg-layer\": \"<bg-image>||<bg-position> [/ <bg-size>]?||<repeat-style>||<attachment>||<visual-box>||<visual-box>\",\n        \"bg-position\": \"[[left|center|right|top|bottom|<length-percentage>]|[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]|[center|[left|right] <length-percentage>?]&&[center|[top|bottom] <length-percentage>?]]\",\n        \"bg-size\": \"[<length-percentage>|auto]{1,2}|cover|contain\",\n        \"blend-mode\": \"normal|multiply|screen|overlay|darken|lighten|color-dodge|color-burn|hard-light|soft-light|difference|exclusion|hue|saturation|color|luminosity\",\n        \"blur()\": \"blur( <length>? )\",\n        \"brightness()\": \"brightness( [<number>|<percentage>]? )\",\n        \"calc()\": \"calc( <calc-sum> )\",\n        \"calc-constant\": \"e|pi|infinity|-infinity|NaN\",\n        \"calc-product\": \"<calc-value> ['*' <calc-value>|'/' <number>]*\",\n        \"calc-size()\": \"calc-size( <calc-size-basis> , <calc-sum> )\",\n        \"calc-size-basis\": \"<intrinsic-size-keyword>|<calc-size()>|any|<calc-sum>\",\n        \"calc-sum\": \"<calc-product> [['+'|'-'] <calc-product>]*\",\n        \"calc-value\": \"<number>|<dimension>|<percentage>|<calc-constant>|( <calc-sum> )\",\n        \"cf-final-image\": \"<image>|<color>\",\n        \"cf-mixing-image\": \"<percentage>?&&<image>\",\n        \"circle()\": \"circle( <radial-size>? [at <position>]? )\",\n        \"clamp()\": \"clamp( <calc-sum>#{3} )\",\n        \"class-selector\": \"'.' <ident-token>\",\n        \"clip-source\": \"<url>\",\n        \"color\": \"<color-base>|currentColor|<system-color>|<device-cmyk()>|<light-dark()>|<-non-standard-color>\",\n        \"color()\": \"color( <colorspace-params> [/ [<alpha-value>|none]]? )\",\n        \"color-base\": \"<hex-color>|<color-function>|<named-color>|<color-mix()>|transparent\",\n        \"color-function\": \"<rgb()>|<rgba()>|<hsl()>|<hsla()>|<hwb()>|<lab()>|<lch()>|<oklab()>|<oklch()>|<color()>\",\n        \"color-interpolation-method\": \"in [<rectangular-color-space>|<polar-color-space> <hue-interpolation-method>?|<custom-color-space>]\",\n        \"color-mix()\": \"color-mix( <color-interpolation-method> , [<color>&&<percentage [0,100]>?]#{2} )\",\n        \"color-stop\": \"<color-stop-length>|<color-stop-angle>\",\n        \"color-stop-angle\": \"[<angle-percentage>|<zero>]{1,2}\",\n        \"color-stop-length\": \"<length-percentage>{1,2}\",\n        \"color-stop-list\": \"<linear-color-stop> , [<linear-color-hint>? , <linear-color-stop>]#?\",\n        \"colorspace-params\": \"[<predefined-rgb-params>|<xyz-params>]\",\n        \"combinator\": \"'>'|'+'|'~'|['|' '|']\",\n        \"common-lig-values\": \"[common-ligatures|no-common-ligatures]\",\n        \"compat-auto\": \"searchfield|textarea|push-button|slider-horizontal|checkbox|radio|square-button|menulist|listbox|meter|progress-bar|button\",\n        \"complex-selector\": \"<complex-selector-unit> [<combinator>? <complex-selector-unit>]*\",\n        \"complex-selector-list\": \"<complex-selector>#\",\n        \"composite-style\": \"clear|copy|source-over|source-in|source-out|source-atop|destination-over|destination-in|destination-out|destination-atop|xor\",\n        \"compositing-operator\": \"add|subtract|intersect|exclude\",\n        \"compound-selector\": \"[<type-selector>? <subclass-selector>*]!\",\n        \"compound-selector-list\": \"<compound-selector>#\",\n        \"conic-gradient()\": \"conic-gradient( [<conic-gradient-syntax>] )\",\n        \"conic-gradient-syntax\": \"[[[from [<angle>|<zero>]]? [at <position>]?]||<color-interpolation-method>]? , <angular-color-stop-list>\",\n        \"container-condition\": \"not <query-in-parens>|<query-in-parens> [[and <query-in-parens>]*|[or <query-in-parens>]*]\",\n        \"container-name\": \"<custom-ident>\",\n        \"container-query\": \"not <query-in-parens>|<query-in-parens> [[and <query-in-parens>]*|[or <query-in-parens>]*]\",\n        \"content-distribution\": \"space-between|space-around|space-evenly|stretch\",\n        \"content-list\": \"[<string>|contents|<image>|<counter>|<quote>|<target>|<leader()>|<attr()>]+\",\n        \"content-position\": \"center|start|end|flex-start|flex-end\",\n        \"content-replacement\": \"<image>\",\n        \"contextual-alt-values\": \"[contextual|no-contextual]\",\n        \"contrast()\": \"contrast( [<number>|<percentage>]? )\",\n        \"coord-box\": \"content-box|padding-box|border-box|fill-box|stroke-box|view-box\",\n        \"cos()\": \"cos( <calc-sum> )\",\n        \"counter\": \"<counter()>|<counters()>\",\n        \"counter()\": \"counter( <counter-name> , <counter-style>? )\",\n        \"counter-name\": \"<custom-ident>\",\n        \"counter-style\": \"<counter-style-name>|symbols( )\",\n        \"counter-style-name\": \"<custom-ident>\",\n        \"counters()\": \"counters( <counter-name> , <string> , <counter-style>? )\",\n        \"cross-fade()\": \"cross-fade( <cf-mixing-image> , <cf-final-image>? )\",\n        \"cubic-bezier()\": \"cubic-bezier( [<number [0,1]> , <number>]#{2} )\",\n        \"cubic-bezier-timing-function\": \"ease|ease-in|ease-out|ease-in-out|<cubic-bezier()>\",\n        \"custom-color-space\": \"<dashed-ident>\",\n        \"custom-params\": \"<dashed-ident> [<number>|<percentage>|none]+\",\n        \"dasharray\": \"[[<length-percentage>|<number>]+]#\",\n        \"dashndashdigit-ident\": \"<ident-token>\",\n        \"deprecated-system-color\": \"ActiveBorder|ActiveCaption|AppWorkspace|Background|ButtonHighlight|ButtonShadow|CaptionText|InactiveBorder|InactiveCaption|InactiveCaptionText|InfoBackground|InfoText|Menu|MenuText|Scrollbar|ThreeDDarkShadow|ThreeDFace|ThreeDHighlight|ThreeDLightShadow|ThreeDShadow|Window|WindowFrame|WindowText\",\n        \"discretionary-lig-values\": \"[discretionary-ligatures|no-discretionary-ligatures]\",\n        \"display-box\": \"contents|none\",\n        \"display-inside\": \"flow|flow-root|table|flex|grid|ruby\",\n        \"display-internal\": \"table-row-group|table-header-group|table-footer-group|table-row|table-cell|table-column-group|table-column|table-caption|ruby-base|ruby-text|ruby-base-container|ruby-text-container\",\n        \"display-legacy\": \"inline-block|inline-list-item|inline-table|inline-flex|inline-grid\",\n        \"display-listitem\": \"<display-outside>?&&[flow|flow-root]?&&list-item\",\n        \"display-outside\": \"block|inline|run-in\",\n        \"drop-shadow()\": \"drop-shadow( [<color>?&&<length>{2,3}] )\",\n        \"easing-function\": \"<linear-easing-function>|<cubic-bezier-easing-function>|<step-easing-function>\",\n        \"east-asian-variant-values\": \"[jis78|jis83|jis90|jis04|simplified|traditional]\",\n        \"east-asian-width-values\": \"[full-width|proportional-width]\",\n        \"element()\": \"element( <custom-ident> , [first|start|last|first-except]? )|element( <id-selector> )\",\n        \"ellipse()\": \"ellipse( <radial-size>? [at <position>]? )\",\n        \"env()\": \"env( <custom-ident> , <declaration-value>? )\",\n        \"exp()\": \"exp( <calc-sum> )\",\n        \"explicit-track-list\": \"[<line-names>? <track-size>]+ <line-names>?\",\n        \"family-name\": \"<string>|<custom-ident>+\",\n        \"feature-tag-value\": \"<string> [<integer>|on|off]?\",\n        \"feature-type\": \"@stylistic|@historical-forms|@styleset|@character-variant|@swash|@ornaments|@annotation\",\n        \"feature-value-block\": \"<feature-type> '{' <feature-value-declaration-list> '}'\",\n        \"feature-value-block-list\": \"<feature-value-block>+\",\n        \"feature-value-declaration\": \"<custom-ident> : <integer>+ ;\",\n        \"feature-value-declaration-list\": \"<feature-value-declaration>\",\n        \"feature-value-name\": \"<custom-ident>\",\n        \"filter-function\": \"<blur()>|<brightness()>|<contrast()>|<drop-shadow()>|<grayscale()>|<hue-rotate()>|<invert()>|<opacity()>|<saturate()>|<sepia()>\",\n        \"filter-value-list\": \"[<filter-function>|<url>]+\",\n        \"final-bg-layer\": \"<'background-color'>||<bg-image>||<bg-position> [/ <bg-size>]?||<repeat-style>||<attachment>||<visual-box>||<visual-box>\",\n        \"fit-content()\": \"fit-content( <length-percentage [0,∞]> )\",\n        \"fixed-breadth\": \"<length-percentage>\",\n        \"fixed-repeat\": \"repeat( [<integer [1,∞]>] , [<line-names>? <fixed-size>]+ <line-names>? )\",\n        \"fixed-size\": \"<fixed-breadth>|minmax( <fixed-breadth> , <track-breadth> )|minmax( <inflexible-breadth> , <fixed-breadth> )\",\n        \"font-stretch-absolute\": \"normal|ultra-condensed|extra-condensed|condensed|semi-condensed|semi-expanded|expanded|extra-expanded|ultra-expanded|<percentage>\",\n        \"font-variant-css21\": \"[normal|small-caps]\",\n        \"font-weight-absolute\": \"normal|bold|<number [1,1000]>\",\n        \"form-control-identifier\": \"select\",\n        \"frequency-percentage\": \"<frequency>|<percentage>\",\n        \"generic-complete\": \"serif|sans-serif|system-ui|cursive|fantasy|math|monospace\",\n        \"general-enclosed\": \"[<function-token> <any-value>? )]|[( <any-value>? )]\",\n        \"generic-family\": \"<generic-script-specific>|<generic-complete>|<generic-incomplete>|<-non-standard-generic-family>\",\n        \"generic-incomplete\": \"ui-serif|ui-sans-serif|ui-monospace|ui-rounded\",\n        \"geometry-box\": \"<shape-box>|fill-box|stroke-box|view-box\",\n        \"gradient\": \"<linear-gradient()>|<repeating-linear-gradient()>|<radial-gradient()>|<repeating-radial-gradient()>|<conic-gradient()>|<repeating-conic-gradient()>|<-legacy-gradient>\",\n        \"grayscale()\": \"grayscale( [<number>|<percentage>]? )\",\n        \"grid-line\": \"auto|<custom-ident>|[<integer>&&<custom-ident>?]|[span&&[<integer>||<custom-ident>]]\",\n        \"historical-lig-values\": \"[historical-ligatures|no-historical-ligatures]\",\n        \"hsl()\": \"hsl( <hue> , <percentage> , <percentage> , <alpha-value>? )|hsl( [<hue>|none] [<percentage>|<number>|none] [<percentage>|<number>|none] [/ [<alpha-value>|none]]? )\",\n        \"hsla()\": \"hsla( <hue> , <percentage> , <percentage> , <alpha-value>? )|hsla( [<hue>|none] [<percentage>|<number>|none] [<percentage>|<number>|none] [/ [<alpha-value>|none]]? )\",\n        \"hue\": \"<number>|<angle>\",\n        \"hue-interpolation-method\": \"[shorter|longer|increasing|decreasing] hue\",\n        \"hue-rotate()\": \"hue-rotate( [<angle>|<zero>]? )\",\n        \"hwb()\": \"hwb( [<hue>|none] [<percentage>|<number>|none] [<percentage>|<number>|none] [/ [<alpha-value>|none]]? )\",\n        \"hypot()\": \"hypot( <calc-sum># )\",\n        \"image\": \"<url>|<image()>|<image-set()>|<element()>|<paint()>|<cross-fade()>|<gradient>\",\n        \"image()\": \"image( <image-tags>? [<image-src>? , <color>?]! )\",\n        \"image-set()\": \"image-set( <image-set-option># )\",\n        \"image-set-option\": \"[<image>|<string>] [<resolution>||type( <string> )]\",\n        \"image-src\": \"<url>|<string>\",\n        \"image-tags\": \"ltr|rtl\",\n        \"inflexible-breadth\": \"<length-percentage>|min-content|max-content|auto\",\n        \"inset()\": \"inset( <length-percentage>{1,4} [round <'border-radius'>]? )\",\n        \"invert()\": \"invert( [<number>|<percentage>]? )\",\n        \"keyframe-block\": \"<keyframe-selector># { <declaration-list> }\",\n        \"keyframe-selector\": \"from|to|<percentage [0,100]>|<timeline-range-name> <percentage>\",\n        \"keyframes-name\": \"<custom-ident>|<string>\",\n        \"lab()\": \"lab( [<percentage>|<number>|none] [<percentage>|<number>|none] [<percentage>|<number>|none] [/ [<alpha-value>|none]]? )\",\n        \"layer()\": \"layer( <layer-name> )\",\n        \"layer-name\": \"<ident> ['.' <ident>]*\",\n        \"lch()\": \"lch( [<percentage>|<number>|none] [<percentage>|<number>|none] [<hue>|none] [/ [<alpha-value>|none]]? )\",\n        \"leader()\": \"leader( <leader-type> )\",\n        \"leader-type\": \"dotted|solid|space|<string>\",\n        \"length-percentage\": \"<length>|<percentage>\",\n        \"light-dark()\": \"light-dark( <color> , <color> )\",\n        \"line-name-list\": \"[<line-names>|<name-repeat>]+\",\n        \"line-names\": \"'[' <custom-ident>* ']'\",\n        \"line-style\": \"none|hidden|dotted|dashed|solid|double|groove|ridge|inset|outset\",\n        \"line-width\": \"<length>|thin|medium|thick\",\n        \"linear()\": \"linear( [<number>&&<percentage>{0,2}]# )\",\n        \"linear-color-hint\": \"<length-percentage>\",\n        \"linear-color-stop\": \"<color> <color-stop-length>?\",\n        \"linear-easing-function\": \"linear|<linear()>\",\n        \"linear-gradient()\": \"linear-gradient( [<linear-gradient-syntax>] )\",\n        \"linear-gradient-syntax\": \"[[<angle>|<zero>|to <side-or-corner>]||<color-interpolation-method>]? , <color-stop-list>\",\n        \"log()\": \"log( <calc-sum> , <calc-sum>? )\",\n        \"mask-layer\": \"<mask-reference>||<position> [/ <bg-size>]?||<repeat-style>||<geometry-box>||[<geometry-box>|no-clip]||<compositing-operator>||<masking-mode>\",\n        \"mask-position\": \"[<length-percentage>|left|center|right] [<length-percentage>|top|center|bottom]?\",\n        \"mask-reference\": \"none|<image>|<mask-source>\",\n        \"mask-source\": \"<url>\",\n        \"masking-mode\": \"alpha|luminance|match-source\",\n        \"matrix()\": \"matrix( <number>#{6} )\",\n        \"matrix3d()\": \"matrix3d( <number>#{16} )\",\n        \"max()\": \"max( <calc-sum># )\",\n        \"media-and\": \"<media-in-parens> [and <media-in-parens>]+\",\n        \"media-condition\": \"<media-not>|<media-and>|<media-or>|<media-in-parens>\",\n        \"media-condition-without-or\": \"<media-not>|<media-and>|<media-in-parens>\",\n        \"media-feature\": \"( [<mf-plain>|<mf-boolean>|<mf-range>] )\",\n        \"media-in-parens\": \"( <media-condition> )|<media-feature>|<general-enclosed>\",\n        \"media-not\": \"not <media-in-parens>\",\n        \"media-or\": \"<media-in-parens> [or <media-in-parens>]+\",\n        \"media-query\": \"<media-condition>|[not|only]? <media-type> [and <media-condition-without-or>]?\",\n        \"media-query-list\": \"<media-query>#\",\n        \"media-type\": \"<ident>\",\n        \"mf-boolean\": \"<mf-name>\",\n        \"mf-name\": \"<ident>\",\n        \"mf-plain\": \"<mf-name> : <mf-value>\",\n        \"mf-range\": \"<mf-name> ['<'|'>']? '='? <mf-value>|<mf-value> ['<'|'>']? '='? <mf-name>|<mf-value> '<' '='? <mf-name> '<' '='? <mf-value>|<mf-value> '>' '='? <mf-name> '>' '='? <mf-value>\",\n        \"mf-value\": \"<number>|<dimension>|<ident>|<ratio>\",\n        \"min()\": \"min( <calc-sum># )\",\n        \"minmax()\": \"minmax( [<length-percentage>|min-content|max-content|auto] , [<length-percentage>|<flex>|min-content|max-content|auto] )\",\n        \"mod()\": \"mod( <calc-sum> , <calc-sum> )\",\n        \"n-dimension\": \"<dimension-token>\",\n        \"name-repeat\": \"repeat( [<integer [1,∞]>|auto-fill] , <line-names>+ )\",\n        \"named-color\": \"aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen\",\n        \"namespace-prefix\": \"<ident>\",\n        \"ndash-dimension\": \"<dimension-token>\",\n        \"ndashdigit-dimension\": \"<dimension-token>\",\n        \"ndashdigit-ident\": \"<ident-token>\",\n        \"ns-prefix\": \"[<ident-token>|'*']? '|'\",\n        \"number-percentage\": \"<number>|<percentage>\",\n        \"numeric-figure-values\": \"[lining-nums|oldstyle-nums]\",\n        \"numeric-fraction-values\": \"[diagonal-fractions|stacked-fractions]\",\n        \"numeric-spacing-values\": \"[proportional-nums|tabular-nums]\",\n        \"offset-path\": \"<ray()>|<url>|<basic-shape>\",\n        \"oklab()\": \"oklab( [<percentage>|<number>|none] [<percentage>|<number>|none] [<percentage>|<number>|none] [/ [<alpha-value>|none]]? )\",\n        \"oklch()\": \"oklch( [<percentage>|<number>|none] [<percentage>|<number>|none] [<hue>|none] [/ [<alpha-value>|none]]? )\",\n        \"opacity()\": \"opacity( [<number>|<percentage>]? )\",\n        \"opacity-value\": \"<number>|<percentage>\",\n        \"outline-line-style\": \"none|dotted|dashed|solid|double|groove|ridge|inset|outset\",\n        \"outline-radius\": \"<length>|<percentage>\",\n        \"overflow-position\": \"unsafe|safe\",\n        \"page-body\": \"<declaration>? [; <page-body>]?|<page-margin-box> <page-body>\",\n        \"page-margin-box\": \"<page-margin-box-type> '{' <declaration-list> '}'\",\n        \"page-margin-box-type\": \"@top-left-corner|@top-left|@top-center|@top-right|@top-right-corner|@bottom-left-corner|@bottom-left|@bottom-center|@bottom-right|@bottom-right-corner|@left-top|@left-middle|@left-bottom|@right-top|@right-middle|@right-bottom\",\n        \"page-selector\": \"<pseudo-page>+|<ident> <pseudo-page>*\",\n        \"page-selector-list\": \"[<page-selector>#]?\",\n        \"page-size\": \"A5|A4|A3|B5|B4|JIS-B5|JIS-B4|letter|legal|ledger\",\n        \"paint\": \"none|<color>|<url> [none|<color>]?|context-fill|context-stroke\",\n        \"paint()\": \"paint( <ident> , <declaration-value>? )\",\n        \"paint-box\": \"<visual-box>|fill-box|stroke-box\",\n        \"palette-identifier\": \"<dashed-ident>\",\n        \"palette-mix()\": \"palette-mix( <color-interpolation-method> , [[normal|light|dark|<palette-identifier>|<palette-mix()>]&&<percentage [0,100]>?]#{2} )\",\n        \"path()\": \"path( <'fill-rule'>? , <string> )\",\n        \"perspective()\": \"perspective( [<length [0,∞]>|none] )\",\n        \"polar-color-space\": \"hsl|hwb|lch|oklch\",\n        \"polygon()\": \"polygon( <'fill-rule'>? , [<length-percentage> <length-percentage>]# )\",\n        \"position\": \"[[left|center|right]||[top|center|bottom]|[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]?|[[left|right] <length-percentage>]&&[[top|bottom] <length-percentage>]]\",\n        \"position-area\": \"[[left|center|right|span-left|span-right|x-start|x-end|span-x-start|span-x-end|x-self-start|x-self-end|span-x-self-start|span-x-self-end|span-all]||[top|center|bottom|span-top|span-bottom|y-start|y-end|span-y-start|span-y-end|y-self-start|y-self-end|span-y-self-start|span-y-self-end|span-all]|[block-start|center|block-end|span-block-start|span-block-end|span-all]||[inline-start|center|inline-end|span-inline-start|span-inline-end|span-all]|[self-block-start|center|self-block-end|span-self-block-start|span-self-block-end|span-all]||[self-inline-start|center|self-inline-end|span-self-inline-start|span-self-inline-end|span-all]|[start|center|end|span-start|span-end|span-all]{1,2}|[self-start|center|self-end|span-self-start|span-self-end|span-all]{1,2}]\",\n        \"pow()\": \"pow( <calc-sum> , <calc-sum> )\",\n        \"predefined-rgb\": \"srgb|srgb-linear|display-p3|a98-rgb|prophoto-rgb|rec2020\",\n        \"predefined-rgb-params\": \"<predefined-rgb> [<number>|<percentage>|none]{3}\",\n        \"pseudo-class-selector\": \"':' <ident-token>|':' <function-token> <any-value> ')'\",\n        \"pseudo-element-selector\": \"':' <pseudo-class-selector>|<legacy-pseudo-element-selector>\",\n        \"pseudo-page\": \": [left|right|first|blank]\",\n        \"query-in-parens\": \"( <container-condition> )|( <size-feature> )|style( <style-query> )|<general-enclosed>\",\n        \"quote\": \"open-quote|close-quote|no-open-quote|no-close-quote\",\n        \"radial-extent\": \"closest-corner|closest-side|farthest-corner|farthest-side\",\n        \"radial-gradient()\": \"radial-gradient( [<radial-gradient-syntax>] )\",\n        \"radial-gradient-syntax\": \"[[[<radial-shape>||<radial-size>]? [at <position>]?]||<color-interpolation-method>]? , <color-stop-list>\",\n        \"radial-shape\": \"circle|ellipse\",\n        \"radial-size\": \"<radial-extent>|<length [0,∞]>|<length-percentage [0,∞]>{2}\",\n        \"ratio\": \"<number [0,∞]> [/ <number [0,∞]>]?\",\n        \"ray()\": \"ray( <angle>&&<ray-size>?&&contain?&&[at <position>]? )\",\n        \"ray-size\": \"closest-side|closest-corner|farthest-side|farthest-corner|sides\",\n        \"rect()\": \"rect( [<length-percentage>|auto]{4} [round <'border-radius'>]? )\",\n        \"rectangular-color-space\": \"srgb|srgb-linear|display-p3|a98-rgb|prophoto-rgb|rec2020|lab|oklab|xyz|xyz-d50|xyz-d65\",\n        \"relative-selector\": \"<combinator>? <complex-selector>\",\n        \"relative-selector-list\": \"<relative-selector>#\",\n        \"relative-size\": \"larger|smaller\",\n        \"rem()\": \"rem( <calc-sum> , <calc-sum> )\",\n        \"repeat-style\": \"repeat-x|repeat-y|[repeat|space|round|no-repeat]{1,2}\",\n        \"repeating-conic-gradient()\": \"repeating-conic-gradient( [<conic-gradient-syntax>] )\",\n        \"repeating-linear-gradient()\": \"repeating-linear-gradient( [<linear-gradient-syntax>] )\",\n        \"repeating-radial-gradient()\": \"repeating-radial-gradient( [<radial-gradient-syntax>] )\",\n        \"reversed-counter-name\": \"reversed( <counter-name> )\",\n        \"rgb()\": \"rgb( <percentage>#{3} , <alpha-value>? )|rgb( <number>#{3} , <alpha-value>? )|rgb( [<number>|<percentage>|none]{3} [/ [<alpha-value>|none]]? )\",\n        \"rgba()\": \"rgba( <percentage>#{3} , <alpha-value>? )|rgba( <number>#{3} , <alpha-value>? )|rgba( [<number>|<percentage>|none]{3} [/ [<alpha-value>|none]]? )\",\n        \"rotate()\": \"rotate( [<angle>|<zero>] )\",\n        \"rotate3d()\": \"rotate3d( <number> , <number> , <number> , [<angle>|<zero>] )\",\n        \"rotateX()\": \"rotateX( [<angle>|<zero>] )\",\n        \"rotateY()\": \"rotateY( [<angle>|<zero>] )\",\n        \"rotateZ()\": \"rotateZ( [<angle>|<zero>] )\",\n        \"round()\": \"round( <rounding-strategy>? , <calc-sum> , <calc-sum> )\",\n        \"rounding-strategy\": \"nearest|up|down|to-zero\",\n        \"saturate()\": \"saturate( [<number>|<percentage>]? )\",\n        \"scale()\": \"scale( [<number>|<percentage>]#{1,2} )\",\n        \"scale3d()\": \"scale3d( [<number>|<percentage>]#{3} )\",\n        \"scaleX()\": \"scaleX( [<number>|<percentage>] )\",\n        \"scaleY()\": \"scaleY( [<number>|<percentage>] )\",\n        \"scaleZ()\": \"scaleZ( [<number>|<percentage>] )\",\n        \"scope-end\": \"<forgiving-selector-list>\",\n        \"scope-start\": \"<forgiving-selector-list>\",\n        \"scroll()\": \"scroll( [<scroller>||<axis>]? )\",\n        \"scroller\": \"root|nearest|self\",\n        \"scroll-state-feature\": \"<media-query-list>\",\n        \"scroll-state-in-parens\": \"( <scroll-state-query> )|( <scroll-state-feature> )|<general-enclosed>\",\n        \"scroll-state-query\": \"not <scroll-state-in-parens>|<scroll-state-in-parens> [[and <scroll-state-in-parens>]*|[or <scroll-state-in-parens>]*]|<scroll-state-feature>\",\n        \"selector-list\": \"<complex-selector-list>\",\n        \"self-position\": \"center|start|end|self-start|self-end|flex-start|flex-end\",\n        \"sepia()\": \"sepia( [<number>|<percentage>]? )\",\n        \"shadow\": \"inset?&&<length>{2,4}&&<color>?\",\n        \"shadow-t\": \"[<length>{2,3}&&<color>?]\",\n        \"shape\": \"rect( <top> , <right> , <bottom> , <left> )|rect( <top> <right> <bottom> <left> )\",\n        \"shape-box\": \"<visual-box>|margin-box\",\n        \"side-or-corner\": \"[left|right]||[top|bottom]\",\n        \"sign()\": \"sign( <calc-sum> )\",\n        \"signed-integer\": \"<number-token>\",\n        \"signless-integer\": \"<number-token>\",\n        \"sin()\": \"sin( <calc-sum> )\",\n        \"single-animation\": \"<'animation-duration'>||<easing-function>||<'animation-delay'>||<single-animation-iteration-count>||<single-animation-direction>||<single-animation-fill-mode>||<single-animation-play-state>||[none|<keyframes-name>]||<single-animation-timeline>\",\n        \"single-animation-composition\": \"replace|add|accumulate\",\n        \"single-animation-direction\": \"normal|reverse|alternate|alternate-reverse\",\n        \"single-animation-fill-mode\": \"none|forwards|backwards|both\",\n        \"single-animation-iteration-count\": \"infinite|<number>\",\n        \"single-animation-play-state\": \"running|paused\",\n        \"single-animation-timeline\": \"auto|none|<dashed-ident>|<scroll()>|<view()>\",\n        \"single-transition\": \"[none|<single-transition-property>]||<time>||<easing-function>||<time>||<transition-behavior-value>\",\n        \"single-transition-property\": \"all|<custom-ident>\",\n        \"size\": \"closest-side|farthest-side|closest-corner|farthest-corner|<length>|<length-percentage>{2}\",\n        \"size-feature\": \"<mf-plain>|<mf-boolean>|<mf-range>\",\n        \"skew()\": \"skew( [<angle>|<zero>] , [<angle>|<zero>]? )\",\n        \"skewX()\": \"skewX( [<angle>|<zero>] )\",\n        \"skewY()\": \"skewY( [<angle>|<zero>] )\",\n        \"sqrt()\": \"sqrt( <calc-sum> )\",\n        \"step-position\": \"jump-start|jump-end|jump-none|jump-both|start|end\",\n        \"step-easing-function\": \"step-start|step-end|<steps()>\",\n        \"steps()\": \"steps( <integer> , <step-position>? )\",\n        \"style-feature\": \"<declaration>\",\n        \"style-in-parens\": \"( <style-condition> )|( <style-feature> )|<general-enclosed>\",\n        \"style-query\": \"<style-condition>|<style-feature>\",\n        \"subclass-selector\": \"<id-selector>|<class-selector>|<attribute-selector>|<pseudo-class-selector>\",\n        \"supports-condition\": \"not <supports-in-parens>|<supports-in-parens> [and <supports-in-parens>]*|<supports-in-parens> [or <supports-in-parens>]*\",\n        \"supports-decl\": \"( <declaration> )\",\n        \"supports-feature\": \"<supports-decl>|<supports-selector-fn>\",\n        \"supports-in-parens\": \"( <supports-condition> )|<supports-feature>|<general-enclosed>\",\n        \"supports-selector-fn\": \"selector( <complex-selector> )\",\n        \"symbol\": \"<string>|<image>|<custom-ident>\",\n        \"symbols()\": \"symbols( <symbols-type>? [<string>|<image>]+ )\",\n        \"symbols-type\": \"cyclic|numeric|alphabetic|symbolic|fixed\",\n        \"system-color\": \"AccentColor|AccentColorText|ActiveText|ButtonBorder|ButtonFace|ButtonText|Canvas|CanvasText|Field|FieldText|GrayText|Highlight|HighlightText|LinkText|Mark|MarkText|SelectedItem|SelectedItemText|VisitedText\",\n        \"tan()\": \"tan( <calc-sum> )\",\n        \"target\": \"<target-counter()>|<target-counters()>|<target-text()>\",\n        \"target-counter()\": \"target-counter( [<string>|<url>] , <custom-ident> , <counter-style>? )\",\n        \"target-counters()\": \"target-counters( [<string>|<url>] , <custom-ident> , <string> , <counter-style>? )\",\n        \"target-text()\": \"target-text( [<string>|<url>] , [content|before|after|first-letter]? )\",\n        \"text-edge\": \"[text|cap|ex|ideographic|ideographic-ink] [text|alphabetic|ideographic|ideographic-ink]?\",\n        \"time-percentage\": \"<time>|<percentage>\",\n        \"timeline-range-name\": \"cover|contain|entry|exit|entry-crossing|exit-crossing\",\n        \"track-breadth\": \"<length-percentage>|<flex>|min-content|max-content|auto\",\n        \"track-list\": \"[<line-names>? [<track-size>|<track-repeat>]]+ <line-names>?\",\n        \"track-repeat\": \"repeat( [<integer [1,∞]>] , [<line-names>? <track-size>]+ <line-names>? )\",\n        \"track-size\": \"<track-breadth>|minmax( <inflexible-breadth> , <track-breadth> )|fit-content( <length-percentage> )\",\n        \"transform-function\": \"<matrix()>|<translate()>|<translateX()>|<translateY()>|<scale()>|<scaleX()>|<scaleY()>|<rotate()>|<skew()>|<skewX()>|<skewY()>|<matrix3d()>|<translate3d()>|<translateZ()>|<scale3d()>|<scaleZ()>|<rotate3d()>|<rotateX()>|<rotateY()>|<rotateZ()>|<perspective()>\",\n        \"transform-list\": \"<transform-function>+\",\n        \"transition-behavior-value\": \"normal|allow-discrete\",\n        \"translate()\": \"translate( <length-percentage> , <length-percentage>? )\",\n        \"translate3d()\": \"translate3d( <length-percentage> , <length-percentage> , <length> )\",\n        \"translateX()\": \"translateX( <length-percentage> )\",\n        \"translateY()\": \"translateY( <length-percentage> )\",\n        \"translateZ()\": \"translateZ( <length> )\",\n        \"try-size\": \"most-width|most-height|most-block-size|most-inline-size\",\n        \"try-tactic\": \"flip-block||flip-inline||flip-start\",\n        \"type-or-unit\": \"string|color|url|integer|number|length|angle|time|frequency|cap|ch|em|ex|ic|lh|rlh|rem|vb|vi|vw|vh|vmin|vmax|mm|Q|cm|in|pt|pc|px|deg|grad|rad|turn|ms|s|Hz|kHz|%\",\n        \"type-selector\": \"<wq-name>|<ns-prefix>? '*'\",\n        \"var()\": \"var( <custom-property-name> , <declaration-value>? )\",\n        \"view()\": \"view( [<axis>||<'view-timeline-inset'>]? )\",\n        \"viewport-length\": \"auto|<length-percentage>\",\n        \"visual-box\": \"content-box|padding-box|border-box\",\n        \"wq-name\": \"<ns-prefix>? <ident-token>\",\n        \"xywh()\": \"xywh( <length-percentage>{2} <length-percentage [0,∞]>{2} [round <'border-radius'>]? )\",\n        \"xyz\": \"xyz|xyz-d50|xyz-d65\",\n        \"xyz-params\": \"<xyz-space> [<number>|<percentage>|none]{3}\",\n        \"-legacy-gradient\": \"<-webkit-gradient()>|<-legacy-linear-gradient>|<-legacy-repeating-linear-gradient>|<-legacy-radial-gradient>|<-legacy-repeating-radial-gradient>\",\n        \"-legacy-linear-gradient\": \"-moz-linear-gradient( <-legacy-linear-gradient-arguments> )|-webkit-linear-gradient( <-legacy-linear-gradient-arguments> )|-o-linear-gradient( <-legacy-linear-gradient-arguments> )\",\n        \"-legacy-repeating-linear-gradient\": \"-moz-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )|-webkit-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )|-o-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )\",\n        \"-legacy-linear-gradient-arguments\": \"[<angle>|<side-or-corner>]? , <color-stop-list>\",\n        \"-legacy-radial-gradient\": \"-moz-radial-gradient( <-legacy-radial-gradient-arguments> )|-webkit-radial-gradient( <-legacy-radial-gradient-arguments> )|-o-radial-gradient( <-legacy-radial-gradient-arguments> )\",\n        \"-legacy-repeating-radial-gradient\": \"-moz-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )|-webkit-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )|-o-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )\",\n        \"-legacy-radial-gradient-arguments\": \"[<position> ,]? [[[<-legacy-radial-gradient-shape>||<-legacy-radial-gradient-size>]|[<length>|<percentage>]{2}] ,]? <color-stop-list>\",\n        \"-legacy-radial-gradient-size\": \"closest-side|closest-corner|farthest-side|farthest-corner|contain|cover\",\n        \"-legacy-radial-gradient-shape\": \"circle|ellipse\",\n        \"-non-standard-font\": \"-apple-system-body|-apple-system-headline|-apple-system-subheadline|-apple-system-caption1|-apple-system-caption2|-apple-system-footnote|-apple-system-short-body|-apple-system-short-headline|-apple-system-short-subheadline|-apple-system-short-caption1|-apple-system-short-footnote|-apple-system-tall-body\",\n        \"-non-standard-color\": \"-moz-ButtonDefault|-moz-ButtonHoverFace|-moz-ButtonHoverText|-moz-CellHighlight|-moz-CellHighlightText|-moz-Combobox|-moz-ComboboxText|-moz-Dialog|-moz-DialogText|-moz-dragtargetzone|-moz-EvenTreeRow|-moz-Field|-moz-FieldText|-moz-html-CellHighlight|-moz-html-CellHighlightText|-moz-mac-accentdarkestshadow|-moz-mac-accentdarkshadow|-moz-mac-accentface|-moz-mac-accentlightesthighlight|-moz-mac-accentlightshadow|-moz-mac-accentregularhighlight|-moz-mac-accentregularshadow|-moz-mac-chrome-active|-moz-mac-chrome-inactive|-moz-mac-focusring|-moz-mac-menuselect|-moz-mac-menushadow|-moz-mac-menutextselect|-moz-MenuHover|-moz-MenuHoverText|-moz-MenuBarText|-moz-MenuBarHoverText|-moz-nativehyperlinktext|-moz-OddTreeRow|-moz-win-communicationstext|-moz-win-mediatext|-moz-activehyperlinktext|-moz-default-background-color|-moz-default-color|-moz-hyperlinktext|-moz-visitedhyperlinktext|-webkit-activelink|-webkit-focus-ring-color|-webkit-link|-webkit-text\",\n        \"-non-standard-image-rendering\": \"optimize-contrast|-moz-crisp-edges|-o-crisp-edges|-webkit-optimize-contrast\",\n        \"-non-standard-overflow\": \"overlay|-moz-scrollbars-none|-moz-scrollbars-horizontal|-moz-scrollbars-vertical|-moz-hidden-unscrollable\",\n        \"-non-standard-size\": \"intrinsic|min-intrinsic|-webkit-fill-available|-webkit-fit-content|-webkit-min-content|-webkit-max-content|-moz-available|-moz-fit-content|-moz-min-content|-moz-max-content\",\n        \"-webkit-gradient()\": \"-webkit-gradient( <-webkit-gradient-type> , <-webkit-gradient-point> [, <-webkit-gradient-point>|, <-webkit-gradient-radius> , <-webkit-gradient-point>] [, <-webkit-gradient-radius>]? [, <-webkit-gradient-color-stop>]* )\",\n        \"-webkit-gradient-color-stop\": \"from( <color> )|color-stop( [<number-zero-one>|<percentage>] , <color> )|to( <color> )\",\n        \"-webkit-gradient-point\": \"[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]\",\n        \"-webkit-gradient-radius\": \"<length>|<percentage>\",\n        \"-webkit-gradient-type\": \"linear|radial\",\n        \"-webkit-mask-box-repeat\": \"repeat|stretch|round\",\n        \"-ms-filter-function-list\": \"<-ms-filter-function>+\",\n        \"-ms-filter-function\": \"<-ms-filter-function-progid>|<-ms-filter-function-legacy>\",\n        \"-ms-filter-function-progid\": \"'progid:' [<ident-token> '.']* [<ident-token>|<function-token> <any-value>? )]\",\n        \"-ms-filter-function-legacy\": \"<ident-token>|<function-token> <any-value>? )\",\n        \"age\": \"child|young|old\",\n        \"attr-name\": \"<wq-name>\",\n        \"attr-fallback\": \"<any-value>\",\n        \"bottom\": \"<length>|auto\",\n        \"cubic-bezier-easing-function\": \"ease|ease-in|ease-out|ease-in-out|cubic-bezier( <number [0,1]> , <number> , <number [0,1]> , <number> )\",\n        \"generic-voice\": \"[<age>? <gender> <integer>?]\",\n        \"gender\": \"male|female|neutral\",\n        \"generic-script-specific\": \"generic( kai )|generic( fangsong )|generic( nastaliq )\",\n        \"-non-standard-generic-family\": \"-apple-system|BlinkMacSystemFont\",\n        \"intrinsic-size-keyword\": \"min-content|max-content|fit-content\",\n        \"left\": \"<length>|auto\",\n        \"device-cmyk()\": \"<legacy-device-cmyk-syntax>|<modern-device-cmyk-syntax>\",\n        \"legacy-device-cmyk-syntax\": \"device-cmyk( <number>#{4} )\",\n        \"modern-device-cmyk-syntax\": \"device-cmyk( <cmyk-component>{4} [/ [<alpha-value>|none]]? )\",\n        \"cmyk-component\": \"<number>|<percentage>|none\",\n        \"color-space\": \"<rectangular-color-space>|<polar-color-space>|<custom-color-space>\",\n        \"right\": \"<length>|auto\",\n        \"forgiving-selector-list\": \"<complex-real-selector-list>\",\n        \"forgiving-relative-selector-list\": \"<relative-real-selector-list>\",\n        \"complex-real-selector-list\": \"<complex-real-selector>#\",\n        \"simple-selector-list\": \"<simple-selector>#\",\n        \"relative-real-selector-list\": \"<relative-real-selector>#\",\n        \"complex-selector-unit\": \"[<compound-selector>? <pseudo-compound-selector>*]!\",\n        \"complex-real-selector\": \"<compound-selector> [<combinator>? <compound-selector>]*\",\n        \"relative-real-selector\": \"<combinator>? <complex-real-selector>\",\n        \"pseudo-compound-selector\": \"<pseudo-element-selector> <pseudo-class-selector>*\",\n        \"simple-selector\": \"<type-selector>|<subclass-selector>\",\n        \"legacy-pseudo-element-selector\": \"':' [before|after|first-line|first-letter]\",\n        \"svg-length\": \"<percentage>|<length>|<number>\",\n        \"svg-writing-mode\": \"lr-tb|rl-tb|tb-rl|lr|rl|tb\",\n        \"top\": \"<length>|auto\",\n        \"x\": \"<number>\",\n        \"y\": \"<number>\",\n        \"declaration\": \"<ident-token> : <declaration-value>? ['!' important]?\",\n        \"declaration-list\": \"[<declaration>? ';']* <declaration>?\",\n        \"url\": \"url( <string> <url-modifier>* )|<url-token>\",\n        \"url-modifier\": \"<ident>|<function-token> <any-value> )\",\n        \"number-zero-one\": \"<number [0,1]>\",\n        \"number-one-or-greater\": \"<number [1,∞]>\",\n        \"xyz-space\": \"xyz|xyz-d50|xyz-d65\",\n        \"style-condition\": \"not <style-in-parens>|<style-in-parens> [[and <style-in-parens>]*|[or <style-in-parens>]*]\",\n        \"-non-standard-display\": \"-ms-inline-flexbox|-ms-grid|-ms-inline-grid|-webkit-flex|-webkit-inline-flex|-webkit-box|-webkit-inline-box|-moz-inline-stack|-moz-box|-moz-inline-box\",\n        \"inset-area\": \"[[left|center|right|span-left|span-right|x-start|x-end|span-x-start|span-x-end|x-self-start|x-self-end|span-x-self-start|span-x-self-end|span-all]||[top|center|bottom|span-top|span-bottom|y-start|y-end|span-y-start|span-y-end|y-self-start|y-self-end|span-y-self-start|span-y-self-end|span-all]|[block-start|center|block-end|span-block-start|span-block-end|span-all]||[inline-start|center|inline-end|span-inline-start|span-inline-end|span-all]|[self-block-start|self-block-end|span-self-block-start|span-self-block-end|span-all]||[self-inline-start|self-inline-end|span-self-inline-start|span-self-inline-end|span-all]|[start|center|end|span-start|span-end|span-all]{1,2}|[self-start|center|self-end|span-self-start|span-self-end|span-all]{1,2}]\",\n        \"font-variant-css2\": \"normal|small-caps\",\n        \"font-width-css3\": \"normal|ultra-condensed|extra-condensed|condensed|semi-condensed|semi-expanded|expanded|extra-expanded|ultra-expanded\",\n        \"system-family-name\": \"caption|icon|menu|message-box|small-caption|status-bar\"\n    },\n    \"properties\": {\n        \"--*\": \"<declaration-value>\",\n        \"-ms-accelerator\": \"false|true\",\n        \"-ms-block-progression\": \"tb|rl|bt|lr\",\n        \"-ms-content-zoom-chaining\": \"none|chained\",\n        \"-ms-content-zoom-limit\": \"<'-ms-content-zoom-limit-min'> <'-ms-content-zoom-limit-max'>\",\n        \"-ms-content-zoom-limit-max\": \"<percentage>\",\n        \"-ms-content-zoom-limit-min\": \"<percentage>\",\n        \"-ms-content-zoom-snap\": \"<'-ms-content-zoom-snap-type'>||<'-ms-content-zoom-snap-points'>\",\n        \"-ms-content-zoom-snap-points\": \"snapInterval( <percentage> , <percentage> )|snapList( <percentage># )\",\n        \"-ms-content-zoom-snap-type\": \"none|proximity|mandatory\",\n        \"-ms-content-zooming\": \"none|zoom\",\n        \"-ms-filter\": \"<string>\",\n        \"-ms-flow-from\": \"[none|<custom-ident>]#\",\n        \"-ms-flow-into\": \"[none|<custom-ident>]#\",\n        \"-ms-grid-columns\": \"none|<track-list>|<auto-track-list>\",\n        \"-ms-grid-rows\": \"none|<track-list>|<auto-track-list>\",\n        \"-ms-high-contrast-adjust\": \"auto|none\",\n        \"-ms-hyphenate-limit-chars\": \"auto|<integer>{1,3}\",\n        \"-ms-hyphenate-limit-lines\": \"no-limit|<integer>\",\n        \"-ms-hyphenate-limit-zone\": \"<percentage>|<length>\",\n        \"-ms-ime-align\": \"auto|after\",\n        \"-ms-overflow-style\": \"auto|none|scrollbar|-ms-autohiding-scrollbar\",\n        \"-ms-scroll-chaining\": \"chained|none\",\n        \"-ms-scroll-limit\": \"<'-ms-scroll-limit-x-min'> <'-ms-scroll-limit-y-min'> <'-ms-scroll-limit-x-max'> <'-ms-scroll-limit-y-max'>\",\n        \"-ms-scroll-limit-x-max\": \"auto|<length>\",\n        \"-ms-scroll-limit-x-min\": \"<length>\",\n        \"-ms-scroll-limit-y-max\": \"auto|<length>\",\n        \"-ms-scroll-limit-y-min\": \"<length>\",\n        \"-ms-scroll-rails\": \"none|railed\",\n        \"-ms-scroll-snap-points-x\": \"snapInterval( <length-percentage> , <length-percentage> )|snapList( <length-percentage># )\",\n        \"-ms-scroll-snap-points-y\": \"snapInterval( <length-percentage> , <length-percentage> )|snapList( <length-percentage># )\",\n        \"-ms-scroll-snap-type\": \"none|proximity|mandatory\",\n        \"-ms-scroll-snap-x\": \"<'-ms-scroll-snap-type'> <'-ms-scroll-snap-points-x'>\",\n        \"-ms-scroll-snap-y\": \"<'-ms-scroll-snap-type'> <'-ms-scroll-snap-points-y'>\",\n        \"-ms-scroll-translation\": \"none|vertical-to-horizontal\",\n        \"-ms-scrollbar-3dlight-color\": \"<color>\",\n        \"-ms-scrollbar-arrow-color\": \"<color>\",\n        \"-ms-scrollbar-base-color\": \"<color>\",\n        \"-ms-scrollbar-darkshadow-color\": \"<color>\",\n        \"-ms-scrollbar-face-color\": \"<color>\",\n        \"-ms-scrollbar-highlight-color\": \"<color>\",\n        \"-ms-scrollbar-shadow-color\": \"<color>\",\n        \"-ms-scrollbar-track-color\": \"<color>\",\n        \"-ms-text-autospace\": \"none|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space\",\n        \"-ms-touch-select\": \"grippers|none\",\n        \"-ms-user-select\": \"none|element|text\",\n        \"-ms-wrap-flow\": \"auto|both|start|end|maximum|clear\",\n        \"-ms-wrap-margin\": \"<length>\",\n        \"-ms-wrap-through\": \"wrap|none\",\n        \"-moz-appearance\": \"none|button|button-arrow-down|button-arrow-next|button-arrow-previous|button-arrow-up|button-bevel|button-focus|caret|checkbox|checkbox-container|checkbox-label|checkmenuitem|dualbutton|groupbox|listbox|listitem|menuarrow|menubar|menucheckbox|menuimage|menuitem|menuitemtext|menulist|menulist-button|menulist-text|menulist-textfield|menupopup|menuradio|menuseparator|meterbar|meterchunk|progressbar|progressbar-vertical|progresschunk|progresschunk-vertical|radio|radio-container|radio-label|radiomenuitem|range|range-thumb|resizer|resizerpanel|scale-horizontal|scalethumbend|scalethumb-horizontal|scalethumbstart|scalethumbtick|scalethumb-vertical|scale-vertical|scrollbarbutton-down|scrollbarbutton-left|scrollbarbutton-right|scrollbarbutton-up|scrollbarthumb-horizontal|scrollbarthumb-vertical|scrollbartrack-horizontal|scrollbartrack-vertical|searchfield|separator|sheet|spinner|spinner-downbutton|spinner-textfield|spinner-upbutton|splitter|statusbar|statusbarpanel|tab|tabpanel|tabpanels|tab-scroll-arrow-back|tab-scroll-arrow-forward|textfield|textfield-multiline|toolbar|toolbarbutton|toolbarbutton-dropdown|toolbargripper|toolbox|tooltip|treeheader|treeheadercell|treeheadersortarrow|treeitem|treeline|treetwisty|treetwistyopen|treeview|-moz-mac-unified-toolbar|-moz-win-borderless-glass|-moz-win-browsertabbar-toolbox|-moz-win-communicationstext|-moz-win-communications-toolbox|-moz-win-exclude-glass|-moz-win-glass|-moz-win-mediatext|-moz-win-media-toolbox|-moz-window-button-box|-moz-window-button-box-maximized|-moz-window-button-close|-moz-window-button-maximize|-moz-window-button-minimize|-moz-window-button-restore|-moz-window-frame-bottom|-moz-window-frame-left|-moz-window-frame-right|-moz-window-titlebar|-moz-window-titlebar-maximized\",\n        \"-moz-binding\": \"<url>|none\",\n        \"-moz-border-bottom-colors\": \"<color>+|none\",\n        \"-moz-border-left-colors\": \"<color>+|none\",\n        \"-moz-border-right-colors\": \"<color>+|none\",\n        \"-moz-border-top-colors\": \"<color>+|none\",\n        \"-moz-context-properties\": \"none|[fill|fill-opacity|stroke|stroke-opacity]#\",\n        \"-moz-float-edge\": \"border-box|content-box|margin-box|padding-box\",\n        \"-moz-force-broken-image-icon\": \"0|1\",\n        \"-moz-image-region\": \"<shape>|auto\",\n        \"-moz-orient\": \"inline|block|horizontal|vertical\",\n        \"-moz-outline-radius\": \"<outline-radius>{1,4} [/ <outline-radius>{1,4}]?\",\n        \"-moz-outline-radius-bottomleft\": \"<outline-radius>\",\n        \"-moz-outline-radius-bottomright\": \"<outline-radius>\",\n        \"-moz-outline-radius-topleft\": \"<outline-radius>\",\n        \"-moz-outline-radius-topright\": \"<outline-radius>\",\n        \"-moz-stack-sizing\": \"ignore|stretch-to-fit\",\n        \"-moz-text-blink\": \"none|blink\",\n        \"-moz-user-focus\": \"ignore|normal|select-after|select-before|select-menu|select-same|select-all|none\",\n        \"-moz-user-input\": \"auto|none|enabled|disabled\",\n        \"-moz-user-modify\": \"read-only|read-write|write-only\",\n        \"-moz-window-dragging\": \"drag|no-drag\",\n        \"-moz-window-shadow\": \"default|menu|tooltip|sheet|none\",\n        \"-webkit-appearance\": \"none|button|button-bevel|caps-lock-indicator|caret|checkbox|default-button|inner-spin-button|listbox|listitem|media-controls-background|media-controls-fullscreen-background|media-current-time-display|media-enter-fullscreen-button|media-exit-fullscreen-button|media-fullscreen-button|media-mute-button|media-overlay-play-button|media-play-button|media-seek-back-button|media-seek-forward-button|media-slider|media-sliderthumb|media-time-remaining-display|media-toggle-closed-captions-button|media-volume-slider|media-volume-slider-container|media-volume-sliderthumb|menulist|menulist-button|menulist-text|menulist-textfield|meter|progress-bar|progress-bar-value|push-button|radio|scrollbarbutton-down|scrollbarbutton-left|scrollbarbutton-right|scrollbarbutton-up|scrollbargripper-horizontal|scrollbargripper-vertical|scrollbarthumb-horizontal|scrollbarthumb-vertical|scrollbartrack-horizontal|scrollbartrack-vertical|searchfield|searchfield-cancel-button|searchfield-decoration|searchfield-results-button|searchfield-results-decoration|slider-horizontal|slider-vertical|sliderthumb-horizontal|sliderthumb-vertical|square-button|textarea|textfield|-apple-pay-button\",\n        \"-webkit-border-before\": \"<'border-width'>||<'border-style'>||<color>\",\n        \"-webkit-border-before-color\": \"<color>\",\n        \"-webkit-border-before-style\": \"<'border-style'>\",\n        \"-webkit-border-before-width\": \"<'border-width'>\",\n        \"-webkit-box-reflect\": \"[above|below|right|left]? <length>? <image>?\",\n        \"-webkit-line-clamp\": \"none|<integer>\",\n        \"-webkit-mask\": \"[<mask-reference>||<position> [/ <bg-size>]?||<repeat-style>||[<visual-box>|border|padding|content|text]||[<visual-box>|border|padding|content]]#\",\n        \"-webkit-mask-attachment\": \"<attachment>#\",\n        \"-webkit-mask-clip\": \"[<coord-box>|no-clip|border|padding|content|text]#\",\n        \"-webkit-mask-composite\": \"<composite-style>#\",\n        \"-webkit-mask-image\": \"<mask-reference>#\",\n        \"-webkit-mask-origin\": \"[<coord-box>|border|padding|content]#\",\n        \"-webkit-mask-position\": \"<position>#\",\n        \"-webkit-mask-position-x\": \"[<length-percentage>|left|center|right]#\",\n        \"-webkit-mask-position-y\": \"[<length-percentage>|top|center|bottom]#\",\n        \"-webkit-mask-repeat\": \"<repeat-style>#\",\n        \"-webkit-mask-repeat-x\": \"repeat|no-repeat|space|round\",\n        \"-webkit-mask-repeat-y\": \"repeat|no-repeat|space|round\",\n        \"-webkit-mask-size\": \"<bg-size>#\",\n        \"-webkit-overflow-scrolling\": \"auto|touch\",\n        \"-webkit-tap-highlight-color\": \"<color>\",\n        \"-webkit-text-fill-color\": \"<color>\",\n        \"-webkit-text-stroke\": \"<length>||<color>\",\n        \"-webkit-text-stroke-color\": \"<color>\",\n        \"-webkit-text-stroke-width\": \"<length>\",\n        \"-webkit-touch-callout\": \"default|none\",\n        \"-webkit-user-modify\": \"read-only|read-write|read-write-plaintext-only\",\n        \"-webkit-user-select\": \"auto|none|text|all\",\n        \"accent-color\": \"auto|<color>\",\n        \"align-content\": \"normal|<baseline-position>|<content-distribution>|<overflow-position>? <content-position>\",\n        \"align-items\": \"normal|stretch|<baseline-position>|[<overflow-position>? <self-position>]\",\n        \"align-self\": \"auto|normal|stretch|<baseline-position>|<overflow-position>? <self-position>\",\n        \"align-tracks\": \"[normal|<baseline-position>|<content-distribution>|<overflow-position>? <content-position>]#\",\n        \"alignment-baseline\": \"auto|baseline|before-edge|text-before-edge|middle|central|after-edge|text-after-edge|ideographic|alphabetic|hanging|mathematical\",\n        \"all\": \"initial|inherit|unset|revert|revert-layer\",\n        \"anchor-name\": \"none|<dashed-ident>#\",\n        \"anchor-scope\": \"none|all|<dashed-ident>#\",\n        \"animation\": \"<single-animation>#\",\n        \"animation-composition\": \"<single-animation-composition>#\",\n        \"animation-delay\": \"<time>#\",\n        \"animation-direction\": \"<single-animation-direction>#\",\n        \"animation-duration\": \"<time>#\",\n        \"animation-fill-mode\": \"<single-animation-fill-mode>#\",\n        \"animation-iteration-count\": \"<single-animation-iteration-count>#\",\n        \"animation-name\": \"[none|<keyframes-name>]#\",\n        \"animation-play-state\": \"<single-animation-play-state>#\",\n        \"animation-range\": \"[<'animation-range-start'> <'animation-range-end'>?]#\",\n        \"animation-range-end\": \"[normal|<length-percentage>|<timeline-range-name> <length-percentage>?]#\",\n        \"animation-range-start\": \"[normal|<length-percentage>|<timeline-range-name> <length-percentage>?]#\",\n        \"animation-timeline\": \"<single-animation-timeline>#\",\n        \"animation-timing-function\": \"<easing-function>#\",\n        \"appearance\": \"none|auto|textfield|menulist-button|<compat-auto>\",\n        \"aspect-ratio\": \"auto||<ratio>\",\n        \"backdrop-filter\": \"none|<filter-value-list>\",\n        \"backface-visibility\": \"visible|hidden\",\n        \"background\": \"[<bg-layer> ,]* <final-bg-layer>\",\n        \"background-attachment\": \"<attachment>#\",\n        \"background-blend-mode\": \"<blend-mode>#\",\n        \"background-clip\": \"<bg-clip>#\",\n        \"background-color\": \"<color>\",\n        \"background-image\": \"<bg-image>#\",\n        \"background-origin\": \"<visual-box>#\",\n        \"background-position\": \"<bg-position>#\",\n        \"background-position-x\": \"[center|[[left|right|x-start|x-end]? <length-percentage>?]!]#\",\n        \"background-position-y\": \"[center|[[top|bottom|y-start|y-end]? <length-percentage>?]!]#\",\n        \"background-repeat\": \"<repeat-style>#\",\n        \"background-size\": \"<bg-size>#\",\n        \"baseline-shift\": \"baseline|sub|super|<svg-length>\",\n        \"block-size\": \"<'width'>\",\n        \"border\": \"<line-width>||<line-style>||<color>\",\n        \"border-block\": \"<'border-block-start'>\",\n        \"border-block-color\": \"<'border-top-color'>{1,2}\",\n        \"border-block-end\": \"<'border-top-width'>||<'border-top-style'>||<color>\",\n        \"border-block-end-color\": \"<'border-top-color'>\",\n        \"border-block-end-style\": \"<'border-top-style'>\",\n        \"border-block-end-width\": \"<'border-top-width'>\",\n        \"border-block-start\": \"<'border-top-width'>||<'border-top-style'>||<color>\",\n        \"border-block-start-color\": \"<'border-top-color'>\",\n        \"border-block-start-style\": \"<'border-top-style'>\",\n        \"border-block-start-width\": \"<'border-top-width'>\",\n        \"border-block-style\": \"<'border-top-style'>{1,2}\",\n        \"border-block-width\": \"<'border-top-width'>{1,2}\",\n        \"border-bottom\": \"<line-width>||<line-style>||<color>\",\n        \"border-bottom-color\": \"<'border-top-color'>\",\n        \"border-bottom-left-radius\": \"<length-percentage>{1,2}\",\n        \"border-bottom-right-radius\": \"<length-percentage>{1,2}\",\n        \"border-bottom-style\": \"<line-style>\",\n        \"border-bottom-width\": \"<line-width>\",\n        \"border-collapse\": \"collapse|separate\",\n        \"border-color\": \"<color>{1,4}\",\n        \"border-end-end-radius\": \"<'border-top-left-radius'>\",\n        \"border-end-start-radius\": \"<'border-top-left-radius'>\",\n        \"border-image\": \"<'border-image-source'>||<'border-image-slice'> [/ <'border-image-width'>|/ <'border-image-width'>? / <'border-image-outset'>]?||<'border-image-repeat'>\",\n        \"border-image-outset\": \"[<length>|<number>]{1,4}\",\n        \"border-image-repeat\": \"[stretch|repeat|round|space]{1,2}\",\n        \"border-image-slice\": \"<number-percentage>{1,4}&&fill?\",\n        \"border-image-source\": \"none|<image>\",\n        \"border-image-width\": \"[<length-percentage>|<number>|auto]{1,4}\",\n        \"border-inline\": \"<'border-block-start'>\",\n        \"border-inline-color\": \"<'border-top-color'>{1,2}\",\n        \"border-inline-end\": \"<'border-top-width'>||<'border-top-style'>||<color>\",\n        \"border-inline-end-color\": \"<'border-top-color'>\",\n        \"border-inline-end-style\": \"<'border-top-style'>\",\n        \"border-inline-end-width\": \"<'border-top-width'>\",\n        \"border-inline-start\": \"<'border-top-width'>||<'border-top-style'>||<color>\",\n        \"border-inline-start-color\": \"<'border-top-color'>\",\n        \"border-inline-start-style\": \"<'border-top-style'>\",\n        \"border-inline-start-width\": \"<'border-top-width'>\",\n        \"border-inline-style\": \"<'border-top-style'>{1,2}\",\n        \"border-inline-width\": \"<'border-top-width'>{1,2}\",\n        \"border-left\": \"<line-width>||<line-style>||<color>\",\n        \"border-left-color\": \"<color>\",\n        \"border-left-style\": \"<line-style>\",\n        \"border-left-width\": \"<line-width>\",\n        \"border-radius\": \"<length-percentage>{1,4} [/ <length-percentage>{1,4}]?\",\n        \"border-right\": \"<line-width>||<line-style>||<color>\",\n        \"border-right-color\": \"<color>\",\n        \"border-right-style\": \"<line-style>\",\n        \"border-right-width\": \"<line-width>\",\n        \"border-spacing\": \"<length> <length>?\",\n        \"border-start-end-radius\": \"<'border-top-left-radius'>\",\n        \"border-start-start-radius\": \"<'border-top-left-radius'>\",\n        \"border-style\": \"<line-style>{1,4}\",\n        \"border-top\": \"<line-width>||<line-style>||<color>\",\n        \"border-top-color\": \"<color>\",\n        \"border-top-left-radius\": \"<length-percentage>{1,2}\",\n        \"border-top-right-radius\": \"<length-percentage>{1,2}\",\n        \"border-top-style\": \"<line-style>\",\n        \"border-top-width\": \"<line-width>\",\n        \"border-width\": \"<line-width>{1,4}\",\n        \"bottom\": \"<length>|<percentage>|auto\",\n        \"box-align\": \"start|center|end|baseline|stretch\",\n        \"box-decoration-break\": \"slice|clone\",\n        \"box-direction\": \"normal|reverse|inherit\",\n        \"box-flex\": \"<number>\",\n        \"box-flex-group\": \"<integer>\",\n        \"box-lines\": \"single|multiple\",\n        \"box-ordinal-group\": \"<integer>\",\n        \"box-orient\": \"horizontal|vertical|inline-axis|block-axis|inherit\",\n        \"box-pack\": \"start|center|end|justify\",\n        \"box-shadow\": \"none|<shadow>#\",\n        \"box-sizing\": \"content-box|border-box\",\n        \"break-after\": \"auto|avoid|always|all|avoid-page|page|left|right|recto|verso|avoid-column|column|avoid-region|region\",\n        \"break-before\": \"auto|avoid|always|all|avoid-page|page|left|right|recto|verso|avoid-column|column|avoid-region|region\",\n        \"break-inside\": \"auto|avoid|avoid-page|avoid-column|avoid-region\",\n        \"caption-side\": \"top|bottom\",\n        \"caret\": \"<'caret-color'>||<'caret-shape'>\",\n        \"caret-color\": \"auto|<color>\",\n        \"caret-shape\": \"auto|bar|block|underscore\",\n        \"clear\": \"none|left|right|both|inline-start|inline-end\",\n        \"clip\": \"<shape>|auto\",\n        \"clip-path\": \"<clip-source>|[<basic-shape>||<geometry-box>]|none\",\n        \"clip-rule\": \"nonzero|evenodd\",\n        \"color\": \"<color>\",\n        \"color-interpolation-filters\": \"auto|sRGB|linearRGB\",\n        \"color-scheme\": \"normal|[light|dark|<custom-ident>]+&&only?\",\n        \"column-count\": \"<integer>|auto\",\n        \"column-fill\": \"auto|balance\",\n        \"column-gap\": \"normal|<length-percentage>\",\n        \"column-rule\": \"<'column-rule-width'>||<'column-rule-style'>||<'column-rule-color'>\",\n        \"column-rule-color\": \"<color>\",\n        \"column-rule-style\": \"<'border-style'>\",\n        \"column-rule-width\": \"<'border-width'>\",\n        \"column-span\": \"none|all\",\n        \"column-width\": \"<length>|auto\",\n        \"columns\": \"<'column-width'>||<'column-count'>\",\n        \"contain\": \"none|strict|content|[[size||inline-size]||layout||style||paint]\",\n        \"contain-intrinsic-block-size\": \"auto? [none|<length>]\",\n        \"contain-intrinsic-height\": \"auto? [none|<length>]\",\n        \"contain-intrinsic-inline-size\": \"auto? [none|<length>]\",\n        \"contain-intrinsic-size\": \"[auto? [none|<length>]]{1,2}\",\n        \"contain-intrinsic-width\": \"auto? [none|<length>]\",\n        \"container\": \"<'container-name'> [/ <'container-type'>]?\",\n        \"container-name\": \"none|<custom-ident>+\",\n        \"container-type\": \"normal|[[size|inline-size]||scroll-state]\",\n        \"content\": \"normal|none|[<content-replacement>|<content-list>] [/ [<string>|<counter>]+]?\",\n        \"content-visibility\": \"visible|auto|hidden\",\n        \"counter-increment\": \"[<counter-name> <integer>?]+|none\",\n        \"counter-reset\": \"[<counter-name> <integer>?|<reversed-counter-name> <integer>?]+|none\",\n        \"counter-set\": \"[<counter-name> <integer>?]+|none\",\n        \"cursor\": \"[[<url> [<x> <y>]? ,]* [auto|default|none|context-menu|help|pointer|progress|wait|cell|crosshair|text|vertical-text|alias|copy|move|no-drop|not-allowed|e-resize|n-resize|ne-resize|nw-resize|s-resize|se-resize|sw-resize|w-resize|ew-resize|ns-resize|nesw-resize|nwse-resize|col-resize|row-resize|all-scroll|zoom-in|zoom-out|grab|grabbing|hand|-webkit-grab|-webkit-grabbing|-webkit-zoom-in|-webkit-zoom-out|-moz-grab|-moz-grabbing|-moz-zoom-in|-moz-zoom-out]]\",\n        \"cx\": \"<length>|<percentage>\",\n        \"cy\": \"<length>|<percentage>\",\n        \"d\": \"none|path( <string> )\",\n        \"direction\": \"ltr|rtl\",\n        \"display\": \"[<display-outside>||<display-inside>]|<display-listitem>|<display-internal>|<display-box>|<display-legacy>|<-non-standard-display>\",\n        \"dominant-baseline\": \"auto|use-script|no-change|reset-size|ideographic|alphabetic|hanging|mathematical|central|middle|text-after-edge|text-before-edge\",\n        \"empty-cells\": \"show|hide\",\n        \"field-sizing\": \"content|fixed\",\n        \"fill\": \"<paint>\",\n        \"fill-opacity\": \"<number-zero-one>\",\n        \"fill-rule\": \"nonzero|evenodd\",\n        \"filter\": \"none|<filter-value-list>|<-ms-filter-function-list>\",\n        \"flex\": \"none|[<'flex-grow'> <'flex-shrink'>?||<'flex-basis'>]\",\n        \"flex-basis\": \"content|<'width'>\",\n        \"flex-direction\": \"row|row-reverse|column|column-reverse\",\n        \"flex-flow\": \"<'flex-direction'>||<'flex-wrap'>\",\n        \"flex-grow\": \"<number>\",\n        \"flex-shrink\": \"<number>\",\n        \"flex-wrap\": \"nowrap|wrap|wrap-reverse\",\n        \"float\": \"left|right|none|inline-start|inline-end\",\n        \"flood-color\": \"<color>\",\n        \"flood-opacity\": \"<'opacity'>\",\n        \"font\": \"[[<'font-style'>||<font-variant-css2>||<'font-weight'>||<font-width-css3>]? <'font-size'> [/ <'line-height'>]? <'font-family'>#]|<system-family-name>|<-non-standard-font>\",\n        \"font-family\": \"[<family-name>|<generic-family>]#\",\n        \"font-feature-settings\": \"normal|<feature-tag-value>#\",\n        \"font-kerning\": \"auto|normal|none\",\n        \"font-language-override\": \"normal|<string>\",\n        \"font-optical-sizing\": \"auto|none\",\n        \"font-palette\": \"normal|light|dark|<palette-identifier>|<palette-mix()>\",\n        \"font-size\": \"<absolute-size>|<relative-size>|<length-percentage [0,∞]>|math\",\n        \"font-size-adjust\": \"none|[ex-height|cap-height|ch-width|ic-width|ic-height]? [from-font|<number>]\",\n        \"font-smooth\": \"auto|never|always|<absolute-size>|<length>\",\n        \"font-stretch\": \"<font-stretch-absolute>\",\n        \"font-style\": \"normal|italic|oblique <angle>?\",\n        \"font-synthesis\": \"none|[weight||style||small-caps||position]\",\n        \"font-synthesis-position\": \"auto|none\",\n        \"font-synthesis-small-caps\": \"auto|none\",\n        \"font-synthesis-style\": \"auto|none\",\n        \"font-synthesis-weight\": \"auto|none\",\n        \"font-variant\": \"normal|none|[<common-lig-values>||<discretionary-lig-values>||<historical-lig-values>||<contextual-alt-values>||stylistic( <feature-value-name> )||historical-forms||styleset( <feature-value-name># )||character-variant( <feature-value-name># )||swash( <feature-value-name> )||ornaments( <feature-value-name> )||annotation( <feature-value-name> )||[small-caps|all-small-caps|petite-caps|all-petite-caps|unicase|titling-caps]||<numeric-figure-values>||<numeric-spacing-values>||<numeric-fraction-values>||ordinal||slashed-zero||<east-asian-variant-values>||<east-asian-width-values>||ruby]\",\n        \"font-variant-alternates\": \"normal|[stylistic( <feature-value-name> )||historical-forms||styleset( <feature-value-name># )||character-variant( <feature-value-name># )||swash( <feature-value-name> )||ornaments( <feature-value-name> )||annotation( <feature-value-name> )]\",\n        \"font-variant-caps\": \"normal|small-caps|all-small-caps|petite-caps|all-petite-caps|unicase|titling-caps\",\n        \"font-variant-east-asian\": \"normal|[<east-asian-variant-values>||<east-asian-width-values>||ruby]\",\n        \"font-variant-emoji\": \"normal|text|emoji|unicode\",\n        \"font-variant-ligatures\": \"normal|none|[<common-lig-values>||<discretionary-lig-values>||<historical-lig-values>||<contextual-alt-values>]\",\n        \"font-variant-numeric\": \"normal|[<numeric-figure-values>||<numeric-spacing-values>||<numeric-fraction-values>||ordinal||slashed-zero]\",\n        \"font-variant-position\": \"normal|sub|super\",\n        \"font-variation-settings\": \"normal|[<string> <number>]#\",\n        \"font-weight\": \"<font-weight-absolute>|bolder|lighter\",\n        \"forced-color-adjust\": \"auto|none|preserve-parent-color\",\n        \"gap\": \"<'row-gap'> <'column-gap'>?\",\n        \"grid\": \"<'grid-template'>|<'grid-template-rows'> / [auto-flow&&dense?] <'grid-auto-columns'>?|[auto-flow&&dense?] <'grid-auto-rows'>? / <'grid-template-columns'>\",\n        \"grid-area\": \"<grid-line> [/ <grid-line>]{0,3}\",\n        \"grid-auto-columns\": \"<track-size>+\",\n        \"grid-auto-flow\": \"[row|column]||dense\",\n        \"grid-auto-rows\": \"<track-size>+\",\n        \"grid-column\": \"<grid-line> [/ <grid-line>]?\",\n        \"grid-column-end\": \"<grid-line>\",\n        \"grid-column-gap\": \"<length-percentage>\",\n        \"grid-column-start\": \"<grid-line>\",\n        \"grid-gap\": \"<'grid-row-gap'> <'grid-column-gap'>?\",\n        \"grid-row\": \"<grid-line> [/ <grid-line>]?\",\n        \"grid-row-end\": \"<grid-line>\",\n        \"grid-row-gap\": \"<length-percentage>\",\n        \"grid-row-start\": \"<grid-line>\",\n        \"grid-template\": \"none|[<'grid-template-rows'> / <'grid-template-columns'>]|[<line-names>? <string> <track-size>? <line-names>?]+ [/ <explicit-track-list>]?\",\n        \"grid-template-areas\": \"none|<string>+\",\n        \"grid-template-columns\": \"none|<track-list>|<auto-track-list>|subgrid <line-name-list>?\",\n        \"grid-template-rows\": \"none|<track-list>|<auto-track-list>|subgrid <line-name-list>?\",\n        \"hanging-punctuation\": \"none|[first||[force-end|allow-end]||last]\",\n        \"height\": \"auto|<length-percentage [0,∞]>|min-content|max-content|fit-content|fit-content( <length-percentage [0,∞]> )|<calc-size()>|<anchor-size()>|stretch|<-non-standard-size>\",\n        \"hyphenate-character\": \"auto|<string>\",\n        \"hyphenate-limit-chars\": \"[auto|<integer>]{1,3}\",\n        \"hyphens\": \"none|manual|auto\",\n        \"image-orientation\": \"from-image|<angle>|[<angle>? flip]\",\n        \"image-rendering\": \"auto|crisp-edges|pixelated|smooth|optimizeSpeed|optimizeQuality|<-non-standard-image-rendering>\",\n        \"image-resolution\": \"[from-image||<resolution>]&&snap?\",\n        \"ime-mode\": \"auto|normal|active|inactive|disabled\",\n        \"initial-letter\": \"normal|[<number> <integer>?]\",\n        \"initial-letter-align\": \"[auto|alphabetic|hanging|ideographic]\",\n        \"inline-size\": \"<'width'>\",\n        \"inset\": \"<'top'>{1,4}\",\n        \"inset-block\": \"<'top'>{1,2}\",\n        \"inset-block-end\": \"<'top'>\",\n        \"inset-block-start\": \"<'top'>\",\n        \"inset-inline\": \"<'top'>{1,2}\",\n        \"inset-inline-end\": \"<'top'>\",\n        \"inset-inline-start\": \"<'top'>\",\n        \"interpolate-size\": \"numeric-only|allow-keywords\",\n        \"isolation\": \"auto|isolate\",\n        \"justify-content\": \"normal|<content-distribution>|<overflow-position>? [<content-position>|left|right]\",\n        \"justify-items\": \"normal|stretch|<baseline-position>|<overflow-position>? [<self-position>|left|right]|legacy|legacy&&[left|right|center]\",\n        \"justify-self\": \"auto|normal|stretch|<baseline-position>|<overflow-position>? [<self-position>|left|right]\",\n        \"justify-tracks\": \"[normal|<content-distribution>|<overflow-position>? [<content-position>|left|right]]#\",\n        \"left\": \"<length>|<percentage>|auto\",\n        \"letter-spacing\": \"normal|<length-percentage>\",\n        \"lighting-color\": \"<color>\",\n        \"line-break\": \"auto|loose|normal|strict|anywhere\",\n        \"line-clamp\": \"none|<integer>\",\n        \"line-height\": \"normal|<number>|<length>|<percentage>\",\n        \"line-height-step\": \"<length>\",\n        \"list-style\": \"<'list-style-type'>||<'list-style-position'>||<'list-style-image'>\",\n        \"list-style-image\": \"<image>|none\",\n        \"list-style-position\": \"inside|outside\",\n        \"list-style-type\": \"<counter-style>|<string>|none\",\n        \"margin\": \"<'margin-top'>{1,4}\",\n        \"margin-block\": \"<'margin-top'>{1,2}\",\n        \"margin-block-end\": \"<'margin-top'>\",\n        \"margin-block-start\": \"<'margin-top'>\",\n        \"margin-bottom\": \"<length-percentage>|auto\",\n        \"margin-inline\": \"<'margin-top'>{1,2}\",\n        \"margin-inline-end\": \"<'margin-top'>\",\n        \"margin-inline-start\": \"<'margin-top'>\",\n        \"margin-left\": \"<length-percentage>|auto\",\n        \"margin-right\": \"<length-percentage>|auto\",\n        \"margin-top\": \"<length-percentage>|auto\",\n        \"margin-trim\": \"none|in-flow|all\",\n        \"marker\": \"none|<url>\",\n        \"marker-end\": \"none|<url>\",\n        \"marker-mid\": \"none|<url>\",\n        \"marker-start\": \"none|<url>\",\n        \"mask\": \"<mask-layer>#\",\n        \"mask-border\": \"<'mask-border-source'>||<'mask-border-slice'> [/ <'mask-border-width'>? [/ <'mask-border-outset'>]?]?||<'mask-border-repeat'>||<'mask-border-mode'>\",\n        \"mask-border-mode\": \"luminance|alpha\",\n        \"mask-border-outset\": \"[<length>|<number>]{1,4}\",\n        \"mask-border-repeat\": \"[stretch|repeat|round|space]{1,2}\",\n        \"mask-border-slice\": \"<number-percentage>{1,4} fill?\",\n        \"mask-border-source\": \"none|<image>\",\n        \"mask-border-width\": \"[<length-percentage>|<number>|auto]{1,4}\",\n        \"mask-clip\": \"[<coord-box>|no-clip]#\",\n        \"mask-composite\": \"<compositing-operator>#\",\n        \"mask-image\": \"<mask-reference>#\",\n        \"mask-mode\": \"<masking-mode>#\",\n        \"mask-origin\": \"<coord-box>#\",\n        \"mask-position\": \"<position>#\",\n        \"mask-repeat\": \"<repeat-style>#\",\n        \"mask-size\": \"<bg-size>#\",\n        \"mask-type\": \"luminance|alpha\",\n        \"masonry-auto-flow\": \"[pack|next]||[definite-first|ordered]\",\n        \"math-depth\": \"auto-add|add( <integer> )|<integer>\",\n        \"math-shift\": \"normal|compact\",\n        \"math-style\": \"normal|compact\",\n        \"max-block-size\": \"<'max-width'>\",\n        \"max-height\": \"none|<length-percentage [0,∞]>|min-content|max-content|fit-content|fit-content( <length-percentage [0,∞]> )|<calc-size()>|<anchor-size()>|stretch|<-non-standard-size>\",\n        \"max-inline-size\": \"<'max-width'>\",\n        \"max-lines\": \"none|<integer>\",\n        \"max-width\": \"none|<length-percentage [0,∞]>|min-content|max-content|fit-content|fit-content( <length-percentage [0,∞]> )|<calc-size()>|<anchor-size()>|stretch|<-non-standard-size>\",\n        \"min-block-size\": \"<'min-width'>\",\n        \"min-height\": \"auto|<length-percentage [0,∞]>|min-content|max-content|fit-content|fit-content( <length-percentage [0,∞]> )|<calc-size()>|<anchor-size()>|stretch|<-non-standard-size>\",\n        \"min-inline-size\": \"<'min-width'>\",\n        \"min-width\": \"auto|<length-percentage [0,∞]>|min-content|max-content|fit-content|fit-content( <length-percentage [0,∞]> )|<calc-size()>|<anchor-size()>|stretch|<-non-standard-size>\",\n        \"mix-blend-mode\": \"<blend-mode>|plus-lighter\",\n        \"object-fit\": \"fill|contain|cover|none|scale-down\",\n        \"object-position\": \"<position>\",\n        \"object-view-box\": \"none|<basic-shape-rect>\",\n        \"offset\": \"[<'offset-position'>? [<'offset-path'> [<'offset-distance'>||<'offset-rotate'>]?]?]! [/ <'offset-anchor'>]?\",\n        \"offset-anchor\": \"auto|<position>\",\n        \"offset-distance\": \"<length-percentage>\",\n        \"offset-path\": \"none|<offset-path>||<coord-box>\",\n        \"offset-position\": \"normal|auto|<position>\",\n        \"offset-rotate\": \"[auto|reverse]||<angle>\",\n        \"opacity\": \"<opacity-value>\",\n        \"order\": \"<integer>\",\n        \"orphans\": \"<integer>\",\n        \"outline\": \"<'outline-width'>||<'outline-style'>||<'outline-color'>\",\n        \"outline-color\": \"auto|<color>\",\n        \"outline-offset\": \"<length>\",\n        \"outline-style\": \"auto|<outline-line-style>\",\n        \"outline-width\": \"<line-width>\",\n        \"overflow\": \"[visible|hidden|clip|scroll|auto]{1,2}|<-non-standard-overflow>\",\n        \"overflow-anchor\": \"auto|none\",\n        \"overflow-block\": \"visible|hidden|clip|scroll|auto\",\n        \"overflow-clip-box\": \"padding-box|content-box\",\n        \"overflow-clip-margin\": \"<visual-box>||<length [0,∞]>\",\n        \"overflow-inline\": \"visible|hidden|clip|scroll|auto\",\n        \"overflow-wrap\": \"normal|break-word|anywhere\",\n        \"overflow-x\": \"visible|hidden|clip|scroll|auto|<-non-standard-overflow>\",\n        \"overflow-y\": \"visible|hidden|clip|scroll|auto|<-non-standard-overflow>\",\n        \"overlay\": \"none|auto\",\n        \"overscroll-behavior\": \"[contain|none|auto]{1,2}\",\n        \"overscroll-behavior-block\": \"contain|none|auto\",\n        \"overscroll-behavior-inline\": \"contain|none|auto\",\n        \"overscroll-behavior-x\": \"contain|none|auto\",\n        \"overscroll-behavior-y\": \"contain|none|auto\",\n        \"padding\": \"<'padding-top'>{1,4}\",\n        \"padding-block\": \"<'padding-top'>{1,2}\",\n        \"padding-block-end\": \"<'padding-top'>\",\n        \"padding-block-start\": \"<'padding-top'>\",\n        \"padding-bottom\": \"<length-percentage [0,∞]>\",\n        \"padding-inline\": \"<'padding-top'>{1,2}\",\n        \"padding-inline-end\": \"<'padding-top'>\",\n        \"padding-inline-start\": \"<'padding-top'>\",\n        \"padding-left\": \"<length-percentage [0,∞]>\",\n        \"padding-right\": \"<length-percentage [0,∞]>\",\n        \"padding-top\": \"<length-percentage [0,∞]>\",\n        \"page\": \"auto|<custom-ident>\",\n        \"page-break-after\": \"auto|always|avoid|left|right|recto|verso\",\n        \"page-break-before\": \"auto|always|avoid|left|right|recto|verso\",\n        \"page-break-inside\": \"auto|avoid\",\n        \"paint-order\": \"normal|[fill||stroke||markers]\",\n        \"perspective\": \"none|<length>\",\n        \"perspective-origin\": \"<position>\",\n        \"place-content\": \"<'align-content'> <'justify-content'>?\",\n        \"place-items\": \"<'align-items'> <'justify-items'>?\",\n        \"place-self\": \"<'align-self'> <'justify-self'>?\",\n        \"pointer-events\": \"auto|none|visiblePainted|visibleFill|visibleStroke|visible|painted|fill|stroke|all|inherit\",\n        \"position\": \"static|relative|absolute|sticky|fixed|-webkit-sticky\",\n        \"position-anchor\": \"auto|<anchor-name>\",\n        \"position-area\": \"none|<position-area>\",\n        \"position-try\": \"<'position-try-order'>? <'position-try-fallbacks'>\",\n        \"position-try-fallbacks\": \"none|[[<dashed-ident>||<try-tactic>]|<'position-area'>]#\",\n        \"position-try-order\": \"normal|<try-size>\",\n        \"position-visibility\": \"always|[anchors-valid||anchors-visible||no-overflow]\",\n        \"print-color-adjust\": \"economy|exact\",\n        \"quotes\": \"none|auto|[<string> <string>]+\",\n        \"r\": \"<length>|<percentage>\",\n        \"resize\": \"none|both|horizontal|vertical|block|inline\",\n        \"right\": \"<length>|<percentage>|auto\",\n        \"rotate\": \"none|<angle>|[x|y|z|<number>{3}]&&<angle>\",\n        \"row-gap\": \"normal|<length-percentage>\",\n        \"ruby-align\": \"start|center|space-between|space-around\",\n        \"ruby-merge\": \"separate|collapse|auto\",\n        \"ruby-position\": \"[alternate||[over|under]]|inter-character\",\n        \"rx\": \"<length>|<percentage>\",\n        \"ry\": \"<length>|<percentage>\",\n        \"scale\": \"none|[<number>|<percentage>]{1,3}\",\n        \"scroll-behavior\": \"auto|smooth\",\n        \"scroll-initial-target\": \"none|nearest\",\n        \"scroll-margin\": \"<length>{1,4}\",\n        \"scroll-margin-block\": \"<length>{1,2}\",\n        \"scroll-margin-block-end\": \"<length>\",\n        \"scroll-margin-block-start\": \"<length>\",\n        \"scroll-margin-bottom\": \"<length>\",\n        \"scroll-margin-inline\": \"<length>{1,2}\",\n        \"scroll-margin-inline-end\": \"<length>\",\n        \"scroll-margin-inline-start\": \"<length>\",\n        \"scroll-margin-left\": \"<length>\",\n        \"scroll-margin-right\": \"<length>\",\n        \"scroll-margin-top\": \"<length>\",\n        \"scroll-padding\": \"[auto|<length-percentage>]{1,4}\",\n        \"scroll-padding-block\": \"[auto|<length-percentage>]{1,2}\",\n        \"scroll-padding-block-end\": \"auto|<length-percentage>\",\n        \"scroll-padding-block-start\": \"auto|<length-percentage>\",\n        \"scroll-padding-bottom\": \"auto|<length-percentage>\",\n        \"scroll-padding-inline\": \"[auto|<length-percentage>]{1,2}\",\n        \"scroll-padding-inline-end\": \"auto|<length-percentage>\",\n        \"scroll-padding-inline-start\": \"auto|<length-percentage>\",\n        \"scroll-padding-left\": \"auto|<length-percentage>\",\n        \"scroll-padding-right\": \"auto|<length-percentage>\",\n        \"scroll-padding-top\": \"auto|<length-percentage>\",\n        \"scroll-snap-align\": \"[none|start|end|center]{1,2}\",\n        \"scroll-snap-coordinate\": \"none|<position>#\",\n        \"scroll-snap-destination\": \"<position>\",\n        \"scroll-snap-points-x\": \"none|repeat( <length-percentage> )\",\n        \"scroll-snap-points-y\": \"none|repeat( <length-percentage> )\",\n        \"scroll-snap-stop\": \"normal|always\",\n        \"scroll-snap-type\": \"none|[x|y|block|inline|both] [mandatory|proximity]?\",\n        \"scroll-snap-type-x\": \"none|mandatory|proximity\",\n        \"scroll-snap-type-y\": \"none|mandatory|proximity\",\n        \"scroll-timeline\": \"[<'scroll-timeline-name'> <'scroll-timeline-axis'>?]#\",\n        \"scroll-timeline-axis\": \"[block|inline|x|y]#\",\n        \"scroll-timeline-name\": \"[none|<dashed-ident>]#\",\n        \"scrollbar-color\": \"auto|<color>{2}\",\n        \"scrollbar-gutter\": \"auto|stable&&both-edges?\",\n        \"scrollbar-width\": \"auto|thin|none\",\n        \"shape-image-threshold\": \"<opacity-value>\",\n        \"shape-margin\": \"<length-percentage>\",\n        \"shape-outside\": \"none|[<shape-box>||<basic-shape>]|<image>\",\n        \"shape-rendering\": \"auto|optimizeSpeed|crispEdges|geometricPrecision\",\n        \"speak-as\": \"normal|spell-out||digits||[literal-punctuation|no-punctuation]\",\n        \"stop-color\": \"<'color'>\",\n        \"stop-opacity\": \"<'opacity'>\",\n        \"stroke\": \"<paint>\",\n        \"stroke-dasharray\": \"none|[<svg-length>+]#\",\n        \"stroke-dashoffset\": \"<svg-length>\",\n        \"stroke-linecap\": \"butt|round|square\",\n        \"stroke-linejoin\": \"miter|round|bevel\",\n        \"stroke-miterlimit\": \"<number-one-or-greater>\",\n        \"stroke-opacity\": \"<'opacity'>\",\n        \"stroke-width\": \"<svg-length>\",\n        \"tab-size\": \"<integer>|<length>\",\n        \"table-layout\": \"auto|fixed\",\n        \"text-align\": \"start|end|left|right|center|justify|match-parent\",\n        \"text-align-last\": \"auto|start|end|left|right|center|justify\",\n        \"text-anchor\": \"start|middle|end\",\n        \"text-box\": \"normal|<'text-box-trim'>||<'text-box-edge'>\",\n        \"text-box-edge\": \"auto|<text-edge>\",\n        \"text-box-trim\": \"none|trim-start|trim-end|trim-both\",\n        \"text-combine-upright\": \"none|all|[digits <integer>?]\",\n        \"text-decoration\": \"<'text-decoration-line'>||<'text-decoration-style'>||<'text-decoration-color'>||<'text-decoration-thickness'>\",\n        \"text-decoration-color\": \"<color>\",\n        \"text-decoration-line\": \"none|[underline||overline||line-through||blink]|spelling-error|grammar-error\",\n        \"text-decoration-skip\": \"none|[objects||[spaces|[leading-spaces||trailing-spaces]]||edges||box-decoration]\",\n        \"text-decoration-skip-ink\": \"auto|all|none\",\n        \"text-decoration-style\": \"solid|double|dotted|dashed|wavy\",\n        \"text-decoration-thickness\": \"auto|from-font|<length>|<percentage>\",\n        \"text-emphasis\": \"<'text-emphasis-style'>||<'text-emphasis-color'>\",\n        \"text-emphasis-color\": \"<color>\",\n        \"text-emphasis-position\": \"auto|[over|under]&&[right|left]?\",\n        \"text-emphasis-style\": \"none|[[filled|open]||[dot|circle|double-circle|triangle|sesame]]|<string>\",\n        \"text-indent\": \"<length-percentage>&&hanging?&&each-line?\",\n        \"text-justify\": \"auto|inter-character|inter-word|none\",\n        \"text-orientation\": \"mixed|upright|sideways\",\n        \"text-overflow\": \"[clip|ellipsis|<string>]{1,2}\",\n        \"text-rendering\": \"auto|optimizeSpeed|optimizeLegibility|geometricPrecision\",\n        \"text-shadow\": \"none|<shadow-t>#\",\n        \"text-size-adjust\": \"none|auto|<percentage>\",\n        \"text-spacing-trim\": \"space-all|normal|space-first|trim-start\",\n        \"text-transform\": \"none|[capitalize|uppercase|lowercase]||full-width||full-size-kana|math-auto\",\n        \"text-underline-offset\": \"auto|<length>|<percentage>\",\n        \"text-underline-position\": \"auto|from-font|[under||[left|right]]\",\n        \"text-wrap\": \"<'text-wrap-mode'>||<'text-wrap-style'>\",\n        \"text-wrap-mode\": \"wrap|nowrap\",\n        \"text-wrap-style\": \"auto|balance|stable|pretty\",\n        \"timeline-scope\": \"none|<dashed-ident>#\",\n        \"top\": \"<length>|<percentage>|auto\",\n        \"touch-action\": \"auto|none|[[pan-x|pan-left|pan-right]||[pan-y|pan-up|pan-down]||pinch-zoom]|manipulation\",\n        \"transform\": \"none|<transform-list>\",\n        \"transform-box\": \"content-box|border-box|fill-box|stroke-box|view-box\",\n        \"transform-origin\": \"[<length-percentage>|left|center|right|top|bottom]|[[<length-percentage>|left|center|right]&&[<length-percentage>|top|center|bottom]] <length>?\",\n        \"transform-style\": \"flat|preserve-3d\",\n        \"transition\": \"<single-transition>#\",\n        \"transition-behavior\": \"<transition-behavior-value>#\",\n        \"transition-delay\": \"<time>#\",\n        \"transition-duration\": \"<time>#\",\n        \"transition-property\": \"none|<single-transition-property>#\",\n        \"transition-timing-function\": \"<easing-function>#\",\n        \"translate\": \"none|<length-percentage> [<length-percentage> <length>?]?\",\n        \"unicode-bidi\": \"normal|embed|isolate|bidi-override|isolate-override|plaintext|-moz-isolate|-moz-isolate-override|-moz-plaintext|-webkit-isolate|-webkit-isolate-override|-webkit-plaintext\",\n        \"user-select\": \"auto|text|none|all\",\n        \"vector-effect\": \"none|non-scaling-stroke|non-scaling-size|non-rotation|fixed-position\",\n        \"vertical-align\": \"baseline|sub|super|text-top|text-bottom|middle|top|bottom|<percentage>|<length>\",\n        \"view-timeline\": \"[<'view-timeline-name'> [<'view-timeline-axis'>||<'view-timeline-inset'>]?]#\",\n        \"view-timeline-axis\": \"[block|inline|x|y]#\",\n        \"view-timeline-inset\": \"[[auto|<length-percentage>]{1,2}]#\",\n        \"view-timeline-name\": \"[none|<dashed-ident>]#\",\n        \"view-transition-class\": \"none|<custom-ident>+\",\n        \"view-transition-name\": \"none|<custom-ident>\",\n        \"visibility\": \"visible|hidden|collapse\",\n        \"white-space\": \"normal|pre|pre-wrap|pre-line|<'white-space-collapse'>||<'text-wrap-mode'>\",\n        \"white-space-collapse\": \"collapse|preserve|preserve-breaks|preserve-spaces|break-spaces\",\n        \"widows\": \"<integer>\",\n        \"width\": \"auto|<length-percentage [0,∞]>|min-content|max-content|fit-content|fit-content( <length-percentage [0,∞]> )|<calc-size()>|<anchor-size()>|stretch|<-non-standard-size>\",\n        \"will-change\": \"auto|<animateable-feature>#\",\n        \"word-break\": \"normal|break-all|keep-all|break-word|auto-phrase\",\n        \"word-spacing\": \"normal|<length>\",\n        \"word-wrap\": \"normal|break-word\",\n        \"writing-mode\": \"horizontal-tb|vertical-rl|vertical-lr|sideways-rl|sideways-lr|<svg-writing-mode>\",\n        \"x\": \"<length>|<percentage>\",\n        \"y\": \"<length>|<percentage>\",\n        \"z-index\": \"auto|<integer>\",\n        \"zoom\": \"normal|reset|<number [0,∞]>||<percentage [0,∞]>\",\n        \"-moz-background-clip\": \"padding|border\",\n        \"-moz-border-radius-bottomleft\": \"<'border-bottom-left-radius'>\",\n        \"-moz-border-radius-bottomright\": \"<'border-bottom-right-radius'>\",\n        \"-moz-border-radius-topleft\": \"<'border-top-left-radius'>\",\n        \"-moz-border-radius-topright\": \"<'border-bottom-right-radius'>\",\n        \"-moz-control-character-visibility\": \"visible|hidden\",\n        \"-moz-osx-font-smoothing\": \"auto|grayscale\",\n        \"-moz-user-select\": \"none|text|all|-moz-none\",\n        \"-ms-flex-align\": \"start|end|center|baseline|stretch\",\n        \"-ms-flex-item-align\": \"auto|start|end|center|baseline|stretch\",\n        \"-ms-flex-line-pack\": \"start|end|center|justify|distribute|stretch\",\n        \"-ms-flex-negative\": \"<'flex-shrink'>\",\n        \"-ms-flex-pack\": \"start|end|center|justify|distribute\",\n        \"-ms-flex-order\": \"<integer>\",\n        \"-ms-flex-positive\": \"<'flex-grow'>\",\n        \"-ms-flex-preferred-size\": \"<'flex-basis'>\",\n        \"-ms-interpolation-mode\": \"nearest-neighbor|bicubic\",\n        \"-ms-grid-column-align\": \"start|end|center|stretch\",\n        \"-ms-grid-row-align\": \"start|end|center|stretch\",\n        \"-ms-hyphenate-limit-last\": \"none|always|column|page|spread\",\n        \"-webkit-background-clip\": \"[<visual-box>|border|padding|content|text]#\",\n        \"-webkit-column-break-after\": \"always|auto|avoid\",\n        \"-webkit-column-break-before\": \"always|auto|avoid\",\n        \"-webkit-column-break-inside\": \"always|auto|avoid\",\n        \"-webkit-font-smoothing\": \"auto|none|antialiased|subpixel-antialiased\",\n        \"-webkit-mask-box-image\": \"[<url>|<gradient>|none] [<length-percentage>{4} <-webkit-mask-box-repeat>{2}]?\",\n        \"-webkit-print-color-adjust\": \"economy|exact\",\n        \"-webkit-text-security\": \"none|circle|disc|square\",\n        \"-webkit-user-drag\": \"none|element|auto\",\n        \"behavior\": \"<url>+\",\n        \"cue\": \"<'cue-before'> <'cue-after'>?\",\n        \"cue-after\": \"<url> <decibel>?|none\",\n        \"cue-before\": \"<url> <decibel>?|none\",\n        \"glyph-orientation-horizontal\": \"<angle>\",\n        \"glyph-orientation-vertical\": \"<angle>\",\n        \"kerning\": \"auto|<svg-length>\",\n        \"pause\": \"<'pause-before'> <'pause-after'>?\",\n        \"pause-after\": \"<time>|none|x-weak|weak|medium|strong|x-strong\",\n        \"pause-before\": \"<time>|none|x-weak|weak|medium|strong|x-strong\",\n        \"position-try-options\": \"<'position-try-fallbacks'>\",\n        \"rest\": \"<'rest-before'> <'rest-after'>?\",\n        \"rest-after\": \"<time>|none|x-weak|weak|medium|strong|x-strong\",\n        \"rest-before\": \"<time>|none|x-weak|weak|medium|strong|x-strong\",\n        \"speak\": \"auto|never|always\",\n        \"voice-balance\": \"<number>|left|center|right|leftwards|rightwards\",\n        \"voice-duration\": \"auto|<time>\",\n        \"voice-family\": \"[[<family-name>|<generic-voice>] ,]* [<family-name>|<generic-voice>]|preserve\",\n        \"voice-pitch\": \"<frequency>&&absolute|[[x-low|low|medium|high|x-high]||[<frequency>|<semitones>|<percentage>]]\",\n        \"voice-range\": \"<frequency>&&absolute|[[x-low|low|medium|high|x-high]||[<frequency>|<semitones>|<percentage>]]\",\n        \"voice-rate\": \"[normal|x-slow|slow|medium|fast|x-fast]||<percentage>\",\n        \"voice-stress\": \"normal|strong|moderate|none|reduced\",\n        \"voice-volume\": \"silent|[[x-soft|soft|medium|loud|x-loud]||<decibel>]\",\n        \"white-space-trim\": \"none|discard-before||discard-after||discard-inner\"\n    },\n    \"atrules\": {\n        \"charset\": {\n            \"prelude\": \"<string>\",\n            \"descriptors\": null\n        },\n        \"counter-style\": {\n            \"prelude\": \"<counter-style-name>\",\n            \"descriptors\": {\n                \"additive-symbols\": \"[<integer>&&<symbol>]#\",\n                \"fallback\": \"<counter-style-name>\",\n                \"negative\": \"<symbol> <symbol>?\",\n                \"pad\": \"<integer>&&<symbol>\",\n                \"prefix\": \"<symbol>\",\n                \"range\": \"[[<integer>|infinite]{2}]#|auto\",\n                \"speak-as\": \"auto|bullets|numbers|words|spell-out|<counter-style-name>\",\n                \"suffix\": \"<symbol>\",\n                \"symbols\": \"<symbol>+\",\n                \"system\": \"cyclic|numeric|alphabetic|symbolic|additive|[fixed <integer>?]|[extends <counter-style-name>]\"\n            }\n        },\n        \"container\": {\n            \"prelude\": \"[<container-name>]? <container-condition>\",\n            \"descriptors\": null\n        },\n        \"document\": {\n            \"prelude\": \"[<url>|url-prefix( <string> )|domain( <string> )|media-document( <string> )|regexp( <string> )]#\",\n            \"descriptors\": null\n        },\n        \"font-face\": {\n            \"prelude\": null,\n            \"descriptors\": {\n                \"ascent-override\": \"normal|<percentage>\",\n                \"descent-override\": \"normal|<percentage>\",\n                \"font-display\": \"auto|block|swap|fallback|optional\",\n                \"font-family\": \"<family-name>\",\n                \"font-feature-settings\": \"normal|<feature-tag-value>#\",\n                \"font-stretch\": \"<font-stretch-absolute>{1,2}\",\n                \"font-style\": \"normal|italic|oblique <angle>{0,2}\",\n                \"font-variation-settings\": \"normal|[<string> <number>]#\",\n                \"font-weight\": \"<font-weight-absolute>{1,2}\",\n                \"line-gap-override\": \"normal|<percentage>\",\n                \"size-adjust\": \"<percentage>\",\n                \"src\": \"[<url> [format( <string># )]?|local( <family-name> )]#\",\n                \"unicode-range\": \"<unicode-range-token>#\"\n            }\n        },\n        \"font-feature-values\": {\n            \"prelude\": \"<family-name>#\",\n            \"descriptors\": null\n        },\n        \"font-palette-values\": {\n            \"prelude\": \"<dashed-ident>\",\n            \"descriptors\": {\n                \"base-palette\": \"light|dark|<integer [0,∞]>\",\n                \"font-family\": \"<family-name>#\",\n                \"override-colors\": \"[<integer [0,∞]> <color>]#\"\n            }\n        },\n        \"import\": {\n            \"prelude\": \"[<string>|<url>] [layer|layer( <layer-name> )]? [supports( [<supports-condition>|<declaration>] )]? <media-query-list>?\",\n            \"descriptors\": null\n        },\n        \"keyframes\": {\n            \"prelude\": \"<keyframes-name>\",\n            \"descriptors\": null\n        },\n        \"layer\": {\n            \"prelude\": \"[<layer-name>#|<layer-name>?]\",\n            \"descriptors\": null\n        },\n        \"media\": {\n            \"prelude\": \"<media-query-list>\",\n            \"descriptors\": null\n        },\n        \"namespace\": {\n            \"prelude\": \"<namespace-prefix>? [<string>|<url>]\",\n            \"descriptors\": null\n        },\n        \"page\": {\n            \"prelude\": \"<page-selector-list>\",\n            \"descriptors\": {\n                \"bleed\": \"auto|<length>\",\n                \"marks\": \"none|[crop||cross]\",\n                \"page-orientation\": \"upright|rotate-left|rotate-right\",\n                \"size\": \"<length>{1,2}|auto|[<page-size>||[portrait|landscape]]\"\n            }\n        },\n        \"position-try\": {\n            \"prelude\": \"<dashed-ident>\",\n            \"descriptors\": {\n                \"top\": \"<'top'>\",\n                \"left\": \"<'left'>\",\n                \"bottom\": \"<'bottom'>\",\n                \"right\": \"<'right'>\",\n                \"inset-block-start\": \"<'inset-block-start'>\",\n                \"inset-block-end\": \"<'inset-block-end'>\",\n                \"inset-inline-start\": \"<'inset-inline-start'>\",\n                \"inset-inline-end\": \"<'inset-inline-end'>\",\n                \"inset-block\": \"<'inset-block'>\",\n                \"inset-inline\": \"<'inset-inline'>\",\n                \"inset\": \"<'inset'>\",\n                \"margin-top\": \"<'margin-top'>\",\n                \"margin-left\": \"<'margin-left'>\",\n                \"margin-bottom\": \"<'margin-bottom'>\",\n                \"margin-right\": \"<'margin-right'>\",\n                \"margin-block-start\": \"<'margin-block-start'>\",\n                \"margin-block-end\": \"<'margin-block-end'>\",\n                \"margin-inline-start\": \"<'margin-inline-start'>\",\n                \"margin-inline-end\": \"<'margin-inline-end'>\",\n                \"margin\": \"<'margin'>\",\n                \"margin-block\": \"<'margin-block'>\",\n                \"margin-inline\": \"<'margin-inline'>\",\n                \"width\": \"<'width'>\",\n                \"height\": \"<'height'>\",\n                \"min-width\": \"<'min-width'>\",\n                \"min-height\": \"<'min-height'>\",\n                \"max-width\": \"<'max-width'>\",\n                \"max-height\": \"<'max-height'>\",\n                \"block-size\": \"<'block-size'>\",\n                \"inline-size\": \"<'inline-size'>\",\n                \"min-block-size\": \"<'min-block-size'>\",\n                \"min-inline-size\": \"<'min-inline-size'>\",\n                \"max-block-size\": \"<'max-block-size'>\",\n                \"max-inline-size\": \"<'max-inline-size'>\",\n                \"align-self\": \"<'align-self'>|anchor-center\",\n                \"justify-self\": \"<'justify-self'>|anchor-center\"\n            }\n        },\n        \"property\": {\n            \"prelude\": \"<custom-property-name>\",\n            \"descriptors\": {\n                \"inherits\": \"true|false\",\n                \"initial-value\": \"<declaration-value>?\",\n                \"syntax\": \"<string>\"\n            }\n        },\n        \"scope\": {\n            \"prelude\": \"[( <scope-start> )]? [to ( <scope-end> )]?\",\n            \"descriptors\": null\n        },\n        \"starting-style\": {\n            \"prelude\": null,\n            \"descriptors\": null\n        },\n        \"supports\": {\n            \"prelude\": \"<supports-condition>\",\n            \"descriptors\": null\n        },\n        \"view-transition\": {\n            \"prelude\": null,\n            \"descriptors\": {\n                \"navigation\": \"auto|none\",\n                \"types\": \"none|<custom-ident>+\"\n            }\n        },\n        \"nest\": {\n            \"prelude\": \"<complex-selector-list>\",\n            \"descriptors\": null\n        }\n    }\n};\n\nconst PLUSSIGN$5 = 0x002B;    // U+002B PLUS SIGN (+)\nconst HYPHENMINUS$2 = 0x002D; // U+002D HYPHEN-MINUS (-)\nconst N = 0x006E;           // U+006E LATIN SMALL LETTER N (n)\nconst DISALLOW_SIGN = true;\nconst ALLOW_SIGN = false;\n\nfunction checkInteger(offset, disallowSign) {\n    let pos = this.tokenStart + offset;\n    const code = this.charCodeAt(pos);\n\n    if (code === PLUSSIGN$5 || code === HYPHENMINUS$2) {\n        if (disallowSign) {\n            this.error('Number sign is not allowed');\n        }\n        pos++;\n    }\n\n    for (; pos < this.tokenEnd; pos++) {\n        if (!isDigit(this.charCodeAt(pos))) {\n            this.error('Integer is expected', pos);\n        }\n    }\n}\n\nfunction checkTokenIsInteger(disallowSign) {\n    return checkInteger.call(this, 0, disallowSign);\n}\n\nfunction expectCharCode(offset, code) {\n    if (!this.cmpChar(this.tokenStart + offset, code)) {\n        let msg = '';\n\n        switch (code) {\n            case N:\n                msg = 'N is expected';\n                break;\n            case HYPHENMINUS$2:\n                msg = 'HyphenMinus is expected';\n                break;\n        }\n\n        this.error(msg, this.tokenStart + offset);\n    }\n}\n\n// ... <signed-integer>\n// ... ['+' | '-'] <signless-integer>\nfunction consumeB() {\n    let offset = 0;\n    let sign = 0;\n    let type = this.tokenType;\n\n    while (type === WhiteSpace$1 || type === Comment$1) {\n        type = this.lookupType(++offset);\n    }\n\n    if (type !== Number$2) {\n        if (this.isDelim(PLUSSIGN$5, offset) ||\n            this.isDelim(HYPHENMINUS$2, offset)) {\n            sign = this.isDelim(PLUSSIGN$5, offset) ? PLUSSIGN$5 : HYPHENMINUS$2;\n\n            do {\n                type = this.lookupType(++offset);\n            } while (type === WhiteSpace$1 || type === Comment$1);\n\n            if (type !== Number$2) {\n                this.skip(offset);\n                checkTokenIsInteger.call(this, DISALLOW_SIGN);\n            }\n        } else {\n            return null;\n        }\n    }\n\n    if (offset > 0) {\n        this.skip(offset);\n    }\n\n    if (sign === 0) {\n        type = this.charCodeAt(this.tokenStart);\n        if (type !== PLUSSIGN$5 && type !== HYPHENMINUS$2) {\n            this.error('Number sign is expected');\n        }\n    }\n\n    checkTokenIsInteger.call(this, sign !== 0);\n    return sign === HYPHENMINUS$2 ? '-' + this.consume(Number$2) : this.consume(Number$2);\n}\n\n// An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb\nconst name$M = 'AnPlusB';\nconst structure$M = {\n    a: [String, null],\n    b: [String, null]\n};\n\nfunction parse$N() {\n    /* eslint-disable brace-style*/\n    const start = this.tokenStart;\n    let a = null;\n    let b = null;\n\n    // <integer>\n    if (this.tokenType === Number$2) {\n        checkTokenIsInteger.call(this, ALLOW_SIGN);\n        b = this.consume(Number$2);\n    }\n\n    // -n\n    // -n <signed-integer>\n    // -n ['+' | '-'] <signless-integer>\n    // -n- <signless-integer>\n    // <dashndashdigit-ident>\n    else if (this.tokenType === Ident && this.cmpChar(this.tokenStart, HYPHENMINUS$2)) {\n        a = '-1';\n\n        expectCharCode.call(this, 1, N);\n\n        switch (this.tokenEnd - this.tokenStart) {\n            // -n\n            // -n <signed-integer>\n            // -n ['+' | '-'] <signless-integer>\n            case 2:\n                this.next();\n                b = consumeB.call(this);\n                break;\n\n            // -n- <signless-integer>\n            case 3:\n                expectCharCode.call(this, 2, HYPHENMINUS$2);\n\n                this.next();\n                this.skipSC();\n\n                checkTokenIsInteger.call(this, DISALLOW_SIGN);\n\n                b = '-' + this.consume(Number$2);\n                break;\n\n            // <dashndashdigit-ident>\n            default:\n                expectCharCode.call(this, 2, HYPHENMINUS$2);\n                checkInteger.call(this, 3, DISALLOW_SIGN);\n                this.next();\n\n                b = this.substrToCursor(start + 2);\n        }\n    }\n\n    // '+'? n\n    // '+'? n <signed-integer>\n    // '+'? n ['+' | '-'] <signless-integer>\n    // '+'? n- <signless-integer>\n    // '+'? <ndashdigit-ident>\n    else if (this.tokenType === Ident || (this.isDelim(PLUSSIGN$5) && this.lookupType(1) === Ident)) {\n        let sign = 0;\n        a = '1';\n\n        // just ignore a plus\n        if (this.isDelim(PLUSSIGN$5)) {\n            sign = 1;\n            this.next();\n        }\n\n        expectCharCode.call(this, 0, N);\n\n        switch (this.tokenEnd - this.tokenStart) {\n            // '+'? n\n            // '+'? n <signed-integer>\n            // '+'? n ['+' | '-'] <signless-integer>\n            case 1:\n                this.next();\n                b = consumeB.call(this);\n                break;\n\n            // '+'? n- <signless-integer>\n            case 2:\n                expectCharCode.call(this, 1, HYPHENMINUS$2);\n\n                this.next();\n                this.skipSC();\n\n                checkTokenIsInteger.call(this, DISALLOW_SIGN);\n\n                b = '-' + this.consume(Number$2);\n                break;\n\n            // '+'? <ndashdigit-ident>\n            default:\n                expectCharCode.call(this, 1, HYPHENMINUS$2);\n                checkInteger.call(this, 2, DISALLOW_SIGN);\n                this.next();\n\n                b = this.substrToCursor(start + sign + 1);\n        }\n    }\n\n    // <ndashdigit-dimension>\n    // <ndash-dimension> <signless-integer>\n    // <n-dimension>\n    // <n-dimension> <signed-integer>\n    // <n-dimension> ['+' | '-'] <signless-integer>\n    else if (this.tokenType === Dimension$1) {\n        const code = this.charCodeAt(this.tokenStart);\n        const sign = code === PLUSSIGN$5 || code === HYPHENMINUS$2;\n        let i = this.tokenStart + sign;\n\n        for (; i < this.tokenEnd; i++) {\n            if (!isDigit(this.charCodeAt(i))) {\n                break;\n            }\n        }\n\n        if (i === this.tokenStart + sign) {\n            this.error('Integer is expected', this.tokenStart + sign);\n        }\n\n        expectCharCode.call(this, i - this.tokenStart, N);\n        a = this.substring(start, i);\n\n        // <n-dimension>\n        // <n-dimension> <signed-integer>\n        // <n-dimension> ['+' | '-'] <signless-integer>\n        if (i + 1 === this.tokenEnd) {\n            this.next();\n            b = consumeB.call(this);\n        } else {\n            expectCharCode.call(this, i - this.tokenStart + 1, HYPHENMINUS$2);\n\n            // <ndash-dimension> <signless-integer>\n            if (i + 2 === this.tokenEnd) {\n                this.next();\n                this.skipSC();\n                checkTokenIsInteger.call(this, DISALLOW_SIGN);\n                b = '-' + this.consume(Number$2);\n            }\n            // <ndashdigit-dimension>\n            else {\n                checkInteger.call(this, i - this.tokenStart + 2, DISALLOW_SIGN);\n                this.next();\n                b = this.substrToCursor(i + 1);\n            }\n        }\n    } else {\n        this.error();\n    }\n\n    if (a !== null && a.charCodeAt(0) === PLUSSIGN$5) {\n        a = a.substr(1);\n    }\n\n    if (b !== null && b.charCodeAt(0) === PLUSSIGN$5) {\n        b = b.substr(1);\n    }\n\n    return {\n        type: 'AnPlusB',\n        loc: this.getLocation(start, this.tokenStart),\n        a,\n        b\n    };\n}\n\nfunction generate$N(node) {\n    if (node.a) {\n        const a =\n            node.a === '+1' && 'n' ||\n            node.a ===  '1' && 'n' ||\n            node.a === '-1' && '-n' ||\n            node.a + 'n';\n\n        if (node.b) {\n            const b = node.b[0] === '-' || node.b[0] === '+'\n                ? node.b\n                : '+' + node.b;\n            this.tokenize(a + b);\n        } else {\n            this.tokenize(a);\n        }\n    } else {\n        this.tokenize(node.b);\n    }\n}\n\nvar AnPlusB = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$M,\n    structure: structure$M,\n    parse: parse$N,\n    generate: generate$N\n});\n\nfunction consumeRaw$4() {\n    return this.Raw(this.consumeUntilLeftCurlyBracketOrSemicolon, true);\n}\n\nfunction isDeclarationBlockAtrule() {\n    for (let offset = 1, type; type = this.lookupType(offset); offset++) {\n        if (type === RightCurlyBracket) {\n            return true;\n        }\n\n        if (type === LeftCurlyBracket ||\n            type === AtKeyword) {\n            return false;\n        }\n    }\n\n    return false;\n}\n\n\nconst name$L = 'Atrule';\nconst walkContext$9 = 'atrule';\nconst structure$L = {\n    name: String,\n    prelude: ['AtrulePrelude', 'Raw', null],\n    block: ['Block', null]\n};\n\nfunction parse$M(isDeclaration = false) {\n    const start = this.tokenStart;\n    let name;\n    let nameLowerCase;\n    let prelude = null;\n    let block = null;\n\n    this.eat(AtKeyword);\n\n    name = this.substrToCursor(start + 1);\n    nameLowerCase = name.toLowerCase();\n    this.skipSC();\n\n    // parse prelude\n    if (this.eof === false &&\n        this.tokenType !== LeftCurlyBracket &&\n        this.tokenType !== Semicolon) {\n        if (this.parseAtrulePrelude) {\n            prelude = this.parseWithFallback(this.AtrulePrelude.bind(this, name, isDeclaration), consumeRaw$4);\n        } else {\n            prelude = consumeRaw$4.call(this, this.tokenIndex);\n        }\n\n        this.skipSC();\n    }\n\n    switch (this.tokenType) {\n        case Semicolon:\n            this.next();\n            break;\n\n        case LeftCurlyBracket:\n            if (hasOwnProperty.call(this.atrule, nameLowerCase) &&\n                typeof this.atrule[nameLowerCase].block === 'function') {\n                block = this.atrule[nameLowerCase].block.call(this, isDeclaration);\n            } else {\n                // TODO: should consume block content as Raw?\n                block = this.Block(isDeclarationBlockAtrule.call(this));\n            }\n\n            break;\n    }\n\n    return {\n        type: 'Atrule',\n        loc: this.getLocation(start, this.tokenStart),\n        name,\n        prelude,\n        block\n    };\n}\n\nfunction generate$M(node) {\n    this.token(AtKeyword, '@' + node.name);\n\n    if (node.prelude !== null) {\n        this.node(node.prelude);\n    }\n\n    if (node.block) {\n        this.node(node.block);\n    } else {\n        this.token(Semicolon, ';');\n    }\n}\n\nvar Atrule = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$L,\n    walkContext: walkContext$9,\n    structure: structure$L,\n    parse: parse$M,\n    generate: generate$M\n});\n\nconst name$K = 'AtrulePrelude';\nconst walkContext$8 = 'atrulePrelude';\nconst structure$K = {\n    children: [[]]\n};\n\nfunction parse$L(name) {\n    let children = null;\n\n    if (name !== null) {\n        name = name.toLowerCase();\n    }\n\n    this.skipSC();\n\n    if (hasOwnProperty.call(this.atrule, name) &&\n        typeof this.atrule[name].prelude === 'function') {\n        // custom consumer\n        children = this.atrule[name].prelude.call(this);\n    } else {\n        // default consumer\n        children = this.readSequence(this.scope.AtrulePrelude);\n    }\n\n    this.skipSC();\n\n    if (this.eof !== true &&\n        this.tokenType !== LeftCurlyBracket &&\n        this.tokenType !== Semicolon) {\n        this.error('Semicolon or block is expected');\n    }\n\n    return {\n        type: 'AtrulePrelude',\n        loc: this.getLocationFromList(children),\n        children\n    };\n}\n\nfunction generate$L(node) {\n    this.children(node);\n}\n\nvar AtrulePrelude = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$K,\n    walkContext: walkContext$8,\n    structure: structure$K,\n    parse: parse$L,\n    generate: generate$L\n});\n\nconst DOLLARSIGN$1 = 0x0024;       // U+0024 DOLLAR SIGN ($)\nconst ASTERISK$5 = 0x002A;         // U+002A ASTERISK (*)\nconst EQUALSSIGN$1 = 0x003D;       // U+003D EQUALS SIGN (=)\nconst CIRCUMFLEXACCENT = 0x005E; // U+005E (^)\nconst VERTICALLINE$2 = 0x007C;     // U+007C VERTICAL LINE (|)\nconst TILDE$2 = 0x007E;            // U+007E TILDE (~)\n\nfunction getAttributeName() {\n    if (this.eof) {\n        this.error('Unexpected end of input');\n    }\n\n    const start = this.tokenStart;\n    let expectIdent = false;\n\n    if (this.isDelim(ASTERISK$5)) {\n        expectIdent = true;\n        this.next();\n    } else if (!this.isDelim(VERTICALLINE$2)) {\n        this.eat(Ident);\n    }\n\n    if (this.isDelim(VERTICALLINE$2)) {\n        if (this.charCodeAt(this.tokenStart + 1) !== EQUALSSIGN$1) {\n            this.next();\n            this.eat(Ident);\n        } else if (expectIdent) {\n            this.error('Identifier is expected', this.tokenEnd);\n        }\n    } else if (expectIdent) {\n        this.error('Vertical line is expected');\n    }\n\n    return {\n        type: 'Identifier',\n        loc: this.getLocation(start, this.tokenStart),\n        name: this.substrToCursor(start)\n    };\n}\n\nfunction getOperator() {\n    const start = this.tokenStart;\n    const code = this.charCodeAt(start);\n\n    if (code !== EQUALSSIGN$1 &&        // =\n        code !== TILDE$2 &&             // ~=\n        code !== CIRCUMFLEXACCENT &&  // ^=\n        code !== DOLLARSIGN$1 &&        // $=\n        code !== ASTERISK$5 &&          // *=\n        code !== VERTICALLINE$2         // |=\n    ) {\n        this.error('Attribute selector (=, ~=, ^=, $=, *=, |=) is expected');\n    }\n\n    this.next();\n\n    if (code !== EQUALSSIGN$1) {\n        if (!this.isDelim(EQUALSSIGN$1)) {\n            this.error('Equal sign is expected');\n        }\n\n        this.next();\n    }\n\n    return this.substrToCursor(start);\n}\n\n// '[' <wq-name> ']'\n// '[' <wq-name> <attr-matcher> [ <string-token> | <ident-token> ] <attr-modifier>? ']'\nconst name$J = 'AttributeSelector';\nconst structure$J = {\n    name: 'Identifier',\n    matcher: [String, null],\n    value: ['String', 'Identifier', null],\n    flags: [String, null]\n};\n\nfunction parse$K() {\n    const start = this.tokenStart;\n    let name;\n    let matcher = null;\n    let value = null;\n    let flags = null;\n\n    this.eat(LeftSquareBracket);\n    this.skipSC();\n\n    name = getAttributeName.call(this);\n    this.skipSC();\n\n    if (this.tokenType !== RightSquareBracket) {\n        // avoid case `[name i]`\n        if (this.tokenType !== Ident) {\n            matcher = getOperator.call(this);\n\n            this.skipSC();\n\n            value = this.tokenType === String$2\n                ? this.String()\n                : this.Identifier();\n\n            this.skipSC();\n        }\n\n        // attribute flags\n        if (this.tokenType === Ident) {\n            flags = this.consume(Ident);\n\n            this.skipSC();\n        }\n    }\n\n    this.eat(RightSquareBracket);\n\n    return {\n        type: 'AttributeSelector',\n        loc: this.getLocation(start, this.tokenStart),\n        name,\n        matcher,\n        value,\n        flags\n    };\n}\n\nfunction generate$K(node) {\n    this.token(Delim, '[');\n    this.node(node.name);\n\n    if (node.matcher !== null) {\n        this.tokenize(node.matcher);\n        this.node(node.value);\n    }\n\n    if (node.flags !== null) {\n        this.token(Ident, node.flags);\n    }\n\n    this.token(Delim, ']');\n}\n\nvar AttributeSelector = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$J,\n    structure: structure$J,\n    parse: parse$K,\n    generate: generate$K\n});\n\nconst AMPERSAND$4 = 0x0026;       // U+0026 AMPERSAND (&)\n\nfunction consumeRaw$3() {\n    return this.Raw(null, true);\n}\nfunction consumeRule() {\n    return this.parseWithFallback(this.Rule, consumeRaw$3);\n}\nfunction consumeRawDeclaration() {\n    return this.Raw(this.consumeUntilSemicolonIncluded, true);\n}\nfunction consumeDeclaration() {\n    if (this.tokenType === Semicolon) {\n        return consumeRawDeclaration.call(this, this.tokenIndex);\n    }\n\n    const node = this.parseWithFallback(this.Declaration, consumeRawDeclaration);\n\n    if (this.tokenType === Semicolon) {\n        this.next();\n    }\n\n    return node;\n}\n\nconst name$I = 'Block';\nconst walkContext$7 = 'block';\nconst structure$I = {\n    children: [[\n        'Atrule',\n        'Rule',\n        'Declaration'\n    ]]\n};\n\nfunction parse$J(isStyleBlock) {\n    const consumer = isStyleBlock ? consumeDeclaration : consumeRule;\n    const start = this.tokenStart;\n    let children = this.createList();\n\n    this.eat(LeftCurlyBracket);\n\n    scan:\n    while (!this.eof) {\n        switch (this.tokenType) {\n            case RightCurlyBracket:\n                break scan;\n\n            case WhiteSpace$1:\n            case Comment$1:\n                this.next();\n                break;\n\n            case AtKeyword:\n                children.push(this.parseWithFallback(this.Atrule.bind(this, isStyleBlock), consumeRaw$3));\n                break;\n\n            default:\n                if (isStyleBlock && this.isDelim(AMPERSAND$4))  {\n                    children.push(consumeRule.call(this));\n                } else {\n                    children.push(consumer.call(this));\n                }\n        }\n    }\n\n    if (!this.eof) {\n        this.eat(RightCurlyBracket);\n    }\n\n    return {\n        type: 'Block',\n        loc: this.getLocation(start, this.tokenStart),\n        children\n    };\n}\n\nfunction generate$J(node) {\n    this.token(LeftCurlyBracket, '{');\n    this.children(node, prev => {\n        if (prev.type === 'Declaration') {\n            this.token(Semicolon, ';');\n        }\n    });\n    this.token(RightCurlyBracket, '}');\n}\n\nvar Block = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$I,\n    walkContext: walkContext$7,\n    structure: structure$I,\n    parse: parse$J,\n    generate: generate$J\n});\n\nconst name$H = 'Brackets';\nconst structure$H = {\n    children: [[]]\n};\n\nfunction parse$I(readSequence, recognizer) {\n    const start = this.tokenStart;\n    let children = null;\n\n    this.eat(LeftSquareBracket);\n\n    children = readSequence.call(this, recognizer);\n\n    if (!this.eof) {\n        this.eat(RightSquareBracket);\n    }\n\n    return {\n        type: 'Brackets',\n        loc: this.getLocation(start, this.tokenStart),\n        children\n    };\n}\n\nfunction generate$I(node) {\n    this.token(Delim, '[');\n    this.children(node);\n    this.token(Delim, ']');\n}\n\nvar Brackets = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$H,\n    structure: structure$H,\n    parse: parse$I,\n    generate: generate$I\n});\n\nconst name$G = 'CDC';\nconst structure$G = [];\n\nfunction parse$H() {\n    const start = this.tokenStart;\n\n    this.eat(CDC$1); // -->\n\n    return {\n        type: 'CDC',\n        loc: this.getLocation(start, this.tokenStart)\n    };\n}\n\nfunction generate$H() {\n    this.token(CDC$1, '-->');\n}\n\nvar CDC = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$G,\n    structure: structure$G,\n    parse: parse$H,\n    generate: generate$H\n});\n\nconst name$F = 'CDO';\nconst structure$F = [];\n\nfunction parse$G() {\n    const start = this.tokenStart;\n\n    this.eat(CDO$1); // <!--\n\n    return {\n        type: 'CDO',\n        loc: this.getLocation(start, this.tokenStart)\n    };\n}\n\nfunction generate$G() {\n    this.token(CDO$1, '<!--');\n}\n\nvar CDO = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$F,\n    structure: structure$F,\n    parse: parse$G,\n    generate: generate$G\n});\n\nconst FULLSTOP$2 = 0x002E; // U+002E FULL STOP (.)\n\n// '.' ident\nconst name$E = 'ClassSelector';\nconst structure$E = {\n    name: String\n};\n\nfunction parse$F() {\n    this.eatDelim(FULLSTOP$2);\n\n    return {\n        type: 'ClassSelector',\n        loc: this.getLocation(this.tokenStart - 1, this.tokenEnd),\n        name: this.consume(Ident)\n    };\n}\n\nfunction generate$F(node) {\n    this.token(Delim, '.');\n    this.token(Ident, node.name);\n}\n\nvar ClassSelector = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$E,\n    structure: structure$E,\n    parse: parse$F,\n    generate: generate$F\n});\n\nconst PLUSSIGN$4 = 0x002B;        // U+002B PLUS SIGN (+)\nconst SOLIDUS$7 = 0x002F;         // U+002F SOLIDUS (/)\nconst GREATERTHANSIGN$2 = 0x003E; // U+003E GREATER-THAN SIGN (>)\nconst TILDE$1 = 0x007E;           // U+007E TILDE (~)\n\nconst name$D = 'Combinator';\nconst structure$D = {\n    name: String\n};\n\n// + | > | ~ | /deep/\nfunction parse$E() {\n    const start = this.tokenStart;\n    let name;\n\n    switch (this.tokenType) {\n        case WhiteSpace$1:\n            name = ' ';\n            break;\n\n        case Delim:\n            switch (this.charCodeAt(this.tokenStart)) {\n                case GREATERTHANSIGN$2:\n                case PLUSSIGN$4:\n                case TILDE$1:\n                    this.next();\n                    break;\n\n                case SOLIDUS$7:\n                    this.next();\n                    this.eatIdent('deep');\n                    this.eatDelim(SOLIDUS$7);\n                    break;\n\n                default:\n                    this.error('Combinator is expected');\n            }\n\n            name = this.substrToCursor(start);\n            break;\n    }\n\n    return {\n        type: 'Combinator',\n        loc: this.getLocation(start, this.tokenStart),\n        name\n    };\n}\n\nfunction generate$E(node) {\n    this.tokenize(node.name);\n}\n\nvar Combinator = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$D,\n    structure: structure$D,\n    parse: parse$E,\n    generate: generate$E\n});\n\nconst ASTERISK$4 = 0x002A;        // U+002A ASTERISK (*)\nconst SOLIDUS$6 = 0x002F;         // U+002F SOLIDUS (/)\n\n\nconst name$C = 'Comment';\nconst structure$C = {\n    value: String\n};\n\nfunction parse$D() {\n    const start = this.tokenStart;\n    let end = this.tokenEnd;\n\n    this.eat(Comment$1);\n\n    if ((end - start + 2) >= 2 &&\n        this.charCodeAt(end - 2) === ASTERISK$4 &&\n        this.charCodeAt(end - 1) === SOLIDUS$6) {\n        end -= 2;\n    }\n\n    return {\n        type: 'Comment',\n        loc: this.getLocation(start, this.tokenStart),\n        value: this.substring(start + 2, end)\n    };\n}\n\nfunction generate$D(node) {\n    this.token(Comment$1, '/*' + node.value + '*/');\n}\n\nvar Comment = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$C,\n    structure: structure$C,\n    parse: parse$D,\n    generate: generate$D\n});\n\nconst likelyFeatureToken = new Set([Colon, RightParenthesis, EOF$1]);\n\nconst name$B = 'Condition';\nconst structure$B = {\n    kind: String,\n    children: [[\n        'Identifier',\n        'Feature',\n        'FeatureFunction',\n        'FeatureRange',\n        'SupportsDeclaration'\n    ]]\n};\n\nfunction featureOrRange(kind) {\n    if (this.lookupTypeNonSC(1) === Ident &&\n        likelyFeatureToken.has(this.lookupTypeNonSC(2))) {\n        return this.Feature(kind);\n    }\n\n    return this.FeatureRange(kind);\n}\n\nconst parentheses = {\n    media: featureOrRange,\n    container: featureOrRange,\n    supports() {\n        return this.SupportsDeclaration();\n    }\n};\n\nfunction parse$C(kind = 'media') {\n    const children = this.createList();\n\n    scan: while (!this.eof) {\n        switch (this.tokenType) {\n            case Comment$1:\n            case WhiteSpace$1:\n                this.next();\n                continue;\n\n            case Ident:\n                children.push(this.Identifier());\n                break;\n\n            case LeftParenthesis: {\n                let term = this.parseWithFallback(\n                    () => parentheses[kind].call(this, kind),\n                    () => null\n                );\n\n                if (!term) {\n                    term = this.parseWithFallback(\n                        () => {\n                            this.eat(LeftParenthesis);\n                            const res = this.Condition(kind);\n                            this.eat(RightParenthesis);\n                            return res;\n                        },\n                        () => {\n                            return this.GeneralEnclosed(kind);\n                        }\n                    );\n                }\n\n                children.push(term);\n                break;\n            }\n\n            case Function$1: {\n                let term = this.parseWithFallback(\n                    () => this.FeatureFunction(kind),\n                    () => null\n                );\n\n                if (!term) {\n                    term = this.GeneralEnclosed(kind);\n                }\n\n                children.push(term);\n                break;\n            }\n\n            default:\n                break scan;\n        }\n    }\n\n    if (children.isEmpty) {\n        this.error('Condition is expected');\n    }\n\n    return {\n        type: 'Condition',\n        loc: this.getLocationFromList(children),\n        kind,\n        children\n    };\n}\n\nfunction generate$C(node) {\n    node.children.forEach(child => {\n        if (child.type === 'Condition') {\n            this.token(LeftParenthesis, '(');\n            this.node(child);\n            this.token(RightParenthesis, ')');\n        } else {\n            this.node(child);\n        }\n    });\n}\n\nvar Condition = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$B,\n    structure: structure$B,\n    parse: parse$C,\n    generate: generate$C\n});\n\nconst EXCLAMATIONMARK$1 = 0x0021; // U+0021 EXCLAMATION MARK (!)\nconst NUMBERSIGN$2 = 0x0023;      // U+0023 NUMBER SIGN (#)\nconst DOLLARSIGN = 0x0024;      // U+0024 DOLLAR SIGN ($)\nconst AMPERSAND$3 = 0x0026;       // U+0026 AMPERSAND (&)\nconst ASTERISK$3 = 0x002A;        // U+002A ASTERISK (*)\nconst PLUSSIGN$3 = 0x002B;        // U+002B PLUS SIGN (+)\nconst SOLIDUS$5 = 0x002F;         // U+002F SOLIDUS (/)\n\nfunction consumeValueRaw() {\n    return this.Raw(this.consumeUntilExclamationMarkOrSemicolon, true);\n}\n\nfunction consumeCustomPropertyRaw() {\n    return this.Raw(this.consumeUntilExclamationMarkOrSemicolon, false);\n}\n\nfunction consumeValue() {\n    const startValueToken = this.tokenIndex;\n    const value = this.Value();\n\n    if (value.type !== 'Raw' &&\n        this.eof === false &&\n        this.tokenType !== Semicolon &&\n        this.isDelim(EXCLAMATIONMARK$1) === false &&\n        this.isBalanceEdge(startValueToken) === false) {\n        this.error();\n    }\n\n    return value;\n}\n\nconst name$A = 'Declaration';\nconst walkContext$6 = 'declaration';\nconst structure$A = {\n    important: [Boolean, String],\n    property: String,\n    value: ['Value', 'Raw']\n};\n\nfunction parse$B() {\n    const start = this.tokenStart;\n    const startToken = this.tokenIndex;\n    const property = readProperty.call(this);\n    const customProperty = isCustomProperty(property);\n    const parseValue = customProperty ? this.parseCustomProperty : this.parseValue;\n    const consumeRaw = customProperty ? consumeCustomPropertyRaw : consumeValueRaw;\n    let important = false;\n    let value;\n\n    this.skipSC();\n    this.eat(Colon);\n\n    const valueStart = this.tokenIndex;\n\n    if (!customProperty) {\n        this.skipSC();\n    }\n\n    if (parseValue) {\n        value = this.parseWithFallback(consumeValue, consumeRaw);\n    } else {\n        value = consumeRaw.call(this, this.tokenIndex);\n    }\n\n    if (customProperty && value.type === 'Value' && value.children.isEmpty) {\n        for (let offset = valueStart - this.tokenIndex; offset <= 0; offset++) {\n            if (this.lookupType(offset) === WhiteSpace$1) {\n                value.children.appendData({\n                    type: 'WhiteSpace',\n                    loc: null,\n                    value: ' '\n                });\n                break;\n            }\n        }\n    }\n\n    if (this.isDelim(EXCLAMATIONMARK$1)) {\n        important = getImportant.call(this);\n        this.skipSC();\n    }\n\n    // Do not include semicolon to range per spec\n    // https://drafts.csswg.org/css-syntax/#declaration-diagram\n\n    if (this.eof === false &&\n        this.tokenType !== Semicolon &&\n        this.isBalanceEdge(startToken) === false) {\n        this.error();\n    }\n\n    return {\n        type: 'Declaration',\n        loc: this.getLocation(start, this.tokenStart),\n        important,\n        property,\n        value\n    };\n}\n\nfunction generate$B(node) {\n    this.token(Ident, node.property);\n    this.token(Colon, ':');\n    this.node(node.value);\n\n    if (node.important) {\n        this.token(Delim, '!');\n        this.token(Ident, node.important === true ? 'important' : node.important);\n    }\n}\n\nfunction readProperty() {\n    const start = this.tokenStart;\n\n    // hacks\n    if (this.tokenType === Delim) {\n        switch (this.charCodeAt(this.tokenStart)) {\n            case ASTERISK$3:\n            case DOLLARSIGN:\n            case PLUSSIGN$3:\n            case NUMBERSIGN$2:\n            case AMPERSAND$3:\n                this.next();\n                break;\n\n            // TODO: not sure we should support this hack\n            case SOLIDUS$5:\n                this.next();\n                if (this.isDelim(SOLIDUS$5)) {\n                    this.next();\n                }\n                break;\n        }\n    }\n\n    if (this.tokenType === Hash$1) {\n        this.eat(Hash$1);\n    } else {\n        this.eat(Ident);\n    }\n\n    return this.substrToCursor(start);\n}\n\n// ! ws* important\nfunction getImportant() {\n    this.eat(Delim);\n    this.skipSC();\n\n    const important = this.consume(Ident);\n\n    // store original value in case it differ from `important`\n    // for better original source restoring and hacks like `!ie` support\n    return important === 'important' ? true : important;\n}\n\nvar Declaration = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$A,\n    walkContext: walkContext$6,\n    structure: structure$A,\n    parse: parse$B,\n    generate: generate$B\n});\n\nconst AMPERSAND$2 = 0x0026;       // U+0026 AMPERSAND (&)\n\nfunction consumeRaw$2() {\n    return this.Raw(this.consumeUntilSemicolonIncluded, true);\n}\n\nconst name$z = 'DeclarationList';\nconst structure$z = {\n    children: [[\n        'Declaration',\n        'Atrule',\n        'Rule'\n    ]]\n};\n\nfunction parse$A() {\n    const children = this.createList();\n\n    while (!this.eof) {\n        switch (this.tokenType) {\n            case WhiteSpace$1:\n            case Comment$1:\n            case Semicolon:\n                this.next();\n                break;\n\n            case AtKeyword:\n                children.push(this.parseWithFallback(this.Atrule.bind(this, true), consumeRaw$2));\n                break;\n\n            default:\n                if (this.isDelim(AMPERSAND$2))  {\n                    children.push(this.parseWithFallback(this.Rule, consumeRaw$2));\n                } else {\n                    children.push(this.parseWithFallback(this.Declaration, consumeRaw$2));\n                }\n        }\n    }\n\n    return {\n        type: 'DeclarationList',\n        loc: this.getLocationFromList(children),\n        children\n    };\n}\n\nfunction generate$A(node) {\n    this.children(node, prev => {\n        if (prev.type === 'Declaration') {\n            this.token(Semicolon, ';');\n        }\n    });\n}\n\nvar DeclarationList = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$z,\n    structure: structure$z,\n    parse: parse$A,\n    generate: generate$A\n});\n\nconst name$y = 'Dimension';\nconst structure$y = {\n    value: String,\n    unit: String\n};\n\nfunction parse$z() {\n    const start = this.tokenStart;\n    const value = this.consumeNumber(Dimension$1);\n\n    return {\n        type: 'Dimension',\n        loc: this.getLocation(start, this.tokenStart),\n        value,\n        unit: this.substring(start + value.length, this.tokenStart)\n    };\n}\n\nfunction generate$z(node) {\n    this.token(Dimension$1, node.value + node.unit);\n}\n\nvar Dimension = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$y,\n    structure: structure$y,\n    parse: parse$z,\n    generate: generate$z\n});\n\nconst SOLIDUS$4 = 0x002F;  // U+002F SOLIDUS (/)\n\nconst name$x = 'Feature';\nconst structure$x = {\n    kind: String,\n    name: String,\n    value: ['Identifier', 'Number', 'Dimension', 'Ratio', 'Function', null]\n};\n\nfunction parse$y(kind) {\n    const start = this.tokenStart;\n    let name;\n    let value = null;\n\n    this.eat(LeftParenthesis);\n    this.skipSC();\n\n    name = this.consume(Ident);\n    this.skipSC();\n\n    if (this.tokenType !== RightParenthesis) {\n        this.eat(Colon);\n        this.skipSC();\n\n        switch (this.tokenType) {\n            case Number$2:\n                if (this.lookupNonWSType(1) === Delim) {\n                    value = this.Ratio();\n                } else {\n                    value = this.Number();\n                }\n\n                break;\n\n            case Dimension$1:\n                value = this.Dimension();\n                break;\n\n            case Ident:\n                value = this.Identifier();\n                break;\n\n            case Function$1:\n                value = this.parseWithFallback(\n                    () => {\n                        const res = this.Function(this.readSequence, this.scope.Value);\n\n                        this.skipSC();\n\n                        if (this.isDelim(SOLIDUS$4)) {\n                            this.error();\n                        }\n\n                        return res;\n                    },\n                    () => {\n                        return this.Ratio();\n                    }\n                );\n                break;\n\n            default:\n                this.error('Number, dimension, ratio or identifier is expected');\n        }\n\n        this.skipSC();\n    }\n\n    if (!this.eof) {\n        this.eat(RightParenthesis);\n    }\n\n    return {\n        type: 'Feature',\n        loc: this.getLocation(start, this.tokenStart),\n        kind,\n        name,\n        value\n    };\n}\n\nfunction generate$y(node) {\n    this.token(LeftParenthesis, '(');\n    this.token(Ident, node.name);\n\n    if (node.value !== null) {\n        this.token(Colon, ':');\n        this.node(node.value);\n    }\n\n    this.token(RightParenthesis, ')');\n}\n\nvar Feature = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$x,\n    structure: structure$x,\n    parse: parse$y,\n    generate: generate$y\n});\n\nconst name$w = 'FeatureFunction';\nconst structure$w = {\n    kind: String,\n    feature: String,\n    value: ['Declaration', 'Selector']\n};\n\nfunction getFeatureParser(kind, name) {\n    const featuresOfKind = this.features[kind] || {};\n    const parser = featuresOfKind[name];\n\n    if (typeof parser !== 'function') {\n        this.error(`Unknown feature ${name}()`);\n    }\n\n    return parser;\n}\n\nfunction parse$x(kind = 'unknown') {\n    const start = this.tokenStart;\n    const functionName = this.consumeFunctionName();\n    const valueParser = getFeatureParser.call(this, kind, functionName.toLowerCase());\n\n    this.skipSC();\n\n    const value = this.parseWithFallback(\n        () => {\n            const startValueToken = this.tokenIndex;\n            const value = valueParser.call(this);\n\n            if (this.eof === false &&\n                this.isBalanceEdge(startValueToken) === false) {\n                this.error();\n            }\n\n            return value;\n        },\n        () => this.Raw(null, false)\n    );\n\n    if (!this.eof) {\n        this.eat(RightParenthesis);\n    }\n\n    return {\n        type: 'FeatureFunction',\n        loc: this.getLocation(start, this.tokenStart),\n        kind,\n        feature: functionName,\n        value\n    };\n}\n\nfunction generate$x(node) {\n    this.token(Function$1, node.feature + '(');\n    this.node(node.value);\n    this.token(RightParenthesis, ')');\n}\n\nvar FeatureFunction = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$w,\n    structure: structure$w,\n    parse: parse$x,\n    generate: generate$x\n});\n\nconst SOLIDUS$3 = 0x002F;         // U+002F SOLIDUS (/)\nconst LESSTHANSIGN = 0x003C;    // U+003C LESS-THAN SIGN (<)\nconst EQUALSSIGN = 0x003D;      // U+003D EQUALS SIGN (=)\nconst GREATERTHANSIGN$1 = 0x003E; // U+003E GREATER-THAN SIGN (>)\n\nconst name$v = 'FeatureRange';\nconst structure$v = {\n    kind: String,\n    left: ['Identifier', 'Number', 'Dimension', 'Ratio', 'Function'],\n    leftComparison: String,\n    middle: ['Identifier', 'Number', 'Dimension', 'Ratio', 'Function'],\n    rightComparison: [String, null],\n    right: ['Identifier', 'Number', 'Dimension', 'Ratio', 'Function', null]\n};\n\nfunction readTerm() {\n    this.skipSC();\n\n    switch (this.tokenType) {\n        case Number$2:\n            if (this.isDelim(SOLIDUS$3, this.lookupOffsetNonSC(1))) {\n                return this.Ratio();\n            } else {\n                return this.Number();\n            }\n\n        case Dimension$1:\n            return this.Dimension();\n\n        case Ident:\n            return this.Identifier();\n\n        case Function$1:\n            return this.parseWithFallback(\n                () => {\n                    const res = this.Function(this.readSequence, this.scope.Value);\n\n                    this.skipSC();\n\n                    if (this.isDelim(SOLIDUS$3)) {\n                        this.error();\n                    }\n\n                    return res;\n                },\n                () => {\n                    return this.Ratio();\n                }\n            );\n\n        default:\n            this.error('Number, dimension, ratio or identifier is expected');\n    }\n}\n\nfunction readComparison(expectColon) {\n    this.skipSC();\n\n    if (this.isDelim(LESSTHANSIGN) ||\n        this.isDelim(GREATERTHANSIGN$1)) {\n        const value = this.source[this.tokenStart];\n\n        this.next();\n\n        if (this.isDelim(EQUALSSIGN)) {\n            this.next();\n            return value + '=';\n        }\n\n        return value;\n    }\n\n    if (this.isDelim(EQUALSSIGN)) {\n        return '=';\n    }\n\n    this.error(`Expected ${expectColon ? '\":\", ' : ''}\"<\", \">\", \"=\" or \")\"`);\n}\n\nfunction parse$w(kind = 'unknown') {\n    const start = this.tokenStart;\n\n    this.skipSC();\n    this.eat(LeftParenthesis);\n\n    const left = readTerm.call(this);\n    const leftComparison = readComparison.call(this, left.type === 'Identifier');\n    const middle = readTerm.call(this);\n    let rightComparison = null;\n    let right = null;\n\n    if (this.lookupNonWSType(0) !== RightParenthesis) {\n        rightComparison = readComparison.call(this);\n        right = readTerm.call(this);\n    }\n\n    this.skipSC();\n    this.eat(RightParenthesis);\n\n    return {\n        type: 'FeatureRange',\n        loc: this.getLocation(start, this.tokenStart),\n        kind,\n        left,\n        leftComparison,\n        middle,\n        rightComparison,\n        right\n    };\n}\n\nfunction generate$w(node) {\n    this.token(LeftParenthesis, '(');\n    this.node(node.left);\n    this.tokenize(node.leftComparison);\n    this.node(node.middle);\n\n    if (node.right) {\n        this.tokenize(node.rightComparison);\n        this.node(node.right);\n    }\n\n    this.token(RightParenthesis, ')');\n}\n\nvar FeatureRange = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$v,\n    structure: structure$v,\n    parse: parse$w,\n    generate: generate$w\n});\n\nconst name$u = 'Function';\nconst walkContext$5 = 'function';\nconst structure$u = {\n    name: String,\n    children: [[]]\n};\n\n// <function-token> <sequence> )\nfunction parse$v(readSequence, recognizer) {\n    const start = this.tokenStart;\n    const name = this.consumeFunctionName();\n    const nameLowerCase = name.toLowerCase();\n    let children;\n\n    children = recognizer.hasOwnProperty(nameLowerCase)\n        ? recognizer[nameLowerCase].call(this, recognizer)\n        : readSequence.call(this, recognizer);\n\n    if (!this.eof) {\n        this.eat(RightParenthesis);\n    }\n\n    return {\n        type: 'Function',\n        loc: this.getLocation(start, this.tokenStart),\n        name,\n        children\n    };\n}\n\nfunction generate$v(node) {\n    this.token(Function$1, node.name + '(');\n    this.children(node);\n    this.token(RightParenthesis, ')');\n}\n\nvar Function = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$u,\n    walkContext: walkContext$5,\n    structure: structure$u,\n    parse: parse$v,\n    generate: generate$v\n});\n\nconst name$t = 'GeneralEnclosed';\nconst structure$t = {\n    kind: String,\n    function: [String, null],\n    children: [[]]\n};\n\n// <function-token> <any-value> )\n// ( <any-value> )\nfunction parse$u(kind) {\n    const start = this.tokenStart;\n    let functionName = null;\n\n    if (this.tokenType === Function$1) {\n        functionName = this.consumeFunctionName();\n    } else {\n        this.eat(LeftParenthesis);\n    }\n\n    const children = this.parseWithFallback(\n        () => {\n            const startValueToken = this.tokenIndex;\n            const children = this.readSequence(this.scope.Value);\n\n            if (this.eof === false &&\n                this.isBalanceEdge(startValueToken) === false) {\n                this.error();\n            }\n\n            return children;\n        },\n        () => this.createSingleNodeList(\n            this.Raw(null, false)\n        )\n    );\n\n    if (!this.eof) {\n        this.eat(RightParenthesis);\n    }\n\n    return {\n        type: 'GeneralEnclosed',\n        loc: this.getLocation(start, this.tokenStart),\n        kind,\n        function: functionName,\n        children\n    };\n}\n\nfunction generate$u(node) {\n    if (node.function) {\n        this.token(Function$1, node.function + '(');\n    } else {\n        this.token(LeftParenthesis, '(');\n    }\n\n    this.children(node);\n    this.token(RightParenthesis, ')');\n}\n\nvar GeneralEnclosed = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$t,\n    structure: structure$t,\n    parse: parse$u,\n    generate: generate$u\n});\n\n// '#' ident\nconst xxx = 'XXX';\nconst name$s = 'Hash';\nconst structure$s = {\n    value: String\n};\nfunction parse$t() {\n    const start = this.tokenStart;\n\n    this.eat(Hash$1);\n\n    return {\n        type: 'Hash',\n        loc: this.getLocation(start, this.tokenStart),\n        value: this.substrToCursor(start + 1)\n    };\n}\nfunction generate$t(node) {\n    this.token(Hash$1, '#' + node.value);\n}\n\nvar Hash = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    xxx: xxx,\n    name: name$s,\n    structure: structure$s,\n    parse: parse$t,\n    generate: generate$t\n});\n\nconst name$r = 'Identifier';\nconst structure$r = {\n    name: String\n};\n\nfunction parse$s() {\n    return {\n        type: 'Identifier',\n        loc: this.getLocation(this.tokenStart, this.tokenEnd),\n        name: this.consume(Ident)\n    };\n}\n\nfunction generate$s(node) {\n    this.token(Ident, node.name);\n}\n\nvar Identifier = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$r,\n    structure: structure$r,\n    parse: parse$s,\n    generate: generate$s\n});\n\nconst name$q = 'IdSelector';\nconst structure$q = {\n    name: String\n};\n\nfunction parse$r() {\n    const start = this.tokenStart;\n\n    // TODO: check value is an ident\n    this.eat(Hash$1);\n\n    return {\n        type: 'IdSelector',\n        loc: this.getLocation(start, this.tokenStart),\n        name: this.substrToCursor(start + 1)\n    };\n}\n\nfunction generate$r(node) {\n    // Using Delim instead of Hash is a hack to avoid for a whitespace between ident and id-selector\n    // in safe mode (e.g. \"a#id\"), because IE11 doesn't allow a sequence <ident-token> <hash-token>\n    // without a whitespace in values (e.g. \"1px solid#000\")\n    this.token(Delim, '#' + node.name);\n}\n\nvar IdSelector = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$q,\n    structure: structure$q,\n    parse: parse$r,\n    generate: generate$r\n});\n\nconst FULLSTOP$1 = 0x002E; // U+002E FULL STOP (.)\n\nconst name$p = 'Layer';\nconst structure$p = {\n    name: String\n};\n\nfunction parse$q() {\n    let tokenStart = this.tokenStart;\n    let name = this.consume(Ident);\n\n    while (this.isDelim(FULLSTOP$1)) {\n        this.eat(Delim);\n        name += '.' + this.consume(Ident);\n    }\n\n    return {\n        type: 'Layer',\n        loc: this.getLocation(tokenStart, this.tokenStart),\n        name\n    };\n}\n\nfunction generate$q(node) {\n    this.tokenize(node.name);\n}\n\nvar Layer = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$p,\n    structure: structure$p,\n    parse: parse$q,\n    generate: generate$q\n});\n\nconst name$o = 'LayerList';\nconst structure$o = {\n    children: [[\n        'Layer'\n    ]]\n};\n\nfunction parse$p() {\n    const children = this.createList();\n\n    this.skipSC();\n\n    while (!this.eof) {\n        children.push(this.Layer());\n\n        if (this.lookupTypeNonSC(0) !== Comma) {\n            break;\n        }\n\n        this.skipSC();\n        this.next();\n        this.skipSC();\n    }\n\n    return {\n        type: 'LayerList',\n        loc: this.getLocationFromList(children),\n        children\n    };\n}\n\nfunction generate$p(node) {\n    this.children(node, () => this.token(Comma, ','));\n}\n\nvar LayerList = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$o,\n    structure: structure$o,\n    parse: parse$p,\n    generate: generate$p\n});\n\nconst name$n = 'MediaQuery';\nconst structure$n = {\n    modifier: [String, null],\n    mediaType: [String, null],\n    condition: ['Condition', null]\n};\n\nfunction parse$o() {\n    const start = this.tokenStart;\n    let modifier = null;\n    let mediaType = null;\n    let condition = null;\n\n    this.skipSC();\n\n    if (this.tokenType === Ident && this.lookupTypeNonSC(1) !== LeftParenthesis) {\n        // [ not | only ]? <media-type>\n        const ident = this.consume(Ident);\n        const identLowerCase = ident.toLowerCase();\n\n        if (identLowerCase === 'not' || identLowerCase === 'only') {\n            this.skipSC();\n            modifier = identLowerCase;\n            mediaType = this.consume(Ident);\n        } else {\n            mediaType = ident;\n        }\n\n        switch (this.lookupTypeNonSC(0)) {\n            case Ident: {\n                // and <media-condition-without-or>\n                this.skipSC();\n                this.eatIdent('and');\n                condition = this.Condition('media');\n                break;\n            }\n\n            case LeftCurlyBracket:\n            case Semicolon:\n            case Comma:\n            case EOF$1:\n                break;\n\n            default:\n                this.error('Identifier or parenthesis is expected');\n        }\n    } else {\n        switch (this.tokenType) {\n            case Ident:\n            case LeftParenthesis:\n            case Function$1: {\n                // <media-condition>\n                condition = this.Condition('media');\n                break;\n            }\n\n            case LeftCurlyBracket:\n            case Semicolon:\n            case EOF$1:\n                break;\n\n            default:\n                this.error('Identifier or parenthesis is expected');\n        }\n    }\n\n    return {\n        type: 'MediaQuery',\n        loc: this.getLocation(start, this.tokenStart),\n        modifier,\n        mediaType,\n        condition\n    };\n}\n\nfunction generate$o(node) {\n    if (node.mediaType) {\n        if (node.modifier) {\n            this.token(Ident, node.modifier);\n        }\n\n        this.token(Ident, node.mediaType);\n\n        if (node.condition) {\n            this.token(Ident, 'and');\n            this.node(node.condition);\n        }\n    } else if (node.condition) {\n        this.node(node.condition);\n    }\n}\n\nvar MediaQuery = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$n,\n    structure: structure$n,\n    parse: parse$o,\n    generate: generate$o\n});\n\nconst name$m = 'MediaQueryList';\nconst structure$m = {\n    children: [[\n        'MediaQuery'\n    ]]\n};\n\nfunction parse$n() {\n    const children = this.createList();\n\n    this.skipSC();\n\n    while (!this.eof) {\n        children.push(this.MediaQuery());\n\n        if (this.tokenType !== Comma) {\n            break;\n        }\n\n        this.next();\n    }\n\n    return {\n        type: 'MediaQueryList',\n        loc: this.getLocationFromList(children),\n        children\n    };\n}\n\nfunction generate$n(node) {\n    this.children(node, () => this.token(Comma, ','));\n}\n\nvar MediaQueryList = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$m,\n    structure: structure$m,\n    parse: parse$n,\n    generate: generate$n\n});\n\nconst AMPERSAND$1 = 0x0026;       // U+0026 AMPERSAND (&)\n\nconst name$l = 'NestingSelector';\nconst structure$l = {\n};\n\nfunction parse$m() {\n    const start = this.tokenStart;\n\n    this.eatDelim(AMPERSAND$1);\n\n    return {\n        type: 'NestingSelector',\n        loc: this.getLocation(start, this.tokenStart)\n    };\n}\n\nfunction generate$m() {\n    this.token(Delim, '&');\n}\n\nvar NestingSelector = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$l,\n    structure: structure$l,\n    parse: parse$m,\n    generate: generate$m\n});\n\nconst name$k = 'Nth';\nconst structure$k = {\n    nth: ['AnPlusB', 'Identifier'],\n    selector: ['SelectorList', null]\n};\n\nfunction parse$l() {\n    this.skipSC();\n\n    const start = this.tokenStart;\n    let end = start;\n    let selector = null;\n    let nth;\n\n    if (this.lookupValue(0, 'odd') || this.lookupValue(0, 'even')) {\n        nth = this.Identifier();\n    } else {\n        nth = this.AnPlusB();\n    }\n\n    end = this.tokenStart;\n    this.skipSC();\n\n    if (this.lookupValue(0, 'of')) {\n        this.next();\n\n        selector = this.SelectorList();\n        end = this.tokenStart;\n    }\n\n    return {\n        type: 'Nth',\n        loc: this.getLocation(start, end),\n        nth,\n        selector\n    };\n}\n\nfunction generate$l(node) {\n    this.node(node.nth);\n    if (node.selector !== null) {\n        this.token(Ident, 'of');\n        this.node(node.selector);\n    }\n}\n\nvar Nth = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$k,\n    structure: structure$k,\n    parse: parse$l,\n    generate: generate$l\n});\n\nconst name$j = 'Number';\nconst structure$j = {\n    value: String\n};\n\nfunction parse$k() {\n    return {\n        type: 'Number',\n        loc: this.getLocation(this.tokenStart, this.tokenEnd),\n        value: this.consume(Number$2)\n    };\n}\n\nfunction generate$k(node) {\n    this.token(Number$2, node.value);\n}\n\nvar Number$1 = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$j,\n    structure: structure$j,\n    parse: parse$k,\n    generate: generate$k\n});\n\n// '/' | '*' | ',' | ':' | '+' | '-'\nconst name$i = 'Operator';\nconst structure$i = {\n    value: String\n};\n\nfunction parse$j() {\n    const start = this.tokenStart;\n\n    this.next();\n\n    return {\n        type: 'Operator',\n        loc: this.getLocation(start, this.tokenStart),\n        value: this.substrToCursor(start)\n    };\n}\n\nfunction generate$j(node) {\n    this.tokenize(node.value);\n}\n\nvar Operator = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$i,\n    structure: structure$i,\n    parse: parse$j,\n    generate: generate$j\n});\n\nconst name$h = 'Parentheses';\nconst structure$h = {\n    children: [[]]\n};\n\nfunction parse$i(readSequence, recognizer) {\n    const start = this.tokenStart;\n    let children = null;\n\n    this.eat(LeftParenthesis);\n\n    children = readSequence.call(this, recognizer);\n\n    if (!this.eof) {\n        this.eat(RightParenthesis);\n    }\n\n    return {\n        type: 'Parentheses',\n        loc: this.getLocation(start, this.tokenStart),\n        children\n    };\n}\n\nfunction generate$i(node) {\n    this.token(LeftParenthesis, '(');\n    this.children(node);\n    this.token(RightParenthesis, ')');\n}\n\nvar Parentheses = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$h,\n    structure: structure$h,\n    parse: parse$i,\n    generate: generate$i\n});\n\nconst name$g = 'Percentage';\nconst structure$g = {\n    value: String\n};\n\nfunction parse$h() {\n    return {\n        type: 'Percentage',\n        loc: this.getLocation(this.tokenStart, this.tokenEnd),\n        value: this.consumeNumber(Percentage$1)\n    };\n}\n\nfunction generate$h(node) {\n    this.token(Percentage$1, node.value + '%');\n}\n\nvar Percentage = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$g,\n    structure: structure$g,\n    parse: parse$h,\n    generate: generate$h\n});\n\nconst name$f = 'PseudoClassSelector';\nconst walkContext$4 = 'function';\nconst structure$f = {\n    name: String,\n    children: [['Raw'], null]\n};\n\n// : [ <ident> | <function-token> <any-value>? ) ]\nfunction parse$g() {\n    const start = this.tokenStart;\n    let children = null;\n    let name;\n    let nameLowerCase;\n\n    this.eat(Colon);\n\n    if (this.tokenType === Function$1) {\n        name = this.consumeFunctionName();\n        nameLowerCase = name.toLowerCase();\n\n        if (this.lookupNonWSType(0) == RightParenthesis) {\n            children = this.createList();\n        } else if (hasOwnProperty.call(this.pseudo, nameLowerCase)) {\n            this.skipSC();\n            children = this.pseudo[nameLowerCase].call(this);\n            this.skipSC();\n        } else {\n            children = this.createList();\n            children.push(\n                this.Raw(null, false)\n            );\n        }\n\n        this.eat(RightParenthesis);\n    } else {\n        name = this.consume(Ident);\n    }\n\n    return {\n        type: 'PseudoClassSelector',\n        loc: this.getLocation(start, this.tokenStart),\n        name,\n        children\n    };\n}\n\nfunction generate$g(node) {\n    this.token(Colon, ':');\n\n    if (node.children === null) {\n        this.token(Ident, node.name);\n    } else {\n        this.token(Function$1, node.name + '(');\n        this.children(node);\n        this.token(RightParenthesis, ')');\n    }\n}\n\nvar PseudoClassSelector = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$f,\n    walkContext: walkContext$4,\n    structure: structure$f,\n    parse: parse$g,\n    generate: generate$g\n});\n\nconst name$e = 'PseudoElementSelector';\nconst walkContext$3 = 'function';\nconst structure$e = {\n    name: String,\n    children: [['Raw'], null]\n};\n\n// :: [ <ident> | <function-token> <any-value>? ) ]\nfunction parse$f() {\n    const start = this.tokenStart;\n    let children = null;\n    let name;\n    let nameLowerCase;\n\n    this.eat(Colon);\n    this.eat(Colon);\n\n    if (this.tokenType === Function$1) {\n        name = this.consumeFunctionName();\n        nameLowerCase = name.toLowerCase();\n\n        if (this.lookupNonWSType(0) == RightParenthesis) {\n            children = this.createList();\n        } else if (hasOwnProperty.call(this.pseudo, nameLowerCase)) {\n            this.skipSC();\n            children = this.pseudo[nameLowerCase].call(this);\n            this.skipSC();\n        } else {\n            children = this.createList();\n            children.push(\n                this.Raw(null, false)\n            );\n        }\n\n        this.eat(RightParenthesis);\n    } else {\n        name = this.consume(Ident);\n    }\n\n    return {\n        type: 'PseudoElementSelector',\n        loc: this.getLocation(start, this.tokenStart),\n        name,\n        children\n    };\n}\n\nfunction generate$f(node) {\n    this.token(Colon, ':');\n    this.token(Colon, ':');\n\n    if (node.children === null) {\n        this.token(Ident, node.name);\n    } else {\n        this.token(Function$1, node.name + '(');\n        this.children(node);\n        this.token(RightParenthesis, ')');\n    }\n}\n\nvar PseudoElementSelector = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$e,\n    walkContext: walkContext$3,\n    structure: structure$e,\n    parse: parse$f,\n    generate: generate$f\n});\n\nconst SOLIDUS$2 = 0x002F;  // U+002F SOLIDUS (/)\n\n// Media Queries Level 3 defines terms of <ratio> as a positive (not zero or negative)\n// integers (see https://drafts.csswg.org/mediaqueries-3/#values)\n// However, Media Queries Level 4 removes any definition of values\n// (see https://drafts.csswg.org/mediaqueries-4/#values) and refers to\n// CSS Values and Units for detail. In CSS Values and Units Level 4 a <ratio>\n// definition was added (see https://drafts.csswg.org/css-values-4/#ratios) which\n// defines ratio as \"<number [0,∞]> [ / <number [0,∞]> ]?\" and based on it\n// any constrains on terms were removed. Parser also doesn't test numbers\n// in any way to make possible for linting and fixing them by the tools using CSSTree.\n// An additional syntax examination may be applied by a lexer.\nfunction consumeTerm() {\n    this.skipSC();\n\n    switch (this.tokenType) {\n        case Number$2:\n            return this.Number();\n\n        case Function$1:\n            return this.Function(this.readSequence, this.scope.Value);\n\n        default:\n            this.error('Number of function is expected');\n    }\n}\n\nconst name$d = 'Ratio';\nconst structure$d = {\n    left: ['Number', 'Function'],\n    right: ['Number', 'Function', null]\n};\n\n// <number [0,∞]> [ / <number [0,∞]> ]?\nfunction parse$e() {\n    const start = this.tokenStart;\n    const left = consumeTerm.call(this);\n    let right = null;\n\n    this.skipSC();\n    if (this.isDelim(SOLIDUS$2)) {\n        this.eatDelim(SOLIDUS$2);\n        right = consumeTerm.call(this);\n    }\n\n    return {\n        type: 'Ratio',\n        loc: this.getLocation(start, this.tokenStart),\n        left,\n        right\n    };\n}\n\nfunction generate$e(node) {\n    this.node(node.left);\n    this.token(Delim, '/');\n    if (node.right) {\n        this.node(node.right);\n    } else {\n        this.node(Number$2, 1);\n    }\n}\n\nvar Ratio = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$d,\n    structure: structure$d,\n    parse: parse$e,\n    generate: generate$e\n});\n\nfunction getOffsetExcludeWS() {\n    if (this.tokenIndex > 0) {\n        if (this.lookupType(-1) === WhiteSpace$1) {\n            return this.tokenIndex > 1\n                ? this.getTokenStart(this.tokenIndex - 1)\n                : this.firstCharOffset;\n        }\n    }\n\n    return this.tokenStart;\n}\n\nconst name$c = 'Raw';\nconst structure$c = {\n    value: String\n};\n\nfunction parse$d(consumeUntil, excludeWhiteSpace) {\n    const startOffset = this.getTokenStart(this.tokenIndex);\n    let endOffset;\n\n    this.skipUntilBalanced(this.tokenIndex, consumeUntil || this.consumeUntilBalanceEnd);\n\n    if (excludeWhiteSpace && this.tokenStart > startOffset) {\n        endOffset = getOffsetExcludeWS.call(this);\n    } else {\n        endOffset = this.tokenStart;\n    }\n\n    return {\n        type: 'Raw',\n        loc: this.getLocation(startOffset, endOffset),\n        value: this.substring(startOffset, endOffset)\n    };\n}\n\nfunction generate$d(node) {\n    this.tokenize(node.value);\n}\n\nvar Raw = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$c,\n    structure: structure$c,\n    parse: parse$d,\n    generate: generate$d\n});\n\nfunction consumeRaw$1() {\n    return this.Raw(this.consumeUntilLeftCurlyBracket, true);\n}\n\nfunction consumePrelude() {\n    const prelude = this.SelectorList();\n\n    if (prelude.type !== 'Raw' &&\n        this.eof === false &&\n        this.tokenType !== LeftCurlyBracket) {\n        this.error();\n    }\n\n    return prelude;\n}\n\nconst name$b = 'Rule';\nconst walkContext$2 = 'rule';\nconst structure$b = {\n    prelude: ['SelectorList', 'Raw'],\n    block: ['Block']\n};\n\nfunction parse$c() {\n    const startToken = this.tokenIndex;\n    const startOffset = this.tokenStart;\n    let prelude;\n    let block;\n\n    if (this.parseRulePrelude) {\n        prelude = this.parseWithFallback(consumePrelude, consumeRaw$1);\n    } else {\n        prelude = consumeRaw$1.call(this, startToken);\n    }\n\n    block = this.Block(true);\n\n    return {\n        type: 'Rule',\n        loc: this.getLocation(startOffset, this.tokenStart),\n        prelude,\n        block\n    };\n}\nfunction generate$c(node) {\n    this.node(node.prelude);\n    this.node(node.block);\n}\n\nvar Rule = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$b,\n    walkContext: walkContext$2,\n    structure: structure$b,\n    parse: parse$c,\n    generate: generate$c\n});\n\nconst name$a = 'Scope';\nconst structure$a = {\n    root: ['SelectorList', 'Raw', null],\n    limit: ['SelectorList', 'Raw', null]\n};\n\nfunction parse$b() {\n    let root = null;\n    let limit = null;\n\n    this.skipSC();\n\n    const startOffset = this.tokenStart;\n    if (this.tokenType === LeftParenthesis) {\n        this.next();\n        this.skipSC();\n        root = this.parseWithFallback(\n            this.SelectorList,\n            () => this.Raw(false, true)\n        );\n        this.skipSC();\n        this.eat(RightParenthesis);\n    }\n\n    if (this.lookupNonWSType(0) === Ident) {\n        this.skipSC();\n        this.eatIdent('to');\n        this.skipSC();\n        this.eat(LeftParenthesis);\n        this.skipSC();\n        limit = this.parseWithFallback(\n            this.SelectorList,\n            () => this.Raw(false, true)\n        );\n        this.skipSC();\n        this.eat(RightParenthesis);\n    }\n\n    return {\n        type: 'Scope',\n        loc: this.getLocation(startOffset, this.tokenStart),\n        root,\n        limit\n    };\n}\n\nfunction generate$b(node) {\n    if (node.root) {\n        this.token(LeftParenthesis, '(');\n        this.node(node.root);\n        this.token(RightParenthesis, ')');\n    }\n\n    if (node.limit) {\n        this.token(Ident, 'to');\n        this.token(LeftParenthesis, '(');\n        this.node(node.limit);\n        this.token(RightParenthesis, ')');\n    }\n}\n\nvar Scope = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$a,\n    structure: structure$a,\n    parse: parse$b,\n    generate: generate$b\n});\n\nconst name$9 = 'Selector';\nconst structure$9 = {\n    children: [[\n        'TypeSelector',\n        'IdSelector',\n        'ClassSelector',\n        'AttributeSelector',\n        'PseudoClassSelector',\n        'PseudoElementSelector',\n        'Combinator'\n    ]]\n};\n\nfunction parse$a() {\n    const children = this.readSequence(this.scope.Selector);\n\n    // nothing were consumed\n    if (this.getFirstListNode(children) === null) {\n        this.error('Selector is expected');\n    }\n\n    return {\n        type: 'Selector',\n        loc: this.getLocationFromList(children),\n        children\n    };\n}\n\nfunction generate$a(node) {\n    this.children(node);\n}\n\nvar Selector = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$9,\n    structure: structure$9,\n    parse: parse$a,\n    generate: generate$a\n});\n\nconst name$8 = 'SelectorList';\nconst walkContext$1 = 'selector';\nconst structure$8 = {\n    children: [[\n        'Selector',\n        'Raw'\n    ]]\n};\n\nfunction parse$9() {\n    const children = this.createList();\n\n    while (!this.eof) {\n        children.push(this.Selector());\n\n        if (this.tokenType === Comma) {\n            this.next();\n            continue;\n        }\n\n        break;\n    }\n\n    return {\n        type: 'SelectorList',\n        loc: this.getLocationFromList(children),\n        children\n    };\n}\n\nfunction generate$9(node) {\n    this.children(node, () => this.token(Comma, ','));\n}\n\nvar SelectorList = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$8,\n    walkContext: walkContext$1,\n    structure: structure$8,\n    parse: parse$9,\n    generate: generate$9\n});\n\nconst REVERSE_SOLIDUS$2 = 0x005c; // U+005C REVERSE SOLIDUS (\\)\nconst QUOTATION_MARK$1 = 0x0022;  // \"\nconst APOSTROPHE$1 = 0x0027;      // '\n\nfunction decode$2(str) {\n    const len = str.length;\n    const firstChar = str.charCodeAt(0);\n    const start = firstChar === QUOTATION_MARK$1 || firstChar === APOSTROPHE$1 ? 1 : 0;\n    const end = start === 1 && len > 1 && str.charCodeAt(len - 1) === firstChar ? len - 2 : len - 1;\n    let decoded = '';\n\n    for (let i = start; i <= end; i++) {\n        let code = str.charCodeAt(i);\n\n        if (code === REVERSE_SOLIDUS$2) {\n            // special case at the ending\n            if (i === end) {\n                // if the next input code point is EOF, do nothing\n                // otherwise include last quote as escaped\n                if (i !== len - 1) {\n                    decoded = str.substr(i + 1);\n                }\n                break;\n            }\n\n            code = str.charCodeAt(++i);\n\n            // consume escaped\n            if (isValidEscape(REVERSE_SOLIDUS$2, code)) {\n                const escapeStart = i - 1;\n                const escapeEnd = consumeEscaped(str, escapeStart);\n\n                i = escapeEnd - 1;\n                decoded += decodeEscaped(str.substring(escapeStart + 1, escapeEnd));\n            } else {\n                // \\r\\n\n                if (code === 0x000d && str.charCodeAt(i + 1) === 0x000a) {\n                    i++;\n                }\n            }\n        } else {\n            decoded += str[i];\n        }\n    }\n\n    return decoded;\n}\n\n// https://drafts.csswg.org/cssom/#serialize-a-string\n// § 2.1. Common Serializing Idioms\nfunction encode$2(str, apostrophe) {\n    const quote = apostrophe ? '\\'' : '\"';\n    const quoteCode = apostrophe ? APOSTROPHE$1 : QUOTATION_MARK$1;\n    let encoded = '';\n    let wsBeforeHexIsNeeded = false;\n\n    for (let i = 0; i < str.length; i++) {\n        const code = str.charCodeAt(i);\n\n        // If the character is NULL (U+0000), then the REPLACEMENT CHARACTER (U+FFFD).\n        if (code === 0x0000) {\n            encoded += '\\uFFFD';\n            continue;\n        }\n\n        // If the character is in the range [\\1-\\1f] (U+0001 to U+001F) or is U+007F,\n        // the character escaped as code point.\n        // Note: Do not compare with 0x0001 since 0x0000 is precessed before\n        if (code <= 0x001f || code === 0x007F) {\n            encoded += '\\\\' + code.toString(16);\n            wsBeforeHexIsNeeded = true;\n            continue;\n        }\n\n        // If the character is '\"' (U+0022) or \"\\\" (U+005C), the escaped character.\n        if (code === quoteCode || code === REVERSE_SOLIDUS$2) {\n            encoded += '\\\\' + str.charAt(i);\n            wsBeforeHexIsNeeded = false;\n        } else {\n            if (wsBeforeHexIsNeeded && (isHexDigit(code) || isWhiteSpace(code))) {\n                encoded += ' ';\n            }\n\n            // Otherwise, the character itself.\n            encoded += str.charAt(i);\n            wsBeforeHexIsNeeded = false;\n        }\n    }\n\n    return quote + encoded + quote;\n}\n\nvar string = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    decode: decode$2,\n    encode: encode$2\n});\n\nconst name$7 = 'String';\nconst structure$7 = {\n    value: String\n};\n\nfunction parse$8() {\n    return {\n        type: 'String',\n        loc: this.getLocation(this.tokenStart, this.tokenEnd),\n        value: decode$2(this.consume(String$2))\n    };\n}\n\nfunction generate$8(node) {\n    this.token(String$2, encode$2(node.value));\n}\n\nvar String$1 = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$7,\n    structure: structure$7,\n    parse: parse$8,\n    generate: generate$8\n});\n\nconst EXCLAMATIONMARK = 0x0021; // U+0021 EXCLAMATION MARK (!)\n\nfunction consumeRaw() {\n    return this.Raw(null, false);\n}\n\nconst name$6 = 'StyleSheet';\nconst walkContext = 'stylesheet';\nconst structure$6 = {\n    children: [[\n        'Comment',\n        'CDO',\n        'CDC',\n        'Atrule',\n        'Rule',\n        'Raw'\n    ]]\n};\n\nfunction parse$7() {\n    const start = this.tokenStart;\n    const children = this.createList();\n    let child;\n\n    while (!this.eof) {\n        switch (this.tokenType) {\n            case WhiteSpace$1:\n                this.next();\n                continue;\n\n            case Comment$1:\n                // ignore comments except exclamation comments (i.e. /*! .. */) on top level\n                if (this.charCodeAt(this.tokenStart + 2) !== EXCLAMATIONMARK) {\n                    this.next();\n                    continue;\n                }\n\n                child = this.Comment();\n                break;\n\n            case CDO$1: // <!--\n                child = this.CDO();\n                break;\n\n            case CDC$1: // -->\n                child = this.CDC();\n                break;\n\n            // CSS Syntax Module Level 3\n            // §2.2 Error handling\n            // At the \"top level\" of a stylesheet, an <at-keyword-token> starts an at-rule.\n            case AtKeyword:\n                child = this.parseWithFallback(this.Atrule, consumeRaw);\n                break;\n\n            // Anything else starts a qualified rule ...\n            default:\n                child = this.parseWithFallback(this.Rule, consumeRaw);\n        }\n\n        children.push(child);\n    }\n\n    return {\n        type: 'StyleSheet',\n        loc: this.getLocation(start, this.tokenStart),\n        children\n    };\n}\n\nfunction generate$7(node) {\n    this.children(node);\n}\n\nvar StyleSheet = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$6,\n    walkContext: walkContext,\n    structure: structure$6,\n    parse: parse$7,\n    generate: generate$7\n});\n\nconst name$5 = 'SupportsDeclaration';\nconst structure$5 = {\n    declaration: 'Declaration'\n};\n\nfunction parse$6() {\n    const start = this.tokenStart;\n\n    this.eat(LeftParenthesis);\n    this.skipSC();\n\n    const declaration = this.Declaration();\n\n    if (!this.eof) {\n        this.eat(RightParenthesis);\n    }\n\n    return {\n        type: 'SupportsDeclaration',\n        loc: this.getLocation(start, this.tokenStart),\n        declaration\n    };\n}\n\nfunction generate$6(node) {\n    this.token(LeftParenthesis, '(');\n    this.node(node.declaration);\n    this.token(RightParenthesis, ')');\n}\n\nvar SupportsDeclaration = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$5,\n    structure: structure$5,\n    parse: parse$6,\n    generate: generate$6\n});\n\nconst ASTERISK$2 = 0x002A;     // U+002A ASTERISK (*)\nconst VERTICALLINE$1 = 0x007C; // U+007C VERTICAL LINE (|)\n\nfunction eatIdentifierOrAsterisk() {\n    if (this.tokenType !== Ident &&\n        this.isDelim(ASTERISK$2) === false) {\n        this.error('Identifier or asterisk is expected');\n    }\n\n    this.next();\n}\n\nconst name$4 = 'TypeSelector';\nconst structure$4 = {\n    name: String\n};\n\n// ident\n// ident|ident\n// ident|*\n// *\n// *|ident\n// *|*\n// |ident\n// |*\nfunction parse$5() {\n    const start = this.tokenStart;\n\n    if (this.isDelim(VERTICALLINE$1)) {\n        this.next();\n        eatIdentifierOrAsterisk.call(this);\n    } else {\n        eatIdentifierOrAsterisk.call(this);\n\n        if (this.isDelim(VERTICALLINE$1)) {\n            this.next();\n            eatIdentifierOrAsterisk.call(this);\n        }\n    }\n\n    return {\n        type: 'TypeSelector',\n        loc: this.getLocation(start, this.tokenStart),\n        name: this.substrToCursor(start)\n    };\n}\n\nfunction generate$5(node) {\n    this.tokenize(node.name);\n}\n\nvar TypeSelector = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$4,\n    structure: structure$4,\n    parse: parse$5,\n    generate: generate$5\n});\n\nconst PLUSSIGN$2 = 0x002B;     // U+002B PLUS SIGN (+)\nconst HYPHENMINUS$1 = 0x002D;  // U+002D HYPHEN-MINUS (-)\nconst QUESTIONMARK = 0x003F; // U+003F QUESTION MARK (?)\n\nfunction eatHexSequence(offset, allowDash) {\n    let len = 0;\n\n    for (let pos = this.tokenStart + offset; pos < this.tokenEnd; pos++) {\n        const code = this.charCodeAt(pos);\n\n        if (code === HYPHENMINUS$1 && allowDash && len !== 0) {\n            eatHexSequence.call(this, offset + len + 1, false);\n            return -1;\n        }\n\n        if (!isHexDigit(code)) {\n            this.error(\n                allowDash && len !== 0\n                    ? 'Hyphen minus' + (len < 6 ? ' or hex digit' : '') + ' is expected'\n                    : (len < 6 ? 'Hex digit is expected' : 'Unexpected input'),\n                pos\n            );\n        }\n\n        if (++len > 6) {\n            this.error('Too many hex digits', pos);\n        }    }\n\n    this.next();\n    return len;\n}\n\nfunction eatQuestionMarkSequence(max) {\n    let count = 0;\n\n    while (this.isDelim(QUESTIONMARK)) {\n        if (++count > max) {\n            this.error('Too many question marks');\n        }\n\n        this.next();\n    }\n}\n\nfunction startsWith(code) {\n    if (this.charCodeAt(this.tokenStart) !== code) {\n        this.error((code === PLUSSIGN$2 ? 'Plus sign' : 'Hyphen minus') + ' is expected');\n    }\n}\n\n// https://drafts.csswg.org/css-syntax/#urange\n// Informally, the <urange> production has three forms:\n// U+0001\n//      Defines a range consisting of a single code point, in this case the code point \"1\".\n// U+0001-00ff\n//      Defines a range of codepoints between the first and the second value, in this case\n//      the range between \"1\" and \"ff\" (255 in decimal) inclusive.\n// U+00??\n//      Defines a range of codepoints where the \"?\" characters range over all hex digits,\n//      in this case defining the same as the value U+0000-00ff.\n// In each form, a maximum of 6 digits is allowed for each hexadecimal number (if you treat \"?\" as a hexadecimal digit).\n//\n// <urange> =\n//   u '+' <ident-token> '?'* |\n//   u <dimension-token> '?'* |\n//   u <number-token> '?'* |\n//   u <number-token> <dimension-token> |\n//   u <number-token> <number-token> |\n//   u '+' '?'+\nfunction scanUnicodeRange() {\n    let hexLength = 0;\n\n    switch (this.tokenType) {\n        case Number$2:\n            // u <number-token> '?'*\n            // u <number-token> <dimension-token>\n            // u <number-token> <number-token>\n            hexLength = eatHexSequence.call(this, 1, true);\n\n            if (this.isDelim(QUESTIONMARK)) {\n                eatQuestionMarkSequence.call(this, 6 - hexLength);\n                break;\n            }\n\n            if (this.tokenType === Dimension$1 ||\n                this.tokenType === Number$2) {\n                startsWith.call(this, HYPHENMINUS$1);\n                eatHexSequence.call(this, 1, false);\n                break;\n            }\n\n            break;\n\n        case Dimension$1:\n            // u <dimension-token> '?'*\n            hexLength = eatHexSequence.call(this, 1, true);\n\n            if (hexLength > 0) {\n                eatQuestionMarkSequence.call(this, 6 - hexLength);\n            }\n\n            break;\n\n        default:\n            // u '+' <ident-token> '?'*\n            // u '+' '?'+\n            this.eatDelim(PLUSSIGN$2);\n\n            if (this.tokenType === Ident) {\n                hexLength = eatHexSequence.call(this, 0, true);\n                if (hexLength > 0) {\n                    eatQuestionMarkSequence.call(this, 6 - hexLength);\n                }\n                break;\n            }\n\n            if (this.isDelim(QUESTIONMARK)) {\n                this.next();\n                eatQuestionMarkSequence.call(this, 5);\n                break;\n            }\n\n            this.error('Hex digit or question mark is expected');\n    }\n}\n\nconst name$3 = 'UnicodeRange';\nconst structure$3 = {\n    value: String\n};\n\nfunction parse$4() {\n    const start = this.tokenStart;\n\n    // U or u\n    this.eatIdent('u');\n    scanUnicodeRange.call(this);\n\n    return {\n        type: 'UnicodeRange',\n        loc: this.getLocation(start, this.tokenStart),\n        value: this.substrToCursor(start)\n    };\n}\n\nfunction generate$4(node) {\n    this.tokenize(node.value);\n}\n\nvar UnicodeRange = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$3,\n    structure: structure$3,\n    parse: parse$4,\n    generate: generate$4\n});\n\nconst SPACE$1 = 0x0020;            // U+0020 SPACE\nconst REVERSE_SOLIDUS$1 = 0x005c;  // U+005C REVERSE SOLIDUS (\\)\nconst QUOTATION_MARK = 0x0022;   // \"\nconst APOSTROPHE = 0x0027;       // '\nconst LEFTPARENTHESIS = 0x0028;  // U+0028 LEFT PARENTHESIS (()\nconst RIGHTPARENTHESIS = 0x0029; // U+0029 RIGHT PARENTHESIS ())\n\nfunction decode$1(str) {\n    const len = str.length;\n    let start = 4; // length of \"url(\"\n    let end = str.charCodeAt(len - 1) === RIGHTPARENTHESIS ? len - 2 : len - 1;\n    let decoded = '';\n\n    while (start < end && isWhiteSpace(str.charCodeAt(start))) {\n        start++;\n    }\n\n    while (start < end && isWhiteSpace(str.charCodeAt(end))) {\n        end--;\n    }\n\n    for (let i = start; i <= end; i++) {\n        let code = str.charCodeAt(i);\n\n        if (code === REVERSE_SOLIDUS$1) {\n            // special case at the ending\n            if (i === end) {\n                // if the next input code point is EOF, do nothing\n                // otherwise include last left parenthesis as escaped\n                if (i !== len - 1) {\n                    decoded = str.substr(i + 1);\n                }\n                break;\n            }\n\n            code = str.charCodeAt(++i);\n\n            // consume escaped\n            if (isValidEscape(REVERSE_SOLIDUS$1, code)) {\n                const escapeStart = i - 1;\n                const escapeEnd = consumeEscaped(str, escapeStart);\n\n                i = escapeEnd - 1;\n                decoded += decodeEscaped(str.substring(escapeStart + 1, escapeEnd));\n            } else {\n                // \\r\\n\n                if (code === 0x000d && str.charCodeAt(i + 1) === 0x000a) {\n                    i++;\n                }\n            }\n        } else {\n            decoded += str[i];\n        }\n    }\n\n    return decoded;\n}\n\nfunction encode$1(str) {\n    let encoded = '';\n    let wsBeforeHexIsNeeded = false;\n\n    for (let i = 0; i < str.length; i++) {\n        const code = str.charCodeAt(i);\n\n        // If the character is NULL (U+0000), then the REPLACEMENT CHARACTER (U+FFFD).\n        if (code === 0x0000) {\n            encoded += '\\uFFFD';\n            continue;\n        }\n\n        // If the character is in the range [\\1-\\1f] (U+0001 to U+001F) or is U+007F,\n        // the character escaped as code point.\n        // Note: Do not compare with 0x0001 since 0x0000 is precessed before\n        if (code <= 0x001f || code === 0x007F) {\n            encoded += '\\\\' + code.toString(16);\n            wsBeforeHexIsNeeded = true;\n            continue;\n        }\n\n        if (code === SPACE$1 ||\n            code === REVERSE_SOLIDUS$1 ||\n            code === QUOTATION_MARK ||\n            code === APOSTROPHE ||\n            code === LEFTPARENTHESIS ||\n            code === RIGHTPARENTHESIS) {\n            encoded += '\\\\' + str.charAt(i);\n            wsBeforeHexIsNeeded = false;\n        } else {\n            if (wsBeforeHexIsNeeded && isHexDigit(code)) {\n                encoded += ' ';\n            }\n\n            encoded += str.charAt(i);\n            wsBeforeHexIsNeeded = false;\n        }\n    }\n\n    return 'url(' + encoded + ')';\n}\n\nvar url = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    decode: decode$1,\n    encode: encode$1\n});\n\nconst name$2 = 'Url';\nconst structure$2 = {\n    value: String\n};\n\n// <url-token> | <function-token> <string> )\nfunction parse$3() {\n    const start = this.tokenStart;\n    let value;\n\n    switch (this.tokenType) {\n        case Url$1:\n            value = decode$1(this.consume(Url$1));\n            break;\n\n        case Function$1:\n            if (!this.cmpStr(this.tokenStart, this.tokenEnd, 'url(')) {\n                this.error('Function name must be `url`');\n            }\n\n            this.eat(Function$1);\n            this.skipSC();\n            value = decode$2(this.consume(String$2));\n            this.skipSC();\n            if (!this.eof) {\n                this.eat(RightParenthesis);\n            }\n            break;\n\n        default:\n            this.error('Url or Function is expected');\n    }\n\n    return {\n        type: 'Url',\n        loc: this.getLocation(start, this.tokenStart),\n        value\n    };\n}\n\nfunction generate$3(node) {\n    this.token(Url$1, encode$1(node.value));\n}\n\nvar Url = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$2,\n    structure: structure$2,\n    parse: parse$3,\n    generate: generate$3\n});\n\nconst name$1 = 'Value';\nconst structure$1 = {\n    children: [[]]\n};\n\nfunction parse$2() {\n    const start = this.tokenStart;\n    const children = this.readSequence(this.scope.Value);\n\n    return {\n        type: 'Value',\n        loc: this.getLocation(start, this.tokenStart),\n        children\n    };\n}\n\nfunction generate$2(node) {\n    this.children(node);\n}\n\nvar Value = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name$1,\n    structure: structure$1,\n    parse: parse$2,\n    generate: generate$2\n});\n\nconst SPACE = Object.freeze({\n    type: 'WhiteSpace',\n    loc: null,\n    value: ' '\n});\n\nconst name = 'WhiteSpace';\nconst structure = {\n    value: String\n};\n\nfunction parse$1() {\n    this.eat(WhiteSpace$1);\n    return SPACE;\n\n    // return {\n    //     type: 'WhiteSpace',\n    //     loc: this.getLocation(this.tokenStart, this.tokenEnd),\n    //     value: this.consume(WHITESPACE)\n    // };\n}\n\nfunction generate$1(node) {\n    this.token(WhiteSpace$1, node.value);\n}\n\nvar WhiteSpace = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    name: name,\n    structure: structure,\n    parse: parse$1,\n    generate: generate$1\n});\n\nvar node$1 = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    AnPlusB: AnPlusB,\n    Atrule: Atrule,\n    AtrulePrelude: AtrulePrelude,\n    AttributeSelector: AttributeSelector,\n    Block: Block,\n    Brackets: Brackets,\n    CDC: CDC,\n    CDO: CDO,\n    ClassSelector: ClassSelector,\n    Combinator: Combinator,\n    Comment: Comment,\n    Condition: Condition,\n    Declaration: Declaration,\n    DeclarationList: DeclarationList,\n    Dimension: Dimension,\n    Feature: Feature,\n    FeatureFunction: FeatureFunction,\n    FeatureRange: FeatureRange,\n    Function: Function,\n    GeneralEnclosed: GeneralEnclosed,\n    Hash: Hash,\n    Identifier: Identifier,\n    IdSelector: IdSelector,\n    Layer: Layer,\n    LayerList: LayerList,\n    MediaQuery: MediaQuery,\n    MediaQueryList: MediaQueryList,\n    NestingSelector: NestingSelector,\n    Nth: Nth,\n    Number: Number$1,\n    Operator: Operator,\n    Parentheses: Parentheses,\n    Percentage: Percentage,\n    PseudoClassSelector: PseudoClassSelector,\n    PseudoElementSelector: PseudoElementSelector,\n    Ratio: Ratio,\n    Raw: Raw,\n    Rule: Rule,\n    Scope: Scope,\n    Selector: Selector,\n    SelectorList: SelectorList,\n    String: String$1,\n    StyleSheet: StyleSheet,\n    SupportsDeclaration: SupportsDeclaration,\n    TypeSelector: TypeSelector,\n    UnicodeRange: UnicodeRange,\n    Url: Url,\n    Value: Value,\n    WhiteSpace: WhiteSpace\n});\n\nvar lexerConfig = {\n    generic: true,\n    cssWideKeywords,\n    ...definitions,\n    node: node$1\n};\n\nconst NUMBERSIGN$1 = 0x0023;  // U+0023 NUMBER SIGN (#)\nconst ASTERISK$1 = 0x002A;    // U+002A ASTERISK (*)\nconst PLUSSIGN$1 = 0x002B;    // U+002B PLUS SIGN (+)\nconst HYPHENMINUS = 0x002D; // U+002D HYPHEN-MINUS (-)\nconst SOLIDUS$1 = 0x002F;     // U+002F SOLIDUS (/)\nconst U = 0x0075;           // U+0075 LATIN SMALL LETTER U (u)\n\nfunction defaultRecognizer(context) {\n    switch (this.tokenType) {\n        case Hash$1:\n            return this.Hash();\n\n        case Comma:\n            return this.Operator();\n\n        case LeftParenthesis:\n            return this.Parentheses(this.readSequence, context.recognizer);\n\n        case LeftSquareBracket:\n            return this.Brackets(this.readSequence, context.recognizer);\n\n        case String$2:\n            return this.String();\n\n        case Dimension$1:\n            return this.Dimension();\n\n        case Percentage$1:\n            return this.Percentage();\n\n        case Number$2:\n            return this.Number();\n\n        case Function$1:\n            return this.cmpStr(this.tokenStart, this.tokenEnd, 'url(')\n                ? this.Url()\n                : this.Function(this.readSequence, context.recognizer);\n\n        case Url$1:\n            return this.Url();\n\n        case Ident:\n            // check for unicode range, it should start with u+ or U+\n            if (this.cmpChar(this.tokenStart, U) &&\n                this.cmpChar(this.tokenStart + 1, PLUSSIGN$1)) {\n                return this.UnicodeRange();\n            } else {\n                return this.Identifier();\n            }\n\n        case Delim: {\n            const code = this.charCodeAt(this.tokenStart);\n\n            if (code === SOLIDUS$1 ||\n                code === ASTERISK$1 ||\n                code === PLUSSIGN$1 ||\n                code === HYPHENMINUS) {\n                return this.Operator(); // TODO: replace with Delim\n            }\n\n            // TODO: produce a node with Delim node type\n\n            if (code === NUMBERSIGN$1) {\n                this.error('Hex or identifier is expected', this.tokenStart + 1);\n            }\n\n            break;\n        }\n    }\n}\n\nvar atrulePrelude = {\n    getNode: defaultRecognizer\n};\n\nconst NUMBERSIGN = 0x0023;      // U+0023 NUMBER SIGN (#)\nconst AMPERSAND = 0x0026;       // U+0026 AMPERSAND (&)\nconst ASTERISK = 0x002A;        // U+002A ASTERISK (*)\nconst PLUSSIGN = 0x002B;        // U+002B PLUS SIGN (+)\nconst SOLIDUS = 0x002F;         // U+002F SOLIDUS (/)\nconst FULLSTOP = 0x002E;        // U+002E FULL STOP (.)\nconst GREATERTHANSIGN = 0x003E; // U+003E GREATER-THAN SIGN (>)\nconst VERTICALLINE = 0x007C;    // U+007C VERTICAL LINE (|)\nconst TILDE = 0x007E;           // U+007E TILDE (~)\n\nfunction onWhiteSpace(next, children) {\n    if (children.last !== null && children.last.type !== 'Combinator' &&\n        next !== null && next.type !== 'Combinator') {\n        children.push({  // FIXME: this.Combinator() should be used instead\n            type: 'Combinator',\n            loc: null,\n            name: ' '\n        });\n    }\n}\n\nfunction getNode() {\n    switch (this.tokenType) {\n        case LeftSquareBracket:\n            return this.AttributeSelector();\n\n        case Hash$1:\n            return this.IdSelector();\n\n        case Colon:\n            if (this.lookupType(1) === Colon) {\n                return this.PseudoElementSelector();\n            } else {\n                return this.PseudoClassSelector();\n            }\n\n        case Ident:\n            return this.TypeSelector();\n\n        case Number$2:\n        case Percentage$1:\n            return this.Percentage();\n\n        case Dimension$1:\n            // throws when .123ident\n            if (this.charCodeAt(this.tokenStart) === FULLSTOP) {\n                this.error('Identifier is expected', this.tokenStart + 1);\n            }\n            break;\n\n        case Delim: {\n            const code = this.charCodeAt(this.tokenStart);\n\n            switch (code) {\n                case PLUSSIGN:\n                case GREATERTHANSIGN:\n                case TILDE:\n                case SOLIDUS:  // /deep/\n                    return this.Combinator();\n\n                case FULLSTOP:\n                    return this.ClassSelector();\n\n                case ASTERISK:\n                case VERTICALLINE:\n                    return this.TypeSelector();\n\n                case NUMBERSIGN:\n                    return this.IdSelector();\n\n                case AMPERSAND:\n                    return this.NestingSelector();\n            }\n\n            break;\n        }\n    }\n}\nvar selector$1 = {\n    onWhiteSpace,\n    getNode\n};\n\n// legacy IE function\n// expression( <any-value> )\nfunction expressionFn() {\n    return this.createSingleNodeList(\n        this.Raw(null, false)\n    );\n}\n\n// var( <ident> , <value>? )\nfunction varFn() {\n    const children = this.createList();\n\n    this.skipSC();\n\n    // NOTE: Don't check more than a first argument is an ident, rest checks are for lexer\n    children.push(this.Identifier());\n\n    this.skipSC();\n\n    if (this.tokenType === Comma) {\n        children.push(this.Operator());\n\n        const startIndex = this.tokenIndex;\n        const value = this.parseCustomProperty\n            ? this.Value(null)\n            : this.Raw(this.consumeUntilExclamationMarkOrSemicolon, false);\n\n        if (value.type === 'Value' && value.children.isEmpty) {\n            for (let offset = startIndex - this.tokenIndex; offset <= 0; offset++) {\n                if (this.lookupType(offset) === WhiteSpace$1) {\n                    value.children.appendData({\n                        type: 'WhiteSpace',\n                        loc: null,\n                        value: ' '\n                    });\n                    break;\n                }\n            }\n        }\n\n        children.push(value);\n    }\n\n    return children;\n}\n\nfunction isPlusMinusOperator(node) {\n    return (\n        node !== null &&\n        node.type === 'Operator' &&\n        (node.value[node.value.length - 1] === '-' || node.value[node.value.length - 1] === '+')\n    );\n}\n\nvar value = {\n    getNode: defaultRecognizer,\n    onWhiteSpace(next, children) {\n        if (isPlusMinusOperator(next)) {\n            next.value = ' ' + next.value;\n        }\n        if (isPlusMinusOperator(children.last)) {\n            children.last.value += ' ';\n        }\n    },\n    'expression': expressionFn,\n    'var': varFn\n};\n\nvar scope$1 = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    AtrulePrelude: atrulePrelude,\n    Selector: selector$1,\n    Value: value\n});\n\n// https://drafts.csswg.org/css-contain-3/#container-rule\n// The keywords `none`, `and`, `not`, and `or` are excluded from the <custom-ident> above.\nconst nonContainerNameKeywords = new Set(['none', 'and', 'not', 'or']);\n\nvar container = {\n    parse: {\n        prelude() {\n            const children = this.createList();\n\n            if (this.tokenType === Ident) {\n                const name = this.substring(this.tokenStart, this.tokenEnd);\n\n                if (!nonContainerNameKeywords.has(name.toLowerCase())) {\n                    children.push(this.Identifier());\n                }\n            }\n\n            children.push(this.Condition('container'));\n\n            return children;\n        },\n        block(nested = false) {\n            return this.Block(nested);\n        }\n    }\n};\n\nvar fontFace = {\n    parse: {\n        prelude: null,\n        block() {\n            return this.Block(true);\n        }\n    }\n};\n\nfunction parseWithFallback(parse, fallback) {\n    return this.parseWithFallback(\n        () => {\n            try {\n                return parse.call(this);\n            } finally {\n                this.skipSC();\n                if (this.lookupNonWSType(0) !== RightParenthesis) {\n                    this.error();\n                }\n            }\n        },\n        fallback || (() => this.Raw(null, true))\n    );\n}\n\nconst parseFunctions = {\n    layer() {\n        this.skipSC();\n\n        const children = this.createList();\n        const node = parseWithFallback.call(this, this.Layer);\n\n        if (node.type !== 'Raw' || node.value !== '') {\n            children.push(node);\n        }\n\n        return children;\n    },\n    supports() {\n        this.skipSC();\n\n        const children = this.createList();\n        const node = parseWithFallback.call(\n            this,\n            this.Declaration,\n            () => parseWithFallback.call(this, () => this.Condition('supports'))\n        );\n\n        if (node.type !== 'Raw' || node.value !== '') {\n            children.push(node);\n        }\n\n        return children;\n    }\n};\n\nvar importAtrule = {\n    parse: {\n        prelude() {\n            const children = this.createList();\n\n            switch (this.tokenType) {\n                case String$2:\n                    children.push(this.String());\n                    break;\n\n                case Url$1:\n                case Function$1:\n                    children.push(this.Url());\n                    break;\n\n                default:\n                    this.error('String or url() is expected');\n            }\n\n            this.skipSC();\n\n            if (this.tokenType === Ident &&\n                this.cmpStr(this.tokenStart, this.tokenEnd, 'layer')) {\n                children.push(this.Identifier());\n            } else if (\n                this.tokenType === Function$1 &&\n                this.cmpStr(this.tokenStart, this.tokenEnd, 'layer(')\n            ) {\n                children.push(this.Function(null, parseFunctions));\n            }\n\n            this.skipSC();\n\n            if (this.tokenType === Function$1 &&\n                this.cmpStr(this.tokenStart, this.tokenEnd, 'supports(')) {\n                children.push(this.Function(null, parseFunctions));\n            }\n\n            if (this.lookupNonWSType(0) === Ident ||\n                this.lookupNonWSType(0) === LeftParenthesis) {\n                children.push(this.MediaQueryList());\n            }\n\n            return children;\n        },\n        block: null\n    }\n};\n\nvar layer = {\n    parse: {\n        prelude() {\n            return this.createSingleNodeList(\n                this.LayerList()\n            );\n        },\n        block() {\n            return this.Block(false);\n        }\n    }\n};\n\nvar media = {\n    parse: {\n        prelude() {\n            return this.createSingleNodeList(\n                this.MediaQueryList()\n            );\n        },\n        block(nested = false) {\n            return this.Block(nested);\n        }\n    }\n};\n\nvar nest = {\n    parse: {\n        prelude() {\n            return this.createSingleNodeList(\n                this.SelectorList()\n            );\n        },\n        block() {\n            return this.Block(true);\n        }\n    }\n};\n\nvar page = {\n    parse: {\n        prelude() {\n            return this.createSingleNodeList(\n                this.SelectorList()\n            );\n        },\n        block() {\n            return this.Block(true);\n        }\n    }\n};\n\nvar scope = {\n    parse: {\n        prelude() {\n            return this.createSingleNodeList(\n                this.Scope()\n            );\n        },\n        block(nested = false) {\n            return this.Block(nested);\n        }\n    }\n};\n\nvar startingStyle = {\n    parse: {\n        prelude: null,\n        block(nested = false) {\n            return this.Block(nested);\n        }\n    }\n};\n\nvar supports = {\n    parse: {\n        prelude() {\n            return this.createSingleNodeList(\n                this.Condition('supports')\n            );\n        },\n        block(nested = false) {\n            return this.Block(nested);\n        }\n    }\n};\n\nvar atrule = {\n    container,\n    'font-face': fontFace,\n    import: importAtrule,\n    layer,\n    media,\n    nest,\n    page,\n    scope,\n    'starting-style': startingStyle,\n    supports\n};\n\nfunction parseLanguageRangeList() {\n    const children = this.createList();\n\n    this.skipSC();\n\n    loop: while (!this.eof) {\n        switch (this.tokenType) {\n            case Ident:\n                children.push(this.Identifier());\n                break;\n\n            case String$2:\n                children.push(this.String());\n                break;\n\n            case Comma:\n                children.push(this.Operator());\n                break;\n\n            case RightParenthesis:\n                break loop;\n\n            default:\n                this.error('Identifier, string or comma is expected');\n        }\n\n        this.skipSC();\n    }\n\n    return children;\n}\n\nconst selectorList = {\n    parse() {\n        return this.createSingleNodeList(\n            this.SelectorList()\n        );\n    }\n};\n\nconst selector = {\n    parse() {\n        return this.createSingleNodeList(\n            this.Selector()\n        );\n    }\n};\n\nconst identList = {\n    parse() {\n        return this.createSingleNodeList(\n            this.Identifier()\n        );\n    }\n};\n\nconst langList = {\n    parse: parseLanguageRangeList\n};\n\nconst nth = {\n    parse() {\n        return this.createSingleNodeList(\n            this.Nth()\n        );\n    }\n};\n\nvar pseudo = {\n    'dir': identList,\n    'has': selectorList,\n    'lang': langList,\n    'matches': selectorList,\n    'is': selectorList,\n    '-moz-any': selectorList,\n    '-webkit-any': selectorList,\n    'where': selectorList,\n    'not': selectorList,\n    'nth-child': nth,\n    'nth-last-child': nth,\n    'nth-last-of-type': nth,\n    'nth-of-type': nth,\n    'slotted': selector,\n    'host': selector,\n    'host-context': selector\n};\n\nvar node = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    AnPlusB: parse$N,\n    Atrule: parse$M,\n    AtrulePrelude: parse$L,\n    AttributeSelector: parse$K,\n    Block: parse$J,\n    Brackets: parse$I,\n    CDC: parse$H,\n    CDO: parse$G,\n    ClassSelector: parse$F,\n    Combinator: parse$E,\n    Comment: parse$D,\n    Condition: parse$C,\n    Declaration: parse$B,\n    DeclarationList: parse$A,\n    Dimension: parse$z,\n    Feature: parse$y,\n    FeatureFunction: parse$x,\n    FeatureRange: parse$w,\n    Function: parse$v,\n    GeneralEnclosed: parse$u,\n    Hash: parse$t,\n    Identifier: parse$s,\n    IdSelector: parse$r,\n    Layer: parse$q,\n    LayerList: parse$p,\n    MediaQuery: parse$o,\n    MediaQueryList: parse$n,\n    NestingSelector: parse$m,\n    Nth: parse$l,\n    Number: parse$k,\n    Operator: parse$j,\n    Parentheses: parse$i,\n    Percentage: parse$h,\n    PseudoClassSelector: parse$g,\n    PseudoElementSelector: parse$f,\n    Ratio: parse$e,\n    Raw: parse$d,\n    Rule: parse$c,\n    Scope: parse$b,\n    Selector: parse$a,\n    SelectorList: parse$9,\n    String: parse$8,\n    StyleSheet: parse$7,\n    SupportsDeclaration: parse$6,\n    TypeSelector: parse$5,\n    UnicodeRange: parse$4,\n    Url: parse$3,\n    Value: parse$2,\n    WhiteSpace: parse$1\n});\n\nvar parserConfig = {\n    parseContext: {\n        default: 'StyleSheet',\n        stylesheet: 'StyleSheet',\n        atrule: 'Atrule',\n        atrulePrelude(options) {\n            return this.AtrulePrelude(options.atrule ? String(options.atrule) : null);\n        },\n        mediaQueryList: 'MediaQueryList',\n        mediaQuery: 'MediaQuery',\n        condition(options) {\n            return this.Condition(options.kind);\n        },\n        rule: 'Rule',\n        selectorList: 'SelectorList',\n        selector: 'Selector',\n        block() {\n            return this.Block(true);\n        },\n        declarationList: 'DeclarationList',\n        declaration: 'Declaration',\n        value: 'Value'\n    },\n    features: {\n        supports: {\n            selector() {\n                return this.Selector();\n            }\n        },\n        container: {\n            style() {\n                return this.Declaration();\n            }\n        }\n    },\n    scope: scope$1,\n    atrule,\n    pseudo,\n    node\n};\n\nvar walkerConfig = {\n    node: node$1\n};\n\nvar syntax = createSyntax$1({\n    ...lexerConfig,\n    ...parserConfig,\n    ...walkerConfig\n});\n\nconst version = \"3.1.0\";\n\nfunction clone(node) {\n    const result = {};\n\n    for (const key of Object.keys(node)) {\n        let value = node[key];\n\n        if (value) {\n            if (Array.isArray(value) || value instanceof List) {\n                value = value.map(clone);\n            } else if (value.constructor === Object) {\n                value = clone(value);\n            }\n        }\n\n        result[key] = value;\n    }\n\n    return result;\n}\n\nconst REVERSE_SOLIDUS = 0x005c; // U+005C REVERSE SOLIDUS (\\)\n\nfunction decode(str) {\n    const end = str.length - 1;\n    let decoded = '';\n\n    for (let i = 0; i < str.length; i++) {\n        let code = str.charCodeAt(i);\n\n        if (code === REVERSE_SOLIDUS) {\n            // special case at the ending\n            if (i === end) {\n                // if the next input code point is EOF, do nothing\n                break;\n            }\n\n            code = str.charCodeAt(++i);\n\n            // consume escaped\n            if (isValidEscape(REVERSE_SOLIDUS, code)) {\n                const escapeStart = i - 1;\n                const escapeEnd = consumeEscaped(str, escapeStart);\n\n                i = escapeEnd - 1;\n                decoded += decodeEscaped(str.substring(escapeStart + 1, escapeEnd));\n            } else {\n                // \\r\\n\n                if (code === 0x000d && str.charCodeAt(i + 1) === 0x000a) {\n                    i++;\n                }\n            }\n        } else {\n            decoded += str[i];\n        }\n    }\n\n    return decoded;\n}\n\n// https://drafts.csswg.org/cssom/#serialize-an-identifier\n// § 2.1. Common Serializing Idioms\nfunction encode(str) {\n    let encoded = '';\n\n    // If the character is the first character and is a \"-\" (U+002D),\n    // and there is no second character, then the escaped character.\n    // Note: That's means a single dash string \"-\" return as escaped dash,\n    // so move the condition out of the main loop\n    if (str.length === 1 && str.charCodeAt(0) === 0x002D) {\n        return '\\\\-';\n    }\n\n    // To serialize an identifier means to create a string represented\n    // by the concatenation of, for each character of the identifier:\n    for (let i = 0; i < str.length; i++) {\n        const code = str.charCodeAt(i);\n\n        // If the character is NULL (U+0000), then the REPLACEMENT CHARACTER (U+FFFD).\n        if (code === 0x0000) {\n            encoded += '\\uFFFD';\n            continue;\n        }\n\n        if (\n            // If the character is in the range [\\1-\\1f] (U+0001 to U+001F) or is U+007F ...\n            // Note: Do not compare with 0x0001 since 0x0000 is precessed before\n            code <= 0x001F || code === 0x007F ||\n            // [or] ... is in the range [0-9] (U+0030 to U+0039),\n            (code >= 0x0030 && code <= 0x0039 && (\n                // If the character is the first character ...\n                i === 0 ||\n                // If the character is the second character ... and the first character is a \"-\" (U+002D)\n                i === 1 && str.charCodeAt(0) === 0x002D\n            ))\n        ) {\n            // ... then the character escaped as code point.\n            encoded += '\\\\' + code.toString(16) + ' ';\n            continue;\n        }\n\n        // If the character is not handled by one of the above rules and is greater\n        // than or equal to U+0080, is \"-\" (U+002D) or \"_\" (U+005F), or is in one\n        // of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to U+005A),\n        // or \\[a-z] (U+0061 to U+007A), then the character itself.\n        if (isName(code)) {\n            encoded += str.charAt(i);\n        } else {\n            // Otherwise, the escaped character.\n            encoded += '\\\\' + str.charAt(i);\n        }\n    }\n\n    return encoded;\n}\n\nvar ident = /*#__PURE__*/Object.freeze({\n    __proto__: null,\n    decode: decode,\n    encode: encode\n});\n\nconst {\n    tokenize,\n    parse,\n    generate,\n    lexer,\n    createLexer,\n\n    walk,\n    find,\n    findLast,\n    findAll,\n\n    toPlainObject,\n    fromPlainObject,\n\n    fork\n} = syntax;\n\nexport { Lexer, List, OffsetToLocation, TokenStream, clone, createLexer, createSyntax$1 as createSyntax, index as definitionSyntax, find, findAll, findLast, fork, fromPlainObject, generate, ident, isCustomProperty, keyword, lexer, parse, property, string, toPlainObject, tokenNames, types as tokenTypes, tokenize, url, vendorPrefix, version, walk };\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/css/csstree/index.d.ts",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport interface CssLocation {\n    source: string;\n    start: {\n        offset: number;\n        line: number;\n        column: number;\n    };\n    end: {\n        offset: number;\n        line: number;\n        column: number;\n    };\n}\n\nexport interface ListItem<TData> {\n    prev: ListItem<TData> | null;\n    next: ListItem<TData> | null;\n    data: TData;\n}\n\nexport type IteratorFn<TData, TResult, TContext = List<TData>> = (\n    this: TContext,\n    item: TData,\n    node: ListItem<TData>,\n    list: List<TData>,\n) => TResult;\nexport type FilterFn<TData, TResult extends TData, TContext = List<TData>> = (\n    this: TContext,\n    item: TData,\n    node: ListItem<TData>,\n    list: List<TData>,\n) => item is TResult;\nexport type ReduceFn<TData, TValue, TContext = List<TData>> = (this: TContext, accum: TValue, data: TData) => TValue;\n\nexport declare class List<TData> {\n    constructor();\n    get size(): number;\n    get isEmpty(): boolean;\n    get first(): TData | null;\n    get last(): TData | null;\n    [Symbol.iterator](): IterableIterator<TData>;\n    fromArray(array: TData[]): List<TData>;\n    createItem(data: TData): ListItem<TData>;\n    toArray(): TData[];\n    toJSON(): TData[];\n    forEach<TContext>(fn: IteratorFn<TData, void, TContext>, context: TContext): void;\n    forEach(fn: IteratorFn<TData, void>): void;\n    forEachRight<TContext>(fn: IteratorFn<TData, void, TContext>, context: TContext): void;\n    forEachRight(fn: IteratorFn<TData, void>): void;\n    nextUntil<TContext>(start: ListItem<TData>, fn: IteratorFn<TData, boolean, TContext>, context: TContext): void;\n    nextUntil(start: ListItem<TData>, fn: IteratorFn<TData, boolean>): void;\n    prevUntil<TContext>(start: ListItem<TData>, fn: IteratorFn<TData, boolean, TContext>, context: TContext): void;\n    prevUntil(start: ListItem<TData>, fn: IteratorFn<TData, boolean>): void;\n    reduce<TValue, TContext>(fn: ReduceFn<TData, TValue, TContext>, initialValue: TValue, context: TContext): TValue;\n    reduce<TValue>(fn: ReduceFn<TData, TValue>, initialValue: TValue): TValue;\n    reduceRight<TValue, TContext>(\n        fn: ReduceFn<TData, TValue, TContext>,\n        initialValue: TValue,\n        context: TContext,\n    ): TValue;\n    reduceRight<TValue>(fn: ReduceFn<TData, TValue>, initialValue: TValue): TValue;\n    some<TContext>(fn: IteratorFn<TData, boolean, TContext>, context: TContext): boolean;\n    some(fn: IteratorFn<TData, boolean>): boolean;\n    map<TContext, TResult>(fn: IteratorFn<TData, TResult, TContext>, context: TContext): List<TResult>;\n    map<TResult>(fn: IteratorFn<TData, TResult>): List<TResult>;\n    filter<TContext, TResult extends TData>(fn: FilterFn<TData, TResult, TContext>, context: TContext): List<TResult>;\n    filter<TResult extends TData>(fn: FilterFn<TData, TResult>): List<TResult>;\n    filter<TContext>(fn: IteratorFn<TData, boolean, TContext>, context: TContext): List<TData>;\n    filter(fn: IteratorFn<TData, boolean>): List<TData>;\n    clear(): void;\n    copy(): List<TData>;\n    prepend(item: ListItem<TData>): List<TData>;\n    prependData(data: TData): List<TData>;\n    append(item: ListItem<TData>): List<TData>;\n    appendData(data: TData): List<TData>;\n    insert(item: ListItem<TData>, before: ListItem<TData>): List<TData>;\n    insertData(data: TData, before: ListItem<TData>): List<TData>;\n    remove(item: ListItem<TData>): ListItem<TData>;\n    push(item: TData): void;\n    pop(): ListItem<TData> | undefined;\n    unshift(data: TData): void;\n    shift(): ListItem<TData> | undefined;\n    prependList(list: List<TData>): List<TData>;\n    appendList(list: List<TData>): List<TData>;\n    insertList(list: List<TData>, before: ListItem<TData>): List<TData>;\n    replace(oldItem: ListItem<TData>, newItemOrList: List<TData> | ListItem<TData>): List<TData>;\n}\n\nexport interface CssNodeCommon {\n    type: string;\n    loc?: CssLocation | undefined;\n}\n\nexport interface AnPlusB extends CssNodeCommon {\n    type: \"AnPlusB\";\n    a: string | null;\n    b: string | null;\n}\n\nexport interface Atrule extends CssNodeCommon {\n    type: \"Atrule\";\n    name: string;\n    prelude: AtrulePrelude | Raw | null;\n    block: Block | null;\n}\n\nexport interface AtrulePlain extends CssNodeCommon {\n    type: \"Atrule\";\n    name: string;\n    prelude: AtrulePreludePlain | Raw | null;\n    block: BlockPlain | null;\n}\n\nexport interface AtrulePrelude extends CssNodeCommon {\n    type: \"AtrulePrelude\";\n    children: List<CssNode>;\n}\n\nexport interface AtrulePreludePlain extends CssNodeCommon {\n    type: \"AtrulePrelude\";\n    children: CssNodePlain[];\n}\n\nexport interface AttributeSelector extends CssNodeCommon {\n    type: \"AttributeSelector\";\n    name: Identifier;\n    matcher: string | null;\n    value: StringNode | Identifier | null;\n    flags: string | null;\n}\n\nexport interface Block extends CssNodeCommon {\n    type: \"Block\";\n    children: List<CssNode>;\n}\n\nexport interface BlockPlain extends CssNodeCommon {\n    type: \"Block\";\n    children: CssNodePlain[];\n}\n\nexport interface Brackets extends CssNodeCommon {\n    type: \"Brackets\";\n    children: List<CssNode>;\n}\n\nexport interface BracketsPlain extends CssNodeCommon {\n    type: \"Brackets\";\n    children: CssNodePlain[];\n}\n\nexport interface CDC extends CssNodeCommon {\n    type: \"CDC\";\n}\n\nexport interface CDO extends CssNodeCommon {\n    type: \"CDO\";\n}\n\nexport interface ClassSelector extends CssNodeCommon {\n    type: \"ClassSelector\";\n    name: string;\n}\n\nexport interface Combinator extends CssNodeCommon {\n    type: \"Combinator\";\n    name: string;\n}\n\nexport interface Comment extends CssNodeCommon {\n    type: \"Comment\";\n    value: string;\n}\n\nexport interface Declaration extends CssNodeCommon {\n    type: \"Declaration\";\n    important: boolean | string;\n    property: string;\n    value: Value | Raw;\n}\n\nexport interface DeclarationPlain extends CssNodeCommon {\n    type: \"Declaration\";\n    important: boolean | string;\n    property: string;\n    value: ValuePlain | Raw;\n}\n\nexport interface DeclarationList extends CssNodeCommon {\n    type: \"DeclarationList\";\n    children: List<CssNode>;\n}\n\nexport interface DeclarationListPlain extends CssNodeCommon {\n    type: \"DeclarationList\";\n    children: CssNodePlain[];\n}\n\nexport interface Dimension extends CssNodeCommon {\n    type: \"Dimension\";\n    value: string;\n    unit: string;\n}\n\nexport interface FunctionNode extends CssNodeCommon {\n    type: \"Function\";\n    name: string;\n    children: List<CssNode>;\n}\n\nexport interface FunctionNodePlain extends CssNodeCommon {\n    type: \"Function\";\n    name: string;\n    children: CssNodePlain[];\n}\n\nexport interface Hash extends CssNodeCommon {\n    type: \"Hash\";\n    value: string;\n}\n\nexport interface IdSelector extends CssNodeCommon {\n    type: \"IdSelector\";\n    name: string;\n}\n\nexport interface Identifier extends CssNodeCommon {\n    type: \"Identifier\";\n    name: string;\n}\n\nexport interface MediaFeature extends CssNodeCommon {\n    type: \"MediaFeature\";\n    name: string;\n    value: Identifier | NumberNode | Dimension | Ratio | null;\n}\n\nexport interface MediaQuery extends CssNodeCommon {\n    type: \"MediaQuery\";\n    children: List<CssNode>;\n}\n\nexport interface MediaQueryPlain extends CssNodeCommon {\n    type: \"MediaQuery\";\n    children: CssNodePlain[];\n}\n\nexport interface MediaQueryList extends CssNodeCommon {\n    type: \"MediaQueryList\";\n    children: List<CssNode>;\n}\n\nexport interface MediaQueryListPlain extends CssNodeCommon {\n    type: \"MediaQueryList\";\n    children: CssNodePlain[];\n}\n\nexport interface NestingSelector extends CssNodeCommon {\n    type: \"NestingSelector\";\n}\n\nexport interface Nth extends CssNodeCommon {\n    type: \"Nth\";\n    nth: AnPlusB | Identifier;\n    selector: SelectorList | null;\n}\n\nexport interface NthPlain extends CssNodeCommon {\n    type: \"Nth\";\n    nth: AnPlusB | Identifier;\n    selector: SelectorListPlain | null;\n}\n\nexport interface NumberNode extends CssNodeCommon {\n    type: \"Number\";\n    value: string;\n}\n\nexport interface Operator extends CssNodeCommon {\n    type: \"Operator\";\n    value: string;\n}\n\nexport interface Parentheses extends CssNodeCommon {\n    type: \"Parentheses\";\n    children: List<CssNode>;\n}\n\nexport interface ParenthesesPlain extends CssNodeCommon {\n    type: \"Parentheses\";\n    children: CssNodePlain[];\n}\n\nexport interface Percentage extends CssNodeCommon {\n    type: \"Percentage\";\n    value: string;\n}\n\nexport interface PseudoClassSelector extends CssNodeCommon {\n    type: \"PseudoClassSelector\";\n    name: string;\n    children: List<CssNode> | null;\n}\n\nexport interface PseudoClassSelectorPlain extends CssNodeCommon {\n    type: \"PseudoClassSelector\";\n    name: string;\n    children: CssNodePlain[] | null;\n}\n\nexport interface PseudoElementSelector extends CssNodeCommon {\n    type: \"PseudoElementSelector\";\n    name: string;\n    children: List<CssNode> | null;\n}\n\nexport interface PseudoElementSelectorPlain extends CssNodeCommon {\n    type: \"PseudoElementSelector\";\n    name: string;\n    children: CssNodePlain[] | null;\n}\n\nexport interface Ratio extends CssNodeCommon {\n    type: \"Ratio\";\n    left: string;\n    right: string;\n}\n\nexport interface Raw extends CssNodeCommon {\n    type: \"Raw\";\n    value: string;\n}\n\nexport interface Rule extends CssNodeCommon {\n    type: \"Rule\";\n    prelude: SelectorList | Raw;\n    block: Block;\n}\n\nexport interface RulePlain extends CssNodeCommon {\n    type: \"Rule\";\n    prelude: SelectorListPlain | Raw;\n    block: BlockPlain;\n}\n\nexport interface Selector extends CssNodeCommon {\n    type: \"Selector\";\n    children: List<CssNode>;\n}\n\nexport interface SelectorPlain extends CssNodeCommon {\n    type: \"Selector\";\n    children: CssNodePlain[];\n}\n\nexport interface SelectorList extends CssNodeCommon {\n    type: \"SelectorList\";\n    children: List<CssNode>;\n}\n\nexport interface SelectorListPlain extends CssNodeCommon {\n    type: \"SelectorList\";\n    children: CssNodePlain[];\n}\n\nexport interface StringNode extends CssNodeCommon {\n    type: \"String\";\n    value: string;\n}\n\nexport interface StyleSheet extends CssNodeCommon {\n    type: \"StyleSheet\";\n    children: List<CssNode>;\n}\n\nexport interface StyleSheetPlain extends CssNodeCommon {\n    type: \"StyleSheet\";\n    children: CssNodePlain[];\n}\n\nexport interface TypeSelector extends CssNodeCommon {\n    type: \"TypeSelector\";\n    name: string;\n}\n\nexport interface UnicodeRange extends CssNodeCommon {\n    type: \"UnicodeRange\";\n    value: string;\n}\n\nexport interface Url extends CssNodeCommon {\n    type: \"Url\";\n    value: string;\n}\n\nexport interface Value extends CssNodeCommon {\n    type: \"Value\";\n    children: List<CssNode>;\n}\n\nexport interface ValuePlain extends CssNodeCommon {\n    type: \"Value\";\n    children: CssNodePlain[];\n}\n\nexport interface WhiteSpace extends CssNodeCommon {\n    type: \"WhiteSpace\";\n    value: string;\n}\n\nexport type CssNode =\n    | AnPlusB\n    | Atrule\n    | AtrulePrelude\n    | AttributeSelector\n    | Block\n    | Brackets\n    | CDC\n    | CDO\n    | ClassSelector\n    | Combinator\n    | Comment\n    | Declaration\n    | DeclarationList\n    | Dimension\n    | FunctionNode\n    | Hash\n    | IdSelector\n    | Identifier\n    | MediaFeature\n    | MediaQuery\n    | MediaQueryList\n    | NestingSelector\n    | Nth\n    | NumberNode\n    | Operator\n    | Parentheses\n    | Percentage\n    | PseudoClassSelector\n    | PseudoElementSelector\n    | Ratio\n    | Raw\n    | Rule\n    | Selector\n    | SelectorList\n    | StringNode\n    | StyleSheet\n    | TypeSelector\n    | UnicodeRange\n    | Url\n    | Value\n    | WhiteSpace;\n\nexport type CssNodePlain =\n    | AnPlusB\n    | AtrulePlain\n    | AtrulePreludePlain\n    | AttributeSelector\n    | BlockPlain\n    | BracketsPlain\n    | CDC\n    | CDO\n    | ClassSelector\n    | Combinator\n    | Comment\n    | DeclarationPlain\n    | DeclarationListPlain\n    | Dimension\n    | FunctionNodePlain\n    | Hash\n    | IdSelector\n    | Identifier\n    | MediaFeature\n    | MediaQueryPlain\n    | MediaQueryListPlain\n    | NthPlain\n    | NumberNode\n    | Operator\n    | ParenthesesPlain\n    | Percentage\n    | PseudoClassSelectorPlain\n    | PseudoElementSelectorPlain\n    | Ratio\n    | Raw\n    | RulePlain\n    | SelectorPlain\n    | SelectorListPlain\n    | StringNode\n    | StyleSheetPlain\n    | TypeSelector\n    | UnicodeRange\n    | Url\n    | ValuePlain\n    | WhiteSpace;\n\nexport interface SyntaxParseError extends SyntaxError {\n    input: string;\n    offset: number;\n    rawMessage: string;\n    formattedMessage: string;\n}\n\nexport interface ParseOptions {\n    context?: string | undefined;\n    atrule?: string | undefined;\n    positions?: boolean | undefined;\n    onComment?: (value: string, loc: CssLocation) => void;\n    onParseError?: ((error: SyntaxParseError, fallbackNode: CssNode) => void) | undefined;\n    filename?: string | undefined;\n    offset?: number | undefined;\n    line?: number | undefined;\n    column?: number | undefined;\n    parseAtrulePrelude?: boolean | undefined;\n    parseRulePrelude?: boolean | undefined;\n    parseValue?: boolean | undefined;\n    parseCustomProperty?: boolean | undefined;\n}\n\nexport declare function parse(text: string, options?: ParseOptions): CssNode;\n\nexport interface GenerateHandlers {\n    children: (node: CssNode, delimiter?: (node: CssNode) => void) => void;\n    node: (node: CssNode) => void;\n    chunk: (chunk: string) => void;\n    result: () => string;\n}\n\nexport interface GenerateOptions {\n    sourceMap?: boolean | undefined;\n    decorator?: ((handlers: GenerateHandlers) => GenerateHandlers) | undefined;\n    mode?: \"safe\" | \"spec\" | undefined;\n}\n\nexport declare function generate(ast: CssNode, options?: GenerateOptions): string;\n\nexport interface WalkContext {\n    /**\n     * Stops traversal. No visitor function will be invoked once this value is\n     * returned by a visitor.\n     */\n    break: symbol;\n    /**\n     * Prevent the current node from being iterated. No visitor function will be\n     * invoked for its properties or children nodes; note that this value only\n     * has an effect for enter visitor as leave visitor invokes after iterating\n     * over all node's properties and children.\n     */\n    skip: symbol;\n    root: CssNode;\n    stylesheet: StyleSheet | null;\n    atrule: Atrule | null;\n    atrulePrelude: AtrulePrelude | null;\n    rule: Rule | null;\n    selector: SelectorList | null;\n    block: Block | null;\n    declaration: Declaration | null;\n    function: FunctionNode | PseudoClassSelector | PseudoElementSelector | null;\n}\n\nexport type EnterOrLeaveFn<NodeType = CssNode> = (\n    this: WalkContext,\n    node: NodeType,\n    item: ListItem<CssNode>,\n    list: List<CssNode>,\n) => void;\n\nexport interface WalkOptionsNoVisit {\n    visit?: never;\n    enter?: EnterOrLeaveFn | undefined;\n    leave?: EnterOrLeaveFn | undefined;\n    reverse?: boolean | undefined;\n}\n\nexport interface WalkOptionsVisit<NodeType extends CssNode = CssNode> {\n    visit: NodeType[\"type\"];\n    enter?: EnterOrLeaveFn<NodeType> | undefined;\n    leave?: EnterOrLeaveFn<NodeType> | undefined;\n    reverse?: boolean | undefined;\n}\n\nexport type WalkOptions =\n    | WalkOptionsVisit<AnPlusB>\n    | WalkOptionsVisit<Atrule>\n    | WalkOptionsVisit<AtrulePrelude>\n    | WalkOptionsVisit<AttributeSelector>\n    | WalkOptionsVisit<Block>\n    | WalkOptionsVisit<Brackets>\n    | WalkOptionsVisit<CDC>\n    | WalkOptionsVisit<CDO>\n    | WalkOptionsVisit<ClassSelector>\n    | WalkOptionsVisit<Combinator>\n    | WalkOptionsVisit<Comment>\n    | WalkOptionsVisit<Declaration>\n    | WalkOptionsVisit<DeclarationList>\n    | WalkOptionsVisit<Dimension>\n    | WalkOptionsVisit<FunctionNode>\n    | WalkOptionsVisit<Hash>\n    | WalkOptionsVisit<IdSelector>\n    | WalkOptionsVisit<Identifier>\n    | WalkOptionsVisit<MediaFeature>\n    | WalkOptionsVisit<MediaQuery>\n    | WalkOptionsVisit<MediaQueryList>\n    | WalkOptionsVisit<Nth>\n    | WalkOptionsVisit<NumberNode>\n    | WalkOptionsVisit<Operator>\n    | WalkOptionsVisit<Parentheses>\n    | WalkOptionsVisit<Percentage>\n    | WalkOptionsVisit<PseudoClassSelector>\n    | WalkOptionsVisit<PseudoElementSelector>\n    | WalkOptionsVisit<Ratio>\n    | WalkOptionsVisit<Raw>\n    | WalkOptionsVisit<Rule>\n    | WalkOptionsVisit<Selector>\n    | WalkOptionsVisit<SelectorList>\n    | WalkOptionsVisit<StringNode>\n    | WalkOptionsVisit<StyleSheet>\n    | WalkOptionsVisit<TypeSelector>\n    | WalkOptionsVisit<UnicodeRange>\n    | WalkOptionsVisit<Url>\n    | WalkOptionsVisit<Value>\n    | WalkOptionsVisit<WhiteSpace>\n    | WalkOptionsNoVisit;\n\nexport declare const walk: {\n    (ast: CssNode, options: EnterOrLeaveFn | WalkOptions): void;\n    /**\n     * Stops traversal. No visitor function will be invoked once this value is returned by a visitor.\n     */\n    readonly break: symbol;\n    /**\n     * Prevent the current node from being iterated. No visitor function will be invoked for its properties or children\n     * nodes; note that this value only has an effect for enter visitor as leave visitor invokes after iterating over\n     * all node's properties and children.\n     */\n    readonly skip: symbol;\n};\n\nexport type FindFn = (this: WalkContext, node: CssNode, item: ListItem<CssNode>, list: List<CssNode>) => boolean;\n\nexport declare function find(ast: CssNode, fn: FindFn): CssNode | null;\nexport declare function findLast(ast: CssNode, fn: FindFn): CssNode | null;\nexport declare function findAll(ast: CssNode, fn: FindFn): CssNode[];\n\nexport interface Property {\n    readonly basename: string;\n    readonly name: string;\n    readonly hack: string;\n    readonly vendor: string;\n    readonly prefix: string;\n    readonly custom: boolean;\n}\n\nexport declare function property(value: string): Property;\n\nexport interface Keyword {\n    readonly basename: string;\n    readonly name: string;\n    readonly vendor: string;\n    readonly prefix: string;\n    readonly custom: boolean;\n}\n\nexport declare function keyword(value: string): Keyword;\n\nexport declare function clone(node: CssNode): CssNode;\n\nexport declare function fromPlainObject(node: CssNodePlain): CssNode;\nexport declare function toPlainObject(node: CssNode): CssNodePlain;\n\n/**\n * Definition syntax AtWord node\n */\nexport interface DSNodeAtWord {\n    type: \"AtKeyword\";\n    name: string;\n}\n\n/**\n * Definition syntax Comma node\n */\nexport interface DSNodeComma {\n    type: \"Comma\";\n}\n\n/**\n * Definition syntax Function node\n */\nexport interface DSNodeFunction {\n    type: \"Function\";\n    name: string;\n}\n\nexport type DSNodeCombinator = \"|\" | \"||\" | \"&&\" | \" \";\n\n/**\n * Definition syntax Group node\n */\nexport interface DSNodeGroup {\n    type: \"Group\";\n    terms: DSNode[];\n    combinator: DSNodeCombinator;\n    disallowEmpty: boolean;\n    explicit: boolean;\n}\n\n/**\n * Definition syntax Keyword node\n */\nexport interface DSNodeKeyword {\n    type: \"Keyword\";\n    name: string;\n}\n\n/**\n * Definition syntax Multiplier node\n */\nexport interface DSNodeMultiplier {\n    type: \"Multiplier\";\n    comma: boolean;\n    min: number;\n    max: number;\n    term: DSNodeMultiplied;\n}\n\n/**\n * Definition syntax Property node\n */\nexport interface DSNodeProperty {\n    type: \"Property\";\n    name: string;\n}\n\n/**\n * Definition syntax String node\n */\nexport interface DSNodeString {\n    type: \"String\";\n    value: string;\n}\n\n/**\n * Definition syntax Token node\n */\nexport interface DSNodeToken {\n    type: \"Token\";\n    value: string;\n}\n\n/**\n * Definition syntax Type node options\n */\nexport interface DSNodeTypeOpts {\n    type: \"Range\";\n    min: number | null;\n    max: number | null;\n}\n\n/**\n * Definition syntax Type node\n */\nexport interface DSNodeType {\n    type: \"Type\";\n    name: string;\n    opts: DSNodeTypeOpts | null;\n}\n\n/**\n * Definition syntax node\n */\nexport type DSNode =\n    | DSNodeAtWord\n    | DSNodeComma\n    | DSNodeFunction\n    | DSNodeGroup\n    | DSNodeKeyword\n    | DSNodeMultiplier\n    | DSNodeProperty\n    | DSNodeString\n    | DSNodeToken\n    | DSNodeType;\n\n/**\n * Definition syntax node compatible with a multiplier\n */\nexport type DSNodeMultiplied =\n    | DSNodeFunction\n    | DSNodeGroup\n    | DSNodeKeyword\n    | DSNodeProperty\n    | DSNodeString\n    | DSNodeType;\n\n/**\n * Definition syntax generate options\n */\nexport interface DSGenerateOptions {\n    forceBraces?: boolean | undefined;\n    compact?: boolean | undefined;\n    decorate?: ((result: string, node: DSNode) => void) | undefined;\n}\n\n/**\n * Definition syntax walk options\n */\nexport interface DSWalkOptions {\n    enter?: DSWalkEnterOrLeaveFn | undefined;\n    leave?: DSWalkEnterOrLeaveFn | undefined;\n}\n\n/**\n * Definition syntax walk callback\n */\nexport type DSWalkEnterOrLeaveFn = (node: DSNode) => void;\n\n/**\n * DefinitionSyntax\n */\nexport interface DefinitionSyntax {\n    /**\n     * Generates CSS value definition syntax from an AST\n     *\n     * @param node - The AST\n     * @param options - Options that affect generation\n     *\n     * @example\n     *  generate({type: 'Keyword', name: 'foo'}) => 'foo'\n     */\n    generate(node: DSNode, options?: DSGenerateOptions): string;\n\n    /**\n     * Generates an AST from a CSS value syntax\n     *\n     * @param source - The CSS value syntax to parse\n     *\n     * @example\n     *  parse('foo | bar') =>\n     *    {\n     *      type: 'Group',\n     *      terms: [\n     *        { type: 'Keyword', name: 'foo' },\n     *        { type: 'Keyword', name: 'bar' }\n     *      ],\n     *      combinator: '|',\n     *      disallowEmpty: false,\n     *      explicit: false\n     *    }\n     */\n    parse(source: string): DSNodeGroup;\n\n    /**\n     * Walks definition syntax AST\n     */\n    walk(node: DSNode, options: DSWalkEnterOrLeaveFn | DSWalkOptions, context?: any): void;\n\n    /**\n     * Wrapper for syntax errors\n     */\n    syntaxError: SyntaxError;\n}\n\nexport declare const definitionSyntax: DefinitionSyntax;\n\nexport declare const ident: {\n    decode(input: string): string;\n    encode(input: string): string;\n};\n\nexport declare const string: {\n    encode(input: string, apostrophe?: boolean): string;\n    decode(input: string): string;\n};\n\nexport declare const url: {\n    decode(input: string): string;\n    encode(input: string): string;\n};\n\nexport class SyntaxMatchError extends SyntaxError {\n    rawMessage: string;\n    syntax: string;\n    css: string;\n    mismatchOffset: number;\n    mismatchLength: number;\n    offset: number;\n    line: number;\n    column: number;\n    loc: {\n        source: string;\n        start: { offset: number; line: number; column: number };\n        end: { offset: number; line: number; column: number };\n    };\n}\n\nexport class SyntaxReferenceError extends SyntaxError {\n    reference: string;\n}\n\nexport interface LexerMatchResult {\n    error: Error | SyntaxMatchError | SyntaxReferenceError | null;\n}\n\nexport declare class Lexer {\n    matchAtruleDescriptor(atruleName: string, descriptorName: string, value: CssNode | string): LexerMatchResult;\n    matchAtrulePrelude(atruleName: string, prelude: CssNode | string): LexerMatchResult;\n    matchDeclaration(node: CssNode): LexerMatchResult;\n    matchProperty(propertyName: string, value: CssNode | string): LexerMatchResult;\n    matchType(typeName: string, value: CssNode | string): LexerMatchResult;\n    match(syntax: DSNode | string, value: CssNode | string): LexerMatchResult;\n}\n\nexport declare const lexer: Lexer;\n\nexport declare function fork(extension: {\n    atrules?: Record<string, string> | undefined;\n    properties?: Record<string, string> | undefined;\n    types?: Record<string, string> | undefined;\n    cssWideKeywords?: Array<string> | undefined;\n}): { lexer: Lexer };\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/css/csstree/index.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/**\n * css-tree\n * @home   : https://github.com/csstree/csstree\n * @branch : master\n * @commit : 56afb6dd761149099cd3cdfb0a38e15e8cc0a71a\n */\n\nexport * from './csstree.rollup.esm';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/css/csstree/version.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport const version = \"3.1.0\";"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/css/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport * from './service';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/css/service.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { EService, Service } from '../../engine/service';\nimport { Plugin } from '../../engine/plugin';\nimport {\n  parse as cssParse, CssNode,\n  type EnterOrLeaveFn, type WalkOptions, type FindFn,\n  walk as cssWalk, find as cssFind, findAll as cssFindAll, generate as cssGenerate,\n} from './csstree';\nimport { MDError, IMDResult } from '../../util';\nimport { StyledUtil } from './styled';\n\nexport class CssService extends Service {\n  readonly type: EService = EService.CSS;\n  add<T extends Plugin>(_plugin: T): void {}\n  parse(content: string): IMDResult<CssNode> {\n    try {\n      const node = cssParse(content);\n      return { data: node };\n    } catch (e) {\n      return { error: new MDError(e) };\n    }\n  }\n  toStyled(style: string) {\n    return StyledUtil.toStyled(style);\n  }\n  static walk(ast: CssNode, options: EnterOrLeaveFn | WalkOptions) {\n    cssWalk(ast, options);\n  }\n  static find<T = CssNode>(ast: CssNode, fn: FindFn): T | undefined {\n    return cssFind(ast, fn) as T ?? undefined;\n  }\n  static findAll<T = CssNode>(ast: CssNode, fn: FindFn): T[] {\n    return cssFindAll(ast, fn) as T[];\n  }\n  static generate(ast: CssNode): string {\n    return cssGenerate(ast);\n  }\n}\n\nexport { CssNode };"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/css/styled.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { parse, walk, generate } from './csstree';\nimport { StyledValue, StyledTextValue } from '../../render';\nimport { MDLength } from '../../util';\n\nexport abstract class StyledUtil {\n  static toStyled(css: string): StyledValue[] {\n    try {\n      const store = new StyledStore();\n      const ast = parse(css, { context: 'declarationList' });\n      walk(ast, node => {\n        if (node.type === 'Declaration') {\n          store.fill(node.property, generate(node.value));\n        }\n      });\n      return store.values;\n    } catch (e) {\n      return [];\n    }\n  }\n}\nclass StyledStore {\n  private _text?: StyledTextValue;\n  private funcs: Record<string, Callback<string, void>> = {\n    'color': (value: string) => {\n      this.text.option.fontColor = value;\n    },\n    'font-size': (value: string) => {\n      const num = Number(value);\n      if (num === 0 || !!num) {\n        this.text.option.fontSize = MDLength.vp(num);\n      } else {\n        this.text.option.fontSize = MDLength.length2vp(value);\n      }\n    },\n    'font-weight': (value: string) => {\n      this.text.option.fontWeight = value;\n    },\n    'font-style': (value: string) => {\n      if (value === 'italic') {\n        this.text.option.fontStyle = FontStyle.Italic;\n      }\n    },\n  };\n  get values(): StyledValue[] {\n    const values: StyledValue[] = [];\n    if (this._text) {\n      values.push(this._text);\n    }\n    return values;\n  }\n  get text(): StyledTextValue {\n    if (!this._text) {\n      this._text = new StyledTextValue();\n    }\n    return this._text;\n  }\n  fill(property: string, value: string) {\n    this.funcs[property]?.(value);\n  }\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ctx/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport * from './service';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/ctx/service.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport type { MeasureOptions, UIContext } from '@kit.ArkUI';\nimport { EService, Service } from '../../engine/service';\nimport { Plugin } from '../../engine/plugin';\nimport { EMarkdownMode } from '../../util';\nimport { type ITyping, type TextContentController } from '../../render';\nimport type { IFragment } from '../ast';\n\nexport class ContextService extends Service {\n  readonly type: EService = EService.CTX;\n  ctx?: UIContext;\n\n  markdownMode: () => EMarkdownMode = () => EMarkdownMode.Normal;\n  typing: () => ITyping = () => ({});\n  textContentController: () => TextContentController | undefined = () => undefined;\n\n  fragment: () => IFragment | undefined = () => undefined;\n  get fragmentEnable(): boolean {\n    return this.fragment()?.enable ?? true;\n  }\n  get fragmentBlockMax(): number {\n    return Number(this.fragment()?.blockMax) || 10;\n  }\n\n  add<T extends Plugin>(_plugin: T): void {\n  }\n  get resourceManager() {\n    return this.ctx?.getHostContext()?.resourceManager;\n  }\n  measureTextWidth(option: IContextServiceMeasureText) {\n    return this.ctx?.getMeasureUtils()?.measureText({\n      textContent: option.textContent,\n      fontSize: option.fontSize ?? (option.textStyle?.fontSize !== undefined ? `${option.textStyle?.fontSize}vp` : undefined),\n      fontWeight: option.fontWeight ?? option.textStyle?.fontWeight,\n      fontStyle: option.fontStyle ?? option.textStyle?.fontStyle,\n      fontFamily: option.fontFamily ?? option.textStyle?.fontFamily,\n      letterSpacing: option.letterSpacing ?? (option.letterSpacingStyle?.letterSpacing !== undefined ? `${option.letterSpacingStyle?.letterSpacing}vp` : undefined),\n      lineHeight: option.lineHeight ?? (option.lineHeightStyle?.lineHeight !== undefined ? `${option.lineHeightStyle?.lineHeight}vp` : undefined),\n      maxLines: option.maxLines,\n      textAlign: option.textAlign,\n      constraintWidth: option.constraintWidth,\n      overflow: option.overflow,\n      baselineOffset: option.baselineOffset,\n      textCase: option.textCase,\n      textIndent: option.textIndent,\n      wordBreak: option.wordBreak,\n    });\n  }\n  measureTextSize(option: IContextServiceMeasureText) {\n    return this.ctx?.getMeasureUtils()?.measureTextSize({\n      textContent: option.textContent,\n      fontSize: option.fontSize ?? (option.textStyle?.fontSize !== undefined ? `${option.textStyle?.fontSize}vp` : undefined),\n      fontWeight: option.fontWeight ?? option.textStyle?.fontWeight,\n      fontStyle: option.fontStyle ?? option.textStyle?.fontStyle,\n      fontFamily: option.fontFamily ?? option.textStyle?.fontFamily,\n      letterSpacing: option.letterSpacing ?? (option.letterSpacingStyle?.letterSpacing !== undefined ? `${option.letterSpacingStyle?.letterSpacing}vp` : undefined),\n      lineHeight: option.lineHeight ?? (option.lineHeightStyle?.lineHeight !== undefined ? `${option.lineHeightStyle?.lineHeight}vp` : undefined),\n      maxLines: option.maxLines,\n      textAlign: option.textAlign,\n      constraintWidth: option.constraintWidth,\n      overflow: option.overflow,\n      baselineOffset: option.baselineOffset,\n      textCase: option.textCase,\n      textIndent: option.textIndent,\n      wordBreak: option.wordBreak,\n    });\n  }\n}\nexport interface IContextServiceMeasureText extends MeasureOptions {\n  textStyle?: TextStyle,\n  letterSpacingStyle?: LetterSpacingStyle,\n  lineHeightStyle?: LineHeightStyle,\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/event/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport * from './service';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/event/service.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { EService, Service } from '../../engine/service';\nimport { Plugin } from '../../engine/plugin';\nimport type { Node } from '../ast';\nimport type {\n  ITextComponentEvent,\n  ITextComponentSelectionChangeEvent,\n  ITextComponentSelectionOption,\n  ITableComponentEvent,\n  ITableComponentActionClickEvent,\n  IContentBoxBar,\n  ICodeComponentEvent,\n  ICodeComponentActionClickEvent,\n} from '../../render';\n\ninterface IClickEvent {\n  node: Node;\n  event: ClickEvent;\n}\ninterface ILongPressEvent {\n  node: Node;\n  event: GestureEvent;\n}\nexport class EventService extends Service {\n  readonly type: EService = EService.Event;\n  onClick?: Callback<IClickEvent>;\n  onLongPress?: Callback<ILongPressEvent>;\n  onTextComponentSelectionChange?: Callback<ITextComponentSelectionChangeEvent>;\n  onTextComponentSelectionOption?: Callback<ITextComponentEvent, ITextComponentSelectionOption>;\n  onTableComponentActionClick?: Callback<ITableComponentActionClickEvent>;\n  onTableComponentBarOption?: Callback<ITableComponentEvent, IContentBoxBar | undefined>;\n  onCodeComponentActionClick?: Callback<ICodeComponentActionClickEvent>;\n  onCodeComponentBarOption?: Callback<ICodeComponentEvent, IContentBoxBar | undefined>;\n  add<T extends Plugin>(plugin: T): void {}\n\n  invokeClickGesture(node: Node, event: ClickEvent) {\n    this.onClick?.({ node, event });\n  }\n  invokeLongPressGesture(node: Node, event: GestureEvent) {\n    this.onLongPress?.({ node, event });\n  }\n  invokeTextSelectionChange(event: ITextComponentSelectionChangeEvent) {\n    this.onTextComponentSelectionChange?.(event);\n  }\n  invokeTextSelectionOption(event: ITextComponentEvent): ITextComponentSelectionOption {\n    return this.onTextComponentSelectionOption?.(event) ?? {};\n  }\n  invokeTableActionClick(event: ITableComponentActionClickEvent) {\n    this.onTableComponentActionClick?.(event);\n  }\n  invokeTableBarOption(event: ITableComponentEvent): IContentBoxBar | undefined {\n    return this.onTableComponentBarOption?.(event);\n  }\n  invokeCodeActionClick(event: ICodeComponentActionClickEvent) {\n    this.onCodeComponentActionClick?.(event);\n  }\n  invokeCodeBarOption(event: ICodeComponentEvent): IContentBoxBar | undefined {\n    return this.onCodeComponentBarOption?.(event);\n  }\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/file/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport * from './service';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/file/service.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { Service, EService, Plugin } from '../../engine';\n\nexport class FileService extends Service {\n  readonly type: EService = EService.File;\n  add<T extends Plugin>(_plugin: T): void {}\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/dom-serializer/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/**\n * dom-serializer\n * @home   : https://github.com/cheeriojs/dom-serializer\n * @branch : master\n * @commit : 7e5024660067f1c02b394f7403f1f4971d3bd7ce\n */\n\nexport * from './src';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/dom-serializer/src/foreignNames.d.ts",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport declare const elementNames: Map<string, string>;\nexport declare const attributeNames: Map<string, string>;\n//# sourceMappingURL=foreignNames.d.ts.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/dom-serializer/src/foreignNames.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport const elementNames = new Map([\n    \"altGlyph\",\n    \"altGlyphDef\",\n    \"altGlyphItem\",\n    \"animateColor\",\n    \"animateMotion\",\n    \"animateTransform\",\n    \"clipPath\",\n    \"feBlend\",\n    \"feColorMatrix\",\n    \"feComponentTransfer\",\n    \"feComposite\",\n    \"feConvolveMatrix\",\n    \"feDiffuseLighting\",\n    \"feDisplacementMap\",\n    \"feDistantLight\",\n    \"feDropShadow\",\n    \"feFlood\",\n    \"feFuncA\",\n    \"feFuncB\",\n    \"feFuncG\",\n    \"feFuncR\",\n    \"feGaussianBlur\",\n    \"feImage\",\n    \"feMerge\",\n    \"feMergeNode\",\n    \"feMorphology\",\n    \"feOffset\",\n    \"fePointLight\",\n    \"feSpecularLighting\",\n    \"feSpotLight\",\n    \"feTile\",\n    \"feTurbulence\",\n    \"foreignObject\",\n    \"glyphRef\",\n    \"linearGradient\",\n    \"radialGradient\",\n    \"textPath\",\n].map((val) => [val.toLowerCase(), val]));\nexport const attributeNames = new Map([\n    \"definitionURL\",\n    \"attributeName\",\n    \"attributeType\",\n    \"baseFrequency\",\n    \"baseProfile\",\n    \"calcMode\",\n    \"clipPathUnits\",\n    \"diffuseConstant\",\n    \"edgeMode\",\n    \"filterUnits\",\n    \"glyphRef\",\n    \"gradientTransform\",\n    \"gradientUnits\",\n    \"kernelMatrix\",\n    \"kernelUnitLength\",\n    \"keyPoints\",\n    \"keySplines\",\n    \"keyTimes\",\n    \"lengthAdjust\",\n    \"limitingConeAngle\",\n    \"markerHeight\",\n    \"markerUnits\",\n    \"markerWidth\",\n    \"maskContentUnits\",\n    \"maskUnits\",\n    \"numOctaves\",\n    \"pathLength\",\n    \"patternContentUnits\",\n    \"patternTransform\",\n    \"patternUnits\",\n    \"pointsAtX\",\n    \"pointsAtY\",\n    \"pointsAtZ\",\n    \"preserveAlpha\",\n    \"preserveAspectRatio\",\n    \"primitiveUnits\",\n    \"refX\",\n    \"refY\",\n    \"repeatCount\",\n    \"repeatDur\",\n    \"requiredExtensions\",\n    \"requiredFeatures\",\n    \"specularConstant\",\n    \"specularExponent\",\n    \"spreadMethod\",\n    \"startOffset\",\n    \"stdDeviation\",\n    \"stitchTiles\",\n    \"surfaceScale\",\n    \"systemLanguage\",\n    \"tableValues\",\n    \"targetX\",\n    \"targetY\",\n    \"textLength\",\n    \"viewBox\",\n    \"viewTarget\",\n    \"xChannelSelector\",\n    \"yChannelSelector\",\n    \"zoomAndPan\",\n].map((val) => [val.toLowerCase(), val]));\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/dom-serializer/src/index.d.ts",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport type { AnyNode } from \"../../domhandler/src\";\nexport interface DomSerializerOptions {\n    /**\n     * Print an empty attribute's value.\n     *\n     * @default xmlMode\n     * @example With <code>emptyAttrs: false</code>: <code>&lt;input checked&gt;</code>\n     * @example With <code>emptyAttrs: true</code>: <code>&lt;input checked=\"\"&gt;</code>\n     */\n    emptyAttrs?: boolean;\n    /**\n     * Print self-closing tags for tags without contents. If `xmlMode` is set, this will apply to all tags.\n     * Otherwise, only tags that are defined as self-closing in the HTML specification will be printed as such.\n     *\n     * @default xmlMode\n     * @example With <code>selfClosingTags: false</code>: <code>&lt;foo&gt;&lt;/foo&gt;&lt;br&gt;&lt;/br&gt;</code>\n     * @example With <code>xmlMode: true</code> and <code>selfClosingTags: true</code>: <code>&lt;foo/&gt;&lt;br/&gt;</code>\n     * @example With <code>xmlMode: false</code> and <code>selfClosingTags: true</code>: <code>&lt;foo&gt;&lt;/foo&gt;&lt;br /&gt;</code>\n     */\n    selfClosingTags?: boolean;\n    /**\n     * Treat the input as an XML document; enables the `emptyAttrs` and `selfClosingTags` options.\n     *\n     * If the value is `\"foreign\"`, it will try to correct mixed-case attribute names.\n     *\n     * @default false\n     */\n    xmlMode?: boolean | \"foreign\";\n    /**\n     * Encode characters that are either reserved in HTML or XML.\n     *\n     * If `xmlMode` is `true` or the value not `'utf8'`, characters outside of the utf8 range will be encoded as well.\n     *\n     * @default `decodeEntities`\n     */\n    encodeEntities?: boolean | \"utf8\";\n    /**\n     * Option inherited from parsing; will be used as the default value for `encodeEntities`.\n     *\n     * @default true\n     */\n    decodeEntities?: boolean;\n}\n/**\n * Renders a DOM node or an array of DOM nodes to a string.\n *\n * Can be thought of as the equivalent of the `outerHTML` of the passed node(s).\n *\n * @param node Node to be rendered.\n * @param options Changes serialization behavior\n */\nexport declare function render(node: AnyNode | ArrayLike<AnyNode>, options?: DomSerializerOptions): string;\nexport default render;\n//# sourceMappingURL=index.d.ts.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/dom-serializer/src/index.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/*\n * Module dependencies\n */\nimport * as ElementType from \"../../domelementtype/src\";\nimport { encodeXML, escapeAttribute, escapeText } from \"../../entities/src\";\n/**\n * Mixed-case SVG and MathML tags & attributes\n * recognized by the HTML parser.\n *\n * @see https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inforeign\n */\nimport { elementNames, attributeNames } from \"./foreignNames.js\";\nconst unencodedElements = new Set([\n    \"style\",\n    \"script\",\n    \"xmp\",\n    \"iframe\",\n    \"noembed\",\n    \"noframes\",\n    \"plaintext\",\n    \"noscript\",\n]);\nfunction replaceQuotes(value) {\n    return value.replace(/\"/g, \"&quot;\");\n}\n/**\n * Format attributes\n */\nfunction formatAttributes(attributes, opts) {\n    var _a;\n    if (!attributes)\n        return;\n    const encode = ((_a = opts.encodeEntities) !== null && _a !== void 0 ? _a : opts.decodeEntities) === false\n        ? replaceQuotes\n        : !!opts.xmlMode || opts.encodeEntities !== \"utf8\"\n            ? encodeXML\n            : escapeAttribute;\n    return Object.keys(attributes)\n        .map((key) => {\n        var _a, _b;\n        const value = (_a = attributes[key]) !== null && _a !== void 0 ? _a : \"\";\n        if (opts.xmlMode === \"foreign\") {\n            /* Fix up mixed-case attribute names */\n            key = (_b = attributeNames.get(key)) !== null && _b !== void 0 ? _b : key;\n        }\n        if (!opts.emptyAttrs && !opts.xmlMode && value === \"\") {\n            return key;\n        }\n        return `${key}=\"${encode(value)}\"`;\n    })\n        .join(\" \");\n}\n/**\n * Self-enclosing tags\n */\nconst singleTag = new Set([\n    \"area\",\n    \"base\",\n    \"basefont\",\n    \"br\",\n    \"col\",\n    \"command\",\n    \"embed\",\n    \"frame\",\n    \"hr\",\n    \"img\",\n    \"input\",\n    \"isindex\",\n    \"keygen\",\n    \"link\",\n    \"meta\",\n    \"param\",\n    \"source\",\n    \"track\",\n    \"wbr\",\n]);\n/**\n * Renders a DOM node or an array of DOM nodes to a string.\n *\n * Can be thought of as the equivalent of the `outerHTML` of the passed node(s).\n *\n * @param node Node to be rendered.\n * @param options Changes serialization behavior\n */\nexport function render(node, options = {}) {\n    const nodes = \"length\" in node ? node : [node];\n    let output = \"\";\n    for (let i = 0; i < nodes.length; i++) {\n        output += renderNode(nodes[i], options);\n    }\n    return output;\n}\nexport default render;\nfunction renderNode(node, options) {\n    switch (node.type) {\n        case ElementType.Root:\n            return render(node.children, options);\n        // @ts-expect-error We don't use `Doctype` yet\n        case ElementType.Doctype:\n        case ElementType.Directive:\n            return renderDirective(node);\n        case ElementType.Comment:\n            return renderComment(node);\n        case ElementType.CDATA:\n            return renderCdata(node);\n        case ElementType.Script:\n        case ElementType.Style:\n        case ElementType.Tag:\n            return renderTag(node, options);\n        case ElementType.Text:\n            return renderText(node, options);\n    }\n}\nconst foreignModeIntegrationPoints = new Set([\n    \"mi\",\n    \"mo\",\n    \"mn\",\n    \"ms\",\n    \"mtext\",\n    \"annotation-xml\",\n    \"foreignObject\",\n    \"desc\",\n    \"title\",\n]);\nconst foreignElements = new Set([\"svg\", \"math\"]);\nfunction renderTag(elem, opts) {\n    var _a;\n    // Handle SVG / MathML in HTML\n    if (opts.xmlMode === \"foreign\") {\n        /* Fix up mixed-case element names */\n        elem.name = (_a = elementNames.get(elem.name)) !== null && _a !== void 0 ? _a : elem.name;\n        /* Exit foreign mode at integration points */\n        if (elem.parent &&\n            foreignModeIntegrationPoints.has(elem.parent.name)) {\n            opts = { ...opts, xmlMode: false };\n        }\n    }\n    if (!opts.xmlMode && foreignElements.has(elem.name)) {\n        opts = { ...opts, xmlMode: \"foreign\" };\n    }\n    let tag = `<${elem.name}`;\n    const attribs = formatAttributes(elem.attribs, opts);\n    if (attribs) {\n        tag += ` ${attribs}`;\n    }\n    if (elem.children.length === 0 &&\n        (opts.xmlMode\n            ? // In XML mode or foreign mode, and user hasn't explicitly turned off self-closing tags\n                opts.selfClosingTags !== false\n            : // User explicitly asked for self-closing tags, even in HTML mode\n                opts.selfClosingTags && singleTag.has(elem.name))) {\n        if (!opts.xmlMode)\n            tag += \" \";\n        tag += \"/>\";\n    }\n    else {\n        tag += \">\";\n        if (elem.children.length > 0) {\n            tag += render(elem.children, opts);\n        }\n        if (!!opts.xmlMode || !singleTag.has(elem.name)) {\n            tag += `</${elem.name}>`;\n        }\n    }\n    return tag;\n}\nfunction renderDirective(elem) {\n    return `<${elem.data}>`;\n}\nfunction renderText(elem, opts) {\n    var _a;\n    let data = elem.data || \"\";\n    // If entities weren't decoded, no need to encode them back\n    if (((_a = opts.encodeEntities) !== null && _a !== void 0 ? _a : opts.decodeEntities) !== false &&\n        !(!opts.xmlMode &&\n            elem.parent &&\n            unencodedElements.has(elem.parent.name))) {\n        data =\n            !!opts.xmlMode || opts.encodeEntities !== \"utf8\"\n                ? encodeXML(data)\n                : escapeText(data);\n    }\n    return data;\n}\nfunction renderCdata(elem) {\n    return `<![CDATA[${elem.children[0].data}]]>`;\n}\nfunction renderComment(elem) {\n    return `<!--${elem.data}-->`;\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/domelementtype/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/**\n * domelementtype\n * @home   : https://github.com/fb55/domelementtype\n * @branch : master\n * @commit : 7de68e75801c708d0445d84fcf4b5df39fd61bc9\n */\n\nexport * from './src';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/domelementtype/src/index.d.ts",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/** Types of elements found in htmlparser2's DOM */\nexport declare enum ElementType {\n  /** Type for the root element of a document */\n  Root = \"root\",\n  /** Type for Text */\n  Text = \"text\",\n  /** Type for <? ... ?> */\n  Directive = \"directive\",\n  /** Type for <!-- ... --> */\n  Comment = \"comment\",\n  /** Type for <script> tags */\n  Script = \"script\",\n  /** Type for <style> tags */\n  Style = \"style\",\n  /** Type for Any tag */\n  Tag = \"tag\",\n  /** Type for <![CDATA[ ... ]]> */\n  CDATA = \"cdata\",\n  /** Type for <!doctype ...> */\n  Doctype = \"doctype\"\n}\n/**\n * Tests whether an element is a tag or not.\n *\n * @param elem Element to test\n */\nexport declare function isTag(elem: {\n  type: ElementType;\n}): boolean;\n/** Type for the root element of a document */\nexport declare const Root: ElementType.Root;\n/** Type for Text */\nexport declare const Text: ElementType.Text;\n/** Type for <? ... ?> */\nexport declare const Directive: ElementType.Directive;\n/** Type for <!-- ... --> */\nexport declare const Comment: ElementType.Comment;\n/** Type for <script> tags */\nexport declare const Script: ElementType.Script;\n/** Type for <style> tags */\nexport declare const Style: ElementType.Style;\n/** Type for Any tag */\nexport declare const Tag: ElementType.Tag;\n/** Type for <![CDATA[ ... ]]> */\nexport declare const CDATA: ElementType.CDATA;\n/** Type for <!doctype ...> */\nexport declare const Doctype: ElementType.Doctype;\n//# sourceMappingURL=index.d.ts.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/domelementtype/src/index.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/** Types of elements found in htmlparser2's DOM */\nexport var ElementType;\n(function (ElementType) {\n    /** Type for the root element of a document */\n    ElementType[\"Root\"] = \"root\";\n    /** Type for Text */\n    ElementType[\"Text\"] = \"text\";\n    /** Type for <? ... ?> */\n    ElementType[\"Directive\"] = \"directive\";\n    /** Type for <!-- ... --> */\n    ElementType[\"Comment\"] = \"comment\";\n    /** Type for <script> tags */\n    ElementType[\"Script\"] = \"script\";\n    /** Type for <style> tags */\n    ElementType[\"Style\"] = \"style\";\n    /** Type for Any tag */\n    ElementType[\"Tag\"] = \"tag\";\n    /** Type for <![CDATA[ ... ]]> */\n    ElementType[\"CDATA\"] = \"cdata\";\n    /** Type for <!doctype ...> */\n    ElementType[\"Doctype\"] = \"doctype\";\n})(ElementType || (ElementType = {}));\n/**\n * Tests whether an element is a tag or not.\n *\n * @param elem Element to test\n */\nexport function isTag(elem) {\n    return (elem.type === ElementType.Tag ||\n        elem.type === ElementType.Script ||\n        elem.type === ElementType.Style);\n}\n// Exports for backwards compatibility\n/** Type for the root element of a document */\nexport const Root = ElementType.Root;\n/** Type for Text */\nexport const Text = ElementType.Text;\n/** Type for <? ... ?> */\nexport const Directive = ElementType.Directive;\n/** Type for <!-- ... --> */\nexport const Comment = ElementType.Comment;\n/** Type for <script> tags */\nexport const Script = ElementType.Script;\n/** Type for <style> tags */\nexport const Style = ElementType.Style;\n/** Type for Any tag */\nexport const Tag = ElementType.Tag;\n/** Type for <![CDATA[ ... ]]> */\nexport const CDATA = ElementType.CDATA;\n/** Type for <!doctype ...> */\nexport const Doctype = ElementType.Doctype;\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/domhandler/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/**\n * domhandler\n * @home   : https://github.com/fb55/domhandler\n * @branch : master\n * @commit : 0a8f49d4201da363f6ba02d8a15da30d9766f0e0\n */\n\nexport * from './src';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/domhandler/src/index.d.ts",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { ChildNode, Element, DataNode, Document, ParentNode } from \"./node\";\nexport * from \"./node\";\nexport interface DomHandlerOptions {\n    /**\n     * Add a `startIndex` property to nodes.\n     * When the parser is used in a non-streaming fashion, `startIndex` is an integer\n     * indicating the position of the start of the node in the document.\n     *\n     * @default false\n     */\n    withStartIndices?: boolean;\n    /**\n     * Add an `endIndex` property to nodes.\n     * When the parser is used in a non-streaming fashion, `endIndex` is an integer\n     * indicating the position of the end of the node in the document.\n     *\n     * @default false\n     */\n    withEndIndices?: boolean;\n    /**\n     * Treat the markup as XML.\n     *\n     * @default false\n     */\n    xmlMode?: boolean;\n}\ninterface ParserInterface {\n    startIndex: number | null;\n    endIndex: number | null;\n}\ntype Callback = (error: Error | null, dom: ChildNode[]) => void;\ntype ElementCallback = (element: Element) => void;\nexport declare class DomHandler {\n    /** The elements of the DOM */\n    dom: ChildNode[];\n    /** The root element for the DOM */\n    root: Document;\n    /** Called once parsing has completed. */\n    private readonly callback;\n    /** Settings for the handler. */\n    private readonly options;\n    /** Callback whenever a tag is closed. */\n    private readonly elementCB;\n    /** Indicated whether parsing has been completed. */\n    private done;\n    /** Stack of open tags. */\n    protected tagStack: ParentNode[];\n    /** A data node that is still being written to. */\n    protected lastNode: DataNode | null;\n    /** Reference to the parser instance. Used for location information. */\n    private parser;\n    /**\n     * @param callback Called once parsing has completed.\n     * @param options Settings for the handler.\n     * @param elementCB Callback whenever a tag is closed.\n     */\n    constructor(callback?: Callback | null, options?: DomHandlerOptions | null, elementCB?: ElementCallback);\n    onparserinit(parser: ParserInterface): void;\n    onreset(): void;\n    onend(): void;\n    onerror(error: Error): void;\n    onclosetag(): void;\n    onopentag(name: string, attribs: {\n        [key: string]: string;\n    }): void;\n    ontext(data: string): void;\n    oncomment(data: string): void;\n    oncommentend(): void;\n    oncdatastart(): void;\n    oncdataend(): void;\n    onprocessinginstruction(name: string, data: string): void;\n    protected handleCallback(error: Error | null): void;\n    protected addNode(node: ChildNode): void;\n}\nexport default DomHandler;\n//# sourceMappingURL=index.d.ts.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/domhandler/src/index.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { ElementType } from \"../../domelementtype/src\";\nimport { Element, Text, Comment, CDATA, Document, ProcessingInstruction, } from \"./node\";\nexport * from \"./node\";\n// Default options\nconst defaultOpts = {\n    withStartIndices: false,\n    withEndIndices: false,\n    xmlMode: false,\n};\nexport class DomHandler {\n    /**\n     * @param callback Called once parsing has completed.\n     * @param options Settings for the handler.\n     * @param elementCB Callback whenever a tag is closed.\n     */\n    constructor(callback, options, elementCB) {\n        /** The elements of the DOM */\n        this.dom = [];\n        /** The root element for the DOM */\n        this.root = new Document(this.dom);\n        /** Indicated whether parsing has been completed. */\n        this.done = false;\n        /** Stack of open tags. */\n        this.tagStack = [this.root];\n        /** A data node that is still being written to. */\n        this.lastNode = null;\n        /** Reference to the parser instance. Used for location information. */\n        this.parser = null;\n        // Make it possible to skip arguments, for backwards-compatibility\n        if (typeof options === \"function\") {\n            elementCB = options;\n            options = defaultOpts;\n        }\n        if (typeof callback === \"object\") {\n            options = callback;\n            callback = undefined;\n        }\n        this.callback = callback !== null && callback !== void 0 ? callback : null;\n        this.options = options !== null && options !== void 0 ? options : defaultOpts;\n        this.elementCB = elementCB !== null && elementCB !== void 0 ? elementCB : null;\n    }\n    onparserinit(parser) {\n        this.parser = parser;\n    }\n    // Resets the handler back to starting state\n    onreset() {\n        this.dom = [];\n        this.root = new Document(this.dom);\n        this.done = false;\n        this.tagStack = [this.root];\n        this.lastNode = null;\n        this.parser = null;\n    }\n    // Signals the handler that parsing is done\n    onend() {\n        if (this.done)\n            return;\n        this.done = true;\n        this.parser = null;\n        this.handleCallback(null);\n    }\n    onerror(error) {\n        this.handleCallback(error);\n    }\n    onclosetag() {\n        this.lastNode = null;\n        const elem = this.tagStack.pop();\n        if (this.options.withEndIndices) {\n            elem.endIndex = this.parser.endIndex;\n        }\n        if (this.elementCB)\n            this.elementCB(elem);\n    }\n    onopentag(name, attribs) {\n        const type = this.options.xmlMode ? ElementType.Tag : undefined;\n        const element = new Element(name, attribs, undefined, type);\n        this.addNode(element);\n        this.tagStack.push(element);\n    }\n    ontext(data) {\n        const { lastNode } = this;\n        if (lastNode && lastNode.type === ElementType.Text) {\n            lastNode.data += data;\n            if (this.options.withEndIndices) {\n                lastNode.endIndex = this.parser.endIndex;\n            }\n        }\n        else {\n            const node = new Text(data);\n            this.addNode(node);\n            this.lastNode = node;\n        }\n    }\n    oncomment(data) {\n        if (this.lastNode && this.lastNode.type === ElementType.Comment) {\n            this.lastNode.data += data;\n            return;\n        }\n        const node = new Comment(data);\n        this.addNode(node);\n        this.lastNode = node;\n    }\n    oncommentend() {\n        this.lastNode = null;\n    }\n    oncdatastart() {\n        const text = new Text(\"\");\n        const node = new CDATA([text]);\n        this.addNode(node);\n        text.parent = node;\n        this.lastNode = text;\n    }\n    oncdataend() {\n        this.lastNode = null;\n    }\n    onprocessinginstruction(name, data) {\n        const node = new ProcessingInstruction(name, data);\n        this.addNode(node);\n    }\n    handleCallback(error) {\n        if (typeof this.callback === \"function\") {\n            this.callback(error, this.dom);\n        }\n        else if (error) {\n            throw error;\n        }\n    }\n    addNode(node) {\n        const parent = this.tagStack[this.tagStack.length - 1];\n        const previousSibling = parent.children[parent.children.length - 1];\n        if (this.options.withStartIndices) {\n            node.startIndex = this.parser.startIndex;\n        }\n        if (this.options.withEndIndices) {\n            node.endIndex = this.parser.endIndex;\n        }\n        parent.children.push(node);\n        if (previousSibling) {\n            node.prev = previousSibling;\n            previousSibling.next = node;\n        }\n        node.parent = parent;\n        this.lastNode = null;\n    }\n}\nexport default DomHandler;\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/domhandler/src/node.d.ts",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { ElementType } from \"../../domelementtype/src\";\ninterface SourceCodeLocation {\n    /** One-based line index of the first character. */\n    startLine: number;\n    /** One-based column index of the first character. */\n    startCol: number;\n    /** Zero-based first character index. */\n    startOffset: number;\n    /** One-based line index of the last character. */\n    endLine: number;\n    /** One-based column index of the last character. Points directly *after* the last character. */\n    endCol: number;\n    /** Zero-based last character index. Points directly *after* the last character. */\n    endOffset: number;\n}\ninterface TagSourceCodeLocation extends SourceCodeLocation {\n    startTag?: SourceCodeLocation;\n    endTag?: SourceCodeLocation;\n}\n/**\n * A node that can have children.\n */\nexport type ParentNode = Document | Element | CDATA;\n/**\n * A node that can have a parent.\n */\nexport type ChildNode = Text | Comment | ProcessingInstruction | Element | CDATA | Document;\nexport type AnyNode = ParentNode | ChildNode;\n/**\n * This object will be used as the prototype for Nodes when creating a\n * DOM-Level-1-compliant structure.\n */\nexport declare abstract class Node {\n    /** The type of the node. */\n    abstract readonly type: ElementType;\n    /** Parent of the node */\n    parent: ParentNode | null;\n    /** Previous sibling */\n    prev: ChildNode | null;\n    /** Next sibling */\n    next: ChildNode | null;\n    /** The start index of the node. Requires `withStartIndices` on the handler to be `true. */\n    startIndex: number | null;\n    /** The end index of the node. Requires `withEndIndices` on the handler to be `true. */\n    endIndex: number | null;\n    /**\n     * `parse5` source code location info.\n     *\n     * Available if parsing with parse5 and location info is enabled.\n     */\n    sourceCodeLocation?: SourceCodeLocation | null;\n    /**\n     * [DOM spec](https://dom.spec.whatwg.org/#dom-node-nodetype)-compatible\n     * node {@link type}.\n     */\n    abstract readonly nodeType: number;\n    /**\n     * Same as {@link parent}.\n     * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.\n     */\n    get parentNode(): ParentNode | null;\n    set parentNode(parent: ParentNode | null);\n    /**\n     * Same as {@link prev}.\n     * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.\n     */\n    get previousSibling(): ChildNode | null;\n    set previousSibling(prev: ChildNode | null);\n    /**\n     * Same as {@link next}.\n     * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.\n     */\n    get nextSibling(): ChildNode | null;\n    set nextSibling(next: ChildNode | null);\n    /**\n     * Clone this node, and optionally its children.\n     *\n     * @param recursive Clone child nodes as well.\n     * @returns A clone of the node.\n     */\n    cloneNode<T extends Node>(this: T, recursive?: boolean): T;\n}\n/**\n * A node that contains some data.\n */\nexport declare abstract class DataNode extends Node {\n    data: string;\n    /**\n     * @param data The content of the data node\n     */\n    constructor(data: string);\n    /**\n     * Same as {@link data}.\n     * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.\n     */\n    get nodeValue(): string;\n    set nodeValue(data: string);\n}\n/**\n * Text within the document.\n */\nexport declare class Text extends DataNode {\n    type: ElementType.Text;\n    get nodeType(): 3;\n}\n/**\n * Comments within the document.\n */\nexport declare class Comment extends DataNode {\n    type: ElementType.Comment;\n    get nodeType(): 8;\n}\n/**\n * Processing instructions, including doc types.\n */\nexport declare class ProcessingInstruction extends DataNode {\n    name: string;\n    type: ElementType.Directive;\n    constructor(name: string, data: string);\n    get nodeType(): 1;\n    /** If this is a doctype, the document type name (parse5 only). */\n    \"x-name\"?: string;\n    /** If this is a doctype, the document type public identifier (parse5 only). */\n    \"x-publicId\"?: string;\n    /** If this is a doctype, the document type system identifier (parse5 only). */\n    \"x-systemId\"?: string;\n}\n/**\n * A node that can have children.\n */\nexport declare abstract class NodeWithChildren extends Node {\n    children: ChildNode[];\n    /**\n     * @param children Children of the node. Only certain node types can have children.\n     */\n    constructor(children: ChildNode[]);\n    /** First child of the node. */\n    get firstChild(): ChildNode | null;\n    /** Last child of the node. */\n    get lastChild(): ChildNode | null;\n    /**\n     * Same as {@link children}.\n     * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.\n     */\n    get childNodes(): ChildNode[];\n    set childNodes(children: ChildNode[]);\n}\n/**\n * CDATA nodes.\n */\nexport declare class CDATA extends NodeWithChildren {\n    type: ElementType.CDATA;\n    get nodeType(): 4;\n}\n/**\n * The root node of the document.\n */\nexport declare class Document extends NodeWithChildren {\n    type: ElementType.Root;\n    get nodeType(): 9;\n    /** [Document mode](https://dom.spec.whatwg.org/#concept-document-limited-quirks) (parse5 only). */\n    \"x-mode\"?: \"no-quirks\" | \"quirks\" | \"limited-quirks\";\n}\n/**\n * The description of an individual attribute.\n */\ninterface Attribute {\n    name: string;\n    value: string;\n    namespace?: string;\n    prefix?: string;\n}\n/**\n * An element within the DOM.\n */\nexport declare class Element extends NodeWithChildren {\n    name: string;\n    attribs: {\n        [name: string]: string;\n    };\n    type: ElementType.Tag | ElementType.Script | ElementType.Style;\n    /**\n     * @param name Name of the tag, eg. `div`, `span`.\n     * @param attribs Object mapping attribute names to attribute values.\n     * @param children Children of the node.\n     */\n    constructor(name: string, attribs: {\n        [name: string]: string;\n    }, children?: ChildNode[], type?: ElementType.Tag | ElementType.Script | ElementType.Style);\n    get nodeType(): 1;\n    /**\n     * `parse5` source code location info, with start & end tags.\n     *\n     * Available if parsing with parse5 and location info is enabled.\n     */\n    sourceCodeLocation?: TagSourceCodeLocation | null;\n    /**\n     * Same as {@link name}.\n     * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.\n     */\n    get tagName(): string;\n    set tagName(name: string);\n    get attributes(): Attribute[];\n    /** Element namespace (parse5 only). */\n    namespace?: string;\n    /** Element attribute namespaces (parse5 only). */\n    \"x-attribsNamespace\"?: Record<string, string>;\n    /** Element attribute namespace-related prefixes (parse5 only). */\n    \"x-attribsPrefix\"?: Record<string, string>;\n}\n/**\n * Checks if `node` is an element node.\n *\n * @param node Node to check.\n * @returns `true` if the node is an element node.\n */\nexport declare function isTag(node: Node): node is Element;\n/**\n * Checks if `node` is a CDATA node.\n *\n * @param node Node to check.\n * @returns `true` if the node is a CDATA node.\n */\nexport declare function isCDATA(node: Node): node is CDATA;\n/**\n * Checks if `node` is a text node.\n *\n * @param node Node to check.\n * @returns `true` if the node is a text node.\n */\nexport declare function isText(node: Node): node is Text;\n/**\n * Checks if `node` is a comment node.\n *\n * @param node Node to check.\n * @returns `true` if the node is a comment node.\n */\nexport declare function isComment(node: Node): node is Comment;\n/**\n * Checks if `node` is a directive node.\n *\n * @param node Node to check.\n * @returns `true` if the node is a directive node.\n */\nexport declare function isDirective(node: Node): node is ProcessingInstruction;\n/**\n * Checks if `node` is a document node.\n *\n * @param node Node to check.\n * @returns `true` if the node is a document node.\n */\nexport declare function isDocument(node: Node): node is Document;\n/**\n * Checks if `node` has children.\n *\n * @param node Node to check.\n * @returns `true` if the node has children.\n */\nexport declare function hasChildren(node: Node): node is ParentNode;\n/**\n * Clone a node, and optionally its children.\n *\n * @param recursive Clone child nodes as well.\n * @returns A clone of the node.\n */\nexport declare function cloneNode<T extends Node>(node: T, recursive?: boolean): T;\nexport {};\n//# sourceMappingURL=node.d.ts.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/domhandler/src/node.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { ElementType, isTag as isTagRaw } from \"../../domelementtype/src\";\n/**\n * This object will be used as the prototype for Nodes when creating a\n * DOM-Level-1-compliant structure.\n */\nexport class Node {\n    constructor() {\n        /** Parent of the node */\n        this.parent = null;\n        /** Previous sibling */\n        this.prev = null;\n        /** Next sibling */\n        this.next = null;\n        /** The start index of the node. Requires `withStartIndices` on the handler to be `true. */\n        this.startIndex = null;\n        /** The end index of the node. Requires `withEndIndices` on the handler to be `true. */\n        this.endIndex = null;\n    }\n    // Read-write aliases for properties\n    /**\n     * Same as {@link parent}.\n     * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.\n     */\n    get parentNode() {\n        return this.parent;\n    }\n    set parentNode(parent) {\n        this.parent = parent;\n    }\n    /**\n     * Same as {@link prev}.\n     * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.\n     */\n    get previousSibling() {\n        return this.prev;\n    }\n    set previousSibling(prev) {\n        this.prev = prev;\n    }\n    /**\n     * Same as {@link next}.\n     * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.\n     */\n    get nextSibling() {\n        return this.next;\n    }\n    set nextSibling(next) {\n        this.next = next;\n    }\n    /**\n     * Clone this node, and optionally its children.\n     *\n     * @param recursive Clone child nodes as well.\n     * @returns A clone of the node.\n     */\n    cloneNode(recursive = false) {\n        return cloneNode(this, recursive);\n    }\n}\n/**\n * A node that contains some data.\n */\nexport class DataNode extends Node {\n    /**\n     * @param data The content of the data node\n     */\n    constructor(data) {\n        super();\n        this.data = data;\n    }\n    /**\n     * Same as {@link data}.\n     * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.\n     */\n    get nodeValue() {\n        return this.data;\n    }\n    set nodeValue(data) {\n        this.data = data;\n    }\n}\n/**\n * Text within the document.\n */\nexport class Text extends DataNode {\n    constructor() {\n        super(...arguments);\n        this.type = ElementType.Text;\n    }\n    get nodeType() {\n        return 3;\n    }\n}\n/**\n * Comments within the document.\n */\nexport class Comment extends DataNode {\n    constructor() {\n        super(...arguments);\n        this.type = ElementType.Comment;\n    }\n    get nodeType() {\n        return 8;\n    }\n}\n/**\n * Processing instructions, including doc types.\n */\nexport class ProcessingInstruction extends DataNode {\n    constructor(name, data) {\n        super(data);\n        this.name = name;\n        this.type = ElementType.Directive;\n    }\n    get nodeType() {\n        return 1;\n    }\n}\n/**\n * A node that can have children.\n */\nexport class NodeWithChildren extends Node {\n    /**\n     * @param children Children of the node. Only certain node types can have children.\n     */\n    constructor(children) {\n        super();\n        this.children = children;\n    }\n    // Aliases\n    /** First child of the node. */\n    get firstChild() {\n        var _a;\n        return (_a = this.children[0]) !== null && _a !== void 0 ? _a : null;\n    }\n    /** Last child of the node. */\n    get lastChild() {\n        return this.children.length > 0\n            ? this.children[this.children.length - 1]\n            : null;\n    }\n    /**\n     * Same as {@link children}.\n     * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.\n     */\n    get childNodes() {\n        return this.children;\n    }\n    set childNodes(children) {\n        this.children = children;\n    }\n}\n/**\n * CDATA nodes.\n */\nexport class CDATA extends NodeWithChildren {\n    constructor() {\n        super(...arguments);\n        this.type = ElementType.CDATA;\n    }\n    get nodeType() {\n        return 4;\n    }\n}\n/**\n * The root node of the document.\n */\nexport class Document extends NodeWithChildren {\n    constructor() {\n        super(...arguments);\n        this.type = ElementType.Root;\n    }\n    get nodeType() {\n        return 9;\n    }\n}\n/**\n * An element within the DOM.\n */\nexport class Element extends NodeWithChildren {\n    /**\n     * @param name Name of the tag, eg. `div`, `span`.\n     * @param attribs Object mapping attribute names to attribute values.\n     * @param children Children of the node.\n     */\n    constructor(name, attribs, children = [], type = name === \"script\"\n        ? ElementType.Script\n        : name === \"style\"\n            ? ElementType.Style\n            : ElementType.Tag) {\n        super(children);\n        this.name = name;\n        this.attribs = attribs;\n        this.type = type;\n    }\n    get nodeType() {\n        return 1;\n    }\n    // DOM Level 1 aliases\n    /**\n     * Same as {@link name}.\n     * [DOM spec](https://dom.spec.whatwg.org)-compatible alias.\n     */\n    get tagName() {\n        return this.name;\n    }\n    set tagName(name) {\n        this.name = name;\n    }\n    get attributes() {\n        return Object.keys(this.attribs).map((name) => {\n            var _a, _b;\n            return ({\n                name,\n                value: this.attribs[name],\n                namespace: (_a = this[\"x-attribsNamespace\"]) === null || _a === void 0 ? void 0 : _a[name],\n                prefix: (_b = this[\"x-attribsPrefix\"]) === null || _b === void 0 ? void 0 : _b[name],\n            });\n        });\n    }\n}\n/**\n * Checks if `node` is an element node.\n *\n * @param node Node to check.\n * @returns `true` if the node is an element node.\n */\nexport function isTag(node) {\n    return isTagRaw(node);\n}\n/**\n * Checks if `node` is a CDATA node.\n *\n * @param node Node to check.\n * @returns `true` if the node is a CDATA node.\n */\nexport function isCDATA(node) {\n    return node.type === ElementType.CDATA;\n}\n/**\n * Checks if `node` is a text node.\n *\n * @param node Node to check.\n * @returns `true` if the node is a text node.\n */\nexport function isText(node) {\n    return node.type === ElementType.Text;\n}\n/**\n * Checks if `node` is a comment node.\n *\n * @param node Node to check.\n * @returns `true` if the node is a comment node.\n */\nexport function isComment(node) {\n    return node.type === ElementType.Comment;\n}\n/**\n * Checks if `node` is a directive node.\n *\n * @param node Node to check.\n * @returns `true` if the node is a directive node.\n */\nexport function isDirective(node) {\n    return node.type === ElementType.Directive;\n}\n/**\n * Checks if `node` is a document node.\n *\n * @param node Node to check.\n * @returns `true` if the node is a document node.\n */\nexport function isDocument(node) {\n    return node.type === ElementType.Root;\n}\n/**\n * Checks if `node` has children.\n *\n * @param node Node to check.\n * @returns `true` if the node has children.\n */\nexport function hasChildren(node) {\n    return Object.prototype.hasOwnProperty.call(node, \"children\");\n}\n/**\n * Clone a node, and optionally its children.\n *\n * @param recursive Clone child nodes as well.\n * @returns A clone of the node.\n */\nexport function cloneNode(node, recursive = false) {\n    let result;\n    if (isText(node)) {\n        result = new Text(node.data);\n    }\n    else if (isComment(node)) {\n        result = new Comment(node.data);\n    }\n    else if (isTag(node)) {\n        const children = recursive ? cloneChildren(node.children) : [];\n        const clone = new Element(node.name, { ...node.attribs }, children);\n        children.forEach((child) => (child.parent = clone));\n        if (node.namespace != null) {\n            clone.namespace = node.namespace;\n        }\n        if (node[\"x-attribsNamespace\"]) {\n            clone[\"x-attribsNamespace\"] = { ...node[\"x-attribsNamespace\"] };\n        }\n        if (node[\"x-attribsPrefix\"]) {\n            clone[\"x-attribsPrefix\"] = { ...node[\"x-attribsPrefix\"] };\n        }\n        result = clone;\n    }\n    else if (isCDATA(node)) {\n        const children = recursive ? cloneChildren(node.children) : [];\n        const clone = new CDATA(children);\n        children.forEach((child) => (child.parent = clone));\n        result = clone;\n    }\n    else if (isDocument(node)) {\n        const children = recursive ? cloneChildren(node.children) : [];\n        const clone = new Document(children);\n        children.forEach((child) => (child.parent = clone));\n        if (node[\"x-mode\"]) {\n            clone[\"x-mode\"] = node[\"x-mode\"];\n        }\n        result = clone;\n    }\n    else if (isDirective(node)) {\n        const instruction = new ProcessingInstruction(node.name, node.data);\n        if (node[\"x-name\"] != null) {\n            instruction[\"x-name\"] = node[\"x-name\"];\n            instruction[\"x-publicId\"] = node[\"x-publicId\"];\n            instruction[\"x-systemId\"] = node[\"x-systemId\"];\n        }\n        result = instruction;\n    }\n    else {\n        throw new Error(`Not implemented yet: ${node.type}`);\n    }\n    result.startIndex = node.startIndex;\n    result.endIndex = node.endIndex;\n    if (node.sourceCodeLocation != null) {\n        result.sourceCodeLocation = node.sourceCodeLocation;\n    }\n    return result;\n}\n/**\n * Clone a list of child nodes.\n *\n * @param childs The child nodes to clone.\n * @returns A list of cloned child nodes.\n */\nfunction cloneChildren(childs) {\n    const children = childs.map((child) => cloneNode(child, true));\n    for (let i = 1; i < children.length; i++) {\n        children[i].prev = children[i - 1];\n        children[i - 1].next = children[i];\n    }\n    return children;\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/domutils/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/**\n * domutils\n * @home   : https://github.com/fb55/domutils\n * @branch : master\n * @commit : 1f562c7052b40efe0eeb7bbcb2be1fb086054c74\n */\n\nexport * from './src';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/domutils/src/feeds.d.ts",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport type { AnyNode } from \"../../domhandler/src\";\n/**\n * The medium of a media item.\n *\n * @category Feeds\n */\nexport type FeedItemMediaMedium = \"image\" | \"audio\" | \"video\" | \"document\" | \"executable\";\n/**\n * The type of a media item.\n *\n * @category Feeds\n */\nexport type FeedItemMediaExpression = \"sample\" | \"full\" | \"nonstop\";\n/**\n * A media item of a feed entry.\n *\n * @category Feeds\n */\nexport interface FeedItemMedia {\n    medium: FeedItemMediaMedium | undefined;\n    isDefault: boolean;\n    url?: string;\n    fileSize?: number;\n    type?: string;\n    expression?: FeedItemMediaExpression;\n    bitrate?: number;\n    framerate?: number;\n    samplingrate?: number;\n    channels?: number;\n    duration?: number;\n    height?: number;\n    width?: number;\n    lang?: string;\n}\n/**\n * An entry of a feed.\n *\n * @category Feeds\n */\nexport interface FeedItem {\n    id?: string;\n    title?: string;\n    link?: string;\n    description?: string;\n    pubDate?: Date;\n    media: FeedItemMedia[];\n}\n/**\n * The root of a feed.\n *\n * @category Feeds\n */\nexport interface Feed {\n    type: string;\n    id?: string;\n    title?: string;\n    link?: string;\n    description?: string;\n    updated?: Date;\n    author?: string;\n    items: FeedItem[];\n}\n/**\n * Get the feed object from the root of a DOM tree.\n *\n * @category Feeds\n * @param doc - The DOM to to extract the feed from.\n * @returns The feed.\n */\nexport declare function getFeed(doc: AnyNode[]): Feed | null;\n//# sourceMappingURL=feeds.d.ts.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/domutils/src/feeds.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { textContent } from \"./stringify\";\nimport { getElementsByTagName } from \"./legacy\";\n/**\n * Get the feed object from the root of a DOM tree.\n *\n * @category Feeds\n * @param doc - The DOM to to extract the feed from.\n * @returns The feed.\n */\nexport function getFeed(doc) {\n    const feedRoot = getOneElement(isValidFeed, doc);\n    return !feedRoot\n        ? null\n        : feedRoot.name === \"feed\"\n            ? getAtomFeed(feedRoot)\n            : getRssFeed(feedRoot);\n}\n/**\n * Parse an Atom feed.\n *\n * @param feedRoot The root of the feed.\n * @returns The parsed feed.\n */\nfunction getAtomFeed(feedRoot) {\n    var _a;\n    const childs = feedRoot.children;\n    const feed = {\n        type: \"atom\",\n        items: getElementsByTagName(\"entry\", childs).map((item) => {\n            var _a;\n            const { children } = item;\n            const entry = { media: getMediaElements(children) };\n            addConditionally(entry, \"id\", \"id\", children);\n            addConditionally(entry, \"title\", \"title\", children);\n            const href = (_a = getOneElement(\"link\", children)) === null || _a === void 0 ? void 0 : _a.attribs[\"href\"];\n            if (href) {\n                entry.link = href;\n            }\n            const description = fetch(\"summary\", children) || fetch(\"content\", children);\n            if (description) {\n                entry.description = description;\n            }\n            const pubDate = fetch(\"updated\", children);\n            if (pubDate) {\n                entry.pubDate = new Date(pubDate);\n            }\n            return entry;\n        }),\n    };\n    addConditionally(feed, \"id\", \"id\", childs);\n    addConditionally(feed, \"title\", \"title\", childs);\n    const href = (_a = getOneElement(\"link\", childs)) === null || _a === void 0 ? void 0 : _a.attribs[\"href\"];\n    if (href) {\n        feed.link = href;\n    }\n    addConditionally(feed, \"description\", \"subtitle\", childs);\n    const updated = fetch(\"updated\", childs);\n    if (updated) {\n        feed.updated = new Date(updated);\n    }\n    addConditionally(feed, \"author\", \"email\", childs, true);\n    return feed;\n}\n/**\n * Parse a RSS feed.\n *\n * @param feedRoot The root of the feed.\n * @returns The parsed feed.\n */\nfunction getRssFeed(feedRoot) {\n    var _a, _b;\n    const childs = (_b = (_a = getOneElement(\"channel\", feedRoot.children)) === null || _a === void 0 ? void 0 : _a.children) !== null && _b !== void 0 ? _b : [];\n    const feed = {\n        type: feedRoot.name.substr(0, 3),\n        id: \"\",\n        items: getElementsByTagName(\"item\", feedRoot.children).map((item) => {\n            const { children } = item;\n            const entry = { media: getMediaElements(children) };\n            addConditionally(entry, \"id\", \"guid\", children);\n            addConditionally(entry, \"title\", \"title\", children);\n            addConditionally(entry, \"link\", \"link\", children);\n            addConditionally(entry, \"description\", \"description\", children);\n            const pubDate = fetch(\"pubDate\", children) || fetch(\"dc:date\", children);\n            if (pubDate)\n                entry.pubDate = new Date(pubDate);\n            return entry;\n        }),\n    };\n    addConditionally(feed, \"title\", \"title\", childs);\n    addConditionally(feed, \"link\", \"link\", childs);\n    addConditionally(feed, \"description\", \"description\", childs);\n    const updated = fetch(\"lastBuildDate\", childs);\n    if (updated) {\n        feed.updated = new Date(updated);\n    }\n    addConditionally(feed, \"author\", \"managingEditor\", childs, true);\n    return feed;\n}\nconst MEDIA_KEYS_STRING = [\"url\", \"type\", \"lang\"];\nconst MEDIA_KEYS_INT = [\n    \"fileSize\",\n    \"bitrate\",\n    \"framerate\",\n    \"samplingrate\",\n    \"channels\",\n    \"duration\",\n    \"height\",\n    \"width\",\n];\n/**\n * Get all media elements of a feed item.\n *\n * @param where Nodes to search in.\n * @returns Media elements.\n */\nfunction getMediaElements(where) {\n    return getElementsByTagName(\"media:content\", where).map((elem) => {\n        const { attribs } = elem;\n        const media = {\n            medium: attribs[\"medium\"],\n            isDefault: !!attribs[\"isDefault\"],\n        };\n        for (const attrib of MEDIA_KEYS_STRING) {\n            if (attribs[attrib]) {\n                media[attrib] = attribs[attrib];\n            }\n        }\n        for (const attrib of MEDIA_KEYS_INT) {\n            if (attribs[attrib]) {\n                media[attrib] = parseInt(attribs[attrib], 10);\n            }\n        }\n        if (attribs[\"expression\"]) {\n            media.expression = attribs[\"expression\"];\n        }\n        return media;\n    });\n}\n/**\n * Get one element by tag name.\n *\n * @param tagName Tag name to look for\n * @param node Node to search in\n * @returns The element or null\n */\nfunction getOneElement(tagName, node) {\n    return getElementsByTagName(tagName, node, true, 1)[0];\n}\n/**\n * Get the text content of an element with a certain tag name.\n *\n * @param tagName Tag name to look for.\n * @param where Node to search in.\n * @param recurse Whether to recurse into child nodes.\n * @returns The text content of the element.\n */\nfunction fetch(tagName, where, recurse = false) {\n    return textContent(getElementsByTagName(tagName, where, recurse, 1)).trim();\n}\n/**\n * Adds a property to an object if it has a value.\n *\n * @param obj Object to be extended\n * @param prop Property name\n * @param tagName Tag name that contains the conditionally added property\n * @param where Element to search for the property\n * @param recurse Whether to recurse into child nodes.\n */\nfunction addConditionally(obj, prop, tagName, where, recurse = false) {\n    const val = fetch(tagName, where, recurse);\n    if (val)\n        obj[prop] = val;\n}\n/**\n * Checks if an element is a feed root node.\n *\n * @param value The name of the element to check.\n * @returns Whether an element is a feed root node.\n */\nfunction isValidFeed(value) {\n    return value === \"rss\" || value === \"feed\" || value === \"rdf:RDF\";\n}\n//# sourceMappingURL=feeds.js.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/domutils/src/helpers.d.ts",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { AnyNode } from \"../../domhandler/src\";\n/**\n * Given an array of nodes, remove any member that is contained by another\n * member.\n *\n * @category Helpers\n * @param nodes Nodes to filter.\n * @returns Remaining nodes that aren't contained by other nodes.\n */\nexport declare function removeSubsets(nodes: AnyNode[]): AnyNode[];\n/**\n * @category Helpers\n * @see {@link http://dom.spec.whatwg.org/#dom-node-comparedocumentposition}\n */\nexport declare const enum DocumentPosition {\n    DISCONNECTED = 1,\n    PRECEDING = 2,\n    FOLLOWING = 4,\n    CONTAINS = 8,\n    CONTAINED_BY = 16\n}\n/**\n * Compare the position of one node against another node in any other document,\n * returning a bitmask with the values from {@link DocumentPosition}.\n *\n * Document order:\n * > There is an ordering, document order, defined on all the nodes in the\n * > document corresponding to the order in which the first character of the\n * > XML representation of each node occurs in the XML representation of the\n * > document after expansion of general entities. Thus, the document element\n * > node will be the first node. Element nodes occur before their children.\n * > Thus, document order orders element nodes in order of the occurrence of\n * > their start-tag in the XML (after expansion of entities). The attribute\n * > nodes of an element occur after the element and before its children. The\n * > relative order of attribute nodes is implementation-dependent.\n *\n * Source:\n * http://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-document-order\n *\n * @category Helpers\n * @param nodeA The first node to use in the comparison\n * @param nodeB The second node to use in the comparison\n * @returns A bitmask describing the input nodes' relative position.\n *\n * See http://dom.spec.whatwg.org/#dom-node-comparedocumentposition for\n * a description of these values.\n */\nexport declare function compareDocumentPosition(nodeA: AnyNode, nodeB: AnyNode): number;\n/**\n * Sort an array of nodes based on their relative position in the document,\n * removing any duplicate nodes. If the array contains nodes that do not belong\n * to the same document, sort order is unspecified.\n *\n * @category Helpers\n * @param nodes Array of DOM nodes.\n * @returns Collection of unique nodes, sorted in document order.\n */\nexport declare function uniqueSort<T extends AnyNode>(nodes: T[]): T[];\n//# sourceMappingURL=helpers.d.ts.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/domutils/src/helpers.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { hasChildren } from \"../../domhandler/src\";\n/**\n * Given an array of nodes, remove any member that is contained by another\n * member.\n *\n * @category Helpers\n * @param nodes Nodes to filter.\n * @returns Remaining nodes that aren't contained by other nodes.\n */\nexport function removeSubsets(nodes) {\n    let idx = nodes.length;\n    /*\n     * Check if each node (or one of its ancestors) is already contained in the\n     * array.\n     */\n    while (--idx >= 0) {\n        const node = nodes[idx];\n        /*\n         * Remove the node if it is not unique.\n         * We are going through the array from the end, so we only\n         * have to check nodes that preceed the node under consideration in the array.\n         */\n        if (idx > 0 && nodes.lastIndexOf(node, idx - 1) >= 0) {\n            nodes.splice(idx, 1);\n            continue;\n        }\n        for (let ancestor = node.parent; ancestor; ancestor = ancestor.parent) {\n            if (nodes.includes(ancestor)) {\n                nodes.splice(idx, 1);\n                break;\n            }\n        }\n    }\n    return nodes;\n}\n/**\n * @category Helpers\n * @see {@link http://dom.spec.whatwg.org/#dom-node-comparedocumentposition}\n */\nexport var DocumentPosition;\n(function (DocumentPosition) {\n    DocumentPosition[DocumentPosition[\"DISCONNECTED\"] = 1] = \"DISCONNECTED\";\n    DocumentPosition[DocumentPosition[\"PRECEDING\"] = 2] = \"PRECEDING\";\n    DocumentPosition[DocumentPosition[\"FOLLOWING\"] = 4] = \"FOLLOWING\";\n    DocumentPosition[DocumentPosition[\"CONTAINS\"] = 8] = \"CONTAINS\";\n    DocumentPosition[DocumentPosition[\"CONTAINED_BY\"] = 16] = \"CONTAINED_BY\";\n})(DocumentPosition || (DocumentPosition = {}));\n/**\n * Compare the position of one node against another node in any other document,\n * returning a bitmask with the values from {@link DocumentPosition}.\n *\n * Document order:\n * > There is an ordering, document order, defined on all the nodes in the\n * > document corresponding to the order in which the first character of the\n * > XML representation of each node occurs in the XML representation of the\n * > document after expansion of general entities. Thus, the document element\n * > node will be the first node. Element nodes occur before their children.\n * > Thus, document order orders element nodes in order of the occurrence of\n * > their start-tag in the XML (after expansion of entities). The attribute\n * > nodes of an element occur after the element and before its children. The\n * > relative order of attribute nodes is implementation-dependent.\n *\n * Source:\n * http://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-document-order\n *\n * @category Helpers\n * @param nodeA The first node to use in the comparison\n * @param nodeB The second node to use in the comparison\n * @returns A bitmask describing the input nodes' relative position.\n *\n * See http://dom.spec.whatwg.org/#dom-node-comparedocumentposition for\n * a description of these values.\n */\nexport function compareDocumentPosition(nodeA, nodeB) {\n    const aParents = [];\n    const bParents = [];\n    if (nodeA === nodeB) {\n        return 0;\n    }\n    let current = hasChildren(nodeA) ? nodeA : nodeA.parent;\n    while (current) {\n        aParents.unshift(current);\n        current = current.parent;\n    }\n    current = hasChildren(nodeB) ? nodeB : nodeB.parent;\n    while (current) {\n        bParents.unshift(current);\n        current = current.parent;\n    }\n    const maxIdx = Math.min(aParents.length, bParents.length);\n    let idx = 0;\n    while (idx < maxIdx && aParents[idx] === bParents[idx]) {\n        idx++;\n    }\n    if (idx === 0) {\n        return DocumentPosition.DISCONNECTED;\n    }\n    const sharedParent = aParents[idx - 1];\n    const siblings = sharedParent.children;\n    const aSibling = aParents[idx];\n    const bSibling = bParents[idx];\n    if (siblings.indexOf(aSibling) > siblings.indexOf(bSibling)) {\n        if (sharedParent === nodeB) {\n            return DocumentPosition.FOLLOWING | DocumentPosition.CONTAINED_BY;\n        }\n        return DocumentPosition.FOLLOWING;\n    }\n    if (sharedParent === nodeA) {\n        return DocumentPosition.PRECEDING | DocumentPosition.CONTAINS;\n    }\n    return DocumentPosition.PRECEDING;\n}\n/**\n * Sort an array of nodes based on their relative position in the document,\n * removing any duplicate nodes. If the array contains nodes that do not belong\n * to the same document, sort order is unspecified.\n *\n * @category Helpers\n * @param nodes Array of DOM nodes.\n * @returns Collection of unique nodes, sorted in document order.\n */\nexport function uniqueSort(nodes) {\n    nodes = nodes.filter((node, i, arr) => !arr.includes(node, i + 1));\n    nodes.sort((a, b) => {\n        const relative = compareDocumentPosition(a, b);\n        if (relative & DocumentPosition.PRECEDING) {\n            return -1;\n        }\n        else if (relative & DocumentPosition.FOLLOWING) {\n            return 1;\n        }\n        return 0;\n    });\n    return nodes;\n}\n//# sourceMappingURL=helpers.js.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/domutils/src/index.d.ts",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport * from \"./stringify\";\nexport * from \"./traversal\";\nexport * from \"./manipulation\";\nexport * from \"./querying\";\nexport * from \"./legacy\";\nexport * from \"./helpers\";\nexport * from \"./feeds\";\n/** @deprecated Use these methods from `domhandler` directly. */\nexport { isTag, isCDATA, isText, isComment, isDocument, hasChildren, } from \"../../domhandler/src\";\n//# sourceMappingURL=index.d.ts.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/domutils/src/index.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport * from \"./stringify\";\nexport * from \"./traversal\";\nexport * from \"./manipulation\";\nexport * from \"./querying\";\nexport * from \"./legacy\";\nexport * from \"./helpers\";\nexport * from \"./feeds.js\";\n/** @deprecated Use these methods from `domhandler` directly. */\nexport { isTag, isCDATA, isText, isComment, isDocument, hasChildren, } from \"../../domhandler/src\";\n//# sourceMappingURL=index.js.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/domutils/src/legacy.d.ts",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { AnyNode, Element } from \"../../domhandler/src\";\nimport type { ElementType } from \"../../domelementtype/src\";\n/**\n * An object with keys to check elements against. If a key is `tag_name`,\n * `tag_type` or `tag_contains`, it will check the value against that specific\n * value. Otherwise, it will check an attribute with the key's name.\n *\n * @category Legacy Query Functions\n */\nexport interface TestElementOpts {\n    tag_name?: string | ((name: string) => boolean);\n    tag_type?: string | ((name: string) => boolean);\n    tag_contains?: string | ((data?: string) => boolean);\n    [attributeName: string]: undefined | string | ((attributeValue: string) => boolean);\n}\n/**\n * Checks whether a node matches the description in `options`.\n *\n * @category Legacy Query Functions\n * @param options An object describing nodes to look for.\n * @param node The element to test.\n * @returns Whether the element matches the description in `options`.\n */\nexport declare function testElement(options: TestElementOpts, node: AnyNode): boolean;\n/**\n * Returns all nodes that match `options`.\n *\n * @category Legacy Query Functions\n * @param options An object describing nodes to look for.\n * @param nodes Nodes to search through.\n * @param recurse Also consider child nodes.\n * @param limit Maximum number of nodes to return.\n * @returns All nodes that match `options`.\n */\nexport declare function getElements(options: TestElementOpts, nodes: AnyNode | AnyNode[], recurse: boolean, limit?: number): AnyNode[];\n/**\n * Returns the node with the supplied ID.\n *\n * @category Legacy Query Functions\n * @param id The unique ID attribute value to look for.\n * @param nodes Nodes to search through.\n * @param recurse Also consider child nodes.\n * @returns The node with the supplied ID.\n */\nexport declare function getElementById(id: string | ((id: string) => boolean), nodes: AnyNode | AnyNode[], recurse?: boolean): Element | null;\n/**\n * Returns all nodes with the supplied `tagName`.\n *\n * @category Legacy Query Functions\n * @param tagName Tag name to search for.\n * @param nodes Nodes to search through.\n * @param recurse Also consider child nodes.\n * @param limit Maximum number of nodes to return.\n * @returns All nodes with the supplied `tagName`.\n */\nexport declare function getElementsByTagName(tagName: string | ((name: string) => boolean), nodes: AnyNode | AnyNode[], recurse?: boolean, limit?: number): Element[];\n/**\n * Returns all nodes with the supplied `className`.\n *\n * @category Legacy Query Functions\n * @param className Class name to search for.\n * @param nodes Nodes to search through.\n * @param recurse Also consider child nodes.\n * @param limit Maximum number of nodes to return.\n * @returns All nodes with the supplied `className`.\n */\nexport declare function getElementsByClassName(className: string | ((name: string) => boolean), nodes: AnyNode | AnyNode[], recurse?: boolean, limit?: number): Element[];\n/**\n * Returns all nodes with the supplied `type`.\n *\n * @category Legacy Query Functions\n * @param type Element type to look for.\n * @param nodes Nodes to search through.\n * @param recurse Also consider child nodes.\n * @param limit Maximum number of nodes to return.\n * @returns All nodes with the supplied `type`.\n */\nexport declare function getElementsByTagType(type: ElementType | ((type: ElementType) => boolean), nodes: AnyNode | AnyNode[], recurse?: boolean, limit?: number): AnyNode[];\n//# sourceMappingURL=legacy.d.ts.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/domutils/src/legacy.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { isTag, isText } from \"../../domhandler/src\";\nimport { filter, findOne } from \"./querying.js\";\n/**\n * A map of functions to check nodes against.\n */\nconst Checks = {\n    tag_name(name) {\n        if (typeof name === \"function\") {\n            return (elem) => isTag(elem) && name(elem.name);\n        }\n        else if (name === \"*\") {\n            return isTag;\n        }\n        return (elem) => isTag(elem) && elem.name === name;\n    },\n    tag_type(type) {\n        if (typeof type === \"function\") {\n            return (elem) => type(elem.type);\n        }\n        return (elem) => elem.type === type;\n    },\n    tag_contains(data) {\n        if (typeof data === \"function\") {\n            return (elem) => isText(elem) && data(elem.data);\n        }\n        return (elem) => isText(elem) && elem.data === data;\n    },\n};\n/**\n * Returns a function to check whether a node has an attribute with a particular\n * value.\n *\n * @param attrib Attribute to check.\n * @param value Attribute value to look for.\n * @returns A function to check whether the a node has an attribute with a\n *   particular value.\n */\nfunction getAttribCheck(attrib, value) {\n    if (typeof value === \"function\") {\n        return (elem) => isTag(elem) && value(elem.attribs[attrib]);\n    }\n    return (elem) => isTag(elem) && elem.attribs[attrib] === value;\n}\n/**\n * Returns a function that returns `true` if either of the input functions\n * returns `true` for a node.\n *\n * @param a First function to combine.\n * @param b Second function to combine.\n * @returns A function taking a node and returning `true` if either of the input\n *   functions returns `true` for the node.\n */\nfunction combineFuncs(a, b) {\n    return (elem) => a(elem) || b(elem);\n}\n/**\n * Returns a function that executes all checks in `options` and returns `true`\n * if any of them match a node.\n *\n * @param options An object describing nodes to look for.\n * @returns A function that executes all checks in `options` and returns `true`\n *   if any of them match a node.\n */\nfunction compileTest(options) {\n    const funcs = Object.keys(options).map((key) => {\n        const value = options[key];\n        return Object.prototype.hasOwnProperty.call(Checks, key)\n            ? Checks[key](value)\n            : getAttribCheck(key, value);\n    });\n    return funcs.length === 0 ? null : funcs.reduce(combineFuncs);\n}\n/**\n * Checks whether a node matches the description in `options`.\n *\n * @category Legacy Query Functions\n * @param options An object describing nodes to look for.\n * @param node The element to test.\n * @returns Whether the element matches the description in `options`.\n */\nexport function testElement(options, node) {\n    const test = compileTest(options);\n    return test ? test(node) : true;\n}\n/**\n * Returns all nodes that match `options`.\n *\n * @category Legacy Query Functions\n * @param options An object describing nodes to look for.\n * @param nodes Nodes to search through.\n * @param recurse Also consider child nodes.\n * @param limit Maximum number of nodes to return.\n * @returns All nodes that match `options`.\n */\nexport function getElements(options, nodes, recurse, limit = Infinity) {\n    const test = compileTest(options);\n    return test ? filter(test, nodes, recurse, limit) : [];\n}\n/**\n * Returns the node with the supplied ID.\n *\n * @category Legacy Query Functions\n * @param id The unique ID attribute value to look for.\n * @param nodes Nodes to search through.\n * @param recurse Also consider child nodes.\n * @returns The node with the supplied ID.\n */\nexport function getElementById(id, nodes, recurse = true) {\n    if (!Array.isArray(nodes))\n        nodes = [nodes];\n    return findOne(getAttribCheck(\"id\", id), nodes, recurse);\n}\n/**\n * Returns all nodes with the supplied `tagName`.\n *\n * @category Legacy Query Functions\n * @param tagName Tag name to search for.\n * @param nodes Nodes to search through.\n * @param recurse Also consider child nodes.\n * @param limit Maximum number of nodes to return.\n * @returns All nodes with the supplied `tagName`.\n */\nexport function getElementsByTagName(tagName, nodes, recurse = true, limit = Infinity) {\n    return filter(Checks[\"tag_name\"](tagName), nodes, recurse, limit);\n}\n/**\n * Returns all nodes with the supplied `className`.\n *\n * @category Legacy Query Functions\n * @param className Class name to search for.\n * @param nodes Nodes to search through.\n * @param recurse Also consider child nodes.\n * @param limit Maximum number of nodes to return.\n * @returns All nodes with the supplied `className`.\n */\nexport function getElementsByClassName(className, nodes, recurse = true, limit = Infinity) {\n    return filter(getAttribCheck(\"class\", className), nodes, recurse, limit);\n}\n/**\n * Returns all nodes with the supplied `type`.\n *\n * @category Legacy Query Functions\n * @param type Element type to look for.\n * @param nodes Nodes to search through.\n * @param recurse Also consider child nodes.\n * @param limit Maximum number of nodes to return.\n * @returns All nodes with the supplied `type`.\n */\nexport function getElementsByTagType(type, nodes, recurse = true, limit = Infinity) {\n    return filter(Checks[\"tag_type\"](type), nodes, recurse, limit);\n}\n//# sourceMappingURL=legacy.js.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/domutils/src/manipulation.d.ts",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport type { ChildNode, ParentNode } from \"../../domhandler/src\";\n/**\n * Remove an element from the dom\n *\n * @category Manipulation\n * @param elem The element to be removed\n */\nexport declare function removeElement(elem: ChildNode): void;\n/**\n * Replace an element in the dom\n *\n * @category Manipulation\n * @param elem The element to be replaced\n * @param replacement The element to be added\n */\nexport declare function replaceElement(elem: ChildNode, replacement: ChildNode): void;\n/**\n * Append a child to an element.\n *\n * @category Manipulation\n * @param parent The element to append to.\n * @param child The element to be added as a child.\n */\nexport declare function appendChild(parent: ParentNode, child: ChildNode): void;\n/**\n * Append an element after another.\n *\n * @category Manipulation\n * @param elem The element to append after.\n * @param next The element be added.\n */\nexport declare function append(elem: ChildNode, next: ChildNode): void;\n/**\n * Prepend a child to an element.\n *\n * @category Manipulation\n * @param parent The element to prepend before.\n * @param child The element to be added as a child.\n */\nexport declare function prependChild(parent: ParentNode, child: ChildNode): void;\n/**\n * Prepend an element before another.\n *\n * @category Manipulation\n * @param elem The element to prepend before.\n * @param prev The element be added.\n */\nexport declare function prepend(elem: ChildNode, prev: ChildNode): void;\n//# sourceMappingURL=manipulation.d.ts.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/domutils/src/manipulation.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/**\n * Remove an element from the dom\n *\n * @category Manipulation\n * @param elem The element to be removed\n */\nexport function removeElement(elem) {\n    if (elem.prev)\n        elem.prev.next = elem.next;\n    if (elem.next)\n        elem.next.prev = elem.prev;\n    if (elem.parent) {\n        const childs = elem.parent.children;\n        const childsIndex = childs.lastIndexOf(elem);\n        if (childsIndex >= 0) {\n            childs.splice(childsIndex, 1);\n        }\n    }\n    elem.next = null;\n    elem.prev = null;\n    elem.parent = null;\n}\n/**\n * Replace an element in the dom\n *\n * @category Manipulation\n * @param elem The element to be replaced\n * @param replacement The element to be added\n */\nexport function replaceElement(elem, replacement) {\n    const prev = (replacement.prev = elem.prev);\n    if (prev) {\n        prev.next = replacement;\n    }\n    const next = (replacement.next = elem.next);\n    if (next) {\n        next.prev = replacement;\n    }\n    const parent = (replacement.parent = elem.parent);\n    if (parent) {\n        const childs = parent.children;\n        childs[childs.lastIndexOf(elem)] = replacement;\n        elem.parent = null;\n    }\n}\n/**\n * Append a child to an element.\n *\n * @category Manipulation\n * @param parent The element to append to.\n * @param child The element to be added as a child.\n */\nexport function appendChild(parent, child) {\n    removeElement(child);\n    child.next = null;\n    child.parent = parent;\n    if (parent.children.push(child) > 1) {\n        const sibling = parent.children[parent.children.length - 2];\n        sibling.next = child;\n        child.prev = sibling;\n    }\n    else {\n        child.prev = null;\n    }\n}\n/**\n * Append an element after another.\n *\n * @category Manipulation\n * @param elem The element to append after.\n * @param next The element be added.\n */\nexport function append(elem, next) {\n    removeElement(next);\n    const { parent } = elem;\n    const currNext = elem.next;\n    next.next = currNext;\n    next.prev = elem;\n    elem.next = next;\n    next.parent = parent;\n    if (currNext) {\n        currNext.prev = next;\n        if (parent) {\n            const childs = parent.children;\n            childs.splice(childs.lastIndexOf(currNext), 0, next);\n        }\n    }\n    else if (parent) {\n        parent.children.push(next);\n    }\n}\n/**\n * Prepend a child to an element.\n *\n * @category Manipulation\n * @param parent The element to prepend before.\n * @param child The element to be added as a child.\n */\nexport function prependChild(parent, child) {\n    removeElement(child);\n    child.parent = parent;\n    child.prev = null;\n    if (parent.children.unshift(child) !== 1) {\n        const sibling = parent.children[1];\n        sibling.prev = child;\n        child.next = sibling;\n    }\n    else {\n        child.next = null;\n    }\n}\n/**\n * Prepend an element before another.\n *\n * @category Manipulation\n * @param elem The element to prepend before.\n * @param prev The element be added.\n */\nexport function prepend(elem, prev) {\n    removeElement(prev);\n    const { parent } = elem;\n    if (parent) {\n        const childs = parent.children;\n        childs.splice(childs.indexOf(elem), 0, prev);\n    }\n    if (elem.prev) {\n        elem.prev.next = prev;\n    }\n    prev.parent = parent;\n    prev.prev = elem.prev;\n    prev.next = elem;\n    elem.prev = prev;\n}\n//# sourceMappingURL=manipulation.js.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/domutils/src/querying.d.ts",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { Element, AnyNode, ParentNode } from \"../../domhandler/src\";\n/**\n * Search a node and its children for nodes passing a test function. If `node` is not an array, it will be wrapped in one.\n *\n * @category Querying\n * @param test Function to test nodes on.\n * @param node Node to search. Will be included in the result set if it matches.\n * @param recurse Also consider child nodes.\n * @param limit Maximum number of nodes to return.\n * @returns All nodes passing `test`.\n */\nexport declare function filter(test: (elem: AnyNode) => boolean, node: AnyNode | AnyNode[], recurse?: boolean, limit?: number): AnyNode[];\n/**\n * Search an array of nodes and their children for nodes passing a test function.\n *\n * @category Querying\n * @param test Function to test nodes on.\n * @param nodes Array of nodes to search.\n * @param recurse Also consider child nodes.\n * @param limit Maximum number of nodes to return.\n * @returns All nodes passing `test`.\n */\nexport declare function find(test: (elem: AnyNode) => boolean, nodes: AnyNode[] | ParentNode, recurse: boolean, limit: number): AnyNode[];\n/**\n * Finds the first element inside of an array that matches a test function. This is an alias for `Array.prototype.find`.\n *\n * @category Querying\n * @param test Function to test nodes on.\n * @param nodes Array of nodes to search.\n * @returns The first node in the array that passes `test`.\n * @deprecated Use `Array.prototype.find` directly.\n */\nexport declare function findOneChild<T>(test: (elem: T) => boolean, nodes: T[]): T | undefined;\n/**\n * Finds one element in a tree that passes a test.\n *\n * @category Querying\n * @param test Function to test nodes on.\n * @param nodes Node or array of nodes to search.\n * @param recurse Also consider child nodes.\n * @returns The first node that passes `test`.\n */\nexport declare function findOne(test: (elem: Element) => boolean, nodes: AnyNode[] | ParentNode, recurse?: boolean): Element | null;\n/**\n * Checks if a tree of nodes contains at least one node passing a test.\n *\n * @category Querying\n * @param test Function to test nodes on.\n * @param nodes Array of nodes to search.\n * @returns Whether a tree of nodes contains at least one node passing the test.\n */\nexport declare function existsOne(test: (elem: Element) => boolean, nodes: AnyNode[] | ParentNode): boolean;\n/**\n * Search an array of nodes and their children for elements passing a test function.\n *\n * Same as `find`, but limited to elements and with less options, leading to reduced complexity.\n *\n * @category Querying\n * @param test Function to test nodes on.\n * @param nodes Array of nodes to search.\n * @returns All nodes passing `test`.\n */\nexport declare function findAll(test: (elem: Element) => boolean, nodes: AnyNode[] | ParentNode): Element[];\n//# sourceMappingURL=querying.d.ts.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/domutils/src/querying.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { isTag, hasChildren } from \"../../domhandler/src\";\n/**\n * Search a node and its children for nodes passing a test function. If `node` is not an array, it will be wrapped in one.\n *\n * @category Querying\n * @param test Function to test nodes on.\n * @param node Node to search. Will be included in the result set if it matches.\n * @param recurse Also consider child nodes.\n * @param limit Maximum number of nodes to return.\n * @returns All nodes passing `test`.\n */\nexport function filter(test, node, recurse = true, limit = Infinity) {\n    return find(test, Array.isArray(node) ? node : [node], recurse, limit);\n}\n/**\n * Search an array of nodes and their children for nodes passing a test function.\n *\n * @category Querying\n * @param test Function to test nodes on.\n * @param nodes Array of nodes to search.\n * @param recurse Also consider child nodes.\n * @param limit Maximum number of nodes to return.\n * @returns All nodes passing `test`.\n */\nexport function find(test, nodes, recurse, limit) {\n    const result = [];\n    /** Stack of the arrays we are looking at. */\n    const nodeStack = [Array.isArray(nodes) ? nodes : [nodes]];\n    /** Stack of the indices within the arrays. */\n    const indexStack = [0];\n    for (;;) {\n        // First, check if the current array has any more elements to look at.\n        if (indexStack[0] >= nodeStack[0].length) {\n            // If we have no more arrays to look at, we are done.\n            if (indexStack.length === 1) {\n                return result;\n            }\n            // Otherwise, remove the current array from the stack.\n            nodeStack.shift();\n            indexStack.shift();\n            // Loop back to the start to continue with the next array.\n            continue;\n        }\n        const elem = nodeStack[0][indexStack[0]++];\n        if (test(elem)) {\n            result.push(elem);\n            if (--limit <= 0)\n                return result;\n        }\n        if (recurse && hasChildren(elem) && elem.children.length > 0) {\n            /*\n             * Add the children to the stack. We are depth-first, so this is\n             * the next array we look at.\n             */\n            indexStack.unshift(0);\n            nodeStack.unshift(elem.children);\n        }\n    }\n}\n/**\n * Finds the first element inside of an array that matches a test function. This is an alias for `Array.prototype.find`.\n *\n * @category Querying\n * @param test Function to test nodes on.\n * @param nodes Array of nodes to search.\n * @returns The first node in the array that passes `test`.\n * @deprecated Use `Array.prototype.find` directly.\n */\nexport function findOneChild(test, nodes) {\n    return nodes.find(test);\n}\n/**\n * Finds one element in a tree that passes a test.\n *\n * @category Querying\n * @param test Function to test nodes on.\n * @param nodes Node or array of nodes to search.\n * @param recurse Also consider child nodes.\n * @returns The first node that passes `test`.\n */\nexport function findOne(test, nodes, recurse = true) {\n    const searchedNodes = Array.isArray(nodes) ? nodes : [nodes];\n    for (let i = 0; i < searchedNodes.length; i++) {\n        const node = searchedNodes[i];\n        if (isTag(node) && test(node)) {\n            return node;\n        }\n        if (recurse && hasChildren(node) && node.children.length > 0) {\n            const found = findOne(test, node.children, true);\n            if (found)\n                return found;\n        }\n    }\n    return null;\n}\n/**\n * Checks if a tree of nodes contains at least one node passing a test.\n *\n * @category Querying\n * @param test Function to test nodes on.\n * @param nodes Array of nodes to search.\n * @returns Whether a tree of nodes contains at least one node passing the test.\n */\nexport function existsOne(test, nodes) {\n    return (Array.isArray(nodes) ? nodes : [nodes]).some((node) => (isTag(node) && test(node)) ||\n        (hasChildren(node) && existsOne(test, node.children)));\n}\n/**\n * Search an array of nodes and their children for elements passing a test function.\n *\n * Same as `find`, but limited to elements and with less options, leading to reduced complexity.\n *\n * @category Querying\n * @param test Function to test nodes on.\n * @param nodes Array of nodes to search.\n * @returns All nodes passing `test`.\n */\nexport function findAll(test, nodes) {\n    const result = [];\n    const nodeStack = [Array.isArray(nodes) ? nodes : [nodes]];\n    const indexStack = [0];\n    for (;;) {\n        if (indexStack[0] >= nodeStack[0].length) {\n            if (nodeStack.length === 1) {\n                return result;\n            }\n            // Otherwise, remove the current array from the stack.\n            nodeStack.shift();\n            indexStack.shift();\n            // Loop back to the start to continue with the next array.\n            continue;\n        }\n        const elem = nodeStack[0][indexStack[0]++];\n        if (isTag(elem) && test(elem))\n            result.push(elem);\n        if (hasChildren(elem) && elem.children.length > 0) {\n            indexStack.unshift(0);\n            nodeStack.unshift(elem.children);\n        }\n    }\n}\n//# sourceMappingURL=querying.js.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/domutils/src/stringify.d.ts",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { AnyNode } from \"../../domhandler/src\";\nimport { DomSerializerOptions } from \"../../dom-serializer/src\";\n/**\n * @category Stringify\n * @deprecated Use the `dom-serializer` module directly.\n * @param node Node to get the outer HTML of.\n * @param options Options for serialization.\n * @returns `node`'s outer HTML.\n */\nexport declare function getOuterHTML(node: AnyNode | ArrayLike<AnyNode>, options?: DomSerializerOptions): string;\n/**\n * @category Stringify\n * @deprecated Use the `dom-serializer` module directly.\n * @param node Node to get the inner HTML of.\n * @param options Options for serialization.\n * @returns `node`'s inner HTML.\n */\nexport declare function getInnerHTML(node: AnyNode, options?: DomSerializerOptions): string;\n/**\n * Get a node's inner text. Same as `textContent`, but inserts newlines for `<br>` tags. Ignores comments.\n *\n * @category Stringify\n * @deprecated Use `textContent` instead.\n * @param node Node to get the inner text of.\n * @returns `node`'s inner text.\n */\nexport declare function getText(node: AnyNode | AnyNode[]): string;\n/**\n * Get a node's text content. Ignores comments.\n *\n * @category Stringify\n * @param node Node to get the text content of.\n * @returns `node`'s text content.\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent}\n */\nexport declare function textContent(node: AnyNode | AnyNode[]): string;\n/**\n * Get a node's inner text, ignoring `<script>` and `<style>` tags. Ignores comments.\n *\n * @category Stringify\n * @param node Node to get the inner text of.\n * @returns `node`'s inner text.\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Node/innerText}\n */\nexport declare function innerText(node: AnyNode | AnyNode[]): string;\n//# sourceMappingURL=stringify.d.ts.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/domutils/src/stringify.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { isTag, isCDATA, isText, hasChildren, isComment, } from \"../../domhandler/src\";\nimport renderHTML from \"../../dom-serializer/src\";\nimport { ElementType } from \"../../domelementtype/src\";\n/**\n * @category Stringify\n * @deprecated Use the `dom-serializer` module directly.\n * @param node Node to get the outer HTML of.\n * @param options Options for serialization.\n * @returns `node`'s outer HTML.\n */\nexport function getOuterHTML(node, options) {\n    return renderHTML(node, options);\n}\n/**\n * @category Stringify\n * @deprecated Use the `dom-serializer` module directly.\n * @param node Node to get the inner HTML of.\n * @param options Options for serialization.\n * @returns `node`'s inner HTML.\n */\nexport function getInnerHTML(node, options) {\n    return hasChildren(node)\n        ? node.children.map((node) => getOuterHTML(node, options)).join(\"\")\n        : \"\";\n}\n/**\n * Get a node's inner text. Same as `textContent`, but inserts newlines for `<br>` tags. Ignores comments.\n *\n * @category Stringify\n * @deprecated Use `textContent` instead.\n * @param node Node to get the inner text of.\n * @returns `node`'s inner text.\n */\nexport function getText(node) {\n    if (Array.isArray(node))\n        return node.map(getText).join(\"\");\n    if (isTag(node))\n        return node.name === \"br\" ? \"\\n\" : getText(node.children);\n    if (isCDATA(node))\n        return getText(node.children);\n    if (isText(node))\n        return node.data;\n    return \"\";\n}\n/**\n * Get a node's text content. Ignores comments.\n *\n * @category Stringify\n * @param node Node to get the text content of.\n * @returns `node`'s text content.\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent}\n */\nexport function textContent(node) {\n    if (Array.isArray(node))\n        return node.map(textContent).join(\"\");\n    if (hasChildren(node) && !isComment(node)) {\n        return textContent(node.children);\n    }\n    if (isText(node))\n        return node.data;\n    return \"\";\n}\n/**\n * Get a node's inner text, ignoring `<script>` and `<style>` tags. Ignores comments.\n *\n * @category Stringify\n * @param node Node to get the inner text of.\n * @returns `node`'s inner text.\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Node/innerText}\n */\nexport function innerText(node) {\n    if (Array.isArray(node))\n        return node.map(innerText).join(\"\");\n    if (hasChildren(node) && (node.type === ElementType.Tag || isCDATA(node))) {\n        return innerText(node.children);\n    }\n    if (isText(node))\n        return node.data;\n    return \"\";\n}\n//# sourceMappingURL=stringify.js.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/domutils/src/traversal.d.ts",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { AnyNode, ChildNode, Element, ParentNode } from \"../../domhandler/src\";\n/**\n * Get a node's children.\n *\n * @category Traversal\n * @param elem Node to get the children of.\n * @returns `elem`'s children, or an empty array.\n */\nexport declare function getChildren(elem: AnyNode): ChildNode[];\nexport declare function getParent(elem: AnyNode): ParentNode | null;\n/**\n * Gets an elements siblings, including the element itself.\n *\n * Attempts to get the children through the element's parent first. If we don't\n * have a parent (the element is a root node), we walk the element's `prev` &\n * `next` to get all remaining nodes.\n *\n * @category Traversal\n * @param elem Element to get the siblings of.\n * @returns `elem`'s siblings, including `elem`.\n */\nexport declare function getSiblings(elem: AnyNode): AnyNode[];\n/**\n * Gets an attribute from an element.\n *\n * @category Traversal\n * @param elem Element to check.\n * @param name Attribute name to retrieve.\n * @returns The element's attribute value, or `undefined`.\n */\nexport declare function getAttributeValue(elem: Element, name: string): string | undefined;\n/**\n * Checks whether an element has an attribute.\n *\n * @category Traversal\n * @param elem Element to check.\n * @param name Attribute name to look for.\n * @returns Returns whether `elem` has the attribute `name`.\n */\nexport declare function hasAttrib(elem: Element, name: string): boolean;\n/**\n * Get the tag name of an element.\n *\n * @category Traversal\n * @param elem The element to get the name for.\n * @returns The tag name of `elem`.\n */\nexport declare function getName(elem: Element): string;\n/**\n * Returns the next element sibling of a node.\n *\n * @category Traversal\n * @param elem The element to get the next sibling of.\n * @returns `elem`'s next sibling that is a tag, or `null` if there is no next\n * sibling.\n */\nexport declare function nextElementSibling(elem: AnyNode): Element | null;\n/**\n * Returns the previous element sibling of a node.\n *\n * @category Traversal\n * @param elem The element to get the previous sibling of.\n * @returns `elem`'s previous sibling that is a tag, or `null` if there is no\n * previous sibling.\n */\nexport declare function prevElementSibling(elem: AnyNode): Element | null;\n//# sourceMappingURL=traversal.d.ts.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/domutils/src/traversal.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { isTag, hasChildren, } from \"../../domhandler/src\";\n/**\n * Get a node's children.\n *\n * @category Traversal\n * @param elem Node to get the children of.\n * @returns `elem`'s children, or an empty array.\n */\nexport function getChildren(elem) {\n    return hasChildren(elem) ? elem.children : [];\n}\n/**\n * Get a node's parent.\n *\n * @category Traversal\n * @param elem Node to get the parent of.\n * @returns `elem`'s parent node, or `null` if `elem` is a root node.\n */\nexport function getParent(elem) {\n    return elem.parent || null;\n}\n/**\n * Gets an elements siblings, including the element itself.\n *\n * Attempts to get the children through the element's parent first. If we don't\n * have a parent (the element is a root node), we walk the element's `prev` &\n * `next` to get all remaining nodes.\n *\n * @category Traversal\n * @param elem Element to get the siblings of.\n * @returns `elem`'s siblings, including `elem`.\n */\nexport function getSiblings(elem) {\n    const parent = getParent(elem);\n    if (parent != null)\n        return getChildren(parent);\n    const siblings = [elem];\n    let { prev, next } = elem;\n    while (prev != null) {\n        siblings.unshift(prev);\n        ({ prev } = prev);\n    }\n    while (next != null) {\n        siblings.push(next);\n        ({ next } = next);\n    }\n    return siblings;\n}\n/**\n * Gets an attribute from an element.\n *\n * @category Traversal\n * @param elem Element to check.\n * @param name Attribute name to retrieve.\n * @returns The element's attribute value, or `undefined`.\n */\nexport function getAttributeValue(elem, name) {\n    var _a;\n    return (_a = elem.attribs) === null || _a === void 0 ? void 0 : _a[name];\n}\n/**\n * Checks whether an element has an attribute.\n *\n * @category Traversal\n * @param elem Element to check.\n * @param name Attribute name to look for.\n * @returns Returns whether `elem` has the attribute `name`.\n */\nexport function hasAttrib(elem, name) {\n    return (elem.attribs != null &&\n        Object.prototype.hasOwnProperty.call(elem.attribs, name) &&\n        elem.attribs[name] != null);\n}\n/**\n * Get the tag name of an element.\n *\n * @category Traversal\n * @param elem The element to get the name for.\n * @returns The tag name of `elem`.\n */\nexport function getName(elem) {\n    return elem.name;\n}\n/**\n * Returns the next element sibling of a node.\n *\n * @category Traversal\n * @param elem The element to get the next sibling of.\n * @returns `elem`'s next sibling that is a tag, or `null` if there is no next\n * sibling.\n */\nexport function nextElementSibling(elem) {\n    let { next } = elem;\n    while (next !== null && !isTag(next))\n        ({ next } = next);\n    return next;\n}\n/**\n * Returns the previous element sibling of a node.\n *\n * @category Traversal\n * @param elem The element to get the previous sibling of.\n * @returns `elem`'s previous sibling that is a tag, or `null` if there is no\n * previous sibling.\n */\nexport function prevElementSibling(elem) {\n    let { prev } = elem;\n    while (prev !== null && !isTag(prev))\n        ({ prev } = prev);\n    return prev;\n}\n//# sourceMappingURL=traversal.js.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/entities/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/**\n * entities\n * @home   : https://github.com/fb55/entities\n * @branch : master\n * @commit : 33dd790cef5928ccdfef32846ed2150cbd5fd5fb\n */\n\nexport * from './src';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/entities/src/decode-codepoint.d.ts",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/**\n * Polyfill for `String.fromCodePoint`. It is used to create a string from a Unicode code point.\n */\nexport declare const fromCodePoint: (...codePoints: number[]) => string;\n/**\n * Replace the given code point with a replacement character if it is a\n * surrogate or is outside the valid range. Otherwise return the code\n * point unchanged.\n */\nexport declare function replaceCodePoint(codePoint: number): number;\n/**\n * Replace the code point if relevant, then convert it to a string.\n *\n * @deprecated Use `fromCodePoint(replaceCodePoint(codePoint))` instead.\n * @param codePoint The code point to decode.\n * @returns The decoded code point.\n */\nexport declare function decodeCodePoint(codePoint: number): string;\n//# sourceMappingURL=decode-codepoint.d.ts.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/entities/src/decode-codepoint.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n// Adapted from https://github.com/mathiasbynens/he/blob/36afe179392226cf1b6ccdb16ebbb7a5a844d93a/src/he.js#L106-L134\nvar _a;\nconst decodeMap = new Map([\n    [0, 65533],\n    // C1 Unicode control character reference replacements\n    [128, 8364],\n    [130, 8218],\n    [131, 402],\n    [132, 8222],\n    [133, 8230],\n    [134, 8224],\n    [135, 8225],\n    [136, 710],\n    [137, 8240],\n    [138, 352],\n    [139, 8249],\n    [140, 338],\n    [142, 381],\n    [145, 8216],\n    [146, 8217],\n    [147, 8220],\n    [148, 8221],\n    [149, 8226],\n    [150, 8211],\n    [151, 8212],\n    [152, 732],\n    [153, 8482],\n    [154, 353],\n    [155, 8250],\n    [156, 339],\n    [158, 382],\n    [159, 376],\n]);\n/**\n * Polyfill for `String.fromCodePoint`. It is used to create a string from a Unicode code point.\n */\nexport const fromCodePoint = \n// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, n/no-unsupported-features/es-builtins\n(_a = String.fromCodePoint) !== null && _a !== void 0 ? _a : function (codePoint) {\n    let output = \"\";\n    if (codePoint > 65535) {\n        codePoint -= 65536;\n        output += String.fromCharCode(((codePoint >>> 10) & 1023) | 55296);\n        codePoint = 56320 | (codePoint & 1023);\n    }\n    output += String.fromCharCode(codePoint);\n    return output;\n};\n/**\n * Replace the given code point with a replacement character if it is a\n * surrogate or is outside the valid range. Otherwise return the code\n * point unchanged.\n */\nexport function replaceCodePoint(codePoint) {\n    var _a;\n    if ((codePoint >= 55296 && codePoint <= 57343) ||\n        codePoint > 1114111) {\n        return 65533;\n    }\n    return (_a = decodeMap.get(codePoint)) !== null && _a !== void 0 ? _a : codePoint;\n}\n/**\n * Replace the code point if relevant, then convert it to a string.\n *\n * @deprecated Use `fromCodePoint(replaceCodePoint(codePoint))` instead.\n * @param codePoint The code point to decode.\n * @returns The decoded code point.\n */\nexport function decodeCodePoint(codePoint) {\n    return fromCodePoint(replaceCodePoint(codePoint));\n}\n//# sourceMappingURL=decode-codepoint.js.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/entities/src/decode.d.ts",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport declare enum BinTrieFlags {\n    VALUE_LENGTH = 49152,\n    BRANCH_LENGTH = 16256,\n    JUMP_TABLE = 127\n}\nexport declare enum DecodingMode {\n    /** Entities in text nodes that can end with any character. */\n    Legacy = 0,\n    /** Only allow entities terminated with a semicolon. */\n    Strict = 1,\n    /** Entities in attributes have limitations on ending characters. */\n    Attribute = 2\n}\n/**\n * Producers for character reference errors as defined in the HTML spec.\n */\nexport interface EntityErrorProducer {\n    missingSemicolonAfterCharacterReference(): void;\n    absenceOfDigitsInNumericCharacterReference(consumedCharacters: number): void;\n    validateNumericCharacterReference(code: number): void;\n}\n/**\n * Token decoder with support of writing partial entities.\n */\nexport declare class EntityDecoder {\n    /** The tree used to decode entities. */\n    private readonly decodeTree;\n    /**\n     * The function that is called when a codepoint is decoded.\n     *\n     * For multi-byte named entities, this will be called multiple times,\n     * with the second codepoint, and the same `consumed` value.\n     *\n     * @param codepoint The decoded codepoint.\n     * @param consumed The number of bytes consumed by the decoder.\n     */\n    private readonly emitCodePoint;\n    /** An object that is used to produce errors. */\n    private readonly errors?;\n    constructor(\n    /** The tree used to decode entities. */\n    decodeTree: Uint16Array, \n    /**\n     * The function that is called when a codepoint is decoded.\n     *\n     * For multi-byte named entities, this will be called multiple times,\n     * with the second codepoint, and the same `consumed` value.\n     *\n     * @param codepoint The decoded codepoint.\n     * @param consumed The number of bytes consumed by the decoder.\n     */\n    emitCodePoint: (cp: number, consumed: number) => void, \n    /** An object that is used to produce errors. */\n    errors?: EntityErrorProducer | undefined);\n    /** The current state of the decoder. */\n    private state;\n    /** Characters that were consumed while parsing an entity. */\n    private consumed;\n    /**\n     * The result of the entity.\n     *\n     * Either the result index of a numeric entity, or the codepoint of a\n     * numeric entity.\n     */\n    private result;\n    /** The current index in the decode tree. */\n    private treeIndex;\n    /** The number of characters that were consumed in excess. */\n    private excess;\n    /** The mode in which the decoder is operating. */\n    private decodeMode;\n    /** Resets the instance to make it reusable. */\n    startEntity(decodeMode: DecodingMode): void;\n    /**\n     * Write an entity to the decoder. This can be called multiple times with partial entities.\n     * If the entity is incomplete, the decoder will return -1.\n     *\n     * Mirrors the implementation of `getDecoder`, but with the ability to stop decoding if the\n     * entity is incomplete, and resume when the next string is written.\n     *\n     * @param input The string containing the entity (or a continuation of the entity).\n     * @param offset The offset at which the entity begins. Should be 0 if this is not the first call.\n     * @returns The number of characters that were consumed, or -1 if the entity is incomplete.\n     */\n    write(input: string, offset: number): number;\n    /**\n     * Switches between the numeric decimal and hexadecimal states.\n     *\n     * Equivalent to the `Numeric character reference state` in the HTML spec.\n     *\n     * @param input The string containing the entity (or a continuation of the entity).\n     * @param offset The current offset.\n     * @returns The number of characters that were consumed, or -1 if the entity is incomplete.\n     */\n    private stateNumericStart;\n    private addToNumericResult;\n    /**\n     * Parses a hexadecimal numeric entity.\n     *\n     * Equivalent to the `Hexademical character reference state` in the HTML spec.\n     *\n     * @param input The string containing the entity (or a continuation of the entity).\n     * @param offset The current offset.\n     * @returns The number of characters that were consumed, or -1 if the entity is incomplete.\n     */\n    private stateNumericHex;\n    /**\n     * Parses a decimal numeric entity.\n     *\n     * Equivalent to the `Decimal character reference state` in the HTML spec.\n     *\n     * @param input The string containing the entity (or a continuation of the entity).\n     * @param offset The current offset.\n     * @returns The number of characters that were consumed, or -1 if the entity is incomplete.\n     */\n    private stateNumericDecimal;\n    /**\n     * Validate and emit a numeric entity.\n     *\n     * Implements the logic from the `Hexademical character reference start\n     * state` and `Numeric character reference end state` in the HTML spec.\n     *\n     * @param lastCp The last code point of the entity. Used to see if the\n     *               entity was terminated with a semicolon.\n     * @param expectedLength The minimum number of characters that should be\n     *                       consumed. Used to validate that at least one digit\n     *                       was consumed.\n     * @returns The number of characters that were consumed.\n     */\n    private emitNumericEntity;\n    /**\n     * Parses a named entity.\n     *\n     * Equivalent to the `Named character reference state` in the HTML spec.\n     *\n     * @param input The string containing the entity (or a continuation of the entity).\n     * @param offset The current offset.\n     * @returns The number of characters that were consumed, or -1 if the entity is incomplete.\n     */\n    private stateNamedEntity;\n    /**\n     * Emit a named entity that was not terminated with a semicolon.\n     *\n     * @returns The number of characters consumed.\n     */\n    private emitNotTerminatedNamedEntity;\n    /**\n     * Emit a named entity.\n     *\n     * @param result The index of the entity in the decode tree.\n     * @param valueLength The number of bytes in the entity.\n     * @param consumed The number of characters consumed.\n     *\n     * @returns The number of characters consumed.\n     */\n    private emitNamedEntityData;\n    /**\n     * Signal to the parser that the end of the input was reached.\n     *\n     * Remaining data will be emitted and relevant errors will be produced.\n     *\n     * @returns The number of characters consumed.\n     */\n    end(): number;\n}\n/**\n * Determines the branch of the current node that is taken given the current\n * character. This function is used to traverse the trie.\n *\n * @param decodeTree The trie.\n * @param current The current node.\n * @param nodeIdx The index right after the current node and its value.\n * @param char The current character.\n * @returns The index of the next node, or -1 if no branch is taken.\n */\nexport declare function determineBranch(decodeTree: Uint16Array, current: number, nodeIndex: number, char: number): number;\n/**\n * Decodes an HTML string.\n *\n * @param htmlString The string to decode.\n * @param mode The decoding mode.\n * @returns The decoded string.\n */\nexport declare function decodeHTML(htmlString: string, mode?: DecodingMode): string;\n/**\n * Decodes an HTML string in an attribute.\n *\n * @param htmlAttribute The string to decode.\n * @returns The decoded string.\n */\nexport declare function decodeHTMLAttribute(htmlAttribute: string): string;\n/**\n * Decodes an HTML string, requiring all entities to be terminated by a semicolon.\n *\n * @param htmlString The string to decode.\n * @returns The decoded string.\n */\nexport declare function decodeHTMLStrict(htmlString: string): string;\n/**\n * Decodes an XML string, requiring all entities to be terminated by a semicolon.\n *\n * @param xmlString The string to decode.\n * @returns The decoded string.\n */\nexport declare function decodeXML(xmlString: string): string;\nexport { htmlDecodeTree } from \"./generated/decode-data-html.js\";\nexport { xmlDecodeTree } from \"./generated/decode-data-xml.js\";\nexport { decodeCodePoint, replaceCodePoint, fromCodePoint, } from \"./decode-codepoint.js\";\n//# sourceMappingURL=decode.d.ts.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/entities/src/decode.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { htmlDecodeTree } from \"./generated/decode-data-html\";\nimport { xmlDecodeTree } from \"./generated/decode-data-xml\";\nimport { replaceCodePoint, fromCodePoint } from \"./decode-codepoint\";\nvar CharCodes;\n(function (CharCodes) {\n    CharCodes[CharCodes[\"NUM\"] = 35] = \"NUM\";\n    CharCodes[CharCodes[\"SEMI\"] = 59] = \"SEMI\";\n    CharCodes[CharCodes[\"EQUALS\"] = 61] = \"EQUALS\";\n    CharCodes[CharCodes[\"ZERO\"] = 48] = \"ZERO\";\n    CharCodes[CharCodes[\"NINE\"] = 57] = \"NINE\";\n    CharCodes[CharCodes[\"LOWER_A\"] = 97] = \"LOWER_A\";\n    CharCodes[CharCodes[\"LOWER_F\"] = 102] = \"LOWER_F\";\n    CharCodes[CharCodes[\"LOWER_X\"] = 120] = \"LOWER_X\";\n    CharCodes[CharCodes[\"LOWER_Z\"] = 122] = \"LOWER_Z\";\n    CharCodes[CharCodes[\"UPPER_A\"] = 65] = \"UPPER_A\";\n    CharCodes[CharCodes[\"UPPER_F\"] = 70] = \"UPPER_F\";\n    CharCodes[CharCodes[\"UPPER_Z\"] = 90] = \"UPPER_Z\";\n})(CharCodes || (CharCodes = {}));\n/** Bit that needs to be set to convert an upper case ASCII character to lower case */\nconst TO_LOWER_BIT = 32;\nexport var BinTrieFlags;\n(function (BinTrieFlags) {\n    BinTrieFlags[BinTrieFlags[\"VALUE_LENGTH\"] = 49152] = \"VALUE_LENGTH\";\n    BinTrieFlags[BinTrieFlags[\"BRANCH_LENGTH\"] = 16256] = \"BRANCH_LENGTH\";\n    BinTrieFlags[BinTrieFlags[\"JUMP_TABLE\"] = 127] = \"JUMP_TABLE\";\n})(BinTrieFlags || (BinTrieFlags = {}));\nfunction isNumber(code) {\n    return code >= CharCodes.ZERO && code <= CharCodes.NINE;\n}\nfunction isHexadecimalCharacter(code) {\n    return ((code >= CharCodes.UPPER_A && code <= CharCodes.UPPER_F) ||\n        (code >= CharCodes.LOWER_A && code <= CharCodes.LOWER_F));\n}\nfunction isAsciiAlphaNumeric(code) {\n    return ((code >= CharCodes.UPPER_A && code <= CharCodes.UPPER_Z) ||\n        (code >= CharCodes.LOWER_A && code <= CharCodes.LOWER_Z) ||\n        isNumber(code));\n}\n/**\n * Checks if the given character is a valid end character for an entity in an attribute.\n *\n * Attribute values that aren't terminated properly aren't parsed, and shouldn't lead to a parser error.\n * See the example in https://html.spec.whatwg.org/multipage/parsing.html#named-character-reference-state\n */\nfunction isEntityInAttributeInvalidEnd(code) {\n    return code === CharCodes.EQUALS || isAsciiAlphaNumeric(code);\n}\nvar EntityDecoderState;\n(function (EntityDecoderState) {\n    EntityDecoderState[EntityDecoderState[\"EntityStart\"] = 0] = \"EntityStart\";\n    EntityDecoderState[EntityDecoderState[\"NumericStart\"] = 1] = \"NumericStart\";\n    EntityDecoderState[EntityDecoderState[\"NumericDecimal\"] = 2] = \"NumericDecimal\";\n    EntityDecoderState[EntityDecoderState[\"NumericHex\"] = 3] = \"NumericHex\";\n    EntityDecoderState[EntityDecoderState[\"NamedEntity\"] = 4] = \"NamedEntity\";\n})(EntityDecoderState || (EntityDecoderState = {}));\nexport var DecodingMode;\n(function (DecodingMode) {\n    /** Entities in text nodes that can end with any character. */\n    DecodingMode[DecodingMode[\"Legacy\"] = 0] = \"Legacy\";\n    /** Only allow entities terminated with a semicolon. */\n    DecodingMode[DecodingMode[\"Strict\"] = 1] = \"Strict\";\n    /** Entities in attributes have limitations on ending characters. */\n    DecodingMode[DecodingMode[\"Attribute\"] = 2] = \"Attribute\";\n})(DecodingMode || (DecodingMode = {}));\n/**\n * Token decoder with support of writing partial entities.\n */\nexport class EntityDecoder {\n    constructor(\n    /** The tree used to decode entities. */\n    decodeTree, \n    /**\n     * The function that is called when a codepoint is decoded.\n     *\n     * For multi-byte named entities, this will be called multiple times,\n     * with the second codepoint, and the same `consumed` value.\n     *\n     * @param codepoint The decoded codepoint.\n     * @param consumed The number of bytes consumed by the decoder.\n     */\n    emitCodePoint, \n    /** An object that is used to produce errors. */\n    errors) {\n        this.decodeTree = decodeTree;\n        this.emitCodePoint = emitCodePoint;\n        this.errors = errors;\n        /** The current state of the decoder. */\n        this.state = EntityDecoderState.EntityStart;\n        /** Characters that were consumed while parsing an entity. */\n        this.consumed = 1;\n        /**\n         * The result of the entity.\n         *\n         * Either the result index of a numeric entity, or the codepoint of a\n         * numeric entity.\n         */\n        this.result = 0;\n        /** The current index in the decode tree. */\n        this.treeIndex = 0;\n        /** The number of characters that were consumed in excess. */\n        this.excess = 1;\n        /** The mode in which the decoder is operating. */\n        this.decodeMode = DecodingMode.Strict;\n    }\n    /** Resets the instance to make it reusable. */\n    startEntity(decodeMode) {\n        this.decodeMode = decodeMode;\n        this.state = EntityDecoderState.EntityStart;\n        this.result = 0;\n        this.treeIndex = 0;\n        this.excess = 1;\n        this.consumed = 1;\n    }\n    /**\n     * Write an entity to the decoder. This can be called multiple times with partial entities.\n     * If the entity is incomplete, the decoder will return -1.\n     *\n     * Mirrors the implementation of `getDecoder`, but with the ability to stop decoding if the\n     * entity is incomplete, and resume when the next string is written.\n     *\n     * @param input The string containing the entity (or a continuation of the entity).\n     * @param offset The offset at which the entity begins. Should be 0 if this is not the first call.\n     * @returns The number of characters that were consumed, or -1 if the entity is incomplete.\n     */\n    write(input, offset) {\n        switch (this.state) {\n            case EntityDecoderState.EntityStart: {\n                if (input.charCodeAt(offset) === CharCodes.NUM) {\n                    this.state = EntityDecoderState.NumericStart;\n                    this.consumed += 1;\n                    return this.stateNumericStart(input, offset + 1);\n                }\n                this.state = EntityDecoderState.NamedEntity;\n                return this.stateNamedEntity(input, offset);\n            }\n            case EntityDecoderState.NumericStart: {\n                return this.stateNumericStart(input, offset);\n            }\n            case EntityDecoderState.NumericDecimal: {\n                return this.stateNumericDecimal(input, offset);\n            }\n            case EntityDecoderState.NumericHex: {\n                return this.stateNumericHex(input, offset);\n            }\n            case EntityDecoderState.NamedEntity: {\n                return this.stateNamedEntity(input, offset);\n            }\n        }\n    }\n    /**\n     * Switches between the numeric decimal and hexadecimal states.\n     *\n     * Equivalent to the `Numeric character reference state` in the HTML spec.\n     *\n     * @param input The string containing the entity (or a continuation of the entity).\n     * @param offset The current offset.\n     * @returns The number of characters that were consumed, or -1 if the entity is incomplete.\n     */\n    stateNumericStart(input, offset) {\n        if (offset >= input.length) {\n            return -1;\n        }\n        if ((input.charCodeAt(offset) | TO_LOWER_BIT) === CharCodes.LOWER_X) {\n            this.state = EntityDecoderState.NumericHex;\n            this.consumed += 1;\n            return this.stateNumericHex(input, offset + 1);\n        }\n        this.state = EntityDecoderState.NumericDecimal;\n        return this.stateNumericDecimal(input, offset);\n    }\n    addToNumericResult(input, start, end, base) {\n        if (start !== end) {\n            const digitCount = end - start;\n            this.result =\n                this.result * Math.pow(base, digitCount) +\n                    Number.parseInt(input.substr(start, digitCount), base);\n            this.consumed += digitCount;\n        }\n    }\n    /**\n     * Parses a hexadecimal numeric entity.\n     *\n     * Equivalent to the `Hexademical character reference state` in the HTML spec.\n     *\n     * @param input The string containing the entity (or a continuation of the entity).\n     * @param offset The current offset.\n     * @returns The number of characters that were consumed, or -1 if the entity is incomplete.\n     */\n    stateNumericHex(input, offset) {\n        const startIndex = offset;\n        while (offset < input.length) {\n            const char = input.charCodeAt(offset);\n            if (isNumber(char) || isHexadecimalCharacter(char)) {\n                offset += 1;\n            }\n            else {\n                this.addToNumericResult(input, startIndex, offset, 16);\n                return this.emitNumericEntity(char, 3);\n            }\n        }\n        this.addToNumericResult(input, startIndex, offset, 16);\n        return -1;\n    }\n    /**\n     * Parses a decimal numeric entity.\n     *\n     * Equivalent to the `Decimal character reference state` in the HTML spec.\n     *\n     * @param input The string containing the entity (or a continuation of the entity).\n     * @param offset The current offset.\n     * @returns The number of characters that were consumed, or -1 if the entity is incomplete.\n     */\n    stateNumericDecimal(input, offset) {\n        const startIndex = offset;\n        while (offset < input.length) {\n            const char = input.charCodeAt(offset);\n            if (isNumber(char)) {\n                offset += 1;\n            }\n            else {\n                this.addToNumericResult(input, startIndex, offset, 10);\n                return this.emitNumericEntity(char, 2);\n            }\n        }\n        this.addToNumericResult(input, startIndex, offset, 10);\n        return -1;\n    }\n    /**\n     * Validate and emit a numeric entity.\n     *\n     * Implements the logic from the `Hexademical character reference start\n     * state` and `Numeric character reference end state` in the HTML spec.\n     *\n     * @param lastCp The last code point of the entity. Used to see if the\n     *               entity was terminated with a semicolon.\n     * @param expectedLength The minimum number of characters that should be\n     *                       consumed. Used to validate that at least one digit\n     *                       was consumed.\n     * @returns The number of characters that were consumed.\n     */\n    emitNumericEntity(lastCp, expectedLength) {\n        var _a;\n        // Ensure we consumed at least one digit.\n        if (this.consumed <= expectedLength) {\n            (_a = this.errors) === null || _a === void 0 ? void 0 : _a.absenceOfDigitsInNumericCharacterReference(this.consumed);\n            return 0;\n        }\n        // Figure out if this is a legit end of the entity\n        if (lastCp === CharCodes.SEMI) {\n            this.consumed += 1;\n        }\n        else if (this.decodeMode === DecodingMode.Strict) {\n            return 0;\n        }\n        this.emitCodePoint(replaceCodePoint(this.result), this.consumed);\n        if (this.errors) {\n            if (lastCp !== CharCodes.SEMI) {\n                this.errors.missingSemicolonAfterCharacterReference();\n            }\n            this.errors.validateNumericCharacterReference(this.result);\n        }\n        return this.consumed;\n    }\n    /**\n     * Parses a named entity.\n     *\n     * Equivalent to the `Named character reference state` in the HTML spec.\n     *\n     * @param input The string containing the entity (or a continuation of the entity).\n     * @param offset The current offset.\n     * @returns The number of characters that were consumed, or -1 if the entity is incomplete.\n     */\n    stateNamedEntity(input, offset) {\n        const { decodeTree } = this;\n        let current = decodeTree[this.treeIndex];\n        // The mask is the number of bytes of the value, including the current byte.\n        let valueLength = (current & BinTrieFlags.VALUE_LENGTH) >> 14;\n        for (; offset < input.length; offset++, this.excess++) {\n            const char = input.charCodeAt(offset);\n            this.treeIndex = determineBranch(decodeTree, current, this.treeIndex + Math.max(1, valueLength), char);\n            if (this.treeIndex < 0) {\n                return this.result === 0 ||\n                    // If we are parsing an attribute\n                    (this.decodeMode === DecodingMode.Attribute &&\n                        // We shouldn't have consumed any characters after the entity,\n                        (valueLength === 0 ||\n                            // And there should be no invalid characters.\n                            isEntityInAttributeInvalidEnd(char)))\n                    ? 0\n                    : this.emitNotTerminatedNamedEntity();\n            }\n            current = decodeTree[this.treeIndex];\n            valueLength = (current & BinTrieFlags.VALUE_LENGTH) >> 14;\n            // If the branch is a value, store it and continue\n            if (valueLength !== 0) {\n                // If the entity is terminated by a semicolon, we are done.\n                if (char === CharCodes.SEMI) {\n                    return this.emitNamedEntityData(this.treeIndex, valueLength, this.consumed + this.excess);\n                }\n                // If we encounter a non-terminated (legacy) entity while parsing strictly, then ignore it.\n                if (this.decodeMode !== DecodingMode.Strict) {\n                    this.result = this.treeIndex;\n                    this.consumed += this.excess;\n                    this.excess = 0;\n                }\n            }\n        }\n        return -1;\n    }\n    /**\n     * Emit a named entity that was not terminated with a semicolon.\n     *\n     * @returns The number of characters consumed.\n     */\n    emitNotTerminatedNamedEntity() {\n        var _a;\n        const { result, decodeTree } = this;\n        const valueLength = (decodeTree[result] & BinTrieFlags.VALUE_LENGTH) >> 14;\n        this.emitNamedEntityData(result, valueLength, this.consumed);\n        (_a = this.errors) === null || _a === void 0 ? void 0 : _a.missingSemicolonAfterCharacterReference();\n        return this.consumed;\n    }\n    /**\n     * Emit a named entity.\n     *\n     * @param result The index of the entity in the decode tree.\n     * @param valueLength The number of bytes in the entity.\n     * @param consumed The number of characters consumed.\n     *\n     * @returns The number of characters consumed.\n     */\n    emitNamedEntityData(result, valueLength, consumed) {\n        const { decodeTree } = this;\n        this.emitCodePoint(valueLength === 1\n            ? decodeTree[result] & ~BinTrieFlags.VALUE_LENGTH\n            : decodeTree[result + 1], consumed);\n        if (valueLength === 3) {\n            // For multi-byte values, we need to emit the second byte.\n            this.emitCodePoint(decodeTree[result + 2], consumed);\n        }\n        return consumed;\n    }\n    /**\n     * Signal to the parser that the end of the input was reached.\n     *\n     * Remaining data will be emitted and relevant errors will be produced.\n     *\n     * @returns The number of characters consumed.\n     */\n    end() {\n        var _a;\n        switch (this.state) {\n            case EntityDecoderState.NamedEntity: {\n                // Emit a named entity if we have one.\n                return this.result !== 0 &&\n                    (this.decodeMode !== DecodingMode.Attribute ||\n                        this.result === this.treeIndex)\n                    ? this.emitNotTerminatedNamedEntity()\n                    : 0;\n            }\n            // Otherwise, emit a numeric entity if we have one.\n            case EntityDecoderState.NumericDecimal: {\n                return this.emitNumericEntity(0, 2);\n            }\n            case EntityDecoderState.NumericHex: {\n                return this.emitNumericEntity(0, 3);\n            }\n            case EntityDecoderState.NumericStart: {\n                (_a = this.errors) === null || _a === void 0 ? void 0 : _a.absenceOfDigitsInNumericCharacterReference(this.consumed);\n                return 0;\n            }\n            case EntityDecoderState.EntityStart: {\n                // Return 0 if we have no entity.\n                return 0;\n            }\n        }\n    }\n}\n/**\n * Creates a function that decodes entities in a string.\n *\n * @param decodeTree The decode tree.\n * @returns A function that decodes entities in a string.\n */\nfunction getDecoder(decodeTree) {\n    let returnValue = \"\";\n    const decoder = new EntityDecoder(decodeTree, (data) => (returnValue += fromCodePoint(data)));\n    return function decodeWithTrie(input, decodeMode) {\n        let lastIndex = 0;\n        let offset = 0;\n        while ((offset = input.indexOf(\"&\", offset)) >= 0) {\n            returnValue += input.slice(lastIndex, offset);\n            decoder.startEntity(decodeMode);\n            const length = decoder.write(input, \n            // Skip the \"&\"\n            offset + 1);\n            if (length < 0) {\n                lastIndex = offset + decoder.end();\n                break;\n            }\n            lastIndex = offset + length;\n            // If `length` is 0, skip the current `&` and continue.\n            offset = length === 0 ? lastIndex + 1 : lastIndex;\n        }\n        const result = returnValue + input.slice(lastIndex);\n        // Make sure we don't keep a reference to the final string.\n        returnValue = \"\";\n        return result;\n    };\n}\n/**\n * Determines the branch of the current node that is taken given the current\n * character. This function is used to traverse the trie.\n *\n * @param decodeTree The trie.\n * @param current The current node.\n * @param nodeIdx The index right after the current node and its value.\n * @param char The current character.\n * @returns The index of the next node, or -1 if no branch is taken.\n */\nexport function determineBranch(decodeTree, current, nodeIndex, char) {\n    const branchCount = (current & BinTrieFlags.BRANCH_LENGTH) >> 7;\n    const jumpOffset = current & BinTrieFlags.JUMP_TABLE;\n    // Case 1: Single branch encoded in jump offset\n    if (branchCount === 0) {\n        return jumpOffset !== 0 && char === jumpOffset ? nodeIndex : -1;\n    }\n    // Case 2: Multiple branches encoded in jump table\n    if (jumpOffset) {\n        const value = char - jumpOffset;\n        return value < 0 || value >= branchCount\n            ? -1\n            : decodeTree[nodeIndex + value] - 1;\n    }\n    // Case 3: Multiple branches encoded in dictionary\n    // Binary search for the character.\n    let lo = nodeIndex;\n    let hi = lo + branchCount - 1;\n    while (lo <= hi) {\n        const mid = (lo + hi) >>> 1;\n        const midValue = decodeTree[mid];\n        if (midValue < char) {\n            lo = mid + 1;\n        }\n        else if (midValue > char) {\n            hi = mid - 1;\n        }\n        else {\n            return decodeTree[mid + branchCount];\n        }\n    }\n    return -1;\n}\nconst htmlDecoder = /* #__PURE__ */ getDecoder(htmlDecodeTree);\nconst xmlDecoder = /* #__PURE__ */ getDecoder(xmlDecodeTree);\n/**\n * Decodes an HTML string.\n *\n * @param htmlString The string to decode.\n * @param mode The decoding mode.\n * @returns The decoded string.\n */\nexport function decodeHTML(htmlString, mode = DecodingMode.Legacy) {\n    return htmlDecoder(htmlString, mode);\n}\n/**\n * Decodes an HTML string in an attribute.\n *\n * @param htmlAttribute The string to decode.\n * @returns The decoded string.\n */\nexport function decodeHTMLAttribute(htmlAttribute) {\n    return htmlDecoder(htmlAttribute, DecodingMode.Attribute);\n}\n/**\n * Decodes an HTML string, requiring all entities to be terminated by a semicolon.\n *\n * @param htmlString The string to decode.\n * @returns The decoded string.\n */\nexport function decodeHTMLStrict(htmlString) {\n    return htmlDecoder(htmlString, DecodingMode.Strict);\n}\n/**\n * Decodes an XML string, requiring all entities to be terminated by a semicolon.\n *\n * @param xmlString The string to decode.\n * @returns The decoded string.\n */\nexport function decodeXML(xmlString) {\n    return xmlDecoder(xmlString, DecodingMode.Strict);\n}\n// Re-export for use by eg. htmlparser2\nexport { htmlDecodeTree } from \"./generated/decode-data-html.js\";\nexport { xmlDecodeTree } from \"./generated/decode-data-xml.js\";\nexport { decodeCodePoint, replaceCodePoint, fromCodePoint, } from \"./decode-codepoint.js\";\n//# sourceMappingURL=decode.js.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/entities/src/encode.d.ts",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/**\n * Encodes all characters in the input using HTML entities. This includes\n * characters that are valid ASCII characters in HTML documents, such as `#`.\n *\n * To get a more compact output, consider using the `encodeNonAsciiHTML`\n * function, which will only encode characters that are not valid in HTML\n * documents, as well as non-ASCII characters.\n *\n * If a character has no equivalent entity, a numeric hexadecimal reference\n * (eg. `&#xfc;`) will be used.\n */\nexport declare function encodeHTML(input: string): string;\n/**\n * Encodes all non-ASCII characters, as well as characters not valid in HTML\n * documents using HTML entities. This function will not encode characters that\n * are valid in HTML documents, such as `#`.\n *\n * If a character has no equivalent entity, a numeric hexadecimal reference\n * (eg. `&#xfc;`) will be used.\n */\nexport declare function encodeNonAsciiHTML(input: string): string;\n//# sourceMappingURL=encode.d.ts.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/entities/src/encode.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { htmlTrie } from \"./generated/encode-html\";\nimport { xmlReplacer, getCodePoint } from \"./escape\";\nconst htmlReplacer = /[\\t\\n\\f!-,./:-@[-`{-}\\u0080-\\uFFFF]/g;\n/**\n * Encodes all characters in the input using HTML entities. This includes\n * characters that are valid ASCII characters in HTML documents, such as `#`.\n *\n * To get a more compact output, consider using the `encodeNonAsciiHTML`\n * function, which will only encode characters that are not valid in HTML\n * documents, as well as non-ASCII characters.\n *\n * If a character has no equivalent entity, a numeric hexadecimal reference\n * (eg. `&#xfc;`) will be used.\n */\nexport function encodeHTML(input) {\n    return encodeHTMLTrieRe(htmlReplacer, input);\n}\n/**\n * Encodes all non-ASCII characters, as well as characters not valid in HTML\n * documents using HTML entities. This function will not encode characters that\n * are valid in HTML documents, such as `#`.\n *\n * If a character has no equivalent entity, a numeric hexadecimal reference\n * (eg. `&#xfc;`) will be used.\n */\nexport function encodeNonAsciiHTML(input) {\n    return encodeHTMLTrieRe(xmlReplacer, input);\n}\nfunction encodeHTMLTrieRe(regExp, input) {\n    let returnValue = \"\";\n    let lastIndex = 0;\n    let match;\n    while ((match = regExp.exec(input)) !== null) {\n        const { index } = match;\n        returnValue += input.substring(lastIndex, index);\n        const char = input.charCodeAt(index);\n        let next = htmlTrie.get(char);\n        if (typeof next === \"object\") {\n            // We are in a branch. Try to match the next char.\n            if (index + 1 < input.length) {\n                const nextChar = input.charCodeAt(index + 1);\n                const value = typeof next.n === \"number\"\n                    ? next.n === nextChar\n                        ? next.o\n                        : undefined\n                    : next.n.get(nextChar);\n                if (value !== undefined) {\n                    returnValue += value;\n                    lastIndex = regExp.lastIndex += 1;\n                    continue;\n                }\n            }\n            next = next.v;\n        }\n        // We might have a tree node without a value; skip and use a numeric entity.\n        if (next === undefined) {\n            const cp = getCodePoint(input, index);\n            returnValue += `&#x${cp.toString(16)};`;\n            // Increase by 1 if we have a surrogate pair\n            lastIndex = regExp.lastIndex += Number(cp !== char);\n        }\n        else {\n            returnValue += next;\n            lastIndex = index + 1;\n        }\n    }\n    return returnValue + input.substr(lastIndex);\n}\n//# sourceMappingURL=encode.js.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/entities/src/escape.d.ts",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport declare const xmlReplacer: RegExp;\nexport declare const getCodePoint: (c: string, index: number) => number;\n/**\n * Encodes all non-ASCII characters, as well as characters not valid in XML\n * documents using XML entities.\n *\n * If a character has no equivalent entity, a\n * numeric hexadecimal reference (eg. `&#xfc;`) will be used.\n */\nexport declare function encodeXML(input: string): string;\n/**\n * Encodes all non-ASCII characters, as well as characters not valid in XML\n * documents using numeric hexadecimal reference (eg. `&#xfc;`).\n *\n * Have a look at `escapeUTF8` if you want a more concise output at the expense\n * of reduced transportability.\n *\n * @param data String to escape.\n */\nexport declare const escape: typeof encodeXML;\n/**\n * Encodes all characters not valid in XML documents using XML entities.\n *\n * Note that the output will be character-set dependent.\n *\n * @param data String to escape.\n */\nexport declare const escapeUTF8: (data: string) => string;\n/**\n * Encodes all characters that have to be escaped in HTML attributes,\n * following {@link https://html.spec.whatwg.org/multipage/parsing.html#escapingString}.\n *\n * @param data String to escape.\n */\nexport declare const escapeAttribute: (data: string) => string;\n/**\n * Encodes all characters that have to be escaped in HTML text,\n * following {@link https://html.spec.whatwg.org/multipage/parsing.html#escapingString}.\n *\n * @param data String to escape.\n */\nexport declare const escapeText: (data: string) => string;\n//# sourceMappingURL=escape.d.ts.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/entities/src/escape.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport const xmlReplacer = /[\"$&'<>\\u0080-\\uFFFF]/g;\nconst xmlCodeMap = new Map([\n    [34, \"&quot;\"],\n    [38, \"&amp;\"],\n    [39, \"&apos;\"],\n    [60, \"&lt;\"],\n    [62, \"&gt;\"],\n]);\n// For compatibility with node < 4, we wrap `codePointAt`\nexport const getCodePoint = \n// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\nString.prototype.codePointAt == null\n    ? (c, index) => (c.charCodeAt(index) & 64512) === 55296\n        ? (c.charCodeAt(index) - 55296) * 1024 +\n            c.charCodeAt(index + 1) -\n            56320 +\n            65536\n        : c.charCodeAt(index)\n    : // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae\n        (input, index) => input.codePointAt(index);\n/**\n * Encodes all non-ASCII characters, as well as characters not valid in XML\n * documents using XML entities.\n *\n * If a character has no equivalent entity, a\n * numeric hexadecimal reference (eg. `&#xfc;`) will be used.\n */\nexport function encodeXML(input) {\n    let returnValue = \"\";\n    let lastIndex = 0;\n    let match;\n    while ((match = xmlReplacer.exec(input)) !== null) {\n        const { index } = match;\n        const char = input.charCodeAt(index);\n        const next = xmlCodeMap.get(char);\n        if (next === undefined) {\n            returnValue += `${input.substring(lastIndex, index)}&#x${getCodePoint(input, index).toString(16)};`;\n            // Increase by 1 if we have a surrogate pair\n            lastIndex = xmlReplacer.lastIndex += Number((char & 64512) === 55296);\n        }\n        else {\n            returnValue += input.substring(lastIndex, index) + next;\n            lastIndex = index + 1;\n        }\n    }\n    return returnValue + input.substr(lastIndex);\n}\n/**\n * Encodes all non-ASCII characters, as well as characters not valid in XML\n * documents using numeric hexadecimal reference (eg. `&#xfc;`).\n *\n * Have a look at `escapeUTF8` if you want a more concise output at the expense\n * of reduced transportability.\n *\n * @param data String to escape.\n */\nexport const escape = encodeXML;\n/**\n * Creates a function that escapes all characters matched by the given regular\n * expression using the given map of characters to escape to their entities.\n *\n * @param regex Regular expression to match characters to escape.\n * @param map Map of characters to escape to their entities.\n *\n * @returns Function that escapes all characters matched by the given regular\n * expression using the given map of characters to escape to their entities.\n */\nfunction getEscaper(regex, map) {\n    return function escape(data) {\n        let match;\n        let lastIndex = 0;\n        let result = \"\";\n        while ((match = regex.exec(data))) {\n            if (lastIndex !== match.index) {\n                result += data.substring(lastIndex, match.index);\n            }\n            // We know that this character will be in the map.\n            result += map.get(match[0].charCodeAt(0));\n            // Every match will be of length 1\n            lastIndex = match.index + 1;\n        }\n        return result + data.substring(lastIndex);\n    };\n}\n/**\n * Encodes all characters not valid in XML documents using XML entities.\n *\n * Note that the output will be character-set dependent.\n *\n * @param data String to escape.\n */\nexport const escapeUTF8 = /* #__PURE__ */ getEscaper(/[\"&'<>]/g, xmlCodeMap);\n/**\n * Encodes all characters that have to be escaped in HTML attributes,\n * following {@link https://html.spec.whatwg.org/multipage/parsing.html#escapingString}.\n *\n * @param data String to escape.\n */\nexport const escapeAttribute = \n/* #__PURE__ */ getEscaper(/[\"&\\u00A0]/g, new Map([\n    [34, \"&quot;\"],\n    [38, \"&amp;\"],\n    [160, \"&nbsp;\"],\n]));\n/**\n * Encodes all characters that have to be escaped in HTML text,\n * following {@link https://html.spec.whatwg.org/multipage/parsing.html#escapingString}.\n *\n * @param data String to escape.\n */\nexport const escapeText = /* #__PURE__ */ getEscaper(/[&<>\\u00A0]/g, new Map([\n    [38, \"&amp;\"],\n    [60, \"&lt;\"],\n    [62, \"&gt;\"],\n    [160, \"&nbsp;\"],\n]));\n//# sourceMappingURL=escape.js.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/entities/src/generated/decode-data-html.d.ts",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport declare const htmlDecodeTree: Uint16Array;\n//# sourceMappingURL=decode-data-html.d.ts.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/entities/src/generated/decode-data-html.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n// Generated using scripts/write-decode-map.ts\nexport const htmlDecodeTree = /* #__PURE__ */ new Uint16Array(\n// prettier-ignore\n/* #__PURE__ */ \"\\u1d41<\\xd5\\u0131\\u028a\\u049d\\u057b\\u05d0\\u0675\\u06de\\u07a2\\u07d6\\u080f\\u0a4a\\u0a91\\u0da1\\u0e6d\\u0f09\\u0f26\\u10ca\\u1228\\u12e1\\u1415\\u149d\\u14c3\\u14df\\u1525\\0\\0\\0\\0\\0\\0\\u156b\\u16cd\\u198d\\u1c12\\u1ddd\\u1f7e\\u2060\\u21b0\\u228d\\u23c0\\u23fb\\u2442\\u2824\\u2912\\u2d08\\u2e48\\u2fce\\u3016\\u32ba\\u3639\\u37ac\\u38fe\\u3a28\\u3a71\\u3ae0\\u3b2e\\u0800EMabcfglmnoprstu\\\\bfms\\x7f\\x84\\x8b\\x90\\x95\\x98\\xa6\\xb3\\xb9\\xc8\\xcflig\\u803b\\xc6\\u40c6P\\u803b&\\u4026cute\\u803b\\xc1\\u40c1reve;\\u4102\\u0100iyx}rc\\u803b\\xc2\\u40c2;\\u4410r;\\uc000\\ud835\\udd04rave\\u803b\\xc0\\u40c0pha;\\u4391acr;\\u4100d;\\u6a53\\u0100gp\\x9d\\xa1on;\\u4104f;\\uc000\\ud835\\udd38plyFunction;\\u6061ing\\u803b\\xc5\\u40c5\\u0100cs\\xbe\\xc3r;\\uc000\\ud835\\udc9cign;\\u6254ilde\\u803b\\xc3\\u40c3ml\\u803b\\xc4\\u40c4\\u0400aceforsu\\xe5\\xfb\\xfe\\u0117\\u011c\\u0122\\u0127\\u012a\\u0100cr\\xea\\xf2kslash;\\u6216\\u0176\\xf6\\xf8;\\u6ae7ed;\\u6306y;\\u4411\\u0180crt\\u0105\\u010b\\u0114ause;\\u6235noullis;\\u612ca;\\u4392r;\\uc000\\ud835\\udd05pf;\\uc000\\ud835\\udd39eve;\\u42d8c\\xf2\\u0113mpeq;\\u624e\\u0700HOacdefhilorsu\\u014d\\u0151\\u0156\\u0180\\u019e\\u01a2\\u01b5\\u01b7\\u01ba\\u01dc\\u0215\\u0273\\u0278\\u027ecy;\\u4427PY\\u803b\\xa9\\u40a9\\u0180cpy\\u015d\\u0162\\u017aute;\\u4106\\u0100;i\\u0167\\u0168\\u62d2talDifferentialD;\\u6145leys;\\u612d\\u0200aeio\\u0189\\u018e\\u0194\\u0198ron;\\u410cdil\\u803b\\xc7\\u40c7rc;\\u4108nint;\\u6230ot;\\u410a\\u0100dn\\u01a7\\u01adilla;\\u40b8terDot;\\u40b7\\xf2\\u017fi;\\u43a7rcle\\u0200DMPT\\u01c7\\u01cb\\u01d1\\u01d6ot;\\u6299inus;\\u6296lus;\\u6295imes;\\u6297o\\u0100cs\\u01e2\\u01f8kwiseContourIntegral;\\u6232eCurly\\u0100DQ\\u0203\\u020foubleQuote;\\u601duote;\\u6019\\u0200lnpu\\u021e\\u0228\\u0247\\u0255on\\u0100;e\\u0225\\u0226\\u6237;\\u6a74\\u0180git\\u022f\\u0236\\u023aruent;\\u6261nt;\\u622fourIntegral;\\u622e\\u0100fr\\u024c\\u024e;\\u6102oduct;\\u6210nterClockwiseContourIntegral;\\u6233oss;\\u6a2fcr;\\uc000\\ud835\\udc9ep\\u0100;C\\u0284\\u0285\\u62d3ap;\\u624d\\u0580DJSZacefios\\u02a0\\u02ac\\u02b0\\u02b4\\u02b8\\u02cb\\u02d7\\u02e1\\u02e6\\u0333\\u048d\\u0100;o\\u0179\\u02a5trahd;\\u6911cy;\\u4402cy;\\u4405cy;\\u440f\\u0180grs\\u02bf\\u02c4\\u02c7ger;\\u6021r;\\u61a1hv;\\u6ae4\\u0100ay\\u02d0\\u02d5ron;\\u410e;\\u4414l\\u0100;t\\u02dd\\u02de\\u6207a;\\u4394r;\\uc000\\ud835\\udd07\\u0100af\\u02eb\\u0327\\u0100cm\\u02f0\\u0322ritical\\u0200ADGT\\u0300\\u0306\\u0316\\u031ccute;\\u40b4o\\u0174\\u030b\\u030d;\\u42d9bleAcute;\\u42ddrave;\\u4060ilde;\\u42dcond;\\u62c4ferentialD;\\u6146\\u0470\\u033d\\0\\0\\0\\u0342\\u0354\\0\\u0405f;\\uc000\\ud835\\udd3b\\u0180;DE\\u0348\\u0349\\u034d\\u40a8ot;\\u60dcqual;\\u6250ble\\u0300CDLRUV\\u0363\\u0372\\u0382\\u03cf\\u03e2\\u03f8ontourIntegra\\xec\\u0239o\\u0274\\u0379\\0\\0\\u037b\\xbb\\u0349nArrow;\\u61d3\\u0100eo\\u0387\\u03a4ft\\u0180ART\\u0390\\u0396\\u03a1rrow;\\u61d0ightArrow;\\u61d4e\\xe5\\u02cang\\u0100LR\\u03ab\\u03c4eft\\u0100AR\\u03b3\\u03b9rrow;\\u67f8ightArrow;\\u67faightArrow;\\u67f9ight\\u0100AT\\u03d8\\u03derrow;\\u61d2ee;\\u62a8p\\u0241\\u03e9\\0\\0\\u03efrrow;\\u61d1ownArrow;\\u61d5erticalBar;\\u6225n\\u0300ABLRTa\\u0412\\u042a\\u0430\\u045e\\u047f\\u037crrow\\u0180;BU\\u041d\\u041e\\u0422\\u6193ar;\\u6913pArrow;\\u61f5reve;\\u4311eft\\u02d2\\u043a\\0\\u0446\\0\\u0450ightVector;\\u6950eeVector;\\u695eector\\u0100;B\\u0459\\u045a\\u61bdar;\\u6956ight\\u01d4\\u0467\\0\\u0471eeVector;\\u695fector\\u0100;B\\u047a\\u047b\\u61c1ar;\\u6957ee\\u0100;A\\u0486\\u0487\\u62a4rrow;\\u61a7\\u0100ct\\u0492\\u0497r;\\uc000\\ud835\\udc9frok;\\u4110\\u0800NTacdfglmopqstux\\u04bd\\u04c0\\u04c4\\u04cb\\u04de\\u04e2\\u04e7\\u04ee\\u04f5\\u0521\\u052f\\u0536\\u0552\\u055d\\u0560\\u0565G;\\u414aH\\u803b\\xd0\\u40d0cute\\u803b\\xc9\\u40c9\\u0180aiy\\u04d2\\u04d7\\u04dcron;\\u411arc\\u803b\\xca\\u40ca;\\u442dot;\\u4116r;\\uc000\\ud835\\udd08rave\\u803b\\xc8\\u40c8ement;\\u6208\\u0100ap\\u04fa\\u04fecr;\\u4112ty\\u0253\\u0506\\0\\0\\u0512mallSquare;\\u65fberySmallSquare;\\u65ab\\u0100gp\\u0526\\u052aon;\\u4118f;\\uc000\\ud835\\udd3csilon;\\u4395u\\u0100ai\\u053c\\u0549l\\u0100;T\\u0542\\u0543\\u6a75ilde;\\u6242librium;\\u61cc\\u0100ci\\u0557\\u055ar;\\u6130m;\\u6a73a;\\u4397ml\\u803b\\xcb\\u40cb\\u0100ip\\u056a\\u056fsts;\\u6203onentialE;\\u6147\\u0280cfios\\u0585\\u0588\\u058d\\u05b2\\u05ccy;\\u4424r;\\uc000\\ud835\\udd09lled\\u0253\\u0597\\0\\0\\u05a3mallSquare;\\u65fcerySmallSquare;\\u65aa\\u0370\\u05ba\\0\\u05bf\\0\\0\\u05c4f;\\uc000\\ud835\\udd3dAll;\\u6200riertrf;\\u6131c\\xf2\\u05cb\\u0600JTabcdfgorst\\u05e8\\u05ec\\u05ef\\u05fa\\u0600\\u0612\\u0616\\u061b\\u061d\\u0623\\u066c\\u0672cy;\\u4403\\u803b>\\u403emma\\u0100;d\\u05f7\\u05f8\\u4393;\\u43dcreve;\\u411e\\u0180eiy\\u0607\\u060c\\u0610dil;\\u4122rc;\\u411c;\\u4413ot;\\u4120r;\\uc000\\ud835\\udd0a;\\u62d9pf;\\uc000\\ud835\\udd3eeater\\u0300EFGLST\\u0635\\u0644\\u064e\\u0656\\u065b\\u0666qual\\u0100;L\\u063e\\u063f\\u6265ess;\\u62dbullEqual;\\u6267reater;\\u6aa2ess;\\u6277lantEqual;\\u6a7eilde;\\u6273cr;\\uc000\\ud835\\udca2;\\u626b\\u0400Aacfiosu\\u0685\\u068b\\u0696\\u069b\\u069e\\u06aa\\u06be\\u06caRDcy;\\u442a\\u0100ct\\u0690\\u0694ek;\\u42c7;\\u405eirc;\\u4124r;\\u610clbertSpace;\\u610b\\u01f0\\u06af\\0\\u06b2f;\\u610dizontalLine;\\u6500\\u0100ct\\u06c3\\u06c5\\xf2\\u06a9rok;\\u4126mp\\u0144\\u06d0\\u06d8ownHum\\xf0\\u012fqual;\\u624f\\u0700EJOacdfgmnostu\\u06fa\\u06fe\\u0703\\u0707\\u070e\\u071a\\u071e\\u0721\\u0728\\u0744\\u0778\\u078b\\u078f\\u0795cy;\\u4415lig;\\u4132cy;\\u4401cute\\u803b\\xcd\\u40cd\\u0100iy\\u0713\\u0718rc\\u803b\\xce\\u40ce;\\u4418ot;\\u4130r;\\u6111rave\\u803b\\xcc\\u40cc\\u0180;ap\\u0720\\u072f\\u073f\\u0100cg\\u0734\\u0737r;\\u412ainaryI;\\u6148lie\\xf3\\u03dd\\u01f4\\u0749\\0\\u0762\\u0100;e\\u074d\\u074e\\u622c\\u0100gr\\u0753\\u0758ral;\\u622bsection;\\u62c2isible\\u0100CT\\u076c\\u0772omma;\\u6063imes;\\u6062\\u0180gpt\\u077f\\u0783\\u0788on;\\u412ef;\\uc000\\ud835\\udd40a;\\u4399cr;\\u6110ilde;\\u4128\\u01eb\\u079a\\0\\u079ecy;\\u4406l\\u803b\\xcf\\u40cf\\u0280cfosu\\u07ac\\u07b7\\u07bc\\u07c2\\u07d0\\u0100iy\\u07b1\\u07b5rc;\\u4134;\\u4419r;\\uc000\\ud835\\udd0dpf;\\uc000\\ud835\\udd41\\u01e3\\u07c7\\0\\u07ccr;\\uc000\\ud835\\udca5rcy;\\u4408kcy;\\u4404\\u0380HJacfos\\u07e4\\u07e8\\u07ec\\u07f1\\u07fd\\u0802\\u0808cy;\\u4425cy;\\u440cppa;\\u439a\\u0100ey\\u07f6\\u07fbdil;\\u4136;\\u441ar;\\uc000\\ud835\\udd0epf;\\uc000\\ud835\\udd42cr;\\uc000\\ud835\\udca6\\u0580JTaceflmost\\u0825\\u0829\\u082c\\u0850\\u0863\\u09b3\\u09b8\\u09c7\\u09cd\\u0a37\\u0a47cy;\\u4409\\u803b<\\u403c\\u0280cmnpr\\u0837\\u083c\\u0841\\u0844\\u084dute;\\u4139bda;\\u439bg;\\u67ealacetrf;\\u6112r;\\u619e\\u0180aey\\u0857\\u085c\\u0861ron;\\u413ddil;\\u413b;\\u441b\\u0100fs\\u0868\\u0970t\\u0500ACDFRTUVar\\u087e\\u08a9\\u08b1\\u08e0\\u08e6\\u08fc\\u092f\\u095b\\u0390\\u096a\\u0100nr\\u0883\\u088fgleBracket;\\u67e8row\\u0180;BR\\u0899\\u089a\\u089e\\u6190ar;\\u61e4ightArrow;\\u61c6eiling;\\u6308o\\u01f5\\u08b7\\0\\u08c3bleBracket;\\u67e6n\\u01d4\\u08c8\\0\\u08d2eeVector;\\u6961ector\\u0100;B\\u08db\\u08dc\\u61c3ar;\\u6959loor;\\u630aight\\u0100AV\\u08ef\\u08f5rrow;\\u6194ector;\\u694e\\u0100er\\u0901\\u0917e\\u0180;AV\\u0909\\u090a\\u0910\\u62a3rrow;\\u61a4ector;\\u695aiangle\\u0180;BE\\u0924\\u0925\\u0929\\u62b2ar;\\u69cfqual;\\u62b4p\\u0180DTV\\u0937\\u0942\\u094cownVector;\\u6951eeVector;\\u6960ector\\u0100;B\\u0956\\u0957\\u61bfar;\\u6958ector\\u0100;B\\u0965\\u0966\\u61bcar;\\u6952ight\\xe1\\u039cs\\u0300EFGLST\\u097e\\u098b\\u0995\\u099d\\u09a2\\u09adqualGreater;\\u62daullEqual;\\u6266reater;\\u6276ess;\\u6aa1lantEqual;\\u6a7dilde;\\u6272r;\\uc000\\ud835\\udd0f\\u0100;e\\u09bd\\u09be\\u62d8ftarrow;\\u61daidot;\\u413f\\u0180npw\\u09d4\\u0a16\\u0a1bg\\u0200LRlr\\u09de\\u09f7\\u0a02\\u0a10eft\\u0100AR\\u09e6\\u09ecrrow;\\u67f5ightArrow;\\u67f7ightArrow;\\u67f6eft\\u0100ar\\u03b3\\u0a0aight\\xe1\\u03bfight\\xe1\\u03caf;\\uc000\\ud835\\udd43er\\u0100LR\\u0a22\\u0a2ceftArrow;\\u6199ightArrow;\\u6198\\u0180cht\\u0a3e\\u0a40\\u0a42\\xf2\\u084c;\\u61b0rok;\\u4141;\\u626a\\u0400acefiosu\\u0a5a\\u0a5d\\u0a60\\u0a77\\u0a7c\\u0a85\\u0a8b\\u0a8ep;\\u6905y;\\u441c\\u0100dl\\u0a65\\u0a6fiumSpace;\\u605flintrf;\\u6133r;\\uc000\\ud835\\udd10nusPlus;\\u6213pf;\\uc000\\ud835\\udd44c\\xf2\\u0a76;\\u439c\\u0480Jacefostu\\u0aa3\\u0aa7\\u0aad\\u0ac0\\u0b14\\u0b19\\u0d91\\u0d97\\u0d9ecy;\\u440acute;\\u4143\\u0180aey\\u0ab4\\u0ab9\\u0aberon;\\u4147dil;\\u4145;\\u441d\\u0180gsw\\u0ac7\\u0af0\\u0b0eative\\u0180MTV\\u0ad3\\u0adf\\u0ae8ediumSpace;\\u600bhi\\u0100cn\\u0ae6\\u0ad8\\xeb\\u0ad9eryThi\\xee\\u0ad9ted\\u0100GL\\u0af8\\u0b06reaterGreate\\xf2\\u0673essLes\\xf3\\u0a48Line;\\u400ar;\\uc000\\ud835\\udd11\\u0200Bnpt\\u0b22\\u0b28\\u0b37\\u0b3areak;\\u6060BreakingSpace;\\u40a0f;\\u6115\\u0680;CDEGHLNPRSTV\\u0b55\\u0b56\\u0b6a\\u0b7c\\u0ba1\\u0beb\\u0c04\\u0c5e\\u0c84\\u0ca6\\u0cd8\\u0d61\\u0d85\\u6aec\\u0100ou\\u0b5b\\u0b64ngruent;\\u6262pCap;\\u626doubleVerticalBar;\\u6226\\u0180lqx\\u0b83\\u0b8a\\u0b9bement;\\u6209ual\\u0100;T\\u0b92\\u0b93\\u6260ilde;\\uc000\\u2242\\u0338ists;\\u6204reater\\u0380;EFGLST\\u0bb6\\u0bb7\\u0bbd\\u0bc9\\u0bd3\\u0bd8\\u0be5\\u626fqual;\\u6271ullEqual;\\uc000\\u2267\\u0338reater;\\uc000\\u226b\\u0338ess;\\u6279lantEqual;\\uc000\\u2a7e\\u0338ilde;\\u6275ump\\u0144\\u0bf2\\u0bfdownHump;\\uc000\\u224e\\u0338qual;\\uc000\\u224f\\u0338e\\u0100fs\\u0c0a\\u0c27tTriangle\\u0180;BE\\u0c1a\\u0c1b\\u0c21\\u62eaar;\\uc000\\u29cf\\u0338qual;\\u62ecs\\u0300;EGLST\\u0c35\\u0c36\\u0c3c\\u0c44\\u0c4b\\u0c58\\u626equal;\\u6270reater;\\u6278ess;\\uc000\\u226a\\u0338lantEqual;\\uc000\\u2a7d\\u0338ilde;\\u6274ested\\u0100GL\\u0c68\\u0c79reaterGreater;\\uc000\\u2aa2\\u0338essLess;\\uc000\\u2aa1\\u0338recedes\\u0180;ES\\u0c92\\u0c93\\u0c9b\\u6280qual;\\uc000\\u2aaf\\u0338lantEqual;\\u62e0\\u0100ei\\u0cab\\u0cb9verseElement;\\u620cghtTriangle\\u0180;BE\\u0ccb\\u0ccc\\u0cd2\\u62ebar;\\uc000\\u29d0\\u0338qual;\\u62ed\\u0100qu\\u0cdd\\u0d0cuareSu\\u0100bp\\u0ce8\\u0cf9set\\u0100;E\\u0cf0\\u0cf3\\uc000\\u228f\\u0338qual;\\u62e2erset\\u0100;E\\u0d03\\u0d06\\uc000\\u2290\\u0338qual;\\u62e3\\u0180bcp\\u0d13\\u0d24\\u0d4eset\\u0100;E\\u0d1b\\u0d1e\\uc000\\u2282\\u20d2qual;\\u6288ceeds\\u0200;EST\\u0d32\\u0d33\\u0d3b\\u0d46\\u6281qual;\\uc000\\u2ab0\\u0338lantEqual;\\u62e1ilde;\\uc000\\u227f\\u0338erset\\u0100;E\\u0d58\\u0d5b\\uc000\\u2283\\u20d2qual;\\u6289ilde\\u0200;EFT\\u0d6e\\u0d6f\\u0d75\\u0d7f\\u6241qual;\\u6244ullEqual;\\u6247ilde;\\u6249erticalBar;\\u6224cr;\\uc000\\ud835\\udca9ilde\\u803b\\xd1\\u40d1;\\u439d\\u0700Eacdfgmoprstuv\\u0dbd\\u0dc2\\u0dc9\\u0dd5\\u0ddb\\u0de0\\u0de7\\u0dfc\\u0e02\\u0e20\\u0e22\\u0e32\\u0e3f\\u0e44lig;\\u4152cute\\u803b\\xd3\\u40d3\\u0100iy\\u0dce\\u0dd3rc\\u803b\\xd4\\u40d4;\\u441eblac;\\u4150r;\\uc000\\ud835\\udd12rave\\u803b\\xd2\\u40d2\\u0180aei\\u0dee\\u0df2\\u0df6cr;\\u414cga;\\u43a9cron;\\u439fpf;\\uc000\\ud835\\udd46enCurly\\u0100DQ\\u0e0e\\u0e1aoubleQuote;\\u601cuote;\\u6018;\\u6a54\\u0100cl\\u0e27\\u0e2cr;\\uc000\\ud835\\udcaaash\\u803b\\xd8\\u40d8i\\u016c\\u0e37\\u0e3cde\\u803b\\xd5\\u40d5es;\\u6a37ml\\u803b\\xd6\\u40d6er\\u0100BP\\u0e4b\\u0e60\\u0100ar\\u0e50\\u0e53r;\\u603eac\\u0100ek\\u0e5a\\u0e5c;\\u63deet;\\u63b4arenthesis;\\u63dc\\u0480acfhilors\\u0e7f\\u0e87\\u0e8a\\u0e8f\\u0e92\\u0e94\\u0e9d\\u0eb0\\u0efcrtialD;\\u6202y;\\u441fr;\\uc000\\ud835\\udd13i;\\u43a6;\\u43a0usMinus;\\u40b1\\u0100ip\\u0ea2\\u0eadncareplan\\xe5\\u069df;\\u6119\\u0200;eio\\u0eb9\\u0eba\\u0ee0\\u0ee4\\u6abbcedes\\u0200;EST\\u0ec8\\u0ec9\\u0ecf\\u0eda\\u627aqual;\\u6aaflantEqual;\\u627cilde;\\u627eme;\\u6033\\u0100dp\\u0ee9\\u0eeeuct;\\u620fortion\\u0100;a\\u0225\\u0ef9l;\\u621d\\u0100ci\\u0f01\\u0f06r;\\uc000\\ud835\\udcab;\\u43a8\\u0200Ufos\\u0f11\\u0f16\\u0f1b\\u0f1fOT\\u803b\\\"\\u4022r;\\uc000\\ud835\\udd14pf;\\u611acr;\\uc000\\ud835\\udcac\\u0600BEacefhiorsu\\u0f3e\\u0f43\\u0f47\\u0f60\\u0f73\\u0fa7\\u0faa\\u0fad\\u1096\\u10a9\\u10b4\\u10bearr;\\u6910G\\u803b\\xae\\u40ae\\u0180cnr\\u0f4e\\u0f53\\u0f56ute;\\u4154g;\\u67ebr\\u0100;t\\u0f5c\\u0f5d\\u61a0l;\\u6916\\u0180aey\\u0f67\\u0f6c\\u0f71ron;\\u4158dil;\\u4156;\\u4420\\u0100;v\\u0f78\\u0f79\\u611cerse\\u0100EU\\u0f82\\u0f99\\u0100lq\\u0f87\\u0f8eement;\\u620builibrium;\\u61cbpEquilibrium;\\u696fr\\xbb\\u0f79o;\\u43a1ght\\u0400ACDFTUVa\\u0fc1\\u0feb\\u0ff3\\u1022\\u1028\\u105b\\u1087\\u03d8\\u0100nr\\u0fc6\\u0fd2gleBracket;\\u67e9row\\u0180;BL\\u0fdc\\u0fdd\\u0fe1\\u6192ar;\\u61e5eftArrow;\\u61c4eiling;\\u6309o\\u01f5\\u0ff9\\0\\u1005bleBracket;\\u67e7n\\u01d4\\u100a\\0\\u1014eeVector;\\u695dector\\u0100;B\\u101d\\u101e\\u61c2ar;\\u6955loor;\\u630b\\u0100er\\u102d\\u1043e\\u0180;AV\\u1035\\u1036\\u103c\\u62a2rrow;\\u61a6ector;\\u695biangle\\u0180;BE\\u1050\\u1051\\u1055\\u62b3ar;\\u69d0qual;\\u62b5p\\u0180DTV\\u1063\\u106e\\u1078ownVector;\\u694feeVector;\\u695cector\\u0100;B\\u1082\\u1083\\u61bear;\\u6954ector\\u0100;B\\u1091\\u1092\\u61c0ar;\\u6953\\u0100pu\\u109b\\u109ef;\\u611dndImplies;\\u6970ightarrow;\\u61db\\u0100ch\\u10b9\\u10bcr;\\u611b;\\u61b1leDelayed;\\u69f4\\u0680HOacfhimoqstu\\u10e4\\u10f1\\u10f7\\u10fd\\u1119\\u111e\\u1151\\u1156\\u1161\\u1167\\u11b5\\u11bb\\u11bf\\u0100Cc\\u10e9\\u10eeHcy;\\u4429y;\\u4428FTcy;\\u442ccute;\\u415a\\u0280;aeiy\\u1108\\u1109\\u110e\\u1113\\u1117\\u6abcron;\\u4160dil;\\u415erc;\\u415c;\\u4421r;\\uc000\\ud835\\udd16ort\\u0200DLRU\\u112a\\u1134\\u113e\\u1149ownArrow\\xbb\\u041eeftArrow\\xbb\\u089aightArrow\\xbb\\u0fddpArrow;\\u6191gma;\\u43a3allCircle;\\u6218pf;\\uc000\\ud835\\udd4a\\u0272\\u116d\\0\\0\\u1170t;\\u621aare\\u0200;ISU\\u117b\\u117c\\u1189\\u11af\\u65a1ntersection;\\u6293u\\u0100bp\\u118f\\u119eset\\u0100;E\\u1197\\u1198\\u628fqual;\\u6291erset\\u0100;E\\u11a8\\u11a9\\u6290qual;\\u6292nion;\\u6294cr;\\uc000\\ud835\\udcaear;\\u62c6\\u0200bcmp\\u11c8\\u11db\\u1209\\u120b\\u0100;s\\u11cd\\u11ce\\u62d0et\\u0100;E\\u11cd\\u11d5qual;\\u6286\\u0100ch\\u11e0\\u1205eeds\\u0200;EST\\u11ed\\u11ee\\u11f4\\u11ff\\u627bqual;\\u6ab0lantEqual;\\u627dilde;\\u627fTh\\xe1\\u0f8c;\\u6211\\u0180;es\\u1212\\u1213\\u1223\\u62d1rset\\u0100;E\\u121c\\u121d\\u6283qual;\\u6287et\\xbb\\u1213\\u0580HRSacfhiors\\u123e\\u1244\\u1249\\u1255\\u125e\\u1271\\u1276\\u129f\\u12c2\\u12c8\\u12d1ORN\\u803b\\xde\\u40deADE;\\u6122\\u0100Hc\\u124e\\u1252cy;\\u440by;\\u4426\\u0100bu\\u125a\\u125c;\\u4009;\\u43a4\\u0180aey\\u1265\\u126a\\u126fron;\\u4164dil;\\u4162;\\u4422r;\\uc000\\ud835\\udd17\\u0100ei\\u127b\\u1289\\u01f2\\u1280\\0\\u1287efore;\\u6234a;\\u4398\\u0100cn\\u128e\\u1298kSpace;\\uc000\\u205f\\u200aSpace;\\u6009lde\\u0200;EFT\\u12ab\\u12ac\\u12b2\\u12bc\\u623cqual;\\u6243ullEqual;\\u6245ilde;\\u6248pf;\\uc000\\ud835\\udd4bipleDot;\\u60db\\u0100ct\\u12d6\\u12dbr;\\uc000\\ud835\\udcafrok;\\u4166\\u0ae1\\u12f7\\u130e\\u131a\\u1326\\0\\u132c\\u1331\\0\\0\\0\\0\\0\\u1338\\u133d\\u1377\\u1385\\0\\u13ff\\u1404\\u140a\\u1410\\u0100cr\\u12fb\\u1301ute\\u803b\\xda\\u40dar\\u0100;o\\u1307\\u1308\\u619fcir;\\u6949r\\u01e3\\u1313\\0\\u1316y;\\u440eve;\\u416c\\u0100iy\\u131e\\u1323rc\\u803b\\xdb\\u40db;\\u4423blac;\\u4170r;\\uc000\\ud835\\udd18rave\\u803b\\xd9\\u40d9acr;\\u416a\\u0100di\\u1341\\u1369er\\u0100BP\\u1348\\u135d\\u0100ar\\u134d\\u1350r;\\u405fac\\u0100ek\\u1357\\u1359;\\u63dfet;\\u63b5arenthesis;\\u63ddon\\u0100;P\\u1370\\u1371\\u62c3lus;\\u628e\\u0100gp\\u137b\\u137fon;\\u4172f;\\uc000\\ud835\\udd4c\\u0400ADETadps\\u1395\\u13ae\\u13b8\\u13c4\\u03e8\\u13d2\\u13d7\\u13f3rrow\\u0180;BD\\u1150\\u13a0\\u13a4ar;\\u6912ownArrow;\\u61c5ownArrow;\\u6195quilibrium;\\u696eee\\u0100;A\\u13cb\\u13cc\\u62a5rrow;\\u61a5own\\xe1\\u03f3er\\u0100LR\\u13de\\u13e8eftArrow;\\u6196ightArrow;\\u6197i\\u0100;l\\u13f9\\u13fa\\u43d2on;\\u43a5ing;\\u416ecr;\\uc000\\ud835\\udcb0ilde;\\u4168ml\\u803b\\xdc\\u40dc\\u0480Dbcdefosv\\u1427\\u142c\\u1430\\u1433\\u143e\\u1485\\u148a\\u1490\\u1496ash;\\u62abar;\\u6aeby;\\u4412ash\\u0100;l\\u143b\\u143c\\u62a9;\\u6ae6\\u0100er\\u1443\\u1445;\\u62c1\\u0180bty\\u144c\\u1450\\u147aar;\\u6016\\u0100;i\\u144f\\u1455cal\\u0200BLST\\u1461\\u1465\\u146a\\u1474ar;\\u6223ine;\\u407ceparator;\\u6758ilde;\\u6240ThinSpace;\\u600ar;\\uc000\\ud835\\udd19pf;\\uc000\\ud835\\udd4dcr;\\uc000\\ud835\\udcb1dash;\\u62aa\\u0280cefos\\u14a7\\u14ac\\u14b1\\u14b6\\u14bcirc;\\u4174dge;\\u62c0r;\\uc000\\ud835\\udd1apf;\\uc000\\ud835\\udd4ecr;\\uc000\\ud835\\udcb2\\u0200fios\\u14cb\\u14d0\\u14d2\\u14d8r;\\uc000\\ud835\\udd1b;\\u439epf;\\uc000\\ud835\\udd4fcr;\\uc000\\ud835\\udcb3\\u0480AIUacfosu\\u14f1\\u14f5\\u14f9\\u14fd\\u1504\\u150f\\u1514\\u151a\\u1520cy;\\u442fcy;\\u4407cy;\\u442ecute\\u803b\\xdd\\u40dd\\u0100iy\\u1509\\u150drc;\\u4176;\\u442br;\\uc000\\ud835\\udd1cpf;\\uc000\\ud835\\udd50cr;\\uc000\\ud835\\udcb4ml;\\u4178\\u0400Hacdefos\\u1535\\u1539\\u153f\\u154b\\u154f\\u155d\\u1560\\u1564cy;\\u4416cute;\\u4179\\u0100ay\\u1544\\u1549ron;\\u417d;\\u4417ot;\\u417b\\u01f2\\u1554\\0\\u155boWidt\\xe8\\u0ad9a;\\u4396r;\\u6128pf;\\u6124cr;\\uc000\\ud835\\udcb5\\u0be1\\u1583\\u158a\\u1590\\0\\u15b0\\u15b6\\u15bf\\0\\0\\0\\0\\u15c6\\u15db\\u15eb\\u165f\\u166d\\0\\u1695\\u169b\\u16b2\\u16b9\\0\\u16becute\\u803b\\xe1\\u40e1reve;\\u4103\\u0300;Ediuy\\u159c\\u159d\\u15a1\\u15a3\\u15a8\\u15ad\\u623e;\\uc000\\u223e\\u0333;\\u623frc\\u803b\\xe2\\u40e2te\\u80bb\\xb4\\u0306;\\u4430lig\\u803b\\xe6\\u40e6\\u0100;r\\xb2\\u15ba;\\uc000\\ud835\\udd1erave\\u803b\\xe0\\u40e0\\u0100ep\\u15ca\\u15d6\\u0100fp\\u15cf\\u15d4sym;\\u6135\\xe8\\u15d3ha;\\u43b1\\u0100ap\\u15dfc\\u0100cl\\u15e4\\u15e7r;\\u4101g;\\u6a3f\\u0264\\u15f0\\0\\0\\u160a\\u0280;adsv\\u15fa\\u15fb\\u15ff\\u1601\\u1607\\u6227nd;\\u6a55;\\u6a5clope;\\u6a58;\\u6a5a\\u0380;elmrsz\\u1618\\u1619\\u161b\\u161e\\u163f\\u164f\\u1659\\u6220;\\u69a4e\\xbb\\u1619sd\\u0100;a\\u1625\\u1626\\u6221\\u0461\\u1630\\u1632\\u1634\\u1636\\u1638\\u163a\\u163c\\u163e;\\u69a8;\\u69a9;\\u69aa;\\u69ab;\\u69ac;\\u69ad;\\u69ae;\\u69aft\\u0100;v\\u1645\\u1646\\u621fb\\u0100;d\\u164c\\u164d\\u62be;\\u699d\\u0100pt\\u1654\\u1657h;\\u6222\\xbb\\xb9arr;\\u637c\\u0100gp\\u1663\\u1667on;\\u4105f;\\uc000\\ud835\\udd52\\u0380;Eaeiop\\u12c1\\u167b\\u167d\\u1682\\u1684\\u1687\\u168a;\\u6a70cir;\\u6a6f;\\u624ad;\\u624bs;\\u4027rox\\u0100;e\\u12c1\\u1692\\xf1\\u1683ing\\u803b\\xe5\\u40e5\\u0180cty\\u16a1\\u16a6\\u16a8r;\\uc000\\ud835\\udcb6;\\u402amp\\u0100;e\\u12c1\\u16af\\xf1\\u0288ilde\\u803b\\xe3\\u40e3ml\\u803b\\xe4\\u40e4\\u0100ci\\u16c2\\u16c8onin\\xf4\\u0272nt;\\u6a11\\u0800Nabcdefiklnoprsu\\u16ed\\u16f1\\u1730\\u173c\\u1743\\u1748\\u1778\\u177d\\u17e0\\u17e6\\u1839\\u1850\\u170d\\u193d\\u1948\\u1970ot;\\u6aed\\u0100cr\\u16f6\\u171ek\\u0200ceps\\u1700\\u1705\\u170d\\u1713ong;\\u624cpsilon;\\u43f6rime;\\u6035im\\u0100;e\\u171a\\u171b\\u623dq;\\u62cd\\u0176\\u1722\\u1726ee;\\u62bded\\u0100;g\\u172c\\u172d\\u6305e\\xbb\\u172drk\\u0100;t\\u135c\\u1737brk;\\u63b6\\u0100oy\\u1701\\u1741;\\u4431quo;\\u601e\\u0280cmprt\\u1753\\u175b\\u1761\\u1764\\u1768aus\\u0100;e\\u010a\\u0109ptyv;\\u69b0s\\xe9\\u170cno\\xf5\\u0113\\u0180ahw\\u176f\\u1771\\u1773;\\u43b2;\\u6136een;\\u626cr;\\uc000\\ud835\\udd1fg\\u0380costuvw\\u178d\\u179d\\u17b3\\u17c1\\u17d5\\u17db\\u17de\\u0180aiu\\u1794\\u1796\\u179a\\xf0\\u0760rc;\\u65efp\\xbb\\u1371\\u0180dpt\\u17a4\\u17a8\\u17adot;\\u6a00lus;\\u6a01imes;\\u6a02\\u0271\\u17b9\\0\\0\\u17becup;\\u6a06ar;\\u6605riangle\\u0100du\\u17cd\\u17d2own;\\u65bdp;\\u65b3plus;\\u6a04e\\xe5\\u1444\\xe5\\u14adarow;\\u690d\\u0180ako\\u17ed\\u1826\\u1835\\u0100cn\\u17f2\\u1823k\\u0180lst\\u17fa\\u05ab\\u1802ozenge;\\u69ebriangle\\u0200;dlr\\u1812\\u1813\\u1818\\u181d\\u65b4own;\\u65beeft;\\u65c2ight;\\u65b8k;\\u6423\\u01b1\\u182b\\0\\u1833\\u01b2\\u182f\\0\\u1831;\\u6592;\\u65914;\\u6593ck;\\u6588\\u0100eo\\u183e\\u184d\\u0100;q\\u1843\\u1846\\uc000=\\u20e5uiv;\\uc000\\u2261\\u20e5t;\\u6310\\u0200ptwx\\u1859\\u185e\\u1867\\u186cf;\\uc000\\ud835\\udd53\\u0100;t\\u13cb\\u1863om\\xbb\\u13cctie;\\u62c8\\u0600DHUVbdhmptuv\\u1885\\u1896\\u18aa\\u18bb\\u18d7\\u18db\\u18ec\\u18ff\\u1905\\u190a\\u1910\\u1921\\u0200LRlr\\u188e\\u1890\\u1892\\u1894;\\u6557;\\u6554;\\u6556;\\u6553\\u0280;DUdu\\u18a1\\u18a2\\u18a4\\u18a6\\u18a8\\u6550;\\u6566;\\u6569;\\u6564;\\u6567\\u0200LRlr\\u18b3\\u18b5\\u18b7\\u18b9;\\u655d;\\u655a;\\u655c;\\u6559\\u0380;HLRhlr\\u18ca\\u18cb\\u18cd\\u18cf\\u18d1\\u18d3\\u18d5\\u6551;\\u656c;\\u6563;\\u6560;\\u656b;\\u6562;\\u655fox;\\u69c9\\u0200LRlr\\u18e4\\u18e6\\u18e8\\u18ea;\\u6555;\\u6552;\\u6510;\\u650c\\u0280;DUdu\\u06bd\\u18f7\\u18f9\\u18fb\\u18fd;\\u6565;\\u6568;\\u652c;\\u6534inus;\\u629flus;\\u629eimes;\\u62a0\\u0200LRlr\\u1919\\u191b\\u191d\\u191f;\\u655b;\\u6558;\\u6518;\\u6514\\u0380;HLRhlr\\u1930\\u1931\\u1933\\u1935\\u1937\\u1939\\u193b\\u6502;\\u656a;\\u6561;\\u655e;\\u653c;\\u6524;\\u651c\\u0100ev\\u0123\\u1942bar\\u803b\\xa6\\u40a6\\u0200ceio\\u1951\\u1956\\u195a\\u1960r;\\uc000\\ud835\\udcb7mi;\\u604fm\\u0100;e\\u171a\\u171cl\\u0180;bh\\u1968\\u1969\\u196b\\u405c;\\u69c5sub;\\u67c8\\u016c\\u1974\\u197el\\u0100;e\\u1979\\u197a\\u6022t\\xbb\\u197ap\\u0180;Ee\\u012f\\u1985\\u1987;\\u6aae\\u0100;q\\u06dc\\u06db\\u0ce1\\u19a7\\0\\u19e8\\u1a11\\u1a15\\u1a32\\0\\u1a37\\u1a50\\0\\0\\u1ab4\\0\\0\\u1ac1\\0\\0\\u1b21\\u1b2e\\u1b4d\\u1b52\\0\\u1bfd\\0\\u1c0c\\u0180cpr\\u19ad\\u19b2\\u19ddute;\\u4107\\u0300;abcds\\u19bf\\u19c0\\u19c4\\u19ca\\u19d5\\u19d9\\u6229nd;\\u6a44rcup;\\u6a49\\u0100au\\u19cf\\u19d2p;\\u6a4bp;\\u6a47ot;\\u6a40;\\uc000\\u2229\\ufe00\\u0100eo\\u19e2\\u19e5t;\\u6041\\xee\\u0693\\u0200aeiu\\u19f0\\u19fb\\u1a01\\u1a05\\u01f0\\u19f5\\0\\u19f8s;\\u6a4don;\\u410ddil\\u803b\\xe7\\u40e7rc;\\u4109ps\\u0100;s\\u1a0c\\u1a0d\\u6a4cm;\\u6a50ot;\\u410b\\u0180dmn\\u1a1b\\u1a20\\u1a26il\\u80bb\\xb8\\u01adptyv;\\u69b2t\\u8100\\xa2;e\\u1a2d\\u1a2e\\u40a2r\\xe4\\u01b2r;\\uc000\\ud835\\udd20\\u0180cei\\u1a3d\\u1a40\\u1a4dy;\\u4447ck\\u0100;m\\u1a47\\u1a48\\u6713ark\\xbb\\u1a48;\\u43c7r\\u0380;Ecefms\\u1a5f\\u1a60\\u1a62\\u1a6b\\u1aa4\\u1aaa\\u1aae\\u65cb;\\u69c3\\u0180;el\\u1a69\\u1a6a\\u1a6d\\u42c6q;\\u6257e\\u0261\\u1a74\\0\\0\\u1a88rrow\\u0100lr\\u1a7c\\u1a81eft;\\u61baight;\\u61bb\\u0280RSacd\\u1a92\\u1a94\\u1a96\\u1a9a\\u1a9f\\xbb\\u0f47;\\u64c8st;\\u629birc;\\u629aash;\\u629dnint;\\u6a10id;\\u6aefcir;\\u69c2ubs\\u0100;u\\u1abb\\u1abc\\u6663it\\xbb\\u1abc\\u02ec\\u1ac7\\u1ad4\\u1afa\\0\\u1b0aon\\u0100;e\\u1acd\\u1ace\\u403a\\u0100;q\\xc7\\xc6\\u026d\\u1ad9\\0\\0\\u1ae2a\\u0100;t\\u1ade\\u1adf\\u402c;\\u4040\\u0180;fl\\u1ae8\\u1ae9\\u1aeb\\u6201\\xee\\u1160e\\u0100mx\\u1af1\\u1af6ent\\xbb\\u1ae9e\\xf3\\u024d\\u01e7\\u1afe\\0\\u1b07\\u0100;d\\u12bb\\u1b02ot;\\u6a6dn\\xf4\\u0246\\u0180fry\\u1b10\\u1b14\\u1b17;\\uc000\\ud835\\udd54o\\xe4\\u0254\\u8100\\xa9;s\\u0155\\u1b1dr;\\u6117\\u0100ao\\u1b25\\u1b29rr;\\u61b5ss;\\u6717\\u0100cu\\u1b32\\u1b37r;\\uc000\\ud835\\udcb8\\u0100bp\\u1b3c\\u1b44\\u0100;e\\u1b41\\u1b42\\u6acf;\\u6ad1\\u0100;e\\u1b49\\u1b4a\\u6ad0;\\u6ad2dot;\\u62ef\\u0380delprvw\\u1b60\\u1b6c\\u1b77\\u1b82\\u1bac\\u1bd4\\u1bf9arr\\u0100lr\\u1b68\\u1b6a;\\u6938;\\u6935\\u0270\\u1b72\\0\\0\\u1b75r;\\u62dec;\\u62dfarr\\u0100;p\\u1b7f\\u1b80\\u61b6;\\u693d\\u0300;bcdos\\u1b8f\\u1b90\\u1b96\\u1ba1\\u1ba5\\u1ba8\\u622arcap;\\u6a48\\u0100au\\u1b9b\\u1b9ep;\\u6a46p;\\u6a4aot;\\u628dr;\\u6a45;\\uc000\\u222a\\ufe00\\u0200alrv\\u1bb5\\u1bbf\\u1bde\\u1be3rr\\u0100;m\\u1bbc\\u1bbd\\u61b7;\\u693cy\\u0180evw\\u1bc7\\u1bd4\\u1bd8q\\u0270\\u1bce\\0\\0\\u1bd2re\\xe3\\u1b73u\\xe3\\u1b75ee;\\u62ceedge;\\u62cfen\\u803b\\xa4\\u40a4earrow\\u0100lr\\u1bee\\u1bf3eft\\xbb\\u1b80ight\\xbb\\u1bbde\\xe4\\u1bdd\\u0100ci\\u1c01\\u1c07onin\\xf4\\u01f7nt;\\u6231lcty;\\u632d\\u0980AHabcdefhijlorstuwz\\u1c38\\u1c3b\\u1c3f\\u1c5d\\u1c69\\u1c75\\u1c8a\\u1c9e\\u1cac\\u1cb7\\u1cfb\\u1cff\\u1d0d\\u1d7b\\u1d91\\u1dab\\u1dbb\\u1dc6\\u1dcdr\\xf2\\u0381ar;\\u6965\\u0200glrs\\u1c48\\u1c4d\\u1c52\\u1c54ger;\\u6020eth;\\u6138\\xf2\\u1133h\\u0100;v\\u1c5a\\u1c5b\\u6010\\xbb\\u090a\\u016b\\u1c61\\u1c67arow;\\u690fa\\xe3\\u0315\\u0100ay\\u1c6e\\u1c73ron;\\u410f;\\u4434\\u0180;ao\\u0332\\u1c7c\\u1c84\\u0100gr\\u02bf\\u1c81r;\\u61catseq;\\u6a77\\u0180glm\\u1c91\\u1c94\\u1c98\\u803b\\xb0\\u40b0ta;\\u43b4ptyv;\\u69b1\\u0100ir\\u1ca3\\u1ca8sht;\\u697f;\\uc000\\ud835\\udd21ar\\u0100lr\\u1cb3\\u1cb5\\xbb\\u08dc\\xbb\\u101e\\u0280aegsv\\u1cc2\\u0378\\u1cd6\\u1cdc\\u1ce0m\\u0180;os\\u0326\\u1cca\\u1cd4nd\\u0100;s\\u0326\\u1cd1uit;\\u6666amma;\\u43ddin;\\u62f2\\u0180;io\\u1ce7\\u1ce8\\u1cf8\\u40f7de\\u8100\\xf7;o\\u1ce7\\u1cf0ntimes;\\u62c7n\\xf8\\u1cf7cy;\\u4452c\\u026f\\u1d06\\0\\0\\u1d0arn;\\u631eop;\\u630d\\u0280lptuw\\u1d18\\u1d1d\\u1d22\\u1d49\\u1d55lar;\\u4024f;\\uc000\\ud835\\udd55\\u0280;emps\\u030b\\u1d2d\\u1d37\\u1d3d\\u1d42q\\u0100;d\\u0352\\u1d33ot;\\u6251inus;\\u6238lus;\\u6214quare;\\u62a1blebarwedg\\xe5\\xfan\\u0180adh\\u112e\\u1d5d\\u1d67ownarrow\\xf3\\u1c83arpoon\\u0100lr\\u1d72\\u1d76ef\\xf4\\u1cb4igh\\xf4\\u1cb6\\u0162\\u1d7f\\u1d85karo\\xf7\\u0f42\\u026f\\u1d8a\\0\\0\\u1d8ern;\\u631fop;\\u630c\\u0180cot\\u1d98\\u1da3\\u1da6\\u0100ry\\u1d9d\\u1da1;\\uc000\\ud835\\udcb9;\\u4455l;\\u69f6rok;\\u4111\\u0100dr\\u1db0\\u1db4ot;\\u62f1i\\u0100;f\\u1dba\\u1816\\u65bf\\u0100ah\\u1dc0\\u1dc3r\\xf2\\u0429a\\xf2\\u0fa6angle;\\u69a6\\u0100ci\\u1dd2\\u1dd5y;\\u445fgrarr;\\u67ff\\u0900Dacdefglmnopqrstux\\u1e01\\u1e09\\u1e19\\u1e38\\u0578\\u1e3c\\u1e49\\u1e61\\u1e7e\\u1ea5\\u1eaf\\u1ebd\\u1ee1\\u1f2a\\u1f37\\u1f44\\u1f4e\\u1f5a\\u0100Do\\u1e06\\u1d34o\\xf4\\u1c89\\u0100cs\\u1e0e\\u1e14ute\\u803b\\xe9\\u40e9ter;\\u6a6e\\u0200aioy\\u1e22\\u1e27\\u1e31\\u1e36ron;\\u411br\\u0100;c\\u1e2d\\u1e2e\\u6256\\u803b\\xea\\u40ealon;\\u6255;\\u444dot;\\u4117\\u0100Dr\\u1e41\\u1e45ot;\\u6252;\\uc000\\ud835\\udd22\\u0180;rs\\u1e50\\u1e51\\u1e57\\u6a9aave\\u803b\\xe8\\u40e8\\u0100;d\\u1e5c\\u1e5d\\u6a96ot;\\u6a98\\u0200;ils\\u1e6a\\u1e6b\\u1e72\\u1e74\\u6a99nters;\\u63e7;\\u6113\\u0100;d\\u1e79\\u1e7a\\u6a95ot;\\u6a97\\u0180aps\\u1e85\\u1e89\\u1e97cr;\\u4113ty\\u0180;sv\\u1e92\\u1e93\\u1e95\\u6205et\\xbb\\u1e93p\\u01001;\\u1e9d\\u1ea4\\u0133\\u1ea1\\u1ea3;\\u6004;\\u6005\\u6003\\u0100gs\\u1eaa\\u1eac;\\u414bp;\\u6002\\u0100gp\\u1eb4\\u1eb8on;\\u4119f;\\uc000\\ud835\\udd56\\u0180als\\u1ec4\\u1ece\\u1ed2r\\u0100;s\\u1eca\\u1ecb\\u62d5l;\\u69e3us;\\u6a71i\\u0180;lv\\u1eda\\u1edb\\u1edf\\u43b5on\\xbb\\u1edb;\\u43f5\\u0200csuv\\u1eea\\u1ef3\\u1f0b\\u1f23\\u0100io\\u1eef\\u1e31rc\\xbb\\u1e2e\\u0269\\u1ef9\\0\\0\\u1efb\\xed\\u0548ant\\u0100gl\\u1f02\\u1f06tr\\xbb\\u1e5dess\\xbb\\u1e7a\\u0180aei\\u1f12\\u1f16\\u1f1als;\\u403dst;\\u625fv\\u0100;D\\u0235\\u1f20D;\\u6a78parsl;\\u69e5\\u0100Da\\u1f2f\\u1f33ot;\\u6253rr;\\u6971\\u0180cdi\\u1f3e\\u1f41\\u1ef8r;\\u612fo\\xf4\\u0352\\u0100ah\\u1f49\\u1f4b;\\u43b7\\u803b\\xf0\\u40f0\\u0100mr\\u1f53\\u1f57l\\u803b\\xeb\\u40ebo;\\u60ac\\u0180cip\\u1f61\\u1f64\\u1f67l;\\u4021s\\xf4\\u056e\\u0100eo\\u1f6c\\u1f74ctatio\\xee\\u0559nential\\xe5\\u0579\\u09e1\\u1f92\\0\\u1f9e\\0\\u1fa1\\u1fa7\\0\\0\\u1fc6\\u1fcc\\0\\u1fd3\\0\\u1fe6\\u1fea\\u2000\\0\\u2008\\u205allingdotse\\xf1\\u1e44y;\\u4444male;\\u6640\\u0180ilr\\u1fad\\u1fb3\\u1fc1lig;\\u8000\\ufb03\\u0269\\u1fb9\\0\\0\\u1fbdg;\\u8000\\ufb00ig;\\u8000\\ufb04;\\uc000\\ud835\\udd23lig;\\u8000\\ufb01lig;\\uc000fj\\u0180alt\\u1fd9\\u1fdc\\u1fe1t;\\u666dig;\\u8000\\ufb02ns;\\u65b1of;\\u4192\\u01f0\\u1fee\\0\\u1ff3f;\\uc000\\ud835\\udd57\\u0100ak\\u05bf\\u1ff7\\u0100;v\\u1ffc\\u1ffd\\u62d4;\\u6ad9artint;\\u6a0d\\u0100ao\\u200c\\u2055\\u0100cs\\u2011\\u2052\\u03b1\\u201a\\u2030\\u2038\\u2045\\u2048\\0\\u2050\\u03b2\\u2022\\u2025\\u2027\\u202a\\u202c\\0\\u202e\\u803b\\xbd\\u40bd;\\u6153\\u803b\\xbc\\u40bc;\\u6155;\\u6159;\\u615b\\u01b3\\u2034\\0\\u2036;\\u6154;\\u6156\\u02b4\\u203e\\u2041\\0\\0\\u2043\\u803b\\xbe\\u40be;\\u6157;\\u615c5;\\u6158\\u01b6\\u204c\\0\\u204e;\\u615a;\\u615d8;\\u615el;\\u6044wn;\\u6322cr;\\uc000\\ud835\\udcbb\\u0880Eabcdefgijlnorstv\\u2082\\u2089\\u209f\\u20a5\\u20b0\\u20b4\\u20f0\\u20f5\\u20fa\\u20ff\\u2103\\u2112\\u2138\\u0317\\u213e\\u2152\\u219e\\u0100;l\\u064d\\u2087;\\u6a8c\\u0180cmp\\u2090\\u2095\\u209dute;\\u41f5ma\\u0100;d\\u209c\\u1cda\\u43b3;\\u6a86reve;\\u411f\\u0100iy\\u20aa\\u20aerc;\\u411d;\\u4433ot;\\u4121\\u0200;lqs\\u063e\\u0642\\u20bd\\u20c9\\u0180;qs\\u063e\\u064c\\u20c4lan\\xf4\\u0665\\u0200;cdl\\u0665\\u20d2\\u20d5\\u20e5c;\\u6aa9ot\\u0100;o\\u20dc\\u20dd\\u6a80\\u0100;l\\u20e2\\u20e3\\u6a82;\\u6a84\\u0100;e\\u20ea\\u20ed\\uc000\\u22db\\ufe00s;\\u6a94r;\\uc000\\ud835\\udd24\\u0100;g\\u0673\\u061bmel;\\u6137cy;\\u4453\\u0200;Eaj\\u065a\\u210c\\u210e\\u2110;\\u6a92;\\u6aa5;\\u6aa4\\u0200Eaes\\u211b\\u211d\\u2129\\u2134;\\u6269p\\u0100;p\\u2123\\u2124\\u6a8arox\\xbb\\u2124\\u0100;q\\u212e\\u212f\\u6a88\\u0100;q\\u212e\\u211bim;\\u62e7pf;\\uc000\\ud835\\udd58\\u0100ci\\u2143\\u2146r;\\u610am\\u0180;el\\u066b\\u214e\\u2150;\\u6a8e;\\u6a90\\u8300>;cdlqr\\u05ee\\u2160\\u216a\\u216e\\u2173\\u2179\\u0100ci\\u2165\\u2167;\\u6aa7r;\\u6a7aot;\\u62d7Par;\\u6995uest;\\u6a7c\\u0280adels\\u2184\\u216a\\u2190\\u0656\\u219b\\u01f0\\u2189\\0\\u218epro\\xf8\\u209er;\\u6978q\\u0100lq\\u063f\\u2196les\\xf3\\u2088i\\xed\\u066b\\u0100en\\u21a3\\u21adrtneqq;\\uc000\\u2269\\ufe00\\xc5\\u21aa\\u0500Aabcefkosy\\u21c4\\u21c7\\u21f1\\u21f5\\u21fa\\u2218\\u221d\\u222f\\u2268\\u227dr\\xf2\\u03a0\\u0200ilmr\\u21d0\\u21d4\\u21d7\\u21dbrs\\xf0\\u1484f\\xbb\\u2024il\\xf4\\u06a9\\u0100dr\\u21e0\\u21e4cy;\\u444a\\u0180;cw\\u08f4\\u21eb\\u21efir;\\u6948;\\u61adar;\\u610firc;\\u4125\\u0180alr\\u2201\\u220e\\u2213rts\\u0100;u\\u2209\\u220a\\u6665it\\xbb\\u220alip;\\u6026con;\\u62b9r;\\uc000\\ud835\\udd25s\\u0100ew\\u2223\\u2229arow;\\u6925arow;\\u6926\\u0280amopr\\u223a\\u223e\\u2243\\u225e\\u2263rr;\\u61fftht;\\u623bk\\u0100lr\\u2249\\u2253eftarrow;\\u61a9ightarrow;\\u61aaf;\\uc000\\ud835\\udd59bar;\\u6015\\u0180clt\\u226f\\u2274\\u2278r;\\uc000\\ud835\\udcbdas\\xe8\\u21f4rok;\\u4127\\u0100bp\\u2282\\u2287ull;\\u6043hen\\xbb\\u1c5b\\u0ae1\\u22a3\\0\\u22aa\\0\\u22b8\\u22c5\\u22ce\\0\\u22d5\\u22f3\\0\\0\\u22f8\\u2322\\u2367\\u2362\\u237f\\0\\u2386\\u23aa\\u23b4cute\\u803b\\xed\\u40ed\\u0180;iy\\u0771\\u22b0\\u22b5rc\\u803b\\xee\\u40ee;\\u4438\\u0100cx\\u22bc\\u22bfy;\\u4435cl\\u803b\\xa1\\u40a1\\u0100fr\\u039f\\u22c9;\\uc000\\ud835\\udd26rave\\u803b\\xec\\u40ec\\u0200;ino\\u073e\\u22dd\\u22e9\\u22ee\\u0100in\\u22e2\\u22e6nt;\\u6a0ct;\\u622dfin;\\u69dcta;\\u6129lig;\\u4133\\u0180aop\\u22fe\\u231a\\u231d\\u0180cgt\\u2305\\u2308\\u2317r;\\u412b\\u0180elp\\u071f\\u230f\\u2313in\\xe5\\u078ear\\xf4\\u0720h;\\u4131f;\\u62b7ed;\\u41b5\\u0280;cfot\\u04f4\\u232c\\u2331\\u233d\\u2341are;\\u6105in\\u0100;t\\u2338\\u2339\\u621eie;\\u69dddo\\xf4\\u2319\\u0280;celp\\u0757\\u234c\\u2350\\u235b\\u2361al;\\u62ba\\u0100gr\\u2355\\u2359er\\xf3\\u1563\\xe3\\u234darhk;\\u6a17rod;\\u6a3c\\u0200cgpt\\u236f\\u2372\\u2376\\u237by;\\u4451on;\\u412ff;\\uc000\\ud835\\udd5aa;\\u43b9uest\\u803b\\xbf\\u40bf\\u0100ci\\u238a\\u238fr;\\uc000\\ud835\\udcben\\u0280;Edsv\\u04f4\\u239b\\u239d\\u23a1\\u04f3;\\u62f9ot;\\u62f5\\u0100;v\\u23a6\\u23a7\\u62f4;\\u62f3\\u0100;i\\u0777\\u23aelde;\\u4129\\u01eb\\u23b8\\0\\u23bccy;\\u4456l\\u803b\\xef\\u40ef\\u0300cfmosu\\u23cc\\u23d7\\u23dc\\u23e1\\u23e7\\u23f5\\u0100iy\\u23d1\\u23d5rc;\\u4135;\\u4439r;\\uc000\\ud835\\udd27ath;\\u4237pf;\\uc000\\ud835\\udd5b\\u01e3\\u23ec\\0\\u23f1r;\\uc000\\ud835\\udcbfrcy;\\u4458kcy;\\u4454\\u0400acfghjos\\u240b\\u2416\\u2422\\u2427\\u242d\\u2431\\u2435\\u243bppa\\u0100;v\\u2413\\u2414\\u43ba;\\u43f0\\u0100ey\\u241b\\u2420dil;\\u4137;\\u443ar;\\uc000\\ud835\\udd28reen;\\u4138cy;\\u4445cy;\\u445cpf;\\uc000\\ud835\\udd5ccr;\\uc000\\ud835\\udcc0\\u0b80ABEHabcdefghjlmnoprstuv\\u2470\\u2481\\u2486\\u248d\\u2491\\u250e\\u253d\\u255a\\u2580\\u264e\\u265e\\u2665\\u2679\\u267d\\u269a\\u26b2\\u26d8\\u275d\\u2768\\u278b\\u27c0\\u2801\\u2812\\u0180art\\u2477\\u247a\\u247cr\\xf2\\u09c6\\xf2\\u0395ail;\\u691barr;\\u690e\\u0100;g\\u0994\\u248b;\\u6a8bar;\\u6962\\u0963\\u24a5\\0\\u24aa\\0\\u24b1\\0\\0\\0\\0\\0\\u24b5\\u24ba\\0\\u24c6\\u24c8\\u24cd\\0\\u24f9ute;\\u413amptyv;\\u69b4ra\\xee\\u084cbda;\\u43bbg\\u0180;dl\\u088e\\u24c1\\u24c3;\\u6991\\xe5\\u088e;\\u6a85uo\\u803b\\xab\\u40abr\\u0400;bfhlpst\\u0899\\u24de\\u24e6\\u24e9\\u24eb\\u24ee\\u24f1\\u24f5\\u0100;f\\u089d\\u24e3s;\\u691fs;\\u691d\\xeb\\u2252p;\\u61abl;\\u6939im;\\u6973l;\\u61a2\\u0180;ae\\u24ff\\u2500\\u2504\\u6aabil;\\u6919\\u0100;s\\u2509\\u250a\\u6aad;\\uc000\\u2aad\\ufe00\\u0180abr\\u2515\\u2519\\u251drr;\\u690crk;\\u6772\\u0100ak\\u2522\\u252cc\\u0100ek\\u2528\\u252a;\\u407b;\\u405b\\u0100es\\u2531\\u2533;\\u698bl\\u0100du\\u2539\\u253b;\\u698f;\\u698d\\u0200aeuy\\u2546\\u254b\\u2556\\u2558ron;\\u413e\\u0100di\\u2550\\u2554il;\\u413c\\xec\\u08b0\\xe2\\u2529;\\u443b\\u0200cqrs\\u2563\\u2566\\u256d\\u257da;\\u6936uo\\u0100;r\\u0e19\\u1746\\u0100du\\u2572\\u2577har;\\u6967shar;\\u694bh;\\u61b2\\u0280;fgqs\\u258b\\u258c\\u0989\\u25f3\\u25ff\\u6264t\\u0280ahlrt\\u2598\\u25a4\\u25b7\\u25c2\\u25e8rrow\\u0100;t\\u0899\\u25a1a\\xe9\\u24f6arpoon\\u0100du\\u25af\\u25b4own\\xbb\\u045ap\\xbb\\u0966eftarrows;\\u61c7ight\\u0180ahs\\u25cd\\u25d6\\u25derrow\\u0100;s\\u08f4\\u08a7arpoon\\xf3\\u0f98quigarro\\xf7\\u21f0hreetimes;\\u62cb\\u0180;qs\\u258b\\u0993\\u25falan\\xf4\\u09ac\\u0280;cdgs\\u09ac\\u260a\\u260d\\u261d\\u2628c;\\u6aa8ot\\u0100;o\\u2614\\u2615\\u6a7f\\u0100;r\\u261a\\u261b\\u6a81;\\u6a83\\u0100;e\\u2622\\u2625\\uc000\\u22da\\ufe00s;\\u6a93\\u0280adegs\\u2633\\u2639\\u263d\\u2649\\u264bppro\\xf8\\u24c6ot;\\u62d6q\\u0100gq\\u2643\\u2645\\xf4\\u0989gt\\xf2\\u248c\\xf4\\u099bi\\xed\\u09b2\\u0180ilr\\u2655\\u08e1\\u265asht;\\u697c;\\uc000\\ud835\\udd29\\u0100;E\\u099c\\u2663;\\u6a91\\u0161\\u2669\\u2676r\\u0100du\\u25b2\\u266e\\u0100;l\\u0965\\u2673;\\u696alk;\\u6584cy;\\u4459\\u0280;acht\\u0a48\\u2688\\u268b\\u2691\\u2696r\\xf2\\u25c1orne\\xf2\\u1d08ard;\\u696bri;\\u65fa\\u0100io\\u269f\\u26a4dot;\\u4140ust\\u0100;a\\u26ac\\u26ad\\u63b0che\\xbb\\u26ad\\u0200Eaes\\u26bb\\u26bd\\u26c9\\u26d4;\\u6268p\\u0100;p\\u26c3\\u26c4\\u6a89rox\\xbb\\u26c4\\u0100;q\\u26ce\\u26cf\\u6a87\\u0100;q\\u26ce\\u26bbim;\\u62e6\\u0400abnoptwz\\u26e9\\u26f4\\u26f7\\u271a\\u272f\\u2741\\u2747\\u2750\\u0100nr\\u26ee\\u26f1g;\\u67ecr;\\u61fdr\\xeb\\u08c1g\\u0180lmr\\u26ff\\u270d\\u2714eft\\u0100ar\\u09e6\\u2707ight\\xe1\\u09f2apsto;\\u67fcight\\xe1\\u09fdparrow\\u0100lr\\u2725\\u2729ef\\xf4\\u24edight;\\u61ac\\u0180afl\\u2736\\u2739\\u273dr;\\u6985;\\uc000\\ud835\\udd5dus;\\u6a2dimes;\\u6a34\\u0161\\u274b\\u274fst;\\u6217\\xe1\\u134e\\u0180;ef\\u2757\\u2758\\u1800\\u65cange\\xbb\\u2758ar\\u0100;l\\u2764\\u2765\\u4028t;\\u6993\\u0280achmt\\u2773\\u2776\\u277c\\u2785\\u2787r\\xf2\\u08a8orne\\xf2\\u1d8car\\u0100;d\\u0f98\\u2783;\\u696d;\\u600eri;\\u62bf\\u0300achiqt\\u2798\\u279d\\u0a40\\u27a2\\u27ae\\u27bbquo;\\u6039r;\\uc000\\ud835\\udcc1m\\u0180;eg\\u09b2\\u27aa\\u27ac;\\u6a8d;\\u6a8f\\u0100bu\\u252a\\u27b3o\\u0100;r\\u0e1f\\u27b9;\\u601arok;\\u4142\\u8400<;cdhilqr\\u082b\\u27d2\\u2639\\u27dc\\u27e0\\u27e5\\u27ea\\u27f0\\u0100ci\\u27d7\\u27d9;\\u6aa6r;\\u6a79re\\xe5\\u25f2mes;\\u62c9arr;\\u6976uest;\\u6a7b\\u0100Pi\\u27f5\\u27f9ar;\\u6996\\u0180;ef\\u2800\\u092d\\u181b\\u65c3r\\u0100du\\u2807\\u280dshar;\\u694ahar;\\u6966\\u0100en\\u2817\\u2821rtneqq;\\uc000\\u2268\\ufe00\\xc5\\u281e\\u0700Dacdefhilnopsu\\u2840\\u2845\\u2882\\u288e\\u2893\\u28a0\\u28a5\\u28a8\\u28da\\u28e2\\u28e4\\u0a83\\u28f3\\u2902Dot;\\u623a\\u0200clpr\\u284e\\u2852\\u2863\\u287dr\\u803b\\xaf\\u40af\\u0100et\\u2857\\u2859;\\u6642\\u0100;e\\u285e\\u285f\\u6720se\\xbb\\u285f\\u0100;s\\u103b\\u2868to\\u0200;dlu\\u103b\\u2873\\u2877\\u287bow\\xee\\u048cef\\xf4\\u090f\\xf0\\u13d1ker;\\u65ae\\u0100oy\\u2887\\u288cmma;\\u6a29;\\u443cash;\\u6014asuredangle\\xbb\\u1626r;\\uc000\\ud835\\udd2ao;\\u6127\\u0180cdn\\u28af\\u28b4\\u28c9ro\\u803b\\xb5\\u40b5\\u0200;acd\\u1464\\u28bd\\u28c0\\u28c4s\\xf4\\u16a7ir;\\u6af0ot\\u80bb\\xb7\\u01b5us\\u0180;bd\\u28d2\\u1903\\u28d3\\u6212\\u0100;u\\u1d3c\\u28d8;\\u6a2a\\u0163\\u28de\\u28e1p;\\u6adb\\xf2\\u2212\\xf0\\u0a81\\u0100dp\\u28e9\\u28eeels;\\u62a7f;\\uc000\\ud835\\udd5e\\u0100ct\\u28f8\\u28fdr;\\uc000\\ud835\\udcc2pos\\xbb\\u159d\\u0180;lm\\u2909\\u290a\\u290d\\u43bctimap;\\u62b8\\u0c00GLRVabcdefghijlmoprstuvw\\u2942\\u2953\\u297e\\u2989\\u2998\\u29da\\u29e9\\u2a15\\u2a1a\\u2a58\\u2a5d\\u2a83\\u2a95\\u2aa4\\u2aa8\\u2b04\\u2b07\\u2b44\\u2b7f\\u2bae\\u2c34\\u2c67\\u2c7c\\u2ce9\\u0100gt\\u2947\\u294b;\\uc000\\u22d9\\u0338\\u0100;v\\u2950\\u0bcf\\uc000\\u226b\\u20d2\\u0180elt\\u295a\\u2972\\u2976ft\\u0100ar\\u2961\\u2967rrow;\\u61cdightarrow;\\u61ce;\\uc000\\u22d8\\u0338\\u0100;v\\u297b\\u0c47\\uc000\\u226a\\u20d2ightarrow;\\u61cf\\u0100Dd\\u298e\\u2993ash;\\u62afash;\\u62ae\\u0280bcnpt\\u29a3\\u29a7\\u29ac\\u29b1\\u29ccla\\xbb\\u02deute;\\u4144g;\\uc000\\u2220\\u20d2\\u0280;Eiop\\u0d84\\u29bc\\u29c0\\u29c5\\u29c8;\\uc000\\u2a70\\u0338d;\\uc000\\u224b\\u0338s;\\u4149ro\\xf8\\u0d84ur\\u0100;a\\u29d3\\u29d4\\u666el\\u0100;s\\u29d3\\u0b38\\u01f3\\u29df\\0\\u29e3p\\u80bb\\xa0\\u0b37mp\\u0100;e\\u0bf9\\u0c00\\u0280aeouy\\u29f4\\u29fe\\u2a03\\u2a10\\u2a13\\u01f0\\u29f9\\0\\u29fb;\\u6a43on;\\u4148dil;\\u4146ng\\u0100;d\\u0d7e\\u2a0aot;\\uc000\\u2a6d\\u0338p;\\u6a42;\\u443dash;\\u6013\\u0380;Aadqsx\\u0b92\\u2a29\\u2a2d\\u2a3b\\u2a41\\u2a45\\u2a50rr;\\u61d7r\\u0100hr\\u2a33\\u2a36k;\\u6924\\u0100;o\\u13f2\\u13f0ot;\\uc000\\u2250\\u0338ui\\xf6\\u0b63\\u0100ei\\u2a4a\\u2a4ear;\\u6928\\xed\\u0b98ist\\u0100;s\\u0ba0\\u0b9fr;\\uc000\\ud835\\udd2b\\u0200Eest\\u0bc5\\u2a66\\u2a79\\u2a7c\\u0180;qs\\u0bbc\\u2a6d\\u0be1\\u0180;qs\\u0bbc\\u0bc5\\u2a74lan\\xf4\\u0be2i\\xed\\u0bea\\u0100;r\\u0bb6\\u2a81\\xbb\\u0bb7\\u0180Aap\\u2a8a\\u2a8d\\u2a91r\\xf2\\u2971rr;\\u61aear;\\u6af2\\u0180;sv\\u0f8d\\u2a9c\\u0f8c\\u0100;d\\u2aa1\\u2aa2\\u62fc;\\u62facy;\\u445a\\u0380AEadest\\u2ab7\\u2aba\\u2abe\\u2ac2\\u2ac5\\u2af6\\u2af9r\\xf2\\u2966;\\uc000\\u2266\\u0338rr;\\u619ar;\\u6025\\u0200;fqs\\u0c3b\\u2ace\\u2ae3\\u2aeft\\u0100ar\\u2ad4\\u2ad9rro\\xf7\\u2ac1ightarro\\xf7\\u2a90\\u0180;qs\\u0c3b\\u2aba\\u2aealan\\xf4\\u0c55\\u0100;s\\u0c55\\u2af4\\xbb\\u0c36i\\xed\\u0c5d\\u0100;r\\u0c35\\u2afei\\u0100;e\\u0c1a\\u0c25i\\xe4\\u0d90\\u0100pt\\u2b0c\\u2b11f;\\uc000\\ud835\\udd5f\\u8180\\xac;in\\u2b19\\u2b1a\\u2b36\\u40acn\\u0200;Edv\\u0b89\\u2b24\\u2b28\\u2b2e;\\uc000\\u22f9\\u0338ot;\\uc000\\u22f5\\u0338\\u01e1\\u0b89\\u2b33\\u2b35;\\u62f7;\\u62f6i\\u0100;v\\u0cb8\\u2b3c\\u01e1\\u0cb8\\u2b41\\u2b43;\\u62fe;\\u62fd\\u0180aor\\u2b4b\\u2b63\\u2b69r\\u0200;ast\\u0b7b\\u2b55\\u2b5a\\u2b5flle\\xec\\u0b7bl;\\uc000\\u2afd\\u20e5;\\uc000\\u2202\\u0338lint;\\u6a14\\u0180;ce\\u0c92\\u2b70\\u2b73u\\xe5\\u0ca5\\u0100;c\\u0c98\\u2b78\\u0100;e\\u0c92\\u2b7d\\xf1\\u0c98\\u0200Aait\\u2b88\\u2b8b\\u2b9d\\u2ba7r\\xf2\\u2988rr\\u0180;cw\\u2b94\\u2b95\\u2b99\\u619b;\\uc000\\u2933\\u0338;\\uc000\\u219d\\u0338ghtarrow\\xbb\\u2b95ri\\u0100;e\\u0ccb\\u0cd6\\u0380chimpqu\\u2bbd\\u2bcd\\u2bd9\\u2b04\\u0b78\\u2be4\\u2bef\\u0200;cer\\u0d32\\u2bc6\\u0d37\\u2bc9u\\xe5\\u0d45;\\uc000\\ud835\\udcc3ort\\u026d\\u2b05\\0\\0\\u2bd6ar\\xe1\\u2b56m\\u0100;e\\u0d6e\\u2bdf\\u0100;q\\u0d74\\u0d73su\\u0100bp\\u2beb\\u2bed\\xe5\\u0cf8\\xe5\\u0d0b\\u0180bcp\\u2bf6\\u2c11\\u2c19\\u0200;Ees\\u2bff\\u2c00\\u0d22\\u2c04\\u6284;\\uc000\\u2ac5\\u0338et\\u0100;e\\u0d1b\\u2c0bq\\u0100;q\\u0d23\\u2c00c\\u0100;e\\u0d32\\u2c17\\xf1\\u0d38\\u0200;Ees\\u2c22\\u2c23\\u0d5f\\u2c27\\u6285;\\uc000\\u2ac6\\u0338et\\u0100;e\\u0d58\\u2c2eq\\u0100;q\\u0d60\\u2c23\\u0200gilr\\u2c3d\\u2c3f\\u2c45\\u2c47\\xec\\u0bd7lde\\u803b\\xf1\\u40f1\\xe7\\u0c43iangle\\u0100lr\\u2c52\\u2c5ceft\\u0100;e\\u0c1a\\u2c5a\\xf1\\u0c26ight\\u0100;e\\u0ccb\\u2c65\\xf1\\u0cd7\\u0100;m\\u2c6c\\u2c6d\\u43bd\\u0180;es\\u2c74\\u2c75\\u2c79\\u4023ro;\\u6116p;\\u6007\\u0480DHadgilrs\\u2c8f\\u2c94\\u2c99\\u2c9e\\u2ca3\\u2cb0\\u2cb6\\u2cd3\\u2ce3ash;\\u62adarr;\\u6904p;\\uc000\\u224d\\u20d2ash;\\u62ac\\u0100et\\u2ca8\\u2cac;\\uc000\\u2265\\u20d2;\\uc000>\\u20d2nfin;\\u69de\\u0180Aet\\u2cbd\\u2cc1\\u2cc5rr;\\u6902;\\uc000\\u2264\\u20d2\\u0100;r\\u2cca\\u2ccd\\uc000<\\u20d2ie;\\uc000\\u22b4\\u20d2\\u0100At\\u2cd8\\u2cdcrr;\\u6903rie;\\uc000\\u22b5\\u20d2im;\\uc000\\u223c\\u20d2\\u0180Aan\\u2cf0\\u2cf4\\u2d02rr;\\u61d6r\\u0100hr\\u2cfa\\u2cfdk;\\u6923\\u0100;o\\u13e7\\u13e5ear;\\u6927\\u1253\\u1a95\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\u2d2d\\0\\u2d38\\u2d48\\u2d60\\u2d65\\u2d72\\u2d84\\u1b07\\0\\0\\u2d8d\\u2dab\\0\\u2dc8\\u2dce\\0\\u2ddc\\u2e19\\u2e2b\\u2e3e\\u2e43\\u0100cs\\u2d31\\u1a97ute\\u803b\\xf3\\u40f3\\u0100iy\\u2d3c\\u2d45r\\u0100;c\\u1a9e\\u2d42\\u803b\\xf4\\u40f4;\\u443e\\u0280abios\\u1aa0\\u2d52\\u2d57\\u01c8\\u2d5alac;\\u4151v;\\u6a38old;\\u69bclig;\\u4153\\u0100cr\\u2d69\\u2d6dir;\\u69bf;\\uc000\\ud835\\udd2c\\u036f\\u2d79\\0\\0\\u2d7c\\0\\u2d82n;\\u42dbave\\u803b\\xf2\\u40f2;\\u69c1\\u0100bm\\u2d88\\u0df4ar;\\u69b5\\u0200acit\\u2d95\\u2d98\\u2da5\\u2da8r\\xf2\\u1a80\\u0100ir\\u2d9d\\u2da0r;\\u69beoss;\\u69bbn\\xe5\\u0e52;\\u69c0\\u0180aei\\u2db1\\u2db5\\u2db9cr;\\u414dga;\\u43c9\\u0180cdn\\u2dc0\\u2dc5\\u01cdron;\\u43bf;\\u69b6pf;\\uc000\\ud835\\udd60\\u0180ael\\u2dd4\\u2dd7\\u01d2r;\\u69b7rp;\\u69b9\\u0380;adiosv\\u2dea\\u2deb\\u2dee\\u2e08\\u2e0d\\u2e10\\u2e16\\u6228r\\xf2\\u1a86\\u0200;efm\\u2df7\\u2df8\\u2e02\\u2e05\\u6a5dr\\u0100;o\\u2dfe\\u2dff\\u6134f\\xbb\\u2dff\\u803b\\xaa\\u40aa\\u803b\\xba\\u40bagof;\\u62b6r;\\u6a56lope;\\u6a57;\\u6a5b\\u0180clo\\u2e1f\\u2e21\\u2e27\\xf2\\u2e01ash\\u803b\\xf8\\u40f8l;\\u6298i\\u016c\\u2e2f\\u2e34de\\u803b\\xf5\\u40f5es\\u0100;a\\u01db\\u2e3as;\\u6a36ml\\u803b\\xf6\\u40f6bar;\\u633d\\u0ae1\\u2e5e\\0\\u2e7d\\0\\u2e80\\u2e9d\\0\\u2ea2\\u2eb9\\0\\0\\u2ecb\\u0e9c\\0\\u2f13\\0\\0\\u2f2b\\u2fbc\\0\\u2fc8r\\u0200;ast\\u0403\\u2e67\\u2e72\\u0e85\\u8100\\xb6;l\\u2e6d\\u2e6e\\u40b6le\\xec\\u0403\\u0269\\u2e78\\0\\0\\u2e7bm;\\u6af3;\\u6afdy;\\u443fr\\u0280cimpt\\u2e8b\\u2e8f\\u2e93\\u1865\\u2e97nt;\\u4025od;\\u402eil;\\u6030enk;\\u6031r;\\uc000\\ud835\\udd2d\\u0180imo\\u2ea8\\u2eb0\\u2eb4\\u0100;v\\u2ead\\u2eae\\u43c6;\\u43d5ma\\xf4\\u0a76ne;\\u660e\\u0180;tv\\u2ebf\\u2ec0\\u2ec8\\u43c0chfork\\xbb\\u1ffd;\\u43d6\\u0100au\\u2ecf\\u2edfn\\u0100ck\\u2ed5\\u2eddk\\u0100;h\\u21f4\\u2edb;\\u610e\\xf6\\u21f4s\\u0480;abcdemst\\u2ef3\\u2ef4\\u1908\\u2ef9\\u2efd\\u2f04\\u2f06\\u2f0a\\u2f0e\\u402bcir;\\u6a23ir;\\u6a22\\u0100ou\\u1d40\\u2f02;\\u6a25;\\u6a72n\\u80bb\\xb1\\u0e9dim;\\u6a26wo;\\u6a27\\u0180ipu\\u2f19\\u2f20\\u2f25ntint;\\u6a15f;\\uc000\\ud835\\udd61nd\\u803b\\xa3\\u40a3\\u0500;Eaceinosu\\u0ec8\\u2f3f\\u2f41\\u2f44\\u2f47\\u2f81\\u2f89\\u2f92\\u2f7e\\u2fb6;\\u6ab3p;\\u6ab7u\\xe5\\u0ed9\\u0100;c\\u0ece\\u2f4c\\u0300;acens\\u0ec8\\u2f59\\u2f5f\\u2f66\\u2f68\\u2f7eppro\\xf8\\u2f43urlye\\xf1\\u0ed9\\xf1\\u0ece\\u0180aes\\u2f6f\\u2f76\\u2f7approx;\\u6ab9qq;\\u6ab5im;\\u62e8i\\xed\\u0edfme\\u0100;s\\u2f88\\u0eae\\u6032\\u0180Eas\\u2f78\\u2f90\\u2f7a\\xf0\\u2f75\\u0180dfp\\u0eec\\u2f99\\u2faf\\u0180als\\u2fa0\\u2fa5\\u2faalar;\\u632eine;\\u6312urf;\\u6313\\u0100;t\\u0efb\\u2fb4\\xef\\u0efbrel;\\u62b0\\u0100ci\\u2fc0\\u2fc5r;\\uc000\\ud835\\udcc5;\\u43c8ncsp;\\u6008\\u0300fiopsu\\u2fda\\u22e2\\u2fdf\\u2fe5\\u2feb\\u2ff1r;\\uc000\\ud835\\udd2epf;\\uc000\\ud835\\udd62rime;\\u6057cr;\\uc000\\ud835\\udcc6\\u0180aeo\\u2ff8\\u3009\\u3013t\\u0100ei\\u2ffe\\u3005rnion\\xf3\\u06b0nt;\\u6a16st\\u0100;e\\u3010\\u3011\\u403f\\xf1\\u1f19\\xf4\\u0f14\\u0a80ABHabcdefhilmnoprstux\\u3040\\u3051\\u3055\\u3059\\u30e0\\u310e\\u312b\\u3147\\u3162\\u3172\\u318e\\u3206\\u3215\\u3224\\u3229\\u3258\\u326e\\u3272\\u3290\\u32b0\\u32b7\\u0180art\\u3047\\u304a\\u304cr\\xf2\\u10b3\\xf2\\u03ddail;\\u691car\\xf2\\u1c65ar;\\u6964\\u0380cdenqrt\\u3068\\u3075\\u3078\\u307f\\u308f\\u3094\\u30cc\\u0100eu\\u306d\\u3071;\\uc000\\u223d\\u0331te;\\u4155i\\xe3\\u116emptyv;\\u69b3g\\u0200;del\\u0fd1\\u3089\\u308b\\u308d;\\u6992;\\u69a5\\xe5\\u0fd1uo\\u803b\\xbb\\u40bbr\\u0580;abcfhlpstw\\u0fdc\\u30ac\\u30af\\u30b7\\u30b9\\u30bc\\u30be\\u30c0\\u30c3\\u30c7\\u30cap;\\u6975\\u0100;f\\u0fe0\\u30b4s;\\u6920;\\u6933s;\\u691e\\xeb\\u225d\\xf0\\u272el;\\u6945im;\\u6974l;\\u61a3;\\u619d\\u0100ai\\u30d1\\u30d5il;\\u691ao\\u0100;n\\u30db\\u30dc\\u6236al\\xf3\\u0f1e\\u0180abr\\u30e7\\u30ea\\u30eer\\xf2\\u17e5rk;\\u6773\\u0100ak\\u30f3\\u30fdc\\u0100ek\\u30f9\\u30fb;\\u407d;\\u405d\\u0100es\\u3102\\u3104;\\u698cl\\u0100du\\u310a\\u310c;\\u698e;\\u6990\\u0200aeuy\\u3117\\u311c\\u3127\\u3129ron;\\u4159\\u0100di\\u3121\\u3125il;\\u4157\\xec\\u0ff2\\xe2\\u30fa;\\u4440\\u0200clqs\\u3134\\u3137\\u313d\\u3144a;\\u6937dhar;\\u6969uo\\u0100;r\\u020e\\u020dh;\\u61b3\\u0180acg\\u314e\\u315f\\u0f44l\\u0200;ips\\u0f78\\u3158\\u315b\\u109cn\\xe5\\u10bbar\\xf4\\u0fa9t;\\u65ad\\u0180ilr\\u3169\\u1023\\u316esht;\\u697d;\\uc000\\ud835\\udd2f\\u0100ao\\u3177\\u3186r\\u0100du\\u317d\\u317f\\xbb\\u047b\\u0100;l\\u1091\\u3184;\\u696c\\u0100;v\\u318b\\u318c\\u43c1;\\u43f1\\u0180gns\\u3195\\u31f9\\u31fcht\\u0300ahlrst\\u31a4\\u31b0\\u31c2\\u31d8\\u31e4\\u31eerrow\\u0100;t\\u0fdc\\u31ada\\xe9\\u30c8arpoon\\u0100du\\u31bb\\u31bfow\\xee\\u317ep\\xbb\\u1092eft\\u0100ah\\u31ca\\u31d0rrow\\xf3\\u0feaarpoon\\xf3\\u0551ightarrows;\\u61c9quigarro\\xf7\\u30cbhreetimes;\\u62ccg;\\u42daingdotse\\xf1\\u1f32\\u0180ahm\\u320d\\u3210\\u3213r\\xf2\\u0feaa\\xf2\\u0551;\\u600foust\\u0100;a\\u321e\\u321f\\u63b1che\\xbb\\u321fmid;\\u6aee\\u0200abpt\\u3232\\u323d\\u3240\\u3252\\u0100nr\\u3237\\u323ag;\\u67edr;\\u61fer\\xeb\\u1003\\u0180afl\\u3247\\u324a\\u324er;\\u6986;\\uc000\\ud835\\udd63us;\\u6a2eimes;\\u6a35\\u0100ap\\u325d\\u3267r\\u0100;g\\u3263\\u3264\\u4029t;\\u6994olint;\\u6a12ar\\xf2\\u31e3\\u0200achq\\u327b\\u3280\\u10bc\\u3285quo;\\u603ar;\\uc000\\ud835\\udcc7\\u0100bu\\u30fb\\u328ao\\u0100;r\\u0214\\u0213\\u0180hir\\u3297\\u329b\\u32a0re\\xe5\\u31f8mes;\\u62cai\\u0200;efl\\u32aa\\u1059\\u1821\\u32ab\\u65b9tri;\\u69celuhar;\\u6968;\\u611e\\u0d61\\u32d5\\u32db\\u32df\\u332c\\u3338\\u3371\\0\\u337a\\u33a4\\0\\0\\u33ec\\u33f0\\0\\u3428\\u3448\\u345a\\u34ad\\u34b1\\u34ca\\u34f1\\0\\u3616\\0\\0\\u3633cute;\\u415bqu\\xef\\u27ba\\u0500;Eaceinpsy\\u11ed\\u32f3\\u32f5\\u32ff\\u3302\\u330b\\u330f\\u331f\\u3326\\u3329;\\u6ab4\\u01f0\\u32fa\\0\\u32fc;\\u6ab8on;\\u4161u\\xe5\\u11fe\\u0100;d\\u11f3\\u3307il;\\u415frc;\\u415d\\u0180Eas\\u3316\\u3318\\u331b;\\u6ab6p;\\u6abaim;\\u62e9olint;\\u6a13i\\xed\\u1204;\\u4441ot\\u0180;be\\u3334\\u1d47\\u3335\\u62c5;\\u6a66\\u0380Aacmstx\\u3346\\u334a\\u3357\\u335b\\u335e\\u3363\\u336drr;\\u61d8r\\u0100hr\\u3350\\u3352\\xeb\\u2228\\u0100;o\\u0a36\\u0a34t\\u803b\\xa7\\u40a7i;\\u403bwar;\\u6929m\\u0100in\\u3369\\xf0nu\\xf3\\xf1t;\\u6736r\\u0100;o\\u3376\\u2055\\uc000\\ud835\\udd30\\u0200acoy\\u3382\\u3386\\u3391\\u33a0rp;\\u666f\\u0100hy\\u338b\\u338fcy;\\u4449;\\u4448rt\\u026d\\u3399\\0\\0\\u339ci\\xe4\\u1464ara\\xec\\u2e6f\\u803b\\xad\\u40ad\\u0100gm\\u33a8\\u33b4ma\\u0180;fv\\u33b1\\u33b2\\u33b2\\u43c3;\\u43c2\\u0400;deglnpr\\u12ab\\u33c5\\u33c9\\u33ce\\u33d6\\u33de\\u33e1\\u33e6ot;\\u6a6a\\u0100;q\\u12b1\\u12b0\\u0100;E\\u33d3\\u33d4\\u6a9e;\\u6aa0\\u0100;E\\u33db\\u33dc\\u6a9d;\\u6a9fe;\\u6246lus;\\u6a24arr;\\u6972ar\\xf2\\u113d\\u0200aeit\\u33f8\\u3408\\u340f\\u3417\\u0100ls\\u33fd\\u3404lsetm\\xe9\\u336ahp;\\u6a33parsl;\\u69e4\\u0100dl\\u1463\\u3414e;\\u6323\\u0100;e\\u341c\\u341d\\u6aaa\\u0100;s\\u3422\\u3423\\u6aac;\\uc000\\u2aac\\ufe00\\u0180flp\\u342e\\u3433\\u3442tcy;\\u444c\\u0100;b\\u3438\\u3439\\u402f\\u0100;a\\u343e\\u343f\\u69c4r;\\u633ff;\\uc000\\ud835\\udd64a\\u0100dr\\u344d\\u0402es\\u0100;u\\u3454\\u3455\\u6660it\\xbb\\u3455\\u0180csu\\u3460\\u3479\\u349f\\u0100au\\u3465\\u346fp\\u0100;s\\u1188\\u346b;\\uc000\\u2293\\ufe00p\\u0100;s\\u11b4\\u3475;\\uc000\\u2294\\ufe00u\\u0100bp\\u347f\\u348f\\u0180;es\\u1197\\u119c\\u3486et\\u0100;e\\u1197\\u348d\\xf1\\u119d\\u0180;es\\u11a8\\u11ad\\u3496et\\u0100;e\\u11a8\\u349d\\xf1\\u11ae\\u0180;af\\u117b\\u34a6\\u05b0r\\u0165\\u34ab\\u05b1\\xbb\\u117car\\xf2\\u1148\\u0200cemt\\u34b9\\u34be\\u34c2\\u34c5r;\\uc000\\ud835\\udcc8tm\\xee\\xf1i\\xec\\u3415ar\\xe6\\u11be\\u0100ar\\u34ce\\u34d5r\\u0100;f\\u34d4\\u17bf\\u6606\\u0100an\\u34da\\u34edight\\u0100ep\\u34e3\\u34eapsilo\\xee\\u1ee0h\\xe9\\u2eafs\\xbb\\u2852\\u0280bcmnp\\u34fb\\u355e\\u1209\\u358b\\u358e\\u0480;Edemnprs\\u350e\\u350f\\u3511\\u3515\\u351e\\u3523\\u352c\\u3531\\u3536\\u6282;\\u6ac5ot;\\u6abd\\u0100;d\\u11da\\u351aot;\\u6ac3ult;\\u6ac1\\u0100Ee\\u3528\\u352a;\\u6acb;\\u628alus;\\u6abfarr;\\u6979\\u0180eiu\\u353d\\u3552\\u3555t\\u0180;en\\u350e\\u3545\\u354bq\\u0100;q\\u11da\\u350feq\\u0100;q\\u352b\\u3528m;\\u6ac7\\u0100bp\\u355a\\u355c;\\u6ad5;\\u6ad3c\\u0300;acens\\u11ed\\u356c\\u3572\\u3579\\u357b\\u3326ppro\\xf8\\u32faurlye\\xf1\\u11fe\\xf1\\u11f3\\u0180aes\\u3582\\u3588\\u331bppro\\xf8\\u331aq\\xf1\\u3317g;\\u666a\\u0680123;Edehlmnps\\u35a9\\u35ac\\u35af\\u121c\\u35b2\\u35b4\\u35c0\\u35c9\\u35d5\\u35da\\u35df\\u35e8\\u35ed\\u803b\\xb9\\u40b9\\u803b\\xb2\\u40b2\\u803b\\xb3\\u40b3;\\u6ac6\\u0100os\\u35b9\\u35bct;\\u6abeub;\\u6ad8\\u0100;d\\u1222\\u35c5ot;\\u6ac4s\\u0100ou\\u35cf\\u35d2l;\\u67c9b;\\u6ad7arr;\\u697bult;\\u6ac2\\u0100Ee\\u35e4\\u35e6;\\u6acc;\\u628blus;\\u6ac0\\u0180eiu\\u35f4\\u3609\\u360ct\\u0180;en\\u121c\\u35fc\\u3602q\\u0100;q\\u1222\\u35b2eq\\u0100;q\\u35e7\\u35e4m;\\u6ac8\\u0100bp\\u3611\\u3613;\\u6ad4;\\u6ad6\\u0180Aan\\u361c\\u3620\\u362drr;\\u61d9r\\u0100hr\\u3626\\u3628\\xeb\\u222e\\u0100;o\\u0a2b\\u0a29war;\\u692alig\\u803b\\xdf\\u40df\\u0be1\\u3651\\u365d\\u3660\\u12ce\\u3673\\u3679\\0\\u367e\\u36c2\\0\\0\\0\\0\\0\\u36db\\u3703\\0\\u3709\\u376c\\0\\0\\0\\u3787\\u0272\\u3656\\0\\0\\u365bget;\\u6316;\\u43c4r\\xeb\\u0e5f\\u0180aey\\u3666\\u366b\\u3670ron;\\u4165dil;\\u4163;\\u4442lrec;\\u6315r;\\uc000\\ud835\\udd31\\u0200eiko\\u3686\\u369d\\u36b5\\u36bc\\u01f2\\u368b\\0\\u3691e\\u01004f\\u1284\\u1281a\\u0180;sv\\u3698\\u3699\\u369b\\u43b8ym;\\u43d1\\u0100cn\\u36a2\\u36b2k\\u0100as\\u36a8\\u36aeppro\\xf8\\u12c1im\\xbb\\u12acs\\xf0\\u129e\\u0100as\\u36ba\\u36ae\\xf0\\u12c1rn\\u803b\\xfe\\u40fe\\u01ec\\u031f\\u36c6\\u22e7es\\u8180\\xd7;bd\\u36cf\\u36d0\\u36d8\\u40d7\\u0100;a\\u190f\\u36d5r;\\u6a31;\\u6a30\\u0180eps\\u36e1\\u36e3\\u3700\\xe1\\u2a4d\\u0200;bcf\\u0486\\u36ec\\u36f0\\u36f4ot;\\u6336ir;\\u6af1\\u0100;o\\u36f9\\u36fc\\uc000\\ud835\\udd65rk;\\u6ada\\xe1\\u3362rime;\\u6034\\u0180aip\\u370f\\u3712\\u3764d\\xe5\\u1248\\u0380adempst\\u3721\\u374d\\u3740\\u3751\\u3757\\u375c\\u375fngle\\u0280;dlqr\\u3730\\u3731\\u3736\\u3740\\u3742\\u65b5own\\xbb\\u1dbbeft\\u0100;e\\u2800\\u373e\\xf1\\u092e;\\u625cight\\u0100;e\\u32aa\\u374b\\xf1\\u105aot;\\u65ecinus;\\u6a3alus;\\u6a39b;\\u69cdime;\\u6a3bezium;\\u63e2\\u0180cht\\u3772\\u377d\\u3781\\u0100ry\\u3777\\u377b;\\uc000\\ud835\\udcc9;\\u4446cy;\\u445brok;\\u4167\\u0100io\\u378b\\u378ex\\xf4\\u1777head\\u0100lr\\u3797\\u37a0eftarro\\xf7\\u084fightarrow\\xbb\\u0f5d\\u0900AHabcdfghlmoprstuw\\u37d0\\u37d3\\u37d7\\u37e4\\u37f0\\u37fc\\u380e\\u381c\\u3823\\u3834\\u3851\\u385d\\u386b\\u38a9\\u38cc\\u38d2\\u38ea\\u38f6r\\xf2\\u03edar;\\u6963\\u0100cr\\u37dc\\u37e2ute\\u803b\\xfa\\u40fa\\xf2\\u1150r\\u01e3\\u37ea\\0\\u37edy;\\u445eve;\\u416d\\u0100iy\\u37f5\\u37farc\\u803b\\xfb\\u40fb;\\u4443\\u0180abh\\u3803\\u3806\\u380br\\xf2\\u13adlac;\\u4171a\\xf2\\u13c3\\u0100ir\\u3813\\u3818sht;\\u697e;\\uc000\\ud835\\udd32rave\\u803b\\xf9\\u40f9\\u0161\\u3827\\u3831r\\u0100lr\\u382c\\u382e\\xbb\\u0957\\xbb\\u1083lk;\\u6580\\u0100ct\\u3839\\u384d\\u026f\\u383f\\0\\0\\u384arn\\u0100;e\\u3845\\u3846\\u631cr\\xbb\\u3846op;\\u630fri;\\u65f8\\u0100al\\u3856\\u385acr;\\u416b\\u80bb\\xa8\\u0349\\u0100gp\\u3862\\u3866on;\\u4173f;\\uc000\\ud835\\udd66\\u0300adhlsu\\u114b\\u3878\\u387d\\u1372\\u3891\\u38a0own\\xe1\\u13b3arpoon\\u0100lr\\u3888\\u388cef\\xf4\\u382digh\\xf4\\u382fi\\u0180;hl\\u3899\\u389a\\u389c\\u43c5\\xbb\\u13faon\\xbb\\u389aparrows;\\u61c8\\u0180cit\\u38b0\\u38c4\\u38c8\\u026f\\u38b6\\0\\0\\u38c1rn\\u0100;e\\u38bc\\u38bd\\u631dr\\xbb\\u38bdop;\\u630eng;\\u416fri;\\u65f9cr;\\uc000\\ud835\\udcca\\u0180dir\\u38d9\\u38dd\\u38e2ot;\\u62f0lde;\\u4169i\\u0100;f\\u3730\\u38e8\\xbb\\u1813\\u0100am\\u38ef\\u38f2r\\xf2\\u38a8l\\u803b\\xfc\\u40fcangle;\\u69a7\\u0780ABDacdeflnoprsz\\u391c\\u391f\\u3929\\u392d\\u39b5\\u39b8\\u39bd\\u39df\\u39e4\\u39e8\\u39f3\\u39f9\\u39fd\\u3a01\\u3a20r\\xf2\\u03f7ar\\u0100;v\\u3926\\u3927\\u6ae8;\\u6ae9as\\xe8\\u03e1\\u0100nr\\u3932\\u3937grt;\\u699c\\u0380eknprst\\u34e3\\u3946\\u394b\\u3952\\u395d\\u3964\\u3996app\\xe1\\u2415othin\\xe7\\u1e96\\u0180hir\\u34eb\\u2ec8\\u3959op\\xf4\\u2fb5\\u0100;h\\u13b7\\u3962\\xef\\u318d\\u0100iu\\u3969\\u396dgm\\xe1\\u33b3\\u0100bp\\u3972\\u3984setneq\\u0100;q\\u397d\\u3980\\uc000\\u228a\\ufe00;\\uc000\\u2acb\\ufe00setneq\\u0100;q\\u398f\\u3992\\uc000\\u228b\\ufe00;\\uc000\\u2acc\\ufe00\\u0100hr\\u399b\\u399fet\\xe1\\u369ciangle\\u0100lr\\u39aa\\u39afeft\\xbb\\u0925ight\\xbb\\u1051y;\\u4432ash\\xbb\\u1036\\u0180elr\\u39c4\\u39d2\\u39d7\\u0180;be\\u2dea\\u39cb\\u39cfar;\\u62bbq;\\u625alip;\\u62ee\\u0100bt\\u39dc\\u1468a\\xf2\\u1469r;\\uc000\\ud835\\udd33tr\\xe9\\u39aesu\\u0100bp\\u39ef\\u39f1\\xbb\\u0d1c\\xbb\\u0d59pf;\\uc000\\ud835\\udd67ro\\xf0\\u0efbtr\\xe9\\u39b4\\u0100cu\\u3a06\\u3a0br;\\uc000\\ud835\\udccb\\u0100bp\\u3a10\\u3a18n\\u0100Ee\\u3980\\u3a16\\xbb\\u397en\\u0100Ee\\u3992\\u3a1e\\xbb\\u3990igzag;\\u699a\\u0380cefoprs\\u3a36\\u3a3b\\u3a56\\u3a5b\\u3a54\\u3a61\\u3a6airc;\\u4175\\u0100di\\u3a40\\u3a51\\u0100bg\\u3a45\\u3a49ar;\\u6a5fe\\u0100;q\\u15fa\\u3a4f;\\u6259erp;\\u6118r;\\uc000\\ud835\\udd34pf;\\uc000\\ud835\\udd68\\u0100;e\\u1479\\u3a66at\\xe8\\u1479cr;\\uc000\\ud835\\udccc\\u0ae3\\u178e\\u3a87\\0\\u3a8b\\0\\u3a90\\u3a9b\\0\\0\\u3a9d\\u3aa8\\u3aab\\u3aaf\\0\\0\\u3ac3\\u3ace\\0\\u3ad8\\u17dc\\u17dftr\\xe9\\u17d1r;\\uc000\\ud835\\udd35\\u0100Aa\\u3a94\\u3a97r\\xf2\\u03c3r\\xf2\\u09f6;\\u43be\\u0100Aa\\u3aa1\\u3aa4r\\xf2\\u03b8r\\xf2\\u09eba\\xf0\\u2713is;\\u62fb\\u0180dpt\\u17a4\\u3ab5\\u3abe\\u0100fl\\u3aba\\u17a9;\\uc000\\ud835\\udd69im\\xe5\\u17b2\\u0100Aa\\u3ac7\\u3acar\\xf2\\u03cer\\xf2\\u0a01\\u0100cq\\u3ad2\\u17b8r;\\uc000\\ud835\\udccd\\u0100pt\\u17d6\\u3adcr\\xe9\\u17d4\\u0400acefiosu\\u3af0\\u3afd\\u3b08\\u3b0c\\u3b11\\u3b15\\u3b1b\\u3b21c\\u0100uy\\u3af6\\u3afbte\\u803b\\xfd\\u40fd;\\u444f\\u0100iy\\u3b02\\u3b06rc;\\u4177;\\u444bn\\u803b\\xa5\\u40a5r;\\uc000\\ud835\\udd36cy;\\u4457pf;\\uc000\\ud835\\udd6acr;\\uc000\\ud835\\udcce\\u0100cm\\u3b26\\u3b29y;\\u444el\\u803b\\xff\\u40ff\\u0500acdefhiosw\\u3b42\\u3b48\\u3b54\\u3b58\\u3b64\\u3b69\\u3b6d\\u3b74\\u3b7a\\u3b80cute;\\u417a\\u0100ay\\u3b4d\\u3b52ron;\\u417e;\\u4437ot;\\u417c\\u0100et\\u3b5d\\u3b61tr\\xe6\\u155fa;\\u43b6r;\\uc000\\ud835\\udd37cy;\\u4436grarr;\\u61ddpf;\\uc000\\ud835\\udd6bcr;\\uc000\\ud835\\udccf\\u0100jn\\u3b85\\u3b87;\\u600dj;\\u600c\"\n    .split(\"\")\n    .map((c) => c.charCodeAt(0)));\n//# sourceMappingURL=decode-data-html.js.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/entities/src/generated/decode-data-xml.d.ts",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport declare const xmlDecodeTree: Uint16Array;\n//# sourceMappingURL=decode-data-xml.d.ts.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/entities/src/generated/decode-data-xml.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n// Generated using scripts/write-decode-map.ts\nexport const xmlDecodeTree = /* #__PURE__ */ new Uint16Array(\n// prettier-ignore\n/* #__PURE__ */ \"\\u0200aglq\\t\\x15\\x18\\x1b\\u026d\\x0f\\0\\0\\x12p;\\u4026os;\\u4027t;\\u403et;\\u403cuot;\\u4022\"\n    .split(\"\")\n    .map((c) => c.charCodeAt(0)));\n//# sourceMappingURL=decode-data-xml.js.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/entities/src/generated/encode-html.d.ts",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\ntype EncodeTrieNode = string | {\n    v?: string;\n    n: number | Map<number, EncodeTrieNode>;\n    o?: string;\n};\nexport declare const htmlTrie: Map<number, EncodeTrieNode>;\nexport {};\n//# sourceMappingURL=encode-html.d.ts.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/entities/src/generated/encode-html.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n// Generated using scripts/write-encode-map.ts\nfunction restoreDiff(array) {\n    for (let index = 1; index < array.length; index++) {\n        array[index][0] += array[index - 1][0] + 1;\n    }\n    return array;\n}\n// prettier-ignore\nexport const htmlTrie = /* #__PURE__ */ new Map(/* #__PURE__ */ restoreDiff([[9, \"&Tab;\"], [0, \"&NewLine;\"], [22, \"&excl;\"], [0, \"&quot;\"], [0, \"&num;\"], [0, \"&dollar;\"], [0, \"&percnt;\"], [0, \"&amp;\"], [0, \"&apos;\"], [0, \"&lpar;\"], [0, \"&rpar;\"], [0, \"&ast;\"], [0, \"&plus;\"], [0, \"&comma;\"], [1, \"&period;\"], [0, \"&sol;\"], [10, \"&colon;\"], [0, \"&semi;\"], [0, { v: \"&lt;\", n: 8402, o: \"&nvlt;\" }], [0, { v: \"&equals;\", n: 8421, o: \"&bne;\" }], [0, { v: \"&gt;\", n: 8402, o: \"&nvgt;\" }], [0, \"&quest;\"], [0, \"&commat;\"], [26, \"&lbrack;\"], [0, \"&bsol;\"], [0, \"&rbrack;\"], [0, \"&Hat;\"], [0, \"&lowbar;\"], [0, \"&DiacriticalGrave;\"], [5, { n: 106, o: \"&fjlig;\" }], [20, \"&lbrace;\"], [0, \"&verbar;\"], [0, \"&rbrace;\"], [34, \"&nbsp;\"], [0, \"&iexcl;\"], [0, \"&cent;\"], [0, \"&pound;\"], [0, \"&curren;\"], [0, \"&yen;\"], [0, \"&brvbar;\"], [0, \"&sect;\"], [0, \"&die;\"], [0, \"&copy;\"], [0, \"&ordf;\"], [0, \"&laquo;\"], [0, \"&not;\"], [0, \"&shy;\"], [0, \"&circledR;\"], [0, \"&macr;\"], [0, \"&deg;\"], [0, \"&PlusMinus;\"], [0, \"&sup2;\"], [0, \"&sup3;\"], [0, \"&acute;\"], [0, \"&micro;\"], [0, \"&para;\"], [0, \"&centerdot;\"], [0, \"&cedil;\"], [0, \"&sup1;\"], [0, \"&ordm;\"], [0, \"&raquo;\"], [0, \"&frac14;\"], [0, \"&frac12;\"], [0, \"&frac34;\"], [0, \"&iquest;\"], [0, \"&Agrave;\"], [0, \"&Aacute;\"], [0, \"&Acirc;\"], [0, \"&Atilde;\"], [0, \"&Auml;\"], [0, \"&angst;\"], [0, \"&AElig;\"], [0, \"&Ccedil;\"], [0, \"&Egrave;\"], [0, \"&Eacute;\"], [0, \"&Ecirc;\"], [0, \"&Euml;\"], [0, \"&Igrave;\"], [0, \"&Iacute;\"], [0, \"&Icirc;\"], [0, \"&Iuml;\"], [0, \"&ETH;\"], [0, \"&Ntilde;\"], [0, \"&Ograve;\"], [0, \"&Oacute;\"], [0, \"&Ocirc;\"], [0, \"&Otilde;\"], [0, \"&Ouml;\"], [0, \"&times;\"], [0, \"&Oslash;\"], [0, \"&Ugrave;\"], [0, \"&Uacute;\"], [0, \"&Ucirc;\"], [0, \"&Uuml;\"], [0, \"&Yacute;\"], [0, \"&THORN;\"], [0, \"&szlig;\"], [0, \"&agrave;\"], [0, \"&aacute;\"], [0, \"&acirc;\"], [0, \"&atilde;\"], [0, \"&auml;\"], [0, \"&aring;\"], [0, \"&aelig;\"], [0, \"&ccedil;\"], [0, \"&egrave;\"], [0, \"&eacute;\"], [0, \"&ecirc;\"], [0, \"&euml;\"], [0, \"&igrave;\"], [0, \"&iacute;\"], [0, \"&icirc;\"], [0, \"&iuml;\"], [0, \"&eth;\"], [0, \"&ntilde;\"], [0, \"&ograve;\"], [0, \"&oacute;\"], [0, \"&ocirc;\"], [0, \"&otilde;\"], [0, \"&ouml;\"], [0, \"&div;\"], [0, \"&oslash;\"], [0, \"&ugrave;\"], [0, \"&uacute;\"], [0, \"&ucirc;\"], [0, \"&uuml;\"], [0, \"&yacute;\"], [0, \"&thorn;\"], [0, \"&yuml;\"], [0, \"&Amacr;\"], [0, \"&amacr;\"], [0, \"&Abreve;\"], [0, \"&abreve;\"], [0, \"&Aogon;\"], [0, \"&aogon;\"], [0, \"&Cacute;\"], [0, \"&cacute;\"], [0, \"&Ccirc;\"], [0, \"&ccirc;\"], [0, \"&Cdot;\"], [0, \"&cdot;\"], [0, \"&Ccaron;\"], [0, \"&ccaron;\"], [0, \"&Dcaron;\"], [0, \"&dcaron;\"], [0, \"&Dstrok;\"], [0, \"&dstrok;\"], [0, \"&Emacr;\"], [0, \"&emacr;\"], [2, \"&Edot;\"], [0, \"&edot;\"], [0, \"&Eogon;\"], [0, \"&eogon;\"], [0, \"&Ecaron;\"], [0, \"&ecaron;\"], [0, \"&Gcirc;\"], [0, \"&gcirc;\"], [0, \"&Gbreve;\"], [0, \"&gbreve;\"], [0, \"&Gdot;\"], [0, \"&gdot;\"], [0, \"&Gcedil;\"], [1, \"&Hcirc;\"], [0, \"&hcirc;\"], [0, \"&Hstrok;\"], [0, \"&hstrok;\"], [0, \"&Itilde;\"], [0, \"&itilde;\"], [0, \"&Imacr;\"], [0, \"&imacr;\"], [2, \"&Iogon;\"], [0, \"&iogon;\"], [0, \"&Idot;\"], [0, \"&imath;\"], [0, \"&IJlig;\"], [0, \"&ijlig;\"], [0, \"&Jcirc;\"], [0, \"&jcirc;\"], [0, \"&Kcedil;\"], [0, \"&kcedil;\"], [0, \"&kgreen;\"], [0, \"&Lacute;\"], [0, \"&lacute;\"], [0, \"&Lcedil;\"], [0, \"&lcedil;\"], [0, \"&Lcaron;\"], [0, \"&lcaron;\"], [0, \"&Lmidot;\"], [0, \"&lmidot;\"], [0, \"&Lstrok;\"], [0, \"&lstrok;\"], [0, \"&Nacute;\"], [0, \"&nacute;\"], [0, \"&Ncedil;\"], [0, \"&ncedil;\"], [0, \"&Ncaron;\"], [0, \"&ncaron;\"], [0, \"&napos;\"], [0, \"&ENG;\"], [0, \"&eng;\"], [0, \"&Omacr;\"], [0, \"&omacr;\"], [2, \"&Odblac;\"], [0, \"&odblac;\"], [0, \"&OElig;\"], [0, \"&oelig;\"], [0, \"&Racute;\"], [0, \"&racute;\"], [0, \"&Rcedil;\"], [0, \"&rcedil;\"], [0, \"&Rcaron;\"], [0, \"&rcaron;\"], [0, \"&Sacute;\"], [0, \"&sacute;\"], [0, \"&Scirc;\"], [0, \"&scirc;\"], [0, \"&Scedil;\"], [0, \"&scedil;\"], [0, \"&Scaron;\"], [0, \"&scaron;\"], [0, \"&Tcedil;\"], [0, \"&tcedil;\"], [0, \"&Tcaron;\"], [0, \"&tcaron;\"], [0, \"&Tstrok;\"], [0, \"&tstrok;\"], [0, \"&Utilde;\"], [0, \"&utilde;\"], [0, \"&Umacr;\"], [0, \"&umacr;\"], [0, \"&Ubreve;\"], [0, \"&ubreve;\"], [0, \"&Uring;\"], [0, \"&uring;\"], [0, \"&Udblac;\"], [0, \"&udblac;\"], [0, \"&Uogon;\"], [0, \"&uogon;\"], [0, \"&Wcirc;\"], [0, \"&wcirc;\"], [0, \"&Ycirc;\"], [0, \"&ycirc;\"], [0, \"&Yuml;\"], [0, \"&Zacute;\"], [0, \"&zacute;\"], [0, \"&Zdot;\"], [0, \"&zdot;\"], [0, \"&Zcaron;\"], [0, \"&zcaron;\"], [19, \"&fnof;\"], [34, \"&imped;\"], [63, \"&gacute;\"], [65, \"&jmath;\"], [142, \"&circ;\"], [0, \"&caron;\"], [16, \"&breve;\"], [0, \"&DiacriticalDot;\"], [0, \"&ring;\"], [0, \"&ogon;\"], [0, \"&DiacriticalTilde;\"], [0, \"&dblac;\"], [51, \"&DownBreve;\"], [127, \"&Alpha;\"], [0, \"&Beta;\"], [0, \"&Gamma;\"], [0, \"&Delta;\"], [0, \"&Epsilon;\"], [0, \"&Zeta;\"], [0, \"&Eta;\"], [0, \"&Theta;\"], [0, \"&Iota;\"], [0, \"&Kappa;\"], [0, \"&Lambda;\"], [0, \"&Mu;\"], [0, \"&Nu;\"], [0, \"&Xi;\"], [0, \"&Omicron;\"], [0, \"&Pi;\"], [0, \"&Rho;\"], [1, \"&Sigma;\"], [0, \"&Tau;\"], [0, \"&Upsilon;\"], [0, \"&Phi;\"], [0, \"&Chi;\"], [0, \"&Psi;\"], [0, \"&ohm;\"], [7, \"&alpha;\"], [0, \"&beta;\"], [0, \"&gamma;\"], [0, \"&delta;\"], [0, \"&epsi;\"], [0, \"&zeta;\"], [0, \"&eta;\"], [0, \"&theta;\"], [0, \"&iota;\"], [0, \"&kappa;\"], [0, \"&lambda;\"], [0, \"&mu;\"], [0, \"&nu;\"], [0, \"&xi;\"], [0, \"&omicron;\"], [0, \"&pi;\"], [0, \"&rho;\"], [0, \"&sigmaf;\"], [0, \"&sigma;\"], [0, \"&tau;\"], [0, \"&upsi;\"], [0, \"&phi;\"], [0, \"&chi;\"], [0, \"&psi;\"], [0, \"&omega;\"], [7, \"&thetasym;\"], [0, \"&Upsi;\"], [2, \"&phiv;\"], [0, \"&piv;\"], [5, \"&Gammad;\"], [0, \"&digamma;\"], [18, \"&kappav;\"], [0, \"&rhov;\"], [3, \"&epsiv;\"], [0, \"&backepsilon;\"], [10, \"&IOcy;\"], [0, \"&DJcy;\"], [0, \"&GJcy;\"], [0, \"&Jukcy;\"], [0, \"&DScy;\"], [0, \"&Iukcy;\"], [0, \"&YIcy;\"], [0, \"&Jsercy;\"], [0, \"&LJcy;\"], [0, \"&NJcy;\"], [0, \"&TSHcy;\"], [0, \"&KJcy;\"], [1, \"&Ubrcy;\"], [0, \"&DZcy;\"], [0, \"&Acy;\"], [0, \"&Bcy;\"], [0, \"&Vcy;\"], [0, \"&Gcy;\"], [0, \"&Dcy;\"], [0, \"&IEcy;\"], [0, \"&ZHcy;\"], [0, \"&Zcy;\"], [0, \"&Icy;\"], [0, \"&Jcy;\"], [0, \"&Kcy;\"], [0, \"&Lcy;\"], [0, \"&Mcy;\"], [0, \"&Ncy;\"], [0, \"&Ocy;\"], [0, \"&Pcy;\"], [0, \"&Rcy;\"], [0, \"&Scy;\"], [0, \"&Tcy;\"], [0, \"&Ucy;\"], [0, \"&Fcy;\"], [0, \"&KHcy;\"], [0, \"&TScy;\"], [0, \"&CHcy;\"], [0, \"&SHcy;\"], [0, \"&SHCHcy;\"], [0, \"&HARDcy;\"], [0, \"&Ycy;\"], [0, \"&SOFTcy;\"], [0, \"&Ecy;\"], [0, \"&YUcy;\"], [0, \"&YAcy;\"], [0, \"&acy;\"], [0, \"&bcy;\"], [0, \"&vcy;\"], [0, \"&gcy;\"], [0, \"&dcy;\"], [0, \"&iecy;\"], [0, \"&zhcy;\"], [0, \"&zcy;\"], [0, \"&icy;\"], [0, \"&jcy;\"], [0, \"&kcy;\"], [0, \"&lcy;\"], [0, \"&mcy;\"], [0, \"&ncy;\"], [0, \"&ocy;\"], [0, \"&pcy;\"], [0, \"&rcy;\"], [0, \"&scy;\"], [0, \"&tcy;\"], [0, \"&ucy;\"], [0, \"&fcy;\"], [0, \"&khcy;\"], [0, \"&tscy;\"], [0, \"&chcy;\"], [0, \"&shcy;\"], [0, \"&shchcy;\"], [0, \"&hardcy;\"], [0, \"&ycy;\"], [0, \"&softcy;\"], [0, \"&ecy;\"], [0, \"&yucy;\"], [0, \"&yacy;\"], [1, \"&iocy;\"], [0, \"&djcy;\"], [0, \"&gjcy;\"], [0, \"&jukcy;\"], [0, \"&dscy;\"], [0, \"&iukcy;\"], [0, \"&yicy;\"], [0, \"&jsercy;\"], [0, \"&ljcy;\"], [0, \"&njcy;\"], [0, \"&tshcy;\"], [0, \"&kjcy;\"], [1, \"&ubrcy;\"], [0, \"&dzcy;\"], [7074, \"&ensp;\"], [0, \"&emsp;\"], [0, \"&emsp13;\"], [0, \"&emsp14;\"], [1, \"&numsp;\"], [0, \"&puncsp;\"], [0, \"&ThinSpace;\"], [0, \"&hairsp;\"], [0, \"&NegativeMediumSpace;\"], [0, \"&zwnj;\"], [0, \"&zwj;\"], [0, \"&lrm;\"], [0, \"&rlm;\"], [0, \"&dash;\"], [2, \"&ndash;\"], [0, \"&mdash;\"], [0, \"&horbar;\"], [0, \"&Verbar;\"], [1, \"&lsquo;\"], [0, \"&CloseCurlyQuote;\"], [0, \"&lsquor;\"], [1, \"&ldquo;\"], [0, \"&CloseCurlyDoubleQuote;\"], [0, \"&bdquo;\"], [1, \"&dagger;\"], [0, \"&Dagger;\"], [0, \"&bull;\"], [2, \"&nldr;\"], [0, \"&hellip;\"], [9, \"&permil;\"], [0, \"&pertenk;\"], [0, \"&prime;\"], [0, \"&Prime;\"], [0, \"&tprime;\"], [0, \"&backprime;\"], [3, \"&lsaquo;\"], [0, \"&rsaquo;\"], [3, \"&oline;\"], [2, \"&caret;\"], [1, \"&hybull;\"], [0, \"&frasl;\"], [10, \"&bsemi;\"], [7, \"&qprime;\"], [7, { v: \"&MediumSpace;\", n: 8202, o: \"&ThickSpace;\" }], [0, \"&NoBreak;\"], [0, \"&af;\"], [0, \"&InvisibleTimes;\"], [0, \"&ic;\"], [72, \"&euro;\"], [46, \"&tdot;\"], [0, \"&DotDot;\"], [37, \"&complexes;\"], [2, \"&incare;\"], [4, \"&gscr;\"], [0, \"&hamilt;\"], [0, \"&Hfr;\"], [0, \"&Hopf;\"], [0, \"&planckh;\"], [0, \"&hbar;\"], [0, \"&imagline;\"], [0, \"&Ifr;\"], [0, \"&lagran;\"], [0, \"&ell;\"], [1, \"&naturals;\"], [0, \"&numero;\"], [0, \"&copysr;\"], [0, \"&weierp;\"], [0, \"&Popf;\"], [0, \"&Qopf;\"], [0, \"&realine;\"], [0, \"&real;\"], [0, \"&reals;\"], [0, \"&rx;\"], [3, \"&trade;\"], [1, \"&integers;\"], [2, \"&mho;\"], [0, \"&zeetrf;\"], [0, \"&iiota;\"], [2, \"&bernou;\"], [0, \"&Cayleys;\"], [1, \"&escr;\"], [0, \"&Escr;\"], [0, \"&Fouriertrf;\"], [1, \"&Mellintrf;\"], [0, \"&order;\"], [0, \"&alefsym;\"], [0, \"&beth;\"], [0, \"&gimel;\"], [0, \"&daleth;\"], [12, \"&CapitalDifferentialD;\"], [0, \"&dd;\"], [0, \"&ee;\"], [0, \"&ii;\"], [10, \"&frac13;\"], [0, \"&frac23;\"], [0, \"&frac15;\"], [0, \"&frac25;\"], [0, \"&frac35;\"], [0, \"&frac45;\"], [0, \"&frac16;\"], [0, \"&frac56;\"], [0, \"&frac18;\"], [0, \"&frac38;\"], [0, \"&frac58;\"], [0, \"&frac78;\"], [49, \"&larr;\"], [0, \"&ShortUpArrow;\"], [0, \"&rarr;\"], [0, \"&darr;\"], [0, \"&harr;\"], [0, \"&updownarrow;\"], [0, \"&nwarr;\"], [0, \"&nearr;\"], [0, \"&LowerRightArrow;\"], [0, \"&LowerLeftArrow;\"], [0, \"&nlarr;\"], [0, \"&nrarr;\"], [1, { v: \"&rarrw;\", n: 824, o: \"&nrarrw;\" }], [0, \"&Larr;\"], [0, \"&Uarr;\"], [0, \"&Rarr;\"], [0, \"&Darr;\"], [0, \"&larrtl;\"], [0, \"&rarrtl;\"], [0, \"&LeftTeeArrow;\"], [0, \"&mapstoup;\"], [0, \"&map;\"], [0, \"&DownTeeArrow;\"], [1, \"&hookleftarrow;\"], [0, \"&hookrightarrow;\"], [0, \"&larrlp;\"], [0, \"&looparrowright;\"], [0, \"&harrw;\"], [0, \"&nharr;\"], [1, \"&lsh;\"], [0, \"&rsh;\"], [0, \"&ldsh;\"], [0, \"&rdsh;\"], [1, \"&crarr;\"], [0, \"&cularr;\"], [0, \"&curarr;\"], [2, \"&circlearrowleft;\"], [0, \"&circlearrowright;\"], [0, \"&leftharpoonup;\"], [0, \"&DownLeftVector;\"], [0, \"&RightUpVector;\"], [0, \"&LeftUpVector;\"], [0, \"&rharu;\"], [0, \"&DownRightVector;\"], [0, \"&dharr;\"], [0, \"&dharl;\"], [0, \"&RightArrowLeftArrow;\"], [0, \"&udarr;\"], [0, \"&LeftArrowRightArrow;\"], [0, \"&leftleftarrows;\"], [0, \"&upuparrows;\"], [0, \"&rightrightarrows;\"], [0, \"&ddarr;\"], [0, \"&leftrightharpoons;\"], [0, \"&Equilibrium;\"], [0, \"&nlArr;\"], [0, \"&nhArr;\"], [0, \"&nrArr;\"], [0, \"&DoubleLeftArrow;\"], [0, \"&DoubleUpArrow;\"], [0, \"&DoubleRightArrow;\"], [0, \"&dArr;\"], [0, \"&DoubleLeftRightArrow;\"], [0, \"&DoubleUpDownArrow;\"], [0, \"&nwArr;\"], [0, \"&neArr;\"], [0, \"&seArr;\"], [0, \"&swArr;\"], [0, \"&lAarr;\"], [0, \"&rAarr;\"], [1, \"&zigrarr;\"], [6, \"&larrb;\"], [0, \"&rarrb;\"], [15, \"&DownArrowUpArrow;\"], [7, \"&loarr;\"], [0, \"&roarr;\"], [0, \"&hoarr;\"], [0, \"&forall;\"], [0, \"&comp;\"], [0, { v: \"&part;\", n: 824, o: \"&npart;\" }], [0, \"&exist;\"], [0, \"&nexist;\"], [0, \"&empty;\"], [1, \"&Del;\"], [0, \"&Element;\"], [0, \"&NotElement;\"], [1, \"&ni;\"], [0, \"&notni;\"], [2, \"&prod;\"], [0, \"&coprod;\"], [0, \"&sum;\"], [0, \"&minus;\"], [0, \"&MinusPlus;\"], [0, \"&dotplus;\"], [1, \"&Backslash;\"], [0, \"&lowast;\"], [0, \"&compfn;\"], [1, \"&radic;\"], [2, \"&prop;\"], [0, \"&infin;\"], [0, \"&angrt;\"], [0, { v: \"&ang;\", n: 8402, o: \"&nang;\" }], [0, \"&angmsd;\"], [0, \"&angsph;\"], [0, \"&mid;\"], [0, \"&nmid;\"], [0, \"&DoubleVerticalBar;\"], [0, \"&NotDoubleVerticalBar;\"], [0, \"&and;\"], [0, \"&or;\"], [0, { v: \"&cap;\", n: 65024, o: \"&caps;\" }], [0, { v: \"&cup;\", n: 65024, o: \"&cups;\" }], [0, \"&int;\"], [0, \"&Int;\"], [0, \"&iiint;\"], [0, \"&conint;\"], [0, \"&Conint;\"], [0, \"&Cconint;\"], [0, \"&cwint;\"], [0, \"&ClockwiseContourIntegral;\"], [0, \"&awconint;\"], [0, \"&there4;\"], [0, \"&becaus;\"], [0, \"&ratio;\"], [0, \"&Colon;\"], [0, \"&dotminus;\"], [1, \"&mDDot;\"], [0, \"&homtht;\"], [0, { v: \"&sim;\", n: 8402, o: \"&nvsim;\" }], [0, { v: \"&backsim;\", n: 817, o: \"&race;\" }], [0, { v: \"&ac;\", n: 819, o: \"&acE;\" }], [0, \"&acd;\"], [0, \"&VerticalTilde;\"], [0, \"&NotTilde;\"], [0, { v: \"&eqsim;\", n: 824, o: \"&nesim;\" }], [0, \"&sime;\"], [0, \"&NotTildeEqual;\"], [0, \"&cong;\"], [0, \"&simne;\"], [0, \"&ncong;\"], [0, \"&ap;\"], [0, \"&nap;\"], [0, \"&ape;\"], [0, { v: \"&apid;\", n: 824, o: \"&napid;\" }], [0, \"&backcong;\"], [0, { v: \"&asympeq;\", n: 8402, o: \"&nvap;\" }], [0, { v: \"&bump;\", n: 824, o: \"&nbump;\" }], [0, { v: \"&bumpe;\", n: 824, o: \"&nbumpe;\" }], [0, { v: \"&doteq;\", n: 824, o: \"&nedot;\" }], [0, \"&doteqdot;\"], [0, \"&efDot;\"], [0, \"&erDot;\"], [0, \"&Assign;\"], [0, \"&ecolon;\"], [0, \"&ecir;\"], [0, \"&circeq;\"], [1, \"&wedgeq;\"], [0, \"&veeeq;\"], [1, \"&triangleq;\"], [2, \"&equest;\"], [0, \"&ne;\"], [0, { v: \"&Congruent;\", n: 8421, o: \"&bnequiv;\" }], [0, \"&nequiv;\"], [1, { v: \"&le;\", n: 8402, o: \"&nvle;\" }], [0, { v: \"&ge;\", n: 8402, o: \"&nvge;\" }], [0, { v: \"&lE;\", n: 824, o: \"&nlE;\" }], [0, { v: \"&gE;\", n: 824, o: \"&ngE;\" }], [0, { v: \"&lnE;\", n: 65024, o: \"&lvertneqq;\" }], [0, { v: \"&gnE;\", n: 65024, o: \"&gvertneqq;\" }], [0, { v: \"&ll;\", n: /* #__PURE__ */ new Map(/* #__PURE__ */ restoreDiff([[824, \"&nLtv;\"], [7577, \"&nLt;\"]])) }], [0, { v: \"&gg;\", n: /* #__PURE__ */ new Map(/* #__PURE__ */ restoreDiff([[824, \"&nGtv;\"], [7577, \"&nGt;\"]])) }], [0, \"&between;\"], [0, \"&NotCupCap;\"], [0, \"&nless;\"], [0, \"&ngt;\"], [0, \"&nle;\"], [0, \"&nge;\"], [0, \"&lesssim;\"], [0, \"&GreaterTilde;\"], [0, \"&nlsim;\"], [0, \"&ngsim;\"], [0, \"&LessGreater;\"], [0, \"&gl;\"], [0, \"&NotLessGreater;\"], [0, \"&NotGreaterLess;\"], [0, \"&pr;\"], [0, \"&sc;\"], [0, \"&prcue;\"], [0, \"&sccue;\"], [0, \"&PrecedesTilde;\"], [0, { v: \"&scsim;\", n: 824, o: \"&NotSucceedsTilde;\" }], [0, \"&NotPrecedes;\"], [0, \"&NotSucceeds;\"], [0, { v: \"&sub;\", n: 8402, o: \"&NotSubset;\" }], [0, { v: \"&sup;\", n: 8402, o: \"&NotSuperset;\" }], [0, \"&nsub;\"], [0, \"&nsup;\"], [0, \"&sube;\"], [0, \"&supe;\"], [0, \"&NotSubsetEqual;\"], [0, \"&NotSupersetEqual;\"], [0, { v: \"&subne;\", n: 65024, o: \"&varsubsetneq;\" }], [0, { v: \"&supne;\", n: 65024, o: \"&varsupsetneq;\" }], [1, \"&cupdot;\"], [0, \"&UnionPlus;\"], [0, { v: \"&sqsub;\", n: 824, o: \"&NotSquareSubset;\" }], [0, { v: \"&sqsup;\", n: 824, o: \"&NotSquareSuperset;\" }], [0, \"&sqsube;\"], [0, \"&sqsupe;\"], [0, { v: \"&sqcap;\", n: 65024, o: \"&sqcaps;\" }], [0, { v: \"&sqcup;\", n: 65024, o: \"&sqcups;\" }], [0, \"&CirclePlus;\"], [0, \"&CircleMinus;\"], [0, \"&CircleTimes;\"], [0, \"&osol;\"], [0, \"&CircleDot;\"], [0, \"&circledcirc;\"], [0, \"&circledast;\"], [1, \"&circleddash;\"], [0, \"&boxplus;\"], [0, \"&boxminus;\"], [0, \"&boxtimes;\"], [0, \"&dotsquare;\"], [0, \"&RightTee;\"], [0, \"&dashv;\"], [0, \"&DownTee;\"], [0, \"&bot;\"], [1, \"&models;\"], [0, \"&DoubleRightTee;\"], [0, \"&Vdash;\"], [0, \"&Vvdash;\"], [0, \"&VDash;\"], [0, \"&nvdash;\"], [0, \"&nvDash;\"], [0, \"&nVdash;\"], [0, \"&nVDash;\"], [0, \"&prurel;\"], [1, \"&LeftTriangle;\"], [0, \"&RightTriangle;\"], [0, { v: \"&LeftTriangleEqual;\", n: 8402, o: \"&nvltrie;\" }], [0, { v: \"&RightTriangleEqual;\", n: 8402, o: \"&nvrtrie;\" }], [0, \"&origof;\"], [0, \"&imof;\"], [0, \"&multimap;\"], [0, \"&hercon;\"], [0, \"&intcal;\"], [0, \"&veebar;\"], [1, \"&barvee;\"], [0, \"&angrtvb;\"], [0, \"&lrtri;\"], [0, \"&bigwedge;\"], [0, \"&bigvee;\"], [0, \"&bigcap;\"], [0, \"&bigcup;\"], [0, \"&diam;\"], [0, \"&sdot;\"], [0, \"&sstarf;\"], [0, \"&divideontimes;\"], [0, \"&bowtie;\"], [0, \"&ltimes;\"], [0, \"&rtimes;\"], [0, \"&leftthreetimes;\"], [0, \"&rightthreetimes;\"], [0, \"&backsimeq;\"], [0, \"&curlyvee;\"], [0, \"&curlywedge;\"], [0, \"&Sub;\"], [0, \"&Sup;\"], [0, \"&Cap;\"], [0, \"&Cup;\"], [0, \"&fork;\"], [0, \"&epar;\"], [0, \"&lessdot;\"], [0, \"&gtdot;\"], [0, { v: \"&Ll;\", n: 824, o: \"&nLl;\" }], [0, { v: \"&Gg;\", n: 824, o: \"&nGg;\" }], [0, { v: \"&leg;\", n: 65024, o: \"&lesg;\" }], [0, { v: \"&gel;\", n: 65024, o: \"&gesl;\" }], [2, \"&cuepr;\"], [0, \"&cuesc;\"], [0, \"&NotPrecedesSlantEqual;\"], [0, \"&NotSucceedsSlantEqual;\"], [0, \"&NotSquareSubsetEqual;\"], [0, \"&NotSquareSupersetEqual;\"], [2, \"&lnsim;\"], [0, \"&gnsim;\"], [0, \"&precnsim;\"], [0, \"&scnsim;\"], [0, \"&nltri;\"], [0, \"&NotRightTriangle;\"], [0, \"&nltrie;\"], [0, \"&NotRightTriangleEqual;\"], [0, \"&vellip;\"], [0, \"&ctdot;\"], [0, \"&utdot;\"], [0, \"&dtdot;\"], [0, \"&disin;\"], [0, \"&isinsv;\"], [0, \"&isins;\"], [0, { v: \"&isindot;\", n: 824, o: \"&notindot;\" }], [0, \"&notinvc;\"], [0, \"&notinvb;\"], [1, { v: \"&isinE;\", n: 824, o: \"&notinE;\" }], [0, \"&nisd;\"], [0, \"&xnis;\"], [0, \"&nis;\"], [0, \"&notnivc;\"], [0, \"&notnivb;\"], [6, \"&barwed;\"], [0, \"&Barwed;\"], [1, \"&lceil;\"], [0, \"&rceil;\"], [0, \"&LeftFloor;\"], [0, \"&rfloor;\"], [0, \"&drcrop;\"], [0, \"&dlcrop;\"], [0, \"&urcrop;\"], [0, \"&ulcrop;\"], [0, \"&bnot;\"], [1, \"&profline;\"], [0, \"&profsurf;\"], [1, \"&telrec;\"], [0, \"&target;\"], [5, \"&ulcorn;\"], [0, \"&urcorn;\"], [0, \"&dlcorn;\"], [0, \"&drcorn;\"], [2, \"&frown;\"], [0, \"&smile;\"], [9, \"&cylcty;\"], [0, \"&profalar;\"], [7, \"&topbot;\"], [6, \"&ovbar;\"], [1, \"&solbar;\"], [60, \"&angzarr;\"], [51, \"&lmoustache;\"], [0, \"&rmoustache;\"], [2, \"&OverBracket;\"], [0, \"&bbrk;\"], [0, \"&bbrktbrk;\"], [37, \"&OverParenthesis;\"], [0, \"&UnderParenthesis;\"], [0, \"&OverBrace;\"], [0, \"&UnderBrace;\"], [2, \"&trpezium;\"], [4, \"&elinters;\"], [59, \"&blank;\"], [164, \"&circledS;\"], [55, \"&boxh;\"], [1, \"&boxv;\"], [9, \"&boxdr;\"], [3, \"&boxdl;\"], [3, \"&boxur;\"], [3, \"&boxul;\"], [3, \"&boxvr;\"], [7, \"&boxvl;\"], [7, \"&boxhd;\"], [7, \"&boxhu;\"], [7, \"&boxvh;\"], [19, \"&boxH;\"], [0, \"&boxV;\"], [0, \"&boxdR;\"], [0, \"&boxDr;\"], [0, \"&boxDR;\"], [0, \"&boxdL;\"], [0, \"&boxDl;\"], [0, \"&boxDL;\"], [0, \"&boxuR;\"], [0, \"&boxUr;\"], [0, \"&boxUR;\"], [0, \"&boxuL;\"], [0, \"&boxUl;\"], [0, \"&boxUL;\"], [0, \"&boxvR;\"], [0, \"&boxVr;\"], [0, \"&boxVR;\"], [0, \"&boxvL;\"], [0, \"&boxVl;\"], [0, \"&boxVL;\"], [0, \"&boxHd;\"], [0, \"&boxhD;\"], [0, \"&boxHD;\"], [0, \"&boxHu;\"], [0, \"&boxhU;\"], [0, \"&boxHU;\"], [0, \"&boxvH;\"], [0, \"&boxVh;\"], [0, \"&boxVH;\"], [19, \"&uhblk;\"], [3, \"&lhblk;\"], [3, \"&block;\"], [8, \"&blk14;\"], [0, \"&blk12;\"], [0, \"&blk34;\"], [13, \"&square;\"], [8, \"&blacksquare;\"], [0, \"&EmptyVerySmallSquare;\"], [1, \"&rect;\"], [0, \"&marker;\"], [2, \"&fltns;\"], [1, \"&bigtriangleup;\"], [0, \"&blacktriangle;\"], [0, \"&triangle;\"], [2, \"&blacktriangleright;\"], [0, \"&rtri;\"], [3, \"&bigtriangledown;\"], [0, \"&blacktriangledown;\"], [0, \"&dtri;\"], [2, \"&blacktriangleleft;\"], [0, \"&ltri;\"], [6, \"&loz;\"], [0, \"&cir;\"], [32, \"&tridot;\"], [2, \"&bigcirc;\"], [8, \"&ultri;\"], [0, \"&urtri;\"], [0, \"&lltri;\"], [0, \"&EmptySmallSquare;\"], [0, \"&FilledSmallSquare;\"], [8, \"&bigstar;\"], [0, \"&star;\"], [7, \"&phone;\"], [49, \"&female;\"], [1, \"&male;\"], [29, \"&spades;\"], [2, \"&clubs;\"], [1, \"&hearts;\"], [0, \"&diamondsuit;\"], [3, \"&sung;\"], [2, \"&flat;\"], [0, \"&natural;\"], [0, \"&sharp;\"], [163, \"&check;\"], [3, \"&cross;\"], [8, \"&malt;\"], [21, \"&sext;\"], [33, \"&VerticalSeparator;\"], [25, \"&lbbrk;\"], [0, \"&rbbrk;\"], [84, \"&bsolhsub;\"], [0, \"&suphsol;\"], [28, \"&LeftDoubleBracket;\"], [0, \"&RightDoubleBracket;\"], [0, \"&lang;\"], [0, \"&rang;\"], [0, \"&Lang;\"], [0, \"&Rang;\"], [0, \"&loang;\"], [0, \"&roang;\"], [7, \"&longleftarrow;\"], [0, \"&longrightarrow;\"], [0, \"&longleftrightarrow;\"], [0, \"&DoubleLongLeftArrow;\"], [0, \"&DoubleLongRightArrow;\"], [0, \"&DoubleLongLeftRightArrow;\"], [1, \"&longmapsto;\"], [2, \"&dzigrarr;\"], [258, \"&nvlArr;\"], [0, \"&nvrArr;\"], [0, \"&nvHarr;\"], [0, \"&Map;\"], [6, \"&lbarr;\"], [0, \"&bkarow;\"], [0, \"&lBarr;\"], [0, \"&dbkarow;\"], [0, \"&drbkarow;\"], [0, \"&DDotrahd;\"], [0, \"&UpArrowBar;\"], [0, \"&DownArrowBar;\"], [2, \"&Rarrtl;\"], [2, \"&latail;\"], [0, \"&ratail;\"], [0, \"&lAtail;\"], [0, \"&rAtail;\"], [0, \"&larrfs;\"], [0, \"&rarrfs;\"], [0, \"&larrbfs;\"], [0, \"&rarrbfs;\"], [2, \"&nwarhk;\"], [0, \"&nearhk;\"], [0, \"&hksearow;\"], [0, \"&hkswarow;\"], [0, \"&nwnear;\"], [0, \"&nesear;\"], [0, \"&seswar;\"], [0, \"&swnwar;\"], [8, { v: \"&rarrc;\", n: 824, o: \"&nrarrc;\" }], [1, \"&cudarrr;\"], [0, \"&ldca;\"], [0, \"&rdca;\"], [0, \"&cudarrl;\"], [0, \"&larrpl;\"], [2, \"&curarrm;\"], [0, \"&cularrp;\"], [7, \"&rarrpl;\"], [2, \"&harrcir;\"], [0, \"&Uarrocir;\"], [0, \"&lurdshar;\"], [0, \"&ldrushar;\"], [2, \"&LeftRightVector;\"], [0, \"&RightUpDownVector;\"], [0, \"&DownLeftRightVector;\"], [0, \"&LeftUpDownVector;\"], [0, \"&LeftVectorBar;\"], [0, \"&RightVectorBar;\"], [0, \"&RightUpVectorBar;\"], [0, \"&RightDownVectorBar;\"], [0, \"&DownLeftVectorBar;\"], [0, \"&DownRightVectorBar;\"], [0, \"&LeftUpVectorBar;\"], [0, \"&LeftDownVectorBar;\"], [0, \"&LeftTeeVector;\"], [0, \"&RightTeeVector;\"], [0, \"&RightUpTeeVector;\"], [0, \"&RightDownTeeVector;\"], [0, \"&DownLeftTeeVector;\"], [0, \"&DownRightTeeVector;\"], [0, \"&LeftUpTeeVector;\"], [0, \"&LeftDownTeeVector;\"], [0, \"&lHar;\"], [0, \"&uHar;\"], [0, \"&rHar;\"], [0, \"&dHar;\"], [0, \"&luruhar;\"], [0, \"&ldrdhar;\"], [0, \"&ruluhar;\"], [0, \"&rdldhar;\"], [0, \"&lharul;\"], [0, \"&llhard;\"], [0, \"&rharul;\"], [0, \"&lrhard;\"], [0, \"&udhar;\"], [0, \"&duhar;\"], [0, \"&RoundImplies;\"], [0, \"&erarr;\"], [0, \"&simrarr;\"], [0, \"&larrsim;\"], [0, \"&rarrsim;\"], [0, \"&rarrap;\"], [0, \"&ltlarr;\"], [1, \"&gtrarr;\"], [0, \"&subrarr;\"], [1, \"&suplarr;\"], [0, \"&lfisht;\"], [0, \"&rfisht;\"], [0, \"&ufisht;\"], [0, \"&dfisht;\"], [5, \"&lopar;\"], [0, \"&ropar;\"], [4, \"&lbrke;\"], [0, \"&rbrke;\"], [0, \"&lbrkslu;\"], [0, \"&rbrksld;\"], [0, \"&lbrksld;\"], [0, \"&rbrkslu;\"], [0, \"&langd;\"], [0, \"&rangd;\"], [0, \"&lparlt;\"], [0, \"&rpargt;\"], [0, \"&gtlPar;\"], [0, \"&ltrPar;\"], [3, \"&vzigzag;\"], [1, \"&vangrt;\"], [0, \"&angrtvbd;\"], [6, \"&ange;\"], [0, \"&range;\"], [0, \"&dwangle;\"], [0, \"&uwangle;\"], [0, \"&angmsdaa;\"], [0, \"&angmsdab;\"], [0, \"&angmsdac;\"], [0, \"&angmsdad;\"], [0, \"&angmsdae;\"], [0, \"&angmsdaf;\"], [0, \"&angmsdag;\"], [0, \"&angmsdah;\"], [0, \"&bemptyv;\"], [0, \"&demptyv;\"], [0, \"&cemptyv;\"], [0, \"&raemptyv;\"], [0, \"&laemptyv;\"], [0, \"&ohbar;\"], [0, \"&omid;\"], [0, \"&opar;\"], [1, \"&operp;\"], [1, \"&olcross;\"], [0, \"&odsold;\"], [1, \"&olcir;\"], [0, \"&ofcir;\"], [0, \"&olt;\"], [0, \"&ogt;\"], [0, \"&cirscir;\"], [0, \"&cirE;\"], [0, \"&solb;\"], [0, \"&bsolb;\"], [3, \"&boxbox;\"], [3, \"&trisb;\"], [0, \"&rtriltri;\"], [0, { v: \"&LeftTriangleBar;\", n: 824, o: \"&NotLeftTriangleBar;\" }], [0, { v: \"&RightTriangleBar;\", n: 824, o: \"&NotRightTriangleBar;\" }], [11, \"&iinfin;\"], [0, \"&infintie;\"], [0, \"&nvinfin;\"], [4, \"&eparsl;\"], [0, \"&smeparsl;\"], [0, \"&eqvparsl;\"], [5, \"&blacklozenge;\"], [8, \"&RuleDelayed;\"], [1, \"&dsol;\"], [9, \"&bigodot;\"], [0, \"&bigoplus;\"], [0, \"&bigotimes;\"], [1, \"&biguplus;\"], [1, \"&bigsqcup;\"], [5, \"&iiiint;\"], [0, \"&fpartint;\"], [2, \"&cirfnint;\"], [0, \"&awint;\"], [0, \"&rppolint;\"], [0, \"&scpolint;\"], [0, \"&npolint;\"], [0, \"&pointint;\"], [0, \"&quatint;\"], [0, \"&intlarhk;\"], [10, \"&pluscir;\"], [0, \"&plusacir;\"], [0, \"&simplus;\"], [0, \"&plusdu;\"], [0, \"&plussim;\"], [0, \"&plustwo;\"], [1, \"&mcomma;\"], [0, \"&minusdu;\"], [2, \"&loplus;\"], [0, \"&roplus;\"], [0, \"&Cross;\"], [0, \"&timesd;\"], [0, \"&timesbar;\"], [1, \"&smashp;\"], [0, \"&lotimes;\"], [0, \"&rotimes;\"], [0, \"&otimesas;\"], [0, \"&Otimes;\"], [0, \"&odiv;\"], [0, \"&triplus;\"], [0, \"&triminus;\"], [0, \"&tritime;\"], [0, \"&intprod;\"], [2, \"&amalg;\"], [0, \"&capdot;\"], [1, \"&ncup;\"], [0, \"&ncap;\"], [0, \"&capand;\"], [0, \"&cupor;\"], [0, \"&cupcap;\"], [0, \"&capcup;\"], [0, \"&cupbrcap;\"], [0, \"&capbrcup;\"], [0, \"&cupcup;\"], [0, \"&capcap;\"], [0, \"&ccups;\"], [0, \"&ccaps;\"], [2, \"&ccupssm;\"], [2, \"&And;\"], [0, \"&Or;\"], [0, \"&andand;\"], [0, \"&oror;\"], [0, \"&orslope;\"], [0, \"&andslope;\"], [1, \"&andv;\"], [0, \"&orv;\"], [0, \"&andd;\"], [0, \"&ord;\"], [1, \"&wedbar;\"], [6, \"&sdote;\"], [3, \"&simdot;\"], [2, { v: \"&congdot;\", n: 824, o: \"&ncongdot;\" }], [0, \"&easter;\"], [0, \"&apacir;\"], [0, { v: \"&apE;\", n: 824, o: \"&napE;\" }], [0, \"&eplus;\"], [0, \"&pluse;\"], [0, \"&Esim;\"], [0, \"&Colone;\"], [0, \"&Equal;\"], [1, \"&ddotseq;\"], [0, \"&equivDD;\"], [0, \"&ltcir;\"], [0, \"&gtcir;\"], [0, \"&ltquest;\"], [0, \"&gtquest;\"], [0, { v: \"&leqslant;\", n: 824, o: \"&nleqslant;\" }], [0, { v: \"&geqslant;\", n: 824, o: \"&ngeqslant;\" }], [0, \"&lesdot;\"], [0, \"&gesdot;\"], [0, \"&lesdoto;\"], [0, \"&gesdoto;\"], [0, \"&lesdotor;\"], [0, \"&gesdotol;\"], [0, \"&lap;\"], [0, \"&gap;\"], [0, \"&lne;\"], [0, \"&gne;\"], [0, \"&lnap;\"], [0, \"&gnap;\"], [0, \"&lEg;\"], [0, \"&gEl;\"], [0, \"&lsime;\"], [0, \"&gsime;\"], [0, \"&lsimg;\"], [0, \"&gsiml;\"], [0, \"&lgE;\"], [0, \"&glE;\"], [0, \"&lesges;\"], [0, \"&gesles;\"], [0, \"&els;\"], [0, \"&egs;\"], [0, \"&elsdot;\"], [0, \"&egsdot;\"], [0, \"&el;\"], [0, \"&eg;\"], [2, \"&siml;\"], [0, \"&simg;\"], [0, \"&simlE;\"], [0, \"&simgE;\"], [0, { v: \"&LessLess;\", n: 824, o: \"&NotNestedLessLess;\" }], [0, { v: \"&GreaterGreater;\", n: 824, o: \"&NotNestedGreaterGreater;\" }], [1, \"&glj;\"], [0, \"&gla;\"], [0, \"&ltcc;\"], [0, \"&gtcc;\"], [0, \"&lescc;\"], [0, \"&gescc;\"], [0, \"&smt;\"], [0, \"&lat;\"], [0, { v: \"&smte;\", n: 65024, o: \"&smtes;\" }], [0, { v: \"&late;\", n: 65024, o: \"&lates;\" }], [0, \"&bumpE;\"], [0, { v: \"&PrecedesEqual;\", n: 824, o: \"&NotPrecedesEqual;\" }], [0, { v: \"&sce;\", n: 824, o: \"&NotSucceedsEqual;\" }], [2, \"&prE;\"], [0, \"&scE;\"], [0, \"&precneqq;\"], [0, \"&scnE;\"], [0, \"&prap;\"], [0, \"&scap;\"], [0, \"&precnapprox;\"], [0, \"&scnap;\"], [0, \"&Pr;\"], [0, \"&Sc;\"], [0, \"&subdot;\"], [0, \"&supdot;\"], [0, \"&subplus;\"], [0, \"&supplus;\"], [0, \"&submult;\"], [0, \"&supmult;\"], [0, \"&subedot;\"], [0, \"&supedot;\"], [0, { v: \"&subE;\", n: 824, o: \"&nsubE;\" }], [0, { v: \"&supE;\", n: 824, o: \"&nsupE;\" }], [0, \"&subsim;\"], [0, \"&supsim;\"], [2, { v: \"&subnE;\", n: 65024, o: \"&varsubsetneqq;\" }], [0, { v: \"&supnE;\", n: 65024, o: \"&varsupsetneqq;\" }], [2, \"&csub;\"], [0, \"&csup;\"], [0, \"&csube;\"], [0, \"&csupe;\"], [0, \"&subsup;\"], [0, \"&supsub;\"], [0, \"&subsub;\"], [0, \"&supsup;\"], [0, \"&suphsub;\"], [0, \"&supdsub;\"], [0, \"&forkv;\"], [0, \"&topfork;\"], [0, \"&mlcp;\"], [8, \"&Dashv;\"], [1, \"&Vdashl;\"], [0, \"&Barv;\"], [0, \"&vBar;\"], [0, \"&vBarv;\"], [1, \"&Vbar;\"], [0, \"&Not;\"], [0, \"&bNot;\"], [0, \"&rnmid;\"], [0, \"&cirmid;\"], [0, \"&midcir;\"], [0, \"&topcir;\"], [0, \"&nhpar;\"], [0, \"&parsim;\"], [9, { v: \"&parsl;\", n: 8421, o: \"&nparsl;\" }], [44343, { n: /* #__PURE__ */ new Map(/* #__PURE__ */ restoreDiff([[56476, \"&Ascr;\"], [1, \"&Cscr;\"], [0, \"&Dscr;\"], [2, \"&Gscr;\"], [2, \"&Jscr;\"], [0, \"&Kscr;\"], [2, \"&Nscr;\"], [0, \"&Oscr;\"], [0, \"&Pscr;\"], [0, \"&Qscr;\"], [1, \"&Sscr;\"], [0, \"&Tscr;\"], [0, \"&Uscr;\"], [0, \"&Vscr;\"], [0, \"&Wscr;\"], [0, \"&Xscr;\"], [0, \"&Yscr;\"], [0, \"&Zscr;\"], [0, \"&ascr;\"], [0, \"&bscr;\"], [0, \"&cscr;\"], [0, \"&dscr;\"], [1, \"&fscr;\"], [1, \"&hscr;\"], [0, \"&iscr;\"], [0, \"&jscr;\"], [0, \"&kscr;\"], [0, \"&lscr;\"], [0, \"&mscr;\"], [0, \"&nscr;\"], [1, \"&pscr;\"], [0, \"&qscr;\"], [0, \"&rscr;\"], [0, \"&sscr;\"], [0, \"&tscr;\"], [0, \"&uscr;\"], [0, \"&vscr;\"], [0, \"&wscr;\"], [0, \"&xscr;\"], [0, \"&yscr;\"], [0, \"&zscr;\"], [52, \"&Afr;\"], [0, \"&Bfr;\"], [1, \"&Dfr;\"], [0, \"&Efr;\"], [0, \"&Ffr;\"], [0, \"&Gfr;\"], [2, \"&Jfr;\"], [0, \"&Kfr;\"], [0, \"&Lfr;\"], [0, \"&Mfr;\"], [0, \"&Nfr;\"], [0, \"&Ofr;\"], [0, \"&Pfr;\"], [0, \"&Qfr;\"], [1, \"&Sfr;\"], [0, \"&Tfr;\"], [0, \"&Ufr;\"], [0, \"&Vfr;\"], [0, \"&Wfr;\"], [0, \"&Xfr;\"], [0, \"&Yfr;\"], [1, \"&afr;\"], [0, \"&bfr;\"], [0, \"&cfr;\"], [0, \"&dfr;\"], [0, \"&efr;\"], [0, \"&ffr;\"], [0, \"&gfr;\"], [0, \"&hfr;\"], [0, \"&ifr;\"], [0, \"&jfr;\"], [0, \"&kfr;\"], [0, \"&lfr;\"], [0, \"&mfr;\"], [0, \"&nfr;\"], [0, \"&ofr;\"], [0, \"&pfr;\"], [0, \"&qfr;\"], [0, \"&rfr;\"], [0, \"&sfr;\"], [0, \"&tfr;\"], [0, \"&ufr;\"], [0, \"&vfr;\"], [0, \"&wfr;\"], [0, \"&xfr;\"], [0, \"&yfr;\"], [0, \"&zfr;\"], [0, \"&Aopf;\"], [0, \"&Bopf;\"], [1, \"&Dopf;\"], [0, \"&Eopf;\"], [0, \"&Fopf;\"], [0, \"&Gopf;\"], [1, \"&Iopf;\"], [0, \"&Jopf;\"], [0, \"&Kopf;\"], [0, \"&Lopf;\"], [0, \"&Mopf;\"], [1, \"&Oopf;\"], [3, \"&Sopf;\"], [0, \"&Topf;\"], [0, \"&Uopf;\"], [0, \"&Vopf;\"], [0, \"&Wopf;\"], [0, \"&Xopf;\"], [0, \"&Yopf;\"], [1, \"&aopf;\"], [0, \"&bopf;\"], [0, \"&copf;\"], [0, \"&dopf;\"], [0, \"&eopf;\"], [0, \"&fopf;\"], [0, \"&gopf;\"], [0, \"&hopf;\"], [0, \"&iopf;\"], [0, \"&jopf;\"], [0, \"&kopf;\"], [0, \"&lopf;\"], [0, \"&mopf;\"], [0, \"&nopf;\"], [0, \"&oopf;\"], [0, \"&popf;\"], [0, \"&qopf;\"], [0, \"&ropf;\"], [0, \"&sopf;\"], [0, \"&topf;\"], [0, \"&uopf;\"], [0, \"&vopf;\"], [0, \"&wopf;\"], [0, \"&xopf;\"], [0, \"&yopf;\"], [0, \"&zopf;\"]])) }], [8906, \"&fflig;\"], [0, \"&filig;\"], [0, \"&fllig;\"], [0, \"&ffilig;\"], [0, \"&ffllig;\"]]));\n//# sourceMappingURL=encode-html.js.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/entities/src/index.d.ts",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { DecodingMode } from \"./decode\";\n/** The level of entities to support. */\nexport declare enum EntityLevel {\n    /** Support only XML entities. */\n    XML = 0,\n    /** Support HTML entities, which are a superset of XML entities. */\n    HTML = 1\n}\nexport declare enum EncodingMode {\n    /**\n     * The output is UTF-8 encoded. Only characters that need escaping within\n     * XML will be escaped.\n     */\n    UTF8 = 0,\n    /**\n     * The output consists only of ASCII characters. Characters that need\n     * escaping within HTML, and characters that aren't ASCII characters will\n     * be escaped.\n     */\n    ASCII = 1,\n    /**\n     * Encode all characters that have an equivalent entity, as well as all\n     * characters that are not ASCII characters.\n     */\n    Extensive = 2,\n    /**\n     * Encode all characters that have to be escaped in HTML attributes,\n     * following {@link https://html.spec.whatwg.org/multipage/parsing.html#escapingString}.\n     */\n    Attribute = 3,\n    /**\n     * Encode all characters that have to be escaped in HTML text,\n     * following {@link https://html.spec.whatwg.org/multipage/parsing.html#escapingString}.\n     */\n    Text = 4\n}\nexport interface DecodingOptions {\n    /**\n     * The level of entities to support.\n     * @default {@link EntityLevel.XML}\n     */\n    level?: EntityLevel;\n    /**\n     * Decoding mode. If `Legacy`, will support legacy entities not terminated\n     * with a semicolon (`;`).\n     *\n     * Always `Strict` for XML. For HTML, set this to `true` if you are parsing\n     * an attribute value.\n     *\n     * The deprecated `decodeStrict` function defaults this to `Strict`.\n     *\n     * @default {@link DecodingMode.Legacy}\n     */\n    mode?: DecodingMode | undefined;\n}\n/**\n * Decodes a string with entities.\n *\n * @param input String to decode.\n * @param options Decoding options.\n */\nexport declare function decode(input: string, options?: DecodingOptions | EntityLevel): string;\n/**\n * Decodes a string with entities. Does not allow missing trailing semicolons for entities.\n *\n * @param input String to decode.\n * @param options Decoding options.\n * @deprecated Use `decode` with the `mode` set to `Strict`.\n */\nexport declare function decodeStrict(input: string, options?: DecodingOptions | EntityLevel): string;\n/**\n * Options for `encode`.\n */\nexport interface EncodingOptions {\n    /**\n     * The level of entities to support.\n     * @default {@link EntityLevel.XML}\n     */\n    level?: EntityLevel;\n    /**\n     * Output format.\n     * @default {@link EncodingMode.Extensive}\n     */\n    mode?: EncodingMode;\n}\n/**\n * Encodes a string with entities.\n *\n * @param input String to encode.\n * @param options Encoding options.\n */\nexport declare function encode(input: string, options?: EncodingOptions | EntityLevel): string;\nexport { encodeXML, escape, escapeUTF8, escapeAttribute, escapeText, } from \"./escape.js\";\nexport { encodeHTML, encodeNonAsciiHTML, encodeHTML as encodeHTML4, encodeHTML as encodeHTML5, } from \"./encode.js\";\nexport { EntityDecoder, DecodingMode, decodeXML, decodeHTML, decodeHTMLStrict, decodeHTMLAttribute, decodeHTML as decodeHTML4, decodeHTML as decodeHTML5, decodeHTMLStrict as decodeHTML4Strict, decodeHTMLStrict as decodeHTML5Strict, decodeXML as decodeXMLStrict, } from \"./decode.js\";\n//# sourceMappingURL=index.d.ts.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/entities/src/index.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { decodeXML, decodeHTML, DecodingMode } from \"./decode\";\nimport { encodeHTML, encodeNonAsciiHTML } from \"./encode\";\nimport { encodeXML, escapeUTF8, escapeAttribute, escapeText } from \"./escape\";\n/** The level of entities to support. */\nexport var EntityLevel;\n(function (EntityLevel) {\n    /** Support only XML entities. */\n    EntityLevel[EntityLevel[\"XML\"] = 0] = \"XML\";\n    /** Support HTML entities, which are a superset of XML entities. */\n    EntityLevel[EntityLevel[\"HTML\"] = 1] = \"HTML\";\n})(EntityLevel || (EntityLevel = {}));\nexport var EncodingMode;\n(function (EncodingMode) {\n    /**\n     * The output is UTF-8 encoded. Only characters that need escaping within\n     * XML will be escaped.\n     */\n    EncodingMode[EncodingMode[\"UTF8\"] = 0] = \"UTF8\";\n    /**\n     * The output consists only of ASCII characters. Characters that need\n     * escaping within HTML, and characters that aren't ASCII characters will\n     * be escaped.\n     */\n    EncodingMode[EncodingMode[\"ASCII\"] = 1] = \"ASCII\";\n    /**\n     * Encode all characters that have an equivalent entity, as well as all\n     * characters that are not ASCII characters.\n     */\n    EncodingMode[EncodingMode[\"Extensive\"] = 2] = \"Extensive\";\n    /**\n     * Encode all characters that have to be escaped in HTML attributes,\n     * following {@link https://html.spec.whatwg.org/multipage/parsing.html#escapingString}.\n     */\n    EncodingMode[EncodingMode[\"Attribute\"] = 3] = \"Attribute\";\n    /**\n     * Encode all characters that have to be escaped in HTML text,\n     * following {@link https://html.spec.whatwg.org/multipage/parsing.html#escapingString}.\n     */\n    EncodingMode[EncodingMode[\"Text\"] = 4] = \"Text\";\n})(EncodingMode || (EncodingMode = {}));\n/**\n * Decodes a string with entities.\n *\n * @param input String to decode.\n * @param options Decoding options.\n */\nexport function decode(input, options = EntityLevel.XML) {\n    const level = typeof options === \"number\" ? options : options.level;\n    if (level === EntityLevel.HTML) {\n        const mode = typeof options === \"object\" ? options.mode : undefined;\n        return decodeHTML(input, mode);\n    }\n    return decodeXML(input);\n}\n/**\n * Decodes a string with entities. Does not allow missing trailing semicolons for entities.\n *\n * @param input String to decode.\n * @param options Decoding options.\n * @deprecated Use `decode` with the `mode` set to `Strict`.\n */\nexport function decodeStrict(input, options = EntityLevel.XML) {\n    var _a;\n    const normalizedOptions = typeof options === \"number\" ? { level: options } : options;\n    (_a = normalizedOptions.mode) !== null && _a !== void 0 ? _a : (normalizedOptions.mode = DecodingMode.Strict);\n    return decode(input, normalizedOptions);\n}\n/**\n * Encodes a string with entities.\n *\n * @param input String to encode.\n * @param options Encoding options.\n */\nexport function encode(input, options = EntityLevel.XML) {\n    const { mode = EncodingMode.Extensive, level = EntityLevel.XML } = typeof options === \"number\" ? { level: options } : options;\n    switch (mode) {\n        case EncodingMode.UTF8: {\n            return escapeUTF8(input);\n        }\n        case EncodingMode.Attribute: {\n            return escapeAttribute(input);\n        }\n        case EncodingMode.Text: {\n            return escapeText(input);\n        }\n        case EncodingMode.ASCII: {\n            return level === EntityLevel.HTML\n                ? encodeNonAsciiHTML(input)\n                : encodeXML(input);\n        }\n        // eslint-disable-next-line unicorn/no-useless-switch-case\n        case EncodingMode.Extensive:\n        default: {\n            return level === EntityLevel.HTML\n                ? encodeHTML(input)\n                : encodeXML(input);\n        }\n    }\n}\nexport { encodeXML, escape, escapeUTF8, escapeAttribute, escapeText, } from \"./escape.js\";\nexport { encodeHTML, encodeNonAsciiHTML, \n// Legacy aliases (deprecated)\nencodeHTML as encodeHTML4, encodeHTML as encodeHTML5, } from \"./encode.js\";\nexport { EntityDecoder, DecodingMode, decodeXML, decodeHTML, decodeHTMLStrict, decodeHTMLAttribute, \n// Legacy aliases (deprecated)\ndecodeHTML as decodeHTML4, decodeHTML as decodeHTML5, decodeHTMLStrict as decodeHTML4Strict, decodeHTMLStrict as decodeHTML5Strict, decodeXML as decodeXMLStrict, } from \"./decode.js\";\n//# sourceMappingURL=index.js.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/htmlparser2/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/**\n * htmlparser2\n * @home   : https://github.com/fb55/htmlparser2\n * @branch : master\n * @commit : c9ce33fc66f0888b13cee2db7c48abed6b35972c\n */\n\nexport * from './src';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/htmlparser2/src/Parser.d.ts",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport Tokenizer, { type Callbacks, QuoteType } from \"./Tokenizer.js\";\nexport interface ParserOptions {\n    /**\n     * Indicates whether special tags (`<script>`, `<style>`, and `<title>`) should get special treatment\n     * and if \"empty\" tags (eg. `<br>`) can have children.  If `false`, the content of special tags\n     * will be text only. For feeds and other XML content (documents that don't consist of HTML),\n     * set this to `true`.\n     *\n     * @default false\n     */\n    xmlMode?: boolean;\n    /**\n     * Decode entities within the document.\n     *\n     * @default true\n     */\n    decodeEntities?: boolean;\n    /**\n     * If set to true, all tags will be lowercased.\n     *\n     * @default !xmlMode\n     */\n    lowerCaseTags?: boolean;\n    /**\n     * If set to `true`, all attribute names will be lowercased. This has noticeable impact on speed.\n     *\n     * @default !xmlMode\n     */\n    lowerCaseAttributeNames?: boolean;\n    /**\n     * If set to true, CDATA sections will be recognized as text even if the xmlMode option is not enabled.\n     * NOTE: If xmlMode is set to `true` then CDATA sections will always be recognized as text.\n     *\n     * @default xmlMode\n     */\n    recognizeCDATA?: boolean;\n    /**\n     * If set to `true`, self-closing tags will trigger the onclosetag event even if xmlMode is not set to `true`.\n     * NOTE: If xmlMode is set to `true` then self-closing tags will always be recognized.\n     *\n     * @default xmlMode\n     */\n    recognizeSelfClosing?: boolean;\n    /**\n     * Allows the default tokenizer to be overwritten.\n     */\n    Tokenizer?: typeof Tokenizer;\n}\nexport interface Handler {\n    onparserinit(parser: Parser): void;\n    /**\n     * Resets the handler back to starting state\n     */\n    onreset(): void;\n    /**\n     * Signals the handler that parsing is done\n     */\n    onend(): void;\n    onerror(error: Error): void;\n    onclosetag(name: string, isImplied: boolean): void;\n    onopentagname(name: string): void;\n    /**\n     *\n     * @param name Name of the attribute\n     * @param value Value of the attribute.\n     * @param quote Quotes used around the attribute. `null` if the attribute has no quotes around the value, `undefined` if the attribute has no value.\n     */\n    onattribute(name: string, value: string, quote?: string | undefined | null): void;\n    onopentag(name: string, attribs: {\n        [s: string]: string;\n    }, isImplied: boolean): void;\n    ontext(data: string): void;\n    oncomment(data: string): void;\n    oncdatastart(): void;\n    oncdataend(): void;\n    oncommentend(): void;\n    onprocessinginstruction(name: string, data: string): void;\n}\nexport declare class Parser implements Callbacks {\n    private readonly options;\n    /** The start index of the last event. */\n    startIndex: number;\n    /** The end index of the last event. */\n    endIndex: number;\n    /**\n     * Store the start index of the current open tag,\n     * so we can update the start index for attributes.\n     */\n    private openTagStart;\n    private tagname;\n    private attribname;\n    private attribvalue;\n    private attribs;\n    private readonly stack;\n    /** Determines whether self-closing tags are recognized. */\n    private readonly foreignContext;\n    private readonly cbs;\n    private readonly lowerCaseTagNames;\n    private readonly lowerCaseAttributeNames;\n    private readonly recognizeSelfClosing;\n    /** We are parsing HTML. Inverse of the `xmlMode` option. */\n    private readonly htmlMode;\n    private readonly tokenizer;\n    private readonly buffers;\n    private bufferOffset;\n    /** The index of the last written buffer. Used when resuming after a `pause()`. */\n    private writeIndex;\n    /** Indicates whether the parser has finished running / `.end` has been called. */\n    private ended;\n    constructor(cbs?: Partial<Handler> | null, options?: ParserOptions);\n    /** @internal */\n    ontext(start: number, endIndex: number): void;\n    /** @internal */\n    ontextentity(cp: number, endIndex: number): void;\n    /**\n     * Checks if the current tag is a void element. Override this if you want\n     * to specify your own additional void elements.\n     */\n    protected isVoidElement(name: string): boolean;\n    /** @internal */\n    onopentagname(start: number, endIndex: number): void;\n    private emitOpenTag;\n    private endOpenTag;\n    /** @internal */\n    onopentagend(endIndex: number): void;\n    /** @internal */\n    onclosetag(start: number, endIndex: number): void;\n    /** @internal */\n    onselfclosingtag(endIndex: number): void;\n    private closeCurrentTag;\n    /** @internal */\n    onattribname(start: number, endIndex: number): void;\n    /** @internal */\n    onattribdata(start: number, endIndex: number): void;\n    /** @internal */\n    onattribentity(cp: number): void;\n    /** @internal */\n    onattribend(quote: QuoteType, endIndex: number): void;\n    private getInstructionName;\n    /** @internal */\n    ondeclaration(start: number, endIndex: number): void;\n    /** @internal */\n    onprocessinginstruction(start: number, endIndex: number): void;\n    /** @internal */\n    oncomment(start: number, endIndex: number, offset: number): void;\n    /** @internal */\n    oncdata(start: number, endIndex: number, offset: number): void;\n    /** @internal */\n    onend(): void;\n    /**\n     * Resets the parser to a blank state, ready to parse a new HTML document\n     */\n    reset(): void;\n    /**\n     * Resets the parser, then parses a complete document and\n     * pushes it to the handler.\n     *\n     * @param data Document to parse.\n     */\n    parseComplete(data: string): void;\n    private getSlice;\n    private shiftBuffer;\n    /**\n     * Parses a chunk of data and calls the corresponding callbacks.\n     *\n     * @param chunk Chunk to parse.\n     */\n    write(chunk: string): void;\n    /**\n     * Parses the end of the buffer and clears the stack, calls onend.\n     *\n     * @param chunk Optional final chunk to parse.\n     */\n    end(chunk?: string): void;\n    /**\n     * Pauses parsing. The parser won't emit events until `resume` is called.\n     */\n    pause(): void;\n    /**\n     * Resumes parsing after `pause` was called.\n     */\n    resume(): void;\n    /**\n     * Alias of `write`, for backwards compatibility.\n     *\n     * @param chunk Chunk to parse.\n     * @deprecated\n     */\n    parseChunk(chunk: string): void;\n    /**\n     * Alias of `end`, for backwards compatibility.\n     *\n     * @param chunk Optional final chunk to parse.\n     * @deprecated\n     */\n    done(chunk?: string): void;\n}\n//# sourceMappingURL=Parser.d.ts.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/htmlparser2/src/Parser.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport Tokenizer, { QuoteType } from \"./Tokenizer.js\";\nimport { fromCodePoint } from \"../../entities/src/decode\";\nconst formTags = new Set([\n    \"input\",\n    \"option\",\n    \"optgroup\",\n    \"select\",\n    \"button\",\n    \"datalist\",\n    \"textarea\",\n]);\nconst pTag = new Set([\"p\"]);\nconst tableSectionTags = new Set([\"thead\", \"tbody\"]);\nconst ddtTags = new Set([\"dd\", \"dt\"]);\nconst rtpTags = new Set([\"rt\", \"rp\"]);\nconst openImpliesClose = new Map([\n    [\"tr\", new Set([\"tr\", \"th\", \"td\"])],\n    [\"th\", new Set([\"th\"])],\n    [\"td\", new Set([\"thead\", \"th\", \"td\"])],\n    [\"body\", new Set([\"head\", \"link\", \"script\"])],\n    [\"li\", new Set([\"li\"])],\n    [\"p\", pTag],\n    [\"h1\", pTag],\n    [\"h2\", pTag],\n    [\"h3\", pTag],\n    [\"h4\", pTag],\n    [\"h5\", pTag],\n    [\"h6\", pTag],\n    [\"select\", formTags],\n    [\"input\", formTags],\n    [\"output\", formTags],\n    [\"button\", formTags],\n    [\"datalist\", formTags],\n    [\"textarea\", formTags],\n    [\"option\", new Set([\"option\"])],\n    [\"optgroup\", new Set([\"optgroup\", \"option\"])],\n    [\"dd\", ddtTags],\n    [\"dt\", ddtTags],\n    [\"address\", pTag],\n    [\"article\", pTag],\n    [\"aside\", pTag],\n    [\"blockquote\", pTag],\n    [\"details\", pTag],\n    [\"div\", pTag],\n    [\"dl\", pTag],\n    [\"fieldset\", pTag],\n    [\"figcaption\", pTag],\n    [\"figure\", pTag],\n    [\"footer\", pTag],\n    [\"form\", pTag],\n    [\"header\", pTag],\n    [\"hr\", pTag],\n    [\"main\", pTag],\n    [\"nav\", pTag],\n    [\"ol\", pTag],\n    [\"pre\", pTag],\n    [\"section\", pTag],\n    [\"table\", pTag],\n    [\"ul\", pTag],\n    [\"rt\", rtpTags],\n    [\"rp\", rtpTags],\n    [\"tbody\", tableSectionTags],\n    [\"tfoot\", tableSectionTags],\n]);\nconst voidElements = new Set([\n    \"area\",\n    \"base\",\n    \"basefont\",\n    \"br\",\n    \"col\",\n    \"command\",\n    \"embed\",\n    \"frame\",\n    \"hr\",\n    \"img\",\n    \"input\",\n    \"isindex\",\n    \"keygen\",\n    \"link\",\n    \"meta\",\n    \"param\",\n    \"source\",\n    \"track\",\n    \"wbr\",\n]);\nconst foreignContextElements = new Set([\"math\", \"svg\"]);\nconst htmlIntegrationElements = new Set([\n    \"mi\",\n    \"mo\",\n    \"mn\",\n    \"ms\",\n    \"mtext\",\n    \"annotation-xml\",\n    \"foreignobject\",\n    \"desc\",\n    \"title\",\n]);\nconst reNameEnd = /\\s|\\//;\nexport class Parser {\n    constructor(cbs, options = {}) {\n        var _a, _b, _c, _d, _e, _f;\n        this.options = options;\n        /** The start index of the last event. */\n        this.startIndex = 0;\n        /** The end index of the last event. */\n        this.endIndex = 0;\n        /**\n         * Store the start index of the current open tag,\n         * so we can update the start index for attributes.\n         */\n        this.openTagStart = 0;\n        this.tagname = \"\";\n        this.attribname = \"\";\n        this.attribvalue = \"\";\n        this.attribs = null;\n        this.stack = [];\n        this.buffers = [];\n        this.bufferOffset = 0;\n        /** The index of the last written buffer. Used when resuming after a `pause()`. */\n        this.writeIndex = 0;\n        /** Indicates whether the parser has finished running / `.end` has been called. */\n        this.ended = false;\n        this.cbs = cbs !== null && cbs !== void 0 ? cbs : {};\n        this.htmlMode = !this.options.xmlMode;\n        this.lowerCaseTagNames = (_a = options.lowerCaseTags) !== null && _a !== void 0 ? _a : this.htmlMode;\n        this.lowerCaseAttributeNames =\n            (_b = options.lowerCaseAttributeNames) !== null && _b !== void 0 ? _b : this.htmlMode;\n        this.recognizeSelfClosing =\n            (_c = options.recognizeSelfClosing) !== null && _c !== void 0 ? _c : !this.htmlMode;\n        this.tokenizer = new ((_d = options.Tokenizer) !== null && _d !== void 0 ? _d : Tokenizer)(this.options, this);\n        this.foreignContext = [!this.htmlMode];\n        (_f = (_e = this.cbs).onparserinit) === null || _f === void 0 ? void 0 : _f.call(_e, this);\n    }\n    // Tokenizer event handlers\n    /** @internal */\n    ontext(start, endIndex) {\n        var _a, _b;\n        const data = this.getSlice(start, endIndex);\n        this.endIndex = endIndex - 1;\n        (_b = (_a = this.cbs).ontext) === null || _b === void 0 ? void 0 : _b.call(_a, data);\n        this.startIndex = endIndex;\n    }\n    /** @internal */\n    ontextentity(cp, endIndex) {\n        var _a, _b;\n        this.endIndex = endIndex - 1;\n        (_b = (_a = this.cbs).ontext) === null || _b === void 0 ? void 0 : _b.call(_a, fromCodePoint(cp));\n        this.startIndex = endIndex;\n    }\n    /**\n     * Checks if the current tag is a void element. Override this if you want\n     * to specify your own additional void elements.\n     */\n    isVoidElement(name) {\n        return this.htmlMode && voidElements.has(name);\n    }\n    /** @internal */\n    onopentagname(start, endIndex) {\n        this.endIndex = endIndex;\n        let name = this.getSlice(start, endIndex);\n        if (this.lowerCaseTagNames) {\n            name = name.toLowerCase();\n        }\n        this.emitOpenTag(name);\n    }\n    emitOpenTag(name) {\n        var _a, _b, _c, _d;\n        this.openTagStart = this.startIndex;\n        this.tagname = name;\n        const impliesClose = this.htmlMode && openImpliesClose.get(name);\n        if (impliesClose) {\n            while (this.stack.length > 0 && impliesClose.has(this.stack[0])) {\n                const element = this.stack.shift();\n                (_b = (_a = this.cbs).onclosetag) === null || _b === void 0 ? void 0 : _b.call(_a, element, true);\n            }\n        }\n        if (!this.isVoidElement(name)) {\n            this.stack.unshift(name);\n            if (this.htmlMode) {\n                if (foreignContextElements.has(name)) {\n                    this.foreignContext.unshift(true);\n                }\n                else if (htmlIntegrationElements.has(name)) {\n                    this.foreignContext.unshift(false);\n                }\n            }\n        }\n        (_d = (_c = this.cbs).onopentagname) === null || _d === void 0 ? void 0 : _d.call(_c, name);\n        if (this.cbs.onopentag)\n            this.attribs = {};\n    }\n    endOpenTag(isImplied) {\n        var _a, _b;\n        this.startIndex = this.openTagStart;\n        if (this.attribs) {\n            (_b = (_a = this.cbs).onopentag) === null || _b === void 0 ? void 0 : _b.call(_a, this.tagname, this.attribs, isImplied);\n            this.attribs = null;\n        }\n        if (this.cbs.onclosetag && this.isVoidElement(this.tagname)) {\n            this.cbs.onclosetag(this.tagname, true);\n        }\n        this.tagname = \"\";\n    }\n    /** @internal */\n    onopentagend(endIndex) {\n        this.endIndex = endIndex;\n        this.endOpenTag(false);\n        // Set `startIndex` for next node\n        this.startIndex = endIndex + 1;\n    }\n    /** @internal */\n    onclosetag(start, endIndex) {\n        var _a, _b, _c, _d, _e, _f, _g, _h;\n        this.endIndex = endIndex;\n        let name = this.getSlice(start, endIndex);\n        if (this.lowerCaseTagNames) {\n            name = name.toLowerCase();\n        }\n        if (this.htmlMode &&\n            (foreignContextElements.has(name) ||\n                htmlIntegrationElements.has(name))) {\n            this.foreignContext.shift();\n        }\n        if (!this.isVoidElement(name)) {\n            const pos = this.stack.indexOf(name);\n            if (pos !== -1) {\n                for (let index = 0; index <= pos; index++) {\n                    const element = this.stack.shift();\n                    // We know the stack has sufficient elements.\n                    (_b = (_a = this.cbs).onclosetag) === null || _b === void 0 ? void 0 : _b.call(_a, element, index !== pos);\n                }\n            }\n            else if (this.htmlMode && name === \"p\") {\n                // Implicit open before close\n                this.emitOpenTag(\"p\");\n                this.closeCurrentTag(true);\n            }\n        }\n        else if (this.htmlMode && name === \"br\") {\n            // We can't use `emitOpenTag` for implicit open, as `br` would be implicitly closed.\n            (_d = (_c = this.cbs).onopentagname) === null || _d === void 0 ? void 0 : _d.call(_c, \"br\");\n            (_f = (_e = this.cbs).onopentag) === null || _f === void 0 ? void 0 : _f.call(_e, \"br\", {}, true);\n            (_h = (_g = this.cbs).onclosetag) === null || _h === void 0 ? void 0 : _h.call(_g, \"br\", false);\n        }\n        // Set `startIndex` for next node\n        this.startIndex = endIndex + 1;\n    }\n    /** @internal */\n    onselfclosingtag(endIndex) {\n        this.endIndex = endIndex;\n        if (this.recognizeSelfClosing || this.foreignContext[0]) {\n            this.closeCurrentTag(false);\n            // Set `startIndex` for next node\n            this.startIndex = endIndex + 1;\n        }\n        else {\n            // Ignore the fact that the tag is self-closing.\n            this.onopentagend(endIndex);\n        }\n    }\n    closeCurrentTag(isOpenImplied) {\n        var _a, _b;\n        const name = this.tagname;\n        this.endOpenTag(isOpenImplied);\n        // Self-closing tags will be on the top of the stack\n        if (this.stack[0] === name) {\n            // If the opening tag isn't implied, the closing tag has to be implied.\n            (_b = (_a = this.cbs).onclosetag) === null || _b === void 0 ? void 0 : _b.call(_a, name, !isOpenImplied);\n            this.stack.shift();\n        }\n    }\n    /** @internal */\n    onattribname(start, endIndex) {\n        this.startIndex = start;\n        const name = this.getSlice(start, endIndex);\n        this.attribname = this.lowerCaseAttributeNames\n            ? name.toLowerCase()\n            : name;\n    }\n    /** @internal */\n    onattribdata(start, endIndex) {\n        this.attribvalue += this.getSlice(start, endIndex);\n    }\n    /** @internal */\n    onattribentity(cp) {\n        this.attribvalue += fromCodePoint(cp);\n    }\n    /** @internal */\n    onattribend(quote, endIndex) {\n        var _a, _b;\n        this.endIndex = endIndex;\n        (_b = (_a = this.cbs).onattribute) === null || _b === void 0 ? void 0 : _b.call(_a, this.attribname, this.attribvalue, quote === QuoteType.Double\n            ? '\"'\n            : quote === QuoteType.Single\n                ? \"'\"\n                : quote === QuoteType.NoValue\n                    ? undefined\n                    : null);\n        if (this.attribs &&\n            !Object.prototype.hasOwnProperty.call(this.attribs, this.attribname)) {\n            this.attribs[this.attribname] = this.attribvalue;\n        }\n        this.attribvalue = \"\";\n    }\n    getInstructionName(value) {\n        const index = value.search(reNameEnd);\n        let name = index < 0 ? value : value.substr(0, index);\n        if (this.lowerCaseTagNames) {\n            name = name.toLowerCase();\n        }\n        return name;\n    }\n    /** @internal */\n    ondeclaration(start, endIndex) {\n        this.endIndex = endIndex;\n        const value = this.getSlice(start, endIndex);\n        if (this.cbs.onprocessinginstruction) {\n            const name = this.getInstructionName(value);\n            this.cbs.onprocessinginstruction(`!${name}`, `!${value}`);\n        }\n        // Set `startIndex` for next node\n        this.startIndex = endIndex + 1;\n    }\n    /** @internal */\n    onprocessinginstruction(start, endIndex) {\n        this.endIndex = endIndex;\n        const value = this.getSlice(start, endIndex);\n        if (this.cbs.onprocessinginstruction) {\n            const name = this.getInstructionName(value);\n            this.cbs.onprocessinginstruction(`?${name}`, `?${value}`);\n        }\n        // Set `startIndex` for next node\n        this.startIndex = endIndex + 1;\n    }\n    /** @internal */\n    oncomment(start, endIndex, offset) {\n        var _a, _b, _c, _d;\n        this.endIndex = endIndex;\n        (_b = (_a = this.cbs).oncomment) === null || _b === void 0 ? void 0 : _b.call(_a, this.getSlice(start, endIndex - offset));\n        (_d = (_c = this.cbs).oncommentend) === null || _d === void 0 ? void 0 : _d.call(_c);\n        // Set `startIndex` for next node\n        this.startIndex = endIndex + 1;\n    }\n    /** @internal */\n    oncdata(start, endIndex, offset) {\n        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;\n        this.endIndex = endIndex;\n        const value = this.getSlice(start, endIndex - offset);\n        if (!this.htmlMode || this.options.recognizeCDATA) {\n            (_b = (_a = this.cbs).oncdatastart) === null || _b === void 0 ? void 0 : _b.call(_a);\n            (_d = (_c = this.cbs).ontext) === null || _d === void 0 ? void 0 : _d.call(_c, value);\n            (_f = (_e = this.cbs).oncdataend) === null || _f === void 0 ? void 0 : _f.call(_e);\n        }\n        else {\n            (_h = (_g = this.cbs).oncomment) === null || _h === void 0 ? void 0 : _h.call(_g, `[CDATA[${value}]]`);\n            (_k = (_j = this.cbs).oncommentend) === null || _k === void 0 ? void 0 : _k.call(_j);\n        }\n        // Set `startIndex` for next node\n        this.startIndex = endIndex + 1;\n    }\n    /** @internal */\n    onend() {\n        var _a, _b;\n        if (this.cbs.onclosetag) {\n            // Set the end index for all remaining tags\n            this.endIndex = this.startIndex;\n            for (let index = 0; index < this.stack.length; index++) {\n                this.cbs.onclosetag(this.stack[index], true);\n            }\n        }\n        (_b = (_a = this.cbs).onend) === null || _b === void 0 ? void 0 : _b.call(_a);\n    }\n    /**\n     * Resets the parser to a blank state, ready to parse a new HTML document\n     */\n    reset() {\n        var _a, _b, _c, _d;\n        (_b = (_a = this.cbs).onreset) === null || _b === void 0 ? void 0 : _b.call(_a);\n        this.tokenizer.reset();\n        this.tagname = \"\";\n        this.attribname = \"\";\n        this.attribs = null;\n        this.stack.length = 0;\n        this.startIndex = 0;\n        this.endIndex = 0;\n        (_d = (_c = this.cbs).onparserinit) === null || _d === void 0 ? void 0 : _d.call(_c, this);\n        this.buffers.length = 0;\n        this.foreignContext.length = 0;\n        this.foreignContext.unshift(!this.htmlMode);\n        this.bufferOffset = 0;\n        this.writeIndex = 0;\n        this.ended = false;\n    }\n    /**\n     * Resets the parser, then parses a complete document and\n     * pushes it to the handler.\n     *\n     * @param data Document to parse.\n     */\n    parseComplete(data) {\n        this.reset();\n        this.end(data);\n    }\n    getSlice(start, end) {\n        while (start - this.bufferOffset >= this.buffers[0].length) {\n            this.shiftBuffer();\n        }\n        let slice = this.buffers[0].slice(start - this.bufferOffset, end - this.bufferOffset);\n        while (end - this.bufferOffset > this.buffers[0].length) {\n            this.shiftBuffer();\n            slice += this.buffers[0].slice(0, end - this.bufferOffset);\n        }\n        return slice;\n    }\n    shiftBuffer() {\n        this.bufferOffset += this.buffers[0].length;\n        this.writeIndex--;\n        this.buffers.shift();\n    }\n    /**\n     * Parses a chunk of data and calls the corresponding callbacks.\n     *\n     * @param chunk Chunk to parse.\n     */\n    write(chunk) {\n        var _a, _b;\n        if (this.ended) {\n            (_b = (_a = this.cbs).onerror) === null || _b === void 0 ? void 0 : _b.call(_a, new Error(\".write() after done!\"));\n            return;\n        }\n        this.buffers.push(chunk);\n        if (this.tokenizer.running) {\n            this.tokenizer.write(chunk);\n            this.writeIndex++;\n        }\n    }\n    /**\n     * Parses the end of the buffer and clears the stack, calls onend.\n     *\n     * @param chunk Optional final chunk to parse.\n     */\n    end(chunk) {\n        var _a, _b;\n        if (this.ended) {\n            (_b = (_a = this.cbs).onerror) === null || _b === void 0 ? void 0 : _b.call(_a, new Error(\".end() after done!\"));\n            return;\n        }\n        if (chunk)\n            this.write(chunk);\n        this.ended = true;\n        this.tokenizer.end();\n    }\n    /**\n     * Pauses parsing. The parser won't emit events until `resume` is called.\n     */\n    pause() {\n        this.tokenizer.pause();\n    }\n    /**\n     * Resumes parsing after `pause` was called.\n     */\n    resume() {\n        this.tokenizer.resume();\n        while (this.tokenizer.running &&\n            this.writeIndex < this.buffers.length) {\n            this.tokenizer.write(this.buffers[this.writeIndex++]);\n        }\n        if (this.ended)\n            this.tokenizer.end();\n    }\n    /**\n     * Alias of `write`, for backwards compatibility.\n     *\n     * @param chunk Chunk to parse.\n     * @deprecated\n     */\n    parseChunk(chunk) {\n        this.write(chunk);\n    }\n    /**\n     * Alias of `end`, for backwards compatibility.\n     *\n     * @param chunk Optional final chunk to parse.\n     * @deprecated\n     */\n    done(chunk) {\n        this.end(chunk);\n    }\n}\n//# sourceMappingURL=Parser.js.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/htmlparser2/src/Tokenizer.d.ts",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport declare enum QuoteType {\n    NoValue = 0,\n    Unquoted = 1,\n    Single = 2,\n    Double = 3\n}\nexport interface Callbacks {\n    onattribdata(start: number, endIndex: number): void;\n    onattribentity(codepoint: number): void;\n    onattribend(quote: QuoteType, endIndex: number): void;\n    onattribname(start: number, endIndex: number): void;\n    oncdata(start: number, endIndex: number, endOffset: number): void;\n    onclosetag(start: number, endIndex: number): void;\n    oncomment(start: number, endIndex: number, endOffset: number): void;\n    ondeclaration(start: number, endIndex: number): void;\n    onend(): void;\n    onopentagend(endIndex: number): void;\n    onopentagname(start: number, endIndex: number): void;\n    onprocessinginstruction(start: number, endIndex: number): void;\n    onselfclosingtag(endIndex: number): void;\n    ontext(start: number, endIndex: number): void;\n    ontextentity(codepoint: number, endIndex: number): void;\n}\nexport default class Tokenizer {\n    private readonly cbs;\n    /** The current state the tokenizer is in. */\n    private state;\n    /** The read buffer. */\n    private buffer;\n    /** The beginning of the section that is currently being read. */\n    private sectionStart;\n    /** The index within the buffer that we are currently looking at. */\n    private index;\n    /** The start of the last entity. */\n    private entityStart;\n    /** Some behavior, eg. when decoding entities, is done while we are in another state. This keeps track of the other state type. */\n    private baseState;\n    /** For special parsing behavior inside of script and style tags. */\n    private isSpecial;\n    /** Indicates whether the tokenizer has been paused. */\n    running: boolean;\n    /** The offset of the current buffer. */\n    private offset;\n    private readonly xmlMode;\n    private readonly decodeEntities;\n    private readonly entityDecoder;\n    constructor({ xmlMode, decodeEntities, }: {\n        xmlMode?: boolean;\n        decodeEntities?: boolean;\n    }, cbs: Callbacks);\n    reset(): void;\n    write(chunk: string): void;\n    end(): void;\n    pause(): void;\n    resume(): void;\n    private stateText;\n    private currentSequence;\n    private sequenceIndex;\n    private stateSpecialStartSequence;\n    /** Look for an end tag. For <title> tags, also decode entities. */\n    private stateInSpecialTag;\n    private stateCDATASequence;\n    /**\n     * When we wait for one specific character, we can speed things up\n     * by skipping through the buffer until we find it.\n     *\n     * @returns Whether the character was found.\n     */\n    private fastForwardTo;\n    /**\n     * Comments and CDATA end with `-->` and `]]>`.\n     *\n     * Their common qualities are:\n     * - Their end sequences have a distinct character they start with.\n     * - That character is then repeated, so we have to check multiple repeats.\n     * - All characters but the start character of the sequence can be skipped.\n     */\n    private stateInCommentLike;\n    /**\n     * HTML only allows ASCII alpha characters (a-z and A-Z) at the beginning of a tag name.\n     *\n     * XML allows a lot more characters here (@see https://www.w3.org/TR/REC-xml/#NT-NameStartChar).\n     * We allow anything that wouldn't end the tag.\n     */\n    private isTagStartChar;\n    private startSpecial;\n    private stateBeforeTagName;\n    private stateInTagName;\n    private stateBeforeClosingTagName;\n    private stateInClosingTagName;\n    private stateAfterClosingTagName;\n    private stateBeforeAttributeName;\n    private stateInSelfClosingTag;\n    private stateInAttributeName;\n    private stateAfterAttributeName;\n    private stateBeforeAttributeValue;\n    private handleInAttributeValue;\n    private stateInAttributeValueDoubleQuotes;\n    private stateInAttributeValueSingleQuotes;\n    private stateInAttributeValueNoQuotes;\n    private stateBeforeDeclaration;\n    private stateInDeclaration;\n    private stateInProcessingInstruction;\n    private stateBeforeComment;\n    private stateInSpecialComment;\n    private stateBeforeSpecialS;\n    private stateBeforeSpecialT;\n    private startEntity;\n    private stateInEntity;\n    /**\n     * Remove data that has already been consumed from the buffer.\n     */\n    private cleanup;\n    private shouldContinue;\n    /**\n     * Iterates through the buffer, calling the function corresponding to the current state.\n     *\n     * States that are more likely to be hit are higher up, as a performance improvement.\n     */\n    private parse;\n    private finish;\n    /** Handle any trailing data. */\n    private handleTrailingData;\n    private emitCodePoint;\n}\n//# sourceMappingURL=Tokenizer.d.ts.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/htmlparser2/src/Tokenizer.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { EntityDecoder, DecodingMode, htmlDecodeTree, xmlDecodeTree, } from \"../../entities/src/decode\";\nvar CharCodes;\n(function (CharCodes) {\n    CharCodes[CharCodes[\"Tab\"] = 9] = \"Tab\";\n    CharCodes[CharCodes[\"NewLine\"] = 10] = \"NewLine\";\n    CharCodes[CharCodes[\"FormFeed\"] = 12] = \"FormFeed\";\n    CharCodes[CharCodes[\"CarriageReturn\"] = 13] = \"CarriageReturn\";\n    CharCodes[CharCodes[\"Space\"] = 32] = \"Space\";\n    CharCodes[CharCodes[\"ExclamationMark\"] = 33] = \"ExclamationMark\";\n    CharCodes[CharCodes[\"Number\"] = 35] = \"Number\";\n    CharCodes[CharCodes[\"Amp\"] = 38] = \"Amp\";\n    CharCodes[CharCodes[\"SingleQuote\"] = 39] = \"SingleQuote\";\n    CharCodes[CharCodes[\"DoubleQuote\"] = 34] = \"DoubleQuote\";\n    CharCodes[CharCodes[\"Dash\"] = 45] = \"Dash\";\n    CharCodes[CharCodes[\"Slash\"] = 47] = \"Slash\";\n    CharCodes[CharCodes[\"Zero\"] = 48] = \"Zero\";\n    CharCodes[CharCodes[\"Nine\"] = 57] = \"Nine\";\n    CharCodes[CharCodes[\"Semi\"] = 59] = \"Semi\";\n    CharCodes[CharCodes[\"Lt\"] = 60] = \"Lt\";\n    CharCodes[CharCodes[\"Eq\"] = 61] = \"Eq\";\n    CharCodes[CharCodes[\"Gt\"] = 62] = \"Gt\";\n    CharCodes[CharCodes[\"Questionmark\"] = 63] = \"Questionmark\";\n    CharCodes[CharCodes[\"UpperA\"] = 65] = \"UpperA\";\n    CharCodes[CharCodes[\"LowerA\"] = 97] = \"LowerA\";\n    CharCodes[CharCodes[\"UpperF\"] = 70] = \"UpperF\";\n    CharCodes[CharCodes[\"LowerF\"] = 102] = \"LowerF\";\n    CharCodes[CharCodes[\"UpperZ\"] = 90] = \"UpperZ\";\n    CharCodes[CharCodes[\"LowerZ\"] = 122] = \"LowerZ\";\n    CharCodes[CharCodes[\"LowerX\"] = 120] = \"LowerX\";\n    CharCodes[CharCodes[\"OpeningSquareBracket\"] = 91] = \"OpeningSquareBracket\";\n})(CharCodes || (CharCodes = {}));\n/** All the states the tokenizer can be in. */\nvar State;\n(function (State) {\n    State[State[\"Text\"] = 1] = \"Text\";\n    State[State[\"BeforeTagName\"] = 2] = \"BeforeTagName\";\n    State[State[\"InTagName\"] = 3] = \"InTagName\";\n    State[State[\"InSelfClosingTag\"] = 4] = \"InSelfClosingTag\";\n    State[State[\"BeforeClosingTagName\"] = 5] = \"BeforeClosingTagName\";\n    State[State[\"InClosingTagName\"] = 6] = \"InClosingTagName\";\n    State[State[\"AfterClosingTagName\"] = 7] = \"AfterClosingTagName\";\n    // Attributes\n    State[State[\"BeforeAttributeName\"] = 8] = \"BeforeAttributeName\";\n    State[State[\"InAttributeName\"] = 9] = \"InAttributeName\";\n    State[State[\"AfterAttributeName\"] = 10] = \"AfterAttributeName\";\n    State[State[\"BeforeAttributeValue\"] = 11] = \"BeforeAttributeValue\";\n    State[State[\"InAttributeValueDq\"] = 12] = \"InAttributeValueDq\";\n    State[State[\"InAttributeValueSq\"] = 13] = \"InAttributeValueSq\";\n    State[State[\"InAttributeValueNq\"] = 14] = \"InAttributeValueNq\";\n    // Declarations\n    State[State[\"BeforeDeclaration\"] = 15] = \"BeforeDeclaration\";\n    State[State[\"InDeclaration\"] = 16] = \"InDeclaration\";\n    // Processing instructions\n    State[State[\"InProcessingInstruction\"] = 17] = \"InProcessingInstruction\";\n    // Comments & CDATA\n    State[State[\"BeforeComment\"] = 18] = \"BeforeComment\";\n    State[State[\"CDATASequence\"] = 19] = \"CDATASequence\";\n    State[State[\"InSpecialComment\"] = 20] = \"InSpecialComment\";\n    State[State[\"InCommentLike\"] = 21] = \"InCommentLike\";\n    // Special tags\n    State[State[\"BeforeSpecialS\"] = 22] = \"BeforeSpecialS\";\n    State[State[\"BeforeSpecialT\"] = 23] = \"BeforeSpecialT\";\n    State[State[\"SpecialStartSequence\"] = 24] = \"SpecialStartSequence\";\n    State[State[\"InSpecialTag\"] = 25] = \"InSpecialTag\";\n    State[State[\"InEntity\"] = 26] = \"InEntity\";\n})(State || (State = {}));\nfunction isWhitespace(c) {\n    return (c === CharCodes.Space ||\n        c === CharCodes.NewLine ||\n        c === CharCodes.Tab ||\n        c === CharCodes.FormFeed ||\n        c === CharCodes.CarriageReturn);\n}\nfunction isEndOfTagSection(c) {\n    return c === CharCodes.Slash || c === CharCodes.Gt || isWhitespace(c);\n}\nfunction isASCIIAlpha(c) {\n    return ((c >= CharCodes.LowerA && c <= CharCodes.LowerZ) ||\n        (c >= CharCodes.UpperA && c <= CharCodes.UpperZ));\n}\nexport var QuoteType;\n(function (QuoteType) {\n    QuoteType[QuoteType[\"NoValue\"] = 0] = \"NoValue\";\n    QuoteType[QuoteType[\"Unquoted\"] = 1] = \"Unquoted\";\n    QuoteType[QuoteType[\"Single\"] = 2] = \"Single\";\n    QuoteType[QuoteType[\"Double\"] = 3] = \"Double\";\n})(QuoteType || (QuoteType = {}));\n/**\n * Sequences used to match longer strings.\n *\n * We don't have `Script`, `Style`, or `Title` here. Instead, we re-use the *End\n * sequences with an increased offset.\n */\nconst Sequences = {\n    Cdata: new Uint8Array([0x43, 0x44, 0x41, 0x54, 0x41, 0x5b]), // CDATA[\n    CdataEnd: new Uint8Array([0x5d, 0x5d, 0x3e]), // ]]>\n    CommentEnd: new Uint8Array([0x2d, 0x2d, 0x3e]), // `-->`\n    ScriptEnd: new Uint8Array([0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74]), // `</script`\n    StyleEnd: new Uint8Array([0x3c, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65]), // `</style`\n    TitleEnd: new Uint8Array([0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65]), // `</title`\n    TextareaEnd: new Uint8Array([\n        0x3c, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61,\n    ]), // `</textarea`\n    XmpEnd: new Uint8Array([0x3c, 0x2f, 0x78, 0x6d, 0x70]), // `</xmp`\n};\nexport default class Tokenizer {\n    constructor({ xmlMode = false, decodeEntities = true, }, cbs) {\n        this.cbs = cbs;\n        /** The current state the tokenizer is in. */\n        this.state = State.Text;\n        /** The read buffer. */\n        this.buffer = \"\";\n        /** The beginning of the section that is currently being read. */\n        this.sectionStart = 0;\n        /** The index within the buffer that we are currently looking at. */\n        this.index = 0;\n        /** The start of the last entity. */\n        this.entityStart = 0;\n        /** Some behavior, eg. when decoding entities, is done while we are in another state. This keeps track of the other state type. */\n        this.baseState = State.Text;\n        /** For special parsing behavior inside of script and style tags. */\n        this.isSpecial = false;\n        /** Indicates whether the tokenizer has been paused. */\n        this.running = true;\n        /** The offset of the current buffer. */\n        this.offset = 0;\n        this.currentSequence = undefined;\n        this.sequenceIndex = 0;\n        this.xmlMode = xmlMode;\n        this.decodeEntities = decodeEntities;\n        this.entityDecoder = new EntityDecoder(xmlMode ? xmlDecodeTree : htmlDecodeTree, (cp, consumed) => this.emitCodePoint(cp, consumed));\n    }\n    reset() {\n        this.state = State.Text;\n        this.buffer = \"\";\n        this.sectionStart = 0;\n        this.index = 0;\n        this.baseState = State.Text;\n        this.currentSequence = undefined;\n        this.running = true;\n        this.offset = 0;\n    }\n    write(chunk) {\n        this.offset += this.buffer.length;\n        this.buffer = chunk;\n        this.parse();\n    }\n    end() {\n        if (this.running)\n            this.finish();\n    }\n    pause() {\n        this.running = false;\n    }\n    resume() {\n        this.running = true;\n        if (this.index < this.buffer.length + this.offset) {\n            this.parse();\n        }\n    }\n    stateText(c) {\n        if (c === CharCodes.Lt ||\n            (!this.decodeEntities && this.fastForwardTo(CharCodes.Lt))) {\n            if (this.index > this.sectionStart) {\n                this.cbs.ontext(this.sectionStart, this.index);\n            }\n            this.state = State.BeforeTagName;\n            this.sectionStart = this.index;\n        }\n        else if (this.decodeEntities && c === CharCodes.Amp) {\n            this.startEntity();\n        }\n    }\n    stateSpecialStartSequence(c) {\n        const isEnd = this.sequenceIndex === this.currentSequence.length;\n        const isMatch = isEnd\n            ? // If we are at the end of the sequence, make sure the tag name has ended\n                isEndOfTagSection(c)\n            : // Otherwise, do a case-insensitive comparison\n                (c | 0x20) === this.currentSequence[this.sequenceIndex];\n        if (!isMatch) {\n            this.isSpecial = false;\n        }\n        else if (!isEnd) {\n            this.sequenceIndex++;\n            return;\n        }\n        this.sequenceIndex = 0;\n        this.state = State.InTagName;\n        this.stateInTagName(c);\n    }\n    /** Look for an end tag. For <title> tags, also decode entities. */\n    stateInSpecialTag(c) {\n        if (this.sequenceIndex === this.currentSequence.length) {\n            if (c === CharCodes.Gt || isWhitespace(c)) {\n                const endOfText = this.index - this.currentSequence.length;\n                if (this.sectionStart < endOfText) {\n                    // Spoof the index so that reported locations match up.\n                    const actualIndex = this.index;\n                    this.index = endOfText;\n                    this.cbs.ontext(this.sectionStart, endOfText);\n                    this.index = actualIndex;\n                }\n                this.isSpecial = false;\n                this.sectionStart = endOfText + 2; // Skip over the `</`\n                this.stateInClosingTagName(c);\n                return; // We are done; skip the rest of the function.\n            }\n            this.sequenceIndex = 0;\n        }\n        if ((c | 0x20) === this.currentSequence[this.sequenceIndex]) {\n            this.sequenceIndex += 1;\n        }\n        else if (this.sequenceIndex === 0) {\n            if (this.currentSequence === Sequences.TitleEnd) {\n                // We have to parse entities in <title> tags.\n                if (this.decodeEntities && c === CharCodes.Amp) {\n                    this.startEntity();\n                }\n            }\n            else if (this.fastForwardTo(CharCodes.Lt)) {\n                // Outside of <title> tags, we can fast-forward.\n                this.sequenceIndex = 1;\n            }\n        }\n        else {\n            // If we see a `<`, set the sequence index to 1; useful for eg. `<</script>`.\n            this.sequenceIndex = Number(c === CharCodes.Lt);\n        }\n    }\n    stateCDATASequence(c) {\n        if (c === Sequences.Cdata[this.sequenceIndex]) {\n            if (++this.sequenceIndex === Sequences.Cdata.length) {\n                this.state = State.InCommentLike;\n                this.currentSequence = Sequences.CdataEnd;\n                this.sequenceIndex = 0;\n                this.sectionStart = this.index + 1;\n            }\n        }\n        else {\n            this.sequenceIndex = 0;\n            this.state = State.InDeclaration;\n            this.stateInDeclaration(c); // Reconsume the character\n        }\n    }\n    /**\n     * When we wait for one specific character, we can speed things up\n     * by skipping through the buffer until we find it.\n     *\n     * @returns Whether the character was found.\n     */\n    fastForwardTo(c) {\n        while (++this.index < this.buffer.length + this.offset) {\n            if (this.buffer.charCodeAt(this.index - this.offset) === c) {\n                return true;\n            }\n        }\n        /*\n         * We increment the index at the end of the `parse` loop,\n         * so set it to `buffer.length - 1` here.\n         *\n         * TODO: Refactor `parse` to increment index before calling states.\n         */\n        this.index = this.buffer.length + this.offset - 1;\n        return false;\n    }\n    /**\n     * Comments and CDATA end with `-->` and `]]>`.\n     *\n     * Their common qualities are:\n     * - Their end sequences have a distinct character they start with.\n     * - That character is then repeated, so we have to check multiple repeats.\n     * - All characters but the start character of the sequence can be skipped.\n     */\n    stateInCommentLike(c) {\n        if (c === this.currentSequence[this.sequenceIndex]) {\n            if (++this.sequenceIndex === this.currentSequence.length) {\n                if (this.currentSequence === Sequences.CdataEnd) {\n                    this.cbs.oncdata(this.sectionStart, this.index, 2);\n                }\n                else {\n                    this.cbs.oncomment(this.sectionStart, this.index, 2);\n                }\n                this.sequenceIndex = 0;\n                this.sectionStart = this.index + 1;\n                this.state = State.Text;\n            }\n        }\n        else if (this.sequenceIndex === 0) {\n            // Fast-forward to the first character of the sequence\n            if (this.fastForwardTo(this.currentSequence[0])) {\n                this.sequenceIndex = 1;\n            }\n        }\n        else if (c !== this.currentSequence[this.sequenceIndex - 1]) {\n            // Allow long sequences, eg. --->, ]]]>\n            this.sequenceIndex = 0;\n        }\n    }\n    /**\n     * HTML only allows ASCII alpha characters (a-z and A-Z) at the beginning of a tag name.\n     *\n     * XML allows a lot more characters here (@see https://www.w3.org/TR/REC-xml/#NT-NameStartChar).\n     * We allow anything that wouldn't end the tag.\n     */\n    isTagStartChar(c) {\n        return this.xmlMode ? !isEndOfTagSection(c) : isASCIIAlpha(c);\n    }\n    startSpecial(sequence, offset) {\n        this.isSpecial = true;\n        this.currentSequence = sequence;\n        this.sequenceIndex = offset;\n        this.state = State.SpecialStartSequence;\n    }\n    stateBeforeTagName(c) {\n        if (c === CharCodes.ExclamationMark) {\n            this.state = State.BeforeDeclaration;\n            this.sectionStart = this.index + 1;\n        }\n        else if (c === CharCodes.Questionmark) {\n            this.state = State.InProcessingInstruction;\n            this.sectionStart = this.index + 1;\n        }\n        else if (this.isTagStartChar(c)) {\n            const lower = c | 0x20;\n            this.sectionStart = this.index;\n            if (this.xmlMode) {\n                this.state = State.InTagName;\n            }\n            else if (lower === Sequences.ScriptEnd[2]) {\n                this.state = State.BeforeSpecialS;\n            }\n            else if (lower === Sequences.TitleEnd[2] ||\n                lower === Sequences.XmpEnd[2]) {\n                this.state = State.BeforeSpecialT;\n            }\n            else {\n                this.state = State.InTagName;\n            }\n        }\n        else if (c === CharCodes.Slash) {\n            this.state = State.BeforeClosingTagName;\n        }\n        else {\n            this.state = State.Text;\n            this.stateText(c);\n        }\n    }\n    stateInTagName(c) {\n        if (isEndOfTagSection(c)) {\n            this.cbs.onopentagname(this.sectionStart, this.index);\n            this.sectionStart = -1;\n            this.state = State.BeforeAttributeName;\n            this.stateBeforeAttributeName(c);\n        }\n    }\n    stateBeforeClosingTagName(c) {\n        if (isWhitespace(c)) {\n            // Ignore\n        }\n        else if (c === CharCodes.Gt) {\n            this.state = State.Text;\n        }\n        else {\n            this.state = this.isTagStartChar(c)\n                ? State.InClosingTagName\n                : State.InSpecialComment;\n            this.sectionStart = this.index;\n        }\n    }\n    stateInClosingTagName(c) {\n        if (c === CharCodes.Gt || isWhitespace(c)) {\n            this.cbs.onclosetag(this.sectionStart, this.index);\n            this.sectionStart = -1;\n            this.state = State.AfterClosingTagName;\n            this.stateAfterClosingTagName(c);\n        }\n    }\n    stateAfterClosingTagName(c) {\n        // Skip everything until \">\"\n        if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {\n            this.state = State.Text;\n            this.sectionStart = this.index + 1;\n        }\n    }\n    stateBeforeAttributeName(c) {\n        if (c === CharCodes.Gt) {\n            this.cbs.onopentagend(this.index);\n            if (this.isSpecial) {\n                this.state = State.InSpecialTag;\n                this.sequenceIndex = 0;\n            }\n            else {\n                this.state = State.Text;\n            }\n            this.sectionStart = this.index + 1;\n        }\n        else if (c === CharCodes.Slash) {\n            this.state = State.InSelfClosingTag;\n        }\n        else if (!isWhitespace(c)) {\n            this.state = State.InAttributeName;\n            this.sectionStart = this.index;\n        }\n    }\n    stateInSelfClosingTag(c) {\n        if (c === CharCodes.Gt) {\n            this.cbs.onselfclosingtag(this.index);\n            this.state = State.Text;\n            this.sectionStart = this.index + 1;\n            this.isSpecial = false; // Reset special state, in case of self-closing special tags\n        }\n        else if (!isWhitespace(c)) {\n            this.state = State.BeforeAttributeName;\n            this.stateBeforeAttributeName(c);\n        }\n    }\n    stateInAttributeName(c) {\n        if (c === CharCodes.Eq || isEndOfTagSection(c)) {\n            this.cbs.onattribname(this.sectionStart, this.index);\n            this.sectionStart = this.index;\n            this.state = State.AfterAttributeName;\n            this.stateAfterAttributeName(c);\n        }\n    }\n    stateAfterAttributeName(c) {\n        if (c === CharCodes.Eq) {\n            this.state = State.BeforeAttributeValue;\n        }\n        else if (c === CharCodes.Slash || c === CharCodes.Gt) {\n            this.cbs.onattribend(QuoteType.NoValue, this.sectionStart);\n            this.sectionStart = -1;\n            this.state = State.BeforeAttributeName;\n            this.stateBeforeAttributeName(c);\n        }\n        else if (!isWhitespace(c)) {\n            this.cbs.onattribend(QuoteType.NoValue, this.sectionStart);\n            this.state = State.InAttributeName;\n            this.sectionStart = this.index;\n        }\n    }\n    stateBeforeAttributeValue(c) {\n        if (c === CharCodes.DoubleQuote) {\n            this.state = State.InAttributeValueDq;\n            this.sectionStart = this.index + 1;\n        }\n        else if (c === CharCodes.SingleQuote) {\n            this.state = State.InAttributeValueSq;\n            this.sectionStart = this.index + 1;\n        }\n        else if (!isWhitespace(c)) {\n            this.sectionStart = this.index;\n            this.state = State.InAttributeValueNq;\n            this.stateInAttributeValueNoQuotes(c); // Reconsume token\n        }\n    }\n    handleInAttributeValue(c, quote) {\n        if (c === quote ||\n            (!this.decodeEntities && this.fastForwardTo(quote))) {\n            this.cbs.onattribdata(this.sectionStart, this.index);\n            this.sectionStart = -1;\n            this.cbs.onattribend(quote === CharCodes.DoubleQuote\n                ? QuoteType.Double\n                : QuoteType.Single, this.index + 1);\n            this.state = State.BeforeAttributeName;\n        }\n        else if (this.decodeEntities && c === CharCodes.Amp) {\n            this.startEntity();\n        }\n    }\n    stateInAttributeValueDoubleQuotes(c) {\n        this.handleInAttributeValue(c, CharCodes.DoubleQuote);\n    }\n    stateInAttributeValueSingleQuotes(c) {\n        this.handleInAttributeValue(c, CharCodes.SingleQuote);\n    }\n    stateInAttributeValueNoQuotes(c) {\n        if (isWhitespace(c) || c === CharCodes.Gt) {\n            this.cbs.onattribdata(this.sectionStart, this.index);\n            this.sectionStart = -1;\n            this.cbs.onattribend(QuoteType.Unquoted, this.index);\n            this.state = State.BeforeAttributeName;\n            this.stateBeforeAttributeName(c);\n        }\n        else if (this.decodeEntities && c === CharCodes.Amp) {\n            this.startEntity();\n        }\n    }\n    stateBeforeDeclaration(c) {\n        if (c === CharCodes.OpeningSquareBracket) {\n            this.state = State.CDATASequence;\n            this.sequenceIndex = 0;\n        }\n        else {\n            this.state =\n                c === CharCodes.Dash\n                    ? State.BeforeComment\n                    : State.InDeclaration;\n        }\n    }\n    stateInDeclaration(c) {\n        if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {\n            this.cbs.ondeclaration(this.sectionStart, this.index);\n            this.state = State.Text;\n            this.sectionStart = this.index + 1;\n        }\n    }\n    stateInProcessingInstruction(c) {\n        if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {\n            this.cbs.onprocessinginstruction(this.sectionStart, this.index);\n            this.state = State.Text;\n            this.sectionStart = this.index + 1;\n        }\n    }\n    stateBeforeComment(c) {\n        if (c === CharCodes.Dash) {\n            this.state = State.InCommentLike;\n            this.currentSequence = Sequences.CommentEnd;\n            // Allow short comments (eg. <!-->)\n            this.sequenceIndex = 2;\n            this.sectionStart = this.index + 1;\n        }\n        else {\n            this.state = State.InDeclaration;\n        }\n    }\n    stateInSpecialComment(c) {\n        if (c === CharCodes.Gt || this.fastForwardTo(CharCodes.Gt)) {\n            this.cbs.oncomment(this.sectionStart, this.index, 0);\n            this.state = State.Text;\n            this.sectionStart = this.index + 1;\n        }\n    }\n    stateBeforeSpecialS(c) {\n        const lower = c | 0x20;\n        if (lower === Sequences.ScriptEnd[3]) {\n            this.startSpecial(Sequences.ScriptEnd, 4);\n        }\n        else if (lower === Sequences.StyleEnd[3]) {\n            this.startSpecial(Sequences.StyleEnd, 4);\n        }\n        else {\n            this.state = State.InTagName;\n            this.stateInTagName(c); // Consume the token again\n        }\n    }\n    stateBeforeSpecialT(c) {\n        const lower = c | 0x20;\n        switch (lower) {\n            case Sequences.TitleEnd[3]: {\n                this.startSpecial(Sequences.TitleEnd, 4);\n                break;\n            }\n            case Sequences.TextareaEnd[3]: {\n                this.startSpecial(Sequences.TextareaEnd, 4);\n                break;\n            }\n            case Sequences.XmpEnd[3]: {\n                this.startSpecial(Sequences.XmpEnd, 4);\n                break;\n            }\n            default: {\n                this.state = State.InTagName;\n                this.stateInTagName(c); // Consume the token again\n            }\n        }\n    }\n    startEntity() {\n        this.baseState = this.state;\n        this.state = State.InEntity;\n        this.entityStart = this.index;\n        this.entityDecoder.startEntity(this.xmlMode\n            ? DecodingMode.Strict\n            : this.baseState === State.Text ||\n                this.baseState === State.InSpecialTag\n                ? DecodingMode.Legacy\n                : DecodingMode.Attribute);\n    }\n    stateInEntity() {\n        const length = this.entityDecoder.write(this.buffer, this.index - this.offset);\n        // If `length` is positive, we are done with the entity.\n        if (length >= 0) {\n            this.state = this.baseState;\n            if (length === 0) {\n                this.index = this.entityStart;\n            }\n        }\n        else {\n            // Mark buffer as consumed.\n            this.index = this.offset + this.buffer.length - 1;\n        }\n    }\n    /**\n     * Remove data that has already been consumed from the buffer.\n     */\n    cleanup() {\n        // If we are inside of text or attributes, emit what we already have.\n        if (this.running && this.sectionStart !== this.index) {\n            if (this.state === State.Text ||\n                (this.state === State.InSpecialTag && this.sequenceIndex === 0)) {\n                this.cbs.ontext(this.sectionStart, this.index);\n                this.sectionStart = this.index;\n            }\n            else if (this.state === State.InAttributeValueDq ||\n                this.state === State.InAttributeValueSq ||\n                this.state === State.InAttributeValueNq) {\n                this.cbs.onattribdata(this.sectionStart, this.index);\n                this.sectionStart = this.index;\n            }\n        }\n    }\n    shouldContinue() {\n        return this.index < this.buffer.length + this.offset && this.running;\n    }\n    /**\n     * Iterates through the buffer, calling the function corresponding to the current state.\n     *\n     * States that are more likely to be hit are higher up, as a performance improvement.\n     */\n    parse() {\n        while (this.shouldContinue()) {\n            const c = this.buffer.charCodeAt(this.index - this.offset);\n            switch (this.state) {\n                case State.Text: {\n                    this.stateText(c);\n                    break;\n                }\n                case State.SpecialStartSequence: {\n                    this.stateSpecialStartSequence(c);\n                    break;\n                }\n                case State.InSpecialTag: {\n                    this.stateInSpecialTag(c);\n                    break;\n                }\n                case State.CDATASequence: {\n                    this.stateCDATASequence(c);\n                    break;\n                }\n                case State.InAttributeValueDq: {\n                    this.stateInAttributeValueDoubleQuotes(c);\n                    break;\n                }\n                case State.InAttributeName: {\n                    this.stateInAttributeName(c);\n                    break;\n                }\n                case State.InCommentLike: {\n                    this.stateInCommentLike(c);\n                    break;\n                }\n                case State.InSpecialComment: {\n                    this.stateInSpecialComment(c);\n                    break;\n                }\n                case State.BeforeAttributeName: {\n                    this.stateBeforeAttributeName(c);\n                    break;\n                }\n                case State.InTagName: {\n                    this.stateInTagName(c);\n                    break;\n                }\n                case State.InClosingTagName: {\n                    this.stateInClosingTagName(c);\n                    break;\n                }\n                case State.BeforeTagName: {\n                    this.stateBeforeTagName(c);\n                    break;\n                }\n                case State.AfterAttributeName: {\n                    this.stateAfterAttributeName(c);\n                    break;\n                }\n                case State.InAttributeValueSq: {\n                    this.stateInAttributeValueSingleQuotes(c);\n                    break;\n                }\n                case State.BeforeAttributeValue: {\n                    this.stateBeforeAttributeValue(c);\n                    break;\n                }\n                case State.BeforeClosingTagName: {\n                    this.stateBeforeClosingTagName(c);\n                    break;\n                }\n                case State.AfterClosingTagName: {\n                    this.stateAfterClosingTagName(c);\n                    break;\n                }\n                case State.BeforeSpecialS: {\n                    this.stateBeforeSpecialS(c);\n                    break;\n                }\n                case State.BeforeSpecialT: {\n                    this.stateBeforeSpecialT(c);\n                    break;\n                }\n                case State.InAttributeValueNq: {\n                    this.stateInAttributeValueNoQuotes(c);\n                    break;\n                }\n                case State.InSelfClosingTag: {\n                    this.stateInSelfClosingTag(c);\n                    break;\n                }\n                case State.InDeclaration: {\n                    this.stateInDeclaration(c);\n                    break;\n                }\n                case State.BeforeDeclaration: {\n                    this.stateBeforeDeclaration(c);\n                    break;\n                }\n                case State.BeforeComment: {\n                    this.stateBeforeComment(c);\n                    break;\n                }\n                case State.InProcessingInstruction: {\n                    this.stateInProcessingInstruction(c);\n                    break;\n                }\n                case State.InEntity: {\n                    this.stateInEntity();\n                    break;\n                }\n            }\n            this.index++;\n        }\n        this.cleanup();\n    }\n    finish() {\n        if (this.state === State.InEntity) {\n            this.entityDecoder.end();\n            this.state = this.baseState;\n        }\n        this.handleTrailingData();\n        this.cbs.onend();\n    }\n    /** Handle any trailing data. */\n    handleTrailingData() {\n        const endIndex = this.buffer.length + this.offset;\n        // If there is no remaining data, we are done.\n        if (this.sectionStart >= endIndex) {\n            return;\n        }\n        if (this.state === State.InCommentLike) {\n            if (this.currentSequence === Sequences.CdataEnd) {\n                this.cbs.oncdata(this.sectionStart, endIndex, 0);\n            }\n            else {\n                this.cbs.oncomment(this.sectionStart, endIndex, 0);\n            }\n        }\n        else if (this.state === State.InTagName ||\n            this.state === State.BeforeAttributeName ||\n            this.state === State.BeforeAttributeValue ||\n            this.state === State.AfterAttributeName ||\n            this.state === State.InAttributeName ||\n            this.state === State.InAttributeValueSq ||\n            this.state === State.InAttributeValueDq ||\n            this.state === State.InAttributeValueNq ||\n            this.state === State.InClosingTagName) {\n            /*\n             * If we are currently in an opening or closing tag, us not calling the\n             * respective callback signals that the tag should be ignored.\n             */\n        }\n        else {\n            this.cbs.ontext(this.sectionStart, endIndex);\n        }\n    }\n    emitCodePoint(cp, consumed) {\n        if (this.baseState !== State.Text &&\n            this.baseState !== State.InSpecialTag) {\n            if (this.sectionStart < this.entityStart) {\n                this.cbs.onattribdata(this.sectionStart, this.entityStart);\n            }\n            this.sectionStart = this.entityStart + consumed;\n            this.index = this.sectionStart - 1;\n            this.cbs.onattribentity(cp);\n        }\n        else {\n            if (this.sectionStart < this.entityStart) {\n                this.cbs.ontext(this.sectionStart, this.entityStart);\n            }\n            this.sectionStart = this.entityStart + consumed;\n            this.index = this.sectionStart - 1;\n            this.cbs.ontextentity(cp, this.sectionStart);\n        }\n    }\n}\n//# sourceMappingURL=Tokenizer.js.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/htmlparser2/src/index.d.ts",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { Parser, type ParserOptions } from \"./Parser\";\nexport type { Handler, ParserOptions } from \"./Parser\";\nexport { Parser } from \"./Parser\";\nimport { type DomHandlerOptions, type ChildNode, type Element, type Document } from \"../../domhandler/src\";\nexport { DomHandler, DomHandler as DefaultHandler, type DomHandlerOptions, } from \"../../domhandler/src\";\nexport type Options = ParserOptions & DomHandlerOptions;\n/**\n * Parses the data, returns the resulting document.\n *\n * @param data The data that should be parsed.\n * @param options Optional options for the parser and DOM handler.\n */\nexport declare function parseDocument(data: string, options?: Options): Document;\n/**\n * Parses data, returns an array of the root nodes.\n *\n * Note that the root nodes still have a `Document` node as their parent.\n * Use `parseDocument` to get the `Document` node instead.\n *\n * @param data The data that should be parsed.\n * @param options Optional options for the parser and DOM handler.\n * @deprecated Use `parseDocument` instead.\n */\nexport declare function parseDOM(data: string, options?: Options): ChildNode[];\n/**\n * Creates a parser instance, with an attached DOM handler.\n *\n * @param callback A callback that will be called once parsing has been completed, with the resulting document.\n * @param options Optional options for the parser and DOM handler.\n * @param elementCallback An optional callback that will be called every time a tag has been completed inside of the DOM.\n */\nexport declare function createDocumentStream(callback: (error: Error | null, document: Document) => void, options?: Options, elementCallback?: (element: Element) => void): Parser;\n/**\n * Creates a parser instance, with an attached DOM handler.\n *\n * @param callback A callback that will be called once parsing has been completed, with an array of root nodes.\n * @param options Optional options for the parser and DOM handler.\n * @param elementCallback An optional callback that will be called every time a tag has been completed inside of the DOM.\n * @deprecated Use `createDocumentStream` instead.\n */\nexport declare function createDomStream(callback: (error: Error | null, dom: ChildNode[]) => void, options?: Options, elementCallback?: (element: Element) => void): Parser;\nexport { default as Tokenizer, type Callbacks as TokenizerCallbacks, QuoteType, } from \"./Tokenizer.js\";\nexport * as ElementType from \"../../domelementtype/src\";\nimport { type Feed } from \"../../domutils/src\";\nexport { getFeed, type Feed } from \"../../domutils/src\";\n/**\n * Parse a feed.\n *\n * @param feed The feed that should be parsed, as a string.\n * @param options Optionally, options for parsing. When using this, you should set `xmlMode` to `true`.\n */\nexport declare function parseFeed(feed: string, options?: Options): Feed | null;\nexport * as DomUtils from \"../../domutils/src\";\n//# sourceMappingURL=index.d.ts.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/htmlparser2/src/index.js",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { Parser } from \"./Parser.js\";\nexport { Parser } from \"./Parser.js\";\nimport { DomHandler, } from \"../../domhandler/src\";\nexport { DomHandler, \n// Old name for DomHandler\nDomHandler as DefaultHandler, } from \"../../domhandler/src\";\n// Helper methods\n/**\n * Parses the data, returns the resulting document.\n *\n * @param data The data that should be parsed.\n * @param options Optional options for the parser and DOM handler.\n */\nexport function parseDocument(data, options) {\n    const handler = new DomHandler(undefined, options);\n    new Parser(handler, options).end(data);\n    return handler.root;\n}\n/**\n * Parses data, returns an array of the root nodes.\n *\n * Note that the root nodes still have a `Document` node as their parent.\n * Use `parseDocument` to get the `Document` node instead.\n *\n * @param data The data that should be parsed.\n * @param options Optional options for the parser and DOM handler.\n * @deprecated Use `parseDocument` instead.\n */\nexport function parseDOM(data, options) {\n    return parseDocument(data, options).children;\n}\n/**\n * Creates a parser instance, with an attached DOM handler.\n *\n * @param callback A callback that will be called once parsing has been completed, with the resulting document.\n * @param options Optional options for the parser and DOM handler.\n * @param elementCallback An optional callback that will be called every time a tag has been completed inside of the DOM.\n */\nexport function createDocumentStream(callback, options, elementCallback) {\n    const handler = new DomHandler((error) => callback(error, handler.root), options, elementCallback);\n    return new Parser(handler, options);\n}\n/**\n * Creates a parser instance, with an attached DOM handler.\n *\n * @param callback A callback that will be called once parsing has been completed, with an array of root nodes.\n * @param options Optional options for the parser and DOM handler.\n * @param elementCallback An optional callback that will be called every time a tag has been completed inside of the DOM.\n * @deprecated Use `createDocumentStream` instead.\n */\nexport function createDomStream(callback, options, elementCallback) {\n    const handler = new DomHandler(callback, options, elementCallback);\n    return new Parser(handler, options);\n}\nexport { default as Tokenizer, QuoteType, } from \"./Tokenizer.js\";\n/*\n * All of the following exports exist for backwards-compatibility.\n * They should probably be removed eventually.\n */\nexport * as ElementType from \"../../domelementtype/src\";\nimport { getFeed } from \"../../domutils/src\";\nexport { getFeed } from \"../../domutils/src\";\nconst parseFeedDefaultOptions = { xmlMode: true };\n/**\n * Parse a feed.\n *\n * @param feed The feed that should be parsed, as a string.\n * @param options Optionally, options for parsing. When using this, you should set `xmlMode` to `true`.\n */\nexport function parseFeed(feed, options = parseFeedDefaultOptions) {\n    return getFeed(parseDOM(feed, options));\n}\nexport * as DomUtils from \"../../domutils/src\";\n//# sourceMappingURL=index.js.map"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport * from './service';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/service.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { parseDocument, ElementType } from './htmlparser2';\nimport { render } from './dom-serializer';\nimport type { AnyNode } from './domhandler';\nimport { Element, isTag, Node, NodeWithChildren } from './domhandler';\nimport { EService, Service } from '../../engine/service';\nimport { Plugin } from '../../engine/plugin';\nimport { StyledUtil } from './styled';\n\ninterface IVisitor {\n  on: (node: AnyNode) => boolean,\n  filter?: (node: AnyNode) => boolean,\n}\nexport class HtmlService extends Service {\n  readonly type: EService = EService.HTML;\n  add<T extends Plugin>(_plugin: T): void {}\n  parse(_content: string) {\n    return parseDocument(_content);\n  }\n  toElement(node?: Node | null) {\n    return isTag(node) ? node as Element : undefined;\n  }\n  toStyled(content: string) {\n    return StyledUtil.toStyled(content, {\n      engine: () => this.engine?.deref(),\n    });\n  }\n  render(node: AnyNode) {\n    return render(node, {\n      decodeEntities: false, selfClosingTags: true,\n    });\n  }\n  traverse(node?: AnyNode, visitor?: IVisitor) {\n    if (!node || !visitor) {\n      return;\n    }\n    let canNext = true;\n    if (visitor.filter) {\n      if (visitor.filter(node)) {\n        canNext = visitor.on(node);\n      }\n    } else {\n      canNext = visitor.on(node);\n    }\n    if (!canNext) {\n      return;\n    }\n    //  children\n    if (node instanceof NodeWithChildren)\n    node.children.forEach(ele => {\n      this.traverse(ele, visitor);\n    });\n  }\n}\nexport { ElementType, Element, isTag };"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/html/styled.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { StyledObject } from '../../render';\nimport { AnyNode, Element, Document, Text, isTag } from './domhandler';\nimport { parseDocument } from './htmlparser2';\nimport type { Engine } from '../../engine';\n\ntype StyledResult = StyledString | undefined;\ninterface IStyledUtil {\n  engine: () => Engine | undefined;\n}\ninterface IStyledUtilFrom extends IStyledUtil {\n  didCreateStyled: (styled: StyledObject) => void;\n}\nexport abstract class StyledUtil {\n  static toStyled(content: string, option: IStyledUtil): StyledResult {\n    try {\n      const document = parseDocument(content);\n      const root = StyledObject.root();\n      fromNode(document, {\n        engine: option.engine,\n        didCreateStyled: (styled) => {\n          root.attach(styled);\n        },\n      });\n      return root.subStyledString(0);\n    } catch (e) {\n      return undefined;\n    }\n  }\n}\nconst fromNode = (node: AnyNode, option: IStyledUtilFrom): void => {\n  if (node instanceof Document) {\n    fromDocument(node, option);\n  } else if (node instanceof Text) {\n    fromText(node, option);\n  } else if (isTag(node)) {\n    fromElement(node, option);\n  }\n}\nconst fromDocument = (document: Document, option: IStyledUtilFrom): void => {\n  const styled = StyledObject.text('');\n  option.didCreateStyled(styled);\n\n  document.children.forEach(ele => fromNode(ele, {\n    engine: option.engine,\n    didCreateStyled: (_styled) => {\n      styled.attach(_styled);\n    },\n  }));\n}\nconst fromText = (text: Text, option: IStyledUtilFrom): void => {\n  option.didCreateStyled(StyledObject.text(text.data));\n}\nconst fromElement = (element: Element, option: IStyledUtilFrom): void => {\n  const values = option.engine()?.css?.toStyled(element.attribs['style'] || '');\n  const styled = StyledObject.text('', values);\n  option.didCreateStyled(styled);\n\n  element.children.forEach(ele => fromNode(ele, {\n    engine: option.engine,\n    didCreateStyled: (_styled) => {\n      styled.attach(_styled);\n    },\n  }));\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/image/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport * from './service';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/image/service.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { Plugin } from '../../engine/plugin';\nimport { EService, Service } from '../../engine/service';\nimport { FileService } from '../file';\nimport { newLog } from '../../util';\nimport Http from '@ohos.net.http';\nimport Image from '@ohos.multimedia.image';\n\nconst log = newLog('ImageService');\n\nexport class ImageServiceError extends Error {\n  code?: number;\n  domain?: string;\n  constructor(message: string, code?: number, domain?: string) {\n    super(message);\n    this.code = code;\n    this.domain = domain;\n  }\n}\nexport interface IImageServiceRequest {\n  url: string;\n}\nexport interface IImageServiceResponse {\n  imageSource?: Image.ImageSource;\n}\nexport class ImageService extends Service {\n  readonly type: EService = EService.Image;\n  private store: Map<string, IImageServiceResponse> = new Map();\n  private plugins: ImageServicePlugin[] = [];\n  add(plugin: ImageServicePlugin): void {\n    this.plugins.push(plugin);\n  }\n  private get hook() {\n    return this.plugins.slice(0, 1).pop();\n  }\n  private storeKey(request: IImageServiceRequest): string {\n    return request.url;\n  }\n  cache(request: IImageServiceRequest): IImageServiceResponse | undefined {\n    if (this.hook?.cash) {\n      return this.hook?.cash(request);\n    }\n    return this.store.get(this.storeKey(request));\n  }\n  async post(request: IImageServiceRequest): Promise<IImageServiceResponse> {\n    if (this.hook?.post) {\n      return await this.hook?.post(request);\n    }\n    const client = Http.createHttp();\n    try {\n      const resp = await client.request(request.url, { method: Http.RequestMethod.GET });\n      if (resp.responseCode !== 200) {\n        throw new ImageServiceError(\n          resp.resultType === Http.HttpDataType.STRING ? resp.result as string : 'http request failed',\n          resp.responseCode\n        );\n      }\n      if (resp.resultType !== Http.HttpDataType.ARRAY_BUFFER) {\n        throw new ImageServiceError(\n          'response type is not array buffer',\n          -1\n        )\n      }\n      const response: IImageServiceResponse = { imageSource: Image.createImageSource(resp.result as ArrayBuffer) };\n      this.store.set(this.storeKey(request), response);\n      return response;\n    } catch (e) {\n      throw new ImageServiceError(e.message, e.code, e.domain);\n    } finally {\n      client.destroy();\n    }\n  }\n  load(fileName: string): Image.ImageSource | undefined {\n    if (this.hook?.load) {\n      return this.hook?.load(fileName);\n    }\n    try {\n      const content = this.engine?.deref()?.ctx?.resourceManager?.\n      getRawFileContentSync(`markdown/${fileName}`);\n      if (content) {\n        return Image.createImageSource(content.buffer);\n      }\n      log.w(`load none image ${fileName}`);\n      return undefined;\n    } catch (e) {\n      log.e(`load image ${fileName} failed. ${e.message}`);\n      return undefined;\n    }\n  }\n  private get fileService() {\n    return this.engine?.deref()?.service<FileService>(EService.File);\n  }\n}\nexport abstract class ImageServicePlugin extends Plugin {\n  load?: (fileName: string) => Image.ImageSource | undefined;\n  cash?: (request: IImageServiceRequest) => IImageServiceResponse | undefined;\n  post?: (request: IImageServiceRequest) => Promise<IImageServiceResponse>;\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport * from './ast';\nexport * from './code';\nexport * from './html';\nexport * from './ctx';\nexport * from './image';\nexport * from './event';\nexport * from './css';\nexport * from './math';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/math/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport * from './service';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/service/math/service.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { Plugin } from '../../engine/plugin';\nimport { EService, Service } from '../../engine/service';\nimport Image from '@ohos.multimedia.image';\nimport { getLatex, initLatex } from 'liblatexentry.so';\nimport { image } from '@kit.ImageKit';\n\nexport class MathService extends Service {\n  readonly type: EService = EService.Math;\n  private store: Map<string, Image.ImageSource> = new Map();\n  private isResLoaded: boolean = false;\n\n  add<T extends Plugin>(_plugin: T): void {}\n\n  private cacheKey(request: IMathServiceRequest): string {\n    return `${request.hash}_${request.fontSize}_${request.fontColor}_${request.backgroundColor}`;\n  }\n\n  private loadRes() {\n    if (!this.isResLoaded) {\n      const context = this.engine?.deref()?.ctx?.ctx?.getHostContext()\n      initLatex(context ? context.resourceDir + \"/res\" : \"\")\n      this.isResLoaded = true\n    }\n  }\n\n  cache(request: IMathServiceRequest): Image.ImageSource | undefined {\n    return this.store.get(this.cacheKey(request));\n  }\n\n  async generate(request: IMathServiceRequest): Promise<IMathServiceResponse> {\n    this.loadRes()\n\n    let response: IMathServiceResponse = {\n      success: false,\n    }\n\n    let buf: ArrayBuffer = getLatex(request.content, 2000, request.fontSize, 10.0, request.fontColor)\n    let imageSource = image.createImageSource(buf)\n\n    this.store.set(this.cacheKey(request), imageSource);\n\n    response.image = imageSource\n    response.success = true\n\n    return response\n  }\n}\n\nexport interface IMathServiceRequest {\n  content: string;\n  hash?: string;\n  fontSize?: number;   //  px\n  fontColor?: number;\n  backgroundColor?: number;\n}\n\nexport interface IMathServiceResponse {\n  success: boolean;\n  image?: Image.ImageSource;\n  errorMessage?: string;\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/theme/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport * from './theme';\nexport * from './styling';\nexport * from './service';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/theme/service.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { Service, EService, Plugin } from '../engine';\nimport { MDLength } from '../util';\nimport type { ITheme } from './theme';\n\nexport class ThemeService extends Service {\n  readonly type: EService = EService.Theme;\n  static _default?: ITheme;\n  add<T extends Plugin>(_plugin: T): void {}\n  get theme(): ITheme {\n    if (!ThemeService._default) {\n      ThemeService._default = ThemeService.default();\n    }\n    return ThemeService._default;\n  }\n  static default(): ITheme {\n    return {\n      document: {\n        letterSpacing: { spacing: MDLength.vp(0.5) },\n        lineHeight: { height: MDLength.vp(24) },\n        font: {\n          fontColor: 0x333333,\n          fontSize: MDLength.vp(15),\n        },\n        blockSpace: MDLength.vp(12),\n        more: {\n          fontColor: 0x999999,\n          fontSize: MDLength.vp(12),\n          fontWeight: FontWeight.Normal,\n        },\n      },\n      paragraph: {\n      },\n      thematicBreak: {\n        lineHeight: { height: MDLength.vp(2) },\n        lineColor: 0xe2e5f3,\n      },\n      heading: {\n        h1: {\n          font: { fontWeight: FontWeight.Bold },\n        },\n        h2: {\n          font: { fontWeight: FontWeight.Bold },\n        },\n        h3: {\n          font: { fontWeight: FontWeight.Bold },\n        },\n        h4: {\n          font: { fontWeight: FontWeight.Bold },\n        },\n        h5: {\n          font: { fontWeight: FontWeight.Bold },\n        },\n        h6: {\n          font: { fontWeight: FontWeight.Bold },\n        },\n      },\n      quote: {\n        contentParagraph: {\n          leadingMargin: MDLength.vp(18),\n        },\n        font: { fontColor: 0x7d88ac },\n        edgeWidth: MDLength.vp(1),\n        edgeColor: 0x7d88ac,\n      },\n      image: {\n        size: { height: MDLength.vp(180) },\n        content: {\n          verticalAlign: ImageSpanAlignment.CENTER,\n          objectFit: ImageFit.Contain,\n          layoutStyle: { borderRadius: MDLength.vp(12) }\n        },\n        border: {\n          width: MDLength.vp(0.5),\n          color: 0x979797,\n          radius: MDLength.vp(12),\n        },\n        background: {\n          color: 0xd8d8d8,\n          radius: MDLength.vp(12),\n        },\n        textFont: { fontColor: Color.White },\n        maxHeight: MDLength.vp(1000),\n      },\n      underline: {\n        markHeight: MDLength.vp(6),\n        markColor: 0x801677ff,\n      },\n      strong: {\n        font: { fontWeight: FontWeight.Bold },\n      },\n      emphasis: {\n        font: { fontStyle: FontStyle.Italic },\n      },\n      strikeThrough: {\n        decoration: { type: TextDecorationType.LineThrough },\n      },\n      subscript: {\n        font: { fontSize: MDLength.vp(9) },\n      },\n      superscript: {\n        font: { fontSize: MDLength.vp(9) },\n      },\n      link: {\n        font: { fontColor: 0x4745ca },\n        iconSize: { width: MDLength.vp(12), height: MDLength.vp(12) },\n        iconSpace: { width: MDLength.vp(1) },\n      },\n      icon: {\n        size: { width: MDLength.vp(13), height: MDLength.vp(13) },\n        content: {\n          verticalAlign: ImageSpanAlignment.CENTER,\n          objectFit: ImageFit.Contain,\n        },\n      },\n      footnoteRef: {\n        font: {\n          fontColor: 0x999999,\n          fontSize: MDLength.vp(10),\n        },\n        background: {\n          color: 0xD8DEE4,\n          radius: MDLength.vp(9),\n        },\n        minSize: { width: MDLength.vp(14), height: MDLength.vp(14) },\n      },\n      inlineCode: {\n        background: {\n          color: 0xD8DEE4,\n          radius: MDLength.vp(4),\n        },\n        contentPadding: { left: MDLength.vp(4).value, right: MDLength.vp(4).value },\n      },\n      listItem: {\n        contentParagraph: { leadingMargin: MDLength.vp(15) },\n        contentTopParagraph: { leadingMargin: MDLength.vp(20) },\n        contentTopBoxWidth: MDLength.vp(14),\n        contentTopBoxFont: { fontSize: MDLength.vp(10), fontColor: Color.White },\n        contentTopBoxRadius: MDLength.vp(3),\n        contentTopBoxBackgroundColor: 0x0e51ce,\n        contentTopBadgeWidth: MDLength.vp(8),\n        contentTopBadgeBackgroundColor: 0x0e51ce,\n        contentBadgeWidth: MDLength.vp(4),\n        contentBadgeBackgroundColor: 0x0d1f38,\n        taskFlagWidth: MDLength.vp(12),\n        taskFlagColor: 0x0e51ce,\n      },\n      table: {\n        headerFont: {\n          fontSize: MDLength.vp(13),\n          fontColor: 0x999999,\n          fontWeight: FontWeight.Bold,\n        },\n        headerBackgroundColor: 0x0a1f3b63,\n        contentFont: {\n          fontSize: MDLength.vp(13),\n          fontColor: 0x333333,\n        },\n        cellMaxWidth: MDLength.vp(210),\n        cellMaxWidth4First: MDLength.vp(90),\n        cellLineHeight: { height: MDLength.vp(20) },\n      },\n      contentBox: {\n        barMargin: {\n          left: MDLength.vp(12), right: MDLength.vp(12),\n          top: MDLength.vp(8), bottom: MDLength.vp(8),\n        },\n        barFont: {\n          fontSize: MDLength.vp(13),\n          fontColor: 0x999999,\n          fontWeight: FontWeight.Bold,\n        },\n        barBackgroundColor: 0x141f3b63,\n        barActionIconWidth: MDLength.vp(20),\n        barActionIconHeight: MDLength.vp(20),\n        headerFont: {\n          fontSize: MDLength.vp(13),\n          fontColor: 0x999999,\n          fontWeight: FontWeight.Bold,\n        },\n        headerBackgroundColor: 0x0a1f3b63,\n        border: {\n          width: MDLength.vp(1),\n          color: 0x28333333,\n          radius: MDLength.vp(12),\n        }\n      },\n      math: {\n        cssFontSize: `${MDLength.vp2px(15).value}px`,\n        cssColor: '#333333',\n      },\n    };\n  }\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/theme/styling.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/**\n * 默认所有 Length 单位均为 vp\n */\n\nimport type { LengthMetrics } from '@kit.ArkUI';\nimport type { \n  IStyledTextValue, IStyledLetterSpacingValue, IStyledBaselineOffsetValue,\n  IStyledLineHeightValue, IStyledDecorationValue,\n  IStyledParagraphValue,\n  IStyledImageAttachmentValue,\n  IStyledBackgroundValue,\n} from '../render/styled/styled-value';\nimport type { IMDMargin } from '../util';\n\nexport interface IBorderStyling {\n  color?: ResourceColor;\n  width?: LengthMetrics;\n  radius?: LengthMetrics;\n}\nexport interface ISizeStyling {\n  height?: LengthMetrics;\n  width?: LengthMetrics;\n}\nexport interface ISpaceStyling extends ISizeStyling {}\nexport interface IStyling {}\nexport interface DocumentStyling extends IStyling {\n  width?: LengthMetrics;\n  letterSpacing?: IStyledLetterSpacingValue;\n  baselineOffset?: IStyledBaselineOffsetValue;\n  lineHeight?: IStyledLineHeightValue;\n  font?: IStyledTextValue;\n  blockSpace?: LengthMetrics;\n  more?: IStyledTextValue;\n}\n\nexport interface ParagraphStyling extends IStyling {\n}\nexport interface ThematicBreakStyling extends IStyling {\n  lineHeight?: IStyledLineHeightValue;\n  lineColor?: ResourceColor;\n}\nexport interface HeadingLevelStyling {\n  font?: IStyledTextValue;\n  lineHeight?: IStyledLineHeightValue;\n}\nexport interface HeadingStyling extends IStyling {\n  h1?: HeadingLevelStyling;\n  h2?: HeadingLevelStyling;\n  h3?: HeadingLevelStyling;\n  h4?: HeadingLevelStyling;\n  h5?: HeadingLevelStyling;\n  h6?: HeadingLevelStyling;\n}\nexport interface QuoteStyling extends IStyling {\n  contentParagraph?: IStyledParagraphValue;\n  font?: IStyledTextValue;\n  edgeWidth?: LengthMetrics;\n  edgeColor?: ResourceColor;\n}\nexport interface CodeStyling extends IStyling {}\nexport interface TableStyling extends IStyling {\n  headerFont?: IStyledTextValue;\n  headerBackgroundColor?: ResourceColor;\n  contentFont?: IStyledTextValue;\n  cellMaxWidth?: LengthMetrics;\n  cellMaxWidth4First?: LengthMetrics;\n  cellLineHeight?: IStyledLineHeightValue;\n}\nexport interface ListStyling extends IStyling {}\nexport interface ListItemStyling extends IStyling {\n  contentParagraph?: IStyledParagraphValue;\n  contentTopParagraph?: IStyledParagraphValue;\n  contentTopBoxWidth?: LengthMetrics;\n  contentTopBoxFont?: IStyledTextValue;\n  contentTopBoxRadius?: LengthMetrics;\n  contentTopBoxBackgroundColor?: ResourceColor;\n  contentTopBadgeWidth?: LengthMetrics;\n  contentTopBadgeBackgroundColor?: ResourceColor;\n  contentBadgeWidth?: LengthMetrics;\n  contentBadgeBackgroundColor?: ResourceColor;\n  taskFlagWidth?: LengthMetrics;\n  taskFlagColor?: ResourceColor;\n}\nexport interface HtmlTagStyling extends IStyling {}\nexport interface MathStyling extends IStyling {\n  cssFontSize?: string;\n  cssColor?: string;\n  cssMaxWidth?: string;\n  cssMaxHeight?: string;\n}\n\nexport interface TextStyling extends IStyling {}\nexport interface LineBreakStyling extends IStyling {}\nexport interface EmojiStyling extends IStyling {}\nexport interface StrongStyling extends IStyling {\n  font?: IStyledTextValue;\n}\nexport interface EmphasisStyling extends IStyling {\n  font?: IStyledTextValue;\n}\nexport interface StrikeThroughStyling extends IStyling {\n  decoration?: IStyledDecorationValue;\n}\nexport interface UnderlineStyling extends IStyling {\n  markHeight?: LengthMetrics;\n  markColor?: ResourceColor;\n}\nexport interface IconStyling extends IStyling {\n  size?: ISizeStyling;\n  content?: IStyledImageAttachmentValue;\n}\nexport interface ImageStyling extends IStyling {\n  size?: ISizeStyling;\n  content?: IStyledImageAttachmentValue;\n  border?: IBorderStyling;\n  background?: IStyledBackgroundValue;\n  textFont?: IStyledTextValue;\n  textBlock?: IStyledParagraphValue;\n  maxHeight?: LengthMetrics;\n}\nexport interface LinkStyling extends IStyling {\n  font?: IStyledTextValue;\n  iconSize?: ISizeStyling;\n  iconSpace?: ISpaceStyling;\n}\nexport interface FootnoteRefStyling extends IStyling {\n  font?: IStyledTextValue;\n  background?: IStyledBackgroundValue;\n  minSize?: ISizeStyling;\n}\nexport interface FootnoteDefStyling extends IStyling {}\nexport interface SuperscriptStyling extends IStyling {\n  font?: IStyledTextValue;\n}\nexport interface SubscriptStyling extends IStyling {\n  font?: IStyledTextValue;\n}\nexport interface InlineCodeStyling extends IStyling {\n  font?: IStyledTextValue;\n  background?: IStyledBackgroundValue;\n  contentPadding?: Padding;\n}\nexport interface ContentBoxStyling extends IStyling {\n  barMargin?: IMDMargin;\n  barFont?: IStyledTextValue;\n  barBackgroundColor?: ResourceColor;\n  barActionIconWidth?: LengthMetrics;\n  barActionIconHeight?: LengthMetrics;\n  headerFont?: IStyledTextValue;\n  headerBackgroundColor?: ResourceColor;\n  border?: IBorderStyling;\n}\n\nexport interface InlineStyling extends IStyling {}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/theme/theme.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/**\n * 默认所有 Length 单位均为 vp\n */\n\nimport * as S from './styling';\n\nexport interface ITheme {\n  document?: S.DocumentStyling;\n  paragraph?: S.ParagraphStyling;\n  thematicBreak?: S.ThematicBreakStyling;\n  heading?: S.HeadingStyling;\n  quote?: S.QuoteStyling;\n  code?: S.CodeStyling;\n  inlineCode?: S.InlineCodeStyling;\n  table?: S.TableStyling;\n  list?: S.ListStyling;\n  listItem?: S.ListItemStyling;\n  htmlTag?: S.HtmlTagStyling;\n  math?: S.MathStyling;\n  text?: S.TextStyling;\n  lineBreak?: S.LineBreakStyling;\n  emoji?: S.EmojiStyling;\n  strong?: S.StrongStyling;\n  emphasis?: S.EmphasisStyling;\n  strikeThrough?: S.StrikeThroughStyling;\n  underline?: S.UnderlineStyling;\n  image?: S.ImageStyling;\n  link?: S.LinkStyling;\n  icon?: S.IconStyling;\n  footnoteRef?: S.FootnoteRefStyling;\n  footnoteDef?: S.FootnoteDefStyling;\n  superscript?: S.SuperscriptStyling;\n  subscript?: S.SubscriptStyling;\n  inline?: S.InlineStyling;\n  contentBox?: S.ContentBoxStyling;\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/color.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { drawing } from '@kit.ArkGraphics2D';\nimport Common2D from '@ohos.graphics.common2D';\nimport Sys from '@ohos.deviceInfo';\nimport { ColorMetrics } from '@kit.ArkUI';\n\nexport abstract class MDColor {\n  static makeColorFromResourceColor(resourceColor: ResourceColor): Common2D.Color {\n    if (Sys.sdkApiVersion >= 15) {\n      return drawing.Tool.makeColorFromResourceColor(resourceColor);\n    } else {\n      return { red: 0, green: 0, blue: 0, alpha: 255 };\n    }\n  }\n  //  return 0xARGB\n  static toHex(color: ResourceColor): number {\n    try {\n      const metrics = ColorMetrics.resourceColor(color);\n      const r = metrics.red & 0xff;\n      const g = metrics.green & 0xff;\n      const b = metrics.blue & 0xff;\n      const a = metrics.alpha & 0xff;\n      return (a << 24) | (r << 16) | (g << 8) | b;\n    } catch (e) {\n      return 0x000000;\n    }\n  }\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/component.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\ninterface IComponentConstant {\n  THEME: string,\n  SHARED_ENGINE: string,\n}\nexport const K_COMPONENT: IComponentConstant = {\n  THEME: '__const.component.theme',\n  SHARED_ENGINE: '__const.component.engine',\n};\nexport enum EMarkdownMode {\n  Normal = 'normal',\n  Typing = 'typing',\n}\nexport enum EMarkdownMainBotEvent {\n  ScrollBegin = 'mainBotScrollBegin',\n  ScrollEnd = 'mainBotScrollEnd',\n  StopTyping = 'mainBotStopTyping',\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/crypto.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { cryptoFramework } from '@kit.CryptoArchitectureKit';\nimport { buffer } from '@kit.ArkTS';\n\nexport abstract class MDCrypto {\n  static async md5(content?: string): Promise<string | undefined> {\n    if (content) {\n      try {\n        const hash = cryptoFramework.createMd('MD5');\n        await hash.update({\n          data: new Uint8Array(buffer.from(content, 'utf-8').buffer)\n        });\n        return Array.from( (await hash.digest()).data )\n          .map(ele => ele.toString(16).padStart(2, '0'))\n          .join('');\n      } catch (e) {\n        return undefined;\n      }\n    }\n    return undefined;\n  }\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/dom.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport namespace DOM {\n  export interface Node {}\n  export interface Element extends Node {\n\n  }\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/error.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\ninterface IMDError {\n  message?: string;\n  code?: number;\n  domain?: string;\n}\nexport class MDError extends Error {\n  private  option?: IMDError;\n  constructor(option?: IMDError) {\n    super(option?.message);\n    this.option = option;\n  }\n  get code() {\n    return this.option?.code;\n  }\n  get domain() {\n    return this.option?.domain;\n  }\n}\nexport interface IMDResult<T> {\n  data?: T;\n  error?: MDError;\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/event.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\ntype Any = string | number | boolean | object;\ntype Callback = <T>(param?: T) => void;\n\nexport class Event {\n  private listeners: Record<string, Callback[]> = {};\n\n  public on<T>(event: string, listener: (param?: T) => void) {\n    if (!this.listeners[event]) {\n      this.listeners[event] = [];\n    }\n    this.listeners[event].push(listener as Callback);\n  }\n\n  protected emit<T>(event: string, param?: T) {\n    if (this.listeners[event]) {\n      this.listeners[event].forEach((listener) => listener(param));\n    }\n  }\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nexport * from './log';\nexport * from './dom';\nexport * from './event';\nexport * from './component';\nexport * from './layout';\nexport * from './crypto';\nexport * from './error';\nexport * from './color';\nexport * from './uuid';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/layout.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { LengthMetrics, display, LengthUnit } from \"@kit.ArkUI\";\nimport { newLog } from './log';\n\nconst log = newLog('LayoutUtil');\n\nexport abstract class MDLength {\n  private static get density() {\n    try {\n      return display.getDefaultDisplaySync().densityDPI / 160;\n    } catch (e) {\n      log.w(`get density error: ${e?.message}`);\n      return 1;\n    }\n  }\n  static px2vp(px: number): LengthMetrics {\n    return LengthMetrics.vp(px / MDLength.density);\n  }\n  static vp2px(vp: number): LengthMetrics {\n    return LengthMetrics.px(vp * MDLength.density);\n  }\n  static vp(vp: number): LengthMetrics {\n    return LengthMetrics.vp(vp);\n  }\n  static px(px: number): LengthMetrics {\n    return LengthMetrics.px(px);\n  }\n  static metrics2length(metrics: LengthMetrics): Length {\n    if (metrics.unit === LengthUnit.PX) {\n      return `${metrics.value}px`;\n    } else if (metrics.unit === LengthUnit.VP) {\n      return `${metrics.value}vp`;\n    } else if (metrics.unit === LengthUnit.FP) {\n      return `${metrics.value}fp`;\n    } else if (metrics.unit === LengthUnit.LPX) {\n      return `${metrics.value}lpx`;\n    } else if (metrics.unit === LengthUnit.PERCENT) {\n      return `${metrics.value}%`;\n    }\n    throw Error(`unsupported Length Unit: ${metrics.unit}`);\n  }\n  static length2metrics(len: Length): LengthMetrics {\n    if (typeof len === 'number') {\n      return MDLength.vp(len);\n    } else if (typeof len === 'string') {\n      if (/px$/.test(len)) {\n        return LengthMetrics.px(Number(len.slice(0, -2)));\n      } else if (/vp$/.test(len)) {\n        return LengthMetrics.vp(Number(len.slice(0, -2)));\n      } else if (/fp$/.test(len)) {\n        return LengthMetrics.fp(Number(len.slice(0, -2)))\n      } else if (/lpx$/.test(len)) {\n        return LengthMetrics.lpx(Number(len.slice(0, -3)))\n      } else if (/%$/.test(len)) {\n        return LengthMetrics.percent(Number(len.slice(0, -1)));\n      }\n    }\n    throw Error(`unsupported Length value: ${len}`);\n  }\n  static length2vp(len: Length): LengthMetrics {\n    const metrics = MDLength.length2metrics(len);\n    if (metrics.unit === LengthUnit.PX) {\n      return MDLength.px2vp(metrics.value);\n    } else if (metrics.unit === LengthUnit.VP) {\n      return metrics;\n    }\n    throw Error(`unsupported Length Unit: ${metrics.unit}`);\n  }\n  static baselineOffsetVP(sizeVP: number, ratio: number = 1/4): LengthMetrics {\n    return MDLength.vp(sizeVP * ratio);\n  }\n  static metricsEqual(value?: LengthMetrics, other?: LengthMetrics) {\n    if (value && other) {\n      return MDLength.metrics2length(value) === MDLength.metrics2length(other);\n    }\n    if (!value && !other) {\n      return true;\n    }\n    return false;\n  }\n}\n\nexport interface IMDArea {\n  width?: LengthMetrics;\n  height?: LengthMetrics;\n}\nexport abstract class MDArea {\n  static area(_area: Area): IMDArea {\n    return {\n      width: MDLength.length2metrics(_area.width),\n      height: MDLength.length2metrics(_area.height),\n    }\n  }\n  static metrics2area(spanMetrics: CustomSpanMetrics): IMDArea {\n    return {\n      width: MDLength.vp(spanMetrics.width),\n      height: spanMetrics.height !== undefined ? MDLength.vp(spanMetrics.height) : undefined,\n    }\n  }\n  static area2metrics(area: IMDArea): CustomSpanMetrics {\n    return {\n      width: area.width ? MDLength.length2vp(MDLength.metrics2length(area.width)).value : 0,\n      height: area.height ? MDLength.length2vp(MDLength.metrics2length(area.height)).value : undefined,\n    }\n  }\n  static isEmpty(area?: IMDArea): boolean {\n    return !area || (area.width === undefined && area.height === undefined);\n  }\n  static isAreaContainFinger(area?: Area, finger?: FingerInfo): boolean {\n    if (area && finger) {\n      const finger_x = MDLength.px2vp(finger.globalX);\n      const finger_y = MDLength.px2vp(finger.globalY);\n      if (area.globalPosition.x && area.globalPosition.y) {\n        const area_x = MDLength.length2vp(area.globalPosition.x);\n        const area_y = MDLength.length2vp(area.globalPosition.y);\n        const area_w = MDLength.length2vp(area.width);\n        const area_h = MDLength.length2vp(area.height);\n        if (finger_x.value >= area_x.value && finger_x.value <= area_x.value + area_w.value) {\n          if (finger_y.value >= area_y.value && finger_y.value <= area_y.value + area_h.value) {\n            return true;\n          }\n        }\n      }\n    }\n    return false;\n  }\n  static mdAreaEqual(value?: IMDArea, other?: IMDArea) {\n    if (value && other) {\n      return MDLength.metricsEqual(value.width, other.width) && MDLength.metricsEqual(value.height, other.height);\n    }\n    if (!value && !other) {\n      return true;\n    }\n    return false;\n  }\n}\n\nexport abstract class MDPosition {\n  static spanMetrics2position(spanMetrics?: CustomSpanMetrics): Position {\n    return {\n      x: spanMetrics?.width !== undefined ? MDLength.metrics2length(MDLength.vp(spanMetrics.width)) : undefined,\n      y: spanMetrics?.height !== undefined ? MDLength.metrics2length(MDLength.vp(spanMetrics.height)) : undefined,\n    };\n  }\n}\n\nexport abstract class MDMargin {\n  static lengthMargin(margin: IMDMargin): Margin {\n    return {\n      top: margin.top ? MDLength.metrics2length(margin.top) : undefined,\n      left: margin.left ? MDLength.metrics2length(margin.left) : undefined,\n      right: margin.right ? MDLength.metrics2length(margin.right) : undefined,\n      bottom: margin.bottom ? MDLength.metrics2length(margin.bottom) : undefined,\n    };\n  }\n  static lengthPadding(padding: IMDMargin): Padding {\n    return MDMargin.lengthMargin(padding);\n  }\n}\nexport interface IMDMargin {\n  left?: LengthMetrics;\n  top?: LengthMetrics;\n  right?: LengthMetrics;\n  bottom?: LengthMetrics;\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/log.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\nimport { hilog } from \"@kit.PerformanceAnalysisKit\";\n\nconst TAG = '[markdown]';\nconst DOMAIN = 0x0001;\ntype Any = string | number | null | undefined | boolean | object;\n\ninterface ILog {\n  d: (format: string, ...args: Any[]) => void,\n  i: (format: string, ...args: Any[]) => void,\n  w: (format: string, ...args: Any[]) => void,\n  e: (format: string, ...args: Any[]) => void,\n  tag: (tag: string, freeze?: boolean) => ILog,\n  domain: (domain: number, freeze?: boolean) => ILog,\n}\n\ninterface ILogInfo {\n  domain: number,\n  tag: string,\n  format: string,\n  args: Any[],\n  isHilog: boolean,\n}\nexport enum ELog {\n  Debug = 'debug',\n  Info = 'info',\n  Warn = 'warn',\n  Error = 'error',\n}\nexport class Log implements ILog {\n  private _tag_default: string = TAG;\n  private _domain_default: number = DOMAIN;\n  private _tag: string = TAG;\n  private _domain: number = DOMAIN;\n  private reset() {\n    this._tag = this._tag_default;\n    this._domain = this._domain_default;\n  }\n  private static __on?: (level: ELog, message: string, info: ILogInfo) => boolean | void;\n  private static _on(isHilog: boolean, level: ELog, domain: number, tag: string, format: string, ...args: Any[]): boolean {\n    if (Log.__on) {\n      let message = `[fluid-markdown|${tag}] ${format}`;\n      args.forEach(ele => {\n        message += ` ${ele}`;\n      });\n      const should = Log.__on(level, message, { domain, tag, format, args, isHilog });\n      if (typeof should === 'boolean') {\n        return should;\n      }\n    }\n    return true;\n  }\n  /**\n   * handle log\n   * @param handler return true to enable fluid-markdown output message, false to disable. default is true.\n   */\n  static set on(handler: (level: ELog, message: string, info: ILogInfo) => boolean | void) {\n    if (!Log.__on) {\n      Log.__on = handler;\n    }\n  }\n\n  _d(...args: Any[]) {\n    console.debug(this._tag, ...args);\n    this.reset();\n  }\n  _i(...args: Any[]) {\n    console.info(this._tag, ...args);\n    this.reset();\n  }\n  _w(...args: Any[]) {\n    console.warn(this._tag, ...args);\n    this.reset();\n  }\n  _e(...args: Any[]) {\n    console.error(this._tag, ...args);\n    this.reset();\n  }\n  d(format: string, ...args: Any[]) {\n    if (Log._on(true, ELog.Debug, this._domain, this._tag, format, ...args)) {\n      hilog.debug(this._domain, this._tag, format, ...args);\n    }\n    this.reset();\n  }\n  i(format: string, ...args: Any[]) {\n    if (Log._on(true, ELog.Info, this._domain, this._tag, format, ...args)) {\n      hilog.info(this._domain, this._tag, format, ...args);\n    }\n    this.reset();\n  }\n  w(format: string, ...args: Any[]) {\n    if (Log._on(true, ELog.Warn, this._domain, this._tag, format, ...args)) {\n      hilog.warn(this._domain, this._tag, format, ...args);\n    }\n    this.reset();\n  }\n  e(format: string, ...args: Any[]) {\n    if (Log._on(true, ELog.Error, this._domain, this._tag, format, ...args)) {\n      hilog.error(this._domain, this._tag, format, ...args);\n    }\n    this.reset();\n  }\n  tag(tag: string, freeze: boolean = false) {\n    this._tag = tag;\n    if (freeze) {\n      this._tag_default = tag;\n    }\n    return this;\n  }\n  domain(domain: number, freeze: boolean = false) {\n    this._domain = domain;\n    if (freeze) {\n      this._domain_default = domain;\n    }\n    return this;\n  }\n}\n\nexport const log = new Log();\nexport const newLog = (tag?: string, domain?: number) => {\n  const _log = new Log();\n  if (tag) {\n    _log.tag(tag, true);\n  }\n  if (domain !== undefined) {\n    _log.domain(domain, true);\n  }\n  return _log;\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/uuid/index.ets",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n/**\n * uuid\n * @home   : https://github.com/uuidjs/uuid\n * @branch : master\n * @commit : 0423d49df2dc8efc300c804731d25f4d7e0fccc4\n */\n\nimport * as UUID from './src';\n\nexport abstract class MDUuid {\n  static md5(content: string): string {\n    return UUID.v5(content, UUID.NIL);\n  }\n}\n\nexport * from './src';"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/uuid/src/index.js",
    "content": "export { default as MAX } from './max.js';\nexport { default as NIL } from './nil.js';\nexport { default as parse } from './parse.js';\nexport { default as stringify } from './stringify.js';\nexport { default as v1 } from './v1.js';\nexport { default as v1ToV6 } from './v1ToV6.js';\nexport { default as v3 } from './v3.js';\nexport { default as v4 } from './v4.js';\nexport { default as v5 } from './v5.js';\nexport { default as v6 } from './v6.js';\nexport { default as v6ToV1 } from './v6ToV1.js';\nexport { default as v7 } from './v7.js';\nexport { default as validate } from './validate.js';\nexport { default as version } from './version.js';\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/uuid/src/max.js",
    "content": "export default 'ffffffff-ffff-ffff-ffff-ffffffffffff';\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/uuid/src/md5.js",
    "content": "function md5(bytes) {\n    const words = uint8ToUint32(bytes);\n    const md5Bytes = wordsToMd5(words, bytes.length * 8);\n    return uint32ToUint8(md5Bytes);\n}\nfunction uint32ToUint8(input) {\n    const bytes = new Uint8Array(input.length * 4);\n    for (let i = 0; i < input.length * 4; i++) {\n        bytes[i] = (input[i >> 2] >>> ((i % 4) * 8)) & 0xff;\n    }\n    return bytes;\n}\nfunction getOutputLength(inputLength8) {\n    return (((inputLength8 + 64) >>> 9) << 4) + 14 + 1;\n}\nfunction wordsToMd5(x, len) {\n    const xpad = new Uint32Array(getOutputLength(len)).fill(0);\n    xpad.set(x);\n    xpad[len >> 5] |= 0x80 << len % 32;\n    xpad[xpad.length - 1] = len;\n    x = xpad;\n    let a = 1732584193;\n    let b = -271733879;\n    let c = -1732584194;\n    let d = 271733878;\n    for (let i = 0; i < x.length; i += 16) {\n        const olda = a;\n        const oldb = b;\n        const oldc = c;\n        const oldd = d;\n        a = md5ff(a, b, c, d, x[i], 7, -680876936);\n        d = md5ff(d, a, b, c, x[i + 1], 12, -389564586);\n        c = md5ff(c, d, a, b, x[i + 2], 17, 606105819);\n        b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330);\n        a = md5ff(a, b, c, d, x[i + 4], 7, -176418897);\n        d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426);\n        c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341);\n        b = md5ff(b, c, d, a, x[i + 7], 22, -45705983);\n        a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416);\n        d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417);\n        c = md5ff(c, d, a, b, x[i + 10], 17, -42063);\n        b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162);\n        a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682);\n        d = md5ff(d, a, b, c, x[i + 13], 12, -40341101);\n        c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290);\n        b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329);\n        a = md5gg(a, b, c, d, x[i + 1], 5, -165796510);\n        d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632);\n        c = md5gg(c, d, a, b, x[i + 11], 14, 643717713);\n        b = md5gg(b, c, d, a, x[i], 20, -373897302);\n        a = md5gg(a, b, c, d, x[i + 5], 5, -701558691);\n        d = md5gg(d, a, b, c, x[i + 10], 9, 38016083);\n        c = md5gg(c, d, a, b, x[i + 15], 14, -660478335);\n        b = md5gg(b, c, d, a, x[i + 4], 20, -405537848);\n        a = md5gg(a, b, c, d, x[i + 9], 5, 568446438);\n        d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690);\n        c = md5gg(c, d, a, b, x[i + 3], 14, -187363961);\n        b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501);\n        a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467);\n        d = md5gg(d, a, b, c, x[i + 2], 9, -51403784);\n        c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473);\n        b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734);\n        a = md5hh(a, b, c, d, x[i + 5], 4, -378558);\n        d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463);\n        c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562);\n        b = md5hh(b, c, d, a, x[i + 14], 23, -35309556);\n        a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060);\n        d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353);\n        c = md5hh(c, d, a, b, x[i + 7], 16, -155497632);\n        b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640);\n        a = md5hh(a, b, c, d, x[i + 13], 4, 681279174);\n        d = md5hh(d, a, b, c, x[i], 11, -358537222);\n        c = md5hh(c, d, a, b, x[i + 3], 16, -722521979);\n        b = md5hh(b, c, d, a, x[i + 6], 23, 76029189);\n        a = md5hh(a, b, c, d, x[i + 9], 4, -640364487);\n        d = md5hh(d, a, b, c, x[i + 12], 11, -421815835);\n        c = md5hh(c, d, a, b, x[i + 15], 16, 530742520);\n        b = md5hh(b, c, d, a, x[i + 2], 23, -995338651);\n        a = md5ii(a, b, c, d, x[i], 6, -198630844);\n        d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415);\n        c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905);\n        b = md5ii(b, c, d, a, x[i + 5], 21, -57434055);\n        a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571);\n        d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606);\n        c = md5ii(c, d, a, b, x[i + 10], 15, -1051523);\n        b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799);\n        a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359);\n        d = md5ii(d, a, b, c, x[i + 15], 10, -30611744);\n        c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380);\n        b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649);\n        a = md5ii(a, b, c, d, x[i + 4], 6, -145523070);\n        d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379);\n        c = md5ii(c, d, a, b, x[i + 2], 15, 718787259);\n        b = md5ii(b, c, d, a, x[i + 9], 21, -343485551);\n        a = safeAdd(a, olda);\n        b = safeAdd(b, oldb);\n        c = safeAdd(c, oldc);\n        d = safeAdd(d, oldd);\n    }\n    return Uint32Array.of(a, b, c, d);\n}\nfunction uint8ToUint32(input) {\n    if (input.length === 0) {\n        return new Uint32Array();\n    }\n    const output = new Uint32Array(getOutputLength(input.length * 8)).fill(0);\n    for (let i = 0; i < input.length; i++) {\n        output[i >> 2] |= (input[i] & 0xff) << ((i % 4) * 8);\n    }\n    return output;\n}\nfunction safeAdd(x, y) {\n    const lsw = (x & 0xffff) + (y & 0xffff);\n    const msw = (x >> 16) + (y >> 16) + (lsw >> 16);\n    return (msw << 16) | (lsw & 0xffff);\n}\nfunction bitRotateLeft(num, cnt) {\n    return (num << cnt) | (num >>> (32 - cnt));\n}\nfunction md5cmn(q, a, b, x, s, t) {\n    return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b);\n}\nfunction md5ff(a, b, c, d, x, s, t) {\n    return md5cmn((b & c) | (~b & d), a, b, x, s, t);\n}\nfunction md5gg(a, b, c, d, x, s, t) {\n    return md5cmn((b & d) | (c & ~d), a, b, x, s, t);\n}\nfunction md5hh(a, b, c, d, x, s, t) {\n    return md5cmn(b ^ c ^ d, a, b, x, s, t);\n}\nfunction md5ii(a, b, c, d, x, s, t) {\n    return md5cmn(c ^ (b | ~d), a, b, x, s, t);\n}\nexport default md5;\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/uuid/src/native.js",
    "content": "const randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto);\nexport default { randomUUID };\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/uuid/src/nil.js",
    "content": "export default '00000000-0000-0000-0000-000000000000';\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/uuid/src/parse.js",
    "content": "import validate from './validate.js';\nfunction parse(uuid) {\n    if (!validate(uuid)) {\n        throw TypeError('Invalid UUID');\n    }\n    let v;\n    return Uint8Array.of((v = parseInt(uuid.slice(0, 8), 16)) >>> 24, (v >>> 16) & 0xff, (v >>> 8) & 0xff, v & 0xff, (v = parseInt(uuid.slice(9, 13), 16)) >>> 8, v & 0xff, (v = parseInt(uuid.slice(14, 18), 16)) >>> 8, v & 0xff, (v = parseInt(uuid.slice(19, 23), 16)) >>> 8, v & 0xff, ((v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000) & 0xff, (v / 0x100000000) & 0xff, (v >>> 24) & 0xff, (v >>> 16) & 0xff, (v >>> 8) & 0xff, v & 0xff);\n}\nexport default parse;\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/uuid/src/regex.js",
    "content": "export default /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i;\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/uuid/src/rng.js",
    "content": "let getRandomValues;\nconst rnds8 = new Uint8Array(16);\nexport default function rng() {\n    if (!getRandomValues) {\n        if (typeof crypto === 'undefined' || !crypto.getRandomValues) {\n            throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');\n        }\n        getRandomValues = crypto.getRandomValues.bind(crypto);\n    }\n    return getRandomValues(rnds8);\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/uuid/src/sha1.js",
    "content": "function f(s, x, y, z) {\n    switch (s) {\n        case 0:\n            return (x & y) ^ (~x & z);\n        case 1:\n            return x ^ y ^ z;\n        case 2:\n            return (x & y) ^ (x & z) ^ (y & z);\n        case 3:\n            return x ^ y ^ z;\n    }\n}\nfunction ROTL(x, n) {\n    return (x << n) | (x >>> (32 - n));\n}\nfunction sha1(bytes) {\n    const K = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6];\n    const H = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0];\n    const newBytes = new Uint8Array(bytes.length + 1);\n    newBytes.set(bytes);\n    newBytes[bytes.length] = 0x80;\n    bytes = newBytes;\n    const l = bytes.length / 4 + 2;\n    const N = Math.ceil(l / 16);\n    const M = new Array(N);\n    for (let i = 0; i < N; ++i) {\n        const arr = new Uint32Array(16);\n        for (let j = 0; j < 16; ++j) {\n            arr[j] =\n                (bytes[i * 64 + j * 4] << 24) |\n                    (bytes[i * 64 + j * 4 + 1] << 16) |\n                    (bytes[i * 64 + j * 4 + 2] << 8) |\n                    bytes[i * 64 + j * 4 + 3];\n        }\n        M[i] = arr;\n    }\n    M[N - 1][14] = ((bytes.length - 1) * 8) / Math.pow(2, 32);\n    M[N - 1][14] = Math.floor(M[N - 1][14]);\n    M[N - 1][15] = ((bytes.length - 1) * 8) & 0xffffffff;\n    for (let i = 0; i < N; ++i) {\n        const W = new Uint32Array(80);\n        for (let t = 0; t < 16; ++t) {\n            W[t] = M[i][t];\n        }\n        for (let t = 16; t < 80; ++t) {\n            W[t] = ROTL(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1);\n        }\n        let a = H[0];\n        let b = H[1];\n        let c = H[2];\n        let d = H[3];\n        let e = H[4];\n        for (let t = 0; t < 80; ++t) {\n            const s = Math.floor(t / 20);\n            const T = (ROTL(a, 5) + f(s, b, c, d) + e + K[s] + W[t]) >>> 0;\n            e = d;\n            d = c;\n            c = ROTL(b, 30) >>> 0;\n            b = a;\n            a = T;\n        }\n        H[0] = (H[0] + a) >>> 0;\n        H[1] = (H[1] + b) >>> 0;\n        H[2] = (H[2] + c) >>> 0;\n        H[3] = (H[3] + d) >>> 0;\n        H[4] = (H[4] + e) >>> 0;\n    }\n    return Uint8Array.of(H[0] >> 24, H[0] >> 16, H[0] >> 8, H[0], H[1] >> 24, H[1] >> 16, H[1] >> 8, H[1], H[2] >> 24, H[2] >> 16, H[2] >> 8, H[2], H[3] >> 24, H[3] >> 16, H[3] >> 8, H[3], H[4] >> 24, H[4] >> 16, H[4] >> 8, H[4]);\n}\nexport default sha1;\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/uuid/src/stringify.js",
    "content": "import validate from './validate.js';\nconst byteToHex = [];\nfor (let i = 0; i < 256; ++i) {\n    byteToHex.push((i + 0x100).toString(16).slice(1));\n}\nexport function unsafeStringify(arr, offset = 0) {\n    return (byteToHex[arr[offset + 0]] +\n        byteToHex[arr[offset + 1]] +\n        byteToHex[arr[offset + 2]] +\n        byteToHex[arr[offset + 3]] +\n        '-' +\n        byteToHex[arr[offset + 4]] +\n        byteToHex[arr[offset + 5]] +\n        '-' +\n        byteToHex[arr[offset + 6]] +\n        byteToHex[arr[offset + 7]] +\n        '-' +\n        byteToHex[arr[offset + 8]] +\n        byteToHex[arr[offset + 9]] +\n        '-' +\n        byteToHex[arr[offset + 10]] +\n        byteToHex[arr[offset + 11]] +\n        byteToHex[arr[offset + 12]] +\n        byteToHex[arr[offset + 13]] +\n        byteToHex[arr[offset + 14]] +\n        byteToHex[arr[offset + 15]]).toLowerCase();\n}\nfunction stringify(arr, offset = 0) {\n    const uuid = unsafeStringify(arr, offset);\n    if (!validate(uuid)) {\n        throw TypeError('Stringified UUID is invalid');\n    }\n    return uuid;\n}\nexport default stringify;\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/uuid/src/types.js",
    "content": "export {};\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/uuid/src/uuid-bin.js",
    "content": "// import * as assert from 'node:assert/strict';\nimport v1 from './v1.js';\nimport v3 from './v3.js';\nimport v4 from './v4.js';\nimport v5 from './v5.js';\nimport v6 from './v6.js';\nimport v7 from './v7.js';\nfunction usage() {\n    console.log('Usage:');\n    console.log('  uuid');\n    console.log('  uuid v1');\n    console.log('  uuid v3 <name> <namespace uuid>');\n    console.log('  uuid v4');\n    console.log('  uuid v5 <name> <namespace uuid>');\n    console.log('  uuid v6');\n    console.log('  uuid v7');\n    console.log('  uuid --help');\n    console.log('\\nNote: <namespace uuid> may be \"URL\" or \"DNS\" to use the corresponding UUIDs defined by RFC9562');\n}\nconst args = process.argv.slice(2);\nif (args.indexOf('--help') >= 0) {\n    usage();\n    process.exit(0);\n}\nconst version = args.shift() || 'v4';\nswitch (version) {\n    case 'v1':\n        console.log(v1());\n        break;\n    case 'v3': {\n        const name = args.shift();\n        let namespace = args.shift();\n        // assert.ok(name != null, 'v3 name not specified');\n        // assert.ok(namespace != null, 'v3 namespace not specified');\n        if (namespace === 'URL') {\n            namespace = v3.URL;\n        }\n        if (namespace === 'DNS') {\n            namespace = v3.DNS;\n        }\n        console.log(v3(name, namespace));\n        break;\n    }\n    case 'v4':\n        console.log(v4());\n        break;\n    case 'v5': {\n        const name = args.shift();\n        let namespace = args.shift();\n        // assert.ok(name != null, 'v5 name not specified');\n        // assert.ok(namespace != null, 'v5 namespace not specified');\n        if (namespace === 'URL') {\n            namespace = v5.URL;\n        }\n        if (namespace === 'DNS') {\n            namespace = v5.DNS;\n        }\n        console.log(v5(name, namespace));\n        break;\n    }\n    case 'v6':\n        console.log(v6());\n        break;\n    case 'v7':\n        console.log(v7());\n        break;\n    default:\n        usage();\n        process.exit(1);\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/uuid/src/v1.js",
    "content": "import rng from './rng.js';\nimport { unsafeStringify } from './stringify.js';\nconst _state = {};\nfunction v1(options, buf, offset) {\n    let bytes;\n    const isV6 = options?._v6 ?? false;\n    if (options) {\n        const optionsKeys = Object.keys(options);\n        if (optionsKeys.length === 1 && optionsKeys[0] === '_v6') {\n            options = undefined;\n        }\n    }\n    if (options) {\n        bytes = v1Bytes(options.random ?? options.rng?.() ?? rng(), options.msecs, options.nsecs, options.clockseq, options.node, buf, offset);\n    }\n    else {\n        const now = Date.now();\n        const rnds = rng();\n        updateV1State(_state, now, rnds);\n        bytes = v1Bytes(rnds, _state.msecs, _state.nsecs, isV6 ? undefined : _state.clockseq, isV6 ? undefined : _state.node, buf, offset);\n    }\n    return buf ?? unsafeStringify(bytes);\n}\nexport function updateV1State(state, now, rnds) {\n    state.msecs ??= -Infinity;\n    state.nsecs ??= 0;\n    if (now === state.msecs) {\n        state.nsecs++;\n        if (state.nsecs >= 10000) {\n            state.node = undefined;\n            state.nsecs = 0;\n        }\n    }\n    else if (now > state.msecs) {\n        state.nsecs = 0;\n    }\n    else if (now < state.msecs) {\n        state.node = undefined;\n    }\n    if (!state.node) {\n        state.node = rnds.slice(10, 16);\n        state.node[0] |= 0x01;\n        state.clockseq = ((rnds[8] << 8) | rnds[9]) & 0x3fff;\n    }\n    state.msecs = now;\n    return state;\n}\nfunction v1Bytes(rnds, msecs, nsecs, clockseq, node, buf, offset = 0) {\n    if (rnds.length < 16) {\n        throw new Error('Random bytes length must be >= 16');\n    }\n    if (!buf) {\n        buf = new Uint8Array(16);\n        offset = 0;\n    }\n    else {\n        if (offset < 0 || offset + 16 > buf.length) {\n            throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);\n        }\n    }\n    msecs ??= Date.now();\n    nsecs ??= 0;\n    clockseq ??= ((rnds[8] << 8) | rnds[9]) & 0x3fff;\n    node ??= rnds.slice(10, 16);\n    msecs += 12219292800000;\n    const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;\n    buf[offset++] = (tl >>> 24) & 0xff;\n    buf[offset++] = (tl >>> 16) & 0xff;\n    buf[offset++] = (tl >>> 8) & 0xff;\n    buf[offset++] = tl & 0xff;\n    const tmh = ((msecs / 0x100000000) * 10000) & 0xfffffff;\n    buf[offset++] = (tmh >>> 8) & 0xff;\n    buf[offset++] = tmh & 0xff;\n    buf[offset++] = ((tmh >>> 24) & 0xf) | 0x10;\n    buf[offset++] = (tmh >>> 16) & 0xff;\n    buf[offset++] = (clockseq >>> 8) | 0x80;\n    buf[offset++] = clockseq & 0xff;\n    for (let n = 0; n < 6; ++n) {\n        buf[offset++] = node[n];\n    }\n    return buf;\n}\nexport default v1;\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/uuid/src/v1ToV6.js",
    "content": "import parse from './parse.js';\nimport { unsafeStringify } from './stringify.js';\nexport default function v1ToV6(uuid) {\n    const v1Bytes = typeof uuid === 'string' ? parse(uuid) : uuid;\n    const v6Bytes = _v1ToV6(v1Bytes);\n    return typeof uuid === 'string' ? unsafeStringify(v6Bytes) : v6Bytes;\n}\nfunction _v1ToV6(v1Bytes) {\n    return Uint8Array.of(((v1Bytes[6] & 0x0f) << 4) | ((v1Bytes[7] >> 4) & 0x0f), ((v1Bytes[7] & 0x0f) << 4) | ((v1Bytes[4] & 0xf0) >> 4), ((v1Bytes[4] & 0x0f) << 4) | ((v1Bytes[5] & 0xf0) >> 4), ((v1Bytes[5] & 0x0f) << 4) | ((v1Bytes[0] & 0xf0) >> 4), ((v1Bytes[0] & 0x0f) << 4) | ((v1Bytes[1] & 0xf0) >> 4), ((v1Bytes[1] & 0x0f) << 4) | ((v1Bytes[2] & 0xf0) >> 4), 0x60 | (v1Bytes[2] & 0x0f), v1Bytes[3], v1Bytes[8], v1Bytes[9], v1Bytes[10], v1Bytes[11], v1Bytes[12], v1Bytes[13], v1Bytes[14], v1Bytes[15]);\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/uuid/src/v3.js",
    "content": "import md5 from './md5.js';\nimport v35, { DNS, URL } from './v35.js';\nexport { DNS, URL } from './v35.js';\nfunction v3(value, namespace, buf, offset) {\n    return v35(0x30, md5, value, namespace, buf, offset);\n}\nv3.DNS = DNS;\nv3.URL = URL;\nexport default v3;\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/uuid/src/v35.js",
    "content": "import parse from './parse.js';\nimport { unsafeStringify } from './stringify.js';\nexport function stringToBytes(str) {\n    str = unescape(encodeURIComponent(str));\n    const bytes = new Uint8Array(str.length);\n    for (let i = 0; i < str.length; ++i) {\n        bytes[i] = str.charCodeAt(i);\n    }\n    return bytes;\n}\nexport const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';\nexport const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8';\nexport default function v35(version, hash, value, namespace, buf, offset) {\n    const valueBytes = typeof value === 'string' ? stringToBytes(value) : value;\n    const namespaceBytes = typeof namespace === 'string' ? parse(namespace) : namespace;\n    if (typeof namespace === 'string') {\n        namespace = parse(namespace);\n    }\n    if (namespace?.length !== 16) {\n        throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)');\n    }\n    let bytes = new Uint8Array(16 + valueBytes.length);\n    bytes.set(namespaceBytes);\n    bytes.set(valueBytes, namespaceBytes.length);\n    bytes = hash(bytes);\n    bytes[6] = (bytes[6] & 0x0f) | version;\n    bytes[8] = (bytes[8] & 0x3f) | 0x80;\n    if (buf) {\n        offset = offset || 0;\n        for (let i = 0; i < 16; ++i) {\n            buf[offset + i] = bytes[i];\n        }\n        return buf;\n    }\n    return unsafeStringify(bytes);\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/uuid/src/v4.js",
    "content": "import native from './native.js';\nimport rng from './rng.js';\nimport { unsafeStringify } from './stringify.js';\nfunction _v4(options, buf, offset) {\n    options = options || {};\n    const rnds = options.random ?? options.rng?.() ?? rng();\n    if (rnds.length < 16) {\n        throw new Error('Random bytes length must be >= 16');\n    }\n    rnds[6] = (rnds[6] & 0x0f) | 0x40;\n    rnds[8] = (rnds[8] & 0x3f) | 0x80;\n    if (buf) {\n        offset = offset || 0;\n        if (offset < 0 || offset + 16 > buf.length) {\n            throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);\n        }\n        for (let i = 0; i < 16; ++i) {\n            buf[offset + i] = rnds[i];\n        }\n        return buf;\n    }\n    return unsafeStringify(rnds);\n}\nfunction v4(options, buf, offset) {\n    if (native.randomUUID && !buf && !options) {\n        return native.randomUUID();\n    }\n    return _v4(options, buf, offset);\n}\nexport default v4;\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/uuid/src/v5.js",
    "content": "import sha1 from './sha1.js';\nimport v35, { DNS, URL } from './v35.js';\nexport { DNS, URL } from './v35.js';\nfunction v5(value, namespace, buf, offset) {\n    return v35(0x50, sha1, value, namespace, buf, offset);\n}\nv5.DNS = DNS;\nv5.URL = URL;\nexport default v5;\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/uuid/src/v6.js",
    "content": "import { unsafeStringify } from './stringify.js';\nimport v1 from './v1.js';\nimport v1ToV6 from './v1ToV6.js';\nfunction v6(options, buf, offset) {\n    options ??= {};\n    offset ??= 0;\n    let bytes = v1({ ...options, _v6: true }, new Uint8Array(16));\n    bytes = v1ToV6(bytes);\n    if (buf) {\n        for (let i = 0; i < 16; i++) {\n            buf[offset + i] = bytes[i];\n        }\n        return buf;\n    }\n    return unsafeStringify(bytes);\n}\nexport default v6;\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/uuid/src/v6ToV1.js",
    "content": "import parse from './parse.js';\nimport { unsafeStringify } from './stringify.js';\nexport default function v6ToV1(uuid) {\n    const v6Bytes = typeof uuid === 'string' ? parse(uuid) : uuid;\n    const v1Bytes = _v6ToV1(v6Bytes);\n    return typeof uuid === 'string' ? unsafeStringify(v1Bytes) : v1Bytes;\n}\nfunction _v6ToV1(v6Bytes) {\n    return Uint8Array.of(((v6Bytes[3] & 0x0f) << 4) | ((v6Bytes[4] >> 4) & 0x0f), ((v6Bytes[4] & 0x0f) << 4) | ((v6Bytes[5] & 0xf0) >> 4), ((v6Bytes[5] & 0x0f) << 4) | (v6Bytes[6] & 0x0f), v6Bytes[7], ((v6Bytes[1] & 0x0f) << 4) | ((v6Bytes[2] & 0xf0) >> 4), ((v6Bytes[2] & 0x0f) << 4) | ((v6Bytes[3] & 0xf0) >> 4), 0x10 | ((v6Bytes[0] & 0xf0) >> 4), ((v6Bytes[0] & 0x0f) << 4) | ((v6Bytes[1] & 0xf0) >> 4), v6Bytes[8], v6Bytes[9], v6Bytes[10], v6Bytes[11], v6Bytes[12], v6Bytes[13], v6Bytes[14], v6Bytes[15]);\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/uuid/src/v7.js",
    "content": "import rng from './rng.js';\nimport { unsafeStringify } from './stringify.js';\nconst _state = {};\nfunction v7(options, buf, offset) {\n    let bytes;\n    if (options) {\n        bytes = v7Bytes(options.random ?? options.rng?.() ?? rng(), options.msecs, options.seq, buf, offset);\n    }\n    else {\n        const now = Date.now();\n        const rnds = rng();\n        updateV7State(_state, now, rnds);\n        bytes = v7Bytes(rnds, _state.msecs, _state.seq, buf, offset);\n    }\n    return buf ?? unsafeStringify(bytes);\n}\nexport function updateV7State(state, now, rnds) {\n    state.msecs ??= -Infinity;\n    state.seq ??= 0;\n    if (now > state.msecs) {\n        state.seq = (rnds[6] << 23) | (rnds[7] << 16) | (rnds[8] << 8) | rnds[9];\n        state.msecs = now;\n    }\n    else {\n        state.seq = (state.seq + 1) | 0;\n        if (state.seq === 0) {\n            state.msecs++;\n        }\n    }\n    return state;\n}\nfunction v7Bytes(rnds, msecs, seq, buf, offset = 0) {\n    if (rnds.length < 16) {\n        throw new Error('Random bytes length must be >= 16');\n    }\n    if (!buf) {\n        buf = new Uint8Array(16);\n        offset = 0;\n    }\n    else {\n        if (offset < 0 || offset + 16 > buf.length) {\n            throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);\n        }\n    }\n    msecs ??= Date.now();\n    seq ??= ((rnds[6] * 0x7f) << 24) | (rnds[7] << 16) | (rnds[8] << 8) | rnds[9];\n    buf[offset++] = (msecs / 0x10000000000) & 0xff;\n    buf[offset++] = (msecs / 0x100000000) & 0xff;\n    buf[offset++] = (msecs / 0x1000000) & 0xff;\n    buf[offset++] = (msecs / 0x10000) & 0xff;\n    buf[offset++] = (msecs / 0x100) & 0xff;\n    buf[offset++] = msecs & 0xff;\n    buf[offset++] = 0x70 | ((seq >>> 28) & 0x0f);\n    buf[offset++] = (seq >>> 20) & 0xff;\n    buf[offset++] = 0x80 | ((seq >>> 14) & 0x3f);\n    buf[offset++] = (seq >>> 6) & 0xff;\n    buf[offset++] = ((seq << 2) & 0xff) | (rnds[10] & 0x03);\n    buf[offset++] = rnds[11];\n    buf[offset++] = rnds[12];\n    buf[offset++] = rnds[13];\n    buf[offset++] = rnds[14];\n    buf[offset++] = rnds[15];\n    return buf;\n}\nexport default v7;\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/uuid/src/validate.js",
    "content": "import REGEX from './regex.js';\nfunction validate(uuid) {\n    return typeof uuid === 'string' && REGEX.test(uuid);\n}\nexport default validate;\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/ets/util/uuid/src/version.js",
    "content": "import validate from './validate.js';\nfunction version(uuid) {\n    if (!validate(uuid)) {\n        throw TypeError('Invalid UUID');\n    }\n    return parseInt(uuid.slice(14, 15), 16);\n}\nexport default version;\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/module.json5",
    "content": "{\n  \"module\": {\n    \"name\": \"markdown\",\n    \"type\": \"har\",\n    \"deviceTypes\": [\n      \"default\",\n      \"tablet\",\n      \"2in1\"\n    ],\n    \"metadata\": [\n      {\n        \"name\": \"metaInfo_module_markdown\",\n        \"value\": \"markdown\"\n      }\n    ]\n  }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/base/element/string.json",
    "content": "{\n  \"string\": [\n    {\n      \"name\": \"page_show\",\n      \"value\": \"page from npm package\"\n    }\n  ]\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/en_US/element/string.json",
    "content": "{\n  \"string\": [\n    {\n      \"name\": \"page_show\",\n      \"value\": \"page from npm package\"\n    }\n  ]\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/cyrillic/cyrillic.map.xml",
    "content": "<?xml version='1.0'?>\n<SymbolMappings>\n  <SymbolMapping name=\"dotlessi\" ch=\"305\" fontId=\"wnr10\"/>\n<!-- Modern Russian -->\n  <SymbolMapping name=\"CYRA\" ch=\"1040\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRB\" ch=\"1041\" fontId=\"wnr10\"/> \n  <SymbolMapping name=\"CYRV\" ch=\"1042\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRG\" ch=\"1043\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRD\" ch=\"1044\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRE\" ch=\"1045\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRYO\" ch=\"1025\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRZH\" ch=\"1046\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRZ\" ch=\"1047\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRI\" ch=\"1048\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRIO\" ch=\"1049\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRK\" ch=\"1050\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRL\" ch=\"1051\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRM\" ch=\"1052\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRN\" ch=\"1053\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRO\" ch=\"1054\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRP\" ch=\"1055\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRR\" ch=\"1056\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRS\" ch=\"1057\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRT\" ch=\"1058\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRU\" ch=\"1059\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRF\" ch=\"1060\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRH\" ch=\"1061\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRC\" ch=\"1062\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRCH\" ch=\"1063\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRSH\" ch=\"1064\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRSHCH\" ch=\"1065\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRHRDSN\" ch=\"1066\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRY\" ch=\"1067\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRSFTSN\" ch=\"1068\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYREREV\" ch=\"1069\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRYU\" ch=\"1070\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRYA\" ch=\"1071\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyra\" ch=\"1072\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrb\" ch=\"1073\" fontId=\"wnr10\"/> \n  <SymbolMapping name=\"cyrv\" ch=\"1074\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrg\" ch=\"1075\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrd\" ch=\"1076\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyre\" ch=\"1077\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyryo\" ch=\"1105\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrzh\" ch=\"1078\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrz\" ch=\"1079\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyri\" ch=\"1080\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrio\" ch=\"1081\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrk\" ch=\"1082\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrl\" ch=\"1083\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrm\" ch=\"1084\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrn\" ch=\"1085\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyro\" ch=\"1086\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrp\" ch=\"1087\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrr\" ch=\"1088\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrs\" ch=\"1089\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrt\" ch=\"1090\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyru\" ch=\"1091\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrf\" ch=\"1092\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrh\" ch=\"1093\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrc\" ch=\"1094\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrch\" ch=\"1095\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrsh\" ch=\"1096\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrshch\" ch=\"1097\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrhrdsn\" ch=\"1098\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyry\" ch=\"1099\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrsftsn\" ch=\"1100\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrerev\" ch=\"1101\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyryu\" ch=\"1102\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrya\" ch=\"1103\" fontId=\"wnr10\"/>\n<!-- Ukrainian -->\n  <SymbolMapping name=\"CYRIE\" ch=\"1028\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRII\" ch=\"1030\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrie\" ch=\"1108\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrii\" ch=\"1110\" fontId=\"wnr10\"/>\n<!-- Other slavic languages and Old Russian -->\n  <SymbolMapping name=\"CYRDJE\" ch=\"1026\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRDZE\" ch=\"1029\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRJE\" ch=\"1032\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRLJE\" ch=\"1033\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRNJE\" ch=\"1034\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRTSHE\" ch=\"1035\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRDZHE\" ch=\"1039\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRIZH\" ch=\"1140\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRYAT\" ch=\"1122\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"CYRFITA\" ch=\"1138\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrdje\" ch=\"1106\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrdze\" ch=\"1109\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrje\" ch=\"1112\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrlje\" ch=\"1113\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrnje\" ch=\"1114\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrtshe\" ch=\"1115\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrdzhe\" ch=\"1119\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrizh\" ch=\"1141\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyryat\" ch=\"1123\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrfita\" ch=\"1139\" fontId=\"wnr10\"/>\n<!-- Accent -->\n  <SymbolMapping name=\"cyrbreve\" ch=\"774\" fontId=\"wnr10\"/>\n  <SymbolMapping name=\"cyrddot\" ch=\"776\" fontId=\"wnr10\"/>\n</SymbolMappings>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/cyrillic/language_cyrillic.xml",
    "content": "<?xml version='1.0'?>\n<!--\n  language_cyrillic.xml\n-->\n\n<TeXFont>\n\n<SymbolMappings>\n  <Mapping include=\"cyrillic.map.xml\" />\n</SymbolMappings>\n\n<FontDescriptions>\n  <Metrics include=\"wnr10.xml\" />\n  <Metrics include=\"wnti10.xml\" />\n  <Metrics include=\"wntt10.xml\" />\n  <Metrics include=\"wnss10.xml\" />\n  <Metrics include=\"wnssi10.xml\" />\n  <Metrics include=\"wnssbx10.xml\" />\n  <Metrics include=\"wnbx10.xml\" />\n  <Metrics include=\"wnbxti10.xml\" />\n</FontDescriptions>\n\n<TeXSymbols include=\"symbols_cyrillic.xml\" />\n\n<FormulaSettings include=\"mappings_cyrillic.xml\" />\n\n</TeXFont>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/cyrillic/mappings_cyrillic.xml",
    "content": "<?xml version='1.0'?>\n<!--\n  mappings_cyrillic.xml\n-->\n\n<FormulaSettings>\n  <CharacterToSymbolMappings>\n    <Map char=\"&#305;\" symbol=\"dotlessi\"/>\n    <Map char=\"&#1040;\" symbol=\"CYRA\"/>\n    <Map char=\"&#1041;\" symbol=\"CYRB\"/>\n    <Map char=\"&#1042;\" symbol=\"CYRV\"/>\n    <Map char=\"&#1043;\" symbol=\"CYRG\"/>\n    <Map char=\"&#1044;\" symbol=\"CYRD\"/>\n    <Map char=\"&#1045;\" symbol=\"CYRE\"/>\n    <Map char=\"&#1025;\" symbol=\"CYRYO\"/>\n    <Map char=\"&#1046;\" symbol=\"CYRZH\"/>\n    <Map char=\"&#1047;\" symbol=\"CYRZ\"/>\n    <Map char=\"&#1048;\" symbol=\"CYRI\"/>\n    <Map char=\"&#1049;\" symbol=\"CYRIO\"/>\n    <Map char=\"&#1050;\" symbol=\"CYRK\"/>\n    <Map char=\"&#1051;\" symbol=\"CYRL\"/>\n    <Map char=\"&#1052;\" symbol=\"CYRM\"/>\n    <Map char=\"&#1053;\" symbol=\"CYRN\"/>\n    <Map char=\"&#1054;\" symbol=\"CYRO\"/>\n    <Map char=\"&#1055;\" symbol=\"CYRP\"/>\n    <Map char=\"&#1056;\" symbol=\"CYRR\"/>\n    <Map char=\"&#1057;\" symbol=\"CYRS\"/>\n    <Map char=\"&#1058;\" symbol=\"CYRT\"/>\n    <Map char=\"&#1059;\" symbol=\"CYRU\"/>\n    <Map char=\"&#1060;\" symbol=\"CYRF\"/>\n    <Map char=\"&#1061;\" symbol=\"CYRH\"/>\n    <Map char=\"&#1062;\" symbol=\"CYRC\"/>\n    <Map char=\"&#1063;\" symbol=\"CYRCH\"/>\n    <Map char=\"&#1064;\" symbol=\"CYRSH\"/>\n    <Map char=\"&#1065;\" symbol=\"CYRSHCH\"/>\n    <Map char=\"&#1066;\" symbol=\"CYRHRDSN\"/>\n    <Map char=\"&#1067;\" symbol=\"CYRY\"/>\n    <Map char=\"&#1068;\" symbol=\"CYRSFTSN\"/>\n    <Map char=\"&#1069;\" symbol=\"CYREREV\"/>\n    <Map char=\"&#1070;\" symbol=\"CYRYU\"/>\n    <Map char=\"&#1071;\" symbol=\"CYRYA\"/>\n    <Map char=\"&#1072;\" symbol=\"cyra\"/>\n    <Map char=\"&#1073;\" symbol=\"cyrb\"/>\n    <Map char=\"&#1074;\" symbol=\"cyrv\"/>\n    <Map char=\"&#1075;\" symbol=\"cyrg\"/>\n    <Map char=\"&#1076;\" symbol=\"cyrd\"/>\n    <Map char=\"&#1077;\" symbol=\"cyre\"/>\n    <Map char=\"&#1105;\" symbol=\"cyryo\"/>\n    <Map char=\"&#1078;\" symbol=\"cyrzh\"/>\n    <Map char=\"&#1079;\" symbol=\"cyrz\"/>\n    <Map char=\"&#1080;\" symbol=\"cyri\"/>\n    <Map char=\"&#1081;\" symbol=\"cyrio\"/>\n    <Map char=\"&#1082;\" symbol=\"cyrk\"/>\n    <Map char=\"&#1083;\" symbol=\"cyrl\"/>\n    <Map char=\"&#1084;\" symbol=\"cyrm\"/>\n    <Map char=\"&#1085;\" symbol=\"cyrn\"/>\n    <Map char=\"&#1086;\" symbol=\"cyro\"/>\n    <Map char=\"&#1087;\" symbol=\"cyrp\"/>\n    <Map char=\"&#1088;\" symbol=\"cyrr\"/>\n    <Map char=\"&#1089;\" symbol=\"cyrs\"/>\n    <Map char=\"&#1090;\" symbol=\"cyrt\"/>\n    <Map char=\"&#1091;\" symbol=\"cyru\"/>\n    <Map char=\"&#1092;\" symbol=\"cyrf\"/>\n    <Map char=\"&#1093;\" symbol=\"cyrh\"/>\n    <Map char=\"&#1094;\" symbol=\"cyrc\"/>\n    <Map char=\"&#1095;\" symbol=\"cyrch\"/>\n    <Map char=\"&#1096;\" symbol=\"cyrsh\"/>\n    <Map char=\"&#1097;\" symbol=\"cyrshch\"/>\n    <Map char=\"&#1098;\" symbol=\"cyrhrdsn\"/>\n    <Map char=\"&#1099;\" symbol=\"cyry\"/>\n    <Map char=\"&#1100;\" symbol=\"cyrsftsn\"/>\n    <Map char=\"&#1101;\" symbol=\"cyrerev\"/>\n    <Map char=\"&#1102;\" symbol=\"cyryu\"/>\n    <Map char=\"&#1103;\" symbol=\"cyrya\"/>\n    <Map char=\"&#1028;\" symbol=\"CYRIE\"/>\n    <Map char=\"&#1030;\" symbol=\"CYRII\"/>\n    <Map char=\"&#1108;\" symbol=\"cyrie\"/>\n    <Map char=\"&#1110;\" symbol=\"cyrii\"/>\n    <Map char=\"&#1026;\" symbol=\"CYRDJE\"/>\n    <Map char=\"&#1029;\" symbol=\"CYRDZE\"/>\n    <Map char=\"&#1032;\" symbol=\"CYRJE\"/>\n    <Map char=\"&#1033;\" symbol=\"CYRLJE\"/>\n    <Map char=\"&#1034;\" symbol=\"CYRNJE\"/>\n    <Map char=\"&#1035;\" symbol=\"CYRTSHE\"/>\n    <Map char=\"&#1039;\" symbol=\"CYRDZHE\"/>\n    <Map char=\"&#1140;\" symbol=\"CYRIZH\"/>\n    <Map char=\"&#1122;\" symbol=\"CYRYAT\"/>\n    <Map char=\"&#1138;\" symbol=\"CYRFITA\"/>\n    <Map char=\"&#1106;\" symbol=\"cyrdje\"/>\n    <Map char=\"&#1109;\" symbol=\"cyrdze\"/>\n    <Map char=\"&#1112;\" symbol=\"cyrje\"/>\n    <Map char=\"&#1113;\" symbol=\"cyrlje\"/>\n    <Map char=\"&#1114;\" symbol=\"cyrnje\"/>\n    <Map char=\"&#1115;\" symbol=\"cyrtshe\"/>\n    <Map char=\"&#1119;\" symbol=\"cyrdzhe\"/>\n    <Map char=\"&#1141;\" symbol=\"cyrizh\"/>\n    <Map char=\"&#1123;\" symbol=\"cyryat\"/>\n    <Map char=\"&#1139;\" symbol=\"cyrfita\"/>\n  </CharacterToSymbolMappings>\n  \n  <CharacterToFormulaMappings>\n    <Map char=\"&#1024;\" formula=\"\\`\\CYRE\"/>\n    <Map char=\"&#1027;\" formula=\"\\'\\CYRG\"/>\n    <Map char=\"&#1031;\" formula=\"\\cyrddot\\CYRII\"/>\n    <Map char=\"&#1111;\" formula=\"\\cyrddot\\dotlessi\"/>\n    <Map char=\"&#1027;\" formula=\"\\'\\CYRG\"/>\n    <Map char=\"&#1027;\" formula=\"\\'\\CYRK\"/>\n    <Map char=\"&#1037;\" formula=\"\\`\\CYRI\"/>\n    <Map char=\"&#1038;\" formula=\"\\cyrbreve\\CYRU\"/>\n    <Map char=\"&#1104;\" formula=\"\\`\\cyre\"/>\n    <Map char=\"&#1107;\" formula=\"\\'\\cyrg\"/>\n    <Map char=\"&#1116;\" formula=\"\\'\\cyrk\"/>\n    <Map char=\"&#1117;\" formula=\"\\`\\cyri\"/>\n    <Map char=\"&#1118;\" formula=\"\\cyrbreve\\cyru\"/>\n  </CharacterToFormulaMappings>\n</FormulaSettings>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/cyrillic/symbols_cyrillic.xml",
    "content": "<?xml version='1.0'?>\n<!--\n  symbols_cyrillic.xml\n-->\n\n<TeXSymbols>\n  <Symbol name=\"dotlessi\" type=\"ord\"/>\n  <Symbol name=\"cyrbreve\" type=\"acc\"/>\n  <Symbol name=\"cyrddot\" type=\"acc\"/>\n  <Symbol name=\"CYRA\" type=\"ord\"/>\n  <Symbol name=\"CYRB\" type=\"ord\"/> \n  <Symbol name=\"CYRV\" type=\"ord\"/>\n  <Symbol name=\"CYRG\" type=\"ord\"/>\n  <Symbol name=\"CYRD\" type=\"ord\"/>\n  <Symbol name=\"CYRE\" type=\"ord\"/>\n  <Symbol name=\"CYRYO\" type=\"ord\"/>\n  <Symbol name=\"CYRZH\" type=\"ord\"/>\n  <Symbol name=\"CYRZ\" type=\"ord\"/>\n  <Symbol name=\"CYRE\" type=\"ord\"/>\n  <Symbol name=\"CYRI\" type=\"ord\"/>\n  <Symbol name=\"CYRIO\" type=\"ord\"/>\n  <Symbol name=\"CYRK\" type=\"ord\"/>\n  <Symbol name=\"CYRL\" type=\"ord\"/>\n  <Symbol name=\"CYRM\" type=\"ord\"/>\n  <Symbol name=\"CYRN\" type=\"ord\"/>\n  <Symbol name=\"CYRO\" type=\"ord\"/>\n  <Symbol name=\"CYRP\" type=\"ord\"/>\n  <Symbol name=\"CYRR\" type=\"ord\"/>\n  <Symbol name=\"CYRS\" type=\"ord\"/>\n  <Symbol name=\"CYRT\" type=\"ord\"/>\n  <Symbol name=\"CYRU\" type=\"ord\"/>\n  <Symbol name=\"CYRF\" type=\"ord\"/>\n  <Symbol name=\"CYRH\" type=\"ord\"/>\n  <Symbol name=\"CYRC\" type=\"ord\"/>\n  <Symbol name=\"CYRCH\" type=\"ord\"/>\n  <Symbol name=\"CYRSH\" type=\"ord\"/>\n  <Symbol name=\"CYRSHCH\" type=\"ord\"/>\n  <Symbol name=\"CYRHRDSN\" type=\"ord\"/>\n  <Symbol name=\"CYRY\" type=\"ord\"/>\n  <Symbol name=\"CYRSFTSN\" type=\"ord\"/>\n  <Symbol name=\"CYREREV\" type=\"ord\"/>\n  <Symbol name=\"CYRYU\" type=\"ord\"/>\n  <Symbol name=\"CYRYA\" type=\"ord\"/>\n  <Symbol name=\"cyra\" type=\"ord\"/>\n  <Symbol name=\"cyrb\" type=\"ord\"/> \n  <Symbol name=\"cyrv\" type=\"ord\"/>\n  <Symbol name=\"cyrg\" type=\"ord\"/>\n  <Symbol name=\"cyrd\" type=\"ord\"/>\n  <Symbol name=\"cyre\" type=\"ord\"/>\n  <Symbol name=\"cyryo\" type=\"ord\"/>\n  <Symbol name=\"cyrzh\" type=\"ord\"/>\n  <Symbol name=\"cyrz\" type=\"ord\"/>\n  <Symbol name=\"cyre\" type=\"ord\"/>\n  <Symbol name=\"cyri\" type=\"ord\"/>\n  <Symbol name=\"cyrio\" type=\"ord\"/>\n  <Symbol name=\"cyrk\" type=\"ord\"/>\n  <Symbol name=\"cyrl\" type=\"ord\"/>\n  <Symbol name=\"cyrm\" type=\"ord\"/>\n  <Symbol name=\"cyrn\" type=\"ord\"/>\n  <Symbol name=\"cyro\" type=\"ord\"/>\n  <Symbol name=\"cyrp\" type=\"ord\"/>\n  <Symbol name=\"cyrr\" type=\"ord\"/>\n  <Symbol name=\"cyrs\" type=\"ord\"/>\n  <Symbol name=\"cyrt\" type=\"ord\"/>\n  <Symbol name=\"cyru\" type=\"ord\"/>\n  <Symbol name=\"cyrf\" type=\"ord\"/>\n  <Symbol name=\"cyrh\" type=\"ord\"/>\n  <Symbol name=\"cyrc\" type=\"ord\"/>\n  <Symbol name=\"cyrch\" type=\"ord\"/>\n  <Symbol name=\"cyrsh\" type=\"ord\"/>\n  <Symbol name=\"cyrshch\" type=\"ord\"/>\n  <Symbol name=\"cyrhrdsn\" type=\"ord\"/>\n  <Symbol name=\"cyry\" type=\"ord\"/>\n  <Symbol name=\"cyrsftsn\" type=\"ord\"/>\n  <Symbol name=\"cyrerev\" type=\"ord\"/>\n  <Symbol name=\"cyryu\" type=\"ord\"/>\n  <Symbol name=\"cyrya\" type=\"ord\"/>\n<!-- Ukrainian -->\n  <Symbol name=\"CYRIE\" type=\"ord\"/>\n  <Symbol name=\"CYRII\" type=\"ord\"/>\n  <Symbol name=\"cyrie\" type=\"ord\"/>\n  <Symbol name=\"cyrii\" type=\"ord\"/>\n<!-- Other slavic languages and Old Russian -->\n  <Symbol name=\"CYRDJE\" type=\"ord\"/>\n  <Symbol name=\"CYRDZE\" type=\"ord\"/>\n  <Symbol name=\"CYRJE\" type=\"ord\"/>\n  <Symbol name=\"CYRLJE\" type=\"ord\"/>\n  <Symbol name=\"CYRNJE\" type=\"ord\"/>\n  <Symbol name=\"CYRTSHE\" type=\"ord\"/>\n  <Symbol name=\"CYRDZHE\" type=\"ord\"/>\n  <Symbol name=\"CYRIZH\" type=\"ord\"/>\n  <Symbol name=\"CYRYAT\" type=\"ord\"/>\n  <Symbol name=\"CYRFITA\" type=\"ord\"/>\n  <Symbol name=\"cyrdje\" type=\"ord\"/>\n  <Symbol name=\"cyrdze\" type=\"ord\"/>\n  <Symbol name=\"cyrje\" type=\"ord\"/>\n  <Symbol name=\"cyrlje\" type=\"ord\"/>\n  <Symbol name=\"cyrnje\" type=\"ord\"/>\n  <Symbol name=\"cyrtshe\" type=\"ord\"/>\n  <Symbol name=\"cyrdzhe\" type=\"ord\"/>\n  <Symbol name=\"cyrizh\" type=\"ord\"/>\n  <Symbol name=\"cyryat\" type=\"ord\"/>\n  <Symbol name=\"cyrfita\" type=\"ord\"/>\n</TeXSymbols>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/cyrillic/wnbx10.xml",
    "content": "<Font name=\"wnbx10.ttf\" id=\"wnbx10\" space=\"0.383331\" xHeight=\"0.444445\" quad=\"1.149994\" unicode=\"95\" itVersion=\"wnbxti10\" ssVersion=\"wnssbx10\" ttVersion=\"wntt10\">\n   <Char code=\"1034\" width=\"1.234021\" height=\"0.686111\" >\n      <Kern code=\"1046\" val=\"-0.031944\"/>\n      <Kern code=\"1061\" val=\"-0.031944\"/>\n      <Kern code=\"1054\" val=\"-0.031944\"/>\n      <Kern code=\"1060\" val=\"-0.031944\"/>\n      <Kern code=\"1138\" val=\"-0.031944\"/>\n      <Kern code=\"1057\" val=\"-0.031944\"/>\n      <Kern code=\"1028\" val=\"-0.031944\"/>\n      <Kern code=\"1058\" val=\"-0.095833\"/>\n      <Kern code=\"1066\" val=\"-0.095833\"/>\n      <Kern code=\"1026\" val=\"-0.095833\"/>\n      <Kern code=\"1035\" val=\"-0.095833\"/>\n      <Kern code=\"1122\" val=\"-0.095833\"/>\n      <Kern code=\"1063\" val=\"-0.095833\"/>\n      <Kern code=\"1059\" val=\"-0.095833\"/>\n      <Kern code=\"1140\" val=\"-0.127777\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.095833\"/>\n   </Char>\n   <Char code=\"1033\" width=\"1.234021\" height=\"0.686111\" >\n      <Kern code=\"1046\" val=\"-0.031944\"/>\n      <Kern code=\"1061\" val=\"-0.031944\"/>\n      <Kern code=\"1054\" val=\"-0.031944\"/>\n      <Kern code=\"1060\" val=\"-0.031944\"/>\n      <Kern code=\"1138\" val=\"-0.031944\"/>\n      <Kern code=\"1057\" val=\"-0.031944\"/>\n      <Kern code=\"1028\" val=\"-0.031944\"/>\n      <Kern code=\"1058\" val=\"-0.095833\"/>\n      <Kern code=\"1066\" val=\"-0.095833\"/>\n      <Kern code=\"1026\" val=\"-0.095833\"/>\n      <Kern code=\"1035\" val=\"-0.095833\"/>\n      <Kern code=\"1122\" val=\"-0.095833\"/>\n      <Kern code=\"1063\" val=\"-0.095833\"/>\n      <Kern code=\"1059\" val=\"-0.095833\"/>\n      <Kern code=\"1140\" val=\"-0.127777\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.095833\"/>\n   </Char>\n   <Char code=\"1039\" width=\"0.901384\" height=\"0.686111\" depth=\"0.194445\" />\n   <Char code=\"1069\" width=\"0.830551\" height=\"0.686111\" >\n      <Kern code=\"1040\" val=\"-0.031944\"/>\n      <Kern code=\"1044\" val=\"-0.031944\"/>\n      <Kern code=\"1046\" val=\"-0.031944\"/>\n      <Kern code=\"1061\" val=\"-0.031944\"/>\n      <Kern code=\"1059\" val=\"-0.031944\"/>\n      <Kern code=\"1140\" val=\"-0.031944\"/>\n      <Kern code=\"1071\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1030\" width=\"0.43611\" height=\"0.686111\" >\n      <Kern code=\"1030\" val=\"0.031944\"/>\n   </Char>\n   <Char code=\"1028\" width=\"0.830551\" height=\"0.686111\" />\n   <Char code=\"1026\" width=\"0.959717\" height=\"0.686111\" >\n      <Kern code=\"1046\" val=\"-0.031944\"/>\n      <Kern code=\"1061\" val=\"-0.031944\"/>\n      <Kern code=\"1054\" val=\"-0.031944\"/>\n      <Kern code=\"1060\" val=\"-0.031944\"/>\n      <Kern code=\"1138\" val=\"-0.031944\"/>\n      <Kern code=\"1057\" val=\"-0.031944\"/>\n      <Kern code=\"1028\" val=\"-0.031944\"/>\n      <Kern code=\"1058\" val=\"-0.095833\"/>\n      <Kern code=\"1066\" val=\"-0.095833\"/>\n      <Kern code=\"1026\" val=\"-0.095833\"/>\n      <Kern code=\"1035\" val=\"-0.095833\"/>\n      <Kern code=\"1122\" val=\"-0.095833\"/>\n      <Kern code=\"1063\" val=\"-0.095833\"/>\n      <Kern code=\"1059\" val=\"-0.095833\"/>\n      <Kern code=\"1140\" val=\"-0.127777\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.095833\"/>\n   </Char>\n   <Char code=\"1035\" width=\"0.8784685\" height=\"0.686111\" />\n   <Char code=\"1114\" width=\"0.86319\" height=\"0.444445\" >\n      <Kern code=\"1091\" val=\"-0.063889\"/>\n      <Kern code=\"1141\" val=\"-0.063889\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.095833\"/>\n      <Kern code=\"1086\" val=\"-0.031944\"/>\n      <Kern code=\"1139\" val=\"-0.031944\"/>\n      <Kern code=\"1092\" val=\"-0.031944\"/>\n      <Kern code=\"1108\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1113\" width=\"0.86319\" height=\"0.444445\" >\n      <Kern code=\"1091\" val=\"-0.063889\"/>\n      <Kern code=\"1141\" val=\"-0.063889\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.095833\"/>\n      <Kern code=\"1086\" val=\"-0.031944\"/>\n      <Kern code=\"1139\" val=\"-0.031944\"/>\n      <Kern code=\"1092\" val=\"-0.031944\"/>\n      <Kern code=\"1108\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1119\" width=\"0.6388855\" height=\"0.444445\" depth=\"0.162038\" />\n   <Char code=\"1101\" width=\"0.511108\" height=\"0.444445\" >\n      <Kern code=\"1076\" val=\"-0.031944\"/>\n      <Kern code=\"1078\" val=\"-0.031944\"/>\n      <Kern code=\"1093\" val=\"-0.031944\"/>\n      <Kern code=\"1103\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1110\" width=\"0.319443\" height=\"0.694445\" />\n   <Char code=\"1108\" width=\"0.50472\" height=\"0.444445\" />\n   <Char code=\"1106\" width=\"0.606941\" height=\"0.694445\" depth=\"0.194445\" />\n   <Char code=\"1115\" width=\"0.6388855\" height=\"0.694445\" />\n   <Char code=\"1070\" width=\"1.273605\" height=\"0.686111\" >\n      <Kern code=\"1040\" val=\"-0.031944\"/>\n      <Kern code=\"1044\" val=\"-0.031944\"/>\n      <Kern code=\"1046\" val=\"-0.031944\"/>\n      <Kern code=\"1061\" val=\"-0.031944\"/>\n      <Kern code=\"1059\" val=\"-0.031944\"/>\n      <Kern code=\"1140\" val=\"-0.031944\"/>\n      <Kern code=\"1071\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1046\" width=\"1.366656\" height=\"0.686111\" >\n      <Kern code=\"1054\" val=\"-0.031944\"/>\n      <Kern code=\"1060\" val=\"-0.031944\"/>\n      <Kern code=\"1138\" val=\"-0.031944\"/>\n      <Kern code=\"1057\" val=\"-0.031944\"/>\n      <Kern code=\"1028\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.031944\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1049\" width=\"0.901384\" height=\"0.894394\" />\n   <Char code=\"1025\" width=\"0.755551\" height=\"0.894394\" />\n   <Char code=\"1140\" width=\"0.945828\" height=\"0.686111\" italic=\"0.015973\" >\n      <Kern code=\"1040\" val=\"-0.127777\"/>\n      <Kern code=\"1071\" val=\"-0.127777\"/>\n      <Kern code=\"1054\" val=\"-0.031944\"/>\n      <Kern code=\"1060\" val=\"-0.031944\"/>\n      <Kern code=\"1138\" val=\"-0.031944\"/>\n      <Kern code=\"1057\" val=\"-0.031944\"/>\n      <Kern code=\"1028\" val=\"-0.031944\"/>\n      <Kern code=\"1072\" val=\"-0.095833\"/>\n      <Kern code=\"1086\" val=\"-0.095833\"/>\n      <Kern code=\"1139\" val=\"-0.095833\"/>\n      <Kern code=\"1077\" val=\"-0.095833\"/>\n      <Kern code=\"1105\" val=\"-0.095833\"/>\n      <Kern code=\"1076\" val=\"-0.127777\"/>\n      <Kern code=\"1083\" val=\"-0.127777\"/>\n      <Kern code=\"1113\" val=\"-0.127777\"/>\n      <Kern code=\"1103\" val=\"-0.127777\"/>\n   </Char>\n   <Char code=\"1138\" width=\"0.89444\" height=\"0.686111\" >\n      <Kern code=\"1040\" val=\"-0.031944\"/>\n      <Kern code=\"1044\" val=\"-0.031944\"/>\n      <Kern code=\"1046\" val=\"-0.031944\"/>\n      <Kern code=\"1061\" val=\"-0.031944\"/>\n      <Kern code=\"1059\" val=\"-0.031944\"/>\n      <Kern code=\"1140\" val=\"-0.031944\"/>\n      <Kern code=\"1071\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1029\" width=\"0.6388855\" height=\"0.686111\" />\n   <Char code=\"1071\" width=\"0.901384\" height=\"0.686111\" />\n   <Char code=\"1102\" width=\"0.862495\" height=\"0.444445\" >\n      <Kern code=\"1076\" val=\"-0.031944\"/>\n      <Kern code=\"1078\" val=\"-0.031944\"/>\n      <Kern code=\"1093\" val=\"-0.031944\"/>\n      <Kern code=\"1103\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1078\" width=\"0.958328\" height=\"0.444445\" >\n      <Kern code=\"1072\" val=\"-0.031944\"/>\n      <Kern code=\"1086\" val=\"-0.031944\"/>\n      <Kern code=\"1139\" val=\"-0.031944\"/>\n      <Kern code=\"1089\" val=\"-0.031944\"/>\n      <Kern code=\"1108\" val=\"-0.031944\"/>\n      <Kern code=\"1077\" val=\"-0.031944\"/>\n      <Kern code=\"1105\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1081\" width=\"0.6388855\" height=\"0.652727\" />\n   <Char code=\"1105\" width=\"0.5270815\" height=\"0.686111\" />\n   <Char code=\"1141\" width=\"0.685414\" height=\"0.444445\" italic=\"0.015973\" >\n      <Kern code=\"1072\" val=\"-0.031944\"/>\n      <Kern code=\"1086\" val=\"-0.031944\"/>\n      <Kern code=\"1139\" val=\"-0.031944\"/>\n      <Kern code=\"1089\" val=\"-0.031944\"/>\n      <Kern code=\"1108\" val=\"-0.031944\"/>\n      <Kern code=\"1077\" val=\"-0.031944\"/>\n      <Kern code=\"1105\" val=\"-0.031944\"/>\n      <Kern code=\"1103\" val=\"-0.031944\"/>\n      <Kern code=\"1076\" val=\"-0.063889\"/>\n      <Kern code=\"1083\" val=\"-0.063889\"/>\n      <Kern code=\"1113\" val=\"-0.063889\"/>\n   </Char>\n   <Char code=\"1139\" width=\"0.511108\" height=\"0.444445\" >\n      <Kern code=\"1076\" val=\"-0.031944\"/>\n      <Kern code=\"1078\" val=\"-0.031944\"/>\n      <Kern code=\"1093\" val=\"-0.031944\"/>\n      <Kern code=\"1103\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1109\" width=\"0.4536085\" height=\"0.444445\" />\n   <Char code=\"1103\" width=\"0.6076355\" height=\"0.444445\" />\n   <Char code=\"776\" width=\"0.574997\" height=\"0.686111\" />\n   <Char code=\"1122\" width=\"0.945828\" height=\"0.75\" >\n      <Kern code=\"1046\" val=\"-0.031944\"/>\n      <Kern code=\"1061\" val=\"-0.031944\"/>\n      <Kern code=\"1054\" val=\"-0.031944\"/>\n      <Kern code=\"1060\" val=\"-0.031944\"/>\n      <Kern code=\"1138\" val=\"-0.031944\"/>\n      <Kern code=\"1057\" val=\"-0.031944\"/>\n      <Kern code=\"1028\" val=\"-0.031944\"/>\n      <Kern code=\"1058\" val=\"-0.095833\"/>\n      <Kern code=\"1066\" val=\"-0.095833\"/>\n      <Kern code=\"1026\" val=\"-0.095833\"/>\n      <Kern code=\"1035\" val=\"-0.095833\"/>\n      <Kern code=\"1122\" val=\"-0.095833\"/>\n      <Kern code=\"1063\" val=\"-0.095833\"/>\n      <Kern code=\"1059\" val=\"-0.095833\"/>\n      <Kern code=\"1140\" val=\"-0.127777\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.095833\"/>\n   </Char>\n   <Char code=\"774\" width=\"0.574997\" height=\"0.652727\" />\n   <Char code=\"1123\" width=\"0.574997\" height=\"0.652727\" >\n      <Kern code=\"1091\" val=\"-0.063889\"/>\n      <Kern code=\"1141\" val=\"-0.063889\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.095833\"/>\n      <Kern code=\"1086\" val=\"-0.031944\"/>\n      <Kern code=\"1139\" val=\"-0.031944\"/>\n      <Kern code=\"1092\" val=\"-0.031944\"/>\n      <Kern code=\"1108\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"171\" width=\"0.6388855\" height=\"0.472223\" />\n   <Char code=\"305\" width=\"0.319443\" height=\"0.444445\" />\n   <Char code=\"187\" width=\"0.6388855\" height=\"0.472223\" />\n   <Char code=\"1040\" width=\"0.86944\" height=\"0.686111\" >\n      <Kern code=\"1054\" val=\"-0.031944\"/>\n      <Kern code=\"1060\" val=\"-0.031944\"/>\n      <Kern code=\"1138\" val=\"-0.031944\"/>\n      <Kern code=\"1057\" val=\"-0.031944\"/>\n      <Kern code=\"1028\" val=\"-0.031944\"/>\n      <Kern code=\"1058\" val=\"-0.095833\"/>\n      <Kern code=\"1066\" val=\"-0.095833\"/>\n      <Kern code=\"1026\" val=\"-0.095833\"/>\n      <Kern code=\"1035\" val=\"-0.095833\"/>\n      <Kern code=\"1122\" val=\"-0.095833\"/>\n      <Kern code=\"1063\" val=\"-0.095833\"/>\n      <Kern code=\"1059\" val=\"-0.095833\"/>\n      <Kern code=\"1140\" val=\"-0.127777\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.095833\"/>\n   </Char>\n   <Char code=\"1041\" width=\"0.818051\" height=\"0.686111\" />\n   <Char code=\"1062\" width=\"0.901384\" height=\"0.686111\" depth=\"0.194445\" >\n      <Lig code=\"1061\" ligCode=\"1063\"/>\n      <Lig code=\"1093\" ligCode=\"1063\"/>\n   </Char>\n   <Char code=\"1044\" width=\"0.901384\" height=\"0.686111\" depth=\"0.194445\" >\n      <Lig code=\"1032\" ligCode=\"1026\"/>\n      <Lig code=\"1112\" ligCode=\"1026\"/>\n   </Char>\n   <Char code=\"1045\" width=\"0.755551\" height=\"0.686111\" >\n   </Char>\n   <Char code=\"1060\" width=\"0.958328\" height=\"0.686111\" >\n      <Kern code=\"1040\" val=\"-0.031944\"/>\n      <Kern code=\"1044\" val=\"-0.031944\"/>\n      <Kern code=\"1046\" val=\"-0.031944\"/>\n      <Kern code=\"1061\" val=\"-0.031944\"/>\n      <Kern code=\"1059\" val=\"-0.031944\"/>\n      <Kern code=\"1140\" val=\"-0.031944\"/>\n      <Kern code=\"1071\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1043\" width=\"0.691663\" height=\"0.686111\" >\n      <Kern code=\"1040\" val=\"-0.095833\"/>\n      <Kern code=\"1044\" val=\"-0.095833\"/>\n      <Kern code=\"1071\" val=\"-0.095833\"/>\n      <Kern code=\"1051\" val=\"-0.031944\"/>\n      <Kern code=\"1033\" val=\"-0.031944\"/>\n      <Kern code=\"1072\" val=\"-0.095833\"/>\n      <Kern code=\"1086\" val=\"-0.095833\"/>\n      <Kern code=\"1139\" val=\"-0.095833\"/>\n      <Kern code=\"1077\" val=\"-0.095833\"/>\n      <Kern code=\"1105\" val=\"-0.095833\"/>\n      <Kern code=\"1089\" val=\"-0.095833\"/>\n      <Kern code=\"1108\" val=\"-0.095833\"/>\n      <Kern code=\"1092\" val=\"-0.095833\"/>\n      <Kern code=\"1076\" val=\"-0.095833\"/>\n      <Kern code=\"1083\" val=\"-0.095833\"/>\n      <Kern code=\"1113\" val=\"-0.095833\"/>\n      <Kern code=\"1103\" val=\"-0.095833\"/>\n   </Char>\n   <Char code=\"1061\" width=\"0.86944\" height=\"0.686111\" >\n      <Kern code=\"1054\" val=\"-0.031944\"/>\n      <Kern code=\"1060\" val=\"-0.031944\"/>\n      <Kern code=\"1138\" val=\"-0.031944\"/>\n      <Kern code=\"1057\" val=\"-0.031944\"/>\n      <Kern code=\"1028\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.031944\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1048\" width=\"0.901384\" height=\"0.686111\" >\n   </Char>\n   <Char code=\"1032\" width=\"0.594441\" height=\"0.686111\" >\n   </Char>\n   <Char code=\"1050\" width=\"0.901384\" height=\"0.686111\" >\n      <Lig code=\"1061\" ligCode=\"1061\"/>\n      <Lig code=\"1093\" ligCode=\"1061\"/>\n      <Kern code=\"1054\" val=\"-0.031944\"/>\n      <Kern code=\"1060\" val=\"-0.031944\"/>\n      <Kern code=\"1138\" val=\"-0.031944\"/>\n      <Kern code=\"1057\" val=\"-0.031944\"/>\n      <Kern code=\"1028\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.031944\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1051\" width=\"0.901384\" height=\"0.686111\" >\n      <Lig code=\"1032\" ligCode=\"1033\"/>\n      <Lig code=\"1112\" ligCode=\"1033\"/>\n   </Char>\n   <Char code=\"1052\" width=\"1.091661\" height=\"0.686111\" />\n   <Char code=\"1053\" width=\"0.901384\" height=\"0.686111\" >\n      <Lig code=\"1032\" ligCode=\"1034\"/>\n      <Lig code=\"1112\" ligCode=\"1034\"/>\n   </Char>\n   <Char code=\"1054\" width=\"0.863884\" height=\"0.686111\" >\n      <Kern code=\"1040\" val=\"-0.031944\"/>\n      <Kern code=\"1044\" val=\"-0.031944\"/>\n      <Kern code=\"1046\" val=\"-0.031944\"/>\n      <Kern code=\"1061\" val=\"-0.031944\"/>\n      <Kern code=\"1059\" val=\"-0.031944\"/>\n      <Kern code=\"1140\" val=\"-0.031944\"/>\n      <Kern code=\"1071\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1055\" width=\"0.901384\" height=\"0.686111\" >\n   </Char>\n   <Char code=\"1063\" width=\"0.901384\" height=\"0.686111\" />\n   <Char code=\"1056\" width=\"0.786107\" height=\"0.686111\" >\n      <Kern code=\"1040\" val=\"-0.095833\"/>\n      <Kern code=\"1044\" val=\"-0.095833\"/>\n      <Kern code=\"1051\" val=\"-0.095833\"/>\n      <Kern code=\"1033\" val=\"-0.095833\"/>\n      <Kern code=\"1071\" val=\"-0.095833\"/>\n      <Kern code=\"1072\" val=\"-0.031944\"/>\n      <Kern code=\"1086\" val=\"-0.031944\"/>\n      <Kern code=\"1139\" val=\"-0.031944\"/>\n      <Kern code=\"1077\" val=\"-0.031944\"/>\n      <Kern code=\"1105\" val=\"-0.031944\"/>\n      <Kern code=\"1076\" val=\"-0.095833\"/>\n      <Kern code=\"1083\" val=\"-0.095833\"/>\n      <Kern code=\"1113\" val=\"-0.095833\"/>\n   </Char>\n   <Char code=\"1057\" width=\"0.830551\" height=\"0.686111\" >\n      <Lig code=\"1061\" ligCode=\"1064\"/>\n      <Lig code=\"1093\" ligCode=\"1064\"/>\n   </Char>\n   <Char code=\"1058\" width=\"0.799995\" height=\"0.686111\" >\n      <Lig code=\"1057\" ligCode=\"1062\"/>\n      <Lig code=\"1089\" ligCode=\"1062\"/>\n      <Kern code=\"1040\" val=\"-0.095833\"/>\n      <Kern code=\"1044\" val=\"-0.095833\"/>\n      <Kern code=\"1071\" val=\"-0.095833\"/>\n      <Kern code=\"1051\" val=\"-0.031944\"/>\n      <Kern code=\"1033\" val=\"-0.031944\"/>\n      <Kern code=\"1072\" val=\"-0.095833\"/>\n      <Kern code=\"1086\" val=\"-0.095833\"/>\n      <Kern code=\"1139\" val=\"-0.095833\"/>\n      <Kern code=\"1077\" val=\"-0.095833\"/>\n      <Kern code=\"1105\" val=\"-0.095833\"/>\n      <Kern code=\"1089\" val=\"-0.095833\"/>\n      <Kern code=\"1108\" val=\"-0.095833\"/>\n      <Kern code=\"1092\" val=\"-0.095833\"/>\n      <Kern code=\"1076\" val=\"-0.095833\"/>\n      <Kern code=\"1083\" val=\"-0.095833\"/>\n      <Kern code=\"1113\" val=\"-0.095833\"/>\n      <Kern code=\"1103\" val=\"-0.095833\"/>\n   </Char>\n   <Char code=\"1059\" width=\"0.86944\" height=\"0.686111\" italic=\"0.015973\" >\n      <Kern code=\"1040\" val=\"-0.095833\"/>\n      <Kern code=\"1071\" val=\"-0.095833\"/>\n      <Kern code=\"1044\" val=\"-0.063889\"/>\n      <Kern code=\"1051\" val=\"-0.063889\"/>\n      <Kern code=\"1033\" val=\"-0.063889\"/>\n      <Kern code=\"1054\" val=\"-0.031944\"/>\n      <Kern code=\"1060\" val=\"-0.031944\"/>\n      <Kern code=\"1138\" val=\"-0.031944\"/>\n      <Kern code=\"1057\" val=\"-0.031944\"/>\n      <Kern code=\"1028\" val=\"-0.031944\"/>\n      <Kern code=\"1072\" val=\"-0.095833\"/>\n      <Kern code=\"1086\" val=\"-0.095833\"/>\n      <Kern code=\"1139\" val=\"-0.095833\"/>\n      <Kern code=\"1077\" val=\"-0.095833\"/>\n      <Kern code=\"1105\" val=\"-0.095833\"/>\n      <Kern code=\"1089\" val=\"-0.095833\"/>\n      <Kern code=\"1108\" val=\"-0.095833\"/>\n      <Kern code=\"1076\" val=\"-0.095833\"/>\n      <Kern code=\"1083\" val=\"-0.095833\"/>\n      <Kern code=\"1113\" val=\"-0.095833\"/>\n      <Kern code=\"1103\" val=\"-0.095833\"/>\n   </Char>\n   <Char code=\"1042\" width=\"0.818051\" height=\"0.686111\" />\n   <Char code=\"1065\" width=\"1.3312435\" height=\"0.686111\" depth=\"0.194445\" />\n   <Char code=\"1064\" width=\"1.3312435\" height=\"0.686111\" >\n      <Lig code=\"1063\" ligCode=\"1065\"/>\n      <Lig code=\"1095\" ligCode=\"1065\"/>\n      <Lig code=\"1062\" ligCode=\"0\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1067\" width=\"1.124994\" height=\"0.686111\" >\n      <Lig code=\"1040\" ligCode=\"1071\"/>\n      <Lig code=\"1072\" ligCode=\"1071\"/>\n      <Lig code=\"1059\" ligCode=\"1070\"/>\n      <Lig code=\"1091\" ligCode=\"1070\"/>\n   </Char>\n   <Char code=\"1047\" width=\"0.702774\" height=\"0.686111\" >\n      <Lig code=\"1061\" ligCode=\"1046\"/>\n      <Lig code=\"1093\" ligCode=\"1046\"/>\n   </Char>\n   <Char code=\"1068\" width=\"0.818051\" height=\"0.686111\" >\n      <Kern code=\"1046\" val=\"-0.031944\"/>\n      <Kern code=\"1061\" val=\"-0.031944\"/>\n      <Kern code=\"1054\" val=\"-0.031944\"/>\n      <Kern code=\"1060\" val=\"-0.031944\"/>\n      <Kern code=\"1138\" val=\"-0.031944\"/>\n      <Kern code=\"1057\" val=\"-0.031944\"/>\n      <Kern code=\"1028\" val=\"-0.031944\"/>\n      <Kern code=\"1058\" val=\"-0.095833\"/>\n      <Kern code=\"1066\" val=\"-0.095833\"/>\n      <Kern code=\"1026\" val=\"-0.095833\"/>\n      <Kern code=\"1035\" val=\"-0.095833\"/>\n      <Kern code=\"1122\" val=\"-0.095833\"/>\n      <Kern code=\"1063\" val=\"-0.095833\"/>\n      <Kern code=\"1059\" val=\"-0.095833\"/>\n      <Kern code=\"1140\" val=\"-0.127777\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.095833\"/>\n   </Char>\n   <Char code=\"1066\" width=\"1.006938\" height=\"0.686111\" >\n      <Kern code=\"1046\" val=\"-0.031944\"/>\n      <Kern code=\"1061\" val=\"-0.031944\"/>\n      <Kern code=\"1054\" val=\"-0.031944\"/>\n      <Kern code=\"1060\" val=\"-0.031944\"/>\n      <Kern code=\"1138\" val=\"-0.031944\"/>\n      <Kern code=\"1057\" val=\"-0.031944\"/>\n      <Kern code=\"1028\" val=\"-0.031944\"/>\n      <Kern code=\"1058\" val=\"-0.095833\"/>\n      <Kern code=\"1066\" val=\"-0.095833\"/>\n      <Kern code=\"1026\" val=\"-0.095833\"/>\n      <Kern code=\"1035\" val=\"-0.095833\"/>\n      <Kern code=\"1122\" val=\"-0.095833\"/>\n      <Kern code=\"1063\" val=\"-0.095833\"/>\n      <Kern code=\"1059\" val=\"-0.095833\"/>\n      <Kern code=\"1140\" val=\"-0.127777\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.095833\"/>\n   </Char>\n   <Char code=\"1072\" width=\"0.559024\" height=\"0.444445\" >\n      <Kern code=\"1095\" val=\"-0.031944\"/>\n      <Kern code=\"1091\" val=\"-0.031944\"/>\n      <Kern code=\"1141\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1073\" width=\"0.574997\" height=\"0.694445\" >\n      <Kern code=\"1076\" val=\"-0.031944\"/>\n      <Kern code=\"1078\" val=\"-0.031944\"/>\n      <Kern code=\"1093\" val=\"-0.031944\"/>\n      <Kern code=\"1103\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1094\" width=\"0.6388855\" height=\"0.444445\" depth=\"0.162038\" >\n      <Lig code=\"1093\" ligCode=\"1095\"/>\n   </Char>\n   <Char code=\"1076\" width=\"0.6388855\" height=\"0.444445\" depth=\"0.162038\" >\n      <Lig code=\"1112\" ligCode=\"1106\"/>\n   </Char>\n   <Char code=\"1077\" width=\"0.5270815\" height=\"0.444445\" >\n   </Char>\n   <Char code=\"1092\" width=\"0.89444\" height=\"0.694445\" depth=\"0.194445\" >\n      <Kern code=\"1076\" val=\"-0.031944\"/>\n      <Kern code=\"1078\" val=\"-0.031944\"/>\n      <Kern code=\"1093\" val=\"-0.031944\"/>\n      <Kern code=\"1103\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1075\" width=\"0.49583\" height=\"0.444445\" >\n      <Kern code=\"1072\" val=\"-0.031944\"/>\n      <Kern code=\"1076\" val=\"-0.031944\"/>\n      <Kern code=\"1083\" val=\"-0.031944\"/>\n      <Kern code=\"1113\" val=\"-0.031944\"/>\n      <Kern code=\"1103\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1093\" width=\"0.606941\" height=\"0.444445\" >\n      <Kern code=\"1072\" val=\"-0.031944\"/>\n      <Kern code=\"1086\" val=\"-0.031944\"/>\n      <Kern code=\"1139\" val=\"-0.031944\"/>\n      <Kern code=\"1089\" val=\"-0.031944\"/>\n      <Kern code=\"1108\" val=\"-0.031944\"/>\n      <Kern code=\"1077\" val=\"-0.031944\"/>\n      <Kern code=\"1105\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1080\" width=\"0.6388855\" height=\"0.444445\" >\n   </Char>\n   <Char code=\"1112\" width=\"0.351387\" height=\"0.694445\" depth=\"0.194445\" >\n   </Char>\n   <Char code=\"1082\" width=\"0.6388855\" height=\"0.444445\" >\n      <Lig code=\"1093\" ligCode=\"1093\"/>\n      <Kern code=\"1072\" val=\"-0.031944\"/>\n      <Kern code=\"1086\" val=\"-0.031944\"/>\n      <Kern code=\"1139\" val=\"-0.031944\"/>\n      <Kern code=\"1089\" val=\"-0.031944\"/>\n      <Kern code=\"1108\" val=\"-0.031944\"/>\n      <Kern code=\"1077\" val=\"-0.031944\"/>\n      <Kern code=\"1105\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1083\" width=\"0.6388855\" height=\"0.444445\" >\n      <Lig code=\"1112\" ligCode=\"1113\"/>\n   </Char>\n   <Char code=\"1084\" width=\"0.766663\" height=\"0.444445\" />\n   <Char code=\"1085\" width=\"0.6388855\" height=\"0.444445\" >\n      <Lig code=\"1112\" ligCode=\"1114\"/>\n   </Char>\n   <Char code=\"1086\" width=\"0.574997\" height=\"0.444445\" >\n      <Kern code=\"1076\" val=\"-0.031944\"/>\n      <Kern code=\"1078\" val=\"-0.031944\"/>\n      <Kern code=\"1093\" val=\"-0.031944\"/>\n      <Kern code=\"1103\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1087\" width=\"0.6388855\" height=\"0.444445\" >\n   </Char>\n   <Char code=\"1095\" width=\"0.6388855\" height=\"0.444445\" />\n   <Char code=\"1088\" width=\"0.6388855\" height=\"0.444445\" depth=\"0.194445\" >\n      <Kern code=\"1076\" val=\"-0.031944\"/>\n      <Kern code=\"1078\" val=\"-0.031944\"/>\n      <Kern code=\"1093\" val=\"-0.031944\"/>\n      <Kern code=\"1103\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1089\" width=\"0.511108\" height=\"0.444445\" >\n      <Lig code=\"1093\" ligCode=\"1096\"/>\n      <Kern code=\"1076\" val=\"-0.031944\"/>\n      <Kern code=\"1078\" val=\"-0.031944\"/>\n      <Kern code=\"1093\" val=\"-0.031944\"/>\n      <Kern code=\"1103\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1090\" width=\"0.544441\" height=\"0.444445\" >\n      <Lig code=\"1089\" ligCode=\"1094\"/>\n      <Kern code=\"1072\" val=\"-0.031944\"/>\n      <Kern code=\"1076\" val=\"-0.031944\"/>\n      <Kern code=\"1083\" val=\"-0.031944\"/>\n      <Kern code=\"1113\" val=\"-0.031944\"/>\n      <Kern code=\"1103\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1091\" width=\"0.606941\" height=\"0.444445\" depth=\"0.194445\" italic=\"0.015973\" >\n      <Kern code=\"1072\" val=\"-0.031944\"/>\n      <Kern code=\"1086\" val=\"-0.031944\"/>\n      <Kern code=\"1139\" val=\"-0.031944\"/>\n      <Kern code=\"1089\" val=\"-0.031944\"/>\n      <Kern code=\"1108\" val=\"-0.031944\"/>\n      <Kern code=\"1077\" val=\"-0.031944\"/>\n      <Kern code=\"1105\" val=\"-0.031944\"/>\n      <Kern code=\"1103\" val=\"-0.031944\"/>\n      <Kern code=\"1076\" val=\"-0.063889\"/>\n      <Kern code=\"1083\" val=\"-0.063889\"/>\n      <Kern code=\"1113\" val=\"-0.063889\"/>\n   </Char>\n   <Char code=\"1074\" width=\"0.574997\" height=\"0.444445\" />\n   <Char code=\"1097\" width=\"0.941663\" height=\"0.444445\" depth=\"0.162038\" />\n   <Char code=\"1096\" width=\"0.941663\" height=\"0.444445\" >\n      <Lig code=\"1095\" ligCode=\"1097\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1099\" width=\"0.830551\" height=\"0.444445\" >\n      <Lig code=\"1072\" ligCode=\"1103\"/>\n      <Lig code=\"1091\" ligCode=\"1102\"/>\n   </Char>\n   <Char code=\"1079\" width=\"0.511108\" height=\"0.444445\" italic=\"0.006389\" >\n      <Lig code=\"1093\" ligCode=\"1078\"/>\n   </Char>\n   <Char code=\"1100\" width=\"0.574997\" height=\"0.444445\" >\n      <Kern code=\"1091\" val=\"-0.063889\"/>\n      <Kern code=\"1141\" val=\"-0.063889\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.095833\"/>\n      <Kern code=\"1086\" val=\"-0.031944\"/>\n      <Kern code=\"1139\" val=\"-0.031944\"/>\n      <Kern code=\"1092\" val=\"-0.031944\"/>\n      <Kern code=\"1108\" val=\"-0.031944\"/>\n   </Char>\n   <Char code=\"1098\" width=\"0.687495\" height=\"0.444445\" >\n      <Kern code=\"1091\" val=\"-0.063889\"/>\n      <Kern code=\"1141\" val=\"-0.063889\"/>\n      <Kern code=\"1090\" val=\"-0.031944\"/>\n      <Kern code=\"1098\" val=\"-0.031944\"/>\n      <Kern code=\"1123\" val=\"-0.031944\"/>\n      <Kern code=\"1095\" val=\"-0.095833\"/>\n      <Kern code=\"1086\" val=\"-0.031944\"/>\n      <Kern code=\"1139\" val=\"-0.031944\"/>\n      <Kern code=\"1092\" val=\"-0.031944\"/>\n      <Kern code=\"1108\" val=\"-0.031944\"/>\n   </Char>\n</Font>\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/cyrillic/wnbxti10.xml",
    "content": "<Font name=\"wnbxti10.ttf\" id=\"wnbxti10\" space=\"0.414441\" xHeight=\"0.444445\" quad=\"1.182211\" unicode=\"95\" romanVersion=\"wnbx10\" ttVersion=\"wntt10\" ssVersion=\"wnssbx10\">\n   <Char code=\"1034\" width=\"1.198877\" height=\"0.686111\" italic=\"0.032991\" >\n      <Kern code=\"1046\" val=\"-0.029445\"/>\n      <Kern code=\"1061\" val=\"-0.029445\"/>\n      <Kern code=\"1054\" val=\"-0.029445\"/>\n      <Kern code=\"1060\" val=\"-0.029445\"/>\n      <Kern code=\"1138\" val=\"-0.029445\"/>\n      <Kern code=\"1057\" val=\"-0.029445\"/>\n      <Kern code=\"1028\" val=\"-0.029445\"/>\n      <Kern code=\"1058\" val=\"-0.088333\"/>\n      <Kern code=\"1066\" val=\"-0.088333\"/>\n      <Kern code=\"1026\" val=\"-0.088333\"/>\n      <Kern code=\"1035\" val=\"-0.088333\"/>\n      <Kern code=\"1122\" val=\"-0.088333\"/>\n      <Kern code=\"1063\" val=\"-0.088333\"/>\n      <Kern code=\"1059\" val=\"-0.088333\"/>\n      <Kern code=\"1140\" val=\"-0.117777\"/>\n      <Kern code=\"1098\" val=\"-0.029445\"/>\n      <Kern code=\"1141\" val=\"-0.029445\"/>\n      <Kern code=\"1082\" val=\"-0.029445\"/>\n      <Kern code=\"1085\" val=\"-0.029445\"/>\n      <Kern code=\"1114\" val=\"-0.029445\"/>\n      <Kern code=\"1087\" val=\"-0.029445\"/>\n      <Kern code=\"1090\" val=\"-0.029445\"/>\n      <Kern code=\"1102\" val=\"-0.029445\"/>\n      <Kern code=\"1123\" val=\"-0.029445\"/>\n      <Kern code=\"1110\" val=\"-0.029445\"/>\n      <Kern code=\"1080\" val=\"-0.029445\"/>\n      <Kern code=\"1081\" val=\"-0.029445\"/>\n      <Kern code=\"1094\" val=\"-0.029445\"/>\n      <Kern code=\"1096\" val=\"-0.029445\"/>\n      <Kern code=\"1097\" val=\"-0.029445\"/>\n      <Kern code=\"1100\" val=\"-0.029445\"/>\n      <Kern code=\"1099\" val=\"-0.029445\"/>\n      <Kern code=\"1091\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1033\" width=\"1.198877\" height=\"0.686111\" italic=\"0.032991\" >\n      <Kern code=\"1046\" val=\"-0.029445\"/>\n      <Kern code=\"1061\" val=\"-0.029445\"/>\n      <Kern code=\"1054\" val=\"-0.029445\"/>\n      <Kern code=\"1060\" val=\"-0.029445\"/>\n      <Kern code=\"1138\" val=\"-0.029445\"/>\n      <Kern code=\"1057\" val=\"-0.029445\"/>\n      <Kern code=\"1028\" val=\"-0.029445\"/>\n      <Kern code=\"1058\" val=\"-0.088333\"/>\n      <Kern code=\"1066\" val=\"-0.088333\"/>\n      <Kern code=\"1026\" val=\"-0.088333\"/>\n      <Kern code=\"1035\" val=\"-0.088333\"/>\n      <Kern code=\"1122\" val=\"-0.088333\"/>\n      <Kern code=\"1063\" val=\"-0.088333\"/>\n      <Kern code=\"1059\" val=\"-0.088333\"/>\n      <Kern code=\"1140\" val=\"-0.117777\"/>\n      <Kern code=\"1098\" val=\"-0.029445\"/>\n      <Kern code=\"1141\" val=\"-0.029445\"/>\n      <Kern code=\"1082\" val=\"-0.029445\"/>\n      <Kern code=\"1085\" val=\"-0.029445\"/>\n      <Kern code=\"1114\" val=\"-0.029445\"/>\n      <Kern code=\"1087\" val=\"-0.029445\"/>\n      <Kern code=\"1090\" val=\"-0.029445\"/>\n      <Kern code=\"1102\" val=\"-0.029445\"/>\n      <Kern code=\"1123\" val=\"-0.029445\"/>\n      <Kern code=\"1110\" val=\"-0.029445\"/>\n      <Kern code=\"1080\" val=\"-0.029445\"/>\n      <Kern code=\"1081\" val=\"-0.029445\"/>\n      <Kern code=\"1094\" val=\"-0.029445\"/>\n      <Kern code=\"1096\" val=\"-0.029445\"/>\n      <Kern code=\"1097\" val=\"-0.029445\"/>\n      <Kern code=\"1100\" val=\"-0.029445\"/>\n      <Kern code=\"1099\" val=\"-0.029445\"/>\n      <Kern code=\"1091\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1039\" width=\"0.894992\" height=\"0.686111\" depth=\"0.194445\" italic=\"0.172084\" />\n   <Char code=\"1069\" width=\"0.826658\" height=\"0.686111\" italic=\"0.090625\" >\n      <Kern code=\"1040\" val=\"-0.029445\"/>\n      <Kern code=\"1044\" val=\"-0.029445\"/>\n      <Kern code=\"1046\" val=\"-0.029445\"/>\n      <Kern code=\"1061\" val=\"-0.029445\"/>\n      <Kern code=\"1059\" val=\"-0.029445\"/>\n      <Kern code=\"1140\" val=\"-0.029445\"/>\n      <Kern code=\"1071\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1030\" width=\"0.471664\" height=\"0.686111\" italic=\"0.156807\" >\n      <Kern code=\"1030\" val=\"0.029445\"/>\n   </Char>\n   <Char code=\"1028\" width=\"0.826658\" height=\"0.686111\" italic=\"0.142084\" />\n   <Char code=\"1026\" width=\"0.943324\" height=\"0.686111\" italic=\"0.12903\" >\n      <Kern code=\"1046\" val=\"-0.029445\"/>\n      <Kern code=\"1061\" val=\"-0.029445\"/>\n      <Kern code=\"1054\" val=\"-0.029445\"/>\n      <Kern code=\"1060\" val=\"-0.029445\"/>\n      <Kern code=\"1138\" val=\"-0.029445\"/>\n      <Kern code=\"1057\" val=\"-0.029445\"/>\n      <Kern code=\"1028\" val=\"-0.029445\"/>\n      <Kern code=\"1058\" val=\"-0.088333\"/>\n      <Kern code=\"1066\" val=\"-0.088333\"/>\n      <Kern code=\"1026\" val=\"-0.088333\"/>\n      <Kern code=\"1035\" val=\"-0.088333\"/>\n      <Kern code=\"1122\" val=\"-0.088333\"/>\n      <Kern code=\"1063\" val=\"-0.088333\"/>\n      <Kern code=\"1059\" val=\"-0.088333\"/>\n      <Kern code=\"1140\" val=\"-0.117777\"/>\n      <Kern code=\"1098\" val=\"-0.029445\"/>\n      <Kern code=\"1141\" val=\"-0.029445\"/>\n      <Kern code=\"1082\" val=\"-0.029445\"/>\n      <Kern code=\"1085\" val=\"-0.029445\"/>\n      <Kern code=\"1114\" val=\"-0.029445\"/>\n      <Kern code=\"1087\" val=\"-0.029445\"/>\n      <Kern code=\"1090\" val=\"-0.029445\"/>\n      <Kern code=\"1102\" val=\"-0.029445\"/>\n      <Kern code=\"1123\" val=\"-0.029445\"/>\n      <Kern code=\"1110\" val=\"-0.029445\"/>\n      <Kern code=\"1080\" val=\"-0.029445\"/>\n      <Kern code=\"1081\" val=\"-0.029445\"/>\n      <Kern code=\"1094\" val=\"-0.029445\"/>\n      <Kern code=\"1096\" val=\"-0.029445\"/>\n      <Kern code=\"1097\" val=\"-0.029445\"/>\n      <Kern code=\"1100\" val=\"-0.029445\"/>\n      <Kern code=\"1099\" val=\"-0.029445\"/>\n      <Kern code=\"1091\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1035\" width=\"0.870825\" height=\"0.686111\" italic=\"0.084864\" />\n   <Char code=\"1114\" width=\"0.82666\" height=\"0.444445\" italic=\"0.078611\" >\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n      <Kern code=\"1141\" val=\"-0.029445\"/>\n      <Kern code=\"1098\" val=\"-0.029445\"/>\n      <Kern code=\"1095\" val=\"-0.088333\"/>\n      <Kern code=\"1086\" val=\"-0.029445\"/>\n      <Kern code=\"1139\" val=\"-0.029445\"/>\n      <Kern code=\"1092\" val=\"-0.029445\"/>\n      <Kern code=\"1108\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1113\" width=\"0.797215\" height=\"0.444445\" italic=\"0.078611\" >\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n      <Kern code=\"1141\" val=\"-0.029445\"/>\n      <Kern code=\"1098\" val=\"-0.029445\"/>\n      <Kern code=\"1095\" val=\"-0.088333\"/>\n      <Kern code=\"1086\" val=\"-0.029445\"/>\n      <Kern code=\"1139\" val=\"-0.029445\"/>\n      <Kern code=\"1092\" val=\"-0.029445\"/>\n      <Kern code=\"1108\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1119\" width=\"0.62055\" height=\"0.444445\" depth=\"0.194445\" italic=\"0.094261\" />\n   <Char code=\"1101\" width=\"0.511606\" height=\"0.444445\" italic=\"0.078611\" >\n      <Kern code=\"1092\" val=\"-0.058888\"/>\n      <Kern code=\"1072\" val=\"-0.058888\"/>\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1110\" width=\"0.355553\" height=\"0.693255\" italic=\"0.113872\" />\n   <Char code=\"1108\" width=\"0.511606\" height=\"0.444445\" italic=\"0.081667\" />\n   <Char code=\"1106\" width=\"0.532217\" height=\"0.694445\" depth=\"0.194445\" italic=\"0.077777\" />\n   <Char code=\"1115\" width=\"0.591105\" height=\"0.694445\" italic=\"0.094261\" />\n   <Char code=\"1070\" width=\"1.236933\" height=\"0.686111\" italic=\"0.090625\" >\n      <Kern code=\"1040\" val=\"-0.029445\"/>\n      <Kern code=\"1044\" val=\"-0.029445\"/>\n      <Kern code=\"1046\" val=\"-0.029445\"/>\n      <Kern code=\"1061\" val=\"-0.029445\"/>\n      <Kern code=\"1059\" val=\"-0.029445\"/>\n      <Kern code=\"1140\" val=\"-0.029445\"/>\n      <Kern code=\"1071\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1046\" width=\"1.318319\" height=\"0.686111\" italic=\"0.142084\" >\n      <Kern code=\"1054\" val=\"-0.029445\"/>\n      <Kern code=\"1060\" val=\"-0.029445\"/>\n      <Kern code=\"1138\" val=\"-0.029445\"/>\n      <Kern code=\"1057\" val=\"-0.029445\"/>\n      <Kern code=\"1028\" val=\"-0.029445\"/>\n      <Kern code=\"1095\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1049\" width=\"0.894992\" height=\"0.894394\" italic=\"0.172084\" />\n   <Char code=\"1025\" width=\"0.756659\" height=\"0.894394\" italic=\"0.114306\" />\n   <Char code=\"1140\" width=\"0.934436\" height=\"0.686111\" italic=\"0.186251\" >\n      <Kern code=\"1040\" val=\"-0.117777\"/>\n      <Kern code=\"1071\" val=\"-0.117777\"/>\n      <Kern code=\"1054\" val=\"-0.029445\"/>\n      <Kern code=\"1060\" val=\"-0.029445\"/>\n      <Kern code=\"1138\" val=\"-0.029445\"/>\n      <Kern code=\"1057\" val=\"-0.029445\"/>\n      <Kern code=\"1028\" val=\"-0.029445\"/>\n      <Kern code=\"1072\" val=\"-0.088333\"/>\n      <Kern code=\"1086\" val=\"-0.088333\"/>\n      <Kern code=\"1139\" val=\"-0.088333\"/>\n      <Kern code=\"1077\" val=\"-0.088333\"/>\n      <Kern code=\"1105\" val=\"-0.088333\"/>\n      <Kern code=\"1080\" val=\"-0.117777\"/>\n      <Kern code=\"1081\" val=\"-0.117777\"/>\n      <Kern code=\"1094\" val=\"-0.117777\"/>\n      <Kern code=\"1096\" val=\"-0.117777\"/>\n      <Kern code=\"1097\" val=\"-0.117777\"/>\n      <Kern code=\"1100\" val=\"-0.117777\"/>\n      <Kern code=\"1099\" val=\"-0.117777\"/>\n      <Kern code=\"1091\" val=\"-0.117777\"/>\n      <Kern code=\"1141\" val=\"-0.117777\"/>\n      <Kern code=\"1098\" val=\"-0.117777\"/>\n      <Kern code=\"1083\" val=\"-0.117777\"/>\n      <Kern code=\"1084\" val=\"-0.117777\"/>\n      <Kern code=\"1113\" val=\"-0.117777\"/>\n   </Char>\n   <Char code=\"1138\" width=\"0.885547\" height=\"0.686111\" italic=\"0.090625\" >\n      <Kern code=\"1040\" val=\"-0.029445\"/>\n      <Kern code=\"1044\" val=\"-0.029445\"/>\n      <Kern code=\"1046\" val=\"-0.029445\"/>\n      <Kern code=\"1061\" val=\"-0.029445\"/>\n      <Kern code=\"1059\" val=\"-0.029445\"/>\n      <Kern code=\"1140\" val=\"-0.029445\"/>\n      <Kern code=\"1071\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1029\" width=\"0.649994\" height=\"0.686111\" italic=\"0.11264\" />\n   <Char code=\"1071\" width=\"0.894992\" height=\"0.686111\" italic=\"0.172084\" />\n   <Char code=\"1102\" width=\"0.835492\" height=\"0.444445\" italic=\"0.078611\" >\n      <Kern code=\"1092\" val=\"-0.058888\"/>\n      <Kern code=\"1072\" val=\"-0.058888\"/>\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1078\" width=\"1.209432\" height=\"0.444445\" italic=\"0.052223\" />\n   <Char code=\"1081\" width=\"0.649994\" height=\"0.652727\" italic=\"0.094261\" />\n   <Char code=\"1105\" width=\"0.511606\" height=\"0.686111\" italic=\"0.085002\" >\n      <Kern code=\"1092\" val=\"-0.058888\"/>\n      <Kern code=\"1072\" val=\"-0.058888\"/>\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1141\" width=\"0.723051\" height=\"0.444445\" italic=\"0.1258335\" >\n      <Kern code=\"1083\" val=\"-0.088333\"/>\n      <Kern code=\"1084\" val=\"-0.088333\"/>\n      <Kern code=\"1113\" val=\"-0.088333\"/>\n   </Char>\n   <Char code=\"1139\" width=\"0.532217\" height=\"0.444445\" italic=\"0.078611\" >\n      <Kern code=\"1092\" val=\"-0.058888\"/>\n      <Kern code=\"1072\" val=\"-0.058888\"/>\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1109\" width=\"0.486941\" height=\"0.444445\" italic=\"0.081667\" />\n   <Char code=\"1103\" width=\"0.62055\" height=\"0.444445\" italic=\"0.094261\" />\n   <Char code=\"776\" width=\"0.591105\" height=\"0.686111\" italic=\"0.112642\" />\n   <Char code=\"1122\" width=\"0.934436\" height=\"0.75\" italic=\"0.099202\" >\n      <Kern code=\"1046\" val=\"-0.029445\"/>\n      <Kern code=\"1061\" val=\"-0.029445\"/>\n      <Kern code=\"1054\" val=\"-0.029445\"/>\n      <Kern code=\"1060\" val=\"-0.029445\"/>\n      <Kern code=\"1138\" val=\"-0.029445\"/>\n      <Kern code=\"1057\" val=\"-0.029445\"/>\n      <Kern code=\"1028\" val=\"-0.029445\"/>\n      <Kern code=\"1058\" val=\"-0.088333\"/>\n      <Kern code=\"1066\" val=\"-0.088333\"/>\n      <Kern code=\"1026\" val=\"-0.088333\"/>\n      <Kern code=\"1035\" val=\"-0.088333\"/>\n      <Kern code=\"1122\" val=\"-0.088333\"/>\n      <Kern code=\"1063\" val=\"-0.088333\"/>\n      <Kern code=\"1059\" val=\"-0.088333\"/>\n      <Kern code=\"1140\" val=\"-0.117777\"/>\n      <Kern code=\"1098\" val=\"-0.029445\"/>\n      <Kern code=\"1141\" val=\"-0.029445\"/>\n      <Kern code=\"1082\" val=\"-0.029445\"/>\n      <Kern code=\"1085\" val=\"-0.029445\"/>\n      <Kern code=\"1114\" val=\"-0.029445\"/>\n      <Kern code=\"1087\" val=\"-0.029445\"/>\n      <Kern code=\"1090\" val=\"-0.029445\"/>\n      <Kern code=\"1102\" val=\"-0.029445\"/>\n      <Kern code=\"1123\" val=\"-0.029445\"/>\n      <Kern code=\"1110\" val=\"-0.029445\"/>\n      <Kern code=\"1080\" val=\"-0.029445\"/>\n      <Kern code=\"1081\" val=\"-0.029445\"/>\n      <Kern code=\"1094\" val=\"-0.029445\"/>\n      <Kern code=\"1096\" val=\"-0.029445\"/>\n      <Kern code=\"1097\" val=\"-0.029445\"/>\n      <Kern code=\"1100\" val=\"-0.029445\"/>\n      <Kern code=\"1099\" val=\"-0.029445\"/>\n      <Kern code=\"1091\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"774\" width=\"0.591105\" height=\"0.652727\" italic=\"0.092905\" />\n   <Char code=\"1123\" width=\"0.826658\" height=\"0.444445\" italic=\"0.078611\" >\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n      <Kern code=\"1141\" val=\"-0.029445\"/>\n      <Kern code=\"1098\" val=\"-0.029445\"/>\n      <Kern code=\"1095\" val=\"-0.088333\"/>\n      <Kern code=\"1086\" val=\"-0.029445\"/>\n      <Kern code=\"1139\" val=\"-0.029445\"/>\n      <Kern code=\"1092\" val=\"-0.029445\"/>\n      <Kern code=\"1108\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"171\" width=\"0.649994\" height=\"0.472223\" italic=\"0.008611\" />\n   <Char code=\"305\" width=\"0.355553\" height=\"0.444445\" italic=\"0.094261\" />\n   <Char code=\"187\" width=\"0.649994\" height=\"0.472223\" />\n   <Char code=\"1040\" width=\"0.865547\" height=\"0.686111\" >\n      <Kern code=\"1054\" val=\"-0.029445\"/>\n      <Kern code=\"1060\" val=\"-0.029445\"/>\n      <Kern code=\"1138\" val=\"-0.029445\"/>\n      <Kern code=\"1057\" val=\"-0.029445\"/>\n      <Kern code=\"1028\" val=\"-0.029445\"/>\n      <Kern code=\"1058\" val=\"-0.088333\"/>\n      <Kern code=\"1066\" val=\"-0.088333\"/>\n      <Kern code=\"1026\" val=\"-0.088333\"/>\n      <Kern code=\"1035\" val=\"-0.088333\"/>\n      <Kern code=\"1122\" val=\"-0.088333\"/>\n      <Kern code=\"1063\" val=\"-0.088333\"/>\n      <Kern code=\"1059\" val=\"-0.088333\"/>\n      <Kern code=\"1140\" val=\"-0.117777\"/>\n      <Kern code=\"1098\" val=\"-0.029445\"/>\n      <Kern code=\"1141\" val=\"-0.029445\"/>\n      <Kern code=\"1082\" val=\"-0.029445\"/>\n      <Kern code=\"1085\" val=\"-0.029445\"/>\n      <Kern code=\"1114\" val=\"-0.029445\"/>\n      <Kern code=\"1087\" val=\"-0.029445\"/>\n      <Kern code=\"1090\" val=\"-0.029445\"/>\n      <Kern code=\"1102\" val=\"-0.029445\"/>\n      <Kern code=\"1123\" val=\"-0.029445\"/>\n      <Kern code=\"1110\" val=\"-0.029445\"/>\n      <Kern code=\"1080\" val=\"-0.029445\"/>\n      <Kern code=\"1081\" val=\"-0.029445\"/>\n      <Kern code=\"1094\" val=\"-0.029445\"/>\n      <Kern code=\"1096\" val=\"-0.029445\"/>\n      <Kern code=\"1097\" val=\"-0.029445\"/>\n      <Kern code=\"1100\" val=\"-0.029445\"/>\n      <Kern code=\"1099\" val=\"-0.029445\"/>\n      <Kern code=\"1091\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1041\" width=\"0.81666\" height=\"0.686111\" italic=\"0.055418\" />\n   <Char code=\"1062\" width=\"0.894992\" height=\"0.686111\" depth=\"0.194445\" italic=\"0.172084\" >\n      <Lig code=\"1061\" ligCode=\"1063\"/>\n      <Lig code=\"1093\" ligCode=\"1063\"/>\n   </Char>\n   <Char code=\"1044\" width=\"0.894992\" height=\"0.686111\" depth=\"0.194445\" italic=\"0.172084\" >\n      <Lig code=\"1032\" ligCode=\"1026\"/>\n      <Lig code=\"1112\" ligCode=\"1026\"/>\n   </Char>\n   <Char code=\"1045\" width=\"0.756659\" height=\"0.686111\" italic=\"0.114306\" >\n   </Char>\n   <Char code=\"1060\" width=\"0.944435\" height=\"0.686111\" italic=\"0.090625\" >\n      <Kern code=\"1040\" val=\"-0.029445\"/>\n      <Kern code=\"1044\" val=\"-0.029445\"/>\n      <Kern code=\"1046\" val=\"-0.029445\"/>\n      <Kern code=\"1061\" val=\"-0.029445\"/>\n      <Kern code=\"1059\" val=\"-0.029445\"/>\n      <Kern code=\"1140\" val=\"-0.029445\"/>\n      <Kern code=\"1071\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1043\" width=\"0.697771\" height=\"0.686111\" italic=\"0.12903\" >\n      <Kern code=\"1040\" val=\"-0.088333\"/>\n      <Kern code=\"1044\" val=\"-0.088333\"/>\n      <Kern code=\"1071\" val=\"-0.088333\"/>\n      <Kern code=\"1051\" val=\"-0.029445\"/>\n      <Kern code=\"1033\" val=\"-0.029445\"/>\n      <Kern code=\"1072\" val=\"-0.088333\"/>\n      <Kern code=\"1086\" val=\"-0.088333\"/>\n      <Kern code=\"1139\" val=\"-0.088333\"/>\n      <Kern code=\"1077\" val=\"-0.088333\"/>\n      <Kern code=\"1105\" val=\"-0.088333\"/>\n      <Kern code=\"1089\" val=\"-0.088333\"/>\n      <Kern code=\"1108\" val=\"-0.088333\"/>\n      <Kern code=\"1092\" val=\"-0.088333\"/>\n      <Kern code=\"1080\" val=\"-0.088333\"/>\n      <Kern code=\"1081\" val=\"-0.088333\"/>\n      <Kern code=\"1094\" val=\"-0.088333\"/>\n      <Kern code=\"1096\" val=\"-0.088333\"/>\n      <Kern code=\"1097\" val=\"-0.088333\"/>\n      <Kern code=\"1100\" val=\"-0.088333\"/>\n      <Kern code=\"1099\" val=\"-0.088333\"/>\n      <Kern code=\"1091\" val=\"-0.088333\"/>\n      <Kern code=\"1141\" val=\"-0.088333\"/>\n      <Kern code=\"1098\" val=\"-0.088333\"/>\n      <Kern code=\"1083\" val=\"-0.088333\"/>\n      <Kern code=\"1084\" val=\"-0.088333\"/>\n      <Kern code=\"1113\" val=\"-0.088333\"/>\n   </Char>\n   <Char code=\"1061\" width=\"0.865547\" height=\"0.686111\" italic=\"0.156807\" >\n      <Kern code=\"1054\" val=\"-0.029445\"/>\n      <Kern code=\"1060\" val=\"-0.029445\"/>\n      <Kern code=\"1138\" val=\"-0.029445\"/>\n      <Kern code=\"1057\" val=\"-0.029445\"/>\n      <Kern code=\"1028\" val=\"-0.029445\"/>\n      <Kern code=\"1095\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1048\" width=\"0.894992\" height=\"0.686111\" italic=\"0.172084\" >\n   </Char>\n   <Char code=\"1032\" width=\"0.61055\" height=\"0.686111\" italic=\"0.145001\" >\n   </Char>\n   <Char code=\"1050\" width=\"0.894992\" height=\"0.686111\" italic=\"0.142084\" >\n      <Lig code=\"1061\" ligCode=\"1061\"/>\n      <Lig code=\"1093\" ligCode=\"1061\"/>\n      <Kern code=\"1054\" val=\"-0.029445\"/>\n      <Kern code=\"1060\" val=\"-0.029445\"/>\n      <Kern code=\"1138\" val=\"-0.029445\"/>\n      <Kern code=\"1057\" val=\"-0.029445\"/>\n      <Kern code=\"1028\" val=\"-0.029445\"/>\n      <Kern code=\"1095\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1051\" width=\"0.894992\" height=\"0.686111\" italic=\"0.172084\" >\n      <Lig code=\"1032\" ligCode=\"1033\"/>\n      <Lig code=\"1112\" ligCode=\"1033\"/>\n   </Char>\n   <Char code=\"1052\" width=\"1.072767\" height=\"0.686111\" italic=\"0.172084\" />\n   <Char code=\"1053\" width=\"0.894992\" height=\"0.686111\" italic=\"0.172084\" >\n      <Lig code=\"1032\" ligCode=\"1034\"/>\n      <Lig code=\"1112\" ligCode=\"1034\"/>\n   </Char>\n   <Char code=\"1054\" width=\"0.854991\" height=\"0.686111\" italic=\"0.090625\" >\n      <Kern code=\"1040\" val=\"-0.029445\"/>\n      <Kern code=\"1044\" val=\"-0.029445\"/>\n      <Kern code=\"1046\" val=\"-0.029445\"/>\n      <Kern code=\"1061\" val=\"-0.029445\"/>\n      <Kern code=\"1059\" val=\"-0.029445\"/>\n      <Kern code=\"1140\" val=\"-0.029445\"/>\n      <Kern code=\"1071\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1055\" width=\"0.894992\" height=\"0.686111\" italic=\"0.172084\" >\n   </Char>\n   <Char code=\"1063\" width=\"0.894992\" height=\"0.686111\" italic=\"0.172084\" />\n   <Char code=\"1056\" width=\"0.787214\" height=\"0.686111\" italic=\"0.099202\" >\n      <Kern code=\"1040\" val=\"-0.088333\"/>\n      <Kern code=\"1044\" val=\"-0.088333\"/>\n      <Kern code=\"1051\" val=\"-0.088333\"/>\n      <Kern code=\"1033\" val=\"-0.088333\"/>\n      <Kern code=\"1071\" val=\"-0.088333\"/>\n      <Kern code=\"1072\" val=\"-0.029445\"/>\n      <Kern code=\"1086\" val=\"-0.029445\"/>\n      <Kern code=\"1139\" val=\"-0.029445\"/>\n      <Kern code=\"1077\" val=\"-0.029445\"/>\n      <Kern code=\"1105\" val=\"-0.029445\"/>\n      <Kern code=\"1076\" val=\"-0.088333\"/>\n      <Kern code=\"1083\" val=\"-0.088333\"/>\n      <Kern code=\"1113\" val=\"-0.088333\"/>\n   </Char>\n   <Char code=\"1057\" width=\"0.826658\" height=\"0.686111\" italic=\"0.142084\" >\n      <Lig code=\"1061\" ligCode=\"1064\"/>\n      <Lig code=\"1093\" ligCode=\"1064\"/>\n   </Char>\n   <Char code=\"1058\" width=\"0.796103\" height=\"0.686111\" italic=\"0.12903\" >\n      <Lig code=\"1057\" ligCode=\"1062\"/>\n      <Lig code=\"1089\" ligCode=\"1062\"/>\n      <Kern code=\"1040\" val=\"-0.088333\"/>\n      <Kern code=\"1044\" val=\"-0.088333\"/>\n      <Kern code=\"1071\" val=\"-0.088333\"/>\n      <Kern code=\"1051\" val=\"-0.029445\"/>\n      <Kern code=\"1033\" val=\"-0.029445\"/>\n      <Kern code=\"1072\" val=\"-0.088333\"/>\n      <Kern code=\"1086\" val=\"-0.088333\"/>\n      <Kern code=\"1139\" val=\"-0.088333\"/>\n      <Kern code=\"1077\" val=\"-0.088333\"/>\n      <Kern code=\"1105\" val=\"-0.088333\"/>\n      <Kern code=\"1089\" val=\"-0.088333\"/>\n      <Kern code=\"1108\" val=\"-0.088333\"/>\n      <Kern code=\"1092\" val=\"-0.088333\"/>\n      <Kern code=\"1080\" val=\"-0.088333\"/>\n      <Kern code=\"1081\" val=\"-0.088333\"/>\n      <Kern code=\"1094\" val=\"-0.088333\"/>\n      <Kern code=\"1096\" val=\"-0.088333\"/>\n      <Kern code=\"1097\" val=\"-0.088333\"/>\n      <Kern code=\"1100\" val=\"-0.088333\"/>\n      <Kern code=\"1099\" val=\"-0.088333\"/>\n      <Kern code=\"1091\" val=\"-0.088333\"/>\n      <Kern code=\"1141\" val=\"-0.088333\"/>\n      <Kern code=\"1098\" val=\"-0.088333\"/>\n      <Kern code=\"1083\" val=\"-0.088333\"/>\n      <Kern code=\"1084\" val=\"-0.088333\"/>\n      <Kern code=\"1113\" val=\"-0.088333\"/>\n   </Char>\n   <Char code=\"1059\" width=\"0.865547\" height=\"0.686111\" italic=\"0.186251\" >\n      <Kern code=\"1040\" val=\"-0.088333\"/>\n      <Kern code=\"1071\" val=\"-0.088333\"/>\n      <Kern code=\"1044\" val=\"-0.058888\"/>\n      <Kern code=\"1051\" val=\"-0.058888\"/>\n      <Kern code=\"1033\" val=\"-0.058888\"/>\n      <Kern code=\"1054\" val=\"-0.029445\"/>\n      <Kern code=\"1060\" val=\"-0.029445\"/>\n      <Kern code=\"1138\" val=\"-0.029445\"/>\n      <Kern code=\"1057\" val=\"-0.029445\"/>\n      <Kern code=\"1028\" val=\"-0.029445\"/>\n      <Kern code=\"1072\" val=\"-0.088333\"/>\n      <Kern code=\"1086\" val=\"-0.088333\"/>\n      <Kern code=\"1139\" val=\"-0.088333\"/>\n      <Kern code=\"1077\" val=\"-0.088333\"/>\n      <Kern code=\"1105\" val=\"-0.088333\"/>\n      <Kern code=\"1089\" val=\"-0.088333\"/>\n      <Kern code=\"1108\" val=\"-0.088333\"/>\n      <Kern code=\"1080\" val=\"-0.117777\"/>\n      <Kern code=\"1081\" val=\"-0.117777\"/>\n      <Kern code=\"1094\" val=\"-0.117777\"/>\n      <Kern code=\"1096\" val=\"-0.117777\"/>\n      <Kern code=\"1097\" val=\"-0.117777\"/>\n      <Kern code=\"1100\" val=\"-0.117777\"/>\n      <Kern code=\"1099\" val=\"-0.117777\"/>\n      <Kern code=\"1091\" val=\"-0.117777\"/>\n      <Kern code=\"1141\" val=\"-0.117777\"/>\n      <Kern code=\"1098\" val=\"-0.117777\"/>\n      <Kern code=\"1083\" val=\"-0.117777\"/>\n      <Kern code=\"1084\" val=\"-0.117777\"/>\n      <Kern code=\"1113\" val=\"-0.117777\"/>\n   </Char>\n   <Char code=\"1042\" width=\"0.81666\" height=\"0.686111\" italic=\"0.069758\" />\n   <Char code=\"1065\" width=\"1.293599\" height=\"0.686111\" depth=\"0.194445\" italic=\"0.172084\" />\n   <Char code=\"1064\" width=\"1.293599\" height=\"0.686111\" italic=\"0.172084\" >\n      <Lig code=\"1063\" ligCode=\"1065\"/>\n      <Lig code=\"1095\" ligCode=\"1065\"/>\n      <Lig code=\"1062\" ligCode=\"0\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1067\" width=\"1.101102\" height=\"0.686111\" italic=\"0.172084\" >\n      <Lig code=\"1040\" ligCode=\"1071\"/>\n      <Lig code=\"1072\" ligCode=\"1071\"/>\n      <Lig code=\"1059\" ligCode=\"1070\"/>\n      <Lig code=\"1091\" ligCode=\"1070\"/>\n   </Char>\n   <Char code=\"1047\" width=\"0.708882\" height=\"0.686111\" italic=\"0.099202\" >\n      <Lig code=\"1061\" ligCode=\"1046\"/>\n      <Lig code=\"1093\" ligCode=\"1046\"/>\n   </Char>\n   <Char code=\"1068\" width=\"0.81666\" height=\"0.686111\" italic=\"0.032991\" >\n      <Kern code=\"1046\" val=\"-0.029445\"/>\n      <Kern code=\"1061\" val=\"-0.029445\"/>\n      <Kern code=\"1054\" val=\"-0.029445\"/>\n      <Kern code=\"1060\" val=\"-0.029445\"/>\n      <Kern code=\"1138\" val=\"-0.029445\"/>\n      <Kern code=\"1057\" val=\"-0.029445\"/>\n      <Kern code=\"1028\" val=\"-0.029445\"/>\n      <Kern code=\"1058\" val=\"-0.088333\"/>\n      <Kern code=\"1066\" val=\"-0.088333\"/>\n      <Kern code=\"1026\" val=\"-0.088333\"/>\n      <Kern code=\"1035\" val=\"-0.088333\"/>\n      <Kern code=\"1122\" val=\"-0.088333\"/>\n      <Kern code=\"1063\" val=\"-0.088333\"/>\n      <Kern code=\"1059\" val=\"-0.088333\"/>\n      <Kern code=\"1140\" val=\"-0.117777\"/>\n      <Kern code=\"1098\" val=\"-0.029445\"/>\n      <Kern code=\"1141\" val=\"-0.029445\"/>\n      <Kern code=\"1082\" val=\"-0.029445\"/>\n      <Kern code=\"1085\" val=\"-0.029445\"/>\n      <Kern code=\"1114\" val=\"-0.029445\"/>\n      <Kern code=\"1087\" val=\"-0.029445\"/>\n      <Kern code=\"1090\" val=\"-0.029445\"/>\n      <Kern code=\"1102\" val=\"-0.029445\"/>\n      <Kern code=\"1123\" val=\"-0.029445\"/>\n      <Kern code=\"1110\" val=\"-0.029445\"/>\n      <Kern code=\"1080\" val=\"-0.029445\"/>\n      <Kern code=\"1081\" val=\"-0.029445\"/>\n      <Kern code=\"1094\" val=\"-0.029445\"/>\n      <Kern code=\"1096\" val=\"-0.029445\"/>\n      <Kern code=\"1097\" val=\"-0.029445\"/>\n      <Kern code=\"1100\" val=\"-0.029445\"/>\n      <Kern code=\"1099\" val=\"-0.029445\"/>\n      <Kern code=\"1091\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1066\" width=\"0.988047\" height=\"0.686111\" italic=\"0.032991\" >\n      <Kern code=\"1046\" val=\"-0.029445\"/>\n      <Kern code=\"1061\" val=\"-0.029445\"/>\n      <Kern code=\"1054\" val=\"-0.029445\"/>\n      <Kern code=\"1060\" val=\"-0.029445\"/>\n      <Kern code=\"1138\" val=\"-0.029445\"/>\n      <Kern code=\"1057\" val=\"-0.029445\"/>\n      <Kern code=\"1028\" val=\"-0.029445\"/>\n      <Kern code=\"1058\" val=\"-0.088333\"/>\n      <Kern code=\"1066\" val=\"-0.088333\"/>\n      <Kern code=\"1026\" val=\"-0.088333\"/>\n      <Kern code=\"1035\" val=\"-0.088333\"/>\n      <Kern code=\"1122\" val=\"-0.088333\"/>\n      <Kern code=\"1063\" val=\"-0.088333\"/>\n      <Kern code=\"1059\" val=\"-0.088333\"/>\n      <Kern code=\"1140\" val=\"-0.117777\"/>\n      <Kern code=\"1098\" val=\"-0.029445\"/>\n      <Kern code=\"1141\" val=\"-0.029445\"/>\n      <Kern code=\"1082\" val=\"-0.029445\"/>\n      <Kern code=\"1085\" val=\"-0.029445\"/>\n      <Kern code=\"1114\" val=\"-0.029445\"/>\n      <Kern code=\"1087\" val=\"-0.029445\"/>\n      <Kern code=\"1090\" val=\"-0.029445\"/>\n      <Kern code=\"1102\" val=\"-0.029445\"/>\n      <Kern code=\"1123\" val=\"-0.029445\"/>\n      <Kern code=\"1110\" val=\"-0.029445\"/>\n      <Kern code=\"1080\" val=\"-0.029445\"/>\n      <Kern code=\"1081\" val=\"-0.029445\"/>\n      <Kern code=\"1094\" val=\"-0.029445\"/>\n      <Kern code=\"1096\" val=\"-0.029445\"/>\n      <Kern code=\"1097\" val=\"-0.029445\"/>\n      <Kern code=\"1100\" val=\"-0.029445\"/>\n      <Kern code=\"1099\" val=\"-0.029445\"/>\n      <Kern code=\"1091\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1072\" width=\"0.570494\" height=\"0.444445\" italic=\"0.094261\" />\n   <Char code=\"1073\" width=\"0.549883\" height=\"0.694445\" italic=\"0.167501\" >\n      <Kern code=\"1092\" val=\"-0.058888\"/>\n      <Kern code=\"1072\" val=\"-0.058888\"/>\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1094\" width=\"0.655884\" height=\"0.444445\" depth=\"0.194445\" italic=\"0.094261\" >\n      <Lig code=\"1093\" ligCode=\"1095\"/>\n   </Char>\n   <Char code=\"1076\" width=\"0.549883\" height=\"0.694445\" italic=\"0.112694\" >\n      <Lig code=\"1112\" ligCode=\"1106\"/>\n   </Char>\n   <Char code=\"1077\" width=\"0.511606\" height=\"0.444445\" italic=\"0.085002\" >\n      <Kern code=\"1092\" val=\"-0.058888\"/>\n      <Kern code=\"1072\" val=\"-0.058888\"/>\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1092\" width=\"0.785437\" height=\"0.694445\" depth=\"0.194445\" italic=\"0.078611\" >\n      <Kern code=\"1092\" val=\"-0.058888\"/>\n      <Kern code=\"1072\" val=\"-0.058888\"/>\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1075\" width=\"0.488052\" height=\"0.444445\" italic=\"0.085002\" />\n   <Char code=\"1093\" width=\"0.648885\" height=\"0.444445\" italic=\"0.1258335\" />\n   <Char code=\"1080\" width=\"0.649994\" height=\"0.444445\" italic=\"0.094261\" >\n   </Char>\n   <Char code=\"1112\" width=\"0.355553\" height=\"0.693255\" depth=\"0.194445\" italic=\"0.167204\" >\n   </Char>\n   <Char code=\"1082\" width=\"0.591105\" height=\"0.444445\" italic=\"0.111112\" >\n      <Lig code=\"1093\" ligCode=\"1093\"/>\n   </Char>\n   <Char code=\"1083\" width=\"0.62055\" height=\"0.444445\" italic=\"0.094261\" >\n      <Lig code=\"1112\" ligCode=\"1113\"/>\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n      <Kern code=\"1141\" val=\"-0.029445\"/>\n      <Kern code=\"1098\" val=\"-0.029445\"/>\n      <Kern code=\"1095\" val=\"-0.088333\"/>\n   </Char>\n   <Char code=\"1084\" width=\"0.856104\" height=\"0.444445\" italic=\"0.094261\" />\n   <Char code=\"1085\" width=\"0.649994\" height=\"0.444445\" italic=\"0.094261\" >\n      <Lig code=\"1112\" ligCode=\"1114\"/>\n   </Char>\n   <Char code=\"1086\" width=\"0.549883\" height=\"0.444445\" italic=\"0.078611\" >\n      <Kern code=\"1092\" val=\"-0.058888\"/>\n      <Kern code=\"1072\" val=\"-0.058888\"/>\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1087\" width=\"0.649994\" height=\"0.444445\" italic=\"0.094261\" >\n   </Char>\n   <Char code=\"1095\" width=\"0.62055\" height=\"0.444445\" italic=\"0.094261\" />\n   <Char code=\"1088\" width=\"0.585216\" height=\"0.444445\" depth=\"0.194445\" italic=\"0.078611\" >\n      <Kern code=\"1092\" val=\"-0.058888\"/>\n      <Kern code=\"1072\" val=\"-0.058888\"/>\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1089\" width=\"0.511606\" height=\"0.444445\" italic=\"0.052223\" >\n      <Lig code=\"1093\" ligCode=\"1096\"/>\n      <Kern code=\"1092\" val=\"-0.058888\"/>\n      <Kern code=\"1072\" val=\"-0.058888\"/>\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1090\" width=\"0.944435\" height=\"0.444445\" italic=\"0.094261\" >\n      <Lig code=\"1089\" ligCode=\"1094\"/>\n   </Char>\n   <Char code=\"1091\" width=\"0.591105\" height=\"0.444445\" depth=\"0.194445\" italic=\"0.105001\" />\n   <Char code=\"1074\" width=\"0.570494\" height=\"0.444445\" italic=\"0.085002\" />\n   <Char code=\"1097\" width=\"0.950325\" height=\"0.444445\" depth=\"0.194445\" italic=\"0.094261\" />\n   <Char code=\"1096\" width=\"0.944435\" height=\"0.444445\" italic=\"0.094261\" >\n      <Lig code=\"1095\" ligCode=\"1097\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1099\" width=\"0.767771\" height=\"0.444445\" italic=\"0.094261\" >\n      <Lig code=\"1072\" ligCode=\"1103\"/>\n      <Lig code=\"1091\" ligCode=\"1102\"/>\n   </Char>\n   <Char code=\"1079\" width=\"0.532217\" height=\"0.444445\" italic=\"0.052223\" >\n      <Lig code=\"1093\" ligCode=\"1078\"/>\n   </Char>\n   <Char code=\"1100\" width=\"0.591105\" height=\"0.444445\" italic=\"0.078611\" >\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n      <Kern code=\"1141\" val=\"-0.029445\"/>\n      <Kern code=\"1098\" val=\"-0.029445\"/>\n      <Kern code=\"1095\" val=\"-0.088333\"/>\n      <Kern code=\"1086\" val=\"-0.029445\"/>\n      <Kern code=\"1139\" val=\"-0.029445\"/>\n      <Kern code=\"1092\" val=\"-0.029445\"/>\n      <Kern code=\"1108\" val=\"-0.029445\"/>\n   </Char>\n   <Char code=\"1098\" width=\"0.561663\" height=\"0.444445\" italic=\"0.078611\" >\n      <Kern code=\"1083\" val=\"-0.029445\"/>\n      <Kern code=\"1084\" val=\"-0.029445\"/>\n      <Kern code=\"1113\" val=\"-0.029445\"/>\n      <Kern code=\"1141\" val=\"-0.029445\"/>\n      <Kern code=\"1098\" val=\"-0.029445\"/>\n      <Kern code=\"1095\" val=\"-0.088333\"/>\n      <Kern code=\"1086\" val=\"-0.029445\"/>\n      <Kern code=\"1139\" val=\"-0.029445\"/>\n      <Kern code=\"1092\" val=\"-0.029445\"/>\n      <Kern code=\"1108\" val=\"-0.029445\"/>\n   </Char>\n</Font>\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/cyrillic/wnr10.xml",
    "content": "<Font name=\"wnr10.ttf\" id=\"wnr10\" space=\"0.333334\" xHeight=\"0.430555\" quad=\"1.000003\" unicode=\"95\" boldVersion=\"wnbx10\" ssVersion=\"wnss10\" ttVersion=\"wntt10\" itVersion=\"wnti10\">\n   <Char code=\"1034\" width=\"1.083338\" height=\"0.683332\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.083334\"/>\n      <Kern code=\"1140\" val=\"-0.111112\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1033\" width=\"1.083338\" height=\"0.683332\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.083334\"/>\n      <Kern code=\"1140\" val=\"-0.111112\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1039\" width=\"0.777781\" height=\"0.683332\" depth=\"0.194445\" />\n   <Char code=\"1069\" width=\"0.722224\" height=\"0.683332\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n      <Kern code=\"1071\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1030\" width=\"0.361112\" height=\"0.683332\" >\n      <Kern code=\"1030\" val=\"0.027779\"/>\n   </Char>\n   <Char code=\"1028\" width=\"0.722224\" height=\"0.683332\" />\n   <Char code=\"1026\" width=\"0.8611145\" height=\"0.683332\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.083334\"/>\n      <Kern code=\"1140\" val=\"-0.111112\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1035\" width=\"0.763891\" height=\"0.683332\" />\n   <Char code=\"1114\" width=\"0.763891\" height=\"0.430555\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1113\" width=\"0.763891\" height=\"0.430555\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1119\" width=\"0.555557\" height=\"0.430555\" depth=\"0.162038\" italic=\"0.001389\" />\n   <Char code=\"1101\" width=\"0.444446\" height=\"0.430555\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1110\" width=\"0.277779\" height=\"0.667859\" />\n   <Char code=\"1108\" width=\"0.43889\" height=\"0.430555\" />\n   <Char code=\"1106\" width=\"0.527781\" height=\"0.694445\" depth=\"0.194445\" />\n   <Char code=\"1115\" width=\"0.555557\" height=\"0.694445\" />\n   <Char code=\"1070\" width=\"1.125003\" height=\"0.683332\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n      <Kern code=\"1071\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1046\" width=\"1.194448\" height=\"0.683332\" >\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.027779\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1049\" width=\"0.777781\" height=\"0.891615\" />\n   <Char code=\"1025\" width=\"0.680557\" height=\"0.891615\" />\n   <Char code=\"1140\" width=\"0.8194475\" height=\"0.683332\" italic=\"0.013888\" >\n      <Kern code=\"1040\" val=\"-0.111112\"/>\n      <Kern code=\"1071\" val=\"-0.111112\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1072\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.083334\"/>\n      <Kern code=\"1139\" val=\"-0.083334\"/>\n      <Kern code=\"1077\" val=\"-0.083334\"/>\n      <Kern code=\"1105\" val=\"-0.083334\"/>\n      <Kern code=\"1076\" val=\"-0.111112\"/>\n      <Kern code=\"1083\" val=\"-0.111112\"/>\n      <Kern code=\"1113\" val=\"-0.111112\"/>\n      <Kern code=\"1103\" val=\"-0.111112\"/>\n   </Char>\n   <Char code=\"1138\" width=\"0.777781\" height=\"0.683332\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n      <Kern code=\"1071\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1029\" width=\"0.555557\" height=\"0.683332\" />\n   <Char code=\"1071\" width=\"0.777781\" height=\"0.683332\" />\n   <Char code=\"1102\" width=\"0.750003\" height=\"0.430555\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1078\" width=\"0.833336\" height=\"0.430555\" >\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1081\" width=\"0.555557\" height=\"0.638838\" italic=\"0.001389\" />\n   <Char code=\"1105\" width=\"0.444446\" height=\"0.659131\" />\n   <Char code=\"1141\" width=\"0.587503\" height=\"0.430555\" italic=\"0.013888\" >\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.055555\"/>\n      <Kern code=\"1083\" val=\"-0.055555\"/>\n      <Kern code=\"1113\" val=\"-0.055555\"/>\n   </Char>\n   <Char code=\"1139\" width=\"0.444446\" height=\"0.430555\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1109\" width=\"0.394445\" height=\"0.430555\" />\n   <Char code=\"1103\" width=\"0.541669\" height=\"0.430555\" italic=\"0.001389\" />\n   <Char code=\"776\" width=\"0.500002\" height=\"0.659131\" />\n   <Char code=\"1122\" width=\"0.8194475\" height=\"0.75\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.083334\"/>\n      <Kern code=\"1140\" val=\"-0.111112\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"774\" width=\"0.500002\" height=\"0.638838\" />\n   <Char code=\"1123\" width=\"0.500002\" height=\"0.638838\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"171\" width=\"0.555557\" height=\"0.483335\" />\n   <Char code=\"305\" width=\"0.277779\" height=\"0.430555\" />\n   <Char code=\"187\" width=\"0.555557\" height=\"0.483335\" />\n   <Char code=\"1040\" width=\"0.750002\" height=\"0.683332\" >\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.083334\"/>\n      <Kern code=\"1140\" val=\"-0.111112\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1041\" width=\"0.708336\" height=\"0.683332\" />\n   <Char code=\"1062\" width=\"0.777781\" height=\"0.683332\" depth=\"0.194445\" >\n      <Lig code=\"1061\" ligCode=\"1063\"/>\n      <Lig code=\"1093\" ligCode=\"1063\"/>\n   </Char>\n   <Char code=\"1044\" width=\"0.777781\" height=\"0.683332\" depth=\"0.194445\" >\n      <Lig code=\"1032\" ligCode=\"1026\"/>\n      <Lig code=\"1112\" ligCode=\"1026\"/>\n   </Char>\n   <Char code=\"1045\" width=\"0.680557\" height=\"0.683332\" >\n   </Char>\n   <Char code=\"1060\" width=\"0.833336\" height=\"0.683332\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n      <Kern code=\"1071\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1043\" width=\"0.625002\" height=\"0.683332\" >\n      <Kern code=\"1040\" val=\"-0.083334\"/>\n      <Kern code=\"1044\" val=\"-0.083334\"/>\n      <Kern code=\"1071\" val=\"-0.083334\"/>\n      <Kern code=\"1051\" val=\"-0.027779\"/>\n      <Kern code=\"1033\" val=\"-0.027779\"/>\n      <Kern code=\"1072\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.083334\"/>\n      <Kern code=\"1139\" val=\"-0.083334\"/>\n      <Kern code=\"1077\" val=\"-0.083334\"/>\n      <Kern code=\"1105\" val=\"-0.083334\"/>\n      <Kern code=\"1089\" val=\"-0.083334\"/>\n      <Kern code=\"1108\" val=\"-0.083334\"/>\n      <Kern code=\"1092\" val=\"-0.083334\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n      <Kern code=\"1103\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1061\" width=\"0.750002\" height=\"0.683332\" >\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.027779\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1048\" width=\"0.777781\" height=\"0.683332\" >\n   </Char>\n   <Char code=\"1032\" width=\"0.51389\" height=\"0.683332\" >\n   </Char>\n   <Char code=\"1050\" width=\"0.777781\" height=\"0.683332\" >\n      <Lig code=\"1061\" ligCode=\"1061\"/>\n      <Lig code=\"1093\" ligCode=\"1061\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.027779\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1051\" width=\"0.777781\" height=\"0.683332\" >\n      <Lig code=\"1032\" ligCode=\"1033\"/>\n      <Lig code=\"1112\" ligCode=\"1033\"/>\n   </Char>\n   <Char code=\"1052\" width=\"0.916669\" height=\"0.683332\" />\n   <Char code=\"1053\" width=\"0.777781\" height=\"0.683332\" >\n      <Lig code=\"1032\" ligCode=\"1034\"/>\n      <Lig code=\"1112\" ligCode=\"1034\"/>\n   </Char>\n   <Char code=\"1054\" width=\"0.777781\" height=\"0.683332\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n      <Kern code=\"1071\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1055\" width=\"0.777781\" height=\"0.683332\" >\n   </Char>\n   <Char code=\"1063\" width=\"0.777781\" height=\"0.683332\" />\n   <Char code=\"1056\" width=\"0.680557\" height=\"0.683332\" >\n      <Kern code=\"1040\" val=\"-0.083334\"/>\n      <Kern code=\"1044\" val=\"-0.083334\"/>\n      <Kern code=\"1051\" val=\"-0.083334\"/>\n      <Kern code=\"1033\" val=\"-0.083334\"/>\n      <Kern code=\"1071\" val=\"-0.083334\"/>\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1057\" width=\"0.722224\" height=\"0.683332\" >\n      <Lig code=\"1061\" ligCode=\"1064\"/>\n      <Lig code=\"1093\" ligCode=\"1064\"/>\n   </Char>\n   <Char code=\"1058\" width=\"0.722224\" height=\"0.683332\" >\n      <Lig code=\"1057\" ligCode=\"1062\"/>\n      <Lig code=\"1089\" ligCode=\"1062\"/>\n      <Kern code=\"1040\" val=\"-0.083334\"/>\n      <Kern code=\"1044\" val=\"-0.083334\"/>\n      <Kern code=\"1071\" val=\"-0.083334\"/>\n      <Kern code=\"1051\" val=\"-0.027779\"/>\n      <Kern code=\"1033\" val=\"-0.027779\"/>\n      <Kern code=\"1072\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.083334\"/>\n      <Kern code=\"1139\" val=\"-0.083334\"/>\n      <Kern code=\"1077\" val=\"-0.083334\"/>\n      <Kern code=\"1105\" val=\"-0.083334\"/>\n      <Kern code=\"1089\" val=\"-0.083334\"/>\n      <Kern code=\"1108\" val=\"-0.083334\"/>\n      <Kern code=\"1092\" val=\"-0.083334\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n      <Kern code=\"1103\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1059\" width=\"0.750002\" height=\"0.683332\" italic=\"0.013888\" >\n      <Kern code=\"1040\" val=\"-0.083334\"/>\n      <Kern code=\"1071\" val=\"-0.083334\"/>\n      <Kern code=\"1044\" val=\"-0.055555\"/>\n      <Kern code=\"1051\" val=\"-0.055555\"/>\n      <Kern code=\"1033\" val=\"-0.055555\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1072\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.083334\"/>\n      <Kern code=\"1139\" val=\"-0.083334\"/>\n      <Kern code=\"1077\" val=\"-0.083334\"/>\n      <Kern code=\"1105\" val=\"-0.083334\"/>\n      <Kern code=\"1089\" val=\"-0.083334\"/>\n      <Kern code=\"1108\" val=\"-0.083334\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n      <Kern code=\"1103\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1042\" width=\"0.708336\" height=\"0.683332\" />\n   <Char code=\"1065\" width=\"1.125003\" height=\"0.683332\" depth=\"0.194445\" />\n   <Char code=\"1064\" width=\"1.125003\" height=\"0.683332\" >\n      <Lig code=\"1063\" ligCode=\"1065\"/>\n      <Lig code=\"1095\" ligCode=\"1065\"/>\n      <Lig code=\"1062\" ligCode=\"0\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1067\" width=\"0.972226\" height=\"0.683332\" >\n      <Lig code=\"1040\" ligCode=\"1071\"/>\n      <Lig code=\"1072\" ligCode=\"1071\"/>\n      <Lig code=\"1059\" ligCode=\"1070\"/>\n      <Lig code=\"1091\" ligCode=\"1070\"/>\n   </Char>\n   <Char code=\"1047\" width=\"0.611113\" height=\"0.683332\" >\n      <Lig code=\"1061\" ligCode=\"1046\"/>\n      <Lig code=\"1093\" ligCode=\"1046\"/>\n   </Char>\n   <Char code=\"1068\" width=\"0.708336\" height=\"0.683332\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.083334\"/>\n      <Kern code=\"1140\" val=\"-0.111112\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1066\" width=\"0.888893\" height=\"0.683332\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.083334\"/>\n      <Kern code=\"1140\" val=\"-0.111112\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1072\" width=\"0.500002\" height=\"0.430555\" >\n      <Kern code=\"1095\" val=\"-0.027779\"/>\n      <Kern code=\"1091\" val=\"-0.027779\"/>\n      <Kern code=\"1141\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1073\" width=\"0.500002\" height=\"0.694445\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1094\" width=\"0.555557\" height=\"0.430555\" depth=\"0.162038\" italic=\"0.001389\" >\n      <Lig code=\"1093\" ligCode=\"1095\"/>\n   </Char>\n   <Char code=\"1076\" width=\"0.555557\" height=\"0.430555\" depth=\"0.162038\" italic=\"0.001389\" >\n      <Lig code=\"1112\" ligCode=\"1106\"/>\n   </Char>\n   <Char code=\"1077\" width=\"0.444446\" height=\"0.430555\" >\n   </Char>\n   <Char code=\"1092\" width=\"0.7777815\" height=\"0.694445\" depth=\"0.194445\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1075\" width=\"0.444446\" height=\"0.430555\" >\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1083\" val=\"-0.027779\"/>\n      <Kern code=\"1113\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1093\" width=\"0.527781\" height=\"0.430555\" >\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1080\" width=\"0.555557\" height=\"0.430555\" italic=\"0.001389\" >\n   </Char>\n   <Char code=\"1112\" width=\"0.305557\" height=\"0.667859\" depth=\"0.194445\" >\n   </Char>\n   <Char code=\"1082\" width=\"0.555557\" height=\"0.430555\" >\n      <Lig code=\"1093\" ligCode=\"1093\"/>\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1083\" width=\"0.555557\" height=\"0.430555\" italic=\"0.001389\" >\n      <Lig code=\"1112\" ligCode=\"1113\"/>\n   </Char>\n   <Char code=\"1084\" width=\"0.666669\" height=\"0.430555\" italic=\"0.001389\" />\n   <Char code=\"1085\" width=\"0.555557\" height=\"0.430555\" italic=\"0.001389\" >\n      <Lig code=\"1112\" ligCode=\"1114\"/>\n   </Char>\n   <Char code=\"1086\" width=\"0.500002\" height=\"0.430555\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1087\" width=\"0.555557\" height=\"0.430555\" italic=\"0.001389\" >\n   </Char>\n   <Char code=\"1095\" width=\"0.555557\" height=\"0.430555\" italic=\"0.001389\" />\n   <Char code=\"1088\" width=\"0.555557\" height=\"0.430555\" depth=\"0.194445\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1089\" width=\"0.444446\" height=\"0.430555\" >\n      <Lig code=\"1093\" ligCode=\"1096\"/>\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1090\" width=\"0.500002\" height=\"0.430555\" >\n      <Lig code=\"1089\" ligCode=\"1094\"/>\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1083\" val=\"-0.027779\"/>\n      <Kern code=\"1113\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1091\" width=\"0.527781\" height=\"0.430555\" depth=\"0.194445\" italic=\"0.013888\" >\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.055555\"/>\n      <Kern code=\"1083\" val=\"-0.055555\"/>\n      <Kern code=\"1113\" val=\"-0.055555\"/>\n   </Char>\n   <Char code=\"1074\" width=\"0.500002\" height=\"0.430555\" />\n   <Char code=\"1097\" width=\"0.805559\" height=\"0.430555\" depth=\"0.162038\" italic=\"0.001389\" />\n   <Char code=\"1096\" width=\"0.805559\" height=\"0.430555\" italic=\"0.001389\" >\n      <Lig code=\"1095\" ligCode=\"1097\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1099\" width=\"0.722224\" height=\"0.430555\" italic=\"0.001389\" >\n      <Lig code=\"1072\" ligCode=\"1103\"/>\n      <Lig code=\"1091\" ligCode=\"1102\"/>\n   </Char>\n   <Char code=\"1079\" width=\"0.444446\" height=\"0.430555\" italic=\"0.005556\" >\n      <Lig code=\"1093\" ligCode=\"1078\"/>\n   </Char>\n   <Char code=\"1100\" width=\"0.500002\" height=\"0.430555\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1098\" width=\"0.611113\" height=\"0.430555\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n</Font>\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/cyrillic/wnss10.xml",
    "content": "<Font name=\"wnss10.ttf\" id=\"wnss10\" space=\"0.333334\" xHeight=\"0.444445\" quad=\"1.000003\" unicode=\"95\" romanVersion=\"wnr10\" ttVersion=\"wntt10\" boldVersion=\"wnssbx10\" itVersion=\"wnssi10\">\n   <Char code=\"1034\" width=\"1.020838\" height=\"0.694445\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1033\" width=\"1.037504\" height=\"0.694445\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1039\" width=\"0.694448\" height=\"0.694445\" depth=\"0.194445\" />\n   <Char code=\"1069\" width=\"0.638891\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1030\" width=\"0.277781\" height=\"0.694445\" >\n      <Kern code=\"1030\" val=\"0.027779\"/>\n   </Char>\n   <Char code=\"1028\" width=\"0.638891\" height=\"0.694445\" />\n   <Char code=\"1026\" width=\"0.8194475\" height=\"0.694445\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1035\" width=\"0.763891\" height=\"0.694445\" />\n   <Char code=\"1114\" width=\"0.765282\" height=\"0.444445\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1113\" width=\"0.755559\" height=\"0.444445\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1119\" width=\"0.537503\" height=\"0.444445\" depth=\"0.162038\" />\n   <Char code=\"1101\" width=\"0.444446\" height=\"0.444445\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1110\" width=\"0.23889\" height=\"0.679365\" />\n   <Char code=\"1108\" width=\"0.43889\" height=\"0.444445\" />\n   <Char code=\"1106\" width=\"0.488892\" height=\"0.694445\" depth=\"0.194445\" />\n   <Char code=\"1115\" width=\"0.516668\" height=\"0.694445\" />\n   <Char code=\"1070\" width=\"1.04167\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1046\" width=\"1.111117\" height=\"0.694445\" >\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.027779\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1049\" width=\"0.694448\" height=\"0.902727\" />\n   <Char code=\"1025\" width=\"0.597224\" height=\"0.902727\" />\n   <Char code=\"1140\" width=\"0.722226\" height=\"0.694445\" italic=\"0.013888\" >\n      <Kern code=\"1040\" val=\"-0.083334\"/>\n      <Kern code=\"1044\" val=\"-0.055555\"/>\n      <Kern code=\"1051\" val=\"-0.055555\"/>\n      <Kern code=\"1033\" val=\"-0.055555\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n      <Kern code=\"1103\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1138\" width=\"0.777781\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1029\" width=\"0.555557\" height=\"0.694445\" />\n   <Char code=\"1071\" width=\"0.645836\" height=\"0.694445\" />\n   <Char code=\"1102\" width=\"0.730558\" height=\"0.444445\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1078\" width=\"0.7388935\" height=\"0.444445\" >\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1081\" width=\"0.537503\" height=\"0.652727\" />\n   <Char code=\"1105\" width=\"0.444446\" height=\"0.660319\" />\n   <Char code=\"1141\" width=\"0.491667\" height=\"0.444445\" italic=\"0.013888\" >\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.055555\"/>\n      <Kern code=\"1083\" val=\"-0.055555\"/>\n      <Kern code=\"1113\" val=\"-0.055555\"/>\n   </Char>\n   <Char code=\"1139\" width=\"0.500002\" height=\"0.444445\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1109\" width=\"0.383334\" height=\"0.444445\" />\n   <Char code=\"1103\" width=\"0.515279\" height=\"0.444445\" />\n   <Char code=\"776\" width=\"0.500002\" height=\"0.660319\" />\n   <Char code=\"1122\" width=\"0.7777815\" height=\"0.75\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"774\" width=\"0.500002\" height=\"0.652727\" />\n   <Char code=\"1123\" width=\"0.500002\" height=\"0.652727\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"171\" width=\"0.666669\" height=\"0.438889\" />\n   <Char code=\"305\" width=\"0.23889\" height=\"0.444445\" />\n   <Char code=\"187\" width=\"0.666669\" height=\"0.438889\" />\n   <Char code=\"1040\" width=\"0.66667\" height=\"0.694445\" >\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1041\" width=\"0.66667\" height=\"0.694445\" />\n   <Char code=\"1062\" width=\"0.711116\" height=\"0.694445\" depth=\"0.194445\" >\n      <Lig code=\"1061\" ligCode=\"1063\"/>\n      <Lig code=\"1093\" ligCode=\"1063\"/>\n   </Char>\n   <Char code=\"1044\" width=\"0.727783\" height=\"0.694445\" depth=\"0.194445\" >\n      <Lig code=\"1032\" ligCode=\"1026\"/>\n      <Lig code=\"1112\" ligCode=\"1026\"/>\n   </Char>\n   <Char code=\"1045\" width=\"0.597224\" height=\"0.694445\" >\n   </Char>\n   <Char code=\"1060\" width=\"0.833336\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1043\" width=\"0.541669\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.083334\"/>\n      <Kern code=\"1044\" val=\"-0.083334\"/>\n      <Kern code=\"1051\" val=\"-0.055555\"/>\n      <Kern code=\"1033\" val=\"-0.055555\"/>\n      <Kern code=\"1072\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.083334\"/>\n      <Kern code=\"1139\" val=\"-0.083334\"/>\n      <Kern code=\"1077\" val=\"-0.083334\"/>\n      <Kern code=\"1105\" val=\"-0.083334\"/>\n      <Kern code=\"1089\" val=\"-0.083334\"/>\n      <Kern code=\"1108\" val=\"-0.083334\"/>\n      <Kern code=\"1092\" val=\"-0.083334\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n      <Kern code=\"1103\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1061\" width=\"0.66667\" height=\"0.694445\" >\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.027779\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1048\" width=\"0.694448\" height=\"0.694445\" >\n   </Char>\n   <Char code=\"1032\" width=\"0.472224\" height=\"0.694445\" >\n   </Char>\n   <Char code=\"1050\" width=\"0.694448\" height=\"0.694445\" >\n      <Lig code=\"1061\" ligCode=\"1061\"/>\n      <Lig code=\"1093\" ligCode=\"1061\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.027779\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1051\" width=\"0.711116\" height=\"0.694445\" >\n      <Lig code=\"1032\" ligCode=\"1033\"/>\n      <Lig code=\"1112\" ligCode=\"1033\"/>\n   </Char>\n   <Char code=\"1052\" width=\"0.875005\" height=\"0.694445\" />\n   <Char code=\"1053\" width=\"0.694448\" height=\"0.694445\" >\n      <Lig code=\"1032\" ligCode=\"1034\"/>\n      <Lig code=\"1112\" ligCode=\"1034\"/>\n   </Char>\n   <Char code=\"1054\" width=\"0.736113\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1055\" width=\"0.694448\" height=\"0.694445\" >\n   </Char>\n   <Char code=\"1063\" width=\"0.694448\" height=\"0.694445\" />\n   <Char code=\"1056\" width=\"0.638891\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.083334\"/>\n      <Kern code=\"1044\" val=\"-0.083334\"/>\n      <Kern code=\"1051\" val=\"-0.083334\"/>\n      <Kern code=\"1033\" val=\"-0.083334\"/>\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1057\" width=\"0.638891\" height=\"0.694445\" >\n      <Lig code=\"1061\" ligCode=\"1064\"/>\n      <Lig code=\"1093\" ligCode=\"1064\"/>\n   </Char>\n   <Char code=\"1058\" width=\"0.680557\" height=\"0.694445\" >\n      <Lig code=\"1057\" ligCode=\"1062\"/>\n      <Lig code=\"1089\" ligCode=\"1062\"/>\n      <Kern code=\"1040\" val=\"-0.083334\"/>\n      <Kern code=\"1044\" val=\"-0.083334\"/>\n      <Kern code=\"1051\" val=\"-0.055555\"/>\n      <Kern code=\"1033\" val=\"-0.055555\"/>\n      <Kern code=\"1072\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.083334\"/>\n      <Kern code=\"1139\" val=\"-0.083334\"/>\n      <Kern code=\"1077\" val=\"-0.083334\"/>\n      <Kern code=\"1105\" val=\"-0.083334\"/>\n      <Kern code=\"1089\" val=\"-0.083334\"/>\n      <Kern code=\"1108\" val=\"-0.083334\"/>\n      <Kern code=\"1092\" val=\"-0.083334\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n      <Kern code=\"1103\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1059\" width=\"0.66667\" height=\"0.694445\" italic=\"0.013888\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.055555\"/>\n      <Kern code=\"1051\" val=\"-0.055555\"/>\n      <Kern code=\"1033\" val=\"-0.055555\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n      <Kern code=\"1103\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1042\" width=\"0.66667\" height=\"0.694445\" />\n   <Char code=\"1065\" width=\"1.100006\" height=\"0.694445\" depth=\"0.194445\" />\n   <Char code=\"1064\" width=\"1.083339\" height=\"0.694445\" >\n      <Lig code=\"1063\" ligCode=\"1065\"/>\n      <Lig code=\"1095\" ligCode=\"1065\"/>\n      <Lig code=\"1062\" ligCode=\"0\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1067\" width=\"0.888895\" height=\"0.694445\" >\n      <Lig code=\"1040\" ligCode=\"1071\"/>\n      <Lig code=\"1072\" ligCode=\"1071\"/>\n      <Lig code=\"1059\" ligCode=\"1070\"/>\n      <Lig code=\"1091\" ligCode=\"1070\"/>\n   </Char>\n   <Char code=\"1047\" width=\"0.611113\" height=\"0.694445\" >\n      <Lig code=\"1061\" ligCode=\"1046\"/>\n      <Lig code=\"1093\" ligCode=\"1046\"/>\n   </Char>\n   <Char code=\"1068\" width=\"0.66667\" height=\"0.694445\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1066\" width=\"0.868059\" height=\"0.694445\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1072\" width=\"0.480557\" height=\"0.444445\" >\n      <Kern code=\"1095\" val=\"-0.027779\"/>\n      <Kern code=\"1091\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1073\" width=\"0.500002\" height=\"0.694445\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1094\" width=\"0.5486145\" height=\"0.444445\" depth=\"0.162038\" >\n      <Lig code=\"1093\" ligCode=\"1095\"/>\n   </Char>\n   <Char code=\"1076\" width=\"0.538892\" height=\"0.444445\" depth=\"0.162038\" >\n      <Lig code=\"1112\" ligCode=\"1106\"/>\n   </Char>\n   <Char code=\"1077\" width=\"0.444446\" height=\"0.444445\" >\n   </Char>\n   <Char code=\"1092\" width=\"0.76667\" height=\"0.694445\" depth=\"0.194445\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1075\" width=\"0.404167\" height=\"0.444445\" italic=\"0.013888\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1083\" val=\"-0.027779\"/>\n      <Kern code=\"1113\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1093\" width=\"0.461113\" height=\"0.444445\" >\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1080\" width=\"0.537503\" height=\"0.444445\" >\n   </Char>\n   <Char code=\"1112\" width=\"0.266668\" height=\"0.679365\" depth=\"0.194445\" >\n   </Char>\n   <Char code=\"1082\" width=\"0.488892\" height=\"0.444445\" >\n      <Lig code=\"1093\" ligCode=\"1093\"/>\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1083\" width=\"0.527781\" height=\"0.444445\" >\n      <Lig code=\"1112\" ligCode=\"1113\"/>\n   </Char>\n   <Char code=\"1084\" width=\"0.669447\" height=\"0.444445\" />\n   <Char code=\"1085\" width=\"0.516668\" height=\"0.444445\" >\n      <Lig code=\"1112\" ligCode=\"1114\"/>\n   </Char>\n   <Char code=\"1086\" width=\"0.500002\" height=\"0.444445\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1087\" width=\"0.516668\" height=\"0.444445\" >\n   </Char>\n   <Char code=\"1095\" width=\"0.537503\" height=\"0.444445\" />\n   <Char code=\"1088\" width=\"0.516668\" height=\"0.444445\" depth=\"0.194445\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1089\" width=\"0.444446\" height=\"0.444445\" >\n      <Lig code=\"1093\" ligCode=\"1096\"/>\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1090\" width=\"0.458334\" height=\"0.444445\" italic=\"0.019444\" >\n      <Lig code=\"1089\" ligCode=\"1094\"/>\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1083\" val=\"-0.027779\"/>\n      <Kern code=\"1113\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1091\" width=\"0.461113\" height=\"0.444445\" depth=\"0.194445\" italic=\"0.013888\" >\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.055555\"/>\n      <Kern code=\"1083\" val=\"-0.055555\"/>\n      <Kern code=\"1113\" val=\"-0.055555\"/>\n   </Char>\n   <Char code=\"1074\" width=\"0.480557\" height=\"0.444445\" />\n   <Char code=\"1097\" width=\"0.7777815\" height=\"0.444445\" depth=\"0.162038\" />\n   <Char code=\"1096\" width=\"0.76667\" height=\"0.444445\" >\n      <Lig code=\"1095\" ligCode=\"1097\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1099\" width=\"0.683336\" height=\"0.444445\" >\n      <Lig code=\"1072\" ligCode=\"1103\"/>\n      <Lig code=\"1091\" ligCode=\"1102\"/>\n   </Char>\n   <Char code=\"1079\" width=\"0.444446\" height=\"0.444445\" italic=\"0.002777\" >\n      <Lig code=\"1093\" ligCode=\"1078\"/>\n   </Char>\n   <Char code=\"1100\" width=\"0.480557\" height=\"0.444445\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1098\" width=\"0.590279\" height=\"0.444445\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n</Font>\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/cyrillic/wnssbx10.xml",
    "content": "<Font name=\"wnssbx10.ttf\" id=\"wnssbx10\" space=\"0.366669\" xHeight=\"0.458333\" quad=\"1.100006\" unicode=\"95\" romanVersion=\"wnbx10\" ttVersion=\"wntt10\">\n   <Char code=\"1034\" width=\"1.115285\" height=\"0.694445\" >\n      <Kern code=\"1046\" val=\"-0.030556\"/>\n      <Kern code=\"1061\" val=\"-0.030556\"/>\n      <Kern code=\"1054\" val=\"-0.030556\"/>\n      <Kern code=\"1060\" val=\"-0.030556\"/>\n      <Kern code=\"1138\" val=\"-0.030556\"/>\n      <Kern code=\"1057\" val=\"-0.030556\"/>\n      <Kern code=\"1028\" val=\"-0.030556\"/>\n      <Kern code=\"1058\" val=\"-0.091667\"/>\n      <Kern code=\"1066\" val=\"-0.091667\"/>\n      <Kern code=\"1026\" val=\"-0.091667\"/>\n      <Kern code=\"1035\" val=\"-0.091667\"/>\n      <Kern code=\"1122\" val=\"-0.091667\"/>\n      <Kern code=\"1063\" val=\"-0.091667\"/>\n      <Kern code=\"1059\" val=\"-0.030556\"/>\n      <Kern code=\"1140\" val=\"-0.091667\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.091667\"/>\n   </Char>\n   <Char code=\"1033\" width=\"1.15834\" height=\"0.694445\" >\n      <Kern code=\"1046\" val=\"-0.030556\"/>\n      <Kern code=\"1061\" val=\"-0.030556\"/>\n      <Kern code=\"1054\" val=\"-0.030556\"/>\n      <Kern code=\"1060\" val=\"-0.030556\"/>\n      <Kern code=\"1138\" val=\"-0.030556\"/>\n      <Kern code=\"1057\" val=\"-0.030556\"/>\n      <Kern code=\"1028\" val=\"-0.030556\"/>\n      <Kern code=\"1058\" val=\"-0.091667\"/>\n      <Kern code=\"1066\" val=\"-0.091667\"/>\n      <Kern code=\"1026\" val=\"-0.091667\"/>\n      <Kern code=\"1035\" val=\"-0.091667\"/>\n      <Kern code=\"1122\" val=\"-0.091667\"/>\n      <Kern code=\"1063\" val=\"-0.091667\"/>\n      <Kern code=\"1059\" val=\"-0.030556\"/>\n      <Kern code=\"1140\" val=\"-0.091667\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.091667\"/>\n   </Char>\n   <Char code=\"1039\" width=\"0.763893\" height=\"0.694445\" depth=\"0.194445\" />\n   <Char code=\"1069\" width=\"0.702782\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.030556\"/>\n      <Kern code=\"1044\" val=\"-0.030556\"/>\n      <Kern code=\"1046\" val=\"-0.030556\"/>\n      <Kern code=\"1061\" val=\"-0.030556\"/>\n      <Kern code=\"1059\" val=\"-0.030556\"/>\n      <Kern code=\"1140\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1030\" width=\"0.330557\" height=\"0.694445\" >\n      <Kern code=\"1030\" val=\"0.030556\"/>\n   </Char>\n   <Char code=\"1028\" width=\"0.702782\" height=\"0.694445\" />\n   <Char code=\"1026\" width=\"0.886116\" height=\"0.694445\" >\n      <Kern code=\"1046\" val=\"-0.030556\"/>\n      <Kern code=\"1061\" val=\"-0.030556\"/>\n      <Kern code=\"1054\" val=\"-0.030556\"/>\n      <Kern code=\"1060\" val=\"-0.030556\"/>\n      <Kern code=\"1138\" val=\"-0.030556\"/>\n      <Kern code=\"1057\" val=\"-0.030556\"/>\n      <Kern code=\"1028\" val=\"-0.030556\"/>\n      <Kern code=\"1058\" val=\"-0.091667\"/>\n      <Kern code=\"1066\" val=\"-0.091667\"/>\n      <Kern code=\"1026\" val=\"-0.091667\"/>\n      <Kern code=\"1035\" val=\"-0.091667\"/>\n      <Kern code=\"1122\" val=\"-0.091667\"/>\n      <Kern code=\"1063\" val=\"-0.091667\"/>\n      <Kern code=\"1059\" val=\"-0.030556\"/>\n      <Kern code=\"1140\" val=\"-0.091667\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.091667\"/>\n   </Char>\n   <Char code=\"1035\" width=\"0.840283\" height=\"0.694445\" />\n   <Char code=\"1114\" width=\"0.845839\" height=\"0.458333\" >\n      <Kern code=\"1091\" val=\"-0.061111\"/>\n      <Kern code=\"1141\" val=\"-0.061111\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.091667\"/>\n      <Kern code=\"1086\" val=\"-0.030556\"/>\n      <Kern code=\"1139\" val=\"-0.030556\"/>\n      <Kern code=\"1092\" val=\"-0.030556\"/>\n      <Kern code=\"1108\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1113\" width=\"0.852783\" height=\"0.458333\" >\n      <Kern code=\"1091\" val=\"-0.061111\"/>\n      <Kern code=\"1141\" val=\"-0.061111\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.091667\"/>\n      <Kern code=\"1086\" val=\"-0.030556\"/>\n      <Kern code=\"1139\" val=\"-0.030556\"/>\n      <Kern code=\"1092\" val=\"-0.030556\"/>\n      <Kern code=\"1108\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1119\" width=\"0.59167\" height=\"0.458333\" depth=\"0.162038\" />\n   <Char code=\"1101\" width=\"0.488892\" height=\"0.458333\" >\n      <Kern code=\"1076\" val=\"-0.030556\"/>\n      <Kern code=\"1078\" val=\"-0.030556\"/>\n      <Kern code=\"1093\" val=\"-0.030556\"/>\n      <Kern code=\"1103\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1110\" width=\"0.255557\" height=\"0.694445\" />\n   <Char code=\"1108\" width=\"0.48278\" height=\"0.458333\" />\n   <Char code=\"1106\" width=\"0.530559\" height=\"0.694445\" depth=\"0.194445\" />\n   <Char code=\"1115\" width=\"0.561114\" height=\"0.694445\" />\n   <Char code=\"1070\" width=\"1.143062\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.030556\"/>\n      <Kern code=\"1044\" val=\"-0.030556\"/>\n      <Kern code=\"1046\" val=\"-0.030556\"/>\n      <Kern code=\"1061\" val=\"-0.030556\"/>\n      <Kern code=\"1059\" val=\"-0.030556\"/>\n      <Kern code=\"1140\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1046\" width=\"1.214895\" height=\"0.694445\" >\n      <Kern code=\"1054\" val=\"-0.030556\"/>\n      <Kern code=\"1060\" val=\"-0.030556\"/>\n      <Kern code=\"1138\" val=\"-0.030556\"/>\n      <Kern code=\"1057\" val=\"-0.030556\"/>\n      <Kern code=\"1028\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.030556\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1049\" width=\"0.763893\" height=\"0.902727\" />\n   <Char code=\"1025\" width=\"0.64167\" height=\"0.902727\" />\n   <Char code=\"1140\" width=\"0.794449\" height=\"0.694445\" italic=\"0.015279\" >\n      <Kern code=\"1040\" val=\"-0.091667\"/>\n      <Kern code=\"1044\" val=\"-0.061111\"/>\n      <Kern code=\"1051\" val=\"-0.061111\"/>\n      <Kern code=\"1033\" val=\"-0.061111\"/>\n      <Kern code=\"1054\" val=\"-0.030556\"/>\n      <Kern code=\"1060\" val=\"-0.030556\"/>\n      <Kern code=\"1138\" val=\"-0.030556\"/>\n      <Kern code=\"1057\" val=\"-0.030556\"/>\n      <Kern code=\"1028\" val=\"-0.030556\"/>\n      <Kern code=\"1072\" val=\"-0.030556\"/>\n      <Kern code=\"1086\" val=\"-0.030556\"/>\n      <Kern code=\"1139\" val=\"-0.030556\"/>\n      <Kern code=\"1077\" val=\"-0.030556\"/>\n      <Kern code=\"1105\" val=\"-0.030556\"/>\n      <Kern code=\"1076\" val=\"-0.091667\"/>\n      <Kern code=\"1083\" val=\"-0.091667\"/>\n      <Kern code=\"1113\" val=\"-0.091667\"/>\n      <Kern code=\"1103\" val=\"-0.091667\"/>\n   </Char>\n   <Char code=\"1138\" width=\"0.85556\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.030556\"/>\n      <Kern code=\"1044\" val=\"-0.030556\"/>\n      <Kern code=\"1046\" val=\"-0.030556\"/>\n      <Kern code=\"1061\" val=\"-0.030556\"/>\n      <Kern code=\"1059\" val=\"-0.030556\"/>\n      <Kern code=\"1140\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1029\" width=\"0.6111145\" height=\"0.694445\" />\n   <Char code=\"1071\" width=\"0.702782\" height=\"0.694445\" />\n   <Char code=\"1102\" width=\"0.800005\" height=\"0.458333\" >\n      <Kern code=\"1076\" val=\"-0.030556\"/>\n      <Kern code=\"1078\" val=\"-0.030556\"/>\n      <Kern code=\"1093\" val=\"-0.030556\"/>\n      <Kern code=\"1103\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1078\" width=\"0.80556\" height=\"0.458333\" >\n      <Kern code=\"1072\" val=\"-0.030556\"/>\n      <Kern code=\"1086\" val=\"-0.030556\"/>\n      <Kern code=\"1139\" val=\"-0.030556\"/>\n      <Kern code=\"1089\" val=\"-0.030556\"/>\n      <Kern code=\"1108\" val=\"-0.030556\"/>\n      <Kern code=\"1077\" val=\"-0.030556\"/>\n      <Kern code=\"1105\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1081\" width=\"0.59167\" height=\"0.6666155\" />\n   <Char code=\"1105\" width=\"0.511114\" height=\"0.694445\" />\n   <Char code=\"1141\" width=\"0.562503\" height=\"0.458333\" italic=\"0.015279\" >\n      <Kern code=\"1072\" val=\"-0.030556\"/>\n      <Kern code=\"1086\" val=\"-0.030556\"/>\n      <Kern code=\"1139\" val=\"-0.030556\"/>\n      <Kern code=\"1089\" val=\"-0.030556\"/>\n      <Kern code=\"1108\" val=\"-0.030556\"/>\n      <Kern code=\"1077\" val=\"-0.030556\"/>\n      <Kern code=\"1105\" val=\"-0.030556\"/>\n      <Kern code=\"1103\" val=\"-0.030556\"/>\n      <Kern code=\"1076\" val=\"-0.061111\"/>\n      <Kern code=\"1083\" val=\"-0.061111\"/>\n      <Kern code=\"1113\" val=\"-0.061111\"/>\n   </Char>\n   <Char code=\"1139\" width=\"0.550003\" height=\"0.458333\" >\n      <Kern code=\"1076\" val=\"-0.030556\"/>\n      <Kern code=\"1078\" val=\"-0.030556\"/>\n      <Kern code=\"1093\" val=\"-0.030556\"/>\n      <Kern code=\"1103\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1109\" width=\"0.421669\" height=\"0.458333\" />\n   <Char code=\"1103\" width=\"0.555559\" height=\"0.458333\" />\n   <Char code=\"776\" width=\"0.550003\" height=\"0.694445\" />\n   <Char code=\"1122\" width=\"0.85556\" height=\"0.75\" >\n      <Kern code=\"1046\" val=\"-0.030556\"/>\n      <Kern code=\"1061\" val=\"-0.030556\"/>\n      <Kern code=\"1054\" val=\"-0.030556\"/>\n      <Kern code=\"1060\" val=\"-0.030556\"/>\n      <Kern code=\"1138\" val=\"-0.030556\"/>\n      <Kern code=\"1057\" val=\"-0.030556\"/>\n      <Kern code=\"1028\" val=\"-0.030556\"/>\n      <Kern code=\"1058\" val=\"-0.091667\"/>\n      <Kern code=\"1066\" val=\"-0.091667\"/>\n      <Kern code=\"1026\" val=\"-0.091667\"/>\n      <Kern code=\"1035\" val=\"-0.091667\"/>\n      <Kern code=\"1122\" val=\"-0.091667\"/>\n      <Kern code=\"1063\" val=\"-0.091667\"/>\n      <Kern code=\"1059\" val=\"-0.030556\"/>\n      <Kern code=\"1140\" val=\"-0.091667\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.091667\"/>\n   </Char>\n   <Char code=\"774\" width=\"0.550003\" height=\"0.6666155\" />\n   <Char code=\"1123\" width=\"0.550003\" height=\"0.6666155\" >\n      <Kern code=\"1091\" val=\"-0.061111\"/>\n      <Kern code=\"1141\" val=\"-0.061111\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.091667\"/>\n      <Kern code=\"1086\" val=\"-0.030556\"/>\n      <Kern code=\"1139\" val=\"-0.030556\"/>\n      <Kern code=\"1092\" val=\"-0.030556\"/>\n      <Kern code=\"1108\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"171\" width=\"0.733337\" height=\"0.5\" />\n   <Char code=\"305\" width=\"0.255557\" height=\"0.458333\" />\n   <Char code=\"187\" width=\"0.733337\" height=\"0.5\" />\n   <Char code=\"1040\" width=\"0.733337\" height=\"0.694445\" >\n      <Kern code=\"1054\" val=\"-0.030556\"/>\n      <Kern code=\"1060\" val=\"-0.030556\"/>\n      <Kern code=\"1138\" val=\"-0.030556\"/>\n      <Kern code=\"1057\" val=\"-0.030556\"/>\n      <Kern code=\"1028\" val=\"-0.030556\"/>\n      <Kern code=\"1058\" val=\"-0.091667\"/>\n      <Kern code=\"1066\" val=\"-0.091667\"/>\n      <Kern code=\"1026\" val=\"-0.091667\"/>\n      <Kern code=\"1035\" val=\"-0.091667\"/>\n      <Kern code=\"1122\" val=\"-0.091667\"/>\n      <Kern code=\"1063\" val=\"-0.091667\"/>\n      <Kern code=\"1059\" val=\"-0.030556\"/>\n      <Kern code=\"1140\" val=\"-0.091667\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.091667\"/>\n   </Char>\n   <Char code=\"1041\" width=\"0.733337\" height=\"0.694445\" />\n   <Char code=\"1062\" width=\"0.806949\" height=\"0.694445\" depth=\"0.194445\" >\n      <Lig code=\"1061\" ligCode=\"1063\"/>\n      <Lig code=\"1093\" ligCode=\"1063\"/>\n   </Char>\n   <Char code=\"1044\" width=\"0.850004\" height=\"0.694445\" depth=\"0.194445\" >\n      <Lig code=\"1032\" ligCode=\"1026\"/>\n      <Lig code=\"1112\" ligCode=\"1026\"/>\n   </Char>\n   <Char code=\"1045\" width=\"0.64167\" height=\"0.694445\" >\n   </Char>\n   <Char code=\"1060\" width=\"0.916672\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.030556\"/>\n      <Kern code=\"1044\" val=\"-0.030556\"/>\n      <Kern code=\"1046\" val=\"-0.030556\"/>\n      <Kern code=\"1061\" val=\"-0.030556\"/>\n      <Kern code=\"1059\" val=\"-0.030556\"/>\n      <Kern code=\"1140\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1043\" width=\"0.580559\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.091667\"/>\n      <Kern code=\"1044\" val=\"-0.091667\"/>\n      <Kern code=\"1051\" val=\"-0.061111\"/>\n      <Kern code=\"1033\" val=\"-0.061111\"/>\n      <Kern code=\"1072\" val=\"-0.091667\"/>\n      <Kern code=\"1086\" val=\"-0.091667\"/>\n      <Kern code=\"1139\" val=\"-0.091667\"/>\n      <Kern code=\"1077\" val=\"-0.091667\"/>\n      <Kern code=\"1105\" val=\"-0.091667\"/>\n      <Kern code=\"1089\" val=\"-0.091667\"/>\n      <Kern code=\"1108\" val=\"-0.091667\"/>\n      <Kern code=\"1092\" val=\"-0.091667\"/>\n      <Kern code=\"1076\" val=\"-0.091667\"/>\n      <Kern code=\"1083\" val=\"-0.091667\"/>\n      <Kern code=\"1113\" val=\"-0.091667\"/>\n      <Kern code=\"1103\" val=\"-0.091667\"/>\n   </Char>\n   <Char code=\"1061\" width=\"0.733337\" height=\"0.694445\" >\n      <Kern code=\"1054\" val=\"-0.030556\"/>\n      <Kern code=\"1060\" val=\"-0.030556\"/>\n      <Kern code=\"1138\" val=\"-0.030556\"/>\n      <Kern code=\"1057\" val=\"-0.030556\"/>\n      <Kern code=\"1028\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.030556\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1048\" width=\"0.763893\" height=\"0.694445\" >\n   </Char>\n   <Char code=\"1032\" width=\"0.519447\" height=\"0.694445\" >\n   </Char>\n   <Char code=\"1050\" width=\"0.763893\" height=\"0.694445\" >\n      <Lig code=\"1061\" ligCode=\"1061\"/>\n      <Lig code=\"1093\" ligCode=\"1061\"/>\n      <Kern code=\"1054\" val=\"-0.030556\"/>\n      <Kern code=\"1060\" val=\"-0.030556\"/>\n      <Kern code=\"1138\" val=\"-0.030556\"/>\n      <Kern code=\"1057\" val=\"-0.030556\"/>\n      <Kern code=\"1028\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.030556\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1051\" width=\"0.806949\" height=\"0.694445\" >\n      <Lig code=\"1032\" ligCode=\"1033\"/>\n      <Lig code=\"1112\" ligCode=\"1033\"/>\n   </Char>\n   <Char code=\"1052\" width=\"0.977783\" height=\"0.694445\" />\n   <Char code=\"1053\" width=\"0.763893\" height=\"0.694445\" >\n      <Lig code=\"1032\" ligCode=\"1034\"/>\n      <Lig code=\"1112\" ligCode=\"1034\"/>\n   </Char>\n   <Char code=\"1054\" width=\"0.794449\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.030556\"/>\n      <Kern code=\"1044\" val=\"-0.030556\"/>\n      <Kern code=\"1046\" val=\"-0.030556\"/>\n      <Kern code=\"1061\" val=\"-0.030556\"/>\n      <Kern code=\"1059\" val=\"-0.030556\"/>\n      <Kern code=\"1140\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1055\" width=\"0.763893\" height=\"0.694445\" >\n   </Char>\n   <Char code=\"1063\" width=\"0.763893\" height=\"0.694445\" />\n   <Char code=\"1056\" width=\"0.702782\" height=\"0.694445\" >\n      <Kern code=\"1040\" val=\"-0.091667\"/>\n      <Kern code=\"1044\" val=\"-0.091667\"/>\n      <Kern code=\"1051\" val=\"-0.091667\"/>\n      <Kern code=\"1033\" val=\"-0.091667\"/>\n      <Kern code=\"1072\" val=\"-0.030556\"/>\n      <Kern code=\"1086\" val=\"-0.030556\"/>\n      <Kern code=\"1139\" val=\"-0.030556\"/>\n      <Kern code=\"1077\" val=\"-0.030556\"/>\n      <Kern code=\"1105\" val=\"-0.030556\"/>\n      <Kern code=\"1076\" val=\"-0.091667\"/>\n      <Kern code=\"1083\" val=\"-0.091667\"/>\n      <Kern code=\"1113\" val=\"-0.091667\"/>\n   </Char>\n   <Char code=\"1057\" width=\"0.702782\" height=\"0.694445\" >\n      <Lig code=\"1061\" ligCode=\"1064\"/>\n      <Lig code=\"1093\" ligCode=\"1064\"/>\n   </Char>\n   <Char code=\"1058\" width=\"0.733337\" height=\"0.694445\" >\n      <Lig code=\"1057\" ligCode=\"1062\"/>\n      <Lig code=\"1089\" ligCode=\"1062\"/>\n      <Kern code=\"1040\" val=\"-0.091667\"/>\n      <Kern code=\"1044\" val=\"-0.091667\"/>\n      <Kern code=\"1051\" val=\"-0.061111\"/>\n      <Kern code=\"1033\" val=\"-0.061111\"/>\n      <Kern code=\"1072\" val=\"-0.091667\"/>\n      <Kern code=\"1086\" val=\"-0.091667\"/>\n      <Kern code=\"1139\" val=\"-0.091667\"/>\n      <Kern code=\"1077\" val=\"-0.091667\"/>\n      <Kern code=\"1105\" val=\"-0.091667\"/>\n      <Kern code=\"1089\" val=\"-0.091667\"/>\n      <Kern code=\"1108\" val=\"-0.091667\"/>\n      <Kern code=\"1092\" val=\"-0.091667\"/>\n      <Kern code=\"1076\" val=\"-0.091667\"/>\n      <Kern code=\"1083\" val=\"-0.091667\"/>\n      <Kern code=\"1113\" val=\"-0.091667\"/>\n      <Kern code=\"1103\" val=\"-0.091667\"/>\n   </Char>\n   <Char code=\"1059\" width=\"0.733337\" height=\"0.694445\" italic=\"0.015279\" >\n      <Kern code=\"1040\" val=\"-0.030556\"/>\n      <Kern code=\"1044\" val=\"-0.061111\"/>\n      <Kern code=\"1051\" val=\"-0.061111\"/>\n      <Kern code=\"1033\" val=\"-0.061111\"/>\n      <Kern code=\"1054\" val=\"-0.030556\"/>\n      <Kern code=\"1060\" val=\"-0.030556\"/>\n      <Kern code=\"1138\" val=\"-0.030556\"/>\n      <Kern code=\"1057\" val=\"-0.030556\"/>\n      <Kern code=\"1028\" val=\"-0.030556\"/>\n      <Kern code=\"1072\" val=\"-0.030556\"/>\n      <Kern code=\"1086\" val=\"-0.030556\"/>\n      <Kern code=\"1139\" val=\"-0.030556\"/>\n      <Kern code=\"1077\" val=\"-0.030556\"/>\n      <Kern code=\"1105\" val=\"-0.030556\"/>\n      <Kern code=\"1089\" val=\"-0.030556\"/>\n      <Kern code=\"1108\" val=\"-0.030556\"/>\n      <Kern code=\"1076\" val=\"-0.091667\"/>\n      <Kern code=\"1083\" val=\"-0.091667\"/>\n      <Kern code=\"1113\" val=\"-0.091667\"/>\n      <Kern code=\"1103\" val=\"-0.091667\"/>\n   </Char>\n   <Char code=\"1042\" width=\"0.733337\" height=\"0.694445\" />\n   <Char code=\"1065\" width=\"1.250008\" height=\"0.694445\" depth=\"0.194445\" />\n   <Char code=\"1064\" width=\"1.206952\" height=\"0.694445\" >\n      <Lig code=\"1063\" ligCode=\"1065\"/>\n      <Lig code=\"1095\" ligCode=\"1065\"/>\n      <Lig code=\"1062\" ligCode=\"0\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1067\" width=\"0.977783\" height=\"0.694445\" >\n      <Lig code=\"1040\" ligCode=\"1071\"/>\n      <Lig code=\"1072\" ligCode=\"1071\"/>\n      <Lig code=\"1059\" ligCode=\"1070\"/>\n      <Lig code=\"1091\" ligCode=\"1070\"/>\n   </Char>\n   <Char code=\"1047\" width=\"0.672226\" height=\"0.694445\" >\n      <Lig code=\"1061\" ligCode=\"1046\"/>\n      <Lig code=\"1093\" ligCode=\"1046\"/>\n   </Char>\n   <Char code=\"1068\" width=\"0.733337\" height=\"0.694445\" >\n      <Kern code=\"1046\" val=\"-0.030556\"/>\n      <Kern code=\"1061\" val=\"-0.030556\"/>\n      <Kern code=\"1054\" val=\"-0.030556\"/>\n      <Kern code=\"1060\" val=\"-0.030556\"/>\n      <Kern code=\"1138\" val=\"-0.030556\"/>\n      <Kern code=\"1057\" val=\"-0.030556\"/>\n      <Kern code=\"1028\" val=\"-0.030556\"/>\n      <Kern code=\"1058\" val=\"-0.091667\"/>\n      <Kern code=\"1066\" val=\"-0.091667\"/>\n      <Kern code=\"1026\" val=\"-0.091667\"/>\n      <Kern code=\"1035\" val=\"-0.091667\"/>\n      <Kern code=\"1122\" val=\"-0.091667\"/>\n      <Kern code=\"1063\" val=\"-0.091667\"/>\n      <Kern code=\"1059\" val=\"-0.030556\"/>\n      <Kern code=\"1140\" val=\"-0.091667\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.091667\"/>\n   </Char>\n   <Char code=\"1066\" width=\"0.940283\" height=\"0.694445\" >\n      <Kern code=\"1046\" val=\"-0.030556\"/>\n      <Kern code=\"1061\" val=\"-0.030556\"/>\n      <Kern code=\"1054\" val=\"-0.030556\"/>\n      <Kern code=\"1060\" val=\"-0.030556\"/>\n      <Kern code=\"1138\" val=\"-0.030556\"/>\n      <Kern code=\"1057\" val=\"-0.030556\"/>\n      <Kern code=\"1028\" val=\"-0.030556\"/>\n      <Kern code=\"1058\" val=\"-0.091667\"/>\n      <Kern code=\"1066\" val=\"-0.091667\"/>\n      <Kern code=\"1026\" val=\"-0.091667\"/>\n      <Kern code=\"1035\" val=\"-0.091667\"/>\n      <Kern code=\"1122\" val=\"-0.091667\"/>\n      <Kern code=\"1063\" val=\"-0.091667\"/>\n      <Kern code=\"1059\" val=\"-0.030556\"/>\n      <Kern code=\"1140\" val=\"-0.091667\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.091667\"/>\n   </Char>\n   <Char code=\"1072\" width=\"0.525003\" height=\"0.458333\" >\n      <Kern code=\"1095\" val=\"-0.030556\"/>\n      <Kern code=\"1091\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1073\" width=\"0.550003\" height=\"0.694445\" >\n      <Kern code=\"1076\" val=\"-0.030556\"/>\n      <Kern code=\"1078\" val=\"-0.030556\"/>\n      <Kern code=\"1093\" val=\"-0.030556\"/>\n      <Kern code=\"1103\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1094\" width=\"0.62917\" height=\"0.458333\" depth=\"0.162038\" >\n      <Lig code=\"1093\" ligCode=\"1095\"/>\n   </Char>\n   <Char code=\"1076\" width=\"0.636114\" height=\"0.458333\" depth=\"0.162038\" >\n      <Lig code=\"1112\" ligCode=\"1106\"/>\n   </Char>\n   <Char code=\"1077\" width=\"0.511114\" height=\"0.458333\" >\n   </Char>\n   <Char code=\"1092\" width=\"0.836118\" height=\"0.694445\" depth=\"0.194445\" >\n      <Kern code=\"1076\" val=\"-0.030556\"/>\n      <Kern code=\"1078\" val=\"-0.030556\"/>\n      <Kern code=\"1093\" val=\"-0.030556\"/>\n      <Kern code=\"1103\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1075\" width=\"0.433336\" height=\"0.458333\" italic=\"0.015279\" >\n      <Kern code=\"1076\" val=\"-0.030556\"/>\n      <Kern code=\"1083\" val=\"-0.030556\"/>\n      <Kern code=\"1113\" val=\"-0.030556\"/>\n      <Kern code=\"1103\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1093\" width=\"0.500003\" height=\"0.458333\" >\n      <Kern code=\"1072\" val=\"-0.030556\"/>\n      <Kern code=\"1086\" val=\"-0.030556\"/>\n      <Kern code=\"1139\" val=\"-0.030556\"/>\n      <Kern code=\"1089\" val=\"-0.030556\"/>\n      <Kern code=\"1108\" val=\"-0.030556\"/>\n      <Kern code=\"1077\" val=\"-0.030556\"/>\n      <Kern code=\"1105\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1080\" width=\"0.59167\" height=\"0.458333\" >\n   </Char>\n   <Char code=\"1112\" width=\"0.286113\" height=\"0.694445\" depth=\"0.194445\" >\n   </Char>\n   <Char code=\"1082\" width=\"0.530559\" height=\"0.458333\" >\n      <Lig code=\"1093\" ligCode=\"1093\"/>\n      <Kern code=\"1072\" val=\"-0.030556\"/>\n      <Kern code=\"1086\" val=\"-0.030556\"/>\n      <Kern code=\"1139\" val=\"-0.030556\"/>\n      <Kern code=\"1089\" val=\"-0.030556\"/>\n      <Kern code=\"1108\" val=\"-0.030556\"/>\n      <Kern code=\"1077\" val=\"-0.030556\"/>\n      <Kern code=\"1105\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1083\" width=\"0.598615\" height=\"0.458333\" >\n      <Lig code=\"1112\" ligCode=\"1113\"/>\n   </Char>\n   <Char code=\"1084\" width=\"0.744449\" height=\"0.458333\" />\n   <Char code=\"1085\" width=\"0.561114\" height=\"0.458333\" >\n      <Lig code=\"1112\" ligCode=\"1114\"/>\n   </Char>\n   <Char code=\"1086\" width=\"0.550003\" height=\"0.458333\" >\n      <Kern code=\"1076\" val=\"-0.030556\"/>\n      <Kern code=\"1078\" val=\"-0.030556\"/>\n      <Kern code=\"1093\" val=\"-0.030556\"/>\n      <Kern code=\"1103\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1087\" width=\"0.561114\" height=\"0.458333\" >\n   </Char>\n   <Char code=\"1095\" width=\"0.59167\" height=\"0.458333\" />\n   <Char code=\"1088\" width=\"0.561114\" height=\"0.458333\" depth=\"0.194445\" >\n      <Kern code=\"1076\" val=\"-0.030556\"/>\n      <Kern code=\"1078\" val=\"-0.030556\"/>\n      <Kern code=\"1093\" val=\"-0.030556\"/>\n      <Kern code=\"1103\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1089\" width=\"0.488892\" height=\"0.458333\" >\n      <Lig code=\"1093\" ligCode=\"1096\"/>\n      <Kern code=\"1076\" val=\"-0.030556\"/>\n      <Kern code=\"1078\" val=\"-0.030556\"/>\n      <Kern code=\"1093\" val=\"-0.030556\"/>\n      <Kern code=\"1103\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1090\" width=\"0.488892\" height=\"0.458333\" italic=\"0.02139\" >\n      <Lig code=\"1089\" ligCode=\"1094\"/>\n      <Kern code=\"1076\" val=\"-0.030556\"/>\n      <Kern code=\"1083\" val=\"-0.030556\"/>\n      <Kern code=\"1113\" val=\"-0.030556\"/>\n      <Kern code=\"1103\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1091\" width=\"0.500003\" height=\"0.458333\" depth=\"0.194445\" italic=\"0.015279\" >\n      <Kern code=\"1072\" val=\"-0.030556\"/>\n      <Kern code=\"1086\" val=\"-0.030556\"/>\n      <Kern code=\"1139\" val=\"-0.030556\"/>\n      <Kern code=\"1089\" val=\"-0.030556\"/>\n      <Kern code=\"1108\" val=\"-0.030556\"/>\n      <Kern code=\"1077\" val=\"-0.030556\"/>\n      <Kern code=\"1105\" val=\"-0.030556\"/>\n      <Kern code=\"1103\" val=\"-0.030556\"/>\n      <Kern code=\"1076\" val=\"-0.061111\"/>\n      <Kern code=\"1083\" val=\"-0.061111\"/>\n      <Kern code=\"1113\" val=\"-0.061111\"/>\n   </Char>\n   <Char code=\"1074\" width=\"0.525003\" height=\"0.458333\" />\n   <Char code=\"1097\" width=\"0.873616\" height=\"0.458333\" depth=\"0.162038\" />\n   <Char code=\"1096\" width=\"0.836116\" height=\"0.458333\" >\n      <Lig code=\"1095\" ligCode=\"1097\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1099\" width=\"0.744449\" height=\"0.458333\" >\n      <Lig code=\"1072\" ligCode=\"1103\"/>\n      <Lig code=\"1091\" ligCode=\"1102\"/>\n   </Char>\n   <Char code=\"1079\" width=\"0.488892\" height=\"0.458333\" italic=\"0.006111\" >\n      <Lig code=\"1093\" ligCode=\"1078\"/>\n   </Char>\n   <Char code=\"1100\" width=\"0.525003\" height=\"0.458333\" >\n      <Kern code=\"1091\" val=\"-0.061111\"/>\n      <Kern code=\"1141\" val=\"-0.061111\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.091667\"/>\n      <Kern code=\"1086\" val=\"-0.030556\"/>\n      <Kern code=\"1139\" val=\"-0.030556\"/>\n      <Kern code=\"1092\" val=\"-0.030556\"/>\n      <Kern code=\"1108\" val=\"-0.030556\"/>\n   </Char>\n   <Char code=\"1098\" width=\"0.64167\" height=\"0.458333\" >\n      <Kern code=\"1091\" val=\"-0.061111\"/>\n      <Kern code=\"1141\" val=\"-0.061111\"/>\n      <Kern code=\"1090\" val=\"-0.030556\"/>\n      <Kern code=\"1098\" val=\"-0.030556\"/>\n      <Kern code=\"1123\" val=\"-0.030556\"/>\n      <Kern code=\"1095\" val=\"-0.091667\"/>\n      <Kern code=\"1086\" val=\"-0.030556\"/>\n      <Kern code=\"1139\" val=\"-0.030556\"/>\n      <Kern code=\"1092\" val=\"-0.030556\"/>\n      <Kern code=\"1108\" val=\"-0.030556\"/>\n   </Char>\n</Font>\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/cyrillic/wnssi10.xml",
    "content": "<Font name=\"wnssi10.ttf\" id=\"wnssi10\" space=\"0.333334\" xHeight=\"0.444445\" quad=\"1.000003\" unicode=\"95\" romanVersion=\"wnti10\" ttVersion=\"wntt10\" boldVersion=\"wnssbx10\">\n   <Char code=\"1034\" width=\"1.020838\" height=\"0.694445\" italic=\"0.02595\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1033\" width=\"1.037504\" height=\"0.694445\" italic=\"0.02595\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1039\" width=\"0.694448\" height=\"0.694445\" depth=\"0.194445\" italic=\"0.080938\" />\n   <Char code=\"1069\" width=\"0.638891\" height=\"0.694445\" italic=\"0.075546\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1030\" width=\"0.277781\" height=\"0.694445\" italic=\"0.1337185\" >\n      <Kern code=\"1030\" val=\"0.027779\"/>\n   </Char>\n   <Char code=\"1028\" width=\"0.638891\" height=\"0.694445\" italic=\"0.119829\" />\n   <Char code=\"1026\" width=\"0.8194475\" height=\"0.694445\" italic=\"0.1337185\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1035\" width=\"0.763891\" height=\"0.694445\" italic=\"0.0920515\" />\n   <Char code=\"1114\" width=\"0.765282\" height=\"0.444445\" italic=\"0.0389\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1113\" width=\"0.755559\" height=\"0.444445\" italic=\"0.0389\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1119\" width=\"0.537503\" height=\"0.444445\" depth=\"0.162038\" italic=\"0.04169\" />\n   <Char code=\"1101\" width=\"0.444446\" height=\"0.444445\" italic=\"0.060573\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1110\" width=\"0.23889\" height=\"0.679365\" italic=\"0.09718\" />\n   <Char code=\"1108\" width=\"0.43889\" height=\"0.444445\" italic=\"0.083357\" />\n   <Char code=\"1106\" width=\"0.488892\" height=\"0.694445\" depth=\"0.194445\" italic=\"0.066129\" />\n   <Char code=\"1115\" width=\"0.516668\" height=\"0.694445\" italic=\"0.017778\" />\n   <Char code=\"1070\" width=\"1.04167\" height=\"0.694445\" italic=\"0.075546\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1046\" width=\"1.111117\" height=\"0.694445\" italic=\"0.119829\" >\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.027779\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1049\" width=\"0.694448\" height=\"0.902727\" italic=\"0.080938\" />\n   <Char code=\"1025\" width=\"0.597224\" height=\"0.902727\" italic=\"0.119829\" />\n   <Char code=\"1140\" width=\"0.722226\" height=\"0.694445\" italic=\"0.161496\" >\n      <Kern code=\"1040\" val=\"-0.083334\"/>\n      <Kern code=\"1044\" val=\"-0.055555\"/>\n      <Kern code=\"1051\" val=\"-0.055555\"/>\n      <Kern code=\"1033\" val=\"-0.055555\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n      <Kern code=\"1103\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1138\" width=\"0.777781\" height=\"0.694445\" italic=\"0.075546\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1029\" width=\"0.555557\" height=\"0.694445\" italic=\"0.0920515\" />\n   <Char code=\"1071\" width=\"0.645836\" height=\"0.694445\" italic=\"0.080938\" />\n   <Char code=\"1102\" width=\"0.730558\" height=\"0.444445\" italic=\"0.066129\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1078\" width=\"0.7388935\" height=\"0.444445\" italic=\"0.083357\" >\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1081\" width=\"0.537503\" height=\"0.652727\" italic=\"0.04169\" />\n   <Char code=\"1105\" width=\"0.444446\" height=\"0.660319\" italic=\"0.067778\" />\n   <Char code=\"1141\" width=\"0.491667\" height=\"0.444445\" italic=\"0.108357\" >\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.055555\"/>\n      <Kern code=\"1083\" val=\"-0.055555\"/>\n      <Kern code=\"1113\" val=\"-0.055555\"/>\n   </Char>\n   <Char code=\"1139\" width=\"0.500002\" height=\"0.444445\" italic=\"0.03835\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1109\" width=\"0.383334\" height=\"0.444445\" italic=\"0.077802\" />\n   <Char code=\"1103\" width=\"0.515279\" height=\"0.444445\" italic=\"0.04169\" />\n   <Char code=\"776\" width=\"0.500002\" height=\"0.660319\" italic=\"0.059799\" />\n   <Char code=\"1122\" width=\"0.7777815\" height=\"0.75\" italic=\"0.082927\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"774\" width=\"0.500002\" height=\"0.652727\" italic=\"0.085962\" />\n   <Char code=\"1123\" width=\"0.500002\" height=\"0.652727\" italic=\"0.030568\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"171\" width=\"0.666669\" height=\"0.438889\" italic=\"0.02018\" />\n   <Char code=\"305\" width=\"0.23889\" height=\"0.444445\" italic=\"0.04169\" />\n   <Char code=\"187\" width=\"0.666669\" height=\"0.438889\" />\n   <Char code=\"1040\" width=\"0.66667\" height=\"0.694445\" >\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1041\" width=\"0.66667\" height=\"0.694445\" italic=\"0.064273\" />\n   <Char code=\"1062\" width=\"0.711116\" height=\"0.694445\" depth=\"0.194445\" italic=\"0.080938\" >\n      <Lig code=\"1061\" ligCode=\"1063\"/>\n      <Lig code=\"1093\" ligCode=\"1063\"/>\n   </Char>\n   <Char code=\"1044\" width=\"0.727783\" height=\"0.694445\" depth=\"0.194445\" italic=\"0.080938\" >\n      <Lig code=\"1032\" ligCode=\"1026\"/>\n      <Lig code=\"1112\" ligCode=\"1026\"/>\n   </Char>\n   <Char code=\"1045\" width=\"0.597224\" height=\"0.694445\" italic=\"0.119829\" >\n   </Char>\n   <Char code=\"1060\" width=\"0.833336\" height=\"0.694445\" italic=\"0.075546\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1043\" width=\"0.541669\" height=\"0.694445\" italic=\"0.1337185\" >\n      <Kern code=\"1040\" val=\"-0.083334\"/>\n      <Kern code=\"1044\" val=\"-0.083334\"/>\n      <Kern code=\"1051\" val=\"-0.055555\"/>\n      <Kern code=\"1033\" val=\"-0.055555\"/>\n      <Kern code=\"1072\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.083334\"/>\n      <Kern code=\"1139\" val=\"-0.083334\"/>\n      <Kern code=\"1077\" val=\"-0.083334\"/>\n      <Kern code=\"1105\" val=\"-0.083334\"/>\n      <Kern code=\"1089\" val=\"-0.083334\"/>\n      <Kern code=\"1108\" val=\"-0.083334\"/>\n      <Kern code=\"1092\" val=\"-0.083334\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n      <Kern code=\"1103\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1061\" width=\"0.66667\" height=\"0.694445\" italic=\"0.1337185\" >\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.027779\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1048\" width=\"0.694448\" height=\"0.694445\" italic=\"0.080938\" >\n   </Char>\n   <Char code=\"1032\" width=\"0.472224\" height=\"0.694445\" italic=\"0.080938\" >\n   </Char>\n   <Char code=\"1050\" width=\"0.694448\" height=\"0.694445\" italic=\"0.119829\" >\n      <Lig code=\"1061\" ligCode=\"1061\"/>\n      <Lig code=\"1093\" ligCode=\"1061\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.027779\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1051\" width=\"0.711116\" height=\"0.694445\" italic=\"0.080938\" >\n      <Lig code=\"1032\" ligCode=\"1033\"/>\n      <Lig code=\"1112\" ligCode=\"1033\"/>\n   </Char>\n   <Char code=\"1052\" width=\"0.875005\" height=\"0.694445\" italic=\"0.080938\" />\n   <Char code=\"1053\" width=\"0.694448\" height=\"0.694445\" italic=\"0.080938\" >\n      <Lig code=\"1032\" ligCode=\"1034\"/>\n      <Lig code=\"1112\" ligCode=\"1034\"/>\n   </Char>\n   <Char code=\"1054\" width=\"0.736113\" height=\"0.694445\" italic=\"0.075546\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.027779\"/>\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1055\" width=\"0.694448\" height=\"0.694445\" italic=\"0.080938\" >\n   </Char>\n   <Char code=\"1063\" width=\"0.694448\" height=\"0.694445\" italic=\"0.080938\" />\n   <Char code=\"1056\" width=\"0.638891\" height=\"0.694445\" italic=\"0.082927\" >\n      <Kern code=\"1040\" val=\"-0.083334\"/>\n      <Kern code=\"1044\" val=\"-0.083334\"/>\n      <Kern code=\"1051\" val=\"-0.083334\"/>\n      <Kern code=\"1033\" val=\"-0.083334\"/>\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1057\" width=\"0.638891\" height=\"0.694445\" italic=\"0.119829\" >\n      <Lig code=\"1061\" ligCode=\"1064\"/>\n      <Lig code=\"1093\" ligCode=\"1064\"/>\n   </Char>\n   <Char code=\"1058\" width=\"0.680557\" height=\"0.694445\" italic=\"0.1337185\" >\n      <Lig code=\"1057\" ligCode=\"1062\"/>\n      <Lig code=\"1089\" ligCode=\"1062\"/>\n      <Kern code=\"1040\" val=\"-0.083334\"/>\n      <Kern code=\"1044\" val=\"-0.083334\"/>\n      <Kern code=\"1051\" val=\"-0.055555\"/>\n      <Kern code=\"1033\" val=\"-0.055555\"/>\n      <Kern code=\"1072\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.083334\"/>\n      <Kern code=\"1139\" val=\"-0.083334\"/>\n      <Kern code=\"1077\" val=\"-0.083334\"/>\n      <Kern code=\"1105\" val=\"-0.083334\"/>\n      <Kern code=\"1089\" val=\"-0.083334\"/>\n      <Kern code=\"1108\" val=\"-0.083334\"/>\n      <Kern code=\"1092\" val=\"-0.083334\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n      <Kern code=\"1103\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1059\" width=\"0.66667\" height=\"0.694445\" italic=\"0.161496\" >\n      <Kern code=\"1040\" val=\"-0.027779\"/>\n      <Kern code=\"1044\" val=\"-0.055555\"/>\n      <Kern code=\"1051\" val=\"-0.055555\"/>\n      <Kern code=\"1033\" val=\"-0.055555\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.083334\"/>\n      <Kern code=\"1083\" val=\"-0.083334\"/>\n      <Kern code=\"1113\" val=\"-0.083334\"/>\n      <Kern code=\"1103\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1042\" width=\"0.66667\" height=\"0.694445\" italic=\"0.05515\" />\n   <Char code=\"1065\" width=\"1.100006\" height=\"0.694445\" depth=\"0.194445\" italic=\"0.080938\" />\n   <Char code=\"1064\" width=\"1.083339\" height=\"0.694445\" italic=\"0.080938\" >\n      <Lig code=\"1063\" ligCode=\"1065\"/>\n      <Lig code=\"1095\" ligCode=\"1065\"/>\n      <Lig code=\"1062\" ligCode=\"0\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1067\" width=\"0.888895\" height=\"0.694445\" italic=\"0.080938\" >\n      <Lig code=\"1040\" ligCode=\"1071\"/>\n      <Lig code=\"1072\" ligCode=\"1071\"/>\n      <Lig code=\"1059\" ligCode=\"1070\"/>\n      <Lig code=\"1091\" ligCode=\"1070\"/>\n   </Char>\n   <Char code=\"1047\" width=\"0.611113\" height=\"0.694445\" italic=\"0.082927\" >\n      <Lig code=\"1061\" ligCode=\"1046\"/>\n      <Lig code=\"1093\" ligCode=\"1046\"/>\n   </Char>\n   <Char code=\"1068\" width=\"0.66667\" height=\"0.694445\" italic=\"0.02595\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1066\" width=\"0.868059\" height=\"0.694445\" italic=\"0.02595\" >\n      <Kern code=\"1046\" val=\"-0.027779\"/>\n      <Kern code=\"1061\" val=\"-0.027779\"/>\n      <Kern code=\"1054\" val=\"-0.027779\"/>\n      <Kern code=\"1060\" val=\"-0.027779\"/>\n      <Kern code=\"1138\" val=\"-0.027779\"/>\n      <Kern code=\"1057\" val=\"-0.027779\"/>\n      <Kern code=\"1028\" val=\"-0.027779\"/>\n      <Kern code=\"1058\" val=\"-0.083334\"/>\n      <Kern code=\"1066\" val=\"-0.083334\"/>\n      <Kern code=\"1026\" val=\"-0.083334\"/>\n      <Kern code=\"1035\" val=\"-0.083334\"/>\n      <Kern code=\"1122\" val=\"-0.083334\"/>\n      <Kern code=\"1063\" val=\"-0.083334\"/>\n      <Kern code=\"1059\" val=\"-0.027779\"/>\n      <Kern code=\"1140\" val=\"-0.083334\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n   </Char>\n   <Char code=\"1072\" width=\"0.480557\" height=\"0.444445\" italic=\"0.009807\" >\n      <Kern code=\"1095\" val=\"-0.027779\"/>\n      <Kern code=\"1091\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1073\" width=\"0.500002\" height=\"0.694445\" italic=\"0.094829\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1094\" width=\"0.5486145\" height=\"0.444445\" depth=\"0.162038\" italic=\"0.04169\" >\n      <Lig code=\"1093\" ligCode=\"1095\"/>\n   </Char>\n   <Char code=\"1076\" width=\"0.538892\" height=\"0.444445\" depth=\"0.162038\" italic=\"0.04169\" >\n      <Lig code=\"1112\" ligCode=\"1106\"/>\n   </Char>\n   <Char code=\"1077\" width=\"0.444446\" height=\"0.444445\" italic=\"0.067778\" >\n   </Char>\n   <Char code=\"1092\" width=\"0.76667\" height=\"0.694445\" depth=\"0.194445\" italic=\"0.0389\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1075\" width=\"0.404167\" height=\"0.444445\" italic=\"0.108357\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1083\" val=\"-0.027779\"/>\n      <Kern code=\"1113\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1093\" width=\"0.461113\" height=\"0.444445\" italic=\"0.09169\" >\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1080\" width=\"0.537503\" height=\"0.444445\" italic=\"0.04169\" >\n   </Char>\n   <Char code=\"1112\" width=\"0.266668\" height=\"0.679365\" depth=\"0.194445\" italic=\"0.091624\" >\n   </Char>\n   <Char code=\"1082\" width=\"0.488892\" height=\"0.444445\" italic=\"0.083357\" >\n      <Lig code=\"1093\" ligCode=\"1093\"/>\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1083\" width=\"0.527781\" height=\"0.444445\" italic=\"0.04169\" >\n      <Lig code=\"1112\" ligCode=\"1113\"/>\n   </Char>\n   <Char code=\"1084\" width=\"0.669447\" height=\"0.444445\" italic=\"0.04169\" />\n   <Char code=\"1085\" width=\"0.516668\" height=\"0.444445\" italic=\"0.04169\" >\n      <Lig code=\"1112\" ligCode=\"1114\"/>\n   </Char>\n   <Char code=\"1086\" width=\"0.500002\" height=\"0.444445\" italic=\"0.066129\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1087\" width=\"0.516668\" height=\"0.444445\" italic=\"0.04169\" >\n   </Char>\n   <Char code=\"1095\" width=\"0.537503\" height=\"0.444445\" italic=\"0.04169\" />\n   <Char code=\"1088\" width=\"0.516668\" height=\"0.444445\" depth=\"0.194445\" italic=\"0.0389\" >\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1089\" width=\"0.444446\" height=\"0.444445\" italic=\"0.083357\" >\n      <Lig code=\"1093\" ligCode=\"1096\"/>\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1078\" val=\"-0.027779\"/>\n      <Kern code=\"1093\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1090\" width=\"0.458334\" height=\"0.444445\" italic=\"0.113913\" >\n      <Lig code=\"1089\" ligCode=\"1094\"/>\n      <Kern code=\"1076\" val=\"-0.027779\"/>\n      <Kern code=\"1083\" val=\"-0.027779\"/>\n      <Kern code=\"1113\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1091\" width=\"0.461113\" height=\"0.444445\" depth=\"0.194445\" italic=\"0.108357\" >\n      <Kern code=\"1072\" val=\"-0.027779\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1089\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n      <Kern code=\"1077\" val=\"-0.027779\"/>\n      <Kern code=\"1105\" val=\"-0.027779\"/>\n      <Kern code=\"1103\" val=\"-0.027779\"/>\n      <Kern code=\"1076\" val=\"-0.055555\"/>\n      <Kern code=\"1083\" val=\"-0.055555\"/>\n      <Kern code=\"1113\" val=\"-0.055555\"/>\n   </Char>\n   <Char code=\"1074\" width=\"0.480557\" height=\"0.444445\" italic=\"0.0389\" />\n   <Char code=\"1097\" width=\"0.7777815\" height=\"0.444445\" depth=\"0.162038\" italic=\"0.04169\" />\n   <Char code=\"1096\" width=\"0.76667\" height=\"0.444445\" italic=\"0.04169\" >\n      <Lig code=\"1095\" ligCode=\"1097\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1099\" width=\"0.683336\" height=\"0.444445\" italic=\"0.04169\" >\n      <Lig code=\"1072\" ligCode=\"1103\"/>\n      <Lig code=\"1091\" ligCode=\"1102\"/>\n   </Char>\n   <Char code=\"1079\" width=\"0.444446\" height=\"0.444445\" italic=\"0.050013\" >\n      <Lig code=\"1093\" ligCode=\"1078\"/>\n   </Char>\n   <Char code=\"1100\" width=\"0.480557\" height=\"0.444445\" italic=\"0.0389\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n   <Char code=\"1098\" width=\"0.590279\" height=\"0.444445\" italic=\"0.0389\" >\n      <Kern code=\"1091\" val=\"-0.055555\"/>\n      <Kern code=\"1141\" val=\"-0.055555\"/>\n      <Kern code=\"1090\" val=\"-0.027779\"/>\n      <Kern code=\"1098\" val=\"-0.027779\"/>\n      <Kern code=\"1123\" val=\"-0.027779\"/>\n      <Kern code=\"1095\" val=\"-0.083334\"/>\n      <Kern code=\"1086\" val=\"-0.027779\"/>\n      <Kern code=\"1139\" val=\"-0.027779\"/>\n      <Kern code=\"1092\" val=\"-0.027779\"/>\n      <Kern code=\"1108\" val=\"-0.027779\"/>\n   </Char>\n</Font>\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/cyrillic/wnti10.xml",
    "content": "<Font name=\"wnti10.ttf\" id=\"wnti10\" space=\"0.357776\" xHeight=\"0.430555\" quad=\"1.022217\" unicode=\"95\" romanVersion=\"wnr10\" boldVersion=\"wnbxti10\" ssVersion=\"wnssi10\" ttVersion=\"wntt10\">\n   <Char code=\"1034\" width=\"1.048883\" height=\"0.683332\" italic=\"0.036629\" >\n      <Kern code=\"1046\" val=\"-0.025556\"/>\n      <Kern code=\"1061\" val=\"-0.025556\"/>\n      <Kern code=\"1054\" val=\"-0.025556\"/>\n      <Kern code=\"1060\" val=\"-0.025556\"/>\n      <Kern code=\"1138\" val=\"-0.025556\"/>\n      <Kern code=\"1057\" val=\"-0.025556\"/>\n      <Kern code=\"1028\" val=\"-0.025556\"/>\n      <Kern code=\"1058\" val=\"-0.076666\"/>\n      <Kern code=\"1066\" val=\"-0.076666\"/>\n      <Kern code=\"1026\" val=\"-0.076666\"/>\n      <Kern code=\"1035\" val=\"-0.076666\"/>\n      <Kern code=\"1122\" val=\"-0.076666\"/>\n      <Kern code=\"1063\" val=\"-0.076666\"/>\n      <Kern code=\"1059\" val=\"-0.076666\"/>\n      <Kern code=\"1140\" val=\"-0.1022215\"/>\n      <Kern code=\"1098\" val=\"-0.025556\"/>\n      <Kern code=\"1141\" val=\"-0.025556\"/>\n      <Kern code=\"1082\" val=\"-0.025556\"/>\n      <Kern code=\"1085\" val=\"-0.025556\"/>\n      <Kern code=\"1114\" val=\"-0.025556\"/>\n      <Kern code=\"1087\" val=\"-0.025556\"/>\n      <Kern code=\"1090\" val=\"-0.025556\"/>\n      <Kern code=\"1102\" val=\"-0.025556\"/>\n      <Kern code=\"1123\" val=\"-0.025556\"/>\n      <Kern code=\"1110\" val=\"-0.025556\"/>\n      <Kern code=\"1080\" val=\"-0.025556\"/>\n      <Kern code=\"1081\" val=\"-0.025556\"/>\n      <Kern code=\"1094\" val=\"-0.025556\"/>\n      <Kern code=\"1096\" val=\"-0.025556\"/>\n      <Kern code=\"1097\" val=\"-0.025556\"/>\n      <Kern code=\"1100\" val=\"-0.025556\"/>\n      <Kern code=\"1099\" val=\"-0.025556\"/>\n      <Kern code=\"1091\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1033\" width=\"1.048883\" height=\"0.683332\" italic=\"0.036629\" >\n      <Kern code=\"1046\" val=\"-0.025556\"/>\n      <Kern code=\"1061\" val=\"-0.025556\"/>\n      <Kern code=\"1054\" val=\"-0.025556\"/>\n      <Kern code=\"1060\" val=\"-0.025556\"/>\n      <Kern code=\"1138\" val=\"-0.025556\"/>\n      <Kern code=\"1057\" val=\"-0.025556\"/>\n      <Kern code=\"1028\" val=\"-0.025556\"/>\n      <Kern code=\"1058\" val=\"-0.076666\"/>\n      <Kern code=\"1066\" val=\"-0.076666\"/>\n      <Kern code=\"1026\" val=\"-0.076666\"/>\n      <Kern code=\"1035\" val=\"-0.076666\"/>\n      <Kern code=\"1122\" val=\"-0.076666\"/>\n      <Kern code=\"1063\" val=\"-0.076666\"/>\n      <Kern code=\"1059\" val=\"-0.076666\"/>\n      <Kern code=\"1140\" val=\"-0.1022215\"/>\n      <Kern code=\"1098\" val=\"-0.025556\"/>\n      <Kern code=\"1141\" val=\"-0.025556\"/>\n      <Kern code=\"1082\" val=\"-0.025556\"/>\n      <Kern code=\"1085\" val=\"-0.025556\"/>\n      <Kern code=\"1114\" val=\"-0.025556\"/>\n      <Kern code=\"1087\" val=\"-0.025556\"/>\n      <Kern code=\"1090\" val=\"-0.025556\"/>\n      <Kern code=\"1102\" val=\"-0.025556\"/>\n      <Kern code=\"1123\" val=\"-0.025556\"/>\n      <Kern code=\"1110\" val=\"-0.025556\"/>\n      <Kern code=\"1080\" val=\"-0.025556\"/>\n      <Kern code=\"1081\" val=\"-0.025556\"/>\n      <Kern code=\"1094\" val=\"-0.025556\"/>\n      <Kern code=\"1096\" val=\"-0.025556\"/>\n      <Kern code=\"1097\" val=\"-0.025556\"/>\n      <Kern code=\"1100\" val=\"-0.025556\"/>\n      <Kern code=\"1099\" val=\"-0.025556\"/>\n      <Kern code=\"1091\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1039\" width=\"0.768885\" height=\"0.683332\" depth=\"0.194445\" italic=\"0.16389\" />\n   <Char code=\"1069\" width=\"0.715551\" height=\"0.683332\" italic=\"0.0940275\" >\n      <Kern code=\"1040\" val=\"-0.025556\"/>\n      <Kern code=\"1044\" val=\"-0.025556\"/>\n      <Kern code=\"1046\" val=\"-0.025556\"/>\n      <Kern code=\"1061\" val=\"-0.025556\"/>\n      <Kern code=\"1059\" val=\"-0.025556\"/>\n      <Kern code=\"1140\" val=\"-0.025556\"/>\n      <Kern code=\"1071\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1030\" width=\"0.385553\" height=\"0.683332\" italic=\"0.158055\" >\n      <Kern code=\"1030\" val=\"0.025556\"/>\n   </Char>\n   <Char code=\"1028\" width=\"0.715551\" height=\"0.683332\" italic=\"0.145277\" />\n   <Char code=\"1026\" width=\"0.843328\" height=\"0.683332\" italic=\"0.133055\" >\n      <Kern code=\"1046\" val=\"-0.025556\"/>\n      <Kern code=\"1061\" val=\"-0.025556\"/>\n      <Kern code=\"1054\" val=\"-0.025556\"/>\n      <Kern code=\"1060\" val=\"-0.025556\"/>\n      <Kern code=\"1138\" val=\"-0.025556\"/>\n      <Kern code=\"1057\" val=\"-0.025556\"/>\n      <Kern code=\"1028\" val=\"-0.025556\"/>\n      <Kern code=\"1058\" val=\"-0.076666\"/>\n      <Kern code=\"1066\" val=\"-0.076666\"/>\n      <Kern code=\"1026\" val=\"-0.076666\"/>\n      <Kern code=\"1035\" val=\"-0.076666\"/>\n      <Kern code=\"1122\" val=\"-0.076666\"/>\n      <Kern code=\"1063\" val=\"-0.076666\"/>\n      <Kern code=\"1059\" val=\"-0.076666\"/>\n      <Kern code=\"1140\" val=\"-0.1022215\"/>\n      <Kern code=\"1098\" val=\"-0.025556\"/>\n      <Kern code=\"1141\" val=\"-0.025556\"/>\n      <Kern code=\"1082\" val=\"-0.025556\"/>\n      <Kern code=\"1085\" val=\"-0.025556\"/>\n      <Kern code=\"1114\" val=\"-0.025556\"/>\n      <Kern code=\"1087\" val=\"-0.025556\"/>\n      <Kern code=\"1090\" val=\"-0.025556\"/>\n      <Kern code=\"1102\" val=\"-0.025556\"/>\n      <Kern code=\"1123\" val=\"-0.025556\"/>\n      <Kern code=\"1110\" val=\"-0.025556\"/>\n      <Kern code=\"1080\" val=\"-0.025556\"/>\n      <Kern code=\"1081\" val=\"-0.025556\"/>\n      <Kern code=\"1094\" val=\"-0.025556\"/>\n      <Kern code=\"1096\" val=\"-0.025556\"/>\n      <Kern code=\"1097\" val=\"-0.025556\"/>\n      <Kern code=\"1100\" val=\"-0.025556\"/>\n      <Kern code=\"1099\" val=\"-0.025556\"/>\n      <Kern code=\"1091\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1035\" width=\"0.753885\" height=\"0.683332\" italic=\"0.094722\" />\n   <Char code=\"1114\" width=\"0.715551\" height=\"0.430555\" italic=\"0.063124\" >\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n      <Kern code=\"1141\" val=\"-0.025556\"/>\n      <Kern code=\"1098\" val=\"-0.025556\"/>\n      <Kern code=\"1095\" val=\"-0.076666\"/>\n      <Kern code=\"1086\" val=\"-0.025556\"/>\n      <Kern code=\"1139\" val=\"-0.025556\"/>\n      <Kern code=\"1092\" val=\"-0.025556\"/>\n      <Kern code=\"1108\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1113\" width=\"0.689997\" height=\"0.430555\" italic=\"0.063124\" >\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n      <Kern code=\"1141\" val=\"-0.025556\"/>\n      <Kern code=\"1098\" val=\"-0.025556\"/>\n      <Kern code=\"1095\" val=\"-0.076666\"/>\n      <Kern code=\"1086\" val=\"-0.025556\"/>\n      <Kern code=\"1139\" val=\"-0.025556\"/>\n      <Kern code=\"1092\" val=\"-0.025556\"/>\n      <Kern code=\"1108\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1119\" width=\"0.536664\" height=\"0.430555\" depth=\"0.194445\" italic=\"0.076714\" />\n   <Char code=\"1101\" width=\"0.442108\" height=\"0.430555\" italic=\"0.063124\" >\n      <Kern code=\"1092\" val=\"-0.051111\"/>\n      <Kern code=\"1072\" val=\"-0.051111\"/>\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1110\" width=\"0.306665\" height=\"0.655359\" italic=\"0.101896\" />\n   <Char code=\"1108\" width=\"0.442108\" height=\"0.430555\" italic=\"0.082083\" />\n   <Char code=\"1106\" width=\"0.459997\" height=\"0.694445\" depth=\"0.194445\" italic=\"0.075346\" />\n   <Char code=\"1115\" width=\"0.511108\" height=\"0.694445\" italic=\"0.076714\" />\n   <Char code=\"1070\" width=\"1.087216\" height=\"0.683332\" italic=\"0.0940275\" >\n      <Kern code=\"1040\" val=\"-0.025556\"/>\n      <Kern code=\"1044\" val=\"-0.025556\"/>\n      <Kern code=\"1046\" val=\"-0.025556\"/>\n      <Kern code=\"1061\" val=\"-0.025556\"/>\n      <Kern code=\"1059\" val=\"-0.025556\"/>\n      <Kern code=\"1140\" val=\"-0.025556\"/>\n      <Kern code=\"1071\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1046\" width=\"1.152216\" height=\"0.683332\" italic=\"0.145277\" >\n      <Kern code=\"1054\" val=\"-0.025556\"/>\n      <Kern code=\"1060\" val=\"-0.025556\"/>\n      <Kern code=\"1138\" val=\"-0.025556\"/>\n      <Kern code=\"1057\" val=\"-0.025556\"/>\n      <Kern code=\"1028\" val=\"-0.025556\"/>\n      <Kern code=\"1095\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1049\" width=\"0.768885\" height=\"0.891615\" italic=\"0.16389\" />\n   <Char code=\"1025\" width=\"0.678329\" height=\"0.891615\" italic=\"0.120277\" />\n   <Char code=\"1140\" width=\"0.806107\" height=\"0.683332\" italic=\"0.183611\" >\n      <Kern code=\"1040\" val=\"-0.1022215\"/>\n      <Kern code=\"1071\" val=\"-0.1022215\"/>\n      <Kern code=\"1054\" val=\"-0.025556\"/>\n      <Kern code=\"1060\" val=\"-0.025556\"/>\n      <Kern code=\"1138\" val=\"-0.025556\"/>\n      <Kern code=\"1057\" val=\"-0.025556\"/>\n      <Kern code=\"1028\" val=\"-0.025556\"/>\n      <Kern code=\"1072\" val=\"-0.076666\"/>\n      <Kern code=\"1086\" val=\"-0.076666\"/>\n      <Kern code=\"1139\" val=\"-0.076666\"/>\n      <Kern code=\"1077\" val=\"-0.076666\"/>\n      <Kern code=\"1105\" val=\"-0.076666\"/>\n      <Kern code=\"1080\" val=\"-0.1022215\"/>\n      <Kern code=\"1081\" val=\"-0.1022215\"/>\n      <Kern code=\"1094\" val=\"-0.1022215\"/>\n      <Kern code=\"1096\" val=\"-0.1022215\"/>\n      <Kern code=\"1097\" val=\"-0.1022215\"/>\n      <Kern code=\"1100\" val=\"-0.1022215\"/>\n      <Kern code=\"1099\" val=\"-0.1022215\"/>\n      <Kern code=\"1091\" val=\"-0.1022215\"/>\n      <Kern code=\"1141\" val=\"-0.1022215\"/>\n      <Kern code=\"1098\" val=\"-0.1022215\"/>\n      <Kern code=\"1083\" val=\"-0.1022215\"/>\n      <Kern code=\"1084\" val=\"-0.1022215\"/>\n      <Kern code=\"1113\" val=\"-0.1022215\"/>\n   </Char>\n   <Char code=\"1138\" width=\"0.766663\" height=\"0.683332\" italic=\"0.0940275\" >\n      <Kern code=\"1040\" val=\"-0.025556\"/>\n      <Kern code=\"1044\" val=\"-0.025556\"/>\n      <Kern code=\"1046\" val=\"-0.025556\"/>\n      <Kern code=\"1061\" val=\"-0.025556\"/>\n      <Kern code=\"1059\" val=\"-0.025556\"/>\n      <Kern code=\"1140\" val=\"-0.025556\"/>\n      <Kern code=\"1071\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1029\" width=\"0.56222\" height=\"0.683332\" italic=\"0.119722\" />\n   <Char code=\"1071\" width=\"0.768885\" height=\"0.683332\" italic=\"0.16389\" />\n   <Char code=\"1102\" width=\"0.723218\" height=\"0.430555\" italic=\"0.063124\" >\n      <Kern code=\"1092\" val=\"-0.051111\"/>\n      <Kern code=\"1072\" val=\"-0.051111\"/>\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1078\" width=\"1.047772\" height=\"0.430555\" italic=\"0.056528\" />\n   <Char code=\"1081\" width=\"0.56222\" height=\"0.638838\" italic=\"0.076714\" />\n   <Char code=\"1105\" width=\"0.442108\" height=\"0.659131\" italic=\"0.075139\" >\n      <Kern code=\"1092\" val=\"-0.051111\"/>\n      <Kern code=\"1072\" val=\"-0.051111\"/>\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1141\" width=\"0.615275\" height=\"0.430555\" italic=\"0.120417\" >\n      <Kern code=\"1083\" val=\"-0.076666\"/>\n      <Kern code=\"1084\" val=\"-0.076666\"/>\n      <Kern code=\"1113\" val=\"-0.076666\"/>\n   </Char>\n   <Char code=\"1139\" width=\"0.459997\" height=\"0.430555\" italic=\"0.063124\" >\n      <Kern code=\"1092\" val=\"-0.051111\"/>\n      <Kern code=\"1072\" val=\"-0.051111\"/>\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1109\" width=\"0.408887\" height=\"0.430555\" italic=\"0.082083\" />\n   <Char code=\"1103\" width=\"0.536664\" height=\"0.430555\" italic=\"0.076714\" />\n   <Char code=\"776\" width=\"0.511108\" height=\"0.659131\" italic=\"0.102562\" />\n   <Char code=\"1122\" width=\"0.806107\" height=\"0.75\" italic=\"0.10257\" >\n      <Kern code=\"1046\" val=\"-0.025556\"/>\n      <Kern code=\"1061\" val=\"-0.025556\"/>\n      <Kern code=\"1054\" val=\"-0.025556\"/>\n      <Kern code=\"1060\" val=\"-0.025556\"/>\n      <Kern code=\"1138\" val=\"-0.025556\"/>\n      <Kern code=\"1057\" val=\"-0.025556\"/>\n      <Kern code=\"1028\" val=\"-0.025556\"/>\n      <Kern code=\"1058\" val=\"-0.076666\"/>\n      <Kern code=\"1066\" val=\"-0.076666\"/>\n      <Kern code=\"1026\" val=\"-0.076666\"/>\n      <Kern code=\"1035\" val=\"-0.076666\"/>\n      <Kern code=\"1122\" val=\"-0.076666\"/>\n      <Kern code=\"1063\" val=\"-0.076666\"/>\n      <Kern code=\"1059\" val=\"-0.076666\"/>\n      <Kern code=\"1140\" val=\"-0.1022215\"/>\n      <Kern code=\"1098\" val=\"-0.025556\"/>\n      <Kern code=\"1141\" val=\"-0.025556\"/>\n      <Kern code=\"1082\" val=\"-0.025556\"/>\n      <Kern code=\"1085\" val=\"-0.025556\"/>\n      <Kern code=\"1114\" val=\"-0.025556\"/>\n      <Kern code=\"1087\" val=\"-0.025556\"/>\n      <Kern code=\"1090\" val=\"-0.025556\"/>\n      <Kern code=\"1102\" val=\"-0.025556\"/>\n      <Kern code=\"1123\" val=\"-0.025556\"/>\n      <Kern code=\"1110\" val=\"-0.025556\"/>\n      <Kern code=\"1080\" val=\"-0.025556\"/>\n      <Kern code=\"1081\" val=\"-0.025556\"/>\n      <Kern code=\"1094\" val=\"-0.025556\"/>\n      <Kern code=\"1096\" val=\"-0.025556\"/>\n      <Kern code=\"1097\" val=\"-0.025556\"/>\n      <Kern code=\"1100\" val=\"-0.025556\"/>\n      <Kern code=\"1099\" val=\"-0.025556\"/>\n      <Kern code=\"1091\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"774\" width=\"0.511108\" height=\"0.638838\" italic=\"0.094154\" />\n   <Char code=\"1123\" width=\"0.715551\" height=\"0.430555\" italic=\"0.063124\" >\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n      <Kern code=\"1141\" val=\"-0.025556\"/>\n      <Kern code=\"1098\" val=\"-0.025556\"/>\n      <Kern code=\"1095\" val=\"-0.076666\"/>\n      <Kern code=\"1086\" val=\"-0.025556\"/>\n      <Kern code=\"1139\" val=\"-0.025556\"/>\n      <Kern code=\"1092\" val=\"-0.025556\"/>\n      <Kern code=\"1108\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"171\" width=\"0.56222\" height=\"0.483335\" italic=\"0.022985\"  />\n   <Char code=\"305\" width=\"0.306665\" height=\"0.430555\" italic=\"0.076714\" />\n   <Char code=\"187\" width=\"0.56222\" height=\"0.483335\" />\n   <Char code=\"1040\" width=\"0.743329\" height=\"0.683332\" >\n      <Kern code=\"1054\" val=\"-0.025556\"/>\n      <Kern code=\"1060\" val=\"-0.025556\"/>\n      <Kern code=\"1138\" val=\"-0.025556\"/>\n      <Kern code=\"1057\" val=\"-0.025556\"/>\n      <Kern code=\"1028\" val=\"-0.025556\"/>\n      <Kern code=\"1058\" val=\"-0.076666\"/>\n      <Kern code=\"1066\" val=\"-0.076666\"/>\n      <Kern code=\"1026\" val=\"-0.076666\"/>\n      <Kern code=\"1035\" val=\"-0.076666\"/>\n      <Kern code=\"1122\" val=\"-0.076666\"/>\n      <Kern code=\"1063\" val=\"-0.076666\"/>\n      <Kern code=\"1059\" val=\"-0.076666\"/>\n      <Kern code=\"1140\" val=\"-0.1022215\"/>\n      <Kern code=\"1098\" val=\"-0.025556\"/>\n      <Kern code=\"1141\" val=\"-0.025556\"/>\n      <Kern code=\"1082\" val=\"-0.025556\"/>\n      <Kern code=\"1085\" val=\"-0.025556\"/>\n      <Kern code=\"1114\" val=\"-0.025556\"/>\n      <Kern code=\"1087\" val=\"-0.025556\"/>\n      <Kern code=\"1090\" val=\"-0.025556\"/>\n      <Kern code=\"1102\" val=\"-0.025556\"/>\n      <Kern code=\"1123\" val=\"-0.025556\"/>\n      <Kern code=\"1110\" val=\"-0.025556\"/>\n      <Kern code=\"1080\" val=\"-0.025556\"/>\n      <Kern code=\"1081\" val=\"-0.025556\"/>\n      <Kern code=\"1094\" val=\"-0.025556\"/>\n      <Kern code=\"1096\" val=\"-0.025556\"/>\n      <Kern code=\"1097\" val=\"-0.025556\"/>\n      <Kern code=\"1100\" val=\"-0.025556\"/>\n      <Kern code=\"1099\" val=\"-0.025556\"/>\n      <Kern code=\"1091\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1041\" width=\"0.703885\" height=\"0.683332\" italic=\"0.069166\" />\n   <Char code=\"1062\" width=\"0.768885\" height=\"0.683332\" depth=\"0.194445\" italic=\"0.16389\" >\n      <Lig code=\"1061\" ligCode=\"1063\"/>\n      <Lig code=\"1093\" ligCode=\"1063\"/>\n   </Char>\n   <Char code=\"1044\" width=\"0.768885\" height=\"0.683332\" depth=\"0.194445\" italic=\"0.16389\" >\n      <Lig code=\"1032\" ligCode=\"1026\"/>\n      <Lig code=\"1112\" ligCode=\"1026\"/>\n   </Char>\n   <Char code=\"1045\" width=\"0.678329\" height=\"0.683332\" italic=\"0.120277\" >\n   </Char>\n   <Char code=\"1060\" width=\"0.817774\" height=\"0.683332\" italic=\"0.0940275\" >\n      <Kern code=\"1040\" val=\"-0.025556\"/>\n      <Kern code=\"1044\" val=\"-0.025556\"/>\n      <Kern code=\"1046\" val=\"-0.025556\"/>\n      <Kern code=\"1061\" val=\"-0.025556\"/>\n      <Kern code=\"1059\" val=\"-0.025556\"/>\n      <Kern code=\"1140\" val=\"-0.025556\"/>\n      <Kern code=\"1071\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1043\" width=\"0.627218\" height=\"0.683332\" italic=\"0.133055\" >\n      <Kern code=\"1040\" val=\"-0.076666\"/>\n      <Kern code=\"1044\" val=\"-0.076666\"/>\n      <Kern code=\"1071\" val=\"-0.076666\"/>\n      <Kern code=\"1051\" val=\"-0.025556\"/>\n      <Kern code=\"1033\" val=\"-0.025556\"/>\n      <Kern code=\"1072\" val=\"-0.076666\"/>\n      <Kern code=\"1086\" val=\"-0.076666\"/>\n      <Kern code=\"1139\" val=\"-0.076666\"/>\n      <Kern code=\"1077\" val=\"-0.076666\"/>\n      <Kern code=\"1105\" val=\"-0.076666\"/>\n      <Kern code=\"1089\" val=\"-0.076666\"/>\n      <Kern code=\"1108\" val=\"-0.076666\"/>\n      <Kern code=\"1092\" val=\"-0.076666\"/>\n      <Kern code=\"1080\" val=\"-0.076666\"/>\n      <Kern code=\"1081\" val=\"-0.076666\"/>\n      <Kern code=\"1094\" val=\"-0.076666\"/>\n      <Kern code=\"1096\" val=\"-0.076666\"/>\n      <Kern code=\"1097\" val=\"-0.076666\"/>\n      <Kern code=\"1100\" val=\"-0.076666\"/>\n      <Kern code=\"1099\" val=\"-0.076666\"/>\n      <Kern code=\"1091\" val=\"-0.076666\"/>\n      <Kern code=\"1141\" val=\"-0.076666\"/>\n      <Kern code=\"1098\" val=\"-0.076666\"/>\n      <Kern code=\"1083\" val=\"-0.076666\"/>\n      <Kern code=\"1084\" val=\"-0.076666\"/>\n      <Kern code=\"1113\" val=\"-0.076666\"/>\n   </Char>\n   <Char code=\"1061\" width=\"0.743329\" height=\"0.683332\" italic=\"0.158055\" >\n      <Kern code=\"1054\" val=\"-0.025556\"/>\n      <Kern code=\"1060\" val=\"-0.025556\"/>\n      <Kern code=\"1138\" val=\"-0.025556\"/>\n      <Kern code=\"1057\" val=\"-0.025556\"/>\n      <Kern code=\"1028\" val=\"-0.025556\"/>\n      <Kern code=\"1095\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1048\" width=\"0.768885\" height=\"0.683332\" italic=\"0.16389\" >\n   </Char>\n   <Char code=\"1032\" width=\"0.524997\" height=\"0.683332\" italic=\"0.140279\" >\n   </Char>\n   <Char code=\"1050\" width=\"0.768885\" height=\"0.683332\" italic=\"0.145277\" >\n      <Lig code=\"1061\" ligCode=\"1061\"/>\n      <Lig code=\"1093\" ligCode=\"1061\"/>\n      <Kern code=\"1054\" val=\"-0.025556\"/>\n      <Kern code=\"1060\" val=\"-0.025556\"/>\n      <Kern code=\"1138\" val=\"-0.025556\"/>\n      <Kern code=\"1057\" val=\"-0.025556\"/>\n      <Kern code=\"1028\" val=\"-0.025556\"/>\n      <Kern code=\"1095\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1051\" width=\"0.768885\" height=\"0.683332\" italic=\"0.16389\" >\n      <Lig code=\"1032\" ligCode=\"1033\"/>\n      <Lig code=\"1112\" ligCode=\"1033\"/>\n   </Char>\n   <Char code=\"1052\" width=\"0.896662\" height=\"0.683332\" italic=\"0.16389\" />\n   <Char code=\"1053\" width=\"0.768885\" height=\"0.683332\" italic=\"0.16389\" >\n      <Lig code=\"1032\" ligCode=\"1034\"/>\n      <Lig code=\"1112\" ligCode=\"1034\"/>\n   </Char>\n   <Char code=\"1054\" width=\"0.766663\" height=\"0.683332\" italic=\"0.0940275\" >\n      <Kern code=\"1040\" val=\"-0.025556\"/>\n      <Kern code=\"1044\" val=\"-0.025556\"/>\n      <Kern code=\"1046\" val=\"-0.025556\"/>\n      <Kern code=\"1061\" val=\"-0.025556\"/>\n      <Kern code=\"1059\" val=\"-0.025556\"/>\n      <Kern code=\"1140\" val=\"-0.025556\"/>\n      <Kern code=\"1071\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1055\" width=\"0.768885\" height=\"0.683332\" italic=\"0.16389\" >\n   </Char>\n   <Char code=\"1063\" width=\"0.768885\" height=\"0.683332\" italic=\"0.16389\" />\n   <Char code=\"1056\" width=\"0.678329\" height=\"0.683332\" italic=\"0.10257\" >\n      <Kern code=\"1040\" val=\"-0.076666\"/>\n      <Kern code=\"1044\" val=\"-0.076666\"/>\n      <Kern code=\"1051\" val=\"-0.076666\"/>\n      <Kern code=\"1033\" val=\"-0.076666\"/>\n      <Kern code=\"1071\" val=\"-0.076666\"/>\n      <Kern code=\"1072\" val=\"-0.025556\"/>\n      <Kern code=\"1086\" val=\"-0.025556\"/>\n      <Kern code=\"1139\" val=\"-0.025556\"/>\n      <Kern code=\"1077\" val=\"-0.025556\"/>\n      <Kern code=\"1105\" val=\"-0.025556\"/>\n      <Kern code=\"1076\" val=\"-0.076666\"/>\n      <Kern code=\"1083\" val=\"-0.076666\"/>\n      <Kern code=\"1113\" val=\"-0.076666\"/>\n   </Char>\n   <Char code=\"1057\" width=\"0.715551\" height=\"0.683332\" italic=\"0.145277\" >\n      <Lig code=\"1061\" ligCode=\"1064\"/>\n      <Lig code=\"1093\" ligCode=\"1064\"/>\n   </Char>\n   <Char code=\"1058\" width=\"0.715551\" height=\"0.683332\" italic=\"0.133055\" >\n      <Lig code=\"1057\" ligCode=\"1062\"/>\n      <Lig code=\"1089\" ligCode=\"1062\"/>\n      <Kern code=\"1040\" val=\"-0.076666\"/>\n      <Kern code=\"1044\" val=\"-0.076666\"/>\n      <Kern code=\"1071\" val=\"-0.076666\"/>\n      <Kern code=\"1051\" val=\"-0.025556\"/>\n      <Kern code=\"1033\" val=\"-0.025556\"/>\n      <Kern code=\"1072\" val=\"-0.076666\"/>\n      <Kern code=\"1086\" val=\"-0.076666\"/>\n      <Kern code=\"1139\" val=\"-0.076666\"/>\n      <Kern code=\"1077\" val=\"-0.076666\"/>\n      <Kern code=\"1105\" val=\"-0.076666\"/>\n      <Kern code=\"1089\" val=\"-0.076666\"/>\n      <Kern code=\"1108\" val=\"-0.076666\"/>\n      <Kern code=\"1092\" val=\"-0.076666\"/>\n      <Kern code=\"1080\" val=\"-0.076666\"/>\n      <Kern code=\"1081\" val=\"-0.076666\"/>\n      <Kern code=\"1094\" val=\"-0.076666\"/>\n      <Kern code=\"1096\" val=\"-0.076666\"/>\n      <Kern code=\"1097\" val=\"-0.076666\"/>\n      <Kern code=\"1100\" val=\"-0.076666\"/>\n      <Kern code=\"1099\" val=\"-0.076666\"/>\n      <Kern code=\"1091\" val=\"-0.076666\"/>\n      <Kern code=\"1141\" val=\"-0.076666\"/>\n      <Kern code=\"1098\" val=\"-0.076666\"/>\n      <Kern code=\"1083\" val=\"-0.076666\"/>\n      <Kern code=\"1084\" val=\"-0.076666\"/>\n      <Kern code=\"1113\" val=\"-0.076666\"/>\n   </Char>\n   <Char code=\"1059\" width=\"0.743329\" height=\"0.683332\" italic=\"0.183611\" >\n      <Kern code=\"1040\" val=\"-0.076666\"/>\n      <Kern code=\"1071\" val=\"-0.076666\"/>\n      <Kern code=\"1044\" val=\"-0.051111\"/>\n      <Kern code=\"1051\" val=\"-0.051111\"/>\n      <Kern code=\"1033\" val=\"-0.051111\"/>\n      <Kern code=\"1054\" val=\"-0.025556\"/>\n      <Kern code=\"1060\" val=\"-0.025556\"/>\n      <Kern code=\"1138\" val=\"-0.025556\"/>\n      <Kern code=\"1057\" val=\"-0.025556\"/>\n      <Kern code=\"1028\" val=\"-0.025556\"/>\n      <Kern code=\"1072\" val=\"-0.076666\"/>\n      <Kern code=\"1086\" val=\"-0.076666\"/>\n      <Kern code=\"1139\" val=\"-0.076666\"/>\n      <Kern code=\"1077\" val=\"-0.076666\"/>\n      <Kern code=\"1105\" val=\"-0.076666\"/>\n      <Kern code=\"1089\" val=\"-0.076666\"/>\n      <Kern code=\"1108\" val=\"-0.076666\"/>\n      <Kern code=\"1080\" val=\"-0.1022215\"/>\n      <Kern code=\"1081\" val=\"-0.1022215\"/>\n      <Kern code=\"1094\" val=\"-0.1022215\"/>\n      <Kern code=\"1096\" val=\"-0.1022215\"/>\n      <Kern code=\"1097\" val=\"-0.1022215\"/>\n      <Kern code=\"1100\" val=\"-0.1022215\"/>\n      <Kern code=\"1099\" val=\"-0.1022215\"/>\n      <Kern code=\"1091\" val=\"-0.1022215\"/>\n      <Kern code=\"1141\" val=\"-0.1022215\"/>\n      <Kern code=\"1098\" val=\"-0.1022215\"/>\n      <Kern code=\"1083\" val=\"-0.1022215\"/>\n      <Kern code=\"1084\" val=\"-0.1022215\"/>\n      <Kern code=\"1113\" val=\"-0.1022215\"/>\n   </Char>\n   <Char code=\"1042\" width=\"0.703885\" height=\"0.683332\" italic=\"0.077014\" />\n   <Char code=\"1065\" width=\"1.088327\" height=\"0.683332\" depth=\"0.194445\" italic=\"0.16389\" />\n   <Char code=\"1064\" width=\"1.088327\" height=\"0.683332\" italic=\"0.16389\" >\n      <Lig code=\"1063\" ligCode=\"1065\"/>\n      <Lig code=\"1095\" ligCode=\"1065\"/>\n      <Lig code=\"1062\" ligCode=\"0\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1067\" width=\"0.947772\" height=\"0.683332\" italic=\"0.16389\" >\n      <Lig code=\"1040\" ligCode=\"1071\"/>\n      <Lig code=\"1072\" ligCode=\"1071\"/>\n      <Lig code=\"1059\" ligCode=\"1070\"/>\n      <Lig code=\"1091\" ligCode=\"1070\"/>\n   </Char>\n   <Char code=\"1047\" width=\"0.61333\" height=\"0.683332\" italic=\"0.10257\" >\n      <Lig code=\"1061\" ligCode=\"1046\"/>\n      <Lig code=\"1093\" ligCode=\"1046\"/>\n   </Char>\n   <Char code=\"1068\" width=\"0.703885\" height=\"0.683332\" italic=\"0.036629\" >\n      <Kern code=\"1046\" val=\"-0.025556\"/>\n      <Kern code=\"1061\" val=\"-0.025556\"/>\n      <Kern code=\"1054\" val=\"-0.025556\"/>\n      <Kern code=\"1060\" val=\"-0.025556\"/>\n      <Kern code=\"1138\" val=\"-0.025556\"/>\n      <Kern code=\"1057\" val=\"-0.025556\"/>\n      <Kern code=\"1028\" val=\"-0.025556\"/>\n      <Kern code=\"1058\" val=\"-0.076666\"/>\n      <Kern code=\"1066\" val=\"-0.076666\"/>\n      <Kern code=\"1026\" val=\"-0.076666\"/>\n      <Kern code=\"1035\" val=\"-0.076666\"/>\n      <Kern code=\"1122\" val=\"-0.076666\"/>\n      <Kern code=\"1063\" val=\"-0.076666\"/>\n      <Kern code=\"1059\" val=\"-0.076666\"/>\n      <Kern code=\"1140\" val=\"-0.1022215\"/>\n      <Kern code=\"1098\" val=\"-0.025556\"/>\n      <Kern code=\"1141\" val=\"-0.025556\"/>\n      <Kern code=\"1082\" val=\"-0.025556\"/>\n      <Kern code=\"1085\" val=\"-0.025556\"/>\n      <Kern code=\"1114\" val=\"-0.025556\"/>\n      <Kern code=\"1087\" val=\"-0.025556\"/>\n      <Kern code=\"1090\" val=\"-0.025556\"/>\n      <Kern code=\"1102\" val=\"-0.025556\"/>\n      <Kern code=\"1123\" val=\"-0.025556\"/>\n      <Kern code=\"1110\" val=\"-0.025556\"/>\n      <Kern code=\"1080\" val=\"-0.025556\"/>\n      <Kern code=\"1081\" val=\"-0.025556\"/>\n      <Kern code=\"1094\" val=\"-0.025556\"/>\n      <Kern code=\"1096\" val=\"-0.025556\"/>\n      <Kern code=\"1097\" val=\"-0.025556\"/>\n      <Kern code=\"1100\" val=\"-0.025556\"/>\n      <Kern code=\"1099\" val=\"-0.025556\"/>\n      <Kern code=\"1091\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1066\" width=\"0.868884\" height=\"0.683332\" italic=\"0.036629\" >\n      <Kern code=\"1046\" val=\"-0.025556\"/>\n      <Kern code=\"1061\" val=\"-0.025556\"/>\n      <Kern code=\"1054\" val=\"-0.025556\"/>\n      <Kern code=\"1060\" val=\"-0.025556\"/>\n      <Kern code=\"1138\" val=\"-0.025556\"/>\n      <Kern code=\"1057\" val=\"-0.025556\"/>\n      <Kern code=\"1028\" val=\"-0.025556\"/>\n      <Kern code=\"1058\" val=\"-0.076666\"/>\n      <Kern code=\"1066\" val=\"-0.076666\"/>\n      <Kern code=\"1026\" val=\"-0.076666\"/>\n      <Kern code=\"1035\" val=\"-0.076666\"/>\n      <Kern code=\"1122\" val=\"-0.076666\"/>\n      <Kern code=\"1063\" val=\"-0.076666\"/>\n      <Kern code=\"1059\" val=\"-0.076666\"/>\n      <Kern code=\"1140\" val=\"-0.1022215\"/>\n      <Kern code=\"1098\" val=\"-0.025556\"/>\n      <Kern code=\"1141\" val=\"-0.025556\"/>\n      <Kern code=\"1082\" val=\"-0.025556\"/>\n      <Kern code=\"1085\" val=\"-0.025556\"/>\n      <Kern code=\"1114\" val=\"-0.025556\"/>\n      <Kern code=\"1087\" val=\"-0.025556\"/>\n      <Kern code=\"1090\" val=\"-0.025556\"/>\n      <Kern code=\"1102\" val=\"-0.025556\"/>\n      <Kern code=\"1123\" val=\"-0.025556\"/>\n      <Kern code=\"1110\" val=\"-0.025556\"/>\n      <Kern code=\"1080\" val=\"-0.025556\"/>\n      <Kern code=\"1081\" val=\"-0.025556\"/>\n      <Kern code=\"1094\" val=\"-0.025556\"/>\n      <Kern code=\"1096\" val=\"-0.025556\"/>\n      <Kern code=\"1097\" val=\"-0.025556\"/>\n      <Kern code=\"1100\" val=\"-0.025556\"/>\n      <Kern code=\"1099\" val=\"-0.025556\"/>\n      <Kern code=\"1091\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1072\" width=\"0.493219\" height=\"0.430555\" italic=\"0.076714\" />\n   <Char code=\"1073\" width=\"0.475329\" height=\"0.694445\" italic=\"0.154445\" >\n      <Kern code=\"1092\" val=\"-0.051111\"/>\n      <Kern code=\"1072\" val=\"-0.051111\"/>\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1094\" width=\"0.567331\" height=\"0.430555\" depth=\"0.194445\" italic=\"0.076714\" >\n      <Lig code=\"1093\" ligCode=\"1095\"/>\n   </Char>\n   <Char code=\"1076\" width=\"0.475329\" height=\"0.694445\" italic=\"0.113861\" >\n      <Lig code=\"1112\" ligCode=\"1106\"/>\n   </Char>\n   <Char code=\"1077\" width=\"0.442108\" height=\"0.430555\" italic=\"0.075139\" >\n      <Kern code=\"1092\" val=\"-0.051111\"/>\n      <Kern code=\"1072\" val=\"-0.051111\"/>\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1092\" width=\"0.679773\" height=\"0.694445\" depth=\"0.194445\" italic=\"0.063124\" >\n      <Kern code=\"1092\" val=\"-0.051111\"/>\n      <Kern code=\"1072\" val=\"-0.051111\"/>\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1075\" width=\"0.421664\" height=\"0.430555\" italic=\"0.075139\" />\n   <Char code=\"1093\" width=\"0.540553\" height=\"0.430555\" italic=\"0.120417\" />\n   <Char code=\"1080\" width=\"0.56222\" height=\"0.430555\" italic=\"0.076714\" >\n   </Char>\n   <Char code=\"1112\" width=\"0.306665\" height=\"0.655359\" depth=\"0.194445\" italic=\"0.144673\" >\n   </Char>\n   <Char code=\"1082\" width=\"0.511108\" height=\"0.430555\" italic=\"0.107638\" >\n      <Lig code=\"1093\" ligCode=\"1093\"/>\n   </Char>\n   <Char code=\"1083\" width=\"0.536664\" height=\"0.430555\" italic=\"0.076714\" >\n      <Lig code=\"1112\" ligCode=\"1113\"/>\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n      <Kern code=\"1141\" val=\"-0.025556\"/>\n      <Kern code=\"1098\" val=\"-0.025556\"/>\n      <Kern code=\"1095\" val=\"-0.076666\"/>\n   </Char>\n   <Char code=\"1084\" width=\"0.741107\" height=\"0.430555\" italic=\"0.076714\" />\n   <Char code=\"1085\" width=\"0.56222\" height=\"0.430555\" italic=\"0.076714\" >\n      <Lig code=\"1112\" ligCode=\"1114\"/>\n   </Char>\n   <Char code=\"1086\" width=\"0.475329\" height=\"0.430555\" italic=\"0.063124\" >\n      <Kern code=\"1092\" val=\"-0.051111\"/>\n      <Kern code=\"1072\" val=\"-0.051111\"/>\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1087\" width=\"0.56222\" height=\"0.430555\" italic=\"0.076714\" >\n   </Char>\n   <Char code=\"1095\" width=\"0.536664\" height=\"0.430555\" italic=\"0.076714\" />\n   <Char code=\"1088\" width=\"0.505997\" height=\"0.430555\" depth=\"0.194445\" italic=\"0.063124\" >\n      <Kern code=\"1092\" val=\"-0.051111\"/>\n      <Kern code=\"1072\" val=\"-0.051111\"/>\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1089\" width=\"0.442108\" height=\"0.430555\" italic=\"0.056528\" >\n      <Lig code=\"1093\" ligCode=\"1096\"/>\n      <Kern code=\"1092\" val=\"-0.051111\"/>\n      <Kern code=\"1072\" val=\"-0.051111\"/>\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1090\" width=\"0.817774\" height=\"0.430555\" italic=\"0.076714\" >\n      <Lig code=\"1089\" ligCode=\"1094\"/>\n   </Char>\n   <Char code=\"1091\" width=\"0.511108\" height=\"0.430555\" depth=\"0.194445\" italic=\"0.088472\" />\n   <Char code=\"1074\" width=\"0.493219\" height=\"0.430555\" italic=\"0.075139\" />\n   <Char code=\"1097\" width=\"0.8228855\" height=\"0.430555\" depth=\"0.194445\" italic=\"0.076714\" />\n   <Char code=\"1096\" width=\"0.817774\" height=\"0.430555\" italic=\"0.076714\" >\n      <Lig code=\"1095\" ligCode=\"1097\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1099\" width=\"0.664441\" height=\"0.430555\" italic=\"0.076714\" >\n      <Lig code=\"1072\" ligCode=\"1103\"/>\n      <Lig code=\"1091\" ligCode=\"1102\"/>\n   </Char>\n   <Char code=\"1079\" width=\"0.459997\" height=\"0.430555\" italic=\"0.056528\" >\n      <Lig code=\"1093\" ligCode=\"1078\"/>\n   </Char>\n   <Char code=\"1100\" width=\"0.511108\" height=\"0.430555\" italic=\"0.063124\" >\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n      <Kern code=\"1141\" val=\"-0.025556\"/>\n      <Kern code=\"1098\" val=\"-0.025556\"/>\n      <Kern code=\"1095\" val=\"-0.076666\"/>\n      <Kern code=\"1086\" val=\"-0.025556\"/>\n      <Kern code=\"1139\" val=\"-0.025556\"/>\n      <Kern code=\"1092\" val=\"-0.025556\"/>\n      <Kern code=\"1108\" val=\"-0.025556\"/>\n   </Char>\n   <Char code=\"1098\" width=\"0.485553\" height=\"0.430555\" italic=\"0.063124\" >\n      <Kern code=\"1083\" val=\"-0.025556\"/>\n      <Kern code=\"1084\" val=\"-0.025556\"/>\n      <Kern code=\"1113\" val=\"-0.025556\"/>\n      <Kern code=\"1141\" val=\"-0.025556\"/>\n      <Kern code=\"1098\" val=\"-0.025556\"/>\n      <Kern code=\"1095\" val=\"-0.076666\"/>\n      <Kern code=\"1086\" val=\"-0.025556\"/>\n      <Kern code=\"1139\" val=\"-0.025556\"/>\n      <Kern code=\"1092\" val=\"-0.025556\"/>\n      <Kern code=\"1108\" val=\"-0.025556\"/>\n   </Char>\n</Font>\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/cyrillic/wntt10.xml",
    "content": "<Font name=\"wntt10.ttf\" id=\"wntt10\" space=\"0.524996\" xHeight=\"0.430555\" quad=\"1.049991\" unicode=\"95\" romanVersion=\"wnr10\" ssVersion=\"wnss10\">\n   <Char code=\"1034\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1033\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1039\" width=\"0.524996\" height=\"0.611112\" depth=\"0.166667\" />\n   <Char code=\"1069\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1030\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1028\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1026\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1035\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1114\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1113\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1119\" width=\"0.524996\" height=\"0.430555\" depth=\"0.13889\" />\n   <Char code=\"1101\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1110\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1108\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1106\" width=\"0.524996\" height=\"0.611112\" depth=\"0.222223\" />\n   <Char code=\"1115\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1070\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1046\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1049\" width=\"0.524996\" height=\"0.819394\" />\n   <Char code=\"1025\" width=\"0.524996\" height=\"0.819394\" />\n   <Char code=\"1140\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1138\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1029\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1071\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1102\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1078\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1081\" width=\"0.524996\" height=\"0.638838\" />\n   <Char code=\"1105\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1141\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1139\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1109\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1103\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"776\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1122\" width=\"0.524996\" height=\"0.694445\" />\n   <Char code=\"774\" width=\"0.524996\" height=\"0.638838\" />\n   <Char code=\"1123\" width=\"0.524996\" height=\"0.638838\" />\n   <Char code=\"171\" width=\"0.524996\" height=\"0.438889\" />\n   <Char code=\"305\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"187\" width=\"0.524996\" height=\"0.438889\" />\n   <Char code=\"1040\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1041\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1062\" width=\"0.524996\" height=\"0.611112\" depth=\"0.166667\" >\n      <Lig code=\"1061\" ligCode=\"1063\"/>\n      <Lig code=\"1093\" ligCode=\"1063\"/>\n   </Char>\n   <Char code=\"1044\" width=\"0.524996\" height=\"0.611112\" depth=\"0.166667\" >\n      <Lig code=\"1032\" ligCode=\"1026\"/>\n      <Lig code=\"1112\" ligCode=\"1026\"/>\n   </Char>\n   <Char code=\"1045\" width=\"0.524996\" height=\"0.611112\" >\n   </Char>\n   <Char code=\"1060\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1043\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1061\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1048\" width=\"0.524996\" height=\"0.611112\" >\n   </Char>\n   <Char code=\"1032\" width=\"0.524996\" height=\"0.611112\" >\n   </Char>\n   <Char code=\"1050\" width=\"0.524996\" height=\"0.611112\" >\n      <Lig code=\"1061\" ligCode=\"1061\"/>\n      <Lig code=\"1093\" ligCode=\"1061\"/>\n   </Char>\n   <Char code=\"1051\" width=\"0.524996\" height=\"0.611112\" >\n      <Lig code=\"1032\" ligCode=\"1033\"/>\n      <Lig code=\"1112\" ligCode=\"1033\"/>\n   </Char>\n   <Char code=\"1052\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1053\" width=\"0.524996\" height=\"0.611112\" >\n      <Lig code=\"1032\" ligCode=\"1034\"/>\n      <Lig code=\"1112\" ligCode=\"1034\"/>\n   </Char>\n   <Char code=\"1054\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1055\" width=\"0.524996\" height=\"0.611112\" >\n   </Char>\n   <Char code=\"1063\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1056\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1057\" width=\"0.524996\" height=\"0.611112\" >\n      <Lig code=\"1061\" ligCode=\"1064\"/>\n      <Lig code=\"1093\" ligCode=\"1064\"/>\n   </Char>\n   <Char code=\"1058\" width=\"0.524996\" height=\"0.611112\" >\n      <Lig code=\"1057\" ligCode=\"1062\"/>\n      <Lig code=\"1089\" ligCode=\"1062\"/>\n   </Char>\n   <Char code=\"1059\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1042\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1065\" width=\"0.524996\" height=\"0.611112\" depth=\"0.166667\" />\n   <Char code=\"1064\" width=\"0.524996\" height=\"0.611112\" >\n      <Lig code=\"1063\" ligCode=\"1065\"/>\n      <Lig code=\"1095\" ligCode=\"1065\"/>\n      <Lig code=\"1062\" ligCode=\"0\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1067\" width=\"0.524996\" height=\"0.611112\" >\n      <Lig code=\"1040\" ligCode=\"1071\"/>\n      <Lig code=\"1072\" ligCode=\"1071\"/>\n      <Lig code=\"1059\" ligCode=\"1070\"/>\n      <Lig code=\"1091\" ligCode=\"1070\"/>\n   </Char>\n   <Char code=\"1047\" width=\"0.524996\" height=\"0.611112\" >\n      <Lig code=\"1061\" ligCode=\"1046\"/>\n      <Lig code=\"1093\" ligCode=\"1046\"/>\n   </Char>\n   <Char code=\"1068\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1066\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1072\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1073\" width=\"0.524996\" height=\"0.611112\" />\n   <Char code=\"1094\" width=\"0.524996\" height=\"0.430555\" depth=\"0.13889\" >\n      <Lig code=\"1093\" ligCode=\"1095\"/>\n   </Char>\n   <Char code=\"1076\" width=\"0.524996\" height=\"0.430555\" depth=\"0.13889\" >\n      <Lig code=\"1112\" ligCode=\"1106\"/>\n   </Char>\n   <Char code=\"1077\" width=\"0.524996\" height=\"0.430555\" >\n   </Char>\n   <Char code=\"1092\" width=\"0.524996\" height=\"0.611112\" depth=\"0.222223\" />\n   <Char code=\"1075\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1093\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1080\" width=\"0.524996\" height=\"0.430555\" >\n   </Char>\n   <Char code=\"1112\" width=\"0.524996\" height=\"0.611112\" depth=\"0.222223\" >\n   </Char>\n   <Char code=\"1082\" width=\"0.524996\" height=\"0.430555\" >\n      <Lig code=\"1093\" ligCode=\"1093\"/>\n   </Char>\n   <Char code=\"1083\" width=\"0.524996\" height=\"0.430555\" >\n      <Lig code=\"1112\" ligCode=\"1113\"/>\n   </Char>\n   <Char code=\"1084\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1085\" width=\"0.524996\" height=\"0.430555\" >\n      <Lig code=\"1112\" ligCode=\"1114\"/>\n   </Char>\n   <Char code=\"1086\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1087\" width=\"0.524996\" height=\"0.430555\" >\n   </Char>\n   <Char code=\"1095\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1088\" width=\"0.524996\" height=\"0.430555\" depth=\"0.222223\" />\n   <Char code=\"1089\" width=\"0.524996\" height=\"0.430555\" >\n      <Lig code=\"1093\" ligCode=\"1096\"/>\n   </Char>\n   <Char code=\"1090\" width=\"0.524996\" height=\"0.430555\" >\n      <Lig code=\"1089\" ligCode=\"1094\"/>\n   </Char>\n   <Char code=\"1091\" width=\"0.524996\" height=\"0.430555\" depth=\"0.222223\" />\n   <Char code=\"1074\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1097\" width=\"0.524996\" height=\"0.430555\" depth=\"0.13889\" />\n   <Char code=\"1096\" width=\"0.524996\" height=\"0.430555\" >\n      <Lig code=\"1095\" ligCode=\"1097\"/>\n      <Lig code=\"1094\" ligCode=\"0\"/>\n   </Char>\n   <Char code=\"1099\" width=\"0.524996\" height=\"0.430555\" >\n      <Lig code=\"1072\" ligCode=\"1103\"/>\n      <Lig code=\"1091\" ligCode=\"1102\"/>\n   </Char>\n   <Char code=\"1079\" width=\"0.524996\" height=\"0.430555\" >\n      <Lig code=\"1093\" ligCode=\"1078\"/>\n   </Char>\n   <Char code=\"1100\" width=\"0.524996\" height=\"0.430555\" />\n   <Char code=\"1098\" width=\"0.524996\" height=\"0.430555\" />\n</Font>\n\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/fonts/licences/Knuth_License.txt",
    "content": "Knuth License\n\nThis software is copyright and you are explicitly granted a license which gives you, the \"user\" of the software, legal permission to copy, distribute and/or modify the software, so long as if you modify the software then it carry a different name from the original software.\n\nAll the same, please check the specific details of the software's license before making modifications. \n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/fonts/licences/License_for_dsrom.txt",
    "content": "License\n-------\n\nYou may use and distribute these fonts as you like.\nYou may modify these fonts as long as you do not\nrename the files to one of those names that \nDonald E. Knuth chose for the Computer Modern fonts.\n(And seriously, who would want to do that?)\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/fonts/licences/OFL.txt",
    "content": "Copyright (c) 1997, 2009, American Mathematical Society (http://www.ams.org).\nAll Rights Reserved.\n\n\"eufb10\" is a Reserved Font Name for this Font Software.\n\"eufm10\" is a Reserved Font Name for this Font Software.\n\"msam10\" is a Reserved Font Name for this Font Software.\n\"msbm10\" is a Reserved Font Name for this Font Software.\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at:\nhttp://scripts.sil.org/OFL\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded, \nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/greek/fcmbipg.xml",
    "content": "<?xml version='1.0'?>\n<Font name=\"fcmbipg.ttf\" id=\"fcmbipg\" space=\"0.355\" xHeight=\"0.451\" quad=\"1\" unicode=\"204\" ssVersion=\"fcsbpg\" ttVersion=\"fctrpg\">\n  <Char code=\"32\" width=\"0.355\" height=\"0.0\" />\n  <Char code=\"168\" width=\"0.255\" height=\"0.644\" italic=\"0.216\" />\n  <Char code=\"884\" width=\"0.224\" height=\"0.714\" italic=\"0.144\" />\n  <Char code=\"885\" width=\"0.224\" height=\"0.005\" depth=\"0.215\" />\n  <Char code=\"890\" width=\"0.128\" height=\"-0.032\" depth=\"0.211\" italic=\"0.064\" />\n  <Char code=\"900\" width=\"0.192\" height=\"0.714\" italic=\"0.15\" >\n    <Kern code=\"913\" val=\"-0.128\"/>\n    <Kern code=\"927\" val=\"-0.064\"/>\n    <Kern code=\"937\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.128\"/>\n    <Kern code=\"8188\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"901\" width=\"0.319\" height=\"0.714\" italic=\"0.206\" />\n  <Char code=\"903\" width=\"0.319\" height=\"0.446\" italic=\"0.021\" />\n  <Char code=\"912\" width=\"0.287\" height=\"0.714\" depth=\"0.006\" italic=\"0.188\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"913\" width=\"0.869\" height=\"0.7\" >\n    <Kern code=\"920\" val=\"-0.096\"/>\n    <Kern code=\"927\" val=\"-0.096\"/>\n    <Kern code=\"932\" val=\"-0.096\"/>\n    <Kern code=\"933\" val=\"-0.16\"/>\n    <Kern code=\"934\" val=\"-0.096\"/>\n    <Kern code=\"936\" val=\"-0.141\"/>\n    <Kern code=\"939\" val=\"-0.16\"/>\n    <Kern code=\"957\" val=\"-0.112\"/>\n  </Char>\n  <Char code=\"914\" width=\"0.818\" height=\"0.689\" italic=\"0.046\" />\n  <Char code=\"915\" width=\"0.691\" height=\"0.681\" italic=\"0.102\" >\n    <Kern code=\"913\" val=\"-0.153\"/>\n    <Kern code=\"916\" val=\"-0.128\"/>\n    <Kern code=\"923\" val=\"-0.141\"/>\n    <Kern code=\"8124\" val=\"-0.153\"/>\n  </Char>\n  <Char code=\"916\" width=\"0.958\" height=\"0.699\" >\n    <Kern code=\"927\" val=\"-0.038\"/>\n    <Kern code=\"933\" val=\"-0.16\"/>\n    <Kern code=\"939\" val=\"-0.16\"/>\n  </Char>\n  <Char code=\"917\" width=\"0.755\" height=\"0.681\" italic=\"0.086\" />\n  <Char code=\"918\" width=\"0.703\" height=\"0.688\" italic=\"0.115\" />\n  <Char code=\"919\" width=\"0.9\" height=\"0.687\" italic=\"0.144\" />\n  <Char code=\"920\" width=\"0.894\" height=\"0.699\" depth=\"0.011\" italic=\"0.04\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"933\" val=\"-0.096\"/>\n    <Kern code=\"939\" val=\"-0.096\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"921\" width=\"0.436\" height=\"0.687\" italic=\"0.15\" />\n  <Char code=\"922\" width=\"0.901\" height=\"0.687\" italic=\"0.119\" >\n    <Kern code=\"927\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"923\" width=\"0.805\" height=\"0.699\" >\n    <Kern code=\"927\" val=\"-0.038\"/>\n    <Kern code=\"933\" val=\"-0.115\"/>\n    <Kern code=\"939\" val=\"-0.115\"/>\n  </Char>\n  <Char code=\"924\" width=\"1.091\" height=\"0.688\" italic=\"0.143\" />\n  <Char code=\"925\" width=\"0.9\" height=\"0.687\" italic=\"0.144\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"926\" width=\"0.766\" height=\"0.676\" italic=\"0.117\" />\n  <Char code=\"927\" width=\"0.864\" height=\"0.699\" depth=\"0.011\" italic=\"0.041\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"931\" val=\"-0.064\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"928\" width=\"0.9\" height=\"0.681\" italic=\"0.142\" />\n  <Char code=\"929\" width=\"0.786\" height=\"0.687\" italic=\"0.073\" >\n    <Kern code=\"913\" val=\"-0.192\"/>\n    <Kern code=\"8124\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"931\" width=\"0.83\" height=\"0.688\" italic=\"0.089\" >\n    <Kern code=\"913\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"932\" width=\"0.8\" height=\"0.676\" italic=\"0.118\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"933\" width=\"0.805\" height=\"0.687\" italic=\"0.166\" >\n    <Kern code=\"913\" val=\"-0.16\"/>\n    <Kern code=\"916\" val=\"-0.16\"/>\n    <Kern code=\"923\" val=\"-0.16\"/>\n    <Kern code=\"8124\" val=\"-0.16\"/>\n  </Char>\n  <Char code=\"934\" width=\"0.83\" height=\"0.687\" italic=\"0.031\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"935\" width=\"0.869\" height=\"0.687\" italic=\"0.101\" />\n  <Char code=\"936\" width=\"0.894\" height=\"0.687\" italic=\"0.077\" >\n    <Kern code=\"913\" val=\"-0.141\"/>\n    <Kern code=\"8124\" val=\"-0.141\"/>\n  </Char>\n  <Char code=\"937\" width=\"0.83\" height=\"0.698\" italic=\"0.065\" />\n  <Char code=\"938\" width=\"0.436\" height=\"0.893\" italic=\"0.219\" />\n  <Char code=\"939\" width=\"0.805\" height=\"0.893\" italic=\"0.166\" >\n    <Kern code=\"913\" val=\"-0.16\"/>\n    <Kern code=\"916\" val=\"-0.16\"/>\n    <Kern code=\"923\" val=\"-0.16\"/>\n    <Kern code=\"8124\" val=\"-0.16\"/>\n  </Char>\n  <Char code=\"940\" width=\"0.639\" height=\"0.714\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"941\" width=\"0.447\" height=\"0.714\" depth=\"0.006\" italic=\"0.055\" >\n    <Kern code=\"940\" val=\"-0.032\"/>\n    <Kern code=\"945\" val=\"-0.032\"/>\n    <Kern code=\"948\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.01\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.032\"/>\n    <Kern code=\"8115\" val=\"-0.032\"/>\n    <Kern code=\"8116\" val=\"-0.032\"/>\n    <Kern code=\"8118\" val=\"-0.032\"/>\n    <Kern code=\"8119\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"942\" width=\"0.594\" height=\"0.713\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"943\" width=\"0.287\" height=\"0.714\" depth=\"0.006\" italic=\"0.101\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"944\" width=\"0.575\" height=\"0.738\" depth=\"0.005\" italic=\"0.07\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"945\" width=\"0.639\" height=\"0.452\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.109\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"993\" val=\"-0.255\"/>\n    <Kern code=\"8016\" val=\"-0.096\"/>\n    <Kern code=\"8018\" val=\"-0.096\"/>\n    <Kern code=\"8020\" val=\"-0.096\"/>\n    <Kern code=\"8021\" val=\"-0.096\"/>\n    <Kern code=\"8022\" val=\"-0.096\"/>\n    <Kern code=\"8023\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n    <Kern code=\"8166\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"946\" width=\"0.511\" height=\"0.702\" depth=\"0.212\" italic=\"0.082\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"943\" val=\"0.032\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"953\" val=\"0.032\"/>\n    <Kern code=\"959\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"0.032\"/>\n    <Kern code=\"966\" val=\"0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.064\"/>\n    <Kern code=\"972\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.064\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8054\" val=\"0.032\"/>\n    <Kern code=\"8056\" val=\"0.032\"/>\n    <Kern code=\"8150\" val=\"0.032\"/>\n  </Char>\n  <Char code=\"947\" width=\"0.575\" height=\"0.46\" depth=\"0.224\" italic=\"0.058\" >\n    <Kern code=\"967\" val=\"0.019\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"948\" width=\"0.537\" height=\"0.702\" depth=\"0.005\" italic=\"0.029\" >\n    <Kern code=\"940\" val=\"-0.032\"/>\n    <Kern code=\"945\" val=\"-0.032\"/>\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"956\" val=\"-0.051\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"960\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.019\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.032\"/>\n    <Kern code=\"8115\" val=\"-0.032\"/>\n    <Kern code=\"8116\" val=\"-0.032\"/>\n    <Kern code=\"8118\" val=\"-0.032\"/>\n    <Kern code=\"8119\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"949\" width=\"0.447\" height=\"0.451\" depth=\"0.006\" italic=\"0.051\" >\n    <Kern code=\"940\" val=\"-0.032\"/>\n    <Kern code=\"945\" val=\"-0.032\"/>\n    <Kern code=\"948\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.01\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.032\"/>\n    <Kern code=\"8115\" val=\"-0.032\"/>\n    <Kern code=\"8116\" val=\"-0.032\"/>\n    <Kern code=\"8118\" val=\"-0.032\"/>\n    <Kern code=\"8119\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"950\" width=\"0.479\" height=\"0.696\" depth=\"0.188\" italic=\"0.06\" >\n    <Kern code=\"940\" val=\"-0.096\"/>\n    <Kern code=\"941\" val=\"-0.096\"/>\n    <Kern code=\"942\" val=\"-0.096\"/>\n    <Kern code=\"945\" val=\"-0.096\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"948\" val=\"-0.064\"/>\n    <Kern code=\"949\" val=\"-0.096\"/>\n    <Kern code=\"951\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.064\"/>\n    <Kern code=\"956\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.102\"/>\n    <Kern code=\"959\" val=\"-0.096\"/>\n    <Kern code=\"960\" val=\"-0.096\"/>\n    <Kern code=\"963\" val=\"-0.096\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"966\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"969\" val=\"-0.096\"/>\n    <Kern code=\"972\" val=\"-0.096\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"974\" val=\"-0.096\"/>\n    <Kern code=\"993\" val=\"-0.064\"/>\n    <Kern code=\"8048\" val=\"-0.096\"/>\n    <Kern code=\"8050\" val=\"-0.096\"/>\n    <Kern code=\"8052\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.096\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n    <Kern code=\"8060\" val=\"-0.096\"/>\n    <Kern code=\"8114\" val=\"-0.096\"/>\n    <Kern code=\"8115\" val=\"-0.096\"/>\n    <Kern code=\"8116\" val=\"-0.096\"/>\n    <Kern code=\"8118\" val=\"-0.096\"/>\n    <Kern code=\"8119\" val=\"-0.096\"/>\n    <Kern code=\"8130\" val=\"-0.096\"/>\n    <Kern code=\"8131\" val=\"-0.096\"/>\n    <Kern code=\"8132\" val=\"-0.096\"/>\n    <Kern code=\"8134\" val=\"-0.096\"/>\n    <Kern code=\"8135\" val=\"-0.096\"/>\n    <Kern code=\"8166\" val=\"-0.096\"/>\n    <Kern code=\"8178\" val=\"-0.096\"/>\n    <Kern code=\"8179\" val=\"-0.096\"/>\n    <Kern code=\"8180\" val=\"-0.096\"/>\n    <Kern code=\"8182\" val=\"-0.096\"/>\n    <Kern code=\"8183\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"951\" width=\"0.594\" height=\"0.452\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"952\" width=\"0.591\" height=\"0.702\" depth=\"0.006\" italic=\"0.075\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"943\" val=\"0.032\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"953\" val=\"0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.064\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8054\" val=\"0.032\"/>\n    <Kern code=\"8150\" val=\"0.032\"/>\n  </Char>\n  <Char code=\"953\" width=\"0.287\" height=\"0.445\" depth=\"0.006\" italic=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"954\" width=\"0.607\" height=\"0.458\" depth=\"0.006\" italic=\"0.063\" >\n    <Kern code=\"946\" val=\"0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"955\" width=\"0.517\" height=\"0.701\" depth=\"0.006\" italic=\"0.014\" >\n    <Kern code=\"940\" val=\"-0.016\"/>\n    <Kern code=\"945\" val=\"-0.016\"/>\n    <Kern code=\"947\" val=\"-0.16\"/>\n    <Kern code=\"952\" val=\"-0.051\"/>\n    <Kern code=\"956\" val=\"0.016\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.064\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"973\" val=\"-0.064\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.016\"/>\n    <Kern code=\"8058\" val=\"-0.064\"/>\n    <Kern code=\"8114\" val=\"-0.016\"/>\n    <Kern code=\"8115\" val=\"-0.016\"/>\n    <Kern code=\"8116\" val=\"-0.016\"/>\n    <Kern code=\"8118\" val=\"-0.016\"/>\n    <Kern code=\"8119\" val=\"-0.016\"/>\n    <Kern code=\"8166\" val=\"-0.064\"/>\n  </Char>\n  <Char code=\"956\" width=\"0.575\" height=\"0.445\" depth=\"0.235\" italic=\"0.001\" >\n    <Kern code=\"940\" val=\"-0.064\"/>\n    <Kern code=\"945\" val=\"-0.064\"/>\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"950\" val=\"-0.032\"/>\n    <Kern code=\"952\" val=\"-0.07\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.064\"/>\n    <Kern code=\"966\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.067\"/>\n    <Kern code=\"969\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.064\"/>\n    <Kern code=\"974\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.255\"/>\n    <Kern code=\"8048\" val=\"-0.064\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.064\"/>\n    <Kern code=\"8060\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.064\"/>\n    <Kern code=\"8115\" val=\"-0.064\"/>\n    <Kern code=\"8116\" val=\"-0.064\"/>\n    <Kern code=\"8118\" val=\"-0.064\"/>\n    <Kern code=\"8119\" val=\"-0.064\"/>\n    <Kern code=\"8166\" val=\"-0.064\"/>\n    <Kern code=\"8178\" val=\"-0.032\"/>\n    <Kern code=\"8179\" val=\"-0.032\"/>\n    <Kern code=\"8180\" val=\"-0.032\"/>\n    <Kern code=\"8182\" val=\"-0.032\"/>\n    <Kern code=\"8183\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"957\" width=\"0.479\" height=\"0.451\" depth=\"0.01\" italic=\"0.06\" >\n    <Kern code=\"940\" val=\"-0.026\"/>\n    <Kern code=\"945\" val=\"-0.026\"/>\n    <Kern code=\"955\" val=\"-0.051\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"961\" val=\"-0.006\"/>\n    <Kern code=\"969\" val=\"0.01\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"974\" val=\"0.01\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.026\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8060\" val=\"0.01\"/>\n    <Kern code=\"8114\" val=\"-0.026\"/>\n    <Kern code=\"8115\" val=\"-0.026\"/>\n    <Kern code=\"8116\" val=\"-0.026\"/>\n    <Kern code=\"8118\" val=\"-0.026\"/>\n    <Kern code=\"8119\" val=\"-0.026\"/>\n    <Kern code=\"8178\" val=\"0.01\"/>\n    <Kern code=\"8179\" val=\"0.01\"/>\n    <Kern code=\"8180\" val=\"0.01\"/>\n    <Kern code=\"8182\" val=\"0.01\"/>\n    <Kern code=\"8183\" val=\"0.01\"/>\n  </Char>\n  <Char code=\"958\" width=\"0.479\" height=\"0.696\" depth=\"0.188\" italic=\"0.031\" >\n    <Kern code=\"940\" val=\"-0.032\"/>\n    <Kern code=\"941\" val=\"-0.064\"/>\n    <Kern code=\"945\" val=\"-0.032\"/>\n    <Kern code=\"947\" val=\"-0.045\"/>\n    <Kern code=\"949\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.064\"/>\n    <Kern code=\"963\" val=\"-0.064\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"966\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.064\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.064\"/>\n    <Kern code=\"8048\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"-0.064\"/>\n    <Kern code=\"8056\" val=\"-0.064\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.032\"/>\n    <Kern code=\"8115\" val=\"-0.032\"/>\n    <Kern code=\"8116\" val=\"-0.032\"/>\n    <Kern code=\"8118\" val=\"-0.032\"/>\n    <Kern code=\"8119\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"959\" width=\"0.543\" height=\"0.452\" depth=\"0.006\" italic=\"0.019\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"964\" val=\"-0.038\"/>\n    <Kern code=\"965\" val=\"-0.064\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.064\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8058\" val=\"-0.064\"/>\n    <Kern code=\"8166\" val=\"-0.064\"/>\n  </Char>\n  <Char code=\"960\" width=\"0.655\" height=\"0.452\" depth=\"0.006\" italic=\"0.076\" >\n    <Kern code=\"943\" val=\"0.032\"/>\n    <Kern code=\"953\" val=\"0.032\"/>\n    <Kern code=\"954\" val=\"0.032\"/>\n    <Kern code=\"959\" val=\"-0.064\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"972\" val=\"-0.064\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8054\" val=\"0.032\"/>\n    <Kern code=\"8056\" val=\"-0.064\"/>\n    <Kern code=\"8150\" val=\"0.032\"/>\n  </Char>\n  <Char code=\"961\" width=\"0.543\" height=\"0.451\" depth=\"0.212\" italic=\"0.022\" >\n    <Kern code=\"943\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.064\"/>\n    <Kern code=\"950\" val=\"0.032\"/>\n    <Kern code=\"953\" val=\"0.032\"/>\n    <Kern code=\"957\" val=\"-0.057\"/>\n    <Kern code=\"959\" val=\"0.032\"/>\n    <Kern code=\"963\" val=\"0.032\"/>\n    <Kern code=\"967\" val=\"-0.013\"/>\n    <Kern code=\"968\" val=\"0.019\"/>\n    <Kern code=\"972\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8054\" val=\"0.032\"/>\n    <Kern code=\"8056\" val=\"0.032\"/>\n    <Kern code=\"8150\" val=\"0.032\"/>\n  </Char>\n  <Char code=\"962\" width=\"0.479\" height=\"0.452\" depth=\"0.159\" italic=\"0.034\" />\n  <Char code=\"963\" width=\"0.575\" height=\"0.476\" depth=\"0.005\" italic=\"0.076\" >\n    <Kern code=\"940\" val=\"-0.051\"/>\n    <Kern code=\"945\" val=\"-0.051\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"961\" val=\"-0.032\"/>\n    <Kern code=\"969\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"974\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.051\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8060\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.051\"/>\n    <Kern code=\"8115\" val=\"-0.051\"/>\n    <Kern code=\"8116\" val=\"-0.051\"/>\n    <Kern code=\"8118\" val=\"-0.051\"/>\n    <Kern code=\"8119\" val=\"-0.051\"/>\n    <Kern code=\"8164\" val=\"-0.032\"/>\n    <Kern code=\"8165\" val=\"-0.032\"/>\n    <Kern code=\"8178\" val=\"-0.032\"/>\n    <Kern code=\"8179\" val=\"-0.032\"/>\n    <Kern code=\"8180\" val=\"-0.032\"/>\n    <Kern code=\"8182\" val=\"-0.032\"/>\n    <Kern code=\"8183\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"964\" width=\"0.527\" height=\"0.484\" depth=\"0.005\" italic=\"0.074\" >\n    <Kern code=\"940\" val=\"-0.032\"/>\n    <Kern code=\"941\" val=\"-0.032\"/>\n    <Kern code=\"945\" val=\"-0.032\"/>\n    <Kern code=\"949\" val=\"-0.032\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"969\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"974\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8060\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.032\"/>\n    <Kern code=\"8115\" val=\"-0.032\"/>\n    <Kern code=\"8116\" val=\"-0.032\"/>\n    <Kern code=\"8118\" val=\"-0.032\"/>\n    <Kern code=\"8119\" val=\"-0.032\"/>\n    <Kern code=\"8178\" val=\"-0.032\"/>\n    <Kern code=\"8179\" val=\"-0.032\"/>\n    <Kern code=\"8180\" val=\"-0.032\"/>\n    <Kern code=\"8182\" val=\"-0.032\"/>\n    <Kern code=\"8183\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"965\" width=\"0.594\" height=\"0.462\" depth=\"0.005\" italic=\"0.018\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"966\" width=\"0.671\" height=\"0.452\" depth=\"0.218\" italic=\"0.031\" >\n    <Kern code=\"942\" val=\"-0.032\"/>\n    <Kern code=\"947\" val=\"-0.064\"/>\n    <Kern code=\"951\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.045\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.064\"/>\n    <Kern code=\"967\" val=\"-0.013\"/>\n    <Kern code=\"973\" val=\"-0.064\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8052\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.064\"/>\n    <Kern code=\"8130\" val=\"-0.032\"/>\n    <Kern code=\"8131\" val=\"-0.032\"/>\n    <Kern code=\"8132\" val=\"-0.032\"/>\n    <Kern code=\"8134\" val=\"-0.064\"/>\n    <Kern code=\"8135\" val=\"-0.064\"/>\n    <Kern code=\"8166\" val=\"-0.064\"/>\n  </Char>\n  <Char code=\"967\" width=\"0.543\" height=\"0.452\" depth=\"0.217\" italic=\"0.022\" >\n    <Kern code=\"940\" val=\"-0.077\"/>\n    <Kern code=\"941\" val=\"-0.032\"/>\n    <Kern code=\"942\" val=\"-0.067\"/>\n    <Kern code=\"943\" val=\"-0.032\"/>\n    <Kern code=\"945\" val=\"-0.077\"/>\n    <Kern code=\"947\" val=\"-0.051\"/>\n    <Kern code=\"948\" val=\"-0.077\"/>\n    <Kern code=\"949\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.067\"/>\n    <Kern code=\"952\" val=\"-0.064\"/>\n    <Kern code=\"953\" val=\"-0.032\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"955\" val=\"-0.077\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"958\" val=\"-0.051\"/>\n    <Kern code=\"959\" val=\"-0.096\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"961\" val=\"-0.051\"/>\n    <Kern code=\"963\" val=\"-0.045\"/>\n    <Kern code=\"964\" val=\"-0.051\"/>\n    <Kern code=\"965\" val=\"-0.051\"/>\n    <Kern code=\"966\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"969\" val=\"-0.077\"/>\n    <Kern code=\"972\" val=\"-0.096\"/>\n    <Kern code=\"973\" val=\"-0.051\"/>\n    <Kern code=\"974\" val=\"-0.077\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.077\"/>\n    <Kern code=\"8050\" val=\"-0.032\"/>\n    <Kern code=\"8052\" val=\"-0.067\"/>\n    <Kern code=\"8054\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.096\"/>\n    <Kern code=\"8058\" val=\"-0.051\"/>\n    <Kern code=\"8060\" val=\"-0.077\"/>\n    <Kern code=\"8114\" val=\"-0.077\"/>\n    <Kern code=\"8115\" val=\"-0.077\"/>\n    <Kern code=\"8116\" val=\"-0.077\"/>\n    <Kern code=\"8118\" val=\"-0.077\"/>\n    <Kern code=\"8119\" val=\"-0.077\"/>\n    <Kern code=\"8130\" val=\"-0.067\"/>\n    <Kern code=\"8131\" val=\"-0.067\"/>\n    <Kern code=\"8132\" val=\"-0.067\"/>\n    <Kern code=\"8134\" val=\"-0.067\"/>\n    <Kern code=\"8135\" val=\"-0.067\"/>\n    <Kern code=\"8150\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.051\"/>\n    <Kern code=\"8178\" val=\"-0.077\"/>\n    <Kern code=\"8179\" val=\"-0.077\"/>\n    <Kern code=\"8180\" val=\"-0.077\"/>\n    <Kern code=\"8182\" val=\"-0.077\"/>\n    <Kern code=\"8183\" val=\"-0.077\"/>\n  </Char>\n  <Char code=\"968\" width=\"0.639\" height=\"0.454\" depth=\"0.213\" italic=\"0.042\" >\n    <Kern code=\"947\" val=\"-0.045\"/>\n    <Kern code=\"965\" val=\"-0.064\"/>\n    <Kern code=\"967\" val=\"-0.006\"/>\n    <Kern code=\"973\" val=\"-0.064\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8058\" val=\"-0.064\"/>\n    <Kern code=\"8166\" val=\"-0.064\"/>\n  </Char>\n  <Char code=\"969\" width=\"0.766\" height=\"0.446\" depth=\"0.006\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"970\" width=\"0.287\" height=\"0.638\" depth=\"0.006\" italic=\"0.192\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"971\" width=\"0.575\" height=\"0.638\" depth=\"0.005\" italic=\"0.071\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"972\" width=\"0.543\" height=\"0.714\" depth=\"0.006\" italic=\"0.019\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"964\" val=\"-0.038\"/>\n    <Kern code=\"965\" val=\"-0.064\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.064\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8058\" val=\"-0.064\"/>\n    <Kern code=\"8166\" val=\"-0.064\"/>\n  </Char>\n  <Char code=\"973\" width=\"0.575\" height=\"0.713\" depth=\"0.005\" italic=\"0.037\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"974\" width=\"0.766\" height=\"0.713\" depth=\"0.006\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"984\" width=\"0.575\" height=\"0.694\" depth=\"0.003\" italic=\"0.096\" />\n  <Char code=\"985\" width=\"0.575\" height=\"0.451\" depth=\"0.222\" italic=\"0.003\" >\n    <Kern code=\"993\" val=\"-0.255\"/>\n  </Char>\n  <Char code=\"986\" width=\"0.894\" height=\"0.677\" italic=\"0.118\" />\n  <Char code=\"987\" width=\"0.575\" height=\"0.504\" depth=\"0.106\" italic=\"0.08\" >\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"988\" width=\"0.723\" height=\"0.681\" italic=\"0.102\" />\n  <Char code=\"989\" width=\"0.575\" height=\"0.696\" italic=\"0.14\" />\n  <Char code=\"991\" width=\"0.447\" height=\"0.696\" depth=\"0.211\" italic=\"0.047\" >\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"992\" width=\"0.881\" height=\"0.705\" />\n  <Char code=\"993\" width=\"0.83\" height=\"0.701\" depth=\"0.028\" >\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"7936\" width=\"0.639\" height=\"0.695\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"7937\" width=\"0.639\" height=\"0.696\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"7938\" width=\"0.639\" height=\"0.713\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"7939\" width=\"0.639\" height=\"0.713\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"7940\" width=\"0.639\" height=\"0.713\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"7941\" width=\"0.639\" height=\"0.714\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.051\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"7942\" width=\"0.639\" height=\"0.724\" depth=\"0.006\" italic=\"0.037\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"7943\" width=\"0.639\" height=\"0.724\" depth=\"0.006\" italic=\"0.037\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"7952\" width=\"0.447\" height=\"0.695\" depth=\"0.006\" italic=\"0.051\" >\n    <Kern code=\"940\" val=\"-0.032\"/>\n    <Kern code=\"945\" val=\"-0.032\"/>\n    <Kern code=\"948\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.01\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.032\"/>\n    <Kern code=\"8115\" val=\"-0.032\"/>\n    <Kern code=\"8116\" val=\"-0.032\"/>\n    <Kern code=\"8118\" val=\"-0.032\"/>\n    <Kern code=\"8119\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7953\" width=\"0.447\" height=\"0.696\" depth=\"0.006\" italic=\"0.051\" >\n    <Kern code=\"940\" val=\"-0.032\"/>\n    <Kern code=\"945\" val=\"-0.032\"/>\n    <Kern code=\"948\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.01\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.032\"/>\n    <Kern code=\"8115\" val=\"-0.032\"/>\n    <Kern code=\"8116\" val=\"-0.032\"/>\n    <Kern code=\"8118\" val=\"-0.032\"/>\n    <Kern code=\"8119\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7954\" width=\"0.447\" height=\"0.713\" depth=\"0.006\" italic=\"0.061\" >\n    <Kern code=\"940\" val=\"-0.032\"/>\n    <Kern code=\"945\" val=\"-0.032\"/>\n    <Kern code=\"948\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.01\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.032\"/>\n    <Kern code=\"8115\" val=\"-0.032\"/>\n    <Kern code=\"8116\" val=\"-0.032\"/>\n    <Kern code=\"8118\" val=\"-0.032\"/>\n    <Kern code=\"8119\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7955\" width=\"0.447\" height=\"0.714\" depth=\"0.006\" italic=\"0.061\" >\n    <Kern code=\"940\" val=\"-0.032\"/>\n    <Kern code=\"945\" val=\"-0.032\"/>\n    <Kern code=\"948\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.01\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.032\"/>\n    <Kern code=\"8115\" val=\"-0.032\"/>\n    <Kern code=\"8116\" val=\"-0.032\"/>\n    <Kern code=\"8118\" val=\"-0.032\"/>\n    <Kern code=\"8119\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7956\" width=\"0.447\" height=\"0.714\" depth=\"0.006\" italic=\"0.102\" >\n    <Kern code=\"940\" val=\"-0.032\"/>\n    <Kern code=\"945\" val=\"-0.032\"/>\n    <Kern code=\"948\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.01\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.032\"/>\n    <Kern code=\"8115\" val=\"-0.032\"/>\n    <Kern code=\"8116\" val=\"-0.032\"/>\n    <Kern code=\"8118\" val=\"-0.032\"/>\n    <Kern code=\"8119\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7957\" width=\"0.447\" height=\"0.713\" depth=\"0.006\" italic=\"0.102\" >\n    <Kern code=\"940\" val=\"-0.032\"/>\n    <Kern code=\"945\" val=\"-0.032\"/>\n    <Kern code=\"948\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.01\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.032\"/>\n    <Kern code=\"8115\" val=\"-0.032\"/>\n    <Kern code=\"8116\" val=\"-0.032\"/>\n    <Kern code=\"8118\" val=\"-0.032\"/>\n    <Kern code=\"8119\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7968\" width=\"0.594\" height=\"0.695\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7969\" width=\"0.594\" height=\"0.696\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7970\" width=\"0.594\" height=\"0.713\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7971\" width=\"0.594\" height=\"0.714\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7972\" width=\"0.594\" height=\"0.714\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7973\" width=\"0.594\" height=\"0.713\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7974\" width=\"0.594\" height=\"0.723\" depth=\"0.214\" italic=\"0.066\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7975\" width=\"0.594\" height=\"0.723\" depth=\"0.214\" italic=\"0.066\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7984\" width=\"0.287\" height=\"0.695\" depth=\"0.006\" italic=\"0.102\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7985\" width=\"0.287\" height=\"0.696\" depth=\"0.006\" italic=\"0.072\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7986\" width=\"0.287\" height=\"0.713\" depth=\"0.006\" italic=\"0.108\" />\n  <Char code=\"7987\" width=\"0.287\" height=\"0.714\" depth=\"0.006\" italic=\"0.108\" />\n  <Char code=\"7988\" width=\"0.287\" height=\"0.714\" depth=\"0.006\" italic=\"0.149\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7989\" width=\"0.287\" height=\"0.713\" depth=\"0.006\" italic=\"0.149\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7990\" width=\"0.287\" height=\"0.724\" depth=\"0.006\" italic=\"0.2\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"7991\" width=\"0.287\" height=\"0.724\" depth=\"0.006\" italic=\"0.2\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8000\" width=\"0.543\" height=\"0.695\" depth=\"0.006\" italic=\"0.024\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"964\" val=\"-0.038\"/>\n    <Kern code=\"965\" val=\"-0.064\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.064\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8058\" val=\"-0.064\"/>\n    <Kern code=\"8166\" val=\"-0.064\"/>\n  </Char>\n  <Char code=\"8001\" width=\"0.543\" height=\"0.696\" depth=\"0.006\" italic=\"0.019\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"964\" val=\"-0.038\"/>\n    <Kern code=\"965\" val=\"-0.064\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.064\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8058\" val=\"-0.064\"/>\n    <Kern code=\"8166\" val=\"-0.064\"/>\n  </Char>\n  <Char code=\"8002\" width=\"0.543\" height=\"0.713\" depth=\"0.006\" italic=\"0.019\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"964\" val=\"-0.038\"/>\n    <Kern code=\"965\" val=\"-0.064\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.064\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8058\" val=\"-0.064\"/>\n    <Kern code=\"8166\" val=\"-0.064\"/>\n  </Char>\n  <Char code=\"8003\" width=\"0.543\" height=\"0.714\" depth=\"0.006\" italic=\"0.019\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"964\" val=\"-0.038\"/>\n    <Kern code=\"965\" val=\"-0.064\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.064\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8058\" val=\"-0.064\"/>\n    <Kern code=\"8166\" val=\"-0.064\"/>\n  </Char>\n  <Char code=\"8004\" width=\"0.543\" height=\"0.714\" depth=\"0.006\" italic=\"0.054\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"964\" val=\"-0.038\"/>\n    <Kern code=\"965\" val=\"-0.064\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.064\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8058\" val=\"-0.064\"/>\n    <Kern code=\"8166\" val=\"-0.064\"/>\n  </Char>\n  <Char code=\"8005\" width=\"0.543\" height=\"0.713\" depth=\"0.006\" italic=\"0.054\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"964\" val=\"-0.038\"/>\n    <Kern code=\"965\" val=\"-0.064\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.064\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8058\" val=\"-0.064\"/>\n    <Kern code=\"8166\" val=\"-0.064\"/>\n  </Char>\n  <Char code=\"8016\" width=\"0.575\" height=\"0.695\" depth=\"0.005\" italic=\"0.037\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"8017\" width=\"0.575\" height=\"0.696\" depth=\"0.005\" italic=\"0.037\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"8018\" width=\"0.575\" height=\"0.714\" depth=\"0.005\" italic=\"0.037\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"8019\" width=\"0.575\" height=\"0.714\" depth=\"0.005\" italic=\"0.037\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"8020\" width=\"0.575\" height=\"0.713\" depth=\"0.005\" italic=\"0.037\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"8021\" width=\"0.575\" height=\"0.714\" depth=\"0.005\" italic=\"0.037\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"8022\" width=\"0.575\" height=\"0.724\" depth=\"0.005\" italic=\"0.081\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"8023\" width=\"0.575\" height=\"0.724\" depth=\"0.005\" italic=\"0.081\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"8032\" width=\"0.766\" height=\"0.695\" depth=\"0.006\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8033\" width=\"0.766\" height=\"0.696\" depth=\"0.006\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8034\" width=\"0.766\" height=\"0.713\" depth=\"0.006\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8035\" width=\"0.766\" height=\"0.714\" depth=\"0.006\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8036\" width=\"0.766\" height=\"0.714\" depth=\"0.006\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8037\" width=\"0.766\" height=\"0.714\" depth=\"0.006\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8038\" width=\"0.766\" height=\"0.724\" depth=\"0.006\" italic=\"0.027\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8039\" width=\"0.766\" height=\"0.724\" depth=\"0.006\" italic=\"0.027\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8048\" width=\"0.639\" height=\"0.713\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8050\" width=\"0.447\" height=\"0.714\" depth=\"0.006\" italic=\"0.051\" >\n    <Kern code=\"940\" val=\"-0.032\"/>\n    <Kern code=\"945\" val=\"-0.032\"/>\n    <Kern code=\"948\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.01\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8048\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.032\"/>\n    <Kern code=\"8115\" val=\"-0.032\"/>\n    <Kern code=\"8116\" val=\"-0.032\"/>\n    <Kern code=\"8118\" val=\"-0.032\"/>\n    <Kern code=\"8119\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8052\" width=\"0.594\" height=\"0.714\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8054\" width=\"0.287\" height=\"0.714\" depth=\"0.006\" italic=\"0.018\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8056\" width=\"0.543\" height=\"0.714\" depth=\"0.006\" italic=\"0.019\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"964\" val=\"-0.038\"/>\n    <Kern code=\"965\" val=\"-0.064\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.064\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8058\" val=\"-0.064\"/>\n    <Kern code=\"8166\" val=\"-0.064\"/>\n  </Char>\n  <Char code=\"8058\" width=\"0.575\" height=\"0.714\" depth=\"0.005\" italic=\"0.037\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"8060\" width=\"0.766\" height=\"0.714\" depth=\"0.006\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8064\" width=\"0.639\" height=\"0.695\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8065\" width=\"0.639\" height=\"0.696\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8066\" width=\"0.639\" height=\"0.713\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8067\" width=\"0.639\" height=\"0.713\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8068\" width=\"0.639\" height=\"0.713\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8069\" width=\"0.639\" height=\"0.714\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.051\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8070\" width=\"0.639\" height=\"0.724\" depth=\"0.211\" italic=\"0.037\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8071\" width=\"0.639\" height=\"0.724\" depth=\"0.211\" italic=\"0.037\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8080\" width=\"0.594\" height=\"0.695\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8081\" width=\"0.594\" height=\"0.696\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8082\" width=\"0.594\" height=\"0.713\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8083\" width=\"0.594\" height=\"0.714\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8084\" width=\"0.594\" height=\"0.714\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8085\" width=\"0.594\" height=\"0.713\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8086\" width=\"0.594\" height=\"0.723\" depth=\"0.214\" italic=\"0.066\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8087\" width=\"0.594\" height=\"0.723\" depth=\"0.214\" italic=\"0.066\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8096\" width=\"0.766\" height=\"0.695\" depth=\"0.211\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8097\" width=\"0.766\" height=\"0.696\" depth=\"0.211\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8098\" width=\"0.766\" height=\"0.713\" depth=\"0.211\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8099\" width=\"0.766\" height=\"0.714\" depth=\"0.211\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8100\" width=\"0.766\" height=\"0.714\" depth=\"0.211\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8101\" width=\"0.766\" height=\"0.714\" depth=\"0.211\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8102\" width=\"0.766\" height=\"0.724\" depth=\"0.211\" italic=\"0.027\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8103\" width=\"0.766\" height=\"0.724\" depth=\"0.211\" italic=\"0.027\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8114\" width=\"0.639\" height=\"0.713\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8115\" width=\"0.639\" height=\"0.452\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.109\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"993\" val=\"-0.255\"/>\n    <Kern code=\"8016\" val=\"-0.096\"/>\n    <Kern code=\"8018\" val=\"-0.096\"/>\n    <Kern code=\"8020\" val=\"-0.096\"/>\n    <Kern code=\"8021\" val=\"-0.096\"/>\n    <Kern code=\"8022\" val=\"-0.096\"/>\n    <Kern code=\"8023\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n    <Kern code=\"8166\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8116\" width=\"0.639\" height=\"0.714\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8118\" width=\"0.639\" height=\"0.636\" depth=\"0.006\" italic=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8119\" width=\"0.639\" height=\"0.636\" depth=\"0.211\" italic=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.096\"/>\n    <Kern code=\"952\" val=\"-0.096\"/>\n    <Kern code=\"957\" val=\"-0.096\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"960\" val=\"-0.051\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"965\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.096\"/>\n    <Kern code=\"968\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.096\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8124\" width=\"0.869\" height=\"0.7\" depth=\"0.211\" >\n    <Kern code=\"920\" val=\"-0.096\"/>\n    <Kern code=\"927\" val=\"-0.096\"/>\n    <Kern code=\"932\" val=\"-0.096\"/>\n    <Kern code=\"933\" val=\"-0.16\"/>\n    <Kern code=\"934\" val=\"-0.096\"/>\n    <Kern code=\"936\" val=\"-0.141\"/>\n    <Kern code=\"939\" val=\"-0.16\"/>\n    <Kern code=\"957\" val=\"-0.112\"/>\n  </Char>\n  <Char code=\"8126\" width=\"0.255\" height=\"0.157\" depth=\"0.155\" italic=\"0.006\" />\n  <Char code=\"8127\" width=\"0.255\" height=\"0.695\" italic=\"0.168\" >\n    <Kern code=\"913\" val=\"-0.16\"/>\n    <Kern code=\"927\" val=\"-0.064\"/>\n    <Kern code=\"937\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.16\"/>\n    <Kern code=\"8188\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8128\" width=\"0.383\" height=\"0.635\" italic=\"0.16\" >\n    <Kern code=\"913\" val=\"-0.128\"/>\n    <Kern code=\"8124\" val=\"-0.128\"/>\n  </Char>\n  <Char code=\"8129\" width=\"0.511\" height=\"0.723\" italic=\"0.122\" />\n  <Char code=\"8130\" width=\"0.594\" height=\"0.714\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8131\" width=\"0.594\" height=\"0.452\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8132\" width=\"0.594\" height=\"0.713\" depth=\"0.214\" italic=\"0.026\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8134\" width=\"0.594\" height=\"0.636\" depth=\"0.214\" italic=\"0.04\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8135\" width=\"0.594\" height=\"0.636\" depth=\"0.214\" italic=\"0.04\" >\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8140\" width=\"0.9\" height=\"0.687\" depth=\"0.211\" italic=\"0.144\" />\n  <Char code=\"8141\" width=\"0.319\" height=\"0.713\" italic=\"0.125\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"927\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8142\" width=\"0.319\" height=\"0.714\" italic=\"0.166\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"927\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8143\" width=\"0.383\" height=\"0.724\" italic=\"0.186\" >\n    <Kern code=\"913\" val=\"-0.128\"/>\n    <Kern code=\"8124\" val=\"-0.128\"/>\n  </Char>\n  <Char code=\"8146\" width=\"0.287\" height=\"0.714\" depth=\"0.006\" italic=\"0.188\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8150\" width=\"0.287\" height=\"0.636\" depth=\"0.006\" italic=\"0.174\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8151\" width=\"0.287\" height=\"0.724\" depth=\"0.006\" italic=\"0.2\" >\n    <Kern code=\"947\" val=\"-0.08\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.038\"/>\n    <Kern code=\"954\" val=\"-0.064\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.096\"/>\n    <Kern code=\"967\" val=\"-0.064\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8157\" width=\"0.319\" height=\"0.714\" italic=\"0.125\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"927\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8158\" width=\"0.319\" height=\"0.713\" italic=\"0.166\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"927\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8159\" width=\"0.383\" height=\"0.724\" italic=\"0.186\" >\n    <Kern code=\"913\" val=\"-0.128\"/>\n    <Kern code=\"8124\" val=\"-0.128\"/>\n  </Char>\n  <Char code=\"8162\" width=\"0.575\" height=\"0.739\" depth=\"0.005\" italic=\"0.07\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"8164\" width=\"0.543\" height=\"0.695\" depth=\"0.212\" italic=\"0.024\" >\n    <Kern code=\"943\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.064\"/>\n    <Kern code=\"950\" val=\"0.032\"/>\n    <Kern code=\"953\" val=\"0.032\"/>\n    <Kern code=\"957\" val=\"-0.057\"/>\n    <Kern code=\"959\" val=\"0.032\"/>\n    <Kern code=\"963\" val=\"0.032\"/>\n    <Kern code=\"967\" val=\"-0.013\"/>\n    <Kern code=\"968\" val=\"0.019\"/>\n    <Kern code=\"972\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8054\" val=\"0.032\"/>\n    <Kern code=\"8056\" val=\"0.032\"/>\n    <Kern code=\"8150\" val=\"0.032\"/>\n  </Char>\n  <Char code=\"8165\" width=\"0.543\" height=\"0.696\" depth=\"0.212\" italic=\"0.022\" >\n    <Kern code=\"943\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.064\"/>\n    <Kern code=\"950\" val=\"0.032\"/>\n    <Kern code=\"953\" val=\"0.032\"/>\n    <Kern code=\"957\" val=\"-0.057\"/>\n    <Kern code=\"959\" val=\"0.032\"/>\n    <Kern code=\"963\" val=\"0.032\"/>\n    <Kern code=\"967\" val=\"-0.013\"/>\n    <Kern code=\"968\" val=\"0.019\"/>\n    <Kern code=\"972\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8054\" val=\"0.032\"/>\n    <Kern code=\"8056\" val=\"0.032\"/>\n    <Kern code=\"8150\" val=\"0.032\"/>\n  </Char>\n  <Char code=\"8166\" width=\"0.575\" height=\"0.636\" depth=\"0.005\" italic=\"0.055\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"8167\" width=\"0.575\" height=\"0.724\" depth=\"0.005\" italic=\"0.081\" >\n    <Kern code=\"952\" val=\"-0.032\"/>\n    <Kern code=\"956\" val=\"-0.013\"/>\n    <Kern code=\"957\" val=\"-0.045\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"968\" val=\"0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"8173\" width=\"0.319\" height=\"0.714\" italic=\"0.206\" />\n  <Char code=\"8175\" width=\"0.192\" height=\"0.714\" italic=\"0.131\" >\n    <Kern code=\"913\" val=\"-0.128\"/>\n    <Kern code=\"927\" val=\"-0.064\"/>\n    <Kern code=\"937\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.128\"/>\n    <Kern code=\"8188\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8178\" width=\"0.766\" height=\"0.714\" depth=\"0.211\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8179\" width=\"0.766\" height=\"0.446\" depth=\"0.211\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"993\" val=\"-0.192\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8180\" width=\"0.766\" height=\"0.713\" depth=\"0.211\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8182\" width=\"0.766\" height=\"0.635\" depth=\"0.006\" italic=\"0.001\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8183\" width=\"0.766\" height=\"0.635\" depth=\"0.211\" italic=\"0.001\" >\n    <Kern code=\"941\" val=\"0.032\"/>\n    <Kern code=\"947\" val=\"-0.128\"/>\n    <Kern code=\"949\" val=\"0.032\"/>\n    <Kern code=\"956\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.032\"/>\n    <Kern code=\"958\" val=\"0.032\"/>\n    <Kern code=\"964\" val=\"-0.054\"/>\n    <Kern code=\"965\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"973\" val=\"-0.032\"/>\n    <Kern code=\"8050\" val=\"0.032\"/>\n    <Kern code=\"8058\" val=\"-0.032\"/>\n    <Kern code=\"8166\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8188\" width=\"0.83\" height=\"0.698\" depth=\"0.211\" italic=\"0.065\" />\n  <Char code=\"8190\" width=\"0.255\" height=\"0.696\" italic=\"0.106\" >\n    <Kern code=\"913\" val=\"-0.192\"/>\n    <Kern code=\"927\" val=\"-0.064\"/>\n    <Kern code=\"937\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.192\"/>\n    <Kern code=\"8188\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8217\" width=\"0.319\" height=\"0.696\" italic=\"0.095\" >\n  </Char>\n  <Char code=\"9001\" width=\"0.473\" height=\"0.751\" depth=\"0.25\" italic=\"0.091\" />\n  <Char code=\"9002\" width=\"0.473\" height=\"0.751\" depth=\"0.25\" />\n</Font>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/greek/fcmbpg.xml",
    "content": "<?xml version='1.0'?>\n<Font name=\"fcmbpg.ttf\" id=\"fcmbpg\" space=\"0.319\" xHeight=\"0.451\" quad=\"1\" unicode=\"205\" itVersion=\"fcmbipg\" ssVersion=\"fcsbpg\" ttVersion=\"fctrpg\">\n  <Char code=\"32\" width=\"0.319\" height=\"0.0\" />\n  <Char code=\"168\" width=\"0.255\" height=\"0.645\" italic=\"0.061\" />\n  <Char code=\"884\" width=\"0.224\" height=\"0.712\" />\n  <Char code=\"885\" width=\"0.224\" height=\"0.007\" depth=\"0.216\" />\n  <Char code=\"890\" width=\"0.128\" height=\"-0.053\" depth=\"0.241\" />\n  <Char code=\"900\" width=\"0.192\" height=\"0.712\" >\n    <Kern code=\"913\" val=\"-0.128\"/>\n    <Kern code=\"927\" val=\"-0.064\"/>\n    <Kern code=\"937\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.128\"/>\n    <Kern code=\"8188\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"901\" width=\"0.319\" height=\"0.711\" italic=\"0.031\" />\n  <Char code=\"903\" width=\"0.319\" height=\"0.445\" />\n  <Char code=\"912\" width=\"0.287\" height=\"0.711\" depth=\"0.007\" italic=\"0.028\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.019\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"913\" width=\"0.869\" height=\"0.7\" >\n    <Kern code=\"920\" val=\"-0.096\"/>\n    <Kern code=\"927\" val=\"-0.096\"/>\n    <Kern code=\"932\" val=\"-0.096\"/>\n    <Kern code=\"933\" val=\"-0.16\"/>\n    <Kern code=\"934\" val=\"-0.096\"/>\n    <Kern code=\"936\" val=\"-0.141\"/>\n    <Kern code=\"939\" val=\"-0.16\"/>\n  </Char>\n  <Char code=\"914\" width=\"0.818\" height=\"0.688\" />\n  <Char code=\"915\" width=\"0.691\" height=\"0.681\" >\n    <Kern code=\"913\" val=\"-0.153\"/>\n    <Kern code=\"916\" val=\"-0.128\"/>\n    <Kern code=\"923\" val=\"-0.141\"/>\n    <Kern code=\"8124\" val=\"-0.153\"/>\n  </Char>\n  <Char code=\"916\" width=\"0.958\" height=\"0.699\" >\n    <Kern code=\"927\" val=\"-0.038\"/>\n    <Kern code=\"933\" val=\"-0.16\"/>\n    <Kern code=\"939\" val=\"-0.16\"/>\n  </Char>\n  <Char code=\"917\" width=\"0.755\" height=\"0.681\" />\n  <Char code=\"918\" width=\"0.703\" height=\"0.687\" />\n  <Char code=\"919\" width=\"0.9\" height=\"0.687\" />\n  <Char code=\"920\" width=\"0.894\" height=\"0.699\" depth=\"0.011\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"921\" width=\"0.436\" height=\"0.687\" />\n  <Char code=\"922\" width=\"0.901\" height=\"0.687\" >\n    <Kern code=\"927\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"923\" width=\"0.805\" height=\"0.7\" >\n    <Kern code=\"927\" val=\"-0.038\"/>\n    <Kern code=\"933\" val=\"-0.115\"/>\n    <Kern code=\"939\" val=\"-0.115\"/>\n  </Char>\n  <Char code=\"924\" width=\"1.091\" height=\"0.688\" />\n  <Char code=\"925\" width=\"0.9\" height=\"0.687\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"926\" width=\"0.766\" height=\"0.676\" />\n  <Char code=\"927\" width=\"0.864\" height=\"0.699\" depth=\"0.011\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"931\" val=\"-0.064\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"928\" width=\"0.9\" height=\"0.681\" />\n  <Char code=\"929\" width=\"0.786\" height=\"0.688\" >\n    <Kern code=\"913\" val=\"-0.192\"/>\n    <Kern code=\"8124\" val=\"-0.192\"/>\n  </Char>\n  <Char code=\"931\" width=\"0.83\" height=\"0.687\" >\n    <Kern code=\"913\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"932\" width=\"0.8\" height=\"0.676\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"933\" width=\"0.894\" height=\"0.699\" >\n    <Kern code=\"913\" val=\"-0.16\"/>\n    <Kern code=\"916\" val=\"-0.16\"/>\n    <Kern code=\"923\" val=\"-0.16\"/>\n    <Kern code=\"8124\" val=\"-0.16\"/>\n  </Char>\n  <Char code=\"934\" width=\"0.83\" height=\"0.687\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"935\" width=\"0.869\" height=\"0.687\" />\n  <Char code=\"936\" width=\"0.894\" height=\"0.687\" >\n    <Kern code=\"913\" val=\"-0.141\"/>\n    <Kern code=\"8124\" val=\"-0.141\"/>\n  </Char>\n  <Char code=\"937\" width=\"0.83\" height=\"0.698\" />\n  <Char code=\"938\" width=\"0.436\" height=\"0.893\" />\n  <Char code=\"939\" width=\"0.894\" height=\"0.892\" >\n    <Kern code=\"913\" val=\"-0.16\"/>\n    <Kern code=\"916\" val=\"-0.16\"/>\n    <Kern code=\"923\" val=\"-0.16\"/>\n    <Kern code=\"8124\" val=\"-0.16\"/>\n  </Char>\n  <Char code=\"940\" width=\"0.575\" height=\"0.711\" depth=\"0.006\" italic=\"0.029\" />\n  <Char code=\"941\" width=\"0.495\" height=\"0.711\" depth=\"0.01\" />\n  <Char code=\"942\" width=\"0.575\" height=\"0.712\" depth=\"0.26\" />\n  <Char code=\"943\" width=\"0.287\" height=\"0.711\" depth=\"0.007\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.031\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"944\" width=\"0.575\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"945\" width=\"0.575\" height=\"0.452\" depth=\"0.006\" italic=\"0.029\" />\n  <Char code=\"946\" width=\"0.575\" height=\"0.701\" depth=\"0.269\" />\n  <Char code=\"947\" width=\"0.639\" height=\"0.452\" depth=\"0.2\" />\n  <Char code=\"948\" width=\"0.543\" height=\"0.704\" depth=\"0.006\" />\n  <Char code=\"949\" width=\"0.495\" height=\"0.456\" depth=\"0.01\" />\n  <Char code=\"950\" width=\"0.543\" height=\"0.707\" depth=\"0.207\" />\n  <Char code=\"951\" width=\"0.575\" height=\"0.456\" depth=\"0.26\" />\n  <Char code=\"952\" width=\"0.519\" height=\"0.706\" depth=\"0.012\" />\n  <Char code=\"953\" width=\"0.287\" height=\"0.452\" depth=\"0.007\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.031\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"954\" width=\"0.607\" height=\"0.457\" depth=\"0.011\" />\n  <Char code=\"955\" width=\"0.575\" height=\"0.698\" depth=\"0.005\" />\n  <Char code=\"956\" width=\"0.622\" height=\"0.457\" depth=\"0.257\" />\n  <Char code=\"957\" width=\"0.543\" height=\"0.452\" depth=\"0.005\" />\n  <Char code=\"958\" width=\"0.543\" height=\"0.707\" depth=\"0.206\" />\n  <Char code=\"959\" width=\"0.607\" height=\"0.452\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.026\"/>\n    <Kern code=\"964\" val=\"-0.026\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"960\" width=\"0.591\" height=\"0.446\" depth=\"0.021\" />\n  <Char code=\"961\" width=\"0.543\" height=\"0.452\" depth=\"0.256\" />\n  <Char code=\"962\" width=\"0.511\" height=\"0.451\" depth=\"0.125\" />\n  <Char code=\"963\" width=\"0.655\" height=\"0.446\" depth=\"0.006\" />\n  <Char code=\"964\" width=\"0.527\" height=\"0.446\" depth=\"0.006\" >\n    <Kern code=\"940\" val=\"-0.032\"/>\n    <Kern code=\"945\" val=\"-0.032\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"969\" val=\"-0.032\"/>\n    <Kern code=\"972\" val=\"-0.032\"/>\n    <Kern code=\"974\" val=\"-0.032\"/>\n    <Kern code=\"7936\" val=\"-0.032\"/>\n    <Kern code=\"7937\" val=\"-0.032\"/>\n    <Kern code=\"7940\" val=\"-0.032\"/>\n    <Kern code=\"7941\" val=\"-0.032\"/>\n    <Kern code=\"7942\" val=\"-0.032\"/>\n    <Kern code=\"7943\" val=\"-0.032\"/>\n    <Kern code=\"8000\" val=\"-0.032\"/>\n    <Kern code=\"8001\" val=\"-0.032\"/>\n    <Kern code=\"8004\" val=\"-0.032\"/>\n    <Kern code=\"8005\" val=\"-0.032\"/>\n    <Kern code=\"8032\" val=\"-0.032\"/>\n    <Kern code=\"8033\" val=\"-0.032\"/>\n    <Kern code=\"8036\" val=\"-0.032\"/>\n    <Kern code=\"8037\" val=\"-0.032\"/>\n    <Kern code=\"8038\" val=\"-0.032\"/>\n    <Kern code=\"8039\" val=\"-0.032\"/>\n    <Kern code=\"8048\" val=\"-0.032\"/>\n    <Kern code=\"8056\" val=\"-0.032\"/>\n    <Kern code=\"8060\" val=\"-0.032\"/>\n    <Kern code=\"8064\" val=\"-0.032\"/>\n    <Kern code=\"8065\" val=\"-0.032\"/>\n    <Kern code=\"8068\" val=\"-0.032\"/>\n    <Kern code=\"8069\" val=\"-0.032\"/>\n    <Kern code=\"8070\" val=\"-0.032\"/>\n    <Kern code=\"8071\" val=\"-0.032\"/>\n    <Kern code=\"8096\" val=\"-0.032\"/>\n    <Kern code=\"8097\" val=\"-0.032\"/>\n    <Kern code=\"8100\" val=\"-0.032\"/>\n    <Kern code=\"8101\" val=\"-0.032\"/>\n    <Kern code=\"8102\" val=\"-0.032\"/>\n    <Kern code=\"8103\" val=\"-0.032\"/>\n    <Kern code=\"8114\" val=\"-0.032\"/>\n    <Kern code=\"8116\" val=\"-0.032\"/>\n    <Kern code=\"8118\" val=\"-0.032\"/>\n    <Kern code=\"8119\" val=\"-0.032\"/>\n    <Kern code=\"8178\" val=\"-0.032\"/>\n    <Kern code=\"8180\" val=\"-0.032\"/>\n    <Kern code=\"8182\" val=\"-0.032\"/>\n    <Kern code=\"8183\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"965\" width=\"0.575\" height=\"0.468\" depth=\"0.006\" />\n  <Char code=\"966\" width=\"0.671\" height=\"0.462\" depth=\"0.268\" />\n  <Char code=\"967\" width=\"0.639\" height=\"0.452\" depth=\"0.256\" />\n  <Char code=\"968\" width=\"0.671\" height=\"0.711\" depth=\"0.268\" />\n  <Char code=\"969\" width=\"0.766\" height=\"0.457\" depth=\"0.006\" />\n  <Char code=\"970\" width=\"0.287\" height=\"0.641\" depth=\"0.007\" italic=\"0.054\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.019\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"971\" width=\"0.575\" height=\"0.641\" depth=\"0.006\" />\n  <Char code=\"972\" width=\"0.607\" height=\"0.711\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.026\"/>\n    <Kern code=\"964\" val=\"-0.026\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"973\" width=\"0.575\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"974\" width=\"0.766\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"977\" width=\"0.655\" height=\"0.701\" depth=\"0.006\" />\n  <Char code=\"984\" width=\"0.575\" height=\"0.693\" depth=\"0.003\" />\n  <Char code=\"985\" width=\"0.575\" height=\"0.64\" depth=\"0.094\" />\n  <Char code=\"986\" width=\"0.894\" height=\"0.677\" />\n  <Char code=\"987\" width=\"0.575\" height=\"0.457\" depth=\"0.024\" />\n  <Char code=\"988\" width=\"0.723\" height=\"0.681\" />\n  <Char code=\"989\" width=\"0.575\" height=\"0.446\" depth=\"0.265\" />\n  <Char code=\"991\" width=\"0.447\" height=\"0.618\" depth=\"0.144\" />\n  <Char code=\"992\" width=\"0.881\" height=\"0.706\" />\n  <Char code=\"993\" width=\"0.83\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"7936\" width=\"0.575\" height=\"0.696\" depth=\"0.006\" italic=\"0.029\" />\n  <Char code=\"7937\" width=\"0.575\" height=\"0.696\" depth=\"0.006\" italic=\"0.029\" />\n  <Char code=\"7938\" width=\"0.575\" height=\"0.711\" depth=\"0.006\" italic=\"0.029\" />\n  <Char code=\"7939\" width=\"0.575\" height=\"0.711\" depth=\"0.006\" italic=\"0.029\" />\n  <Char code=\"7940\" width=\"0.575\" height=\"0.711\" depth=\"0.006\" italic=\"0.029\" />\n  <Char code=\"7941\" width=\"0.575\" height=\"0.711\" depth=\"0.006\" italic=\"0.029\" />\n  <Char code=\"7942\" width=\"0.575\" height=\"0.696\" depth=\"0.006\" italic=\"0.029\" />\n  <Char code=\"7943\" width=\"0.575\" height=\"0.696\" depth=\"0.006\" italic=\"0.029\" />\n  <Char code=\"7952\" width=\"0.495\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"7953\" width=\"0.495\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"7954\" width=\"0.495\" height=\"0.711\" depth=\"0.01\" />\n  <Char code=\"7955\" width=\"0.495\" height=\"0.711\" depth=\"0.01\" />\n  <Char code=\"7956\" width=\"0.495\" height=\"0.711\" depth=\"0.01\" />\n  <Char code=\"7957\" width=\"0.495\" height=\"0.711\" depth=\"0.01\" />\n  <Char code=\"7968\" width=\"0.575\" height=\"0.696\" depth=\"0.26\" />\n  <Char code=\"7969\" width=\"0.575\" height=\"0.696\" depth=\"0.26\" />\n  <Char code=\"7970\" width=\"0.575\" height=\"0.712\" depth=\"0.26\" />\n  <Char code=\"7971\" width=\"0.575\" height=\"0.712\" depth=\"0.26\" />\n  <Char code=\"7972\" width=\"0.575\" height=\"0.712\" depth=\"0.26\" />\n  <Char code=\"7973\" width=\"0.575\" height=\"0.712\" depth=\"0.26\" />\n  <Char code=\"7974\" width=\"0.575\" height=\"0.696\" depth=\"0.26\" />\n  <Char code=\"7975\" width=\"0.575\" height=\"0.696\" depth=\"0.26\" />\n  <Char code=\"7984\" width=\"0.287\" height=\"0.696\" depth=\"0.007\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.031\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"7985\" width=\"0.287\" height=\"0.696\" depth=\"0.007\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.031\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"7986\" width=\"0.287\" height=\"0.711\" depth=\"0.007\" />\n  <Char code=\"7987\" width=\"0.287\" height=\"0.711\" depth=\"0.007\" />\n  <Char code=\"7988\" width=\"0.287\" height=\"0.711\" depth=\"0.007\" italic=\"0.001\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.019\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"7989\" width=\"0.287\" height=\"0.711\" depth=\"0.007\" italic=\"0.001\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.019\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"7990\" width=\"0.287\" height=\"0.696\" depth=\"0.007\" italic=\"0.029\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.019\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"7991\" width=\"0.287\" height=\"0.696\" depth=\"0.007\" italic=\"0.029\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.019\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"8000\" width=\"0.607\" height=\"0.696\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.026\"/>\n    <Kern code=\"964\" val=\"-0.026\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8001\" width=\"0.607\" height=\"0.696\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.026\"/>\n    <Kern code=\"964\" val=\"-0.026\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8002\" width=\"0.607\" height=\"0.711\" depth=\"0.006\" />\n  <Char code=\"8003\" width=\"0.607\" height=\"0.711\" depth=\"0.006\" />\n  <Char code=\"8004\" width=\"0.607\" height=\"0.711\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.026\"/>\n    <Kern code=\"964\" val=\"-0.026\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8005\" width=\"0.607\" height=\"0.711\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.026\"/>\n    <Kern code=\"964\" val=\"-0.026\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8016\" width=\"0.575\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8017\" width=\"0.575\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8018\" width=\"0.575\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"8019\" width=\"0.575\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"8020\" width=\"0.575\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"8021\" width=\"0.575\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"8022\" width=\"0.575\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8023\" width=\"0.575\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8032\" width=\"0.766\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8033\" width=\"0.766\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8034\" width=\"0.766\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"8035\" width=\"0.766\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"8036\" width=\"0.766\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"8037\" width=\"0.766\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"8038\" width=\"0.766\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8039\" width=\"0.766\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8048\" width=\"0.575\" height=\"0.711\" depth=\"0.006\" italic=\"0.029\" />\n  <Char code=\"8050\" width=\"0.495\" height=\"0.711\" depth=\"0.01\" />\n  <Char code=\"8052\" width=\"0.575\" height=\"0.712\" depth=\"0.26\" />\n  <Char code=\"8054\" width=\"0.287\" height=\"0.711\" depth=\"0.007\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.019\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"8056\" width=\"0.607\" height=\"0.711\" depth=\"0.006\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"955\" val=\"-0.032\"/>\n    <Kern code=\"957\" val=\"-0.026\"/>\n    <Kern code=\"964\" val=\"-0.026\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8058\" width=\"0.575\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"8060\" width=\"0.766\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"8064\" width=\"0.575\" height=\"0.696\" depth=\"0.241\" italic=\"0.029\" />\n  <Char code=\"8065\" width=\"0.575\" height=\"0.696\" depth=\"0.241\" italic=\"0.029\" />\n  <Char code=\"8066\" width=\"0.575\" height=\"0.711\" depth=\"0.241\" italic=\"0.029\" />\n  <Char code=\"8067\" width=\"0.575\" height=\"0.711\" depth=\"0.241\" italic=\"0.029\" />\n  <Char code=\"8068\" width=\"0.575\" height=\"0.711\" depth=\"0.241\" italic=\"0.029\" />\n  <Char code=\"8069\" width=\"0.575\" height=\"0.711\" depth=\"0.241\" italic=\"0.029\" />\n  <Char code=\"8070\" width=\"0.575\" height=\"0.696\" depth=\"0.241\" italic=\"0.029\" />\n  <Char code=\"8071\" width=\"0.575\" height=\"0.696\" depth=\"0.241\" italic=\"0.029\" />\n  <Char code=\"8080\" width=\"0.575\" height=\"0.696\" depth=\"0.26\" />\n  <Char code=\"8081\" width=\"0.575\" height=\"0.696\" depth=\"0.26\" />\n  <Char code=\"8082\" width=\"0.575\" height=\"0.712\" depth=\"0.26\" />\n  <Char code=\"8083\" width=\"0.575\" height=\"0.712\" depth=\"0.26\" />\n  <Char code=\"8084\" width=\"0.575\" height=\"0.712\" depth=\"0.26\" />\n  <Char code=\"8085\" width=\"0.575\" height=\"0.712\" depth=\"0.26\" />\n  <Char code=\"8086\" width=\"0.575\" height=\"0.696\" depth=\"0.26\" />\n  <Char code=\"8087\" width=\"0.575\" height=\"0.696\" depth=\"0.26\" />\n  <Char code=\"8096\" width=\"0.766\" height=\"0.696\" depth=\"0.241\" />\n  <Char code=\"8097\" width=\"0.766\" height=\"0.696\" depth=\"0.241\" />\n  <Char code=\"8098\" width=\"0.766\" height=\"0.712\" depth=\"0.241\" />\n  <Char code=\"8099\" width=\"0.766\" height=\"0.712\" depth=\"0.241\" />\n  <Char code=\"8100\" width=\"0.766\" height=\"0.712\" depth=\"0.241\" />\n  <Char code=\"8101\" width=\"0.766\" height=\"0.712\" depth=\"0.241\" />\n  <Char code=\"8102\" width=\"0.766\" height=\"0.696\" depth=\"0.241\" />\n  <Char code=\"8103\" width=\"0.766\" height=\"0.696\" depth=\"0.241\" />\n  <Char code=\"8114\" width=\"0.575\" height=\"0.711\" depth=\"0.241\" italic=\"0.029\" />\n  <Char code=\"8115\" width=\"0.575\" height=\"0.452\" depth=\"0.241\" italic=\"0.029\" />\n  <Char code=\"8116\" width=\"0.575\" height=\"0.711\" depth=\"0.241\" italic=\"0.029\" />\n  <Char code=\"8118\" width=\"0.575\" height=\"0.641\" depth=\"0.006\" italic=\"0.029\" />\n  <Char code=\"8119\" width=\"0.575\" height=\"0.641\" depth=\"0.241\" italic=\"0.029\" />\n  <Char code=\"8124\" width=\"0.869\" height=\"0.7\" depth=\"0.241\" >\n    <Kern code=\"920\" val=\"-0.096\"/>\n    <Kern code=\"927\" val=\"-0.096\"/>\n    <Kern code=\"932\" val=\"-0.096\"/>\n    <Kern code=\"933\" val=\"-0.16\"/>\n    <Kern code=\"934\" val=\"-0.096\"/>\n    <Kern code=\"936\" val=\"-0.141\"/>\n    <Kern code=\"939\" val=\"-0.16\"/>\n  </Char>\n  <Char code=\"8126\" width=\"0.255\" height=\"0.157\" depth=\"0.155\" />\n  <Char code=\"8127\" width=\"0.255\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.16\"/>\n    <Kern code=\"927\" val=\"-0.064\"/>\n    <Kern code=\"937\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.16\"/>\n    <Kern code=\"8188\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8128\" width=\"0.383\" height=\"0.641\" >\n    <Kern code=\"913\" val=\"-0.128\"/>\n    <Kern code=\"8124\" val=\"-0.128\"/>\n  </Char>\n  <Char code=\"8129\" width=\"0.511\" height=\"0.696\" />\n  <Char code=\"8130\" width=\"0.575\" height=\"0.712\" depth=\"0.26\" />\n  <Char code=\"8131\" width=\"0.575\" height=\"0.456\" depth=\"0.26\" />\n  <Char code=\"8132\" width=\"0.575\" height=\"0.712\" depth=\"0.26\" />\n  <Char code=\"8134\" width=\"0.575\" height=\"0.641\" depth=\"0.26\" />\n  <Char code=\"8135\" width=\"0.575\" height=\"0.641\" depth=\"0.26\" />\n  <Char code=\"8140\" width=\"0.9\" height=\"0.687\" depth=\"0.241\" />\n  <Char code=\"8141\" width=\"0.319\" height=\"0.711\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"927\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8142\" width=\"0.319\" height=\"0.711\" italic=\"0.004\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"927\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8143\" width=\"0.383\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.128\"/>\n    <Kern code=\"8124\" val=\"-0.128\"/>\n  </Char>\n  <Char code=\"8146\" width=\"0.287\" height=\"0.711\" depth=\"0.007\" italic=\"0.028\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.031\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"8150\" width=\"0.287\" height=\"0.641\" depth=\"0.007\" italic=\"0.029\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.019\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"8151\" width=\"0.287\" height=\"0.696\" depth=\"0.007\" italic=\"0.029\" >\n    <Kern code=\"947\" val=\"-0.032\"/>\n    <Kern code=\"951\" val=\"-0.019\"/>\n    <Kern code=\"952\" val=\"-0.019\"/>\n    <Kern code=\"957\" val=\"-0.064\"/>\n    <Kern code=\"959\" val=\"-0.032\"/>\n    <Kern code=\"962\" val=\"-0.032\"/>\n    <Kern code=\"963\" val=\"-0.032\"/>\n    <Kern code=\"964\" val=\"-0.032\"/>\n    <Kern code=\"967\" val=\"-0.032\"/>\n    <Kern code=\"977\" val=\"-0.019\"/>\n  </Char>\n  <Char code=\"8157\" width=\"0.319\" height=\"0.711\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"927\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8158\" width=\"0.319\" height=\"0.711\" italic=\"0.004\" >\n    <Kern code=\"913\" val=\"-0.096\"/>\n    <Kern code=\"927\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.096\"/>\n  </Char>\n  <Char code=\"8159\" width=\"0.383\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.128\"/>\n    <Kern code=\"8124\" val=\"-0.128\"/>\n  </Char>\n  <Char code=\"8162\" width=\"0.575\" height=\"0.712\" depth=\"0.006\" />\n  <Char code=\"8164\" width=\"0.543\" height=\"0.696\" depth=\"0.256\" />\n  <Char code=\"8165\" width=\"0.543\" height=\"0.696\" depth=\"0.256\" />\n  <Char code=\"8166\" width=\"0.575\" height=\"0.641\" depth=\"0.006\" />\n  <Char code=\"8167\" width=\"0.575\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8173\" width=\"0.319\" height=\"0.711\" italic=\"0.031\" />\n  <Char code=\"8175\" width=\"0.192\" height=\"0.712\" >\n    <Kern code=\"913\" val=\"-0.128\"/>\n    <Kern code=\"927\" val=\"-0.064\"/>\n    <Kern code=\"937\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.128\"/>\n    <Kern code=\"8188\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8178\" width=\"0.766\" height=\"0.712\" depth=\"0.241\" />\n  <Char code=\"8179\" width=\"0.766\" height=\"0.457\" depth=\"0.241\" />\n  <Char code=\"8180\" width=\"0.766\" height=\"0.712\" depth=\"0.241\" />\n  <Char code=\"8182\" width=\"0.766\" height=\"0.641\" depth=\"0.006\" />\n  <Char code=\"8183\" width=\"0.766\" height=\"0.641\" depth=\"0.241\" />\n  <Char code=\"8188\" width=\"0.83\" height=\"0.698\" depth=\"0.241\" />\n  <Char code=\"8190\" width=\"0.255\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.192\"/>\n    <Kern code=\"927\" val=\"-0.064\"/>\n    <Kern code=\"937\" val=\"-0.032\"/>\n    <Kern code=\"8124\" val=\"-0.192\"/>\n    <Kern code=\"8188\" val=\"-0.032\"/>\n  </Char>\n  <Char code=\"8217\" width=\"0.319\" height=\"0.696\" >\n  </Char>\n  <Char code=\"9001\" width=\"0.447\" height=\"0.751\" depth=\"0.251\" />\n  <Char code=\"9002\" width=\"0.447\" height=\"0.751\" depth=\"0.251\" />\n</Font>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/greek/fcmripg.xml",
    "content": "<?xml version='1.0'?>\n<Font name=\"fcmripg.ttf\" id=\"fcmripg\" space=\"0.307\" xHeight=\"0.441\" quad=\"1\" unicode=\"204\" romanVersion=\"fcmrpg\" boldVersion=\"fcmbipg\" ssVersion=\"fcsropg\" ttVersion=\"fctrpg\">\n  <Char code=\"32\" width=\"0.307\" height=\"0.0\" />\n  <Char code=\"168\" width=\"0.222\" height=\"0.609\" italic=\"0.192\" />\n  <Char code=\"884\" width=\"0.194\" height=\"0.702\" italic=\"0.145\" />\n  <Char code=\"885\" width=\"0.194\" height=\"0.003\" depth=\"0.216\" />\n  <Char code=\"890\" width=\"0.111\" height=\"-0.043\" depth=\"0.211\" italic=\"0.009\" />\n  <Char code=\"900\" width=\"0.167\" height=\"0.702\" italic=\"0.152\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"901\" width=\"0.278\" height=\"0.702\" italic=\"0.155\" />\n  <Char code=\"903\" width=\"0.278\" height=\"0.431\" italic=\"0.017\" />\n  <Char code=\"912\" width=\"0.25\" height=\"0.702\" depth=\"0.011\" italic=\"0.13\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"913\" width=\"0.75\" height=\"0.717\" >\n    <Kern code=\"920\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.083\"/>\n    <Kern code=\"932\" val=\"-0.083\"/>\n    <Kern code=\"933\" val=\"-0.139\"/>\n    <Kern code=\"934\" val=\"-0.083\"/>\n    <Kern code=\"936\" val=\"-0.122\"/>\n    <Kern code=\"939\" val=\"-0.139\"/>\n    <Kern code=\"957\" val=\"-0.097\"/>\n  </Char>\n  <Char code=\"914\" width=\"0.708\" height=\"0.685\" italic=\"0.058\" />\n  <Char code=\"915\" width=\"0.625\" height=\"0.681\" italic=\"0.111\" >\n    <Kern code=\"913\" val=\"-0.133\"/>\n    <Kern code=\"916\" val=\"-0.111\"/>\n    <Kern code=\"923\" val=\"-0.122\"/>\n    <Kern code=\"8124\" val=\"-0.133\"/>\n  </Char>\n  <Char code=\"916\" width=\"0.833\" height=\"0.718\" >\n    <Kern code=\"927\" val=\"-0.033\"/>\n    <Kern code=\"933\" val=\"-0.139\"/>\n    <Kern code=\"939\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"917\" width=\"0.68\" height=\"0.681\" italic=\"0.098\" />\n  <Char code=\"918\" width=\"0.611\" height=\"0.685\" italic=\"0.124\" />\n  <Char code=\"919\" width=\"0.75\" height=\"0.684\" italic=\"0.148\" />\n  <Char code=\"920\" width=\"0.778\" height=\"0.706\" depth=\"0.022\" italic=\"0.049\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"933\" val=\"-0.083\"/>\n    <Kern code=\"939\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"921\" width=\"0.361\" height=\"0.684\" italic=\"0.154\" />\n  <Char code=\"922\" width=\"0.778\" height=\"0.684\" italic=\"0.126\" >\n    <Kern code=\"927\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"923\" width=\"0.694\" height=\"0.717\" >\n    <Kern code=\"927\" val=\"-0.033\"/>\n    <Kern code=\"933\" val=\"-0.1\"/>\n    <Kern code=\"939\" val=\"-0.1\"/>\n  </Char>\n  <Char code=\"924\" width=\"0.916\" height=\"0.684\" italic=\"0.144\" />\n  <Char code=\"925\" width=\"0.75\" height=\"0.684\" italic=\"0.148\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"926\" width=\"0.667\" height=\"0.678\" italic=\"0.125\" />\n  <Char code=\"927\" width=\"0.778\" height=\"0.706\" depth=\"0.022\" italic=\"0.049\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"931\" val=\"-0.056\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"928\" width=\"0.75\" height=\"0.681\" italic=\"0.148\" />\n  <Char code=\"929\" width=\"0.68\" height=\"0.685\" italic=\"0.083\" >\n    <Kern code=\"913\" val=\"-0.167\"/>\n    <Kern code=\"8124\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"931\" width=\"0.722\" height=\"0.685\" italic=\"0.099\" >\n    <Kern code=\"913\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"932\" width=\"0.722\" height=\"0.678\" italic=\"0.125\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"933\" width=\"0.694\" height=\"0.684\" italic=\"0.172\" >\n    <Kern code=\"913\" val=\"-0.139\"/>\n    <Kern code=\"916\" val=\"-0.139\"/>\n    <Kern code=\"923\" val=\"-0.139\"/>\n    <Kern code=\"8124\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"934\" width=\"0.722\" height=\"0.684\" italic=\"0.041\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"935\" width=\"0.75\" height=\"0.684\" italic=\"0.117\" />\n  <Char code=\"936\" width=\"0.778\" height=\"0.685\" italic=\"0.089\" >\n    <Kern code=\"913\" val=\"-0.122\"/>\n    <Kern code=\"8124\" val=\"-0.122\"/>\n  </Char>\n  <Char code=\"937\" width=\"0.722\" height=\"0.706\" italic=\"0.074\" />\n  <Char code=\"938\" width=\"0.361\" height=\"0.834\" italic=\"0.171\" />\n  <Char code=\"939\" width=\"0.694\" height=\"0.833\" italic=\"0.172\" >\n    <Kern code=\"913\" val=\"-0.139\"/>\n    <Kern code=\"916\" val=\"-0.139\"/>\n    <Kern code=\"923\" val=\"-0.139\"/>\n    <Kern code=\"8124\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"940\" width=\"0.555\" height=\"0.702\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"941\" width=\"0.389\" height=\"0.702\" depth=\"0.011\" italic=\"0.067\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"948\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.008\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8115\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"942\" width=\"0.517\" height=\"0.702\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"943\" width=\"0.25\" height=\"0.702\" depth=\"0.011\" italic=\"0.097\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"944\" width=\"0.5\" height=\"0.729\" depth=\"0.011\" italic=\"0.045\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"945\" width=\"0.555\" height=\"0.443\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.094\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"993\" val=\"-0.222\"/>\n    <Kern code=\"8016\" val=\"-0.083\"/>\n    <Kern code=\"8018\" val=\"-0.083\"/>\n    <Kern code=\"8020\" val=\"-0.083\"/>\n    <Kern code=\"8021\" val=\"-0.083\"/>\n    <Kern code=\"8022\" val=\"-0.083\"/>\n    <Kern code=\"8023\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n    <Kern code=\"8166\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"946\" width=\"0.444\" height=\"0.707\" depth=\"0.212\" italic=\"0.093\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"943\" val=\"0.028\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"953\" val=\"0.028\"/>\n    <Kern code=\"959\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"0.028\"/>\n    <Kern code=\"966\" val=\"0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.056\"/>\n    <Kern code=\"972\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.056\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8054\" val=\"0.028\"/>\n    <Kern code=\"8056\" val=\"0.028\"/>\n    <Kern code=\"8150\" val=\"0.028\"/>\n  </Char>\n  <Char code=\"947\" width=\"0.5\" height=\"0.447\" depth=\"0.217\" italic=\"0.067\" >\n    <Kern code=\"967\" val=\"0.017\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"948\" width=\"0.467\" height=\"0.707\" depth=\"0.01\" italic=\"0.033\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"956\" val=\"-0.044\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"960\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.017\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8115\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"949\" width=\"0.389\" height=\"0.442\" depth=\"0.011\" italic=\"0.052\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"948\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.008\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8115\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"950\" width=\"0.417\" height=\"0.696\" depth=\"0.156\" italic=\"0.082\" >\n    <Kern code=\"940\" val=\"-0.083\"/>\n    <Kern code=\"941\" val=\"-0.083\"/>\n    <Kern code=\"942\" val=\"-0.083\"/>\n    <Kern code=\"945\" val=\"-0.083\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"948\" val=\"-0.056\"/>\n    <Kern code=\"949\" val=\"-0.083\"/>\n    <Kern code=\"951\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.056\"/>\n    <Kern code=\"956\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.089\"/>\n    <Kern code=\"959\" val=\"-0.083\"/>\n    <Kern code=\"960\" val=\"-0.083\"/>\n    <Kern code=\"963\" val=\"-0.083\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"966\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"969\" val=\"-0.083\"/>\n    <Kern code=\"972\" val=\"-0.083\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"974\" val=\"-0.083\"/>\n    <Kern code=\"993\" val=\"-0.056\"/>\n    <Kern code=\"8048\" val=\"-0.083\"/>\n    <Kern code=\"8050\" val=\"-0.083\"/>\n    <Kern code=\"8052\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.083\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n    <Kern code=\"8060\" val=\"-0.083\"/>\n    <Kern code=\"8114\" val=\"-0.083\"/>\n    <Kern code=\"8115\" val=\"-0.083\"/>\n    <Kern code=\"8116\" val=\"-0.083\"/>\n    <Kern code=\"8118\" val=\"-0.083\"/>\n    <Kern code=\"8119\" val=\"-0.083\"/>\n    <Kern code=\"8130\" val=\"-0.083\"/>\n    <Kern code=\"8131\" val=\"-0.083\"/>\n    <Kern code=\"8132\" val=\"-0.083\"/>\n    <Kern code=\"8134\" val=\"-0.083\"/>\n    <Kern code=\"8135\" val=\"-0.083\"/>\n    <Kern code=\"8166\" val=\"-0.083\"/>\n    <Kern code=\"8178\" val=\"-0.083\"/>\n    <Kern code=\"8179\" val=\"-0.083\"/>\n    <Kern code=\"8180\" val=\"-0.083\"/>\n    <Kern code=\"8182\" val=\"-0.083\"/>\n    <Kern code=\"8183\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"951\" width=\"0.517\" height=\"0.443\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"952\" width=\"0.514\" height=\"0.707\" depth=\"0.011\" italic=\"0.065\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"943\" val=\"0.028\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"953\" val=\"0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.056\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8054\" val=\"0.028\"/>\n    <Kern code=\"8150\" val=\"0.028\"/>\n  </Char>\n  <Char code=\"953\" width=\"0.25\" height=\"0.431\" depth=\"0.011\" italic=\"0.002\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"954\" width=\"0.528\" height=\"0.447\" depth=\"0.011\" italic=\"0.053\" >\n    <Kern code=\"946\" val=\"0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"955\" width=\"0.45\" height=\"0.707\" depth=\"0.011\" italic=\"0.011\" >\n    <Kern code=\"940\" val=\"-0.014\"/>\n    <Kern code=\"945\" val=\"-0.014\"/>\n    <Kern code=\"947\" val=\"-0.139\"/>\n    <Kern code=\"952\" val=\"-0.044\"/>\n    <Kern code=\"956\" val=\"0.014\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.056\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"973\" val=\"-0.056\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.014\"/>\n    <Kern code=\"8058\" val=\"-0.056\"/>\n    <Kern code=\"8114\" val=\"-0.014\"/>\n    <Kern code=\"8115\" val=\"-0.014\"/>\n    <Kern code=\"8116\" val=\"-0.014\"/>\n    <Kern code=\"8118\" val=\"-0.014\"/>\n    <Kern code=\"8119\" val=\"-0.014\"/>\n    <Kern code=\"8166\" val=\"-0.056\"/>\n  </Char>\n  <Char code=\"956\" width=\"0.5\" height=\"0.432\" depth=\"0.222\" italic=\"0.002\" >\n    <Kern code=\"940\" val=\"-0.056\"/>\n    <Kern code=\"945\" val=\"-0.056\"/>\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"950\" val=\"-0.028\"/>\n    <Kern code=\"952\" val=\"-0.061\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.056\"/>\n    <Kern code=\"966\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.058\"/>\n    <Kern code=\"969\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.056\"/>\n    <Kern code=\"974\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.222\"/>\n    <Kern code=\"8048\" val=\"-0.056\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.056\"/>\n    <Kern code=\"8060\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.056\"/>\n    <Kern code=\"8115\" val=\"-0.056\"/>\n    <Kern code=\"8116\" val=\"-0.056\"/>\n    <Kern code=\"8118\" val=\"-0.056\"/>\n    <Kern code=\"8119\" val=\"-0.056\"/>\n    <Kern code=\"8166\" val=\"-0.056\"/>\n    <Kern code=\"8178\" val=\"-0.028\"/>\n    <Kern code=\"8179\" val=\"-0.028\"/>\n    <Kern code=\"8180\" val=\"-0.028\"/>\n    <Kern code=\"8182\" val=\"-0.028\"/>\n    <Kern code=\"8183\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"957\" width=\"0.417\" height=\"0.442\" depth=\"0.02\" italic=\"0.068\" >\n    <Kern code=\"940\" val=\"-0.022\"/>\n    <Kern code=\"945\" val=\"-0.022\"/>\n    <Kern code=\"955\" val=\"-0.044\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"961\" val=\"-0.006\"/>\n    <Kern code=\"969\" val=\"0.008\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"974\" val=\"0.008\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.022\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8060\" val=\"0.008\"/>\n    <Kern code=\"8114\" val=\"-0.022\"/>\n    <Kern code=\"8115\" val=\"-0.022\"/>\n    <Kern code=\"8116\" val=\"-0.022\"/>\n    <Kern code=\"8118\" val=\"-0.022\"/>\n    <Kern code=\"8119\" val=\"-0.022\"/>\n    <Kern code=\"8178\" val=\"0.008\"/>\n    <Kern code=\"8179\" val=\"0.008\"/>\n    <Kern code=\"8180\" val=\"0.008\"/>\n    <Kern code=\"8182\" val=\"0.008\"/>\n    <Kern code=\"8183\" val=\"0.008\"/>\n  </Char>\n  <Char code=\"958\" width=\"0.417\" height=\"0.696\" depth=\"0.155\" italic=\"0.036\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"941\" val=\"-0.056\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"947\" val=\"-0.039\"/>\n    <Kern code=\"949\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.056\"/>\n    <Kern code=\"963\" val=\"-0.056\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"966\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.056\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.056\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"-0.056\"/>\n    <Kern code=\"8056\" val=\"-0.056\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8115\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"959\" width=\"0.472\" height=\"0.443\" depth=\"0.011\" italic=\"0.025\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"964\" val=\"-0.033\"/>\n    <Kern code=\"965\" val=\"-0.056\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.056\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8058\" val=\"-0.056\"/>\n    <Kern code=\"8166\" val=\"-0.056\"/>\n  </Char>\n  <Char code=\"960\" width=\"0.569\" height=\"0.434\" depth=\"0.011\" italic=\"0.068\" >\n    <Kern code=\"943\" val=\"0.028\"/>\n    <Kern code=\"953\" val=\"0.028\"/>\n    <Kern code=\"954\" val=\"0.028\"/>\n    <Kern code=\"959\" val=\"-0.056\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"972\" val=\"-0.056\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8054\" val=\"0.028\"/>\n    <Kern code=\"8056\" val=\"-0.056\"/>\n    <Kern code=\"8150\" val=\"0.028\"/>\n  </Char>\n  <Char code=\"961\" width=\"0.472\" height=\"0.442\" depth=\"0.212\" italic=\"0.028\" >\n    <Kern code=\"943\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.056\"/>\n    <Kern code=\"950\" val=\"0.028\"/>\n    <Kern code=\"953\" val=\"0.028\"/>\n    <Kern code=\"957\" val=\"-0.05\"/>\n    <Kern code=\"959\" val=\"0.028\"/>\n    <Kern code=\"963\" val=\"0.028\"/>\n    <Kern code=\"967\" val=\"-0.011\"/>\n    <Kern code=\"968\" val=\"0.017\"/>\n    <Kern code=\"972\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8054\" val=\"0.028\"/>\n    <Kern code=\"8056\" val=\"0.028\"/>\n    <Kern code=\"8150\" val=\"0.028\"/>\n  </Char>\n  <Char code=\"962\" width=\"0.417\" height=\"0.443\" depth=\"0.13\" italic=\"0.048\" />\n  <Char code=\"963\" width=\"0.5\" height=\"0.451\" depth=\"0.011\" italic=\"0.081\" >\n    <Kern code=\"940\" val=\"-0.044\"/>\n    <Kern code=\"945\" val=\"-0.044\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"961\" val=\"-0.028\"/>\n    <Kern code=\"969\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"974\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.044\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8060\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.044\"/>\n    <Kern code=\"8115\" val=\"-0.044\"/>\n    <Kern code=\"8116\" val=\"-0.044\"/>\n    <Kern code=\"8118\" val=\"-0.044\"/>\n    <Kern code=\"8119\" val=\"-0.044\"/>\n    <Kern code=\"8164\" val=\"-0.028\"/>\n    <Kern code=\"8165\" val=\"-0.028\"/>\n    <Kern code=\"8178\" val=\"-0.028\"/>\n    <Kern code=\"8179\" val=\"-0.028\"/>\n    <Kern code=\"8180\" val=\"-0.028\"/>\n    <Kern code=\"8182\" val=\"-0.028\"/>\n    <Kern code=\"8183\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"964\" width=\"0.458\" height=\"0.454\" depth=\"0.011\" italic=\"0.075\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"941\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"949\" val=\"-0.028\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"969\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"974\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8060\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8115\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8178\" val=\"-0.028\"/>\n    <Kern code=\"8179\" val=\"-0.028\"/>\n    <Kern code=\"8180\" val=\"-0.028\"/>\n    <Kern code=\"8182\" val=\"-0.028\"/>\n    <Kern code=\"8183\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"965\" width=\"0.517\" height=\"0.443\" depth=\"0.011\" italic=\"0.024\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"966\" width=\"0.583\" height=\"0.443\" depth=\"0.223\" italic=\"0.037\" >\n    <Kern code=\"942\" val=\"-0.028\"/>\n    <Kern code=\"947\" val=\"-0.056\"/>\n    <Kern code=\"951\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.039\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.056\"/>\n    <Kern code=\"967\" val=\"-0.011\"/>\n    <Kern code=\"973\" val=\"-0.056\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8052\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.056\"/>\n    <Kern code=\"8130\" val=\"-0.028\"/>\n    <Kern code=\"8131\" val=\"-0.028\"/>\n    <Kern code=\"8132\" val=\"-0.028\"/>\n    <Kern code=\"8134\" val=\"-0.056\"/>\n    <Kern code=\"8135\" val=\"-0.056\"/>\n    <Kern code=\"8166\" val=\"-0.056\"/>\n  </Char>\n  <Char code=\"967\" width=\"0.472\" height=\"0.442\" depth=\"0.223\" italic=\"0.031\" >\n    <Kern code=\"940\" val=\"-0.067\"/>\n    <Kern code=\"941\" val=\"-0.028\"/>\n    <Kern code=\"942\" val=\"-0.058\"/>\n    <Kern code=\"943\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.067\"/>\n    <Kern code=\"947\" val=\"-0.044\"/>\n    <Kern code=\"948\" val=\"-0.067\"/>\n    <Kern code=\"949\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.058\"/>\n    <Kern code=\"952\" val=\"-0.056\"/>\n    <Kern code=\"953\" val=\"-0.028\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"955\" val=\"-0.067\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"958\" val=\"-0.044\"/>\n    <Kern code=\"959\" val=\"-0.083\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"961\" val=\"-0.044\"/>\n    <Kern code=\"963\" val=\"-0.039\"/>\n    <Kern code=\"964\" val=\"-0.044\"/>\n    <Kern code=\"965\" val=\"-0.044\"/>\n    <Kern code=\"966\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"969\" val=\"-0.067\"/>\n    <Kern code=\"972\" val=\"-0.083\"/>\n    <Kern code=\"973\" val=\"-0.044\"/>\n    <Kern code=\"974\" val=\"-0.067\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.067\"/>\n    <Kern code=\"8050\" val=\"-0.028\"/>\n    <Kern code=\"8052\" val=\"-0.058\"/>\n    <Kern code=\"8054\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.083\"/>\n    <Kern code=\"8058\" val=\"-0.044\"/>\n    <Kern code=\"8060\" val=\"-0.067\"/>\n    <Kern code=\"8114\" val=\"-0.067\"/>\n    <Kern code=\"8115\" val=\"-0.067\"/>\n    <Kern code=\"8116\" val=\"-0.067\"/>\n    <Kern code=\"8118\" val=\"-0.067\"/>\n    <Kern code=\"8119\" val=\"-0.067\"/>\n    <Kern code=\"8130\" val=\"-0.058\"/>\n    <Kern code=\"8131\" val=\"-0.058\"/>\n    <Kern code=\"8132\" val=\"-0.058\"/>\n    <Kern code=\"8134\" val=\"-0.058\"/>\n    <Kern code=\"8135\" val=\"-0.058\"/>\n    <Kern code=\"8150\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.044\"/>\n    <Kern code=\"8178\" val=\"-0.067\"/>\n    <Kern code=\"8179\" val=\"-0.067\"/>\n    <Kern code=\"8180\" val=\"-0.067\"/>\n    <Kern code=\"8182\" val=\"-0.067\"/>\n    <Kern code=\"8183\" val=\"-0.067\"/>\n  </Char>\n  <Char code=\"968\" width=\"0.555\" height=\"0.444\" depth=\"0.226\" italic=\"0.045\" >\n    <Kern code=\"947\" val=\"-0.039\"/>\n    <Kern code=\"965\" val=\"-0.056\"/>\n    <Kern code=\"967\" val=\"-0.006\"/>\n    <Kern code=\"973\" val=\"-0.056\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8058\" val=\"-0.056\"/>\n    <Kern code=\"8166\" val=\"-0.056\"/>\n  </Char>\n  <Char code=\"969\" width=\"0.667\" height=\"0.432\" depth=\"0.011\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"970\" width=\"0.25\" height=\"0.637\" depth=\"0.011\" italic=\"0.147\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"971\" width=\"0.5\" height=\"0.637\" depth=\"0.011\" italic=\"0.06\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"972\" width=\"0.472\" height=\"0.702\" depth=\"0.011\" italic=\"0.027\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"964\" val=\"-0.033\"/>\n    <Kern code=\"965\" val=\"-0.056\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.056\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8058\" val=\"-0.056\"/>\n    <Kern code=\"8166\" val=\"-0.056\"/>\n  </Char>\n  <Char code=\"973\" width=\"0.5\" height=\"0.702\" depth=\"0.011\" italic=\"0.041\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"974\" width=\"0.667\" height=\"0.702\" depth=\"0.011\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"984\" width=\"0.5\" height=\"0.695\" depth=\"0.001\" italic=\"0.103\" />\n  <Char code=\"985\" width=\"0.5\" height=\"0.443\" depth=\"0.217\" italic=\"0.011\" >\n    <Kern code=\"993\" val=\"-0.222\"/>\n  </Char>\n  <Char code=\"986\" width=\"0.778\" height=\"0.679\" italic=\"0.125\" />\n  <Char code=\"987\" width=\"0.5\" height=\"0.496\" depth=\"0.106\" italic=\"0.086\" >\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"988\" width=\"0.653\" height=\"0.681\" italic=\"0.111\" />\n  <Char code=\"989\" width=\"0.5\" height=\"0.695\" italic=\"0.146\" />\n  <Char code=\"991\" width=\"0.389\" height=\"0.695\" depth=\"0.211\" italic=\"0.046\" >\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"992\" width=\"0.766\" height=\"0.695\" />\n  <Char code=\"993\" width=\"0.722\" height=\"0.706\" depth=\"0.029\" >\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"7936\" width=\"0.555\" height=\"0.696\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"7937\" width=\"0.555\" height=\"0.696\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"7938\" width=\"0.555\" height=\"0.702\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"7939\" width=\"0.555\" height=\"0.702\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"7940\" width=\"0.555\" height=\"0.702\" depth=\"0.011\" italic=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"7941\" width=\"0.555\" height=\"0.702\" depth=\"0.011\" italic=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.044\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"7942\" width=\"0.555\" height=\"0.723\" depth=\"0.011\" italic=\"0.055\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"7943\" width=\"0.555\" height=\"0.723\" depth=\"0.011\" italic=\"0.055\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"7952\" width=\"0.389\" height=\"0.696\" depth=\"0.011\" italic=\"0.052\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"948\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.008\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8115\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7953\" width=\"0.389\" height=\"0.696\" depth=\"0.011\" italic=\"0.052\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"948\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.008\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8115\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7954\" width=\"0.389\" height=\"0.702\" depth=\"0.011\" italic=\"0.073\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"948\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.008\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8115\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7955\" width=\"0.389\" height=\"0.702\" depth=\"0.011\" italic=\"0.073\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"948\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.008\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8115\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7956\" width=\"0.389\" height=\"0.702\" depth=\"0.011\" italic=\"0.117\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"948\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.008\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8115\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7957\" width=\"0.389\" height=\"0.702\" depth=\"0.011\" italic=\"0.117\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"948\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.008\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8115\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7968\" width=\"0.517\" height=\"0.696\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7969\" width=\"0.517\" height=\"0.696\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7970\" width=\"0.517\" height=\"0.702\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7971\" width=\"0.517\" height=\"0.702\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7972\" width=\"0.517\" height=\"0.702\" depth=\"0.214\" italic=\"0.041\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7973\" width=\"0.517\" height=\"0.702\" depth=\"0.214\" italic=\"0.041\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7974\" width=\"0.517\" height=\"0.723\" depth=\"0.214\" italic=\"0.085\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7975\" width=\"0.517\" height=\"0.723\" depth=\"0.214\" italic=\"0.085\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7984\" width=\"0.25\" height=\"0.696\" depth=\"0.011\" italic=\"0.107\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7985\" width=\"0.25\" height=\"0.696\" depth=\"0.011\" italic=\"0.065\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7986\" width=\"0.25\" height=\"0.702\" depth=\"0.011\" italic=\"0.102\" />\n  <Char code=\"7987\" width=\"0.25\" height=\"0.702\" depth=\"0.011\" italic=\"0.102\" />\n  <Char code=\"7988\" width=\"0.25\" height=\"0.702\" depth=\"0.011\" italic=\"0.148\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7989\" width=\"0.25\" height=\"0.702\" depth=\"0.011\" italic=\"0.148\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7990\" width=\"0.25\" height=\"0.723\" depth=\"0.011\" italic=\"0.191\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7991\" width=\"0.25\" height=\"0.723\" depth=\"0.011\" italic=\"0.191\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8000\" width=\"0.472\" height=\"0.696\" depth=\"0.011\" italic=\"0.05\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"964\" val=\"-0.033\"/>\n    <Kern code=\"965\" val=\"-0.056\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.056\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8058\" val=\"-0.056\"/>\n    <Kern code=\"8166\" val=\"-0.056\"/>\n  </Char>\n  <Char code=\"8001\" width=\"0.472\" height=\"0.696\" depth=\"0.011\" italic=\"0.025\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"964\" val=\"-0.033\"/>\n    <Kern code=\"965\" val=\"-0.056\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.056\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8058\" val=\"-0.056\"/>\n    <Kern code=\"8166\" val=\"-0.056\"/>\n  </Char>\n  <Char code=\"8002\" width=\"0.472\" height=\"0.702\" depth=\"0.011\" italic=\"0.031\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"964\" val=\"-0.033\"/>\n    <Kern code=\"965\" val=\"-0.056\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.056\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8058\" val=\"-0.056\"/>\n    <Kern code=\"8166\" val=\"-0.056\"/>\n  </Char>\n  <Char code=\"8003\" width=\"0.472\" height=\"0.702\" depth=\"0.011\" italic=\"0.031\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"964\" val=\"-0.033\"/>\n    <Kern code=\"965\" val=\"-0.056\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.056\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8058\" val=\"-0.056\"/>\n    <Kern code=\"8166\" val=\"-0.056\"/>\n  </Char>\n  <Char code=\"8004\" width=\"0.472\" height=\"0.701\" depth=\"0.011\" italic=\"0.077\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"964\" val=\"-0.033\"/>\n    <Kern code=\"965\" val=\"-0.056\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.056\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8058\" val=\"-0.056\"/>\n    <Kern code=\"8166\" val=\"-0.056\"/>\n  </Char>\n  <Char code=\"8005\" width=\"0.472\" height=\"0.701\" depth=\"0.011\" italic=\"0.077\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"964\" val=\"-0.033\"/>\n    <Kern code=\"965\" val=\"-0.056\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.056\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8058\" val=\"-0.056\"/>\n    <Kern code=\"8166\" val=\"-0.056\"/>\n  </Char>\n  <Char code=\"8016\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.041\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"8017\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.041\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"8018\" width=\"0.5\" height=\"0.702\" depth=\"0.011\" italic=\"0.041\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"8019\" width=\"0.5\" height=\"0.702\" depth=\"0.011\" italic=\"0.041\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"8020\" width=\"0.5\" height=\"0.702\" depth=\"0.011\" italic=\"0.059\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"8021\" width=\"0.5\" height=\"0.702\" depth=\"0.011\" italic=\"0.059\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"8022\" width=\"0.5\" height=\"0.723\" depth=\"0.011\" italic=\"0.103\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"8023\" width=\"0.5\" height=\"0.723\" depth=\"0.011\" italic=\"0.103\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"8032\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8033\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8034\" width=\"0.667\" height=\"0.702\" depth=\"0.011\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8035\" width=\"0.667\" height=\"0.702\" depth=\"0.011\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8036\" width=\"0.667\" height=\"0.702\" depth=\"0.011\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8037\" width=\"0.667\" height=\"0.702\" depth=\"0.011\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8038\" width=\"0.667\" height=\"0.724\" depth=\"0.011\" italic=\"0.05\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8039\" width=\"0.667\" height=\"0.724\" depth=\"0.011\" italic=\"0.05\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8048\" width=\"0.555\" height=\"0.702\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8050\" width=\"0.389\" height=\"0.702\" depth=\"0.011\" italic=\"0.052\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"948\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.008\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8115\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8052\" width=\"0.517\" height=\"0.702\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8054\" width=\"0.25\" height=\"0.702\" depth=\"0.011\" italic=\"0.007\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8056\" width=\"0.472\" height=\"0.702\" depth=\"0.011\" italic=\"0.025\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"964\" val=\"-0.033\"/>\n    <Kern code=\"965\" val=\"-0.056\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.056\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8058\" val=\"-0.056\"/>\n    <Kern code=\"8166\" val=\"-0.056\"/>\n  </Char>\n  <Char code=\"8058\" width=\"0.5\" height=\"0.702\" depth=\"0.011\" italic=\"0.041\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"8060\" width=\"0.667\" height=\"0.702\" depth=\"0.011\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8064\" width=\"0.555\" height=\"0.696\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8065\" width=\"0.555\" height=\"0.696\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8066\" width=\"0.555\" height=\"0.702\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8067\" width=\"0.555\" height=\"0.702\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8068\" width=\"0.555\" height=\"0.702\" depth=\"0.211\" italic=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8069\" width=\"0.555\" height=\"0.702\" depth=\"0.211\" italic=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.044\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8070\" width=\"0.555\" height=\"0.723\" depth=\"0.211\" italic=\"0.055\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8071\" width=\"0.555\" height=\"0.723\" depth=\"0.211\" italic=\"0.055\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8080\" width=\"0.517\" height=\"0.696\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8081\" width=\"0.517\" height=\"0.696\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8082\" width=\"0.517\" height=\"0.702\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8083\" width=\"0.517\" height=\"0.702\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8084\" width=\"0.517\" height=\"0.702\" depth=\"0.214\" italic=\"0.041\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8085\" width=\"0.517\" height=\"0.702\" depth=\"0.214\" italic=\"0.041\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8086\" width=\"0.517\" height=\"0.723\" depth=\"0.214\" italic=\"0.085\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8087\" width=\"0.517\" height=\"0.723\" depth=\"0.214\" italic=\"0.085\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8096\" width=\"0.667\" height=\"0.696\" depth=\"0.211\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8097\" width=\"0.667\" height=\"0.696\" depth=\"0.211\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8098\" width=\"0.667\" height=\"0.702\" depth=\"0.211\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8099\" width=\"0.667\" height=\"0.702\" depth=\"0.211\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8100\" width=\"0.667\" height=\"0.702\" depth=\"0.211\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8101\" width=\"0.667\" height=\"0.702\" depth=\"0.211\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8102\" width=\"0.667\" height=\"0.724\" depth=\"0.211\" italic=\"0.05\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8103\" width=\"0.667\" height=\"0.724\" depth=\"0.211\" italic=\"0.05\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8114\" width=\"0.555\" height=\"0.702\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8115\" width=\"0.555\" height=\"0.443\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.094\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"993\" val=\"-0.222\"/>\n    <Kern code=\"8016\" val=\"-0.083\"/>\n    <Kern code=\"8018\" val=\"-0.083\"/>\n    <Kern code=\"8020\" val=\"-0.083\"/>\n    <Kern code=\"8021\" val=\"-0.083\"/>\n    <Kern code=\"8022\" val=\"-0.083\"/>\n    <Kern code=\"8023\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n    <Kern code=\"8166\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8116\" width=\"0.555\" height=\"0.702\" depth=\"0.211\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8118\" width=\"0.555\" height=\"0.615\" depth=\"0.011\" italic=\"0.026\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8119\" width=\"0.555\" height=\"0.615\" depth=\"0.211\" italic=\"0.026\" >\n    <Kern code=\"947\" val=\"-0.083\"/>\n    <Kern code=\"952\" val=\"-0.083\"/>\n    <Kern code=\"957\" val=\"-0.083\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"960\" val=\"-0.044\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"965\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.083\"/>\n    <Kern code=\"968\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.083\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8124\" width=\"0.75\" height=\"0.717\" depth=\"0.211\" >\n    <Kern code=\"920\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.083\"/>\n    <Kern code=\"932\" val=\"-0.083\"/>\n    <Kern code=\"933\" val=\"-0.139\"/>\n    <Kern code=\"934\" val=\"-0.083\"/>\n    <Kern code=\"936\" val=\"-0.122\"/>\n    <Kern code=\"939\" val=\"-0.139\"/>\n    <Kern code=\"957\" val=\"-0.097\"/>\n  </Char>\n  <Char code=\"8126\" width=\"0.222\" height=\"0.158\" depth=\"0.156\" italic=\"0.012\" />\n  <Char code=\"8127\" width=\"0.222\" height=\"0.696\" italic=\"0.175\" >\n    <Kern code=\"913\" val=\"-0.139\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.139\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8128\" width=\"0.333\" height=\"0.615\" italic=\"0.16\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n  </Char>\n  <Char code=\"8129\" width=\"0.444\" height=\"0.723\" italic=\"0.134\" />\n  <Char code=\"8130\" width=\"0.517\" height=\"0.702\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8131\" width=\"0.517\" height=\"0.443\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8132\" width=\"0.517\" height=\"0.702\" depth=\"0.214\" italic=\"0.035\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8134\" width=\"0.517\" height=\"0.616\" depth=\"0.214\" italic=\"0.056\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8135\" width=\"0.517\" height=\"0.616\" depth=\"0.214\" italic=\"0.056\" >\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8140\" width=\"0.75\" height=\"0.684\" depth=\"0.211\" italic=\"0.148\" />\n  <Char code=\"8141\" width=\"0.278\" height=\"0.702\" italic=\"0.128\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8142\" width=\"0.278\" height=\"0.701\" italic=\"0.174\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8143\" width=\"0.333\" height=\"0.723\" italic=\"0.189\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n  </Char>\n  <Char code=\"8146\" width=\"0.25\" height=\"0.702\" depth=\"0.011\" italic=\"0.13\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8150\" width=\"0.25\" height=\"0.615\" depth=\"0.011\" italic=\"0.162\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8151\" width=\"0.25\" height=\"0.723\" depth=\"0.011\" italic=\"0.191\" >\n    <Kern code=\"947\" val=\"-0.069\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.033\"/>\n    <Kern code=\"954\" val=\"-0.056\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.083\"/>\n    <Kern code=\"967\" val=\"-0.056\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8157\" width=\"0.278\" height=\"0.702\" italic=\"0.128\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8158\" width=\"0.278\" height=\"0.701\" italic=\"0.174\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8159\" width=\"0.333\" height=\"0.723\" italic=\"0.189\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n  </Char>\n  <Char code=\"8162\" width=\"0.5\" height=\"0.729\" depth=\"0.011\" italic=\"0.045\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"8164\" width=\"0.472\" height=\"0.696\" depth=\"0.212\" italic=\"0.05\" >\n    <Kern code=\"943\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.056\"/>\n    <Kern code=\"950\" val=\"0.028\"/>\n    <Kern code=\"953\" val=\"0.028\"/>\n    <Kern code=\"957\" val=\"-0.05\"/>\n    <Kern code=\"959\" val=\"0.028\"/>\n    <Kern code=\"963\" val=\"0.028\"/>\n    <Kern code=\"967\" val=\"-0.011\"/>\n    <Kern code=\"968\" val=\"0.017\"/>\n    <Kern code=\"972\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8054\" val=\"0.028\"/>\n    <Kern code=\"8056\" val=\"0.028\"/>\n    <Kern code=\"8150\" val=\"0.028\"/>\n  </Char>\n  <Char code=\"8165\" width=\"0.472\" height=\"0.696\" depth=\"0.212\" italic=\"0.028\" >\n    <Kern code=\"943\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.056\"/>\n    <Kern code=\"950\" val=\"0.028\"/>\n    <Kern code=\"953\" val=\"0.028\"/>\n    <Kern code=\"957\" val=\"-0.05\"/>\n    <Kern code=\"959\" val=\"0.028\"/>\n    <Kern code=\"963\" val=\"0.028\"/>\n    <Kern code=\"967\" val=\"-0.011\"/>\n    <Kern code=\"968\" val=\"0.017\"/>\n    <Kern code=\"972\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8054\" val=\"0.028\"/>\n    <Kern code=\"8056\" val=\"0.028\"/>\n    <Kern code=\"8150\" val=\"0.028\"/>\n  </Char>\n  <Char code=\"8166\" width=\"0.5\" height=\"0.616\" depth=\"0.011\" italic=\"0.074\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"8167\" width=\"0.5\" height=\"0.723\" depth=\"0.011\" italic=\"0.103\" >\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"956\" val=\"-0.011\"/>\n    <Kern code=\"957\" val=\"-0.039\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"968\" val=\"0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"8173\" width=\"0.278\" height=\"0.702\" italic=\"0.155\" />\n  <Char code=\"8175\" width=\"0.167\" height=\"0.702\" italic=\"0.116\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8178\" width=\"0.667\" height=\"0.702\" depth=\"0.211\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8179\" width=\"0.667\" height=\"0.432\" depth=\"0.211\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"993\" val=\"-0.167\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8180\" width=\"0.667\" height=\"0.702\" depth=\"0.211\" italic=\"0.019\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8182\" width=\"0.667\" height=\"0.615\" depth=\"0.011\" italic=\"0.021\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8183\" width=\"0.667\" height=\"0.615\" depth=\"0.211\" italic=\"0.021\" >\n    <Kern code=\"941\" val=\"0.028\"/>\n    <Kern code=\"947\" val=\"-0.111\"/>\n    <Kern code=\"949\" val=\"0.028\"/>\n    <Kern code=\"956\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.028\"/>\n    <Kern code=\"958\" val=\"0.028\"/>\n    <Kern code=\"964\" val=\"-0.047\"/>\n    <Kern code=\"965\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"973\" val=\"-0.028\"/>\n    <Kern code=\"8050\" val=\"0.028\"/>\n    <Kern code=\"8058\" val=\"-0.028\"/>\n    <Kern code=\"8166\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8188\" width=\"0.722\" height=\"0.706\" depth=\"0.211\" italic=\"0.074\" />\n  <Char code=\"8190\" width=\"0.222\" height=\"0.696\" italic=\"0.105\" >\n    <Kern code=\"913\" val=\"-0.167\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.167\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8217\" width=\"0.278\" height=\"0.695\" italic=\"0.093\" >\n  </Char>\n  <Char code=\"9001\" width=\"0.409\" height=\"0.751\" depth=\"0.249\" italic=\"0.106\" />\n  <Char code=\"9002\" width=\"0.409\" height=\"0.751\" depth=\"0.249\" />\n</Font>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/greek/fcmrpg.xml",
    "content": "<?xml version='1.0'?>\n<Font name=\"fcmrpg.ttf\" id=\"fcmrpg\" space=\"0.278\" xHeight=\"0.443\" quad=\"1\" unicode=\"205\" itVersion=\"fcmripg\" boldVersion=\"fcmbpg\" ssVersion=\"fcsrpg\" ttVersion=\"fctrpg\">\n  <Char code=\"32\" width=\"0.278\" height=\"0.0\" />\n  <Char code=\"168\" width=\"0.222\" height=\"0.603\" italic=\"0.041\" />\n  <Char code=\"884\" width=\"0.194\" height=\"0.701\" />\n  <Char code=\"885\" width=\"0.194\" height=\"0.003\" depth=\"0.217\" />\n  <Char code=\"890\" width=\"0.111\" height=\"-0.063\" depth=\"0.228\" />\n  <Char code=\"900\" width=\"0.167\" height=\"0.701\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"901\" width=\"0.278\" height=\"0.701\" />\n  <Char code=\"903\" width=\"0.278\" height=\"0.431\" />\n  <Char code=\"912\" width=\"0.25\" height=\"0.701\" depth=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"913\" width=\"0.75\" height=\"0.717\" >\n    <Kern code=\"920\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.083\"/>\n    <Kern code=\"932\" val=\"-0.083\"/>\n    <Kern code=\"933\" val=\"-0.139\"/>\n    <Kern code=\"934\" val=\"-0.083\"/>\n    <Kern code=\"936\" val=\"-0.122\"/>\n    <Kern code=\"939\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"914\" width=\"0.708\" height=\"0.685\" />\n  <Char code=\"915\" width=\"0.625\" height=\"0.681\" >\n    <Kern code=\"913\" val=\"-0.133\"/>\n    <Kern code=\"916\" val=\"-0.111\"/>\n    <Kern code=\"923\" val=\"-0.122\"/>\n    <Kern code=\"8124\" val=\"-0.133\"/>\n  </Char>\n  <Char code=\"916\" width=\"0.833\" height=\"0.718\" >\n    <Kern code=\"927\" val=\"-0.033\"/>\n    <Kern code=\"933\" val=\"-0.139\"/>\n    <Kern code=\"939\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"917\" width=\"0.68\" height=\"0.681\" />\n  <Char code=\"918\" width=\"0.611\" height=\"0.685\" />\n  <Char code=\"919\" width=\"0.75\" height=\"0.684\" />\n  <Char code=\"920\" width=\"0.778\" height=\"0.706\" depth=\"0.021\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"921\" width=\"0.361\" height=\"0.684\" />\n  <Char code=\"922\" width=\"0.778\" height=\"0.684\" >\n    <Kern code=\"927\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"923\" width=\"0.694\" height=\"0.718\" >\n    <Kern code=\"927\" val=\"-0.033\"/>\n    <Kern code=\"933\" val=\"-0.1\"/>\n    <Kern code=\"939\" val=\"-0.1\"/>\n  </Char>\n  <Char code=\"924\" width=\"0.916\" height=\"0.684\" />\n  <Char code=\"925\" width=\"0.75\" height=\"0.684\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"926\" width=\"0.667\" height=\"0.678\" />\n  <Char code=\"927\" width=\"0.778\" height=\"0.706\" depth=\"0.021\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"931\" val=\"-0.056\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"928\" width=\"0.75\" height=\"0.681\" />\n  <Char code=\"929\" width=\"0.68\" height=\"0.685\" >\n    <Kern code=\"913\" val=\"-0.167\"/>\n    <Kern code=\"8124\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"931\" width=\"0.722\" height=\"0.684\" >\n    <Kern code=\"913\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"932\" width=\"0.722\" height=\"0.678\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"933\" width=\"0.778\" height=\"0.707\" >\n    <Kern code=\"913\" val=\"-0.139\"/>\n    <Kern code=\"916\" val=\"-0.139\"/>\n    <Kern code=\"923\" val=\"-0.139\"/>\n    <Kern code=\"8124\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"934\" width=\"0.722\" height=\"0.684\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"935\" width=\"0.75\" height=\"0.684\" />\n  <Char code=\"936\" width=\"0.778\" height=\"0.684\" >\n    <Kern code=\"913\" val=\"-0.122\"/>\n    <Kern code=\"8124\" val=\"-0.122\"/>\n  </Char>\n  <Char code=\"937\" width=\"0.722\" height=\"0.706\" />\n  <Char code=\"938\" width=\"0.361\" height=\"0.833\" />\n  <Char code=\"939\" width=\"0.778\" height=\"0.833\" >\n    <Kern code=\"913\" val=\"-0.139\"/>\n    <Kern code=\"916\" val=\"-0.139\"/>\n    <Kern code=\"923\" val=\"-0.139\"/>\n    <Kern code=\"8124\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"940\" width=\"0.5\" height=\"0.702\" depth=\"0.011\" italic=\"0.001\" />\n  <Char code=\"941\" width=\"0.43\" height=\"0.701\" depth=\"0.021\" />\n  <Char code=\"942\" width=\"0.5\" height=\"0.701\" depth=\"0.271\" />\n  <Char code=\"943\" width=\"0.25\" height=\"0.701\" depth=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"944\" width=\"0.5\" height=\"0.702\" depth=\"0.01\" />\n  <Char code=\"945\" width=\"0.5\" height=\"0.443\" depth=\"0.011\" italic=\"0.001\" />\n  <Char code=\"946\" width=\"0.5\" height=\"0.706\" depth=\"0.276\" />\n  <Char code=\"947\" width=\"0.555\" height=\"0.442\" depth=\"0.2\" />\n  <Char code=\"948\" width=\"0.472\" height=\"0.7\" depth=\"0.01\" />\n  <Char code=\"949\" width=\"0.43\" height=\"0.454\" depth=\"0.021\" />\n  <Char code=\"950\" width=\"0.472\" height=\"0.718\" depth=\"0.139\" />\n  <Char code=\"951\" width=\"0.5\" height=\"0.454\" depth=\"0.271\" />\n  <Char code=\"952\" width=\"0.472\" height=\"0.717\" depth=\"0.022\" />\n  <Char code=\"953\" width=\"0.25\" height=\"0.443\" depth=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"954\" width=\"0.528\" height=\"0.454\" depth=\"0.022\" />\n  <Char code=\"955\" width=\"0.5\" height=\"0.697\" depth=\"0.01\" />\n  <Char code=\"956\" width=\"0.519\" height=\"0.453\" depth=\"0.26\" />\n  <Char code=\"957\" width=\"0.472\" height=\"0.443\" depth=\"0.01\" />\n  <Char code=\"958\" width=\"0.472\" height=\"0.717\" depth=\"0.139\" />\n  <Char code=\"959\" width=\"0.528\" height=\"0.443\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"960\" width=\"0.514\" height=\"0.432\" depth=\"0.018\" />\n  <Char code=\"961\" width=\"0.472\" height=\"0.442\" depth=\"0.261\" />\n  <Char code=\"962\" width=\"0.444\" height=\"0.443\" depth=\"0.125\" />\n  <Char code=\"963\" width=\"0.569\" height=\"0.432\" depth=\"0.01\" />\n  <Char code=\"964\" width=\"0.458\" height=\"0.432\" depth=\"0.01\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"969\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"974\" val=\"-0.028\"/>\n    <Kern code=\"7936\" val=\"-0.028\"/>\n    <Kern code=\"7937\" val=\"-0.028\"/>\n    <Kern code=\"7940\" val=\"-0.028\"/>\n    <Kern code=\"7941\" val=\"-0.028\"/>\n    <Kern code=\"7942\" val=\"-0.028\"/>\n    <Kern code=\"7943\" val=\"-0.028\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8032\" val=\"-0.028\"/>\n    <Kern code=\"8033\" val=\"-0.028\"/>\n    <Kern code=\"8036\" val=\"-0.028\"/>\n    <Kern code=\"8037\" val=\"-0.028\"/>\n    <Kern code=\"8038\" val=\"-0.028\"/>\n    <Kern code=\"8039\" val=\"-0.028\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8060\" val=\"-0.028\"/>\n    <Kern code=\"8064\" val=\"-0.028\"/>\n    <Kern code=\"8065\" val=\"-0.028\"/>\n    <Kern code=\"8068\" val=\"-0.028\"/>\n    <Kern code=\"8069\" val=\"-0.028\"/>\n    <Kern code=\"8070\" val=\"-0.028\"/>\n    <Kern code=\"8071\" val=\"-0.028\"/>\n    <Kern code=\"8096\" val=\"-0.028\"/>\n    <Kern code=\"8097\" val=\"-0.028\"/>\n    <Kern code=\"8100\" val=\"-0.028\"/>\n    <Kern code=\"8101\" val=\"-0.028\"/>\n    <Kern code=\"8102\" val=\"-0.028\"/>\n    <Kern code=\"8103\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8178\" val=\"-0.028\"/>\n    <Kern code=\"8180\" val=\"-0.028\"/>\n    <Kern code=\"8182\" val=\"-0.028\"/>\n    <Kern code=\"8183\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"965\" width=\"0.5\" height=\"0.457\" depth=\"0.01\" />\n  <Char code=\"966\" width=\"0.583\" height=\"0.455\" depth=\"0.275\" />\n  <Char code=\"967\" width=\"0.555\" height=\"0.444\" depth=\"0.262\" />\n  <Char code=\"968\" width=\"0.583\" height=\"0.72\" depth=\"0.276\" />\n  <Char code=\"969\" width=\"0.667\" height=\"0.453\" depth=\"0.011\" />\n  <Char code=\"970\" width=\"0.25\" height=\"0.626\" depth=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"971\" width=\"0.5\" height=\"0.626\" depth=\"0.01\" />\n  <Char code=\"972\" width=\"0.528\" height=\"0.701\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"973\" width=\"0.5\" height=\"0.702\" depth=\"0.01\" />\n  <Char code=\"974\" width=\"0.667\" height=\"0.701\" depth=\"0.011\" />\n  <Char code=\"977\" width=\"0.569\" height=\"0.707\" depth=\"0.011\" />\n  <Char code=\"984\" width=\"0.5\" height=\"0.695\" depth=\"0.001\" />\n  <Char code=\"985\" width=\"0.5\" height=\"0.599\" depth=\"0.063\" />\n  <Char code=\"986\" width=\"0.778\" height=\"0.679\" />\n  <Char code=\"987\" width=\"0.5\" height=\"0.454\" depth=\"0.027\" />\n  <Char code=\"988\" width=\"0.653\" height=\"0.681\" />\n  <Char code=\"989\" width=\"0.5\" height=\"0.432\" depth=\"0.257\" />\n  <Char code=\"991\" width=\"0.389\" height=\"0.595\" depth=\"0.138\" />\n  <Char code=\"992\" width=\"0.766\" height=\"0.695\" />\n  <Char code=\"993\" width=\"0.722\" height=\"0.696\" depth=\"0.022\" />\n  <Char code=\"7936\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.001\" />\n  <Char code=\"7937\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.001\" />\n  <Char code=\"7938\" width=\"0.5\" height=\"0.702\" depth=\"0.011\" italic=\"0.001\" />\n  <Char code=\"7939\" width=\"0.5\" height=\"0.702\" depth=\"0.011\" italic=\"0.001\" />\n  <Char code=\"7940\" width=\"0.5\" height=\"0.701\" depth=\"0.011\" italic=\"0.001\" />\n  <Char code=\"7941\" width=\"0.5\" height=\"0.701\" depth=\"0.011\" italic=\"0.001\" />\n  <Char code=\"7942\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.001\" />\n  <Char code=\"7943\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.001\" />\n  <Char code=\"7952\" width=\"0.43\" height=\"0.696\" depth=\"0.021\" />\n  <Char code=\"7953\" width=\"0.43\" height=\"0.696\" depth=\"0.021\" />\n  <Char code=\"7954\" width=\"0.43\" height=\"0.701\" depth=\"0.021\" />\n  <Char code=\"7955\" width=\"0.43\" height=\"0.701\" depth=\"0.021\" />\n  <Char code=\"7956\" width=\"0.43\" height=\"0.701\" depth=\"0.021\" />\n  <Char code=\"7957\" width=\"0.43\" height=\"0.701\" depth=\"0.021\" />\n  <Char code=\"7968\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"7969\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"7970\" width=\"0.5\" height=\"0.701\" depth=\"0.271\" />\n  <Char code=\"7971\" width=\"0.5\" height=\"0.701\" depth=\"0.271\" />\n  <Char code=\"7972\" width=\"0.5\" height=\"0.701\" depth=\"0.271\" />\n  <Char code=\"7973\" width=\"0.5\" height=\"0.701\" depth=\"0.271\" />\n  <Char code=\"7974\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"7975\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"7984\" width=\"0.25\" height=\"0.696\" depth=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"7985\" width=\"0.25\" height=\"0.696\" depth=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"7986\" width=\"0.25\" height=\"0.701\" depth=\"0.012\" />\n  <Char code=\"7987\" width=\"0.25\" height=\"0.701\" depth=\"0.012\" />\n  <Char code=\"7988\" width=\"0.25\" height=\"0.701\" depth=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"7989\" width=\"0.25\" height=\"0.701\" depth=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"7990\" width=\"0.25\" height=\"0.696\" depth=\"0.012\" italic=\"0.008\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"7991\" width=\"0.25\" height=\"0.696\" depth=\"0.012\" italic=\"0.008\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"8000\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8001\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8002\" width=\"0.528\" height=\"0.701\" depth=\"0.011\" />\n  <Char code=\"8003\" width=\"0.528\" height=\"0.701\" depth=\"0.011\" />\n  <Char code=\"8004\" width=\"0.528\" height=\"0.701\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8005\" width=\"0.528\" height=\"0.701\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8016\" width=\"0.5\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8017\" width=\"0.5\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8018\" width=\"0.5\" height=\"0.701\" depth=\"0.01\" />\n  <Char code=\"8019\" width=\"0.5\" height=\"0.701\" depth=\"0.01\" />\n  <Char code=\"8020\" width=\"0.5\" height=\"0.701\" depth=\"0.01\" />\n  <Char code=\"8021\" width=\"0.5\" height=\"0.701\" depth=\"0.01\" />\n  <Char code=\"8022\" width=\"0.5\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8023\" width=\"0.5\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8032\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8033\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8034\" width=\"0.667\" height=\"0.702\" depth=\"0.011\" />\n  <Char code=\"8035\" width=\"0.667\" height=\"0.702\" depth=\"0.011\" />\n  <Char code=\"8036\" width=\"0.667\" height=\"0.701\" depth=\"0.011\" />\n  <Char code=\"8037\" width=\"0.667\" height=\"0.701\" depth=\"0.011\" />\n  <Char code=\"8038\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8039\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8048\" width=\"0.5\" height=\"0.701\" depth=\"0.011\" italic=\"0.001\" />\n  <Char code=\"8050\" width=\"0.43\" height=\"0.701\" depth=\"0.021\" />\n  <Char code=\"8052\" width=\"0.5\" height=\"0.701\" depth=\"0.271\" />\n  <Char code=\"8054\" width=\"0.25\" height=\"0.701\" depth=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"8056\" width=\"0.528\" height=\"0.701\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8058\" width=\"0.5\" height=\"0.701\" depth=\"0.01\" />\n  <Char code=\"8060\" width=\"0.667\" height=\"0.701\" depth=\"0.011\" />\n  <Char code=\"8064\" width=\"0.5\" height=\"0.696\" depth=\"0.228\" italic=\"0.001\" />\n  <Char code=\"8065\" width=\"0.5\" height=\"0.696\" depth=\"0.228\" italic=\"0.001\" />\n  <Char code=\"8066\" width=\"0.5\" height=\"0.702\" depth=\"0.228\" italic=\"0.001\" />\n  <Char code=\"8067\" width=\"0.5\" height=\"0.702\" depth=\"0.228\" italic=\"0.001\" />\n  <Char code=\"8068\" width=\"0.5\" height=\"0.701\" depth=\"0.228\" italic=\"0.001\" />\n  <Char code=\"8069\" width=\"0.5\" height=\"0.701\" depth=\"0.228\" italic=\"0.001\" />\n  <Char code=\"8070\" width=\"0.5\" height=\"0.696\" depth=\"0.228\" italic=\"0.001\" />\n  <Char code=\"8071\" width=\"0.5\" height=\"0.696\" depth=\"0.228\" italic=\"0.001\" />\n  <Char code=\"8080\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"8081\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"8082\" width=\"0.5\" height=\"0.701\" depth=\"0.271\" />\n  <Char code=\"8083\" width=\"0.5\" height=\"0.701\" depth=\"0.271\" />\n  <Char code=\"8084\" width=\"0.5\" height=\"0.701\" depth=\"0.271\" />\n  <Char code=\"8085\" width=\"0.5\" height=\"0.701\" depth=\"0.271\" />\n  <Char code=\"8086\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"8087\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"8096\" width=\"0.667\" height=\"0.696\" depth=\"0.228\" />\n  <Char code=\"8097\" width=\"0.667\" height=\"0.696\" depth=\"0.228\" />\n  <Char code=\"8098\" width=\"0.667\" height=\"0.702\" depth=\"0.228\" />\n  <Char code=\"8099\" width=\"0.667\" height=\"0.702\" depth=\"0.228\" />\n  <Char code=\"8100\" width=\"0.667\" height=\"0.701\" depth=\"0.228\" />\n  <Char code=\"8101\" width=\"0.667\" height=\"0.701\" depth=\"0.228\" />\n  <Char code=\"8102\" width=\"0.667\" height=\"0.696\" depth=\"0.228\" />\n  <Char code=\"8103\" width=\"0.667\" height=\"0.696\" depth=\"0.228\" />\n  <Char code=\"8114\" width=\"0.5\" height=\"0.701\" depth=\"0.228\" italic=\"0.001\" />\n  <Char code=\"8115\" width=\"0.5\" height=\"0.443\" depth=\"0.228\" italic=\"0.001\" />\n  <Char code=\"8116\" width=\"0.5\" height=\"0.702\" depth=\"0.228\" italic=\"0.001\" />\n  <Char code=\"8118\" width=\"0.5\" height=\"0.627\" depth=\"0.011\" italic=\"0.001\" />\n  <Char code=\"8119\" width=\"0.5\" height=\"0.627\" depth=\"0.228\" italic=\"0.001\" />\n  <Char code=\"8124\" width=\"0.75\" height=\"0.717\" depth=\"0.228\" >\n    <Kern code=\"920\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.083\"/>\n    <Kern code=\"932\" val=\"-0.083\"/>\n    <Kern code=\"933\" val=\"-0.139\"/>\n    <Kern code=\"934\" val=\"-0.083\"/>\n    <Kern code=\"936\" val=\"-0.122\"/>\n    <Kern code=\"939\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"8126\" width=\"0.222\" height=\"0.158\" depth=\"0.156\" />\n  <Char code=\"8127\" width=\"0.222\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.139\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.139\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8128\" width=\"0.333\" height=\"0.627\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n  </Char>\n  <Char code=\"8129\" width=\"0.444\" height=\"0.696\" />\n  <Char code=\"8130\" width=\"0.5\" height=\"0.701\" depth=\"0.271\" />\n  <Char code=\"8131\" width=\"0.5\" height=\"0.454\" depth=\"0.271\" />\n  <Char code=\"8132\" width=\"0.5\" height=\"0.701\" depth=\"0.271\" />\n  <Char code=\"8134\" width=\"0.5\" height=\"0.627\" depth=\"0.271\" />\n  <Char code=\"8135\" width=\"0.5\" height=\"0.627\" depth=\"0.271\" />\n  <Char code=\"8140\" width=\"0.75\" height=\"0.684\" depth=\"0.228\" />\n  <Char code=\"8141\" width=\"0.278\" height=\"0.701\" italic=\"0.016\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8142\" width=\"0.278\" height=\"0.701\" italic=\"0.012\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8143\" width=\"0.333\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n  </Char>\n  <Char code=\"8146\" width=\"0.25\" height=\"0.701\" depth=\"0.012\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"8150\" width=\"0.25\" height=\"0.627\" depth=\"0.012\" italic=\"0.008\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"8151\" width=\"0.25\" height=\"0.696\" depth=\"0.012\" italic=\"0.008\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n    <Kern code=\"977\" val=\"-0.017\"/>\n  </Char>\n  <Char code=\"8157\" width=\"0.278\" height=\"0.701\" italic=\"0.016\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8158\" width=\"0.278\" height=\"0.701\" italic=\"0.012\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8159\" width=\"0.333\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n  </Char>\n  <Char code=\"8162\" width=\"0.5\" height=\"0.701\" depth=\"0.01\" />\n  <Char code=\"8164\" width=\"0.472\" height=\"0.696\" depth=\"0.261\" />\n  <Char code=\"8165\" width=\"0.472\" height=\"0.696\" depth=\"0.261\" />\n  <Char code=\"8166\" width=\"0.5\" height=\"0.627\" depth=\"0.01\" />\n  <Char code=\"8167\" width=\"0.5\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8173\" width=\"0.278\" height=\"0.701\" />\n  <Char code=\"8175\" width=\"0.167\" height=\"0.701\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8178\" width=\"0.667\" height=\"0.701\" depth=\"0.228\" />\n  <Char code=\"8179\" width=\"0.667\" height=\"0.453\" depth=\"0.228\" />\n  <Char code=\"8180\" width=\"0.667\" height=\"0.701\" depth=\"0.228\" />\n  <Char code=\"8182\" width=\"0.667\" height=\"0.628\" depth=\"0.011\" />\n  <Char code=\"8183\" width=\"0.667\" height=\"0.628\" depth=\"0.228\" />\n  <Char code=\"8188\" width=\"0.722\" height=\"0.706\" depth=\"0.228\" />\n  <Char code=\"8190\" width=\"0.222\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.167\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.167\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8217\" width=\"0.278\" height=\"0.695\" >\n  </Char>\n  <Char code=\"9001\" width=\"0.389\" height=\"0.751\" depth=\"0.249\" />\n  <Char code=\"9002\" width=\"0.389\" height=\"0.751\" depth=\"0.25\" />\n</Font>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/greek/fcsbpg.xml",
    "content": "<?xml version='1.0'?>\n<Font name=\"fcsbpg.ttf\" id=\"fcsbpg\" space=\"0.255\" xHeight=\"0.472\" quad=\"1\" unicode=\"204\" itVersion=\"fcsropg\" romanVersion=\"fcmbpg\" ttVersion=\"fctrpg\">\n  <Char code=\"32\" width=\"0.255\" height=\"0.0\" />\n  <Char code=\"168\" width=\"0.244\" height=\"0.63\" italic=\"0.056\" />\n  <Char code=\"884\" width=\"0.214\" height=\"0.695\" />\n  <Char code=\"885\" width=\"0.214\" height=\"0.001\" depth=\"0.188\" />\n  <Char code=\"890\" width=\"0.122\" height=\"-0.067\" depth=\"0.247\" />\n  <Char code=\"900\" width=\"0.183\" height=\"0.695\" >\n    <Kern code=\"913\" val=\"-0.122\"/>\n    <Kern code=\"927\" val=\"-0.061\"/>\n    <Kern code=\"937\" val=\"-0.031\"/>\n    <Kern code=\"8124\" val=\"-0.122\"/>\n    <Kern code=\"8188\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"901\" width=\"0.305\" height=\"0.695\" />\n  <Char code=\"903\" width=\"0.305\" height=\"0.459\" />\n  <Char code=\"912\" width=\"0.275\" height=\"0.695\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"913\" width=\"0.733\" height=\"0.687\" >\n    <Kern code=\"920\" val=\"-0.092\"/>\n    <Kern code=\"927\" val=\"-0.092\"/>\n    <Kern code=\"932\" val=\"-0.092\"/>\n    <Kern code=\"933\" val=\"-0.153\"/>\n    <Kern code=\"934\" val=\"-0.092\"/>\n    <Kern code=\"936\" val=\"-0.134\"/>\n    <Kern code=\"939\" val=\"-0.153\"/>\n  </Char>\n  <Char code=\"914\" width=\"0.733\" height=\"0.687\" />\n  <Char code=\"915\" width=\"0.58\" height=\"0.684\" >\n    <Kern code=\"913\" val=\"-0.147\"/>\n    <Kern code=\"916\" val=\"-0.122\"/>\n    <Kern code=\"923\" val=\"-0.134\"/>\n    <Kern code=\"8124\" val=\"-0.147\"/>\n  </Char>\n  <Char code=\"916\" width=\"0.916\" height=\"0.687\" >\n    <Kern code=\"927\" val=\"-0.037\"/>\n    <Kern code=\"933\" val=\"-0.153\"/>\n    <Kern code=\"939\" val=\"-0.153\"/>\n  </Char>\n  <Char code=\"917\" width=\"0.642\" height=\"0.684\" />\n  <Char code=\"918\" width=\"0.672\" height=\"0.687\" />\n  <Char code=\"919\" width=\"0.794\" height=\"0.687\" />\n  <Char code=\"920\" width=\"0.855\" height=\"0.709\" depth=\"0.022\" >\n    <Kern code=\"913\" val=\"-0.092\"/>\n    <Kern code=\"8124\" val=\"-0.092\"/>\n  </Char>\n  <Char code=\"921\" width=\"0.308\" height=\"0.687\" />\n  <Char code=\"922\" width=\"0.764\" height=\"0.687\" >\n    <Kern code=\"927\" val=\"-0.092\"/>\n  </Char>\n  <Char code=\"923\" width=\"0.672\" height=\"0.687\" >\n    <Kern code=\"927\" val=\"-0.037\"/>\n    <Kern code=\"933\" val=\"-0.11\"/>\n    <Kern code=\"939\" val=\"-0.11\"/>\n  </Char>\n  <Char code=\"924\" width=\"0.978\" height=\"0.687\" />\n  <Char code=\"925\" width=\"0.794\" height=\"0.687\" >\n    <Kern code=\"913\" val=\"-0.092\"/>\n    <Kern code=\"8124\" val=\"-0.092\"/>\n  </Char>\n  <Char code=\"926\" width=\"0.733\" height=\"0.681\" />\n  <Char code=\"927\" width=\"0.794\" height=\"0.71\" depth=\"0.022\" >\n    <Kern code=\"913\" val=\"-0.092\"/>\n    <Kern code=\"931\" val=\"-0.061\"/>\n    <Kern code=\"8124\" val=\"-0.092\"/>\n  </Char>\n  <Char code=\"928\" width=\"0.794\" height=\"0.684\" />\n  <Char code=\"929\" width=\"0.703\" height=\"0.687\" >\n    <Kern code=\"913\" val=\"-0.183\"/>\n    <Kern code=\"8124\" val=\"-0.183\"/>\n  </Char>\n  <Char code=\"931\" width=\"0.794\" height=\"0.687\" >\n    <Kern code=\"913\" val=\"-0.031\"/>\n    <Kern code=\"8124\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"932\" width=\"0.733\" height=\"0.681\" >\n    <Kern code=\"913\" val=\"-0.092\"/>\n    <Kern code=\"8124\" val=\"-0.092\"/>\n  </Char>\n  <Char code=\"933\" width=\"0.855\" height=\"0.709\" >\n    <Kern code=\"913\" val=\"-0.153\"/>\n    <Kern code=\"916\" val=\"-0.153\"/>\n    <Kern code=\"923\" val=\"-0.153\"/>\n    <Kern code=\"8124\" val=\"-0.153\"/>\n  </Char>\n  <Char code=\"934\" width=\"0.794\" height=\"0.687\" >\n    <Kern code=\"913\" val=\"-0.092\"/>\n    <Kern code=\"8124\" val=\"-0.092\"/>\n  </Char>\n  <Char code=\"935\" width=\"0.733\" height=\"0.687\" />\n  <Char code=\"936\" width=\"0.855\" height=\"0.687\" >\n    <Kern code=\"913\" val=\"-0.134\"/>\n    <Kern code=\"8124\" val=\"-0.134\"/>\n  </Char>\n  <Char code=\"937\" width=\"0.794\" height=\"0.709\" />\n  <Char code=\"938\" width=\"0.308\" height=\"0.847\" italic=\"0.01\" />\n  <Char code=\"939\" width=\"0.855\" height=\"0.847\" >\n    <Kern code=\"913\" val=\"-0.153\"/>\n    <Kern code=\"916\" val=\"-0.153\"/>\n    <Kern code=\"923\" val=\"-0.153\"/>\n    <Kern code=\"8124\" val=\"-0.153\"/>\n  </Char>\n  <Char code=\"940\" width=\"0.55\" height=\"0.695\" depth=\"0.011\" italic=\"0.061\" />\n  <Char code=\"941\" width=\"0.473\" height=\"0.695\" depth=\"0.022\" />\n  <Char code=\"942\" width=\"0.55\" height=\"0.695\" depth=\"0.272\" />\n  <Char code=\"943\" width=\"0.275\" height=\"0.695\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"944\" width=\"0.55\" height=\"0.695\" depth=\"0.011\" />\n  <Char code=\"945\" width=\"0.55\" height=\"0.471\" depth=\"0.011\" italic=\"0.061\" />\n  <Char code=\"946\" width=\"0.55\" height=\"0.706\" depth=\"0.271\" />\n  <Char code=\"947\" width=\"0.611\" height=\"0.471\" depth=\"0.228\" />\n  <Char code=\"948\" width=\"0.519\" height=\"0.707\" depth=\"0.011\" />\n  <Char code=\"949\" width=\"0.473\" height=\"0.482\" depth=\"0.022\" />\n  <Char code=\"950\" width=\"0.519\" height=\"0.718\" depth=\"0.186\" />\n  <Char code=\"951\" width=\"0.55\" height=\"0.482\" depth=\"0.272\" />\n  <Char code=\"952\" width=\"0.626\" height=\"0.706\" depth=\"0.011\" />\n  <Char code=\"953\" width=\"0.275\" height=\"0.47\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"954\" width=\"0.58\" height=\"0.487\" depth=\"0.027\" />\n  <Char code=\"955\" width=\"0.55\" height=\"0.697\" depth=\"0.01\" />\n  <Char code=\"956\" width=\"0.586\" height=\"0.482\" depth=\"0.266\" italic=\"0.001\" />\n  <Char code=\"957\" width=\"0.519\" height=\"0.472\" depth=\"0.01\" />\n  <Char code=\"958\" width=\"0.519\" height=\"0.718\" depth=\"0.186\" />\n  <Char code=\"959\" width=\"0.58\" height=\"0.471\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"955\" val=\"-0.031\"/>\n    <Kern code=\"957\" val=\"-0.024\"/>\n    <Kern code=\"964\" val=\"-0.024\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"960\" width=\"0.565\" height=\"0.459\" depth=\"0.011\" italic=\"0.027\" />\n  <Char code=\"961\" width=\"0.519\" height=\"0.471\" depth=\"0.266\" />\n  <Char code=\"962\" width=\"0.489\" height=\"0.471\" depth=\"0.125\" />\n  <Char code=\"963\" width=\"0.626\" height=\"0.459\" depth=\"0.012\" />\n  <Char code=\"964\" width=\"0.504\" height=\"0.46\" depth=\"0.011\" >\n    <Kern code=\"940\" val=\"-0.031\"/>\n    <Kern code=\"945\" val=\"-0.031\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"969\" val=\"-0.031\"/>\n    <Kern code=\"972\" val=\"-0.031\"/>\n    <Kern code=\"974\" val=\"-0.031\"/>\n    <Kern code=\"7936\" val=\"-0.031\"/>\n    <Kern code=\"7937\" val=\"-0.031\"/>\n    <Kern code=\"7940\" val=\"-0.031\"/>\n    <Kern code=\"7941\" val=\"-0.031\"/>\n    <Kern code=\"7942\" val=\"-0.031\"/>\n    <Kern code=\"7943\" val=\"-0.031\"/>\n    <Kern code=\"8000\" val=\"-0.031\"/>\n    <Kern code=\"8001\" val=\"-0.031\"/>\n    <Kern code=\"8004\" val=\"-0.031\"/>\n    <Kern code=\"8005\" val=\"-0.031\"/>\n    <Kern code=\"8032\" val=\"-0.031\"/>\n    <Kern code=\"8033\" val=\"-0.031\"/>\n    <Kern code=\"8036\" val=\"-0.031\"/>\n    <Kern code=\"8037\" val=\"-0.031\"/>\n    <Kern code=\"8038\" val=\"-0.031\"/>\n    <Kern code=\"8039\" val=\"-0.031\"/>\n    <Kern code=\"8048\" val=\"-0.031\"/>\n    <Kern code=\"8056\" val=\"-0.031\"/>\n    <Kern code=\"8060\" val=\"-0.031\"/>\n    <Kern code=\"8064\" val=\"-0.031\"/>\n    <Kern code=\"8065\" val=\"-0.031\"/>\n    <Kern code=\"8068\" val=\"-0.031\"/>\n    <Kern code=\"8069\" val=\"-0.031\"/>\n    <Kern code=\"8070\" val=\"-0.031\"/>\n    <Kern code=\"8071\" val=\"-0.031\"/>\n    <Kern code=\"8096\" val=\"-0.031\"/>\n    <Kern code=\"8097\" val=\"-0.031\"/>\n    <Kern code=\"8100\" val=\"-0.031\"/>\n    <Kern code=\"8101\" val=\"-0.031\"/>\n    <Kern code=\"8102\" val=\"-0.031\"/>\n    <Kern code=\"8103\" val=\"-0.031\"/>\n    <Kern code=\"8114\" val=\"-0.031\"/>\n    <Kern code=\"8116\" val=\"-0.031\"/>\n    <Kern code=\"8118\" val=\"-0.031\"/>\n    <Kern code=\"8119\" val=\"-0.031\"/>\n    <Kern code=\"8178\" val=\"-0.031\"/>\n    <Kern code=\"8180\" val=\"-0.031\"/>\n    <Kern code=\"8182\" val=\"-0.031\"/>\n    <Kern code=\"8183\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"965\" width=\"0.55\" height=\"0.492\" depth=\"0.01\" />\n  <Char code=\"966\" width=\"0.642\" height=\"0.486\" depth=\"0.272\" />\n  <Char code=\"967\" width=\"0.611\" height=\"0.473\" depth=\"0.263\" />\n  <Char code=\"968\" width=\"0.642\" height=\"0.718\" depth=\"0.272\" />\n  <Char code=\"969\" width=\"0.733\" height=\"0.481\" depth=\"0.011\" />\n  <Char code=\"970\" width=\"0.275\" height=\"0.641\" depth=\"0.01\" italic=\"0.001\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"971\" width=\"0.55\" height=\"0.64\" depth=\"0.01\" />\n  <Char code=\"972\" width=\"0.58\" height=\"0.695\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"955\" val=\"-0.031\"/>\n    <Kern code=\"957\" val=\"-0.024\"/>\n    <Kern code=\"964\" val=\"-0.024\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"973\" width=\"0.55\" height=\"0.695\" depth=\"0.01\" />\n  <Char code=\"974\" width=\"0.733\" height=\"0.695\" depth=\"0.011\" />\n  <Char code=\"984\" width=\"0.55\" height=\"0.698\" />\n  <Char code=\"985\" width=\"0.55\" height=\"0.646\" depth=\"0.077\" />\n  <Char code=\"986\" width=\"0.855\" height=\"0.682\" depth=\"0.001\" />\n  <Char code=\"987\" width=\"0.55\" height=\"0.481\" />\n  <Char code=\"988\" width=\"0.611\" height=\"0.684\" />\n  <Char code=\"989\" width=\"0.55\" height=\"0.461\" depth=\"0.249\" />\n  <Char code=\"991\" width=\"0.428\" height=\"0.577\" depth=\"0.075\" />\n  <Char code=\"992\" width=\"0.703\" height=\"0.686\" />\n  <Char code=\"993\" width=\"0.794\" height=\"0.695\" />\n  <Char code=\"7936\" width=\"0.55\" height=\"0.696\" depth=\"0.011\" italic=\"0.061\" />\n  <Char code=\"7937\" width=\"0.55\" height=\"0.696\" depth=\"0.011\" italic=\"0.061\" />\n  <Char code=\"7938\" width=\"0.55\" height=\"0.696\" depth=\"0.011\" italic=\"0.061\" />\n  <Char code=\"7939\" width=\"0.55\" height=\"0.696\" depth=\"0.011\" italic=\"0.061\" />\n  <Char code=\"7940\" width=\"0.55\" height=\"0.696\" depth=\"0.011\" italic=\"0.061\" />\n  <Char code=\"7941\" width=\"0.55\" height=\"0.696\" depth=\"0.011\" italic=\"0.061\" />\n  <Char code=\"7942\" width=\"0.55\" height=\"0.695\" depth=\"0.011\" italic=\"0.061\" />\n  <Char code=\"7943\" width=\"0.55\" height=\"0.695\" depth=\"0.011\" italic=\"0.061\" />\n  <Char code=\"7952\" width=\"0.473\" height=\"0.696\" depth=\"0.022\" />\n  <Char code=\"7953\" width=\"0.473\" height=\"0.696\" depth=\"0.022\" />\n  <Char code=\"7954\" width=\"0.473\" height=\"0.696\" depth=\"0.022\" />\n  <Char code=\"7955\" width=\"0.473\" height=\"0.696\" depth=\"0.022\" />\n  <Char code=\"7956\" width=\"0.473\" height=\"0.696\" depth=\"0.022\" />\n  <Char code=\"7957\" width=\"0.473\" height=\"0.696\" depth=\"0.022\" />\n  <Char code=\"7968\" width=\"0.55\" height=\"0.696\" depth=\"0.272\" />\n  <Char code=\"7969\" width=\"0.55\" height=\"0.696\" depth=\"0.272\" />\n  <Char code=\"7970\" width=\"0.55\" height=\"0.696\" depth=\"0.272\" />\n  <Char code=\"7971\" width=\"0.55\" height=\"0.696\" depth=\"0.272\" />\n  <Char code=\"7972\" width=\"0.55\" height=\"0.696\" depth=\"0.272\" />\n  <Char code=\"7973\" width=\"0.55\" height=\"0.696\" depth=\"0.272\" />\n  <Char code=\"7974\" width=\"0.55\" height=\"0.695\" depth=\"0.272\" />\n  <Char code=\"7975\" width=\"0.55\" height=\"0.695\" depth=\"0.272\" />\n  <Char code=\"7984\" width=\"0.275\" height=\"0.696\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"7985\" width=\"0.275\" height=\"0.696\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"7986\" width=\"0.275\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"7987\" width=\"0.275\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"7988\" width=\"0.275\" height=\"0.696\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"7989\" width=\"0.275\" height=\"0.696\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"7990\" width=\"0.275\" height=\"0.696\" depth=\"0.01\" italic=\"0.016\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"7991\" width=\"0.275\" height=\"0.696\" depth=\"0.01\" italic=\"0.016\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"8000\" width=\"0.58\" height=\"0.696\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"955\" val=\"-0.031\"/>\n    <Kern code=\"957\" val=\"-0.024\"/>\n    <Kern code=\"964\" val=\"-0.024\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"8001\" width=\"0.58\" height=\"0.696\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"955\" val=\"-0.031\"/>\n    <Kern code=\"957\" val=\"-0.024\"/>\n    <Kern code=\"964\" val=\"-0.024\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"8002\" width=\"0.58\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8003\" width=\"0.58\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8004\" width=\"0.58\" height=\"0.696\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"955\" val=\"-0.031\"/>\n    <Kern code=\"957\" val=\"-0.024\"/>\n    <Kern code=\"964\" val=\"-0.024\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"8005\" width=\"0.58\" height=\"0.696\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"955\" val=\"-0.031\"/>\n    <Kern code=\"957\" val=\"-0.024\"/>\n    <Kern code=\"964\" val=\"-0.024\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"8016\" width=\"0.55\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8017\" width=\"0.55\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8018\" width=\"0.55\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8019\" width=\"0.55\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8020\" width=\"0.55\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8021\" width=\"0.55\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8022\" width=\"0.55\" height=\"0.695\" depth=\"0.01\" />\n  <Char code=\"8023\" width=\"0.55\" height=\"0.695\" depth=\"0.01\" />\n  <Char code=\"8032\" width=\"0.733\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8033\" width=\"0.733\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8034\" width=\"0.733\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8035\" width=\"0.733\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8036\" width=\"0.733\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8037\" width=\"0.733\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8038\" width=\"0.733\" height=\"0.695\" depth=\"0.011\" />\n  <Char code=\"8039\" width=\"0.733\" height=\"0.695\" depth=\"0.011\" />\n  <Char code=\"8048\" width=\"0.55\" height=\"0.695\" depth=\"0.011\" italic=\"0.061\" />\n  <Char code=\"8050\" width=\"0.473\" height=\"0.695\" depth=\"0.022\" />\n  <Char code=\"8052\" width=\"0.55\" height=\"0.695\" depth=\"0.272\" />\n  <Char code=\"8054\" width=\"0.275\" height=\"0.695\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"8056\" width=\"0.58\" height=\"0.695\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"955\" val=\"-0.031\"/>\n    <Kern code=\"957\" val=\"-0.024\"/>\n    <Kern code=\"964\" val=\"-0.024\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"8058\" width=\"0.55\" height=\"0.695\" depth=\"0.01\" />\n  <Char code=\"8060\" width=\"0.733\" height=\"0.695\" depth=\"0.011\" />\n  <Char code=\"8064\" width=\"0.55\" height=\"0.696\" depth=\"0.247\" italic=\"0.061\" />\n  <Char code=\"8065\" width=\"0.55\" height=\"0.696\" depth=\"0.247\" italic=\"0.061\" />\n  <Char code=\"8066\" width=\"0.55\" height=\"0.696\" depth=\"0.247\" italic=\"0.061\" />\n  <Char code=\"8067\" width=\"0.55\" height=\"0.696\" depth=\"0.247\" italic=\"0.061\" />\n  <Char code=\"8068\" width=\"0.55\" height=\"0.696\" depth=\"0.247\" italic=\"0.061\" />\n  <Char code=\"8069\" width=\"0.55\" height=\"0.696\" depth=\"0.247\" italic=\"0.061\" />\n  <Char code=\"8070\" width=\"0.55\" height=\"0.695\" depth=\"0.247\" italic=\"0.061\" />\n  <Char code=\"8071\" width=\"0.55\" height=\"0.695\" depth=\"0.247\" italic=\"0.061\" />\n  <Char code=\"8080\" width=\"0.55\" height=\"0.696\" depth=\"0.272\" />\n  <Char code=\"8081\" width=\"0.55\" height=\"0.696\" depth=\"0.272\" />\n  <Char code=\"8082\" width=\"0.55\" height=\"0.696\" depth=\"0.272\" />\n  <Char code=\"8083\" width=\"0.55\" height=\"0.696\" depth=\"0.272\" />\n  <Char code=\"8084\" width=\"0.55\" height=\"0.696\" depth=\"0.272\" />\n  <Char code=\"8085\" width=\"0.55\" height=\"0.696\" depth=\"0.272\" />\n  <Char code=\"8086\" width=\"0.55\" height=\"0.695\" depth=\"0.272\" />\n  <Char code=\"8087\" width=\"0.55\" height=\"0.695\" depth=\"0.272\" />\n  <Char code=\"8096\" width=\"0.733\" height=\"0.696\" depth=\"0.247\" />\n  <Char code=\"8097\" width=\"0.733\" height=\"0.696\" depth=\"0.247\" />\n  <Char code=\"8098\" width=\"0.733\" height=\"0.696\" depth=\"0.247\" />\n  <Char code=\"8099\" width=\"0.733\" height=\"0.696\" depth=\"0.247\" />\n  <Char code=\"8100\" width=\"0.733\" height=\"0.696\" depth=\"0.247\" />\n  <Char code=\"8101\" width=\"0.733\" height=\"0.696\" depth=\"0.247\" />\n  <Char code=\"8102\" width=\"0.733\" height=\"0.695\" depth=\"0.247\" />\n  <Char code=\"8103\" width=\"0.733\" height=\"0.695\" depth=\"0.247\" />\n  <Char code=\"8114\" width=\"0.55\" height=\"0.695\" depth=\"0.247\" italic=\"0.061\" />\n  <Char code=\"8115\" width=\"0.55\" height=\"0.471\" depth=\"0.247\" italic=\"0.061\" />\n  <Char code=\"8116\" width=\"0.55\" height=\"0.695\" depth=\"0.247\" italic=\"0.061\" />\n  <Char code=\"8118\" width=\"0.55\" height=\"0.64\" depth=\"0.011\" italic=\"0.061\" />\n  <Char code=\"8119\" width=\"0.55\" height=\"0.64\" depth=\"0.247\" italic=\"0.061\" />\n  <Char code=\"8124\" width=\"0.733\" height=\"0.687\" depth=\"0.247\" >\n    <Kern code=\"920\" val=\"-0.092\"/>\n    <Kern code=\"927\" val=\"-0.092\"/>\n    <Kern code=\"932\" val=\"-0.092\"/>\n    <Kern code=\"933\" val=\"-0.153\"/>\n    <Kern code=\"934\" val=\"-0.092\"/>\n    <Kern code=\"936\" val=\"-0.134\"/>\n    <Kern code=\"939\" val=\"-0.153\"/>\n  </Char>\n  <Char code=\"8126\" width=\"0.244\" height=\"0.155\" depth=\"0.153\" />\n  <Char code=\"8127\" width=\"0.244\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.153\"/>\n    <Kern code=\"927\" val=\"-0.061\"/>\n    <Kern code=\"937\" val=\"-0.031\"/>\n    <Kern code=\"8124\" val=\"-0.153\"/>\n    <Kern code=\"8188\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"8128\" width=\"0.367\" height=\"0.64\" >\n    <Kern code=\"913\" val=\"-0.122\"/>\n    <Kern code=\"8124\" val=\"-0.122\"/>\n  </Char>\n  <Char code=\"8129\" width=\"0.489\" height=\"0.696\" />\n  <Char code=\"8130\" width=\"0.55\" height=\"0.695\" depth=\"0.272\" />\n  <Char code=\"8131\" width=\"0.55\" height=\"0.482\" depth=\"0.272\" />\n  <Char code=\"8132\" width=\"0.55\" height=\"0.695\" depth=\"0.272\" />\n  <Char code=\"8134\" width=\"0.55\" height=\"0.64\" depth=\"0.272\" />\n  <Char code=\"8135\" width=\"0.55\" height=\"0.64\" depth=\"0.272\" />\n  <Char code=\"8140\" width=\"0.794\" height=\"0.687\" depth=\"0.247\" />\n  <Char code=\"8141\" width=\"0.305\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.092\"/>\n    <Kern code=\"927\" val=\"-0.031\"/>\n    <Kern code=\"8124\" val=\"-0.092\"/>\n  </Char>\n  <Char code=\"8142\" width=\"0.305\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.092\"/>\n    <Kern code=\"927\" val=\"-0.031\"/>\n    <Kern code=\"8124\" val=\"-0.092\"/>\n  </Char>\n  <Char code=\"8143\" width=\"0.367\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.122\"/>\n    <Kern code=\"8124\" val=\"-0.122\"/>\n  </Char>\n  <Char code=\"8146\" width=\"0.275\" height=\"0.695\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"8150\" width=\"0.275\" height=\"0.64\" depth=\"0.01\" italic=\"0.016\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"8151\" width=\"0.275\" height=\"0.696\" depth=\"0.01\" italic=\"0.016\" >\n    <Kern code=\"947\" val=\"-0.031\"/>\n    <Kern code=\"951\" val=\"-0.018\"/>\n    <Kern code=\"952\" val=\"-0.018\"/>\n    <Kern code=\"957\" val=\"-0.061\"/>\n    <Kern code=\"959\" val=\"-0.031\"/>\n    <Kern code=\"962\" val=\"-0.031\"/>\n    <Kern code=\"963\" val=\"-0.031\"/>\n    <Kern code=\"964\" val=\"-0.031\"/>\n    <Kern code=\"967\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"8157\" width=\"0.305\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.092\"/>\n    <Kern code=\"927\" val=\"-0.031\"/>\n    <Kern code=\"8124\" val=\"-0.092\"/>\n  </Char>\n  <Char code=\"8158\" width=\"0.305\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.092\"/>\n    <Kern code=\"927\" val=\"-0.031\"/>\n    <Kern code=\"8124\" val=\"-0.092\"/>\n  </Char>\n  <Char code=\"8159\" width=\"0.367\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.122\"/>\n    <Kern code=\"8124\" val=\"-0.122\"/>\n  </Char>\n  <Char code=\"8162\" width=\"0.55\" height=\"0.695\" depth=\"0.01\" />\n  <Char code=\"8164\" width=\"0.519\" height=\"0.696\" depth=\"0.266\" />\n  <Char code=\"8165\" width=\"0.519\" height=\"0.696\" depth=\"0.266\" />\n  <Char code=\"8166\" width=\"0.55\" height=\"0.64\" depth=\"0.01\" />\n  <Char code=\"8167\" width=\"0.55\" height=\"0.695\" depth=\"0.01\" />\n  <Char code=\"8173\" width=\"0.305\" height=\"0.695\" />\n  <Char code=\"8175\" width=\"0.183\" height=\"0.695\" >\n    <Kern code=\"913\" val=\"-0.122\"/>\n    <Kern code=\"927\" val=\"-0.061\"/>\n    <Kern code=\"937\" val=\"-0.031\"/>\n    <Kern code=\"8124\" val=\"-0.122\"/>\n    <Kern code=\"8188\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"8178\" width=\"0.733\" height=\"0.695\" depth=\"0.247\" />\n  <Char code=\"8179\" width=\"0.733\" height=\"0.481\" depth=\"0.247\" />\n  <Char code=\"8180\" width=\"0.733\" height=\"0.695\" depth=\"0.247\" />\n  <Char code=\"8182\" width=\"0.733\" height=\"0.641\" depth=\"0.011\" />\n  <Char code=\"8183\" width=\"0.733\" height=\"0.641\" depth=\"0.247\" />\n  <Char code=\"8188\" width=\"0.794\" height=\"0.709\" depth=\"0.247\" />\n  <Char code=\"8190\" width=\"0.244\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.183\"/>\n    <Kern code=\"927\" val=\"-0.061\"/>\n    <Kern code=\"937\" val=\"-0.031\"/>\n    <Kern code=\"8124\" val=\"-0.183\"/>\n    <Kern code=\"8188\" val=\"-0.031\"/>\n  </Char>\n  <Char code=\"8217\" width=\"0.305\" height=\"0.696\" >\n  </Char>\n  <Char code=\"9001\" width=\"0.428\" height=\"0.751\" depth=\"0.25\" />\n  <Char code=\"9002\" width=\"0.428\" height=\"0.751\" depth=\"0.25\" />\n</Font>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/greek/fcsropg.xml",
    "content": "<?xml version='1.0'?>\n<Font name=\"fcsropg.ttf\" id=\"fcsropg\" space=\"0.239\" xHeight=\"0.444\" quad=\"1\" unicode=\"204\" romanVersion=\"fcmripg\" boldVersion=\"fcsbpg\" ttVersion=\"fctrpg\">\n  <Char code=\"32\" width=\"0.239\" height=\"0.0\" />\n  <Char code=\"168\" width=\"0.222\" height=\"0.603\" italic=\"0.17\" />\n  <Char code=\"884\" width=\"0.194\" height=\"0.695\" italic=\"0.14\" />\n  <Char code=\"885\" width=\"0.194\" height=\"0.001\" depth=\"0.21\" italic=\"0.003\" />\n  <Char code=\"890\" width=\"0.111\" height=\"-0.064\" depth=\"0.238\" />\n  <Char code=\"900\" width=\"0.167\" height=\"0.695\" italic=\"0.145\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"901\" width=\"0.278\" height=\"0.695\" italic=\"0.117\" />\n  <Char code=\"903\" width=\"0.278\" height=\"0.431\" />\n  <Char code=\"912\" width=\"0.25\" height=\"0.695\" depth=\"0.011\" italic=\"0.099\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"913\" width=\"0.667\" height=\"0.685\" >\n    <Kern code=\"920\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.083\"/>\n    <Kern code=\"932\" val=\"-0.083\"/>\n    <Kern code=\"933\" val=\"-0.139\"/>\n    <Kern code=\"934\" val=\"-0.083\"/>\n    <Kern code=\"936\" val=\"-0.122\"/>\n    <Kern code=\"939\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"914\" width=\"0.667\" height=\"0.685\" italic=\"0.028\" />\n  <Char code=\"915\" width=\"0.542\" height=\"0.681\" italic=\"0.101\" >\n    <Kern code=\"913\" val=\"-0.133\"/>\n    <Kern code=\"916\" val=\"-0.111\"/>\n    <Kern code=\"923\" val=\"-0.122\"/>\n    <Kern code=\"8124\" val=\"-0.133\"/>\n  </Char>\n  <Char code=\"916\" width=\"0.833\" height=\"0.684\" >\n    <Kern code=\"927\" val=\"-0.033\"/>\n    <Kern code=\"933\" val=\"-0.139\"/>\n    <Kern code=\"939\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"917\" width=\"0.597\" height=\"0.681\" italic=\"0.088\" />\n  <Char code=\"918\" width=\"0.611\" height=\"0.684\" italic=\"0.089\" />\n  <Char code=\"919\" width=\"0.708\" height=\"0.684\" italic=\"0.049\" />\n  <Char code=\"920\" width=\"0.778\" height=\"0.707\" depth=\"0.022\" italic=\"0.026\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"921\" width=\"0.278\" height=\"0.684\" italic=\"0.049\" />\n  <Char code=\"922\" width=\"0.694\" height=\"0.684\" italic=\"0.089\" >\n    <Kern code=\"927\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"923\" width=\"0.611\" height=\"0.684\" >\n    <Kern code=\"927\" val=\"-0.033\"/>\n    <Kern code=\"933\" val=\"-0.1\"/>\n    <Kern code=\"939\" val=\"-0.1\"/>\n  </Char>\n  <Char code=\"924\" width=\"0.875\" height=\"0.684\" italic=\"0.044\" />\n  <Char code=\"925\" width=\"0.708\" height=\"0.684\" italic=\"0.047\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"926\" width=\"0.667\" height=\"0.679\" italic=\"0.096\" />\n  <Char code=\"927\" width=\"0.736\" height=\"0.706\" depth=\"0.021\" italic=\"0.026\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"931\" val=\"-0.056\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"928\" width=\"0.708\" height=\"0.681\" italic=\"0.048\" />\n  <Char code=\"929\" width=\"0.639\" height=\"0.685\" italic=\"0.051\" >\n    <Kern code=\"913\" val=\"-0.167\"/>\n    <Kern code=\"8124\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"931\" width=\"0.722\" height=\"0.684\" italic=\"0.089\" >\n    <Kern code=\"913\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"932\" width=\"0.68\" height=\"0.679\" italic=\"0.107\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"933\" width=\"0.778\" height=\"0.707\" italic=\"0.064\" >\n    <Kern code=\"913\" val=\"-0.139\"/>\n    <Kern code=\"916\" val=\"-0.139\"/>\n    <Kern code=\"923\" val=\"-0.139\"/>\n    <Kern code=\"8124\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"934\" width=\"0.722\" height=\"0.684\" italic=\"0.021\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"935\" width=\"0.667\" height=\"0.684\" italic=\"0.088\" />\n  <Char code=\"936\" width=\"0.778\" height=\"0.684\" italic=\"0.072\" >\n    <Kern code=\"913\" val=\"-0.122\"/>\n    <Kern code=\"8124\" val=\"-0.122\"/>\n  </Char>\n  <Char code=\"937\" width=\"0.722\" height=\"0.706\" italic=\"0.046\" />\n  <Char code=\"938\" width=\"0.278\" height=\"0.833\" italic=\"0.168\" />\n  <Char code=\"939\" width=\"0.778\" height=\"0.833\" italic=\"0.064\" >\n    <Kern code=\"913\" val=\"-0.139\"/>\n    <Kern code=\"916\" val=\"-0.139\"/>\n    <Kern code=\"923\" val=\"-0.139\"/>\n    <Kern code=\"8124\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"940\" width=\"0.5\" height=\"0.695\" depth=\"0.011\" italic=\"0.065\" />\n  <Char code=\"941\" width=\"0.43\" height=\"0.695\" depth=\"0.022\" italic=\"0.042\" />\n  <Char code=\"942\" width=\"0.5\" height=\"0.695\" depth=\"0.272\" italic=\"0.022\" />\n  <Char code=\"943\" width=\"0.25\" height=\"0.695\" depth=\"0.011\" italic=\"0.099\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"944\" width=\"0.5\" height=\"0.695\" depth=\"0.011\" italic=\"0.013\" />\n  <Char code=\"945\" width=\"0.5\" height=\"0.443\" depth=\"0.011\" italic=\"0.065\" />\n  <Char code=\"946\" width=\"0.5\" height=\"0.706\" depth=\"0.272\" italic=\"0.03\" />\n  <Char code=\"947\" width=\"0.555\" height=\"0.443\" depth=\"0.216\" italic=\"0.044\" />\n  <Char code=\"948\" width=\"0.472\" height=\"0.652\" depth=\"0.01\" italic=\"0.05\" />\n  <Char code=\"949\" width=\"0.43\" height=\"0.453\" depth=\"0.022\" italic=\"0.042\" />\n  <Char code=\"950\" width=\"0.472\" height=\"0.718\" depth=\"0.153\" italic=\"0.089\" />\n  <Char code=\"951\" width=\"0.5\" height=\"0.453\" depth=\"0.272\" italic=\"0.011\" />\n  <Char code=\"952\" width=\"0.569\" height=\"0.707\" depth=\"0.012\" italic=\"0.031\" />\n  <Char code=\"953\" width=\"0.25\" height=\"0.443\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"954\" width=\"0.528\" height=\"0.458\" depth=\"0.026\" italic=\"0.05\" />\n  <Char code=\"955\" width=\"0.5\" height=\"0.698\" depth=\"0.011\" />\n  <Char code=\"956\" width=\"0.522\" height=\"0.453\" depth=\"0.267\" italic=\"0.018\" />\n  <Char code=\"957\" width=\"0.472\" height=\"0.443\" depth=\"0.01\" italic=\"0.022\" />\n  <Char code=\"958\" width=\"0.472\" height=\"0.718\" depth=\"0.152\" italic=\"0.088\" />\n  <Char code=\"959\" width=\"0.528\" height=\"0.442\" depth=\"0.011\" italic=\"0.009\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"960\" width=\"0.514\" height=\"0.432\" depth=\"0.011\" italic=\"0.048\" />\n  <Char code=\"961\" width=\"0.472\" height=\"0.443\" depth=\"0.266\" italic=\"0.009\" />\n  <Char code=\"962\" width=\"0.444\" height=\"0.443\" depth=\"0.124\" italic=\"0.044\" />\n  <Char code=\"963\" width=\"0.569\" height=\"0.431\" depth=\"0.01\" italic=\"0.061\" />\n  <Char code=\"964\" width=\"0.458\" height=\"0.432\" depth=\"0.011\" italic=\"0.048\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"969\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"974\" val=\"-0.028\"/>\n    <Kern code=\"7936\" val=\"-0.028\"/>\n    <Kern code=\"7937\" val=\"-0.028\"/>\n    <Kern code=\"7940\" val=\"-0.028\"/>\n    <Kern code=\"7941\" val=\"-0.028\"/>\n    <Kern code=\"7942\" val=\"-0.028\"/>\n    <Kern code=\"7943\" val=\"-0.028\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8032\" val=\"-0.028\"/>\n    <Kern code=\"8033\" val=\"-0.028\"/>\n    <Kern code=\"8036\" val=\"-0.028\"/>\n    <Kern code=\"8037\" val=\"-0.028\"/>\n    <Kern code=\"8038\" val=\"-0.028\"/>\n    <Kern code=\"8039\" val=\"-0.028\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8060\" val=\"-0.028\"/>\n    <Kern code=\"8064\" val=\"-0.028\"/>\n    <Kern code=\"8065\" val=\"-0.028\"/>\n    <Kern code=\"8068\" val=\"-0.028\"/>\n    <Kern code=\"8069\" val=\"-0.028\"/>\n    <Kern code=\"8070\" val=\"-0.028\"/>\n    <Kern code=\"8071\" val=\"-0.028\"/>\n    <Kern code=\"8096\" val=\"-0.028\"/>\n    <Kern code=\"8097\" val=\"-0.028\"/>\n    <Kern code=\"8100\" val=\"-0.028\"/>\n    <Kern code=\"8101\" val=\"-0.028\"/>\n    <Kern code=\"8102\" val=\"-0.028\"/>\n    <Kern code=\"8103\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8178\" val=\"-0.028\"/>\n    <Kern code=\"8180\" val=\"-0.028\"/>\n    <Kern code=\"8182\" val=\"-0.028\"/>\n    <Kern code=\"8183\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"965\" width=\"0.5\" height=\"0.456\" depth=\"0.011\" italic=\"0.013\" />\n  <Char code=\"966\" width=\"0.583\" height=\"0.454\" depth=\"0.272\" italic=\"0.012\" />\n  <Char code=\"967\" width=\"0.555\" height=\"0.445\" depth=\"0.263\" italic=\"0.051\" />\n  <Char code=\"968\" width=\"0.583\" height=\"0.718\" depth=\"0.272\" italic=\"0.021\" />\n  <Char code=\"969\" width=\"0.667\" height=\"0.453\" depth=\"0.011\" italic=\"0.01\" />\n  <Char code=\"970\" width=\"0.25\" height=\"0.626\" depth=\"0.011\" italic=\"0.12\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"971\" width=\"0.5\" height=\"0.626\" depth=\"0.011\" italic=\"0.013\" />\n  <Char code=\"972\" width=\"0.528\" height=\"0.695\" depth=\"0.011\" italic=\"0.009\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"973\" width=\"0.5\" height=\"0.695\" depth=\"0.011\" italic=\"0.013\" />\n  <Char code=\"974\" width=\"0.667\" height=\"0.695\" depth=\"0.011\" italic=\"0.01\" />\n  <Char code=\"984\" width=\"0.5\" height=\"0.695\" italic=\"0.072\" />\n  <Char code=\"985\" width=\"0.5\" height=\"0.601\" depth=\"0.064\" italic=\"0.042\" />\n  <Char code=\"986\" width=\"0.778\" height=\"0.679\" />\n  <Char code=\"987\" width=\"0.5\" height=\"0.454\" italic=\"0.04\" />\n  <Char code=\"988\" width=\"0.569\" height=\"0.681\" italic=\"0.101\" />\n  <Char code=\"989\" width=\"0.5\" height=\"0.432\" depth=\"0.25\" italic=\"0.028\" />\n  <Char code=\"991\" width=\"0.389\" height=\"0.563\" depth=\"0.106\" italic=\"0.005\" />\n  <Char code=\"992\" width=\"0.639\" height=\"0.683\" />\n  <Char code=\"993\" width=\"0.722\" height=\"0.696\" />\n  <Char code=\"7936\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.065\" />\n  <Char code=\"7937\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.065\" />\n  <Char code=\"7938\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.065\" />\n  <Char code=\"7939\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.065\" />\n  <Char code=\"7940\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.065\" />\n  <Char code=\"7941\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.065\" />\n  <Char code=\"7942\" width=\"0.5\" height=\"0.695\" depth=\"0.011\" italic=\"0.067\" />\n  <Char code=\"7943\" width=\"0.5\" height=\"0.695\" depth=\"0.011\" italic=\"0.067\" />\n  <Char code=\"7952\" width=\"0.43\" height=\"0.696\" depth=\"0.022\" italic=\"0.042\" />\n  <Char code=\"7953\" width=\"0.43\" height=\"0.696\" depth=\"0.022\" italic=\"0.042\" />\n  <Char code=\"7954\" width=\"0.43\" height=\"0.696\" depth=\"0.022\" italic=\"0.048\" />\n  <Char code=\"7955\" width=\"0.43\" height=\"0.696\" depth=\"0.022\" italic=\"0.048\" />\n  <Char code=\"7956\" width=\"0.43\" height=\"0.696\" depth=\"0.022\" italic=\"0.083\" />\n  <Char code=\"7957\" width=\"0.43\" height=\"0.696\" depth=\"0.022\" italic=\"0.083\" />\n  <Char code=\"7968\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.011\" />\n  <Char code=\"7969\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.011\" />\n  <Char code=\"7970\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.029\" />\n  <Char code=\"7971\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.029\" />\n  <Char code=\"7972\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.064\" />\n  <Char code=\"7973\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.064\" />\n  <Char code=\"7974\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.079\" />\n  <Char code=\"7975\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.079\" />\n  <Char code=\"7984\" width=\"0.25\" height=\"0.696\" depth=\"0.011\" italic=\"0.071\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7985\" width=\"0.25\" height=\"0.696\" depth=\"0.011\" italic=\"0.022\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7986\" width=\"0.25\" height=\"0.696\" depth=\"0.011\" italic=\"0.106\" />\n  <Char code=\"7987\" width=\"0.25\" height=\"0.696\" depth=\"0.011\" italic=\"0.106\" />\n  <Char code=\"7988\" width=\"0.25\" height=\"0.696\" depth=\"0.011\" italic=\"0.141\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7989\" width=\"0.25\" height=\"0.696\" depth=\"0.011\" italic=\"0.141\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7990\" width=\"0.25\" height=\"0.696\" depth=\"0.011\" italic=\"0.155\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7991\" width=\"0.25\" height=\"0.696\" depth=\"0.011\" italic=\"0.155\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8000\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" italic=\"0.009\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8001\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" italic=\"0.009\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8002\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" italic=\"0.009\" />\n  <Char code=\"8003\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" italic=\"0.009\" />\n  <Char code=\"8004\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" italic=\"0.034\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8005\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" italic=\"0.034\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8016\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.013\" />\n  <Char code=\"8017\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.013\" />\n  <Char code=\"8018\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.013\" />\n  <Char code=\"8019\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.013\" />\n  <Char code=\"8020\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.013\" />\n  <Char code=\"8021\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.013\" />\n  <Char code=\"8022\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.026\" />\n  <Char code=\"8023\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.026\" />\n  <Char code=\"8032\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" italic=\"0.01\" />\n  <Char code=\"8033\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" italic=\"0.01\" />\n  <Char code=\"8034\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" italic=\"0.01\" />\n  <Char code=\"8035\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" italic=\"0.01\" />\n  <Char code=\"8036\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" italic=\"0.01\" />\n  <Char code=\"8037\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" italic=\"0.01\" />\n  <Char code=\"8038\" width=\"0.667\" height=\"0.695\" depth=\"0.011\" italic=\"0.035\" />\n  <Char code=\"8039\" width=\"0.667\" height=\"0.695\" depth=\"0.011\" italic=\"0.035\" />\n  <Char code=\"8048\" width=\"0.5\" height=\"0.695\" depth=\"0.011\" italic=\"0.065\" />\n  <Char code=\"8050\" width=\"0.43\" height=\"0.695\" depth=\"0.022\" italic=\"0.042\" />\n  <Char code=\"8052\" width=\"0.5\" height=\"0.695\" depth=\"0.272\" italic=\"0.011\" />\n  <Char code=\"8054\" width=\"0.25\" height=\"0.695\" depth=\"0.011\" italic=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8056\" width=\"0.528\" height=\"0.695\" depth=\"0.011\" italic=\"0.009\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8058\" width=\"0.5\" height=\"0.695\" depth=\"0.011\" italic=\"0.013\" />\n  <Char code=\"8060\" width=\"0.667\" height=\"0.695\" depth=\"0.011\" italic=\"0.01\" />\n  <Char code=\"8064\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.065\" />\n  <Char code=\"8065\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.065\" />\n  <Char code=\"8066\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.065\" />\n  <Char code=\"8067\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.065\" />\n  <Char code=\"8068\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.065\" />\n  <Char code=\"8069\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.065\" />\n  <Char code=\"8070\" width=\"0.5\" height=\"0.695\" depth=\"0.238\" italic=\"0.067\" />\n  <Char code=\"8071\" width=\"0.5\" height=\"0.695\" depth=\"0.238\" italic=\"0.067\" />\n  <Char code=\"8080\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.011\" />\n  <Char code=\"8081\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.011\" />\n  <Char code=\"8082\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.029\" />\n  <Char code=\"8083\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.029\" />\n  <Char code=\"8084\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.064\" />\n  <Char code=\"8085\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.064\" />\n  <Char code=\"8086\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.079\" />\n  <Char code=\"8087\" width=\"0.5\" height=\"0.696\" depth=\"0.272\" italic=\"0.079\" />\n  <Char code=\"8096\" width=\"0.667\" height=\"0.696\" depth=\"0.238\" italic=\"0.01\" />\n  <Char code=\"8097\" width=\"0.667\" height=\"0.696\" depth=\"0.238\" italic=\"0.01\" />\n  <Char code=\"8098\" width=\"0.667\" height=\"0.696\" depth=\"0.238\" italic=\"0.01\" />\n  <Char code=\"8099\" width=\"0.667\" height=\"0.696\" depth=\"0.238\" italic=\"0.01\" />\n  <Char code=\"8100\" width=\"0.667\" height=\"0.696\" depth=\"0.238\" italic=\"0.01\" />\n  <Char code=\"8101\" width=\"0.667\" height=\"0.696\" depth=\"0.238\" italic=\"0.01\" />\n  <Char code=\"8102\" width=\"0.667\" height=\"0.695\" depth=\"0.238\" italic=\"0.035\" />\n  <Char code=\"8103\" width=\"0.667\" height=\"0.695\" depth=\"0.238\" italic=\"0.035\" />\n  <Char code=\"8114\" width=\"0.5\" height=\"0.695\" depth=\"0.238\" italic=\"0.065\" />\n  <Char code=\"8115\" width=\"0.5\" height=\"0.443\" depth=\"0.238\" italic=\"0.065\" />\n  <Char code=\"8116\" width=\"0.5\" height=\"0.695\" depth=\"0.238\" italic=\"0.065\" />\n  <Char code=\"8118\" width=\"0.5\" height=\"0.627\" depth=\"0.011\" italic=\"0.065\" />\n  <Char code=\"8119\" width=\"0.5\" height=\"0.627\" depth=\"0.238\" italic=\"0.065\" />\n  <Char code=\"8124\" width=\"0.667\" height=\"0.685\" depth=\"0.238\" >\n    <Kern code=\"920\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.083\"/>\n    <Kern code=\"932\" val=\"-0.083\"/>\n    <Kern code=\"933\" val=\"-0.139\"/>\n    <Kern code=\"934\" val=\"-0.083\"/>\n    <Kern code=\"936\" val=\"-0.122\"/>\n    <Kern code=\"939\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"8126\" width=\"0.222\" height=\"0.158\" depth=\"0.156\" />\n  <Char code=\"8127\" width=\"0.222\" height=\"0.696\" italic=\"0.117\" >\n    <Kern code=\"913\" val=\"-0.139\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.139\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8128\" width=\"0.333\" height=\"0.627\" italic=\"0.132\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n  </Char>\n  <Char code=\"8129\" width=\"0.444\" height=\"0.695\" italic=\"0.091\" />\n  <Char code=\"8130\" width=\"0.5\" height=\"0.695\" depth=\"0.272\" italic=\"0.011\" />\n  <Char code=\"8131\" width=\"0.5\" height=\"0.453\" depth=\"0.272\" italic=\"0.011\" />\n  <Char code=\"8132\" width=\"0.5\" height=\"0.695\" depth=\"0.272\" italic=\"0.022\" />\n  <Char code=\"8134\" width=\"0.5\" height=\"0.626\" depth=\"0.272\" italic=\"0.064\" />\n  <Char code=\"8135\" width=\"0.5\" height=\"0.626\" depth=\"0.272\" italic=\"0.064\" />\n  <Char code=\"8140\" width=\"0.708\" height=\"0.684\" depth=\"0.238\" italic=\"0.049\" />\n  <Char code=\"8141\" width=\"0.278\" height=\"0.696\" italic=\"0.124\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8142\" width=\"0.278\" height=\"0.696\" italic=\"0.159\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8143\" width=\"0.333\" height=\"0.695\" italic=\"0.146\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n  </Char>\n  <Char code=\"8146\" width=\"0.25\" height=\"0.695\" depth=\"0.011\" italic=\"0.08\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8150\" width=\"0.25\" height=\"0.627\" depth=\"0.011\" italic=\"0.141\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8151\" width=\"0.25\" height=\"0.696\" depth=\"0.011\" italic=\"0.155\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8157\" width=\"0.278\" height=\"0.696\" italic=\"0.124\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8158\" width=\"0.278\" height=\"0.696\" italic=\"0.159\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8159\" width=\"0.333\" height=\"0.695\" italic=\"0.146\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n  </Char>\n  <Char code=\"8162\" width=\"0.5\" height=\"0.695\" depth=\"0.011\" italic=\"0.013\" />\n  <Char code=\"8164\" width=\"0.472\" height=\"0.696\" depth=\"0.266\" italic=\"0.009\" />\n  <Char code=\"8165\" width=\"0.472\" height=\"0.696\" depth=\"0.266\" italic=\"0.009\" />\n  <Char code=\"8166\" width=\"0.5\" height=\"0.627\" depth=\"0.011\" italic=\"0.013\" />\n  <Char code=\"8167\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.026\" />\n  <Char code=\"8173\" width=\"0.278\" height=\"0.695\" italic=\"0.098\" />\n  <Char code=\"8175\" width=\"0.167\" height=\"0.695\" italic=\"0.112\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8178\" width=\"0.667\" height=\"0.695\" depth=\"0.238\" italic=\"0.01\" />\n  <Char code=\"8179\" width=\"0.667\" height=\"0.453\" depth=\"0.238\" italic=\"0.01\" />\n  <Char code=\"8180\" width=\"0.667\" height=\"0.695\" depth=\"0.238\" italic=\"0.01\" />\n  <Char code=\"8182\" width=\"0.667\" height=\"0.627\" depth=\"0.011\" italic=\"0.021\" />\n  <Char code=\"8183\" width=\"0.667\" height=\"0.627\" depth=\"0.238\" italic=\"0.021\" />\n  <Char code=\"8188\" width=\"0.722\" height=\"0.706\" depth=\"0.238\" italic=\"0.046\" />\n  <Char code=\"8190\" width=\"0.222\" height=\"0.696\" italic=\"0.068\" >\n    <Kern code=\"913\" val=\"-0.167\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.167\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8217\" width=\"0.278\" height=\"0.695\" italic=\"0.057\" >\n  </Char>\n  <Char code=\"9001\" width=\"0.389\" height=\"0.752\" depth=\"0.249\" italic=\"0.099\" />\n  <Char code=\"9002\" width=\"0.389\" height=\"0.751\" depth=\"0.249\" />\n</Font>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/greek/fcsrpg.xml",
    "content": "<?xml version='1.0'?>\n<Font name=\"fcsrpg.ttf\" id=\"fcsrpg\" space=\"0.239\" xHeight=\"0.443\" quad=\"1\" unicode=\"204\" itVersion=\"fcsropg\" boldVersion=\"fcsbpg\" ttVersion=\"fctrpg\">\n  <Char code=\"32\" width=\"0.239\" height=\"0.0\" />\n  <Char code=\"168\" width=\"0.222\" height=\"0.603\" italic=\"0.052\" />\n  <Char code=\"884\" width=\"0.194\" height=\"0.695\" />\n  <Char code=\"885\" width=\"0.194\" height=\"0.001\" depth=\"0.21\" italic=\"0.003\" />\n  <Char code=\"890\" width=\"0.111\" height=\"-0.064\" depth=\"0.238\" />\n  <Char code=\"900\" width=\"0.167\" height=\"0.695\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"901\" width=\"0.278\" height=\"0.695\" />\n  <Char code=\"903\" width=\"0.278\" height=\"0.431\" />\n  <Char code=\"912\" width=\"0.25\" height=\"0.695\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"913\" width=\"0.667\" height=\"0.685\" >\n    <Kern code=\"920\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.083\"/>\n    <Kern code=\"932\" val=\"-0.083\"/>\n    <Kern code=\"933\" val=\"-0.139\"/>\n    <Kern code=\"934\" val=\"-0.083\"/>\n    <Kern code=\"936\" val=\"-0.122\"/>\n    <Kern code=\"939\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"914\" width=\"0.667\" height=\"0.684\" />\n  <Char code=\"915\" width=\"0.542\" height=\"0.681\" >\n    <Kern code=\"913\" val=\"-0.133\"/>\n    <Kern code=\"916\" val=\"-0.111\"/>\n    <Kern code=\"923\" val=\"-0.122\"/>\n    <Kern code=\"8124\" val=\"-0.133\"/>\n  </Char>\n  <Char code=\"916\" width=\"0.833\" height=\"0.685\" >\n    <Kern code=\"927\" val=\"-0.033\"/>\n    <Kern code=\"933\" val=\"-0.139\"/>\n    <Kern code=\"939\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"917\" width=\"0.597\" height=\"0.681\" />\n  <Char code=\"918\" width=\"0.611\" height=\"0.684\" />\n  <Char code=\"919\" width=\"0.708\" height=\"0.684\" />\n  <Char code=\"920\" width=\"0.778\" height=\"0.706\" depth=\"0.021\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"921\" width=\"0.278\" height=\"0.684\" />\n  <Char code=\"922\" width=\"0.694\" height=\"0.684\" >\n    <Kern code=\"927\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"923\" width=\"0.611\" height=\"0.685\" >\n    <Kern code=\"927\" val=\"-0.033\"/>\n    <Kern code=\"933\" val=\"-0.1\"/>\n    <Kern code=\"939\" val=\"-0.1\"/>\n  </Char>\n  <Char code=\"924\" width=\"0.875\" height=\"0.684\" />\n  <Char code=\"925\" width=\"0.708\" height=\"0.684\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"926\" width=\"0.667\" height=\"0.678\" />\n  <Char code=\"927\" width=\"0.736\" height=\"0.707\" depth=\"0.021\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"931\" val=\"-0.056\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"928\" width=\"0.708\" height=\"0.681\" />\n  <Char code=\"929\" width=\"0.639\" height=\"0.685\" >\n    <Kern code=\"913\" val=\"-0.167\"/>\n    <Kern code=\"8124\" val=\"-0.167\"/>\n  </Char>\n  <Char code=\"931\" width=\"0.722\" height=\"0.684\" >\n    <Kern code=\"913\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"932\" width=\"0.68\" height=\"0.678\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"933\" width=\"0.778\" height=\"0.707\" >\n    <Kern code=\"913\" val=\"-0.139\"/>\n    <Kern code=\"916\" val=\"-0.139\"/>\n    <Kern code=\"923\" val=\"-0.139\"/>\n    <Kern code=\"8124\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"934\" width=\"0.722\" height=\"0.684\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"935\" width=\"0.667\" height=\"0.684\" />\n  <Char code=\"936\" width=\"0.778\" height=\"0.684\" >\n    <Kern code=\"913\" val=\"-0.122\"/>\n    <Kern code=\"8124\" val=\"-0.122\"/>\n  </Char>\n  <Char code=\"937\" width=\"0.722\" height=\"0.707\" />\n  <Char code=\"938\" width=\"0.278\" height=\"0.833\" italic=\"0.001\" />\n  <Char code=\"939\" width=\"0.778\" height=\"0.833\" >\n    <Kern code=\"913\" val=\"-0.139\"/>\n    <Kern code=\"916\" val=\"-0.139\"/>\n    <Kern code=\"923\" val=\"-0.139\"/>\n    <Kern code=\"8124\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"940\" width=\"0.5\" height=\"0.695\" depth=\"0.011\" italic=\"0.045\" />\n  <Char code=\"941\" width=\"0.43\" height=\"0.695\" depth=\"0.022\" />\n  <Char code=\"942\" width=\"0.5\" height=\"0.695\" depth=\"0.271\" />\n  <Char code=\"943\" width=\"0.25\" height=\"0.695\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"944\" width=\"0.5\" height=\"0.695\" depth=\"0.01\" />\n  <Char code=\"945\" width=\"0.5\" height=\"0.443\" depth=\"0.011\" italic=\"0.045\" />\n  <Char code=\"946\" width=\"0.5\" height=\"0.707\" depth=\"0.271\" />\n  <Char code=\"947\" width=\"0.555\" height=\"0.444\" depth=\"0.216\" />\n  <Char code=\"948\" width=\"0.472\" height=\"0.652\" depth=\"0.011\" />\n  <Char code=\"949\" width=\"0.43\" height=\"0.453\" depth=\"0.022\" />\n  <Char code=\"950\" width=\"0.472\" height=\"0.718\" depth=\"0.153\" />\n  <Char code=\"951\" width=\"0.5\" height=\"0.454\" depth=\"0.271\" />\n  <Char code=\"952\" width=\"0.569\" height=\"0.707\" depth=\"0.011\" />\n  <Char code=\"953\" width=\"0.25\" height=\"0.442\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"954\" width=\"0.528\" height=\"0.457\" depth=\"0.025\" />\n  <Char code=\"955\" width=\"0.5\" height=\"0.697\" depth=\"0.011\" />\n  <Char code=\"956\" width=\"0.522\" height=\"0.453\" depth=\"0.266\" />\n  <Char code=\"957\" width=\"0.472\" height=\"0.443\" depth=\"0.01\" />\n  <Char code=\"958\" width=\"0.472\" height=\"0.718\" depth=\"0.152\" />\n  <Char code=\"959\" width=\"0.528\" height=\"0.443\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"960\" width=\"0.514\" height=\"0.432\" depth=\"0.01\" italic=\"0.009\" />\n  <Char code=\"961\" width=\"0.472\" height=\"0.442\" depth=\"0.266\" />\n  <Char code=\"962\" width=\"0.444\" height=\"0.443\" depth=\"0.124\" />\n  <Char code=\"963\" width=\"0.569\" height=\"0.432\" depth=\"0.01\" />\n  <Char code=\"964\" width=\"0.458\" height=\"0.432\" depth=\"0.01\" >\n    <Kern code=\"940\" val=\"-0.028\"/>\n    <Kern code=\"945\" val=\"-0.028\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"969\" val=\"-0.028\"/>\n    <Kern code=\"972\" val=\"-0.028\"/>\n    <Kern code=\"974\" val=\"-0.028\"/>\n    <Kern code=\"7936\" val=\"-0.028\"/>\n    <Kern code=\"7937\" val=\"-0.028\"/>\n    <Kern code=\"7940\" val=\"-0.028\"/>\n    <Kern code=\"7941\" val=\"-0.028\"/>\n    <Kern code=\"7942\" val=\"-0.028\"/>\n    <Kern code=\"7943\" val=\"-0.028\"/>\n    <Kern code=\"8000\" val=\"-0.028\"/>\n    <Kern code=\"8001\" val=\"-0.028\"/>\n    <Kern code=\"8004\" val=\"-0.028\"/>\n    <Kern code=\"8005\" val=\"-0.028\"/>\n    <Kern code=\"8032\" val=\"-0.028\"/>\n    <Kern code=\"8033\" val=\"-0.028\"/>\n    <Kern code=\"8036\" val=\"-0.028\"/>\n    <Kern code=\"8037\" val=\"-0.028\"/>\n    <Kern code=\"8038\" val=\"-0.028\"/>\n    <Kern code=\"8039\" val=\"-0.028\"/>\n    <Kern code=\"8048\" val=\"-0.028\"/>\n    <Kern code=\"8056\" val=\"-0.028\"/>\n    <Kern code=\"8060\" val=\"-0.028\"/>\n    <Kern code=\"8064\" val=\"-0.028\"/>\n    <Kern code=\"8065\" val=\"-0.028\"/>\n    <Kern code=\"8068\" val=\"-0.028\"/>\n    <Kern code=\"8069\" val=\"-0.028\"/>\n    <Kern code=\"8070\" val=\"-0.028\"/>\n    <Kern code=\"8071\" val=\"-0.028\"/>\n    <Kern code=\"8096\" val=\"-0.028\"/>\n    <Kern code=\"8097\" val=\"-0.028\"/>\n    <Kern code=\"8100\" val=\"-0.028\"/>\n    <Kern code=\"8101\" val=\"-0.028\"/>\n    <Kern code=\"8102\" val=\"-0.028\"/>\n    <Kern code=\"8103\" val=\"-0.028\"/>\n    <Kern code=\"8114\" val=\"-0.028\"/>\n    <Kern code=\"8116\" val=\"-0.028\"/>\n    <Kern code=\"8118\" val=\"-0.028\"/>\n    <Kern code=\"8119\" val=\"-0.028\"/>\n    <Kern code=\"8178\" val=\"-0.028\"/>\n    <Kern code=\"8180\" val=\"-0.028\"/>\n    <Kern code=\"8182\" val=\"-0.028\"/>\n    <Kern code=\"8183\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"965\" width=\"0.5\" height=\"0.457\" depth=\"0.01\" />\n  <Char code=\"966\" width=\"0.583\" height=\"0.454\" depth=\"0.272\" />\n  <Char code=\"967\" width=\"0.555\" height=\"0.444\" depth=\"0.262\" />\n  <Char code=\"968\" width=\"0.583\" height=\"0.717\" depth=\"0.271\" />\n  <Char code=\"969\" width=\"0.667\" height=\"0.453\" depth=\"0.011\" />\n  <Char code=\"970\" width=\"0.25\" height=\"0.626\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"971\" width=\"0.5\" height=\"0.626\" depth=\"0.01\" />\n  <Char code=\"972\" width=\"0.528\" height=\"0.695\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"973\" width=\"0.5\" height=\"0.695\" depth=\"0.01\" />\n  <Char code=\"974\" width=\"0.667\" height=\"0.695\" depth=\"0.011\" />\n  <Char code=\"984\" width=\"0.5\" height=\"0.696\" />\n  <Char code=\"985\" width=\"0.5\" height=\"0.601\" depth=\"0.064\" />\n  <Char code=\"986\" width=\"0.778\" height=\"0.679\" />\n  <Char code=\"987\" width=\"0.5\" height=\"0.454\" />\n  <Char code=\"988\" width=\"0.569\" height=\"0.681\" />\n  <Char code=\"989\" width=\"0.5\" height=\"0.432\" depth=\"0.249\" />\n  <Char code=\"991\" width=\"0.389\" height=\"0.563\" depth=\"0.107\" />\n  <Char code=\"992\" width=\"0.639\" height=\"0.683\" />\n  <Char code=\"993\" width=\"0.722\" height=\"0.695\" />\n  <Char code=\"7936\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.045\" />\n  <Char code=\"7937\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.045\" />\n  <Char code=\"7938\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.045\" />\n  <Char code=\"7939\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.045\" />\n  <Char code=\"7940\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.045\" />\n  <Char code=\"7941\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.045\" />\n  <Char code=\"7942\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.045\" />\n  <Char code=\"7943\" width=\"0.5\" height=\"0.696\" depth=\"0.011\" italic=\"0.045\" />\n  <Char code=\"7952\" width=\"0.43\" height=\"0.696\" depth=\"0.022\" />\n  <Char code=\"7953\" width=\"0.43\" height=\"0.696\" depth=\"0.022\" />\n  <Char code=\"7954\" width=\"0.43\" height=\"0.696\" depth=\"0.022\" />\n  <Char code=\"7955\" width=\"0.43\" height=\"0.696\" depth=\"0.022\" />\n  <Char code=\"7956\" width=\"0.43\" height=\"0.696\" depth=\"0.022\" />\n  <Char code=\"7957\" width=\"0.43\" height=\"0.696\" depth=\"0.022\" />\n  <Char code=\"7968\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"7969\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"7970\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"7971\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"7972\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"7973\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"7974\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"7975\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"7984\" width=\"0.25\" height=\"0.696\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7985\" width=\"0.25\" height=\"0.696\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7986\" width=\"0.25\" height=\"0.696\" depth=\"0.01\" italic=\"0.003\" />\n  <Char code=\"7987\" width=\"0.25\" height=\"0.696\" depth=\"0.01\" italic=\"0.003\" />\n  <Char code=\"7988\" width=\"0.25\" height=\"0.696\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7989\" width=\"0.25\" height=\"0.696\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7990\" width=\"0.25\" height=\"0.695\" depth=\"0.01\" italic=\"0.008\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"7991\" width=\"0.25\" height=\"0.695\" depth=\"0.01\" italic=\"0.008\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8000\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8001\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8002\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8003\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8004\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8005\" width=\"0.528\" height=\"0.696\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8016\" width=\"0.5\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8017\" width=\"0.5\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8018\" width=\"0.5\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8019\" width=\"0.5\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8020\" width=\"0.5\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8021\" width=\"0.5\" height=\"0.696\" depth=\"0.01\" />\n  <Char code=\"8022\" width=\"0.5\" height=\"0.695\" depth=\"0.01\" />\n  <Char code=\"8023\" width=\"0.5\" height=\"0.695\" depth=\"0.01\" />\n  <Char code=\"8032\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8033\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8034\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8035\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8036\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8037\" width=\"0.667\" height=\"0.696\" depth=\"0.011\" />\n  <Char code=\"8038\" width=\"0.667\" height=\"0.695\" depth=\"0.011\" />\n  <Char code=\"8039\" width=\"0.667\" height=\"0.695\" depth=\"0.011\" />\n  <Char code=\"8048\" width=\"0.5\" height=\"0.695\" depth=\"0.011\" italic=\"0.045\" />\n  <Char code=\"8050\" width=\"0.43\" height=\"0.695\" depth=\"0.022\" />\n  <Char code=\"8052\" width=\"0.5\" height=\"0.695\" depth=\"0.271\" />\n  <Char code=\"8054\" width=\"0.25\" height=\"0.695\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8056\" width=\"0.528\" height=\"0.695\" depth=\"0.011\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"955\" val=\"-0.028\"/>\n    <Kern code=\"957\" val=\"-0.022\"/>\n    <Kern code=\"964\" val=\"-0.022\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8058\" width=\"0.5\" height=\"0.695\" depth=\"0.01\" />\n  <Char code=\"8060\" width=\"0.667\" height=\"0.695\" depth=\"0.011\" />\n  <Char code=\"8064\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.045\" />\n  <Char code=\"8065\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.045\" />\n  <Char code=\"8066\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.045\" />\n  <Char code=\"8067\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.045\" />\n  <Char code=\"8068\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.045\" />\n  <Char code=\"8069\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.045\" />\n  <Char code=\"8070\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.045\" />\n  <Char code=\"8071\" width=\"0.5\" height=\"0.696\" depth=\"0.238\" italic=\"0.045\" />\n  <Char code=\"8080\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"8081\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"8082\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"8083\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"8084\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"8085\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"8086\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"8087\" width=\"0.5\" height=\"0.696\" depth=\"0.271\" />\n  <Char code=\"8096\" width=\"0.667\" height=\"0.696\" depth=\"0.238\" />\n  <Char code=\"8097\" width=\"0.667\" height=\"0.696\" depth=\"0.238\" />\n  <Char code=\"8098\" width=\"0.667\" height=\"0.696\" depth=\"0.238\" />\n  <Char code=\"8099\" width=\"0.667\" height=\"0.696\" depth=\"0.238\" />\n  <Char code=\"8100\" width=\"0.667\" height=\"0.696\" depth=\"0.238\" />\n  <Char code=\"8101\" width=\"0.667\" height=\"0.696\" depth=\"0.238\" />\n  <Char code=\"8102\" width=\"0.667\" height=\"0.695\" depth=\"0.238\" />\n  <Char code=\"8103\" width=\"0.667\" height=\"0.695\" depth=\"0.238\" />\n  <Char code=\"8114\" width=\"0.5\" height=\"0.695\" depth=\"0.238\" italic=\"0.045\" />\n  <Char code=\"8115\" width=\"0.5\" height=\"0.443\" depth=\"0.238\" italic=\"0.045\" />\n  <Char code=\"8116\" width=\"0.5\" height=\"0.695\" depth=\"0.238\" italic=\"0.045\" />\n  <Char code=\"8118\" width=\"0.5\" height=\"0.627\" depth=\"0.011\" italic=\"0.045\" />\n  <Char code=\"8119\" width=\"0.5\" height=\"0.627\" depth=\"0.238\" italic=\"0.045\" />\n  <Char code=\"8124\" width=\"0.667\" height=\"0.685\" depth=\"0.238\" >\n    <Kern code=\"920\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.083\"/>\n    <Kern code=\"932\" val=\"-0.083\"/>\n    <Kern code=\"933\" val=\"-0.139\"/>\n    <Kern code=\"934\" val=\"-0.083\"/>\n    <Kern code=\"936\" val=\"-0.122\"/>\n    <Kern code=\"939\" val=\"-0.139\"/>\n  </Char>\n  <Char code=\"8126\" width=\"0.222\" height=\"0.158\" depth=\"0.156\" />\n  <Char code=\"8127\" width=\"0.222\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.139\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.139\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8128\" width=\"0.333\" height=\"0.626\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n  </Char>\n  <Char code=\"8129\" width=\"0.444\" height=\"0.696\" />\n  <Char code=\"8130\" width=\"0.5\" height=\"0.695\" depth=\"0.271\" />\n  <Char code=\"8131\" width=\"0.5\" height=\"0.454\" depth=\"0.271\" />\n  <Char code=\"8132\" width=\"0.5\" height=\"0.695\" depth=\"0.271\" />\n  <Char code=\"8134\" width=\"0.5\" height=\"0.627\" depth=\"0.271\" />\n  <Char code=\"8135\" width=\"0.5\" height=\"0.627\" depth=\"0.271\" />\n  <Char code=\"8140\" width=\"0.708\" height=\"0.684\" depth=\"0.238\" />\n  <Char code=\"8141\" width=\"0.278\" height=\"0.696\" italic=\"0.021\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8142\" width=\"0.278\" height=\"0.696\" italic=\"0.012\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8143\" width=\"0.333\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n  </Char>\n  <Char code=\"8146\" width=\"0.25\" height=\"0.695\" depth=\"0.01\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8150\" width=\"0.25\" height=\"0.628\" depth=\"0.01\" italic=\"0.008\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8151\" width=\"0.25\" height=\"0.695\" depth=\"0.01\" italic=\"0.008\" >\n    <Kern code=\"947\" val=\"-0.028\"/>\n    <Kern code=\"951\" val=\"-0.017\"/>\n    <Kern code=\"952\" val=\"-0.017\"/>\n    <Kern code=\"957\" val=\"-0.056\"/>\n    <Kern code=\"959\" val=\"-0.028\"/>\n    <Kern code=\"962\" val=\"-0.028\"/>\n    <Kern code=\"963\" val=\"-0.028\"/>\n    <Kern code=\"964\" val=\"-0.028\"/>\n    <Kern code=\"967\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8157\" width=\"0.278\" height=\"0.696\" italic=\"0.021\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8158\" width=\"0.278\" height=\"0.696\" italic=\"0.012\" >\n    <Kern code=\"913\" val=\"-0.083\"/>\n    <Kern code=\"927\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.083\"/>\n  </Char>\n  <Char code=\"8159\" width=\"0.333\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n  </Char>\n  <Char code=\"8162\" width=\"0.5\" height=\"0.695\" depth=\"0.01\" />\n  <Char code=\"8164\" width=\"0.472\" height=\"0.696\" depth=\"0.266\" />\n  <Char code=\"8165\" width=\"0.472\" height=\"0.696\" depth=\"0.266\" />\n  <Char code=\"8166\" width=\"0.5\" height=\"0.626\" depth=\"0.01\" />\n  <Char code=\"8167\" width=\"0.5\" height=\"0.695\" depth=\"0.01\" />\n  <Char code=\"8173\" width=\"0.278\" height=\"0.695\" />\n  <Char code=\"8175\" width=\"0.167\" height=\"0.695\" italic=\"0.009\" >\n    <Kern code=\"913\" val=\"-0.111\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.111\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8178\" width=\"0.667\" height=\"0.695\" depth=\"0.238\" />\n  <Char code=\"8179\" width=\"0.667\" height=\"0.453\" depth=\"0.238\" />\n  <Char code=\"8180\" width=\"0.667\" height=\"0.695\" depth=\"0.238\" />\n  <Char code=\"8182\" width=\"0.667\" height=\"0.626\" depth=\"0.011\" />\n  <Char code=\"8183\" width=\"0.667\" height=\"0.626\" depth=\"0.238\" />\n  <Char code=\"8188\" width=\"0.722\" height=\"0.707\" depth=\"0.238\" />\n  <Char code=\"8190\" width=\"0.222\" height=\"0.696\" >\n    <Kern code=\"913\" val=\"-0.167\"/>\n    <Kern code=\"927\" val=\"-0.056\"/>\n    <Kern code=\"937\" val=\"-0.028\"/>\n    <Kern code=\"8124\" val=\"-0.167\"/>\n    <Kern code=\"8188\" val=\"-0.028\"/>\n  </Char>\n  <Char code=\"8217\" width=\"0.278\" height=\"0.696\" >\n  </Char>\n  <Char code=\"9001\" width=\"0.389\" height=\"0.751\" depth=\"0.249\" />\n  <Char code=\"9002\" width=\"0.389\" height=\"0.751\" depth=\"0.25\" />\n</Font>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/greek/fctrpg.xml",
    "content": "<?xml version='1.0'?>\n<Font name=\"fctrpg.ttf\" id=\"fctrpg\" space=\"0.525\" xHeight=\"0.438\" quad=\"1\" unicode=\"204\">\n  <Char code=\"32\" width=\"0.525\" height=\"0.0\" />\n  <Char code=\"168\" width=\"0.525\" height=\"0.607\" />\n  <Char code=\"884\" width=\"0.525\" height=\"0.613\" />\n  <Char code=\"885\" width=\"0.525\" height=\"0.001\" depth=\"0.14\" />\n  <Char code=\"890\" width=\"0.525\" height=\"-0.053\" depth=\"0.184\" />\n  <Char code=\"900\" width=\"0.525\" height=\"0.613\" />\n  <Char code=\"901\" width=\"0.525\" height=\"0.613\" />\n  <Char code=\"903\" width=\"0.525\" height=\"0.431\" />\n  <Char code=\"912\" width=\"0.525\" height=\"0.613\" depth=\"0.006\" />\n  <Char code=\"913\" width=\"0.525\" height=\"0.653\" />\n  <Char code=\"914\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"915\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"916\" width=\"0.525\" height=\"0.653\" />\n  <Char code=\"917\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"918\" width=\"0.525\" height=\"0.64\" />\n  <Char code=\"919\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"920\" width=\"0.525\" height=\"0.652\" depth=\"0.011\" />\n  <Char code=\"921\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"922\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"923\" width=\"0.525\" height=\"0.653\" />\n  <Char code=\"924\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"925\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"926\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"927\" width=\"0.525\" height=\"0.652\" depth=\"0.011\" />\n  <Char code=\"928\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"929\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"931\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"932\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"933\" width=\"0.525\" height=\"0.651\" />\n  <Char code=\"934\" width=\"0.525\" height=\"0.64\" />\n  <Char code=\"935\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"936\" width=\"0.525\" height=\"0.64\" />\n  <Char code=\"937\" width=\"0.525\" height=\"0.651\" />\n  <Char code=\"938\" width=\"0.525\" height=\"0.783\" />\n  <Char code=\"939\" width=\"0.525\" height=\"0.783\" />\n  <Char code=\"940\" width=\"0.525\" height=\"0.613\" depth=\"0.006\" italic=\"0.002\" />\n  <Char code=\"941\" width=\"0.525\" height=\"0.613\" depth=\"0.011\" />\n  <Char code=\"942\" width=\"0.525\" height=\"0.613\" depth=\"0.232\" />\n  <Char code=\"943\" width=\"0.525\" height=\"0.613\" depth=\"0.006\" />\n  <Char code=\"944\" width=\"0.525\" height=\"0.669\" depth=\"0.006\" />\n  <Char code=\"945\" width=\"0.525\" height=\"0.438\" depth=\"0.006\" italic=\"0.002\" />\n  <Char code=\"946\" width=\"0.525\" height=\"0.647\" depth=\"0.232\" />\n  <Char code=\"947\" width=\"0.525\" height=\"0.438\" depth=\"0.177\" />\n  <Char code=\"948\" width=\"0.525\" height=\"0.637\" depth=\"0.005\" />\n  <Char code=\"949\" width=\"0.525\" height=\"0.443\" depth=\"0.011\" />\n  <Char code=\"950\" width=\"0.525\" height=\"0.651\" depth=\"0.133\" />\n  <Char code=\"951\" width=\"0.525\" height=\"0.442\" depth=\"0.232\" />\n  <Char code=\"952\" width=\"0.525\" height=\"0.652\" depth=\"0.011\" />\n  <Char code=\"953\" width=\"0.525\" height=\"0.437\" depth=\"0.006\" />\n  <Char code=\"954\" width=\"0.525\" height=\"0.445\" depth=\"0.013\" />\n  <Char code=\"955\" width=\"0.525\" height=\"0.642\" depth=\"0.005\" />\n  <Char code=\"956\" width=\"0.525\" height=\"0.442\" depth=\"0.227\" />\n  <Char code=\"957\" width=\"0.525\" height=\"0.438\" depth=\"0.005\" />\n  <Char code=\"958\" width=\"0.525\" height=\"0.651\" depth=\"0.133\" />\n  <Char code=\"959\" width=\"0.525\" height=\"0.438\" depth=\"0.006\" />\n  <Char code=\"960\" width=\"0.525\" height=\"0.432\" depth=\"0.006\" />\n  <Char code=\"961\" width=\"0.525\" height=\"0.437\" depth=\"0.221\" />\n  <Char code=\"962\" width=\"0.525\" height=\"0.437\" depth=\"0.111\" />\n  <Char code=\"963\" width=\"0.525\" height=\"0.437\" depth=\"0.005\" />\n  <Char code=\"964\" width=\"0.525\" height=\"0.431\" depth=\"0.006\" />\n  <Char code=\"965\" width=\"0.525\" height=\"0.443\" depth=\"0.006\" />\n  <Char code=\"966\" width=\"0.525\" height=\"0.443\" depth=\"0.232\" />\n  <Char code=\"967\" width=\"0.525\" height=\"0.439\" depth=\"0.229\" />\n  <Char code=\"968\" width=\"0.525\" height=\"0.651\" depth=\"0.232\" />\n  <Char code=\"969\" width=\"0.525\" height=\"0.442\" depth=\"0.006\" />\n  <Char code=\"970\" width=\"0.525\" height=\"0.641\" depth=\"0.006\" />\n  <Char code=\"971\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"972\" width=\"0.525\" height=\"0.613\" depth=\"0.006\" />\n  <Char code=\"973\" width=\"0.525\" height=\"0.613\" depth=\"0.006\" />\n  <Char code=\"974\" width=\"0.525\" height=\"0.613\" depth=\"0.006\" />\n  <Char code=\"984\" width=\"0.525\" height=\"0.647\" />\n  <Char code=\"985\" width=\"0.525\" height=\"0.609\" depth=\"0.055\" />\n  <Char code=\"986\" width=\"0.525\" height=\"0.641\" depth=\"0.028\" />\n  <Char code=\"987\" width=\"0.525\" height=\"0.443\" depth=\"0.018\" />\n  <Char code=\"988\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"989\" width=\"0.525\" height=\"0.432\" depth=\"0.221\" />\n  <Char code=\"991\" width=\"0.525\" height=\"0.542\" depth=\"0.101\" />\n  <Char code=\"992\" width=\"0.525\" height=\"0.667\" />\n  <Char code=\"993\" width=\"0.525\" height=\"0.64\" depth=\"0.011\" />\n  <Char code=\"7936\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" italic=\"0.002\" />\n  <Char code=\"7937\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" italic=\"0.002\" />\n  <Char code=\"7938\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" italic=\"0.002\" />\n  <Char code=\"7939\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" italic=\"0.002\" />\n  <Char code=\"7940\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" italic=\"0.002\" />\n  <Char code=\"7941\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" italic=\"0.002\" />\n  <Char code=\"7942\" width=\"0.525\" height=\"0.696\" depth=\"0.006\" italic=\"0.002\" />\n  <Char code=\"7943\" width=\"0.525\" height=\"0.696\" depth=\"0.006\" italic=\"0.002\" />\n  <Char code=\"7952\" width=\"0.525\" height=\"0.64\" depth=\"0.011\" />\n  <Char code=\"7953\" width=\"0.525\" height=\"0.64\" depth=\"0.011\" />\n  <Char code=\"7954\" width=\"0.525\" height=\"0.64\" depth=\"0.011\" />\n  <Char code=\"7955\" width=\"0.525\" height=\"0.64\" depth=\"0.011\" />\n  <Char code=\"7956\" width=\"0.525\" height=\"0.64\" depth=\"0.011\" />\n  <Char code=\"7957\" width=\"0.525\" height=\"0.64\" depth=\"0.011\" />\n  <Char code=\"7968\" width=\"0.525\" height=\"0.64\" depth=\"0.232\" />\n  <Char code=\"7969\" width=\"0.525\" height=\"0.64\" depth=\"0.232\" />\n  <Char code=\"7970\" width=\"0.525\" height=\"0.64\" depth=\"0.232\" />\n  <Char code=\"7971\" width=\"0.525\" height=\"0.64\" depth=\"0.232\" />\n  <Char code=\"7972\" width=\"0.525\" height=\"0.64\" depth=\"0.232\" />\n  <Char code=\"7973\" width=\"0.525\" height=\"0.64\" depth=\"0.232\" />\n  <Char code=\"7974\" width=\"0.525\" height=\"0.696\" depth=\"0.232\" />\n  <Char code=\"7975\" width=\"0.525\" height=\"0.696\" depth=\"0.232\" />\n  <Char code=\"7984\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"7985\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"7986\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"7987\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"7988\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"7989\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"7990\" width=\"0.525\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"7991\" width=\"0.525\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8000\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8001\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8002\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8003\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8004\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8005\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8016\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8017\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8018\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8019\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8020\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8021\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8022\" width=\"0.525\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8023\" width=\"0.525\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8032\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8033\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8034\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8035\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8036\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8037\" width=\"0.525\" height=\"0.64\" depth=\"0.006\" />\n  <Char code=\"8038\" width=\"0.525\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8039\" width=\"0.525\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8048\" width=\"0.525\" height=\"0.613\" depth=\"0.006\" italic=\"0.002\" />\n  <Char code=\"8050\" width=\"0.525\" height=\"0.614\" depth=\"0.011\" />\n  <Char code=\"8052\" width=\"0.525\" height=\"0.614\" depth=\"0.232\" />\n  <Char code=\"8054\" width=\"0.525\" height=\"0.613\" depth=\"0.006\" />\n  <Char code=\"8056\" width=\"0.525\" height=\"0.614\" depth=\"0.006\" />\n  <Char code=\"8058\" width=\"0.525\" height=\"0.613\" depth=\"0.006\" />\n  <Char code=\"8060\" width=\"0.525\" height=\"0.614\" depth=\"0.006\" />\n  <Char code=\"8064\" width=\"0.525\" height=\"0.64\" depth=\"0.184\" italic=\"0.002\" />\n  <Char code=\"8065\" width=\"0.525\" height=\"0.64\" depth=\"0.184\" italic=\"0.002\" />\n  <Char code=\"8066\" width=\"0.525\" height=\"0.64\" depth=\"0.184\" italic=\"0.002\" />\n  <Char code=\"8067\" width=\"0.525\" height=\"0.64\" depth=\"0.184\" italic=\"0.002\" />\n  <Char code=\"8068\" width=\"0.525\" height=\"0.64\" depth=\"0.184\" italic=\"0.002\" />\n  <Char code=\"8069\" width=\"0.525\" height=\"0.64\" depth=\"0.184\" italic=\"0.002\" />\n  <Char code=\"8070\" width=\"0.525\" height=\"0.696\" depth=\"0.184\" italic=\"0.002\" />\n  <Char code=\"8071\" width=\"0.525\" height=\"0.696\" depth=\"0.184\" italic=\"0.002\" />\n  <Char code=\"8080\" width=\"0.525\" height=\"0.64\" depth=\"0.232\" />\n  <Char code=\"8081\" width=\"0.525\" height=\"0.64\" depth=\"0.232\" />\n  <Char code=\"8082\" width=\"0.525\" height=\"0.64\" depth=\"0.232\" />\n  <Char code=\"8083\" width=\"0.525\" height=\"0.64\" depth=\"0.232\" />\n  <Char code=\"8084\" width=\"0.525\" height=\"0.64\" depth=\"0.232\" />\n  <Char code=\"8085\" width=\"0.525\" height=\"0.64\" depth=\"0.232\" />\n  <Char code=\"8086\" width=\"0.525\" height=\"0.696\" depth=\"0.232\" />\n  <Char code=\"8087\" width=\"0.525\" height=\"0.696\" depth=\"0.232\" />\n  <Char code=\"8096\" width=\"0.525\" height=\"0.64\" depth=\"0.184\" />\n  <Char code=\"8097\" width=\"0.525\" height=\"0.64\" depth=\"0.184\" />\n  <Char code=\"8098\" width=\"0.525\" height=\"0.64\" depth=\"0.184\" />\n  <Char code=\"8099\" width=\"0.525\" height=\"0.64\" depth=\"0.184\" />\n  <Char code=\"8100\" width=\"0.525\" height=\"0.64\" depth=\"0.184\" />\n  <Char code=\"8101\" width=\"0.525\" height=\"0.64\" depth=\"0.184\" />\n  <Char code=\"8102\" width=\"0.525\" height=\"0.696\" depth=\"0.184\" />\n  <Char code=\"8103\" width=\"0.525\" height=\"0.696\" depth=\"0.184\" />\n  <Char code=\"8114\" width=\"0.525\" height=\"0.613\" depth=\"0.184\" italic=\"0.002\" />\n  <Char code=\"8115\" width=\"0.525\" height=\"0.438\" depth=\"0.184\" italic=\"0.002\" />\n  <Char code=\"8116\" width=\"0.525\" height=\"0.613\" depth=\"0.184\" italic=\"0.002\" />\n  <Char code=\"8118\" width=\"0.525\" height=\"0.641\" depth=\"0.006\" italic=\"0.002\" />\n  <Char code=\"8119\" width=\"0.525\" height=\"0.641\" depth=\"0.184\" italic=\"0.002\" />\n  <Char code=\"8124\" width=\"0.525\" height=\"0.653\" depth=\"0.184\" />\n  <Char code=\"8126\" width=\"0.525\" height=\"0.137\" depth=\"0.135\" />\n  <Char code=\"8127\" width=\"0.525\" height=\"0.64\" />\n  <Char code=\"8128\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"8129\" width=\"0.525\" height=\"0.696\" />\n  <Char code=\"8130\" width=\"0.525\" height=\"0.614\" depth=\"0.232\" />\n  <Char code=\"8131\" width=\"0.525\" height=\"0.442\" depth=\"0.232\" />\n  <Char code=\"8132\" width=\"0.525\" height=\"0.613\" depth=\"0.232\" />\n  <Char code=\"8134\" width=\"0.525\" height=\"0.641\" depth=\"0.232\" />\n  <Char code=\"8135\" width=\"0.525\" height=\"0.641\" depth=\"0.232\" />\n  <Char code=\"8140\" width=\"0.525\" height=\"0.641\" depth=\"0.184\" />\n  <Char code=\"8141\" width=\"0.525\" height=\"0.64\" >\n    <Kern code=\"913\" val=\"-0.087\"/>\n    <Kern code=\"927\" val=\"-0.029\"/>\n    <Kern code=\"8124\" val=\"-0.087\"/>\n  </Char>\n  <Char code=\"8142\" width=\"0.525\" height=\"0.64\" />\n  <Char code=\"8143\" width=\"0.525\" height=\"0.696\" />\n  <Char code=\"8146\" width=\"0.525\" height=\"0.613\" depth=\"0.006\" />\n  <Char code=\"8150\" width=\"0.525\" height=\"0.641\" depth=\"0.006\" />\n  <Char code=\"8151\" width=\"0.525\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8157\" width=\"0.525\" height=\"0.64\" >\n    <Kern code=\"913\" val=\"-0.087\"/>\n    <Kern code=\"927\" val=\"-0.029\"/>\n    <Kern code=\"8124\" val=\"-0.087\"/>\n  </Char>\n  <Char code=\"8158\" width=\"0.525\" height=\"0.64\" />\n  <Char code=\"8159\" width=\"0.525\" height=\"0.696\" />\n  <Char code=\"8162\" width=\"0.525\" height=\"0.668\" depth=\"0.006\" />\n  <Char code=\"8164\" width=\"0.525\" height=\"0.64\" depth=\"0.221\" />\n  <Char code=\"8165\" width=\"0.525\" height=\"0.64\" depth=\"0.221\" />\n  <Char code=\"8166\" width=\"0.525\" height=\"0.641\" depth=\"0.006\" />\n  <Char code=\"8167\" width=\"0.525\" height=\"0.696\" depth=\"0.006\" />\n  <Char code=\"8173\" width=\"0.525\" height=\"0.613\" />\n  <Char code=\"8175\" width=\"0.525\" height=\"0.614\" />\n  <Char code=\"8178\" width=\"0.525\" height=\"0.614\" depth=\"0.184\" />\n  <Char code=\"8179\" width=\"0.525\" height=\"0.442\" depth=\"0.184\" />\n  <Char code=\"8180\" width=\"0.525\" height=\"0.613\" depth=\"0.184\" />\n  <Char code=\"8182\" width=\"0.525\" height=\"0.641\" depth=\"0.006\" />\n  <Char code=\"8183\" width=\"0.525\" height=\"0.641\" depth=\"0.184\" />\n  <Char code=\"8188\" width=\"0.525\" height=\"0.651\" depth=\"0.184\" />\n  <Char code=\"8190\" width=\"0.525\" height=\"0.64\" />\n  <Char code=\"8217\" width=\"0.525\" height=\"0.641\" />\n  <Char code=\"9001\" width=\"0.525\" height=\"0.695\" depth=\"0.083\" />\n  <Char code=\"9002\" width=\"0.525\" height=\"0.695\" depth=\"0.083\" />\n</Font>"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/greek/greek.map.xml",
    "content": "<?xml version='1.0'?>\n<SymbolMappings>\n  <SymbolMapping name=\"ʹ\" ch=\"884\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"͵\" ch=\"885\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ͺ\" ch=\"890\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"΄\" ch=\"900\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"΅\" ch=\"901\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"·\" ch=\"903\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ΐ\" ch=\"912\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Α\" ch=\"913\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Β\" ch=\"914\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Γ\" ch=\"915\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Δ\" ch=\"916\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ε\" ch=\"917\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ζ\" ch=\"918\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Η\" ch=\"919\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Θ\" ch=\"920\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ι\" ch=\"921\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Κ\" ch=\"922\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Λ\" ch=\"923\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Μ\" ch=\"924\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ν\" ch=\"925\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ξ\" ch=\"926\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ο\" ch=\"927\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Π\" ch=\"928\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ρ\" ch=\"929\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Σ\" ch=\"931\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Τ\" ch=\"932\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Υ\" ch=\"933\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Φ\" ch=\"934\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Χ\" ch=\"935\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ψ\" ch=\"936\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ω\" ch=\"937\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ϊ\" ch=\"938\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ϋ\" ch=\"939\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ά\" ch=\"940\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"έ\" ch=\"941\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ή\" ch=\"942\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ί\" ch=\"943\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ΰ\" ch=\"944\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"α\" ch=\"945\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"β\" ch=\"946\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"γ\" ch=\"947\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"δ\" ch=\"948\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ε\" ch=\"949\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ζ\" ch=\"950\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"η\" ch=\"951\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"θ\" ch=\"952\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ι\" ch=\"953\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"κ\" ch=\"954\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"λ\" ch=\"955\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"μ\" ch=\"956\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ν\" ch=\"957\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ξ\" ch=\"958\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ο\" ch=\"959\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"π\" ch=\"960\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ρ\" ch=\"961\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ς\" ch=\"962\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"σ\" ch=\"963\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"τ\" ch=\"964\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"υ\" ch=\"965\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"φ\" ch=\"966\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"χ\" ch=\"967\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ψ\" ch=\"968\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ω\" ch=\"969\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ϊ\" ch=\"970\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ϋ\" ch=\"971\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ό\" ch=\"972\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ύ\" ch=\"973\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ώ\" ch=\"974\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ϑ\" ch=\"977\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ϙ\" ch=\"984\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ϙ\" ch=\"985\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ϛ\" ch=\"986\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ϛ\" ch=\"987\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ϝ\" ch=\"988\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ϝ\" ch=\"989\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ϟ\" ch=\"991\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"Ϡ\" ch=\"992\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ϡ\" ch=\"993\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἀ\" ch=\"7936\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἁ\" ch=\"7937\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἂ\" ch=\"7938\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἃ\" ch=\"7939\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἄ\" ch=\"7940\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἅ\" ch=\"7941\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἆ\" ch=\"7942\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἇ\" ch=\"7943\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἐ\" ch=\"7952\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἑ\" ch=\"7953\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἒ\" ch=\"7954\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἓ\" ch=\"7955\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἔ\" ch=\"7956\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἕ\" ch=\"7957\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἠ\" ch=\"7968\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἡ\" ch=\"7969\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἢ\" ch=\"7970\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἣ\" ch=\"7971\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἤ\" ch=\"7972\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἥ\" ch=\"7973\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἦ\" ch=\"7974\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἧ\" ch=\"7975\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἰ\" ch=\"7984\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἱ\" ch=\"7985\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἲ\" ch=\"7986\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἳ\" ch=\"7987\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἴ\" ch=\"7988\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἵ\" ch=\"7989\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἶ\" ch=\"7990\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ἷ\" ch=\"7991\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὀ\" ch=\"8000\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὁ\" ch=\"8001\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὂ\" ch=\"8002\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὃ\" ch=\"8003\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὄ\" ch=\"8004\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὅ\" ch=\"8005\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὐ\" ch=\"8016\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὑ\" ch=\"8017\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὒ\" ch=\"8018\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὓ\" ch=\"8019\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὔ\" ch=\"8020\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὕ\" ch=\"8021\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὖ\" ch=\"8022\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὗ\" ch=\"8023\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὠ\" ch=\"8032\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὡ\" ch=\"8033\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὢ\" ch=\"8034\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὣ\" ch=\"8035\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὤ\" ch=\"8036\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὥ\" ch=\"8037\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὦ\" ch=\"8038\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὧ\" ch=\"8039\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὰ\" ch=\"8048\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὲ\" ch=\"8050\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὴ\" ch=\"8052\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὶ\" ch=\"8054\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὸ\" ch=\"8056\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὺ\" ch=\"8058\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ὼ\" ch=\"8060\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾀ\" ch=\"8064\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾁ\" ch=\"8065\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾂ\" ch=\"8066\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾃ\" ch=\"8067\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾄ\" ch=\"8068\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾅ\" ch=\"8069\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾆ\" ch=\"8070\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾇ\" ch=\"8071\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾐ\" ch=\"8080\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾑ\" ch=\"8081\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾒ\" ch=\"8082\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾓ\" ch=\"8083\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾔ\" ch=\"8084\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾕ\" ch=\"8085\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾖ\" ch=\"8086\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾗ\" ch=\"8087\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾠ\" ch=\"8096\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾡ\" ch=\"8097\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾢ\" ch=\"8098\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾣ\" ch=\"8099\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾤ\" ch=\"8100\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾥ\" ch=\"8101\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾦ\" ch=\"8102\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾧ\" ch=\"8103\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾲ\" ch=\"8114\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾳ\" ch=\"8115\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾴ\" ch=\"8116\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾶ\" ch=\"8118\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾷ\" ch=\"8119\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ᾼ\" ch=\"8124\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ι\" ch=\"8126\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"᾿\" ch=\"8127\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"῀\" ch=\"8128\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"῁\" ch=\"8129\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῂ\" ch=\"8130\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῃ\" ch=\"8131\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῄ\" ch=\"8132\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῆ\" ch=\"8134\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῇ\" ch=\"8135\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῌ\" ch=\"8140\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"῍\" ch=\"8141\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"῎\" ch=\"8142\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"῏\" ch=\"8143\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῒ\" ch=\"8146\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῖ\" ch=\"8150\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῗ\" ch=\"8151\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"῝\" ch=\"8157\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"῞\" ch=\"8158\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"῟\" ch=\"8159\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῢ\" ch=\"8162\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῤ\" ch=\"8164\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῥ\" ch=\"8165\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῦ\" ch=\"8166\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῧ\" ch=\"8167\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"῭\" ch=\"8173\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"`\" ch=\"8175\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῲ\" ch=\"8178\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῳ\" ch=\"8179\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῴ\" ch=\"8180\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῶ\" ch=\"8182\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῷ\" ch=\"8183\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"ῼ\" ch=\"8188\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"῾\" ch=\"8190\" fontId=\"fcmrpg\"/>\n  <SymbolMapping name=\"’\" ch=\"8217\" fontId=\"fcmrpg\"/>\n</SymbolMappings>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/greek/language_greek.xml",
    "content": "<?xml version='1.0'?>\n<!--\n  language_greek.xml\n-->\n\n<TeXFont>\n\n<SymbolMappings>\n  <Mapping include=\"greek.map.xml\" />\n</SymbolMappings>\n\n<FontDescriptions>\n  <Metrics include=\"fcmbipg.xml\" />\n  <Metrics include=\"fcmbpg.xml\" />\n  <Metrics include=\"fcmripg.xml\" />\n  <Metrics include=\"fcmrpg.xml\" />\n  <Metrics include=\"fcsbpg.xml\" />\n  <Metrics include=\"fcsropg.xml\" />\n  <Metrics include=\"fcsrpg.xml\" />\n  <Metrics include=\"fctrpg.xml\" />\n</FontDescriptions>\n\n<TeXSymbols include=\"symbols_greek.xml\" />\n\n<FormulaSettings include=\"mappings_greek.xml\" />\n\n</TeXFont>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/greek/mappings_greek.xml",
    "content": "<?xml version='1.0'?>\n<!--\n  mappings_greek.xml\n-->\n\n<FormulaSettings>\n  <CharacterToSymbolMappings>\n    <Map char=\"&#884;\" symbol=\"ʹ\"/>\n    <Map char=\"&#885;\" symbol=\"͵\"/>\n    <Map char=\"&#890;\" symbol=\"ͺ\"/>\n    <Map char=\"&#900;\" symbol=\"΄\"/>\n    <Map char=\"&#901;\" symbol=\"΅\"/>\n    <Map char=\"&#903;\" symbol=\"·\"/>\n    <Map char=\"&#912;\" symbol=\"ΐ\"/>\n    <Map char=\"&#938;\" symbol=\"Ϊ\"/>\n    <Map char=\"&#939;\" symbol=\"Ϋ\"/>\n    <Map char=\"&#940;\" symbol=\"ά\"/>\n    <Map char=\"&#941;\" symbol=\"έ\"/>\n    <Map char=\"&#942;\" symbol=\"ή\"/>\n    <Map char=\"&#943;\" symbol=\"ί\"/>\n    <Map char=\"&#944;\" symbol=\"ΰ\"/>\n    <Map char=\"&#970;\" symbol=\"ϊ\"/>\n    <Map char=\"&#971;\" symbol=\"ϋ\"/>\n    <Map char=\"&#972;\" symbol=\"ό\"/>\n    <Map char=\"&#973;\" symbol=\"ύ\"/>\n    <Map char=\"&#974;\" symbol=\"ώ\"/>\n    <Map char=\"&#984;\" symbol=\"Ϙ\"/>\n    <Map char=\"&#985;\" symbol=\"ϙ\"/>\n    <Map char=\"&#986;\" symbol=\"Ϛ\"/>\n    <Map char=\"&#987;\" symbol=\"ϛ\"/>\n    <Map char=\"&#988;\" symbol=\"Ϝ\"/>\n    <Map char=\"&#989;\" symbol=\"ϝ\"/>\n    <Map char=\"&#991;\" symbol=\"ϟ\"/>\n    <Map char=\"&#992;\" symbol=\"Ϡ\"/>\n    <Map char=\"&#993;\" symbol=\"ϡ\"/>\n    <Map char=\"&#7936;\" symbol=\"ἀ\"/>\n    <Map char=\"&#7937;\" symbol=\"ἁ\"/>\n    <Map char=\"&#7938;\" symbol=\"ἂ\"/>\n    <Map char=\"&#7939;\" symbol=\"ἃ\"/>\n    <Map char=\"&#7940;\" symbol=\"ἄ\"/>\n    <Map char=\"&#7941;\" symbol=\"ἅ\"/>\n    <Map char=\"&#7942;\" symbol=\"ἆ\"/>\n    <Map char=\"&#7943;\" symbol=\"ἇ\"/>\n    <Map char=\"&#7952;\" symbol=\"ἐ\"/>\n    <Map char=\"&#7953;\" symbol=\"ἑ\"/>\n    <Map char=\"&#7954;\" symbol=\"ἒ\"/>\n    <Map char=\"&#7955;\" symbol=\"ἓ\"/>\n    <Map char=\"&#7956;\" symbol=\"ἔ\"/>\n    <Map char=\"&#7957;\" symbol=\"ἕ\"/>\n    <Map char=\"&#7968;\" symbol=\"ἠ\"/>\n    <Map char=\"&#7969;\" symbol=\"ἡ\"/>\n    <Map char=\"&#7970;\" symbol=\"ἢ\"/>\n    <Map char=\"&#7971;\" symbol=\"ἣ\"/>\n    <Map char=\"&#7972;\" symbol=\"ἤ\"/>\n    <Map char=\"&#7973;\" symbol=\"ἥ\"/>\n    <Map char=\"&#7974;\" symbol=\"ἦ\"/>\n    <Map char=\"&#7975;\" symbol=\"ἧ\"/>\n    <Map char=\"&#7984;\" symbol=\"ἰ\"/>\n    <Map char=\"&#7985;\" symbol=\"ἱ\"/>\n    <Map char=\"&#7986;\" symbol=\"ἲ\"/>\n    <Map char=\"&#7987;\" symbol=\"ἳ\"/>\n    <Map char=\"&#7988;\" symbol=\"ἴ\"/>\n    <Map char=\"&#7989;\" symbol=\"ἵ\"/>\n    <Map char=\"&#7990;\" symbol=\"ἶ\"/>\n    <Map char=\"&#7991;\" symbol=\"ἷ\"/>\n    <Map char=\"&#8000;\" symbol=\"ὀ\"/>\n    <Map char=\"&#8001;\" symbol=\"ὁ\"/>\n    <Map char=\"&#8002;\" symbol=\"ὂ\"/>\n    <Map char=\"&#8003;\" symbol=\"ὃ\"/>\n    <Map char=\"&#8004;\" symbol=\"ὄ\"/>\n    <Map char=\"&#8005;\" symbol=\"ὅ\"/>\n    <Map char=\"&#8016;\" symbol=\"ὐ\"/>\n    <Map char=\"&#8017;\" symbol=\"ὑ\"/>\n    <Map char=\"&#8018;\" symbol=\"ὒ\"/>\n    <Map char=\"&#8019;\" symbol=\"ὓ\"/>\n    <Map char=\"&#8020;\" symbol=\"ὔ\"/>\n    <Map char=\"&#8021;\" symbol=\"ὕ\"/>\n    <Map char=\"&#8022;\" symbol=\"ὖ\"/>\n    <Map char=\"&#8023;\" symbol=\"ὗ\"/>\n    <Map char=\"&#8032;\" symbol=\"ὠ\"/>\n    <Map char=\"&#8033;\" symbol=\"ὡ\"/>\n    <Map char=\"&#8034;\" symbol=\"ὢ\"/>\n    <Map char=\"&#8035;\" symbol=\"ὣ\"/>\n    <Map char=\"&#8036;\" symbol=\"ὤ\"/>\n    <Map char=\"&#8037;\" symbol=\"ὥ\"/>\n    <Map char=\"&#8038;\" symbol=\"ὦ\"/>\n    <Map char=\"&#8039;\" symbol=\"ὧ\"/>\n    <Map char=\"&#8048;\" symbol=\"ὰ\"/>\n    <Map char=\"&#8050;\" symbol=\"ὲ\"/>\n    <Map char=\"&#8052;\" symbol=\"ὴ\"/>\n    <Map char=\"&#8054;\" symbol=\"ὶ\"/>\n    <Map char=\"&#8056;\" symbol=\"ὸ\"/>\n    <Map char=\"&#8058;\" symbol=\"ὺ\"/>\n    <Map char=\"&#8060;\" symbol=\"ὼ\"/>\n    <Map char=\"&#8064;\" symbol=\"ᾀ\"/>\n    <Map char=\"&#8065;\" symbol=\"ᾁ\"/>\n    <Map char=\"&#8066;\" symbol=\"ᾂ\"/>\n    <Map char=\"&#8067;\" symbol=\"ᾃ\"/>\n    <Map char=\"&#8068;\" symbol=\"ᾄ\"/>\n    <Map char=\"&#8069;\" symbol=\"ᾅ\"/>\n    <Map char=\"&#8070;\" symbol=\"ᾆ\"/>\n    <Map char=\"&#8071;\" symbol=\"ᾇ\"/>\n    <Map char=\"&#8080;\" symbol=\"ᾐ\"/>\n    <Map char=\"&#8081;\" symbol=\"ᾑ\"/>\n    <Map char=\"&#8082;\" symbol=\"ᾒ\"/>\n    <Map char=\"&#8083;\" symbol=\"ᾓ\"/>\n    <Map char=\"&#8084;\" symbol=\"ᾔ\"/>\n    <Map char=\"&#8085;\" symbol=\"ᾕ\"/>\n    <Map char=\"&#8086;\" symbol=\"ᾖ\"/>\n    <Map char=\"&#8087;\" symbol=\"ᾗ\"/>\n    <Map char=\"&#8096;\" symbol=\"ᾠ\"/>\n    <Map char=\"&#8097;\" symbol=\"ᾡ\"/>\n    <Map char=\"&#8098;\" symbol=\"ᾢ\"/>\n    <Map char=\"&#8099;\" symbol=\"ᾣ\"/>\n    <Map char=\"&#8100;\" symbol=\"ᾤ\"/>\n    <Map char=\"&#8101;\" symbol=\"ᾥ\"/>\n    <Map char=\"&#8102;\" symbol=\"ᾦ\"/>\n    <Map char=\"&#8103;\" symbol=\"ᾧ\"/>\n    <Map char=\"&#8114;\" symbol=\"ᾲ\"/>\n    <Map char=\"&#8115;\" symbol=\"ᾳ\"/>\n    <Map char=\"&#8116;\" symbol=\"ᾴ\"/>\n    <Map char=\"&#8118;\" symbol=\"ᾶ\"/>\n    <Map char=\"&#8119;\" symbol=\"ᾷ\"/>\n    <Map char=\"&#8124;\" symbol=\"ᾼ\"/>\n    <Map char=\"&#8125;\" symbol=\"᾿\"/>\n    <Map char=\"&#8126;\" symbol=\"ι\"/>\n    <Map char=\"&#8127;\" symbol=\"᾿\"/>\n    <Map char=\"&#8128;\" symbol=\"῀\"/>\n    <Map char=\"&#8129;\" symbol=\"῁\"/>\n    <Map char=\"&#8130;\" symbol=\"ῂ\"/>\n    <Map char=\"&#8131;\" symbol=\"ῃ\"/>\n    <Map char=\"&#8132;\" symbol=\"ῄ\"/>\n    <Map char=\"&#8134;\" symbol=\"ῆ\"/>\n    <Map char=\"&#8135;\" symbol=\"ῇ\"/>\n    <Map char=\"&#8140;\" symbol=\"ῌ\"/>\n    <Map char=\"&#8141;\" symbol=\"῍\"/>\n    <Map char=\"&#8142;\" symbol=\"῎\"/>\n    <Map char=\"&#8143;\" symbol=\"῏\"/>\n    <Map char=\"&#8146;\" symbol=\"ῒ\"/>\n    <Map char=\"&#8150;\" symbol=\"ῖ\"/>\n    <Map char=\"&#8151;\" symbol=\"ῗ\"/>\n    <Map char=\"&#8157;\" symbol=\"῝\"/>\n    <Map char=\"&#8158;\" symbol=\"῞\"/>\n    <Map char=\"&#8159;\" symbol=\"῟\"/>\n    <Map char=\"&#8162;\" symbol=\"ῢ\"/>\n    <Map char=\"&#8164;\" symbol=\"ῤ\"/>\n    <Map char=\"&#8165;\" symbol=\"ῥ\"/>\n    <Map char=\"&#8166;\" symbol=\"ῦ\"/>\n    <Map char=\"&#8167;\" symbol=\"ῧ\"/>\n    <Map char=\"&#8173;\" symbol=\"῭\"/>\n    <Map char=\"&#8174;\" symbol=\"΅\"/>\n    <Map char=\"&#8175;\" symbol=\"`\"/>\n    <Map char=\"&#8178;\" symbol=\"ῲ\"/>\n    <Map char=\"&#8179;\" symbol=\"ῳ\"/>\n    <Map char=\"&#8180;\" symbol=\"ῴ\"/>\n    <Map char=\"&#8182;\" symbol=\"ῶ\"/>\n    <Map char=\"&#8183;\" symbol=\"ῷ\"/>\n    <Map char=\"&#8188;\" symbol=\"ῼ\"/>\n    <Map char=\"&#8189;\" symbol=\"ʹ\"/>\n    <Map char=\"&#8190;\" symbol=\"῾\"/>\n    <Map char=\"&#8217;\" symbol=\"’\"/>\n  </CharacterToSymbolMappings>\n  \n  <CharacterToFormulaMappings>\n    <Map char=\"&#902;\" formula=\"\\grkaccent{ʹ}{\\phantom{ι}}\\!\\!A\"/>\n    <Map char=\"&#904;\" formula=\"\\grkaccent{ʹ}{\\phantom{ι}}Ε\"/>\n    <Map char=\"&#905;\" formula=\"\\grkaccent{ʹ}{\\phantom{ι}}H\"/>\n    <Map char=\"&#906;\" formula=\"\\grkaccent{ʹ}{\\phantom{ι}}Ι\"/>\n    <Map char=\"&#908;\" formula=\"\\grkaccent{ʹ}{\\phantom{ι}}\\!Ο\"/>\n    <Map char=\"&#910;\" formula=\"\\grkaccent{ʹ}{\\phantom{ι}}Υ\"/>\n    <Map char=\"&#911;\" formula=\"\\grkaccent{ʹ}{\\phantom{ι}}\\!Ω\"/>\n    <Map char=\"&#7944;\" formula=\"’Α\"/>\n    <Map char=\"&#7945;\" formula=\"῾Α\"/>\n    <Map char=\"&#7946;\" formula=\"῍Α\"/>\n    <Map char=\"&#7947;\" formula=\"῝Α\"/>\n    <Map char=\"&#7948;\" formula=\"῎Α\"/>\n    <Map char=\"&#7949;\" formula=\"῞Α\"/>\n    <Map char=\"&#7950;\" formula=\"῏Α\"/>\n    <Map char=\"&#7951;\" formula=\"῟Α\"/>\n    <Map char=\"&#7960;\" formula=\"’Ε\"/>\n    <Map char=\"&#7961;\" formula=\"῾Ε\"/>\n    <Map char=\"&#7962;\" formula=\"῍Ε\"/>\n    <Map char=\"&#7963;\" formula=\"῝Ε\"/>\n    <Map char=\"&#7964;\" formula=\"῎Ε\"/>\n    <Map char=\"&#7965;\" formula=\"῞Ε\"/>\n    <Map char=\"&#7976;\" formula=\"’Η\"/>\n    <Map char=\"&#7977;\" formula=\"῾Η\"/>\n    <Map char=\"&#7978;\" formula=\"῍Η\"/>\n    <Map char=\"&#7979;\" formula=\"῝Η\"/>\n    <Map char=\"&#7980;\" formula=\"῎Η\"/>\n    <Map char=\"&#7981;\" formula=\"῞Η\"/>\n    <Map char=\"&#7982;\" formula=\"῏Η\"/>\n    <Map char=\"&#7983;\" formula=\"῟Η\"/>\n    <Map char=\"&#7992;\" formula=\"’Ι\"/>\n    <Map char=\"&#7993;\" formula=\"῾Ι\"/>\n    <Map char=\"&#7994;\" formula=\"῍Ι\"/>\n    <Map char=\"&#7995;\" formula=\"῝Ι\"/>\n    <Map char=\"&#7996;\" formula=\"῎Ι\"/>\n    <Map char=\"&#7997;\" formula=\"῞Ι\"/>\n    <Map char=\"&#7998;\" formula=\"῏Ι\"/>\n    <Map char=\"&#7999;\" formula=\"῟Ι\"/>\n    <Map char=\"&#8008;\" formula=\"’Ο\"/>\n    <Map char=\"&#8009;\" formula=\"῾Ο\"/>\n    <Map char=\"&#8010;\" formula=\"῍Ο\"/>\n    <Map char=\"&#8011;\" formula=\"῝Ο\"/>\n    <Map char=\"&#8012;\" formula=\"῎Ο\"/>\n    <Map char=\"&#8013;\" formula=\"῞Ο\"/>\n    <Map char=\"&#8025;\" formula=\"῾Υ\"/>\n    <Map char=\"&#8026;\" formula=\"῝Υ\"/>\n    <Map char=\"&#8027;\" formula=\"῞Υ\"/>\n    <Map char=\"&#8028;\" formula=\"῟Υ\"/>\n    <Map char=\"&#8040;\" formula=\"’Ω\"/>\n    <Map char=\"&#8041;\" formula=\"῾Ω\"/>\n    <Map char=\"&#8042;\" formula=\"῍Ω\"/>\n    <Map char=\"&#8043;\" formula=\"῝Ω\"/>\n    <Map char=\"&#8044;\" formula=\"῎Ω\"/>\n    <Map char=\"&#8045;\" formula=\"῞Ω\"/>\n    <Map char=\"&#8046;\" formula=\"῏Ω\"/>\n    <Map char=\"&#8047;\" formula=\"῟Ω\"/>\n    <Map char=\"&#8049;\" formula=\"\\grkaccent{΄}α\"/>\n    <Map char=\"&#8051;\" formula=\"\\grkaccent{΄}ε\"/>\n    <Map char=\"&#8053;\" formula=\"\\grkaccent{΄}η\"/>\n    <Map char=\"&#8055;\" formula=\"\\grkaccent{΄}ι\"/>\n    <Map char=\"&#8057;\" formula=\"\\grkaccent{΄}ο\"/>\n    <Map char=\"&#8059;\" formula=\"\\grkaccent{΄}υ\"/>\n    <Map char=\"&#8061;\" formula=\"\\grkaccent{΄}ω\"/>\n    <Map char=\"&#8072;\" formula=\"’ᾼ\"/>\n    <Map char=\"&#8073;\" formula=\"῾ᾼ\"/>\n    <Map char=\"&#8074;\" formula=\"῍ᾼ\"/>\n    <Map char=\"&#8075;\" formula=\"῝ᾼ\"/>\n    <Map char=\"&#8076;\" formula=\"῎ᾼ\"/>\n    <Map char=\"&#8077;\" formula=\"῞ᾼ\"/>\n    <Map char=\"&#8078;\" formula=\"῏ᾼ\"/>\n    <Map char=\"&#8079;\" formula=\"῟ᾼ\"/>\n    <Map char=\"&#8088;\" formula=\"’ῌ\"/>\n    <Map char=\"&#8089;\" formula=\"῾ῌ\"/>\n    <Map char=\"&#8090;\" formula=\"῍ῌ\"/>\n    <Map char=\"&#8091;\" formula=\"῝ῌ\"/>\n    <Map char=\"&#8092;\" formula=\"῎ῌ\"/>\n    <Map char=\"&#8093;\" formula=\"῞ῌ\"/>\n    <Map char=\"&#8094;\" formula=\"῏ῌ\"/>\n    <Map char=\"&#8095;\" formula=\"῟ῌ\"/>\n    <Map char=\"&#8100;\" formula=\"\\grkaccent{῎}ῳ\"/>\n    <Map char=\"&#8104;\" formula=\"’ῼ\"/>\n    <Map char=\"&#8105;\" formula=\"῾ῼ\"/>\n    <Map char=\"&#8106;\" formula=\"῍ῼ\"/>\n    <Map char=\"&#8107;\" formula=\"῝ῼ\"/>\n    <Map char=\"&#8108;\" formula=\"῎ῼ\"/>\n    <Map char=\"&#8109;\" formula=\"῞ῼ\"/>\n    <Map char=\"&#8110;\" formula=\"῏ῼ\"/>\n    <Map char=\"&#8111;\" formula=\"῟ῼ\"/>\n    <Map char=\"&#8112;\" formula=\"\\u α\"/>\n    <Map char=\"&#8113;\" formula=\"\\= α\"/>\n    <Map char=\"&#8120;\" formula=\"\\u Α\"/>\n    <Map char=\"&#8121;\" formula=\"\\= Α\"/>\n    <Map char=\"&#8122;\" formula=\"\\grkaccent{`}{\\vphantom{ι}}Α\"/>\n    <Map char=\"&#8123;\" formula=\"\\grkaccent{ʹ}{\\vphantom{ι}}\\!\\!Α\"/>\n    <Map char=\"&#8136;\" formula=\"\\grkaccent{`}{\\vphantom{ι}}Ε\"/>\n    <Map char=\"&#8137;\" formula=\"\\grkaccent{ʹ}{\\vphantom{ι}}Ε\"/>\n    <Map char=\"&#8138;\" formula=\"\\grkaccent{`}{\\vphantom{ι}}Η\"/>\n    <Map char=\"&#8139;\" formula=\"\\grkaccent{ʹ}{\\vphantom{ι}}Η\"/>\n    <Map char=\"&#8144;\" formula=\"\\u ι\"/>\n    <Map char=\"&#8145;\" formula=\"\\= ι\"/>\n    <Map char=\"&#8147;\" formula=\"\\grkaccent{΅}ι\"/>\n    <Map char=\"&#8152;\" formula=\"\\u Ι\"/>\n    <Map char=\"&#8153;\" formula=\"\\= Ι\"/>\n    <Map char=\"&#8154;\" formula=\"\\grkaccent{`}{\\phantom{ι}}Ι\"/>\n    <Map char=\"&#8155;\" formula=\"\\grkaccent{ʹ}{\\phantom{ι}}Ι\"/>\n    <Map char=\"&#8160;\" formula=\"\\u υ\"/>\n    <Map char=\"&#8161;\" formula=\"\\= υ\"/>\n    <Map char=\"&#8163;\" formula=\"\\grkaccent{΅}υ\"/>\n    <Map char=\"&#8168;\" formula=\"\\u Υ\"/>\n    <Map char=\"&#8169;\" formula=\"\\= Υ\"/>\n    <Map char=\"&#8170;\" formula=\"\\grkaccent{`}{\\phantom{ι}}Υ\"/>\n    <Map char=\"&#8171;\" formula=\"\\grkaccent{ʹ}{\\phantom{ι}}Υ\"/>\n    <Map char=\"&#8184;\" formula=\"\\grkaccent{`}{\\vphantom{ι}}Ο\"/>\n    <Map char=\"&#8185;\" formula=\"\\grkaccent{ʹ}{\\vphantom{ι}}\\!Ο\"/>\n    <Map char=\"&#8186;\" formula=\"\\grkaccent{`}{\\vphantom{ι}}Ω\"/>\n    <Map char=\"&#8187;\" formula=\"\\grkaccent{ʹ}{\\vphantom{ι}}\\!Ω\"/>\n  </CharacterToFormulaMappings>\n</FormulaSettings>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/resfile/res/greek/symbols_greek.xml",
    "content": "<?xml version='1.0'?>\n<!--\n  symbols_greek.xml\n-->\n\n<TeXSymbols>\n  <Symbol name=\"ʹ\" type=\"acc\"/>\n  <Symbol name=\"͵\" type=\"acc\"/>\n  <Symbol name=\"ͺ\" type=\"acc\"/>\n  <Symbol name=\"΄\" type=\"acc\"/>\n  <Symbol name=\"΅\" type=\"acc\"/>\n  <Symbol name=\"·\" type=\"acc\"/>\n  <Symbol name=\"ΐ\" type=\"ord\"/>\n  <Symbol name=\"Α\" type=\"ord\"/>\n  <Symbol name=\"Β\" type=\"ord\"/>\n  <Symbol name=\"Γ\" type=\"ord\"/>\n  <Symbol name=\"Δ\" type=\"ord\"/>\n  <Symbol name=\"Ε\" type=\"ord\"/>\n  <Symbol name=\"Ζ\" type=\"ord\"/>\n  <Symbol name=\"Η\" type=\"ord\"/>\n  <Symbol name=\"Θ\" type=\"ord\"/>\n  <Symbol name=\"Ι\" type=\"ord\"/>\n  <Symbol name=\"Κ\" type=\"ord\"/>\n  <Symbol name=\"Λ\" type=\"ord\"/>\n  <Symbol name=\"Μ\" type=\"ord\"/>\n  <Symbol name=\"Ν\" type=\"ord\"/>\n  <Symbol name=\"Ξ\" type=\"ord\"/>\n  <Symbol name=\"Ο\" type=\"ord\"/>\n  <Symbol name=\"Π\" type=\"ord\"/>\n  <Symbol name=\"Ρ\" type=\"ord\"/>\n  <Symbol name=\"Σ\" type=\"ord\"/>\n  <Symbol name=\"Τ\" type=\"ord\"/>\n  <Symbol name=\"Υ\" type=\"ord\"/>\n  <Symbol name=\"Φ\" type=\"ord\"/>\n  <Symbol name=\"Χ\" type=\"ord\"/>\n  <Symbol name=\"Ψ\" type=\"ord\"/>\n  <Symbol name=\"Ω\" type=\"ord\"/>\n  <Symbol name=\"Ϊ\" type=\"ord\"/>\n  <Symbol name=\"Ϋ\" type=\"ord\"/>\n  <Symbol name=\"ά\" type=\"ord\"/>\n  <Symbol name=\"έ\" type=\"ord\"/>\n  <Symbol name=\"ή\" type=\"ord\"/>\n  <Symbol name=\"ί\" type=\"ord\"/>\n  <Symbol name=\"ΰ\" type=\"ord\"/>\n  <Symbol name=\"α\" type=\"ord\"/>\n  <Symbol name=\"β\" type=\"ord\"/>\n  <Symbol name=\"γ\" type=\"ord\"/>\n  <Symbol name=\"δ\" type=\"ord\"/>\n  <Symbol name=\"ε\" type=\"ord\"/>\n  <Symbol name=\"ζ\" type=\"ord\"/>\n  <Symbol name=\"η\" type=\"ord\"/>\n  <Symbol name=\"θ\" type=\"ord\"/>\n  <Symbol name=\"ι\" type=\"ord\"/>\n  <Symbol name=\"κ\" type=\"ord\"/>\n  <Symbol name=\"λ\" type=\"ord\"/>\n  <Symbol name=\"μ\" type=\"ord\"/>\n  <Symbol name=\"ν\" type=\"ord\"/>\n  <Symbol name=\"ξ\" type=\"ord\"/>\n  <Symbol name=\"ο\" type=\"ord\"/>\n  <Symbol name=\"π\" type=\"ord\"/>\n  <Symbol name=\"ρ\" type=\"ord\"/>\n  <Symbol name=\"ς\" type=\"ord\"/>\n  <Symbol name=\"σ\" type=\"ord\"/>\n  <Symbol name=\"τ\" type=\"ord\"/>\n  <Symbol name=\"υ\" type=\"ord\"/>\n  <Symbol name=\"φ\" type=\"ord\"/>\n  <Symbol name=\"χ\" type=\"ord\"/>\n  <Symbol name=\"ψ\" type=\"ord\"/>\n  <Symbol name=\"ω\" type=\"ord\"/>\n  <Symbol name=\"ϊ\" type=\"ord\"/>\n  <Symbol name=\"ϋ\" type=\"ord\"/>\n  <Symbol name=\"ό\" type=\"ord\"/>\n  <Symbol name=\"ύ\" type=\"ord\"/>\n  <Symbol name=\"ώ\" type=\"ord\"/>\n  <Symbol name=\"ϑ\" type=\"ord\"/>\n  <Symbol name=\"Ϙ\" type=\"ord\"/>\n  <Symbol name=\"ϙ\" type=\"ord\"/>\n  <Symbol name=\"Ϛ\" type=\"ord\"/>\n  <Symbol name=\"ϛ\" type=\"ord\"/>\n  <Symbol name=\"Ϝ\" type=\"ord\"/>\n  <Symbol name=\"ϝ\" type=\"ord\"/>\n  <Symbol name=\"ϟ\" type=\"ord\"/>\n  <Symbol name=\"Ϡ\" type=\"ord\"/>\n  <Symbol name=\"ϡ\" type=\"ord\"/>\n  <Symbol name=\"ἀ\" type=\"ord\"/>\n  <Symbol name=\"ἁ\" type=\"ord\"/>\n  <Symbol name=\"ἂ\" type=\"ord\"/>\n  <Symbol name=\"ἃ\" type=\"ord\"/>\n  <Symbol name=\"ἄ\" type=\"ord\"/>\n  <Symbol name=\"ἅ\" type=\"ord\"/>\n  <Symbol name=\"ἆ\" type=\"ord\"/>\n  <Symbol name=\"ἇ\" type=\"ord\"/>\n  <Symbol name=\"ἐ\" type=\"ord\"/>\n  <Symbol name=\"ἑ\" type=\"ord\"/>\n  <Symbol name=\"ἒ\" type=\"ord\"/>\n  <Symbol name=\"ἓ\" type=\"ord\"/>\n  <Symbol name=\"ἔ\" type=\"ord\"/>\n  <Symbol name=\"ἕ\" type=\"ord\"/>\n  <Symbol name=\"ἠ\" type=\"ord\"/>\n  <Symbol name=\"ἡ\" type=\"ord\"/>\n  <Symbol name=\"ἢ\" type=\"ord\"/>\n  <Symbol name=\"ἣ\" type=\"ord\"/>\n  <Symbol name=\"ἤ\" type=\"ord\"/>\n  <Symbol name=\"ἥ\" type=\"ord\"/>\n  <Symbol name=\"ἦ\" type=\"ord\"/>\n  <Symbol name=\"ἧ\" type=\"ord\"/>\n  <Symbol name=\"ἰ\" type=\"ord\"/>\n  <Symbol name=\"ἱ\" type=\"ord\"/>\n  <Symbol name=\"ἲ\" type=\"ord\"/>\n  <Symbol name=\"ἳ\" type=\"ord\"/>\n  <Symbol name=\"ἴ\" type=\"ord\"/>\n  <Symbol name=\"ἵ\" type=\"ord\"/>\n  <Symbol name=\"ἶ\" type=\"ord\"/>\n  <Symbol name=\"ἷ\" type=\"ord\"/>\n  <Symbol name=\"ὀ\" type=\"ord\"/>\n  <Symbol name=\"ὁ\" type=\"ord\"/>\n  <Symbol name=\"ὂ\" type=\"ord\"/>\n  <Symbol name=\"ὃ\" type=\"ord\"/>\n  <Symbol name=\"ὄ\" type=\"ord\"/>\n  <Symbol name=\"ὅ\" type=\"ord\"/>\n  <Symbol name=\"ὐ\" type=\"ord\"/>\n  <Symbol name=\"ὑ\" type=\"ord\"/>\n  <Symbol name=\"ὒ\" type=\"ord\"/>\n  <Symbol name=\"ὓ\" type=\"ord\"/>\n  <Symbol name=\"ὔ\" type=\"ord\"/>\n  <Symbol name=\"ὕ\" type=\"ord\"/>\n  <Symbol name=\"ὖ\" type=\"ord\"/>\n  <Symbol name=\"ὗ\" type=\"ord\"/>\n  <Symbol name=\"ὠ\" type=\"ord\"/>\n  <Symbol name=\"ὡ\" type=\"ord\"/>\n  <Symbol name=\"ὢ\" type=\"ord\"/>\n  <Symbol name=\"ὣ\" type=\"ord\"/>\n  <Symbol name=\"ὤ\" type=\"ord\"/>\n  <Symbol name=\"ὥ\" type=\"ord\"/>\n  <Symbol name=\"ὦ\" type=\"ord\"/>\n  <Symbol name=\"ὧ\" type=\"ord\"/>\n  <Symbol name=\"ὰ\" type=\"ord\"/>\n  <Symbol name=\"ὲ\" type=\"ord\"/>\n  <Symbol name=\"ὴ\" type=\"ord\"/>\n  <Symbol name=\"ὶ\" type=\"ord\"/>\n  <Symbol name=\"ὸ\" type=\"ord\"/>\n  <Symbol name=\"ὺ\" type=\"ord\"/>\n  <Symbol name=\"ὼ\" type=\"ord\"/>\n  <Symbol name=\"ᾀ\" type=\"ord\"/>\n  <Symbol name=\"ᾁ\" type=\"ord\"/>\n  <Symbol name=\"ᾂ\" type=\"ord\"/>\n  <Symbol name=\"ᾃ\" type=\"ord\"/>\n  <Symbol name=\"ᾄ\" type=\"ord\"/>\n  <Symbol name=\"ᾅ\" type=\"ord\"/>\n  <Symbol name=\"ᾆ\" type=\"ord\"/>\n  <Symbol name=\"ᾇ\" type=\"ord\"/>\n  <Symbol name=\"ᾐ\" type=\"ord\"/>\n  <Symbol name=\"ᾑ\" type=\"ord\"/>\n  <Symbol name=\"ᾒ\" type=\"ord\"/>\n  <Symbol name=\"ᾓ\" type=\"ord\"/>\n  <Symbol name=\"ᾔ\" type=\"ord\"/>\n  <Symbol name=\"ᾕ\" type=\"ord\"/>\n  <Symbol name=\"ᾖ\" type=\"ord\"/>\n  <Symbol name=\"ᾗ\" type=\"ord\"/>\n  <Symbol name=\"ᾠ\" type=\"ord\"/>\n  <Symbol name=\"ᾡ\" type=\"ord\"/>\n  <Symbol name=\"ᾢ\" type=\"ord\"/>\n  <Symbol name=\"ᾣ\" type=\"ord\"/>\n  <Symbol name=\"ᾤ\" type=\"ord\"/>\n  <Symbol name=\"ᾥ\" type=\"ord\"/>\n  <Symbol name=\"ᾦ\" type=\"ord\"/>\n  <Symbol name=\"ᾧ\" type=\"ord\"/>\n  <Symbol name=\"ᾲ\" type=\"ord\"/>\n  <Symbol name=\"ᾳ\" type=\"ord\"/>\n  <Symbol name=\"ᾴ\" type=\"ord\"/>\n  <Symbol name=\"ᾶ\" type=\"ord\"/>\n  <Symbol name=\"ᾷ\" type=\"ord\"/>\n  <Symbol name=\"ᾼ\" type=\"ord\"/>\n  <Symbol name=\"ι\" type=\"acc\"/>\n  <Symbol name=\"᾿\" type=\"acc\"/>\n  <Symbol name=\"῀\" type=\"acc\"/>\n  <Symbol name=\"῁\" type=\"acc\"/>\n  <Symbol name=\"ῂ\" type=\"ord\"/>\n  <Symbol name=\"ῃ\" type=\"ord\"/>\n  <Symbol name=\"ῄ\" type=\"ord\"/>\n  <Symbol name=\"ῆ\" type=\"ord\"/>\n  <Symbol name=\"ῇ\" type=\"ord\"/>\n  <Symbol name=\"ῌ\" type=\"ord\"/>\n  <Symbol name=\"῍\" type=\"acc\"/>\n  <Symbol name=\"῎\" type=\"acc\"/>\n  <Symbol name=\"῏\" type=\"acc\"/>\n  <Symbol name=\"ῒ\" type=\"ord\"/>\n  <Symbol name=\"ῖ\" type=\"ord\"/>\n  <Symbol name=\"ῗ\" type=\"ord\"/>\n  <Symbol name=\"῝\" type=\"acc\"/>\n  <Symbol name=\"῞\" type=\"acc\"/>\n  <Symbol name=\"῟\" type=\"acc\"/>\n  <Symbol name=\"ῢ\" type=\"ord\"/>\n  <Symbol name=\"ῤ\" type=\"ord\"/>\n  <Symbol name=\"ῥ\" type=\"ord\"/>\n  <Symbol name=\"ῦ\" type=\"ord\"/>\n  <Symbol name=\"ῧ\" type=\"ord\"/>\n  <Symbol name=\"῭\" type=\"acc\"/>\n  <Symbol name=\"`\" type=\"acc\"/>\n  <Symbol name=\"ῲ\" type=\"ord\"/>\n  <Symbol name=\"ῳ\" type=\"ord\"/>\n  <Symbol name=\"ῴ\" type=\"ord\"/>\n  <Symbol name=\"ῶ\" type=\"ord\"/>\n  <Symbol name=\"ῷ\" type=\"ord\"/>\n  <Symbol name=\"ῼ\" type=\"ord\"/>\n  <Symbol name=\"῾\" type=\"acc\"/>\n  <Symbol name=\"’\" type=\"acc\"/>\n</TeXSymbols>\n"
  },
  {
    "path": "HarmonyOS/markdown/src/main/resources/zh_CN/element/string.json",
    "content": "{\n  \"string\": [\n    {\n      \"name\": \"page_show\",\n      \"value\": \"page from npm package\"\n    }\n  ]\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/ohosTest/ets/test/Ability.test.ets",
    "content": "import { hilog } from '@kit.PerformanceAnalysisKit';\nimport { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';\n\nexport default function abilityTest() {\n  describe('ActsAbilityTest', () => {\n    // Defines a test suite. Two parameters are supported: test suite name and test suite function.\n    beforeAll(() => {\n      // Presets an action, which is performed only once before all test cases of the test suite start.\n      // This API supports only one parameter: preset action function.\n    })\n    beforeEach(() => {\n      // Presets an action, which is performed before each unit test case starts.\n      // The number of execution times is the same as the number of test cases defined by **it**.\n      // This API supports only one parameter: preset action function.\n    })\n    afterEach(() => {\n      // Presets a clear action, which is performed after each unit test case ends.\n      // The number of execution times is the same as the number of test cases defined by **it**.\n      // This API supports only one parameter: clear action function.\n    })\n    afterAll(() => {\n      // Presets a clear action, which is performed after all test cases of the test suite end.\n      // This API supports only one parameter: clear action function.\n    })\n    it('assertContain', 0, () => {\n      // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.\n      hilog.info(0x0000, 'testTag', '%{public}s', 'it begin');\n      let a = 'abc';\n      let b = 'b';\n      // Defines a variety of assertion methods, which are used to declare expected boolean conditions.\n      expect(a).assertContain(b);\n      expect(a).assertEqual(a);\n    })\n  })\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/ohosTest/ets/test/List.test.ets",
    "content": "import abilityTest from './Ability.test';\n\nexport default function testsuite() {\n  abilityTest();\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/ohosTest/module.json5",
    "content": "{\n  \"module\": {\n    \"name\": \"markdown_test\",\n    \"type\": \"feature\",\n    \"deviceTypes\": [\n      \"default\"\n    ],\n    \"deliveryWithInstall\": true,\n    \"installationFree\": false\n  }\n}\n"
  },
  {
    "path": "HarmonyOS/markdown/src/test/List.test.ets",
    "content": "import local from './LocalUnit.test';\n\nexport default function testsuite() {\n  local();\n}"
  },
  {
    "path": "HarmonyOS/markdown/src/test/LocalUnit.test.ets",
    "content": "import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';\n\nexport default function localUnitTest() {\n  describe('localUnitTest', () => {\n    // Defines a test suite. Two parameters are supported: test suite name and test suite function.\n    beforeAll(() => {\n      // Presets an action, which is performed only once before all test cases of the test suite start.\n      // This API supports only one parameter: preset action function.\n    });\n    beforeEach(() => {\n      // Presets an action, which is performed before each unit test case starts.\n      // The number of execution times is the same as the number of test cases defined by **it**.\n      // This API supports only one parameter: preset action function.\n    });\n    afterEach(() => {\n      // Presets a clear action, which is performed after each unit test case ends.\n      // The number of execution times is the same as the number of test cases defined by **it**.\n      // This API supports only one parameter: clear action function.\n    });\n    afterAll(() => {\n      // Presets a clear action, which is performed after all test cases of the test suite end.\n      // This API supports only one parameter: clear action function.\n    });\n    it('assertContain', 0, () => {\n      // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.\n      let a = 'abc';\n      let b = 'b';\n      // Defines a variety of assertion methods, which are used to declare expected boolean conditions.\n      expect(a).assertContain(b);\n      expect(a).assertEqual(a);\n    });\n  });\n}"
  },
  {
    "path": "HarmonyOS/oh-package.json5",
    "content": "{\n  \"modelVersion\": \"5.1.1\",\n  \"description\": \"Please describe the basic information.\",\n  \"dependencies\": {\n  },\n  \"devDependencies\": {\n    \"@ohos/hypium\": \"1.0.21\",\n    \"@ohos/hamock\": \"1.0.0\"\n  }\n}\n"
  },
  {
    "path": "HarmonyOS/playground/.gitignore",
    "content": "/node_modules\n/oh_modules\n/.preview\n/build\n/.cxx\n/.test"
  },
  {
    "path": "HarmonyOS/playground/build-profile.json5",
    "content": "{\n  \"apiType\": \"stageMode\",\n  \"buildOption\": {\n  },\n  \"buildOptionSet\": [\n    {\n      \"name\": \"release\",\n      \"arkOptions\": {\n        \"obfuscation\": {\n          \"ruleOptions\": {\n            \"enable\": false,\n            \"files\": [\n              \"./obfuscation-rules.txt\"\n            ]\n          }\n        }\n      }\n    },\n  ],\n  \"targets\": [\n    {\n      \"name\": \"default\"\n    },\n    {\n      \"name\": \"ohosTest\",\n    }\n  ]\n}"
  },
  {
    "path": "HarmonyOS/playground/hvigorfile.ts",
    "content": "import { hapTasks } from '@ohos/hvigor-ohos-plugin';\n\nexport default {\n  system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */\n  plugins: []       /* Custom plugin to extend the functionality of Hvigor. */\n}"
  },
  {
    "path": "HarmonyOS/playground/obfuscation-rules.txt",
    "content": "# Define project specific obfuscation rules here.\n# You can include the obfuscation configuration files in the current module's build-profile.json5.\n#\n# For more details, see\n#   https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5\n\n# Obfuscation options:\n# -disable-obfuscation: disable all obfuscations\n# -enable-property-obfuscation: obfuscate the property names\n# -enable-toplevel-obfuscation: obfuscate the names in the global scope\n# -compact: remove unnecessary blank spaces and all line feeds\n# -remove-log: remove all console.* statements\n# -print-namecache: print the name cache that contains the mapping from the old names to new names\n# -apply-namecache: reuse the given cache file\n\n# Keep options:\n# -keep-property-name: specifies property names that you want to keep\n# -keep-global-name: specifies names that you want to keep in the global scope\n\n-enable-property-obfuscation\n-enable-toplevel-obfuscation\n-enable-filename-obfuscation\n-enable-export-obfuscation"
  },
  {
    "path": "HarmonyOS/playground/oh-package.json5",
    "content": "{\n  \"name\": \"playground\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Please describe the basic information.\",\n  \"main\": \"\",\n  \"author\": \"\",\n  \"license\": \"\",\n  \"dependencies\": {\n    \"fluid-markdown\": \"file:../markdown\"\n  }\n}\n\n"
  },
  {
    "path": "HarmonyOS/playground/src/main/ets/pages/board.ets",
    "content": "import { Markdown, newLog, EMarkdownMode, MarkdownController, ETypingMode, EMarkdownMainBotEvent } from 'fluid-markdown';\nimport { NAV, PAGE_BGCOLOR } from './shared';\n\nconst log = newLog('Playground');\n\nexport enum EShowMode {\n  Normal = 'normal',\n  Typing = 'typing',\n  Stream = 'stream',\n}\n\n@ComponentV2\nexport struct BoardComponent {\n  @Consumer(NAV.STACK) stack: NavPathStack = new NavPathStack();\n  @Param content?: string = undefined;\n  @Param @Require mode: EShowMode;\n  private scroller: Scroller = new Scroller();\n\n  markdownController: MarkdownController = new MarkdownController({\n    typingMore: '\\n(已终止回答)'\n  });\n\n  aboutToAppear(): void {}\n\n  build() {\n    NavDestination() {\n      Scroll(this.scroller) {\n        Markdown({\n          content: this.content,\n          controller: this.markdownController,\n          mode: (this.mode === EShowMode.Normal ? EMarkdownMode.Normal : EMarkdownMode.Typing),\n          onMarkdownTypingReady: () => {\n            if (this.mode === EShowMode.Stream) {\n              const message = this.content ?? '';\n              let offset = 0;\n              const step = 20;\n              const timer = setInterval(() => {\n                let mode = ETypingMode.Append;\n                if (offset === 0) {\n                  mode = ETypingMode.Begin;\n                } else if (offset >= message.length) {\n                  mode = ETypingMode.End;\n                }\n                offset += step;\n                this.markdownController.typing.update(message.substring(0, offset), mode);\n                if (mode === ETypingMode.End) {\n                  clearInterval(timer);\n                }\n              }, 200);\n            } else if (this.mode === EShowMode.Typing) {\n              this.markdownController.typing.update(this.content, ETypingMode.Begin);\n            }\n          },\n          onMarkdownAreaChange: event => {\n            if (this.mode !== EShowMode.Normal && event.oldValue.height !== event.newValue.height) {\n              if (this.mode === EShowMode.Typing) {\n                this.scroller.scrollEdge(Edge.Bottom);\n              } else if (this.mode === EShowMode.Stream) {\n                this.scroller.scrollTo({ xOffset: 0, yOffset: Number(event.newValue.height) });\n              }\n            }\n          },\n          onMarkdownNodeClick: data => {\n            log.i('click node: %{public}s event: %{public}s', JSON.stringify(data.node.summary), JSON.stringify(data.event));\n          },\n          onMarkdownTextComponentSelectionOption: data => {\n            return {\n              enableSelection: true,\n              bindSelectionMenuBuilder: () => {},\n              bindSelectionMenuOptions: {},\n              editSelectionMenuOptions: {\n                onCreateMenu: menuItems => [],\n                onMenuItemClick: (menuItem, range) => false,\n              },\n              // if true, will ignore any ohos build-in selection gesture. you need use MarkdownController.TextContentController.selectGesture to invoke selection.\n              // ignoreInternal: true,\n            }\n          },\n          onMarkdownTextComponentSelectionChange: data => {\n            log.i('text selection change: %{public}d %{public}d', data.textEvent.start, data.textEvent.end);\n          },\n          onMarkdownTableComponentActionClick: data => {\n            log.i('click table action: %{public}s event: %{public}s', JSON.stringify(data.tableEvent.action.tag), JSON.stringify(data.tableEvent.event));\n          },\n          onMarkdownTableComponentContentBoxBar: data => {\n            log.i('table using default action bar');\n            return undefined;\n          },\n        })\n          .margin(12)\n      }\n      .scrollable(ScrollDirection.Vertical)\n      .margin(12)\n      .backgroundColor(Color.White)\n      .borderRadius(14)\n      .onScrollStart(() => {\n        if (this.mode === EShowMode.Stream) {\n          getContext()?.eventHub?.emit(EMarkdownMainBotEvent.ScrollBegin);\n        }\n      })\n      .onScrollStop(() => {\n        if (this.mode === EShowMode.Stream) {\n          getContext()?.eventHub?.emit(EMarkdownMainBotEvent.ScrollEnd);\n        }\n      })\n    }\n    .title('Board')\n    .width('100%')\n    .height('100%')\n    .backgroundColor(PAGE_BGCOLOR)\n    .onReady(() => {})\n  }\n}"
  },
  {
    "path": "HarmonyOS/playground/src/main/ets/pages/feature-detail.ets",
    "content": "import { Markdown, EMarkdownMode, MarkdownController } from 'fluid-markdown';\nimport { NAV, PAGE_BGCOLOR, IFeature } from './shared';\n\n@ComponentV2\nexport struct FeatureDetailComponent {\n  @Consumer(NAV.STACK) stack: NavPathStack = new NavPathStack();\n  @Local feature?: IFeature = undefined;\n  markdownController: MarkdownController = new MarkdownController({});\n\n  aboutToAppear(): void {}\n\n  build() {\n    NavDestination() {\n      Column() {\n        TextArea({ text: this.feature?.content })\n          .backgroundColor(Color.White)\n          .margin(12)\n          .layoutWeight(1)\n          .borderRadius(14)\n          .focusable(false)\n          .fontColor(0xa6000000)\n\n        Divider()\n          .color(0x91d5ff)\n\n        Scroll() {\n          Markdown({\n            content: this.feature?.content ?? ' ',\n            controller: this.markdownController,\n            mode: EMarkdownMode.Normal,\n            onMarkdownAreaChange: () => {},\n            onMarkdownNodeClick: data => {},\n            onMarkdownTextComponentSelectionOption: data => {\n              return {\n                enableSelection: true,\n                bindSelectionMenuBuilder: () => {},\n                bindSelectionMenuOptions: {},\n                editSelectionMenuOptions: {\n                  onCreateMenu: menuItems => [],\n                  onMenuItemClick: (menuItem, range) => false,\n                },\n              }\n            },\n            onMarkdownTextComponentSelectionChange: data => {},\n            onMarkdownTableComponentActionClick: data => {},\n            onMarkdownTableComponentContentBoxBar: data => {\n              return undefined;\n            },\n          })\n            .margin(12)\n        }\n        .scrollable(ScrollDirection.Vertical)\n        .margin(12)\n        .layoutWeight(2)\n        .align(Alignment.TopStart)\n        .backgroundColor(Color.White)\n        .borderRadius(14)\n      }\n    }\n    .title(this.feature?.name)\n    .width('100%')\n    .height('100%')\n    .backgroundColor(PAGE_BGCOLOR)\n    .onReady((ctx: NavDestinationContext) => {\n      if (ctx.pathInfo.param) {\n        this.feature = ctx.pathInfo.param as IFeature;\n      }\n    })\n  }\n}"
  },
  {
    "path": "HarmonyOS/playground/src/main/ets/pages/feature-list.ets",
    "content": "import { NAV, PAGE_BGCOLOR, Feature, FeatureMeta, IFeature, EPage } from './shared';\n\nconst HEADER_BG_COLOR = 0xf0f0f0;\nconst HEADER_FONT_COLOR = 0xe0000000;\nconst BORDER_COLOR = 0xd9d9d9;\nconst ITEM_FONT_COLOR = 0xa6000000;\n\n@ComponentV2\nexport struct FeatureListComponent {\n  @Consumer(NAV.STACK) stack: NavPathStack = new NavPathStack();\n  @Local meta: FeatureMeta = {};\n\n  aboutToAppear(): void {\n    this.meta = Feature.shared().meta(this.getUIContext()) ?? {};\n  }\n\n  @Builder\n  FeatureGroupHeader(group: string) {\n    Text(group)\n      .width('100%')\n      .padding({ left: 20, right: 20 })\n      .height(30)\n      .fontSize(16)\n      .fontColor(HEADER_FONT_COLOR)\n      .borderColor(BORDER_COLOR)\n      .borderWidth({ bottom: 1 })\n      .backgroundColor(HEADER_BG_COLOR)\n  }\n  @Builder\n  FeatureGroup() {\n    List() {\n      ForEach(Object.keys(this.meta), (key: string) => {\n        ListItemGroup({\n          header: this.FeatureGroupHeader(key)\n        }) {\n          this.FeatureItem(key)\n        }\n      })\n    }\n  }\n\n  @Builder\n  FeatureItem(group: string) {\n    List() {\n      ForEach(this.meta[group], (item: IFeature) => {\n        ListItem() {\n          Text(item.name)\n            .width('100%')\n            .padding({ left: 20, right: 20 })\n            .height(44)\n            .fontSize(20)\n            .fontColor(ITEM_FONT_COLOR)\n            .borderColor(BORDER_COLOR)\n            .borderWidth({ bottom: 1 })\n            .onClick(() => {\n              this.stack.pushPathByName(EPage.FeatureDetail, item);\n            })\n        }\n      })\n    }\n  }\n\n  build() {\n    NavDestination() {\n      Scroll() {\n        this.FeatureGroup()\n      }\n      .width('100%')\n      .height('100%')\n      // .margin(10)\n      // .borderRadius(20)\n      .backgroundColor(Color.White)\n      .scrollable(ScrollDirection.Vertical)\n    }\n    .title('Feature List')\n    .backgroundColor(PAGE_BGCOLOR)\n    .onReady(() => {})\n  }\n}"
  },
  {
    "path": "HarmonyOS/playground/src/main/ets/pages/index.ets",
    "content": "import { NAV, PAGE_BGCOLOR, EPage } from 'ets/pages/shared';\nimport { EShowMode, BoardComponent } from './board';\nimport { FeatureListComponent } from './feature-list';\nimport { FeatureDetailComponent } from './feature-detail';\n\nlet markdown = `\n<u>🌴 **三亚两日游攻略**</u>\n\n### 📅 行程推荐\n**方案一：经典海岛+文化组合**\n**Day1：蜈支洲岛+亚龙湾**\n- 上午：蜈支洲岛潜水/摩托艇（建议8:30前登船）[^4]\n- 下午：亚龙湾沙滩漫步，体验玻璃海\n- 傍晚：椰梦长廊拍摄落日剪影[^1]\n\n**Day2：南山观音+天涯海角**\n- 上午：南山文化旅游区祈福，观108米海上观音[^4]\n- 下午：天涯海角打卡“天涯石”“海角石”[^2]\n- 晚上：第一市场夜市品尝海鲜[^1]\n\n---\n\n### 🚗 交通贴士\n> 1. **蜈支洲岛**需乘船20分钟，建议8:30前到达码头[^1]。\n> 2. **亚龙湾至南山**车程约40分钟，可包车或跟团接送[^3]。\n\n---\n\n### ⚠️ 注意事项\n- 防晒必备：SPF50+防晒霜+物理防晒装备[^5]。\n- 海鲜消费：选择明码标价餐厅，称重前甩干水分[^5]。\n- 水上安全：浮潜需穿救生衣，警惕低价潜水陷阱[^5]。\n\n---\n\n### 🦐 必吃美食推荐\n\n| 小吃       | 招牌菜品        | 人均消费 | 位置参考      |\n|-----------------|-----------------|----------|---------------|\n| 炒冰       | 榴莲炒冰       | 36元     | 市区分店      |\n| 清补凉茶     | 十料椰奶       | 15元     | 渔村路        |\n| 香味海鲜   | 椒盐皮皮虾     | 120元    | 亚龙湾/海棠湾 |\n\n---\n\n查看更多[酒店机票](url)优惠套餐和[跟团旅游](url)推荐行程。\n\n[^1]: ref1\n[^2]: ref2\n[^3]: ref3\n[^4]: ref4\n[^5]: ref5\n`;\n\n@Entry\n@ComponentV2\nexport struct Index {\n  @Provider(NAV.STACK) stack: NavPathStack = new NavPathStack();\n\n  private content: string = markdown;\n  private textAreaController: TextAreaController = new TextAreaController();\n\n  private get actions(): IAction[] {\n    return [\n      { title: EShowMode.Normal, mode: EShowMode.Normal },\n      { title: EShowMode.Typing, mode: EShowMode.Typing },\n      { title: EShowMode.Stream, mode: EShowMode.Stream }\n    ];\n  }\n\n  @Builder\n  Action(title: string, mode: EShowMode) {\n    Button(title)\n      .backgroundColor(0x1890ff)\n      .onClick(() => {\n        this.stack.pushPath({ name: mode })\n      })\n  }\n  @Builder\n  Page(name: string) {\n    if (name === EShowMode.Normal) {\n      BoardComponent({ content: this.content, mode: EShowMode.Normal })\n    } else if (name === EShowMode.Typing) {\n      BoardComponent({ content: this.content, mode: EShowMode.Typing })\n    } else if (name === EShowMode.Stream) {\n      BoardComponent({ content: this.content, mode: EShowMode.Stream })\n    } else if (name === EPage.FeatureList) {\n      FeatureListComponent()\n    } else if (name === EPage.FeatureDetail) {\n      FeatureDetailComponent()\n    }\n  }\n\n  build() {\n    Navigation(this.stack) {\n      Column() {\n        Column() {\n          Row() {\n            TextArea({\n              text: this.content,\n              placeholder: 'input markdown content here',\n              controller: this.textAreaController\n            })\n              .width('100%')\n              .height('100%')\n              .fontColor(Color.Black)\n              .backgroundColor(Color.White)\n              .onSubmit(() => { this.textAreaController.stopEditing() })\n              .onChange(e => { this.content = e })\n          }\n          .width('100%')\n          .layoutWeight(1)\n          .padding(10)\n\n          Row() {\n            Blank()\n            ForEach(this.actions, (item: IAction) => {\n              Button(item.title)\n                .backgroundColor(0x1890ff)\n                .onClick(() => {\n                  this.stack.pushPath({ name: item.mode });\n                })\n              Blank()\n            })\n          }\n          .width('100%')\n          .height(60)\n        }\n      }\n      .height('100%')\n    }\n    .title('Fluid Markdown')\n    .backgroundColor(PAGE_BGCOLOR)\n    .mode(NavigationMode.Auto)\n    .titleMode(NavigationTitleMode.Mini)\n    .hideBackButton(true)\n    .navDestination(this.Page)\n    .menus([{\n      value: '',\n      icon:'resources/base/media/pl_icon_list_bullet.svg',\n      action: () => this.stack.pushPath({ name: EPage.FeatureList }),\n    }])\n    .onClick(() => this.textAreaController.stopEditing())\n  }\n}\n\ninterface IAction {\n  title: string;\n  mode: EShowMode;\n}"
  },
  {
    "path": "HarmonyOS/playground/src/main/ets/pages/shared/feature.ets",
    "content": "import { resourceManager } from \"@kit.LocalizationKit\";\nimport { util } from '@kit.ArkTS';\n\nexport abstract class Feature {\n  private _meta?: FeatureMeta;\n  private static __instance?: Feature;\n  static shared() {\n    if (!Feature.__instance) {\n      Feature.__instance = new FeatureImpl();\n    }\n    return Feature.__instance;\n  }\n  private load(ctx: UIContext) {\n    const rm = ctx.getHostContext()?.resourceManager;\n    if (rm) {\n      if (!this._meta) {\n        this._meta = {};\n        Feature.walk(rm, 'feature', (root, name, content) => {\n          let features = this._meta![root];\n          if (!features) {\n            features = [];\n            this._meta![root] = features;\n          }\n          features.push({ root, name, content });\n        });\n      }\n    }\n  }\n  private static walk(\n    rm: resourceManager.ResourceManager, path: string,\n    callback: (root: string, name: string, content: string) => void,\n  ) {\n    const files = rm.getRawFileListSync(path);\n    files.map(ele => `${path}/${ele}`).forEach(ele => {\n      if (rm.isRawDir(ele)) {\n        Feature.walk(rm, ele, callback);\n      } else {\n        const name = ele.split(path).join('');\n        const content = util.TextDecoder\n          .create('utf-8', { fatal: false, ignoreBOM: true })\n          .decodeToString(rm.getRawFileContentSync(ele), { stream: false });\n        callback(path, name, content);\n      }\n    });\n  }\n  meta(ctx: UIContext) {\n    this.load(ctx);\n    return this._meta;\n  }\n}\nclass FeatureImpl extends Feature {}\n\nexport type FeatureMeta = Record<string, IFeature[]>;\nexport interface IFeature {\n  root: string;\n  name: string;\n  content: string;\n}"
  },
  {
    "path": "HarmonyOS/playground/src/main/ets/pages/shared/index.ets",
    "content": "export * from './navigation';\nexport * from './feature';"
  },
  {
    "path": "HarmonyOS/playground/src/main/ets/pages/shared/navigation.ets",
    "content": "interface INavigation {\n  STACK: string,\n}\nexport const NAV: INavigation = {\n  STACK: '_nav.stack',\n};\nexport const PAGE_BGCOLOR: ResourceColor = 0xe6f7ff;\nexport enum EPage {\n  FeatureList = 'feature_list',\n  FeatureDetail = 'feature_detail',\n}"
  },
  {
    "path": "HarmonyOS/playground/src/main/ets/playgroundability/PlaygroundAbility.ets",
    "content": "import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';\nimport { hilog } from '@kit.PerformanceAnalysisKit';\nimport { window } from '@kit.ArkUI';\n\nconst DOMAIN = 0x0000;\n\nexport default class PlaygroundAbility extends UIAbility {\n  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {\n    this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);\n    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');\n  }\n\n  onDestroy(): void {\n    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');\n  }\n\n  onWindowStageCreate(windowStage: window.WindowStage): void {\n    // Main window is created, set main page for this ability\n    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');\n\n    // windowStage.on('windowStageEvent', event => {\n    //   windowStage.getMainWindow().then(v => {\n    //     Engine.shared().service.ctx.ctx = v.getUIContext();\n    //   }).catch((e: Error) => {\n    //     hilog.error(DOMAIN, 'testTag', '%s', e.message);\n    //   });\n    // });\n    windowStage.loadContent('pages/index', (err) => {\n      if (err.code) {\n        hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));\n        return;\n      }\n      hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');\n    });\n  }\n\n  onWindowStageDestroy(): void {\n    // Main window is destroyed, release UI related resources\n    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');\n  }\n\n  onForeground(): void {\n    // Ability has brought to foreground\n    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground');\n  }\n\n  onBackground(): void {\n    // Ability has back to background\n    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground');\n  }\n}"
  },
  {
    "path": "HarmonyOS/playground/src/main/ets/playgroundbackupability/PlaygroundBackupAbility.ets",
    "content": "import { hilog } from '@kit.PerformanceAnalysisKit';\nimport { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit';\n\nconst DOMAIN = 0x0000;\n\nexport default class PlaygroundBackupAbility extends BackupExtensionAbility {\n  async onBackup() {\n    hilog.info(DOMAIN, 'testTag', 'onBackup ok');\n    await Promise.resolve();\n  }\n\n  async onRestore(bundleVersion: BundleVersion) {\n    hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion));\n    await Promise.resolve();\n  }\n}"
  },
  {
    "path": "HarmonyOS/playground/src/main/module.json5",
    "content": "{\n  \"module\": {\n    \"name\": \"playground\",\n    \"type\": \"entry\",\n    \"description\": \"$string:module_desc\",\n    \"mainElement\": \"PlaygroundAbility\",\n    \"deviceTypes\": [\n      \"phone\"\n    ],\n    \"deliveryWithInstall\": true,\n    \"installationFree\": false,\n    \"pages\": \"$profile:main_pages\",\n    \"abilities\": [\n      {\n        \"name\": \"PlaygroundAbility\",\n        \"srcEntry\": \"./ets/playgroundability/PlaygroundAbility.ets\",\n        \"description\": \"$string:PlaygroundAbility_desc\",\n        \"icon\": \"$media:layered_image\",\n        \"label\": \"$string:PlaygroundAbility_label\",\n        \"startWindowIcon\": \"$media:startIcon\",\n        \"startWindowBackground\": \"$color:start_window_background\",\n        \"exported\": true,\n        \"skills\": [\n          {\n            \"entities\": [\n              \"entity.system.home\"\n            ],\n            \"actions\": [\n              \"ohos.want.action.home\"\n            ]\n          }\n        ]\n      }\n    ],\n    \"extensionAbilities\": [\n      {\n        \"name\": \"PlaygroundBackupAbility\",\n        \"srcEntry\": \"./ets/playgroundbackupability/PlaygroundBackupAbility.ets\",\n        \"type\": \"backup\",\n        \"exported\": false,\n        \"metadata\": [\n          {\n            \"name\": \"ohos.extension.backup\",\n            \"resource\": \"$profile:backup_config\"\n          }\n        ],\n      }\n    ]\n  }\n}"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/base/element/color.json",
    "content": "{\n  \"color\": [\n    {\n      \"name\": \"start_window_background\",\n      \"value\": \"#FFFFFF\"\n    }\n  ]\n}"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/base/element/float.json",
    "content": "{\n  \"float\": [\n    {\n      \"name\": \"page_text_font_size\",\n      \"value\": \"50fp\"\n    }\n  ]\n}"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/base/element/string.json",
    "content": "{\n  \"string\": [\n    {\n      \"name\": \"module_desc\",\n      \"value\": \"module description\"\n    },\n    {\n      \"name\": \"PlaygroundAbility_desc\",\n      \"value\": \"description\"\n    },\n    {\n      \"name\": \"PlaygroundAbility_label\",\n      \"value\": \"Playground\"\n    }\n  ]\n}"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/base/media/layered_image.json",
    "content": "{\n  \"layered-image\":\n  {\n    \"background\" : \"$media:background\",\n    \"foreground\" : \"$media:foreground\"\n  }\n}"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/base/profile/backup_config.json",
    "content": "{\n  \"allowToBackupRestore\": true\n}"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/base/profile/main_pages.json",
    "content": "{\n  \"src\": [\n    \"pages/index\"\n  ]\n}"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/dark/element/color.json",
    "content": "{\n  \"color\": [\n    {\n      \"name\": \"start_window_background\",\n      \"value\": \"#000000\"\n    }\n  ]\n}"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/cmark-gfm-bench/block-bq-flat.md",
    "content": "> the simple example of a blockquote \n> the simple example of a blockquote\n> the simple example of a blockquote\n> the simple example of a blockquote\n... continuation\n... continuation\n... continuation\n... continuation\n\nempty blockquote:\n\n>\n>\n>\n>\n\n"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/cmark-gfm-bench/block-bq-nested.md",
    "content": ">>>>>> deeply nested blockquote\n>>>>> deeply nested blockquote\n>>>> deeply nested blockquote\n>>> deeply nested blockquote\n>> deeply nested blockquote\n> deeply nested blockquote\n\n> deeply nested blockquote\n>> deeply nested blockquote\n>>> deeply nested blockquote\n>>>> deeply nested blockquote\n>>>>> deeply nested blockquote\n>>>>>> deeply nested blockquote\n"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/cmark-gfm-bench/block-code.md",
    "content": "\n        an\n        example\n\n        of\n\n\n\n        a code\n        block\n\n"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/cmark-gfm-bench/block-fences.md",
    "content": "\n``````````text\nan\nexample\n```\nof\n\n\na fenced\n```\ncode\nblock\n``````````\n\n"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/cmark-gfm-bench/block-heading.md",
    "content": "# heading\n### heading\n##### heading\n\n# heading #\n### heading ###\n##### heading \\#\\#\\#\\#\\######\n\n############ not a heading\n"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/cmark-gfm-bench/block-hr.md",
    "content": "\n * * * * *\n\n -  -  -  -  -\n\n ________\n\n\n ************************* text\n\n"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/cmark-gfm-bench/block-html.md",
    "content": "<div class=\"this is an html block\">\n\nblah blah\n\n</div>\n\n<table>\n  <tr>\n    <td>\n      **test**\n    </td>\n  </tr>\n</table>\n\n<table>\n\n  <tr>\n\n    <td>\n\n      test\n\n    </td>\n\n  </tr>\n\n</table>\n\n<![CDATA[\n  [[[[[[[[[[[... *cdata section - this should not be parsed* ...]]]]]]]]]]]\n]]>\n\n"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/cmark-gfm-bench/block-lheading.md",
    "content": "heading\n---\n\nheading\n===================================\n\nnot a heading\n----------------------------------- text\n"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/cmark-gfm-bench/block-list-flat.md",
    "content": " - tidy\n - bullet\n - list\n\n\n - loose\n\n - bullet\n\n - list\n\n\n 0. ordered\n 1. list\n 2. example\n\n\n -\n -\n -\n -\n\n\n 1.\n 2.\n 3.\n\n\n -  an example\nof a list item\n       with a continuation\n\n    this part is inside the list\n\n   this part is just a paragraph  \n\n\n 1. test\n -  test\n 1. test\n -  test\n\n\n111111111111111111111111111111111111111111. is this a valid bullet?\n\n - _________________________\n\n - this\n - is\n\n   a\n\n   long\n - loose\n - list\n\n - with\n - some\n\n   tidy\n\n - list\n - items\n - in\n\n - between\n - _________________________\n"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/cmark-gfm-bench/block-list-nested.md",
    "content": "\n - this\n   - is\n     - a\n       - deeply\n         - nested\n           - bullet\n             - list\n   \n\n 1. this\n    2. is\n       3. a\n          4. deeply\n             5. nested\n                6. unordered\n                   7. list\n\n\n - 1\n  - 2\n   - 3\n    - 4\n     - 5\n      - 6\n       - 7\n      - 6\n     - 5\n    - 4\n   - 3\n  - 2\n - 1\n\n\n - - - - - - - - - deeply-nested one-element item\n\n"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/cmark-gfm-bench/block-ref-flat.md",
    "content": "[1] [2] [3] [1] [2] [3]\n\n[looooooooooooooooooooooooooooooooooooooooooooooooooong label]\n\n [1]: <http://something.example.com/foo/bar>\n [2]: http://something.example.com/foo/bar 'test'\n [3]:\n http://foo/bar\n [    looooooooooooooooooooooooooooooooooooooooooooooooooong   label    ]:\n 111\n 'test'\n [[[[[[[[[[[[[[[[[[[[ this should not slow down anything ]]]]]]]]]]]]]]]]]]]]: q\n (as long as it is not referenced anywhere)\n\n [[[[[[[[[[[[[[[[[[[[]: this is not a valid reference\n"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/cmark-gfm-bench/block-ref-nested.md",
    "content": "[[[[[[[foo]]]]]]]\n\n[[[[[[[foo]]]]]]]: bar\n[[[[[[foo]]]]]]: bar\n[[[[[foo]]]]]: bar\n[[[[foo]]]]: bar\n[[[foo]]]: bar\n[[foo]]: bar\n[foo]: bar\n\n[*[*[*[*[foo]*]*]*]*]\n\n[*[*[*[*[foo]*]*]*]*]: bar\n[*[*[*[foo]*]*]*]: bar\n[*[*[foo]*]*]: bar\n[*[foo]*]: bar\n[foo]: bar\n"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/cmark-gfm-bench/inline-autolink.md",
    "content": "closed (valid) autolinks:\n\n <ftp://1.2.3.4:21/path/foo>\n <http://foo.bar.baz?q=hello&id=22&boolean>\n <http://veeeeeeeeeeeeeeeeeeery.loooooooooooooooooooooooooooooooong.autolink/>\n <teeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeest@gmail.com>\n\nthese are not autolinks:\n\n <ftp://1.2.3.4:21/path/foo\n <http://foo.bar.baz?q=hello&id=22&boolean\n <http://veeeeeeeeeeeeeeeeeeery.loooooooooooooooooooooooooooooooong.autolink\n <teeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeest@gmail.com\n < http://foo.bar.baz?q=hello&id=22&boolean >\n"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/cmark-gfm-bench/inline-backticks.md",
    "content": "`lots`of`backticks`\n\n``i``wonder``how``this``will``be``parsed``\n"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/cmark-gfm-bench/inline-em-flat.md",
    "content": "*this* *is* *your* *basic* *boring* *emphasis*\n\n_this_ _is_ _your_ _basic_ _boring_ _emphasis_\n\n**this** **is** **your** **basic** **boring** **emphasis**\n"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/cmark-gfm-bench/inline-em-nested.md",
    "content": "*this *is *a *bunch* of* nested* emphases* \n\n__this __is __a __bunch__ of__ nested__ emphases__ \n\n***this ***is ***a ***bunch*** of*** nested*** emphases*** \n"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/cmark-gfm-bench/inline-em-worst.md",
    "content": "*this *is *a *worst *case *for *em *backtracking\n\n__this __is __a __worst __case __for __em __backtracking\n\n***this ***is ***a ***worst ***case ***for ***em ***backtracking\n"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/cmark-gfm-bench/inline-entity.md",
    "content": "entities:\n\n&nbsp; &amp; &copy; &AElig; &Dcaron; &frac34; &HilbertSpace; &DifferentialD; &ClockwiseContourIntegral;\n\n&#35; &#1234; &#992; &#98765432;\n\nnon-entities:\n\n&18900987654321234567890; &1234567890098765432123456789009876543212345678987654;\n\n&qwertyuioppoiuytrewqwer; &oiuytrewqwertyuioiuytrewqwertyuioytrewqwertyuiiuytri;\n"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/cmark-gfm-bench/inline-escape.md",
    "content": "\n\\t\\e\\s\\t\\i\\n\\g \\e\\s\\c\\a\\p\\e \\s\\e\\q\\u\\e\\n\\c\\e\\s\n\n\\!\\\\\\\"\\#\\$\\%\\&\\'\\(\\)\\*\\+\\,\\.\\/\\:\\;\\<\\=\\>\\?\n\n\\@ \\[ \\] \\^ \\_ \\` \\{ \\| \\} \\~ \\- \\'\n\n\\\n\\\\\n\\\\\\\n\\\\\\\\\n\\\\\\\\\\\n\n\\<this\\> \\<is\\> \\<not\\> \\<html\\>\n\n"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/cmark-gfm-bench/inline-html.md",
    "content": "Taking commonmark tests from the spec for benchmarking here:\n\n<a><bab><c2c>\n\n<a/><b2/>\n\n<a  /><b2\ndata=\"foo\" >\n\n<a foo=\"bar\" bam = 'baz <em>\"</em>'\n_boolean zoop:33=zoop:33 />\n\n<33> <__>\n\n<a h*#ref=\"hi\">\n\n<a href=\"hi'> <a href=hi'>\n\n< a><\nfoo><bar/ >\n\n<a href='bar'title=title>\n\n</a>\n</foo >\n\n</a href=\"foo\">\n\nfoo <!-- this is a\ncomment - with hyphen -->\n\nfoo <!-- not a comment -- two hyphens -->\n\nfoo <?php echo $a; ?>\n\nfoo <!ELEMENT br EMPTY>\n\nfoo <![CDATA[>&<]]>\n\n<a href=\"&ouml;\">\n\n<a href=\"\\*\">\n\n<a href=\"\\\"\">\n"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/cmark-gfm-bench/inline-links-flat.md",
    "content": "Valid links:\n\n [this is a link]()\n [this is a link](<http://something.example.com/foo/bar>)\n [this is a link](http://something.example.com/foo/bar 'test')\n ![this is an image]()\n ![this is an image](<http://something.example.com/foo/bar>)\n ![this is an image](http://something.example.com/foo/bar 'test')\n \n [escape test](<\\>\\>\\>\\>\\>\\>\\>\\>\\>\\>\\>\\>\\>\\>> '\\'\\'\\'\\'\\'\\'\\'\\'\\'\\'\\'\\'\\'\\'')\n [escape test \\]\\]\\]\\]\\]\\]\\]\\]\\]\\]\\]\\]\\]\\]\\]\\]](\\)\\)\\)\\)\\)\\)\\)\\)\\)\\)\\)\\)\\)\\))\n\nInvalid links:\n\n [this is not a link\n\n [this is not a link](\n\n [this is not a link](http://something.example.com/foo/bar 'test'\n \n [this is not a link](((((((((((((((((((((((((((((((((((((((((((((((\n \n [this is not a link]((((((((((()))))))))) (((((((((()))))))))))\n"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/cmark-gfm-bench/inline-links-nested.md",
    "content": "Valid links:\n\n[[[[[[[[](test)](test)](test)](test)](test)](test)](test)]\n\n[ [[[[[[[[[[[[[[[[[[ [](test) ]]]]]]]]]]]]]]]]]] ](test)\n\nInvalid links:\n\n[[[[[[[[[\n\n[ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [\n\n![![![![![![![![![![![![![![![![![![![![![![![![![![![![![![![![![![![![![![\n"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/cmark-gfm-bench/inline-newlines.md",
    "content": "\nthis\\\nshould\\\nbe\\\nseparated\\\nby\\\nnewlines\n\nthis  \nshould  \nbe  \nseparated  \nby  \nnewlines  \ntoo\n\nthis\nshould\nnot\nbe\nseparated\nby\nnewlines\n\n"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/cmark-gfm-bench/lorem1.md",
    "content": "Lorem ipsum dolor sit amet, __consectetur__ adipiscing elit. Cras imperdiet nec erat ac condimentum. Nulla vel rutrum ligula. Sed hendrerit interdum orci a posuere. Vivamus ut velit aliquet, mollis purus eget, iaculis nisl. Proin posuere malesuada ante. Proin auctor orci eros, ac molestie lorem dictum nec. Vestibulum sit amet erat est. Morbi luctus sed elit ac luctus. Proin blandit, enim vitae egestas posuere, neque elit ultricies dui, vel mattis nibh enim ac lorem. Maecenas molestie nisl sit amet velit dictum lobortis. Aliquam erat volutpat.\n\nVivamus sagittis, diam in [vehicula](https://github.com/markdown-it/markdown-it) lobortis, sapien arcu mattis erat, vel aliquet sem urna et risus. Ut feugiat sapien vitae mi elementum laoreet. Suspendisse potenti. Aliquam erat nisl, aliquam pretium libero aliquet, sagittis eleifend nunc. In hac habitasse platea dictumst. Integer turpis augue, tincidunt dignissim mauris id, rhoncus dapibus purus. Maecenas et enim odio. Nullam massa metus, varius quis vehicula sed, pharetra mollis erat. In quis viverra velit. Vivamus placerat, est nec hendrerit varius, enim dui hendrerit magna, ut pulvinar nibh lorem vel lacus. Mauris a orci iaculis, hendrerit eros sed, gravida leo. In dictum mauris vel augue varius, ac ullamcorper nisl ornare. In eu posuere velit, ac fermentum arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nullam sed malesuada leo, at interdum elit.\n\nNullam ut tincidunt nunc. [Pellentesque][1] metus lacus, commodo eget justo ut, rutrum varius nunc. Sed non rhoncus risus. Morbi sodales gravida pulvinar. Duis malesuada, odio volutpat elementum vulputate, massa magna scelerisque ante, et accumsan tellus nunc in sem. Donec mattis arcu et velit aliquet, non sagittis justo vestibulum. Suspendisse volutpat felis lectus, nec consequat ipsum mattis id. Donec dapibus vehicula facilisis. In tincidunt mi nisi, nec faucibus tortor euismod nec. Suspendisse ante ligula, aliquet vitae libero eu, vulputate dapibus libero. Sed bibendum, sapien at posuere interdum, libero est sollicitudin magna, ac gravida tellus purus eu ipsum. Proin ut quam arcu.\n\nSuspendisse potenti. Donec ante velit, ornare at augue quis, tristique laoreet sem. Etiam in ipsum elit. Nullam cursus dolor sit amet nulla feugiat tristique. Phasellus ac tellus tincidunt, imperdiet purus eget, ullamcorper ipsum. Cras eu tincidunt sem. Nullam sed dapibus magna. Lorem ipsum dolor sit amet, consectetur adipiscing elit. In id venenatis tortor. In consectetur sollicitudin pharetra. Etiam convallis nisi nunc, et aliquam turpis viverra sit amet. Maecenas faucibus sodales tortor. Suspendisse lobortis mi eu leo viverra volutpat. Pellentesque velit ante, vehicula sodales congue ut, elementum a urna. Cras tempor, ipsum eget luctus rhoncus, arcu ligula fermentum urna, vulputate pharetra enim enim non libero.\n\nProin diam quam, elementum in eleifend id, elementum et metus. Cras in justo consequat justo semper ultrices. Sed dignissim lectus a ante mollis, nec vulputate ante molestie. Proin in porta nunc. Etiam pulvinar turpis sed velit porttitor, vel adipiscing velit fringilla. Cras ac tellus vitae purus pharetra tincidunt. Sed cursus aliquet aliquet. Cras eleifend commodo malesuada. In turpis turpis, ullamcorper ut tincidunt a, ullamcorper a nunc. Etiam luctus tellus ac dapibus gravida. Ut nec lacus laoreet neque ullamcorper volutpat.\n\nNunc et leo erat. Aenean mattis ultrices lorem, eget adipiscing dolor ultricies eu. In hac habitasse platea dictumst. Vivamus cursus feugiat sapien quis aliquam. Mauris quam libero, porta vel volutpat ut, blandit a purus. Vivamus vestibulum dui vel tortor molestie, sit amet feugiat sem commodo. Nulla facilisi. Sed molestie arcu eget tellus vestibulum tristique.\n\n[1]: https://github.com/markdown-it\n"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/cmark-gfm-bench/rawtabs.md",
    "content": "\nthis is a test for tab expansion, be careful not to replace them with spaces\n\n1\t4444\n22\t333\n333\t22\n4444\t1\n\n\n\ttab-indented line\n    space-indented line\n\ttab-indented line\n\n\na lot of                                                spaces in between here\n\na lot of\t\t\t\t\t\t\t\t\t\t\t\ttabs in between here\n\n"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/markdown-ant/html-tag-a.md",
    "content": "<a src=\"https://some-url.com\">*link*</a>"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/markdown-ant/html-tag-mark.md",
    "content": "<mark>**foo**</mark>"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/markdown-ant/html-tag-sub.md",
    "content": "H<sub>2</sub>O"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/markdown-ant/html-tag-sup.md",
    "content": "x<sup>2</sup>"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/markdown-ant/html-tag-u.md",
    "content": "<u>underline</u>"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/markdown-it/code.md",
    "content": "```block code\nauto a = 1;\na++;\n```\n\n\n`inline code`"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/markdown-it/emoji.md",
    "content": ":smile:"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/markdown-it/emph.md",
    "content": "*A*\n_B_"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/markdown-it/footnote.md",
    "content": "[^1]\n\na[^2]b\n\n[^2]: y\n\n[^1]: x"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/markdown-it/heading.md",
    "content": "# H1\n## H2\n### H3  \n#### H4  \n##### H5 \n###### H6"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/markdown-it/image.md",
    "content": "![image](https://mdn.alipayobjects.com/huamei_wspxri/afts/img/A*_pUbS4n2yBYAAAAAZLAAAAgAenh5AQ/original)"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/markdown-it/line-break.md",
    "content": "a\nb\n\nc\n\n\nd"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/markdown-it/link.md",
    "content": "[url](https://www.some-test.com)"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/markdown-it/list.md",
    "content": "* A1\n  * A1.1\n  * A1.2\n* A2\n  * A2.1\n  * A2.2\n\n- A3\n    - A3.1\n    - A3.2\n- A4\n    - A4.1\n    - A4.2\n\n1. O1\n    1. O1.1\n    2. O1.2\n2. O2\n    1. O2.1\n    2. O2.2"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/markdown-it/math.md",
    "content": "$inline: a^2 + b^2 = c^2$\n\n$$block: a^2 + b^2 = c^2$$"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/markdown-it/paragraph.md",
    "content": "水调歌头·明月几时有\n\n丙辰中秋，欢饮达旦，大醉，作此篇，兼怀子由。\n\n\n明月几时有？把酒问青天。\n不知天上宫阙，今夕是何年？\n我欲乘风归去，又恐琼楼玉宇，\n高处不胜寒。起舞弄清影，何似在人间？\n\n\n转朱阁，低绮户，照无眠。\n不应有恨，何事长向别时圆？\n人有悲欢离合，月有阴晴圆缺，\n此事古难全。但愿人长久，千里共婵娟。"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/markdown-it/quote.md",
    "content": "> Q1\n>> Q2\n>>> Q3\n>>>> Q4"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/markdown-it/strike-through.md",
    "content": "~~A~~"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/markdown-it/strong.md",
    "content": "**A**"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/markdown-it/sub.md",
    "content": "H~2~O"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/markdown-it/sup.md",
    "content": "X^2^"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/markdown-it/table.md",
    "content": "| A  |\n|----|\n| a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1 |\n| a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a |\n\n| A  | B  |\n|----|----|\n| a1 | b1 |\n| a2 | b2 |\n\n| X  |  Y  |  Z |\n|:---|:---:|---:| \n| x1 | y1  | z1 |\n| x2 | y2  | z2 |"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/markdown-it/task.md",
    "content": "- [ ] false\n- [x] true"
  },
  {
    "path": "HarmonyOS/playground/src/main/resources/rawfile/feature/markdown-it/thematic-break.md",
    "content": "***\n\n---"
  },
  {
    "path": "HarmonyOS/playground/src/mock/mock-config.json5",
    "content": "{\n}"
  },
  {
    "path": "HarmonyOS/playground/src/ohosTest/ets/test/Ability.test.ets",
    "content": "import { hilog } from '@kit.PerformanceAnalysisKit';\nimport { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';\n\nexport default function abilityTest() {\n  describe('ActsAbilityTest', () => {\n    // Defines a test suite. Two parameters are supported: test suite name and test suite function.\n    beforeAll(() => {\n      // Presets an action, which is performed only once before all test cases of the test suite start.\n      // This API supports only one parameter: preset action function.\n    })\n    beforeEach(() => {\n      // Presets an action, which is performed before each unit test case starts.\n      // The number of execution times is the same as the number of test cases defined by **it**.\n      // This API supports only one parameter: preset action function.\n    })\n    afterEach(() => {\n      // Presets a clear action, which is performed after each unit test case ends.\n      // The number of execution times is the same as the number of test cases defined by **it**.\n      // This API supports only one parameter: clear action function.\n    })\n    afterAll(() => {\n      // Presets a clear action, which is performed after all test cases of the test suite end.\n      // This API supports only one parameter: clear action function.\n    })\n    it('assertContain', 0, () => {\n      // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.\n      hilog.info(0x0000, 'testTag', '%{public}s', 'it begin');\n      let a = 'abc';\n      let b = 'b';\n      // Defines a variety of assertion methods, which are used to declare expected boolean conditions.\n      expect(a).assertContain(b);\n      expect(a).assertEqual(a);\n    })\n  })\n}"
  },
  {
    "path": "HarmonyOS/playground/src/ohosTest/ets/test/List.test.ets",
    "content": "import abilityTest from './Ability.test';\n\nexport default function testsuite() {\n  abilityTest();\n}"
  },
  {
    "path": "HarmonyOS/playground/src/ohosTest/module.json5",
    "content": "{\n  \"module\": {\n    \"name\": \"playground_test\",\n    \"type\": \"feature\",\n    \"deviceTypes\": [\n      \"phone\"\n    ],\n    \"deliveryWithInstall\": true,\n    \"installationFree\": false\n  }\n}\n"
  },
  {
    "path": "HarmonyOS/playground/src/test/List.test.ets",
    "content": "import localUnitTest from './LocalUnit.test';\n\nexport default function testsuite() {\n  localUnitTest();\n}"
  },
  {
    "path": "HarmonyOS/playground/src/test/LocalUnit.test.ets",
    "content": "import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';\n\nexport default function localUnitTest() {\n  describe('localUnitTest', () => {\n    // Defines a test suite. Two parameters are supported: test suite name and test suite function.\n    beforeAll(() => {\n      // Presets an action, which is performed only once before all test cases of the test suite start.\n      // This API supports only one parameter: preset action function.\n    });\n    beforeEach(() => {\n      // Presets an action, which is performed before each unit test case starts.\n      // The number of execution times is the same as the number of test cases defined by **it**.\n      // This API supports only one parameter: preset action function.\n    });\n    afterEach(() => {\n      // Presets a clear action, which is performed after each unit test case ends.\n      // The number of execution times is the same as the number of test cases defined by **it**.\n      // This API supports only one parameter: clear action function.\n    });\n    afterAll(() => {\n      // Presets a clear action, which is performed after all test cases of the test suite end.\n      // This API supports only one parameter: clear action function.\n    });\n    it('assertContain', 0, () => {\n      // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.\n      let a = 'abc';\n      let b = 'b';\n      // Defines a variety of assertion methods, which are used to declare expected boolean conditions.\n      expect(a).assertContain(b);\n      expect(a).assertEqual(a);\n    });\n  });\n}"
  },
  {
    "path": "INSTALL.md",
    "content": "## iOS\n```plain\n// clone code to local\ngit clone git@github.com:antgroup/FluidMarkdown.git\n\n// switch to the target directory\ncd <your-project-path>/FluidMarkdown\n\n// switch to the project directory\ncd iOS\n\n// open project\nopen FluidMarkdown.xcworkspace\n```\n\n\n\n## Android\n1.  Clone code to local\n\n```\ngit clone git@github.com:antgroup/FluidMarkdown.git\n```\n\n2. Add dependencies to your gradle file\n\n```groovy\n  api project(':fluid-markdown')\n```\n\n \n\n## HarmonyOS\n``` shell\n// clone code to local\ngit clone git@github.com:antgroup/FluidMarkdown.git\n\n// switch to the project directory\ncd your/project/FluidMarkdown/HarmonyOS\n\n// open the project via DevEco-Studio\n```"
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "README.md",
    "content": "# FluidMarkdown\nWe are committed to enabling the streaming rendering of Markdown content generated by large language models on the client side within AI-driven business applications.\n\n# Overview\nThis library is designed for native Android, iOS and HarmonyOS developers. Built on the open-source CommonMark parsing library, it supports core Markdown syntax and selected HTML tags, rendering them progressively within UI components. It exposes Markdown styling as a structured model, enabling customization and integration into your specific application contexts. For faster integration, refer to the sample code to preview the rendering effect based on input text.\n\n# Features\n+ Support for markdown syntax: titles, paragraphs, ordered lists, unordered lists, tables, code blocks, mathematical formulas, inline code blocks, quotes, dividing lines, footnotes, links, and images.\n+ Support for HTML tags:`<s>` `<sup>` `<sub>` `<mark>` `<a>` `<span>` `<cite>` `<del>` `<font>` `<img>` `<u>`, etc.\n+ Streaming rendering and one-time full rendering modes.\n+ Customizable rendering styles for Markdown syntax.\n+ Adjustable streaming speed via custom parameters.\n+ Event support for clickable elements, including click handling, visibility callbacks, and rendering status updates<font style=\"color:rgb(38, 38, 38);\">, etc.\n+ Added some new extended HTML tags such as `<iconlink>` `<icon>`in `AMHTMLTransformer` class.\n\n# Install\nThe source code of this project is open-source. For information on how to download and run the project, please refer to the file [INSTALL](https://github.com/antgroup/FluidMarkdown/blob/main/INSTALL.md).\n\n# Directory structure\n## iOS\n+ AntMarkdown —— a standard markdown parser and rendering module based on commonMark.\n+ FluidMarkdown —— Component for streaming output.\n\n## Android\n+ fluid-markdown —— Component for streaming output.\n+ markwon-xxx —— Syntax parsing and style rendering implementation based on the open-source markwon library.\n\n## HarmonyOS\n+ markdown —— the folder contains all the source code for the markdown component, such as syntax parsing, layout rendering, theme configuration, runtime services, etc.\n+ playground —— a demo to show markdown component feature list.\n\n``` shell\nyour/project/markdown/src/main/ets\n├── engine\t\t\t\t\t//\t[folder] engine manages all services and plugins at runtime.\n├── index.ets       //  [file]   default exports.\n├── markdown.ets\t\t//\t[file]   markdown component compliant with the @ComponentV2 specification.\n├── render\t\t\t\t\t//\t[folder] rendering-related logic based on the StyledString mechanism.\n├── service\t\t\t\t\t//\t[folder] runtime service modules, such as syntax parsing, code highlighting, etc.\n├── theme\t\t\t\t\t\t//\t[folder] style and theme-related logic based on the StyledString mechanism.\n└── util\t\t\t\t\t\t//\t[folder] built-in utility api.\n```\n\n# Usage\n## iOS\n+ Native API： `AMXMarkdownWidget.h` is summary header file of the open API. The following is the general calling process of streaming rendering components.\n    1. Create a TextView instance.\n    2. Generate default styles and set custom styles ( if needed )\n    3. Begin streaming the Markdown content.\n    4. Append data dynamically during rendering.\n    5. Adjust list scrolling in response to content size changes in the TextView.\n    6. Handle completion when rendering is finished.\n\n```objectivec\nAMXMarkdownTextView* contentTextView = [[AMXMarkdownTextView alloc] initWithFrame_ant_mark:CGRectMake(0, 0, screenWidht - 20 * 2, 1)];\n\n// get default style config\nAMXMarkdownStyleConfig* config = [AMXMarkdownStyleConfig defaultConfig];\n\n// modify code block style for example\nconfig.codeBlockConfig.backgroundColor = [UIColor greenColor];\n\n// set the style with unique Id\n[[AMXRenderService shared] setMarkdownStyleWithId:config styleId:@\"demo\"];\n\n// begin print\n[self.contentTextView startStreamingWithContent:@\"testing data\"];\n\n// append content during printing\n[self.contentTextView addStreamContent:@\"**append test data**\"];\n\n// stop print when you need\n[self.contentTextView stop];\n```\n\n```objectivec\n@interface StreamPreviewViewController ()<AMXMarkdownTextViewDelegate>\n-(void)initUI\n{\n    // set delegate\n    self.contentTextView.textViewDelegate = self;\n}\n// size change delegate\n-(void)onSizeChange:(CGSize)size\n{\n    // adjust size of AMXMarkdownTextView and container view\n    [self.contentTextView setFrame:CGRectMake(0, 0, self.contentTextView.frame.size.width, size.height)];\n    [self.containerView setContentSize:size];\n    CGPoint bottomOffset = CGPointMake(0, self.containerView.contentSize.height - self.containerView.bounds.size.height);\n    if (bottomOffset.y > 0) {\n        // scroll the container view to bottom\n        [self.containerView setContentOffset:bottomOffset animated:NO];\n    }\n}\n```\n\n\n\n+ Sample Description \n    1. The `StreamPreviewViewController` class is a sample page for previewing streaming output.\n    2. The `AIChatViewController` class demonstrates FluidMarkdown usage in simulated AI conversation scenarios. Note that the conversation data is statically defined and intended solely for rendering demonstration purposes.\n\n![StreamingPreview](https://github.com/antgroup/FluidMarkdown/blob/main/media/StreamViewController.gif)![AIChat](https://github.com/antgroup/FluidMarkdown/blob/main/media/AIChatViewController.gif)\n\n## Android\n1. Initialize by calling AFMInitializer.init(context, backgroundTaskHandler, imageHandler, logHandler) once globally. Except for context, all other parameters can be null.\n2. Create PrinterMarkDownTextView to display markdown content.\n3. Create MarkdownStyles to set render styles.\n4. **Call PrinterMarkDownTextView.init()** to bind MarkdownStyles and ElementClickEventCallback.  Must be called, MarkdownStyles cannot be null.\n5. Set markdown content or call the print start method.\n\n```java\nAFMInitializer.init(context, null, null, null);\n// Create PrinterMarkDownTextView\nPrinterMarkDownTextView markdownTextView = findViewById(R.id.markdown_view);\n\n// Create MarkdownStyles，or you can also create custom styles with new MarkdownStyles()\nMarkdownStyles styles = MarkdownStyles.getDefaultStyles();\n// set style sample\nstyles.linkStyle().icon(\"https://you_image_url\");\nstyles.setTitleStyle(0, TitleStyle.create(1.5f).icon(https://you_image_url));// Set title level 1 style\n\n// bind MarkdownStyles and ElementClickEventCallback. \nmarkdownTextView.init(styles, elementClickEventCallback);\n// Set markdown content or you can call the startPrinting(content) to starting printing.\nmarkdownTextView.setMarkdownText(markdown);\n```\n\n+ Sample Description \n    - MainActivity - Markdown normal mode sample.\n    - PrinterActivity - Streaming print sample.\n    - ListActivity - Streaming print list sample.\n\n![print](https://github.com/antgroup/FluidMarkdown/blob/main/media/android-print.gif)![list](https://github.com/antgroup/FluidMarkdown/blob/main/media/android-list.gif)\n\n## HarmonyOS\n### Combine Markdown\n+ Import and combine the Markdown component in your page `build()` method.\n+ Bind markdown-formatted content text via the `@Param content` parameter.\n+ Handle various callback events inside the Markdown component to enhance the business interaction flow, such as `@Event onMarkdownAreaChange`, `@Event onMarkdownNodeClick`, etc.\n\n``` ts\nimport { Markdown, EMarkdownMode } from 'fluid-markdown';\n\n@ComponentV2\nexport struct MyComponent {\n  @Param content: string;\n  private scroller: Scroller = new Scroller();\n\n  build() {\n      Scroll(this.scroller) {\n        Markdown({\n          content: this.content,\n          mode: EMarkdownMode.Normal,\n          onMarkdownAreaChange: () => {},\n          onMarkdownNodeClick: data => {},\n        })\n          .margin(12)\n      }\n      .width('100%')\n      .height('100%')\n      .scrollable(ScrollDirection.Vertical)\n      .margin(12)\n  }\n}\n```\n\n### Streaming Output\n+ Enable streaming output mode by setting the `@Param` mode parameter to `EMarkdownMode.Typing`.\n+ Create a `MarkdownController` instance and bind it to the `@Param controller` parameter to manage the streaming output process, such as `update()`, `pause()`, `resume()`, etc.\n+ Note: Control methods of `MarkdownController`, such as `update()`, can only be reliably executed within the `@Event onMarkdownTypingReady` callback event.\n+ Note: The `@Param content` parameter will be ignored in streaming output mode.\n\n``` ts\nimport { \n  Markdown, EMarkdownMode, MarkdownController, ETypingMode,\n} from 'fluid-markdown';\n\n@ComponentV2\nexport struct MyComponent {\n  private scroller: Scroller = new Scroller();\n  private markdownController: MarkdownController = new MarkdownController();\n\n  build() {\n      Scroll(this.scroller) {\n        Markdown({\n          controller: this.markdownController,\n          mode: EMarkdownMode.Typing,\n          onMarkdownTypingReady: () => {\n            this.markdownController.typing.update('Hello FluidMarkdown', ETypingMode.Begin);\n          },\n        })\n          .margin(12)\n      }\n      .width('100%')\n      .height('100%')\n      .scrollable(ScrollDirection.Vertical)\n      .margin(12)\n  }\n}\n```\n\n### Theme Config\n+ Create a new Engine instance and bind it to the `@Param engine` parameter.\n+ Set `ITheme` properties for theme styling through the `theme service` within the Engine.\n\n``` ts\nimport { Markdown, EMarkdownMode, BaseEngine } from 'fluid-markdown';\n\n@ComponentV2\nexport struct MyComponent {\n  @Param content: string;\n  private scroller: Scroller = new Scroller();\n  private engine: BaseEngine = new BaseEngine();\n\n  aboutToAppear() {\n    this.engine.theme!.theme!.document!.font!.fontColor = Color.Red;\n  }\n  \n  build() {\n      Scroll(this.scroller) {\n        Markdown({\n          engine: this.engine,\n          content: this.content,\n          mode: EMarkdownMode.Normal,\n          onMarkdownAreaChange: () => {},\n          onMarkdownNodeClick: data => {},\n        })\n          .margin(12)\n      }\n      .width('100%')\n      .height('100%')\n      .scrollable(ScrollDirection.Vertical)\n      .margin(12)\n  }\n}\n```\n\n### Playground\nBuild and run the Playground app to try out FluidMarkdown—have fun!\n![fluid-markdown-ohos-playground](https://mdn.alipayobjects.com/huamei_iobbj9/afts/img/A*uca1RLdcS90AAAAAgEAAAAgAetF-AQ/original)\n\n# Known Issues\n+ Clickable elements within tables appear as plain text and are not interactive.\n+ Nested HTML tags within table cells are not supported.\n+ Tables on Android may overflow their container and do not support horizontal scrolling.\n+ LaTex capability on the HarmonyOS platform is under development and not yet available.\n+ The minimum required HarmonyOS API version is 15 or higher.\n\n# Contribute\nThe FluidMarkdown team welcomes individual or team contributions. For more informations, please refer to the file [CONTRIBUTING](https://github.com/antgroup/FluidMarkdown/blob/main/CONTRIBUTING.md).\n\n# Licensing\nAll source code is licensed under the Apache 2.0 license. For details, please refer to [LICENSE](https://github.com/antgroup/FluidMarkdown/blob/main/LICENSE).\n\nWe acknowledge the following open-source projects:\n\n+ [noties/Markwon](https://github.com/noties/Markwon)\n    - license: Apache-2.0\n+ [indragiek/CocoaMarkdown](https://github.com/indragiek/CocoaMarkdown)\n    - license: <font style=\"color:rgb(31, 35, 40);\">MIT License</font>\n+ [commonmark/commonmark-spec](https://commonmark.org/)\n    - license: <font style=\"color:rgb(31, 35, 40);\">MIT License</font>\n+ [https://github.com/max-lfeng/iosMath/](https://github.com/max-lfeng/iosMath/)\n    - license: <font style=\"color:rgb(31, 35, 40);\">MIT License</font>\n+ [https://github.com/mattt/Ono/](https://github.com/mattt/Ono/)\n    - license: <font style=\"color:rgb(31, 35, 40);\">MIT License</font>\n+ [markdown-it](https://github.com/markdown-it/markdown-it/blob/master/LICENSE)\n    - license: <font style=\"color:rgb(31, 35, 40);\">MIT License</font>\n+ [highlight.js](https://github.com/highlightjs/highlight.js/blob/main/LICENSE)\n    - license: <font style=\"color:rgb(31, 35, 40);\">BSD 3-Clause License</font>\n+ [csstree](https://github.com/csstree/csstree/blob/master/LICENSE)\n    - license: <font style=\"color:rgb(31, 35, 40);\">MIT License</font>\n+ [htmlparser2](https://github.com/fb55/htmlparser2/blob/master/LICENSE)\n    - license: <font style=\"color:rgb(31, 35, 40);\">MIT License</font>\n\n# Acknowledgements and References\n+ All developers who have contributed code to the Ant Markdown component\n+ Thanks to the following open source projects：\n    - [noties/Markwon](https://github.com/noties/Markwon)\n    - [indragiek/CocoaMarkdown](https://github.com/indragiek/CocoaMarkdown)\n    - [commonmark/commonmark-spec](https://commonmark.org/)\n    - [https://github.com/max-lfeng/iosMath/](https://github.com/max-lfeng/iosMath/)\n    - [https://github.com/mattt/Ono/](https://github.com/mattt/Ono/)\n    - [markdown-it](https://github.com/markdown-it/markdown-it/)\n    - [highlight.js](https://github.com/highlightjs/highlight.js/)\n    - [csstree](https://github.com/csstree/csstree/)\n    - [htmlparser2](https://github.com/fb55/htmlparser2/)\n\n\n"
  },
  {
    "path": "iOS/AntMarkdown/.ruby-version",
    "content": "3.2.2\n"
  },
  {
    "path": "iOS/AntMarkdown/.travis.yml",
    "content": "# references:\n# * https://www.objc.io/issues/6-build-tools/travis-ci/\n# * https://github.com/supermarin/xcpretty#usage\n\nosx_image: xcode7.3\nlanguage: objective-c\n# cache: cocoapods\n# podfile: Example/Podfile\n# before_install:\n# - gem install cocoapods # Since Travis is not always on latest version\n# - pod install --project-directory=Example\nscript:\n- set -o pipefail && xcodebuild test -enableCodeCoverage YES -workspace Example/AntMarkdown.xcworkspace -scheme AntMarkdown-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty\n- pod lib lint\n"
  },
  {
    "path": "iOS/AntMarkdown/AntMarkdown.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t0A8283772D37AC3100EAB366 /* AMMarkDownTableViewBlowUpControllerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A8283762D37AC3100EAB366 /* AMMarkDownTableViewBlowUpControllerViewController.m */; };\n\t\t0A8283782D37AC3100EAB366 /* AMMarkDownTableViewBlowUpControllerViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A8283752D37AC3100EAB366 /* AMMarkDownTableViewBlowUpControllerViewController.h */; };\n\t\t0E449DC22D806CFC001E7430 /* CMHorizontalRuleAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E449DC12D806CFC001E7430 /* CMHorizontalRuleAttachment.m */; };\n\t\t0E449DC32D806CFC001E7430 /* CMHorizontalRuleAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E449DC02D806CFC001E7430 /* CMHorizontalRuleAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t771F1B9D2E1674570009C5B5 /* AMIconAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 771F1B9C2E1674570009C5B5 /* AMIconAttachment.m */; };\n\t\t771F1B9E2E1674570009C5B5 /* AMIconAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 771F1B9B2E1674570009C5B5 /* AMIconAttachment.h */; };\n\t\t77A5FD682D9CE399009B0C1D /* AMIconLinkAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 77A5FD672D9CE399009B0C1D /* AMIconLinkAttachment.m */; };\n\t\t77A5FD692D9CE399009B0C1D /* AMIconLinkAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 77A5FD662D9CE399009B0C1D /* AMIconLinkAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t77EB5F0B2E69B3FA0042F5BD /* AMUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 77EB5F0A2E69B3FA0042F5BD /* AMUtils.m */; };\n\t\t9C3EA8682CFA8C7800C8F03B /* NSMutableAttributedString+AntMarkdown.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C3EA8662CFA8C7800C8F03B /* NSMutableAttributedString+AntMarkdown.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9C3EA8692CFA8C7800C8F03B /* NSMutableAttributedString+AntMarkdown.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C3EA8672CFA8C7800C8F03B /* NSMutableAttributedString+AntMarkdown.m */; };\n\t\t9C48DDDB2CE4C5BE00E10317 /* AMUnderline.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C48DDD92CE4C5BE00E10317 /* AMUnderline.m */; };\n\t\t9C48DDDC2CE4C5BE00E10317 /* AMUnderline.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C48DDDA2CE4C5BE00E10317 /* AMUnderline.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9C48DDE02CE5953400E10317 /* AMGradientView.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C48DDDE2CE5953400E10317 /* AMGradientView.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9C48DDE12CE5953400E10317 /* AMGradientView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C48DDDF2CE5953400E10317 /* AMGradientView.m */; };\n\t\t9C7D1B172CEF21AD00EFB06A /* Ono.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7922CDB9D8200451CBD /* Ono.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9C7D1B182CEF21B200EFB06A /* ONOXMLDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7932CDB9D8200451CBD /* ONOXMLDocument.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CB413932CDC657D0000585E /* NSString+AntMarkdown.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CB413912CDC657D0000585E /* NSString+AntMarkdown.m */; };\n\t\t9CB413942CDC657D0000585E /* NSString+AntMarkdown.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CB413922CDC657D0000585E /* NSString+AntMarkdown.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CB413AB2CDC90EB0000585E /* cmark-gfm_export.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E72E2CDB9D8200451CBD /* cmark-gfm_export.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CB413AC2CDC90F50000585E /* cmark-gfm_version.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E72F2CDB9D8200451CBD /* cmark-gfm_version.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CB413B32CDDC31B0000585E /* AMImageTextAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CB413B12CDDC31B0000585E /* AMImageTextAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CB413B42CDDC31B0000585E /* AMImageTextAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CB413B22CDDC31B0000585E /* AMImageTextAttachment.m */; };\n\t\t9CF1E7972CDB9D8200451CBD /* AMAttributedStringRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6BC2CDB9D8200451CBD /* AMAttributedStringRenderer.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E7982CDB9D8200451CBD /* AMAttributedStringRenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6BD2CDB9D8200451CBD /* AMAttributedStringRenderer.m */; };\n\t\t9CF1E7992CDB9D8200451CBD /* AMBlockMathAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6BE2CDB9D8200451CBD /* AMBlockMathAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E79A2CDB9D8200451CBD /* AMBlockMathAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6BF2CDB9D8200451CBD /* AMBlockMathAttachment.m */; };\n\t\t9CF1E79B2CDB9D8200451CBD /* AMCodeHighlighter.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6C02CDB9D8200451CBD /* AMCodeHighlighter.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E79C2CDB9D8200451CBD /* AMCodeHighlighter.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6C12CDB9D8200451CBD /* AMCodeHighlighter.m */; };\n\t\t9CF1E79D2CDB9D8200451CBD /* AMCodeViewAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6C22CDB9D8200451CBD /* AMCodeViewAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E79E2CDB9D8200451CBD /* AMCodeViewAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6C32CDB9D8200451CBD /* AMCodeViewAttachment.m */; };\n\t\t9CF1E79F2CDB9D8200451CBD /* AMDrawable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6C42CDB9D8200451CBD /* AMDrawable.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E7A02CDB9D8200451CBD /* AMDrawable.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6C52CDB9D8200451CBD /* AMDrawable.m */; };\n\t\t9CF1E7A12CDB9D8200451CBD /* AMGradient.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6C62CDB9D8200451CBD /* AMGradient.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E7A22CDB9D8200451CBD /* AMGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6C72CDB9D8200451CBD /* AMGradient.m */; };\n\t\t9CF1E7A32CDB9D8200451CBD /* AMHTMLTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6C82CDB9D8200451CBD /* AMHTMLTransformer.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E7A42CDB9D8200451CBD /* AMHTMLTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6C92CDB9D8200451CBD /* AMHTMLTransformer.m */; };\n\t\t9CF1E7A52CDB9D8200451CBD /* AMInlineMathAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6CA2CDB9D8200451CBD /* AMInlineMathAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E7A62CDB9D8200451CBD /* AMInlineMathAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6CB2CDB9D8200451CBD /* AMInlineMathAttachment.m */; };\n\t\t9CF1E7A72CDB9D8200451CBD /* AMLayoutManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6CC2CDB9D8200451CBD /* AMLayoutManager.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E7A82CDB9D8200451CBD /* AMLayoutManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6CD2CDB9D8200451CBD /* AMLayoutManager.m */; };\n\t\t9CF1E7A92CDB9D8200451CBD /* AMMarkdownCodeView.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6CE2CDB9D8200451CBD /* AMMarkdownCodeView.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E7AA2CDB9D8200451CBD /* AMMarkdownCodeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6CF2CDB9D8200451CBD /* AMMarkdownCodeView.m */; };\n\t\t9CF1E7AB2CDB9D8200451CBD /* AMMarkdownTableLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6D02CDB9D8200451CBD /* AMMarkdownTableLayout.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E7AC2CDB9D8200451CBD /* AMMarkdownTableLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6D12CDB9D8200451CBD /* AMMarkdownTableLayout.m */; };\n\t\t9CF1E7AD2CDB9D8200451CBD /* AMMarkdownTableView.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6D22CDB9D8200451CBD /* AMMarkdownTableView.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E7AE2CDB9D8200451CBD /* AMMarkdownTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6D32CDB9D8200451CBD /* AMMarkdownTableView.m */; };\n\t\t9CF1E7AF2CDB9D8200451CBD /* AMTableViewAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6D42CDB9D8200451CBD /* AMTableViewAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E7B02CDB9D8200451CBD /* AMTableViewAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6D52CDB9D8200451CBD /* AMTableViewAttachment.m */; };\n\t\t9CF1E7B12CDB9D8200451CBD /* AMTextBackground.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6D62CDB9D8200451CBD /* AMTextBackground.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E7B22CDB9D8200451CBD /* AMTextBackground.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6D72CDB9D8200451CBD /* AMTextBackground.m */; };\n\t\t9CF1E7B32CDB9D8200451CBD /* AMTextStyles.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6D82CDB9D8200451CBD /* AMTextStyles.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E7B42CDB9D8200451CBD /* AMTextStyles.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6D92CDB9D8200451CBD /* AMTextStyles.m */; };\n\t\t9CF1E7B52CDB9D8200451CBD /* AMUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6DA2CDB9D8200451CBD /* AMUtils.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E7B72CDB9D8200451CBD /* AMViewAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6DC2CDB9D8200451CBD /* AMViewAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E7B82CDB9D8200451CBD /* AMViewAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6DD2CDB9D8200451CBD /* AMViewAttachment.m */; };\n\t\t9CF1E7B92CDB9D8200451CBD /* AntMarkdown.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6DE2CDB9D8200451CBD /* AntMarkdown.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E7BA2CDB9D8200451CBD /* UILabel+AntMarkdown.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6DF2CDB9D8200451CBD /* UILabel+AntMarkdown.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E7BB2CDB9D8200451CBD /* UILabel+AntMarkdown.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6E02CDB9D8200451CBD /* UILabel+AntMarkdown.m */; };\n\t\t9CF1E7BC2CDB9D8200451CBD /* UITextView+AntMarkdown.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6E12CDB9D8200451CBD /* UITextView+AntMarkdown.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E7BD2CDB9D8200451CBD /* UITextView+AntMarkdown.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6E22CDB9D8200451CBD /* UITextView+AntMarkdown.m */; };\n\t\t9CF1E7BE2CDB9D8200451CBD /* autolink.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6E42CDB9D8200451CBD /* autolink.c */; };\n\t\t9CF1E7C22CDB9D8200451CBD /* core-extensions.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6E82CDB9D8200451CBD /* core-extensions.c */; };\n\t\t9CF1E7C32CDB9D8200451CBD /* ext_scanners.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6E92CDB9D8200451CBD /* ext_scanners.c */; };\n\t\t9CF1E7C62CDB9D8200451CBD /* math_mark.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6EC2CDB9D8200451CBD /* math_mark.c */; };\n\t\t9CF1E7C82CDB9D8200451CBD /* strikethrough.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6EE2CDB9D8200451CBD /* strikethrough.c */; };\n\t\t9CF1E7CA2CDB9D8200451CBD /* table.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6F02CDB9D8200451CBD /* table.c */; };\n\t\t9CF1E7CC2CDB9D8200451CBD /* tagfilter.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6F22CDB9D8200451CBD /* tagfilter.c */; };\n\t\t9CF1E7CE2CDB9D8200451CBD /* tasklist.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6F42CDB9D8200451CBD /* tasklist.c */; };\n\t\t9CF1E7D02CDB9D8200451CBD /* arena.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6F72CDB9D8200451CBD /* arena.c */; };\n\t\t9CF1E7D12CDB9D8200451CBD /* blocks.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6F82CDB9D8200451CBD /* blocks.c */; };\n\t\t9CF1E7D22CDB9D8200451CBD /* buffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6F92CDB9D8200451CBD /* buffer.c */; };\n\t\t9CF1E7D72CDB9D8200451CBD /* cmark_ctype.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E6FE2CDB9D8200451CBD /* cmark_ctype.c */; };\n\t\t9CF1E7DC2CDB9D8200451CBD /* cmark.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7032CDB9D8200451CBD /* cmark.c */; };\n\t\t9CF1E7DD2CDB9D8200451CBD /* commonmark.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7042CDB9D8200451CBD /* commonmark.c */; };\n\t\t9CF1E7E02CDB9D8200451CBD /* footnotes.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7072CDB9D8200451CBD /* footnotes.c */; };\n\t\t9CF1E7E22CDB9D8200451CBD /* houdini_href_e.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7092CDB9D8200451CBD /* houdini_href_e.c */; };\n\t\t9CF1E7E32CDB9D8200451CBD /* houdini_html_e.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E70A2CDB9D8200451CBD /* houdini_html_e.c */; };\n\t\t9CF1E7E42CDB9D8200451CBD /* houdini_html_u.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E70B2CDB9D8200451CBD /* houdini_html_u.c */; };\n\t\t9CF1E7E62CDB9D8200451CBD /* html.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E70D2CDB9D8200451CBD /* html.c */; };\n\t\t9CF1E7E82CDB9D8200451CBD /* inlines.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E70F2CDB9D8200451CBD /* inlines.c */; };\n\t\t9CF1E7EA2CDB9D8200451CBD /* iterator.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7112CDB9D8200451CBD /* iterator.c */; };\n\t\t9CF1E7EC2CDB9D8200451CBD /* latex.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7132CDB9D8200451CBD /* latex.c */; };\n\t\t9CF1E7EE2CDB9D8200451CBD /* linked_list.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7152CDB9D8200451CBD /* linked_list.c */; };\n\t\t9CF1E7EF2CDB9D8200451CBD /* man.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7162CDB9D8200451CBD /* man.c */; };\n\t\t9CF1E7F02CDB9D8200451CBD /* map.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7172CDB9D8200451CBD /* map.c */; };\n\t\t9CF1E7F22CDB9D8200451CBD /* node.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7192CDB9D8200451CBD /* node.c */; };\n\t\t9CF1E7F52CDB9D8200451CBD /* plaintext.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E71C2CDB9D8200451CBD /* plaintext.c */; };\n\t\t9CF1E7F62CDB9D8200451CBD /* plugin.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E71D2CDB9D8200451CBD /* plugin.c */; };\n\t\t9CF1E7F82CDB9D8200451CBD /* references.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E71F2CDB9D8200451CBD /* references.c */; };\n\t\t9CF1E7FA2CDB9D8200451CBD /* registry.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7212CDB9D8200451CBD /* registry.c */; };\n\t\t9CF1E7FC2CDB9D8200451CBD /* render.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7232CDB9D8200451CBD /* render.c */; };\n\t\t9CF1E7FE2CDB9D8200451CBD /* scanners.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7252CDB9D8200451CBD /* scanners.c */; };\n\t\t9CF1E8012CDB9D8200451CBD /* syntax_extension.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7282CDB9D8200451CBD /* syntax_extension.c */; };\n\t\t9CF1E8032CDB9D8200451CBD /* utf8.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E72A2CDB9D8200451CBD /* utf8.c */; };\n\t\t9CF1E8052CDB9D8200451CBD /* xml.c in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E72C2CDB9D8200451CBD /* xml.c */; };\n\t\t9CF1E8092CDB9D8200451CBD /* CMAttributedStringRenderer_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7332CDB9D8200451CBD /* CMAttributedStringRenderer_Private.h */; };\n\t\t9CF1E80A2CDB9D8200451CBD /* CMAttributedStringRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7342CDB9D8200451CBD /* CMAttributedStringRenderer.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E80B2CDB9D8200451CBD /* CMAttributedStringRenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7352CDB9D8200451CBD /* CMAttributedStringRenderer.m */; };\n\t\t9CF1E80C2CDB9D8200451CBD /* CMAttributeRun.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7362CDB9D8200451CBD /* CMAttributeRun.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E80D2CDB9D8200451CBD /* CMAttributeRun.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7372CDB9D8200451CBD /* CMAttributeRun.m */; };\n\t\t9CF1E80E2CDB9D8200451CBD /* CMBlockTextAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7382CDB9D8200451CBD /* CMBlockTextAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E80F2CDB9D8200451CBD /* CMBlockTextAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7392CDB9D8200451CBD /* CMBlockTextAttachment.m */; };\n\t\t9CF1E8102CDB9D8200451CBD /* CMCascadingAttributeStack.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E73A2CDB9D8200451CBD /* CMCascadingAttributeStack.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E8112CDB9D8200451CBD /* CMCascadingAttributeStack.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E73B2CDB9D8200451CBD /* CMCascadingAttributeStack.m */; };\n\t\t9CF1E8122CDB9D8200451CBD /* CMDocument_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E73C2CDB9D8200451CBD /* CMDocument_Private.h */; };\n\t\t9CF1E8132CDB9D8200451CBD /* CMDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E73D2CDB9D8200451CBD /* CMDocument.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E8142CDB9D8200451CBD /* CMDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E73E2CDB9D8200451CBD /* CMDocument.m */; };\n\t\t9CF1E8152CDB9D8200451CBD /* CMDocument+AttributedStringAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E73F2CDB9D8200451CBD /* CMDocument+AttributedStringAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E8162CDB9D8200451CBD /* CMDocument+AttributedStringAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7402CDB9D8200451CBD /* CMDocument+AttributedStringAdditions.m */; };\n\t\t9CF1E8172CDB9D8200451CBD /* CMDocument+HTMLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7412CDB9D8200451CBD /* CMDocument+HTMLAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E8182CDB9D8200451CBD /* CMDocument+HTMLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7422CDB9D8200451CBD /* CMDocument+HTMLAdditions.m */; };\n\t\t9CF1E8192CDB9D8200451CBD /* CMHTMLElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7432CDB9D8200451CBD /* CMHTMLElement.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E81A2CDB9D8200451CBD /* CMHTMLElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7442CDB9D8200451CBD /* CMHTMLElement.m */; };\n\t\t9CF1E81B2CDB9D8200451CBD /* CMHTMLElementTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7452CDB9D8200451CBD /* CMHTMLElementTransformer.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E81C2CDB9D8200451CBD /* CMHTMLRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7462CDB9D8200451CBD /* CMHTMLRenderer.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E81D2CDB9D8200451CBD /* CMHTMLRenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7472CDB9D8200451CBD /* CMHTMLRenderer.m */; };\n\t\t9CF1E81E2CDB9D8200451CBD /* CMHTMLScriptTransformer_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7482CDB9D8200451CBD /* CMHTMLScriptTransformer_Private.h */; };\n\t\t9CF1E81F2CDB9D8200451CBD /* CMHTMLScriptTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7492CDB9D8200451CBD /* CMHTMLScriptTransformer.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E8202CDB9D8200451CBD /* CMHTMLScriptTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E74A2CDB9D8200451CBD /* CMHTMLScriptTransformer.m */; };\n\t\t9CF1E8212CDB9D8200451CBD /* CMHTMLStrikethroughTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E74B2CDB9D8200451CBD /* CMHTMLStrikethroughTransformer.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E8222CDB9D8200451CBD /* CMHTMLStrikethroughTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E74C2CDB9D8200451CBD /* CMHTMLStrikethroughTransformer.m */; };\n\t\t9CF1E8232CDB9D8200451CBD /* CMHTMLSubscriptTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E74D2CDB9D8200451CBD /* CMHTMLSubscriptTransformer.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E8242CDB9D8200451CBD /* CMHTMLSubscriptTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E74E2CDB9D8200451CBD /* CMHTMLSubscriptTransformer.m */; };\n\t\t9CF1E8252CDB9D8200451CBD /* CMHTMLSuperscriptTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E74F2CDB9D8200451CBD /* CMHTMLSuperscriptTransformer.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E8262CDB9D8200451CBD /* CMHTMLSuperscriptTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7502CDB9D8200451CBD /* CMHTMLSuperscriptTransformer.m */; };\n\t\t9CF1E8272CDB9D8200451CBD /* CMHTMLUnderlineTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7512CDB9D8200451CBD /* CMHTMLUnderlineTransformer.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E8282CDB9D8200451CBD /* CMHTMLUnderlineTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7522CDB9D8200451CBD /* CMHTMLUnderlineTransformer.m */; };\n\t\t9CF1E8292CDB9D8200451CBD /* CMHTMLUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7532CDB9D8200451CBD /* CMHTMLUtilities.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E82A2CDB9D8200451CBD /* CMHTMLUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7542CDB9D8200451CBD /* CMHTMLUtilities.m */; };\n\t\t9CF1E82B2CDB9D8200451CBD /* CMImageTextAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7552CDB9D8200451CBD /* CMImageTextAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E82C2CDB9D8200451CBD /* CMImageTextAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7562CDB9D8200451CBD /* CMImageTextAttachment.m */; };\n\t\t9CF1E82D2CDB9D8200451CBD /* CMInlineTextAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7572CDB9D8200451CBD /* CMInlineTextAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E82E2CDB9D8200451CBD /* CMInlineTextAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7582CDB9D8200451CBD /* CMInlineTextAttachment.m */; };\n\t\t9CF1E82F2CDB9D8200451CBD /* CMIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7592CDB9D8200451CBD /* CMIterator.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E8302CDB9D8200451CBD /* CMIterator.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E75A2CDB9D8200451CBD /* CMIterator.m */; };\n\t\t9CF1E8322CDB9D8200451CBD /* CMNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E75C2CDB9D8200451CBD /* CMNode.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E8332CDB9D8200451CBD /* CMNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E75D2CDB9D8200451CBD /* CMNode.m */; };\n\t\t9CF1E8342CDB9D8200451CBD /* CMNode+Table.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E75E2CDB9D8200451CBD /* CMNode+Table.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E8352CDB9D8200451CBD /* CMNode+Table.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E75F2CDB9D8200451CBD /* CMNode+Table.m */; };\n\t\t9CF1E8362CDB9D8200451CBD /* CMParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7602CDB9D8200451CBD /* CMParser.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E8372CDB9D8200451CBD /* CMParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7612CDB9D8200451CBD /* CMParser.m */; };\n\t\t9CF1E8382CDB9D8200451CBD /* CMPlatformDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7622CDB9D8200451CBD /* CMPlatformDefines.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E8392CDB9D8200451CBD /* CMStack.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7632CDB9D8200451CBD /* CMStack.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E83A2CDB9D8200451CBD /* CMStack.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7642CDB9D8200451CBD /* CMStack.m */; };\n\t\t9CF1E83B2CDB9D8200451CBD /* CMTextAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7652CDB9D8200451CBD /* CMTextAttributes.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E83C2CDB9D8200451CBD /* CMTextAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7662CDB9D8200451CBD /* CMTextAttributes.m */; };\n\t\t9CF1E83D2CDB9D8200451CBD /* CocoaMarkdown.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7672CDB9D8200451CBD /* CocoaMarkdown.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E8402CDB9D8200451CBD /* MTMathAtomFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E76B2CDB9D8200451CBD /* MTMathAtomFactory.m */; };\n\t\t9CF1E8422CDB9D8200451CBD /* MTMathList.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E76D2CDB9D8200451CBD /* MTMathList.m */; };\n\t\t9CF1E8442CDB9D8200451CBD /* MTMathListBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E76F2CDB9D8200451CBD /* MTMathListBuilder.m */; };\n\t\t9CF1E8462CDB9D8200451CBD /* MTMathListIndex.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7712CDB9D8200451CBD /* MTMathListIndex.m */; };\n\t\t9CF1E8482CDB9D8200451CBD /* MTUnicode.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7732CDB9D8200451CBD /* MTUnicode.m */; };\n\t\t9CF1E84B2CDB9D8200451CBD /* MTFontMathTable.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7772CDB9D8200451CBD /* MTFontMathTable.m */; };\n\t\t9CF1E84E2CDB9D8200451CBD /* MTTypesetter.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E77A2CDB9D8200451CBD /* MTTypesetter.m */; };\n\t\t9CF1E8512CDB9D8200451CBD /* MTFont.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E77E2CDB9D8200451CBD /* MTFont.m */; };\n\t\t9CF1E8532CDB9D8200451CBD /* MTFontManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7802CDB9D8200451CBD /* MTFontManager.m */; };\n\t\t9CF1E8552CDB9D8200451CBD /* MTLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7822CDB9D8200451CBD /* MTLabel.m */; };\n\t\t9CF1E8572CDB9D8200451CBD /* MTMathListDisplay.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7842CDB9D8200451CBD /* MTMathListDisplay.m */; };\n\t\t9CF1E8592CDB9D8200451CBD /* MTMathUILabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7862CDB9D8200451CBD /* MTMathUILabel.m */; };\n\t\t9CF1E85B2CDB9D8200451CBD /* NSBezierPath+addLineToPoint.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7882CDB9D8200451CBD /* NSBezierPath+addLineToPoint.m */; };\n\t\t9CF1E85D2CDB9D8200451CBD /* NSColor+HexString.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E78A2CDB9D8200451CBD /* NSColor+HexString.m */; };\n\t\t9CF1E85F2CDB9D8200451CBD /* NSView+backgroundColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E78C2CDB9D8200451CBD /* NSView+backgroundColor.m */; };\n\t\t9CF1E8612CDB9D8200451CBD /* UIColor+HexString.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E78E2CDB9D8200451CBD /* UIColor+HexString.m */; };\n\t\t9CF1E8652CDB9D8200451CBD /* ONOXMLDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1E7942CDB9D8200451CBD /* ONOXMLDocument.m */; };\n\t\t9CF1E8682CDB9FE300451CBD /* mathFonts.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 9CF1E8662CDB9FE300451CBD /* mathFonts.bundle */; };\n\t\t9CF1E8692CDB9FE300451CBD /* highlightjs.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 9CF1E8672CDB9FE300451CBD /* highlightjs.bundle */; };\n\t\t9CF1E86C2CDBA3FB00451CBD /* AntMarkdown.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9CF1E86B2CDBA3FB00451CBD /* AntMarkdown.framework */; };\n\t\t9CF1E86D2CDBA56200451CBD /* strikethrough.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6EF2CDB9D8200451CBD /* strikethrough.h */; };\n\t\t9CF1E86E2CDBA56200451CBD /* tagfilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6F32CDB9D8200451CBD /* tagfilter.h */; };\n\t\t9CF1E86F2CDBA56200451CBD /* table.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6F12CDB9D8200451CBD /* table.h */; };\n\t\t9CF1E8702CDBA56200451CBD /* math_mark.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6ED2CDB9D8200451CBD /* math_mark.h */; };\n\t\t9CF1E8712CDBA56200451CBD /* tasklist.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6F52CDB9D8200451CBD /* tasklist.h */; };\n\t\t9CF1E8722CDBA56200451CBD /* autolink.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6E52CDB9D8200451CBD /* autolink.h */; };\n\t\t9CF1E8732CDBA56200451CBD /* cmark-gfm-core-extensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6E72CDB9D8200451CBD /* cmark-gfm-core-extensions.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E8742CDBA56200451CBD /* ext_scanners.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6EA2CDB9D8200451CBD /* ext_scanners.h */; };\n\t\t9CF1E8752CDBA59300451CBD /* chunk.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6FC2CDB9D8200451CBD /* chunk.h */; };\n\t\t9CF1E8762CDBA59300451CBD /* buffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6FA2CDB9D8200451CBD /* buffer.h */; };\n\t\t9CF1E8772CDBA59800451CBD /* cmark_ctype.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E6FF2CDB9D8200451CBD /* cmark_ctype.h */; };\n\t\t9CF1E8782CDBA59F00451CBD /* references.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7202CDB9D8200451CBD /* references.h */; };\n\t\t9CF1E8792CDBA59F00451CBD /* registry.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7222CDB9D8200451CBD /* registry.h */; };\n\t\t9CF1E87A2CDBA59F00451CBD /* render.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7242CDB9D8200451CBD /* render.h */; };\n\t\t9CF1E87B2CDBA59F00451CBD /* node.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E71A2CDB9D8200451CBD /* node.h */; };\n\t\t9CF1E87C2CDBA59F00451CBD /* footnotes.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7082CDB9D8200451CBD /* footnotes.h */; };\n\t\t9CF1E87D2CDBA59F00451CBD /* iterator.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7122CDB9D8200451CBD /* iterator.h */; };\n\t\t9CF1E87E2CDBA59F00451CBD /* scanners.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7262CDB9D8200451CBD /* scanners.h */; };\n\t\t9CF1E87F2CDBA59F00451CBD /* inlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7102CDB9D8200451CBD /* inlines.h */; };\n\t\t9CF1E8802CDBA59F00451CBD /* houdini.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E70C2CDB9D8200451CBD /* houdini.h */; };\n\t\t9CF1E8812CDBA59F00451CBD /* map.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7182CDB9D8200451CBD /* map.h */; };\n\t\t9CF1E8822CDBA59F00451CBD /* plugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E71E2CDB9D8200451CBD /* plugin.h */; };\n\t\t9CF1E8832CDBA59F00451CBD /* syntax_extension.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7292CDB9D8200451CBD /* syntax_extension.h */; };\n\t\t9CF1E8842CDBA59F00451CBD /* parser.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E71B2CDB9D8200451CBD /* parser.h */; };\n\t\t9CF1E8852CDBA59F00451CBD /* html.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E70E2CDB9D8200451CBD /* html.h */; };\n\t\t9CF1E8862CDBA59F00451CBD /* utf8.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E72B2CDB9D8200451CBD /* utf8.h */; };\n\t\t9CF1E8872CDBA5B100451CBD /* cmark-gfm-extension_api.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7012CDB9D8200451CBD /* cmark-gfm-extension_api.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E8882CDBA5B500451CBD /* cmark-gfm.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E7022CDB9D8200451CBD /* cmark-gfm.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\t9CF1E8892CDBA5F500451CBD /* CMNode_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CF1E75B2CDB9D8200451CBD /* CMNode_Private.h */; };\n\t\tA2CA04A0188A78A900D1E152 /* AntMarkdown-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = A2CA0499188A78A900D1E152 /* AntMarkdown-Info.plist */; };\n\t\tA2CA04A1188A78A900D1E152 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = A2CA049B188A78A900D1E152 /* InfoPlist.strings */; };\n\t\tA2E668DD2D310BA2005CC3B6 /* AMGradientLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = A2E668DC2D310BA2005CC3B6 /* AMGradientLayer.m */; };\n\t\tA2E668DE2D310BA2005CC3B6 /* AMGradientLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = A2E668DB2D310BA2005CC3B6 /* AMGradientLayer.h */; };\n\t\tAAC068C2188D1F8E001B468D /* AntMarkdown.bundle in Resources */ = {isa = PBXBuildFile; fileRef = AAC068C1188D1F8E001B468D /* AntMarkdown.bundle */; };\n\t\tEC2133272D9AB6F700C86B39 /* CMTaskCheckAttachment+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = EC2133242D9AB6F700C86B39 /* CMTaskCheckAttachment+Private.h */; };\n\t\tEC3578F52D816E8200F10E01 /* AMLayoutManager+Quote.m in Sources */ = {isa = PBXBuildFile; fileRef = EC3578F42D816E8200F10E01 /* AMLayoutManager+Quote.m */; };\n\t\tEC3578F62D816E8200F10E01 /* AMLayoutManager+Quote.h in Headers */ = {isa = PBXBuildFile; fileRef = EC3578F32D816E8200F10E01 /* AMLayoutManager+Quote.h */; };\n\t\tEC5421962D928E5E00510C86 /* AMEmojiManager.h in Headers */ = {isa = PBXBuildFile; fileRef = EC5421942D928E5E00510C86 /* AMEmojiManager.h */; };\n\t\tEC5421972D928E5E00510C86 /* AMEmojiManager.m in Sources */ = {isa = PBXBuildFile; fileRef = EC5421952D928E5E00510C86 /* AMEmojiManager.m */; };\n\t\tECE1C84D2D924D930034FEE2 /* emoji.c in Sources */ = {isa = PBXBuildFile; fileRef = ECE1C84C2D924D930034FEE2 /* emoji.c */; };\n\t\tECE1C84E2D924D930034FEE2 /* emoji.h in Headers */ = {isa = PBXBuildFile; fileRef = ECE1C84B2D924D930034FEE2 /* emoji.h */; };\n\t\tECF404AC2D9A45C400B04B59 /* CMTaskCheckAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = ECF404AA2D9A45C400B04B59 /* CMTaskCheckAttachment.h */; };\n\t\tECF404AD2D9A45C400B04B59 /* CMTaskCheckAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = ECF404AB2D9A45C400B04B59 /* CMTaskCheckAttachment.m */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\t0A8283752D37AC3100EAB366 /* AMMarkDownTableViewBlowUpControllerViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AMMarkDownTableViewBlowUpControllerViewController.h; sourceTree = \"<group>\"; };\n\t\t0A8283762D37AC3100EAB366 /* AMMarkDownTableViewBlowUpControllerViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AMMarkDownTableViewBlowUpControllerViewController.m; sourceTree = \"<group>\"; };\n\t\t0E449DC02D806CFC001E7430 /* CMHorizontalRuleAttachment.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CMHorizontalRuleAttachment.h; sourceTree = \"<group>\"; };\n\t\t0E449DC12D806CFC001E7430 /* CMHorizontalRuleAttachment.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CMHorizontalRuleAttachment.m; sourceTree = \"<group>\"; };\n\t\t771F1B9B2E1674570009C5B5 /* AMIconAttachment.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AMIconAttachment.h; sourceTree = \"<group>\"; };\n\t\t771F1B9C2E1674570009C5B5 /* AMIconAttachment.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AMIconAttachment.m; sourceTree = \"<group>\"; };\n\t\t77A5FD662D9CE399009B0C1D /* AMIconLinkAttachment.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AMIconLinkAttachment.h; sourceTree = \"<group>\"; };\n\t\t77A5FD672D9CE399009B0C1D /* AMIconLinkAttachment.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AMIconLinkAttachment.m; sourceTree = \"<group>\"; };\n\t\t77EB5F0A2E69B3FA0042F5BD /* AMUtils.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AMUtils.m; sourceTree = \"<group>\"; };\n\t\t9C3EA8662CFA8C7800C8F03B /* NSMutableAttributedString+AntMarkdown.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"NSMutableAttributedString+AntMarkdown.h\"; sourceTree = \"<group>\"; };\n\t\t9C3EA8672CFA8C7800C8F03B /* NSMutableAttributedString+AntMarkdown.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"NSMutableAttributedString+AntMarkdown.m\"; sourceTree = \"<group>\"; };\n\t\t9C48DDD92CE4C5BE00E10317 /* AMUnderline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AMUnderline.m; sourceTree = \"<group>\"; };\n\t\t9C48DDDA2CE4C5BE00E10317 /* AMUnderline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AMUnderline.h; sourceTree = \"<group>\"; };\n\t\t9C48DDDE2CE5953400E10317 /* AMGradientView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AMGradientView.h; sourceTree = \"<group>\"; };\n\t\t9C48DDDF2CE5953400E10317 /* AMGradientView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AMGradientView.m; sourceTree = \"<group>\"; };\n\t\t9CB413912CDC657D0000585E /* NSString+AntMarkdown.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"NSString+AntMarkdown.m\"; sourceTree = \"<group>\"; };\n\t\t9CB413922CDC657D0000585E /* NSString+AntMarkdown.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"NSString+AntMarkdown.h\"; sourceTree = \"<group>\"; };\n\t\t9CB413B12CDDC31B0000585E /* AMImageTextAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AMImageTextAttachment.h; sourceTree = \"<group>\"; };\n\t\t9CB413B22CDDC31B0000585E /* AMImageTextAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AMImageTextAttachment.m; sourceTree = \"<group>\"; };\n\t\t9CF1E6BC2CDB9D8200451CBD /* AMAttributedStringRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AMAttributedStringRenderer.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6BD2CDB9D8200451CBD /* AMAttributedStringRenderer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AMAttributedStringRenderer.m; sourceTree = \"<group>\"; };\n\t\t9CF1E6BE2CDB9D8200451CBD /* AMBlockMathAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AMBlockMathAttachment.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6BF2CDB9D8200451CBD /* AMBlockMathAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AMBlockMathAttachment.m; sourceTree = \"<group>\"; };\n\t\t9CF1E6C02CDB9D8200451CBD /* AMCodeHighlighter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AMCodeHighlighter.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6C12CDB9D8200451CBD /* AMCodeHighlighter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AMCodeHighlighter.m; sourceTree = \"<group>\"; };\n\t\t9CF1E6C22CDB9D8200451CBD /* AMCodeViewAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AMCodeViewAttachment.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6C32CDB9D8200451CBD /* AMCodeViewAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AMCodeViewAttachment.m; sourceTree = \"<group>\"; };\n\t\t9CF1E6C42CDB9D8200451CBD /* AMDrawable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AMDrawable.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6C52CDB9D8200451CBD /* AMDrawable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AMDrawable.m; sourceTree = \"<group>\"; };\n\t\t9CF1E6C62CDB9D8200451CBD /* AMGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AMGradient.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6C72CDB9D8200451CBD /* AMGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AMGradient.m; sourceTree = \"<group>\"; };\n\t\t9CF1E6C82CDB9D8200451CBD /* AMHTMLTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AMHTMLTransformer.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6C92CDB9D8200451CBD /* AMHTMLTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AMHTMLTransformer.m; sourceTree = \"<group>\"; };\n\t\t9CF1E6CA2CDB9D8200451CBD /* AMInlineMathAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AMInlineMathAttachment.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6CB2CDB9D8200451CBD /* AMInlineMathAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AMInlineMathAttachment.m; sourceTree = \"<group>\"; };\n\t\t9CF1E6CC2CDB9D8200451CBD /* AMLayoutManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AMLayoutManager.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6CD2CDB9D8200451CBD /* AMLayoutManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AMLayoutManager.m; sourceTree = \"<group>\"; };\n\t\t9CF1E6CE2CDB9D8200451CBD /* AMMarkdownCodeView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AMMarkdownCodeView.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6CF2CDB9D8200451CBD /* AMMarkdownCodeView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AMMarkdownCodeView.m; sourceTree = \"<group>\"; };\n\t\t9CF1E6D02CDB9D8200451CBD /* AMMarkdownTableLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AMMarkdownTableLayout.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6D12CDB9D8200451CBD /* AMMarkdownTableLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AMMarkdownTableLayout.m; sourceTree = \"<group>\"; };\n\t\t9CF1E6D22CDB9D8200451CBD /* AMMarkdownTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AMMarkdownTableView.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6D32CDB9D8200451CBD /* AMMarkdownTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AMMarkdownTableView.m; sourceTree = \"<group>\"; };\n\t\t9CF1E6D42CDB9D8200451CBD /* AMTableViewAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AMTableViewAttachment.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6D52CDB9D8200451CBD /* AMTableViewAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AMTableViewAttachment.m; sourceTree = \"<group>\"; };\n\t\t9CF1E6D62CDB9D8200451CBD /* AMTextBackground.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AMTextBackground.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6D72CDB9D8200451CBD /* AMTextBackground.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AMTextBackground.m; sourceTree = \"<group>\"; };\n\t\t9CF1E6D82CDB9D8200451CBD /* AMTextStyles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AMTextStyles.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6D92CDB9D8200451CBD /* AMTextStyles.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AMTextStyles.m; sourceTree = \"<group>\"; };\n\t\t9CF1E6DA2CDB9D8200451CBD /* AMUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AMUtils.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6DC2CDB9D8200451CBD /* AMViewAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AMViewAttachment.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6DD2CDB9D8200451CBD /* AMViewAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AMViewAttachment.m; sourceTree = \"<group>\"; };\n\t\t9CF1E6DE2CDB9D8200451CBD /* AntMarkdown.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AntMarkdown.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6DF2CDB9D8200451CBD /* UILabel+AntMarkdown.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"UILabel+AntMarkdown.h\"; sourceTree = \"<group>\"; };\n\t\t9CF1E6E02CDB9D8200451CBD /* UILabel+AntMarkdown.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"UILabel+AntMarkdown.m\"; sourceTree = \"<group>\"; };\n\t\t9CF1E6E12CDB9D8200451CBD /* UITextView+AntMarkdown.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"UITextView+AntMarkdown.h\"; sourceTree = \"<group>\"; };\n\t\t9CF1E6E22CDB9D8200451CBD /* UITextView+AntMarkdown.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"UITextView+AntMarkdown.m\"; sourceTree = \"<group>\"; };\n\t\t9CF1E6E42CDB9D8200451CBD /* autolink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = autolink.c; sourceTree = \"<group>\"; };\n\t\t9CF1E6E52CDB9D8200451CBD /* autolink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = autolink.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6E72CDB9D8200451CBD /* cmark-gfm-core-extensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"cmark-gfm-core-extensions.h\"; sourceTree = \"<group>\"; };\n\t\t9CF1E6E82CDB9D8200451CBD /* core-extensions.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = \"core-extensions.c\"; sourceTree = \"<group>\"; };\n\t\t9CF1E6E92CDB9D8200451CBD /* ext_scanners.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ext_scanners.c; sourceTree = \"<group>\"; };\n\t\t9CF1E6EA2CDB9D8200451CBD /* ext_scanners.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ext_scanners.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6EC2CDB9D8200451CBD /* math_mark.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = math_mark.c; sourceTree = \"<group>\"; };\n\t\t9CF1E6ED2CDB9D8200451CBD /* math_mark.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = math_mark.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6EE2CDB9D8200451CBD /* strikethrough.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = strikethrough.c; sourceTree = \"<group>\"; };\n\t\t9CF1E6EF2CDB9D8200451CBD /* strikethrough.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = strikethrough.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6F02CDB9D8200451CBD /* table.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = table.c; sourceTree = \"<group>\"; };\n\t\t9CF1E6F12CDB9D8200451CBD /* table.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = table.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6F22CDB9D8200451CBD /* tagfilter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tagfilter.c; sourceTree = \"<group>\"; };\n\t\t9CF1E6F32CDB9D8200451CBD /* tagfilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tagfilter.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6F42CDB9D8200451CBD /* tasklist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tasklist.c; sourceTree = \"<group>\"; };\n\t\t9CF1E6F52CDB9D8200451CBD /* tasklist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tasklist.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6F72CDB9D8200451CBD /* arena.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = arena.c; sourceTree = \"<group>\"; };\n\t\t9CF1E6F82CDB9D8200451CBD /* blocks.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocks.c; sourceTree = \"<group>\"; };\n\t\t9CF1E6F92CDB9D8200451CBD /* buffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = buffer.c; sourceTree = \"<group>\"; };\n\t\t9CF1E6FA2CDB9D8200451CBD /* buffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = buffer.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6FB2CDB9D8200451CBD /* case_fold_switch.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = case_fold_switch.inc; sourceTree = \"<group>\"; };\n\t\t9CF1E6FC2CDB9D8200451CBD /* chunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = chunk.h; sourceTree = \"<group>\"; };\n\t\t9CF1E6FE2CDB9D8200451CBD /* cmark_ctype.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmark_ctype.c; sourceTree = \"<group>\"; };\n\t\t9CF1E6FF2CDB9D8200451CBD /* cmark_ctype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cmark_ctype.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7012CDB9D8200451CBD /* cmark-gfm-extension_api.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"cmark-gfm-extension_api.h\"; sourceTree = \"<group>\"; };\n\t\t9CF1E7022CDB9D8200451CBD /* cmark-gfm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"cmark-gfm.h\"; sourceTree = \"<group>\"; };\n\t\t9CF1E7032CDB9D8200451CBD /* cmark.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cmark.c; sourceTree = \"<group>\"; };\n\t\t9CF1E7042CDB9D8200451CBD /* commonmark.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = commonmark.c; sourceTree = \"<group>\"; };\n\t\t9CF1E7072CDB9D8200451CBD /* footnotes.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = footnotes.c; sourceTree = \"<group>\"; };\n\t\t9CF1E7082CDB9D8200451CBD /* footnotes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = footnotes.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7092CDB9D8200451CBD /* houdini_href_e.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = houdini_href_e.c; sourceTree = \"<group>\"; };\n\t\t9CF1E70A2CDB9D8200451CBD /* houdini_html_e.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = houdini_html_e.c; sourceTree = \"<group>\"; };\n\t\t9CF1E70B2CDB9D8200451CBD /* houdini_html_u.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = houdini_html_u.c; sourceTree = \"<group>\"; };\n\t\t9CF1E70C2CDB9D8200451CBD /* houdini.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = houdini.h; sourceTree = \"<group>\"; };\n\t\t9CF1E70D2CDB9D8200451CBD /* html.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = html.c; sourceTree = \"<group>\"; };\n\t\t9CF1E70E2CDB9D8200451CBD /* html.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = html.h; sourceTree = \"<group>\"; };\n\t\t9CF1E70F2CDB9D8200451CBD /* inlines.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = inlines.c; sourceTree = \"<group>\"; };\n\t\t9CF1E7102CDB9D8200451CBD /* inlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = inlines.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7112CDB9D8200451CBD /* iterator.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = iterator.c; sourceTree = \"<group>\"; };\n\t\t9CF1E7122CDB9D8200451CBD /* iterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iterator.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7132CDB9D8200451CBD /* latex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = latex.c; sourceTree = \"<group>\"; };\n\t\t9CF1E7152CDB9D8200451CBD /* linked_list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = linked_list.c; sourceTree = \"<group>\"; };\n\t\t9CF1E7162CDB9D8200451CBD /* man.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = man.c; sourceTree = \"<group>\"; };\n\t\t9CF1E7172CDB9D8200451CBD /* map.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = map.c; sourceTree = \"<group>\"; };\n\t\t9CF1E7182CDB9D8200451CBD /* map.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = map.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7192CDB9D8200451CBD /* node.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = node.c; sourceTree = \"<group>\"; };\n\t\t9CF1E71A2CDB9D8200451CBD /* node.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = node.h; sourceTree = \"<group>\"; };\n\t\t9CF1E71B2CDB9D8200451CBD /* parser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = parser.h; sourceTree = \"<group>\"; };\n\t\t9CF1E71C2CDB9D8200451CBD /* plaintext.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = plaintext.c; sourceTree = \"<group>\"; };\n\t\t9CF1E71D2CDB9D8200451CBD /* plugin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = plugin.c; sourceTree = \"<group>\"; };\n\t\t9CF1E71E2CDB9D8200451CBD /* plugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = plugin.h; sourceTree = \"<group>\"; };\n\t\t9CF1E71F2CDB9D8200451CBD /* references.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = references.c; sourceTree = \"<group>\"; };\n\t\t9CF1E7202CDB9D8200451CBD /* references.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = references.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7212CDB9D8200451CBD /* registry.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = registry.c; sourceTree = \"<group>\"; };\n\t\t9CF1E7222CDB9D8200451CBD /* registry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = registry.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7232CDB9D8200451CBD /* render.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = render.c; sourceTree = \"<group>\"; };\n\t\t9CF1E7242CDB9D8200451CBD /* render.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = render.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7252CDB9D8200451CBD /* scanners.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = scanners.c; sourceTree = \"<group>\"; };\n\t\t9CF1E7262CDB9D8200451CBD /* scanners.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scanners.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7282CDB9D8200451CBD /* syntax_extension.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = syntax_extension.c; sourceTree = \"<group>\"; };\n\t\t9CF1E7292CDB9D8200451CBD /* syntax_extension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = syntax_extension.h; sourceTree = \"<group>\"; };\n\t\t9CF1E72A2CDB9D8200451CBD /* utf8.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = utf8.c; sourceTree = \"<group>\"; };\n\t\t9CF1E72B2CDB9D8200451CBD /* utf8.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utf8.h; sourceTree = \"<group>\"; };\n\t\t9CF1E72C2CDB9D8200451CBD /* xml.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xml.c; sourceTree = \"<group>\"; };\n\t\t9CF1E72E2CDB9D8200451CBD /* cmark-gfm_export.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"cmark-gfm_export.h\"; sourceTree = \"<group>\"; };\n\t\t9CF1E72F2CDB9D8200451CBD /* cmark-gfm_version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"cmark-gfm_version.h\"; sourceTree = \"<group>\"; };\n\t\t9CF1E7302CDB9D8200451CBD /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7332CDB9D8200451CBD /* CMAttributedStringRenderer_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMAttributedStringRenderer_Private.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7342CDB9D8200451CBD /* CMAttributedStringRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMAttributedStringRenderer.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7352CDB9D8200451CBD /* CMAttributedStringRenderer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CMAttributedStringRenderer.m; sourceTree = \"<group>\"; };\n\t\t9CF1E7362CDB9D8200451CBD /* CMAttributeRun.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMAttributeRun.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7372CDB9D8200451CBD /* CMAttributeRun.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CMAttributeRun.m; sourceTree = \"<group>\"; };\n\t\t9CF1E7382CDB9D8200451CBD /* CMBlockTextAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMBlockTextAttachment.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7392CDB9D8200451CBD /* CMBlockTextAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CMBlockTextAttachment.m; sourceTree = \"<group>\"; };\n\t\t9CF1E73A2CDB9D8200451CBD /* CMCascadingAttributeStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMCascadingAttributeStack.h; sourceTree = \"<group>\"; };\n\t\t9CF1E73B2CDB9D8200451CBD /* CMCascadingAttributeStack.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CMCascadingAttributeStack.m; sourceTree = \"<group>\"; };\n\t\t9CF1E73C2CDB9D8200451CBD /* CMDocument_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMDocument_Private.h; sourceTree = \"<group>\"; };\n\t\t9CF1E73D2CDB9D8200451CBD /* CMDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMDocument.h; sourceTree = \"<group>\"; };\n\t\t9CF1E73E2CDB9D8200451CBD /* CMDocument.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CMDocument.m; sourceTree = \"<group>\"; };\n\t\t9CF1E73F2CDB9D8200451CBD /* CMDocument+AttributedStringAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"CMDocument+AttributedStringAdditions.h\"; sourceTree = \"<group>\"; };\n\t\t9CF1E7402CDB9D8200451CBD /* CMDocument+AttributedStringAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"CMDocument+AttributedStringAdditions.m\"; sourceTree = \"<group>\"; };\n\t\t9CF1E7412CDB9D8200451CBD /* CMDocument+HTMLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"CMDocument+HTMLAdditions.h\"; sourceTree = \"<group>\"; };\n\t\t9CF1E7422CDB9D8200451CBD /* CMDocument+HTMLAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"CMDocument+HTMLAdditions.m\"; sourceTree = \"<group>\"; };\n\t\t9CF1E7432CDB9D8200451CBD /* CMHTMLElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMHTMLElement.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7442CDB9D8200451CBD /* CMHTMLElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CMHTMLElement.m; sourceTree = \"<group>\"; };\n\t\t9CF1E7452CDB9D8200451CBD /* CMHTMLElementTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMHTMLElementTransformer.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7462CDB9D8200451CBD /* CMHTMLRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMHTMLRenderer.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7472CDB9D8200451CBD /* CMHTMLRenderer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CMHTMLRenderer.m; sourceTree = \"<group>\"; };\n\t\t9CF1E7482CDB9D8200451CBD /* CMHTMLScriptTransformer_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMHTMLScriptTransformer_Private.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7492CDB9D8200451CBD /* CMHTMLScriptTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMHTMLScriptTransformer.h; sourceTree = \"<group>\"; };\n\t\t9CF1E74A2CDB9D8200451CBD /* CMHTMLScriptTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CMHTMLScriptTransformer.m; sourceTree = \"<group>\"; };\n\t\t9CF1E74B2CDB9D8200451CBD /* CMHTMLStrikethroughTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMHTMLStrikethroughTransformer.h; sourceTree = \"<group>\"; };\n\t\t9CF1E74C2CDB9D8200451CBD /* CMHTMLStrikethroughTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CMHTMLStrikethroughTransformer.m; sourceTree = \"<group>\"; };\n\t\t9CF1E74D2CDB9D8200451CBD /* CMHTMLSubscriptTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMHTMLSubscriptTransformer.h; sourceTree = \"<group>\"; };\n\t\t9CF1E74E2CDB9D8200451CBD /* CMHTMLSubscriptTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CMHTMLSubscriptTransformer.m; sourceTree = \"<group>\"; };\n\t\t9CF1E74F2CDB9D8200451CBD /* CMHTMLSuperscriptTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMHTMLSuperscriptTransformer.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7502CDB9D8200451CBD /* CMHTMLSuperscriptTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CMHTMLSuperscriptTransformer.m; sourceTree = \"<group>\"; };\n\t\t9CF1E7512CDB9D8200451CBD /* CMHTMLUnderlineTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMHTMLUnderlineTransformer.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7522CDB9D8200451CBD /* CMHTMLUnderlineTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CMHTMLUnderlineTransformer.m; sourceTree = \"<group>\"; };\n\t\t9CF1E7532CDB9D8200451CBD /* CMHTMLUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMHTMLUtilities.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7542CDB9D8200451CBD /* CMHTMLUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CMHTMLUtilities.m; sourceTree = \"<group>\"; };\n\t\t9CF1E7552CDB9D8200451CBD /* CMImageTextAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMImageTextAttachment.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7562CDB9D8200451CBD /* CMImageTextAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CMImageTextAttachment.m; sourceTree = \"<group>\"; };\n\t\t9CF1E7572CDB9D8200451CBD /* CMInlineTextAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMInlineTextAttachment.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7582CDB9D8200451CBD /* CMInlineTextAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CMInlineTextAttachment.m; sourceTree = \"<group>\"; };\n\t\t9CF1E7592CDB9D8200451CBD /* CMIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMIterator.h; sourceTree = \"<group>\"; };\n\t\t9CF1E75A2CDB9D8200451CBD /* CMIterator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CMIterator.m; sourceTree = \"<group>\"; };\n\t\t9CF1E75B2CDB9D8200451CBD /* CMNode_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMNode_Private.h; sourceTree = \"<group>\"; };\n\t\t9CF1E75C2CDB9D8200451CBD /* CMNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMNode.h; sourceTree = \"<group>\"; };\n\t\t9CF1E75D2CDB9D8200451CBD /* CMNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CMNode.m; sourceTree = \"<group>\"; };\n\t\t9CF1E75E2CDB9D8200451CBD /* CMNode+Table.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"CMNode+Table.h\"; sourceTree = \"<group>\"; };\n\t\t9CF1E75F2CDB9D8200451CBD /* CMNode+Table.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"CMNode+Table.m\"; sourceTree = \"<group>\"; };\n\t\t9CF1E7602CDB9D8200451CBD /* CMParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMParser.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7612CDB9D8200451CBD /* CMParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CMParser.m; sourceTree = \"<group>\"; };\n\t\t9CF1E7622CDB9D8200451CBD /* CMPlatformDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMPlatformDefines.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7632CDB9D8200451CBD /* CMStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMStack.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7642CDB9D8200451CBD /* CMStack.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CMStack.m; sourceTree = \"<group>\"; };\n\t\t9CF1E7652CDB9D8200451CBD /* CMTextAttributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMTextAttributes.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7662CDB9D8200451CBD /* CMTextAttributes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CMTextAttributes.m; sourceTree = \"<group>\"; };\n\t\t9CF1E7672CDB9D8200451CBD /* CocoaMarkdown.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CocoaMarkdown.h; sourceTree = \"<group>\"; };\n\t\t9CF1E76A2CDB9D8200451CBD /* MTMathAtomFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTMathAtomFactory.h; sourceTree = \"<group>\"; };\n\t\t9CF1E76B2CDB9D8200451CBD /* MTMathAtomFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTMathAtomFactory.m; sourceTree = \"<group>\"; };\n\t\t9CF1E76C2CDB9D8200451CBD /* MTMathList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTMathList.h; sourceTree = \"<group>\"; };\n\t\t9CF1E76D2CDB9D8200451CBD /* MTMathList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTMathList.m; sourceTree = \"<group>\"; };\n\t\t9CF1E76E2CDB9D8200451CBD /* MTMathListBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTMathListBuilder.h; sourceTree = \"<group>\"; };\n\t\t9CF1E76F2CDB9D8200451CBD /* MTMathListBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTMathListBuilder.m; sourceTree = \"<group>\"; };\n\t\t9CF1E7702CDB9D8200451CBD /* MTMathListIndex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTMathListIndex.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7712CDB9D8200451CBD /* MTMathListIndex.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTMathListIndex.m; sourceTree = \"<group>\"; };\n\t\t9CF1E7722CDB9D8200451CBD /* MTUnicode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTUnicode.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7732CDB9D8200451CBD /* MTUnicode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTUnicode.m; sourceTree = \"<group>\"; };\n\t\t9CF1E7752CDB9D8200451CBD /* MTFont+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"MTFont+Internal.h\"; sourceTree = \"<group>\"; };\n\t\t9CF1E7762CDB9D8200451CBD /* MTFontMathTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTFontMathTable.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7772CDB9D8200451CBD /* MTFontMathTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTFontMathTable.m; sourceTree = \"<group>\"; };\n\t\t9CF1E7782CDB9D8200451CBD /* MTMathListDisplayInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTMathListDisplayInternal.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7792CDB9D8200451CBD /* MTTypesetter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTTypesetter.h; sourceTree = \"<group>\"; };\n\t\t9CF1E77A2CDB9D8200451CBD /* MTTypesetter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTTypesetter.m; sourceTree = \"<group>\"; };\n\t\t9CF1E77C2CDB9D8200451CBD /* MTConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTConfig.h; sourceTree = \"<group>\"; };\n\t\t9CF1E77D2CDB9D8200451CBD /* MTFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTFont.h; sourceTree = \"<group>\"; };\n\t\t9CF1E77E2CDB9D8200451CBD /* MTFont.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTFont.m; sourceTree = \"<group>\"; };\n\t\t9CF1E77F2CDB9D8200451CBD /* MTFontManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTFontManager.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7802CDB9D8200451CBD /* MTFontManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTFontManager.m; sourceTree = \"<group>\"; };\n\t\t9CF1E7812CDB9D8200451CBD /* MTLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTLabel.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7822CDB9D8200451CBD /* MTLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTLabel.m; sourceTree = \"<group>\"; };\n\t\t9CF1E7832CDB9D8200451CBD /* MTMathListDisplay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTMathListDisplay.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7842CDB9D8200451CBD /* MTMathListDisplay.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTMathListDisplay.m; sourceTree = \"<group>\"; };\n\t\t9CF1E7852CDB9D8200451CBD /* MTMathUILabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTMathUILabel.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7862CDB9D8200451CBD /* MTMathUILabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTMathUILabel.m; sourceTree = \"<group>\"; };\n\t\t9CF1E7872CDB9D8200451CBD /* NSBezierPath+addLineToPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"NSBezierPath+addLineToPoint.h\"; sourceTree = \"<group>\"; };\n\t\t9CF1E7882CDB9D8200451CBD /* NSBezierPath+addLineToPoint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"NSBezierPath+addLineToPoint.m\"; sourceTree = \"<group>\"; };\n\t\t9CF1E7892CDB9D8200451CBD /* NSColor+HexString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"NSColor+HexString.h\"; sourceTree = \"<group>\"; };\n\t\t9CF1E78A2CDB9D8200451CBD /* NSColor+HexString.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"NSColor+HexString.m\"; sourceTree = \"<group>\"; };\n\t\t9CF1E78B2CDB9D8200451CBD /* NSView+backgroundColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"NSView+backgroundColor.h\"; sourceTree = \"<group>\"; };\n\t\t9CF1E78C2CDB9D8200451CBD /* NSView+backgroundColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"NSView+backgroundColor.m\"; sourceTree = \"<group>\"; };\n\t\t9CF1E78D2CDB9D8200451CBD /* UIColor+HexString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"UIColor+HexString.h\"; sourceTree = \"<group>\"; };\n\t\t9CF1E78E2CDB9D8200451CBD /* UIColor+HexString.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"UIColor+HexString.m\"; sourceTree = \"<group>\"; };\n\t\t9CF1E7902CDB9D8200451CBD /* IosMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IosMath.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7922CDB9D8200451CBD /* Ono.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Ono.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7932CDB9D8200451CBD /* ONOXMLDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ONOXMLDocument.h; sourceTree = \"<group>\"; };\n\t\t9CF1E7942CDB9D8200451CBD /* ONOXMLDocument.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ONOXMLDocument.m; sourceTree = \"<group>\"; };\n\t\t9CF1E8662CDB9FE300451CBD /* mathFonts.bundle */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.plug-in\"; path = mathFonts.bundle; sourceTree = \"<group>\"; };\n\t\t9CF1E8672CDB9FE300451CBD /* highlightjs.bundle */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.plug-in\"; path = highlightjs.bundle; sourceTree = \"<group>\"; };\n\t\t9CF1E86B2CDBA3FB00451CBD /* AntMarkdown.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AntMarkdown.framework; path = \"../Debug-iphonesimulator/AntMarkdown.framework\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tA2CA0499188A78A900D1E152 /* AntMarkdown-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = \"AntMarkdown-Info.plist\"; sourceTree = \"<group>\"; };\n\t\tA2CA049A188A78A900D1E152 /* AntMarkdown-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"AntMarkdown-Prefix.pch\"; sourceTree = \"<group>\"; };\n\t\tA2CA049C188A78A900D1E152 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = \"<group>\"; };\n\t\tA2E668DB2D310BA2005CC3B6 /* AMGradientLayer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AMGradientLayer.h; sourceTree = \"<group>\"; };\n\t\tA2E668DC2D310BA2005CC3B6 /* AMGradientLayer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AMGradientLayer.m; sourceTree = \"<group>\"; };\n\t\tA2E9D364170BD32000B11F5E /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };\n\t\tA2E9D366170BD32000B11F5E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };\n\t\tA2E9D368170BD32000B11F5E /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };\n\t\tA2E9D38A170BD37D00B11F5E /* AntMarkdown.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AntMarkdown.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tA2E9D38B170BD37D00B11F5E /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };\n\t\tAAC068C1188D1F8E001B468D /* AntMarkdown.bundle */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.plug-in\"; path = AntMarkdown.bundle; sourceTree = \"<group>\"; };\n\t\tEC2133242D9AB6F700C86B39 /* CMTaskCheckAttachment+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"CMTaskCheckAttachment+Private.h\"; sourceTree = \"<group>\"; };\n\t\tEC3578F32D816E8200F10E01 /* AMLayoutManager+Quote.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"AMLayoutManager+Quote.h\"; sourceTree = \"<group>\"; };\n\t\tEC3578F42D816E8200F10E01 /* AMLayoutManager+Quote.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = \"AMLayoutManager+Quote.m\"; sourceTree = \"<group>\"; };\n\t\tEC5421942D928E5E00510C86 /* AMEmojiManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AMEmojiManager.h; sourceTree = \"<group>\"; };\n\t\tEC5421952D928E5E00510C86 /* AMEmojiManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AMEmojiManager.m; sourceTree = \"<group>\"; };\n\t\tECE1C84B2D924D930034FEE2 /* emoji.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = emoji.h; sourceTree = \"<group>\"; };\n\t\tECE1C84C2D924D930034FEE2 /* emoji.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = emoji.c; sourceTree = \"<group>\"; };\n\t\tECF404AA2D9A45C400B04B59 /* CMTaskCheckAttachment.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CMTaskCheckAttachment.h; sourceTree = \"<group>\"; };\n\t\tECF404AB2D9A45C400B04B59 /* CMTaskCheckAttachment.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CMTaskCheckAttachment.m; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\tA2E9D387170BD37D00B11F5E /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t9CF1E86C2CDBA3FB00451CBD /* AntMarkdown.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t9CF1E6E32CDB9D8200451CBD /* Public */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t771F1B9B2E1674570009C5B5 /* AMIconAttachment.h */,\n\t\t\t\t771F1B9C2E1674570009C5B5 /* AMIconAttachment.m */,\n\t\t\t\t77A5FD662D9CE399009B0C1D /* AMIconLinkAttachment.h */,\n\t\t\t\t77A5FD672D9CE399009B0C1D /* AMIconLinkAttachment.m */,\n\t\t\t\t9CF1E6BC2CDB9D8200451CBD /* AMAttributedStringRenderer.h */,\n\t\t\t\t9CF1E6BD2CDB9D8200451CBD /* AMAttributedStringRenderer.m */,\n\t\t\t\t9CF1E6BE2CDB9D8200451CBD /* AMBlockMathAttachment.h */,\n\t\t\t\t9CF1E6BF2CDB9D8200451CBD /* AMBlockMathAttachment.m */,\n\t\t\t\t9CF1E6C02CDB9D8200451CBD /* AMCodeHighlighter.h */,\n\t\t\t\t9CF1E6C12CDB9D8200451CBD /* AMCodeHighlighter.m */,\n\t\t\t\t9CF1E6C22CDB9D8200451CBD /* AMCodeViewAttachment.h */,\n\t\t\t\t9CF1E6C32CDB9D8200451CBD /* AMCodeViewAttachment.m */,\n\t\t\t\t9CF1E6C42CDB9D8200451CBD /* AMDrawable.h */,\n\t\t\t\t9CF1E6C52CDB9D8200451CBD /* AMDrawable.m */,\n\t\t\t\t9CF1E6C62CDB9D8200451CBD /* AMGradient.h */,\n\t\t\t\t9CF1E6C72CDB9D8200451CBD /* AMGradient.m */,\n\t\t\t\t9C48DDDE2CE5953400E10317 /* AMGradientView.h */,\n\t\t\t\t9C48DDDF2CE5953400E10317 /* AMGradientView.m */,\n\t\t\t\t9CF1E6C82CDB9D8200451CBD /* AMHTMLTransformer.h */,\n\t\t\t\t9CF1E6C92CDB9D8200451CBD /* AMHTMLTransformer.m */,\n\t\t\t\t9CB413B12CDDC31B0000585E /* AMImageTextAttachment.h */,\n\t\t\t\t9CB413B22CDDC31B0000585E /* AMImageTextAttachment.m */,\n\t\t\t\t9CF1E6CA2CDB9D8200451CBD /* AMInlineMathAttachment.h */,\n\t\t\t\t9CF1E6CB2CDB9D8200451CBD /* AMInlineMathAttachment.m */,\n\t\t\t\t9CF1E6CC2CDB9D8200451CBD /* AMLayoutManager.h */,\n\t\t\t\t9CF1E6CD2CDB9D8200451CBD /* AMLayoutManager.m */,\n\t\t\t\tEC3578F32D816E8200F10E01 /* AMLayoutManager+Quote.h */,\n\t\t\t\tEC3578F42D816E8200F10E01 /* AMLayoutManager+Quote.m */,\n\t\t\t\t9CF1E6CE2CDB9D8200451CBD /* AMMarkdownCodeView.h */,\n\t\t\t\t9CF1E6CF2CDB9D8200451CBD /* AMMarkdownCodeView.m */,\n\t\t\t\t9CF1E6D02CDB9D8200451CBD /* AMMarkdownTableLayout.h */,\n\t\t\t\t9CF1E6D12CDB9D8200451CBD /* AMMarkdownTableLayout.m */,\n\t\t\t\t9CF1E6D22CDB9D8200451CBD /* AMMarkdownTableView.h */,\n\t\t\t\t9CF1E6D32CDB9D8200451CBD /* AMMarkdownTableView.m */,\n\t\t\t\t0A8283752D37AC3100EAB366 /* AMMarkDownTableViewBlowUpControllerViewController.h */,\n\t\t\t\t0A8283762D37AC3100EAB366 /* AMMarkDownTableViewBlowUpControllerViewController.m */,\n\t\t\t\t9CF1E6D42CDB9D8200451CBD /* AMTableViewAttachment.h */,\n\t\t\t\t9CF1E6D52CDB9D8200451CBD /* AMTableViewAttachment.m */,\n\t\t\t\t9CF1E6D62CDB9D8200451CBD /* AMTextBackground.h */,\n\t\t\t\t9CF1E6D72CDB9D8200451CBD /* AMTextBackground.m */,\n\t\t\t\t9CF1E6D82CDB9D8200451CBD /* AMTextStyles.h */,\n\t\t\t\t9CF1E6D92CDB9D8200451CBD /* AMTextStyles.m */,\n\t\t\t\t9C48DDDA2CE4C5BE00E10317 /* AMUnderline.h */,\n\t\t\t\t9C48DDD92CE4C5BE00E10317 /* AMUnderline.m */,\n\t\t\t\t9CF1E6DA2CDB9D8200451CBD /* AMUtils.h */,\n\t\t\t\t77EB5F0A2E69B3FA0042F5BD /* AMUtils.m */,\n\t\t\t\t9CF1E6DC2CDB9D8200451CBD /* AMViewAttachment.h */,\n\t\t\t\t9CF1E6DD2CDB9D8200451CBD /* AMViewAttachment.m */,\n\t\t\t\t9CF1E6DE2CDB9D8200451CBD /* AntMarkdown.h */,\n\t\t\t\t9C3EA8662CFA8C7800C8F03B /* NSMutableAttributedString+AntMarkdown.h */,\n\t\t\t\t9C3EA8672CFA8C7800C8F03B /* NSMutableAttributedString+AntMarkdown.m */,\n\t\t\t\t9CB413922CDC657D0000585E /* NSString+AntMarkdown.h */,\n\t\t\t\t9CB413912CDC657D0000585E /* NSString+AntMarkdown.m */,\n\t\t\t\t9CF1E6DF2CDB9D8200451CBD /* UILabel+AntMarkdown.h */,\n\t\t\t\t9CF1E6E02CDB9D8200451CBD /* UILabel+AntMarkdown.m */,\n\t\t\t\t9CF1E6E12CDB9D8200451CBD /* UITextView+AntMarkdown.h */,\n\t\t\t\t9CF1E6E22CDB9D8200451CBD /* UITextView+AntMarkdown.m */,\n\t\t\t\tA2E668DB2D310BA2005CC3B6 /* AMGradientLayer.h */,\n\t\t\t\tA2E668DC2D310BA2005CC3B6 /* AMGradientLayer.m */,\n\t\t\t\tEC5421942D928E5E00510C86 /* AMEmojiManager.h */,\n\t\t\t\tEC5421952D928E5E00510C86 /* AMEmojiManager.m */,\n\t\t\t);\n\t\t\tpath = Public;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t9CF1E6F62CDB9D8200451CBD /* extensions */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9CF1E6E42CDB9D8200451CBD /* autolink.c */,\n\t\t\t\t9CF1E6E52CDB9D8200451CBD /* autolink.h */,\n\t\t\t\t9CF1E6E72CDB9D8200451CBD /* cmark-gfm-core-extensions.h */,\n\t\t\t\t9CF1E6E82CDB9D8200451CBD /* core-extensions.c */,\n\t\t\t\t9CF1E6E92CDB9D8200451CBD /* ext_scanners.c */,\n\t\t\t\t9CF1E6EA2CDB9D8200451CBD /* ext_scanners.h */,\n\t\t\t\t9CF1E6EC2CDB9D8200451CBD /* math_mark.c */,\n\t\t\t\t9CF1E6ED2CDB9D8200451CBD /* math_mark.h */,\n\t\t\t\t9CF1E6EE2CDB9D8200451CBD /* strikethrough.c */,\n\t\t\t\t9CF1E6EF2CDB9D8200451CBD /* strikethrough.h */,\n\t\t\t\t9CF1E6F02CDB9D8200451CBD /* table.c */,\n\t\t\t\t9CF1E6F12CDB9D8200451CBD /* table.h */,\n\t\t\t\t9CF1E6F22CDB9D8200451CBD /* tagfilter.c */,\n\t\t\t\t9CF1E6F32CDB9D8200451CBD /* tagfilter.h */,\n\t\t\t\t9CF1E6F42CDB9D8200451CBD /* tasklist.c */,\n\t\t\t\t9CF1E6F52CDB9D8200451CBD /* tasklist.h */,\n\t\t\t\tECE1C84B2D924D930034FEE2 /* emoji.h */,\n\t\t\t\tECE1C84C2D924D930034FEE2 /* emoji.c */,\n\t\t\t);\n\t\t\tpath = extensions;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t9CF1E72D2CDB9D8200451CBD /* src */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9CF1E6F72CDB9D8200451CBD /* arena.c */,\n\t\t\t\t9CF1E6F82CDB9D8200451CBD /* blocks.c */,\n\t\t\t\t9CF1E6F92CDB9D8200451CBD /* buffer.c */,\n\t\t\t\t9CF1E6FA2CDB9D8200451CBD /* buffer.h */,\n\t\t\t\t9CF1E6FB2CDB9D8200451CBD /* case_fold_switch.inc */,\n\t\t\t\t9CF1E6FC2CDB9D8200451CBD /* chunk.h */,\n\t\t\t\t9CF1E6FE2CDB9D8200451CBD /* cmark_ctype.c */,\n\t\t\t\t9CF1E6FF2CDB9D8200451CBD /* cmark_ctype.h */,\n\t\t\t\t9CF1E7012CDB9D8200451CBD /* cmark-gfm-extension_api.h */,\n\t\t\t\t9CF1E7022CDB9D8200451CBD /* cmark-gfm.h */,\n\t\t\t\t9CF1E7032CDB9D8200451CBD /* cmark.c */,\n\t\t\t\t9CF1E7042CDB9D8200451CBD /* commonmark.c */,\n\t\t\t\t9CF1E7072CDB9D8200451CBD /* footnotes.c */,\n\t\t\t\t9CF1E7082CDB9D8200451CBD /* footnotes.h */,\n\t\t\t\t9CF1E7092CDB9D8200451CBD /* houdini_href_e.c */,\n\t\t\t\t9CF1E70A2CDB9D8200451CBD /* houdini_html_e.c */,\n\t\t\t\t9CF1E70B2CDB9D8200451CBD /* houdini_html_u.c */,\n\t\t\t\t9CF1E70C2CDB9D8200451CBD /* houdini.h */,\n\t\t\t\t9CF1E70D2CDB9D8200451CBD /* html.c */,\n\t\t\t\t9CF1E70E2CDB9D8200451CBD /* html.h */,\n\t\t\t\t9CF1E70F2CDB9D8200451CBD /* inlines.c */,\n\t\t\t\t9CF1E7102CDB9D8200451CBD /* inlines.h */,\n\t\t\t\t9CF1E7112CDB9D8200451CBD /* iterator.c */,\n\t\t\t\t9CF1E7122CDB9D8200451CBD /* iterator.h */,\n\t\t\t\t9CF1E7132CDB9D8200451CBD /* latex.c */,\n\t\t\t\t9CF1E7152CDB9D8200451CBD /* linked_list.c */,\n\t\t\t\t9CF1E7162CDB9D8200451CBD /* man.c */,\n\t\t\t\t9CF1E7172CDB9D8200451CBD /* map.c */,\n\t\t\t\t9CF1E7182CDB9D8200451CBD /* map.h */,\n\t\t\t\t9CF1E7192CDB9D8200451CBD /* node.c */,\n\t\t\t\t9CF1E71A2CDB9D8200451CBD /* node.h */,\n\t\t\t\t9CF1E71B2CDB9D8200451CBD /* parser.h */,\n\t\t\t\t9CF1E71C2CDB9D8200451CBD /* plaintext.c */,\n\t\t\t\t9CF1E71D2CDB9D8200451CBD /* plugin.c */,\n\t\t\t\t9CF1E71E2CDB9D8200451CBD /* plugin.h */,\n\t\t\t\t9CF1E71F2CDB9D8200451CBD /* references.c */,\n\t\t\t\t9CF1E7202CDB9D8200451CBD /* references.h */,\n\t\t\t\t9CF1E7212CDB9D8200451CBD /* registry.c */,\n\t\t\t\t9CF1E7222CDB9D8200451CBD /* registry.h */,\n\t\t\t\t9CF1E7232CDB9D8200451CBD /* render.c */,\n\t\t\t\t9CF1E7242CDB9D8200451CBD /* render.h */,\n\t\t\t\t9CF1E7252CDB9D8200451CBD /* scanners.c */,\n\t\t\t\t9CF1E7262CDB9D8200451CBD /* scanners.h */,\n\t\t\t\t9CF1E7282CDB9D8200451CBD /* syntax_extension.c */,\n\t\t\t\t9CF1E7292CDB9D8200451CBD /* syntax_extension.h */,\n\t\t\t\t9CF1E72A2CDB9D8200451CBD /* utf8.c */,\n\t\t\t\t9CF1E72B2CDB9D8200451CBD /* utf8.h */,\n\t\t\t\t9CF1E72C2CDB9D8200451CBD /* xml.c */,\n\t\t\t);\n\t\t\tpath = src;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t9CF1E7312CDB9D8200451CBD /* cmark-gfm */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9CF1E72E2CDB9D8200451CBD /* cmark-gfm_export.h */,\n\t\t\t\t9CF1E72F2CDB9D8200451CBD /* cmark-gfm_version.h */,\n\t\t\t\t9CF1E7302CDB9D8200451CBD /* config.h */,\n\t\t\t\t9CF1E6F62CDB9D8200451CBD /* extensions */,\n\t\t\t\t9CF1E72D2CDB9D8200451CBD /* src */,\n\t\t\t);\n\t\t\tpath = \"cmark-gfm\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t9CF1E7692CDB9D8200451CBD /* CocoaMarkdown */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t0E449DC02D806CFC001E7430 /* CMHorizontalRuleAttachment.h */,\n\t\t\t\t0E449DC12D806CFC001E7430 /* CMHorizontalRuleAttachment.m */,\n\t\t\t\tECF404AA2D9A45C400B04B59 /* CMTaskCheckAttachment.h */,\n\t\t\t\tEC2133242D9AB6F700C86B39 /* CMTaskCheckAttachment+Private.h */,\n\t\t\t\tECF404AB2D9A45C400B04B59 /* CMTaskCheckAttachment.m */,\n\t\t\t\t9CF1E7332CDB9D8200451CBD /* CMAttributedStringRenderer_Private.h */,\n\t\t\t\t9CF1E7342CDB9D8200451CBD /* CMAttributedStringRenderer.h */,\n\t\t\t\t9CF1E7352CDB9D8200451CBD /* CMAttributedStringRenderer.m */,\n\t\t\t\t9CF1E7362CDB9D8200451CBD /* CMAttributeRun.h */,\n\t\t\t\t9CF1E7372CDB9D8200451CBD /* CMAttributeRun.m */,\n\t\t\t\t9CF1E7382CDB9D8200451CBD /* CMBlockTextAttachment.h */,\n\t\t\t\t9CF1E7392CDB9D8200451CBD /* CMBlockTextAttachment.m */,\n\t\t\t\t9CF1E73A2CDB9D8200451CBD /* CMCascadingAttributeStack.h */,\n\t\t\t\t9CF1E73B2CDB9D8200451CBD /* CMCascadingAttributeStack.m */,\n\t\t\t\t9CF1E73C2CDB9D8200451CBD /* CMDocument_Private.h */,\n\t\t\t\t9CF1E73D2CDB9D8200451CBD /* CMDocument.h */,\n\t\t\t\t9CF1E73E2CDB9D8200451CBD /* CMDocument.m */,\n\t\t\t\t9CF1E73F2CDB9D8200451CBD /* CMDocument+AttributedStringAdditions.h */,\n\t\t\t\t9CF1E7402CDB9D8200451CBD /* CMDocument+AttributedStringAdditions.m */,\n\t\t\t\t9CF1E7412CDB9D8200451CBD /* CMDocument+HTMLAdditions.h */,\n\t\t\t\t9CF1E7422CDB9D8200451CBD /* CMDocument+HTMLAdditions.m */,\n\t\t\t\t9CF1E7432CDB9D8200451CBD /* CMHTMLElement.h */,\n\t\t\t\t9CF1E7442CDB9D8200451CBD /* CMHTMLElement.m */,\n\t\t\t\t9CF1E7452CDB9D8200451CBD /* CMHTMLElementTransformer.h */,\n\t\t\t\t9CF1E7462CDB9D8200451CBD /* CMHTMLRenderer.h */,\n\t\t\t\t9CF1E7472CDB9D8200451CBD /* CMHTMLRenderer.m */,\n\t\t\t\t9CF1E7482CDB9D8200451CBD /* CMHTMLScriptTransformer_Private.h */,\n\t\t\t\t9CF1E7492CDB9D8200451CBD /* CMHTMLScriptTransformer.h */,\n\t\t\t\t9CF1E74A2CDB9D8200451CBD /* CMHTMLScriptTransformer.m */,\n\t\t\t\t9CF1E74B2CDB9D8200451CBD /* CMHTMLStrikethroughTransformer.h */,\n\t\t\t\t9CF1E74C2CDB9D8200451CBD /* CMHTMLStrikethroughTransformer.m */,\n\t\t\t\t9CF1E74D2CDB9D8200451CBD /* CMHTMLSubscriptTransformer.h */,\n\t\t\t\t9CF1E74E2CDB9D8200451CBD /* CMHTMLSubscriptTransformer.m */,\n\t\t\t\t9CF1E74F2CDB9D8200451CBD /* CMHTMLSuperscriptTransformer.h */,\n\t\t\t\t9CF1E7502CDB9D8200451CBD /* CMHTMLSuperscriptTransformer.m */,\n\t\t\t\t9CF1E7512CDB9D8200451CBD /* CMHTMLUnderlineTransformer.h */,\n\t\t\t\t9CF1E7522CDB9D8200451CBD /* CMHTMLUnderlineTransformer.m */,\n\t\t\t\t9CF1E7532CDB9D8200451CBD /* CMHTMLUtilities.h */,\n\t\t\t\t9CF1E7542CDB9D8200451CBD /* CMHTMLUtilities.m */,\n\t\t\t\t9CF1E7552CDB9D8200451CBD /* CMImageTextAttachment.h */,\n\t\t\t\t9CF1E7562CDB9D8200451CBD /* CMImageTextAttachment.m */,\n\t\t\t\t9CF1E7572CDB9D8200451CBD /* CMInlineTextAttachment.h */,\n\t\t\t\t9CF1E7582CDB9D8200451CBD /* CMInlineTextAttachment.m */,\n\t\t\t\t9CF1E7592CDB9D8200451CBD /* CMIterator.h */,\n\t\t\t\t9CF1E75A2CDB9D8200451CBD /* CMIterator.m */,\n\t\t\t\t9CF1E75B2CDB9D8200451CBD /* CMNode_Private.h */,\n\t\t\t\t9CF1E75C2CDB9D8200451CBD /* CMNode.h */,\n\t\t\t\t9CF1E75D2CDB9D8200451CBD /* CMNode.m */,\n\t\t\t\t9CF1E75E2CDB9D8200451CBD /* CMNode+Table.h */,\n\t\t\t\t9CF1E75F2CDB9D8200451CBD /* CMNode+Table.m */,\n\t\t\t\t9CF1E7602CDB9D8200451CBD /* CMParser.h */,\n\t\t\t\t9CF1E7612CDB9D8200451CBD /* CMParser.m */,\n\t\t\t\t9CF1E7622CDB9D8200451CBD /* CMPlatformDefines.h */,\n\t\t\t\t9CF1E7632CDB9D8200451CBD /* CMStack.h */,\n\t\t\t\t9CF1E7642CDB9D8200451CBD /* CMStack.m */,\n\t\t\t\t9CF1E7652CDB9D8200451CBD /* CMTextAttributes.h */,\n\t\t\t\t9CF1E7662CDB9D8200451CBD /* CMTextAttributes.m */,\n\t\t\t\t9CF1E7672CDB9D8200451CBD /* CocoaMarkdown.h */,\n\t\t\t);\n\t\t\tpath = CocoaMarkdown;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t9CF1E7742CDB9D8200451CBD /* lib */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9CF1E76A2CDB9D8200451CBD /* MTMathAtomFactory.h */,\n\t\t\t\t9CF1E76B2CDB9D8200451CBD /* MTMathAtomFactory.m */,\n\t\t\t\t9CF1E76C2CDB9D8200451CBD /* MTMathList.h */,\n\t\t\t\t9CF1E76D2CDB9D8200451CBD /* MTMathList.m */,\n\t\t\t\t9CF1E76E2CDB9D8200451CBD /* MTMathListBuilder.h */,\n\t\t\t\t9CF1E76F2CDB9D8200451CBD /* MTMathListBuilder.m */,\n\t\t\t\t9CF1E7702CDB9D8200451CBD /* MTMathListIndex.h */,\n\t\t\t\t9CF1E7712CDB9D8200451CBD /* MTMathListIndex.m */,\n\t\t\t\t9CF1E7722CDB9D8200451CBD /* MTUnicode.h */,\n\t\t\t\t9CF1E7732CDB9D8200451CBD /* MTUnicode.m */,\n\t\t\t);\n\t\t\tpath = lib;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t9CF1E77B2CDB9D8200451CBD /* internal */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9CF1E7752CDB9D8200451CBD /* MTFont+Internal.h */,\n\t\t\t\t9CF1E7762CDB9D8200451CBD /* MTFontMathTable.h */,\n\t\t\t\t9CF1E7772CDB9D8200451CBD /* MTFontMathTable.m */,\n\t\t\t\t9CF1E7782CDB9D8200451CBD /* MTMathListDisplayInternal.h */,\n\t\t\t\t9CF1E7792CDB9D8200451CBD /* MTTypesetter.h */,\n\t\t\t\t9CF1E77A2CDB9D8200451CBD /* MTTypesetter.m */,\n\t\t\t);\n\t\t\tpath = internal;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t9CF1E78F2CDB9D8200451CBD /* render */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9CF1E77B2CDB9D8200451CBD /* internal */,\n\t\t\t\t9CF1E77C2CDB9D8200451CBD /* MTConfig.h */,\n\t\t\t\t9CF1E77D2CDB9D8200451CBD /* MTFont.h */,\n\t\t\t\t9CF1E77E2CDB9D8200451CBD /* MTFont.m */,\n\t\t\t\t9CF1E77F2CDB9D8200451CBD /* MTFontManager.h */,\n\t\t\t\t9CF1E7802CDB9D8200451CBD /* MTFontManager.m */,\n\t\t\t\t9CF1E7812CDB9D8200451CBD /* MTLabel.h */,\n\t\t\t\t9CF1E7822CDB9D8200451CBD /* MTLabel.m */,\n\t\t\t\t9CF1E7832CDB9D8200451CBD /* MTMathListDisplay.h */,\n\t\t\t\t9CF1E7842CDB9D8200451CBD /* MTMathListDisplay.m */,\n\t\t\t\t9CF1E7852CDB9D8200451CBD /* MTMathUILabel.h */,\n\t\t\t\t9CF1E7862CDB9D8200451CBD /* MTMathUILabel.m */,\n\t\t\t\t9CF1E7872CDB9D8200451CBD /* NSBezierPath+addLineToPoint.h */,\n\t\t\t\t9CF1E7882CDB9D8200451CBD /* NSBezierPath+addLineToPoint.m */,\n\t\t\t\t9CF1E7892CDB9D8200451CBD /* NSColor+HexString.h */,\n\t\t\t\t9CF1E78A2CDB9D8200451CBD /* NSColor+HexString.m */,\n\t\t\t\t9CF1E78B2CDB9D8200451CBD /* NSView+backgroundColor.h */,\n\t\t\t\t9CF1E78C2CDB9D8200451CBD /* NSView+backgroundColor.m */,\n\t\t\t\t9CF1E78D2CDB9D8200451CBD /* UIColor+HexString.h */,\n\t\t\t\t9CF1E78E2CDB9D8200451CBD /* UIColor+HexString.m */,\n\t\t\t);\n\t\t\tpath = render;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t9CF1E7912CDB9D8200451CBD /* iosMath */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9CF1E7742CDB9D8200451CBD /* lib */,\n\t\t\t\t9CF1E78F2CDB9D8200451CBD /* render */,\n\t\t\t\t9CF1E7902CDB9D8200451CBD /* IosMath.h */,\n\t\t\t);\n\t\t\tpath = iosMath;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t9CF1E7952CDB9D8200451CBD /* Ono */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9CF1E7922CDB9D8200451CBD /* Ono.h */,\n\t\t\t\t9CF1E7932CDB9D8200451CBD /* ONOXMLDocument.h */,\n\t\t\t\t9CF1E7942CDB9D8200451CBD /* ONOXMLDocument.m */,\n\t\t\t);\n\t\t\tpath = Ono;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t9CF1E7962CDB9D8200451CBD /* External */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9CF1E7312CDB9D8200451CBD /* cmark-gfm */,\n\t\t\t\t9CF1E7692CDB9D8200451CBD /* CocoaMarkdown */,\n\t\t\t\t9CF1E7912CDB9D8200451CBD /* iosMath */,\n\t\t\t\t9CF1E7952CDB9D8200451CBD /* Ono */,\n\t\t\t);\n\t\t\tpath = External;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t9CF1E86A2CDBA39200451CBD /* Product */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9CF1E86B2CDBA3FB00451CBD /* AntMarkdown.framework */,\n\t\t\t);\n\t\t\tname = Product;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA2CA048C188A78A900D1E152 /* Sources */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9CF1E7962CDB9D8200451CBD /* External */,\n\t\t\t\t9CF1E6E32CDB9D8200451CBD /* Public */,\n\t\t\t);\n\t\t\tpath = Sources;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA2CA0498188A78A900D1E152 /* SupportingFiles */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tA2CA0499188A78A900D1E152 /* AntMarkdown-Info.plist */,\n\t\t\t\tA2CA049A188A78A900D1E152 /* AntMarkdown-Prefix.pch */,\n\t\t\t\tA2CA049B188A78A900D1E152 /* InfoPlist.strings */,\n\t\t\t);\n\t\t\tpath = SupportingFiles;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA2E9D358170BD32000B11F5E = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tA2CA048C188A78A900D1E152 /* Sources */,\n\t\t\t\tAAC068C0188D1F8E001B468D /* Resources */,\n\t\t\t\tA2CA0498188A78A900D1E152 /* SupportingFiles */,\n\t\t\t\tA2E9D363170BD32000B11F5E /* Frameworks */,\n\t\t\t\t9CF1E86A2CDBA39200451CBD /* Product */,\n\t\t\t\tA2E9D362170BD32000B11F5E /* Products */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA2E9D362170BD32000B11F5E /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tA2E9D38A170BD37D00B11F5E /* AntMarkdown.framework */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA2E9D363170BD32000B11F5E /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tA2E9D364170BD32000B11F5E /* UIKit.framework */,\n\t\t\t\tA2E9D366170BD32000B11F5E /* Foundation.framework */,\n\t\t\t\tA2E9D368170BD32000B11F5E /* CoreGraphics.framework */,\n\t\t\t\tA2E9D38B170BD37D00B11F5E /* CoreFoundation.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tAAC068C0188D1F8E001B468D /* Resources */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9CF1E8672CDB9FE300451CBD /* highlightjs.bundle */,\n\t\t\t\t9CF1E8662CDB9FE300451CBD /* mathFonts.bundle */,\n\t\t\t\tAAC068C1188D1F8E001B468D /* AntMarkdown.bundle */,\n\t\t\t);\n\t\t\tpath = Resources;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXHeadersBuildPhase section */\n\t\tAA43C4EC19650DB400944353 /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t77A5FD692D9CE399009B0C1D /* AMIconLinkAttachment.h in Headers */,\n\t\t\t\tEC3578F62D816E8200F10E01 /* AMLayoutManager+Quote.h in Headers */,\n\t\t\t\t9CF1E7972CDB9D8200451CBD /* AMAttributedStringRenderer.h in Headers */,\n\t\t\t\t9CF1E7992CDB9D8200451CBD /* AMBlockMathAttachment.h in Headers */,\n\t\t\t\tECE1C84E2D924D930034FEE2 /* emoji.h in Headers */,\n\t\t\t\tECF404AC2D9A45C400B04B59 /* CMTaskCheckAttachment.h in Headers */,\n\t\t\t\t9CF1E79B2CDB9D8200451CBD /* AMCodeHighlighter.h in Headers */,\n\t\t\t\t9CF1E79D2CDB9D8200451CBD /* AMCodeViewAttachment.h in Headers */,\n\t\t\t\t9CF1E79F2CDB9D8200451CBD /* AMDrawable.h in Headers */,\n\t\t\t\t9CF1E7A12CDB9D8200451CBD /* AMGradient.h in Headers */,\n\t\t\t\t9CF1E7A32CDB9D8200451CBD /* AMHTMLTransformer.h in Headers */,\n\t\t\t\t9C7D1B172CEF21AD00EFB06A /* Ono.h in Headers */,\n\t\t\t\t9CF1E7A52CDB9D8200451CBD /* AMInlineMathAttachment.h in Headers */,\n\t\t\t\t9CF1E7A72CDB9D8200451CBD /* AMLayoutManager.h in Headers */,\n\t\t\t\t9CF1E8772CDBA59800451CBD /* cmark_ctype.h in Headers */,\n\t\t\t\t9CF1E7A92CDB9D8200451CBD /* AMMarkdownCodeView.h in Headers */,\n\t\t\t\t9CF1E7AB2CDB9D8200451CBD /* AMMarkdownTableLayout.h in Headers */,\n\t\t\t\t9CF1E8782CDBA59F00451CBD /* references.h in Headers */,\n\t\t\t\t9CF1E8792CDBA59F00451CBD /* registry.h in Headers */,\n\t\t\t\t9CB413AB2CDC90EB0000585E /* cmark-gfm_export.h in Headers */,\n\t\t\t\t9CF1E87A2CDBA59F00451CBD /* render.h in Headers */,\n\t\t\t\t9CF1E87B2CDBA59F00451CBD /* node.h in Headers */,\n\t\t\t\t9CF1E87C2CDBA59F00451CBD /* footnotes.h in Headers */,\n\t\t\t\t9CB413B32CDDC31B0000585E /* AMImageTextAttachment.h in Headers */,\n\t\t\t\t9CF1E87D2CDBA59F00451CBD /* iterator.h in Headers */,\n\t\t\t\t9CF1E87E2CDBA59F00451CBD /* scanners.h in Headers */,\n\t\t\t\tEC5421962D928E5E00510C86 /* AMEmojiManager.h in Headers */,\n\t\t\t\t9CF1E87F2CDBA59F00451CBD /* inlines.h in Headers */,\n\t\t\t\t9CF1E8802CDBA59F00451CBD /* houdini.h in Headers */,\n\t\t\t\t9CF1E8812CDBA59F00451CBD /* map.h in Headers */,\n\t\t\t\t9CF1E8822CDBA59F00451CBD /* plugin.h in Headers */,\n\t\t\t\t9CF1E8832CDBA59F00451CBD /* syntax_extension.h in Headers */,\n\t\t\t\t9CF1E8892CDBA5F500451CBD /* CMNode_Private.h in Headers */,\n\t\t\t\t9CF1E8842CDBA59F00451CBD /* parser.h in Headers */,\n\t\t\t\t9CF1E8852CDBA59F00451CBD /* html.h in Headers */,\n\t\t\t\t9CF1E8862CDBA59F00451CBD /* utf8.h in Headers */,\n\t\t\t\t9CF1E8872CDBA5B100451CBD /* cmark-gfm-extension_api.h in Headers */,\n\t\t\t\tA2E668DE2D310BA2005CC3B6 /* AMGradientLayer.h in Headers */,\n\t\t\t\t9CF1E7AD2CDB9D8200451CBD /* AMMarkdownTableView.h in Headers */,\n\t\t\t\t9CF1E7AF2CDB9D8200451CBD /* AMTableViewAttachment.h in Headers */,\n\t\t\t\t9CF1E7B12CDB9D8200451CBD /* AMTextBackground.h in Headers */,\n\t\t\t\t9CF1E7B32CDB9D8200451CBD /* AMTextStyles.h in Headers */,\n\t\t\t\t9CF1E7B52CDB9D8200451CBD /* AMUtils.h in Headers */,\n\t\t\t\t9CF1E7B72CDB9D8200451CBD /* AMViewAttachment.h in Headers */,\n\t\t\t\t9CF1E8132CDB9D8200451CBD /* CMDocument.h in Headers */,\n\t\t\t\t9CF1E80E2CDB9D8200451CBD /* CMBlockTextAttachment.h in Headers */,\n\t\t\t\t9CF1E8192CDB9D8200451CBD /* CMHTMLElement.h in Headers */,\n\t\t\t\t9CF1E8752CDBA59300451CBD /* chunk.h in Headers */,\n\t\t\t\t9C48DDE02CE5953400E10317 /* AMGradientView.h in Headers */,\n\t\t\t\t9CF1E8762CDBA59300451CBD /* buffer.h in Headers */,\n\t\t\t\t9CF1E82B2CDB9D8200451CBD /* CMImageTextAttachment.h in Headers */,\n\t\t\t\t9CF1E8152CDB9D8200451CBD /* CMDocument+AttributedStringAdditions.h in Headers */,\n\t\t\t\t9CF1E81B2CDB9D8200451CBD /* CMHTMLElementTransformer.h in Headers */,\n\t\t\t\t9CF1E86D2CDBA56200451CBD /* strikethrough.h in Headers */,\n\t\t\t\t771F1B9E2E1674570009C5B5 /* AMIconAttachment.h in Headers */,\n\t\t\t\t0E449DC32D806CFC001E7430 /* CMHorizontalRuleAttachment.h in Headers */,\n\t\t\t\t9CF1E86E2CDBA56200451CBD /* tagfilter.h in Headers */,\n\t\t\t\t9CF1E86F2CDBA56200451CBD /* table.h in Headers */,\n\t\t\t\t9CF1E8702CDBA56200451CBD /* math_mark.h in Headers */,\n\t\t\t\t9CF1E8712CDBA56200451CBD /* tasklist.h in Headers */,\n\t\t\t\t9CF1E8722CDBA56200451CBD /* autolink.h in Headers */,\n\t\t\t\t9CF1E8732CDBA56200451CBD /* cmark-gfm-core-extensions.h in Headers */,\n\t\t\t\t9CF1E8742CDBA56200451CBD /* ext_scanners.h in Headers */,\n\t\t\t\t9CF1E8212CDB9D8200451CBD /* CMHTMLStrikethroughTransformer.h in Headers */,\n\t\t\t\t9CF1E82D2CDB9D8200451CBD /* CMInlineTextAttachment.h in Headers */,\n\t\t\t\t9CF1E80C2CDB9D8200451CBD /* CMAttributeRun.h in Headers */,\n\t\t\t\t9CF1E8342CDB9D8200451CBD /* CMNode+Table.h in Headers */,\n\t\t\t\t9CF1E8172CDB9D8200451CBD /* CMDocument+HTMLAdditions.h in Headers */,\n\t\t\t\t9CF1E8392CDB9D8200451CBD /* CMStack.h in Headers */,\n\t\t\t\t0A8283782D37AC3100EAB366 /* AMMarkDownTableViewBlowUpControllerViewController.h in Headers */,\n\t\t\t\t9C48DDDC2CE4C5BE00E10317 /* AMUnderline.h in Headers */,\n\t\t\t\t9CF1E8232CDB9D8200451CBD /* CMHTMLSubscriptTransformer.h in Headers */,\n\t\t\t\t9CF1E8102CDB9D8200451CBD /* CMCascadingAttributeStack.h in Headers */,\n\t\t\t\t9CF1E8092CDB9D8200451CBD /* CMAttributedStringRenderer_Private.h in Headers */,\n\t\t\t\t9CF1E82F2CDB9D8200451CBD /* CMIterator.h in Headers */,\n\t\t\t\t9CF1E80A2CDB9D8200451CBD /* CMAttributedStringRenderer.h in Headers */,\n\t\t\t\t9CF1E8382CDB9D8200451CBD /* CMPlatformDefines.h in Headers */,\n\t\t\t\t9CF1E8362CDB9D8200451CBD /* CMParser.h in Headers */,\n\t\t\t\t9CF1E81F2CDB9D8200451CBD /* CMHTMLScriptTransformer.h in Headers */,\n\t\t\t\t9C7D1B182CEF21B200EFB06A /* ONOXMLDocument.h in Headers */,\n\t\t\t\t9CF1E8122CDB9D8200451CBD /* CMDocument_Private.h in Headers */,\n\t\t\t\t9CF1E8882CDBA5B500451CBD /* cmark-gfm.h in Headers */,\n\t\t\t\tEC2133272D9AB6F700C86B39 /* CMTaskCheckAttachment+Private.h in Headers */,\n\t\t\t\t9CB413AC2CDC90F50000585E /* cmark-gfm_version.h in Headers */,\n\t\t\t\t9CF1E81C2CDB9D8200451CBD /* CMHTMLRenderer.h in Headers */,\n\t\t\t\t9CF1E83B2CDB9D8200451CBD /* CMTextAttributes.h in Headers */,\n\t\t\t\t9CF1E83D2CDB9D8200451CBD /* CocoaMarkdown.h in Headers */,\n\t\t\t\t9CF1E8272CDB9D8200451CBD /* CMHTMLUnderlineTransformer.h in Headers */,\n\t\t\t\t9CF1E8252CDB9D8200451CBD /* CMHTMLSuperscriptTransformer.h in Headers */,\n\t\t\t\t9CF1E8292CDB9D8200451CBD /* CMHTMLUtilities.h in Headers */,\n\t\t\t\t9CF1E81E2CDB9D8200451CBD /* CMHTMLScriptTransformer_Private.h in Headers */,\n\t\t\t\t9C3EA8682CFA8C7800C8F03B /* NSMutableAttributedString+AntMarkdown.h in Headers */,\n\t\t\t\t9CF1E8322CDB9D8200451CBD /* CMNode.h in Headers */,\n\t\t\t\t9CF1E7B92CDB9D8200451CBD /* AntMarkdown.h in Headers */,\n\t\t\t\t9CF1E7BA2CDB9D8200451CBD /* UILabel+AntMarkdown.h in Headers */,\n\t\t\t\t9CF1E7BC2CDB9D8200451CBD /* UITextView+AntMarkdown.h in Headers */,\n\t\t\t\t9CB413942CDC657D0000585E /* NSString+AntMarkdown.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXHeadersBuildPhase section */\n\n/* Begin PBXNativeTarget section */\n\t\tA2E9D389170BD37D00B11F5E /* AntMarkdown */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = A2E9D394170BD37D00B11F5E /* Build configuration list for PBXNativeTarget \"AntMarkdown\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tA2E9D386170BD37D00B11F5E /* Sources */,\n\t\t\t\tA2E9D387170BD37D00B11F5E /* Frameworks */,\n\t\t\t\tA2E9D388170BD37D00B11F5E /* Resources */,\n\t\t\t\tAA43C4EC19650DB400944353 /* Headers */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = AntMarkdown;\n\t\t\tproductName = AntMarkdown;\n\t\t\tproductReference = A2E9D38A170BD37D00B11F5E /* AntMarkdown.framework */;\n\t\t\tproductType = \"com.apple.product-type.framework\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\tA2E9D359170BD32000B11F5E /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastUpgradeCheck = 0460;\n\t\t\t\tORGANIZATIONNAME = Alipay;\n\t\t\t};\n\t\t\tbuildConfigurationList = A2E9D35C170BD32000B11F5E /* Build configuration list for PBXProject \"AntMarkdown\" */;\n\t\t\tcompatibilityVersion = \"Xcode 3.2\";\n\t\t\tdevelopmentRegion = English;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\tEnglish,\n\t\t\t\ten,\n\t\t\t);\n\t\t\tmainGroup = A2E9D358170BD32000B11F5E;\n\t\t\tproductRefGroup = A2E9D362170BD32000B11F5E /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\tA2E9D389170BD37D00B11F5E /* AntMarkdown */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\tA2E9D388170BD37D00B11F5E /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t9CF1E8682CDB9FE300451CBD /* mathFonts.bundle in Resources */,\n\t\t\t\t9CF1E8692CDB9FE300451CBD /* highlightjs.bundle in Resources */,\n\t\t\t\tA2CA04A0188A78A900D1E152 /* AntMarkdown-Info.plist in Resources */,\n\t\t\t\tA2CA04A1188A78A900D1E152 /* InfoPlist.strings in Resources */,\n\t\t\t\tAAC068C2188D1F8E001B468D /* AntMarkdown.bundle in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\tA2E9D386170BD37D00B11F5E /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t9CF1E8442CDB9D8200451CBD /* MTMathListBuilder.m in Sources */,\n\t\t\t\t9CF1E7EC2CDB9D8200451CBD /* latex.c in Sources */,\n\t\t\t\t0A8283772D37AC3100EAB366 /* AMMarkDownTableViewBlowUpControllerViewController.m in Sources */,\n\t\t\t\t9CF1E7B42CDB9D8200451CBD /* AMTextStyles.m in Sources */,\n\t\t\t\t9CF1E7EA2CDB9D8200451CBD /* iterator.c in Sources */,\n\t\t\t\t9CF1E8202CDB9D8200451CBD /* CMHTMLScriptTransformer.m in Sources */,\n\t\t\t\t9CF1E8512CDB9D8200451CBD /* MTFont.m in Sources */,\n\t\t\t\t9CF1E8332CDB9D8200451CBD /* CMNode.m in Sources */,\n\t\t\t\t9CF1E8652CDB9D8200451CBD /* ONOXMLDocument.m in Sources */,\n\t\t\t\t9CF1E7AE2CDB9D8200451CBD /* AMMarkdownTableView.m in Sources */,\n\t\t\t\t9CF1E84B2CDB9D8200451CBD /* MTFontMathTable.m in Sources */,\n\t\t\t\t9CF1E7F52CDB9D8200451CBD /* plaintext.c in Sources */,\n\t\t\t\t9CF1E7CC2CDB9D8200451CBD /* tagfilter.c in Sources */,\n\t\t\t\t9CF1E8372CDB9D8200451CBD /* CMParser.m in Sources */,\n\t\t\t\t9CF1E7AA2CDB9D8200451CBD /* AMMarkdownCodeView.m in Sources */,\n\t\t\t\t9CF1E7E02CDB9D8200451CBD /* footnotes.c in Sources */,\n\t\t\t\t9CF1E8222CDB9D8200451CBD /* CMHTMLStrikethroughTransformer.m in Sources */,\n\t\t\t\t77EB5F0B2E69B3FA0042F5BD /* AMUtils.m in Sources */,\n\t\t\t\t9CF1E85B2CDB9D8200451CBD /* NSBezierPath+addLineToPoint.m in Sources */,\n\t\t\t\t9CF1E85F2CDB9D8200451CBD /* NSView+backgroundColor.m in Sources */,\n\t\t\t\t9CF1E82A2CDB9D8200451CBD /* CMHTMLUtilities.m in Sources */,\n\t\t\t\t9CF1E7CE2CDB9D8200451CBD /* tasklist.c in Sources */,\n\t\t\t\t9CF1E7B82CDB9D8200451CBD /* AMViewAttachment.m in Sources */,\n\t\t\t\t9CF1E7C32CDB9D8200451CBD /* ext_scanners.c in Sources */,\n\t\t\t\tECE1C84D2D924D930034FEE2 /* emoji.c in Sources */,\n\t\t\t\t9CF1E8402CDB9D8200451CBD /* MTMathAtomFactory.m in Sources */,\n\t\t\t\t9CF1E7E42CDB9D8200451CBD /* houdini_html_u.c in Sources */,\n\t\t\t\t77A5FD682D9CE399009B0C1D /* AMIconLinkAttachment.m in Sources */,\n\t\t\t\t9CF1E81D2CDB9D8200451CBD /* CMHTMLRenderer.m in Sources */,\n\t\t\t\t9CF1E7C22CDB9D8200451CBD /* core-extensions.c in Sources */,\n\t\t\t\t9CF1E7AC2CDB9D8200451CBD /* AMMarkdownTableLayout.m in Sources */,\n\t\t\t\t9CF1E7BE2CDB9D8200451CBD /* autolink.c in Sources */,\n\t\t\t\t9CF1E8352CDB9D8200451CBD /* CMNode+Table.m in Sources */,\n\t\t\t\t9CF1E7B02CDB9D8200451CBD /* AMTableViewAttachment.m in Sources */,\n\t\t\t\t9CF1E7B22CDB9D8200451CBD /* AMTextBackground.m in Sources */,\n\t\t\t\t9C48DDDB2CE4C5BE00E10317 /* AMUnderline.m in Sources */,\n\t\t\t\t9CF1E83A2CDB9D8200451CBD /* CMStack.m in Sources */,\n\t\t\t\t9CF1E8242CDB9D8200451CBD /* CMHTMLSubscriptTransformer.m in Sources */,\n\t\t\t\t9CF1E7D22CDB9D8200451CBD /* buffer.c in Sources */,\n\t\t\t\t9CF1E8612CDB9D8200451CBD /* UIColor+HexString.m in Sources */,\n\t\t\t\t9CF1E8422CDB9D8200451CBD /* MTMathList.m in Sources */,\n\t\t\t\t9CF1E8032CDB9D8200451CBD /* utf8.c in Sources */,\n\t\t\t\t9CF1E79A2CDB9D8200451CBD /* AMBlockMathAttachment.m in Sources */,\n\t\t\t\t9CF1E85D2CDB9D8200451CBD /* NSColor+HexString.m in Sources */,\n\t\t\t\t0E449DC22D806CFC001E7430 /* CMHorizontalRuleAttachment.m in Sources */,\n\t\t\t\t9CF1E82C2CDB9D8200451CBD /* CMImageTextAttachment.m in Sources */,\n\t\t\t\t9CF1E8532CDB9D8200451CBD /* MTFontManager.m in Sources */,\n\t\t\t\t9CF1E8592CDB9D8200451CBD /* MTMathUILabel.m in Sources */,\n\t\t\t\t9CF1E7DD2CDB9D8200451CBD /* commonmark.c in Sources */,\n\t\t\t\tECF404AD2D9A45C400B04B59 /* CMTaskCheckAttachment.m in Sources */,\n\t\t\t\t9CF1E8012CDB9D8200451CBD /* syntax_extension.c in Sources */,\n\t\t\t\t9CF1E7E22CDB9D8200451CBD /* houdini_href_e.c in Sources */,\n\t\t\t\t9CF1E7E62CDB9D8200451CBD /* html.c in Sources */,\n\t\t\t\t9C3EA8692CFA8C7800C8F03B /* NSMutableAttributedString+AntMarkdown.m in Sources */,\n\t\t\t\t9CF1E7C62CDB9D8200451CBD /* math_mark.c in Sources */,\n\t\t\t\tEC3578F52D816E8200F10E01 /* AMLayoutManager+Quote.m in Sources */,\n\t\t\t\t9CF1E7FC2CDB9D8200451CBD /* render.c in Sources */,\n\t\t\t\t9CF1E7F62CDB9D8200451CBD /* plugin.c in Sources */,\n\t\t\t\t9CF1E7D72CDB9D8200451CBD /* cmark_ctype.c in Sources */,\n\t\t\t\t9CF1E7F22CDB9D8200451CBD /* node.c in Sources */,\n\t\t\t\t9CF1E8052CDB9D8200451CBD /* xml.c in Sources */,\n\t\t\t\t9CF1E83C2CDB9D8200451CBD /* CMTextAttributes.m in Sources */,\n\t\t\t\t9CF1E7A22CDB9D8200451CBD /* AMGradient.m in Sources */,\n\t\t\t\t9CF1E7BD2CDB9D8200451CBD /* UITextView+AntMarkdown.m in Sources */,\n\t\t\t\t9CF1E7A42CDB9D8200451CBD /* AMHTMLTransformer.m in Sources */,\n\t\t\t\t9CF1E8162CDB9D8200451CBD /* CMDocument+AttributedStringAdditions.m in Sources */,\n\t\t\t\t9CF1E7F02CDB9D8200451CBD /* map.c in Sources */,\n\t\t\t\t9CF1E7A62CDB9D8200451CBD /* AMInlineMathAttachment.m in Sources */,\n\t\t\t\t771F1B9D2E1674570009C5B5 /* AMIconAttachment.m in Sources */,\n\t\t\t\t9CF1E7E32CDB9D8200451CBD /* houdini_html_e.c in Sources */,\n\t\t\t\t9CF1E8302CDB9D8200451CBD /* CMIterator.m in Sources */,\n\t\t\t\t9CF1E7A82CDB9D8200451CBD /* AMLayoutManager.m in Sources */,\n\t\t\t\tA2E668DD2D310BA2005CC3B6 /* AMGradientLayer.m in Sources */,\n\t\t\t\t9CF1E8262CDB9D8200451CBD /* CMHTMLSuperscriptTransformer.m in Sources */,\n\t\t\t\t9CF1E84E2CDB9D8200451CBD /* MTTypesetter.m in Sources */,\n\t\t\t\t9CF1E80B2CDB9D8200451CBD /* CMAttributedStringRenderer.m in Sources */,\n\t\t\t\t9CF1E7FA2CDB9D8200451CBD /* registry.c in Sources */,\n\t\t\t\t9CF1E7A02CDB9D8200451CBD /* AMDrawable.m in Sources */,\n\t\t\t\t9CF1E7EF2CDB9D8200451CBD /* man.c in Sources */,\n\t\t\t\t9CB413932CDC657D0000585E /* NSString+AntMarkdown.m in Sources */,\n\t\t\t\t9CF1E7DC2CDB9D8200451CBD /* cmark.c in Sources */,\n\t\t\t\t9CF1E7C82CDB9D8200451CBD /* strikethrough.c in Sources */,\n\t\t\t\t9CF1E7CA2CDB9D8200451CBD /* table.c in Sources */,\n\t\t\t\t9CF1E8142CDB9D8200451CBD /* CMDocument.m in Sources */,\n\t\t\t\t9CF1E7982CDB9D8200451CBD /* AMAttributedStringRenderer.m in Sources */,\n\t\t\t\t9CF1E79E2CDB9D8200451CBD /* AMCodeViewAttachment.m in Sources */,\n\t\t\t\t9CF1E8462CDB9D8200451CBD /* MTMathListIndex.m in Sources */,\n\t\t\t\t9CF1E8112CDB9D8200451CBD /* CMCascadingAttributeStack.m in Sources */,\n\t\t\t\t9CF1E8282CDB9D8200451CBD /* CMHTMLUnderlineTransformer.m in Sources */,\n\t\t\t\t9CF1E8482CDB9D8200451CBD /* MTUnicode.m in Sources */,\n\t\t\t\t9CF1E8572CDB9D8200451CBD /* MTMathListDisplay.m in Sources */,\n\t\t\t\t9CF1E80F2CDB9D8200451CBD /* CMBlockTextAttachment.m in Sources */,\n\t\t\t\tEC5421972D928E5E00510C86 /* AMEmojiManager.m in Sources */,\n\t\t\t\t9CF1E79C2CDB9D8200451CBD /* AMCodeHighlighter.m in Sources */,\n\t\t\t\t9C48DDE12CE5953400E10317 /* AMGradientView.m in Sources */,\n\t\t\t\t9CF1E7BB2CDB9D8200451CBD /* UILabel+AntMarkdown.m in Sources */,\n\t\t\t\t9CF1E7EE2CDB9D8200451CBD /* linked_list.c in Sources */,\n\t\t\t\t9CF1E80D2CDB9D8200451CBD /* CMAttributeRun.m in Sources */,\n\t\t\t\t9CF1E81A2CDB9D8200451CBD /* CMHTMLElement.m in Sources */,\n\t\t\t\t9CF1E82E2CDB9D8200451CBD /* CMInlineTextAttachment.m in Sources */,\n\t\t\t\t9CF1E7D02CDB9D8200451CBD /* arena.c in Sources */,\n\t\t\t\t9CB413B42CDDC31B0000585E /* AMImageTextAttachment.m in Sources */,\n\t\t\t\t9CF1E7F82CDB9D8200451CBD /* references.c in Sources */,\n\t\t\t\t9CF1E8552CDB9D8200451CBD /* MTLabel.m in Sources */,\n\t\t\t\t9CF1E7FE2CDB9D8200451CBD /* scanners.c in Sources */,\n\t\t\t\t9CF1E7D12CDB9D8200451CBD /* blocks.c in Sources */,\n\t\t\t\t9CF1E7E82CDB9D8200451CBD /* inlines.c in Sources */,\n\t\t\t\t9CF1E8182CDB9D8200451CBD /* CMDocument+HTMLAdditions.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXVariantGroup section */\n\t\tA2CA049B188A78A900D1E152 /* InfoPlist.strings */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\tA2CA049C188A78A900D1E152 /* en */,\n\t\t\t);\n\t\t\tname = InfoPlist.strings;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\tA2E9D37C170BD32100B11F5E /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_SYMBOLS_PRIVATE_EXTERN = NO;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tHEADER_SEARCH_PATHS = \"${SRCROOT}/Pods/Headers/Public/**\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 6.1;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tA2E9D37D170BD32100B11F5E /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tHEADER_SEARCH_PATHS = \"${SRCROOT}/Pods/Headers/Public/**\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 6.1;\n\t\t\t\tOTHER_CFLAGS = \"-DNS_BLOCK_ASSERTIONS=1\";\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tA2E9D395170BD37D00B11F5E /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tARCHS = \"$(ARCHS_STANDARD)\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tDEAD_CODE_STRIPPING = NO;\n\t\t\t\tENABLE_BITCODE = NO;\n\t\t\t\tEXCLUDED_ARCHS = \"\";\n\t\t\t\t\"EXCLUDED_ARCHS[sdk=iphonesimulator*]\" = \"\";\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = \"$(inherited)\";\n\t\t\t\tGCC_ENABLE_OBJC_EXCEPTIONS = YES;\n\t\t\t\tGCC_PRECOMPILE_PREFIX_HEADER = NO;\n\t\t\t\tGCC_PREFIX_HEADER = \"SupportingFiles/AntMarkdown-Prefix.pch\";\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tHEADER_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"./Sources/**\",\n\t\t\t\t);\n\t\t\t\tINFOPLIST_FILE = \"SupportingFiles/AntMarkdown-Info.plist\";\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Bundles\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.0;\n\t\t\t\tLINK_WITH_STANDARD_LIBRARIES = NO;\n\t\t\t\tMACH_O_TYPE = staticlib;\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = \"\";\n\t\t\t\tOTHER_LDFLAGS = \"\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tVALIDATE_WORKSPACE = YES;\n\t\t\t\tWRAPPER_EXTENSION = framework;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tA2E9D396170BD37D00B11F5E /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tARCHS = \"$(ARCHS_STANDARD)\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tDEAD_CODE_STRIPPING = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_BITCODE = NO;\n\t\t\t\tEXCLUDED_ARCHS = \"\";\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = \"$(inherited)\";\n\t\t\t\tGCC_ENABLE_OBJC_EXCEPTIONS = YES;\n\t\t\t\tGCC_PRECOMPILE_PREFIX_HEADER = NO;\n\t\t\t\tGCC_PREFIX_HEADER = \"SupportingFiles/AntMarkdown-Prefix.pch\";\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tHEADER_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"./Sources/**\",\n\t\t\t\t);\n\t\t\t\tINFOPLIST_FILE = \"SupportingFiles/AntMarkdown-Info.plist\";\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Bundles\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.0;\n\t\t\t\tLINK_WITH_STANDARD_LIBRARIES = NO;\n\t\t\t\tMACH_O_TYPE = staticlib;\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = \"\";\n\t\t\t\tOTHER_LDFLAGS = \"\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tVALIDATE_WORKSPACE = YES;\n\t\t\t\tWRAPPER_EXTENSION = framework;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\tA2E9D35C170BD32000B11F5E /* Build configuration list for PBXProject \"AntMarkdown\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tA2E9D37C170BD32100B11F5E /* Debug */,\n\t\t\t\tA2E9D37D170BD32100B11F5E /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tA2E9D394170BD37D00B11F5E /* Build configuration list for PBXNativeTarget \"AntMarkdown\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tA2E9D395170BD37D00B11F5E /* Debug */,\n\t\t\t\tA2E9D396170BD37D00B11F5E /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = A2E9D359170BD32000B11F5E /* Project object */;\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Makefile",
    "content": "include ~/.aptkit/templates/makefile"
  },
  {
    "path": "iOS/AntMarkdown/Resources/AntMarkdown.bundle/Images.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Resources/mathFonts.bundle/xits-math.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>accents</key>\n\t<dict>\n\t\t<key>A</key>\n\t\t<integer>361</integer>\n\t\t<key>B</key>\n\t\t<integer>305</integer>\n\t\t<key>C</key>\n\t\t<integer>360</integer>\n\t\t<key>D</key>\n\t\t<integer>350</integer>\n\t\t<key>E</key>\n\t\t<integer>304</integer>\n\t\t<key>F</key>\n\t\t<integer>294</integer>\n\t\t<key>G</key>\n\t\t<integer>376</integer>\n\t\t<key>H</key>\n\t\t<integer>360</integer>\n\t\t<key>I</key>\n\t\t<integer>166</integer>\n\t\t<key>J</key>\n\t\t<integer>214</integer>\n\t\t<key>K</key>\n\t\t<integer>368</integer>\n\t\t<key>L</key>\n\t\t<integer>151</integer>\n\t\t<key>M</key>\n\t\t<integer>438</integer>\n\t\t<key>N</key>\n\t\t<integer>360</integer>\n\t\t<key>O</key>\n\t\t<integer>361</integer>\n\t\t<key>P</key>\n\t\t<integer>279</integer>\n\t\t<key>Q</key>\n\t\t<integer>358</integer>\n\t\t<key>R</key>\n\t\t<integer>272</integer>\n\t\t<key>S</key>\n\t\t<integer>267</integer>\n\t\t<key>T</key>\n\t\t<integer>305</integer>\n\t\t<key>U</key>\n\t\t<integer>390</integer>\n\t\t<key>V</key>\n\t\t<integer>388</integer>\n\t\t<key>W</key>\n\t\t<integer>456</integer>\n\t\t<key>X</key>\n\t\t<integer>397</integer>\n\t\t<key>Y</key>\n\t\t<integer>396</integer>\n\t\t<key>Z</key>\n\t\t<integer>304</integer>\n\t\t<key>a</key>\n\t\t<integer>222</integer>\n\t\t<key>b</key>\n\t\t<integer>112</integer>\n\t\t<key>breve</key>\n\t\t<integer>168</integer>\n\t\t<key>c</key>\n\t\t<integer>244</integer>\n\t\t<key>caron</key>\n\t\t<integer>166</integer>\n\t\t<key>circumflex</key>\n\t\t<integer>166</integer>\n\t\t<key>d</key>\n\t\t<integer>367</integer>\n\t\t<key>dotaccent</key>\n\t\t<integer>168</integer>\n\t\t<key>dotlessi</key>\n\t\t<integer>134</integer>\n\t\t<key>e</key>\n\t\t<integer>224</integer>\n\t\t<key>f</key>\n\t\t<integer>264</integer>\n\t\t<key>g</key>\n\t\t<integer>233</integer>\n\t\t<key>h</key>\n\t\t<integer>116</integer>\n\t\t<key>hungarumlaut</key>\n\t\t<integer>186</integer>\n\t\t<key>i</key>\n\t\t<integer>132</integer>\n\t\t<key>j</key>\n\t\t<integer>144</integer>\n\t\t<key>k</key>\n\t\t<integer>116</integer>\n\t\t<key>l</key>\n\t\t<integer>138</integer>\n\t\t<key>m</key>\n\t\t<integer>396</integer>\n\t\t<key>n</key>\n\t\t<integer>250</integer>\n\t\t<key>o</key>\n\t\t<integer>250</integer>\n\t\t<key>p</key>\n\t\t<integer>238</integer>\n\t\t<key>periodcentered</key>\n\t\t<integer>126</integer>\n\t\t<key>q</key>\n\t\t<integer>256</integer>\n\t\t<key>r</key>\n\t\t<integer>170</integer>\n\t\t<key>ring</key>\n\t\t<integer>166</integer>\n\t\t<key>s</key>\n\t\t<integer>200</integer>\n\t\t<key>t</key>\n\t\t<integer>116</integer>\n\t\t<key>tilde</key>\n\t\t<integer>166</integer>\n\t\t<key>u</key>\n\t\t<integer>234</integer>\n\t\t<key>u1D400</key>\n\t\t<integer>345</integer>\n\t\t<key>u1D401</key>\n\t\t<integer>318</integer>\n\t\t<key>u1D402</key>\n\t\t<integer>368</integer>\n\t\t<key>u1D403</key>\n\t\t<integer>352</integer>\n\t\t<key>u1D404</key>\n\t\t<integer>328</integer>\n\t\t<key>u1D405</key>\n\t\t<integer>300</integer>\n\t\t<key>u1D406</key>\n\t\t<integer>396</integer>\n\t\t<key>u1D407</key>\n\t\t<integer>390</integer>\n\t\t<key>u1D408</key>\n\t\t<integer>195</integer>\n\t\t<key>u1D409</key>\n\t\t<integer>310</integer>\n\t\t<key>u1D40A</key>\n\t\t<integer>410</integer>\n\t\t<key>u1D40B</key>\n\t\t<integer>192</integer>\n\t\t<key>u1D40C</key>\n\t\t<integer>468</integer>\n\t\t<key>u1D40D</key>\n\t\t<integer>358</integer>\n\t\t<key>u1D40E</key>\n\t\t<integer>389</integer>\n\t\t<key>u1D40F</key>\n\t\t<integer>308</integer>\n\t\t<key>u1D410</key>\n\t\t<integer>389</integer>\n\t\t<key>u1D411</key>\n\t\t<integer>323</integer>\n\t\t<key>u1D412</key>\n\t\t<integer>274</integer>\n\t\t<key>u1D413</key>\n\t\t<integer>334</integer>\n\t\t<key>u1D414</key>\n\t\t<integer>420</integer>\n\t\t<key>u1D415</key>\n\t\t<integer>424</integer>\n\t\t<key>u1D416</key>\n\t\t<integer>540</integer>\n\t\t<key>u1D417</key>\n\t\t<integer>402</integer>\n\t\t<key>u1D418</key>\n\t\t<integer>415</integer>\n\t\t<key>u1D419</key>\n\t\t<integer>331</integer>\n\t\t<key>u1D41A</key>\n\t\t<integer>256</integer>\n\t\t<key>u1D41B</key>\n\t\t<integer>139</integer>\n\t\t<key>u1D41C</key>\n\t\t<integer>261</integer>\n\t\t<key>u1D41D</key>\n\t\t<integer>400</integer>\n\t\t<key>u1D41E</key>\n\t\t<integer>235</integer>\n\t\t<key>u1D41F</key>\n\t\t<integer>246</integer>\n\t\t<key>u1D420</key>\n\t\t<integer>240</integer>\n\t\t<key>u1D421</key>\n\t\t<integer>130</integer>\n\t\t<key>u1D422</key>\n\t\t<integer>136</integer>\n\t\t<key>u1D422.dtls</key>\n\t\t<integer>139</integer>\n\t\t<key>u1D423</key>\n\t\t<integer>189</integer>\n\t\t<key>u1D423.dtls</key>\n\t\t<integer>190</integer>\n\t\t<key>u1D424</key>\n\t\t<integer>140</integer>\n\t\t<key>u1D425</key>\n\t\t<integer>136</integer>\n\t\t<key>u1D426</key>\n\t\t<integer>414</integer>\n\t\t<key>u1D427</key>\n\t\t<integer>280</integer>\n\t\t<key>u1D428</key>\n\t\t<integer>250</integer>\n\t\t<key>u1D429</key>\n\t\t<integer>272</integer>\n\t\t<key>u1D42A</key>\n\t\t<integer>285</integer>\n\t\t<key>u1D42B</key>\n\t\t<integer>231</integer>\n\t\t<key>u1D42C</key>\n\t\t<integer>193</integer>\n\t\t<key>u1D42D</key>\n\t\t<integer>176</integer>\n\t\t<key>u1D42E</key>\n\t\t<integer>249</integer>\n\t\t<key>u1D42F</key>\n\t\t<integer>288</integer>\n\t\t<key>u1D430</key>\n\t\t<integer>407</integer>\n\t\t<key>u1D431</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D432</key>\n\t\t<integer>265</integer>\n\t\t<key>u1D433</key>\n\t\t<integer>220</integer>\n\t\t<key>u1D434</key>\n\t\t<integer>510</integer>\n\t\t<key>u1D435</key>\n\t\t<integer>476</integer>\n\t\t<key>u1D436</key>\n\t\t<integer>492</integer>\n\t\t<key>u1D437</key>\n\t\t<integer>494</integer>\n\t\t<key>u1D438</key>\n\t\t<integer>490</integer>\n\t\t<key>u1D439</key>\n\t\t<integer>490</integer>\n\t\t<key>u1D43A</key>\n\t\t<integer>488</integer>\n\t\t<key>u1D43B</key>\n\t\t<integer>556</integer>\n\t\t<key>u1D43C</key>\n\t\t<integer>388</integer>\n\t\t<key>u1D43D</key>\n\t\t<integer>478</integer>\n\t\t<key>u1D43E</key>\n\t\t<integer>536</integer>\n\t\t<key>u1D43F</key>\n\t\t<integer>387</integer>\n\t\t<key>u1D440</key>\n\t\t<integer>624</integer>\n\t\t<key>u1D441</key>\n\t\t<integer>536</integer>\n\t\t<key>u1D442</key>\n\t\t<integer>475</integer>\n\t\t<key>u1D443</key>\n\t\t<integer>477</integer>\n\t\t<key>u1D444</key>\n\t\t<integer>490</integer>\n\t\t<key>u1D445</key>\n\t\t<integer>474</integer>\n\t\t<key>u1D446</key>\n\t\t<integer>469</integer>\n\t\t<key>u1D447</key>\n\t\t<integer>382</integer>\n\t\t<key>u1D448</key>\n\t\t<integer>440</integer>\n\t\t<key>u1D449</key>\n\t\t<integer>438</integer>\n\t\t<key>u1D44A</key>\n\t\t<integer>574</integer>\n\t\t<key>u1D44B</key>\n\t\t<integer>530</integer>\n\t\t<key>u1D44C</key>\n\t\t<integer>391</integer>\n\t\t<key>u1D44D</key>\n\t\t<integer>521</integer>\n\t\t<key>u1D44E</key>\n\t\t<integer>324</integer>\n\t\t<key>u1D44F</key>\n\t\t<integer>240</integer>\n\t\t<key>u1D450</key>\n\t\t<integer>304</integer>\n\t\t<key>u1D451</key>\n\t\t<integer>470</integer>\n\t\t<key>u1D452</key>\n\t\t<integer>299</integer>\n\t\t<key>u1D453</key>\n\t\t<integer>528</integer>\n\t\t<key>u1D454</key>\n\t\t<integer>324</integer>\n\t\t<key>u1D456</key>\n\t\t<integer>208</integer>\n\t\t<key>u1D457</key>\n\t\t<integer>322</integer>\n\t\t<key>u1D458</key>\n\t\t<integer>234</integer>\n\t\t<key>u1D459</key>\n\t\t<integer>222</integer>\n\t\t<key>u1D45A</key>\n\t\t<integer>399</integer>\n\t\t<key>u1D45B</key>\n\t\t<integer>306</integer>\n\t\t<key>u1D45C</key>\n\t\t<integer>293</integer>\n\t\t<key>u1D45D</key>\n\t\t<integer>320</integer>\n\t\t<key>u1D45E</key>\n\t\t<integer>340</integer>\n\t\t<key>u1D45F</key>\n\t\t<integer>244</integer>\n\t\t<key>u1D460</key>\n\t\t<integer>268</integer>\n\t\t<key>u1D461</key>\n\t\t<integer>214</integer>\n\t\t<key>u1D462</key>\n\t\t<integer>277</integer>\n\t\t<key>u1D463</key>\n\t\t<integer>319</integer>\n\t\t<key>u1D464</key>\n\t\t<integer>481</integer>\n\t\t<key>u1D465</key>\n\t\t<integer>304</integer>\n\t\t<key>u1D466</key>\n\t\t<integer>319</integer>\n\t\t<key>u1D467</key>\n\t\t<integer>300</integer>\n\t\t<key>u1D468</key>\n\t\t<integer>518</integer>\n\t\t<key>u1D469</key>\n\t\t<integer>486</integer>\n\t\t<key>u1D46A</key>\n\t\t<integer>494</integer>\n\t\t<key>u1D46B</key>\n\t\t<integer>478</integer>\n\t\t<key>u1D46C</key>\n\t\t<integer>492</integer>\n\t\t<key>u1D46D</key>\n\t\t<integer>491</integer>\n\t\t<key>u1D46E</key>\n\t\t<integer>510</integer>\n\t\t<key>u1D46F</key>\n\t\t<integer>564</integer>\n\t\t<key>u1D470</key>\n\t\t<integer>404</integer>\n\t\t<key>u1D471</key>\n\t\t<integer>490</integer>\n\t\t<key>u1D472</key>\n\t\t<integer>554</integer>\n\t\t<key>u1D473</key>\n\t\t<integer>399</integer>\n\t\t<key>u1D474</key>\n\t\t<integer>630</integer>\n\t\t<key>u1D475</key>\n\t\t<integer>537</integer>\n\t\t<key>u1D476</key>\n\t\t<integer>493</integer>\n\t\t<key>u1D477</key>\n\t\t<integer>460</integer>\n\t\t<key>u1D478</key>\n\t\t<integer>483</integer>\n\t\t<key>u1D479</key>\n\t\t<integer>455</integer>\n\t\t<key>u1D47A</key>\n\t\t<integer>474</integer>\n\t\t<key>u1D47B</key>\n\t\t<integer>404</integer>\n\t\t<key>u1D47C</key>\n\t\t<integer>473</integer>\n\t\t<key>u1D47D</key>\n\t\t<integer>462</integer>\n\t\t<key>u1D47E</key>\n\t\t<integer>598</integer>\n\t\t<key>u1D47F</key>\n\t\t<integer>529</integer>\n\t\t<key>u1D480</key>\n\t\t<integer>410</integer>\n\t\t<key>u1D481</key>\n\t\t<integer>512</integer>\n\t\t<key>u1D482</key>\n\t\t<integer>330</integer>\n\t\t<key>u1D483</key>\n\t\t<integer>244</integer>\n\t\t<key>u1D484</key>\n\t\t<integer>328</integer>\n\t\t<key>u1D485</key>\n\t\t<integer>502</integer>\n\t\t<key>u1D486</key>\n\t\t<integer>338</integer>\n\t\t<key>u1D487</key>\n\t\t<integer>528</integer>\n\t\t<key>u1D488</key>\n\t\t<integer>338</integer>\n\t\t<key>u1D489</key>\n\t\t<integer>246</integer>\n\t\t<key>u1D48A</key>\n\t\t<integer>234</integer>\n\t\t<key>u1D48A.dtls</key>\n\t\t<integer>178</integer>\n\t\t<key>u1D48B</key>\n\t\t<integer>348</integer>\n\t\t<key>u1D48B.dtls</key>\n\t\t<integer>345</integer>\n\t\t<key>u1D48C</key>\n\t\t<integer>247</integer>\n\t\t<key>u1D48D</key>\n\t\t<integer>238</integer>\n\t\t<key>u1D48E</key>\n\t\t<integer>380</integer>\n\t\t<key>u1D48F</key>\n\t\t<integer>318</integer>\n\t\t<key>u1D490</key>\n\t\t<integer>340</integer>\n\t\t<key>u1D491</key>\n\t\t<integer>354</integer>\n\t\t<key>u1D492</key>\n\t\t<integer>368</integer>\n\t\t<key>u1D493</key>\n\t\t<integer>264</integer>\n\t\t<key>u1D494</key>\n\t\t<integer>289</integer>\n\t\t<key>u1D495</key>\n\t\t<integer>243</integer>\n\t\t<key>u1D496</key>\n\t\t<integer>298</integer>\n\t\t<key>u1D497</key>\n\t\t<integer>342</integer>\n\t\t<key>u1D498</key>\n\t\t<integer>486</integer>\n\t\t<key>u1D499</key>\n\t\t<integer>332</integer>\n\t\t<key>u1D49A</key>\n\t\t<integer>335</integer>\n\t\t<key>u1D49B</key>\n\t\t<integer>308</integer>\n\t\t<key>u1D49C</key>\n\t\t<integer>800</integer>\n\t\t<key>u1D49C.cal</key>\n\t\t<integer>642</integer>\n\t\t<key>u1D49E</key>\n\t\t<integer>697</integer>\n\t\t<key>u1D49E.cal</key>\n\t\t<integer>444</integer>\n\t\t<key>u1D49F</key>\n\t\t<integer>725</integer>\n\t\t<key>u1D49F.cal</key>\n\t\t<integer>500</integer>\n\t\t<key>u1D4A2</key>\n\t\t<integer>642</integer>\n\t\t<key>u1D4A2.cal</key>\n\t\t<integer>452</integer>\n\t\t<key>u1D4A5</key>\n\t\t<integer>662</integer>\n\t\t<key>u1D4A5.cal</key>\n\t\t<integer>612</integer>\n\t\t<key>u1D4A6</key>\n\t\t<integer>772</integer>\n\t\t<key>u1D4A6.cal</key>\n\t\t<integer>500</integer>\n\t\t<key>u1D4A9</key>\n\t\t<integer>740</integer>\n\t\t<key>u1D4A9.cal</key>\n\t\t<integer>636</integer>\n\t\t<key>u1D4AA</key>\n\t\t<integer>519</integer>\n\t\t<key>u1D4AA.cal</key>\n\t\t<integer>466</integer>\n\t\t<key>u1D4AB</key>\n\t\t<integer>710</integer>\n\t\t<key>u1D4AB.cal</key>\n\t\t<integer>391</integer>\n\t\t<key>u1D4AC</key>\n\t\t<integer>520</integer>\n\t\t<key>u1D4AC.cal</key>\n\t\t<integer>456</integer>\n\t\t<key>u1D4AE</key>\n\t\t<integer>562</integer>\n\t\t<key>u1D4AE.cal</key>\n\t\t<integer>477</integer>\n\t\t<key>u1D4AF</key>\n\t\t<integer>605</integer>\n\t\t<key>u1D4AF.cal</key>\n\t\t<integer>396</integer>\n\t\t<key>u1D4B0</key>\n\t\t<integer>552</integer>\n\t\t<key>u1D4B0.cal</key>\n\t\t<integer>536</integer>\n\t\t<key>u1D4B1</key>\n\t\t<integer>660</integer>\n\t\t<key>u1D4B1.cal</key>\n\t\t<integer>433</integer>\n\t\t<key>u1D4B2</key>\n\t\t<integer>756</integer>\n\t\t<key>u1D4B2.cal</key>\n\t\t<integer>574</integer>\n\t\t<key>u1D4B3</key>\n\t\t<integer>602</integer>\n\t\t<key>u1D4B3.cal</key>\n\t\t<integer>510</integer>\n\t\t<key>u1D4B4</key>\n\t\t<integer>648</integer>\n\t\t<key>u1D4B4.cal</key>\n\t\t<integer>495</integer>\n\t\t<key>u1D4B5</key>\n\t\t<integer>652</integer>\n\t\t<key>u1D4B5.cal</key>\n\t\t<integer>496</integer>\n\t\t<key>u1D4B6</key>\n\t\t<integer>499</integer>\n\t\t<key>u1D4B7</key>\n\t\t<integer>497</integer>\n\t\t<key>u1D4B8</key>\n\t\t<integer>487</integer>\n\t\t<key>u1D4B9</key>\n\t\t<integer>782</integer>\n\t\t<key>u1D4BB</key>\n\t\t<integer>600</integer>\n\t\t<key>u1D4BD</key>\n\t\t<integer>511</integer>\n\t\t<key>u1D4BE</key>\n\t\t<integer>443</integer>\n\t\t<key>u1D4BE.dtls</key>\n\t\t<integer>317</integer>\n\t\t<key>u1D4BF</key>\n\t\t<integer>671</integer>\n\t\t<key>u1D4BF.dtls</key>\n\t\t<integer>554</integer>\n\t\t<key>u1D4C0</key>\n\t\t<integer>513</integer>\n\t\t<key>u1D4C1</key>\n\t\t<integer>511</integer>\n\t\t<key>u1D4C2</key>\n\t\t<integer>603</integer>\n\t\t<key>u1D4C3</key>\n\t\t<integer>455</integer>\n\t\t<key>u1D4C5</key>\n\t\t<integer>545</integer>\n\t\t<key>u1D4C6</key>\n\t\t<integer>492</integer>\n\t\t<key>u1D4C7</key>\n\t\t<integer>404</integer>\n\t\t<key>u1D4C8</key>\n\t\t<integer>376</integer>\n\t\t<key>u1D4C9</key>\n\t\t<integer>422</integer>\n\t\t<key>u1D4CA</key>\n\t\t<integer>433</integer>\n\t\t<key>u1D4CB</key>\n\t\t<integer>393</integer>\n\t\t<key>u1D4CC</key>\n\t\t<integer>525</integer>\n\t\t<key>u1D4CD</key>\n\t\t<integer>454</integer>\n\t\t<key>u1D4CE</key>\n\t\t<integer>434</integer>\n\t\t<key>u1D4CF</key>\n\t\t<integer>399</integer>\n\t\t<key>u1D4D0</key>\n\t\t<integer>900</integer>\n\t\t<key>u1D4D0.cal</key>\n\t\t<integer>651</integer>\n\t\t<key>u1D4D1</key>\n\t\t<integer>856</integer>\n\t\t<key>u1D4D1.cal</key>\n\t\t<integer>553</integer>\n\t\t<key>u1D4D2</key>\n\t\t<integer>744</integer>\n\t\t<key>u1D4D2.cal</key>\n\t\t<integer>519</integer>\n\t\t<key>u1D4D3</key>\n\t\t<integer>799</integer>\n\t\t<key>u1D4D3.cal</key>\n\t\t<integer>511</integer>\n\t\t<key>u1D4D4</key>\n\t\t<integer>657</integer>\n\t\t<key>u1D4D4.cal</key>\n\t\t<integer>460</integer>\n\t\t<key>u1D4D5</key>\n\t\t<integer>719</integer>\n\t\t<key>u1D4D5.cal</key>\n\t\t<integer>474</integer>\n\t\t<key>u1D4D6</key>\n\t\t<integer>667</integer>\n\t\t<key>u1D4D6.cal</key>\n\t\t<integer>481</integer>\n\t\t<key>u1D4D7</key>\n\t\t<integer>787</integer>\n\t\t<key>u1D4D7.cal</key>\n\t\t<integer>502</integer>\n\t\t<key>u1D4D8</key>\n\t\t<integer>726</integer>\n\t\t<key>u1D4D8.cal</key>\n\t\t<integer>418</integer>\n\t\t<key>u1D4D9</key>\n\t\t<integer>631</integer>\n\t\t<key>u1D4D9.cal</key>\n\t\t<integer>622</integer>\n\t\t<key>u1D4DA</key>\n\t\t<integer>843</integer>\n\t\t<key>u1D4DA.cal</key>\n\t\t<integer>516</integer>\n\t\t<key>u1D4DB</key>\n\t\t<integer>906</integer>\n\t\t<key>u1D4DB.cal</key>\n\t\t<integer>493</integer>\n\t\t<key>u1D4DC</key>\n\t\t<integer>1006</integer>\n\t\t<key>u1D4DC.cal</key>\n\t\t<integer>707</integer>\n\t\t<key>u1D4DD</key>\n\t\t<integer>827</integer>\n\t\t<key>u1D4DD.cal</key>\n\t\t<integer>654</integer>\n\t\t<key>u1D4DE</key>\n\t\t<integer>562</integer>\n\t\t<key>u1D4DE.cal</key>\n\t\t<integer>482</integer>\n\t\t<key>u1D4DF</key>\n\t\t<integer>816</integer>\n\t\t<key>u1D4DF.cal</key>\n\t\t<integer>462</integer>\n\t\t<key>u1D4E0</key>\n\t\t<integer>562</integer>\n\t\t<key>u1D4E0.cal</key>\n\t\t<integer>473</integer>\n\t\t<key>u1D4E1</key>\n\t\t<integer>816</integer>\n\t\t<key>u1D4E1.cal</key>\n\t\t<integer>474</integer>\n\t\t<key>u1D4E2</key>\n\t\t<integer>606</integer>\n\t\t<key>u1D4E2.cal</key>\n\t\t<integer>487</integer>\n\t\t<key>u1D4E3</key>\n\t\t<integer>715</integer>\n\t\t<key>u1D4E3.cal</key>\n\t\t<integer>411</integer>\n\t\t<key>u1D4E4</key>\n\t\t<integer>624</integer>\n\t\t<key>u1D4E4.cal</key>\n\t\t<integer>549</integer>\n\t\t<key>u1D4E5</key>\n\t\t<integer>722</integer>\n\t\t<key>u1D4E5.cal</key>\n\t\t<integer>438</integer>\n\t\t<key>u1D4E6</key>\n\t\t<integer>936</integer>\n\t\t<key>u1D4E6.cal</key>\n\t\t<integer>580</integer>\n\t\t<key>u1D4E7</key>\n\t\t<integer>666</integer>\n\t\t<key>u1D4E7.cal</key>\n\t\t<integer>534</integer>\n\t\t<key>u1D4E8</key>\n\t\t<integer>634</integer>\n\t\t<key>u1D4E8.cal</key>\n\t\t<integer>522</integer>\n\t\t<key>u1D4E9</key>\n\t\t<integer>676</integer>\n\t\t<key>u1D4E9.cal</key>\n\t\t<integer>513</integer>\n\t\t<key>u1D4EA</key>\n\t\t<integer>585</integer>\n\t\t<key>u1D4EB</key>\n\t\t<integer>525</integer>\n\t\t<key>u1D4EC</key>\n\t\t<integer>560</integer>\n\t\t<key>u1D4ED</key>\n\t\t<integer>848</integer>\n\t\t<key>u1D4EE</key>\n\t\t<integer>523</integer>\n\t\t<key>u1D4EF</key>\n\t\t<integer>642</integer>\n\t\t<key>u1D4F0</key>\n\t\t<integer>557</integer>\n\t\t<key>u1D4F1</key>\n\t\t<integer>557</integer>\n\t\t<key>u1D4F2</key>\n\t\t<integer>469</integer>\n\t\t<key>u1D4F2.dtls</key>\n\t\t<integer>354</integer>\n\t\t<key>u1D4F3</key>\n\t\t<integer>758</integer>\n\t\t<key>u1D4F3.dtls</key>\n\t\t<integer>651</integer>\n\t\t<key>u1D4F4</key>\n\t\t<integer>555</integer>\n\t\t<key>u1D4F5</key>\n\t\t<integer>525</integer>\n\t\t<key>u1D4F6</key>\n\t\t<integer>648</integer>\n\t\t<key>u1D4F7</key>\n\t\t<integer>481</integer>\n\t\t<key>u1D4F8</key>\n\t\t<integer>576</integer>\n\t\t<key>u1D4F9</key>\n\t\t<integer>636</integer>\n\t\t<key>u1D4FA</key>\n\t\t<integer>562</integer>\n\t\t<key>u1D4FB</key>\n\t\t<integer>452</integer>\n\t\t<key>u1D4FC</key>\n\t\t<integer>375</integer>\n\t\t<key>u1D4FD</key>\n\t\t<integer>475</integer>\n\t\t<key>u1D4FE</key>\n\t\t<integer>475</integer>\n\t\t<key>u1D4FF</key>\n\t\t<integer>464</integer>\n\t\t<key>u1D500</key>\n\t\t<integer>622</integer>\n\t\t<key>u1D501</key>\n\t\t<integer>488</integer>\n\t\t<key>u1D502</key>\n\t\t<integer>500</integer>\n\t\t<key>u1D503</key>\n\t\t<integer>391</integer>\n\t\t<key>u1D526.dtls</key>\n\t\t<integer>177</integer>\n\t\t<key>u1D527.dtls</key>\n\t\t<integer>199</integer>\n\t\t<key>u1D538.bi</key>\n\t\t<integer>467</integer>\n\t\t<key>u1D538.it</key>\n\t\t<integer>434</integer>\n\t\t<key>u1D539.bi</key>\n\t\t<integer>496</integer>\n\t\t<key>u1D539.it</key>\n\t\t<integer>476</integer>\n\t\t<key>u1D53B.bi</key>\n\t\t<integer>484</integer>\n\t\t<key>u1D53B.it</key>\n\t\t<integer>460</integer>\n\t\t<key>u1D53C.bi</key>\n\t\t<integer>490</integer>\n\t\t<key>u1D53C.it</key>\n\t\t<integer>470</integer>\n\t\t<key>u1D53D.bi</key>\n\t\t<integer>490</integer>\n\t\t<key>u1D53D.it</key>\n\t\t<integer>471</integer>\n\t\t<key>u1D53E.bi</key>\n\t\t<integer>501</integer>\n\t\t<key>u1D53E.it</key>\n\t\t<integer>498</integer>\n\t\t<key>u1D540.bi</key>\n\t\t<integer>346</integer>\n\t\t<key>u1D540.it</key>\n\t\t<integer>315</integer>\n\t\t<key>u1D541.bi</key>\n\t\t<integer>461</integer>\n\t\t<key>u1D541.it</key>\n\t\t<integer>435</integer>\n\t\t<key>u1D542.bi</key>\n\t\t<integer>522</integer>\n\t\t<key>u1D542.it</key>\n\t\t<integer>503</integer>\n\t\t<key>u1D543.bi</key>\n\t\t<integer>423</integer>\n\t\t<key>u1D543.it</key>\n\t\t<integer>401</integer>\n\t\t<key>u1D544.bi</key>\n\t\t<integer>614</integer>\n\t\t<key>u1D544.it</key>\n\t\t<integer>588</integer>\n\t\t<key>u1D546.bi</key>\n\t\t<integer>514</integer>\n\t\t<key>u1D546.it</key>\n\t\t<integer>504</integer>\n\t\t<key>u1D54A.bi</key>\n\t\t<integer>500</integer>\n\t\t<key>u1D54A.it</key>\n\t\t<integer>440</integer>\n\t\t<key>u1D54B.bi</key>\n\t\t<integer>344</integer>\n\t\t<key>u1D54B.it</key>\n\t\t<integer>373</integer>\n\t\t<key>u1D54C.bi</key>\n\t\t<integer>525</integer>\n\t\t<key>u1D54C.it</key>\n\t\t<integer>504</integer>\n\t\t<key>u1D54D.bi</key>\n\t\t<integer>409</integer>\n\t\t<key>u1D54D.it</key>\n\t\t<integer>397</integer>\n\t\t<key>u1D54E.bi</key>\n\t\t<integer>598</integer>\n\t\t<key>u1D54E.it</key>\n\t\t<integer>581</integer>\n\t\t<key>u1D54F.bi</key>\n\t\t<integer>549</integer>\n\t\t<key>u1D54F.it</key>\n\t\t<integer>503</integer>\n\t\t<key>u1D550.bi</key>\n\t\t<integer>410</integer>\n\t\t<key>u1D550.it</key>\n\t\t<integer>387</integer>\n\t\t<key>u1D552.bi</key>\n\t\t<integer>417</integer>\n\t\t<key>u1D552.it</key>\n\t\t<integer>380</integer>\n\t\t<key>u1D553.bi</key>\n\t\t<integer>426</integer>\n\t\t<key>u1D553.it</key>\n\t\t<integer>392</integer>\n\t\t<key>u1D554.bi</key>\n\t\t<integer>395</integer>\n\t\t<key>u1D554.it</key>\n\t\t<integer>360</integer>\n\t\t<key>u1D555.it</key>\n\t\t<integer>437</integer>\n\t\t<key>u1D556.bi</key>\n\t\t<integer>392</integer>\n\t\t<key>u1D556.it</key>\n\t\t<integer>362</integer>\n\t\t<key>u1D557.bi</key>\n\t\t<integer>431</integer>\n\t\t<key>u1D557.it</key>\n\t\t<integer>373</integer>\n\t\t<key>u1D558.bi</key>\n\t\t<integer>435</integer>\n\t\t<key>u1D558.it</key>\n\t\t<integer>390</integer>\n\t\t<key>u1D559.bi</key>\n\t\t<integer>425</integer>\n\t\t<key>u1D559.it</key>\n\t\t<integer>385</integer>\n\t\t<key>u1D55A.bi</key>\n\t\t<integer>302</integer>\n\t\t<key>u1D55A.dtls</key>\n\t\t<integer>129</integer>\n\t\t<key>u1D55A.it</key>\n\t\t<integer>286</integer>\n\t\t<key>u1D55B.bi</key>\n\t\t<integer>341</integer>\n\t\t<key>u1D55B.dtls</key>\n\t\t<integer>182</integer>\n\t\t<key>u1D55B.it</key>\n\t\t<integer>313</integer>\n\t\t<key>u1D55C.bi</key>\n\t\t<integer>425</integer>\n\t\t<key>u1D55C.it</key>\n\t\t<integer>377</integer>\n\t\t<key>u1D55D.bi</key>\n\t\t<integer>323</integer>\n\t\t<key>u1D55D.it</key>\n\t\t<integer>291</integer>\n\t\t<key>u1D55E.bi</key>\n\t\t<integer>566</integer>\n\t\t<key>u1D55E.it</key>\n\t\t<integer>519</integer>\n\t\t<key>u1D55F.bi</key>\n\t\t<integer>425</integer>\n\t\t<key>u1D55F.it</key>\n\t\t<integer>385</integer>\n\t\t<key>u1D560.bi</key>\n\t\t<integer>354</integer>\n\t\t<key>u1D560.it</key>\n\t\t<integer>314</integer>\n\t\t<key>u1D561.bi</key>\n\t\t<integer>424</integer>\n\t\t<key>u1D561.it</key>\n\t\t<integer>396</integer>\n\t\t<key>u1D562.bi</key>\n\t\t<integer>437</integer>\n\t\t<key>u1D562.it</key>\n\t\t<integer>407</integer>\n\t\t<key>u1D563.bi</key>\n\t\t<integer>385</integer>\n\t\t<key>u1D563.it</key>\n\t\t<integer>347</integer>\n\t\t<key>u1D564.bi</key>\n\t\t<integer>376</integer>\n\t\t<key>u1D564.it</key>\n\t\t<integer>351</integer>\n\t\t<key>u1D565.bi</key>\n\t\t<integer>322</integer>\n\t\t<key>u1D565.it</key>\n\t\t<integer>274</integer>\n\t\t<key>u1D566.bi</key>\n\t\t<integer>436</integer>\n\t\t<key>u1D566.it</key>\n\t\t<integer>343</integer>\n\t\t<key>u1D567.bi</key>\n\t\t<integer>319</integer>\n\t\t<key>u1D567.it</key>\n\t\t<integer>300</integer>\n\t\t<key>u1D568.bi</key>\n\t\t<integer>446</integer>\n\t\t<key>u1D568.it</key>\n\t\t<integer>403</integer>\n\t\t<key>u1D569.bi</key>\n\t\t<integer>356</integer>\n\t\t<key>u1D569.it</key>\n\t\t<integer>348</integer>\n\t\t<key>u1D56A.bi</key>\n\t\t<integer>417</integer>\n\t\t<key>u1D56A.it</key>\n\t\t<integer>343</integer>\n\t\t<key>u1D56B.bi</key>\n\t\t<integer>414</integer>\n\t\t<key>u1D56B.it</key>\n\t\t<integer>375</integer>\n\t\t<key>u1D58E.dtls</key>\n\t\t<integer>199</integer>\n\t\t<key>u1D58F.dtls</key>\n\t\t<integer>206</integer>\n\t\t<key>u1D5A0</key>\n\t\t<integer>333</integer>\n\t\t<key>u1D5A1</key>\n\t\t<integer>250</integer>\n\t\t<key>u1D5A2</key>\n\t\t<integer>364</integer>\n\t\t<key>u1D5A3</key>\n\t\t<integer>365</integer>\n\t\t<key>u1D5A4</key>\n\t\t<integer>307</integer>\n\t\t<key>u1D5A5</key>\n\t\t<integer>298</integer>\n\t\t<key>u1D5A6</key>\n\t\t<integer>371</integer>\n\t\t<key>u1D5A7</key>\n\t\t<integer>329</integer>\n\t\t<key>u1D5A8</key>\n\t\t<integer>200</integer>\n\t\t<key>u1D5A9</key>\n\t\t<integer>264</integer>\n\t\t<key>u1D5AA</key>\n\t\t<integer>280</integer>\n\t\t<key>u1D5AB</key>\n\t\t<integer>318</integer>\n\t\t<key>u1D5AC</key>\n\t\t<integer>421</integer>\n\t\t<key>u1D5AD</key>\n\t\t<integer>337</integer>\n\t\t<key>u1D5AE</key>\n\t\t<integer>357</integer>\n\t\t<key>u1D5AF</key>\n\t\t<integer>261</integer>\n\t\t<key>u1D5B0</key>\n\t\t<integer>360</integer>\n\t\t<key>u1D5B1</key>\n\t\t<integer>261</integer>\n\t\t<key>u1D5B2</key>\n\t\t<integer>256</integer>\n\t\t<key>u1D5B3</key>\n\t\t<integer>304</integer>\n\t\t<key>u1D5B4</key>\n\t\t<integer>330</integer>\n\t\t<key>u1D5B5</key>\n\t\t<integer>327</integer>\n\t\t<key>u1D5B6</key>\n\t\t<integer>460</integer>\n\t\t<key>u1D5B7</key>\n\t\t<integer>350</integer>\n\t\t<key>u1D5B8</key>\n\t\t<integer>315</integer>\n\t\t<key>u1D5B9</key>\n\t\t<integer>315</integer>\n\t\t<key>u1D5BA</key>\n\t\t<integer>213</integer>\n\t\t<key>u1D5BB</key>\n\t\t<integer>264</integer>\n\t\t<key>u1D5BC</key>\n\t\t<integer>227</integer>\n\t\t<key>u1D5BD</key>\n\t\t<integer>232</integer>\n\t\t<key>u1D5BE</key>\n\t\t<integer>225</integer>\n\t\t<key>u1D5BF</key>\n\t\t<integer>244</integer>\n\t\t<key>u1D5C0</key>\n\t\t<integer>244</integer>\n\t\t<key>u1D5C1</key>\n\t\t<integer>243</integer>\n\t\t<key>u1D5C2</key>\n\t\t<integer>110</integer>\n\t\t<key>u1D5C2.dtls</key>\n\t\t<integer>110</integer>\n\t\t<key>u1D5C3</key>\n\t\t<integer>141</integer>\n\t\t<key>u1D5C3.dtls</key>\n\t\t<integer>139</integer>\n\t\t<key>u1D5C4</key>\n\t\t<integer>257</integer>\n\t\t<key>u1D5C5</key>\n\t\t<integer>102</integer>\n\t\t<key>u1D5C6</key>\n\t\t<integer>378</integer>\n\t\t<key>u1D5C7</key>\n\t\t<integer>243</integer>\n\t\t<key>u1D5C8</key>\n\t\t<integer>249</integer>\n\t\t<key>u1D5C9</key>\n\t\t<integer>268</integer>\n\t\t<key>u1D5CA</key>\n\t\t<integer>231</integer>\n\t\t<key>u1D5CB</key>\n\t\t<integer>195</integer>\n\t\t<key>u1D5CC</key>\n\t\t<integer>199</integer>\n\t\t<key>u1D5CD</key>\n\t\t<integer>124</integer>\n\t\t<key>u1D5CE</key>\n\t\t<integer>246</integer>\n\t\t<key>u1D5CF</key>\n\t\t<integer>237</integer>\n\t\t<key>u1D5D0</key>\n\t\t<integer>351</integer>\n\t\t<key>u1D5D1</key>\n\t\t<integer>241</integer>\n\t\t<key>u1D5D2</key>\n\t\t<integer>260</integer>\n\t\t<key>u1D5D3</key>\n\t\t<integer>221</integer>\n\t\t<key>u1D5D4</key>\n\t\t<integer>345</integer>\n\t\t<key>u1D5D5</key>\n\t\t<integer>273</integer>\n\t\t<key>u1D5D6</key>\n\t\t<integer>368</integer>\n\t\t<key>u1D5D7</key>\n\t\t<integer>377</integer>\n\t\t<key>u1D5D8</key>\n\t\t<integer>338</integer>\n\t\t<key>u1D5D9</key>\n\t\t<integer>325</integer>\n\t\t<key>u1D5DA</key>\n\t\t<integer>392</integer>\n\t\t<key>u1D5DB</key>\n\t\t<integer>357</integer>\n\t\t<key>u1D5DC</key>\n\t\t<integer>220</integer>\n\t\t<key>u1D5DD</key>\n\t\t<integer>344</integer>\n\t\t<key>u1D5DE</key>\n\t\t<integer>333</integer>\n\t\t<key>u1D5DF</key>\n\t\t<integer>333</integer>\n\t\t<key>u1D5E0</key>\n\t\t<integer>456</integer>\n\t\t<key>u1D5E1</key>\n\t\t<integer>362</integer>\n\t\t<key>u1D5E2</key>\n\t\t<integer>389</integer>\n\t\t<key>u1D5E3</key>\n\t\t<integer>290</integer>\n\t\t<key>u1D5E4</key>\n\t\t<integer>394</integer>\n\t\t<key>u1D5E5</key>\n\t\t<integer>298</integer>\n\t\t<key>u1D5E6</key>\n\t\t<integer>273</integer>\n\t\t<key>u1D5E7</key>\n\t\t<integer>320</integer>\n\t\t<key>u1D5E8</key>\n\t\t<integer>349</integer>\n\t\t<key>u1D5E9</key>\n\t\t<integer>345</integer>\n\t\t<key>u1D5EA</key>\n\t\t<integer>498</integer>\n\t\t<key>u1D5EB</key>\n\t\t<integer>370</integer>\n\t\t<key>u1D5EC</key>\n\t\t<integer>347</integer>\n\t\t<key>u1D5ED</key>\n\t\t<integer>324</integer>\n\t\t<key>u1D5EE</key>\n\t\t<integer>225</integer>\n\t\t<key>u1D5EF</key>\n\t\t<integer>271</integer>\n\t\t<key>u1D5F0</key>\n\t\t<integer>233</integer>\n\t\t<key>u1D5F1</key>\n\t\t<integer>244</integer>\n\t\t<key>u1D5F2</key>\n\t\t<integer>229</integer>\n\t\t<key>u1D5F3</key>\n\t\t<integer>242</integer>\n\t\t<key>u1D5F4</key>\n\t\t<integer>259</integer>\n\t\t<key>u1D5F5</key>\n\t\t<integer>255</integer>\n\t\t<key>u1D5F6</key>\n\t\t<integer>122</integer>\n\t\t<key>u1D5F6.dtls</key>\n\t\t<integer>122</integer>\n\t\t<key>u1D5F7</key>\n\t\t<integer>106</integer>\n\t\t<key>u1D5F7.dtls</key>\n\t\t<integer>195</integer>\n\t\t<key>u1D5F8</key>\n\t\t<integer>280</integer>\n\t\t<key>u1D5F9</key>\n\t\t<integer>117</integer>\n\t\t<key>u1D5FA</key>\n\t\t<integer>388</integer>\n\t\t<key>u1D5FB</key>\n\t\t<integer>255</integer>\n\t\t<key>u1D5FC</key>\n\t\t<integer>250</integer>\n\t\t<key>u1D5FD</key>\n\t\t<integer>271</integer>\n\t\t<key>u1D5FE</key>\n\t\t<integer>241</integer>\n\t\t<key>u1D5FF</key>\n\t\t<integer>230</integer>\n\t\t<key>u1D600</key>\n\t\t<integer>191</integer>\n\t\t<key>u1D601</key>\n\t\t<integer>189</integer>\n\t\t<key>u1D602</key>\n\t\t<integer>259</integer>\n\t\t<key>u1D603</key>\n\t\t<integer>231</integer>\n\t\t<key>u1D604</key>\n\t\t<integer>350</integer>\n\t\t<key>u1D605</key>\n\t\t<integer>253</integer>\n\t\t<key>u1D606</key>\n\t\t<integer>236</integer>\n\t\t<key>u1D607</key>\n\t\t<integer>219</integer>\n\t\t<key>u1D608</key>\n\t\t<integer>499</integer>\n\t\t<key>u1D609</key>\n\t\t<integer>436</integer>\n\t\t<key>u1D60A</key>\n\t\t<integer>536</integer>\n\t\t<key>u1D60B</key>\n\t\t<integer>412</integer>\n\t\t<key>u1D60C</key>\n\t\t<integer>470</integer>\n\t\t<key>u1D60D</key>\n\t\t<integer>472</integer>\n\t\t<key>u1D60E</key>\n\t\t<integer>544</integer>\n\t\t<key>u1D60F</key>\n\t\t<integer>472</integer>\n\t\t<key>u1D610</key>\n\t\t<integer>352</integer>\n\t\t<key>u1D611</key>\n\t\t<integer>424</integer>\n\t\t<key>u1D612</key>\n\t\t<integer>468</integer>\n\t\t<key>u1D613</key>\n\t\t<integer>430</integer>\n\t\t<key>u1D614</key>\n\t\t<integer>584</integer>\n\t\t<key>u1D615</key>\n\t\t<integer>526</integer>\n\t\t<key>u1D616</key>\n\t\t<integer>527</integer>\n\t\t<key>u1D617</key>\n\t\t<integer>436</integer>\n\t\t<key>u1D618</key>\n\t\t<integer>525</integer>\n\t\t<key>u1D619</key>\n\t\t<integer>420</integer>\n\t\t<key>u1D61A</key>\n\t\t<integer>426</integer>\n\t\t<key>u1D61B</key>\n\t\t<integer>454</integer>\n\t\t<key>u1D61C</key>\n\t\t<integer>489</integer>\n\t\t<key>u1D61D</key>\n\t\t<integer>492</integer>\n\t\t<key>u1D61E</key>\n\t\t<integer>626</integer>\n\t\t<key>u1D61F</key>\n\t\t<integer>510</integer>\n\t\t<key>u1D620</key>\n\t\t<integer>480</integer>\n\t\t<key>u1D621</key>\n\t\t<integer>486</integer>\n\t\t<key>u1D622</key>\n\t\t<integer>333</integer>\n\t\t<key>u1D623</key>\n\t\t<integer>304</integer>\n\t\t<key>u1D624</key>\n\t\t<integer>355</integer>\n\t\t<key>u1D625</key>\n\t\t<integer>458</integer>\n\t\t<key>u1D626</key>\n\t\t<integer>350</integer>\n\t\t<key>u1D627</key>\n\t\t<integer>414</integer>\n\t\t<key>u1D628</key>\n\t\t<integer>352</integer>\n\t\t<key>u1D629</key>\n\t\t<integer>286</integer>\n\t\t<key>u1D62A</key>\n\t\t<integer>268</integer>\n\t\t<key>u1D62A.dtls</key>\n\t\t<integer>219</integer>\n\t\t<key>u1D62B</key>\n\t\t<integer>303</integer>\n\t\t<key>u1D62B.dtls</key>\n\t\t<integer>244</integer>\n\t\t<key>u1D62C</key>\n\t\t<integer>309</integer>\n\t\t<key>u1D62D</key>\n\t\t<integer>268</integer>\n\t\t<key>u1D62E</key>\n\t\t<integer>512</integer>\n\t\t<key>u1D62F</key>\n\t\t<integer>360</integer>\n\t\t<key>u1D630</key>\n\t\t<integer>360</integer>\n\t\t<key>u1D631</key>\n\t\t<integer>396</integer>\n\t\t<key>u1D632</key>\n\t\t<integer>360</integer>\n\t\t<key>u1D633</key>\n\t\t<integer>335</integer>\n\t\t<key>u1D634</key>\n\t\t<integer>310</integer>\n\t\t<key>u1D635</key>\n\t\t<integer>278</integer>\n\t\t<key>u1D636</key>\n\t\t<integer>346</integer>\n\t\t<key>u1D637</key>\n\t\t<integer>349</integer>\n\t\t<key>u1D638</key>\n\t\t<integer>439</integer>\n\t\t<key>u1D639</key>\n\t\t<integer>343</integer>\n\t\t<key>u1D63A</key>\n\t\t<integer>355</integer>\n\t\t<key>u1D63B</key>\n\t\t<integer>351</integer>\n\t\t<key>u1D63C</key>\n\t\t<integer>517</integer>\n\t\t<key>u1D63D</key>\n\t\t<integer>468</integer>\n\t\t<key>u1D63E</key>\n\t\t<integer>570</integer>\n\t\t<key>u1D63F</key>\n\t\t<integer>494</integer>\n\t\t<key>u1D640</key>\n\t\t<integer>496</integer>\n\t\t<key>u1D641</key>\n\t\t<integer>504</integer>\n\t\t<key>u1D642</key>\n\t\t<integer>564</integer>\n\t\t<key>u1D643</key>\n\t\t<integer>524</integer>\n\t\t<key>u1D644</key>\n\t\t<integer>408</integer>\n\t\t<key>u1D645</key>\n\t\t<integer>506</integer>\n\t\t<key>u1D646</key>\n\t\t<integer>512</integer>\n\t\t<key>u1D647</key>\n\t\t<integer>440</integer>\n\t\t<key>u1D648</key>\n\t\t<integer>620</integer>\n\t\t<key>u1D649</key>\n\t\t<integer>548</integer>\n\t\t<key>u1D64A</key>\n\t\t<integer>561</integer>\n\t\t<key>u1D64B</key>\n\t\t<integer>458</integer>\n\t\t<key>u1D64C</key>\n\t\t<integer>562</integer>\n\t\t<key>u1D64D</key>\n\t\t<integer>467</integer>\n\t\t<key>u1D64E</key>\n\t\t<integer>444</integer>\n\t\t<key>u1D64F</key>\n\t\t<integer>507</integer>\n\t\t<key>u1D650</key>\n\t\t<integer>522</integer>\n\t\t<key>u1D651</key>\n\t\t<integer>513</integer>\n\t\t<key>u1D652</key>\n\t\t<integer>666</integer>\n\t\t<key>u1D653</key>\n\t\t<integer>536</integer>\n\t\t<key>u1D654</key>\n\t\t<integer>515</integer>\n\t\t<key>u1D655</key>\n\t\t<integer>531</integer>\n\t\t<key>u1D656</key>\n\t\t<integer>353</integer>\n\t\t<key>u1D657</key>\n\t\t<integer>304</integer>\n\t\t<key>u1D658</key>\n\t\t<integer>371</integer>\n\t\t<key>u1D659</key>\n\t\t<integer>443</integer>\n\t\t<key>u1D65A</key>\n\t\t<integer>355</integer>\n\t\t<key>u1D65B</key>\n\t\t<integer>412</integer>\n\t\t<key>u1D65C</key>\n\t\t<integer>372</integer>\n\t\t<key>u1D65D</key>\n\t\t<integer>298</integer>\n\t\t<key>u1D65E</key>\n\t\t<integer>284</integer>\n\t\t<key>u1D65E.dtls</key>\n\t\t<integer>233</integer>\n\t\t<key>u1D65F</key>\n\t\t<integer>351</integer>\n\t\t<key>u1D65F.dtls</key>\n\t\t<integer>306</integer>\n\t\t<key>u1D660</key>\n\t\t<integer>327</integer>\n\t\t<key>u1D661</key>\n\t\t<integer>263</integer>\n\t\t<key>u1D662</key>\n\t\t<integer>534</integer>\n\t\t<key>u1D663</key>\n\t\t<integer>362</integer>\n\t\t<key>u1D664</key>\n\t\t<integer>371</integer>\n\t\t<key>u1D665</key>\n\t\t<integer>367</integer>\n\t\t<key>u1D666</key>\n\t\t<integer>359</integer>\n\t\t<key>u1D667</key>\n\t\t<integer>373</integer>\n\t\t<key>u1D668</key>\n\t\t<integer>311</integer>\n\t\t<key>u1D669</key>\n\t\t<integer>332</integer>\n\t\t<key>u1D66A</key>\n\t\t<integer>367</integer>\n\t\t<key>u1D66B</key>\n\t\t<integer>345</integer>\n\t\t<key>u1D66C</key>\n\t\t<integer>464</integer>\n\t\t<key>u1D66D</key>\n\t\t<integer>361</integer>\n\t\t<key>u1D66E</key>\n\t\t<integer>349</integer>\n\t\t<key>u1D66F</key>\n\t\t<integer>347</integer>\n\t\t<key>u1D670</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D671</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D672</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D673</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D674</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D675</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D676</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D677</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D678</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D679</key>\n\t\t<integer>360</integer>\n\t\t<key>u1D67A</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D67B</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D67C</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D67D</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D67E</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D67F</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D680</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D681</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D682</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D683</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D684</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D685</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D686</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D687</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D688</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D689</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D68A</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D68B</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D68C</key>\n\t\t<integer>308</integer>\n\t\t<key>u1D68D</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D68E</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D68F</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D690</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D691</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D692</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D692.dtls</key>\n\t\t<integer>206</integer>\n\t\t<key>u1D693</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D693.dtls</key>\n\t\t<integer>253</integer>\n\t\t<key>u1D694</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D695</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D696</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D697</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D698</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D699</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D69A</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D69B</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D69C</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D69D</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D69E</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D69F</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D6A0</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D6A1</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D6A2</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D6A3</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D6A4</key>\n\t\t<integer>179</integer>\n\t\t<key>u1D6A5</key>\n\t\t<integer>193</integer>\n\t\t<key>u1D6A8</key>\n\t\t<integer>343</integer>\n\t\t<key>u1D6A9</key>\n\t\t<integer>318</integer>\n\t\t<key>u1D6AA</key>\n\t\t<integer>304</integer>\n\t\t<key>u1D6AB</key>\n\t\t<integer>326</integer>\n\t\t<key>u1D6AC</key>\n\t\t<integer>328</integer>\n\t\t<key>u1D6AD</key>\n\t\t<integer>331</integer>\n\t\t<key>u1D6AE</key>\n\t\t<integer>390</integer>\n\t\t<key>u1D6AF</key>\n\t\t<integer>389</integer>\n\t\t<key>u1D6B0</key>\n\t\t<integer>195</integer>\n\t\t<key>u1D6B1</key>\n\t\t<integer>410</integer>\n\t\t<key>u1D6B2</key>\n\t\t<integer>336</integer>\n\t\t<key>u1D6B3</key>\n\t\t<integer>468</integer>\n\t\t<key>u1D6B4</key>\n\t\t<integer>358</integer>\n\t\t<key>u1D6B5</key>\n\t\t<integer>312</integer>\n\t\t<key>u1D6B6</key>\n\t\t<integer>389</integer>\n\t\t<key>u1D6B7</key>\n\t\t<integer>390</integer>\n\t\t<key>u1D6B8</key>\n\t\t<integer>308</integer>\n\t\t<key>u1D6B9</key>\n\t\t<integer>389</integer>\n\t\t<key>u1D6BA</key>\n\t\t<integer>320</integer>\n\t\t<key>u1D6BB</key>\n\t\t<integer>334</integer>\n\t\t<key>u1D6BC</key>\n\t\t<integer>403</integer>\n\t\t<key>u1D6BD</key>\n\t\t<integer>418</integer>\n\t\t<key>u1D6BE</key>\n\t\t<integer>400</integer>\n\t\t<key>u1D6BF</key>\n\t\t<integer>394</integer>\n\t\t<key>u1D6C0</key>\n\t\t<integer>379</integer>\n\t\t<key>u1D6C1</key>\n\t\t<integer>336</integer>\n\t\t<key>u1D6C2</key>\n\t\t<integer>256</integer>\n\t\t<key>u1D6C3</key>\n\t\t<integer>284</integer>\n\t\t<key>u1D6C4</key>\n\t\t<integer>256</integer>\n\t\t<key>u1D6C5</key>\n\t\t<integer>252</integer>\n\t\t<key>u1D6C6</key>\n\t\t<integer>228</integer>\n\t\t<key>u1D6C7</key>\n\t\t<integer>230</integer>\n\t\t<key>u1D6C8</key>\n\t\t<integer>278</integer>\n\t\t<key>u1D6C9</key>\n\t\t<integer>250</integer>\n\t\t<key>u1D6CA</key>\n\t\t<integer>136</integer>\n\t\t<key>u1D6CB</key>\n\t\t<integer>290</integer>\n\t\t<key>u1D6CC</key>\n\t\t<integer>141</integer>\n\t\t<key>u1D6CD</key>\n\t\t<integer>282</integer>\n\t\t<key>u1D6CE</key>\n\t\t<integer>255</integer>\n\t\t<key>u1D6CF</key>\n\t\t<integer>231</integer>\n\t\t<key>u1D6D0</key>\n\t\t<integer>250</integer>\n\t\t<key>u1D6D1</key>\n\t\t<integer>314</integer>\n\t\t<key>u1D6D2</key>\n\t\t<integer>280</integer>\n\t\t<key>u1D6D3</key>\n\t\t<integer>234</integer>\n\t\t<key>u1D6D4</key>\n\t\t<integer>277</integer>\n\t\t<key>u1D6D5</key>\n\t\t<integer>238</integer>\n\t\t<key>u1D6D6</key>\n\t\t<integer>282</integer>\n\t\t<key>u1D6D7</key>\n\t\t<integer>326</integer>\n\t\t<key>u1D6D8</key>\n\t\t<integer>304</integer>\n\t\t<key>u1D6D9</key>\n\t\t<integer>382</integer>\n\t\t<key>u1D6DA</key>\n\t\t<integer>367</integer>\n\t\t<key>u1D6DB</key>\n\t\t<integer>258</integer>\n\t\t<key>u1D6DC</key>\n\t\t<integer>228</integer>\n\t\t<key>u1D6DD</key>\n\t\t<integer>316</integer>\n\t\t<key>u1D6DE</key>\n\t\t<integer>279</integer>\n\t\t<key>u1D6DF</key>\n\t\t<integer>326</integer>\n\t\t<key>u1D6E0</key>\n\t\t<integer>256</integer>\n\t\t<key>u1D6E1</key>\n\t\t<integer>476</integer>\n\t\t<key>u1D6E2</key>\n\t\t<integer>508</integer>\n\t\t<key>u1D6E2.ss</key>\n\t\t<integer>499</integer>\n\t\t<key>u1D6E3</key>\n\t\t<integer>464</integer>\n\t\t<key>u1D6E3.ss</key>\n\t\t<integer>436</integer>\n\t\t<key>u1D6E4</key>\n\t\t<integer>492</integer>\n\t\t<key>u1D6E4.ss</key>\n\t\t<integer>443</integer>\n\t\t<key>u1D6E5</key>\n\t\t<integer>453</integer>\n\t\t<key>u1D6E5.ss</key>\n\t\t<integer>498</integer>\n\t\t<key>u1D6E6</key>\n\t\t<integer>492</integer>\n\t\t<key>u1D6E6.ss</key>\n\t\t<integer>470</integer>\n\t\t<key>u1D6E7</key>\n\t\t<integer>503</integer>\n\t\t<key>u1D6E7.ss</key>\n\t\t<integer>486</integer>\n\t\t<key>u1D6E8</key>\n\t\t<integer>560</integer>\n\t\t<key>u1D6E8.ss</key>\n\t\t<integer>472</integer>\n\t\t<key>u1D6E9</key>\n\t\t<integer>463</integer>\n\t\t<key>u1D6E9.ss</key>\n\t\t<integer>490</integer>\n\t\t<key>u1D6EA</key>\n\t\t<integer>360</integer>\n\t\t<key>u1D6EA.ss</key>\n\t\t<integer>352</integer>\n\t\t<key>u1D6EB</key>\n\t\t<integer>540</integer>\n\t\t<key>u1D6EB.ss</key>\n\t\t<integer>468</integer>\n\t\t<key>u1D6EC</key>\n\t\t<integer>510</integer>\n\t\t<key>u1D6EC.ss</key>\n\t\t<integer>492</integer>\n\t\t<key>u1D6ED</key>\n\t\t<integer>614</integer>\n\t\t<key>u1D6ED.ss</key>\n\t\t<integer>584</integer>\n\t\t<key>u1D6EE</key>\n\t\t<integer>538</integer>\n\t\t<key>u1D6EE.ss</key>\n\t\t<integer>526</integer>\n\t\t<key>u1D6EF</key>\n\t\t<integer>476</integer>\n\t\t<key>u1D6EF.ss</key>\n\t\t<integer>495</integer>\n\t\t<key>u1D6F0</key>\n\t\t<integer>465</integer>\n\t\t<key>u1D6F0.ss</key>\n\t\t<integer>490</integer>\n\t\t<key>u1D6F1</key>\n\t\t<integer>554</integer>\n\t\t<key>u1D6F1.ss</key>\n\t\t<integer>504</integer>\n\t\t<key>u1D6F2</key>\n\t\t<integer>477</integer>\n\t\t<key>u1D6F2.ss</key>\n\t\t<integer>436</integer>\n\t\t<key>u1D6F3</key>\n\t\t<integer>465</integer>\n\t\t<key>u1D6F3.ss</key>\n\t\t<integer>490</integer>\n\t\t<key>u1D6F4</key>\n\t\t<integer>509</integer>\n\t\t<key>u1D6F4.ss</key>\n\t\t<integer>463</integer>\n\t\t<key>u1D6F5</key>\n\t\t<integer>348</integer>\n\t\t<key>u1D6F5.ss</key>\n\t\t<integer>392</integer>\n\t\t<key>u1D6F6</key>\n\t\t<integer>358</integer>\n\t\t<key>u1D6F6.ss</key>\n\t\t<integer>396</integer>\n\t\t<key>u1D6F7</key>\n\t\t<integer>464</integer>\n\t\t<key>u1D6F7.ss</key>\n\t\t<integer>486</integer>\n\t\t<key>u1D6F8</key>\n\t\t<integer>530</integer>\n\t\t<key>u1D6F8.ss</key>\n\t\t<integer>510</integer>\n\t\t<key>u1D6F9</key>\n\t\t<integer>386</integer>\n\t\t<key>u1D6F9.ss</key>\n\t\t<integer>456</integer>\n\t\t<key>u1D6FA</key>\n\t\t<integer>546</integer>\n\t\t<key>u1D6FA.ss</key>\n\t\t<integer>539</integer>\n\t\t<key>u1D6FB</key>\n\t\t<integer>321</integer>\n\t\t<key>u1D6FC</key>\n\t\t<integer>284</integer>\n\t\t<key>u1D6FC.ss</key>\n\t\t<integer>393</integer>\n\t\t<key>u1D6FD</key>\n\t\t<integer>424</integer>\n\t\t<key>u1D6FD.ss</key>\n\t\t<integer>427</integer>\n\t\t<key>u1D6FE</key>\n\t\t<integer>246</integer>\n\t\t<key>u1D6FE.ss</key>\n\t\t<integer>351</integer>\n\t\t<key>u1D6FF</key>\n\t\t<integer>342</integer>\n\t\t<key>u1D6FF.ss</key>\n\t\t<integer>376</integer>\n\t\t<key>u1D700</key>\n\t\t<integer>291</integer>\n\t\t<key>u1D700.ss</key>\n\t\t<integer>347</integer>\n\t\t<key>u1D701</key>\n\t\t<integer>334</integer>\n\t\t<key>u1D701.ss</key>\n\t\t<integer>336</integer>\n\t\t<key>u1D702</key>\n\t\t<integer>288</integer>\n\t\t<key>u1D702.ss</key>\n\t\t<integer>346</integer>\n\t\t<key>u1D703</key>\n\t\t<integer>323</integer>\n\t\t<key>u1D703.ss</key>\n\t\t<integer>359</integer>\n\t\t<key>u1D704</key>\n\t\t<integer>164</integer>\n\t\t<key>u1D704.ss</key>\n\t\t<integer>248</integer>\n\t\t<key>u1D705</key>\n\t\t<integer>300</integer>\n\t\t<key>u1D705.ss</key>\n\t\t<integer>336</integer>\n\t\t<key>u1D706</key>\n\t\t<integer>348</integer>\n\t\t<key>u1D706.ss</key>\n\t\t<integer>368</integer>\n\t\t<key>u1D707</key>\n\t\t<integer>374</integer>\n\t\t<key>u1D707.ss</key>\n\t\t<integer>380</integer>\n\t\t<key>u1D708</key>\n\t\t<integer>284</integer>\n\t\t<key>u1D708.ss</key>\n\t\t<integer>288</integer>\n\t\t<key>u1D709</key>\n\t\t<integer>308</integer>\n\t\t<key>u1D709.ss</key>\n\t\t<integer>349</integer>\n\t\t<key>u1D70A</key>\n\t\t<integer>293</integer>\n\t\t<key>u1D70A.ss</key>\n\t\t<integer>366</integer>\n\t\t<key>u1D70B</key>\n\t\t<integer>370</integer>\n\t\t<key>u1D70B.ss</key>\n\t\t<integer>382</integer>\n\t\t<key>u1D70C</key>\n\t\t<integer>333</integer>\n\t\t<key>u1D70C.ss</key>\n\t\t<integer>367</integer>\n\t\t<key>u1D70D</key>\n\t\t<integer>250</integer>\n\t\t<key>u1D70D.ss</key>\n\t\t<integer>318</integer>\n\t\t<key>u1D70E</key>\n\t\t<integer>294</integer>\n\t\t<key>u1D70E.ss</key>\n\t\t<integer>403</integer>\n\t\t<key>u1D70F</key>\n\t\t<integer>295</integer>\n\t\t<key>u1D70F.ss</key>\n\t\t<integer>334</integer>\n\t\t<key>u1D710</key>\n\t\t<integer>238</integer>\n\t\t<key>u1D710.ss</key>\n\t\t<integer>357</integer>\n\t\t<key>u1D711</key>\n\t\t<integer>340</integer>\n\t\t<key>u1D711.ss</key>\n\t\t<integer>432</integer>\n\t\t<key>u1D712</key>\n\t\t<integer>438</integer>\n\t\t<key>u1D712.ss</key>\n\t\t<integer>357</integer>\n\t\t<key>u1D713</key>\n\t\t<integer>370</integer>\n\t\t<key>u1D713.ss</key>\n\t\t<integer>427</integer>\n\t\t<key>u1D714</key>\n\t\t<integer>392</integer>\n\t\t<key>u1D714.ss</key>\n\t\t<integer>415</integer>\n\t\t<key>u1D715</key>\n\t\t<integer>314</integer>\n\t\t<key>u1D715.ss</key>\n\t\t<integer>368</integer>\n\t\t<key>u1D716</key>\n\t\t<integer>309</integer>\n\t\t<key>u1D716.ss</key>\n\t\t<integer>331</integer>\n\t\t<key>u1D717</key>\n\t\t<integer>348</integer>\n\t\t<key>u1D717.ss</key>\n\t\t<integer>367</integer>\n\t\t<key>u1D718</key>\n\t\t<integer>300</integer>\n\t\t<key>u1D719</key>\n\t\t<integer>442</integer>\n\t\t<key>u1D719.ss</key>\n\t\t<integer>458</integer>\n\t\t<key>u1D71A</key>\n\t\t<integer>350</integer>\n\t\t<key>u1D71A.ss</key>\n\t\t<integer>368</integer>\n\t\t<key>u1D71B</key>\n\t\t<integer>504</integer>\n\t\t<key>u1D71B.ss</key>\n\t\t<integer>497</integer>\n\t\t<key>u1D71C</key>\n\t\t<integer>518</integer>\n\t\t<key>u1D71D</key>\n\t\t<integer>496</integer>\n\t\t<key>u1D71E</key>\n\t\t<integer>532</integer>\n\t\t<key>u1D71F</key>\n\t\t<integer>464</integer>\n\t\t<key>u1D720</key>\n\t\t<integer>512</integer>\n\t\t<key>u1D721</key>\n\t\t<integer>518</integer>\n\t\t<key>u1D722</key>\n\t\t<integer>560</integer>\n\t\t<key>u1D723</key>\n\t\t<integer>485</integer>\n\t\t<key>u1D724</key>\n\t\t<integer>366</integer>\n\t\t<key>u1D725</key>\n\t\t<integer>558</integer>\n\t\t<key>u1D726</key>\n\t\t<integer>520</integer>\n\t\t<key>u1D727</key>\n\t\t<integer>632</integer>\n\t\t<key>u1D728</key>\n\t\t<integer>523</integer>\n\t\t<key>u1D729</key>\n\t\t<integer>495</integer>\n\t\t<key>u1D72A</key>\n\t\t<integer>483</integer>\n\t\t<key>u1D72B</key>\n\t\t<integer>558</integer>\n\t\t<key>u1D72C</key>\n\t\t<integer>526</integer>\n\t\t<key>u1D72D</key>\n\t\t<integer>485</integer>\n\t\t<key>u1D72E</key>\n\t\t<integer>526</integer>\n\t\t<key>u1D72F</key>\n\t\t<integer>364</integer>\n\t\t<key>u1D730</key>\n\t\t<integer>376</integer>\n\t\t<key>u1D731</key>\n\t\t<integer>482</integer>\n\t\t<key>u1D732</key>\n\t\t<integer>535</integer>\n\t\t<key>u1D733</key>\n\t\t<integer>406</integer>\n\t\t<key>u1D734</key>\n\t\t<integer>548</integer>\n\t\t<key>u1D735</key>\n\t\t<integer>322</integer>\n\t\t<key>u1D736</key>\n\t\t<integer>337</integer>\n\t\t<key>u1D737</key>\n\t\t<integer>462</integer>\n\t\t<key>u1D738</key>\n\t\t<integer>274</integer>\n\t\t<key>u1D739</key>\n\t\t<integer>369</integer>\n\t\t<key>u1D73A</key>\n\t\t<integer>280</integer>\n\t\t<key>u1D73B</key>\n\t\t<integer>369</integer>\n\t\t<key>u1D73C</key>\n\t\t<integer>336</integer>\n\t\t<key>u1D73D</key>\n\t\t<integer>378</integer>\n\t\t<key>u1D73E</key>\n\t\t<integer>164</integer>\n\t\t<key>u1D73F</key>\n\t\t<integer>316</integer>\n\t\t<key>u1D740</key>\n\t\t<integer>346</integer>\n\t\t<key>u1D741</key>\n\t\t<integer>404</integer>\n\t\t<key>u1D742</key>\n\t\t<integer>372</integer>\n\t\t<key>u1D743</key>\n\t\t<integer>348</integer>\n\t\t<key>u1D744</key>\n\t\t<integer>340</integer>\n\t\t<key>u1D745</key>\n\t\t<integer>384</integer>\n\t\t<key>u1D746</key>\n\t\t<integer>398</integer>\n\t\t<key>u1D747</key>\n\t\t<integer>404</integer>\n\t\t<key>u1D748</key>\n\t\t<integer>324</integer>\n\t\t<key>u1D749</key>\n\t\t<integer>308</integer>\n\t\t<key>u1D74A</key>\n\t\t<integer>284</integer>\n\t\t<key>u1D74B</key>\n\t\t<integer>429</integer>\n\t\t<key>u1D74C</key>\n\t\t<integer>444</integer>\n\t\t<key>u1D74D</key>\n\t\t<integer>394</integer>\n\t\t<key>u1D74E</key>\n\t\t<integer>398</integer>\n\t\t<key>u1D74F</key>\n\t\t<integer>404</integer>\n\t\t<key>u1D750</key>\n\t\t<integer>326</integer>\n\t\t<key>u1D751</key>\n\t\t<integer>398</integer>\n\t\t<key>u1D752</key>\n\t\t<integer>309</integer>\n\t\t<key>u1D753</key>\n\t\t<integer>454</integer>\n\t\t<key>u1D754</key>\n\t\t<integer>370</integer>\n\t\t<key>u1D755</key>\n\t\t<integer>506</integer>\n\t\t<key>u1D790</key>\n\t\t<integer>517</integer>\n\t\t<key>u1D791</key>\n\t\t<integer>468</integer>\n\t\t<key>u1D792</key>\n\t\t<integer>501</integer>\n\t\t<key>u1D793</key>\n\t\t<integer>534</integer>\n\t\t<key>u1D794</key>\n\t\t<integer>496</integer>\n\t\t<key>u1D795</key>\n\t\t<integer>531</integer>\n\t\t<key>u1D796</key>\n\t\t<integer>524</integer>\n\t\t<key>u1D797</key>\n\t\t<integer>559</integer>\n\t\t<key>u1D798</key>\n\t\t<integer>417</integer>\n\t\t<key>u1D799</key>\n\t\t<integer>512</integer>\n\t\t<key>u1D79A</key>\n\t\t<integer>507</integer>\n\t\t<key>u1D79B</key>\n\t\t<integer>620</integer>\n\t\t<key>u1D79C</key>\n\t\t<integer>548</integer>\n\t\t<key>u1D79D</key>\n\t\t<integer>513</integer>\n\t\t<key>u1D79E</key>\n\t\t<integer>561</integer>\n\t\t<key>u1D79F</key>\n\t\t<integer>532</integer>\n\t\t<key>u1D7A0</key>\n\t\t<integer>458</integer>\n\t\t<key>u1D7A1</key>\n\t\t<integer>559</integer>\n\t\t<key>u1D7A2</key>\n\t\t<integer>504</integer>\n\t\t<key>u1D7A3</key>\n\t\t<integer>520</integer>\n\t\t<key>u1D7A4</key>\n\t\t<integer>465</integer>\n\t\t<key>u1D7A5</key>\n\t\t<integer>561</integer>\n\t\t<key>u1D7A6</key>\n\t\t<integer>536</integer>\n\t\t<key>u1D7A7</key>\n\t\t<integer>535</integer>\n\t\t<key>u1D7A8</key>\n\t\t<integer>548</integer>\n\t\t<key>u1D7A9</key>\n\t\t<integer>454</integer>\n\t\t<key>u1D7AA</key>\n\t\t<integer>439</integer>\n\t\t<key>u1D7AB</key>\n\t\t<integer>436</integer>\n\t\t<key>u1D7AC</key>\n\t\t<integer>362</integer>\n\t\t<key>u1D7AD</key>\n\t\t<integer>391</integer>\n\t\t<key>u1D7AE</key>\n\t\t<integer>352</integer>\n\t\t<key>u1D7AF</key>\n\t\t<integer>402</integer>\n\t\t<key>u1D7B0</key>\n\t\t<integer>366</integer>\n\t\t<key>u1D7B1</key>\n\t\t<integer>380</integer>\n\t\t<key>u1D7B2</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D7B3</key>\n\t\t<integer>368</integer>\n\t\t<key>u1D7B4</key>\n\t\t<integer>387</integer>\n\t\t<key>u1D7B5</key>\n\t\t<integer>397</integer>\n\t\t<key>u1D7B6</key>\n\t\t<integer>362</integer>\n\t\t<key>u1D7B7</key>\n\t\t<integer>392</integer>\n\t\t<key>u1D7B8</key>\n\t\t<integer>371</integer>\n\t\t<key>u1D7B9</key>\n\t\t<integer>416</integer>\n\t\t<key>u1D7BA</key>\n\t\t<integer>380</integer>\n\t\t<key>u1D7BB</key>\n\t\t<integer>358</integer>\n\t\t<key>u1D7BC</key>\n\t\t<integer>407</integer>\n\t\t<key>u1D7BD</key>\n\t\t<integer>361</integer>\n\t\t<key>u1D7BE</key>\n\t\t<integer>375</integer>\n\t\t<key>u1D7BF</key>\n\t\t<integer>441</integer>\n\t\t<key>u1D7C0</key>\n\t\t<integer>387</integer>\n\t\t<key>u1D7C1</key>\n\t\t<integer>451</integer>\n\t\t<key>u1D7C2</key>\n\t\t<integer>478</integer>\n\t\t<key>u1D7C3</key>\n\t\t<integer>374</integer>\n\t\t<key>u1D7C4</key>\n\t\t<integer>334</integer>\n\t\t<key>u1D7C5</key>\n\t\t<integer>389</integer>\n\t\t<key>u1D7C6</key>\n\t\t<integer>423</integer>\n\t\t<key>u1D7C7</key>\n\t\t<integer>489</integer>\n\t\t<key>u1D7C8</key>\n\t\t<integer>372</integer>\n\t\t<key>u1D7C9</key>\n\t\t<integer>544</integer>\n\t\t<key>uni0237</key>\n\t\t<integer>150</integer>\n\t\t<key>uni02C8</key>\n\t\t<integer>139</integer>\n\t\t<key>uni02C9</key>\n\t\t<integer>166</integer>\n\t\t<key>uni02CA</key>\n\t\t<integer>206</integer>\n\t\t<key>uni02CB</key>\n\t\t<integer>136</integer>\n\t\t<key>uni02CC</key>\n\t\t<integer>139</integer>\n\t\t<key>uni02CD</key>\n\t\t<integer>167</integer>\n\t\t<key>uni02CE</key>\n\t\t<integer>137</integer>\n\t\t<key>uni02CF</key>\n\t\t<integer>196</integer>\n\t\t<key>uni02F3</key>\n\t\t<integer>166</integer>\n\t\t<key>uni02F7</key>\n\t\t<integer>166</integer>\n\t\t<key>uni0300</key>\n\t\t<integer>-259</integer>\n\t\t<key>uni0301</key>\n\t\t<integer>-259</integer>\n\t\t<key>uni0302</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0302.size1</key>\n\t\t<integer>280</integer>\n\t\t<key>uni0302.size2</key>\n\t\t<integer>489</integer>\n\t\t<key>uni0302.size3</key>\n\t\t<integer>730</integer>\n\t\t<key>uni0302.size4</key>\n\t\t<integer>943</integer>\n\t\t<key>uni0302.size5</key>\n\t\t<integer>1164</integer>\n\t\t<key>uni0303</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0303.size1</key>\n\t\t<integer>280</integer>\n\t\t<key>uni0303.size2</key>\n\t\t<integer>489</integer>\n\t\t<key>uni0303.size3</key>\n\t\t<integer>730</integer>\n\t\t<key>uni0303.size4</key>\n\t\t<integer>943</integer>\n\t\t<key>uni0303.size5</key>\n\t\t<integer>1164</integer>\n\t\t<key>uni0304</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0305</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0305.size1</key>\n\t\t<integer>500</integer>\n\t\t<key>uni0305.size2</key>\n\t\t<integer>750</integer>\n\t\t<key>uni0305.size3</key>\n\t\t<integer>1000</integer>\n\t\t<key>uni0305.size4</key>\n\t\t<integer>1250</integer>\n\t\t<key>uni0305.size5</key>\n\t\t<integer>1500</integer>\n\t\t<key>uni0306</key>\n\t\t<integer>-232</integer>\n\t\t<key>uni0307</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0308</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0309</key>\n\t\t<integer>-212</integer>\n\t\t<key>uni030A</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni030B</key>\n\t\t<integer>-212</integer>\n\t\t<key>uni030C</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni030C.size1</key>\n\t\t<integer>280</integer>\n\t\t<key>uni030C.size2</key>\n\t\t<integer>489</integer>\n\t\t<key>uni030C.size3</key>\n\t\t<integer>730</integer>\n\t\t<key>uni030C.size4</key>\n\t\t<integer>943</integer>\n\t\t<key>uni030C.size5</key>\n\t\t<integer>1164</integer>\n\t\t<key>uni030D</key>\n\t\t<integer>-222</integer>\n\t\t<key>uni030E</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni030F</key>\n\t\t<integer>-212</integer>\n\t\t<key>uni0310</key>\n\t\t<integer>-232</integer>\n\t\t<key>uni0311</key>\n\t\t<integer>-232</integer>\n\t\t<key>uni0312</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0313</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0314</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0315</key>\n\t\t<integer>-16</integer>\n\t\t<key>uni0316</key>\n\t\t<integer>-239</integer>\n\t\t<key>uni0317</key>\n\t\t<integer>-259</integer>\n\t\t<key>uni0318</key>\n\t\t<integer>-304</integer>\n\t\t<key>uni0319</key>\n\t\t<integer>-174</integer>\n\t\t<key>uni031A</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni031B</key>\n\t\t<integer>4</integer>\n\t\t<key>uni031C</key>\n\t\t<integer>-296</integer>\n\t\t<key>uni031D</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni031E</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni031F</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0320</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0321</key>\n\t\t<integer>-117</integer>\n\t\t<key>uni0322</key>\n\t\t<integer>64</integer>\n\t\t<key>uni0323</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0324</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0325</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0326</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0327</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0328</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0329</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni032A</key>\n\t\t<integer>-229</integer>\n\t\t<key>uni032B</key>\n\t\t<integer>-228</integer>\n\t\t<key>uni032C</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni032D</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni032E</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni032F</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0330</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0330.size1</key>\n\t\t<integer>280</integer>\n\t\t<key>uni0330.size2</key>\n\t\t<integer>489</integer>\n\t\t<key>uni0330.size3</key>\n\t\t<integer>730</integer>\n\t\t<key>uni0330.size4</key>\n\t\t<integer>943</integer>\n\t\t<key>uni0330.size5</key>\n\t\t<integer>1164</integer>\n\t\t<key>uni0331</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0332</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0332.size1</key>\n\t\t<integer>500</integer>\n\t\t<key>uni0332.size2</key>\n\t\t<integer>750</integer>\n\t\t<key>uni0332.size3</key>\n\t\t<integer>1000</integer>\n\t\t<key>uni0332.size4</key>\n\t\t<integer>1250</integer>\n\t\t<key>uni0332.size5</key>\n\t\t<integer>1500</integer>\n\t\t<key>uni0333</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0334</key>\n\t\t<integer>-236</integer>\n\t\t<key>uni0335</key>\n\t\t<integer>-231</integer>\n\t\t<key>uni0336</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0337</key>\n\t\t<integer>-210</integer>\n\t\t<key>uni0338</key>\n\t\t<integer>-174</integer>\n\t\t<key>uni0338.size1</key>\n\t\t<integer>-339</integer>\n\t\t<key>uni0338.size2</key>\n\t\t<integer>-339</integer>\n\t\t<key>uni0338.size3</key>\n\t\t<integer>-340</integer>\n\t\t<key>uni0338.size4</key>\n\t\t<integer>-330</integer>\n\t\t<key>uni0338.size5</key>\n\t\t<integer>-343</integer>\n\t\t<key>uni0338.size6</key>\n\t\t<integer>-486</integer>\n\t\t<key>uni0339</key>\n\t\t<integer>-216</integer>\n\t\t<key>uni033A</key>\n\t\t<integer>-229</integer>\n\t\t<key>uni033B</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni033C</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni033D</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni033E</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni033F</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0346</key>\n\t\t<integer>-209</integer>\n\t\t<key>uni034C</key>\n\t\t<integer>-221</integer>\n\t\t<key>uni034D</key>\n\t\t<integer>239</integer>\n\t\t<key>uni0359</key>\n\t\t<integer>-222</integer>\n\t\t<key>uni035C</key>\n\t\t<integer>-39</integer>\n\t\t<key>uni0360</key>\n\t\t<integer>-15</integer>\n\t\t<key>uni0361</key>\n\t\t<integer>-39</integer>\n\t\t<key>uni0362</key>\n\t\t<integer>-20</integer>\n\t\t<key>uni0391</key>\n\t\t<integer>361</integer>\n\t\t<key>uni0392</key>\n\t\t<integer>305</integer>\n\t\t<key>uni0393</key>\n\t\t<integer>294</integer>\n\t\t<key>uni0394</key>\n\t\t<integer>362</integer>\n\t\t<key>uni0395</key>\n\t\t<integer>304</integer>\n\t\t<key>uni0396</key>\n\t\t<integer>304</integer>\n\t\t<key>uni0397</key>\n\t\t<integer>360</integer>\n\t\t<key>uni0398</key>\n\t\t<integer>361</integer>\n\t\t<key>uni0399</key>\n\t\t<integer>166</integer>\n\t\t<key>uni039A</key>\n\t\t<integer>370</integer>\n\t\t<key>uni039B</key>\n\t\t<integer>349</integer>\n\t\t<key>uni039C</key>\n\t\t<integer>438</integer>\n\t\t<key>uni039D</key>\n\t\t<integer>360</integer>\n\t\t<key>uni039E</key>\n\t\t<integer>322</integer>\n\t\t<key>uni039F</key>\n\t\t<integer>361</integer>\n\t\t<key>uni03A0</key>\n\t\t<integer>360</integer>\n\t\t<key>uni03A1</key>\n\t\t<integer>279</integer>\n\t\t<key>uni03A3</key>\n\t\t<integer>315</integer>\n\t\t<key>uni03A4</key>\n\t\t<integer>305</integer>\n\t\t<key>uni03A5</key>\n\t\t<integer>390</integer>\n\t\t<key>uni03A6</key>\n\t\t<integer>382</integer>\n\t\t<key>uni03A7</key>\n\t\t<integer>401</integer>\n\t\t<key>uni03A8</key>\n\t\t<integer>373</integer>\n\t\t<key>uni03A9</key>\n\t\t<integer>372</integer>\n\t\t<key>uni03B1</key>\n\t\t<integer>279</integer>\n\t\t<key>uni03B2</key>\n\t\t<integer>260</integer>\n\t\t<key>uni03B3</key>\n\t\t<integer>227</integer>\n\t\t<key>uni03B4</key>\n\t\t<integer>250</integer>\n\t\t<key>uni03B5</key>\n\t\t<integer>216</integer>\n\t\t<key>uni03B6</key>\n\t\t<integer>221</integer>\n\t\t<key>uni03B7</key>\n\t\t<integer>231</integer>\n\t\t<key>uni03B8</key>\n\t\t<integer>248</integer>\n\t\t<key>uni03B9</key>\n\t\t<integer>144</integer>\n\t\t<key>uni03BA</key>\n\t\t<integer>255</integer>\n\t\t<key>uni03BB</key>\n\t\t<integer>136</integer>\n\t\t<key>uni03BC</key>\n\t\t<integer>254</integer>\n\t\t<key>uni03BD</key>\n\t\t<integer>232</integer>\n\t\t<key>uni03BE</key>\n\t\t<integer>221</integer>\n\t\t<key>uni03BF</key>\n\t\t<integer>254</integer>\n\t\t<key>uni03C0</key>\n\t\t<integer>246</integer>\n\t\t<key>uni03C1</key>\n\t\t<integer>260</integer>\n\t\t<key>uni03C2</key>\n\t\t<integer>234</integer>\n\t\t<key>uni03C3</key>\n\t\t<integer>274</integer>\n\t\t<key>uni03C4</key>\n\t\t<integer>240</integer>\n\t\t<key>uni03C5</key>\n\t\t<integer>255</integer>\n\t\t<key>uni03C6</key>\n\t\t<integer>311</integer>\n\t\t<key>uni03C7</key>\n\t\t<integer>272</integer>\n\t\t<key>uni03C8</key>\n\t\t<integer>352</integer>\n\t\t<key>uni03C9</key>\n\t\t<integer>312</integer>\n\t\t<key>uni03D0</key>\n\t\t<integer>232</integer>\n\t\t<key>uni03D1</key>\n\t\t<integer>242</integer>\n\t\t<key>uni03D2</key>\n\t\t<integer>398</integer>\n\t\t<key>uni03D5</key>\n\t\t<integer>311</integer>\n\t\t<key>uni03D6</key>\n\t\t<integer>406</integer>\n\t\t<key>uni03D8</key>\n\t\t<integer>361</integer>\n\t\t<key>uni03D9</key>\n\t\t<integer>250</integer>\n\t\t<key>uni03DA</key>\n\t\t<integer>441</integer>\n\t\t<key>uni03DB</key>\n\t\t<integer>236</integer>\n\t\t<key>uni03DC</key>\n\t\t<integer>278</integer>\n\t\t<key>uni03DD</key>\n\t\t<integer>258</integer>\n\t\t<key>uni03F0</key>\n\t\t<integer>278</integer>\n\t\t<key>uni03F1</key>\n\t\t<integer>250</integer>\n\t\t<key>uni03F4</key>\n\t\t<integer>361</integer>\n\t\t<key>uni03F5</key>\n\t\t<integer>216</integer>\n\t\t<key>uni03F6</key>\n\t\t<integer>223</integer>\n\t\t<key>uni203E</key>\n\t\t<integer>250</integer>\n\t\t<key>uni203E.size1</key>\n\t\t<integer>500</integer>\n\t\t<key>uni203E.size2</key>\n\t\t<integer>750</integer>\n\t\t<key>uni203E.size3</key>\n\t\t<integer>1000</integer>\n\t\t<key>uni203E.size4</key>\n\t\t<integer>1250</integer>\n\t\t<key>uni203E.size5</key>\n\t\t<integer>1500</integer>\n\t\t<key>uni20D0</key>\n\t\t<integer>218</integer>\n\t\t<key>uni20D1</key>\n\t\t<integer>218</integer>\n\t\t<key>uni20D2</key>\n\t\t<integer>-217</integer>\n\t\t<key>uni20D2.size1</key>\n\t\t<integer>-217</integer>\n\t\t<key>uni20D2.size2</key>\n\t\t<integer>-217</integer>\n\t\t<key>uni20D2.size3</key>\n\t\t<integer>-217</integer>\n\t\t<key>uni20D2.size4</key>\n\t\t<integer>-217</integer>\n\t\t<key>uni20D2.size5</key>\n\t\t<integer>-217</integer>\n\t\t<key>uni20D2.size6</key>\n\t\t<integer>-217</integer>\n\t\t<key>uni20D6</key>\n\t\t<integer>218</integer>\n\t\t<key>uni20D7</key>\n\t\t<integer>218</integer>\n\t\t<key>uni20DB</key>\n\t\t<integer>-214</integer>\n\t\t<key>uni20DC</key>\n\t\t<integer>-252</integer>\n\t\t<key>uni20DD</key>\n\t\t<integer>-250</integer>\n\t\t<key>uni20DE</key>\n\t\t<integer>-250</integer>\n\t\t<key>uni20DF</key>\n\t\t<integer>-248</integer>\n\t\t<key>uni20E1</key>\n\t\t<integer>239</integer>\n\t\t<key>uni20E4</key>\n\t\t<integer>-249</integer>\n\t\t<key>uni20E5</key>\n\t\t<integer>-235</integer>\n\t\t<key>uni20E6</key>\n\t\t<integer>-218</integer>\n\t\t<key>uni20E7</key>\n\t\t<integer>-242</integer>\n\t\t<key>uni20E8</key>\n\t\t<integer>-214</integer>\n\t\t<key>uni20E9</key>\n\t\t<integer>-214</integer>\n\t\t<key>uni20EA</key>\n\t\t<integer>-270</integer>\n\t\t<key>uni20EB</key>\n\t\t<integer>-128</integer>\n\t\t<key>uni20EC</key>\n\t\t<integer>218</integer>\n\t\t<key>uni20ED</key>\n\t\t<integer>218</integer>\n\t\t<key>uni20EE</key>\n\t\t<integer>218</integer>\n\t\t<key>uni20EF</key>\n\t\t<integer>218</integer>\n\t\t<key>uni20F0</key>\n\t\t<integer>-222</integer>\n\t\t<key>uni2102.bi</key>\n\t\t<integer>458</integer>\n\t\t<key>uni2102.it</key>\n\t\t<integer>468</integer>\n\t\t<key>uni210A</key>\n\t\t<integer>491</integer>\n\t\t<key>uni210B</key>\n\t\t<integer>700</integer>\n\t\t<key>uni210B.cal</key>\n\t\t<integer>509</integer>\n\t\t<key>uni210D.bi</key>\n\t\t<integer>502</integer>\n\t\t<key>uni210D.it</key>\n\t\t<integer>492</integer>\n\t\t<key>uni210E</key>\n\t\t<integer>246</integer>\n\t\t<key>uni210F</key>\n\t\t<integer>246</integer>\n\t\t<key>uni2110</key>\n\t\t<integer>647</integer>\n\t\t<key>uni2110.cal</key>\n\t\t<integer>411</integer>\n\t\t<key>uni2112</key>\n\t\t<integer>850</integer>\n\t\t<key>uni2112.cal</key>\n\t\t<integer>476</integer>\n\t\t<key>uni2113</key>\n\t\t<integer>506</integer>\n\t\t<key>uni2115.bi</key>\n\t\t<integer>497</integer>\n\t\t<key>uni2115.it</key>\n\t\t<integer>490</integer>\n\t\t<key>uni2119.bi</key>\n\t\t<integer>454</integer>\n\t\t<key>uni2119.it</key>\n\t\t<integer>451</integer>\n\t\t<key>uni211A.bi</key>\n\t\t<integer>458</integer>\n\t\t<key>uni211A.it</key>\n\t\t<integer>474</integer>\n\t\t<key>uni211B</key>\n\t\t<integer>770</integer>\n\t\t<key>uni211B.cal</key>\n\t\t<integer>427</integer>\n\t\t<key>uni211D.bi</key>\n\t\t<integer>458</integer>\n\t\t<key>uni211D.it</key>\n\t\t<integer>451</integer>\n\t\t<key>uni2124.bi</key>\n\t\t<integer>554</integer>\n\t\t<key>uni2124.it</key>\n\t\t<integer>478</integer>\n\t\t<key>uni212C</key>\n\t\t<integer>808</integer>\n\t\t<key>uni212C.cal</key>\n\t\t<integer>512</integer>\n\t\t<key>uni212F</key>\n\t\t<integer>463</integer>\n\t\t<key>uni2130</key>\n\t\t<integer>633</integer>\n\t\t<key>uni2130.cal</key>\n\t\t<integer>446</integer>\n\t\t<key>uni2131</key>\n\t\t<integer>658</integer>\n\t\t<key>uni2131.cal</key>\n\t\t<integer>410</integer>\n\t\t<key>uni2133</key>\n\t\t<integer>867</integer>\n\t\t<key>uni2133.cal</key>\n\t\t<integer>713</integer>\n\t\t<key>uni2145</key>\n\t\t<integer>460</integer>\n\t\t<key>uni2146</key>\n\t\t<integer>437</integer>\n\t\t<key>uni2147</key>\n\t\t<integer>362</integer>\n\t\t<key>uni2148</key>\n\t\t<integer>286</integer>\n\t\t<key>uni2148.dtls</key>\n\t\t<integer>206</integer>\n\t\t<key>uni2149</key>\n\t\t<integer>313</integer>\n\t\t<key>uni2149.dtls</key>\n\t\t<integer>248</integer>\n\t\t<key>uni2202</key>\n\t\t<integer>232</integer>\n\t\t<key>uni2202.rtlm</key>\n\t\t<integer>201</integer>\n\t\t<key>uni2202.ss</key>\n\t\t<integer>349</integer>\n\t\t<key>uni220F</key>\n\t\t<integer>500</integer>\n\t\t<key>uni220F.display</key>\n\t\t<integer>678</integer>\n\t\t<key>uni2210</key>\n\t\t<integer>500</integer>\n\t\t<key>uni2210.display</key>\n\t\t<integer>678</integer>\n\t\t<key>uni2211</key>\n\t\t<integer>457</integer>\n\t\t<key>uni2211.display</key>\n\t\t<integer>646</integer>\n\t\t<key>uni22C5</key>\n\t\t<integer>143</integer>\n\t\t<key>uni23B4.size1</key>\n\t\t<integer>532</integer>\n\t\t<key>uni23B4.size2</key>\n\t\t<integer>803</integer>\n\t\t<key>uni23B4.size3</key>\n\t\t<integer>1074</integer>\n\t\t<key>uni23B4.size4</key>\n\t\t<integer>1346</integer>\n\t\t<key>uni23B4.size5</key>\n\t\t<integer>1618</integer>\n\t\t<key>uni23B5.size1</key>\n\t\t<integer>530</integer>\n\t\t<key>uni23B5.size2</key>\n\t\t<integer>803</integer>\n\t\t<key>uni23B5.size3</key>\n\t\t<integer>1074</integer>\n\t\t<key>uni23B5.size4</key>\n\t\t<integer>1346</integer>\n\t\t<key>uni23B5.size5</key>\n\t\t<integer>1618</integer>\n\t\t<key>uni23DC.size1</key>\n\t\t<integer>463</integer>\n\t\t<key>uni23DC.size2</key>\n\t\t<integer>730</integer>\n\t\t<key>uni23DC.size3</key>\n\t\t<integer>943</integer>\n\t\t<key>uni23DC.size4</key>\n\t\t<integer>1164</integer>\n\t\t<key>uni23DC.size5</key>\n\t\t<integer>1618</integer>\n\t\t<key>uni23DD.size1</key>\n\t\t<integer>463</integer>\n\t\t<key>uni23DD.size2</key>\n\t\t<integer>730</integer>\n\t\t<key>uni23DD.size3</key>\n\t\t<integer>943</integer>\n\t\t<key>uni23DD.size4</key>\n\t\t<integer>1164</integer>\n\t\t<key>uni23DD.size5</key>\n\t\t<integer>1618</integer>\n\t\t<key>uni23DE.size1</key>\n\t\t<integer>462</integer>\n\t\t<key>uni23DE.size2</key>\n\t\t<integer>730</integer>\n\t\t<key>uni23DE.size3</key>\n\t\t<integer>943</integer>\n\t\t<key>uni23DE.size4</key>\n\t\t<integer>1164</integer>\n\t\t<key>uni23DE.size5</key>\n\t\t<integer>1619</integer>\n\t\t<key>uni23DF.size1</key>\n\t\t<integer>462</integer>\n\t\t<key>uni23DF.size2</key>\n\t\t<integer>730</integer>\n\t\t<key>uni23DF.size3</key>\n\t\t<integer>943</integer>\n\t\t<key>uni23DF.size4</key>\n\t\t<integer>1164</integer>\n\t\t<key>uni23DF.size5</key>\n\t\t<integer>1619</integer>\n\t\t<key>uni23E0.size1</key>\n\t\t<integer>730</integer>\n\t\t<key>uni23E0.size2</key>\n\t\t<integer>943</integer>\n\t\t<key>uni23E0.size3</key>\n\t\t<integer>1156</integer>\n\t\t<key>uni23E0.size4</key>\n\t\t<integer>1369</integer>\n\t\t<key>uni23E0.size5</key>\n\t\t<integer>1582</integer>\n\t\t<key>uni23E1.size1</key>\n\t\t<integer>730</integer>\n\t\t<key>uni23E1.size2</key>\n\t\t<integer>943</integer>\n\t\t<key>uni23E1.size3</key>\n\t\t<integer>1156</integer>\n\t\t<key>uni23E1.size4</key>\n\t\t<integer>1369</integer>\n\t\t<key>uni23E1.size5</key>\n\t\t<integer>1582</integer>\n\t\t<key>v</key>\n\t\t<integer>276</integer>\n\t\t<key>w</key>\n\t\t<integer>358</integer>\n\t\t<key>x</key>\n\t\t<integer>254</integer>\n\t\t<key>y</key>\n\t\t<integer>284</integer>\n\t\t<key>z</key>\n\t\t<integer>246</integer>\n\t</dict>\n\t<key>constants</key>\n\t<dict>\n\t\t<key>AccentBaseHeight</key>\n\t\t<integer>450</integer>\n\t\t<key>AxisHeight</key>\n\t\t<integer>250</integer>\n\t\t<key>DelimitedSubFormulaMinHeight</key>\n\t\t<integer>1500</integer>\n\t\t<key>DisplayOperatorMinHeight</key>\n\t\t<integer>1450</integer>\n\t\t<key>FlattenedAccentBaseHeight</key>\n\t\t<integer>662</integer>\n\t\t<key>FractionDenomDisplayStyleGapMin</key>\n\t\t<integer>198</integer>\n\t\t<key>FractionDenominatorDisplayStyleShiftDown</key>\n\t\t<integer>700</integer>\n\t\t<key>FractionDenominatorGapMin</key>\n\t\t<integer>66</integer>\n\t\t<key>FractionDenominatorShiftDown</key>\n\t\t<integer>480</integer>\n\t\t<key>FractionNumDisplayStyleGapMin</key>\n\t\t<integer>198</integer>\n\t\t<key>FractionNumeratorDisplayStyleShiftUp</key>\n\t\t<integer>580</integer>\n\t\t<key>FractionNumeratorGapMin</key>\n\t\t<integer>66</integer>\n\t\t<key>FractionNumeratorShiftUp</key>\n\t\t<integer>480</integer>\n\t\t<key>FractionRuleThickness</key>\n\t\t<integer>66</integer>\n\t\t<key>LowerLimitBaselineDropMin</key>\n\t\t<integer>600</integer>\n\t\t<key>LowerLimitGapMin</key>\n\t\t<integer>150</integer>\n\t\t<key>MathLeading</key>\n\t\t<integer>150</integer>\n\t\t<key>MinConnectorOverlap</key>\n\t\t<integer>50</integer>\n\t\t<key>OverbarExtraAscender</key>\n\t\t<integer>66</integer>\n\t\t<key>OverbarRuleThickness</key>\n\t\t<integer>66</integer>\n\t\t<key>OverbarVerticalGap</key>\n\t\t<integer>198</integer>\n\t\t<key>RadicalDegreeBottomRaisePercent</key>\n\t\t<integer>70</integer>\n\t\t<key>RadicalDisplayStyleVerticalGap</key>\n\t\t<integer>186</integer>\n\t\t<key>RadicalExtraAscender</key>\n\t\t<integer>66</integer>\n\t\t<key>RadicalKernAfterDegree</key>\n\t\t<integer>-555</integer>\n\t\t<key>RadicalKernBeforeDegree</key>\n\t\t<integer>277</integer>\n\t\t<key>RadicalRuleThickness</key>\n\t\t<integer>66</integer>\n\t\t<key>RadicalVerticalGap</key>\n\t\t<integer>82</integer>\n\t\t<key>ScriptPercentScaleDown</key>\n\t\t<integer>75</integer>\n\t\t<key>ScriptScriptPercentScaleDown</key>\n\t\t<integer>60</integer>\n\t\t<key>SkewedFractionHorizontalGap</key>\n\t\t<integer>300</integer>\n\t\t<key>SkewedFractionVerticalGap</key>\n\t\t<integer>66</integer>\n\t\t<key>SpaceAfterScript</key>\n\t\t<integer>41</integer>\n\t\t<key>StackBottomDisplayStyleShiftDown</key>\n\t\t<integer>900</integer>\n\t\t<key>StackBottomShiftDown</key>\n\t\t<integer>800</integer>\n\t\t<key>StackDisplayStyleGapMin</key>\n\t\t<integer>462</integer>\n\t\t<key>StackGapMin</key>\n\t\t<integer>198</integer>\n\t\t<key>StackTopDisplayStyleShiftUp</key>\n\t\t<integer>580</integer>\n\t\t<key>StackTopShiftUp</key>\n\t\t<integer>480</integer>\n\t\t<key>StretchStackBottomShiftDown</key>\n\t\t<integer>600</integer>\n\t\t<key>StretchStackGapAboveMin</key>\n\t\t<integer>150</integer>\n\t\t<key>StretchStackGapBelowMin</key>\n\t\t<integer>150</integer>\n\t\t<key>StretchStackTopShiftUp</key>\n\t\t<integer>300</integer>\n\t\t<key>SubSuperscriptGapMin</key>\n\t\t<integer>264</integer>\n\t\t<key>SubscriptBaselineDropMin</key>\n\t\t<integer>50</integer>\n\t\t<key>SubscriptShiftDown</key>\n\t\t<integer>250</integer>\n\t\t<key>SubscriptTopMax</key>\n\t\t<integer>400</integer>\n\t\t<key>SuperscriptBaselineDropMax</key>\n\t\t<integer>375</integer>\n\t\t<key>SuperscriptBottomMaxWithSubscript</key>\n\t\t<integer>400</integer>\n\t\t<key>SuperscriptBottomMin</key>\n\t\t<integer>125</integer>\n\t\t<key>SuperscriptShiftUp</key>\n\t\t<integer>400</integer>\n\t\t<key>SuperscriptShiftUpCramped</key>\n\t\t<integer>275</integer>\n\t\t<key>UnderbarExtraDescender</key>\n\t\t<integer>66</integer>\n\t\t<key>UnderbarRuleThickness</key>\n\t\t<integer>66</integer>\n\t\t<key>UnderbarVerticalGap</key>\n\t\t<integer>198</integer>\n\t\t<key>UpperLimitBaselineRiseMin</key>\n\t\t<integer>300</integer>\n\t\t<key>UpperLimitGapMin</key>\n\t\t<integer>150</integer>\n\t</dict>\n\t<key>h_variants</key>\n\t<dict>\n\t\t<key>uni0302</key>\n\t\t<array>\n\t\t\t<string>uni0302</string>\n\t\t\t<string>uni0302.size1</string>\n\t\t\t<string>uni0302.size2</string>\n\t\t\t<string>uni0302.size3</string>\n\t\t\t<string>uni0302.size4</string>\n\t\t\t<string>uni0302.size5</string>\n\t\t</array>\n\t\t<key>uni0303</key>\n\t\t<array>\n\t\t\t<string>uni0303</string>\n\t\t\t<string>uni0303.size1</string>\n\t\t\t<string>uni0303.size2</string>\n\t\t\t<string>uni0303.size3</string>\n\t\t\t<string>uni0303.size4</string>\n\t\t\t<string>uni0303.size5</string>\n\t\t</array>\n\t\t<key>uni0305</key>\n\t\t<array>\n\t\t\t<string>uni0305</string>\n\t\t\t<string>uni0305.size1</string>\n\t\t\t<string>uni0305.size2</string>\n\t\t\t<string>uni0305.size3</string>\n\t\t\t<string>uni0305.size4</string>\n\t\t\t<string>uni0305.size5</string>\n\t\t</array>\n\t\t<key>uni030C</key>\n\t\t<array>\n\t\t\t<string>uni030C</string>\n\t\t\t<string>uni030C.size1</string>\n\t\t\t<string>uni030C.size2</string>\n\t\t\t<string>uni030C.size3</string>\n\t\t\t<string>uni030C.size4</string>\n\t\t\t<string>uni030C.size5</string>\n\t\t</array>\n\t\t<key>uni0330</key>\n\t\t<array>\n\t\t\t<string>uni0330</string>\n\t\t\t<string>uni0330.size1</string>\n\t\t\t<string>uni0330.size2</string>\n\t\t\t<string>uni0330.size3</string>\n\t\t\t<string>uni0330.size4</string>\n\t\t\t<string>uni0330.size5</string>\n\t\t</array>\n\t\t<key>uni0332</key>\n\t\t<array>\n\t\t\t<string>uni0332</string>\n\t\t\t<string>uni0332.size1</string>\n\t\t\t<string>uni0332.size2</string>\n\t\t\t<string>uni0332.size3</string>\n\t\t\t<string>uni0332.size4</string>\n\t\t\t<string>uni0332.size5</string>\n\t\t</array>\n\t\t<key>uni034D</key>\n\t\t<array>\n\t\t\t<string>uni034D</string>\n\t\t</array>\n\t\t<key>uni203E</key>\n\t\t<array>\n\t\t\t<string>uni203E</string>\n\t\t\t<string>uni203E.size1</string>\n\t\t\t<string>uni203E.size2</string>\n\t\t\t<string>uni203E.size3</string>\n\t\t\t<string>uni203E.size4</string>\n\t\t\t<string>uni203E.size5</string>\n\t\t</array>\n\t\t<key>uni20D0</key>\n\t\t<array>\n\t\t\t<string>uni20D0</string>\n\t\t</array>\n\t\t<key>uni20D1</key>\n\t\t<array>\n\t\t\t<string>uni20D1</string>\n\t\t</array>\n\t\t<key>uni20D6</key>\n\t\t<array>\n\t\t\t<string>uni20D6</string>\n\t\t</array>\n\t\t<key>uni20D7</key>\n\t\t<array>\n\t\t\t<string>uni20D7</string>\n\t\t</array>\n\t\t<key>uni20E1</key>\n\t\t<array>\n\t\t\t<string>uni20E1</string>\n\t\t</array>\n\t\t<key>uni20E9</key>\n\t\t<array>\n\t\t\t<string>uni20E9</string>\n\t\t</array>\n\t\t<key>uni20EC</key>\n\t\t<array>\n\t\t\t<string>uni20EC</string>\n\t\t</array>\n\t\t<key>uni20ED</key>\n\t\t<array>\n\t\t\t<string>uni20ED</string>\n\t\t</array>\n\t\t<key>uni20EE</key>\n\t\t<array>\n\t\t\t<string>uni20EE</string>\n\t\t</array>\n\t\t<key>uni20EF</key>\n\t\t<array>\n\t\t\t<string>uni20EF</string>\n\t\t</array>\n\t\t<key>uni2190</key>\n\t\t<array/>\n\t\t<key>uni2192</key>\n\t\t<array/>\n\t\t<key>uni2194</key>\n\t\t<array/>\n\t\t<key>uni21A4</key>\n\t\t<array/>\n\t\t<key>uni21A6</key>\n\t\t<array/>\n\t\t<key>uni21BC</key>\n\t\t<array/>\n\t\t<key>uni21BD</key>\n\t\t<array/>\n\t\t<key>uni21C0</key>\n\t\t<array/>\n\t\t<key>uni21D0</key>\n\t\t<array/>\n\t\t<key>uni21D2</key>\n\t\t<array/>\n\t\t<key>uni21D4</key>\n\t\t<array/>\n\t\t<key>uni21DA</key>\n\t\t<array/>\n\t\t<key>uni21DB</key>\n\t\t<array/>\n\t\t<key>uni23B4</key>\n\t\t<array>\n\t\t\t<string>uni23B4</string>\n\t\t\t<string>uni23B4.size1</string>\n\t\t\t<string>uni23B4.size2</string>\n\t\t\t<string>uni23B4.size3</string>\n\t\t\t<string>uni23B4.size4</string>\n\t\t\t<string>uni23B4.size5</string>\n\t\t</array>\n\t\t<key>uni23B5</key>\n\t\t<array>\n\t\t\t<string>uni23B5</string>\n\t\t\t<string>uni23B5.size1</string>\n\t\t\t<string>uni23B5.size2</string>\n\t\t\t<string>uni23B5.size3</string>\n\t\t\t<string>uni23B5.size4</string>\n\t\t\t<string>uni23B5.size5</string>\n\t\t</array>\n\t\t<key>uni23DC</key>\n\t\t<array>\n\t\t\t<string>uni23DC</string>\n\t\t\t<string>uni23DC.size1</string>\n\t\t\t<string>uni23DC.size2</string>\n\t\t\t<string>uni23DC.size3</string>\n\t\t\t<string>uni23DC.size4</string>\n\t\t\t<string>uni23DC.size5</string>\n\t\t</array>\n\t\t<key>uni23DD</key>\n\t\t<array>\n\t\t\t<string>uni23DD</string>\n\t\t\t<string>uni23DD.size1</string>\n\t\t\t<string>uni23DD.size2</string>\n\t\t\t<string>uni23DD.size3</string>\n\t\t\t<string>uni23DD.size4</string>\n\t\t\t<string>uni23DD.size5</string>\n\t\t</array>\n\t\t<key>uni23DE</key>\n\t\t<array>\n\t\t\t<string>uni23DE</string>\n\t\t\t<string>uni23DE.size1</string>\n\t\t\t<string>uni23DE.size2</string>\n\t\t\t<string>uni23DE.size3</string>\n\t\t\t<string>uni23DE.size4</string>\n\t\t\t<string>uni23DE.size5</string>\n\t\t</array>\n\t\t<key>uni23DF</key>\n\t\t<array>\n\t\t\t<string>uni23DF</string>\n\t\t\t<string>uni23DF.size1</string>\n\t\t\t<string>uni23DF.size2</string>\n\t\t\t<string>uni23DF.size3</string>\n\t\t\t<string>uni23DF.size4</string>\n\t\t\t<string>uni23DF.size5</string>\n\t\t</array>\n\t\t<key>uni23E0</key>\n\t\t<array>\n\t\t\t<string>uni23E0</string>\n\t\t\t<string>uni23E0.size1</string>\n\t\t\t<string>uni23E0.size2</string>\n\t\t\t<string>uni23E0.size3</string>\n\t\t\t<string>uni23E0.size4</string>\n\t\t\t<string>uni23E0.size5</string>\n\t\t</array>\n\t\t<key>uni23E1</key>\n\t\t<array>\n\t\t\t<string>uni23E1</string>\n\t\t\t<string>uni23E1.size1</string>\n\t\t\t<string>uni23E1.size2</string>\n\t\t\t<string>uni23E1.size3</string>\n\t\t\t<string>uni23E1.size4</string>\n\t\t\t<string>uni23E1.size5</string>\n\t\t</array>\n\t\t<key>uni2B45</key>\n\t\t<array/>\n\t\t<key>uni2B46</key>\n\t\t<array/>\n\t</dict>\n\t<key>italic</key>\n\t<dict>\n\t\t<key>f</key>\n\t\t<integer>100</integer>\n\t\t<key>r</key>\n\t\t<integer>60</integer>\n\t\t<key>t</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D41F</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D42B</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D42D</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D431</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D432</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D433</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D435</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D436</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D437</key>\n\t\t<integer>15</integer>\n\t\t<key>u1D438</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D439</key>\n\t\t<integer>145</integer>\n\t\t<key>u1D43A</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D43B</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D43C</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D43D</key>\n\t\t<integer>120</integer>\n\t\t<key>u1D43E</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D440</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D441</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D442</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D443</key>\n\t\t<integer>150</integer>\n\t\t<key>u1D446</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D447</key>\n\t\t<integer>160</integer>\n\t\t<key>u1D448</key>\n\t\t<integer>110</integer>\n\t\t<key>u1D449</key>\n\t\t<integer>225</integer>\n\t\t<key>u1D44A</key>\n\t\t<integer>225</integer>\n\t\t<key>u1D44B</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D44C</key>\n\t\t<integer>200</integer>\n\t\t<key>u1D44D</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D450</key>\n\t\t<integer>50</integer>\n\t\t<key>u1D451</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D453</key>\n\t\t<integer>120</integer>\n\t\t<key>u1D454</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D457</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D459</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D45E</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D469</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D46A</key>\n\t\t<integer>84</integer>\n\t\t<key>u1D46B</key>\n\t\t<integer>68</integer>\n\t\t<key>u1D46C</key>\n\t\t<integer>62</integer>\n\t\t<key>u1D46D</key>\n\t\t<integer>155</integer>\n\t\t<key>u1D46E</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D46F</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D470</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D471</key>\n\t\t<integer>128</integer>\n\t\t<key>u1D472</key>\n\t\t<integer>84</integer>\n\t\t<key>u1D474</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D475</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D476</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D477</key>\n\t\t<integer>161</integer>\n\t\t<key>u1D479</key>\n\t\t<integer>25</integer>\n\t\t<key>u1D47A</key>\n\t\t<integer>73</integer>\n\t\t<key>u1D47B</key>\n\t\t<integer>172</integer>\n\t\t<key>u1D47C</key>\n\t\t<integer>117</integer>\n\t\t<key>u1D47D</key>\n\t\t<integer>244</integer>\n\t\t<key>u1D47E</key>\n\t\t<integer>244</integer>\n\t\t<key>u1D47F</key>\n\t\t<integer>62</integer>\n\t\t<key>u1D480</key>\n\t\t<integer>216</integer>\n\t\t<key>u1D481</key>\n\t\t<integer>73</integer>\n\t\t<key>u1D484</key>\n\t\t<integer>50</integer>\n\t\t<key>u1D485</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D487</key>\n\t\t<integer>120</integer>\n\t\t<key>u1D48B</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D492</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D49C</key>\n\t\t<integer>125</integer>\n\t\t<key>u1D49E</key>\n\t\t<integer>145</integer>\n\t\t<key>u1D49E.cal</key>\n\t\t<integer>62</integer>\n\t\t<key>u1D49F</key>\n\t\t<integer>125</integer>\n\t\t<key>u1D4A2</key>\n\t\t<integer>145</integer>\n\t\t<key>u1D4A5</key>\n\t\t<integer>185</integer>\n\t\t<key>u1D4A5.cal</key>\n\t\t<integer>198</integer>\n\t\t<key>u1D4A6</key>\n\t\t<integer>125</integer>\n\t\t<key>u1D4A9</key>\n\t\t<integer>245</integer>\n\t\t<key>u1D4A9.cal</key>\n\t\t<integer>152</integer>\n\t\t<key>u1D4AA</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D4AB</key>\n\t\t<integer>245</integer>\n\t\t<key>u1D4AB.cal</key>\n\t\t<integer>87</integer>\n\t\t<key>u1D4AC</key>\n\t\t<integer>45</integer>\n\t\t<key>u1D4AE</key>\n\t\t<integer>145</integer>\n\t\t<key>u1D4AE.cal</key>\n\t\t<integer>82</integer>\n\t\t<key>u1D4AF</key>\n\t\t<integer>245</integer>\n\t\t<key>u1D4AF.cal</key>\n\t\t<integer>266</integer>\n\t\t<key>u1D4B0</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D4B0.cal</key>\n\t\t<integer>178</integer>\n\t\t<key>u1D4B1</key>\n\t\t<integer>245</integer>\n\t\t<key>u1D4B1.cal</key>\n\t\t<integer>87</integer>\n\t\t<key>u1D4B2</key>\n\t\t<integer>245</integer>\n\t\t<key>u1D4B2.cal</key>\n\t\t<integer>87</integer>\n\t\t<key>u1D4B3</key>\n\t\t<integer>125</integer>\n\t\t<key>u1D4B3.cal</key>\n\t\t<integer>92</integer>\n\t\t<key>u1D4B4</key>\n\t\t<integer>125</integer>\n\t\t<key>u1D4B4.cal</key>\n\t\t<integer>89</integer>\n\t\t<key>u1D4B5</key>\n\t\t<integer>125</integer>\n\t\t<key>u1D4BB</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D4BE</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D4BF</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D4C1</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D4C9</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D4D2.cal</key>\n\t\t<integer>47</integer>\n\t\t<key>u1D4D3.cal</key>\n\t\t<integer>51</integer>\n\t\t<key>u1D4D4.cal</key>\n\t\t<integer>62</integer>\n\t\t<key>u1D4D5.cal</key>\n\t\t<integer>138</integer>\n\t\t<key>u1D4D7.cal</key>\n\t\t<integer>54</integer>\n\t\t<key>u1D4D8.cal</key>\n\t\t<integer>47</integer>\n\t\t<key>u1D4D9.cal</key>\n\t\t<integer>211</integer>\n\t\t<key>u1D4DD.cal</key>\n\t\t<integer>146</integer>\n\t\t<key>u1D4DE.cal</key>\n\t\t<integer>55</integer>\n\t\t<key>u1D4DF.cal</key>\n\t\t<integer>131</integer>\n\t\t<key>u1D4E2.cal</key>\n\t\t<integer>77</integer>\n\t\t<key>u1D4E3.cal</key>\n\t\t<integer>245</integer>\n\t\t<key>u1D4E4.cal</key>\n\t\t<integer>194</integer>\n\t\t<key>u1D4E5.cal</key>\n\t\t<integer>99</integer>\n\t\t<key>u1D4E6.cal</key>\n\t\t<integer>99</integer>\n\t\t<key>u1D4E7.cal</key>\n\t\t<integer>106</integer>\n\t\t<key>u1D4E8.cal</key>\n\t\t<integer>98</integer>\n\t\t<key>u1D4EF</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D4F2</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D4F3</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D4F5</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D4FD</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D53B.it</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D53C.bi</key>\n\t\t<integer>68</integer>\n\t\t<key>u1D53C.it</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D53D</key>\n\t\t<integer>140</integer>\n\t\t<key>u1D53D.bf</key>\n\t\t<integer>166</integer>\n\t\t<key>u1D53D.bi</key>\n\t\t<integer>274</integer>\n\t\t<key>u1D53D.it</key>\n\t\t<integer>240</integer>\n\t\t<key>u1D540.bi</key>\n\t\t<integer>74</integer>\n\t\t<key>u1D540.it</key>\n\t\t<integer>75</integer>\n\t\t<key>u1D541.bi</key>\n\t\t<integer>86</integer>\n\t\t<key>u1D541.it</key>\n\t\t<integer>78</integer>\n\t\t<key>u1D542.it</key>\n\t\t<integer>75</integer>\n\t\t<key>u1D544.bi</key>\n\t\t<integer>76</integer>\n\t\t<key>u1D544.it</key>\n\t\t<integer>79</integer>\n\t\t<key>u1D54A.bi</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D54A.it</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D54B</key>\n\t\t<integer>140</integer>\n\t\t<key>u1D54B.bf</key>\n\t\t<integer>134</integer>\n\t\t<key>u1D54B.bi</key>\n\t\t<integer>253</integer>\n\t\t<key>u1D54B.it</key>\n\t\t<integer>264</integer>\n\t\t<key>u1D54C.bi</key>\n\t\t<integer>91</integer>\n\t\t<key>u1D54C.it</key>\n\t\t<integer>113</integer>\n\t\t<key>u1D54D</key>\n\t\t<integer>130</integer>\n\t\t<key>u1D54D.bf</key>\n\t\t<integer>122</integer>\n\t\t<key>u1D54D.bi</key>\n\t\t<integer>246</integer>\n\t\t<key>u1D54D.it</key>\n\t\t<integer>231</integer>\n\t\t<key>u1D54E</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D54E.bf</key>\n\t\t<integer>64</integer>\n\t\t<key>u1D54E.bi</key>\n\t\t<integer>145</integer>\n\t\t<key>u1D54E.it</key>\n\t\t<integer>198</integer>\n\t\t<key>u1D54F.bi</key>\n\t\t<integer>118</integer>\n\t\t<key>u1D54F.it</key>\n\t\t<integer>165</integer>\n\t\t<key>u1D550</key>\n\t\t<integer>150</integer>\n\t\t<key>u1D550.bf</key>\n\t\t<integer>132</integer>\n\t\t<key>u1D550.bi</key>\n\t\t<integer>297</integer>\n\t\t<key>u1D550.it</key>\n\t\t<integer>245</integer>\n\t\t<key>u1D555.it</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D557</key>\n\t\t<integer>105</integer>\n\t\t<key>u1D557.bf</key>\n\t\t<integer>107</integer>\n\t\t<key>u1D557.bi</key>\n\t\t<integer>225</integer>\n\t\t<key>u1D557.it</key>\n\t\t<integer>233</integer>\n\t\t<key>u1D55A.it</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D55B.it</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D55D.bi</key>\n\t\t<integer>86</integer>\n\t\t<key>u1D55D.it</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D563</key>\n\t\t<integer>145</integer>\n\t\t<key>u1D563.bf</key>\n\t\t<integer>151</integer>\n\t\t<key>u1D563.bi</key>\n\t\t<integer>180</integer>\n\t\t<key>u1D563.it</key>\n\t\t<integer>180</integer>\n\t\t<key>u1D565.bi</key>\n\t\t<integer>64</integer>\n\t\t<key>u1D567</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D567.bf</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D567.bi</key>\n\t\t<integer>102</integer>\n\t\t<key>u1D567.it</key>\n\t\t<integer>112</integer>\n\t\t<key>u1D568</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D568.bi</key>\n\t\t<integer>75</integer>\n\t\t<key>u1D568.it</key>\n\t\t<integer>96</integer>\n\t\t<key>u1D569.bi</key>\n\t\t<integer>72</integer>\n\t\t<key>u1D56A</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D56A.bf</key>\n\t\t<integer>111</integer>\n\t\t<key>u1D56A.bi</key>\n\t\t<integer>104</integer>\n\t\t<key>u1D56A.it</key>\n\t\t<integer>112</integer>\n\t\t<key>u1D5BF</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D5F3</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D609</key>\n\t\t<integer>77</integer>\n\t\t<key>u1D60A</key>\n\t\t<integer>124</integer>\n\t\t<key>u1D60B</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D60C</key>\n\t\t<integer>135</integer>\n\t\t<key>u1D60D</key>\n\t\t<integer>184</integer>\n\t\t<key>u1D60E</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D60F</key>\n\t\t<integer>130</integer>\n\t\t<key>u1D610</key>\n\t\t<integer>150</integer>\n\t\t<key>u1D611</key>\n\t\t<integer>112</integer>\n\t\t<key>u1D612</key>\n\t\t<integer>135</integer>\n\t\t<key>u1D614</key>\n\t\t<integer>130</integer>\n\t\t<key>u1D615</key>\n\t\t<integer>130</integer>\n\t\t<key>u1D616</key>\n\t\t<integer>105</integer>\n\t\t<key>u1D617</key>\n\t\t<integer>153</integer>\n\t\t<key>u1D618</key>\n\t\t<integer>103</integer>\n\t\t<key>u1D619</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D61A</key>\n\t\t<integer>96</integer>\n\t\t<key>u1D61B</key>\n\t\t<integer>180</integer>\n\t\t<key>u1D61C</key>\n\t\t<integer>106</integer>\n\t\t<key>u1D61D</key>\n\t\t<integer>174</integer>\n\t\t<key>u1D61E</key>\n\t\t<integer>176</integer>\n\t\t<key>u1D61F</key>\n\t\t<integer>146</integer>\n\t\t<key>u1D620</key>\n\t\t<integer>184</integer>\n\t\t<key>u1D621</key>\n\t\t<integer>166</integer>\n\t\t<key>u1D625</key>\n\t\t<integer>160</integer>\n\t\t<key>u1D627</key>\n\t\t<integer>240</integer>\n\t\t<key>u1D628</key>\n\t\t<integer>120</integer>\n\t\t<key>u1D629</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D62A</key>\n\t\t<integer>145</integer>\n\t\t<key>u1D62B</key>\n\t\t<integer>140</integer>\n\t\t<key>u1D62C</key>\n\t\t<integer>120</integer>\n\t\t<key>u1D62D</key>\n\t\t<integer>160</integer>\n\t\t<key>u1D62E</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D62F</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D630</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D631</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D632</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D633</key>\n\t\t<integer>140</integer>\n\t\t<key>u1D634</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D635</key>\n\t\t<integer>120</integer>\n\t\t<key>u1D636</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D637</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D638</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D639</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D63A</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D63B</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D63D</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D63E</key>\n\t\t<integer>114</integer>\n\t\t<key>u1D63F</key>\n\t\t<integer>103</integer>\n\t\t<key>u1D640</key>\n\t\t<integer>133</integer>\n\t\t<key>u1D641</key>\n\t\t<integer>183</integer>\n\t\t<key>u1D642</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D643</key>\n\t\t<integer>128</integer>\n\t\t<key>u1D644</key>\n\t\t<integer>134</integer>\n\t\t<key>u1D645</key>\n\t\t<integer>133</integer>\n\t\t<key>u1D646</key>\n\t\t<integer>144</integer>\n\t\t<key>u1D648</key>\n\t\t<integer>128</integer>\n\t\t<key>u1D649</key>\n\t\t<integer>128</integer>\n\t\t<key>u1D64A</key>\n\t\t<integer>102</integer>\n\t\t<key>u1D64B</key>\n\t\t<integer>145</integer>\n\t\t<key>u1D64C</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D64D</key>\n\t\t<integer>68</integer>\n\t\t<key>u1D64E</key>\n\t\t<integer>123</integer>\n\t\t<key>u1D64F</key>\n\t\t<integer>184</integer>\n\t\t<key>u1D650</key>\n\t\t<integer>133</integer>\n\t\t<key>u1D651</key>\n\t\t<integer>183</integer>\n\t\t<key>u1D652</key>\n\t\t<integer>178</integer>\n\t\t<key>u1D653</key>\n\t\t<integer>153</integer>\n\t\t<key>u1D654</key>\n\t\t<integer>188</integer>\n\t\t<key>u1D655</key>\n\t\t<integer>156</integer>\n\t\t<key>u1D657</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D658</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D659</key>\n\t\t<integer>140</integer>\n\t\t<key>u1D65A</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D65B</key>\n\t\t<integer>240</integer>\n\t\t<key>u1D65C</key>\n\t\t<integer>140</integer>\n\t\t<key>u1D65D</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D65E</key>\n\t\t<integer>140</integer>\n\t\t<key>u1D65F</key>\n\t\t<integer>140</integer>\n\t\t<key>u1D660</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D661</key>\n\t\t<integer>140</integer>\n\t\t<key>u1D662</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D663</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D664</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D665</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D666</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D667</key>\n\t\t<integer>120</integer>\n\t\t<key>u1D668</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D669</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D66A</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D66B</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D66C</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D66D</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D66E</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D66F</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D6E3</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D6E4</key>\n\t\t<integer>145</integer>\n\t\t<key>u1D6E4.ss</key>\n\t\t<integer>148</integer>\n\t\t<key>u1D6E6</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D6E6.ss</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D6E7</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D6E7.ss</key>\n\t\t<integer>107</integer>\n\t\t<key>u1D6E8</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D6E8.ss</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D6E9</key>\n\t\t<integer>15</integer>\n\t\t<key>u1D6EA</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D6EA.ss</key>\n\t\t<integer>115</integer>\n\t\t<key>u1D6EB</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D6EB.ss</key>\n\t\t<integer>129</integer>\n\t\t<key>u1D6ED</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D6ED.ss</key>\n\t\t<integer>73</integer>\n\t\t<key>u1D6EE</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D6EE.ss</key>\n\t\t<integer>73</integer>\n\t\t<key>u1D6EF</key>\n\t\t<integer>75</integer>\n\t\t<key>u1D6EF.ss</key>\n\t\t<integer>77</integer>\n\t\t<key>u1D6F0</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D6F1</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D6F1.ss</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D6F2</key>\n\t\t<integer>150</integer>\n\t\t<key>u1D6F2.ss</key>\n\t\t<integer>131</integer>\n\t\t<key>u1D6F3</key>\n\t\t<integer>15</integer>\n\t\t<key>u1D6F4</key>\n\t\t<integer>65</integer>\n\t\t<key>u1D6F4.ss</key>\n\t\t<integer>97</integer>\n\t\t<key>u1D6F5</key>\n\t\t<integer>160</integer>\n\t\t<key>u1D6F5.ss</key>\n\t\t<integer>119</integer>\n\t\t<key>u1D6F6</key>\n\t\t<integer>160</integer>\n\t\t<key>u1D6F6.ss</key>\n\t\t<integer>177</integer>\n\t\t<key>u1D6F7</key>\n\t\t<integer>15</integer>\n\t\t<key>u1D6F8</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D6F8.ss</key>\n\t\t<integer>118</integer>\n\t\t<key>u1D6F9</key>\n\t\t<integer>113</integer>\n\t\t<key>u1D6F9.ss</key>\n\t\t<integer>138</integer>\n\t\t<key>u1D6FA</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D6FB</key>\n\t\t<integer>15</integer>\n\t\t<key>u1D6FC</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D6FC.ss</key>\n\t\t<integer>75</integer>\n\t\t<key>u1D6FD</key>\n\t\t<integer>65</integer>\n\t\t<key>u1D6FD.ss</key>\n\t\t<integer>69</integer>\n\t\t<key>u1D6FE</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D6FE.ss</key>\n\t\t<integer>69</integer>\n\t\t<key>u1D6FF</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D6FF.ss</key>\n\t\t<integer>85</integer>\n\t\t<key>u1D701</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D701.ss</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D702</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D703</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D705</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D705.ss</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D707</key>\n\t\t<integer>30</integer>\n\t\t<key>u1D708</key>\n\t\t<integer>50</integer>\n\t\t<key>u1D708.ss</key>\n\t\t<integer>85</integer>\n\t\t<key>u1D709</key>\n\t\t<integer>50</integer>\n\t\t<key>u1D709.ss</key>\n\t\t<integer>75</integer>\n\t\t<key>u1D70B</key>\n\t\t<integer>50</integer>\n\t\t<key>u1D70B.ss</key>\n\t\t<integer>69</integer>\n\t\t<key>u1D70D</key>\n\t\t<integer>65</integer>\n\t\t<key>u1D70D.ss</key>\n\t\t<integer>109</integer>\n\t\t<key>u1D70E</key>\n\t\t<integer>50</integer>\n\t\t<key>u1D70E.ss</key>\n\t\t<integer>63</integer>\n\t\t<key>u1D70F</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D70F.ss</key>\n\t\t<integer>63</integer>\n\t\t<key>u1D712</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D712.ss</key>\n\t\t<integer>83</integer>\n\t\t<key>u1D713</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D713.ss</key>\n\t\t<integer>96</integer>\n\t\t<key>u1D714.ss</key>\n\t\t<integer>51</integer>\n\t\t<key>u1D715</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D716</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D718</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D71B</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D71B.ss</key>\n\t\t<integer>61</integer>\n\t\t<key>u1D71D</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D71E</key>\n\t\t<integer>155</integer>\n\t\t<key>u1D720</key>\n\t\t<integer>62</integer>\n\t\t<key>u1D721</key>\n\t\t<integer>73</integer>\n\t\t<key>u1D722</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D723</key>\n\t\t<integer>68</integer>\n\t\t<key>u1D724</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D725</key>\n\t\t<integer>84</integer>\n\t\t<key>u1D727</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D728</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D729</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D72A</key>\n\t\t<integer>18</integer>\n\t\t<key>u1D72B</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D72C</key>\n\t\t<integer>161</integer>\n\t\t<key>u1D72D</key>\n\t\t<integer>12</integer>\n\t\t<key>u1D72E</key>\n\t\t<integer>68</integer>\n\t\t<key>u1D72F</key>\n\t\t<integer>172</integer>\n\t\t<key>u1D730</key>\n\t\t<integer>172</integer>\n\t\t<key>u1D731</key>\n\t\t<integer>12</integer>\n\t\t<key>u1D732</key>\n\t\t<integer>18</integer>\n\t\t<key>u1D733</key>\n\t\t<integer>127</integer>\n\t\t<key>u1D734</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D735</key>\n\t\t<integer>10</integer>\n\t\t<key>u1D736</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D737</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D738</key>\n\t\t<integer>53</integer>\n\t\t<key>u1D73B</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D73F</key>\n\t\t<integer>50</integer>\n\t\t<key>u1D742</key>\n\t\t<integer>50</integer>\n\t\t<key>u1D743</key>\n\t\t<integer>50</integer>\n\t\t<key>u1D745</key>\n\t\t<integer>50</integer>\n\t\t<key>u1D747</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D748</key>\n\t\t<integer>50</integer>\n\t\t<key>u1D749</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D74C</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D74D</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D74F</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D750</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D752</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D755</key>\n\t\t<integer>50</integer>\n\t\t<key>u1D7AA</key>\n\t\t<integer>65</integer>\n\t\t<key>u1D7AB</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D7AC</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D7AD</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D7AF</key>\n\t\t<integer>120</integer>\n\t\t<key>u1D7B3</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D7B6</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D7B7</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D7B9</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D7BB</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D7BC</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D7BD</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D7C0</key>\n\t\t<integer>110</integer>\n\t\t<key>u1D7C1</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D7C3</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D7C4</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D7C6</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D7C9</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D7E2.ss</key>\n\t\t<integer>123</integer>\n\t\t<key>u1D7E4.ss</key>\n\t\t<integer>119</integer>\n\t\t<key>u1D7E5.ss</key>\n\t\t<integer>89</integer>\n\t\t<key>u1D7E6.ss</key>\n\t\t<integer>92</integer>\n\t\t<key>u1D7E7.ss</key>\n\t\t<integer>171</integer>\n\t\t<key>u1D7E8.ss</key>\n\t\t<integer>162</integer>\n\t\t<key>u1D7E9.ss</key>\n\t\t<integer>161</integer>\n\t\t<key>u1D7EA.ss</key>\n\t\t<integer>105</integer>\n\t\t<key>u1D7EB.ss</key>\n\t\t<integer>124</integer>\n\t\t<key>u1D7EC.ss</key>\n\t\t<integer>123</integer>\n\t\t<key>u1D7EE.ss</key>\n\t\t<integer>126</integer>\n\t\t<key>u1D7EF.ss</key>\n\t\t<integer>131</integer>\n\t\t<key>u1D7F0.ss</key>\n\t\t<integer>128</integer>\n\t\t<key>u1D7F1.ss</key>\n\t\t<integer>196</integer>\n\t\t<key>u1D7F2.ss</key>\n\t\t<integer>183</integer>\n\t\t<key>u1D7F3.ss</key>\n\t\t<integer>184</integer>\n\t\t<key>u1D7F4.ss</key>\n\t\t<integer>139</integer>\n\t\t<key>u1D7F5.ss</key>\n\t\t<integer>133</integer>\n\t\t<key>uni03C3.ss</key>\n\t\t<integer>61</integer>\n\t\t<key>uni03C7.ss</key>\n\t\t<integer>86</integer>\n\t\t<key>uni03C8</key>\n\t\t<integer>40</integer>\n\t\t<key>uni210B</key>\n\t\t<integer>145</integer>\n\t\t<key>uni210B.cal</key>\n\t\t<integer>59</integer>\n\t\t<key>uni2110</key>\n\t\t<integer>195</integer>\n\t\t<key>uni2110.cal</key>\n\t\t<integer>61</integer>\n\t\t<key>uni2112</key>\n\t\t<integer>125</integer>\n\t\t<key>uni211B</key>\n\t\t<integer>45</integer>\n\t\t<key>uni212C</key>\n\t\t<integer>45</integer>\n\t\t<key>uni2130</key>\n\t\t<integer>105</integer>\n\t\t<key>uni2130.cal</key>\n\t\t<integer>91</integer>\n\t\t<key>uni2131</key>\n\t\t<integer>195</integer>\n\t\t<key>uni2131.cal</key>\n\t\t<integer>103</integer>\n\t\t<key>uni2133</key>\n\t\t<integer>45</integer>\n\t\t<key>uni213E</key>\n\t\t<integer>130</integer>\n\t\t<key>uni2145</key>\n\t\t<integer>20</integer>\n\t\t<key>uni2146</key>\n\t\t<integer>80</integer>\n\t\t<key>uni2148</key>\n\t\t<integer>80</integer>\n\t\t<key>uni2149</key>\n\t\t<integer>80</integer>\n\t\t<key>uni222B</key>\n\t\t<integer>180</integer>\n\t\t<key>uni222B.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni222B.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni222B.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni222B.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni222B.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni222B.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni222C</key>\n\t\t<integer>180</integer>\n\t\t<key>uni222C.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni222C.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni222C.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni222C.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni222C.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni222C.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni222D</key>\n\t\t<integer>180</integer>\n\t\t<key>uni222D.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni222D.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni222D.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni222D.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni222D.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni222D.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni222E</key>\n\t\t<integer>180</integer>\n\t\t<key>uni222E.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni222E.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni222E.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni222E.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni222E.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni222E.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni222F</key>\n\t\t<integer>180</integer>\n\t\t<key>uni222F.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni222F.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni222F.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni222F.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni222F.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni222F.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2230</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2230.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2230.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2230.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2230.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2230.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2230.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2231</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2231.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2231.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2231.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2231.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2231.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2231.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2232</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2232.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2232.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2232.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2232.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2232.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2232.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2233</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2233.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2233.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2233.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2233.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2233.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2233.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A0B</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A0B.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A0B.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A0B.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A0B.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A0B.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A0B.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A0C</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A0C.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A0C.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A0C.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A0C.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A0C.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A0C.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A0D</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A0D.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A0D.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A0D.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A0D.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A0D.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A0D.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A0E</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A0E.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A0E.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A0E.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A0E.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A0E.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A0E.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A0F</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A0F.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A0F.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A0F.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A0F.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A0F.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A0F.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A10</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A10.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A10.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A10.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A10.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A10.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A10.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A11</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A11.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A11.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A11.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A11.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A11.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A11.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A12</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A12.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A12.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A12.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A12.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A12.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A12.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A13</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A13.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A13.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A13.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A13.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A13.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A13.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A14</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A14.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A14.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A14.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A14.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A14.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A14.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A15</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A15.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A15.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A15.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A15.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A15.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A15.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A16</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A16.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A16.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A16.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A16.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A16.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A16.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A17</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A17.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A17.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A17.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A17.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A17.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A17.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A18</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A18.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A18.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A18.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A18.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A18.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A18.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A19</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A19.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A19.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A19.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A19.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A19.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A19.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A1A</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A1A.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A1A.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A1A.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A1A.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A1A.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A1A.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A1B</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A1B.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A1B.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A1B.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A1B.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A1B.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A1B.up.display</key>\n\t\t<integer>140</integer>\n\t\t<key>uni2A1C</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A1C.display</key>\n\t\t<integer>300</integer>\n\t\t<key>uni2A1C.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A1C.rtlm.display</key>\n\t\t<integer>300</integer>\n\t\t<key>uni2A1C.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A1C.up</key>\n\t\t<integer>50</integer>\n\t\t<key>uni2A1C.up.display</key>\n\t\t<integer>-200</integer>\n\t\t<key>y</key>\n\t\t<integer>20</integer>\n\t</dict>\n\t<key>v_assembly</key>\n\t<dict>\n\t\t<key>bar</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>879</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>400</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>bar</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>879</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>bar</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>400</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>braceleft</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>600</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A9</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>200</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23AA</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>600</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>200</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A8</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>200</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>600</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23AA</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>200</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A7</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>600</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>braceright</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>600</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23AD</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>200</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23AA</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>600</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>200</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23AC</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>200</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>600</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23AA</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>200</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23AB</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>600</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>bracketleft</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>950</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A3</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>500</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A2</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>500</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A1</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>950</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>bracketright</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>950</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A6</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>500</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A5</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>500</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A4</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>950</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>parenleft</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>150</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni239D</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>150</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni239C</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>150</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni239B</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>150</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>parenright</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>150</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A0</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>150</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni239F</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>150</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni239E</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>150</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni2016</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>879</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>400</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2016</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>879</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2016</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>400</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni2191</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23D0</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2191</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni2193</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2193</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23D0</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni2195</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2193</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23D0</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2191</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni21BE</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23D0</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni21BE</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni21BF</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23D0</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni21BF</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni21C2</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni21C2</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23D0</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni21C3</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni21C3</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23D0</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni21D1</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni21D1.ex</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni21D1</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni21D3</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni21D3</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni21D1.ex</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni21D5</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni21D3</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni21D1.ex</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni21D1</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni221A</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1855</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>600</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23B7</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>635</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>300</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni221A.ex</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>300</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>626</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni221A.top</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>500</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni221A.rtlm</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1855</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>600</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni221A.rtlm.bot</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>635</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>300</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni221A.rtlm.ex</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>300</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>626</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni221A.rtlm.top</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>500</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni221B</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1855</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>600</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni221B.base</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>635</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>300</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni221A.ex</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>300</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>626</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni221A.top</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>500</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni221C</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1855</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>600</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni221C.base</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>635</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>300</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni221A.ex</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>300</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>626</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni221A.top</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>600</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni2223</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>879</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>293</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2223</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>293</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>879</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>293</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2223</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>293</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni2225</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>879</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>293</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2225</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>293</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>879</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>293</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2225</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>293</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni2308</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>337</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A2</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>337</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>335</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A1</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>335</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni2309</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>337</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A5</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>337</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>335</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A4</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>335</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni230A</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>335</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A3</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>335</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>337</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A2</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>337</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni230B</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>335</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A6</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>335</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>337</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A5</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>337</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni23B0</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23AD</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23AA</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A7</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni23B1</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A9</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23AA</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23AB</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni27EE</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni239D</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni239C</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni239B</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni27EF</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A0</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni239F</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni239E</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni27F0</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni27F0.ex</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni27F0</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni27F1</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni27F1</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni27F0.ex</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni290A</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni290A.ex</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni290A</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni290B</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni290B</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni290A.ex</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni2980</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>879</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>400</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2980</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>879</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2980</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>400</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni2AF4</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>884</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>295</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2AF4</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>295</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>884</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>295</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2AF4</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>295</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t</dict>\n\t<key>v_variants</key>\n\t<dict>\n\t\t<key>uni232A</key>\n\t\t<array>\n\t\t\t<string>uni232A</string>\n\t\t\t<string>uni27E9.size1</string>\n\t\t\t<string>uni27E9.size2</string>\n\t\t\t<string>uni27E9.size3</string>\n\t\t\t<string>uni27E9.size4</string>\n\t\t</array>\n\t\t<key>uni2329</key>\n\t\t<array>\n\t\t\t<string>uni2329</string>\n\t\t\t<string>uni27E8.size1</string>\n\t\t\t<string>uni27E8.size2</string>\n\t\t\t<string>uni27E8.size3</string>\n\t\t\t<string>uni27E8.size4</string>\n\t\t</array>\n\t\t<key>backslash</key>\n\t\t<array>\n\t\t\t<string>backslash</string>\n\t\t\t<string>backslash.size1</string>\n\t\t\t<string>backslash.size2</string>\n\t\t\t<string>backslash.size3</string>\n\t\t\t<string>backslash.size4</string>\n\t\t</array>\n\t\t<key>bar</key>\n\t\t<array>\n\t\t\t<string>bar</string>\n\t\t\t<string>bar.size1</string>\n\t\t\t<string>bar.size2</string>\n\t\t\t<string>bar.size3</string>\n\t\t\t<string>bar.size4</string>\n\t\t</array>\n\t\t<key>braceleft</key>\n\t\t<array>\n\t\t\t<string>braceleft</string>\n\t\t\t<string>braceleft.size1</string>\n\t\t\t<string>braceleft.size2</string>\n\t\t\t<string>braceleft.size3</string>\n\t\t\t<string>braceleft.size4</string>\n\t\t</array>\n\t\t<key>braceright</key>\n\t\t<array>\n\t\t\t<string>braceright</string>\n\t\t\t<string>braceright.size1</string>\n\t\t\t<string>braceright.size2</string>\n\t\t\t<string>braceright.size3</string>\n\t\t\t<string>braceright.size4</string>\n\t\t</array>\n\t\t<key>bracketleft</key>\n\t\t<array>\n\t\t\t<string>bracketleft</string>\n\t\t\t<string>bracketleft.size1</string>\n\t\t\t<string>bracketleft.size2</string>\n\t\t\t<string>bracketleft.size3</string>\n\t\t\t<string>bracketleft.size4</string>\n\t\t</array>\n\t\t<key>bracketright</key>\n\t\t<array>\n\t\t\t<string>bracketright</string>\n\t\t\t<string>bracketright.size1</string>\n\t\t\t<string>bracketright.size2</string>\n\t\t\t<string>bracketright.size3</string>\n\t\t\t<string>bracketright.size4</string>\n\t\t</array>\n\t\t<key>fraction</key>\n\t\t<array>\n\t\t\t<string>fraction</string>\n\t\t\t<string>slash.size1</string>\n\t\t\t<string>slash.size2</string>\n\t\t\t<string>slash.size3</string>\n\t\t\t<string>slash.size4</string>\n\t\t</array>\n\t\t<key>parenleft</key>\n\t\t<array>\n\t\t\t<string>parenleft</string>\n\t\t\t<string>parenleft.size1</string>\n\t\t\t<string>parenleft.size2</string>\n\t\t\t<string>parenleft.size3</string>\n\t\t\t<string>parenleft.size4</string>\n\t\t</array>\n\t\t<key>parenright</key>\n\t\t<array>\n\t\t\t<string>parenright</string>\n\t\t\t<string>parenright.size1</string>\n\t\t\t<string>parenright.size2</string>\n\t\t\t<string>parenright.size3</string>\n\t\t\t<string>parenright.size4</string>\n\t\t</array>\n\t\t<key>slash</key>\n\t\t<array>\n\t\t\t<string>slash</string>\n\t\t\t<string>slash.size1</string>\n\t\t\t<string>slash.size2</string>\n\t\t\t<string>slash.size3</string>\n\t\t\t<string>slash.size4</string>\n\t\t</array>\n\t\t<key>uni0338</key>\n\t\t<array>\n\t\t\t<string>uni0338</string>\n\t\t\t<string>uni0338.size1</string>\n\t\t\t<string>uni0338.size2</string>\n\t\t\t<string>uni0338.size3</string>\n\t\t\t<string>uni0338.size4</string>\n\t\t\t<string>uni0338.size5</string>\n\t\t\t<string>uni0338.size6</string>\n\t\t</array>\n\t\t<key>uni0606</key>\n\t\t<array>\n\t\t\t<string>uni0606</string>\n\t\t\t<string>uni0606.size1</string>\n\t\t\t<string>uni0606.size2</string>\n\t\t\t<string>uni0606.size3</string>\n\t\t</array>\n\t\t<key>uni0607</key>\n\t\t<array>\n\t\t\t<string>uni0607</string>\n\t\t\t<string>uni0607.size1</string>\n\t\t\t<string>uni0607.size2</string>\n\t\t\t<string>uni0607.size3</string>\n\t\t</array>\n\t\t<key>uni2016</key>\n\t\t<array>\n\t\t\t<string>uni2016</string>\n\t\t\t<string>uni2016.size1</string>\n\t\t\t<string>uni2016.size2</string>\n\t\t\t<string>uni2016.size3</string>\n\t\t\t<string>uni2016.size4</string>\n\t\t</array>\n\t\t<key>uni20D2</key>\n\t\t<array>\n\t\t\t<string>uni20D2</string>\n\t\t\t<string>uni20D2.size1</string>\n\t\t\t<string>uni20D2.size2</string>\n\t\t\t<string>uni20D2.size3</string>\n\t\t\t<string>uni20D2.size4</string>\n\t\t\t<string>uni20D2.size5</string>\n\t\t\t<string>uni20D2.size6</string>\n\t\t</array>\n\t\t<key>uni2140</key>\n\t\t<array>\n\t\t\t<string>uni2140</string>\n\t\t\t<string>uni2140.display</string>\n\t\t</array>\n\t\t<key>uni2140.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2140.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2191</key>\n\t\t<array/>\n\t\t<key>uni2193</key>\n\t\t<array/>\n\t\t<key>uni2195</key>\n\t\t<array/>\n\t\t<key>uni21BE</key>\n\t\t<array/>\n\t\t<key>uni21BF</key>\n\t\t<array/>\n\t\t<key>uni21C2</key>\n\t\t<array/>\n\t\t<key>uni21C3</key>\n\t\t<array/>\n\t\t<key>uni21D1</key>\n\t\t<array/>\n\t\t<key>uni21D3</key>\n\t\t<array/>\n\t\t<key>uni21D5</key>\n\t\t<array/>\n\t\t<key>uni220F</key>\n\t\t<array>\n\t\t\t<string>uni220F</string>\n\t\t\t<string>uni220F.display</string>\n\t\t</array>\n\t\t<key>uni2210</key>\n\t\t<array>\n\t\t\t<string>uni2210</string>\n\t\t\t<string>uni2210.display</string>\n\t\t</array>\n\t\t<key>uni2211</key>\n\t\t<array>\n\t\t\t<string>uni2211</string>\n\t\t\t<string>uni2211.display</string>\n\t\t</array>\n\t\t<key>uni2211.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2211.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni221A</key>\n\t\t<array>\n\t\t\t<string>uni221A</string>\n\t\t\t<string>uni221A.size1</string>\n\t\t\t<string>uni221A.size2</string>\n\t\t\t<string>uni221A.size3</string>\n\t\t</array>\n\t\t<key>uni221A.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni221A.rtlm.size1</string>\n\t\t\t<string>uni221A.rtlm.size2</string>\n\t\t\t<string>uni221A.rtlm.size3</string>\n\t\t</array>\n\t\t<key>uni221B</key>\n\t\t<array>\n\t\t\t<string>uni221B</string>\n\t\t\t<string>uni221B.size1</string>\n\t\t\t<string>uni221B.size2</string>\n\t\t\t<string>uni221B.size3</string>\n\t\t</array>\n\t\t<key>uni221B.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni221B.rtlm.size1</string>\n\t\t\t<string>uni221B.rtlm.size2</string>\n\t\t\t<string>uni221B.rtlm.size3</string>\n\t\t</array>\n\t\t<key>uni221C</key>\n\t\t<array>\n\t\t\t<string>uni221C</string>\n\t\t\t<string>uni221C.size1</string>\n\t\t\t<string>uni221C.size2</string>\n\t\t\t<string>uni221C.size3</string>\n\t\t</array>\n\t\t<key>uni221C.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni221C.rtlm.size1</string>\n\t\t\t<string>uni221C.rtlm.size2</string>\n\t\t\t<string>uni221C.rtlm.size3</string>\n\t\t</array>\n\t\t<key>uni2223</key>\n\t\t<array/>\n\t\t<key>uni2225</key>\n\t\t<array/>\n\t\t<key>uni222B</key>\n\t\t<array>\n\t\t\t<string>uni222B</string>\n\t\t\t<string>uni222B.display</string>\n\t\t</array>\n\t\t<key>uni222B.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni222B.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni222B.up</key>\n\t\t<array>\n\t\t\t<string>uni222B.up</string>\n\t\t\t<string>uni222B.up.display</string>\n\t\t</array>\n\t\t<key>uni222C</key>\n\t\t<array>\n\t\t\t<string>uni222C</string>\n\t\t\t<string>uni222C.display</string>\n\t\t</array>\n\t\t<key>uni222C.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni222C.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni222C.up</key>\n\t\t<array>\n\t\t\t<string>uni222C.up</string>\n\t\t\t<string>uni222C.up.display</string>\n\t\t</array>\n\t\t<key>uni222D</key>\n\t\t<array>\n\t\t\t<string>uni222D</string>\n\t\t\t<string>uni222D.display</string>\n\t\t</array>\n\t\t<key>uni222D.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni222D.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni222D.up</key>\n\t\t<array>\n\t\t\t<string>uni222D.up</string>\n\t\t\t<string>uni222D.up.display</string>\n\t\t</array>\n\t\t<key>uni222E</key>\n\t\t<array>\n\t\t\t<string>uni222E</string>\n\t\t\t<string>uni222E.display</string>\n\t\t</array>\n\t\t<key>uni222E.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni222E.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni222E.up</key>\n\t\t<array>\n\t\t\t<string>uni222E.up</string>\n\t\t\t<string>uni222E.up.display</string>\n\t\t</array>\n\t\t<key>uni222F</key>\n\t\t<array>\n\t\t\t<string>uni222F</string>\n\t\t\t<string>uni222F.display</string>\n\t\t</array>\n\t\t<key>uni222F.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni222F.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni222F.up</key>\n\t\t<array>\n\t\t\t<string>uni222F.up</string>\n\t\t\t<string>uni222F.up.display</string>\n\t\t</array>\n\t\t<key>uni2230</key>\n\t\t<array>\n\t\t\t<string>uni2230</string>\n\t\t\t<string>uni2230.display</string>\n\t\t</array>\n\t\t<key>uni2230.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2230.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2230.up</key>\n\t\t<array>\n\t\t\t<string>uni2230.up</string>\n\t\t\t<string>uni2230.up.display</string>\n\t\t</array>\n\t\t<key>uni2231</key>\n\t\t<array>\n\t\t\t<string>uni2231</string>\n\t\t\t<string>uni2231.display</string>\n\t\t</array>\n\t\t<key>uni2231.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2231.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2231.up</key>\n\t\t<array>\n\t\t\t<string>uni2231.up</string>\n\t\t\t<string>uni2231.up.display</string>\n\t\t</array>\n\t\t<key>uni2232</key>\n\t\t<array>\n\t\t\t<string>uni2232</string>\n\t\t\t<string>uni2232.display</string>\n\t\t</array>\n\t\t<key>uni2232.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2232.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2232.up</key>\n\t\t<array>\n\t\t\t<string>uni2232.up</string>\n\t\t\t<string>uni2232.up.display</string>\n\t\t</array>\n\t\t<key>uni2233</key>\n\t\t<array>\n\t\t\t<string>uni2233</string>\n\t\t\t<string>uni2233.display</string>\n\t\t</array>\n\t\t<key>uni2233.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2233.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2233.up</key>\n\t\t<array>\n\t\t\t<string>uni2233.up</string>\n\t\t\t<string>uni2233.up.display</string>\n\t\t</array>\n\t\t<key>uni22C0</key>\n\t\t<array>\n\t\t\t<string>uni22C0</string>\n\t\t\t<string>uni22C0.display</string>\n\t\t</array>\n\t\t<key>uni22C1</key>\n\t\t<array>\n\t\t\t<string>uni22C1</string>\n\t\t\t<string>uni22C1.display</string>\n\t\t</array>\n\t\t<key>uni22C2</key>\n\t\t<array>\n\t\t\t<string>uni22C2</string>\n\t\t\t<string>uni22C2.display</string>\n\t\t</array>\n\t\t<key>uni22C3</key>\n\t\t<array>\n\t\t\t<string>uni22C3</string>\n\t\t\t<string>uni22C3.display</string>\n\t\t</array>\n\t\t<key>uni2308</key>\n\t\t<array>\n\t\t\t<string>uni2308</string>\n\t\t\t<string>uni2308.size1</string>\n\t\t\t<string>uni2308.size2</string>\n\t\t\t<string>uni2308.size3</string>\n\t\t\t<string>uni2308.size4</string>\n\t\t</array>\n\t\t<key>uni2309</key>\n\t\t<array>\n\t\t\t<string>uni2309</string>\n\t\t\t<string>uni2309.size1</string>\n\t\t\t<string>uni2309.size2</string>\n\t\t\t<string>uni2309.size3</string>\n\t\t\t<string>uni2309.size4</string>\n\t\t</array>\n\t\t<key>uni230A</key>\n\t\t<array>\n\t\t\t<string>uni230A</string>\n\t\t\t<string>uni230A.size1</string>\n\t\t\t<string>uni230A.size2</string>\n\t\t\t<string>uni230A.size3</string>\n\t\t\t<string>uni230A.size4</string>\n\t\t</array>\n\t\t<key>uni230B</key>\n\t\t<array>\n\t\t\t<string>uni230B</string>\n\t\t\t<string>uni230B.size1</string>\n\t\t\t<string>uni230B.size2</string>\n\t\t\t<string>uni230B.size3</string>\n\t\t\t<string>uni230B.size4</string>\n\t\t</array>\n\t\t<key>uni23B0</key>\n\t\t<array>\n\t\t\t<string>uni23B0</string>\n\t\t</array>\n\t\t<key>uni23B1</key>\n\t\t<array>\n\t\t\t<string>uni23B1</string>\n\t\t</array>\n\t\t<key>uni2772</key>\n\t\t<array>\n\t\t\t<string>uni2772</string>\n\t\t\t<string>uni2772.size1</string>\n\t\t\t<string>uni2772.size2</string>\n\t\t\t<string>uni2772.size3</string>\n\t\t\t<string>uni2772.size4</string>\n\t\t</array>\n\t\t<key>uni2773</key>\n\t\t<array>\n\t\t\t<string>uni2773</string>\n\t\t\t<string>uni2773.size1</string>\n\t\t\t<string>uni2773.size2</string>\n\t\t\t<string>uni2773.size3</string>\n\t\t\t<string>uni2773.size4</string>\n\t\t</array>\n\t\t<key>uni27E6</key>\n\t\t<array>\n\t\t\t<string>uni27E6</string>\n\t\t\t<string>uni27E6.size1</string>\n\t\t\t<string>uni27E6.size2</string>\n\t\t\t<string>uni27E6.size3</string>\n\t\t\t<string>uni27E6.size4</string>\n\t\t</array>\n\t\t<key>uni27E7</key>\n\t\t<array>\n\t\t\t<string>uni27E7</string>\n\t\t\t<string>uni27E7.size1</string>\n\t\t\t<string>uni27E7.size2</string>\n\t\t\t<string>uni27E7.size3</string>\n\t\t\t<string>uni27E7.size4</string>\n\t\t</array>\n\t\t<key>uni27E8</key>\n\t\t<array>\n\t\t\t<string>uni27E8</string>\n\t\t\t<string>uni27E8.size1</string>\n\t\t\t<string>uni27E8.size2</string>\n\t\t\t<string>uni27E8.size3</string>\n\t\t\t<string>uni27E8.size4</string>\n\t\t</array>\n\t\t<key>uni27E9</key>\n\t\t<array>\n\t\t\t<string>uni27E9</string>\n\t\t\t<string>uni27E9.size1</string>\n\t\t\t<string>uni27E9.size2</string>\n\t\t\t<string>uni27E9.size3</string>\n\t\t\t<string>uni27E9.size4</string>\n\t\t</array>\n\t\t<key>uni27EA</key>\n\t\t<array>\n\t\t\t<string>uni27EA</string>\n\t\t\t<string>uni27EA.size1</string>\n\t\t\t<string>uni27EA.size2</string>\n\t\t\t<string>uni27EA.size3</string>\n\t\t\t<string>uni27EA.size4</string>\n\t\t</array>\n\t\t<key>uni27EB</key>\n\t\t<array>\n\t\t\t<string>uni27EB</string>\n\t\t\t<string>uni27EB.size1</string>\n\t\t\t<string>uni27EB.size2</string>\n\t\t\t<string>uni27EB.size3</string>\n\t\t\t<string>uni27EB.size4</string>\n\t\t</array>\n\t\t<key>uni27EE</key>\n\t\t<array>\n\t\t\t<string>uni27EE</string>\n\t\t</array>\n\t\t<key>uni27EF</key>\n\t\t<array>\n\t\t\t<string>uni27EF</string>\n\t\t</array>\n\t\t<key>uni27F0</key>\n\t\t<array/>\n\t\t<key>uni27F1</key>\n\t\t<array/>\n\t\t<key>uni290A</key>\n\t\t<array/>\n\t\t<key>uni290B</key>\n\t\t<array/>\n\t\t<key>uni2980</key>\n\t\t<array>\n\t\t\t<string>uni2980</string>\n\t\t\t<string>uni2980.size1</string>\n\t\t\t<string>uni2980.size2</string>\n\t\t\t<string>uni2980.size3</string>\n\t\t\t<string>uni2980.size4</string>\n\t\t</array>\n\t\t<key>uni2983</key>\n\t\t<array>\n\t\t\t<string>uni2983</string>\n\t\t\t<string>uni2983.size1</string>\n\t\t\t<string>uni2983.size2</string>\n\t\t\t<string>uni2983.size3</string>\n\t\t\t<string>uni2983.size4</string>\n\t\t</array>\n\t\t<key>uni2984</key>\n\t\t<array>\n\t\t\t<string>uni2984</string>\n\t\t\t<string>uni2984.size1</string>\n\t\t\t<string>uni2984.size2</string>\n\t\t\t<string>uni2984.size3</string>\n\t\t\t<string>uni2984.size4</string>\n\t\t</array>\n\t\t<key>uni2985</key>\n\t\t<array>\n\t\t\t<string>uni2985</string>\n\t\t\t<string>uni2985.size1</string>\n\t\t\t<string>uni2985.size2</string>\n\t\t\t<string>uni2985.size3</string>\n\t\t\t<string>uni2985.size4</string>\n\t\t</array>\n\t\t<key>uni2986</key>\n\t\t<array>\n\t\t\t<string>uni2986</string>\n\t\t\t<string>uni2986.size1</string>\n\t\t\t<string>uni2986.size2</string>\n\t\t\t<string>uni2986.size3</string>\n\t\t\t<string>uni2986.size4</string>\n\t\t</array>\n\t\t<key>uni29F8</key>\n\t\t<array>\n\t\t\t<string>uni29F8</string>\n\t\t\t<string>uni29F8.size1</string>\n\t\t</array>\n\t\t<key>uni29F9</key>\n\t\t<array>\n\t\t\t<string>uni29F9</string>\n\t\t\t<string>uni29F9.size1</string>\n\t\t</array>\n\t\t<key>uni2A00</key>\n\t\t<array>\n\t\t\t<string>uni2A00</string>\n\t\t\t<string>uni2A00.display</string>\n\t\t</array>\n\t\t<key>uni2A01</key>\n\t\t<array>\n\t\t\t<string>uni2A01</string>\n\t\t\t<string>uni2A01.display</string>\n\t\t</array>\n\t\t<key>uni2A02</key>\n\t\t<array>\n\t\t\t<string>uni2A02</string>\n\t\t\t<string>uni2A02.display</string>\n\t\t</array>\n\t\t<key>uni2A03</key>\n\t\t<array>\n\t\t\t<string>uni2A03</string>\n\t\t\t<string>uni2A03.display</string>\n\t\t</array>\n\t\t<key>uni2A04</key>\n\t\t<array>\n\t\t\t<string>uni2A04</string>\n\t\t\t<string>uni2A04.display</string>\n\t\t</array>\n\t\t<key>uni2A05</key>\n\t\t<array>\n\t\t\t<string>uni2A05</string>\n\t\t\t<string>uni2A05.display</string>\n\t\t</array>\n\t\t<key>uni2A06</key>\n\t\t<array>\n\t\t\t<string>uni2A06</string>\n\t\t\t<string>uni2A06.display</string>\n\t\t</array>\n\t\t<key>uni2A07</key>\n\t\t<array>\n\t\t\t<string>uni2A07</string>\n\t\t\t<string>uni2A07.display</string>\n\t\t</array>\n\t\t<key>uni2A08</key>\n\t\t<array>\n\t\t\t<string>uni2A08</string>\n\t\t\t<string>uni2A08.display</string>\n\t\t</array>\n\t\t<key>uni2A09</key>\n\t\t<array>\n\t\t\t<string>uni2A09</string>\n\t\t\t<string>uni2A09.display</string>\n\t\t</array>\n\t\t<key>uni2A0A</key>\n\t\t<array>\n\t\t\t<string>uni2A0A</string>\n\t\t\t<string>uni2A0A.display</string>\n\t\t</array>\n\t\t<key>uni2A0A.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A0A.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A0B</key>\n\t\t<array>\n\t\t\t<string>uni2A0B</string>\n\t\t\t<string>uni2A0B.display</string>\n\t\t</array>\n\t\t<key>uni2A0B.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A0B.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A0B.up</key>\n\t\t<array>\n\t\t\t<string>uni2A0B.up</string>\n\t\t\t<string>uni2A0B.up.display</string>\n\t\t</array>\n\t\t<key>uni2A0C</key>\n\t\t<array>\n\t\t\t<string>uni2A0C</string>\n\t\t\t<string>uni2A0C.display</string>\n\t\t</array>\n\t\t<key>uni2A0C.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A0C.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A0C.up</key>\n\t\t<array>\n\t\t\t<string>uni2A0C.up</string>\n\t\t\t<string>uni2A0C.up.display</string>\n\t\t</array>\n\t\t<key>uni2A0D</key>\n\t\t<array>\n\t\t\t<string>uni2A0D</string>\n\t\t\t<string>uni2A0D.display</string>\n\t\t</array>\n\t\t<key>uni2A0D.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A0D.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A0D.up</key>\n\t\t<array>\n\t\t\t<string>uni2A0D.up</string>\n\t\t\t<string>uni2A0D.up.display</string>\n\t\t</array>\n\t\t<key>uni2A0E</key>\n\t\t<array>\n\t\t\t<string>uni2A0E</string>\n\t\t\t<string>uni2A0E.display</string>\n\t\t</array>\n\t\t<key>uni2A0E.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A0E.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A0E.up</key>\n\t\t<array>\n\t\t\t<string>uni2A0E.up</string>\n\t\t\t<string>uni2A0E.up.display</string>\n\t\t</array>\n\t\t<key>uni2A0F</key>\n\t\t<array>\n\t\t\t<string>uni2A0F</string>\n\t\t\t<string>uni2A0F.display</string>\n\t\t</array>\n\t\t<key>uni2A0F.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A0F.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A0F.up</key>\n\t\t<array>\n\t\t\t<string>uni2A0F.up</string>\n\t\t\t<string>uni2A0F.up.display</string>\n\t\t</array>\n\t\t<key>uni2A10</key>\n\t\t<array>\n\t\t\t<string>uni2A10</string>\n\t\t\t<string>uni2A10.display</string>\n\t\t</array>\n\t\t<key>uni2A10.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A10.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A10.up</key>\n\t\t<array>\n\t\t\t<string>uni2A10.up</string>\n\t\t\t<string>uni2A10.up.display</string>\n\t\t</array>\n\t\t<key>uni2A11</key>\n\t\t<array>\n\t\t\t<string>uni2A11</string>\n\t\t\t<string>uni2A11.display</string>\n\t\t</array>\n\t\t<key>uni2A11.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A11.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A11.up</key>\n\t\t<array>\n\t\t\t<string>uni2A11.up</string>\n\t\t\t<string>uni2A11.up.display</string>\n\t\t</array>\n\t\t<key>uni2A12</key>\n\t\t<array>\n\t\t\t<string>uni2A12</string>\n\t\t\t<string>uni2A12.display</string>\n\t\t</array>\n\t\t<key>uni2A12.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A12.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A12.up</key>\n\t\t<array>\n\t\t\t<string>uni2A12.up</string>\n\t\t\t<string>uni2A12.up.display</string>\n\t\t</array>\n\t\t<key>uni2A13</key>\n\t\t<array>\n\t\t\t<string>uni2A13</string>\n\t\t\t<string>uni2A13.display</string>\n\t\t</array>\n\t\t<key>uni2A13.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A13.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A13.up</key>\n\t\t<array>\n\t\t\t<string>uni2A13.up</string>\n\t\t\t<string>uni2A13.up.display</string>\n\t\t</array>\n\t\t<key>uni2A14</key>\n\t\t<array>\n\t\t\t<string>uni2A14</string>\n\t\t\t<string>uni2A14.display</string>\n\t\t</array>\n\t\t<key>uni2A14.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A14.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A14.up</key>\n\t\t<array>\n\t\t\t<string>uni2A14.up</string>\n\t\t\t<string>uni2A14.up.display</string>\n\t\t</array>\n\t\t<key>uni2A15</key>\n\t\t<array>\n\t\t\t<string>uni2A15</string>\n\t\t\t<string>uni2A15.display</string>\n\t\t</array>\n\t\t<key>uni2A15.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A15.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A15.up</key>\n\t\t<array>\n\t\t\t<string>uni2A15.up</string>\n\t\t\t<string>uni2A15.up.display</string>\n\t\t</array>\n\t\t<key>uni2A16</key>\n\t\t<array>\n\t\t\t<string>uni2A16</string>\n\t\t\t<string>uni2A16.display</string>\n\t\t</array>\n\t\t<key>uni2A16.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A16.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A16.up</key>\n\t\t<array>\n\t\t\t<string>uni2A16.up</string>\n\t\t\t<string>uni2A16.up.display</string>\n\t\t</array>\n\t\t<key>uni2A17</key>\n\t\t<array>\n\t\t\t<string>uni2A17</string>\n\t\t\t<string>uni2A17.display</string>\n\t\t</array>\n\t\t<key>uni2A17.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A17.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A17.up</key>\n\t\t<array>\n\t\t\t<string>uni2A17.up</string>\n\t\t\t<string>uni2A17.up.display</string>\n\t\t</array>\n\t\t<key>uni2A18</key>\n\t\t<array>\n\t\t\t<string>uni2A18</string>\n\t\t\t<string>uni2A18.display</string>\n\t\t</array>\n\t\t<key>uni2A18.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A18.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A18.up</key>\n\t\t<array>\n\t\t\t<string>uni2A18.up</string>\n\t\t\t<string>uni2A18.up.display</string>\n\t\t</array>\n\t\t<key>uni2A19</key>\n\t\t<array>\n\t\t\t<string>uni2A19</string>\n\t\t\t<string>uni2A19.display</string>\n\t\t</array>\n\t\t<key>uni2A19.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A19.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A19.up</key>\n\t\t<array>\n\t\t\t<string>uni2A19.up</string>\n\t\t\t<string>uni2A19.up.display</string>\n\t\t</array>\n\t\t<key>uni2A1A</key>\n\t\t<array>\n\t\t\t<string>uni2A1A</string>\n\t\t\t<string>uni2A1A.display</string>\n\t\t</array>\n\t\t<key>uni2A1A.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A1A.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A1A.up</key>\n\t\t<array>\n\t\t\t<string>uni2A1A.up</string>\n\t\t\t<string>uni2A1A.up.display</string>\n\t\t</array>\n\t\t<key>uni2A1B</key>\n\t\t<array>\n\t\t\t<string>uni2A1B</string>\n\t\t\t<string>uni2A1B.display</string>\n\t\t</array>\n\t\t<key>uni2A1B.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A1B.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A1B.up</key>\n\t\t<array>\n\t\t\t<string>uni2A1B.up</string>\n\t\t\t<string>uni2A1B.up.display</string>\n\t\t</array>\n\t\t<key>uni2A1C</key>\n\t\t<array>\n\t\t\t<string>uni2A1C</string>\n\t\t\t<string>uni2A1C.display</string>\n\t\t</array>\n\t\t<key>uni2A1C.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A1C.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A1C.up</key>\n\t\t<array>\n\t\t\t<string>uni2A1C.up</string>\n\t\t\t<string>uni2A1C.up.display</string>\n\t\t</array>\n\t\t<key>uni2AF4</key>\n\t\t<array/>\n\t\t<key>uni2AFC</key>\n\t\t<array>\n\t\t\t<string>uni2AFC</string>\n\t\t\t<string>uni2AFC.display</string>\n\t\t</array>\n\t\t<key>uni2AFF</key>\n\t\t<array>\n\t\t\t<string>uni2AFF</string>\n\t\t\t<string>uni2AFF.display</string>\n\t\t</array>\n\t</dict>\n\t<key>version</key>\n\t<string>1.3</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "iOS/AntMarkdown/Scripts/inject.ini",
    "content": "AntOptimizer"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMAttributeRun.h",
    "content": "//\n//  CMAttributeRun.h\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/15/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n#import \"CMPlatformDefines.h\"\n\n@class CMStyleAttributes;\n\n@interface CMAttributeRun : NSObject\n@property (nonatomic, readonly) CMStyleAttributes *attributes;\n@property (nonatomic) NSInteger orderedListItemNumber;\n@property (nonatomic, readonly) BOOL listTight;\n\n- (instancetype)initWithAttributes:(CMStyleAttributes *)attributes\n                 orderedListNumber:(NSInteger)orderedListNumber;\n\n@end\n\nCMAttributeRun * CMDefaultAttributeRun(CMStyleAttributes *attributes);\nCMAttributeRun * CMOrderedListAttributeRun(CMStyleAttributes *attributes, NSInteger startingNumber);\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMAttributeRun.m",
    "content": "//\n//  CMAttributeRun.m\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/15/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import \"CMAttributeRun.h\"\n\nCMAttributeRun * CMDefaultAttributeRun(CMStyleAttributes *attributes)\n{\n    return [[CMAttributeRun alloc] initWithAttributes:attributes orderedListNumber:0];\n}\n\nCMAttributeRun * CMOrderedListAttributeRun(CMStyleAttributes *attributes, NSInteger startingNumber)\n{\n    return [[CMAttributeRun alloc] initWithAttributes:attributes orderedListNumber:startingNumber];\n}\n\n@implementation CMAttributeRun\n\n- (instancetype)initWithAttributes:(CMStyleAttributes *)attributes\n                 orderedListNumber:(NSInteger)orderedListNumber\n{\n    if ((self = [super init])) {\n        _attributes = attributes;\n        _orderedListItemNumber = orderedListNumber;\n    }\n    return self;\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMAttributedStringRenderer.h",
    "content": "//\n//  CMAttributedStringRenderer.h\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/14/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n#import \"CMNode.h\"\n\n@class CMDocument;\n@class CMTextAttributes;\n@protocol CMHTMLElementTransformer;\n\n@protocol CMAttributedStringRendererDelegate <NSObject>\n/**\n *  Notify the infos of all clickable elements.\n *\n *  @param dataArray   Contents of clickable elements that is visible .\n */\n-(void)notifyNodeUpdate:( NSArray* _Nonnull )dataArray;\n/**\n *  Notify the locations base on parent textView of all clickable elements.\n *\n *  @param dataArray   Locations of clickable elements that is visible .\n */\n-(void)notifyNodeLocation:(NSArray* _Nonnull )locArray;\n\n@end\n/**\n *  Renders an attributed string from a Markdown document\n */\n@interface CMAttributedStringRenderer : NSObject\n\n/**\n *  Designated initializer.\n *\n *  @param document   A Markdown document.\n *  @param attributes Attributes used to style the string.\n *\n *  @return An initialized instance of the receiver.\n */\n- (instancetype)initWithDocument:(CMDocument *)document attributes:(CMTextAttributes *)attributes;\n/**\n *  Designated initializer.\n *\n *  @param document   A Markdown document.\n *  @param attributes Attributes used to style the string.\n *  @param delegate Clickable elements info delegate.\n *\n *  @return An initialized instance of the receiver.\n */\n- (instancetype)initWithDocument:(CMDocument *)document attributes:(CMTextAttributes *)attributes delegate:(nullable id<CMAttributedStringRendererDelegate>)delegate;\n\n/**\n *  Registers a handler to transform HTML elements.\n *\n *  Only a single transformer can be registered for an element. If a transformer\n *  is already registered for an element, it will be replaced.\n *\n *  @param transformer The transformer to register.\n */\n- (void)registerHTMLElementTransformer:(id<CMHTMLElementTransformer>)transformer;\n\n/**\n *  Renders an attributed string from the Markdown document.\n *\n *  @return An attributed string containing the contents of the Markdown document,\n *  styled using the attributes set on the receiver.\n */\n- (NSAttributedString *)render;\n\n/**\n *  Get the clickable object infos.\n *\n *  @return An array that has all clickable object.\n */\n-(NSArray*)clickableObjs;\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMAttributedStringRenderer.m",
    "content": "//\n//  CMAttributedStringRenderer.m\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/14/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import \"CMAttributedStringRenderer.h\"\n#import \"CMAttributedStringRenderer_Private.h\"\n#import \"CMAttributeRun.h\"\n#import \"CMCascadingAttributeStack.h\"\n#import \"CMStack.h\"\n#import \"CMHTMLElementTransformer.h\"\n#import \"CMHTMLElement.h\"\n#import \"CMHTMLUtilities.h\"\n#import \"CMTextAttributes.h\"\n#import \"CMImageTextAttachment.h\"\n#import \"CMNode_Private.h\"\n#import \"CMParser.h\"\n#import \"CMHorizontalRuleAttachment.h\"\n#import \"AMTextBackground.h\"\n#import \"Ono.h\"\n#import \"AMEmojiManager.h\"\n#import \"CMTaskCheckAttachment+Private.h\"\n\n@implementation CMAttributedStringRenderer\n\n- (instancetype)initWithDocument:(CMDocument *)document attributes:(CMTextAttributes *)attributes\n{\n    if ((self = [super init])) {\n        _document = document;\n        _attributes = attributes;\n        _tagNameToTransformerMapping = [[NSMutableDictionary alloc] init];\n\n    }\n    return self;\n}\n- (instancetype)initWithDocument:(CMDocument *)document attributes:(CMTextAttributes *)attributes delegate:(nullable id<CMAttributedStringRendererDelegate>)delegate\n{\n    if ((self = [super init])) {\n        _document = document;\n        _attributes = attributes;\n        _tagNameToTransformerMapping = [[NSMutableDictionary alloc] init];\n        _delegate = delegate;\n    }\n    return self;\n}\n- (NSTextAttachment *)imageAttachmentWithURL:(NSURL *)url title:(NSString *)title\n{\n    return [[CMImageTextAttachment alloc] initWithImageURL:url title:title];\n}\n\n- (void)appendBulletString:(NSString *)string\n{\n    [self appendString:string];\n}\n\n- (void)registerHTMLElementTransformer:(id<CMHTMLElementTransformer>)transformer\n{\n    NSParameterAssert(transformer);\n    _tagNameToTransformerMapping[[transformer.class tagName]] = transformer;\n}\n\n- (NSAttributedString *)render\n{\n    if (_attributedString == nil) {\n        _attributeStack = [[CMCascadingAttributeStack alloc] init];\n        _HTMLStack = [[CMStack alloc] init];\n        _buffer = [[NSMutableAttributedString alloc] init];\n        \n        CMParser *parser = [[CMParser alloc] initWithDocument:_document delegate:self];\n        [parser parse];\n        \n        _attributedString = [_buffer copy];\n        _attributeStack = nil;\n        _HTMLStack = nil;\n        _buffer = nil;\n    }\n    \n    return _attributedString;\n}\n\n#pragma mark - CMParserDelegate\n\n- (void)parserDidStartDocument:(CMParser *)parser\n{\n    [_attributeStack pushAttributes:_attributes.baseTextAttributes];\n}\n\n- (void)parserDidEndDocument:(CMParser *)parser\n{\n    CFStringTrimWhitespace((__bridge CFMutableStringRef)_buffer.mutableString);\n}\n\n- (void)parser:(CMParser *)parser foundText:(NSString *)text\n{\n    if (! [self isImageDescriptionNode:parser.currentNode]) { // An image description text shall not be append to the current buffer\n        CMHTMLElement *element = [_HTMLStack peek];\n        if (element != nil) {\n            [element.buffer appendString:text];\n        } else {\n            [self appendString:text];\n        }\n    }\n}\n\n- (void)parser:(CMParser *)parser didStartHeaderWithLevel:(NSInteger)level\n{\n    [_attributeStack pushAttributes:[_attributes attributesForHeaderLevel:level]];\n}\n\n- (void)parser:(CMParser *)parser didEndHeaderWithLevel:(NSInteger)level\n{\n    [self closeBlockForNode:parser.currentNode];\n    [_attributeStack pop];\n}\n\n- (void)parserDidStartParagraph:(CMParser *)parser\n{\n    BOOL isInTightList = [self nodeIsInTightMode:parser.currentNode];\n    [_attributeStack pushAttributes:!isInTightList ? _attributes.paragraphAttributes : nil];\n    BOOL isInListItem = parser.currentNode.parent.type == CMNodeTypeItem;\n    if (isInListItem && parser.currentNode.previous != nil) {\n        CMStyleAttributes * parentAttributes = [_attributeStack attributesWithDepth:1];\n        NSString *prefix = parentAttributes.paragraphStyleAttributes[CMParagraphStyleAttributeListItemParagraphPrefix];\n        if (prefix) {\n            [self appendString:prefix];\n        }\n    }\n}\n\n- (void)parserDidEndParagraph:(CMParser *)parser\n{\n    CMHTMLElement *element = [_HTMLStack pop];\n    while (element) {\n        [element.buffer appendFormat:@\"</%@>\", element.tagName];\n        [self appendHTMLElement:element];\n        element = [_HTMLStack pop];\n    }\n    [self closeBlockForNode:parser.currentNode];\n    [_attributeStack pop];\n}\n\n- (void)parserDidStartEmphasis:(CMParser *)parser\n{\n    [_attributeStack pushAttributes:_attributes.emphasisAttributes];\n}\n\n- (void)parserDidEndEmphasis:(CMParser *)parser\n{\n    [_attributeStack pop];\n}\n\n- (void)parserDidStartStrong:(CMParser *)parser\n{\n    [_attributeStack pushAttributes:_attributes.strongAttributes];\n}\n\n- (void)parserDidEndStrong:(CMParser *)parse\n{\n    [_attributeStack pop];\n}\n\n- (void)parser:(CMParser *)parser didStartLinkWithURL:(NSURL *)URL title:(NSString *)title\n{\n    CMStyleAttributes * linkStyleAttributes = _attributes.linkAttributes.copy;\n    linkStyleAttributes.stringAttributes [NSLinkAttributeName] = URL;\n#if !TARGET_OS_IPHONE\n    if (title != nil) {\n        linkStyleAttributes.stringAttributes [NSToolTipAttributeName] = title;\n    }\n#endif\n    if ([linkStyleAttributes.stringAttributes[CMLinkBold] boolValue]) {\n        CMAttributeRun *parentRun = [_attributeStack peek];\n        CMStyleAttributes * parentAttributes = parentRun.attributes;\n        UIFont* font = parentAttributes.stringAttributes[NSFontAttributeName];\n        if (!font) {\n            font = self.attributes.paragraphAttributes.stringAttributes[NSFontAttributeName];\n        }\n        UIFont* linkFont = [UIFont systemFontOfSize:font.pointSize weight:UIFontWeightSemibold];\n            [linkStyleAttributes.stringAttributes addEntriesFromDictionary:@{NSFontAttributeName: linkFont}];\n    }\n    \n    [_attributeStack pushAttributes:linkStyleAttributes];\n}\n\n- (void)parser:(CMParser *)parser didEndLinkWithURL:(NSURL *)URL title:(NSString *)title\n{\n    [_attributeStack pop];\n    [self addClickableObjects:CMNodeTypeLink data:URL.absoluteString tag:@\"\"];\n}\n\n- (void)parser:(CMParser *)parser didStartImageWithURL:(NSURL *)URL title:(NSString *)title\n{\n    NSTextAttachment* textAttachment = [self imageAttachmentWithURL:URL title:title];\n    if (textAttachment != nil) {\n        // Detect if an image has its own paragraph, in which cas we can apply specific attributes.\n        // (Note: This test also detect the case: image in link in paragraph)\n        CMNode* imageNode = parser.currentNode;\n        BOOL isInImageParagraph = ((imageNode.next == nil) && (imageNode.previous == nil) \n                                   && ((imageNode.parent.type == CMNodeTypeParagraph) \n                                       || ((imageNode.parent.next == nil) && (imageNode.parent.previous == nil) && (imageNode.parent.parent.type == CMNodeTypeParagraph))));\n        \n        CMHTMLElement *element = [_HTMLStack peek];\n        if (element != nil) {\n            // TODO: how should we handle a markdown image inside HTML;? Is this possible????\n        } else {\n            CMStyleAttributes * imageAttachmentAttributes;\n            if (isInImageParagraph) {\n                imageAttachmentAttributes = _attributes.imageParagraphAttributes.copy;\n            }\n            else {\n                imageAttachmentAttributes = [CMStyleAttributes new];\n            }\n            imageAttachmentAttributes.stringAttributes[NSAttachmentAttributeName] = textAttachment;\n#if !TARGET_OS_IPHONE\n            CMNode *imageDescriptionNode = imageNode.firstChild;\n            if ((imageDescriptionNode.type == CMNodeTypeText) && (imageDescriptionNode.stringValue.length > 0)) {\n                imageAttachmentAttributes.stringAttributes [NSToolTipAttributeName] = imageDescriptionNode.stringValue;\n            }\n#endif     \n            [_attributeStack pushAttributes:imageAttachmentAttributes];\n            \n            const unichar attachmentChar = NSAttachmentCharacter;\n            [self appendString:[NSString stringWithCharacters:&attachmentChar length:1]];\n            \n            if (isInImageParagraph) {\n                [self closeBlockForNode:imageNode];\n            }\n        }\n    }\n}\n\n- (void)parser:(CMParser *)parser didEndImageWithURL:(NSURL *)URL title:(NSString *)title\n{\n    [_attributeStack pop];\n}\n\n- (void)parser:(CMParser *)parser foundHTML:(NSString *)HTML\n{\n    NSString *tagName = CMTagNameFromHTMLTag(HTML);\n    if (tagName.length != 0) {\n        CMHTMLElement *element = [self newHTMLElementForTagName:tagName HTML:HTML];\n        if (element != nil) {\n            [self appendHTMLElement:element];\n        }\n    }\n}\n\n- (void)parser:(CMParser *)parser foundInlineHTML:(NSString *)HTML\n{\n    NSString *tagName = CMTagNameFromHTMLTag(HTML);\n    if (tagName.length != 0) {\n        CMHTMLElement *element = nil;\n        if (CMIsHTMLVoidTagName(tagName)) {\n            element = [self newHTMLElementForTagName:tagName HTML:HTML];\n            if (element != nil) {\n                [self appendHTMLElement:element];\n            }\n        } else if (CMIsHTMLClosingTag(HTML)) {\n            if ((element = [_HTMLStack pop])) {\n                NSAssert([element.tagName isEqualToString:tagName], @\"Closing tag does not match opening tag\");\n                [element.buffer appendString:HTML];\n                [self appendHTMLElement:element];\n            }\n        } else if (CMIsHTMLTag(HTML)) {\n            element = [self newHTMLElementForTagName:tagName HTML:HTML];\n            if (element != nil) {\n                [_HTMLStack push:element];\n            }\n        }\n    }\n}\n\n- (void)parser:(CMParser *)parser foundEmoji:(NSString *)emoji {\n    NSString *emojiVal = [[AMEmojiManager sharedManager] emojiWithName:emoji];\n    if (emojiVal) {\n        [self appendString:emojiVal];\n    } else {\n        [self appendString:emoji];\n    }\n}\n\n- (void)parser:(CMParser *)parser foundCodeBlock:(NSString *)code info:(NSString *)info\n{\n    [_attributeStack pushAttributes:_attributes.codeBlockAttributes];\n    if ([code hasSuffix:@\"\\n\"]) {\n        code = [code substringToIndex:code.length - 1]; // Remove final \"\\n\"\n    }\n    NSString* const lineSeparatorCharacterString = @\"\\u2028\";\n    [self appendString:[code stringByReplacingOccurrencesOfString:@\"\\n\" withString:lineSeparatorCharacterString]];\n    [self closeBlockForNode:parser.currentNode];\n    [_attributeStack pop];\n}\n\n- (void)parser:(CMParser *)parser foundInlineCode:(NSString *)code\n{\n    [_attributeStack pushAttributes:_attributes.inlineCodeAttributes];\n    [self appendString:code];\n    [_attributeStack pop];\n}\n\n- (void)parserFoundSoftBreak:(CMParser *)parser\n{\n    [self appendString:@\" \"];\n}\n\n- (void)parserFoundLineBreak:(CMParser *)parser\n{\n    [self appendString:@\"\\u2028\"];\n}\n\n- (void)parserFoundHRule:(CMParser *)parser\n{\n    if (![_buffer.string hasSuffix:@\"\\n\"]) {\n        [self appendString:@\"\\n\"];\n    }\n    \n    CMHorizontalRuleAttachment *hruleAttachment = [[CMHorizontalRuleAttachment alloc] init];\n    \n    CMStyleAttributes *hruleAttributes = _attributes.horizontalRuleAttributes;\n    if (hruleAttributes.stringAttributes[NSForegroundColorAttributeName]) {\n        hruleAttachment.lineColor = hruleAttributes.stringAttributes[NSForegroundColorAttributeName];\n    }\n    if (self.attributes.horizontalRuleAttributes.paragraphStyleAttributes[CMParagraphStyleAttributeParagraphSpacingBefore]) {\n        hruleAttachment.verticalPaddingBefore = [self.attributes.horizontalRuleAttributes.paragraphStyleAttributes[CMParagraphStyleAttributeParagraphSpacingBefore] intValue];\n    }\n    if (self.attributes.horizontalRuleAttributes.paragraphStyleAttributes[CMParagraphStyleAttributeParagraphSpacing]) {\n        hruleAttachment.verticalPadding = [self.attributes.horizontalRuleAttributes.paragraphStyleAttributes[CMParagraphStyleAttributeParagraphSpacing] intValue];\n    }\n    \n    NSNumber *thickness = hruleAttributes.stringAttributes[CMHorizontalRuleThickness];\n    if (thickness) {\n        hruleAttachment.lineThickness = [thickness floatValue];\n    }\n    \n    NSMutableDictionary *attachmentAttributes = [NSMutableDictionary dictionaryWithDictionary:_attributeStack.cascadedAttributes];\n    attachmentAttributes[NSAttachmentAttributeName] = hruleAttachment;\n    \n    NSAttributedString *attachmentString = [NSAttributedString attributedStringWithAttachment:hruleAttachment];\n    NSMutableAttributedString *hruleAttrString = [[NSMutableAttributedString alloc] initWithAttributedString:attachmentString];\n    [hruleAttrString addAttributes:attachmentAttributes range:NSMakeRange(0, hruleAttrString.length)];\n    \n    [_buffer appendAttributedString:hruleAttrString];\n    \n    [self appendString:@\"\\n\"];\n    \n    [self closeBlockForNode:parser.currentNode];\n}\n\n- (void)parserDidStartBlockQuote:(CMParser *)parser\n{\n    quoteLevel++;\n    CMStyleAttributes *styleAttributes = [_attributes.blockQuoteAttributes copy];\n    AMTextBackground *bg = styleAttributes.stringAttributes[AMBackgroundDrawableAttributeName];\n    if ([bg isKindOfClass:AMTextBackground.class]) {\n        bg.isQuote = YES;\n    }\n    if (quoteLevel == 1) {\n        if (styleAttributes.stringAttributes[NSForegroundColorAttributeName]) {\n            paragraphColor = self.attributes.paragraphAttributes.stringAttributes[NSForegroundColorAttributeName];\n            paragraphFont = self.attributes.paragraphAttributes.stringAttributes[NSFontAttributeName];\n            paragrahpSpace = [self.attributes.paragraphAttributes.paragraphStyleAttributes[CMParagraphStyleAttributeParagraphSpacing] floatValue];\n            paragrahpSpaceBofore = [self.attributes.paragraphAttributes.paragraphStyleAttributes[CMParagraphStyleAttributeParagraphSpacingBefore] floatValue];\n            [self.attributes.paragraphAttributes.stringAttributes removeObjectForKey:NSForegroundColorAttributeName];\n            [self.attributes.paragraphAttributes.stringAttributes removeObjectForKey:NSFontAttributeName];\n            [self.attributes.paragraphAttributes.stringAttributes removeObjectForKey:CMParagraphStyleAttributeParagraphSpacing];\n            [self.attributes.paragraphAttributes.stringAttributes removeObjectForKey:CMParagraphStyleAttributeParagraphSpacingBefore];\n            self.attributes.paragraphAttributes.stringAttributes[NSForegroundColorAttributeName] = styleAttributes.stringAttributes[NSForegroundColorAttributeName];\n            self.attributes.paragraphAttributes.stringAttributes[NSFontAttributeName] = styleAttributes.stringAttributes[NSFontAttributeName];\n            self.attributes.paragraphAttributes.paragraphStyleAttributes[CMParagraphStyleAttributeParagraphSpacing] = styleAttributes.paragraphStyleAttributes[CMParagraphStyleAttributeParagraphSpacing];\n            self.attributes.paragraphAttributes.paragraphStyleAttributes[CMParagraphStyleAttributeParagraphSpacingBefore] = styleAttributes.paragraphStyleAttributes[CMParagraphStyleAttributeParagraphSpacingBefore];\n        }\n    }\n    \n  \n    [_attributeStack pushAttributes:styleAttributes];\n}\n\n- (void)parserDidEndBlockQuote:(CMParser *)parser\n{\n    quoteLevel--;\n    [self closeBlockForNode:parser.currentNode];\n    [_attributeStack pop];\n    if (quoteLevel == 0) {\n        if (self.attributes.blockQuoteAttributes.stringAttributes[NSForegroundColorAttributeName]) {\n            [self.attributes.paragraphAttributes.stringAttributes removeObjectForKey:NSForegroundColorAttributeName];\n            self.attributes.paragraphAttributes.stringAttributes[NSForegroundColorAttributeName] = paragraphColor;\n        }\n        if (self.attributes.blockQuoteAttributes.stringAttributes[NSFontAttributeName]) {\n            [self.attributes.paragraphAttributes.stringAttributes removeObjectForKey:NSFontAttributeName];\n            self.attributes.paragraphAttributes.stringAttributes[NSFontAttributeName] = paragraphFont;\n        }\n        if (self.attributes.blockQuoteAttributes.paragraphStyleAttributes[CMParagraphStyleAttributeParagraphSpacing]) {\n            [self.attributes.paragraphAttributes.paragraphStyleAttributes removeObjectForKey:CMParagraphStyleAttributeParagraphSpacing];\n            self.attributes.paragraphAttributes.paragraphStyleAttributes[CMParagraphStyleAttributeParagraphSpacing] = @(paragrahpSpace);\n        }\n        if (self.attributes.blockQuoteAttributes.paragraphStyleAttributes[CMParagraphStyleAttributeParagraphSpacingBefore]) {\n            [self.attributes.paragraphAttributes.paragraphStyleAttributes removeObjectForKey:CMParagraphStyleAttributeParagraphSpacingBefore];\n            self.attributes.paragraphAttributes.paragraphStyleAttributes[CMParagraphStyleAttributeParagraphSpacingBefore] = @(paragrahpSpaceBofore);\n        }\n    }\n}\n\n- (void)parser:(CMParser *)parser didStartUnorderedListWithTightness:(BOOL)tight\n{\n    if ([self sublistLevel:parser.currentNode.parent] == 0) {\n       [_attributeStack pushAttributes:_attributes.unorderedListAttributes];\n    }\n    else {\n        [self closeBlockForNode:parser.currentNode]; // When starting a sublist, the parent item must have its block closed first\n        [_attributeStack pushAttributes:_attributes.unorderedSublistAttributes];\n    }\n}\n\n- (void)parser:(CMParser *)parser didEndUnorderedListWithTightness:(BOOL)tight\n{\n    [_attributeStack pop];\n}\n\n- (void)parser:(CMParser *)parser didStartOrderedListWithStartingNumber:(NSInteger)num tight:(BOOL)tight\n{\n    if ([self sublistLevel:parser.currentNode.parent] == 0) {\n        [_attributeStack pushOrderedListAttributes:_attributes.orderedListAttributes withStartingNumber:num];\n    }\n    else {\n        [self closeBlockForNode:parser.currentNode]; // When starting a sublist, the parent item must have its block closed first\n        [_attributeStack pushOrderedListAttributes:_attributes.orderedSublistAttributes withStartingNumber:num];\n    }\n}\n\n- (void)parser:(CMParser *)parser didEndOrderedListWithStartingNumber:(NSInteger)num tight:(BOOL)tight\n{\n    [_attributeStack pop];\n}\n-(NSInteger)getOrderListNumber {\n    CMAttributeRun *parentRun = [_attributeStack peek];\n    return parentRun.orderedListItemNumber;\n}\n- (void)parserDidStartListItem:(CMParser *)parser\n{\n    CMAttributeRun *parentRun = [_attributeStack peek];\n    CMStyleAttributes * parentAttributes = parentRun.attributes;\n    \n    CMNode *node = parser.currentNode.parent;\n    CMNode *curNode = parser.currentNode;\n    switch (node.listType) {\n        case CMListTypeNone:\n            NSAssert(NO, @\"Parent node of list item must be a list\");\n            break;\n        case CMListTypeUnordered: {\n            if (curNode && curNode.isCheckBox) {\n                [self addCheckBoxAttachment:curNode];\n            } else {\n                if (!self.attributes.paragraphAttributes.stringAttributes[CMCustomListBullet]) {\n                    [self appendBulletString:[NSString stringWithFormat:@\"%@\\t\", parentAttributes.paragraphStyleAttributes [CMParagraphStyleAttributeListItemBulletString]]];\n                } else {\n                    [self appendBulletString:@\"\\t\"];\n                }\n            }\n            [_attributeStack pushAttributes:_attributes.unorderedListItemAttributes];\n            \n            break;\n        }\n        case CMListTypeOrdered: {\n            if (curNode && curNode.isCheckBox) {\n                [self addCheckBoxAttachment:curNode];\n            } else {\n                \n                if (!self.attributes.paragraphAttributes.stringAttributes[CMCustomListBullet]) {\n                    [self appendString:[[NSString stringWithFormat:parentAttributes.paragraphStyleAttributes[CMParagraphStyleAttributeListItemNumberFormat] ?: @\"%ld.\",\n                                         (long)parentRun.orderedListItemNumber]\n                                        stringByAppendingString:@\"\\t\"]];\n                } else {\n                    [self appendString:@\"\\t\"];\n                }\n                \n\n                parentRun.orderedListItemNumber++;\n            }\n            [_attributeStack pushAttributes:_attributes.orderedListItemAttributes];\n            break;\n        }\n        default:\n            break;\n    }\n}\n\n- (void)addCheckBoxAttachment:(CMNode *)curNode {\n\n    CMTaskCheckAttachment *attachment = [[CMTaskCheckAttachment alloc] init];\n    attachment.checked = curNode.checked;\n    \n    NSDictionary *cascadedAttributes = _attributeStack.cascadedAttributes;\n    UIFont *casFont = cascadedAttributes[NSFontAttributeName];\n    if (casFont) {\n        attachment.lineHeight = ceil(casFont.lineHeight);\n    }\n    CMStyleAttributes *checkboxAttributes = _attributes.checkboxAttributes;\n    if (checkboxAttributes.stringAttributes[NSForegroundColorAttributeName]) {\n        attachment.borderColor = checkboxAttributes.stringAttributes[NSForegroundColorAttributeName];\n    }\n    \n    if (checkboxAttributes.stringAttributes[NSBackgroundColorAttributeName]) {\n        attachment.backgroundColor = checkboxAttributes.stringAttributes[NSBackgroundColorAttributeName];\n    }\n    \n    NSNumber *borderWidth = checkboxAttributes.stringAttributes[CMCheckBoxBorderWidth];\n    if (borderWidth) {\n        attachment.borderWidth = [borderWidth floatValue];\n    }\n    \n    NSAttributedString *attachmentString = [NSAttributedString attributedStringWithAttachment:attachment];\n    [_buffer appendAttributedString:attachmentString];\n}\n\n- (void)parserDidEndListItem:(CMParser *)parser\n{\n    [self closeBlockForNode:parser.currentNode];\n    [_attributeStack pop];\n}\n\n#pragma mark - Private\n\n- (NSUInteger)sublistLevel:(CMNode *)node\n{\n    if (node.parent == nil) {\n        return 0;\n    } else {\n        return (node.listType == CMListTypeNone ? 0 : 1) + [self sublistLevel:node.parent];\n    }\n}\n\n- (CMHTMLElement *)newHTMLElementForTagName:(NSString *)tagName HTML:(NSString *)HTML\n{\n    NSParameterAssert(tagName);\n    id<CMHTMLElementTransformer> transformer = _tagNameToTransformerMapping[tagName];\n    if (transformer != nil) {\n        CMHTMLElement *element = [[CMHTMLElement alloc] initWithTransformer:transformer];\n        [element.buffer appendString:HTML];\n        return element;\n    }\n    return nil;\n}\n\n- (BOOL)isImageDescriptionNode:(CMNode *)node\n{\n    return node.parent.type == CMNodeTypeImage;\n}\n\n- (BOOL)nodeIsInTightMode:(CMNode *)node\n{\n    CMNode *grandparent = node.parent.parent;\n    return grandparent.listTight;\n}\n\n- (void)appendString:(NSString *)string\n{\n    NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:string attributes:_attributeStack.cascadedAttributes];\n    [_buffer appendAttributedString:attrString];\n}\n\n- (void)closeBlockForNode:(CMNode *)currentNode\n{\n    // Add a paragraph boundary to the attributted string if needed\n    if (![_buffer.string hasSuffix:@\"\\n\"]) {\n        \n        NSRange bufferLastParagraphRange = [_buffer.string paragraphRangeForRange:NSMakeRange(_buffer.string.length, 0)];\n        \n        [self appendString:@\"\\n\"];\n        \n        if (bufferLastParagraphRange.length > 0) {\n            // Extend the current paragraph style to enclode the whole paragraph if needed\n            NSParagraphStyle* bufferLastParagraphStyle = [_buffer attribute:NSParagraphStyleAttributeName atIndex:bufferLastParagraphRange.location effectiveRange:NULL];\n            NSParagraphStyle* appendedParagraphStyle = _attributeStack.cascadedAttributes[NSParagraphStyleAttributeName];\n            if ((appendedParagraphStyle != nil) && ![appendedParagraphStyle isEqual:bufferLastParagraphStyle]) {\n                [_buffer addAttribute:NSParagraphStyleAttributeName value:appendedParagraphStyle range:bufferLastParagraphRange];\n            }\n            \n            if ([self sublistLevel:currentNode] != 0) {\n                // In a list: adjust the indentation and tabs of list item's first paragraphs\n                [self adjustListItemIndentForNode:currentNode paragraphStyle:appendedParagraphStyle inRange:bufferLastParagraphRange];\n            }\n        }\n    }\n}\n\nstatic NSTextTab * textTabWithPosition(CGFloat tabPosition)\n{\n    return [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentNatural location:tabPosition options:@{}];\n}\n\n- (void) adjustListItemIndentForNode:(CMNode*)currentNode paragraphStyle:(NSParagraphStyle*)currentParagraphStyle inRange:(NSRange)currentParagraphRange\n{\n    NSUInteger listAttributesStackDepth = 0;\n    CGFloat itemContentIndent = 0;\n    \n    while ((currentNode != nil) && (currentNode.type != CMNodeTypeItem)) {\n        if ([currentNode isEqual:currentNode.parent.firstChild]) {\n            // indentation change is only needed for list-items' first child\n            \n            CMStyleAttributes* currentStyleAttributes = [_attributeStack attributesWithDepth:listAttributesStackDepth];\n            NSNumber* currentFirstLineExtraIndent = currentStyleAttributes.paragraphStyleAttributes[CMParagraphStyleAttributeFirstLineHeadExtraIndent];\n            itemContentIndent += currentFirstLineExtraIndent.doubleValue;\n            \n            currentNode = currentNode.parent;\n            listAttributesStackDepth += 1;\n        }\n        else {\n            currentNode = nil;\n        }\n    }\n    \n    if (currentNode.parent.type == CMNodeTypeList) {\n        CMStyleAttributes* listStyleAttributes = [_attributeStack attributesWithDepth:listAttributesStackDepth + 1];\n        \n        NSNumber* listItemMarkerIndent = listStyleAttributes.paragraphStyleAttributes [CMParagraphStyleAttributeListItemLabelIndent];\n        if ([listItemMarkerIndent isKindOfClass:[NSNumber class]]) {\n            NSMutableParagraphStyle* itemParagrahStyle = [currentParagraphStyle mutableCopy];\n            // Set a tab at the original first line head indent, plus a few extra tabs in case the list item marker extends beyond the first tab\n            // (typically with dynamic type, in case of bigger text size, extra tabs will help a list item to stay on a single line)\n            itemParagrahStyle.tabStops = @[ textTabWithPosition(itemParagrahStyle.firstLineHeadIndent),\n                                            textTabWithPosition(itemParagrahStyle.firstLineHeadIndent + listItemMarkerIndent.doubleValue),\n                                            textTabWithPosition(itemParagrahStyle.firstLineHeadIndent + listItemMarkerIndent.doubleValue * 2)];\n            itemParagrahStyle.firstLineHeadIndent -= listItemMarkerIndent.doubleValue + itemContentIndent;\n            // And update the pargraph style attributes\n            [_buffer addAttribute:NSParagraphStyleAttributeName value:itemParagrahStyle range:currentParagraphRange];\n        }\n    }\n}    \n\n- (void)appendHTMLElement:(CMHTMLElement *)element\n{\n    NSError *error = nil;\n    ONOXMLDocument *document = [ONOXMLDocument HTMLDocumentWithString:element.buffer encoding:NSUTF8StringEncoding error:&error];\n    if (document == nil) {\n        NSLog(@\"Error creating HTML document for buffer \\\"%@\\\": %@\", element.buffer, error);\n        return;\n    }\n    \n    ONOXMLElement *XMLElement = document.rootElement[0][0];\n    if (XMLElement != nil) {\n        NSDictionary *attributes = _attributeStack.cascadedAttributes;\n        NSAttributedString *attrString = [element.transformer attributedStringForElement:XMLElement attributes:attributes];\n        \n        if (attrString != nil) {\n            CMHTMLElement *parentElement = [_HTMLStack peek];\n            if (parentElement == nil) {\n                if (_tableCellBuffer) {\n                    [_tableCellBuffer appendAttributedString:attrString];\n                } else {\n                    [_buffer appendAttributedString:attrString];\n                }\n            } else {\n                [parentElement.buffer appendString:attrString.string];\n            }\n            if ([NSStringFromClass(element.transformer.class) isEqualToString:@\"AMHTMLIconLinkTransformer\"]) {\n                NSDictionary* linkUrl = [element.transformer getParams];\n                [self addClickableObjects:CMNodeTypeInlineHTML data:[linkUrl objectForKey:@\"linkUrl\"] tag:@\"iconLink\"];\n            }\n        }\n    } else {\n        NSLog(@\"Warning: XMLElement is nil for HTML buffer: \\\"%@\\\"\", element.buffer);\n    }\n}\n-(void)addClickableObjects:(CMNodeType)type data:(id)data tag:(NSString*)tag {\n    if (!data) {\n        return;\n    }\n    NSDictionary* subDic = nil;\n    if ((type == CMNodeTypeInlineHTML && [tag isEqualToString:@\"iconLink\"])\n        || type == CMNodeTypeLink\n        || type == CMNodeTypeImage) {\n        subDic = @{@\"url\":(NSString*)data, @\"type\":@(type), @\"tag\":tag};\n    }\n    if (!subDic) {\n        return;\n    }\n    if (!_clickableObjs) {\n        _clickableObjs = [[NSMutableArray alloc] init];\n    }\n    [_clickableObjs addObject:subDic];\n}\n-(NSArray*)clickableObjs\n{\n    return [_clickableObjs mutableCopy];\n}\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMAttributedStringRenderer_Private.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"CMAttributedStringRenderer.h\"\n#import \"CMCascadingAttributeStack.h\"\n#import \"CMParser.h\"\n#import \"CMStack.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface CMAttributedStringRenderer () <CMParserDelegate>\n{\n@protected\n    CMDocument *_document;\n    CMTextAttributes *_attributes;\n    CMCascadingAttributeStack *_attributeStack;\n    CMStack *_HTMLStack;\n    NSMutableDictionary *_tagNameToTransformerMapping;\n    NSMutableAttributedString *_buffer;\n    NSAttributedString *_attributedString;\n    NSMutableArray*    _clickableObjs;\n    NSMutableAttributedString * _tableCellBuffer;\n\tUIColor* paragraphColor;\n    UIFont* paragraphFont;\n    CGFloat paragrahpSpace;\n    CGFloat paragrahpSpaceBofore;\n    NSInteger quoteLevel;\n}\n@property (readonly) CMDocument *document;\n@property (readonly) CMTextAttributes *attributes;\n@property (readonly) CMCascadingAttributeStack *attributeStack;\n@property (readonly) CMStack *HTMLStack;\n@property (readonly) NSMutableDictionary *tagNameToTransformerMapping;\n@property (readonly) NSMutableAttributedString *buffer;\n@property (nonatomic, weak)id<CMAttributedStringRendererDelegate> delegate;\n\n- (void)appendString:(NSString *)string;\n\n- (NSTextAttachment *)imageAttachmentWithURL:(NSURL *)url title:(NSString *)title;\n\n- (void)appendBulletString:(NSString *)string;\n\n- (void)closeBlockForNode:(CMNode *)currentNode;\n\n-(void)addClickableObjects:(CMNodeType)type data:(NSString*)data tag:(NSString*)tag;\n\n-(NSInteger)getOrderListNumber;\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMBlockTextAttachment.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <UIKit/UIKit.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface CMBlockTextAttachment : NSTextAttachment\n@property (nonatomic, nullable) NSString *text;\n\n- (void)setNeedsUpdate;\n- (NSAttributedString *)attributedString;\n\n- (BOOL)isEqualToAttachment:(CMBlockTextAttachment *)attach;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMBlockTextAttachment.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"CMBlockTextAttachment.h\"\n#import \"CMImageTextAttachment.h\"\n\n@implementation CMBlockTextAttachment\n{\n    __weak NSTextContainer *_textContainer;\n}\n\n- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer\n                      proposedLineFragment:(CGRect)lineFrag\n                             glyphPosition:(CGPoint)position\n                            characterIndex:(NSUInteger)charIndex {\n    _textContainer = textContainer;\n    \n    textContainer.widthTracksTextView = YES;\n    const CGFloat width = textContainer.size.width - textContainer.lineFragmentPadding * 2;\n    CGRect rect = [super attachmentBoundsForTextContainer:textContainer\n                                     proposedLineFragment:lineFrag\n                                            glyphPosition:position\n                                           characterIndex:charIndex];\n    rect.size.width = width;\n    return rect;\n}\n\n- (void)setNeedsUpdate {\n    [_textContainer.layoutManager setNeedsLayoutForAttachment:self];\n}\n\n- (BOOL)isEqual:(nullable id)object {\n    if ([super isEqual:object]) {\n        return YES;\n    }\n    \n    if (![object isKindOfClass:[self class]]) {\n        return NO;\n    }\n    \n    return [self isEqualToAttachment:(CMBlockTextAttachment *)object];\n}\n\n- (BOOL)isEqualToAttachment:(CMBlockTextAttachment *)attach\n{\n    return [self.text isEqualToString:attach.text];\n}\n\n- (NSAttributedString *)attributedString\n{\n    return [NSAttributedString attributedStringWithAttachment:self];\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMCascadingAttributeStack.h",
    "content": "//\n//  CMCascadingAttributeStack.h\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/15/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n#import \"CMPlatformDefines.h\"\n#import \"CMTextAttributes.h\"\n\n@class CMStyleAttributes;\n@class CMAttributeRun;\n\n@interface CMCascadingAttributeStack : NSObject\n\n@property (nonatomic, readonly) NSDictionary *cascadedAttributes;\n\n- (void) pushAttributes:(CMStyleAttributes*)attributes;\n- (void) pushOrderedListAttributes:(CMStyleAttributes*)attributes withStartingNumber:(NSInteger)startingNumber;\n- (void)pop;\n- (CMAttributeRun *)peek;\n\n- (CMStyleAttributes*) attributesWithDepth:(NSUInteger)depth; // depth=0 means stack top\n@end\n\n@interface CMFont (CMAdditions)\n- (CMFont*) fontByAddingCMAttributes:(NSDictionary<CMFontDescriptorAttributeName, id>*)addedFontAttributes;\n@end\n\n@interface NSParagraphStyle (CMAdditions)\n+ (NSParagraphStyle*) paragraphStyleWithCMAttributes:(NSDictionary<CMParagraphStyleAttributeName, id> *)paragraphStyleAttributes;\n- (NSParagraphStyle*) paragraphStyleByAddingCMAttributes:(NSDictionary<CMParagraphStyleAttributeName, id> *)paragraphStyleAttributes;\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMCascadingAttributeStack.m",
    "content": "//\n//  CMCascadingAttributeStack.m\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/15/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import \"CMCascadingAttributeStack.h\"\n#import \"CMAttributeRun.h\"\n#import \"CMPlatformDefines.h\"\n#import \"CMStack.h\"\n#import \"CMTextAttributes.h\"\n\n@implementation CMCascadingAttributeStack {\n    CMStack<CMAttributeRun*> *_stack;\n    NSMutableArray<NSDictionary*> * _cascadedAttributes;\n}\n\n- (instancetype)init\n{\n    if ((self = [super init])) {\n        _stack = [[CMStack alloc] init];\n        _cascadedAttributes = [NSMutableArray new];\n    }\n    return self;\n}\n\n- (void) pushAttributes:(CMStyleAttributes*)attributes\n{\n    [self push:CMDefaultAttributeRun(attributes)];\n}\n\n- (void) pushOrderedListAttributes:(CMStyleAttributes*)attributes withStartingNumber:(NSInteger)startingNumber\n{\n    [self push:CMOrderedListAttributeRun(attributes, startingNumber)];\n}\n\n- (CMStyleAttributes*) attributesWithDepth:(NSUInteger)depth\n{\n    return (depth < _stack.objects.count) ? _stack.objects[_stack.objects.count - 1 - depth].attributes : nil;\n}\n\n- (void)push:(CMAttributeRun *)run\n{\n    [_stack push:run];\n}\n\n- (void)pop\n{\n    [_stack pop];\n    if (_cascadedAttributes.count > _stack.objects.count) {\n        [_cascadedAttributes removeLastObject];\n    }\n}\n\n- (CMAttributeRun *)peek\n{\n    return [_stack peek];\n}\n\n- (NSDictionary *)cascadedAttributes\n{\n    if (_cascadedAttributes.count < _stack.objects.count) {\n        \n        NSMutableDictionary *combinedAttributes = [NSMutableDictionary dictionaryWithDictionary:_cascadedAttributes.lastObject ?: @{}];\n        \n        for (NSUInteger level = _cascadedAttributes.count; level < _stack.objects.count; level += 1) {\n\n            CMStyleAttributes * currentStyleAttributes = _stack.objects[level].attributes;\n            \n            if (currentStyleAttributes != nil) {\n                \n                // Set explicit string attributes\n                [combinedAttributes addEntriesFromDictionary:currentStyleAttributes.stringAttributes];\n                \n                // Set font attributes\n                if (currentStyleAttributes.fontAttributes.count > 0) {\n                    CMFont *baseFont = combinedAttributes[NSFontAttributeName];\n                    CMFont *adjustedFont = nil;\n                    if (baseFont != nil) {\n                        adjustedFont = [baseFont fontByAddingCMAttributes:currentStyleAttributes.fontAttributes];\n                    }\n                    else {\n                        CMFontDescriptor * adjustedFontDescriptor = [CMFontDescriptor fontDescriptorWithFontAttributes:currentStyleAttributes.fontAttributes];\n                        if (adjustedFontDescriptor != nil) {\n                            adjustedFont = [CMFont fontWithDescriptor:adjustedFontDescriptor size:adjustedFontDescriptor.pointSize];\n                        }\n                    }\n                    if (adjustedFont != nil) {\n                        combinedAttributes[NSFontAttributeName] = adjustedFont;\n                    }\n                }\n                \n                // Set paragraph style attributes\n                if (currentStyleAttributes.paragraphStyleAttributes.count > 0) {\n                    NSParagraphStyle* baseParagraphStyle = combinedAttributes[NSParagraphStyleAttributeName];\n                    NSParagraphStyle* adjustedParagraphStyle = nil;\n                    if (baseParagraphStyle != nil) {\n                        adjustedParagraphStyle = [baseParagraphStyle paragraphStyleByAddingCMAttributes:currentStyleAttributes.paragraphStyleAttributes];\n                    }\n                    else {\n                        adjustedParagraphStyle = [NSParagraphStyle paragraphStyleWithCMAttributes:currentStyleAttributes.paragraphStyleAttributes];\n                    }\n                    if (adjustedParagraphStyle != nil) {\n                        combinedAttributes[NSParagraphStyleAttributeName] = adjustedParagraphStyle;\n                    }\n                }\n            }\n            \n            [_cascadedAttributes addObject:combinedAttributes.copy];\n        }\n    }\n    return _cascadedAttributes.lastObject;\n}\n\n@end\n\n\n@implementation CMFont (CMAdditions)\n\n#if TARGET_OS_IPHONE\n#define CMFontNameAttribute UIFontDescriptorNameAttribute\n#define CMFontFamilyAttribute UIFontDescriptorFamilyAttribute\n#define CMFontTraitsAttribute UIFontDescriptorTraitsAttribute\n#define CMFontDescriptorTraitKey UIFontDescriptorTraitKey\n#define CMFontSymbolicTraitKey UIFontSymbolicTrait\n\n#else\n#define CMFontNameAttribute NSFontNameAttribute\n#define CMFontFamilyAttribute NSFontFamilyAttribute\n#define CMFontTraitsAttribute NSFontTraitsAttribute\n#define CMFontDescriptorTraitKey NSFontDescriptorTraitKey\n#define CMFontSymbolicTraitKey NSFontSymbolicTrait\n#endif\n\n\n- (CMFont*) fontByAddingCMAttributes:(NSDictionary<CMFontDescriptorAttributeName, id>*)addedFontAttributes\n{\n    CMFont* matchingFont = nil;\n    CMFontDescriptor* currentFontDescriptor = self.fontDescriptor;\n    \n#if TARGET_OS_IPHONE\n    // Get the current font text style\n    UIFontTextStyle currentFontTextStyle = [currentFontDescriptor objectForKey:UIFontDescriptorTextStyleAttribute] ?: UIFontTextStyleBody;\n#endif\n    \n    if ([addedFontAttributes isKindOfClass:[NSDictionary class]] && (addedFontAttributes.count > 0)) {\n        NSMutableDictionary<CMFontDescriptorAttributeName, id>* fontAttributes = [currentFontDescriptor.fontAttributes mutableCopy];\n        \n        if (((addedFontAttributes[CMFontTraitsAttribute] != nil) || (addedFontAttributes[CMFontFamilyAttribute] != nil)) \n            && (addedFontAttributes[CMFontNameAttribute] == nil)) {\n            // Replace the font name in the font attributes by font-family\n            fontAttributes[CMFontFamilyAttribute] = [currentFontDescriptor objectForKey:CMFontFamilyAttribute];\n            [fontAttributes removeObjectForKey:CMFontNameAttribute];\n        }\n        \n        if ((addedFontAttributes[CMFontFamilyAttribute] != nil) || (addedFontAttributes[CMFontNameAttribute] != nil)) {\n            // A font is specified in the added attributes: Remove an eventual text-style font attribute as it could break the font change\n#if TARGET_OS_IPHONE\n            [fontAttributes removeObjectForKey:UIFontDescriptorTextStyleAttribute];\n#else\n            [fontAttributes removeObjectForKey:@\"NSCTFontUIUsageAttribute\"];\n#endif\n        }\n        \n        // Add the parameter attributes\n        [fontAttributes addEntriesFromDictionary:addedFontAttributes];\n        \n        // If only font traits are added, try to preserve current font traits\n        BOOL hasCombinedFontTraits = NO;\n        NSDictionary<CMFontDescriptorTraitKey, id>* addedFontTraits = addedFontAttributes[CMFontTraitsAttribute];\n        NSDictionary<CMFontDescriptorTraitKey, id>* currentFontTraits;\n        if ((addedFontTraits != nil) && (addedFontAttributes.count == 1)) {\n            currentFontTraits = [currentFontDescriptor objectForKey:CMFontTraitsAttribute];\n            NSUInteger currentSymbolicTraits = [currentFontTraits[CMFontSymbolicTraitKey] unsignedIntValue];\n            NSUInteger addedSymbolicTraits = [addedFontTraits[CMFontSymbolicTraitKey] unsignedIntValue];\n            \n            NSMutableDictionary<CMFontDescriptorTraitKey, id>* combinedFontTraits = [NSMutableDictionary new];\n            [currentFontTraits enumerateKeysAndObjectsUsingBlock:^(CMFontDescriptorTraitKey traitKey, id traitValue, BOOL * _Nonnull stop) {\n                if (![traitKey isEqualToString:CMFontSymbolicTraitKey] && ([traitValue doubleValue] != 0)) {\n                    // Only keep traits with non-default value\n                    combinedFontTraits[traitKey] = traitValue;\n                }\n            }];\n            [combinedFontTraits addEntriesFromDictionary:addedFontAttributes[CMFontTraitsAttribute]];\n            // Combine symbolic traits\n            if ((currentSymbolicTraits != 0) && (addedSymbolicTraits != 0)) {\n                combinedFontTraits[CMFontSymbolicTraitKey] = @(currentSymbolicTraits | addedSymbolicTraits);\n            }\n            // support for iphone italic style\n            if ((addedSymbolicTraits & CMFontTraitItalic) == CMFontTraitItalic) {\n                // use transform instead italic style\n                fontAttributes[UIFontDescriptorMatrixAttribute] = [NSValue valueWithCGAffineTransform:CGAffineTransformMake(1, 0, tanf(15 * M_PI / 180), 1, 0, 0)];\n                // removed origin italic style\n                combinedFontTraits[CMFontSymbolicTraitKey] = @(addedSymbolicTraits ^ UIFontDescriptorTraitItalic);\n            }\n            \n            fontAttributes[CMFontTraitsAttribute] = combinedFontTraits;\n            hasCombinedFontTraits = YES;\n        }\n        \n        // Get a font descriptor with the transformed font attributes\n        CMFontDescriptor* matchingFontDescriptor = [CMFontDescriptor fontDescriptorWithFontAttributes:fontAttributes];\n        \n        if (hasCombinedFontTraits && (matchingFontDescriptor != nil)) {\n            // Check if the font descriptor consistently creates a font with the expected font family\n            NSString* expectedFontFamily = [matchingFontDescriptor objectForKey:CMFontFamilyAttribute];\n            NSString* resultingFontFamily = [[CMFont fontWithDescriptor:matchingFontDescriptor size:0].fontDescriptor objectForKey:CMFontFamilyAttribute];\n            if (! [resultingFontFamily isEqualToString:expectedFontFamily]) {\n                // Retry without font traits attribute inheritance\n                fontAttributes [CMFontTraitsAttribute] = addedFontTraits;\n                matchingFontDescriptor = [CMFontDescriptor fontDescriptorWithFontAttributes:fontAttributes];\n                \n                // If added font traits break the expected font familly, ignore them\n                resultingFontFamily = [[CMFont fontWithDescriptor:matchingFontDescriptor size:0].fontDescriptor objectForKey:CMFontFamilyAttribute];\n                if (! [resultingFontFamily isEqualToString:expectedFontFamily]) {\n                    // Restore current font traits\n                    fontAttributes [CMFontTraitsAttribute] = currentFontTraits;\n                    matchingFontDescriptor = [CMFontDescriptor fontDescriptorWithFontAttributes:fontAttributes];\n                }\n            }            \n        }\n        \n        if (matchingFontDescriptor != nil) {\n    \n#if TARGET_OS_IPHONE\n            if (@available(iOS 11.0, *)) {\n                CGFloat currentStyleFontSize = [UIFont preferredFontForTextStyle:currentFontTextStyle].pointSize;\n                CGFloat currentStyleBaseFontSize = [UIFont preferredFontForTextStyle:currentFontTextStyle \n                                                compatibleWithTraitCollection:[UITraitCollection traitCollectionWithPreferredContentSizeCategory:UIContentSizeCategoryMedium]].pointSize;\n                UIFont* nonScalableFont = [UIFont fontWithDescriptor:matchingFontDescriptor \n                                                                size:matchingFontDescriptor.pointSize * currentStyleBaseFontSize / currentStyleFontSize];\n                matchingFont = [[UIFontMetrics metricsForTextStyle:currentFontTextStyle] scaledFontForFont:nonScalableFont];\n            }\n            else {\n                matchingFont = [UIFont fontWithDescriptor:matchingFontDescriptor size:matchingFontDescriptor.pointSize];\n            }\n#else   \n            matchingFont = [CMFont fontWithDescriptor:matchingFontDescriptor size:matchingFontDescriptor.pointSize];\n#endif\n\n        }\n    }\n\n    return matchingFont;\n}\n\n@end\n\n\n#pragma mark - NSParagraphStyle additions\n\n@interface NSMutableParagraphStyle (CMAdditions)\n- (void) applyParagraphStyleAttributes:(NSDictionary<CMParagraphStyleAttributeName, id> *)paragraphStyleAttributes;\n@end\n\n@implementation NSParagraphStyle (CMAdditions)\n\n+ (NSParagraphStyle*) paragraphStyleWithCMAttributes:(NSDictionary<CMParagraphStyleAttributeName, id> *)paragraphStyleAttributes\n{\n    NSMutableParagraphStyle* newParagraphStyle = nil;\n    if ([paragraphStyleAttributes isKindOfClass:[NSDictionary class]] && (paragraphStyleAttributes.count > 0)) {\n        newParagraphStyle = [NSMutableParagraphStyle new];\n        [newParagraphStyle applyParagraphStyleAttributes:paragraphStyleAttributes];\n    }\n    return newParagraphStyle;\n}\n\n- (NSParagraphStyle*) paragraphStyleByAddingCMAttributes:(NSDictionary<CMParagraphStyleAttributeName, id> *)paragraphStyleAttributes\n{\n    NSMutableParagraphStyle* newParagraphStyle = nil;\n    if ([paragraphStyleAttributes isKindOfClass:[NSDictionary class]] && (paragraphStyleAttributes.count > 0)) {\n        newParagraphStyle = [self mutableCopy];\n        [newParagraphStyle applyParagraphStyleAttributes:paragraphStyleAttributes];\n    }\n    return newParagraphStyle;\n}\n\n@end\n\n@implementation NSMutableParagraphStyle (CMAdditions)\n\n- (void) applyParagraphStyleAttributes:(NSDictionary<CMParagraphStyleAttributeName, id> *)paragraphStyleAttributes\n{\n    static NSDictionary* applyAttributeBlocks;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        applyAttributeBlocks = \n        @{ CMParagraphStyleAttributeLineSpacing: ^(NSMutableParagraphStyle* paragraphStyle, id attribute){ paragraphStyle.lineSpacing = [attribute doubleValue]; },\n           CMParagraphStyleAttributeParagraphSpacing: ^(NSMutableParagraphStyle* paragraphStyle, id attribute){ paragraphStyle.paragraphSpacing = [attribute doubleValue]; },\n           CMParagraphStyleAttributeAlignment: ^(NSMutableParagraphStyle* paragraphStyle, id attribute){ paragraphStyle.alignment = (NSTextAlignment)[attribute integerValue]; },\n           CMParagraphStyleAttributeLineBreakMode: ^(NSMutableParagraphStyle* paragraphStyle, id attribute){ paragraphStyle.lineBreakMode = (NSLineBreakMode)[attribute integerValue]; },\n           CMParagraphStyleAttributeMinimumLineHeight: ^(NSMutableParagraphStyle* paragraphStyle, id attribute){ paragraphStyle.minimumLineHeight = [attribute doubleValue]; },\n           CMParagraphStyleAttributeMaximumLineHeight: ^(NSMutableParagraphStyle* paragraphStyle, id attribute){ paragraphStyle.maximumLineHeight = [attribute doubleValue]; },\n           CMParagraphStyleAttributeLineHeightMultiple: ^(NSMutableParagraphStyle* paragraphStyle, id attribute){ paragraphStyle.lineHeightMultiple = [attribute doubleValue]; },\n           CMParagraphStyleAttributeParagraphSpacingBefore: ^(NSMutableParagraphStyle* paragraphStyle, id attribute){ paragraphStyle.paragraphSpacingBefore = [attribute doubleValue]; },\n           CMParagraphStyleAttributeHyphenationFactor: ^(NSMutableParagraphStyle* paragraphStyle, id attribute){ paragraphStyle.hyphenationFactor = [attribute floatValue]; },\n           // Attributes with defining increment values\n           CMParagraphStyleAttributeFirstLineHeadExtraIndent: ^(NSMutableParagraphStyle* paragraphStyle, id attribute){ paragraphStyle.firstLineHeadIndent += [attribute doubleValue]; },\n           CMParagraphStyleAttributeHeadExtraIndent: ^(NSMutableParagraphStyle* paragraphStyle, id attribute){ paragraphStyle.headIndent += [attribute doubleValue]; },\n           CMParagraphStyleAttributeTailExtraIndent: ^(NSMutableParagraphStyle* paragraphStyle, id attribute){ paragraphStyle.tailIndent += [attribute doubleValue]; },\n           \n           // List-specific attributes (ignored)\n           CMParagraphStyleAttributeListItemLabelIndent: ^(NSMutableParagraphStyle* paragraphStyle, id attribute){},\n           CMParagraphStyleAttributeListItemBulletString: ^(NSMutableParagraphStyle* paragraphStyle, id attribute){},\n           CMParagraphStyleAttributeListItemNumberFormat: ^(NSMutableParagraphStyle* paragraphStyle, id attribute){},\n           CMParagraphStyleAttributeListItemParagraphPrefix: ^(NSMutableParagraphStyle* paragraphStyle, id attribute){},\n        };\n    });\n    \n    [paragraphStyleAttributes enumerateKeysAndObjectsUsingBlock:^(CMParagraphStyleAttributeName attributeName, id attributeValue, BOOL * _Nonnull stop) {\n        \n        ((void(^)(NSMutableParagraphStyle* paragraphStyle, id attribute))applyAttributeBlocks[attributeName])(self, attributeValue);\n    }];\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMDocument+AttributedStringAdditions.h",
    "content": "//\n//  CMDocument+AttributedStringAdditions.h\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/20/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import \"CMDocument.h\"\n\n@class CMTextAttributes;\n\n@interface CMDocument (AttributedStringAdditions)\n\n/**\n *  Creates an attributed string from the receiver that is styled using the\n *  specified attributes.\n *\n *  @param attributes Attributes used to style the text.\n *\n *  @return Attributed string containing the formatted contents of the receiver.\n */\n- (NSAttributedString *)attributedStringWithAttributes:(CMTextAttributes *)attributes;\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMDocument+AttributedStringAdditions.m",
    "content": "//\n//  CMDocument+AttributedStringAdditions.m\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/20/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import \"CMDocument+AttributedStringAdditions.h\"\n#import \"CMAttributedStringRenderer.h\"\n\n@implementation CMDocument (AttributedStringAdditions)\n\n- (NSAttributedString *)attributedStringWithAttributes:(CMTextAttributes *)attributes\n{\n    CMAttributedStringRenderer *renderer = [[CMAttributedStringRenderer alloc] initWithDocument:self attributes:attributes];\n    return [renderer render];\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMDocument+HTMLAdditions.h",
    "content": "//\n//  CMDocument+HTMLAdditions.h\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/20/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import \"CMDocument.h\"\n#import \"CMHTMLRenderer.h\"\n\n@interface CMDocument (HTMLAdditions)\n\n/**\n *  Creates an HTML representation of the receiver.\n *\n *  @return String containing the HTML representation of the receiver.\n */\n- (NSString *)HTMLString;\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMDocument+HTMLAdditions.m",
    "content": "//\n//  CMDocument+HTMLAdditions.m\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/20/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import \"CMDocument+HTMLAdditions.h\"\n\n@implementation CMDocument (HTMLAdditions)\n\n- (NSString *)HTMLString\n{\n    CMHTMLRenderer *renderer = [[CMHTMLRenderer alloc] initWithDocument:self];\n    return [renderer render];\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMDocument.h",
    "content": "//\n//  CMDocument.h\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/12/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n#include \"cmark-gfm.h\"\n\n@class CMNode;\n\ntypedef NS_OPTIONS(NSInteger, CMDocumentOptions) {\n    /** Default options.\n     */\n    CMDocumentOptionsDefault = CMARK_OPT_DEFAULT,\n    /**\n     * Include a `data-sourcepos` attribute on all block elements.\n     */\n    CMDocumentOptionsSourcepos = CMARK_OPT_SOURCEPOS,\n    /**\n     * Render `softbreak` elements as hard line breaks.\n     */\n    CMDocumentOptionsHardBreaks = CMARK_OPT_HARDBREAKS,\n    /** `CMARK_OPT_SAFE` is defined here for API compatibility,\n        but it no longer has any effect. \"Safe\" mode is now the default:\n        set `CMARK_OPT_UNSAFE` to disable it.\n     */\n    CMDocumentOptionsSafe = CMARK_OPT_SAFE,\n    /** Render `softbreak` elements as spaces.\n     */\n    CMDocumentOptionsNoBreaks = CMARK_OPT_NOBREAKS,\n    /**\n     * Normalize tree by consolidating adjacent text nodes.\n     */\n    CMDocumentOptionsNormalize = CMARK_OPT_NORMALIZE,\n    /** Validate UTF-8 in the input before parsing, replacing illegal\n     * sequences with the replacement character U+FFFD.\n     */\n    CMDocumentOptionsValidateUTF8 = CMARK_OPT_VALIDATE_UTF8,\n    /**\n     * Convert straight quotes to curly, --- to em dashes, -- to en dashes.\n     */\n    CMDocumentOptionsSmart = CMARK_OPT_SMART,\n    /** Use GitHub-style <pre lang=\"x\"></pre> tags for code blocks instead of\n     * <pre><code class=\"language-x\"></code></pre>\n     */\n    CMDocumentOptionsGithubPreLang = CMARK_OPT_GITHUB_PRE_LANG,\n\n    /** Be liberal in interpreting inline HTML tags.\n     */\n    CMDocumentOptionsLiberalHTMLTag = CMARK_OPT_LIBERAL_HTML_TAG,\n\n    /** Parse footnotes.\n     */\n    CMDocumentOptionsFootNotes = CMARK_OPT_FOOTNOTES,\n    /** Only parse strikethroughs if surrounded by exactly 2 tildes.\n     * Gives some compatibility with redcarpet.\n     */\n    CMDocumentOptionsStrikeThrough = CMARK_OPT_STRIKETHROUGH_DOUBLE_TILDE,\n\n    /** Use style attributes to align table cells instead of align attributes.\n     */\n    CMDocumentOptionsTablePreferStyle =  CMARK_OPT_TABLE_PREFER_STYLE_ATTRIBUTES,\n\n    /** Include the remainder of the info string in code blocks in\n     * a separate attribute.\n     */\n    CMDocumentOptionsFullInfo = CMARK_OPT_FULL_INFO_STRING,\n    /** Render raw HTML and unsafe links (`javascript:`, `vbscript:`,\n     * `file:`, and `data:`, except for `image/png`, `image/gif`,\n     * `image/jpeg`, or `image/webp` mime types).  By default,\n     * raw HTML is replaced by a placeholder HTML comment. Unsafe\n     * links are replaced by empty strings.\n     */\n    CMDocumentOptionsUnsafe = CMARK_OPT_UNSAFE,\n    \n    CMDocumentOptionsFootNotesWithoutDefinition = CMARK_OPT_FOOTNOTES_WITHOUT_DEFINITION,\n};\n\n/**\n *  A Markdown document conforming to the CommonMark spec.\n */\n@interface CMDocument : NSObject\n\n/**\n *  Root node of the document.\n */\n@property (nonatomic, readonly) CMNode *rootNode;\n\n/**\n *  Initializes the receiver with a string.\n *\n *  @param string Markdown document string.\n *  @param options Document options.\n *\n *  @return An initialized instance of the receiver.\n */\n- (instancetype)initWithString:(NSString *)string options:(CMDocumentOptions)options;\n\n/**\n *  Initializes the receiver with data.\n *\n *  @param data Markdown document data.\n *  @param options Document options.\n *\n *  @return An initialized instance of the receiver.\n */\n- (instancetype)initWithData:(NSData *)data options:(CMDocumentOptions)options;\n\n/**\n *  Initializes the receiver with data read from a file.\n *\n *  @param path The file path to read from.\n *  @param options Document options.\n *\n *  @return An initialized instance of the receiver, or `nil` if the file\n *  could not be opened.\n */\n- (instancetype)initWithContentsOfFile:(NSString *)path options:(CMDocumentOptions)options;\n\n\n/**\n *  Base URL for links and images in the document.\n *\n *  Used as a base when a link destination is a scheme-less path (relative or absolute).\n *\n *  If the document has been created using `-[initWithContentsOfFile:options]`, linkBaseURL defaults to the document file's parent directory.\n */\n@property (nonatomic) NSURL *linksBaseURL;\n\n/**\n *  Get the absolute URL for a link or image node based on the documents's link base URL if needed\n *\n *  @param node Markdown document data.\n *\n *  @return the actual target URL of the node taking into account the documents's link base URL\n */\n- (NSURL*) targetURLForNode:(CMNode *)node;\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMDocument.m",
    "content": "//\n//  CMDocument.m\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/12/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import \"CMDocument_Private.h\"\n#import \"CMNode_Private.h\"\n#include \"cmark-gfm-core-extensions.h\"\n#include \"table.h\"\n\n@implementation CMDocument\n\n+ (void)initialize {\n//    [super initialize];\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        cmark_gfm_core_extensions_ensure_registered();\n    });\n}\n\n- (instancetype)initWithString:(NSString *)string options:(CMDocumentOptions)options\n{\n    if (string != nil) {\n        if ((self = [super init])) {\n            const char* utf8String = string.UTF8String;\n            if(utf8String == NULL)\n                return nil;\n            cmark_node *node = cmark_parse_document(utf8String, strlen(utf8String), (int)options);\n            if (node == NULL) return nil;\n            \n            _rootNode = [[CMNode alloc] initWithNode:node freeWhenDone:YES];\n            _options = options;\n        }\n    } else {\n        self = nil;\n    }\n    return self;\n}\n\n- (instancetype)initWithData:(NSData *)data options:(CMDocumentOptions)options\n{\n    NSParameterAssert(data);\n    \n    if ((self = [super init])) {\n        cmark_node *node = cmark_parse_document((const char *)data.bytes, data.length, (int)options);\n        if (node == NULL) return nil;\n        \n        _rootNode = [[CMNode alloc] initWithNode:node freeWhenDone:YES];\n        _options = options;\n    }\n    return self;\n}\n\n- (instancetype)initWithContentsOfFile:(NSString *)path options:(CMDocumentOptions)options\n{\n    if ((self = [super init])) {\n        FILE *fp = fopen(path.UTF8String, \"r\");\n        if (fp == NULL) return nil;\n        \n        cmark_node *node = cmark_parse_file(fp, (int)options);\n        fclose(fp);\n        if (node == NULL) return nil;\n        \n        _rootNode = [[CMNode alloc] initWithNode:node freeWhenDone:YES];\n        _options = options;\n        \n        _linksBaseURL = [NSURL fileURLWithPath:path.stringByDeletingLastPathComponent];\n    }\n    return self;\n}\n\n- (NSURL*) targetURLForNode:(CMNode *)node\n{\n    NSURL* nodeTargetUrl = node.URL;\n    if ((nodeTargetUrl.scheme == nil) && (_linksBaseURL != nil))\n    {\n        // If the node URL doesn't have a scheme, consider it relative to the base URL\n        nodeTargetUrl = [NSURL URLWithString:node.URLString relativeToURL:_linksBaseURL].absoluteURL;\n    }\n    return nodeTargetUrl;\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMDocument_Private.h",
    "content": "//\n//  CMDocument_Private.h\n//  CocoaMarkdown\n//\n//  Created by Indragie on 4/27/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import \"CMDocument.h\"\n\n@interface CMDocument ()\n/**\n *  Options passed in at initialization time.\n */\n@property (nonatomic, readonly) CMDocumentOptions options;\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMHTMLElement.h",
    "content": "//\n//  CMHTMLElement.h\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/16/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n@protocol CMHTMLElementTransformer;\n\n@interface CMHTMLElement : NSObject\n@property (nonatomic, readonly) id<CMHTMLElementTransformer> transformer;\n@property (nonatomic, readonly) NSString *tagName;\n@property (nonatomic, readonly) NSMutableString *buffer;\n\n- (instancetype)initWithTransformer:(id<CMHTMLElementTransformer>)transformer;\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMHTMLElement.m",
    "content": "//\n//  CMHTMLElement.m\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/16/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import \"CMHTMLElement.h\"\n#import \"CMHTMLElementTransformer.h\"\n\n@implementation CMHTMLElement\n\n- (instancetype)initWithTransformer:(id<CMHTMLElementTransformer>)transformer\n{\n    if ((self = [super init])) {\n        _transformer = transformer;\n        _buffer = [[NSMutableString alloc] init];\n    }\n    return self;\n}\n\n- (NSString *)tagName;\n{\n    return [_transformer.class tagName];\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMHTMLElementTransformer.h",
    "content": "//\n//  CMHTMLElementTransformer.h\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/16/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n@class ONOXMLElement;\n\n/**\n *  Interface for an object that can transform an HTML element to an attributed string.\n */\n@protocol CMHTMLElementTransformer <NSObject>\n/**\n *  @return The name of the tag that this transformer handles.\n */\n+ (NSString *)tagName;\n\n/**\n *  Transforms an HTML element to an attributed string.\n *\n *  @param element   The HTML element to transform.\n *  @param attributes The base attributes to be applied to the attributed string.\n *\n *  @return An attributed string.\n */\n- (NSAttributedString *)attributedStringForElement:(ONOXMLElement *)element attributes:(NSDictionary *)attributes;\n\n@optional\n\n-(NSDictionary*)getParams;\n\n@end\n\n/**\n *  Use this macro inside an implementation of `-attributedStringForElement:attributes:`\n *  to assert that the root element's tag matches the transformer's tag.\n */\n#define CMAssertCorrectTag(element) \\\n    NSAssert([element.tag isEqualToString:self.class.tagName], @\"Tag does not match\");\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMHTMLRenderer.h",
    "content": "//\n//  CMHTMLRenderer.h\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/20/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n@class CMDocument;\n\n/**\n *  Renders HTML from a Markdown document.\n */\n@interface CMHTMLRenderer : NSObject\n\n/**\n *  Designated initializer.\n *\n *  @param document A Markdown document.\n *\n *  @return An initialized instance of the receiver.\n */\n- (instancetype)initWithDocument:(CMDocument *)document;\n\n/**\n *  Renders HTML from the Markdown document.\n *\n *  @return A string containing the HTML representation\n *  of the document.\n */\n- (NSString *)render;\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMHTMLRenderer.m",
    "content": "//\n//  CMHTMLRenderer.m\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/20/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import \"CMHTMLRenderer.h\"\n#import \"CMDocument_Private.h\"\n#import \"CMNode_Private.h\"\n#include \"cmark-gfm-core-extensions.h\"\n#include \"registry.h\"\n\n@implementation CMHTMLRenderer {\n    CMDocument *_document;\n    cmark_llist * _extensions;\n}\n\n- (instancetype)initWithDocument:(CMDocument *)document\n{\n    if ((self = [super init])) {\n        _document = document;\n        _extensions = cmark_list_syntax_extensions(cmark_get_default_mem_allocator());\n    }\n    return self;\n}\n\n- (void)dealloc\n{\n    cmark_llist_free(cmark_get_default_mem_allocator(), _extensions);\n}\n\n- (NSString *)render\n{\n    char *html = cmark_render_html(_document.rootNode.node, (int)_document.options, _extensions);\n    return [NSString stringWithUTF8String:html];\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMHTMLScriptTransformer.h",
    "content": "//\n//  CMHTMLScriptTransformer.h\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/16/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n#import \"CMHTMLElementTransformer.h\"\n\n@interface CMHTMLScriptTransformer : NSObject <CMHTMLElementTransformer>\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMHTMLScriptTransformer.m",
    "content": "//\n//  CMHTMLScriptTransformer.m\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/16/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import \"CMHTMLScriptTransformer.h\"\n#import \"CMHTMLScriptTransformer_Private.h\"\n#import \"CMPlatformDefines.h\"\n\n#import \"Ono.h\"\n\n#if TARGET_OS_IPHONE\n#import <CoreText/CTStringAttributes.h>\n#endif\n\n@implementation CMHTMLScriptTransformer {\n    CMHTMLScriptStyle _style;\n    CGFloat _fontSizeRatio;\n    CGFloat _baselineOffset;\n}\n\n- (instancetype)initWithStyle:(CMHTMLScriptStyle)style fontSizeRatio:(CGFloat)ratio baselineOffset:(CGFloat)offset\n{\n    if ((self = [super init])) {\n        _style = style;\n        _fontSizeRatio = ratio;\n        _baselineOffset = offset;\n    }\n    return self;\n}\n\n#pragma mark - CMHTMLElementTransformer\n\n+ (NSString *)tagName\n{\n    NSAssert(NO, @\"Must be implemented by a subclass\");\n    return nil;\n}\n\n- (NSAttributedString *)attributedStringForElement:(ONOXMLElement *)element attributes:(NSDictionary *)attributes\n{\n    CMAssertCorrectTag(element);\n    \n    NSMutableDictionary *allAttributes = [attributes mutableCopy];\n    NSString *superscriptAttribute = nil;\n#if TARGET_OS_IPHONE\n    superscriptAttribute = (__bridge NSString *)kCTSuperscriptAttributeName;\n#else\n    superscriptAttribute = NSSuperscriptAttributeName;\n#endif\n    allAttributes[superscriptAttribute] = @(_style);\n    CMFont *font = attributes[NSFontAttributeName];\n    if (font != nil) {\n        font = [CMFont fontWithDescriptor:font.fontDescriptor size:font.pointSize * _fontSizeRatio];\n        allAttributes[NSFontAttributeName] = font;\n    }\n    if (_baselineOffset != 0.0) {\n        allAttributes[NSBaselineOffsetAttributeName] = @(_baselineOffset);\n    }\n\n    return [[NSAttributedString alloc] initWithString:element.stringValue attributes:allAttributes];\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMHTMLScriptTransformer_Private.h",
    "content": "//\n//  CMHTMLScriptTransformer_Private.h\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/16/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import \"CMHTMLScriptTransformer.h\"\n\n#if TARGET_OS_IPHONE\n#import <UIKit/UIKit.h>\n#else\n#import <Cocoa/Cocoa.h>\n#endif\n\ntypedef NS_ENUM(NSInteger, CMHTMLScriptStyle) {\n    CMHTMLScriptStyleSubscript = -1,\n    CMHTMLScriptStyleSuperscript = 1\n};\n\n@interface CMHTMLScriptTransformer ()\n- (instancetype)initWithStyle:(CMHTMLScriptStyle)style fontSizeRatio:(CGFloat)ratio baselineOffset:(CGFloat)offset;\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMHTMLStrikethroughTransformer.h",
    "content": "//\n//  CMHTMLStrikethroughTransformer.h\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/16/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n#import \"CMHTMLElementTransformer.h\"\n#import \"CMPlatformDefines.h\"\n\n/**\n Transforms HTML strikethrough elements (<s></s>) into attributed strings.\n */\n@interface CMHTMLStrikethroughTransformer : NSObject <CMHTMLElementTransformer>\n\n/**\n *  Initializes the receiver with the default attributes -- a single line\n *  style and a color that matches the color of the text.\n *\n *  @return An initialized instance of the receiver.\n */\n- (instancetype)init;\n\n/**\n *  Initializes the receiver with a custom style and color.\n *\n *  @param style Strikethrough style.\n *  @param color Strikethrough color. If `nil`, the transformer uses\n *  the color of the text if it has been specified.\n *\n *  @return An initialized instance of the receiver.\n */\n- (instancetype)initWithStrikethroughStyle:(CMUnderlineStyle)style color:(CMColor *)color;\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMHTMLStrikethroughTransformer.m",
    "content": "//\n//  CMHTMLStrikethroughTransformer.m\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/16/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import \"CMHTMLStrikethroughTransformer.h\"\n#import \"Ono.h\"\n\n@implementation CMHTMLStrikethroughTransformer {\n    CMUnderlineStyle _style;\n    CMColor *_color;\n}\n\n- (instancetype)init\n{\n    return [self initWithStrikethroughStyle:NSUnderlineStyleSingle color:nil];\n}\n\n- (instancetype)initWithStrikethroughStyle:(CMUnderlineStyle)style color:(CMColor *)color\n{\n    if ((self = [super init])) {\n        _style = style;\n        _color = color;\n    }\n    return self;\n}\n\n#pragma mark - CMHTMLElementTransformer\n\n+ (NSString *)tagName { return @\"s\"; };\n\n- (NSAttributedString *)attributedStringForElement:(ONOXMLElement *)element attributes:(NSDictionary *)attributes\n{\n    CMAssertCorrectTag(element);\n    \n    NSMutableDictionary *allAttributes = [attributes mutableCopy];\n    allAttributes[NSStrikethroughStyleAttributeName] = @(_style);\n    \n    CMColor *color = _color ?: allAttributes[NSForegroundColorAttributeName];\n    if (color != nil) {\n        allAttributes[NSStrikethroughColorAttributeName] = color;\n    }\n    \n    return [[NSAttributedString alloc] initWithString:element.stringValue attributes:allAttributes];\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMHTMLSubscriptTransformer.h",
    "content": "//\n//  CMHTMLSubscriptTransformer.h\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/16/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n#import \"CMHTMLScriptTransformer.h\"\n\n#if TARGET_OS_IPHONE\n#import <UIKit/UIKit.h>\n#else\n#import <Cocoa/Cocoa.h>\n#endif\n\n/**\n *  Transforms HTML subscript elements (<sub></sub>) into attributed strings.\n */\n@interface CMHTMLSubscriptTransformer : CMHTMLScriptTransformer\n\n/**\n *  Initializes the receiver with the default font ratio (0.7)\n *\n *  @return An initialized instance of the receiver.\n */\n- (instancetype)init;\n\n/**\n *  Initializes the receiver with a custom font size ratio.\n *\n *  @param ratio The factor to multiply the existing font point\n *  size by to calculate the size of the subscript font.\n *\n *  @return An initialized instance of the receiver.\n */\n- (instancetype)initWithFontSizeRatio:(CGFloat)ratio;\n\n/**\n *  Initializes the receiver with a custom font size ratio and a custom baseline offset.\n *\n *  @param ratio The factor to multiply the existing font point\n *  size by to calculate the size of the superscript font.\n *  @param offset The offset for the baseline of the subscript.\n *\n *  @return An initialized instance of the receiver.\n */\n- (instancetype)initWithFontSizeRatio:(CGFloat)ratio baselineOffset:(CGFloat)offset;\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMHTMLSubscriptTransformer.m",
    "content": "//\n//  CMHTMLSubscriptTransformer.m\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/16/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import \"CMHTMLSubscriptTransformer.h\"\n#import \"CMHTMLScriptTransformer_Private.h\"\n\n@implementation CMHTMLSubscriptTransformer\n\n- (instancetype)init\n{\n    return [self initWithFontSizeRatio:0.7];\n}\n\n- (instancetype)initWithFontSizeRatio:(CGFloat)ratio\n{\n    return [self initWithStyle:CMHTMLScriptStyleSubscript fontSizeRatio:ratio baselineOffset:0.0];\n}\n\n- (instancetype)initWithFontSizeRatio:(CGFloat)ratio baselineOffset:(CGFloat)offset\n{\n    return [super initWithStyle:CMHTMLScriptStyleSubscript fontSizeRatio:ratio baselineOffset:offset];\n}\n\n#pragma mark - CMHTMLElementTransformer\n\n+ (NSString *)tagName { return @\"sub\"; };\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMHTMLSuperscriptTransformer.h",
    "content": "//\n//  CMHTMLSuperscriptTransformer.h\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/16/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n#import \"CMHTMLScriptTransformer.h\"\n\n#if TARGET_OS_IPHONE\n#import <UIKit/UIKit.h>\n#else\n#import <Cocoa/Cocoa.h>\n#endif\n\n/**\n *  Transforms HTML superscript elements (<sup></sup>) into attributed strings.\n */\n@interface CMHTMLSuperscriptTransformer : CMHTMLScriptTransformer\n\n/**\n *  Initializes the receiver with the default font ratio (0.7)\n *\n *  @return An initialized instance of the receiver.\n */\n- (instancetype)init;\n\n/**\n *  Initializes the receiver with a custom font size ratio and a default baseline offset.\n *\n *  @param ratio The factor to multiply the existing font point\n *  size by to calculate the size of the superscript font.\n *\n *  @return An initialized instance of the receiver.\n */\n- (instancetype)initWithFontSizeRatio:(CGFloat)ratio;\n\n/**\n *  Initializes the receiver with a custom font size ratio and a custom baseline offset.\n *\n *  @param ratio The factor to multiply the existing font point\n *  size by to calculate the size of the superscript font.\n *  @param offset The offset for the baseline of the superscript.\n *\n *  @return An initialized instance of the receiver.\n */\n- (instancetype)initWithFontSizeRatio:(CGFloat)ratio baselineOffset:(CGFloat)offset;\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMHTMLSuperscriptTransformer.m",
    "content": "//\n//  CMHTMLSuperscriptTransformer.m\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/16/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import \"CMHTMLSuperscriptTransformer.h\"\n#import \"CMHTMLScriptTransformer_Private.h\"\n\n@implementation CMHTMLSuperscriptTransformer\n\n- (instancetype)init\n{\n    return [self initWithFontSizeRatio:0.7];\n}\n\n- (instancetype)initWithFontSizeRatio:(CGFloat)ratio\n{\n    return [self initWithStyle:CMHTMLScriptStyleSuperscript fontSizeRatio:ratio baselineOffset:0.0];\n}\n\n- (instancetype)initWithFontSizeRatio:(CGFloat)ratio baselineOffset:(CGFloat)offset\n{\n    return [super initWithStyle:CMHTMLScriptStyleSuperscript fontSizeRatio:ratio baselineOffset:offset];\n}\n\n#pragma mark - CMHTMLElementTransformer\n\n+ (NSString *)tagName { return @\"sup\"; };\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMHTMLUnderlineTransformer.h",
    "content": "//\n//  CMHTMLUnderlineTransformer.h\n//  CocoaMarkdown\n//\n//  Created by Damien Rambout on 19/01/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n#import \"CMHTMLElementTransformer.h\"\n#import \"CMPlatformDefines.h\"\n\n/**\n Transforms HTML underline elements (<u></u>) into attributed strings.\n */\n@interface CMHTMLUnderlineTransformer : NSObject <CMHTMLElementTransformer>\n\n/**\n *  Initializes the receiver with the default attributes -- a single line\n *  style and a color that matches the color of the text.\n *\n *  @return An initialized instance of the receiver.\n */\n- (instancetype)init;\n\n/**\n *  Initializes the receiver with a custom style and color.\n *\n *  @param style Strikethrough style.\n *  @param color Strikethrough color. If `nil`, the transformer uses\n *  the color of the text if it has been specified.\n *\n *  @return An initialized instance of the receiver.\n */\n- (instancetype)initWithUnderlineStyle:(CMUnderlineStyle)style color:(CMColor *)color;\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMHTMLUnderlineTransformer.m",
    "content": "//\n//  CMHTMLUnderlineTransformer.m\n//  CocoaMarkdown\n//\n//  Created by Damien Rambout on 21/01/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import \"CMHTMLUnderlineTransformer.h\"\n#import \"Ono.h\"\n\n@implementation CMHTMLUnderlineTransformer {\n    CMUnderlineStyle _style;\n    CMColor *_color;\n}\n\n- (instancetype)init\n{\n    return [self initWithUnderlineStyle:NSUnderlineStyleSingle color:nil];\n}\n\n- (instancetype)initWithUnderlineStyle:(CMUnderlineStyle)style color:(CMColor *)color\n{\n    if ((self = [super init])) {\n        _style = style;\n        _color = color;\n    }\n    return self;\n}\n\n#pragma mark - CMHTMLElementTransformer\n\n+ (NSString *)tagName { return @\"u\"; };\n\n- (NSAttributedString *)attributedStringForElement:(ONOXMLElement *)element attributes:(NSDictionary *)attributes\n{\n    CMAssertCorrectTag(element);\n    \n    NSMutableDictionary *allAttributes = [attributes mutableCopy];\n    allAttributes[NSUnderlineStyleAttributeName] = @(_style);\n    \n    CMColor *color = _color ?: allAttributes[NSForegroundColorAttributeName];\n    if (color != nil) {\n        allAttributes[NSUnderlineColorAttributeName] = color;\n    }\n    \n    return [[NSAttributedString alloc] initWithString:element.stringValue attributes:allAttributes];\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMHTMLUtilities.h",
    "content": "//\n//  CMHTMLUtilities.h\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/16/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\nNSString * CMTagNameFromHTMLTag(NSString *tag);\nBOOL CMIsHTMLVoidTagName(NSString *name);\nBOOL CMIsHTMLTag(NSString *tag);\nBOOL CMIsHTMLClosingTag(NSString *tag);\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMHTMLUtilities.m",
    "content": "//\n//  CMHTMLUtilities.m\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/16/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import \"CMHTMLUtilities.h\"\n\nNSString * CMTagNameFromHTMLTag(NSString *tag)\n{\n    // Assumes a well-formed HTML tag.\n    NSCharacterSet *alphanumeric = NSCharacterSet.alphanumericCharacterSet;\n    NSUInteger start = [tag rangeOfCharacterFromSet:alphanumeric].location;\n    if (start == NSNotFound) return nil;\n    \n    NSCharacterSet *inverseAlphanumeric = alphanumeric.invertedSet;\n    NSUInteger end = [tag rangeOfCharacterFromSet:inverseAlphanumeric options:0 range:NSMakeRange(start, tag.length - start)].location;\n    if (end == NSNotFound) return nil;\n    \n    return [tag substringWithRange:NSMakeRange(start, end - start)];\n}\n\nBOOL CMIsHTMLVoidTagName(NSString *name)\n{\n    static NSSet *voidNames = nil;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        voidNames = [NSSet setWithObjects:\n            @\"area\",\n            @\"base\",\n            @\"br\",\n            @\"col\",\n            @\"command\",\n            @\"embed\",\n            @\"hr\",\n            @\"img\",\n            @\"input\",\n            @\"keygen\",\n            @\"link\",\n            @\"meta\",\n            @\"param\",\n            @\"source\",\n            @\"track\",\n            @\"wbr\",\n            nil\n        ];\n    });\n    return [voidNames containsObject:name];\n}\n\nBOOL CMIsHTMLTag(NSString *tag)\n{\n    return [tag hasPrefix:@\"<\"] && [tag hasSuffix:@\">\"];\n}\n\nBOOL CMIsHTMLClosingTag(NSString *tag)\n{\n    return [tag hasPrefix:@\"</\"] && [tag hasSuffix:@\">\"];\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMHorizontalRuleAttachment.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n#import <AntMarkdown/CMPlatformDefines.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n *  A text attachment for displaying horizontal rules in Markdown.\n */\n@interface CMHorizontalRuleAttachment : NSTextAttachment\n\n/**\n *  Initializes a horizontal rule attachment with default settings.\n *\n *  @return An initialized instance of the receiver.\n */\n- (instancetype)init;\n\n/**\n *  The color of the horizontal rule.\n *  Defaults to light gray.\n */\n@property (nonatomic, strong) CMColor *lineColor;\n\n/**\n *  The thickness of the horizontal rule line.\n *  Defaults to 1.0.\n */\n@property (nonatomic, assign) CGFloat lineThickness;\n\n/**\n *  The inset from the left and right edges.\n *  Defaults to 0.0.\n */\n@property (nonatomic, assign) CGFloat horizontalInset;\n\n/**\n *  The vertical padding  below the line.\n *  Defaults to 6.0.\n */\n@property (nonatomic, assign) CGFloat verticalPadding;\n/**\n *  The vertical padding above the line.\n *  Defaults to 6.0.\n */\n@property (nonatomic, assign) CGFloat verticalPaddingBefore;\n\n@end\n\nNS_ASSUME_NONNULL_END \n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMHorizontalRuleAttachment.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"CMHorizontalRuleAttachment.h\"\n#import \"AMUtils.h\"\n\n@implementation CMHorizontalRuleAttachment\n\n- (instancetype)init {\n    self = [super init];\n    if (self) {\n        _lineColor = [CMColor lightGrayColor];\n        _lineThickness = 1.0;\n        _horizontalInset = 0.0;\n        _verticalPadding = 6.0;\n        _verticalPaddingBefore = 6.0;\n        \n        self.bounds = CGRectMake(0, 0, 1, _lineThickness + _verticalPadding + _verticalPaddingBefore);\n        self.image = nil;\n    }\n    return self;\n}\n\n- (nullable UIImage *)imageForBounds:(CGRect)imageBounds textContainer:(nullable NSTextContainer *)textContainer characterIndex:(NSUInteger)charIndex {\n    CGSize size = imageBounds.size;\n    \n    if (textContainer) {\n        size.width = textContainer.size.width - textContainer.lineFragmentPadding * 2 - _horizontalInset * 2;\n    }\n    \n    size.height = _lineThickness + _verticalPadding + _verticalPaddingBefore;\n    \n    AMUIGraphicsBeginImageContextWithOptions(size, NO, 0);\n    CGContextRef context = UIGraphicsGetCurrentContext();\n\n    CGContextSetStrokeColorWithColor(context, _lineColor.CGColor);\n    CGContextSetLineWidth(context, _lineThickness);\n\n    CGFloat yPosition = _verticalPaddingBefore + _lineThickness / 2.0;\n    CGContextMoveToPoint(context, 0, yPosition);\n    CGContextAddLineToPoint(context, size.width, yPosition);\n    CGContextStrokePath(context);\n    \n    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();\n    UIGraphicsEndImageContext();\n    \n    return image;\n}\n\n- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer proposedLineFragment:(CGRect)lineFrag glyphPosition:(CGPoint)position characterIndex:(NSUInteger)charIndex {\n\n    CGFloat width = textContainer.size.width - textContainer.lineFragmentPadding * 2 - _horizontalInset * 2;\n    CGFloat height = _lineThickness + _verticalPadding + _verticalPaddingBefore;\n\n    CGFloat x = _horizontalInset;\n\n    CGFloat y = -_verticalPaddingBefore;\n    \n    return CGRectMake(x, y, width, height);\n}\n\n@end \n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMImageTextAttachment.h",
    "content": "//\n//  CMImageTextAttachment.h\n//  CocoaMarkdown\n//\n//  Created by Jean-Luc on 10/05/2019.\n//  Copyright © 2019 Indragie Karunaratne. All rights reserved.\n//\n@import Foundation;\n\n#if TARGET_OS_IPHONE\n@import UIKit;\n#else\n@import Cocoa;\n#endif\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface CMImageTextAttachment : NSTextAttachment\n{\n    @protected\n    NSURL       * _imageURL;\n    CGSize      _imageSize;\n}\n- (instancetype) initWithImageURL:(NSURL*)imageURL title:(NSString*)title size:(CGSize)size;\n- (instancetype) initWithImageURL:(NSURL*)imageURL title:(NSString*)title;\n\n- (instancetype) initWithImageURL:(NSURL*)imageURL;\n\n@property (nonatomic, copy) NSString* altText;\n\n@property (nonatomic, readonly) NSURL* imageURL;\n\n@property (nonatomic, readonly, weak) NSTextContainer *textContainer;\n\n@property (nonatomic, assign) BOOL isImageLoaded;\n\n- (void)setImageWithData:(NSData *)imageData;\n\n- (void)downloadImage:(NSURL *)imageURL\n           completion:(void(^)(NSError * _Nullable error, NSData * _Nullable data))block;\n\n- (BOOL)isEqualToAttachment:(CMImageTextAttachment *)attach;\n\n- (NSString*)imageCaption;\n\n@end\n\n@interface NSLayoutManager (CMImageTextAttachment)\n\n- (void) setNeedsDisplayForAttachment:(NSTextAttachment*)textAttachment;\n- (void) setNeedsLayoutForAttachment:(NSTextAttachment*)textAttachment;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMImageTextAttachment.m",
    "content": "//\n//  CMImageTextAttachment.m\n//  CocoaMarkdown\n//\n//  Created by Jean-Luc Jumpertz on 10/05/2019.\n//  Inspired by https://www.cocoanetics.com/2016/09/asynchronous-nstextattachments-22/\n//  Copyright © 2019 Jean-Luc Jumpertz. All rights reserved.\n//\n\n#import \"CMImageTextAttachment.h\"\n#import \"AMUtils.h\"\n\n#if TARGET_OS_IPHONE\n#import <MobileCoreServices/MobileCoreServices.h> // For UTType...\n#endif\n\n@interface CMImageTextAttachment ()\n{\n    NSTextContainer* __weak _textContainer;\n    NSURLSessionDataTask* _downloadTask;\n    BOOL _isImageLoaded;\n    NSString* _imageTitle;\n}\n\n@end\n\n\n@implementation CMImageTextAttachment\n\nstatic CGSize _placeholderImageSize = {16, 16};\nstatic CGFloat _placeholderImageCornerRadius = 3.0;\n\n#if TARGET_OS_IPHONE\nstatic UIImage* _placeholderImage;\n\n+ (UIImage*) placeholderImage\n{\n    if (_placeholderImage == nil) {\n        AMUIGraphicsBeginImageContextWithOptions(_placeholderImageSize, NO, 0);\n        \n        CGRect imageRect = CGRectMake(0, 0, _placeholderImageSize.width, _placeholderImageSize.height);\n        UIBezierPath* placeholderShape = [UIBezierPath bezierPathWithRoundedRect: imageRect cornerRadius:(CGFloat)_placeholderImageCornerRadius];\n        [UIColor.lightGrayColor setFill];\n        [placeholderShape fill];\n        [UIColor.grayColor setStroke];\n        [placeholderShape stroke];\n        [@\"?\" drawInRect:CGRectInset(imageRect, 4, -1) withAttributes:@{ NSFontAttributeName: [UIFont systemFontOfSize:imageRect.size.height - 2],\n                                                                         NSForegroundColorAttributeName: UIColor.whiteColor }];\n        _placeholderImage = UIGraphicsGetImageFromCurrentImageContext();\n        \n        UIGraphicsEndImageContext();\n    }\n    return _placeholderImage;\n}\n\n#else\n\nstatic NSImage* _placeholderImage;\n\n+ (NSImage*) placeholderImage\n{\n    if (_placeholderImage == nil) {\n        _placeholderImage = [NSImage imageWithSize:_placeholderImageSize flipped:NO drawingHandler:^BOOL(NSRect dstRect) {\n            NSBezierPath* placeholderShape = [NSBezierPath bezierPathWithRoundedRect:dstRect xRadius:_placeholderImageCornerRadius yRadius:_placeholderImageCornerRadius];\n            [NSColor.lightGrayColor setFill];\n            [placeholderShape fill];\n            [NSColor.grayColor setStroke];\n            [placeholderShape stroke];\n            [@\"?\" drawInRect:CGRectInset(dstRect, 4, -1) withAttributes:@{ NSFontAttributeName: [NSFont systemFontOfSize:dstRect.size.height - 2],\n                                                                           NSForegroundColorAttributeName: NSColor.whiteColor }];\n            return YES;\n        }];\n    }\n    return _placeholderImage;\n}\n#endif\n\n- (instancetype) initWithImageURL:(NSURL*)imageURL\n{\n    return [self initWithImageURL:imageURL title:nil];\n}\n\n- (instancetype) initWithImageURL:(NSURL*)imageURL title:(NSString*)title\n{\n    NSString* imageUrlUti = (__bridge_transfer NSString*) UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)imageURL.pathExtension, kUTTypeData);\n    \n    self = [super initWithData:nil ofType:imageUrlUti];\n    if (self != nil) {\n        _imageURL = imageURL;\n        _imageSize = CGSizeZero;\n        _isImageLoaded = NO;\n        _imageTitle = title;\n        self.image = [self.class placeholderImage];\n    }\n    return self;\n}\n- (instancetype) initWithImageURL:(NSURL*)imageURL title:(NSString*)title size:(CGSize)size {\n    NSString* imageUrlUti = (__bridge_transfer NSString*) UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)imageURL.pathExtension, kUTTypeData);\n    \n    self = [super initWithData:nil ofType:imageUrlUti];\n    if (self != nil) {\n        _imageURL = imageURL;\n        _imageSize = size;\n        _isImageLoaded = NO;\n        _imageTitle = title;\n        self.image = [self.class placeholderImage];\n    }\n    return self;\n}\n- (NSString*)imageCaption\n{\n    // 优先使用title,如果title不可用，则使用alt\n    return ([_imageTitle length] > 0)?_imageTitle:self.altText;\n}\n\n- (BOOL)isImageLoaded\n{\n    return _isImageLoaded;\n}\n\n- (NSTextContainer *)textContainer\n{\n    return _textContainer;\n}\n\n- (BOOL)isEqual:(nullable id)object {\n    if (object == nil) {\n        return NO;\n    }\n    \n    if (self == object) {\n        return YES;\n    }\n    \n    if (![object isKindOfClass:[self class]]) {\n        return NO;\n    }\n    \n    return [self isEqualToAttachment:(CMImageTextAttachment *)object];\n}\n\n- (BOOL)isEqualToAttachment:(CMImageTextAttachment *)attach\n{\n    return [self.imageURL isEqual:attach.imageURL];\n}\n\n- (void)downloadImage:(NSURL *)imageURL completion:(void(^)(NSError * _Nullable error, NSData * _Nullable data))block {\n    // Not a file URL and no download task in progress: use an URL-data-task to get the data\n    _downloadTask = [NSURLSession.sharedSession dataTaskWithURL:_imageURL \n                                              completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {\n        block(error, data);\n        \n        self->_downloadTask = nil;\n    }];\n    \n    [_downloadTask resume];\n}\n\n- (CGRect) attachmentBoundsForTextContainer:(NSTextContainer *)textContainer proposedLineFragment:(CGRect)lineFrag glyphPosition:(CGPoint)position characterIndex:(NSUInteger)charIndex\n{\n    CGSize attachmentImageSize = self.image.size;\n    \n    CGFloat maxWidth = lineFrag.size.width - textContainer.lineFragmentPadding * 2;\n    if (attachmentImageSize.width > maxWidth) {\n        attachmentImageSize = CGSizeMake(maxWidth, attachmentImageSize.height * maxWidth / attachmentImageSize.width);\n    }\n    \n    CGRect attachmentBounds;\n    attachmentBounds.origin = CGPointZero;\n    attachmentBounds.size = attachmentImageSize;\n    return attachmentBounds;\n}\n\n#if TARGET_OS_IPHONE\n- (nullable UIImage *)imageForBounds:(CGRect)imageBounds textContainer:(nullable NSTextContainer *)textContainer characterIndex:(NSUInteger)charIndex\n#else\n- (nullable NSImage *)imageForBounds:(NSRect)imageBounds textContainer:(nullable NSTextContainer *)textContainer characterIndex:(NSUInteger)charIndex\n#endif\n{    \n    if (! _isImageLoaded && (_imageURL != nil)) {\n        \n        // Save a reference to the textcontainer\n        _textContainer = textContainer;\n        \n        // Load the image asynchronously\n        if (_imageURL.isFileURL) {\n            dispatch_async(dispatch_get_main_queue(), ^{\n                \n                NSData* imageData = [NSData dataWithContentsOfURL:self->_imageURL];\n                if (imageData.length > 0) {\n                    [self setImageWithData:imageData];\n                    self->_isImageLoaded = YES;\n                }\n            });\n        }\n        else if (_downloadTask == nil) {\n            // Not a file URL and no download task in progress: use an URL-data-task to get the data\n            [self downloadImage:_imageURL\n                     completion:^(NSError * _Nullable error, NSData * _Nullable data) {\n                if ((error == nil) && (data.length > 0)) {\n                    dispatch_async(dispatch_get_main_queue(), ^{\n                        [self setImageWithData:data];\n                        self->_isImageLoaded = YES;\n                    });\n                }\n            }];\n        }\n    }    \n    \n#if !TARGET_OS_IPHONE\n#ifdef __MAC_10_15\n    if (! [NSProcessInfo.processInfo isOperatingSystemAtLeastVersion: (NSOperatingSystemVersion){10, 15, 0}]) \n#endif\n    {\n        // On macOS 10.14.6 and below, the image attachment is dislayed vertically flipped, so we need to flip it again to display it correctly\n        // This issue has been fixed on macOS 10.15 for applications compiled with Xcode 11 or later (SDK version >= 10.15)\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n        [self.image setFlipped:NSGraphicsContext.currentContext.isFlipped];\n#pragma clang diagnostic pop\n    }\n#endif\n    \n    return self.image;\n}\n- (void)imageResize:(UIImage *)image scaledToSize:(CGSize)newSize {\n    AMUIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);\n    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];\n    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();\n    UIGraphicsEndImageContext();\n    self.image = newImage;\n}\n- (void) setImageWithData:(NSData*)imageData\n{\n    NSString* imageUti = (__bridge_transfer NSString*) UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)_imageURL.pathExtension, kUTTypeData);\n    self.fileType = imageUti;\n    self.contents = imageData;\n    \n    CGSize currentImageSize = self.image.size;\n    \n#if TARGET_OS_IPHONE\n    self.image = [UIImage imageWithData: imageData];\n#else\n    self.image = [[NSImage alloc] initWithData:imageData];\n#endif\n    \n    if (self.image != nil) {\n        if (_imageSize.width != 0 && _imageSize.height !=0) {\n            [self imageResize:self.image scaledToSize:_imageSize];\n        }\n        if (! CGSizeEqualToSize(self.image.size, currentImageSize)) {\n             // The layout needs to be refreshed\n            [_textContainer.layoutManager setNeedsLayoutForAttachment:self];\n        }\n        else {\n            // The image display should be refreshed\n            [_textContainer.layoutManager setNeedsDisplayForAttachment:self];\n        }\n    }\n}\n\n@end\n\n#pragma mark - NSLayoutManager class extension\n\n@implementation NSLayoutManager (CMImageTextAttachment)\n\n/// Trigger a re-display for an attachment\n- (void) setNeedsDisplayForAttachment:(NSTextAttachment*)textAttachment\n{\n    NSArray<NSValue*>* rangesForAttachment = [self rangesForAttachment:textAttachment];\n    \n    [rangesForAttachment enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSValue * _Nonnull rangeObject, NSUInteger idx, BOOL * _Nonnull stop) {\n        // invalidate the display for the range\n        [self invalidateDisplayForCharacterRange:rangeObject.rangeValue];\n    }];\n}\n\n/// Trigger a relayout for an attachment\n- (void) setNeedsLayoutForAttachment:(NSTextAttachment*)textAttachment\n{\n    NSArray<NSValue*>* rangesForAttachment = [self rangesForAttachment:textAttachment];\n    \n    [rangesForAttachment enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSValue * _Nonnull rangeObject, NSUInteger idx, BOOL * _Nonnull stop) {\n        // invalidate the layout for the range\n        [self invalidateLayoutForCharacterRange:rangeObject.rangeValue actualCharacterRange:NULL];\n        // also need to trigger re-display or already visible images might not get updated\n        [self invalidateDisplayForCharacterRange:rangeObject.rangeValue];\n    }];\n}\n\n- (NSArray<NSValue*>*) rangesForAttachment:(NSTextAttachment*)textAttachment\n{\n    NSMutableArray<NSValue*>* rangesForAttachment = [NSMutableArray new];\n    \n    [self.textStorage enumerateAttribute:NSAttachmentAttributeName inRange:NSMakeRange(0, self.textStorage.length) options:0 usingBlock:^(id  _Nullable value, NSRange range, BOOL * _Nonnull stop) {\n        if (value == textAttachment) {\n            [rangesForAttachment addObject:[NSValue valueWithRange:range]];\n        }\n    }];\n    \n    return rangesForAttachment;\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMInlineTextAttachment.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <UIKit/UIKit.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface CMInlineTextAttachment : NSTextAttachment\n@property (nonatomic, nullable) NSString *text;\n\n- (instancetype)initWithSize:(CGSize)size;\n- (instancetype)initWithText:(nullable NSString *)text size:(CGSize)size;\n\n- (void)setNeedsUpdate;\n\n- (BOOL)isEqualToAttachment:(CMInlineTextAttachment *)attach;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMInlineTextAttachment.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"CMInlineTextAttachment.h\"\n#import \"CMImageTextAttachment.h\"\n\n@implementation CMInlineTextAttachment\n{\n    __weak NSTextContainer *_textContainer;\n}\n\n- (instancetype)initWithData:(NSData *)contentData ofType:(NSString *)uti {\n    self = [super initWithData:contentData ofType:uti];\n    if (self) {\n        \n    }\n    return self;\n}\n\n- (instancetype)initWithText:(NSString *)text size:(CGSize)size {\n    self = [self initWithData:nil ofType:nil];\n    if (self) {\n        self.text = text;\n        self.bounds = CGRectMake(0, -size.height / 2, size.width, size.height);\n    }\n    return self;\n}\n\n- (instancetype)initWithSize:(CGSize)size {\n    return [self initWithText:nil size:size];\n}\n\n- (void)setNeedsUpdate {\n    [_textContainer.layoutManager setNeedsLayoutForAttachment:self];\n}\n\n- (BOOL)isEqual:(nullable id)object {\n    if (object == nil) {\n        return NO;\n    }\n    \n    if (self == object) {\n        return YES;\n    }\n    \n    if (![object isKindOfClass:[self class]]) {\n        return NO;\n    }\n    \n    return [self isEqualToAttachment:(CMInlineTextAttachment *)object];\n}\n\n- (BOOL)isEqualToAttachment:(CMInlineTextAttachment *)attach\n{\n    return [self.text isEqual:attach.text];\n}\n\n- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer\n                      proposedLineFragment:(CGRect)lineFrag\n                             glyphPosition:(CGPoint)position\n                            characterIndex:(NSUInteger)charIndex {\n    _textContainer = textContainer;\n    return [super attachmentBoundsForTextContainer:textContainer\n                              proposedLineFragment:lineFrag\n                                     glyphPosition:position\n                                    characterIndex:charIndex];\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMIterator.h",
    "content": "//\n//  CMIterator.h\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/13/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\ntypedef NS_ENUM(NSInteger, CMEventType) {\n    CMEventTypeNone,\n    CMEventTypeDone,\n    CMEventTypeEnter,\n    CMEventTypeExit\n};\n\n@class CMNode;\n\n/**\n *  Walks through a tree of nodes.\n */\n@interface CMIterator : NSObject\n\n/**\n *  Initializes the receiver with a root node.\n *\n *  @param rootNode Root node to start traversing from.\n *\n *  @return An initialized instance of the receiver.\n */\n- (instancetype)initWithRootNode:(CMNode *)rootNode;\n\n/**\n *  Returns the current node.\n */\n@property (readonly) CMNode *currentNode;\n\n/**\n *  Returns the current event type.\n */\n@property (readonly) CMEventType currentEvent;\n\n/**\n *  Walks through a tree of nodes, starting from the root node.\n *\n *  @discussion See the section on iterators in cmark.h for more details.\n *\n *  @param block Block to call upon entering or exiting a node during traversal.\n *  Set `stop` to `YES` to stop iteration.\n */\n- (void)enumerateUsingBlock:(void (^)(CMNode *node, CMEventType event, BOOL *stop))block;\n\n/**\n *  Resets the iterator to the specified node and event. The node must be either\n *  the root node or a child of the root node.\n *\n *  @param node      The node to reset to.\n *  @param eventType The event to reset to.\n */\n- (void)resetToNode:(CMNode *)node withEventType:(CMEventType)eventType;\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMIterator.m",
    "content": "//\n//  CMIterator.m\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/13/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import \"CMIterator.h\"\n#import \"CMNode_Private.h\"\n\n@implementation CMIterator {\n    cmark_iter *_iter;\n}\n\n#pragma mark - Initialization\n\n- (instancetype)initWithRootNode:(CMNode *)rootNode\n{\n    NSParameterAssert(rootNode);\n    \n    if ((self = [super init])) {\n        _iter = cmark_iter_new(rootNode.node);\n        if (_iter == NULL) return nil;\n    }\n    return self;\n}\n\n- (void)dealloc\n{\n    cmark_iter_free(_iter);\n}\n\n#pragma mark - Accessors\n\n- (CMNode *)currentNode\n{\n    return [[CMNode alloc] initWithNode:cmark_iter_get_node(_iter) freeWhenDone:NO];\n}\n\n- (CMEventType)currentEvent\n{\n    return (CMEventType)cmark_iter_get_event_type(_iter);\n}\n\n#pragma mark - Iteration\n\n- (void)enumerateUsingBlock:(void (^)(CMNode *node, CMEventType event, BOOL *stop))block\n{\n    NSParameterAssert(block);\n    \n    cmark_event_type event;\n    BOOL stop = NO;\n    \n    while ((event = cmark_iter_next(_iter)) != CMARK_EVENT_DONE) {\n        CMNode *currentNode = [[CMNode alloc] initWithNode:cmark_iter_get_node(_iter) freeWhenDone:NO];\n        block(currentNode, (CMEventType)event, &stop);\n        if (stop) break;\n    }\n}\n\n- (void)resetToNode:(CMNode *)node withEventType:(CMEventType)eventType\n{\n    cmark_iter_reset(_iter, node.node, (cmark_event_type)eventType);\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMNode+Table.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n#import \"CMNode.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface CMTableCell : NSObject\n@property (nonatomic, readonly) NSTextAlignment alignment;\n@property (nonatomic, readonly) NSAttributedString *content;\n\n+ (instancetype)cellWithContent:(NSAttributedString *)content;\n+ (instancetype)cellWithContent:(NSAttributedString *)content\n                      alignment:(NSTextAlignment)alignment;\n\n- (BOOL)isEqualToCell:(CMTableCell *)cell;\n\n@end\n\n@interface CMTableRow : NSObject\n@property (nonatomic, readonly) NSArray <CMTableCell *> *cells;\n@property (nonatomic, readonly) NSInteger numberOfColumns;\n@property (nonatomic, readonly) BOOL isHeader;\n\n+ (instancetype)row;\n+ (instancetype)rowWithHeader:(BOOL)isHeader;\n\n- (void)push:(CMTableCell *)cell;\n\n- (BOOL)isEqualToRow:(CMTableRow *)row;\n\n@end\n\n@interface CMTable : NSObject\n@property (nonatomic, readonly) NSArray <CMTableRow *> *rows;\n@property (nonatomic, readonly) NSInteger numberOfColumns;\n@property (nonatomic, readonly) NSInteger numberOfRows;\n\n+ (instancetype)tableWithNumberOfColumns:(NSUInteger)numberOfColumns;\n\n- (void)push:(CMTableRow *)row;\n- (CMTableRow *)peekRow;\n\n\n- (CMTableCell *)cellAtIndexPath:(NSIndexPath *)indexPath;\n- (BOOL)isHeaderAtIndexPath:(NSIndexPath *)indexPath;\n\n- (BOOL)isEqualToTable:(CMTable *)table;\n\n@end\n\n@interface CMNode (Table)\n\n@property (readonly, nullable) CMTable *table;\n@property (nonatomic, readonly) NSInteger numberOfColumns;\n@property (readonly) BOOL rowIsHeader;\n@property (readonly) NSTextAlignment cellAlignment;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMNode+Table.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"CMNode+Table.h\"\n#import \"CMNode_Private.h\"\n\n@implementation CMTable\n{\n    NSMutableArray<CMTableRow *> * _rows;\n    CMNode * _node;\n}\n\n+ (instancetype)tableWithNumberOfColumns:(NSUInteger)numberOfColumns\n{\n    CMTable *table = [self new];\n    table->_numberOfColumns = numberOfColumns;\n    return table;\n}\n\n- (instancetype)init\n{\n    self = [super init];\n    if (self) {\n        _rows = [NSMutableArray array];\n    }\n    return self;\n}\n\n- (instancetype)initWithNode:(CMNode *)node {\n    self = [self init];\n    if (self) {\n        _node = node;\n    }\n    return self;\n}\n\n- (NSArray<CMTableRow *> *)rows\n{\n    return [_rows copy];\n}\n\n- (void)push:(nonnull CMTableRow *)row {\n    [_rows addObject:row];\n}\n\n- (nonnull CMTableRow *)peekRow {\n    return _rows.lastObject;\n}\n\n- (NSInteger)numberOfRows\n{\n    return _rows.count;\n}\n\n- (CMTableCell *)cellAtIndexPath:(NSIndexPath *)indexPath\n{\n    return self.rows[indexPath.section].cells[indexPath.item];\n}\n\n- (BOOL)isHeaderAtIndexPath:(NSIndexPath *)indexPath\n{\n    return self.rows[indexPath.section].isHeader;\n}\n\n- (BOOL)isEqual:(nullable id)object {\n    if (object == nil) {\n        return NO;\n    }\n    \n    if (self == object) {\n        return YES;\n    }\n    \n    if (![object isKindOfClass:[self class]]) {\n        return NO;\n    }\n    \n    return [self isEqualToTable:(CMTable *)object];\n}\n\n- (BOOL)isEqualToTable:(CMTable *)table\n{\n    return self.numberOfRows == table.numberOfRows\n    && self.numberOfColumns == table.numberOfColumns\n    && [self.rows isEqualToArray:table.rows];\n}\n\n@end\n\n@implementation CMTableRow\n{\n    NSMutableArray<CMTableCell *> * _cells;\n    CMNode * _node;\n}\n\n- (instancetype)init {\n    self = [super init];\n    if (self) {\n        _cells = [NSMutableArray array];\n    }\n    return self;\n}\n\n- (instancetype)initWithNode:(CMNode *)node {\n    self = [self init];\n    if (self) {\n        _node = node;\n    }\n    return self;\n}\n\n\n+ (nonnull instancetype)rowWithHeader:(BOOL)isHeader {\n    CMTableRow *row = [self new];\n    row->_isHeader = isHeader;\n    return row;\n}\n\n+ (nonnull instancetype)row {\n    return [self rowWithHeader:NO];\n}\n\n- (void)push:(nonnull CMTableCell *)cell {\n    [_cells addObject:cell];\n}\n\n- (NSInteger)numberOfColumns\n{\n    return _cells.count;\n}\n\n- (BOOL)isEqual:(nullable id)object {\n    if (object == nil) {\n        return NO;\n    }\n    \n    if (self == object) {\n        return YES;\n    }\n    \n    if (![object isKindOfClass:[self class]]) {\n        return NO;\n    }\n    \n    return [self isEqualToRow:(CMTableRow *)object];\n}\n\n- (BOOL)isEqualToRow:(CMTableRow *)row\n{\n    return self.isHeader == row.isHeader\n    && [self.cells isEqualToArray:row.cells];\n}\n\n@end\n\n@implementation CMTableCell\n{\n    CMNode * _node;\n}\n\n- (instancetype)initWithNode:(CMNode *)node {\n    self = [super init];\n    if (self) {\n        _node = node;\n    }\n    return self;\n}\n\n- (BOOL)isEqual:(nullable id)object {\n    if (object == nil) {\n        return NO;\n    }\n    \n    if (self == object) {\n        return YES;\n    }\n    \n    if (![object isKindOfClass:[self class]]) {\n        return NO;\n    }\n    \n    return [self isEqualToCell:(CMTableCell *)object];\n}\n\n- (BOOL)isEqualToCell:(CMTableCell *)cell\n{\n    return self.alignment == cell.alignment\n    && [self.content isEqualToAttributedString:cell.content];\n}\n\n+ (nonnull instancetype)cellWithContent:(nonnull NSAttributedString *)content\n                              alignment:(NSTextAlignment)alignment {\n    CMTableCell *cell = [self new];\n    cell->_content = [content copy];\n    cell->_alignment = alignment;\n    return cell;\n}\n\n+ (nonnull instancetype)cellWithContent:(nonnull NSAttributedString *)content {\n    return [self cellWithContent:content alignment:NSTextAlignmentNatural];\n}\n\n@end\n\n@implementation CMNode (Table)\n\n- (CMTable *)table {\n    if (self.type != CMNodeTypeTable) {\n        return nil;\n    }\n    return [[CMTable alloc] initWithNode:self];\n}\n\n- (BOOL)rowIsHeader {\n    return cmark_gfm_extensions_get_table_row_is_header(self.node);\n}\n\n- (NSInteger)numberOfColumns {\n    return cmark_gfm_extensions_get_table_columns(self.node);\n}\n\n- (NSTextAlignment)cellAlignment {\n    uint8_t align = cmark_gfm_extensions_get_table_cell_alignment(self.node);\n    switch (align) {\n        case 'l':\n            return NSTextAlignmentLeft;\n            break;\n        case 'r':\n            return NSTextAlignmentRight;\n            break;\n        case 'c':\n            return NSTextAlignmentCenter;\n            break;\n        default:\n            return NSTextAlignmentNatural;\n            break;\n    }\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMNode.h",
    "content": "//\n//  CMNode.h\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/12/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n#include \"cmark-gfm.h\"\n\nextern cmark_node_type CMARK_NODE_TABLE, CMARK_NODE_TABLE_ROW, CMARK_NODE_TABLE_CELL, CMARK_NODE_STRIKETHROUGH, CMARK_NODE_MATH_INLINE, CMARK_NODE_MATH_BLOCK, CMARK_NODE_EMOJI;\n\n@class CMIterator;\n\ntypedef NS_ENUM(NSInteger, CMNodeType) {\n    /* Error status */\n    CMNodeTypeNone          = CMARK_NODE_NONE,\n    \n    /* Block */\n    CMNodeTypeDocument      = CMARK_NODE_DOCUMENT,\n    CMNodeTypeBlockQuote    = CMARK_NODE_BLOCK_QUOTE,\n    CMNodeTypeList          = CMARK_NODE_LIST,\n    CMNodeTypeItem          = CMARK_NODE_ITEM,\n    CMNodeTypeCodeBlock     = CMARK_NODE_CODE_BLOCK,\n    CMNodeTypeHTML          = CMARK_NODE_HTML,\n    CMNodeTypeCustomBlock   = CMARK_NODE_CUSTOM_BLOCK,\n    CMNodeTypeParagraph     = CMARK_NODE_PARAGRAPH,\n    CMNodeTypeHeader        = CMARK_NODE_HEADER,\n    CMNodeTypeHRule         = CMARK_NODE_HRULE,\n    CMNodeTypeFootNote      = CMARK_NODE_FOOTNOTE_DEFINITION,\n    \n    CMNodeTypeFirstBlock    = CMNodeTypeDocument,\n    CMNodeTypeLastBlock     = CMNodeTypeFootNote,\n    \n    /* Inline */\n    CMNodeTypeText          = CMARK_NODE_TEXT,\n    CMNodeTypeSoftbreak     = CMARK_NODE_SOFTBREAK,\n    CMNodeTypeLinebreak     = CMARK_NODE_LINEBREAK,\n    CMNodeTypeCode          = CMARK_NODE_CODE,\n    CMNodeTypeInlineHTML    = CMARK_NODE_INLINE_HTML,\n    CMNodeTypeCustomInline  = CMARK_NODE_CUSTOM_INLINE,\n    CMNodeTypeEmphasis      = CMARK_NODE_EMPH,\n    CMNodeTypeStrong        = CMARK_NODE_STRONG,\n    CMNodeTypeLink          = CMARK_NODE_LINK,\n    CMNodeTypeImage         = CMARK_NODE_IMAGE,\n    CMNodeTypeFootNoteRef   = CMARK_NODE_FOOTNOTE_REFERENCE,\n    \n    CMNodeTypeFirstInline   = CMNodeTypeText,\n    CMNodeTypeLastInline    = CMNodeTypeFootNoteRef,\n};\n\n#define CMNodeTypeTable ((CMNodeType)CMARK_NODE_TABLE)\n#define CMNodeTypeTableRow ((CMNodeType)CMARK_NODE_TABLE_ROW)\n#define CMNodeTypeTableCell ((CMNodeType)CMARK_NODE_TABLE_CELL)\n#define CMNodeTypeStrikeThrough ((CMNodeType)CMARK_NODE_STRIKETHROUGH)\n#define CMNodeTypeMathInline ((CMNodeType)CMARK_NODE_MATH_INLINE)\n#define CMNodeTypeMathBlock ((CMNodeType)CMARK_NODE_MATH_BLOCK)\n#define CMNodeTypeEmoji ((CMNodeType)CMARK_NODE_EMOJI)\n\ntypedef NS_ENUM(NSInteger, CMListType) {\n    CMListTypeNone,\n    CMListTypeUnordered,\n    CMListTypeOrdered\n};\n\ntypedef NS_ENUM(NSInteger, CMDelimeterType) {\n    CMDelimeterTypeNone,\n    CMDelimeterTypePeriod,\n    CMDelimeterTypeParen\n};\n\n/**\n *  Immutable interface to a CommonMark node.\n */\n@interface CMNode : NSObject\n\n/**\n *  Creates an iterator for the node tree that has the\n *  receiver as its root.\n *\n *  @return A new iterator.\n */\n- (CMIterator *)iterator;\n\n/**\n *  The next node in the sequence, or `nil` if there is none.\n */\n@property (readonly) CMNode *next;\n\n/**\n *  The previous node in the sequence, or `nil` if there is none.\n */\n@property (readonly) CMNode *previous;\n\n/**\n *  The receiver's parent node, or `nil` if there is none.\n */\n@property (readonly) CMNode *parent;\n\n/**\n *  The first child node of the receiver, or `nil` if there is none.\n */\n@property (readonly) CMNode *firstChild;\n\n/**\n *  The last child node of the receiver, or `nil` if there is none.\n */\n@property (readonly) CMNode *lastChild;\n\n/**\n *  The type of the node, or `CMNodeTypeNone` on error.\n */\n@property (readonly) CMNodeType type;\n\n/**\n *  String representation of `type`.\n */\n@property (readonly) NSString *humanReadableType;\n\n/**\n *  String contents of the receiver, or `nil` if there is none.\n */\n@property (readonly) NSString *stringValue;\n\n/**\n *  Content of the receiver, or `nil` if there is none.\n */\n@property (readonly) NSString *contentValue;\n\n/**\n *  Header level of the receiver, or `0` if the receiver is not a header.\n */\n@property (readonly) NSInteger headerLevel;\n\n/**\n *  Info string from a fenced code block, or `nil` if there is none.\n */\n@property (readonly) NSString *fencedCodeInfo;\n\n/**\n *  The receiver's list type, or `CMListTypeNone` if the receiver\n *  is not a list.\n */\n@property (readonly) CMListType listType;\n\n/**\n *  The receiver's list delimeter type, or `CMDelimeterTypeNone` if the\n *  receiver is not a list.\n */\n@property (readonly) CMDelimeterType listDelimeterType;\n\n/**\n *  Starting number of the list, or `0` if the receiver is not\n *  an ordered list.\n */\n@property (readonly) NSInteger listStartingNumber;\n\n/**\n *  `YES` if the receiver is a tight list, `NO` otherwise.\n */\n@property (readonly) BOOL listTight;\n\n/**\n *  Link or image URL string (as set in the document), or `nil` if there is none.\n */\n@property (readonly) NSString *URLString;\n\n/**\n *  Link or image URL, or `nil` if there is none.\n */\n@property (readonly) NSURL *URL;\n\n/**\n *  Link or image title, or `nil` if there is none.\n */\n@property (readonly) NSString *title;\n\n/**\n *  The line on which the receiver begins.\n */\n@property (readonly) NSInteger startLine;\n\n/**\n *  The column on which the receiver begins.\n */\n@property (readonly) NSInteger startColumn;\n\n/**\n *  The line on which the receiver ends.\n */\n@property (readonly) NSInteger endLine;\n\n/**\n *  The column on which the receiver ends.\n */\n@property (readonly) NSInteger endColumn;\n\n@property (readonly) NSInteger footNoteIndex;\n\n@property (readonly) CMNode *footNoteDefination;\n\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMNode.m",
    "content": "//\n//  CMNode.m\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/12/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import \"CMNode.h\"\n#import \"CMNode_Private.h\"\n#import \"CMIterator.h\"\n\nstatic CMNode * wrap(cmark_node *node) {\n    if (node == NULL) return nil;\n    \n    return [[CMNode alloc] initWithNode:node freeWhenDone:NO];\n}\n\nstatic NSString * str(const char *buf) {\n    if (buf == NULL) return nil;\n    \n    return [NSString stringWithUTF8String:buf];\n}\n\nstatic NSString * NSStringFromCMNodeType(CMNodeType type) {\n    switch (type) {\n        case CMNodeTypeBlockQuote:\n            return @\"Block Quote\";\n        case CMNodeTypeCode:\n            return @\"Code\";\n        case CMNodeTypeCodeBlock:\n            return @\"Code Block\";\n        case CMNodeTypeDocument:\n            return @\"Document\";\n        case CMNodeTypeEmphasis:\n            return @\"Emphasis\";\n        case CMNodeTypeHeader:\n            return @\"Header\";\n        case CMNodeTypeHRule:\n            return @\"Horizontal Rule\";\n        case CMNodeTypeHTML:\n            return @\"HTML\";\n        case CMNodeTypeImage:\n            return @\"Image\";\n        case CMNodeTypeInlineHTML:\n            return @\"Inline HTML\";\n        case CMNodeTypeItem:\n            return @\"List Item\";\n        case CMNodeTypeLinebreak:\n            return @\"Linebreak\";\n        case CMNodeTypeLink:\n            return @\"Link\";\n        case CMNodeTypeList:\n            return @\"List\";\n        case CMNodeTypeNone:\n            return @\"None\";\n        case CMNodeTypeParagraph:\n            return @\"Paragraph\";\n        case CMNodeTypeSoftbreak:\n            return @\"Softbreak\";\n        case CMNodeTypeStrong:\n            return @\"Strong\";\n        case CMNodeTypeText:\n            return @\"Text\";\n        default: {\n            if (type == CMNodeTypeTable) {\n                return @\"Table\";\n            } else if (type == CMNodeTypeTableRow) {\n                return @\"Table Row\";\n            } else if (type == CMNodeTypeTableCell) {\n                return @\"Table Cell\";\n            } else if (type == CMNodeTypeStrikeThrough) {\n                return @\"Strikethrough\";\n            } else if (type == CMNodeTypeMathInline) {\n                return @\"Math\";\n            } else if (type == CMNodeTypeMathBlock) {\n                return @\"Math Block\";\n            } else if (type == CMNodeTypeEmoji) {\n                return @\"Emoji\";\n            }\n            return nil;\n        }\n    }\n}\n\n@implementation CMNode {\n    BOOL _freeWhenDone;\n}\n\n#pragma mark - Initialization\n\n- (instancetype)init\n{\n    NSAssert(NO, @\"CMNode instance can not be created.\");\n    return nil;\n}\n\n- (instancetype)initWithNode:(cmark_node *)node freeWhenDone:(BOOL)free\n{\n    NSParameterAssert(node);\n    \n    if ((self = [super init])) {\n        _node = node;\n        _freeWhenDone = free;\n    }\n    return self;\n}\n\n- (void)dealloc\n{\n    if (_freeWhenDone) {\n        cmark_node_free(_node);\n    }\n}\n\n#pragma mark - NSObject\n\n- (BOOL)isEqual:(CMNode *)node\n{\n    if (self == node) return YES;\n    if (![node isMemberOfClass:self.class]) return NO;\n    \n    return _node == node->_node;\n}\n\n- (NSUInteger)hash\n{\n    return (NSUInteger)_node;\n}\n\n- (NSString *)description\n{\n    return [NSString stringWithFormat:@\"<%@:%p type:%@ stringValue:%@>\", self.class, self, self.humanReadableType, self.stringValue];\n}\n\n#pragma mark - Iteration\n\n- (CMIterator *)iterator\n{\n    return [[CMIterator alloc] initWithRootNode:self];\n}\n\n#pragma mark - Tree Traversal\n\n- (CMNode *)next\n{\n    return wrap(cmark_node_next(_node));\n}\n\n- (CMNode *)previous\n{\n    return wrap(cmark_node_previous(_node));\n}\n\n- (CMNode *)parent\n{\n    return wrap(cmark_node_parent(_node));\n}\n\n- (CMNode *)firstChild\n{\n    return wrap(cmark_node_first_child(_node));\n}\n\n- (CMNode *)lastChild\n{\n    return wrap(cmark_node_last_child(_node));\n}\n\n#pragma mark CheckBox\n\n- (BOOL)isCheckBox {\n    return (cmark_node_get_is_checkbox(_node) == 1);\n}\n\n- (BOOL)checked {\n    return (cmark_node_get_checked(_node) == 1);\n}\n\n#pragma mark - Attributes\n- (CMNodeType)type\n{\n    return (CMNodeType)cmark_node_get_type(_node);\n}\n\n- (NSString *)humanReadableType\n{\n    return str(cmark_node_get_type_string(_node));\n}\n\n- (NSString *)stringValue\n{\n    return str(cmark_node_get_literal(_node));\n}\n\n- (NSString *)contentValue\n{\n    return str(cmark_node_get_string_content(_node));\n}\n\n- (NSInteger)headerLevel\n{\n    return cmark_node_get_header_level(_node);\n}\n\n- (NSString *)fencedCodeInfo\n{\n    return str(cmark_node_get_fence_info(_node));\n}\n\n- (CMListType)listType\n{\n    return (CMListType)cmark_node_get_list_type(_node);\n}\n\n- (CMDelimeterType)listDelimeterType\n{\n    return (CMDelimeterType)cmark_node_get_list_delim(_node);\n}\n\n- (NSInteger)listStartingNumber\n{\n    return cmark_node_get_list_start(_node);\n}\n\n- (BOOL)listTight\n{\n    return (cmark_node_get_list_tight(_node) == 0) ? NO : YES;\n}\n\n- (NSString *)URLString\n{\n    return str(cmark_node_get_url(_node));\n}\n\n- (NSURL *)URL\n{\n    NSString *URLString = str(cmark_node_get_url(_node));\n    if (URLString != nil) {\n        return [NSURL URLWithString:URLString];\n    }\n    return nil;\n}\n\n- (NSString *)title\n{\n    return str(cmark_node_get_title(_node));\n}\n\n- (NSInteger)startLine\n{\n    return cmark_node_get_start_line(_node);\n}\n\n- (NSInteger)startColumn\n{\n    return cmark_node_get_start_column(_node);\n}\n\n- (NSInteger)endLine\n{\n    return cmark_node_get_end_line(_node);\n}\n\n- (NSInteger)endColumn\n{\n    return cmark_node_get_end_column(_node);\n}\n\n- (NSInteger)footNoteIndex\n{\n    return cmark_node_get_footnote_idx(_node);\n}\n\n- (CMNode *)footNoteDefination\n{\n    return wrap(cmark_node_parent_footnote_def(_node));\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMNode_Private.h",
    "content": "//\n//  CMNode_Private.h\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/13/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import \"CMNode.h\"\n#import \"cmark-gfm.h\"\n#import \"cmark-gfm-core-extensions.h\"\n\n@interface CMNode ()\n/**\n *  Designated initializer.\n *\n *  @param node Pointer to the node to wrap.\n *  @param free Whether to free the underlying node when the\n *  receiver is deallocated.\n *\n *  @return An initialized instance of the receiver.\n */\n- (instancetype)initWithNode:(cmark_node *)node freeWhenDone:(BOOL)free;\n\n@property (readonly) cmark_node *node;\n\n@property (readonly) BOOL isCheckBox;\n\n@property (readonly) BOOL checked;\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMParser.h",
    "content": "//\n//  CMParser.h\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/13/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n@class CMNode;\n@class CMTable;\n@class CMDocument;\n@protocol CMParserDelegate;\n\n/**\n *  Not really a parser, but you can pretend it is. \n *\n *  This class takes a `CMDocument` (which contains the tree for the already-parsed \n *  Markdown data) and traverses the tree to implement `NSXMLParser`-style delegate \n *  callbacks.\n *\n *  This is useful for implementing custom renderers.\n *\n *  @warning This class is not thread-safe and can only be accessed from a single\n *  thread at a time.\n */\n@interface CMParser : NSObject\n\n/**\n *  Initializes the receiver with a document.\n *\n *  @param document CommonMark document.\n *  @param delegate Delegate to receive callbacks during parsing.\n *\n *  @return An initialized instance of the receiver.\n */\n- (instancetype)initWithDocument:(CMDocument *)document delegate:(id<CMParserDelegate>)delegate;\n\n/**\n *  Document being parsed.\n */\n@property (nonatomic, readonly) CMDocument *document;\n\n/**\n *  Delegate to receive callbacks during parsing.\n */\n@property (nonatomic, weak, readonly) id<CMParserDelegate> delegate;\n\n/**\n *  Returns the node currently being parsed, or `nil` if not parsing.\n */\n@property (atomic, readonly) CMNode *currentNode;\n\n/**\n *  Start parsing.\n */\n- (void)parse;\n\n/**\n *  Stop parsing. If implemented, `-parserDidAbort:` will be called on the delegate.\n */\n- (void)abortParsing;\n\n@end\n\n@protocol CMParserDelegate <NSObject>\n@optional\n- (void)parserDidStartDocument:(CMParser *)parser;\n- (void)parserDidEndDocument:(CMParser *)parser;\n- (void)parserDidAbort:(CMParser *)parser;\n\n- (void)parser:(CMParser *)parser foundText:(NSString *)text;\n- (void)parserFoundHRule:(CMParser *)parser;\n\n- (void)parser:(CMParser *)parser didStartHeaderWithLevel:(NSInteger)level;\n- (void)parser:(CMParser *)parser didEndHeaderWithLevel:(NSInteger)level;\n\n- (void)parserDidStartParagraph:(CMParser *)parser;\n- (void)parserDidEndParagraph:(CMParser *)parser;\n\n- (void)parserDidStartEmphasis:(CMParser *)parser;\n- (void)parserDidEndEmphasis:(CMParser *)parser;\n\n- (void)parserDidStartStrong:(CMParser *)parser;\n- (void)parserDidEndStrong:(CMParser *)parser;\n\n- (void)parserDidStartStrikethrough:(CMParser *)parser;\n- (void)parserDidEndStrikethrough:(CMParser *)parser;\n\n- (void)parser:(CMParser *)parser didStartLinkWithURL:(NSURL *)URL title:(NSString *)title;\n- (void)parser:(CMParser *)parser didEndLinkWithURL:(NSURL *)URL title:(NSString *)title;\n\n- (void)parser:(CMParser *)parser didStartImageWithURL:(NSURL *)URL title:(NSString *)title;\n- (void)parser:(CMParser *)parser didEndImageWithURL:(NSURL *)URL title:(NSString *)title;\n\n- (void)parser:(CMParser *)parser didStartFootNoteDefination:(NSString *)content refCount:(NSInteger)index;\n- (void)parser:(CMParser *)parser didEndFootNoteDefination:(NSString *)content refCount:(NSInteger)index;\n\n- (void)parser:(CMParser *)parser didStartFootNoteRefIndex:(NSInteger)index title:(NSString *)title defination:(NSString *)content;\n- (void)parser:(CMParser *)parser didEndFootNoteRefIndex:(NSInteger)index title:(NSString *)title defination:(NSString *)content;\n\n- (void)parser:(CMParser *)parser didStartTableWithNumberOfColumns:(NSUInteger)columns;\n- (void)parser:(CMParser *)parser didEndTableWithNumberOfColumns:(NSUInteger)columns;\n\n- (void)parser:(CMParser *)parser didStartTableRowIsHeader:(BOOL)isHeader;\n- (void)parser:(CMParser *)parser didEndTableRowIsHeader:(BOOL)isHeader;\n\n- (void)parser:(CMParser *)parser didStartTableCellWithAlignment:(NSTextAlignment)alignment;\n- (void)parser:(CMParser *)parser didEndTableCellWithAlignment:(NSTextAlignment)alignment;\n\n- (void)parser:(CMParser *)parser foundHTML:(NSString *)HTML;\n- (void)parser:(CMParser *)parser foundInlineHTML:(NSString *)HTML;\n\n- (void)parser:(CMParser *)parser foundEmoji:(NSString *)emoji;\n\n- (void)parser:(CMParser *)parser foundCodeBlock:(NSString *)code info:(NSString *)info;\n- (void)parser:(CMParser *)parser foundInlineCode:(NSString *)code;\n\n- (void)parser:(CMParser *)parser foundMathBlock:(NSString *)code;\n- (void)parser:(CMParser *)parser foundInlineMath:(NSString *)code;\n\n- (void)parserFoundSoftBreak:(CMParser *)parser;\n- (void)parserFoundLineBreak:(CMParser *)parser;\n\n- (void)parserDidStartBlockQuote:(CMParser *)parser;\n- (void)parserDidEndBlockQuote:(CMParser *)parser;\n\n- (void)parser:(CMParser *)parser didStartUnorderedListWithTightness:(BOOL)tight;\n- (void)parser:(CMParser *)parser didEndUnorderedListWithTightness:(BOOL)tight;\n\n- (void)parser:(CMParser *)parser didStartOrderedListWithStartingNumber:(NSInteger)num tight:(BOOL)tight;\n- (void)parser:(CMParser *)parser didEndOrderedListWithStartingNumber:(NSInteger)num tight:(BOOL)tight;\n\n- (void)parserDidStartListItem:(CMParser *)parser;\n- (void)parserDidEndListItem:(CMParser *)parser;\n\n@end\n\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMParser.m",
    "content": "//\n//  CMParser.m\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/13/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import \"CMParser.h\"\n#import \"CMDocument.h\"\n#import \"CMIterator.h\"\n#import \"CMNode.h\"\n#import \"CMNode+Table.h\"\n#import <libkern/OSAtomic.h>\n\n@interface CMParser ()\n@property (atomic, readwrite) CMNode *currentNode;\n@property (nonatomic, weak, readwrite) id<CMParserDelegate> delegate;\n@end\n\n@implementation CMParser {\n    struct {\n        unsigned int didStartDocument:1;\n        unsigned int didEndDocument:1;\n        unsigned int didAbort:1;\n        unsigned int foundText:1;\n        unsigned int foundHRule:1;\n        unsigned int didStartHeader:1;\n        unsigned int didEndHeader:1;\n        unsigned int didStartParagraph:1;\n        unsigned int didEndParagraph:1;\n        unsigned int didStartEmphasis:1;\n        unsigned int didEndEmphasis:1;\n        unsigned int didStartStrong:1;\n        unsigned int didEndStrong:1;\n        unsigned int didStartStrikethrough:1;\n        unsigned int didEndStrikethrough:1;\n        unsigned int didStartLink:1;\n        unsigned int didEndLink:1;\n        unsigned int didStartImage:1;\n        unsigned int didEndImage:1;\n        unsigned int didStartTable:1;\n        unsigned int didStartTableRow:1;\n        unsigned int didStartTableCell:1;\n        unsigned int didEndTable:1;\n        unsigned int didEndTableRow:1;\n        unsigned int didEndTableCell:1;\n        unsigned int foundHTML:1;\n        unsigned int foundInlineHTML:1;\n        unsigned int foundCodeBlock:1;\n        unsigned int foundInlineCode:1;\n        unsigned int foundMathBlock:1;\n        unsigned int foundInlineMath:1;\n        unsigned int foundSoftBreak:1;\n        unsigned int foundLineBreak:1;\n        unsigned int foundEmoji:1;\n        unsigned int foundTasklist:1;\n        unsigned int didStartBlockQuote:1;\n        unsigned int didEndBlockQuote:1;\n        unsigned int didStartUnorderedList:1;\n        unsigned int didEndUnorderedList:1;\n        unsigned int didStartOrderedList:1;\n        unsigned int didEndOrderedList:1;\n        unsigned int didStartListItem:1;\n        unsigned int didEndListItem:1;\n        unsigned int didStartFootNoteRef:1;\n        unsigned int didEndFootNoteRef:1;\n        unsigned int didStartFootNote:1;\n        unsigned int didEndFootNote:1;\n    } _delegateFlags;\n    volatile int32_t _parsing;\n}\n\n#pragma mark - Initialization\n\n- (instancetype)initWithDocument:(CMDocument *)document delegate:(id<CMParserDelegate>)delegate\n{\n    NSParameterAssert(document);\n    NSParameterAssert(delegate);\n    \n    if ((self = [super init])) {\n        _document = document;\n        self.delegate = delegate;\n    }\n    return self;\n}\n\n#pragma mark - Parsing\n\n- (void)parse\n{\n    if (!OSAtomicCompareAndSwap32Barrier(0, 1, &_parsing)) return;\n    \n    [[_document.rootNode iterator] enumerateUsingBlock:^(CMNode *node, CMEventType event, BOOL *stop) {\n        self.currentNode = node;\n        [self handleNode:node event:event];\n        if (self->_parsing == 0) *stop = YES;\n    }];\n    \n    _parsing = 0;\n}\n\n- (void)abortParsing\n{\n    if (!OSAtomicCompareAndSwap32Barrier(1, 0, &_parsing)) return;\n    \n    if (_delegateFlags.didAbort) {\n        [_delegate parserDidAbort:self];\n    }\n}\n\n- (void)handleNode:(CMNode *)node event:(CMEventType)event {\n    NSAssert((event == CMEventTypeEnter) || (event == CMEventTypeExit), @\"Event must be either an exit or enter event\");\n    \n    switch (node.type) {\n        case CMNodeTypeDocument:\n            if (event == CMEventTypeEnter) {\n                if (_delegateFlags.didStartDocument) {\n                    [_delegate parserDidStartDocument:self];\n                }\n            } else if (_delegateFlags.didEndDocument) {\n                [_delegate parserDidEndDocument:self];\n            }\n            break;\n        case CMNodeTypeText:\n            if (_delegateFlags.foundText) {\n                [_delegate parser:self foundText:node.stringValue];\n            }\n            break;\n        case CMNodeTypeHRule:\n            if (_delegateFlags.foundHRule) {\n                [_delegate parserFoundHRule:self];\n            }\n            break;\n        case CMNodeTypeHeader:\n            if (event == CMEventTypeEnter) {\n                if (_delegateFlags.didStartHeader) {\n                    [_delegate parser:self didStartHeaderWithLevel:node.headerLevel];\n                }\n            } else if (_delegateFlags.didEndHeader) {\n                [_delegate parser:self didEndHeaderWithLevel:node.headerLevel];\n            }\n            break;\n        case CMNodeTypeParagraph:\n            if (event == CMEventTypeEnter) {\n                if (_delegateFlags.didStartParagraph) {\n                    [_delegate parserDidStartParagraph:self];\n                }\n            } else if (_delegateFlags.didEndParagraph) {\n                [_delegate parserDidEndParagraph:self];\n            }\n            break;\n        case CMNodeTypeEmphasis:\n            if (event == CMEventTypeEnter) {\n                if (_delegateFlags.didStartEmphasis) {\n                    [_delegate parserDidStartEmphasis:self];\n                }\n            } else if (_delegateFlags.didEndEmphasis) {\n                [_delegate parserDidEndEmphasis:self];\n            }\n            break;\n        case CMNodeTypeStrong:\n            if (event == CMEventTypeEnter) {\n                if (_delegateFlags.didStartStrong) {\n                    [_delegate parserDidStartStrong:self];\n                }\n            } else if (_delegateFlags.didEndStrong) {\n                [_delegate parserDidEndStrong:self];\n            }\n            break;\n        case CMNodeTypeLink: {\n            NSURL *nodeURL = [_document targetURLForNode:node];\n            \n            if (node.parent.type == CMNodeTypeTableCell) {\n                break;\n            }\n            if (event == CMEventTypeEnter) {\n                if (_delegateFlags.didStartLink) {\n                    [_delegate parser:self didStartLinkWithURL:nodeURL title:node.title];\n                }\n            } else if (_delegateFlags.didEndLink) {\n                [_delegate parser:self didEndLinkWithURL:nodeURL title:node.title];\n            }\n        }   break;\n        case CMNodeTypeImage: {\n            NSURL *nodeURL = [_document targetURLForNode:node];\n            if (event == CMEventTypeEnter) {\n                if (_delegateFlags.didStartImage) {\n                    [_delegate parser:self didStartImageWithURL:nodeURL title:node.title];\n                }\n            } else if (_delegateFlags.didEndImage) {\n                [_delegate parser:self didEndImageWithURL:nodeURL title:node.title];\n            }\n        }   break;\n        case CMNodeTypeHTML:\n            if (_delegateFlags.foundHTML) {\n                [_delegate parser:self foundHTML:node.stringValue];\n            }\n            break;\n        case CMNodeTypeInlineHTML:\n            if (_delegateFlags.foundInlineHTML) {\n                [_delegate parser:self foundInlineHTML:node.stringValue];\n            }\n            break;\n        case CMNodeTypeCodeBlock:\n            if (_delegateFlags.foundCodeBlock) {\n                [_delegate parser:self foundCodeBlock:node.stringValue info:node.fencedCodeInfo];\n            }\n            break;\n        case CMNodeTypeCode:\n            if (_delegateFlags.foundInlineCode) {\n                [_delegate parser:self foundInlineCode:node.stringValue];\n            }\n            break;\n        case CMNodeTypeSoftbreak:\n            if (_delegateFlags.foundSoftBreak) {\n                [_delegate parserFoundSoftBreak:self];\n            }\n            break;\n        case CMNodeTypeLinebreak:\n            if (_delegateFlags.foundLineBreak) {\n                [_delegate parserFoundLineBreak:self];\n            }\n            break;\n        case CMNodeTypeBlockQuote:\n            if (event == CMEventTypeEnter) {\n                if (_delegateFlags.didStartBlockQuote) {\n                    [_delegate parserDidStartBlockQuote:self];\n                }\n            } else if (_delegateFlags.didEndBlockQuote) {\n                [_delegate parserDidEndBlockQuote:self];\n            }\n            break;\n        case CMNodeTypeList:\n            switch (node.listType) {\n                case CMListTypeOrdered:\n                    if (event == CMEventTypeEnter) {\n                        if (_delegateFlags.didStartOrderedList) {\n                            [_delegate parser:self didStartOrderedListWithStartingNumber:node.listStartingNumber tight:node.listTight];\n                        }\n                    } else if (_delegateFlags.didEndOrderedList) {\n                        [_delegate parser:self didEndOrderedListWithStartingNumber:node.listStartingNumber tight:node.listTight];\n                    }\n                    break;\n                case CMListTypeUnordered:\n                    if (event == CMEventTypeEnter) {\n                        if (_delegateFlags.didStartUnorderedList) {\n                            [_delegate parser:self didStartUnorderedListWithTightness:node.listTight];\n                        }\n                    } else if (_delegateFlags.didEndUnorderedList) {\n                        [_delegate parser:self didEndUnorderedListWithTightness:node.listTight];\n                    }\n                    break;\n                default:\n                    break;\n            }\n            break;\n        case CMNodeTypeItem:\n            if (event == CMEventTypeEnter) {\n                if (_delegateFlags.didStartListItem) {\n                    [_delegate parserDidStartListItem:self];\n                }\n            } else if (_delegateFlags.didEndListItem) {\n                [_delegate parserDidEndListItem:self];\n            }\n            break;\n        case CMNodeTypeFootNote:\n            if (event == CMEventTypeEnter) {\n                if (_delegateFlags.didStartFootNote) {\n                    [_delegate parser:self didStartFootNoteDefination:node.stringValue refCount:node.footNoteIndex];\n                }\n            } else if (_delegateFlags.didEndFootNote) {\n                [_delegate parser:self didEndFootNoteDefination:node.stringValue refCount:node.footNoteIndex];\n            }\n            break;\n        case CMNodeTypeFootNoteRef:\n            if (event == CMEventTypeEnter) {\n                if (_delegateFlags.didStartFootNoteRef) {\n                    [_delegate parser:self \n             didStartFootNoteRefIndex:node.footNoteIndex\n                                title:node.stringValue\n                           defination:node.footNoteDefination.stringValue ?: node.stringValue];\n                }\n            } else if (_delegateFlags.didEndFootNoteRef) {\n                [_delegate parser:self\n           didEndFootNoteRefIndex:node.footNoteIndex\n                            title:node.stringValue\n                       defination:node.footNoteDefination.stringValue ?: node.stringValue];\n            }\n            break;\n        default: {\n            const CMNodeType type = node.type;\n            if (type == CMNodeTypeTable) {\n                if (event == CMEventTypeEnter) {\n                    if (_delegateFlags.didStartTable) {\n                        [_delegate parser:self didStartTableWithNumberOfColumns:node.numberOfColumns];\n                    }\n                } else {\n                    if (_delegateFlags.didEndTable) {\n                        [_delegate parser:self didEndTableWithNumberOfColumns:node.numberOfColumns];\n                    }\n                }\n            } else if (type == CMNodeTypeTableRow) {\n                if (event == CMEventTypeEnter) {\n                    if (_delegateFlags.didStartTableRow) {\n                        [_delegate parser:self didStartTableRowIsHeader:node.rowIsHeader];\n                    }\n                } else {\n                    if (_delegateFlags.didEndTableRow) {\n                        [_delegate parser:self didEndTableRowIsHeader:node.rowIsHeader];\n                    }  \n                }\n            } else if (type == CMNodeTypeTableCell) {\n                if (event == CMEventTypeEnter) {\n                    if (_delegateFlags.didStartTableCell) {\n                        [_delegate parser:self didStartTableCellWithAlignment:node.cellAlignment];\n                    }\n                } else {\n                    if (_delegateFlags.didEndTableCell) {\n                        [_delegate parser:self didEndTableCellWithAlignment:node.cellAlignment];\n                    }\n                }\n            } else if (type == CMNodeTypeStrikeThrough) {\n                if (event == CMEventTypeEnter) {\n                    if (_delegateFlags.didStartStrikethrough) {\n                        [_delegate parserDidStartStrikethrough:self];\n                    }\n                } else if (_delegateFlags.didEndStrikethrough) {\n                    [_delegate parserDidEndStrikethrough:self];\n                }\n            } else if (type == CMNodeTypeMathInline) {\n                if (event == CMEventTypeExit && _delegateFlags.foundInlineMath) {\n                    [_delegate parser:self foundInlineMath:node.contentValue];\n                }\n            } else if (type == CMNodeTypeMathBlock) {\n                if (event == CMEventTypeExit && _delegateFlags.foundMathBlock) {\n                    [_delegate parser:self foundMathBlock:node.contentValue];\n                }\n            } else if (type == CMNodeTypeEmoji) {\n                if (event == CMEventTypeEnter && _delegateFlags.foundEmoji) {\n                    [_delegate parser:self foundEmoji:node.contentValue];\n                }\n            }\n        }\n            break;\n    }\n}\n\n#pragma mark - Accessors\n\n- (void)setDelegate:(id<CMParserDelegate>)delegate\n{\n    if (_delegate != delegate) {\n        _delegate = delegate;\n        _delegateFlags.didStartDocument = [_delegate respondsToSelector:@selector(parserDidStartDocument:)];\n        _delegateFlags.didEndDocument = [_delegate respondsToSelector:@selector(parserDidEndDocument:)];\n        _delegateFlags.didAbort = [_delegate respondsToSelector:@selector(parserDidAbort:)];\n        _delegateFlags.foundText = [_delegate respondsToSelector:@selector(parser:foundText:)];\n        _delegateFlags.foundHRule = [_delegate respondsToSelector:@selector(parserFoundHRule:)];\n        _delegateFlags.didStartHeader = [_delegate respondsToSelector:@selector(parser:didStartHeaderWithLevel:)];\n        _delegateFlags.didEndHeader = [_delegate respondsToSelector:@selector(parser:didEndHeaderWithLevel:)];\n        _delegateFlags.didStartParagraph = [_delegate respondsToSelector:@selector(parserDidStartParagraph:)];\n        _delegateFlags.didEndParagraph = [_delegate respondsToSelector:@selector(parserDidEndParagraph:)];\n        _delegateFlags.didStartEmphasis = [_delegate respondsToSelector:@selector(parserDidStartEmphasis:)];\n        _delegateFlags.didEndEmphasis = [_delegate respondsToSelector:@selector(parserDidEndEmphasis:)];\n        _delegateFlags.didStartStrong = [_delegate respondsToSelector:@selector(parserDidStartStrong:)];\n        _delegateFlags.didEndStrong = [_delegate respondsToSelector:@selector(parserDidEndStrong:)];\n        _delegateFlags.didStartStrikethrough = [_delegate respondsToSelector:@selector(parserDidStartStrikethrough:)];\n        _delegateFlags.didEndStrikethrough = [_delegate respondsToSelector:@selector(parserDidEndStrikethrough:)];\n        _delegateFlags.didStartLink = [_delegate respondsToSelector:@selector(parser:didStartLinkWithURL:title:)];\n        _delegateFlags.didEndLink = [_delegate respondsToSelector:@selector(parser:didEndLinkWithURL:title:)];\n        _delegateFlags.didStartImage = [_delegate respondsToSelector:@selector(parser:didStartImageWithURL:title:)];\n        _delegateFlags.didEndImage = [_delegate respondsToSelector:@selector(parser:didEndImageWithURL:title:)];\n        _delegateFlags.didStartFootNote = [_delegate respondsToSelector:@selector(parser:didStartFootNoteDefination:refCount:)];\n        _delegateFlags.didEndFootNote = [_delegate respondsToSelector:@selector(parser:didEndFootNoteDefination:refCount:)];\n        _delegateFlags.didStartFootNoteRef = [_delegate respondsToSelector:@selector(parser:didStartFootNoteRefIndex:title:defination:)];\n        _delegateFlags.didEndFootNoteRef = [_delegate respondsToSelector:@selector(parser:didEndFootNoteRefIndex:title:defination:)];\n        _delegateFlags.didStartTable = [_delegate respondsToSelector:@selector(parser:didStartTableWithNumberOfColumns:)];\n        _delegateFlags.didStartTableRow = [_delegate respondsToSelector:@selector(parser:didEndTableRowIsHeader:)];\n        _delegateFlags.didStartTableCell = [_delegate respondsToSelector:@selector(parser:didStartTableCellWithAlignment:)];\n        _delegateFlags.didEndTable = [_delegate respondsToSelector:@selector(parser:didEndTableWithNumberOfColumns:)];\n        _delegateFlags.didEndTableRow = [_delegate respondsToSelector:@selector(parser:didEndTableRowIsHeader:)];\n        _delegateFlags.didEndTableCell = [_delegate respondsToSelector:@selector(parser:didEndTableCellWithAlignment:)];\n        _delegateFlags.foundHTML = [_delegate respondsToSelector:@selector(parser:foundHTML:)];\n        _delegateFlags.foundInlineHTML = [_delegate respondsToSelector:@selector(parser:foundInlineHTML:)];\n        _delegateFlags.foundEmoji = [_delegate respondsToSelector:@selector(parser:foundEmoji:)];\n        _delegateFlags.foundCodeBlock = [_delegate respondsToSelector:@selector(parser:foundCodeBlock:info:)];\n        _delegateFlags.foundInlineCode = [_delegate respondsToSelector:@selector(parser:foundInlineCode:)];\n        _delegateFlags.foundMathBlock = [_delegate respondsToSelector:@selector(parser:foundMathBlock:)];\n        _delegateFlags.foundInlineMath = [_delegate respondsToSelector:@selector(parser:foundInlineMath:)];\n        _delegateFlags.foundSoftBreak = [_delegate respondsToSelector:@selector(parserFoundSoftBreak:)];\n        _delegateFlags.foundLineBreak = [_delegate respondsToSelector:@selector(parserFoundLineBreak:)];\n        _delegateFlags.didStartBlockQuote = [_delegate respondsToSelector:@selector(parserDidStartBlockQuote:)];\n        _delegateFlags.didEndBlockQuote = [_delegate respondsToSelector:@selector(parserDidEndBlockQuote:)];\n        _delegateFlags.didStartUnorderedList = [_delegate respondsToSelector:@selector(parser:didStartUnorderedListWithTightness:)];\n        _delegateFlags.didEndUnorderedList = [_delegate respondsToSelector:@selector(parser:didEndUnorderedListWithTightness:)];\n        _delegateFlags.didStartOrderedList = [_delegate respondsToSelector:@selector(parser:didStartOrderedListWithStartingNumber:tight:)];\n        _delegateFlags.didEndOrderedList = [_delegate respondsToSelector:@selector(parser:didEndOrderedListWithStartingNumber:tight:)];\n        _delegateFlags.didStartListItem = [_delegate respondsToSelector:@selector(parserDidStartListItem:)];\n        _delegateFlags.didEndListItem = [_delegate respondsToSelector:@selector(parserDidEndListItem:)];\n    }\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMPlatformDefines.h",
    "content": "//\n//  CMPlatformDefines.h\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/15/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#ifndef CocoaMarkdown_CMPlatformDefines_h\n#define CocoaMarkdown_CMPlatformDefines_h\n\n#if TARGET_OS_IPHONE\n#import <UIKit/UIKit.h>\n\n#define CMColor UIColor\n#define CMFontSymbolicTraits UIFontDescriptorSymbolicTraits\n#define CMFont UIFont\n#define CMFontDescriptor UIFontDescriptor\n#define CMFontTraitsAttribute UIFontDescriptorTraitsAttribute\n#define CMFontTraitItalic UIFontDescriptorTraitItalic\n#define CMFontTraitBold UIFontDescriptorTraitBold\n#define CMUnderlineStyle NSUnderlineStyle\n\ntypedef UIFontDescriptorAttributeName CMFontDescriptorAttributeName;\ntypedef UIFontDescriptorTraitKey CMFontDescriptorTraitKey;\n\n#else\n#import <Cocoa/Cocoa.h>\n\n#define CMColor NSColor\n#define CMFontSymbolicTraits NSFontSymbolicTraits\n#define CMFont NSFont\n#define CMFontDescriptor NSFontDescriptor\n#define CMFontTraitsAttribute NSFontTraitsAttribute\n#define CMFontTraitItalic NSFontItalicTrait\n#define CMFontTraitBold NSFontBoldTrait\n#define CMUnderlineStyle NSInteger\n\ntypedef NSFontDescriptorAttributeName CMFontDescriptorAttributeName;\ntypedef NSFontDescriptorTraitKey CMFontDescriptorTraitKey;\n\n#endif\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMStack.h",
    "content": "//\n//  CMStack.h\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/16/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n/**\n *  Array backed stack.\n */\n@interface CMStack<ElementType> : NSObject\n@property (nonatomic, readonly) NSArray<ElementType> *objects;\n\n- (void)push:(ElementType)object;\n- (ElementType)pop;\n- (ElementType)peek;\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMStack.m",
    "content": "\n//\n//  CMStack.m\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/16/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import \"CMStack.h\"\n\n@implementation CMStack {\n    NSMutableArray *_objects;\n}\n\n- (instancetype)init\n{\n    if ((self = [super init])) {\n        _objects = [[NSMutableArray alloc] init];\n    }\n    return self;\n}\n\n- (void)push:(id)object\n{\n    [_objects addObject:object];\n}\n\n- (id)pop\n{\n    id object = _objects.lastObject;\n    [_objects removeLastObject];\n    return object;\n}\n\n- (id)peek\n{\n    return _objects.lastObject;\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMTaskCheckAttachment+Private.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"CMTaskCheckAttachment.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface CMTaskCheckAttachment (Private)\n\n@property (nonatomic, assign) CGFloat lineHeight;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMTaskCheckAttachment.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <UIKit/UIKit.h>\n#import \"CMPlatformDefines.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface CMTaskCheckAttachment : NSTextAttachment\n\n@property (nonatomic, assign) BOOL checked;\n//\n/**\n*  border color of uncheckedbox\n*  Defaults to lightGrayColor\n*/\n@property (nonatomic, strong) CMColor *borderColor;\n\n/**\n*  The border width of the uncheckedbox\n*  Defaults to 3.0.\n*/\n@property (nonatomic, assign) CGFloat borderWidth;\n\n/**\n*  background of checkedbox\n*  Defaults to system green\n*/\n@property (nonatomic, strong) CMColor *backgroundColor;\n\n/**\n*  The inset from the left and right edges.\n*  Defaults to 0.0.\n*/\n@property (nonatomic, assign) CGFloat horizontalPadding;\n\n/**\n*  The vertical padding above and below the checkbox.\n*  Defaults to 6.0.\n*/\n@property (nonatomic, assign) CGFloat verticalPadding;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMTaskCheckAttachment.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"CMTaskCheckAttachment.h\"\n\n@interface CMTaskCheckAttachment ()\n\n@property (nonatomic, assign) CGFloat cornerRadius;\n@property (nonatomic, assign) CGFloat lineHeight;\n@property (nonatomic, assign) CGFloat marigin;\n\n@end\n\n@implementation CMTaskCheckAttachment\n\n- (instancetype)init {\n    self = [super init];\n    if (self) {\n        _borderColor = [CMColor lightGrayColor];\n        _borderWidth = 3.0;\n        _backgroundColor = [CMColor systemGreenColor];\n        _cornerRadius = 3.0;\n        _horizontalPadding = 2.0;\n        _verticalPadding = 5.0;\n        _lineHeight = 0;\n        _marigin = 2.0;\n        \n        self.bounds = CGRectMake(0, 0, 15, 15);\n        self.image = nil;\n    }\n    return self;\n}\n\n- (nullable UIImage *)imageForBounds:(CGRect)imageBounds\n                       textContainer:(nullable NSTextContainer *)textContainer\n                      characterIndex:(NSUInteger)charIndex {\n    CGRect checkRect = CGRectMake(_horizontalPadding,\n                                  imageBounds.origin.y - imageBounds.size.height + 3 * _marigin,\n                                  imageBounds.size.width - 2 * _marigin - 2 * _horizontalPadding ,\n                                  imageBounds.size.height - 2 * _marigin);\n    \n    CGContextRef context = UIGraphicsGetCurrentContext();\n    CGContextSaveGState(context);\n\n    UIBezierPath *roundedRect = [UIBezierPath bezierPathWithRoundedRect:checkRect\n                                                           cornerRadius:_cornerRadius];\n    [roundedRect addClip];\n    \n    if (self.checked) {\n        [_backgroundColor setFill];\n        [roundedRect fill];\n\n        CGContextSetLineWidth(context, 2.0);\n        CGFloat checkIndent = _cornerRadius;\n        CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);\n        CGContextMoveToPoint(context,\n                             checkRect.origin.x + checkIndent,\n                             checkRect.origin.y + checkRect.size.height / 2);\n        CGContextAddLineToPoint(context,\n                                checkRect.origin.x + checkRect.size.width / 3,\n                                checkRect.origin.y + checkRect.size.height - checkIndent);\n        CGContextAddLineToPoint(context,\n                                checkRect.origin.x + checkRect.size.width - checkIndent,\n                                checkRect.origin.y + checkIndent);\n        CGContextStrokePath(context);\n    } else {\n        CGContextSetStrokeColorWithColor(context, _borderColor.CGColor);\n        CGContextSetLineWidth(context, _borderWidth);\n        CGContextAddPath(context, roundedRect.CGPath);\n        CGContextStrokePath(context);\n    }\n    \n    CGContextRestoreGState(context);\n    \n    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();\n    UIGraphicsEndImageContext();\n    \n    return image;\n}\n\n- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer\n                      proposedLineFragment:(CGRect)lineFrag\n                             glyphPosition:(CGPoint)position\n                            characterIndex:(NSUInteger)charIndex {\n    CGFloat defaultSize = 18.0f;\n    CGFloat size = (_lineHeight > 0) ? _lineHeight : defaultSize;\n    return CGRectMake(0, 0, size + _horizontalPadding * 2, size);\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMTextAttributes.h",
    "content": "//\n//  CMTextAttributes.h\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/15/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n#import \"CMPlatformDefines.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\ntypedef NS_OPTIONS(NSUInteger, CMElementKind) {\n    CMElementKindText = 1 << 0,\n    \n    CMElementKindHeader1 = 1 << 1,\n    CMElementKindHeader2 = 1 << 2,\n    CMElementKindHeader3 = 1 << 3,\n    CMElementKindHeader4 = 1 << 4,\n    CMElementKindHeader5 = 1 << 5,\n    CMElementKindHeader6 = 1 << 6,\n    CMElementKindAnyHeader = CMElementKindHeader1 | CMElementKindHeader2 | CMElementKindHeader3 | CMElementKindHeader4 | CMElementKindHeader5 | CMElementKindHeader6,\n    \n    CMElementKindParagraph = 1 << 7,\n    CMElementKindLink = 1 << 8,\n    CMElementKindImageParagraph = 1 << 9,\n    CMElementKindCodeBlock = 1 << 10,\n    CMElementKindInlineCode = 1 << 11,\n    CMElementKindBlockQuote = 1 << 12,\n    \n    CMElementKindOrderedList = 1 << 13,\n    CMElementKindOrderedSublist = 1 << 14,\n    CMElementKindOrderedListItem = 1 << 15,\n    CMElementKindUnorderedList = 1 << 16,\n    CMElementKindUnorderedSublist = 1 << 17,\n    CMElementKindUnorderedListItem = 1 << 18,\n};\n\n@class CMStyleAttributes;\n\ntypedef NSString * CMParagraphStyleAttributeName NS_EXTENSIBLE_STRING_ENUM;\n\ntypedef NSString * CMCustomStyleAttributeName NS_EXTENSIBLE_STRING_ENUM;\n\n/**\n *  Container for sets of text attributes used to style \n *  attributed strings.\n */\n@interface CMTextAttributes : NSObject\n\n/**\n *  Initializes the receiver with the default attributes.\n *\n *  @return An initialized instance of the receiver.\n */\n- (instancetype)init;\n\n/// Set additional attributes for one or more element-kind\n/// \n/// @param attributes A dictionary of string attributes that will be added to existing attributes for every specified element kind\n/// @param elementKinds The mask of target element kinds\n///\n- (void) addStringAttributes:(NSDictionary<NSAttributedStringKey, id>*)attributes forElementWithKinds:(CMElementKind)elementKinds;\n\n/// Set additional font attributes for one or more element-kind\n/// \n/// @param fontAttributes A dictionary of font-descriptor attributes that will be added to existing attributes for every specified element kind\n/// @param elementKinds The mask of target element kinds\n///\n- (void) addFontAttributes:(NSDictionary<CMFontDescriptorAttributeName, id>*)fontAttributes forElementWithKinds:(CMElementKind)elementKinds;\n\n/// Set font traits for one or more element-kind\n/// \n/// @param fontTraits A dictionary of font-trait attributes that will be set for every specified element kind\n/// @param elementKinds The mask of target element kinds\n/// @description This is a specialized version of `addFontAttributes:forElementWithKinds:` dedicated to the font-trait attribute\n///\n- (void) setFontTraits:(NSDictionary<CMFontDescriptorTraitKey, id>*)fontTraits forElementWithKinds:(CMElementKind)elementKinds;\n\n/// Set additional paragraph attributes for one or more element-kind\n/// \n/// @param attributes A dictionary of string attributes that will be added to existing attributes for every specified element kind\n/// @param elementKinds The mask of target element kinds\n///\n- (void) addParagraphStyleAttributes:(NSDictionary<CMParagraphStyleAttributeName, id>*)attributes forElementWithKinds:(CMElementKind)elementKinds;\n\n/**\n *  @param level The header level.\n *\n *  @return The attributes for the specified header level.\n */\n- (CMStyleAttributes *)attributesForHeaderLevel:(NSInteger)level;\n\n/**\n *  Attributes used to style text.\n *\n *  On iOS, defaults to using the Dynamic Type font with style `UIFontTextStyleBody`\n *  On OS X, defaults to using the user font with size 12pt.\n */\n@property (nonatomic) CMStyleAttributes *baseTextAttributes;\n\n/**\n *  Attributes used to style level 1 headers.\n *\n *  On iOS, defaults to using the Dynamic Type font with style `UIFontTextStyleHeadline`\n *  On OS X, defaults to using the user font with size 24pt.\n */\n@property (nonatomic) CMStyleAttributes *h1Attributes;\n\n/**\n *  Attributes used to style level 2 headers.\n *\n *  On iOS, defaults to using the Dynamic Type font with style `UIFontTextStyleHeadline`\n *  On OS X, defaults to using the user font with size 18pt.\n */\n@property (nonatomic) CMStyleAttributes *h2Attributes;\n\n/**\n *  Attributes used to style level 3 headers.\n *\n *  On iOS, defaults to using the Dynamic Type font with style `UIFontTextStyleHeadline`\n *  On OS X, defaults to using the user font with size 14pt.\n */\n@property (nonatomic) CMStyleAttributes *h3Attributes;\n\n/**\n *  Attributes used to style level 4 headers.\n *\n *  On iOS, defaults to using the Dynamic Type font with style `UIFontTextStyleSubheadline`\n *  On OS X, defaults to using the user font with size 12pt.\n */\n@property (nonatomic) CMStyleAttributes *h4Attributes;\n\n/**\n *  Attributes used to style level 5 headers.\n *\n *  On iOS, defaults to using the Dynamic Type font with style `UIFontTextStyleSubheadline`\n *  On OS X, defaults to using the user font with size 10pt.\n */\n@property (nonatomic) CMStyleAttributes *h5Attributes;\n\n/**\n *  Attributes used to style level 6 headers.\n *\n *  On iOS, defaults to using the Dynamic Type font with style `UIFontTextStyleSubheadline`\n *  On OS X, defaults to using the user font with size 8pt.\n */\n@property (nonatomic) CMStyleAttributes *h6Attributes;\n\n/**\n *  Attributes used to style paragraphs.\n *\n *  Defaults to using a 12pt paragraph spacing\n */\n@property (nonatomic) CMStyleAttributes *paragraphAttributes;\n\n/**\n *  Attributes used to style emphasized text.\n *\n *  If not set, the renderer will attempt to infer the emphasized font from the\n *  regular text font.\n */\n@property (nonatomic) CMStyleAttributes *emphasisAttributes;\n\n/**\n *  Attributes used to style strong text.\n *\n *  If not set, the renderer will attempt to infer the strong font from the\n *  regular text font.\n */\n@property (nonatomic) CMStyleAttributes *strongAttributes;\n\n/**\n *  Attributes used to style linked text.\n *\n *  Defaults to using a blue foreground color and a single line underline style.\n */\n@property (nonatomic) CMStyleAttributes *linkAttributes;\n\n\n/**\n *  Attributes used to style images paragraphs.\n *\n *  Defaults to centering the image.\n */\n@property (nonatomic) CMStyleAttributes *imageParagraphAttributes;\n\n/**\n *  Attributes used to style code blocks.\n *\n *  On iOS, defaults to the Menlo font when available, or Courier as a fallback.\n *  On OS X, defaults to the user monospaced font.\n */\n@property (nonatomic) CMStyleAttributes *codeBlockAttributes;\n\n/**\n *  Attributes used to style inline code.\n *\n *  On iOS, defaults to the Menlo font when available, or Courier as a fallback.\n *  On OS X, defaults to the user monospaced font.\n */\n@property (nonatomic) CMStyleAttributes *inlineCodeAttributes;\n\n/**\n *  Attributes used to style block quotes.\n *\n *  Defaults to using a paragraph style with a head indent of 30px.\n */\n@property (nonatomic) CMStyleAttributes *blockQuoteAttributes;\n\n/**\n *  Attributes used to style ordered lists.\n *\n *  These attributes will apply to the entire list (unless overriden by attributes\n *  for the list items), including the numbers.\n *\n *  Defaults to using a paragraph style with a head indent of 30px.\n */\n@property (nonatomic) CMStyleAttributes *orderedListAttributes;\n\n/**\n *  Attributes used to style unordered lists.\n *\n *  These attributes will apply to the entire list (unless overriden by attributes\n *  for the list items), including the bullets.\n *\n *  Defaults to using a paragraph style with a head indent of 30px.\n */\n@property (nonatomic) CMStyleAttributes *unorderedListAttributes;\n\n/**\n *  Attributes used to style ordered sublists.\n *\n *  These attributes will apply to the entire list (unless overriden by attributes\n *  for the list items), including the numbers.\n *\n *  Defaults to using a paragraph style with a head indent of 30px.\n */\n@property (nonatomic) CMStyleAttributes *orderedSublistAttributes;\n\n/**\n *  Attributes used to style unordered sublists.\n *\n *  These attributes will apply to the entire list (unless overriden by attributes\n *  for the list items), including the bullets.\n *\n *  Defaults to using a paragraph style with a head indent of 30px.\n */\n@property (nonatomic) CMStyleAttributes *unorderedSublistAttributes;\n\n/**\n *  Attributes used to style ordered list items.\n *\n *  These attribtues do _not_ apply to the numbers.\n */\n@property (nonatomic) CMStyleAttributes *orderedListItemAttributes;\n\n/**\n *  Attributes used to style unordered list items.\n *\n *  These attribtues do _not_ apply to the bullets.\n */\n@property (nonatomic) CMStyleAttributes *unorderedListItemAttributes;\n\n/**\n *  Attributes used to style horizontal rules.\n *\n *  Defaults to using a centered alignment with light gray color.\n */\n@property (nonatomic) CMStyleAttributes *horizontalRuleAttributes;\n\n/**\n *  Attributes used to style Checkbox.\n *\n *  Defaults to using a centered alignment with light blue color.\n */\n@property (nonatomic) CMStyleAttributes *checkboxAttributes;\n\n/**\n *  Set properties for horizontal rule.\n *\n *  @param color The color of the horizontal rule.\n *  @param thickness The thickness of the horizontal rule line.\n */\n- (void)setHorizontalRuleColor:(CMColor *)color thickness:(CGFloat)thickness;\n\n/**\n *  Set properties for horizontal rule.\n *\n *  @param bgColor The backgroundColor of checkbox\n *  @param borderColor The color of the border.\n *  @param borderWidth The width of the border.\n */\n- (void)setCheckBoxCheckedBackgroundColor:(CMColor *)bgColor\n                              borderColor:(CMColor *)borderColor\n                              borderWidth:(CGFloat)borderWidth;\n\n@end\n\n\n@interface CMStyleAttributes: NSObject <NSCopying>\n\n@property (readonly) NSMutableDictionary<NSAttributedStringKey, id> * stringAttributes;\n@property (readonly) NSMutableDictionary<CMFontDescriptorAttributeName, id> * fontAttributes;\n@property (readonly) NSMutableDictionary<CMParagraphStyleAttributeName, id> * paragraphStyleAttributes;\n\n// Helper method for setting specific symbolic traits in fontAttributes\n- (void) setFontSymbolicTraits:(CMFontSymbolicTraits)fontSymbolicTraits;\n\n@end\n\n\nextern CMParagraphStyleAttributeName const CMParagraphStyleAttributeLineSpacing;\nextern CMParagraphStyleAttributeName const CMParagraphStyleAttributeParagraphSpacing;\nextern CMParagraphStyleAttributeName const CMParagraphStyleAttributeAlignment;\nextern CMParagraphStyleAttributeName const CMParagraphStyleAttributeFirstLineHeadExtraIndent;\nextern CMParagraphStyleAttributeName const CMParagraphStyleAttributeHeadExtraIndent;\nextern CMParagraphStyleAttributeName const CMParagraphStyleAttributeTailExtraIndent;\nextern CMParagraphStyleAttributeName const CMParagraphStyleAttributeLineBreakMode;\nextern CMParagraphStyleAttributeName const CMParagraphStyleAttributeMinimumLineHeight;\nextern CMParagraphStyleAttributeName const CMParagraphStyleAttributeMaximumLineHeight;\nextern CMParagraphStyleAttributeName const CMParagraphStyleAttributeLineHeightMultiple;\nextern CMParagraphStyleAttributeName const CMParagraphStyleAttributeParagraphSpacingBefore;\nextern CMParagraphStyleAttributeName const CMParagraphStyleAttributeHyphenationFactor;\nextern CMParagraphStyleAttributeName const CMParagraphStyleAttributeListItemLabelIndent;\nextern CMParagraphStyleAttributeName const CMParagraphStyleAttributeListItemBulletString;\nextern CMParagraphStyleAttributeName const CMParagraphStyleAttributeListItemNumberFormat;\nextern CMParagraphStyleAttributeName const CMParagraphStyleAttributeListItemParagraphPrefix;\n\nextern CMCustomStyleAttributeName const CMHorizontalRuleThickness;\nextern CMCustomStyleAttributeName const CMLinkBold;\nextern CMCustomStyleAttributeName const CMCustomListBullet;\nextern CMCustomStyleAttributeName const CMCheckBoxBorderWidth;\nextern CMCustomStyleAttributeName const CMParagraphStyleAttributeListItemLabelIcon;\nextern CMCustomStyleAttributeName const CMListSingleDigitSize;\nextern CMCustomStyleAttributeName const CMListTwoDigitSize;\nextern CMCustomStyleAttributeName const CMListThreeDigitSize;\nextern CMCustomStyleAttributeName const CMLinkIconPrefix;\nextern CMCustomStyleAttributeName const CMLinkIconSpace;\nextern CMCustomStyleAttributeName const CMLinkIconSuffix;\nextern CMCustomStyleAttributeName const CMOrderListFirstLevelIndent;\nextern CMCustomStyleAttributeName const CMParagraphStyleAttributeListItemLabelIconSize;\nextern CMCustomStyleAttributeName const CMListLevelIndent;\nextern CMCustomStyleAttributeName const CMListInternalSpace;\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CMTextAttributes.m",
    "content": "//\n//  CMTextAttributes.m\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/15/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import \"CMTextAttributes.h\"\n#import \"CMPlatformDefines.h\"\n\n@interface CMStyleAttributes ()\n\n- (instancetype) initWithStringAttributes:(NSDictionary<NSAttributedStringKey, id>*) textAttributes;\n- (instancetype) initWithStringAttributes:(NSDictionary<NSAttributedStringKey, id>*) textAttributes paragraphStyleAttributes:(NSDictionary<CMParagraphStyleAttributeName, id>*)paragraphStyleAttributes;\n- (instancetype) initWithParagraphStyleAttributes:(NSDictionary<CMParagraphStyleAttributeName, id>*)paragraphStyleAttributes;\n- (instancetype) initWithFontSymbolicTraits:(CMFontSymbolicTraits)fontSymbolicTraits;\n\n@end\n\nstatic CMStyleAttributes * CMDefaultBaseTextAttributes(void)\n{\n    NSDictionary* stringAttributes;\n#if TARGET_OS_IPHONE\n    stringAttributes = @{NSFontAttributeName: [UIFont preferredFontForTextStyle:UIFontTextStyleBody]};\n#else\n    stringAttributes = @{NSFontAttributeName: [NSFont userFontOfSize:12.0]};\n#endif\n    return [[CMStyleAttributes alloc] initWithStringAttributes:stringAttributes];\n}\n\nstatic NSDictionary<CMParagraphStyleAttributeName, id> * defaultHeaderParagraphStyleAttributes(void)\n{\n    return @{ CMParagraphStyleAttributeParagraphSpacingBefore: @16,\n              CMParagraphStyleAttributeParagraphSpacing: @8 };\n}\n\nstatic CMStyleAttributes * CMDefaultH1Attributes(void)\n{\n    NSDictionary* stringAttributes;\n#if TARGET_OS_IPHONE\n    stringAttributes = @{ NSFontAttributeName: [UIFont preferredFontForTextStyle:UIFontTextStyleTitle1] };\n#else\n    stringAttributes = @{ NSFontAttributeName: [NSFont boldSystemFontOfSize:28.0] };\n#endif\n    return [[CMStyleAttributes alloc] initWithStringAttributes:stringAttributes \n                                      paragraphStyleAttributes:@{ CMParagraphStyleAttributeParagraphSpacingBefore: @28,\n                                                                  CMParagraphStyleAttributeParagraphSpacing: @14 }];\n}\n\nstatic CMStyleAttributes * CMDefaultH2Attributes(void)\n{\n    NSDictionary* stringAttributes;\n    #if TARGET_OS_IPHONE\n        stringAttributes = @{ NSFontAttributeName: [UIFont preferredFontForTextStyle:UIFontTextStyleTitle2] };\n    #else\n        stringAttributes = @{ NSFontAttributeName: [NSFont boldSystemFontOfSize:22.0] };\n    #endif\n    return [[CMStyleAttributes alloc] initWithStringAttributes:stringAttributes \n                                      paragraphStyleAttributes:@{ CMParagraphStyleAttributeParagraphSpacingBefore: @20,\n                                                                  CMParagraphStyleAttributeParagraphSpacing: @10 }];\n}\n\nstatic CMStyleAttributes * CMDefaultH3Attributes(void)\n{\n    NSDictionary* stringAttributes;\n#if TARGET_OS_IPHONE\n    stringAttributes = @{ NSFontAttributeName: [UIFont preferredFontForTextStyle:UIFontTextStyleTitle3] };\n#else\n    stringAttributes = @{ NSFontAttributeName: [NSFont boldSystemFontOfSize:16.0] };\n#endif\n    return [[CMStyleAttributes alloc] initWithStringAttributes:stringAttributes \n                                      paragraphStyleAttributes:defaultHeaderParagraphStyleAttributes()];\n}\n\nstatic CMStyleAttributes * CMDefaultH4Attributes(void)\n{\n    NSDictionary* stringAttributes;\n#if TARGET_OS_IPHONE\n    stringAttributes = @{ NSFontAttributeName: [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline] };\n#else\n    stringAttributes = @{ NSFontAttributeName: [NSFont boldSystemFontOfSize:14.0] };\n#endif\n    return [[CMStyleAttributes alloc] initWithStringAttributes:stringAttributes \n                                      paragraphStyleAttributes:defaultHeaderParagraphStyleAttributes()];\n}\n\nstatic CMStyleAttributes * CMDefaultH5Attributes(void)\n{\n    NSDictionary* stringAttributes;\n#if TARGET_OS_IPHONE\n    stringAttributes = @{ NSFontAttributeName: [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline] };\n#else\n    stringAttributes = @{ NSFontAttributeName: [NSFont boldSystemFontOfSize:12.0] };\n#endif\n    return [[CMStyleAttributes alloc] initWithStringAttributes:stringAttributes \n                                      paragraphStyleAttributes:defaultHeaderParagraphStyleAttributes()];\n}\n\nstatic CMStyleAttributes * CMDefaultH6Attributes(void)\n{\n    NSDictionary* stringAttributes;\n#if TARGET_OS_IPHONE\n    stringAttributes = @{ NSFontAttributeName: [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline] };\n#else\n    stringAttributes = @{ NSFontAttributeName: [NSFont boldSystemFontOfSize:10.0] };\n#endif\n    return [[CMStyleAttributes alloc] initWithStringAttributes:stringAttributes \n                                      paragraphStyleAttributes:defaultHeaderParagraphStyleAttributes()];\n}\n\nstatic CMStyleAttributes * CMDefaultParagraphAttributes(void)\n{\n    return [[CMStyleAttributes alloc] initWithParagraphStyleAttributes:@{ CMParagraphStyleAttributeParagraphSpacingBefore: @12 }];\n}\n\nstatic CMStyleAttributes * CMDefaultLinkAttributes(void)\n{\n    return [[CMStyleAttributes alloc] initWithStringAttributes:@{ NSForegroundColorAttributeName: CMColor.blueColor,\n                                                                  NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle) }];\n}\n\nstatic CMStyleAttributes * CMDefaultImageParagraphAttributes(void)\n{\n    return [[CMStyleAttributes alloc] initWithParagraphStyleAttributes:@{ CMParagraphStyleAttributeParagraphSpacingBefore: @12,\n                                                                          CMParagraphStyleAttributeAlignment: @(NSTextAlignmentCenter) }];\n}\n\n#if TARGET_OS_IPHONE\nstatic UIFont * defaultMonospaceFont(void)\n{\n    if (@available(iOS 11.0, *)) {\n        CGFloat baseFontSize = [UIFont preferredFontForTextStyle:UIFontTextStyleBody \n                                   compatibleWithTraitCollection:[UITraitCollection traitCollectionWithPreferredContentSizeCategory:UIContentSizeCategoryMedium]].pointSize;\n        UIFont* baseMonospaceFont = [UIFont fontWithName:@\"Menlo\" size:baseFontSize] ?: [UIFont fontWithName:@\"Courier\" size:baseFontSize];\n        return [[UIFontMetrics metricsForTextStyle:UIFontTextStyleBody] scaledFontForFont:baseMonospaceFont];\n    } else {\n        // Fallback on earlier versions\n        CGFloat size = [[UIFont preferredFontForTextStyle:UIFontTextStyleBody] pointSize];\n        return [UIFont fontWithName:@\"Menlo\" size:size] ?: [UIFont fontWithName:@\"Courier\" size:size];\n    }\n}\n#endif\n\nstatic CGFloat defaultIndentationStep = 30.0;\n\nstatic CMStyleAttributes * CMDefaultCodeBlockAttributes(void)\n{\n    NSDictionary* stringAttributes;\n#if TARGET_OS_IPHONE\n    stringAttributes = @{ NSFontAttributeName: defaultMonospaceFont(), };\n#else\n    stringAttributes = @{ NSFontAttributeName: [NSFont userFixedPitchFontOfSize:12.0] };\n#endif\n\n    NSDictionary* paragraphStyleAttributes = @{ CMParagraphStyleAttributeParagraphSpacingBefore: @12.0,\n                                                CMParagraphStyleAttributeFirstLineHeadExtraIndent: @(defaultIndentationStep),\n                                                CMParagraphStyleAttributeHeadExtraIndent: @(defaultIndentationStep) };\n    \n    return [[CMStyleAttributes alloc] initWithStringAttributes:stringAttributes \n                                      paragraphStyleAttributes:paragraphStyleAttributes];\n}\n\nstatic CMStyleAttributes * CMDefaultInlineCodeAttributes(void)\n{\n    NSDictionary* stringAttributes;\n#if TARGET_OS_IPHONE\n    stringAttributes = @{ NSFontAttributeName: defaultMonospaceFont(), };\n#else\n    stringAttributes = @{ NSFontAttributeName: [NSFont userFixedPitchFontOfSize:12.0] };\n#endif\n    return [[CMStyleAttributes alloc] initWithStringAttributes:stringAttributes];\n}\n\nstatic  CMStyleAttributes *  CMDefaultBlockQuoteAttributes(void)\n{\n    return [[CMStyleAttributes alloc] initWithParagraphStyleAttributes:@{ CMParagraphStyleAttributeFirstLineHeadExtraIndent: @(defaultIndentationStep),\n                                                                          CMParagraphStyleAttributeHeadExtraIndent: @(defaultIndentationStep) }];\n}\n\nstatic CGFloat itemLabelIndent = 20.0;\n\nstatic NSDictionary<CMParagraphStyleAttributeName, id> * DefaultListParagraphStyleAttributes(void)\n{\n    return @{ CMParagraphStyleAttributeFirstLineHeadExtraIndent: @(defaultIndentationStep + itemLabelIndent),\n              CMParagraphStyleAttributeHeadExtraIndent: @(defaultIndentationStep + itemLabelIndent),\n              CMParagraphStyleAttributeListItemLabelIndent: @(itemLabelIndent),\n              CMParagraphStyleAttributeListItemBulletString: @\"●\",\n              CMParagraphStyleAttributeListItemNumberFormat: @\"%ld.\",\n    };\n}\n\nstatic  CMStyleAttributes *  CMDefaultOrderedListAttributes(void)\n{\n    return [[CMStyleAttributes alloc] initWithParagraphStyleAttributes:DefaultListParagraphStyleAttributes()];\n}\n\nstatic  CMStyleAttributes *  CMDefaultUnorderedListAttributes(void)\n{\n    return [[CMStyleAttributes alloc] initWithParagraphStyleAttributes:DefaultListParagraphStyleAttributes()];\n}\n\nstatic NSDictionary<CMParagraphStyleAttributeName, id> * DefaultSublistParagraphStyleAttributes(void)\n{\n    return @{ CMParagraphStyleAttributeFirstLineHeadExtraIndent: @(itemLabelIndent), // Align label with parent list content\n              CMParagraphStyleAttributeHeadExtraIndent: @(itemLabelIndent),\n              CMParagraphStyleAttributeListItemLabelIndent: @(itemLabelIndent),\n              CMParagraphStyleAttributeListItemBulletString: @\"○\",\n              CMParagraphStyleAttributeListItemNumberFormat: @\"%ld.\",\n    };\n}\n\nstatic  CMStyleAttributes *  CMDefaultOrderedSublistAttributes(void)\n{\n    return [[CMStyleAttributes alloc] initWithParagraphStyleAttributes:DefaultSublistParagraphStyleAttributes()];\n}\n\nstatic  CMStyleAttributes *  CMDefaultUnorderedSublistAttributes(void)\n{\n    return [[CMStyleAttributes alloc] initWithParagraphStyleAttributes:DefaultSublistParagraphStyleAttributes()];\n}\n\nstatic CMStyleAttributes * CMDefaultHorizontalRuleAttributes(void)\n{\n    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];\n    paragraphStyle.alignment = NSTextAlignmentCenter;\n    \n    NSDictionary *hruleAttributes;\n#if TARGET_OS_IPHONE\n    hruleAttributes = @{\n        NSParagraphStyleAttributeName: paragraphStyle,\n        NSForegroundColorAttributeName: [UIColor lightGrayColor]\n    };\n#else\n    hruleAttributes = @{\n        NSParagraphStyleAttributeName: paragraphStyle,\n        NSForegroundColorAttributeName: [NSColor lightGrayColor]\n    };\n#endif\n    \n    return [[CMStyleAttributes alloc] initWithStringAttributes:hruleAttributes];\n}\n\n@implementation CMTextAttributes\n\n- (instancetype)init\n{\n    if ((self = [super init])) {\n        _baseTextAttributes = CMDefaultBaseTextAttributes();\n        _h1Attributes = CMDefaultH1Attributes();\n        _h2Attributes = CMDefaultH2Attributes();\n        _h3Attributes = CMDefaultH3Attributes();\n        _h4Attributes = CMDefaultH4Attributes();\n        _h5Attributes = CMDefaultH5Attributes();\n        _h6Attributes = CMDefaultH6Attributes();\n        _paragraphAttributes = CMDefaultParagraphAttributes();\n        \n        _emphasisAttributes = [[CMStyleAttributes alloc] initWithFontSymbolicTraits:CMFontTraitItalic];\n        _strongAttributes = [[CMStyleAttributes alloc] initWithFontSymbolicTraits:CMFontTraitBold];\n        \n        _linkAttributes = CMDefaultLinkAttributes();\n        _imageParagraphAttributes = CMDefaultImageParagraphAttributes();\n        _codeBlockAttributes = CMDefaultCodeBlockAttributes();\n        _inlineCodeAttributes = CMDefaultInlineCodeAttributes();\n        _blockQuoteAttributes = CMDefaultBlockQuoteAttributes();\n        _orderedListAttributes = CMDefaultOrderedListAttributes();\n        _unorderedListAttributes = CMDefaultUnorderedListAttributes();\n        _orderedSublistAttributes = CMDefaultOrderedSublistAttributes();\n        _unorderedSublistAttributes = CMDefaultUnorderedSublistAttributes();\n        _horizontalRuleAttributes = CMDefaultHorizontalRuleAttributes();\n        _checkboxAttributes = CMDefaultHorizontalRuleAttributes();\n    }\n    return self;\n}\n\n- (void) updateAttributesForElementKinds:(CMElementKind)elementKinds usingBlock:(void(^)(CMStyleAttributes * styleAttributes))block\n{\n    if ((elementKinds & CMElementKindText) != 0) {\n        block(_baseTextAttributes);\n    }\n    if ((elementKinds & CMElementKindHeader1) != 0) {\n        block(_h1Attributes);\n    }\n    if ((elementKinds & CMElementKindHeader2) != 0) {\n        block(_h2Attributes);\n    }\n    if ((elementKinds & CMElementKindHeader3) != 0) {\n        block(_h3Attributes);\n    }\n    if ((elementKinds & CMElementKindHeader4) != 0) {\n        block(_h4Attributes);\n    }\n    if ((elementKinds & CMElementKindHeader5) != 0) {\n        block(_h5Attributes);\n    }\n    if ((elementKinds & CMElementKindHeader6) != 0) {\n        block(_h6Attributes);\n    }\n    if ((elementKinds & CMElementKindParagraph) != 0) {\n        block(_paragraphAttributes);\n    }\n    if ((elementKinds & CMElementKindLink) != 0) {\n        block(_linkAttributes);\n    }\n    if ((elementKinds & CMElementKindImageParagraph) != 0) {\n        block(_imageParagraphAttributes);\n    }\n    if ((elementKinds & CMElementKindCodeBlock) != 0) {\n        block(_codeBlockAttributes);\n    }\n    if ((elementKinds & CMElementKindInlineCode) != 0) {\n        block(_inlineCodeAttributes);\n    }\n    if ((elementKinds & CMElementKindBlockQuote) != 0) {\n        block(_blockQuoteAttributes);\n    }\n    if ((elementKinds & CMElementKindOrderedList) != 0) {\n        block(_orderedListAttributes);\n    }\n    if ((elementKinds & CMElementKindOrderedSublist) != 0) {\n        block(_orderedSublistAttributes);\n    }\n    if ((elementKinds & CMElementKindOrderedListItem) != 0) {\n        block(_orderedListItemAttributes);\n    }\n    if ((elementKinds & CMElementKindUnorderedList) != 0) {\n        block(_unorderedListAttributes);\n    }\n    if ((elementKinds & CMElementKindUnorderedSublist) != 0) {\n        block(_unorderedSublistAttributes);\n    }\n    if ((elementKinds & CMElementKindUnorderedListItem) != 0) {\n        block(_unorderedListItemAttributes);\n    }\n}\n\n- (void) addStringAttributes:(NSDictionary<NSAttributedStringKey, id>*)attributes forElementWithKinds:(CMElementKind)elementKinds\n{\n    [self updateAttributesForElementKinds:elementKinds usingBlock:^(CMStyleAttributes *styleAttributes) {\n        [styleAttributes.stringAttributes addEntriesFromDictionary:attributes];\n    }];\n}\n\n- (void) addFontAttributes:(NSDictionary<CMFontDescriptorAttributeName, id>*)fontAttributes forElementWithKinds:(CMElementKind)elementKinds\n{\n    [self updateAttributesForElementKinds:elementKinds usingBlock:^(CMStyleAttributes *styleAttributes) {\n        [styleAttributes.fontAttributes addEntriesFromDictionary:fontAttributes];\n    }];\n}\n\n- (void) setFontTraits:(NSDictionary<CMFontDescriptorTraitKey, id>*)fontTraits forElementWithKinds:(CMElementKind)elementKinds\n{\n    [self updateAttributesForElementKinds:elementKinds usingBlock:^(CMStyleAttributes *styleAttributes) {\n        styleAttributes.fontAttributes[CMFontTraitsAttribute] = fontTraits;\n    }];\n}\n\n- (void) addParagraphStyleAttributes:(NSDictionary<CMParagraphStyleAttributeName, id>*)attributes forElementWithKinds:(CMElementKind)elementKinds\n{\n    [self updateAttributesForElementKinds:elementKinds usingBlock:^(CMStyleAttributes *styleAttributes) {\n        [styleAttributes.paragraphStyleAttributes addEntriesFromDictionary:attributes];\n    }];\n}\n\n- (CMStyleAttributes *)attributesForHeaderLevel:(NSInteger)level\n{\n    switch (level) {\n        case 1: return _h1Attributes;\n        case 2: return _h2Attributes;\n        case 3: return _h3Attributes;\n        case 4: return _h4Attributes;\n        case 5: return _h5Attributes;\n        default: return _h6Attributes;\n    }\n}\n\n- (void)setHorizontalRuleColor:(CMColor *)color thickness:(CGFloat)thickness {\n    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];\n    paragraphStyle.alignment = NSTextAlignmentCenter;\n    \n    NSDictionary *hruleAttributes = @{\n        NSParagraphStyleAttributeName: paragraphStyle,\n        NSForegroundColorAttributeName: color,\n        CMHorizontalRuleThickness: @(thickness) // 自定义键来存储厚度信息\n    };\n    \n    _horizontalRuleAttributes = [[CMStyleAttributes alloc] initWithStringAttributes:hruleAttributes];\n}\n\n- (void)setCheckBoxCheckedBackgroundColor:(UIColor *)bgColor\n                              borderColor:(UIColor *)borderColor\n                              borderWidth:(CGFloat)borderWidth {\n    NSDictionary *checkboxAttributes = @{\n        NSForegroundColorAttributeName: borderColor,\n        NSBackgroundColorAttributeName: bgColor,\n        CMCheckBoxBorderWidth: @(borderWidth) // 自定义键来存储厚度信息\n    };\n    \n    _checkboxAttributes = [[CMStyleAttributes alloc] initWithStringAttributes:checkboxAttributes];\n}\n\n@end\n\n\n@implementation CMStyleAttributes\n\n- (instancetype) init\n{\n    self = [super init];\n    if (self != nil) {\n        _stringAttributes = [NSMutableDictionary new];\n        _fontAttributes = [NSMutableDictionary new];\n        _paragraphStyleAttributes =[NSMutableDictionary new];\n    }\n    return self;\n}\n\n- (instancetype) initWithStringAttributes:(NSDictionary<NSAttributedStringKey,id> *)stringAttributes\n{\n    self = [self init];\n    if (self != nil) {\n        [_stringAttributes addEntriesFromDictionary:stringAttributes];\n    }\n    return self;\n}\n\n- (instancetype) initWithParagraphStyleAttributes:(NSDictionary<CMParagraphStyleAttributeName, id>*)paragraphStyleAttributes\n{\n    self = [self init];\n    if (self != nil) {\n        [_paragraphStyleAttributes addEntriesFromDictionary:paragraphStyleAttributes];\n    }\n    return self;\n}\n\n- (instancetype) initWithStringAttributes:(NSDictionary<NSAttributedStringKey, id>*)stringAttributes\n                 paragraphStyleAttributes:(NSDictionary<CMParagraphStyleAttributeName, id>*)paragraphStyleAttributes\n{\n    self = [self init];\n    if (self != nil) {\n        [_stringAttributes addEntriesFromDictionary:stringAttributes];\n        [_paragraphStyleAttributes addEntriesFromDictionary:paragraphStyleAttributes];\n    }\n    return self;    \n}\n\n- (instancetype) initWithFontSymbolicTraits:(CMFontSymbolicTraits)fontSymbolicTraits\n{\n    self = [self init];\n    if (self != nil) {\n        [self setFontSymbolicTraits:fontSymbolicTraits];\n    }\n    return self;\n}\n\n- (id)copyWithZone:(nullable NSZone *)zone\n{\n    CMStyleAttributes * copiedAttributes = [CMStyleAttributes new];\n    [copiedAttributes.stringAttributes addEntriesFromDictionary:_stringAttributes];\n    [copiedAttributes.fontAttributes addEntriesFromDictionary:_fontAttributes];\n    [copiedAttributes.paragraphStyleAttributes addEntriesFromDictionary:_paragraphStyleAttributes];\n    return copiedAttributes;\n}\n\n- (void) setFontSymbolicTraits:(CMFontSymbolicTraits)fontSymbolicTraits\n{\n#if TARGET_OS_IPHONE\n    NSDictionary<UIFontDescriptorTraitKey, id> * currentFontTraits = _fontAttributes[UIFontDescriptorTraitsAttribute];\n    if (currentFontTraits == nil) {\n        _fontAttributes[UIFontDescriptorTraitsAttribute] = @{ UIFontSymbolicTrait: @(fontSymbolicTraits) };\n    }\n    else {\n        NSMutableDictionary* newFontTraits = currentFontTraits.mutableCopy;\n        newFontTraits[UIFontSymbolicTrait] = @(fontSymbolicTraits);\n        _fontAttributes[UIFontDescriptorTraitsAttribute] = newFontTraits;\n    }\n#else\n    NSDictionary<NSFontDescriptorTraitKey, id> * currentFontTraits = _fontAttributes[NSFontTraitsAttribute];\n    if (currentFontTraits == nil) {\n        _fontAttributes[NSFontTraitsAttribute] = @{ NSFontSymbolicTrait: @(fontSymbolicTraits) };\n    }\n    else {\n        NSMutableDictionary* newFontTraits = currentFontTraits.mutableCopy;\n        newFontTraits[NSFontSymbolicTrait] = @(fontSymbolicTraits);\n        _fontAttributes[NSFontTraitsAttribute] = newFontTraits;\n    }\n#endif\n}\n\n@end\n\nCMParagraphStyleAttributeName const CMParagraphStyleAttributeLineSpacing = @\"lineSpacing\";\nCMParagraphStyleAttributeName const CMParagraphStyleAttributeParagraphSpacing = @\"paragraphSpacing\";\nCMParagraphStyleAttributeName const CMParagraphStyleAttributeAlignment = @\"alignment\";\nCMParagraphStyleAttributeName const CMParagraphStyleAttributeFirstLineHeadExtraIndent = @\"firstLineHeadIndent\";\nCMParagraphStyleAttributeName const CMParagraphStyleAttributeHeadExtraIndent = @\"headIndent\";\nCMParagraphStyleAttributeName const CMParagraphStyleAttributeTailExtraIndent = @\"tailIndent\";\nCMParagraphStyleAttributeName const CMParagraphStyleAttributeLineBreakMode = @\"lineBreakMode\";\nCMParagraphStyleAttributeName const CMParagraphStyleAttributeMinimumLineHeight = @\"minimumLineHeight\";\nCMParagraphStyleAttributeName const CMParagraphStyleAttributeMaximumLineHeight = @\"maximumLineHeight\";\nCMParagraphStyleAttributeName const CMParagraphStyleAttributeLineHeightMultiple = @\"lineHeightMultiple\";\nCMParagraphStyleAttributeName const CMParagraphStyleAttributeParagraphSpacingBefore = @\"paragraphSpacingBefore\";\nCMParagraphStyleAttributeName const CMParagraphStyleAttributeHyphenationFactor = @\"hyphenationFactor\";\nCMParagraphStyleAttributeName const CMParagraphStyleAttributeListItemLabelIndent = @\"listItemLabelIndent\";\nCMParagraphStyleAttributeName const CMParagraphStyleAttributeListItemBulletString = @\"listItemBulletString\";\nCMParagraphStyleAttributeName const CMParagraphStyleAttributeListItemNumberFormat = @\"listItemNumberFormat\";\nCMParagraphStyleAttributeName const CMParagraphStyleAttributeListItemParagraphPrefix = @\"listItemParagraphPrefix\";\n\n\nCMCustomStyleAttributeName const CMHorizontalRuleThickness = @\"CMHorizontalRuleThickness\";\nCMCustomStyleAttributeName const CMLinkBold = @\"CMLinkBold\";\nCMCustomStyleAttributeName const CMCustomListBullet = @\"CMCustomListBullet\";\nCMCustomStyleAttributeName const CMCheckBoxBorderWidth = @\"CMCheckBoxBorderWidth\";\nCMCustomStyleAttributeName const CMParagraphStyleAttributeListItemLabelIcon = @\"CMParagraphStyleAttributeListItemLabelIcon\";\nCMCustomStyleAttributeName const CMListSingleDigitSize = @\"CMListSingleDigitSize\";\nCMCustomStyleAttributeName const CMListTwoDigitSize = @\"CMListTwoDigitSize\";\nCMCustomStyleAttributeName const CMListThreeDigitSize = @\"CMListThreeDigitSize\";\nCMCustomStyleAttributeName const CMLinkIconPrefix = @\"CMLinkIconPrefix\";\nCMCustomStyleAttributeName const CMLinkIconSpace = @\"CMLinkIconSpace\";\nCMCustomStyleAttributeName const CMLinkIconSuffix = @\"CMLinkIconSuffix\";\nCMCustomStyleAttributeName const CMOrderListFirstLevelIndent = @\"CMOrderListFirstLevelIndent\";\nCMCustomStyleAttributeName const CMParagraphStyleAttributeListItemLabelIconSize = @\"CMParagraphStyleAttributeListItemLabelIconSize\";\nCMCustomStyleAttributeName const CMListLevelIndent = @\"CMListLevelIndent\";\nCMCustomStyleAttributeName const CMListInternalSpace = @\"CMListInternalSpace\";\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/CocoaMarkdown.h",
    "content": "//\n//  CocoaMarkdown.h\n//  CocoaMarkdown\n//\n//  Created by Indragie on 1/12/15.\n//  Copyright (c) 2015 Indragie Karunaratne. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n//! Project version number for CocoaMarkdown.\nFOUNDATION_EXPORT double CocoaMarkdownVersionNumber;\n\n//! Project version string for CocoaMarkdown.\nFOUNDATION_EXPORT const unsigned char CocoaMarkdownVersionString[];\n\n#if __has_include(<CocoaMarkdown/CMDocument.h>)\n#import <CocoaMarkdown/CMAttributedStringRenderer.h>\n#import <CocoaMarkdown/CMDocument.h>\n#import <CocoaMarkdown/CMDocument+AttributedStringAdditions.h>\n#import <CocoaMarkdown/CMDocument+HTMLAdditions.h>\n#import <CocoaMarkdown/CMHTMLRenderer.h>\n#import <CocoaMarkdown/CMHTMLStrikethroughTransformer.h>\n#import <CocoaMarkdown/CMHTMLUnderlineTransformer.h>\n#import <CocoaMarkdown/CMHTMLSuperscriptTransformer.h>\n#import <CocoaMarkdown/CMHTMLSubscriptTransformer.h>\n#import <CocoaMarkdown/CMImageTextAttachment.h>\n#import <CocoaMarkdown/CMInlineTextAttachment.h>\n#import <CocoaMarkdown/CMHorizontalRuleAttachment.h>\n#import <CocoaMarkdown/CMIterator.h>\n#import <CocoaMarkdown/CMNode.h>\n#import <CocoaMarkdown/CMNode+Table.h>\n#import <CocoaMarkdown/CMParser.h>\n#import <CocoaMarkdown/CMTextAttributes.h>\n#else\n#import \"CMAttributedStringRenderer.h\"\n#import \"CMDocument.h\"\n#import \"CMDocument+AttributedStringAdditions.h\"\n#import \"CMDocument+HTMLAdditions.h\"\n#import \"CMHTMLRenderer.h\"\n#import \"CMHTMLStrikethroughTransformer.h\"\n#import \"CMHTMLUnderlineTransformer.h\"\n#import \"CMHTMLSuperscriptTransformer.h\"\n#import \"CMHTMLSubscriptTransformer.h\"\n#import \"CMImageTextAttachment.h\"\n#import \"CMInlineTextAttachment.h\"\n#import \"CMHorizontalRuleAttachment.h\"\n#import \"CMIterator.h\"\n#import \"CMNode.h\"\n#import \"CMNode+Table.h\"\n#import \"CMParser.h\"\n#import \"CMTextAttributes.h\"\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/CocoaMarkdown/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>FMWK</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>$(CURRENT_PROJECT_VERSION)</string>\n\t<key>NSHumanReadableCopyright</key>\n\t<string>Copyright © 2015 Indragie Karunaratne. All rights reserved.</string>\n\t<key>NSPrincipalClass</key>\n\t<string></string>\n</dict>\n</plist>\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/Ono/ONOXMLDocument.h",
    "content": "// ONOXMLDocument.h\n//\n// Copyright (c) 2014 Mattt Thompson (http://mattt.me/)\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\n#import <Foundation/Foundation.h>\n\n@class ONOXMLElement;\n\n/**\n The `ONOSearching` protocol is adopted by `ONOXMLDocument` and `ONOXMLElement`, denoting that they can search for elements using XPath or CSS selectors.\n\n @see http://www.w3.org/TR/xpath/\n @see http://www.w3.org/TR/CSS21/selector.html\n */\n@protocol ONOSearching\n\n///---------------------------\n/// @name Searching with XPath\n///---------------------------\n\n/**\n Returns the results for an XPath selector.\n \n @param XPath The XPath selector\n \n @return An enumerable collection of results.\n */\n- (id <NSFastEnumeration>)XPath:(NSString *)XPath;\n\n/**\n @deprecated Use `enumerateElementsWithXPath:usingBlock:` instead\n */\n- (void)enumerateElementsWithXPath:(NSString *)XPath\n                             block:(void (^)(ONOXMLElement *element))block DEPRECATED_ATTRIBUTE;\n\n/**\n Enumerate elements matching an XPath selector.\n \n @param XPath The XPath selector\n @param block A block that is executed for each result. This block has no return value and takes three arguments:\n    element: The enumerated element.\n    idx: The index of the current item.\n    stop: The block can set the value to `YES` to stop further processing of the elements. The stop argument is an out-only argument. You should only ever set this BOOL to `YES` within the block.\n */\n- (void)enumerateElementsWithXPath:(NSString *)XPath\n                        usingBlock:(void (^)(ONOXMLElement *element, NSUInteger idx, BOOL *stop))block;\n\n/**\n Returns the first elements matching an XPath selector, or `nil` if there are no results.\n \n @param XPath The XPath selector\n \n @return The child element.\n */\n- (ONOXMLElement *)firstChildWithXPath:(NSString *)XPath;\n\n///---------------------------\n/// @name Searching with CSS\n///---------------------------\n\n/**\n Returns the results for a CSS selector.\n\n @param CSS The CSS selector\n\n @return An enumerable collection of results.\n */\n- (id <NSFastEnumeration>)CSS:(NSString *)CSS;\n\n/**\n @deprecated Use `enumerateElementsWithCSS:usingBlock:` instead\n */\n- (void)enumerateElementsWithCSS:(NSString *)CSS\n                           block:(void (^)(ONOXMLElement *element))block DEPRECATED_ATTRIBUTE;\n\n/**\n Enumerate elements matching a CSS selector.\n \n @param CSS The CSS selector\n @param block A block that is executed for each result. This block has no return value and takes three arguments:\n    element: the enumerated element.\n    idx: the index of the current item.\n    stop: the block can set the value to `YES` to stop further processing of the elements. The stop argument is an out-only argument. You should only ever set this BOOL to `YES` within the block.\n */\n- (void)enumerateElementsWithCSS:(NSString *)CSS\n                      usingBlock:(void (^)(ONOXMLElement *element, NSUInteger idx, BOOL *stop))block;\n\n/**\n Returns the first elements matching a CSS selector, or `nil` if there are no results.\n \n @param CSS The CSS selector\n \n @return The child element.\n */\n- (ONOXMLElement *)firstChildWithCSS:(NSString *)CSS;\n\n@end\n\n#pragma mark -\n\n/**\n `ONOXMLDocument` encapsulates an XML or HTML document, which can be searched and queried.\n */\n@interface ONOXMLDocument : NSObject <ONOSearching, NSCopying, NSCoding>\n\n///------------------------------------\n/// @name Accessing Document Attributes\n///------------------------------------\n\n/**\n The XML version.\n */\n@property (readonly, nonatomic, copy) NSString *version;\n\n/**\n The string encoding for the document. This is 0 if no encoding is set, or it cannot be calculated.\n */\n@property (readonly, nonatomic, assign) NSStringEncoding stringEncoding;\n\n\n///---------------------------------\n/// @name Accessing the Root Element\n///---------------------------------\n\n/**\n The root element of the document.\n */\n@property (readonly, nonatomic, strong) ONOXMLElement *rootElement;\n\n///------------------------------------\n/// @name Accessing Document Formatters\n///------------------------------------\n\n/**\n The formatter used to determine `numberValue` for elements in the document. By default, this is an `NSNumberFormatter` instance with `NSNumberFormatterDecimalStyle`.\n */\n@property (readonly, nonatomic, strong) NSNumberFormatter *numberFormatter;\n\n/**\n The formatter used to determine `dateValue` for elements in the document. By default, this is an `NSDateFormatter` instance configured to accept ISO 8601 formatted timestamps.\n \n @see http://en.wikipedia.org/wiki/ISO_8601\n */\n@property (readonly, nonatomic, strong) NSDateFormatter *dateFormatter;\n\n///-----------------------------\n/// @name Creating XML Documents\n///-----------------------------\n\n/**\n Creates and returns an instance of ONOXMLDocument from an XML string.\n \n @param string The XML string.\n @param encoding The string encoding.\n @param error The error error that occured while parsing the XML, or `nil`.\n \n @return An `ONOXMLDocument` with the contents of the specified XML string.\n */\n+ (instancetype)XMLDocumentWithString:(NSString *)string\n                             encoding:(NSStringEncoding)encoding\n                                error:(NSError * __autoreleasing *)error;\n\n/**\n Creates and returns an instance of ONOXMLDocument from XML data.\n\n @param data The XML data.\n @param error The error error that occured while parsing the XML, or `nil`.\n\n @return An `ONOXMLDocument` with the contents of the specified XML data.\n */\n+ (instancetype)XMLDocumentWithData:(NSData *)data\n                              error:(NSError * __autoreleasing *)error;\n\n///------------------------------\n/// @name Creating HTML Documents\n///------------------------------\n\n/**\n Creates and returns an instance of ONOXMLDocument from an HTML string.\n\n @param string The HTML string.\n @param encoding The string encoding.\n @param error The error error that occured while parsing the HTML, or `nil`.\n\n @return An `ONOXMLDocument` with the contents of the specified HTML string.\n */\n+ (instancetype)HTMLDocumentWithString:(NSString *)string\n                              encoding:(NSStringEncoding)encoding\n                                 error:(NSError * __autoreleasing *)error;\n\n/**\n Creates and returns an instance of ONOXMLDocument from HTML data.\n\n @param data The HTML string.\n @param error The error error that occured while parsing the HTML, or `nil`.\n\n @return An `ONOXMLDocument` with the contents of the specified HTML string.\n */\n+ (instancetype)HTMLDocumentWithData:(NSData *)data\n                               error:(NSError * __autoreleasing *)error;\n\n@end\n\n#pragma mark -\n\n/**\n `ONOXMLElement` represents an element in an `ONOXMLDocument`.\n */\n@interface ONOXMLElement : NSObject <ONOSearching, NSCopying, NSCoding>\n\n/**\n The document containing the element.\n */\n@property (readonly, nonatomic, weak) ONOXMLDocument *document;\n\n/**\n The element's namespace.\n */\n#ifdef __cplusplus\n@property (readonly, nonatomic, copy) NSString *ns;\n#else\n@property (readonly, nonatomic, copy) NSString *namespace;\n#endif\n\n/**\n The element's tag.\n */\n@property (readonly, nonatomic, copy) NSString *tag;\n\n/**\n The element's line number\n */\n@property (readonly, nonatomic, assign) NSUInteger lineNumber;\n\n///---------------------------\n/// @name Accessing Attributes\n///---------------------------\n\n/**\n All attributes for the element.\n */\n@property (readonly, nonatomic, strong) NSDictionary *attributes;\n\n/**\n Returns the value for the specified attribute.\n \n @param attribute The attribute name.\n \n @return The associated value.\n */\n- (id)valueForAttribute:(NSString *)attribute;\n\n/**\n Returns the value for an attribute in a particular namespace.\n\n @param attribute The attribute name.\n @param ns The attribute namespace.\n\n @return The associated value.\n */\n- (id)valueForAttribute:(NSString *)attribute\n            inNamespace:(NSString *)ns;\n\n///----------------------------------------------------\n/// @name Accessing Parent, Child, and Sibling Elements\n///----------------------------------------------------\n\n/**\n The element's parent element.\n */\n@property (readonly, nonatomic, strong) ONOXMLElement *parent;\n\n/**\n The element's children elements.\n */\n@property (readonly, nonatomic, strong) NSArray *children;\n\n/**\n The element's previous sibling.\n */\n@property (readonly, nonatomic, strong) ONOXMLElement *previousSibling;\n\n/**\n The element's next sibling.\n */\n@property (readonly, nonatomic, strong) ONOXMLElement *nextSibling;\n\n/**\n Returns the first child element with the specified tag, or `nil` if no such element exists.\n \n @param tag The tag name.\n \n @return The child element.\n */\n- (ONOXMLElement *)firstChildWithTag:(NSString *)tag;\n\n/**\n Returns the first child element with a tag in a particular namespace, or `nil` if no such element exists.\n\n @param tag The tag name.\n @param ns The namespace.\n\n @return The child element.\n */\n- (ONOXMLElement *)firstChildWithTag:(NSString *)tag\n                         inNamespace:(NSString *)ns;\n\n/**\n Returns all children elements with the specified tag.\n\n @param tag The tag name.\n\n @return The children elements.\n */\n- (NSArray *)childrenWithTag:(NSString *)tag;\n\n/**\n Returns all children elements with the specified tag.\n\n @param tag The tag name.\n @param ns The namepsace.\n\n @return The children elements.\n */\n- (NSArray *)childrenWithTag:(NSString *)tag\n                 inNamespace:(NSString *)ns;\n\n///------------------------\n/// @name Accessing Content\n///------------------------\n\n/**\n Whether the element has a value.\n */\n@property (readonly, nonatomic, assign, getter = isBlank) BOOL blank;\n\n/**\n A string representation of the element's value.\n \n @return The string value.\n */\n- (NSString *)stringValue;\n\n/**\n A number representation of the element's value, which is generated from the document's `numberFormatter` property.\n \n @return The number value;\n */\n- (NSNumber *)numberValue;\n\n/**\n A date representation of the element's value, which is generated from the document's `dateFormatter` property.\n \n @return The date value.\n */\n- (NSDate *)dateValue;\n\n///--------------------------------------\n/// @name Subscripted Convenience Methods\n///--------------------------------------\n\n/**\n Returns the child element at the specified index.\n \n @param idx The index.\n \n @return The child element.\n */\n- (id)objectAtIndexedSubscript:(NSUInteger)idx;\n\n/**\n Returns the value for the attribute with the specified key.\n \n @param key The key.\n \n @return The attribute value, or `nil` if the attribute is not defined.\n */\n- (id)objectForKeyedSubscript:(id)key;\n\n@end\n\n\n///---------------------------\n/// @name Constants\n///---------------------------\n\n/**\n ## Error Domains\n\n The following error domain is predefined.\n\n - `NSString * const ONOErrorDomain`\n\n ### Constants\n\n `ONOErrorDomain`\n Ono errors. Error codes for `ONOErrorDomain` are not currently defined.\n */\nextern NSString * const ONOErrorDomain;\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/Ono/ONOXMLDocument.m",
    "content": "// ONOXMLDocument.m\n//\n// Copyright (c) 2014 Mattt Thompson (http://mattt.me/)\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\n#import \"ONOXMLDocument.h\"\n\n#import <libxml2/libxml/xmlreader.h>\n#import <libxml2/libxml/xpath.h>\n#import <libxml2/libxml/xpathInternals.h>\n#import <libxml2/libxml/HTMLparser.h>\n\nstatic NSRegularExpression * ONOIdRegularExpression() {\n    static NSRegularExpression *_ONOIdRegularExpression = nil;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        _ONOIdRegularExpression = [NSRegularExpression regularExpressionWithPattern:@\"\\\\#([\\\\w-_]+)\" options:(NSRegularExpressionOptions)0 error:nil];\n    });\n\n    return _ONOIdRegularExpression;\n}\n\nstatic NSRegularExpression * ONOClassRegularExpression() {\n    static NSRegularExpression *_ONOClassRegularExpression = nil;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        _ONOClassRegularExpression = [NSRegularExpression regularExpressionWithPattern:@\"\\\\.([^\\\\.]+)\" options:(NSRegularExpressionOptions)0 error:nil];\n    });\n\n    return _ONOClassRegularExpression;\n}\n\nstatic NSRegularExpression * ONOAttributeRegularExpression() {\n    static NSRegularExpression *_ONOAttributeRegularExpression = nil;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        _ONOAttributeRegularExpression = [NSRegularExpression regularExpressionWithPattern:@\"\\\\[(\\\\w+)\\\\]\" options:(NSRegularExpressionOptions)0 error:nil];\n    });\n\n    return _ONOAttributeRegularExpression;\n}\n\nNSString * ONOXPathFromCSS(NSString *CSS) {\n    NSMutableArray *mutableXPathExpressions = [NSMutableArray array];\n    [[CSS componentsSeparatedByString:@\",\"] enumerateObjectsUsingBlock:^(NSString *expression, NSUInteger idx, BOOL *stop) {\n        if (expression && [expression length] > 0) {\n            __block NSMutableArray *mutableXPathComponents = [NSMutableArray arrayWithObject:@\"./\"];\n            __block NSString *prefix = nil;\n\n            [[[expression stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] enumerateObjectsUsingBlock:^(NSString *token, NSUInteger idx, __unused BOOL *stop) {\n                if ([token isEqualToString:@\"*\"] && idx != 0) {\n                    [mutableXPathComponents addObject:@\"/*\"];\n                } else if ([token isEqualToString:@\">\"]) {\n                    prefix = @\"\";\n                } else if ([token isEqualToString:@\"+\"]) {\n                    prefix = @\"following-sibling::*[1]/self::\";\n                } else if ([token isEqualToString:@\"~\"]) {\n                    prefix = @\"following-sibling::\";\n                } else {\n                    if (!prefix && idx != 0) {\n                        prefix = @\"descendant::\";\n                    }\n\n                    NSRange symbolRange = [token rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@\"#.[]\"]];\n                    if (symbolRange.location != NSNotFound) {\n                        NSMutableString *mutableXPathComponent = [NSMutableString stringWithString:[token substringToIndex:symbolRange.location]];\n                        NSRange range = NSMakeRange(0, [token length]);\n\n                        {\n                            NSTextCheckingResult *result = [ONOIdRegularExpression() firstMatchInString:CSS options:(NSMatchingOptions)0 range:range];\n                            if ([result numberOfRanges] > 1) {\n                                [mutableXPathComponent appendFormat:@\"%@[@id = '%@']\", (symbolRange.location == 0) ? @\"*\" : @\"\", [token substringWithRange:[result rangeAtIndex:1]]];\n                            }\n                        }\n\n                        {\n                            for (NSTextCheckingResult *result in [ONOClassRegularExpression() matchesInString:token options:(NSMatchingOptions)0 range:range]) {\n                                if ([result numberOfRanges] > 1) {\n                                    [mutableXPathComponent appendFormat:@\"%@[contains(concat(' ',normalize-space(@class),' '),' %@ ')]\", (symbolRange.location == 0) ? @\"*\" : @\"\", [token substringWithRange:[result rangeAtIndex:1]]];\n                                }\n                            }\n                        }\n\n                        {\n                            for (NSTextCheckingResult *result in [ONOAttributeRegularExpression() matchesInString:token options:(NSMatchingOptions)0 range:range]) {\n                                if ([result numberOfRanges] > 1) {\n                                    [mutableXPathComponent appendFormat:@\"[@%@]\", [token substringWithRange:[result rangeAtIndex:1]]];\n                                }\n                            }\n                        }\n\n                        token = mutableXPathComponent;\n                    }\n\n                    if (prefix) {\n                        token = [prefix stringByAppendingString:token];\n                        prefix = nil;\n                    }\n\n                    [mutableXPathComponents addObject:token];\n                }\n            }];\n\n            [mutableXPathExpressions addObject:[mutableXPathComponents componentsJoinedByString:@\"/\"]];\n        }\n    }];\n\n    return [mutableXPathExpressions componentsJoinedByString:@\" | \"];\n}\n\nstatic BOOL ONOXMLNodeMatchesTagInNamespace(xmlNodePtr node, NSString *tag, NSString *ns) {\n    BOOL matchingTag = !tag || [[NSString stringWithUTF8String:(const char *)node->name] compare:tag options:NSCaseInsensitiveSearch] == NSOrderedSame;\n\n    BOOL matchingNamespace = !ns ? YES : (((node->ns != NULL) && (node->ns->prefix != NULL)) ? [[NSString stringWithUTF8String:(const char *)node->ns->prefix] compare:ns options:NSCaseInsensitiveSearch] == NSOrderedSame : NO);\n\n    return matchingTag && matchingNamespace;\n}\n\n@interface ONOXPathEnumerator : NSEnumerator <NSFastEnumeration>\n@end\n\n@interface ONOXPathEnumerator ()\n@property (readwrite, nonatomic, assign) xmlXPathObjectPtr xmlXPath;\n@property (readwrite, nonatomic, assign) NSUInteger cursor;\n@property (readwrite, nonatomic, strong) ONOXMLDocument *document;\n@end\n\n@interface ONOXMLElement ()\n@property (readwrite, nonatomic, assign) xmlNodePtr xmlNode;\n@property (readwrite, nonatomic, weak) ONOXMLDocument *document;\n@end\n\n@interface ONOXMLDocument ()\n@property (readwrite, nonatomic, assign) xmlDocPtr xmlDocument;\n@property (readwrite, nonatomic, strong) ONOXMLElement *rootElement;\n@property (readwrite, nonatomic, copy) NSString *version;\n@property (readwrite, nonatomic, assign) NSStringEncoding stringEncoding;\n@property (readwrite, nonatomic, strong) NSNumberFormatter *numberFormatter;\n@property (readwrite, nonatomic, strong) NSDateFormatter *dateFormatter;\n\n- (ONOXMLElement *)elementWithNode:(xmlNodePtr)node;\n- (ONOXPathEnumerator *)enumeratorWithXPathObject:(xmlXPathObjectPtr)XPath;\n@end\n\n#pragma mark -\n\n@implementation ONOXPathEnumerator\n\n- (void)dealloc {\n    if (_xmlXPath) {\n        xmlXPathFreeObject(_xmlXPath);\n    }\n}\n\n- (id)objectAtIndex:(NSUInteger)idx {\n    if (idx >= (NSUInteger)xmlXPathNodeSetGetLength(self.xmlXPath->nodesetval)) {\n        return nil;\n    }\n\n    return [self.document elementWithNode:self.xmlXPath->nodesetval->nodeTab[idx]];\n}\n\n#pragma mark - NSEnumerator\n\n- (NSArray *)allObjects {\n    NSMutableArray *mutableObjects = [NSMutableArray arrayWithCapacity:(NSUInteger)self.xmlXPath->nodesetval->nodeNr];\n    for (NSInteger idx = 0; idx < xmlXPathNodeSetGetLength(self.xmlXPath->nodesetval); idx++) {\n        ONOXMLElement *element = [self objectAtIndex:idx];\n        if (element) {\n            [mutableObjects addObject:element];\n        }\n    }\n\n    return [NSArray arrayWithArray:mutableObjects];\n}\n\n- (id)nextObject {\n    if (self.cursor >= (NSUInteger)self.xmlXPath->nodesetval->nodeNr) {\n        return nil;\n    }\n\n    return [self objectAtIndex:((NSUInteger)self.cursor++)];\n}\n\n@end\n\n#pragma mark -\n\n@implementation ONOXMLDocument\n\n+ (instancetype)XMLDocumentWithString:(NSString *)string\n                             encoding:(NSStringEncoding)encoding\n                                error:(NSError * __autoreleasing *)error\n{\n    return [self XMLDocumentWithData:[string dataUsingEncoding:encoding] error:error];\n}\n\n+ (instancetype)XMLDocumentWithData:(NSData *)data\n                              error:(NSError * __autoreleasing *)error\n{\n    xmlDocPtr document = xmlReadMemory([data bytes], (int)[data length], \"\", nil, XML_PARSE_RECOVER);\n    if (!document) {\n        return nil;\n    }\n\n    return [[self alloc] initWithDocument:document];\n}\n\n+ (instancetype)HTMLDocumentWithString:(NSString *)string\n                              encoding:(NSStringEncoding)encoding\n                                 error:(NSError * __autoreleasing *)error\n{\n    return [self HTMLDocumentWithData:[string dataUsingEncoding:encoding] error:error];\n}\n\n+ (instancetype)HTMLDocumentWithData:(NSData *)data\n                               error:(NSError * __autoreleasing *)error\n{\n    xmlDocPtr document = htmlReadMemory([data bytes], (int)[data length], \"\", nil, HTML_PARSE_NOWARNING | HTML_PARSE_NOERROR);\n    if (!document) {\n        return nil;\n    }\n\n    return [[self alloc] initWithDocument:document];\n}\n\n#pragma mark -\n\n- (instancetype)initWithDocument:(xmlDocPtr)document {\n    self = [super init];\n    if (!self) {\n        return nil;\n    }\n\n    _xmlDocument = document;\n    if (self.xmlDocument) {\n        self.rootElement = [self elementWithNode:xmlDocGetRootElement(self.xmlDocument)];\n    }\n\n    return self;\n}\n\n- (void)dealloc {\n    if (_xmlDocument) {\n        xmlFreeDoc(_xmlDocument);\n    }\n}\n\n#pragma mark -\n\n- (NSNumberFormatter *)numberFormatter {\n    if (!_numberFormatter) {\n        _numberFormatter = [[NSNumberFormatter alloc] init];\n        [_numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];\n    }\n\n    return _numberFormatter;\n}\n\n- (NSDateFormatter *)dateFormatter {\n    if (!_dateFormatter) {\n        _dateFormatter = [[NSDateFormatter alloc] init];\n        [_dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@\"en_US_POSIX\"]];\n        [_dateFormatter setDateFormat:@\"yyyy-MM-dd'T'HH:mm:ssZ\"];\n    }\n\n    return _dateFormatter;\n}\n\n#pragma mark -\n\n- (ONOXMLElement *)elementWithNode:(xmlNodePtr)node {\n    if (!node) {\n        return nil;\n    }\n\n    ONOXMLElement *element = [[ONOXMLElement alloc] init];\n    element.xmlNode = node;\n    element.document = self;\n\n    return element;\n}\n\n- (ONOXPathEnumerator *)enumeratorWithXPathObject:(xmlXPathObjectPtr)XPath {\n    if (!XPath || xmlXPathNodeSetIsEmpty(XPath->nodesetval)) {\n        return nil;\n    }\n\n    ONOXPathEnumerator *enumerator = [[ONOXPathEnumerator alloc] init];\n    enumerator.xmlXPath = XPath;\n    enumerator.document = self;\n\n    return enumerator;\n}\n\n#pragma mark - ONOSearching\n\n- (id <NSFastEnumeration>)XPath:(NSString *)XPath {\n    return [self.rootElement XPath:XPath];\n}\n\n- (void)enumerateElementsWithXPath:(NSString *)XPath\n                             block:(void (^)(ONOXMLElement *element))block\n{\n    if (!block) {\n        return;\n    }\n\n    [self.rootElement enumerateElementsWithXPath:XPath usingBlock:^(ONOXMLElement *element, __unused NSUInteger idx, __unused BOOL *stop) {\n        block(element);\n    }];\n}\n\n- (void)enumerateElementsWithXPath:(NSString *)XPath\n                        usingBlock:(void (^)(ONOXMLElement *element, NSUInteger idx, BOOL *stop))block\n{\n    [self.rootElement enumerateElementsWithXPath:XPath usingBlock:block];\n}\n\n- (ONOXMLElement *)firstChildWithXPath:(NSString *)XPath\n{\n    return [self.rootElement firstChildWithXPath:XPath];\n}\n\n- (id <NSFastEnumeration>)CSS:(NSString *)CSS {\n    return [self.rootElement CSS:CSS];\n}\n\n- (void)enumerateElementsWithCSS:(NSString *)CSS\n                           block:(void (^)(ONOXMLElement *))block\n{\n    [self.rootElement enumerateElementsWithCSS:CSS block:block];\n}\n\n- (void)enumerateElementsWithCSS:(NSString *)CSS\n                      usingBlock:(void (^)(ONOXMLElement *element, NSUInteger idx, BOOL *stop))block\n{\n    [self.rootElement enumerateElementsWithCSS:CSS usingBlock:block];\n}\n\n- (ONOXMLElement *)firstChildWithCSS:(NSString *)CSS\n{\n    return [self.rootElement firstChildWithCSS:CSS];\n}\n\n#pragma mark -\n\n- (NSString *)version {\n    if (!_version && self.xmlDocument->version != NULL) {\n        self.version = [NSString stringWithUTF8String:(const char *)self.xmlDocument->version];\n    }\n\n    return _version;\n}\n\n- (NSStringEncoding)stringEncoding {\n    if (!_stringEncoding && self.xmlDocument->encoding != NULL) {\n        NSString *encodingName = [NSString stringWithUTF8String:(const char *)self.xmlDocument->encoding];\n        CFStringEncoding encoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef)encodingName);\n        if (encoding != kCFStringEncodingInvalidId) {\n            self.stringEncoding = CFStringConvertEncodingToNSStringEncoding(encoding);\n        }\n    }\n\n    return _stringEncoding;\n}\n\n#pragma mark - NSObject\n\n- (NSString *)description {\n    return [self.rootElement description];\n}\n\n- (BOOL)isEqual:(id)object {\n    if (self == object) {\n        return YES;\n    }\n\n    if (![object isKindOfClass:[self class]]) {\n        return NO;\n    }\n\n    return [self hash] == [object hash];\n}\n\n- (NSUInteger)hash {\n    return (NSUInteger)self.xmlDocument;\n}\n\n#pragma mark - NSCopying\n\n- (id)copyWithZone:(NSZone *)zone {\n    ONOXMLDocument *document = [[[self class] allocWithZone:zone] init];\n    document.version = self.version;\n    document.rootElement = self.rootElement;\n\n    return document;\n}\n\n#pragma mark - NSCoding\n\n- (id)initWithCoder:(NSCoder *)decoder {\n    self = [super init];\n    if (!self) {\n        return nil;\n    }\n\n    self.version = [decoder decodeObjectForKey:NSStringFromSelector(@selector(version))];\n    self.rootElement = [decoder decodeObjectForKey:NSStringFromSelector(@selector(rootElement))];\n\n    return self;\n}\n\n- (void)encodeWithCoder:(NSCoder *)coder {\n    [coder encodeObject:self.version forKey:NSStringFromSelector(@selector(version))];\n    [coder encodeObject:self.rootElement forKey:NSStringFromSelector(@selector(rootElement))];\n}\n\n@end\n\n#pragma mark -\n\n@interface ONOXMLElement ()\n@property (readwrite, nonatomic, copy) NSString *rawXMLString;\n@property (readwrite, nonatomic, copy) NSString *tag;\n@property (readwrite, nonatomic, assign) NSUInteger lineNumber;\n#ifdef __cplusplus\n@property (readwrite, nonatomic, copy) NSString *ns;\n#else\n@property (readwrite, nonatomic, copy) NSString *namespace;\n#endif\n@property (readwrite, nonatomic, strong) ONOXMLElement *parent;\n@property (readwrite, nonatomic, strong) NSArray *children;\n@property (readwrite, nonatomic, strong) ONOXMLElement *previousSibling;\n@property (readwrite, nonatomic, strong) ONOXMLElement *nextSibling;\n@property (readwrite, nonatomic, strong) NSDictionary *attributes;\n@property (readwrite, nonatomic, copy) NSString *stringValue;\n@property (readwrite, nonatomic, copy) NSNumber *numberValue;\n@property (readwrite, nonatomic, copy) NSDate *dateValue;\n@end\n\n@implementation ONOXMLElement\n@dynamic children;\n\n#ifdef __cplusplus\n- (NSString *)ns {\n    if (!_ns && self.xmlNode->ns != NULL && self.xmlNode->ns->prefix != NULL) {\n        self.ns = [NSString stringWithUTF8String:(const char *)self.xmlNode->ns->prefix];\n    }\n\n    return _ns;\n}\n#else\n- (NSString *)namespace {\n    if (!_namespace && self.xmlNode->ns != NULL && self.xmlNode->ns->prefix != NULL) {\n        self.namespace = [NSString stringWithUTF8String:(const char *)self.xmlNode->ns->prefix];\n    }\n\n    return _namespace;\n}\n#endif\n\n- (NSString *)tag {\n    if (!_tag && self.xmlNode->name != NULL) {\n        self.tag = [NSString stringWithUTF8String:(const char *)self.xmlNode->name];\n    }\n\n    return _tag;\n}\n\n- (NSUInteger)lineNumber {\n    if (!_lineNumber) {\n        self.lineNumber = xmlGetLineNo(self.xmlNode);\n    }\n\n    return _lineNumber;\n}\n\n#pragma mark -\n\n- (NSDictionary *)attributes {\n    if (!_attributes) {\n        NSMutableDictionary *mutableAttributes = [NSMutableDictionary dictionary];\n        for (xmlAttrPtr attribute = self.xmlNode->properties; attribute != NULL; attribute = attribute->next) {\n            NSString *key = [NSString stringWithUTF8String:(const char *)attribute->name];\n            [mutableAttributes setObject:[self valueForAttribute:key] forKey:key];\n        }\n\n        self.attributes = [NSDictionary dictionaryWithDictionary:mutableAttributes];\n    }\n\n    return _attributes;\n}\n\n- (id)valueForAttribute:(NSString *)attribute {\n    id value = nil;\n    const unsigned char *xmlValue = xmlGetProp(self.xmlNode, (const xmlChar *)[attribute cStringUsingEncoding:NSUTF8StringEncoding]);\n    if (xmlValue) {\n        value = [NSString stringWithUTF8String:(const char *)xmlValue];\n        xmlFree((void *)xmlValue);\n    }\n\n    return value;\n}\n\n- (id)valueForAttribute:(NSString *)attribute\n            inNamespace:(NSString *)ns\n{\n    id value = nil;\n    const unsigned char *xmlValue = xmlGetNsProp(self.xmlNode, (const xmlChar *)[attribute cStringUsingEncoding:NSUTF8StringEncoding], (const xmlChar *)[ns cStringUsingEncoding:NSUTF8StringEncoding]);\n    if (xmlValue) {\n        value = [NSString stringWithUTF8String:(const char *)xmlValue];\n        xmlFree((void *)xmlValue);\n    }\n\n    return value;\n}\n\n#pragma mark -\n\n- (ONOXMLElement *)parent {\n    if (!_parent) {\n        self.parent = [self.document elementWithNode:self.xmlNode->parent];\n    }\n\n    return _parent;\n}\n\n- (NSArray *)children {\n    return [self childrenAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, NSIntegerMax)]];\n}\n\n- (ONOXMLElement *)firstChildWithTag:(NSString *)tag {\n    return [self firstChildWithTag:tag inNamespace:nil];\n}\n\n- (ONOXMLElement *)firstChildWithTag:(NSString *)tag\n                         inNamespace:(NSString *)ns\n{\n    NSArray *children = [self childrenAtIndexes:[self indexesOfChildrenPassingTest:^BOOL(xmlNodePtr node, BOOL *stop) {\n        *stop = ONOXMLNodeMatchesTagInNamespace(node, tag, ns);\n        return *stop;\n    }]];\n\n    if ([children count] == 0) {\n        return nil;\n    }\n\n    return [children objectAtIndex:0];\n}\n\n- (NSArray *)childrenWithTag:(NSString *)tag {\n    return [self childrenWithTag:tag inNamespace:nil];\n}\n\n- (NSArray *)childrenWithTag:(NSString *)tag\n                 inNamespace:(NSString *)ns\n{\n    return [self childrenAtIndexes:[self indexesOfChildrenPassingTest:^BOOL(xmlNodePtr node, BOOL *stop) {\n        return ONOXMLNodeMatchesTagInNamespace(node, tag, ns);\n    }]];\n}\n\n- (NSArray *)childrenAtIndexes:(NSIndexSet *)indexes {\n    NSMutableArray *mutableChildren = [NSMutableArray array];\n\n    xmlNodePtr cursor = self.xmlNode->children;\n    NSUInteger idx = 0;\n    while (cursor) {\n        if ([indexes containsIndex:idx] && cursor->type == XML_ELEMENT_NODE) {\n            [mutableChildren addObject:[self.document elementWithNode:cursor]];\n        }\n\n        cursor = cursor->next;\n        idx++;\n    }\n\n    return [NSArray arrayWithArray:mutableChildren];\n}\n\n- (NSIndexSet *)indexesOfChildrenPassingTest:(BOOL (^)(xmlNodePtr node, BOOL *stop))block {\n    if (!block) {\n        return nil;\n    }\n\n    NSMutableIndexSet *mutableIndexSet = [NSMutableIndexSet indexSet];\n\n    xmlNodePtr cursor = self.xmlNode->children;\n    NSUInteger idx = 0;\n    BOOL stop = NO;\n    while (cursor && !stop) {\n        if (block(cursor, &stop)) {\n            [mutableIndexSet addIndex:idx];\n        }\n\n        cursor = cursor->next;\n        idx++;\n    }\n\n    return mutableIndexSet;\n}\n\n- (ONOXMLElement *)previousSibling {\n    if (!_previousSibling) {\n        self.previousSibling = [self.document elementWithNode:self.xmlNode->prev];\n    }\n\n    return _previousSibling;\n}\n\n- (ONOXMLElement *)nextSibling {\n    if (!_nextSibling) {\n        self.nextSibling = [self.document elementWithNode:self.xmlNode->next];\n    }\n\n    return _nextSibling;\n}\n\n#pragma mark -\n\n- (BOOL)isBlank {\n    return [[self stringValue] length] == 0;\n}\n\n- (NSString *)stringValue {\n    if (!_stringValue) {\n        xmlChar *key = xmlNodeGetContent(self.xmlNode);\n        self.stringValue = key ? [NSString stringWithUTF8String:(const char *)key] : @\"\";\n        xmlFree(key);\n    }\n\n    return _stringValue;\n}\n\n- (NSNumber *)numberValue {\n    if (_numberValue != nil) {\n        self.numberValue = [self.document.numberFormatter numberFromString:[self stringValue]];\n    }\n\n    return _numberValue;\n}\n\n- (NSDate *)dateValue {\n    if (!_dateValue) {\n        self.dateValue = [self.document.dateFormatter dateFromString:[self stringValue]];\n    }\n\n    return _dateValue;\n}\n\n#pragma mark -\n\n- (id)objectForKeyedSubscript:(id)key {\n    return [self valueForAttribute:key];\n}\n\n- (id)objectAtIndexedSubscript:(NSUInteger)idx {\n    return [self.children objectAtIndex:idx];\n}\n\n#pragma mark - NSObject\n\n- (NSString *)description {\n    xmlBufferPtr buffer = xmlBufferCreate();\n    xmlNodeDump(buffer, self.xmlNode->doc, self.xmlNode, 0, false);\n    NSString *rawXMLString = [NSString stringWithUTF8String:(const char *)xmlBufferContent(buffer)];\n    xmlBufferFree(buffer);\n\n    return rawXMLString;\n}\n\n- (BOOL)isEqual:(id)object {\n    if (self == object) {\n        return YES;\n    }\n\n    if (![object isKindOfClass:[self class]]) {\n        return NO;\n    }\n\n    return [self hash] == [object hash];\n}\n\n- (NSUInteger)hash {\n    return (NSUInteger)self.xmlNode;\n}\n\n#pragma mark - ONOSearching\n\n- (id <NSFastEnumeration>)XPath:(NSString *)XPath {\n    if (!XPath) {\n        return nil;\n    }\n\n    ONOXPathEnumerator *enumerator = nil;\n    xmlXPathContextPtr context = xmlXPathNewContext(self.xmlNode->doc);\n    if (context) {\n        context->node = self.xmlNode;\n\n        // Due to a bug in libxml2, namespaces may not appear in `xmlNode->ns`.\n        // As a workaround, `xmlNode->nsDef` is recursed to explicitly register namespaces.\n        for (xmlNodePtr node = self.xmlNode; node->parent != NULL; node = node->parent) {\n            for (xmlNsPtr ns = node->nsDef; ns != NULL; ns = ns->next) {\n                if (ns->prefix) {\n                    xmlXPathRegisterNs(context, ns->prefix, ns->href);\n                }\n            }\n        }\n        \n        xmlXPathObjectPtr xmlXPath = xmlXPathEvalExpression((xmlChar *)[XPath cStringUsingEncoding:NSUTF8StringEncoding], context);\n        enumerator = [self.document enumeratorWithXPathObject:xmlXPath];\n\n        xmlXPathFreeContext(context);\n    }\n\n    return enumerator;\n}\n\n- (void)enumerateElementsWithXPath:(NSString *)XPath\n                             block:(void (^)(ONOXMLElement *element))block\n{\n    if (!block) {\n        return;\n    }\n\n    [self enumerateElementsWithXPath:XPath usingBlock:^(ONOXMLElement *element, __unused NSUInteger idx, __unused BOOL *stop) {\n        block(element);\n    }];\n}\n\n- (void)enumerateElementsWithXPath:(NSString *)XPath\n                        usingBlock:(void (^)(ONOXMLElement *element, NSUInteger idx, BOOL *stop))block\n{\n    if (!block) {\n        return;\n    }\n    \n    NSUInteger idx = 0;\n    BOOL stop = NO;\n    for (ONOXMLElement *element in [self XPath:XPath]) {\n        block(element, idx++, &stop);\n\n        if (stop) {\n            break;\n        }\n    }\n}\n\n- (ONOXMLElement *)firstChildWithXPath:(NSString *)XPath\n{\n    for (ONOXMLElement *element in [self XPath:XPath]) {\n        return element;\n    }\n\n    return nil;\n}\n\n- (id <NSFastEnumeration>)CSS:(NSString *)CSS {\n    return [self XPath:ONOXPathFromCSS(CSS)];\n}\n\n- (void)enumerateElementsWithCSS:(NSString *)CSS\n                           block:(void (^)(ONOXMLElement *element))block\n{\n    if (!block) {\n        return;\n    }\n\n    [self enumerateElementsWithCSS:ONOXPathFromCSS(CSS) usingBlock:^(ONOXMLElement *element, __unused NSUInteger idx, __unused BOOL *stop) {\n        block(element);\n    }];\n}\n\n- (void)enumerateElementsWithCSS:(NSString *)CSS\n                      usingBlock:(void (^)(ONOXMLElement *element, NSUInteger idx, BOOL *stop))block\n{\n    [self enumerateElementsWithXPath:ONOXPathFromCSS(CSS) usingBlock:block];\n}\n\n- (ONOXMLElement *)firstChildWithCSS:(NSString *)CSS\n{\n    for (ONOXMLElement *element in [self CSS:CSS]) {\n        return element;\n    }\n    \n    return nil;\n}\n\n#pragma mark - NSObject\n\n- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {\n    return [[self stringValue] methodSignatureForSelector:selector];\n}\n\n- (void)forwardInvocation:(NSInvocation *)invocation {\n    [invocation invokeWithTarget:[self stringValue]];\n}\n\n#pragma mark - NSCopying\n\n- (id)copyWithZone:(NSZone *)zone {\n    ONOXMLElement *element = [[[self class] allocWithZone:zone] init];\n    element.xmlNode = self.xmlNode;\n    element.document = self.document;\n\n    return element;\n}\n\n#pragma mark - NSCoding\n\n- (id)initWithCoder:(NSCoder *)decoder {\n    self = [super init];\n    if (!self) {\n        return nil;\n    }\n\n    self.tag = [decoder decodeObjectForKey:NSStringFromSelector(@selector(tag))];\n    self.attributes = [decoder decodeObjectForKey:NSStringFromSelector(@selector(attributes))];\n    self.stringValue = [decoder decodeObjectForKey:NSStringFromSelector(@selector(stringValue))];\n    self.children = [decoder decodeObjectForKey:NSStringFromSelector(@selector(children))];\n\n    return self;\n}\n\n- (void)encodeWithCoder:(NSCoder *)coder {\n    [coder encodeObject:self.tag forKey:NSStringFromSelector(@selector(tag))];\n    [coder encodeObject:self.attributes forKey:NSStringFromSelector(@selector(attributes))];\n    [coder encodeObject:self.stringValue forKey:NSStringFromSelector(@selector(stringValue))];\n    [coder encodeObject:self.children forKey:NSStringFromSelector(@selector(children))];\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/Ono/Ono.h",
    "content": "// Ono.h\n//\n// Copyright (c) 2014 Mattt Thompson (http://mattt.me/)\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\n#ifndef __ONO__\n    #import \"ONOXMLDocument.h\"\n\n    #define __ONO__\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/cmark-gfm_export.h",
    "content": "\n#ifndef CMARK_GFM_EXPORT_H\n#define CMARK_GFM_EXPORT_H\n\n#ifdef CMARK_GFM_STATIC_DEFINE\n#  define CMARK_GFM_EXPORT\n#  define CMARK_GFM_NO_EXPORT\n#else\n#  ifndef CMARK_GFM_EXPORT\n#    ifdef libcmark_gfm_EXPORTS\n        /* We are building this library */\n#      define CMARK_GFM_EXPORT __attribute__((visibility(\"default\")))\n#    else\n        /* We are using this library */\n#      define CMARK_GFM_EXPORT __attribute__((visibility(\"hidden\")))\n#    endif\n#  endif\n\n#  ifndef CMARK_GFM_NO_EXPORT\n#    define CMARK_GFM_NO_EXPORT __attribute__((visibility(\"hidden\")))\n#  endif\n#endif\n\n#ifndef CMARK_GFM_DEPRECATED\n#  define CMARK_GFM_DEPRECATED __attribute__ ((__deprecated__))\n#endif\n\n#ifndef CMARK_GFM_DEPRECATED_EXPORT\n#  define CMARK_GFM_DEPRECATED_EXPORT CMARK_GFM_EXPORT CMARK_GFM_DEPRECATED\n#endif\n\n#ifndef CMARK_GFM_DEPRECATED_NO_EXPORT\n#  define CMARK_GFM_DEPRECATED_NO_EXPORT CMARK_GFM_NO_EXPORT CMARK_GFM_DEPRECATED\n#endif\n\n/* NOLINTNEXTLINE(readability-avoid-unconditional-preprocessor-if) */\n#if 0 /* DEFINE_NO_DEPRECATED */\n#  ifndef CMARK_GFM_NO_DEPRECATED\n#    define CMARK_GFM_NO_DEPRECATED\n#  endif\n#endif\n\n#endif /* CMARK_GFM_EXPORT_H */\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/cmark-gfm_version.h",
    "content": "#ifndef CMARK_GFM_VERSION_H\n#define CMARK_GFM_VERSION_H\n\n#define CMARK_GFM_VERSION ((0 << 24) | (29 << 16) | (0 << 8) | 13)\n#define CMARK_GFM_VERSION_STRING \"0.29.0.gfm.13\"\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/config.h",
    "content": "#ifndef CMARK_CONFIG_H\n#define CMARK_CONFIG_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define HAVE_STDBOOL_H\n\n#ifdef HAVE_STDBOOL_H\n  #include <stdbool.h>\n#elif !defined(__cplusplus)\n  typedef char bool;\n#endif\n\n#define HAVE___BUILTIN_EXPECT\n\n#define HAVE___ATTRIBUTE__\n\n#ifdef HAVE___ATTRIBUTE__\n  #define CMARK_ATTRIBUTE(list) __attribute__ (list)\n#else\n  #define CMARK_ATTRIBUTE(list)\n#endif\n\n#ifndef CMARK_INLINE\n  #if defined(_MSC_VER) && !defined(__cplusplus)\n    #define CMARK_INLINE __inline\n  #else\n    #define CMARK_INLINE inline\n  #endif\n#endif\n\n/* snprintf and vsnprintf fallbacks for MSVC before 2015,\n   due to Valentin Milea http://stackoverflow.com/questions/2915672/\n*/\n\n#if defined(_MSC_VER) && _MSC_VER < 1900\n\n#include <stdio.h>\n#include <stdarg.h>\n\n#define snprintf c99_snprintf\n#define vsnprintf c99_vsnprintf\n\nCMARK_INLINE int c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap)\n{\n    int count = -1;\n\n    if (size != 0)\n        count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);\n    if (count == -1)\n        count = _vscprintf(format, ap);\n\n    return count;\n}\n\nCMARK_INLINE int c99_snprintf(char *outBuf, size_t size, const char *format, ...)\n{\n    int count;\n    va_list ap;\n\n    va_start(ap, format);\n    count = c99_vsnprintf(outBuf, size, format, ap);\n    va_end(ap);\n\n    return count;\n}\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/extensions/CMakeLists.txt",
    "content": "set(LIBRARY \"libcmark-gfm-extensions\")\nset(STATICLIBRARY \"libcmark-gfm-extensions_static\")\nset(LIBRARY_SOURCES\n    core-extensions.c\n    table.c\n    strikethrough.c\n    autolink.c\n    tagfilter.c\n    ext_scanners.c\n    ext_scanners.re\n    ext_scanners.h\n    tasklist.c\n   )\n\ninclude_directories(\n  ${PROJECT_SOURCE_DIR}/src\n  ${PROJECT_BINARY_DIR}/src\n)\n\ninclude_directories(. ${CMAKE_CURRENT_BINARY_DIR})\n\nset(CMAKE_C_FLAGS_PROFILE \"${CMAKE_C_FLAGS_RELEASE} -pg\")\nset(CMAKE_LINKER_PROFILE \"${CMAKE_LINKER_FLAGS_RELEASE} -pg\")\n\nif (CMARK_SHARED)\n  add_library(${LIBRARY} SHARED ${LIBRARY_SOURCES})\n\n  set_target_properties(${LIBRARY} PROPERTIES\n    OUTPUT_NAME \"cmark-gfm-extensions\"\n    DEFINE_SYMBOL \"cmark-gfm\"\n    SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}.gfm.${PROJECT_VERSION_GFM}\n    VERSION ${PROJECT_VERSION})\n\n  set_property(TARGET ${LIBRARY}\n    APPEND PROPERTY MACOSX_RPATH true)\n\n  # Avoid name clash between PROGRAM and LIBRARY pdb files.\n  set_target_properties(${LIBRARY} PROPERTIES PDB_NAME cmark-gfm-extensions_dll)\n\n  list(APPEND CMARK_INSTALL ${LIBRARY})\n  target_link_libraries(${LIBRARY} libcmark-gfm)\n\nendif()\n\nif (CMARK_STATIC)\n  add_library(${STATICLIBRARY} STATIC ${LIBRARY_SOURCES})\n\n  set_target_properties(${STATICLIBRARY} PROPERTIES\n    COMPILE_FLAGS \"-DCMARK_GFM_STATIC_DEFINE -DCMARK_GFM_EXTENSIONS_STATIC_DEFINE\"\n    DEFINE_SYMBOL \"cmark-gfm\"\n    POSITION_INDEPENDENT_CODE ON)\n\n  if (MSVC)\n    set_target_properties(${STATICLIBRARY} PROPERTIES\n      OUTPUT_NAME \"cmark-gfm-extensions_static\"\n      VERSION ${PROJECT_VERSION})\n  else()\n    set_target_properties(${STATICLIBRARY} PROPERTIES\n      OUTPUT_NAME \"cmark-gfm-extensions\"\n      VERSION ${PROJECT_VERSION})\n  endif(MSVC)\n\n  list(APPEND CMARK_INSTALL ${STATICLIBRARY})\nendif()\n\nset(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS ON)\n\ninclude (InstallRequiredSystemLibraries)\ninstall(TARGETS ${CMARK_INSTALL}\n  EXPORT cmark-gfm-extensions\n  RUNTIME DESTINATION bin\n  LIBRARY DESTINATION lib${LIB_SUFFIX}\n  ARCHIVE DESTINATION lib${LIB_SUFFIX}\n  )\n\nif (CMARK_SHARED OR CMARK_STATIC)\n  install(FILES\n  cmark-gfm-core-extensions.h\n  DESTINATION include\n  )\n\n  install(EXPORT cmark-gfm-extensions DESTINATION lib${LIB_SUFFIX}/cmake-gfm-extensions)\nendif()\n\n# Feature tests\ninclude(CheckIncludeFile)\ninclude(CheckCSourceCompiles)\ninclude(CheckCSourceRuns)\ninclude(CheckSymbolExists)\nCHECK_INCLUDE_FILE(stdbool.h HAVE_STDBOOL_H)\nCHECK_C_SOURCE_COMPILES(\n  \"int main() { __builtin_expect(0,0); return 0; }\"\n  HAVE___BUILTIN_EXPECT)\nCHECK_C_SOURCE_COMPILES(\"\n  int f(void) __attribute__ (());\n  int main() { return 0; }\n\" HAVE___ATTRIBUTE__)\n\n# Always compile with warnings\nif(MSVC)\n  # Force to always compile with W4\n  if(CMAKE_CXX_FLAGS MATCHES \"/W[0-4]\")\n    string(REGEX REPLACE \"/W[0-4]\" \"/W4\" CMAKE_C_FLAGS \"${CMAKE_C_FLAGS}\")\n  else()\n    set(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} /W4\")\n  endif()\n  set(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} /WX /wd4706 /wd4204 /wd4221 /wd4100 /D_CRT_SECURE_NO_WARNINGS\")\nelseif(CMAKE_COMPILER_IS_GNUCC OR \"${CMAKE_CXX_COMPILER_ID}\" STREQUAL \"Clang\")\n  set(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} -Wall -Wextra -Wno-unused-parameter -std=c99 -pedantic\")\nendif()\n\n# Compile as C++ under MSVC older than 12.0\nif(MSVC AND MSVC_VERSION LESS 1800)\n  set(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} /TP\")\nendif()\n\nif(CMAKE_BUILD_TYPE STREQUAL \"Ubsan\")\n  set(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} -fsanitize=undefined\")\nendif()\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/extensions/autolink.c",
    "content": "#include \"autolink.h\"\n#include <parser.h>\n#include <string.h>\n#include <utf8.h>\n#include <stddef.h>\n\n#if defined(_WIN32)\n#define strncasecmp _strnicmp\n#else\n#include <strings.h>\n#endif\n\nstatic int is_valid_hostchar(const uint8_t *link, size_t link_len) {\n  int32_t ch;\n  int r = cmark_utf8proc_iterate(link, (bufsize_t)link_len, &ch);\n  if (r < 0)\n    return 0;\n  return !cmark_utf8proc_is_space(ch) && !cmark_utf8proc_is_punctuation(ch);\n}\n\nstatic int sd_autolink_issafe(const uint8_t *link, size_t link_len) {\n  static const size_t valid_uris_count = 3;\n  static const char *valid_uris[] = {\"http://\", \"https://\", \"ftp://\"};\n\n  size_t i;\n\n  for (i = 0; i < valid_uris_count; ++i) {\n    size_t len = strlen(valid_uris[i]);\n\n    if (link_len > len && strncasecmp((char *)link, valid_uris[i], len) == 0 &&\n        is_valid_hostchar(link + len, link_len - len))\n      return 1;\n  }\n\n  return 0;\n}\n\nstatic size_t autolink_delim(uint8_t *data, size_t link_end) {\n  size_t i;\n  size_t closing = 0;\n  size_t opening = 0;\n\n  for (i = 0; i < link_end; ++i) {\n    const uint8_t c = data[i];\n    if (c == '<') {\n      link_end = i;\n      break;\n    } else if (c == '(') {\n      opening++;\n    } else if (c == ')') {\n      closing++;\n    }\n  }\n\n  while (link_end > 0) {\n    switch (data[link_end - 1]) {\n    case ')':\n      /* Allow any number of matching brackets (as recognised in copen/cclose)\n       * at the end of the URL.  If there is a greater number of closing\n       * brackets than opening ones, we remove one character from the end of\n       * the link.\n       *\n       * Examples (input text => output linked portion):\n       *\n       *        http://www.pokemon.com/Pikachu_(Electric)\n       *                => http://www.pokemon.com/Pikachu_(Electric)\n       *\n       *        http://www.pokemon.com/Pikachu_((Electric)\n       *                => http://www.pokemon.com/Pikachu_((Electric)\n       *\n       *        http://www.pokemon.com/Pikachu_(Electric))\n       *                => http://www.pokemon.com/Pikachu_(Electric)\n       *\n       *        http://www.pokemon.com/Pikachu_((Electric))\n       *                => http://www.pokemon.com/Pikachu_((Electric))\n       */\n      if (closing <= opening) {\n        return link_end;\n      }\n      closing--;\n      link_end--;\n      break;\n    case '?':\n    case '!':\n    case '.':\n    case ',':\n    case ':':\n    case '*':\n    case '_':\n    case '~':\n    case '\\'':\n    case '\"':\n      link_end--;\n      break;\n    case ';': {\n      size_t new_end = link_end - 2;\n\n      while (new_end > 0 && cmark_isalpha(data[new_end]))\n        new_end--;\n\n      if (new_end < link_end - 2 && data[new_end] == '&')\n        link_end = new_end;\n      else\n        link_end--;\n      break;\n    }\n\n    default:\n      return link_end;\n    }\n  }\n\n  return link_end;\n}\n\nstatic size_t check_domain(uint8_t *data, size_t size, int allow_short) {\n  size_t i, np = 0, uscore1 = 0, uscore2 = 0;\n\n  /* The purpose of this code is to reject urls that contain an underscore\n   * in one of the last two segments. Examples:\n   *\n   *   www.xxx.yyy.zzz     autolinked\n   *   www.xxx.yyy._zzz    not autolinked\n   *   www.xxx._yyy.zzz    not autolinked\n   *   www._xxx.yyy.zzz    autolinked\n   *\n   * The reason is that domain names are allowed to include underscores,\n   * but host names are not. See: https://stackoverflow.com/a/2183140\n   */\n  for (i = 1; i < size - 1; i++) {\n    if (data[i] == '\\\\' && i < size - 2)\n      i++;\n    if (data[i] == '_')\n      uscore2++;\n    else if (data[i] == '.') {\n      uscore1 = uscore2;\n      uscore2 = 0;\n      np++;\n    } else if (!is_valid_hostchar(data + i, size - i) && data[i] != '-')\n      break;\n  }\n\n  if (uscore1 > 0 || uscore2 > 0) {\n    /* If the url is very long then accept it despite the underscores,\n     * to avoid quadratic behavior causing a denial of service. See:\n     * https://github.com/github/cmark-gfm/security/advisories/GHSA-29g3-96g3-jg6c\n     * Reasonable urls are unlikely to have more than 10 segments, so\n     * this extra condition shouldn't have any impact on normal usage.\n     */\n    if (np <= 10) {\n      return 0;\n    }\n  }\n\n  if (allow_short) {\n    /* We don't need a valid domain in the strict sense (with\n     * least one dot; so just make sure it's composed of valid\n     * domain characters and return the length of the the valid\n     * sequence. */\n    return i;\n  } else {\n    /* a valid domain needs to have at least a dot.\n     * that's as far as we get */\n    return np ? i : 0;\n  }\n}\n\nstatic cmark_node *www_match(cmark_parser *parser, cmark_node *parent,\n                             cmark_inline_parser *inline_parser) {\n  cmark_chunk *chunk = cmark_inline_parser_get_chunk(inline_parser);\n  size_t max_rewind = cmark_inline_parser_get_offset(inline_parser);\n  uint8_t *data = chunk->data + max_rewind;\n  size_t size = chunk->len - max_rewind;\n  int start = cmark_inline_parser_get_column(inline_parser);\n\n  size_t link_end;\n\n  if (max_rewind > 0 && strchr(\"*_~(\", data[-1]) == NULL &&\n      !cmark_isspace(data[-1]))\n    return 0;\n\n  if (size < 4 || memcmp(data, \"www.\", strlen(\"www.\")) != 0)\n    return 0;\n\n  link_end = check_domain(data, size, 0);\n\n  if (link_end == 0)\n    return NULL;\n\n  while (link_end < size && !cmark_isspace(data[link_end]) && data[link_end] != '<')\n    link_end++;\n\n  link_end = autolink_delim(data, link_end);\n\n  if (link_end == 0)\n    return NULL;\n\n  cmark_inline_parser_set_offset(inline_parser, (int)(max_rewind + link_end));\n\n  cmark_node *node = cmark_node_new_with_mem(CMARK_NODE_LINK, parser->mem);\n\n  cmark_strbuf buf;\n  cmark_strbuf_init(parser->mem, &buf, 10);\n  cmark_strbuf_puts(&buf, \"http://\");\n  cmark_strbuf_put(&buf, data, (bufsize_t)link_end);\n  node->as.link.url = cmark_chunk_buf_detach(&buf);\n\n  cmark_node *text = cmark_node_new_with_mem(CMARK_NODE_TEXT, parser->mem);\n  text->as.literal =\n      cmark_chunk_dup(chunk, (bufsize_t)max_rewind, (bufsize_t)link_end);\n  cmark_node_append_child(node, text);\n\n  node->start_line = text->start_line =\n    node->end_line = text->end_line =\n    cmark_inline_parser_get_line(inline_parser);\n\n  node->start_column = text->start_column = start - 1;\n  node->end_column = text->end_column = cmark_inline_parser_get_column(inline_parser) - 1;\n\n  return node;\n}\n\nstatic cmark_node *url_match(cmark_parser *parser, cmark_node *parent,\n                             cmark_inline_parser *inline_parser) {\n  size_t link_end, domain_len;\n  int rewind = 0;\n\n  cmark_chunk *chunk = cmark_inline_parser_get_chunk(inline_parser);\n  int max_rewind = cmark_inline_parser_get_offset(inline_parser);\n  uint8_t *data = chunk->data + max_rewind;\n  size_t size = chunk->len - max_rewind;\n\n  if (size < 4 || data[1] != '/' || data[2] != '/')\n    return 0;\n\n  while (rewind < max_rewind && cmark_isalpha(data[-rewind - 1]))\n    rewind++;\n\n  if (!sd_autolink_issafe(data - rewind, size + rewind))\n    return 0;\n\n  link_end = strlen(\"://\");\n\n  domain_len = check_domain(data + link_end, size - link_end, 1);\n\n  if (domain_len == 0)\n    return 0;\n\n  link_end += domain_len;\n  while (link_end < size && !cmark_isspace(data[link_end]) && data[link_end] != '<')\n    link_end++;\n\n  link_end = autolink_delim(data, link_end);\n\n  if (link_end == 0)\n    return NULL;\n\n  cmark_inline_parser_set_offset(inline_parser, (int)(max_rewind + link_end));\n  cmark_node_unput(parent, rewind);\n\n  cmark_node *node = cmark_node_new_with_mem(CMARK_NODE_LINK, parser->mem);\n\n  cmark_chunk url = cmark_chunk_dup(chunk, max_rewind - rewind,\n                                    (bufsize_t)(link_end + rewind));\n  node->as.link.url = url;\n\n  cmark_node *text = cmark_node_new_with_mem(CMARK_NODE_TEXT, parser->mem);\n  text->as.literal = url;\n  cmark_node_append_child(node, text);\n  \n  node->start_line = text->start_line = node->end_line = text->end_line = cmark_inline_parser_get_line(inline_parser);\n\n  node->start_column = text->start_column = max_rewind - rewind;\n  node->end_column = text->end_column = cmark_inline_parser_get_column(inline_parser) - 1;\n\n  return node;\n}\n\nstatic cmark_node *match(cmark_syntax_extension *ext, cmark_parser *parser,\n                         cmark_node *parent, unsigned char c,\n                         cmark_inline_parser *inline_parser) {\n  if (cmark_inline_parser_in_bracket(inline_parser, false) ||\n      cmark_inline_parser_in_bracket(inline_parser, true))\n    return NULL;\n\n  if (c == ':')\n    return url_match(parser, parent, inline_parser);\n\n  if (c == 'w')\n    return www_match(parser, parent, inline_parser);\n\n  return NULL;\n\n  // note that we could end up re-consuming something already a\n  // part of an inline, because we don't track when the last\n  // inline was finished in inlines.c.\n}\n\nstatic bool validate_protocol(const char protocol[], uint8_t *data, size_t rewind, size_t max_rewind) {\n  size_t len = strlen(protocol);\n\n  if (len > (max_rewind - rewind)) {\n    return false;\n  }\n\n  // Check that the protocol matches\n  if (memcmp(data - rewind - len, protocol, len) != 0) {\n    return false;\n  }\n\n  if (len == (max_rewind - rewind)) {\n    return true;\n  }\n\n  char prev_char = data[-((ptrdiff_t)rewind) - len - 1];\n\n  // Make sure the character before the protocol is non-alphanumeric\n  return !cmark_isalnum(prev_char);\n}\n\nstatic void postprocess_text(cmark_parser *parser, cmark_node *text) {\n  size_t start = 0;\n  size_t offset = 0;\n  // `text` is going to be split into a list of nodes containing shorter segments\n  // of text, so we detach the memory buffer from text and use `cmark_chunk_dup` to\n  // create references to it. Later, `cmark_chunk_to_cstr` is used to convert\n  // the references into allocated buffers. The detached buffer is freed before we\n  // return.\n  cmark_chunk detached_chunk = text->as.literal;\n  text->as.literal = cmark_chunk_dup(&detached_chunk, 0, detached_chunk.len);\n\n  uint8_t *data = text->as.literal.data;\n  size_t remaining = text->as.literal.len;\n\n  while (true) {\n    size_t link_end;\n    uint8_t *at;\n    bool auto_mailto = true;\n    bool is_xmpp = false;\n    size_t rewind;\n    size_t max_rewind;\n    size_t np = 0;\n\n    if (offset >= remaining)\n      break;\n\n    at = (uint8_t *)memchr(data + start + offset, '@', remaining - offset);\n    if (!at)\n      break;\n\n    max_rewind = at - (data + start + offset);\n\nfound_at:\n    for (rewind = 0; rewind < max_rewind; ++rewind) {\n      uint8_t c = data[start + offset + max_rewind - rewind - 1];\n\n      if (cmark_isalnum(c))\n        continue;\n\n      if (strchr(\".+-_\", c) != NULL)\n        continue;\n\n      if (strchr(\":\", c) != NULL) {\n        if (validate_protocol(\"mailto:\", data + start + offset + max_rewind, rewind, max_rewind)) {\n          auto_mailto = false;\n          continue;\n        }\n\n        if (validate_protocol(\"xmpp:\", data + start + offset + max_rewind, rewind, max_rewind)) {\n          auto_mailto = false;\n          is_xmpp = true;\n          continue;\n        }\n      }\n\n      break;\n    }\n\n    if (rewind == 0) {\n      offset += max_rewind + 1;\n      continue;\n    }\n\n    assert(data[start + offset + max_rewind] == '@');\n    for (link_end = 1; link_end < remaining - offset - max_rewind; ++link_end) {\n      uint8_t c = data[start + offset + max_rewind + link_end];\n\n      if (cmark_isalnum(c))\n        continue;\n\n      if (c == '@') {\n        // Found another '@', so go back and try again with an updated offset and max_rewind.\n        offset += max_rewind + 1;\n        max_rewind = link_end - 1;\n        goto found_at;\n      } else if (c == '.' && link_end < remaining - offset - max_rewind - 1 &&\n               cmark_isalnum(data[start + offset + max_rewind + link_end + 1]))\n        np++;\n      else if (c == '/' && is_xmpp)\n        continue;\n      else if (c != '-' && c != '_')\n        break;\n    }\n\n    if (link_end < 2 || np == 0 ||\n        (!cmark_isalpha(data[start + offset + max_rewind + link_end - 1]) &&\n         data[start + offset + max_rewind + link_end - 1] != '.')) {\n      offset += max_rewind + link_end;\n      continue;\n    }\n\n    link_end = autolink_delim(data + start + offset + max_rewind, link_end);\n\n    if (link_end == 0) {\n      offset += max_rewind + 1;\n      continue;\n    }\n\n    cmark_node *link_node = cmark_node_new_with_mem(CMARK_NODE_LINK, parser->mem);\n    cmark_strbuf buf;\n    cmark_strbuf_init(parser->mem, &buf, 10);\n    if (auto_mailto)\n      cmark_strbuf_puts(&buf, \"mailto:\");\n    cmark_strbuf_put(&buf, data + start + offset + max_rewind - rewind, (bufsize_t)(link_end + rewind));\n    link_node->as.link.url = cmark_chunk_buf_detach(&buf);\n\n    cmark_node *link_text = cmark_node_new_with_mem(CMARK_NODE_TEXT, parser->mem);\n    cmark_chunk email = cmark_chunk_dup(\n      &detached_chunk,\n      (bufsize_t)(start + offset + max_rewind - rewind),\n      (bufsize_t)(link_end + rewind));\n    cmark_chunk_to_cstr(parser->mem, &email);\n    link_text->as.literal = email;\n    cmark_node_append_child(link_node, link_text);\n\n    cmark_node_insert_after(text, link_node);\n\n    cmark_node *post = cmark_node_new_with_mem(CMARK_NODE_TEXT, parser->mem);\n    post->as.literal = cmark_chunk_dup(&detached_chunk,\n                                       (bufsize_t)(start + offset + max_rewind + link_end),\n                                       (bufsize_t)(remaining - offset - max_rewind - link_end));\n\n    cmark_node_insert_after(link_node, post);\n\n    text->as.literal = cmark_chunk_dup(&detached_chunk, (bufsize_t)start, (bufsize_t)(offset + max_rewind - rewind));\n    cmark_chunk_to_cstr(parser->mem, &text->as.literal);\n\n    text = post;\n    start += offset + max_rewind + link_end;\n    remaining -= offset + max_rewind + link_end;\n    offset = 0;\n  }\n\n  // Convert the reference to allocated memory.\n  assert(!text->as.literal.alloc);\n  cmark_chunk_to_cstr(parser->mem, &text->as.literal);\n\n  // Free the detached buffer.\n  cmark_chunk_free(parser->mem, &detached_chunk);\n}\n\nstatic cmark_node *postprocess(cmark_syntax_extension *ext, cmark_parser *parser, cmark_node *root) {\n  cmark_iter *iter;\n  cmark_event_type ev;\n  cmark_node *node;\n  bool in_link = false;\n\n  cmark_consolidate_text_nodes(root);\n  iter = cmark_iter_new(root);\n\n  while ((ev = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {\n    node = cmark_iter_get_node(iter);\n    if (in_link) {\n      if (ev == CMARK_EVENT_EXIT && node->type == CMARK_NODE_LINK) {\n        in_link = false;\n      }\n      continue;\n    }\n\n    if (ev == CMARK_EVENT_ENTER && node->type == CMARK_NODE_LINK) {\n      in_link = true;\n      continue;\n    }\n\n    if (ev == CMARK_EVENT_ENTER && node->type == CMARK_NODE_TEXT) {\n      postprocess_text(parser, node);\n    }\n  }\n\n  cmark_iter_free(iter);\n\n  return root;\n}\n\ncmark_syntax_extension *create_autolink_extension(void) {\n  cmark_syntax_extension *ext = cmark_syntax_extension_new(\"autolink\");\n  cmark_llist *special_chars = NULL;\n\n  cmark_syntax_extension_set_match_inline_func(ext, match);\n  cmark_syntax_extension_set_postprocess_func(ext, postprocess);\n\n  cmark_mem *mem = cmark_get_default_mem_allocator();\n  special_chars = cmark_llist_append(mem, special_chars, (void *)':');\n  special_chars = cmark_llist_append(mem, special_chars, (void *)'w');\n  cmark_syntax_extension_set_special_inline_chars(ext, special_chars);\n\n  return ext;\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/extensions/autolink.h",
    "content": "#ifndef CMARK_GFM_AUTOLINK_H\n#define CMARK_GFM_AUTOLINK_H\n\n#include \"cmark-gfm-core-extensions.h\"\n\nCMARK_GFM_NO_EXPORT\ncmark_syntax_extension *create_autolink_extension(void);\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/extensions/cmark-gfm-core-extensions.h",
    "content": "#ifndef CMARK_GFM_CORE_EXTENSIONS_H\n#define CMARK_GFM_CORE_EXTENSIONS_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"cmark-gfm-extension_api.h\"\n#include \"cmark-gfm_export.h\"\n#include <stdbool.h>\n#include <stdint.h>\n\nCMARK_GFM_EXPORT\nvoid cmark_gfm_core_extensions_ensure_registered(void);\n\nCMARK_GFM_EXPORT\nuint16_t cmark_gfm_extensions_get_table_columns(cmark_node *node);\n\n/** Sets the number of columns for the table, returning 1 on success and 0 on error.\n */\nCMARK_GFM_EXPORT\nint cmark_gfm_extensions_set_table_columns(cmark_node *node, uint16_t n_columns);\n\nCMARK_GFM_EXPORT\nuint8_t *cmark_gfm_extensions_get_table_alignments(cmark_node *node);\n\n/** Sets the alignments for the table, returning 1 on success and 0 on error.\n */\nCMARK_GFM_EXPORT\nint cmark_gfm_extensions_set_table_alignments(cmark_node *node, uint16_t ncols, uint8_t *alignments);\n\nCMARK_GFM_EXPORT\nint cmark_gfm_extensions_get_table_row_is_header(cmark_node *node);\n\n/** Sets whether the node is a table header row, returning 1 on success and 0 on error.\n */\nCMARK_GFM_EXPORT\nint cmark_gfm_extensions_set_table_row_is_header(cmark_node *node, int is_header);\n\nCMARK_GFM_EXPORT\nuint8_t cmark_gfm_extensions_get_table_cell_alignment(cmark_node *node);\n\nCMARK_GFM_EXPORT\nbool cmark_gfm_extensions_get_tasklist_item_checked(cmark_node *node);\n/* For backwards compatibility */\n#define cmark_gfm_extensions_tasklist_is_checked cmark_gfm_extensions_get_tasklist_item_checked\n\n/** Sets whether a tasklist item is \"checked\" (completed), returning 1 on success and 0 on error.\n */\nCMARK_GFM_EXPORT\nint cmark_gfm_extensions_set_tasklist_item_checked(cmark_node *node, bool is_checked);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/extensions/core-extensions.c",
    "content": "#include \"cmark-gfm-core-extensions.h\"\n#include \"autolink.h\"\n#include \"strikethrough.h\"\n#include \"table.h\"\n#include \"tagfilter.h\"\n#include \"tasklist.h\"\n#include \"math_mark.h\"\n#include \"registry.h\"\n#include \"plugin.h\"\n#include \"emoji.h\"\n\nstatic int core_extensions_registration(cmark_plugin *plugin) {\n    cmark_plugin_register_syntax_extension(plugin, create_table_extension());\n    cmark_plugin_register_syntax_extension(plugin, create_strikethrough_extension());\n    cmark_plugin_register_syntax_extension(plugin, create_autolink_extension());\n    cmark_plugin_register_syntax_extension(plugin, create_tagfilter_extension());\n    cmark_plugin_register_syntax_extension(plugin, create_tasklist_extension());\n    cmark_plugin_register_syntax_extension(plugin, create_math_extension());\n    cmark_plugin_register_syntax_extension(plugin, create_emoji_extension());\n    return 1;\n}\n\nvoid cmark_gfm_core_extensions_ensure_registered(void) {\n  static int registered = 0;\n\n  if (!registered) {\n    cmark_register_plugin(core_extensions_registration);\n    registered = 1;\n  }\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/extensions/emoji.c",
    "content": "//\n//  emoji.c\n//  AntMarkdown\n//\n//  Created by ToccaLee on 2025/3/25.\n//  Copyright © 2025 Alipay. All rights reserved.\n//\n\n#include \"emoji.h\"\n#include <parser.h>\n#include <render.h>\n#include <html.h>\n#include \"inlines.h\"\n#include \"ext_scanners.h\"\n\ncmark_node_type CMARK_NODE_EMOJI;\n\nstatic cmark_node *match(cmark_syntax_extension *self, cmark_parser *parser,\n                         cmark_node *parent, unsigned char character,\n                         cmark_inline_parser *inline_parser) {\n    cmark_node *res = NULL;\n    \n    if (character != ':')\n        return NULL;\n    \n    int pos = cmark_inline_parser_get_offset(inline_parser);\n    cmark_chunk *chunk = cmark_inline_parser_get_chunk(inline_parser);\n    unsigned char *input = chunk->data + pos;\n    int len = chunk->len - pos;\n    if (len <= 2) {\n        return NULL;\n    }\n    bufsize_t matched = 0;\n    if ((matched = scan_emoji(chunk->data, chunk->len, pos))) {\n        cmark_node *node = cmark_node_new_with_mem_and_ext(CMARK_NODE_EMOJI, parser->mem, self);\n        \n        node->start_line = node->end_line = cmark_inline_parser_get_line(inline_parser);\n        node->start_column = cmark_inline_parser_get_column(inline_parser);\n        node->end_column = node->start_column + matched;\n        \n        cmark_strbuf_init(parser->mem, &node->content, matched);\n        cmark_strbuf_put(&node->content, input, matched);\n        \n        {\n            int nls = 0;\n            int since_nl = 0;\n            int len = matched;\n            int from = pos;\n            \n            while (len--) {\n                if (chunk->data[from++] == '\\n') {\n                    ++nls;\n                    since_nl = 0;\n                } else {\n                    ++since_nl;\n                }\n            }\n            node->end_line = node->start_line + nls;\n            node->end_column = since_nl;\n        }\n        \n        cmark_strbuf buf;\n        cmark_strbuf_init(parser->mem, &buf, matched);\n        cmark_strbuf_put(&buf, input + 2, matched - 4);\n        \n        node->as.code.fenced = true;\n        node->as.code.fence_char = ':';\n        node->as.code.fence_length = (matched > 255) ? 255 : matched;\n        node->as.code.fence_offset = parser->first_nonspace - parser->offset;\n        node->as.code.info = cmark_chunk_literal(\"emoji\");\n        node->as.code.literal = cmark_chunk_buf_detach(&buf);\n        \n        cmark_inline_parser_set_offset(inline_parser, pos + matched);\n        cmark_parser_advance_offset(parser, (char *)input,\n                                    parser->first_nonspace + matched - parser->offset,\n                                    false);\n        res = node;\n    }\n    return res;\n}\n\nstatic const char *get_type_string(cmark_syntax_extension *extension,\n                                   cmark_node *node) {\n    if (node->type == CMARK_NODE_EMOJI) {\n        return \"emoji\";\n    } else {\n        return \"<unknown>\";\n    }\n}\n\nstatic int can_contain(cmark_syntax_extension *extension, cmark_node *node,\n                       cmark_node_type child_type) {\n    return false;\n}\n\nstatic void commonmark_render(cmark_syntax_extension *extension,\n                              cmark_renderer *renderer, cmark_node *node,\n                              cmark_event_type ev_type, int options) {\n    renderer->out(renderer, node, \":\", false, LITERAL);\n}\n\nstatic void latex_render(cmark_syntax_extension *extension,\n                         cmark_renderer *renderer, cmark_node *node,\n                         cmark_event_type ev_type, int options) {\n    // requires \\usepackage{ulem}\n    bool entering = (ev_type == CMARK_EVENT_ENTER);\n    if (entering) {\n        renderer->out(renderer, node, \"\", false, LITERAL);\n    } else {\n        renderer->out(renderer, node, \"\", false, LITERAL);\n    }\n}\n\nstatic void html_render(cmark_syntax_extension *extension,\n                        cmark_html_renderer *renderer, cmark_node *node,\n                        cmark_event_type ev_type, int options) {\n    bool entering = (ev_type == CMARK_EVENT_ENTER);\n    if (entering) {\n        cmark_strbuf_puts(renderer->html, \"<emoji\");\n        cmark_html_render_sourcepos(node, renderer->html, options);\n        cmark_strbuf_putc(renderer->html, '>');\n    } else {\n        cmark_strbuf_puts(renderer->html, \"</emoji>\");\n    }\n}\n\ncmark_syntax_extension *create_emoji_extension(void) {\n    cmark_syntax_extension *ext = cmark_syntax_extension_new(\"emoji\");\n    cmark_llist *special_chars = NULL;\n    cmark_syntax_extension_set_get_type_string_func(ext, get_type_string);\n    cmark_syntax_extension_set_can_contain_func(ext, can_contain);\n    cmark_syntax_extension_set_commonmark_render_func(ext, commonmark_render);\n    cmark_syntax_extension_set_latex_render_func(ext, latex_render);\n    cmark_syntax_extension_set_html_render_func(ext, html_render);\n    cmark_syntax_extension_set_plaintext_render_func(ext, commonmark_render);\n    \n    CMARK_NODE_EMOJI = cmark_syntax_extension_add_node(0);\n    \n    cmark_syntax_extension_set_match_inline_func(ext, match);\n    \n    cmark_mem *mem = cmark_get_default_mem_allocator();\n    special_chars = cmark_llist_append(mem, special_chars, (void *)':');\n    cmark_syntax_extension_set_special_inline_chars(ext, special_chars);\n    \n    cmark_syntax_extension_set_emphasis(ext, 0);\n    \n    return ext;\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/extensions/emoji.h",
    "content": "//\n//  emoji.h\n//  AntMarkdown\n//\n//  Created by ToccaLee on 2025/3/25.\n//  Copyright © 2025 Alipay. All rights reserved.\n//\n\n#ifndef cmark_emoji_h\n#define cmark_emoji_h\n\n#include \"cmark-gfm-core-extensions.h\"\n\nextern cmark_node_type CMARK_NODE_EMOJI;\n\nCMARK_GFM_NO_EXPORT\ncmark_syntax_extension *create_emoji_extension(void);\n\n#endif /* emoji_h */\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/extensions/ext_scanners.c",
    "content": "/* Generated by re2c 4.1 on Thu Apr  3 11:15:42 2025 */\n#line 1 \"ext_scanners.re\"\n\n#line 2 \"ext_scanners.re\"\n\n\n#include <stdlib.h>\n#include \"ext_scanners.h\"\n\nbufsize_t _ext_scan_at(bufsize_t (*scanner)(const unsigned char *), unsigned char *ptr, int len, bufsize_t offset)\n{\n\tbufsize_t res;\n\n        if (ptr == NULL || offset >= len) {\n          return 0;\n        } else {\n\t  unsigned char lim = ptr[len];\n\n\t  ptr[len] = '\\0';\n\t  res = scanner(ptr + offset);\n\t  ptr[len] = lim;\n        }\n\n\treturn res;\n}\n\n#line 49 \"ext_scanners.re\"\n\n\nbufsize_t _scan_table_start(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n  \n#line 36 \"ext_scanners.c\"\n{\n  unsigned char yych;\n  static const unsigned char yybm[256] = {\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,  64,   0,  64,  64,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n     64,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0, 128,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0\n  };\n  yych = *p;\n  {\n    static const void* yytarget[256] = {\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy3, &&yy1, &&yy3, &&yy3, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy3, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy4, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy5, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy3, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1,\n      &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1, &&yy1\n    };\n    goto *yytarget[yych];\n  }\nyy1:\n  ++p;\nyy2:\n#line 59 \"ext_scanners.re\"\n  { return 0; }\n#line 116 \"ext_scanners.c\"\nyy3:\n  yych = *(marker = ++p);\n  if (yybm[0+yych] & 64) goto yy6;\n  if (yych == '-') goto yy8;\n  if (yych == ':') goto yy9;\n  goto yy2;\nyy4:\n  yych = *(marker = ++p);\n  {\n    static const void* yytarget[256] = {\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2, &&yy11, &&yy11, &&yy11, &&yy11, &&yy11,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n      &&yy11,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy8,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2, &&yy10,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2, &&yy11,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,\n       &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2,  &&yy2\n    };\n    goto *yytarget[yych];\n  }\nyy5:\n  yych = *(marker = ++p);\n  if (yybm[0+yych] & 128) goto yy8;\n  goto yy2;\nyy6:\n  yych = *++p;\n  if (yybm[0+yych] & 64) goto yy6;\n  if (yych == '-') goto yy8;\n  if (yych == ':') goto yy9;\nyy7:\n  p = marker;\n  goto yy2;\nyy8:\n  yych = *++p;\n  {\n    static const void* yytarget[256] = {\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7, &&yy10, &&yy12, &&yy10, &&yy10, &&yy13,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n      &&yy10,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy8,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7, &&yy10,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7, &&yy14,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7\n    };\n    goto *yytarget[yych];\n  }\nyy9:\n  yych = *++p;\n  if (yybm[0+yych] & 128) goto yy8;\n  goto yy7;\nyy10:\n  yych = *++p;\nyy11:\n  {\n    static const void* yytarget[256] = {\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7, &&yy10, &&yy12, &&yy10, &&yy10, &&yy13,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n      &&yy10,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7, &&yy14,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7\n    };\n    goto *yytarget[yych];\n  }\nyy12:\n  ++p;\n#line 56 \"ext_scanners.re\"\n  {\n      return (bufsize_t)(p - start);\n    }\n#line 263 \"ext_scanners.c\"\nyy13:\n  yych = *++p;\n  if (yych == '\\n') goto yy12;\n  goto yy7;\nyy14:\n  yych = *++p;\n  {\n    static const void* yytarget[256] = {\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7, &&yy14, &&yy12, &&yy14, &&yy14, &&yy13,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n      &&yy14,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy8,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy9,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,\n       &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7,  &&yy7\n    };\n    goto *yytarget[yych];\n  }\n}\n#line 60 \"ext_scanners.re\"\n\n}\n\nbufsize_t _scan_table_cell(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n  \n#line 317 \"ext_scanners.c\"\n{\n  unsigned char yych;\n  static const unsigned char yybm[256] = {\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,   0,  64,  64,   0,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64, 128,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,   0,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64\n  };\n  yych = *p;\n  if (yybm[0+yych] & 64) goto yy16;\n  if (yych <= '\\r') goto yy18;\n  if (yych <= '\\\\') goto yy19;\n  goto yy18;\nyy16:\n  yych = *++p;\n  if (yybm[0+yych] & 64) goto yy16;\n  if (yych <= '\\r') goto yy17;\n  if (yych <= '\\\\') goto yy19;\nyy17:\n#line 71 \"ext_scanners.re\"\n  { return (bufsize_t)(p - start); }\n#line 367 \"ext_scanners.c\"\nyy18:\n  ++p;\n#line 72 \"ext_scanners.re\"\n  { return 0; }\n#line 372 \"ext_scanners.c\"\nyy19:\n  yych = *++p;\n  if (yybm[0+yych] & 128) goto yy19;\n  if (yych == '\\n') goto yy17;\n  if (yych == '\\r') goto yy17;\n  goto yy16;\n}\n#line 73 \"ext_scanners.re\"\n\n}\n\nbufsize_t _scan_table_cell_end(const unsigned char *p)\n{\n  const unsigned char *start = p;\n  \n#line 388 \"ext_scanners.c\"\n{\n  unsigned char yych;\n  static const unsigned char yybm[256] = {\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0, 128,   0, 128, 128,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n    128,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0\n  };\n  yych = *p;\n  if (yych == '|') goto yy21;\n  ++p;\n#line 81 \"ext_scanners.re\"\n  { return 0; }\n#line 430 \"ext_scanners.c\"\nyy21:\n  yych = *++p;\n  if (yybm[0+yych] & 128) goto yy21;\n#line 80 \"ext_scanners.re\"\n  { return (bufsize_t)(p - start); }\n#line 436 \"ext_scanners.c\"\n}\n#line 82 \"ext_scanners.re\"\n\n}\n\nbufsize_t _scan_table_row_end(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n  \n#line 447 \"ext_scanners.c\"\n{\n  unsigned char yych;\n  static const unsigned char yybm[256] = {\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0, 128,   0, 128, 128,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n    128,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0\n  };\n  yych = *p;\n  if (yych <= '\\f') {\n    if (yych <= 0x08) goto yy23;\n    if (yych == '\\n') goto yy26;\n    goto yy25;\n  } else {\n    if (yych <= '\\r') goto yy27;\n    if (yych == ' ') goto yy25;\n  }\nyy23:\n  ++p;\nyy24:\n#line 91 \"ext_scanners.re\"\n  { return 0; }\n#line 498 \"ext_scanners.c\"\nyy25:\n  yych = *(marker = ++p);\n  if (yych <= 0x08) goto yy24;\n  if (yych <= '\\r') goto yy29;\n  if (yych == ' ') goto yy29;\n  goto yy24;\nyy26:\n  ++p;\n#line 90 \"ext_scanners.re\"\n  { return (bufsize_t)(p - start); }\n#line 509 \"ext_scanners.c\"\nyy27:\n  yych = *++p;\n  if (yych == '\\n') goto yy26;\n  goto yy24;\nyy28:\n  yych = *++p;\nyy29:\n  if (yybm[0+yych] & 128) goto yy28;\n  if (yych <= 0x08) goto yy30;\n  if (yych <= '\\n') goto yy26;\n  if (yych <= '\\r') goto yy31;\nyy30:\n  p = marker;\n  goto yy24;\nyy31:\n  yych = *++p;\n  if (yych == '\\n') goto yy26;\n  goto yy30;\n}\n#line 92 \"ext_scanners.re\"\n\n}\n\nbufsize_t _scan_tasklist(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n  \n#line 538 \"ext_scanners.c\"\n{\n  unsigned char yych;\n  static const unsigned char yybm[256] = {\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,  64,   0,  64,  64,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n     64,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n    128, 128, 128, 128, 128, 128, 128, 128,\n    128, 128,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0\n  };\n  yych = *p;\n  {\n    static const void* yytarget[256] = {\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy35, &&yy33, &&yy35, &&yy35, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy35, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy36, &&yy36, &&yy33, &&yy36, &&yy33, &&yy33,\n      &&yy37, &&yy37, &&yy37, &&yy37, &&yy37, &&yy37, &&yy37, &&yy37,\n      &&yy37, &&yy37, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33,\n      &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33, &&yy33\n    };\n    goto *yytarget[yych];\n  }\nyy33:\n  ++p;\nyy34:\n#line 101 \"ext_scanners.re\"\n  { return 0; }\n#line 618 \"ext_scanners.c\"\nyy35:\n  yych = *(marker = ++p);\n  {\n    static const void* yytarget[256] = {\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy38, &&yy34, &&yy38, &&yy38, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy38, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy40, &&yy40, &&yy34, &&yy40, &&yy34, &&yy34,\n      &&yy41, &&yy41, &&yy41, &&yy41, &&yy41, &&yy41, &&yy41, &&yy41,\n      &&yy41, &&yy41, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34,\n      &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34, &&yy34\n    };\n    goto *yytarget[yych];\n  }\nyy36:\n  yych = *(marker = ++p);\n  if (yych <= '\\n') {\n    if (yych == '\\t') goto yy42;\n    goto yy34;\n  } else {\n    if (yych <= '\\f') goto yy42;\n    if (yych == ' ') goto yy42;\n    goto yy34;\n  }\nyy37:\n  yych = *(marker = ++p);\n  if (yybm[0+yych] & 128) goto yy44;\n  if (yych == '\\n') goto yy34;\n  goto yy40;\nyy38:\n  yych = *++p;\n  {\n    static const void* yytarget[256] = {\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy38, &&yy39, &&yy38, &&yy38, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy38, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy40, &&yy40, &&yy39, &&yy40, &&yy39, &&yy39,\n      &&yy41, &&yy41, &&yy41, &&yy41, &&yy41, &&yy41, &&yy41, &&yy41,\n      &&yy41, &&yy41, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39\n    };\n    goto *yytarget[yych];\n  }\nyy39:\n  p = marker;\n  goto yy34;\nyy40:\n  yych = *++p;\n  if (yych == '[') goto yy39;\n  goto yy43;\nyy41:\n  yych = *++p;\n  if (yybm[0+yych] & 128) goto yy44;\n  if (yych == '\\n') goto yy39;\n  goto yy40;\nyy42:\n  yych = *++p;\nyy43:\n  {\n    static const void* yytarget[256] = {\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy42, &&yy39, &&yy42, &&yy42, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy42, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy45, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39,\n      &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39, &&yy39\n    };\n    goto *yytarget[yych];\n  }\nyy44:\n  yych = *++p;\n  if (yybm[0+yych] & 128) goto yy44;\n  if (yych <= '\\n') {\n    if (yych <= 0x08) goto yy40;\n    if (yych <= '\\t') goto yy42;\n    goto yy39;\n  } else {\n    if (yych <= '\\f') goto yy42;\n    if (yych == ' ') goto yy42;\n    goto yy40;\n  }\nyy45:\n  yych = *++p;\n  if (yych == ' ') goto yy46;\n  if (yych != 'x') goto yy39;\nyy46:\n  yych = *++p;\n  if (yych != ']') goto yy39;\n  yych = *++p;\n  if (yych <= '\\n') {\n    if (yych != '\\t') goto yy39;\n  } else {\n    if (yych <= '\\f') goto yy47;\n    if (yych != ' ') goto yy39;\n  }\nyy47:\n  yych = *++p;\n  if (yych <= '\\n') {\n    if (yych == '\\t') goto yy47;\n  } else {\n    if (yych <= '\\f') goto yy47;\n    if (yych == ' ') goto yy47;\n  }\n#line 100 \"ext_scanners.re\"\n  { return (bufsize_t)(p - start); }\n#line 800 \"ext_scanners.c\"\n}\n#line 102 \"ext_scanners.re\"\n\n}\n\nbufsize_t _scan_math_inline(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n  \n#line 811 \"ext_scanners.c\"\n{\n  unsigned char yych;\n  unsigned int yyaccept = 0;\n  static const unsigned char yybm[256] = {\n      0,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,   0,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64, 128,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64\n  };\n  yych = *p;\n  if (yych == '$') goto yy50;\n  if (yych == '\\\\') goto yy51;\n  ++p;\nyy49:\n#line 111 \"ext_scanners.re\"\n  { return 0; }\n#line 856 \"ext_scanners.c\"\nyy50:\n  yyaccept = 0;\n  yych = *(marker = ++p);\n  if (yych <= 0x00) goto yy49;\n  if (yych == '$') goto yy49;\n  goto yy53;\nyy51:\n  yyaccept = 0;\n  yych = *(marker = ++p);\n  if (yych == '(') goto yy56;\n  goto yy49;\nyy52:\n  yych = *++p;\nyy53:\n  if (yybm[0+yych] & 64) goto yy52;\n  if (yych <= 0x00) goto yy54;\n  if (yych <= '$') goto yy57;\n  goto yy55;\nyy54:\n  p = marker;\n  if (yyaccept == 0) goto yy49;\n  else goto yy58;\nyy55:\n  yych = *++p;\n  if (yybm[0+yych] & 64) goto yy52;\n  if (yych <= 0x00) goto yy54;\n  if (yych <= '$') goto yy59;\n  goto yy55;\nyy56:\n  yych = *++p;\n  if (yych == '\\\\') goto yy62;\n  goto yy61;\nyy57:\n  ++p;\nyy58:\n#line 110 \"ext_scanners.re\"\n  { return (bufsize_t)(p - start); }\n#line 894 \"ext_scanners.c\"\nyy59:\n  yyaccept = 1;\n  yych = *(marker = ++p);\n  if (yybm[0+yych] & 64) goto yy52;\n  if (yych <= 0x00) goto yy58;\n  if (yych <= '$') goto yy57;\n  goto yy55;\nyy60:\n  yych = *++p;\nyy61:\n  if (yych <= '$') {\n    if (yych <= 0x00) goto yy54;\n    if (yych <= '#') goto yy60;\n    goto yy54;\n  } else {\n    if (yych == '\\\\') goto yy63;\n    goto yy60;\n  }\nyy62:\n  yych = *++p;\n  if (yych == '$') goto yy60;\n  goto yy61;\nyy63:\n  yych = *++p;\n  if (yych <= ')') {\n    if (yych <= 0x00) goto yy54;\n    if (yych <= '(') goto yy60;\n  } else {\n    if (yych == '\\\\') goto yy63;\n    goto yy60;\n  }\n  yyaccept = 1;\n  yych = *(marker = ++p);\n  if (yych <= '$') {\n    if (yych <= 0x00) goto yy58;\n    if (yych <= '#') goto yy60;\n    goto yy58;\n  } else {\n    if (yych == '\\\\') goto yy63;\n    goto yy60;\n  }\n}\n#line 112 \"ext_scanners.re\"\n\n}\n\nbufsize_t _scan_math_block(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n  \n#line 946 \"ext_scanners.c\"\n{\n  unsigned char yych;\n  unsigned int yyaccept = 0;\n  static const unsigned char yybm[256] = {\n      0,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,   0,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64, 128,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64,\n     64,  64,  64,  64,  64,  64,  64,  64\n  };\n  yych = *p;\n  if (yych == '$') goto yy66;\n  if (yych == '\\\\') goto yy67;\n  ++p;\nyy65:\n#line 121 \"ext_scanners.re\"\n  { return 0; }\n#line 991 \"ext_scanners.c\"\nyy66:\n  yyaccept = 0;\n  yych = *(marker = ++p);\n  if (yych == '$') goto yy68;\n  goto yy65;\nyy67:\n  yyaccept = 0;\n  yych = *(marker = ++p);\n  if (yych == '[') goto yy70;\n  goto yy65;\nyy68:\n  yych = *++p;\n  if (yybm[0+yych] & 64) goto yy68;\n  if (yych <= 0x00) goto yy69;\n  if (yych <= '$') goto yy71;\n  goto yy72;\nyy69:\n  p = marker;\n  if (yyaccept == 0) goto yy65;\n  else goto yy75;\nyy70:\n  yych = *++p;\n  if (yych <= '$') {\n    if (yych <= 0x00) goto yy69;\n    if (yych <= '#') goto yy70;\n    goto yy69;\n  } else {\n    if (yych == '\\\\') goto yy73;\n    goto yy70;\n  }\nyy71:\n  yych = *++p;\n  if (yych == '$') goto yy74;\n  goto yy69;\nyy72:\n  yych = *++p;\n  if (yybm[0+yych] & 64) goto yy68;\n  if (yych <= 0x00) goto yy69;\n  if (yych <= '$') goto yy76;\n  goto yy72;\nyy73:\n  yych = *++p;\n  if (yych <= 0x00) goto yy69;\n  if (yych <= '[') goto yy70;\n  if (yych <= '\\\\') goto yy73;\n  if (yych <= ']') goto yy77;\n  goto yy70;\nyy74:\n  ++p;\nyy75:\n#line 120 \"ext_scanners.re\"\n  { return (bufsize_t)(p - start); }\n#line 1044 \"ext_scanners.c\"\nyy76:\n  yych = *++p;\n  if (yybm[0+yych] & 64) goto yy68;\n  if (yych <= 0x00) goto yy69;\n  if (yych <= '$') goto yy78;\n  goto yy72;\nyy77:\n  yyaccept = 1;\n  yych = *(marker = ++p);\n  if (yych <= '$') {\n    if (yych <= 0x00) goto yy75;\n    if (yych <= '#') goto yy70;\n    goto yy75;\n  } else {\n    if (yych == '\\\\') goto yy73;\n    goto yy70;\n  }\nyy78:\n  yych = *++p;\n  if (yych == '$') goto yy74;\n  goto yy75;\n}\n#line 122 \"ext_scanners.re\"\n\n}\n\nbufsize_t _scan_emoji(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n  \n#line 1076 \"ext_scanners.c\"\n{\n  unsigned char yych;\n  static const unsigned char yybm[256] = {\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0, 128,   0, 128,   0,   0,\n    128, 128, 128, 128, 128, 128, 128, 128,\n    128, 128,   0,   0,   0,   0,   0,   0,\n      0, 128, 128, 128, 128, 128, 128, 128,\n    128, 128, 128, 128, 128, 128, 128, 128,\n    128, 128, 128, 128, 128, 128, 128, 128,\n    128, 128, 128,   0,   0,   0,   0, 128,\n      0, 128, 128, 128, 128, 128, 128, 128,\n    128, 128, 128, 128, 128, 128, 128, 128,\n    128, 128, 128, 128, 128, 128, 128, 128,\n    128, 128, 128,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0,\n      0,   0,   0,   0,   0,   0,   0,   0\n  };\n  yych = *p;\n  if (yych == ':') goto yy81;\n  ++p;\nyy80:\n#line 131 \"ext_scanners.re\"\n  { return 0; }\n#line 1119 \"ext_scanners.c\"\nyy81:\n  yych = *(marker = ++p);\n  if (yybm[0+yych] & 128) goto yy82;\n  goto yy80;\nyy82:\n  yych = *++p;\n  if (yybm[0+yych] & 128) goto yy82;\n  if (yych <= '/') goto yy83;\n  if (yych <= ':') goto yy84;\nyy83:\n  p = marker;\n  goto yy80;\nyy84:\n  ++p;\n#line 130 \"ext_scanners.re\"\n  { return (bufsize_t)(p - start); }\n#line 1136 \"ext_scanners.c\"\n}\n#line 132 \"ext_scanners.re\"\n\n}\n\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/extensions/ext_scanners.h",
    "content": "#include \"chunk.h\"\n#include \"cmark-gfm.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nbufsize_t _ext_scan_at(bufsize_t (*scanner)(const unsigned char *),\n                       unsigned char *ptr, int len, bufsize_t offset);\nbufsize_t _scan_table_start(const unsigned char *p);\nbufsize_t _scan_table_cell(const unsigned char *p);\nbufsize_t _scan_table_cell_end(const unsigned char *p);\nbufsize_t _scan_table_row_end(const unsigned char *p);\nbufsize_t _scan_tasklist(const unsigned char *p);\nbufsize_t _scan_math_inline(const unsigned char *p);\nbufsize_t _scan_math_block(const unsigned char *p);\nbufsize_t _scan_emoji(const unsigned char *p);\n\n#define scan_table_start(c, l, n) _ext_scan_at(&_scan_table_start, c, l, n)\n#define scan_table_cell(c, l, n) _ext_scan_at(&_scan_table_cell, c, l, n)\n#define scan_table_cell_end(c, l, n) _ext_scan_at(&_scan_table_cell_end, c, l, n)\n#define scan_table_row_end(c, l, n) _ext_scan_at(&_scan_table_row_end, c, l, n)\n#define scan_tasklist(c, l, n) _ext_scan_at(&_scan_tasklist, c, l, n)\n#define scan_math_inline(c, l, n) _ext_scan_at(&_scan_math_inline, c, l, n)\n#define scan_math_block(c, l, n) _ext_scan_at(&_scan_math_block, c, l, n)\n#define scan_emoji(c, l, n) _ext_scan_at(&_scan_emoji, c, l, n)\n\n#ifdef __cplusplus\n}\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/extensions/ext_scanners.re",
    "content": "\n/*!re2c re2c:indent:string = '  '; */\n\n#include <stdlib.h>\n#include \"ext_scanners.h\"\n\nbufsize_t _ext_scan_at(bufsize_t (*scanner)(const unsigned char *), unsigned char *ptr, int len, bufsize_t offset)\n{\n\tbufsize_t res;\n\n        if (ptr == NULL || offset >= len) {\n          return 0;\n        } else {\n\t  unsigned char lim = ptr[len];\n\n\t  ptr[len] = '\\0';\n\t  res = scanner(ptr + offset);\n\t  ptr[len] = lim;\n        }\n\n\treturn res;\n}\n\n/*!re2c\n  re2c:define:YYCTYPE  = \"unsigned char\";\n  re2c:define:YYCURSOR = p;\n  re2c:define:YYMARKER = marker;\n  re2c:yyfill:enable = 0;\n\n  spacechar = [ \\t\\v\\f];\n  newline = [\\r]?[\\n];\n  escaped_char = [\\\\][|!\"#$%&'()*+,./:;<=>?@[\\\\\\]^_`{}~-];\n  escaped_char1 = [\\\\][|!\"#$%&'*+,./:;<=>?@[\\\\\\]^_`{}~-];\n  escaped_char2 = [\\\\][|!\"#$%&'()*+,./:;<=>?@\\\\^_`{}~-];\n\n  table_marker = (spacechar*[:]?[-]+[:]?spacechar*);\n  table_cell = (escaped_char|[^|\\r\\n])+;\n\n  emoji = \":\" [a-zA-Z0-9_+-]+ \":\";\n\n  tasklist = spacechar*(\"-\"|\"+\"|\"*\"|[0-9]+.)spacechar+(\"[ ]\"|\"[x]\")spacechar+;\n\n  math_inline1 = \"$\" ([^$\\x00] | escaped_char) ([^$\\x00]*([^$\\x00] | escaped_char))* \"$\";\n  math_inline2 = \"\\\\\\(\" ([^$\\x00] | escaped_char1) ([^$\\x00]*([^$\\x00] | escaped_char1))* \"\\\\\\)\";\n  math_inline = math_inline1 | math_inline2;\n  math_block1 = \"$$\" ([^$\\x00]+ | escaped_char+ )* \"$$\";\n  math_block2 = \"\\\\\\[\" ([^$\\x00]+ | escaped_char2+ )* \"\\\\\\]\";\n  math_block = math_block1 | math_block2;\n*/\n\nbufsize_t _scan_table_start(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n  /*!re2c\n    [|]? table_marker ([|] table_marker)* [|]? spacechar* newline {\n      return (bufsize_t)(p - start);\n    }\n    * { return 0; }\n  */\n}\n\nbufsize_t _scan_table_cell(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n  /*!re2c\n    // In fact, `table_cell` matches non-empty table cells only. The empty\n    // string is also a valid table cell, but is handled by the default rule.\n    // This approach prevents re2c's match-empty-string warning.\n    table_cell { return (bufsize_t)(p - start); }\n    * { return 0; }\n  */\n}\n\nbufsize_t _scan_table_cell_end(const unsigned char *p)\n{\n  const unsigned char *start = p;\n  /*!re2c\n    [|] spacechar* { return (bufsize_t)(p - start); }\n    * { return 0; }\n  */\n}\n\nbufsize_t _scan_table_row_end(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n  /*!re2c\n    spacechar* newline { return (bufsize_t)(p - start); }\n    * { return 0; }\n  */\n}\n\nbufsize_t _scan_tasklist(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n  /*!re2c\n    tasklist { return (bufsize_t)(p - start); }\n    * { return 0; }\n  */\n}\n\nbufsize_t _scan_math_inline(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n  /*!re2c\n    math_inline { return (bufsize_t)(p - start); }\n    * { return 0; }\n  */\n}\n\nbufsize_t _scan_math_block(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n  /*!re2c\n    math_block { return (bufsize_t)(p - start); }\n    * { return 0; }\n  */\n}\n\nbufsize_t _scan_emoji(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n  /*!re2c\n    emoji { return (bufsize_t)(p - start); }\n    * { return 0; }\n  */\n}\n\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/extensions/math_mark.c",
    "content": "#include <parser.h>\n#include <render.h>\n#include <html.h>\n\n#include \"math_mark.h\"\n#include \"inlines.h\"\n#include \"ext_scanners.h\"\n\ncmark_node_type CMARK_NODE_MATH_INLINE, CMARK_NODE_MATH_BLOCK;\n\nstatic cmark_node *match(cmark_syntax_extension *self, cmark_parser *parser,\n                         cmark_node *parent, unsigned char character,\n                         cmark_inline_parser *inline_parser) {\n    cmark_node *res = NULL;\n    \n    if (character != '$' && character != '\\\\')\n        return NULL;\n    \n    int pos = cmark_inline_parser_get_offset(inline_parser);\n    cmark_chunk *chunk = cmark_inline_parser_get_chunk(inline_parser);\n    unsigned char *input = chunk->data + pos;\n    int len = chunk->len - pos;\n    if (len <= 2) {\n        return NULL;\n    }\n    bufsize_t matched = 0;\n    if ((matched = scan_math_block(chunk->data, chunk->len, pos))) {\n        cmark_node *node = cmark_node_new_with_mem_and_ext(CMARK_NODE_MATH_BLOCK, parser->mem, self);\n        \n        node->start_line = node->end_line = cmark_inline_parser_get_line(inline_parser);\n        node->start_column = cmark_inline_parser_get_column(inline_parser);\n        node->end_column = node->start_column + matched;\n        \n        cmark_strbuf_init(parser->mem, &node->content, matched);\n        cmark_strbuf_put(&node->content, input, matched);\n        \n        {\n            int nls = 0;\n            int since_nl = 0;\n            int len = matched;\n            int from = pos;\n            \n            while (len--) {\n                if (chunk->data[from++] == '\\n') {\n                    ++nls;\n                    since_nl = 0;\n                } else {\n                    ++since_nl;\n                }\n            }\n            node->end_line = node->start_line + nls;\n            node->end_column = since_nl;\n        }\n        \n        cmark_strbuf buf;\n        cmark_strbuf_init(parser->mem, &buf, matched);\n        cmark_strbuf_put(&buf, input + 2, matched - 4);\n        \n        node->as.code.fenced = true;\n        node->as.code.fence_char = '$';\n        node->as.code.fence_length = (matched > 255) ? 255 : matched;\n        node->as.code.fence_offset = parser->first_nonspace - parser->offset;\n        node->as.code.info = cmark_chunk_literal(\"latex\");\n        node->as.code.literal = cmark_chunk_buf_detach(&buf);\n        \n        cmark_inline_parser_set_offset(inline_parser, pos + matched);\n        cmark_parser_advance_offset(parser, (char *)input,\n                                    parser->first_nonspace + matched - parser->offset,\n                                    false);\n        res = node;\n    } else if ((matched = scan_math_inline(chunk->data, chunk->len, pos))) {\n        cmark_node *node = cmark_node_new_with_mem_and_ext(CMARK_NODE_MATH_INLINE, parser->mem, self);\n        \n        node->start_line = node->end_line = cmark_inline_parser_get_line(inline_parser);\n        node->start_column = cmark_inline_parser_get_column(inline_parser);\n        node->end_column = node->start_column + matched - 1;\n        \n        cmark_strbuf_init(parser->mem, &node->content, matched);\n        cmark_strbuf_put(&node->content, input, matched);\n        \n        cmark_strbuf buf;\n        cmark_strbuf_init(parser->mem, &buf, matched);\n        cmark_strbuf_put(&buf, input + 1, matched - 2);\n        \n        node->as.code.fenced = false;\n        node->as.code.fence_char = '$';\n        node->as.code.fence_length = (matched > 255) ? 255 : matched;\n        node->as.code.fence_offset = parser->first_nonspace - parser->offset;\n        node->as.code.info = cmark_chunk_literal(\"latex\");\n        node->as.code.literal = cmark_chunk_buf_detach(&buf);\n        \n        cmark_inline_parser_set_offset(inline_parser, pos + matched);\n        res = node;\n    }\n    return res;\n}\n\nstatic delimiter *insert(cmark_syntax_extension *self, cmark_parser *parser,\n                         cmark_inline_parser *inline_parser, delimiter *opener,\n                         delimiter *closer) {\n    cmark_node *math;\n    cmark_node *tmp, *next;\n    delimiter *delim, *tmp_delim;\n    delimiter *res = closer->next;\n    \n    math = opener->inl_text;\n    \n    if (opener->inl_text->as.literal.len != closer->inl_text->as.literal.len)\n        goto done;\n    \n    if (!cmark_node_set_type(math, CMARK_NODE_MATH_INLINE))\n        goto done;\n    \n    cmark_node_set_syntax_extension(math, self);\n    \n    tmp = cmark_node_next(opener->inl_text);\n    \n    while (tmp) {\n        if (tmp == closer->inl_text)\n            break;\n        next = cmark_node_next(tmp);\n        cmark_node_append_child(math, tmp);\n        tmp = next;\n    }\n    \n    math->end_column = closer->inl_text->start_column + closer->inl_text->as.literal.len - 1;\n    cmark_node_free(closer->inl_text);\n    \ndone:\n    delim = closer;\n    while (delim != NULL && delim != opener) {\n        tmp_delim = delim->previous;\n        cmark_inline_parser_remove_delimiter(inline_parser, delim);\n        delim = tmp_delim;\n    }\n    \n    cmark_inline_parser_remove_delimiter(inline_parser, opener);\n    \n    return res;\n}\n\nstatic const char *get_type_string(cmark_syntax_extension *extension,\n                                   cmark_node *node) {\n    if (node->type == CMARK_NODE_MATH_INLINE) {\n        return \"math\";\n    } else if (node->type == CMARK_NODE_MATH_BLOCK) {\n        return \"math_block\";\n    } else {\n        return \"<unknown>\";\n    }\n}\n\nstatic int can_contain(cmark_syntax_extension *extension, cmark_node *node,\n                       cmark_node_type child_type) {\n    if (node->type == CMARK_NODE_MATH_INLINE) {\n        return child_type == CMARK_NODE_TEXT;\n    } else if (node->type == CMARK_NODE_MATH_BLOCK) {\n        return child_type == CMARK_NODE_TEXT;\n    }\n    return false;\n}\n\nstatic void commonmark_render(cmark_syntax_extension *extension,\n                              cmark_renderer *renderer, cmark_node *node,\n                              cmark_event_type ev_type, int options) {\n    renderer->out(renderer, node, node->type == CMARK_NODE_MATH_INLINE ? \"$\" : \"$$\", false, LITERAL);\n}\n\nstatic void latex_render(cmark_syntax_extension *extension,\n                         cmark_renderer *renderer, cmark_node *node,\n                         cmark_event_type ev_type, int options) {\n    // requires \\usepackage{ulem}\n    bool entering = (ev_type == CMARK_EVENT_ENTER);\n    if (entering) {\n        renderer->out(renderer, node, \"\", false, LITERAL);\n    } else {\n        renderer->out(renderer, node, \"\", false, LITERAL);\n    }\n}\n\nstatic void html_render(cmark_syntax_extension *extension,\n                        cmark_html_renderer *renderer, cmark_node *node,\n                        cmark_event_type ev_type, int options) {\n    bool entering = (ev_type == CMARK_EVENT_ENTER);\n    if (entering) {\n        cmark_strbuf_puts(renderer->html, \"<math\");\n        cmark_strbuf_puts(renderer->html, \" style=\\\"display: \");\n        if (node->type == CMARK_NODE_MATH_INLINE) {\n            cmark_strbuf_puts(renderer->html, \"inline;\\\"\");\n        } else {\n            cmark_strbuf_puts(renderer->html, \"block;\\\"\");\n        }\n        cmark_html_render_sourcepos(node, renderer->html, options);\n        cmark_strbuf_putc(renderer->html, '>');\n    } else {\n        cmark_strbuf_puts(renderer->html, \"</math>\");\n    }\n}\n\ncmark_syntax_extension *create_math_extension(void) {\n    cmark_syntax_extension *ext = cmark_syntax_extension_new(\"math\");\n    cmark_llist *special_chars = NULL;\n    cmark_syntax_extension_set_get_type_string_func(ext, get_type_string);\n    cmark_syntax_extension_set_can_contain_func(ext, can_contain);\n    cmark_syntax_extension_set_commonmark_render_func(ext, commonmark_render);\n    cmark_syntax_extension_set_latex_render_func(ext, latex_render);\n    cmark_syntax_extension_set_html_render_func(ext, html_render);\n    cmark_syntax_extension_set_plaintext_render_func(ext, commonmark_render);\n    \n    CMARK_NODE_MATH_INLINE = cmark_syntax_extension_add_node(1);\n    CMARK_NODE_MATH_BLOCK = cmark_syntax_extension_add_node(0);\n    \n    cmark_syntax_extension_set_match_inline_func(ext, match);\n    cmark_syntax_extension_set_inline_from_delim_func(ext, insert);\n    \n    cmark_mem *mem = cmark_get_default_mem_allocator();\n    special_chars = cmark_llist_append(mem, special_chars, (void *)'\\\\');\n    special_chars = cmark_llist_append(mem, special_chars, (void *)'$');\n    cmark_syntax_extension_set_special_inline_chars(ext, special_chars);\n    \n    cmark_syntax_extension_set_emphasis(ext, 0);\n    \n    return ext;\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/extensions/math_mark.h",
    "content": "#ifndef CMARK_GFM_MATH_H\n#define CMARK_GFM_MATH_H\n\n#include \"cmark-gfm-core-extensions.h\"\n\nextern cmark_node_type CMARK_NODE_MATH_INLINE, CMARK_NODE_MATH_BLOCK;\n\nCMARK_GFM_NO_EXPORT\ncmark_syntax_extension *create_math_extension(void);\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/extensions/strikethrough.c",
    "content": "#include \"strikethrough.h\"\n#include <parser.h>\n#include <render.h>\n\ncmark_node_type CMARK_NODE_STRIKETHROUGH;\n\nstatic cmark_node *match(cmark_syntax_extension *self, cmark_parser *parser,\n                         cmark_node *parent, unsigned char character,\n                         cmark_inline_parser *inline_parser) {\n  cmark_node *res = NULL;\n  int left_flanking, right_flanking, punct_before, punct_after, delims;\n  char buffer[101];\n\n  if (character != '~')\n    return NULL;\n\n  delims = cmark_inline_parser_scan_delimiters(\n      inline_parser, sizeof(buffer) - 1, '~',\n      &left_flanking,\n      &right_flanking, &punct_before, &punct_after);\n\n  memset(buffer, '~', delims);\n  buffer[delims] = 0;\n\n  res = cmark_node_new_with_mem(CMARK_NODE_TEXT, parser->mem);\n  cmark_node_set_literal(res, buffer);\n  res->start_line = res->end_line = cmark_inline_parser_get_line(inline_parser);\n  res->start_column = cmark_inline_parser_get_column(inline_parser) - delims;\n\n  if ((left_flanking || right_flanking) &&\n      (delims == 2 || (!(parser->options & CMARK_OPT_STRIKETHROUGH_DOUBLE_TILDE) && delims == 1))) {\n    cmark_inline_parser_push_delimiter(inline_parser, character, left_flanking,\n                                       right_flanking, res);\n  }\n\n  return res;\n}\n\nstatic delimiter *insert(cmark_syntax_extension *self, cmark_parser *parser,\n                         cmark_inline_parser *inline_parser, delimiter *opener,\n                         delimiter *closer) {\n  cmark_node *strikethrough;\n  cmark_node *tmp, *next;\n  delimiter *delim, *tmp_delim;\n  delimiter *res = closer->next;\n\n  strikethrough = opener->inl_text;\n\n  if (opener->inl_text->as.literal.len != closer->inl_text->as.literal.len)\n    goto done;\n\n  if (!cmark_node_set_type(strikethrough, CMARK_NODE_STRIKETHROUGH))\n    goto done;\n\n  cmark_node_set_syntax_extension(strikethrough, self);\n\n  tmp = cmark_node_next(opener->inl_text);\n\n  while (tmp) {\n    if (tmp == closer->inl_text)\n      break;\n    next = cmark_node_next(tmp);\n    cmark_node_append_child(strikethrough, tmp);\n    tmp = next;\n  }\n\n  strikethrough->end_column = closer->inl_text->start_column + closer->inl_text->as.literal.len - 1;\n  cmark_node_free(closer->inl_text);\n\ndone:\n  delim = closer;\n  while (delim != NULL && delim != opener) {\n    tmp_delim = delim->previous;\n    cmark_inline_parser_remove_delimiter(inline_parser, delim);\n    delim = tmp_delim;\n  }\n\n  cmark_inline_parser_remove_delimiter(inline_parser, opener);\n\n  return res;\n}\n\nstatic const char *get_type_string(cmark_syntax_extension *extension,\n                                   cmark_node *node) {\n  return node->type == CMARK_NODE_STRIKETHROUGH ? \"strikethrough\" : \"<unknown>\";\n}\n\nstatic int can_contain(cmark_syntax_extension *extension, cmark_node *node,\n                       cmark_node_type child_type) {\n  if (node->type != CMARK_NODE_STRIKETHROUGH)\n    return false;\n\n  return CMARK_NODE_TYPE_INLINE_P(child_type);\n}\n\nstatic void commonmark_render(cmark_syntax_extension *extension,\n                              cmark_renderer *renderer, cmark_node *node,\n                              cmark_event_type ev_type, int options) {\n  renderer->out(renderer, node, \"~~\", false, LITERAL);\n}\n\nstatic void latex_render(cmark_syntax_extension *extension,\n                         cmark_renderer *renderer, cmark_node *node,\n                         cmark_event_type ev_type, int options) {\n  // requires \\usepackage{ulem}\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n  if (entering) {\n    renderer->out(renderer, node, \"\\\\sout{\", false, LITERAL);\n  } else {\n    renderer->out(renderer, node, \"}\", false, LITERAL);\n  }\n}\n\nstatic void man_render(cmark_syntax_extension *extension,\n                       cmark_renderer *renderer, cmark_node *node,\n                       cmark_event_type ev_type, int options) {\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n  if (entering) {\n    renderer->cr(renderer);\n    renderer->out(renderer, node, \".ST \\\"\", false, LITERAL);\n  } else {\n    renderer->out(renderer, node, \"\\\"\", false, LITERAL);\n    renderer->cr(renderer);\n  }\n}\n\nstatic void html_render(cmark_syntax_extension *extension,\n                        cmark_html_renderer *renderer, cmark_node *node,\n                        cmark_event_type ev_type, int options) {\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n  if (entering) {\n    cmark_strbuf_puts(renderer->html, \"<del>\");\n  } else {\n    cmark_strbuf_puts(renderer->html, \"</del>\");\n  }\n}\n\nstatic void plaintext_render(cmark_syntax_extension *extension,\n                             cmark_renderer *renderer, cmark_node *node,\n                             cmark_event_type ev_type, int options) {\n  renderer->out(renderer, node, \"~\", false, LITERAL);\n}\n\ncmark_syntax_extension *create_strikethrough_extension(void) {\n  cmark_syntax_extension *ext = cmark_syntax_extension_new(\"strikethrough\");\n  cmark_llist *special_chars = NULL;\n\n  cmark_syntax_extension_set_get_type_string_func(ext, get_type_string);\n  cmark_syntax_extension_set_can_contain_func(ext, can_contain);\n  cmark_syntax_extension_set_commonmark_render_func(ext, commonmark_render);\n  cmark_syntax_extension_set_latex_render_func(ext, latex_render);\n  cmark_syntax_extension_set_man_render_func(ext, man_render);\n  cmark_syntax_extension_set_html_render_func(ext, html_render);\n  cmark_syntax_extension_set_plaintext_render_func(ext, plaintext_render);\n  CMARK_NODE_STRIKETHROUGH = cmark_syntax_extension_add_node(1);\n\n  cmark_syntax_extension_set_match_inline_func(ext, match);\n  cmark_syntax_extension_set_inline_from_delim_func(ext, insert);\n\n  cmark_mem *mem = cmark_get_default_mem_allocator();\n  special_chars = cmark_llist_append(mem, special_chars, (void *)'~');\n  cmark_syntax_extension_set_special_inline_chars(ext, special_chars);\n\n  cmark_syntax_extension_set_emphasis(ext, 1);\n\n  return ext;\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/extensions/strikethrough.h",
    "content": "#ifndef CMARK_GFM_STRIKETHROUGH_H\n#define CMARK_GFM_STRIKETHROUGH_H\n\n#include \"cmark-gfm-core-extensions.h\"\n\nextern cmark_node_type CMARK_NODE_STRIKETHROUGH;\n\nCMARK_GFM_NO_EXPORT\ncmark_syntax_extension *create_strikethrough_extension(void);\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/extensions/table.c",
    "content": "#include <cmark-gfm-extension_api.h>\n#include <html.h>\n#include <inlines.h>\n#include <parser.h>\n#include <references.h>\n#include <string.h>\n#include <render.h>\n\n#include \"ext_scanners.h\"\n#include \"strikethrough.h\"\n#include \"table.h\"\n#include \"cmark-gfm-core-extensions.h\"\n\n// Limit to prevent a malicious input from causing a denial of service.\n#define MAX_AUTOCOMPLETED_CELLS 0x80000\n\n// Custom node flag, initialized in `create_table_extension`.\nstatic cmark_node_internal_flags CMARK_NODE__TABLE_VISITED;\n\ncmark_node_type CMARK_NODE_TABLE, CMARK_NODE_TABLE_ROW,\n    CMARK_NODE_TABLE_CELL;\n\ntypedef struct {\n  cmark_strbuf *buf;\n  int start_offset, end_offset, internal_offset;\n} node_cell;\n\ntypedef struct {\n  uint16_t n_columns;\n  int paragraph_offset;\n  node_cell *cells;\n} table_row;\n\ntypedef struct {\n  uint16_t n_columns;\n  uint8_t *alignments;\n  int n_rows;\n  int n_nonempty_cells;\n} node_table;\n\ntypedef struct {\n  bool is_header;\n} node_table_row;\n\nstatic void free_table_cell(cmark_mem *mem, node_cell *cell) {\n  cmark_strbuf_free((cmark_strbuf *)cell->buf);\n  mem->free(cell->buf);\n}\n\nstatic void free_row_cells(cmark_mem *mem, table_row *row) {\n  while (row->n_columns > 0) {\n    free_table_cell(mem, &row->cells[--row->n_columns]);\n  }\n  mem->free(row->cells);\n  row->cells = NULL;\n}\n\nstatic void free_table_row(cmark_mem *mem, table_row *row) {\n  if (!row)\n    return;\n\n  free_row_cells(mem, row);\n  mem->free(row);\n}\n\nstatic void free_node_table(cmark_mem *mem, void *ptr) {\n  node_table *t = (node_table *)ptr;\n  mem->free(t->alignments);\n  mem->free(t);\n}\n\nstatic void free_node_table_row(cmark_mem *mem, void *ptr) {\n  mem->free(ptr);\n}\n\nstatic int get_n_table_columns(cmark_node *node) {\n  if (!node || node->type != CMARK_NODE_TABLE)\n    return -1;\n\n  return (int)((node_table *)node->as.opaque)->n_columns;\n}\n\nstatic int set_n_table_columns(cmark_node *node, uint16_t n_columns) {\n  if (!node || node->type != CMARK_NODE_TABLE)\n    return 0;\n\n  ((node_table *)node->as.opaque)->n_columns = n_columns;\n  return 1;\n}\n\n// Increment the number of rows in the table. Also update n_nonempty_cells,\n// which keeps track of the number of cells which were parsed from the\n// input file. (If one of the rows is too short, then the trailing cells\n// are autocompleted. Autocompleted cells are not counted in n_nonempty_cells.)\n// The purpose of this is to prevent a malicious input from generating a very\n// large number of autocompleted cells, which could cause a denial of service\n// vulnerability.\nstatic int incr_table_row_count(cmark_node *node, int i) {\n  if (!node || node->type != CMARK_NODE_TABLE) {\n    return 0;\n  }\n\n  ((node_table *)node->as.opaque)->n_rows++;\n  ((node_table *)node->as.opaque)->n_nonempty_cells += i;\n  return 1;\n}\n\n// Calculate the number of autocompleted cells.\nstatic int get_n_autocompleted_cells(cmark_node *node) {\n  if (!node || node->type != CMARK_NODE_TABLE) {\n    return 0;\n  }\n\n  const node_table *nt = (node_table *)node->as.opaque;\n  return (nt->n_columns * nt->n_rows) - nt->n_nonempty_cells;\n}\n\nstatic uint8_t *get_table_alignments(cmark_node *node) {\n  if (!node || node->type != CMARK_NODE_TABLE)\n    return 0;\n\n  return ((node_table *)node->as.opaque)->alignments;\n}\n\nstatic int set_table_alignments(cmark_node *node, uint8_t *alignments) {\n  if (!node || node->type != CMARK_NODE_TABLE)\n    return 0;\n\n  ((node_table *)node->as.opaque)->alignments = alignments;\n  return 1;\n}\n\nstatic uint8_t get_cell_alignment(cmark_node *node) {\n  if (!node || node->type != CMARK_NODE_TABLE_CELL)\n    return 0;\n\n  const uint8_t *alignments = get_table_alignments(node->parent->parent);\n  int i = node->as.cell_index;\n  return alignments[i];\n}\n\nstatic int set_cell_index(cmark_node *node, int i) {\n  if (!node || node->type != CMARK_NODE_TABLE_CELL)\n    return 0;\n\n  node->as.cell_index = i;\n  return 1;\n}\n\nstatic cmark_strbuf *unescape_pipes(cmark_mem *mem, unsigned char *string, bufsize_t len)\n{\n  cmark_strbuf *res = (cmark_strbuf *)mem->calloc(1, sizeof(cmark_strbuf));\n  bufsize_t r, w;\n\n  cmark_strbuf_init(mem, res, len + 1);\n  cmark_strbuf_put(res, string, len);\n  cmark_strbuf_putc(res, '\\0');\n\n  for (r = 0, w = 0; r < len; ++r) {\n    if (res->ptr[r] == '\\\\' && res->ptr[r + 1] == '|')\n      r++;\n\n    res->ptr[w++] = res->ptr[r];\n  }\n\n  cmark_strbuf_truncate(res, w);\n\n  return res;\n}\n\n// Adds a new cell to the end of the row. A pointer to the new cell is returned\n// for the caller to initialize.\nstatic node_cell* append_row_cell(cmark_mem *mem, table_row *row) {\n  const uint32_t n_columns = row->n_columns + 1;\n  // realloc when n_columns is a power of 2\n  if ((n_columns & (n_columns-1)) == 0) {\n    // make sure we never wrap row->n_columns\n    // offset will != len and our exit will clean up as intended\n    if (n_columns > UINT16_MAX) {\n      return NULL;\n    }\n    // Use realloc to double the size of the buffer.\n    row->cells = (node_cell *)mem->realloc(row->cells, (2 * n_columns - 1) * sizeof(node_cell));\n  }\n  row->n_columns = (uint16_t)n_columns;\n  return &row->cells[n_columns-1];\n}\n\nstatic table_row *row_from_string(cmark_syntax_extension *self,\n                                  cmark_parser *parser, unsigned char *string,\n                                  int len) {\n  // Parses a single table row. It has the following form:\n  // `delim? table_cell (delim table_cell)* delim? newline`\n  // Note that cells are allowed to be empty.\n  //\n  // From the GitHub-flavored Markdown specification:\n  //\n  // > Each row consists of cells containing arbitrary text, in which inlines\n  // > are parsed, separated by pipes (|). A leading and trailing pipe is also\n  // > recommended for clarity of reading, and if there’s otherwise parsing\n  // > ambiguity.\n\n  table_row *row = NULL;\n  bufsize_t cell_matched = 1, pipe_matched = 1, offset;\n  int expect_more_cells = 1;\n  int row_end_offset = 0;\n  int int_overflow_abort = 0;\n\n  row = (table_row *)parser->mem->calloc(1, sizeof(table_row));\n  row->n_columns = 0;\n  row->cells = NULL;\n\n  // Scan past the (optional) leading pipe.\n  offset = scan_table_cell_end(string, len, 0);\n\n  // Parse the cells of the row. Stop if we reach the end of the input, or if we\n  // cannot detect any more cells.\n  while (offset < len && expect_more_cells) {\n    cell_matched = scan_table_cell(string, len, offset);\n    pipe_matched = scan_table_cell_end(string, len, offset + cell_matched);\n\n    if (cell_matched || pipe_matched) {\n      // We are guaranteed to have a cell, since (1) either we found some\n      // content and cell_matched, or (2) we found an empty cell followed by a\n      // pipe.\n      cmark_strbuf *cell_buf = unescape_pipes(parser->mem, string + offset,\n          cell_matched);\n      cmark_strbuf_trim(cell_buf);\n\n      node_cell *cell = append_row_cell(parser->mem, row);\n      if (!cell) {\n        int_overflow_abort = 1;\n        cmark_strbuf_free(cell_buf);\n        parser->mem->free(cell_buf);\n        break;\n      }\n      cell->buf = cell_buf;\n      cell->start_offset = offset;\n      cell->end_offset = offset + cell_matched - 1;\n      cell->internal_offset = 0;\n\n      while (cell->start_offset > row->paragraph_offset && string[cell->start_offset - 1] != '|') {\n        --cell->start_offset;\n        ++cell->internal_offset;\n      }\n    }\n\n    offset += cell_matched + pipe_matched;\n\n    if (pipe_matched) {\n      expect_more_cells = 1;\n    } else {\n      // We've scanned the last cell. Check if we have reached the end of the row\n      row_end_offset = scan_table_row_end(string, len, offset);\n      offset += row_end_offset;\n\n      // If the end of the row is not the end of the input,\n      // the row is not a real row but potentially part of the paragraph\n      // preceding the table.\n      if (row_end_offset && offset != len) {\n        row->paragraph_offset = offset;\n\n        free_row_cells(parser->mem, row);\n\n        // Scan past the (optional) leading pipe.\n        offset += scan_table_cell_end(string, len, offset);\n\n        expect_more_cells = 1;\n      } else {\n        expect_more_cells = 0;\n      }\n    }\n  }\n\n  if (offset != len || row->n_columns == 0 || int_overflow_abort) {\n    free_table_row(parser->mem, row);\n    row = NULL;\n  }\n\n  return row;\n}\n\nstatic void try_inserting_table_header_paragraph(cmark_parser *parser,\n                                                 cmark_node *parent_container,\n                                                 unsigned char *parent_string,\n                                                 int paragraph_offset) {\n  cmark_node *paragraph;\n  cmark_strbuf *paragraph_content;\n\n  paragraph = cmark_node_new_with_mem(CMARK_NODE_PARAGRAPH, parser->mem);\n\n  paragraph_content = unescape_pipes(parser->mem, parent_string, paragraph_offset);\n  cmark_strbuf_trim(paragraph_content);\n  cmark_node_set_string_content(paragraph, (char *) paragraph_content->ptr);\n  cmark_strbuf_free(paragraph_content);\n  parser->mem->free(paragraph_content);\n\n  if (!cmark_node_insert_before(parent_container, paragraph)) {\n    parser->mem->free(paragraph);\n  }\n}\n\nstatic cmark_node *try_opening_table_header(cmark_syntax_extension *self,\n                                            cmark_parser *parser,\n                                            cmark_node *parent_container,\n                                            unsigned char *input, int len) {\n  cmark_node *table_header;\n  table_row *header_row = NULL;\n  table_row *delimiter_row = NULL;\n  node_table_row *ntr;\n  const char *parent_string;\n  uint16_t i;\n\n  if (parent_container->flags & CMARK_NODE__TABLE_VISITED) {\n    return parent_container;\n  }\n\n  if (!scan_table_start(input, len, cmark_parser_get_first_nonspace(parser))) {\n    return parent_container;\n  }\n\n  // Since scan_table_start was successful, we must have a delimiter row.\n  delimiter_row = row_from_string(\n    self, parser, input + cmark_parser_get_first_nonspace(parser),\n    len - cmark_parser_get_first_nonspace(parser));\n  // assert may be optimized out, don't rely on it for security boundaries\n  if (!delimiter_row) {\n      return parent_container;\n  }\n\n  assert(delimiter_row);\n\n  cmark_arena_push();\n\n  // Check for a matching header row. We call `row_from_string` with the entire\n  // (potentially long) parent container as input, but this should be safe since\n  // `row_from_string` bails out early if it does not find a row.\n  parent_string = cmark_node_get_string_content(parent_container);\n  header_row = row_from_string(self, parser, (unsigned char *)parent_string,\n                               (int)strlen(parent_string));\n  if (!header_row || header_row->n_columns != delimiter_row->n_columns) {\n    free_table_row(parser->mem, delimiter_row);\n    free_table_row(parser->mem, header_row);\n    cmark_arena_pop();\n    parent_container->flags |= CMARK_NODE__TABLE_VISITED;\n    return parent_container;\n  }\n\n  if (cmark_arena_pop()) {\n    delimiter_row = row_from_string(\n        self, parser, input + cmark_parser_get_first_nonspace(parser),\n        len - cmark_parser_get_first_nonspace(parser));\n    header_row = row_from_string(self, parser, (unsigned char *)parent_string,\n                                 (int)strlen(parent_string));\n    // row_from_string can return NULL, add additional check to ensure n_columns match\n    if (!delimiter_row || !header_row || header_row->n_columns != delimiter_row->n_columns) {\n        free_table_row(parser->mem, delimiter_row);\n        free_table_row(parser->mem, header_row);\n        return parent_container;\n    }\n  }\n\n  if (!cmark_node_set_type(parent_container, CMARK_NODE_TABLE)) {\n    free_table_row(parser->mem, header_row);\n    free_table_row(parser->mem, delimiter_row);\n    return parent_container;\n  }\n\n  if (header_row->paragraph_offset) {\n    try_inserting_table_header_paragraph(parser, parent_container, (unsigned char *)parent_string,\n                                         header_row->paragraph_offset);\n  }\n\n  cmark_node_set_syntax_extension(parent_container, self);\n  parent_container->as.opaque = parser->mem->calloc(1, sizeof(node_table));\n  set_n_table_columns(parent_container, header_row->n_columns);\n\n  // allocate alignments based on delimiter_row->n_columns\n  // since we populate the alignments array based on delimiter_row->cells\n  uint8_t *alignments =\n      (uint8_t *)parser->mem->calloc(delimiter_row->n_columns, sizeof(uint8_t));\n  for (i = 0; i < delimiter_row->n_columns; ++i) {\n    node_cell *node = &delimiter_row->cells[i];\n    bool left = node->buf->ptr[0] == ':', right = node->buf->ptr[node->buf->size - 1] == ':';\n\n    if (left && right)\n      alignments[i] = 'c';\n    else if (left)\n      alignments[i] = 'l';\n    else if (right)\n      alignments[i] = 'r';\n  }\n  set_table_alignments(parent_container, alignments);\n\n  table_header =\n      cmark_parser_add_child(parser, parent_container, CMARK_NODE_TABLE_ROW,\n                             parent_container->start_column);\n  cmark_node_set_syntax_extension(table_header, self);\n  table_header->end_column = parent_container->start_column + (int)strlen(parent_string) - 2;\n  table_header->start_line = table_header->end_line = parent_container->start_line;\n\n  table_header->as.opaque = ntr = (node_table_row *)parser->mem->calloc(1, sizeof(node_table_row));\n  ntr->is_header = true;\n\n  for (i = 0; i < header_row->n_columns; ++i) {\n    node_cell *cell = &header_row->cells[i];\n    cmark_node *header_cell = cmark_parser_add_child(parser, table_header,\n                                                     CMARK_NODE_TABLE_CELL, parent_container->start_column + cell->start_offset);\n    header_cell->start_line = header_cell->end_line = parent_container->start_line;\n    header_cell->internal_offset = cell->internal_offset;\n    header_cell->end_column = parent_container->start_column + cell->end_offset;\n    cmark_node_set_string_content(header_cell, (char *) cell->buf->ptr);\n    cmark_node_set_syntax_extension(header_cell, self);\n    set_cell_index(header_cell, i);\n  }\n\n  incr_table_row_count(parent_container, i);\n\n  cmark_parser_advance_offset(\n      parser, (char *)input,\n      (int)strlen((char *)input) - 1 - cmark_parser_get_offset(parser), false);\n\n  free_table_row(parser->mem, header_row);\n  free_table_row(parser->mem, delimiter_row);\n  return parent_container;\n}\n\nstatic cmark_node *try_opening_table_row(cmark_syntax_extension *self,\n                                         cmark_parser *parser,\n                                         cmark_node *parent_container,\n                                         unsigned char *input, int len) {\n  cmark_node *table_row_block;\n  table_row *row;\n\n  if (cmark_parser_is_blank(parser))\n    return NULL;\n\n  if (get_n_autocompleted_cells(parent_container) > MAX_AUTOCOMPLETED_CELLS) {\n    return NULL;\n  }\n\n  table_row_block =\n      cmark_parser_add_child(parser, parent_container, CMARK_NODE_TABLE_ROW,\n                             parent_container->start_column);\n  cmark_node_set_syntax_extension(table_row_block, self);\n  table_row_block->end_column = parent_container->end_column;\n  table_row_block->as.opaque = parser->mem->calloc(1, sizeof(node_table_row));\n\n  row = row_from_string(self, parser, input + cmark_parser_get_first_nonspace(parser),\n      len - cmark_parser_get_first_nonspace(parser));\n\n  if (!row) {\n      // clean up the dangling node\n      cmark_node_free(table_row_block);\n      return NULL;\n  }\n\n  {\n    int i, table_columns = get_n_table_columns(parent_container);\n\n    for (i = 0; i < row->n_columns && i < table_columns; ++i) {\n      node_cell *cell = &row->cells[i];\n      cmark_node *node = cmark_parser_add_child(parser, table_row_block,\n          CMARK_NODE_TABLE_CELL, parent_container->start_column + cell->start_offset);\n      node->internal_offset = cell->internal_offset;\n      node->end_column = parent_container->start_column + cell->end_offset;\n      cmark_node_set_string_content(node, (char *) cell->buf->ptr);\n      cmark_node_set_syntax_extension(node, self);\n      set_cell_index(node, i);\n    }\n\n    incr_table_row_count(parent_container, i);\n\n    for (; i < table_columns; ++i) {\n      cmark_node *node = cmark_parser_add_child(\n          parser, table_row_block, CMARK_NODE_TABLE_CELL, 0);\n      cmark_node_set_syntax_extension(node, self);\n      set_cell_index(node, i);\n    }\n  }\n\n  free_table_row(parser->mem, row);\n\n  cmark_parser_advance_offset(parser, (char *)input,\n                              len - 1 - cmark_parser_get_offset(parser), false);\n\n  return table_row_block;\n}\n\nstatic cmark_node *try_opening_table_block(cmark_syntax_extension *self,\n                                           int indented, cmark_parser *parser,\n                                           cmark_node *parent_container,\n                                           unsigned char *input, int len) {\n  cmark_node_type parent_type = cmark_node_get_type(parent_container);\n\n  if (!indented && parent_type == CMARK_NODE_PARAGRAPH) {\n    return try_opening_table_header(self, parser, parent_container, input, len);\n  } else if (!indented && parent_type == CMARK_NODE_TABLE) {\n    return try_opening_table_row(self, parser, parent_container, input, len);\n  }\n\n  return NULL;\n}\n\nstatic int matches(cmark_syntax_extension *self, cmark_parser *parser,\n                   unsigned char *input, int len,\n                   cmark_node *parent_container) {\n  int res = 0;\n\n  if (cmark_node_get_type(parent_container) == CMARK_NODE_TABLE) {\n    cmark_arena_push();\n    table_row *new_row = row_from_string(\n        self, parser, input + cmark_parser_get_first_nonspace(parser),\n        len - cmark_parser_get_first_nonspace(parser));\n    if (new_row && new_row->n_columns)\n      res = 1;\n    free_table_row(parser->mem, new_row);\n    cmark_arena_pop();\n  }\n\n  return res;\n}\n\nstatic const char *get_type_string(cmark_syntax_extension *self,\n                                   cmark_node *node) {\n  if (node->type == CMARK_NODE_TABLE) {\n    return \"table\";\n  } else if (node->type == CMARK_NODE_TABLE_ROW) {\n    if (((node_table_row *)node->as.opaque)->is_header)\n      return \"table_header\";\n    else\n      return \"table_row\";\n  } else if (node->type == CMARK_NODE_TABLE_CELL) {\n    return \"table_cell\";\n  }\n\n  return \"<unknown>\";\n}\n\nstatic int can_contain(cmark_syntax_extension *extension, cmark_node *node,\n                       cmark_node_type child_type) {\n  if (node->type == CMARK_NODE_TABLE) {\n    return child_type == CMARK_NODE_TABLE_ROW;\n  } else if (node->type == CMARK_NODE_TABLE_ROW) {\n    return child_type == CMARK_NODE_TABLE_CELL;\n  } else if (node->type == CMARK_NODE_TABLE_CELL) {\n    return child_type == CMARK_NODE_TEXT || child_type == CMARK_NODE_CODE ||\n           child_type == CMARK_NODE_EMPH || child_type == CMARK_NODE_STRONG ||\n           child_type == CMARK_NODE_LINK || child_type == CMARK_NODE_IMAGE ||\n           child_type == CMARK_NODE_STRIKETHROUGH ||\n           child_type == CMARK_NODE_HTML_INLINE ||\n           child_type == CMARK_NODE_FOOTNOTE_REFERENCE;\n  }\n  return false;\n}\n\nstatic int contains_inlines(cmark_syntax_extension *extension,\n                            cmark_node *node) {\n  return node->type == CMARK_NODE_TABLE_CELL;\n}\n\nstatic void commonmark_render(cmark_syntax_extension *extension,\n                              cmark_renderer *renderer, cmark_node *node,\n                              cmark_event_type ev_type, int options) {\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n\n  if (node->type == CMARK_NODE_TABLE) {\n    renderer->blankline(renderer);\n  } else if (node->type == CMARK_NODE_TABLE_ROW) {\n    if (entering) {\n      renderer->cr(renderer);\n      renderer->out(renderer, node, \"|\", false, LITERAL);\n    }\n  } else if (node->type == CMARK_NODE_TABLE_CELL) {\n    if (entering) {\n      renderer->out(renderer, node, \" \", false, LITERAL);\n    } else {\n      renderer->out(renderer, node, \" |\", false, LITERAL);\n      if (((node_table_row *)node->parent->as.opaque)->is_header &&\n          !node->next) {\n        int i;\n        uint8_t *alignments = get_table_alignments(node->parent->parent);\n        uint16_t n_cols =\n            ((node_table *)node->parent->parent->as.opaque)->n_columns;\n        renderer->cr(renderer);\n        renderer->out(renderer, node, \"|\", false, LITERAL);\n        for (i = 0; i < n_cols; i++) {\n          switch (alignments[i]) {\n          case 0:   renderer->out(renderer, node, \" --- |\", false, LITERAL); break;\n          case 'l': renderer->out(renderer, node, \" :-- |\", false, LITERAL); break;\n          case 'c': renderer->out(renderer, node, \" :-: |\", false, LITERAL); break;\n          case 'r': renderer->out(renderer, node, \" --: |\", false, LITERAL); break;\n          }\n        }\n        renderer->cr(renderer);\n      }\n    }\n  } else {\n    assert(false);\n  }\n}\n\nstatic void latex_render(cmark_syntax_extension *extension,\n                         cmark_renderer *renderer, cmark_node *node,\n                         cmark_event_type ev_type, int options) {\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n\n  if (node->type == CMARK_NODE_TABLE) {\n    if (entering) {\n      int i;\n      uint16_t n_cols;\n      uint8_t *alignments = get_table_alignments(node);\n\n      renderer->cr(renderer);\n      renderer->out(renderer, node, \"\\\\begin{table}\", false, LITERAL);\n      renderer->cr(renderer);\n      renderer->out(renderer, node, \"\\\\begin{tabular}{\", false, LITERAL);\n\n      n_cols = ((node_table *)node->as.opaque)->n_columns;\n      for (i = 0; i < n_cols; i++) {\n        switch(alignments[i]) {\n        case 0:\n        case 'l':\n          renderer->out(renderer, node, \"l\", false, LITERAL);\n          break;\n        case 'c':\n          renderer->out(renderer, node, \"c\", false, LITERAL);\n          break;\n        case 'r':\n          renderer->out(renderer, node, \"r\", false, LITERAL);\n          break;\n        }\n      }\n      renderer->out(renderer, node, \"}\", false, LITERAL);\n      renderer->cr(renderer);\n    } else {\n      renderer->out(renderer, node, \"\\\\end{tabular}\", false, LITERAL);\n      renderer->cr(renderer);\n      renderer->out(renderer, node, \"\\\\end{table}\", false, LITERAL);\n      renderer->cr(renderer);\n    }\n  } else if (node->type == CMARK_NODE_TABLE_ROW) {\n    if (!entering) {\n      renderer->cr(renderer);\n    }\n  } else if (node->type == CMARK_NODE_TABLE_CELL) {\n    if (!entering) {\n      if (node->next) {\n        renderer->out(renderer, node, \" & \", false, LITERAL);\n      } else {\n        renderer->out(renderer, node, \" \\\\\\\\\", false, LITERAL);\n      }\n    }\n  } else {\n    assert(false);\n  }\n}\n\nstatic const char *xml_attr(cmark_syntax_extension *extension,\n                            cmark_node *node) {\n  if (node->type == CMARK_NODE_TABLE_CELL) {\n    if (cmark_gfm_extensions_get_table_row_is_header(node->parent)) {\n      switch (get_cell_alignment(node)) {\n      case 'l': return \" align=\\\"left\\\"\";\n      case 'c': return \" align=\\\"center\\\"\";\n      case 'r': return \" align=\\\"right\\\"\";\n      }\n    }\n  }\n\n  return NULL;\n}\n\nstatic void man_render(cmark_syntax_extension *extension,\n                       cmark_renderer *renderer, cmark_node *node,\n                       cmark_event_type ev_type, int options) {\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n\n  if (node->type == CMARK_NODE_TABLE) {\n    if (entering) {\n      int i;\n      uint16_t n_cols;\n      uint8_t *alignments = get_table_alignments(node);\n\n      renderer->cr(renderer);\n      renderer->out(renderer, node, \".TS\", false, LITERAL);\n      renderer->cr(renderer);\n      renderer->out(renderer, node, \"tab(@);\", false, LITERAL);\n      renderer->cr(renderer);\n\n      n_cols = ((node_table *)node->as.opaque)->n_columns;\n\n      for (i = 0; i < n_cols; i++) {\n        switch (alignments[i]) {\n        case 'l':\n          renderer->out(renderer, node, \"l\", false, LITERAL);\n          break;\n        case 0:\n        case 'c':\n          renderer->out(renderer, node, \"c\", false, LITERAL);\n          break;\n        case 'r':\n          renderer->out(renderer, node, \"r\", false, LITERAL);\n          break;\n        }\n      }\n\n      if (n_cols) {\n        renderer->out(renderer, node, \".\", false, LITERAL);\n        renderer->cr(renderer);\n      }\n    } else {\n      renderer->out(renderer, node, \".TE\", false, LITERAL);\n      renderer->cr(renderer);\n    }\n  } else if (node->type == CMARK_NODE_TABLE_ROW) {\n    if (!entering) {\n      renderer->cr(renderer);\n    }\n  } else if (node->type == CMARK_NODE_TABLE_CELL) {\n    if (!entering && node->next) {\n      renderer->out(renderer, node, \"@\", false, LITERAL);\n    }\n  } else {\n    assert(false);\n  }\n}\n\nstatic void html_table_add_align(cmark_strbuf* html, const char* align, int options) {\n  if (options & CMARK_OPT_TABLE_PREFER_STYLE_ATTRIBUTES) {\n    cmark_strbuf_puts(html, \" style=\\\"text-align: \");\n    cmark_strbuf_puts(html, align);\n    cmark_strbuf_puts(html, \"\\\"\");\n  } else {\n    cmark_strbuf_puts(html, \" align=\\\"\");\n    cmark_strbuf_puts(html, align);\n    cmark_strbuf_puts(html, \"\\\"\");\n  }\n}\n\nstruct html_table_state {\n  unsigned need_closing_table_body : 1;\n  unsigned in_table_header : 1;\n};\n\nstatic void html_render(cmark_syntax_extension *extension,\n                        cmark_html_renderer *renderer, cmark_node *node,\n                        cmark_event_type ev_type, int options) {\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n  cmark_strbuf *html = renderer->html;\n\n  // XXX: we just monopolise renderer->opaque.\n  struct html_table_state *table_state =\n      (struct html_table_state *)&renderer->opaque;\n\n  if (node->type == CMARK_NODE_TABLE) {\n    if (entering) {\n      cmark_html_render_cr(html);\n      cmark_strbuf_puts(html, \"<table\");\n      cmark_html_render_sourcepos(node, html, options);\n      cmark_strbuf_putc(html, '>');\n      table_state->need_closing_table_body = false;\n    } else {\n      if (table_state->need_closing_table_body) {\n        cmark_html_render_cr(html);\n        cmark_strbuf_puts(html, \"</tbody>\");\n        cmark_html_render_cr(html);\n      }\n      table_state->need_closing_table_body = false;\n      cmark_html_render_cr(html);\n      cmark_strbuf_puts(html, \"</table>\");\n      cmark_html_render_cr(html);\n    }\n  } else if (node->type == CMARK_NODE_TABLE_ROW) {\n    if (entering) {\n      cmark_html_render_cr(html);\n      if (((node_table_row *)node->as.opaque)->is_header) {\n        table_state->in_table_header = 1;\n        cmark_strbuf_puts(html, \"<thead>\");\n        cmark_html_render_cr(html);\n      } else if (!table_state->need_closing_table_body) {\n        cmark_strbuf_puts(html, \"<tbody>\");\n        cmark_html_render_cr(html);\n        table_state->need_closing_table_body = 1;\n      }\n      cmark_strbuf_puts(html, \"<tr\");\n      cmark_html_render_sourcepos(node, html, options);\n      cmark_strbuf_putc(html, '>');\n    } else {\n      cmark_html_render_cr(html);\n      cmark_strbuf_puts(html, \"</tr>\");\n      if (((node_table_row *)node->as.opaque)->is_header) {\n        cmark_html_render_cr(html);\n        cmark_strbuf_puts(html, \"</thead>\");\n        table_state->in_table_header = false;\n      }\n    }\n  } else if (node->type == CMARK_NODE_TABLE_CELL) {\n    if (entering) {\n      cmark_html_render_cr(html);\n      if (table_state->in_table_header) {\n        cmark_strbuf_puts(html, \"<th\");\n      } else {\n        cmark_strbuf_puts(html, \"<td\");\n      }\n\n      switch (get_cell_alignment(node)) {\n      case 'l': html_table_add_align(html, \"left\", options); break;\n      case 'c': html_table_add_align(html, \"center\", options); break;\n      case 'r': html_table_add_align(html, \"right\", options); break;\n      }\n\n      cmark_html_render_sourcepos(node, html, options);\n      cmark_strbuf_putc(html, '>');\n    } else {\n      if (table_state->in_table_header) {\n        cmark_strbuf_puts(html, \"</th>\");\n      } else {\n        cmark_strbuf_puts(html, \"</td>\");\n      }\n    }\n  } else {\n    assert(false);\n  }\n}\n\nstatic void opaque_alloc(cmark_syntax_extension *self, cmark_mem *mem, cmark_node *node) {\n  if (node->type == CMARK_NODE_TABLE) {\n    node->as.opaque = mem->calloc(1, sizeof(node_table));\n  } else if (node->type == CMARK_NODE_TABLE_ROW) {\n    node->as.opaque = mem->calloc(1, sizeof(node_table_row));\n  } else if (node->type == CMARK_NODE_TABLE_CELL) {\n    node->as.opaque = mem->calloc(1, sizeof(node_cell));\n  }\n}\n\nstatic void opaque_free(cmark_syntax_extension *self, cmark_mem *mem, cmark_node *node) {\n  if (node->type == CMARK_NODE_TABLE) {\n    free_node_table(mem, node->as.opaque);\n  } else if (node->type == CMARK_NODE_TABLE_ROW) {\n    free_node_table_row(mem, node->as.opaque);\n  }\n}\n\nstatic int escape(cmark_syntax_extension *self, cmark_node *node, int c) {\n  return\n    node->type != CMARK_NODE_TABLE &&\n    node->type != CMARK_NODE_TABLE_ROW &&\n    node->type != CMARK_NODE_TABLE_CELL &&\n    c == '|';\n}\n\ncmark_syntax_extension *create_table_extension(void) {\n  cmark_syntax_extension *self = cmark_syntax_extension_new(\"table\");\n\n  cmark_register_node_flag(&CMARK_NODE__TABLE_VISITED);\n  cmark_syntax_extension_set_match_block_func(self, matches);\n  cmark_syntax_extension_set_open_block_func(self, try_opening_table_block);\n  cmark_syntax_extension_set_get_type_string_func(self, get_type_string);\n  cmark_syntax_extension_set_can_contain_func(self, can_contain);\n  cmark_syntax_extension_set_contains_inlines_func(self, contains_inlines);\n  cmark_syntax_extension_set_commonmark_render_func(self, commonmark_render);\n  cmark_syntax_extension_set_plaintext_render_func(self, commonmark_render);\n  cmark_syntax_extension_set_latex_render_func(self, latex_render);\n  cmark_syntax_extension_set_xml_attr_func(self, xml_attr);\n  cmark_syntax_extension_set_man_render_func(self, man_render);\n  cmark_syntax_extension_set_html_render_func(self, html_render);\n  cmark_syntax_extension_set_opaque_alloc_func(self, opaque_alloc);\n  cmark_syntax_extension_set_opaque_free_func(self, opaque_free);\n  cmark_syntax_extension_set_commonmark_escape_func(self, escape);\n  CMARK_NODE_TABLE = cmark_syntax_extension_add_node(0);\n  CMARK_NODE_TABLE_ROW = cmark_syntax_extension_add_node(0);\n  CMARK_NODE_TABLE_CELL = cmark_syntax_extension_add_node(0);\n\n  return self;\n}\n\nuint16_t cmark_gfm_extensions_get_table_columns(cmark_node *node) {\n  if (node->type != CMARK_NODE_TABLE)\n    return 0;\n\n  return ((node_table *)node->as.opaque)->n_columns;\n}\n\nuint8_t *cmark_gfm_extensions_get_table_alignments(cmark_node *node) {\n  if (node->type != CMARK_NODE_TABLE)\n    return 0;\n\n  return ((node_table *)node->as.opaque)->alignments;\n}\n\nint cmark_gfm_extensions_set_table_columns(cmark_node *node, uint16_t n_columns) {\n  return set_n_table_columns(node, n_columns);\n}\n\nint cmark_gfm_extensions_set_table_alignments(cmark_node *node, uint16_t ncols, uint8_t *alignments) {\n  uint8_t *a = (uint8_t *)cmark_node_mem(node)->calloc(1, ncols);\n  memcpy(a, alignments, ncols);\n  return set_table_alignments(node, a);\n}\n\nint cmark_gfm_extensions_get_table_row_is_header(cmark_node *node)\n{\n  if (!node || node->type != CMARK_NODE_TABLE_ROW)\n    return 0;\n\n  return ((node_table_row *)node->as.opaque)->is_header;\n}\n\nint cmark_gfm_extensions_set_table_row_is_header(cmark_node *node, int is_header)\n{\n  if (!node || node->type != CMARK_NODE_TABLE_ROW)\n    return 0;\n\n  ((node_table_row *)node->as.opaque)->is_header = (is_header != 0);\n  return 1;\n}\n\nuint8_t cmark_gfm_extensions_get_table_cell_alignment(cmark_node *node)\n{\n    if (!node || node->type != CMARK_NODE_TABLE_CELL)\n      return 0;\n\n    const uint8_t *alignments = get_table_alignments(node->parent->parent);\n    int i = node->as.cell_index;\n    return alignments[i];\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/extensions/table.h",
    "content": "#ifndef CMARK_GFM_TABLE_H\n#define CMARK_GFM_TABLE_H\n\n#include \"cmark-gfm-core-extensions.h\"\n\n\nextern cmark_node_type CMARK_NODE_TABLE, CMARK_NODE_TABLE_ROW,\n    CMARK_NODE_TABLE_CELL;\n\nCMARK_GFM_NO_EXPORT\ncmark_syntax_extension *create_table_extension(void);\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/extensions/tagfilter.c",
    "content": "#include \"tagfilter.h\"\n#include <parser.h>\n#include <ctype.h>\n\nstatic const char *blacklist[] = {\n    \"title\",   \"textarea\", \"style\",  \"xmp\",       \"iframe\",\n    \"noembed\", \"noframes\", \"script\", \"plaintext\", NULL,\n};\n\nstatic int is_tag(const unsigned char *tag_data, size_t tag_size,\n                  const char *tagname) {\n  size_t i;\n\n  if (tag_size < 3 || tag_data[0] != '<')\n    return 0;\n\n  i = 1;\n\n  if (tag_data[i] == '/') {\n    i++;\n  }\n\n  for (; i < tag_size; ++i, ++tagname) {\n    if (*tagname == 0)\n      break;\n\n    if (tolower(tag_data[i]) != *tagname)\n      return 0;\n  }\n\n  if (i == tag_size)\n    return 0;\n\n  if (cmark_isspace(tag_data[i]) || tag_data[i] == '>')\n    return 1;\n\n  if (tag_data[i] == '/' && tag_size >= i + 2 && tag_data[i + 1] == '>')\n    return 1;\n\n  return 0;\n}\n\nstatic int filter(cmark_syntax_extension *ext, const unsigned char *tag,\n                  size_t tag_len) {\n  const char **it;\n\n  for (it = blacklist; *it; ++it) {\n    if (is_tag(tag, tag_len, *it)) {\n      return 0;\n    }\n  }\n\n  return 1;\n}\n\ncmark_syntax_extension *create_tagfilter_extension(void) {\n  cmark_syntax_extension *ext = cmark_syntax_extension_new(\"tagfilter\");\n  cmark_syntax_extension_set_html_filter_func(ext, filter);\n  return ext;\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/extensions/tagfilter.h",
    "content": "#ifndef CMARK_GFM_TAGFILTER_H\n#define CMARK_GFM_TAGFILTER_H\n\n#include \"cmark-gfm-core-extensions.h\"\n\nCMARK_GFM_NO_EXPORT\ncmark_syntax_extension *create_tagfilter_extension(void);\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/extensions/tasklist.c",
    "content": "#include \"tasklist.h\"\n#include <parser.h>\n#include <render.h>\n#include <html.h>\n#include \"ext_scanners.h\"\n\ntypedef enum {\n  CMARK_TASKLIST_NOCHECKED,\n  CMARK_TASKLIST_CHECKED,\n} cmark_tasklist_type;\n\n// Local constants\nstatic const char *TYPE_STRING = \"tasklist\";\n\nstatic const char *get_type_string(cmark_syntax_extension *extension, cmark_node *node) {\n  return TYPE_STRING;\n}\n\n\n// Return 1 if state was set, 0 otherwise\nint cmark_gfm_extensions_set_tasklist_item_checked(cmark_node *node, bool is_checked) {\n  // The node has to exist, and be an extension, and actually be the right type in order to get the value.\n  if (!node || !node->extension || strcmp(cmark_node_get_type_string(node), TYPE_STRING))\n    return 0;\n\n  node->as.list.checked = is_checked;\n  return 1;\n}\n\nbool cmark_gfm_extensions_get_tasklist_item_checked(cmark_node *node) {\n  if (!node || !node->extension || strcmp(cmark_node_get_type_string(node), TYPE_STRING))\n    return false;\n\n  if (node->as.list.checked) {\n    return true;\n  }\n  else {\n    return false;\n  }\n}\n\nstatic bool parse_node_item_prefix(cmark_parser *parser, const char *input,\n                                   cmark_node *container) {\n  bool res = false;\n  if (parser->indent >=\n      container->as.list.marker_offset + container->as.list.padding) {\n    cmark_parser_advance_offset(parser, input, container->as.list.marker_offset +\n                                        container->as.list.padding,\n                     true);\n    res = true;\n  } else if (parser->blank && container->first_child != NULL) {\n    // if container->first_child is NULL, then the opening line\n    // of the list item was blank after the list marker; in this\n    // case, we are done with the list item.\n    cmark_parser_advance_offset(parser, input, parser->first_nonspace - parser->offset,\n                     false);\n    res = true;\n  }\n  return res;\n}\n\nstatic int matches(cmark_syntax_extension *self, cmark_parser *parser,\n                   unsigned char *input, int len,\n                   cmark_node *parent_container) {\n  return parse_node_item_prefix(parser, (const char*)input, parent_container);\n}\n\nstatic int can_contain(cmark_syntax_extension *extension, cmark_node *node,\n                       cmark_node_type child_type) {\n  return (node->type == CMARK_NODE_ITEM) ? 1 : 0;\n}\n\nstatic cmark_node *open_tasklist_item(cmark_syntax_extension *self,\n                                      int indented, cmark_parser *parser,\n                                      cmark_node *parent_container,\n                                      unsigned char *input, int len) {\n  cmark_node_type node_type = cmark_node_get_type(parent_container);\n  if (node_type != CMARK_NODE_ITEM) {\n    return NULL;\n  }\n\n  bufsize_t matched = scan_tasklist(input, len, 0);\n  if (!matched) {\n    return NULL;\n  }\n\n  cmark_node_set_syntax_extension(parent_container, self);\n  cmark_parser_advance_offset(parser, (char *)input, 3, false);\n\n  // Either an upper or lower case X means the task is completed.\n  parent_container->as.list.is_check_box = (strstr((char*)input, \"- [x]\") ||\n                                              strstr((char*)input, \"- [X]\") ||\n                                              strstr((char*)input, \"- [ ]\"));\n  parent_container->as.list.checked = (strstr((char*)input, \"[x]\") || strstr((char*)input, \"[X]\"));\n\n  return NULL;\n}\n\nstatic void commonmark_render(cmark_syntax_extension *extension,\n                              cmark_renderer *renderer, cmark_node *node,\n                              cmark_event_type ev_type, int options) {\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n  if (entering) {\n    renderer->cr(renderer);\n    if (node->as.list.checked) {\n      renderer->out(renderer, node, \"- [x] \", false, LITERAL);\n    } else {\n      renderer->out(renderer, node, \"- [ ] \", false, LITERAL);\n    }\n    cmark_strbuf_puts(renderer->prefix, \"  \");\n  } else {\n    cmark_strbuf_truncate(renderer->prefix, renderer->prefix->size - 2);\n    renderer->cr(renderer);\n  }\n}\n\nstatic void html_render(cmark_syntax_extension *extension,\n                        cmark_html_renderer *renderer, cmark_node *node,\n                        cmark_event_type ev_type, int options) {\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n  if (entering) {\n    cmark_html_render_cr(renderer->html);\n    cmark_strbuf_puts(renderer->html, \"<li\");\n    cmark_html_render_sourcepos(node, renderer->html, options);\n    cmark_strbuf_putc(renderer->html, '>');\n    if (node->as.list.checked) {\n      cmark_strbuf_puts(renderer->html, \"<input type=\\\"checkbox\\\" checked=\\\"\\\" disabled=\\\"\\\" /> \");\n    } else {\n      cmark_strbuf_puts(renderer->html, \"<input type=\\\"checkbox\\\" disabled=\\\"\\\" /> \");\n    }\n  } else {\n    cmark_strbuf_puts(renderer->html, \"</li>\\n\");\n  }\n}\n\nstatic const char *xml_attr(cmark_syntax_extension *extension,\n                            cmark_node *node) {\n  if (node->as.list.checked) {\n    return \" completed=\\\"true\\\"\";\n  } else {\n    return \" completed=\\\"false\\\"\";\n      \n  }\n}\n\ncmark_syntax_extension *create_tasklist_extension(void) {\n  cmark_syntax_extension *ext = cmark_syntax_extension_new(\"tasklist\");\n\n  cmark_syntax_extension_set_match_block_func(ext, matches);\n  cmark_syntax_extension_set_get_type_string_func(ext, get_type_string);\n  cmark_syntax_extension_set_open_block_func(ext, open_tasklist_item);\n  cmark_syntax_extension_set_can_contain_func(ext, can_contain);\n  cmark_syntax_extension_set_commonmark_render_func(ext, commonmark_render);\n  cmark_syntax_extension_set_plaintext_render_func(ext, commonmark_render);\n  cmark_syntax_extension_set_html_render_func(ext, html_render);\n  cmark_syntax_extension_set_xml_attr_func(ext, xml_attr);\n\n  return ext;\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/extensions/tasklist.h",
    "content": "#ifndef TASKLIST_H\n#define TASKLIST_H\n\n#include \"cmark-gfm-core-extensions.h\"\n\nCMARK_GFM_NO_EXPORT\ncmark_syntax_extension *create_tasklist_extension(void);\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/CMakeLists.txt",
    "content": "if(${CMAKE_VERSION} VERSION_GREATER \"3.3\")\n    cmake_policy(SET CMP0063 NEW)\nendif()\n\ninclude(GNUInstallDirs)\n\nset(LIBRARY \"libcmark-gfm\")\nset(STATICLIBRARY \"libcmark-gfm_static\")\nset(HEADERS\n  cmark-gfm.h\n  cmark-gfm-extension_api.h\n  parser.h\n  buffer.h\n  node.h\n  iterator.h\n  chunk.h\n  references.h\n  footnotes.h\n  map.h\n  utf8.h\n  scanners.h\n  inlines.h\n  houdini.h\n  cmark_ctype.h\n  render.h\n  registry.h\n  syntax_extension.h\n  plugin.h\n  )\nset(LIBRARY_SOURCES\n  cmark.c\n  node.c\n  iterator.c\n  blocks.c\n  inlines.c\n  scanners.c\n  scanners.re\n  utf8.c\n  buffer.c\n  references.c\n  footnotes.c\n  map.c\n  render.c\n  man.c\n  xml.c\n  html.c\n  commonmark.c\n  plaintext.c\n  latex.c\n  houdini_href_e.c\n  houdini_html_e.c\n  houdini_html_u.c\n  cmark_ctype.c\n  arena.c\n  linked_list.c\n  syntax_extension.c\n  registry.c\n  plugin.c\n  ${HEADERS}\n  )\n\nset(PROGRAM \"cmark-gfm\")\nset(PROGRAM_SOURCES main.c)\n\ninclude_directories(. ${CMAKE_CURRENT_BINARY_DIR})\ninclude_directories(\n  ${PROJECT_BINARY_DIR}/extensions\n)\n\nconfigure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmark-gfm_version.h.in\n  ${CMAKE_CURRENT_BINARY_DIR}/cmark-gfm_version.h)\n\ninclude (GenerateExportHeader)\n\ninclude(\"../CheckFileOffsetBits.cmake\")\nCHECK_FILE_OFFSET_BITS()\n\nadd_executable(${PROGRAM} ${PROGRAM_SOURCES})\n\nif(CMARK_SHARED)\n  target_link_libraries(${PROGRAM} libcmark-gfm-extensions libcmark-gfm)\nelseif(CMARK_STATIC)\n  target_link_libraries(${PROGRAM} libcmark-gfm-extensions_static libcmark-gfm_static)\nendif()\n\n# Disable the PUBLIC declarations when compiling the executable:\nset_target_properties(${PROGRAM} PROPERTIES\n  COMPILE_FLAGS \"-DCMARK_GFM_STATIC_DEFINE -DCMARK_GFM_EXTENSIONS_STATIC_DEFINE\")\n\n# Check integrity of node structure when compiled as debug:\nset(CMAKE_C_FLAGS_DEBUG \"${CMAKE_C_FLAGS_DEBUG} -DCMARK_DEBUG_NODES -DDEBUG\")\nset(CMAKE_LINKER_DEBUG \"${CMAKE_LINKER_FLAGS_DEBUG}\")\n\nset(CMAKE_C_FLAGS_PROFILE \"${CMAKE_C_FLAGS_RELEASE} -pg\")\nset(CMAKE_LINKER_PROFILE \"${CMAKE_LINKER_FLAGS_RELEASE} -pg\")\n\n# -fvisibility=hidden\nset(CMAKE_C_VISIBILITY_PRESET hidden)\nset(CMAKE_VISIBILITY_INLINES_HIDDEN 1)\n\nif (CMARK_SHARED)\n  add_library(${LIBRARY} SHARED ${LIBRARY_SOURCES})\n  # Include minor version and patch level in soname for now.\n  set_target_properties(${LIBRARY} PROPERTIES\n    OUTPUT_NAME \"cmark-gfm\"\n    SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}.gfm.${PROJECT_VERSION_GFM}\n    VERSION ${PROJECT_VERSION})\n\n  set_property(TARGET ${LIBRARY}\n    APPEND PROPERTY MACOSX_RPATH true)\n\n  # Avoid name clash between PROGRAM and LIBRARY pdb files.\n  set_target_properties(${LIBRARY} PROPERTIES PDB_NAME cmark-gfm_dll)\n\n  generate_export_header(${LIBRARY}\n    BASE_NAME ${PROJECT_NAME})\n\n  list(APPEND CMARK_INSTALL ${LIBRARY})\nendif()\n\nif (CMARK_STATIC)\n  add_library(${STATICLIBRARY} STATIC ${LIBRARY_SOURCES})\n  set_target_properties(${STATICLIBRARY} PROPERTIES\n    COMPILE_FLAGS -DCMARK_GFM_STATIC_DEFINE\n    POSITION_INDEPENDENT_CODE ON)\n\n  if (MSVC)\n    set_target_properties(${STATICLIBRARY} PROPERTIES\n      OUTPUT_NAME \"cmark-gfm_static\"\n      VERSION ${PROJECT_VERSION})\n  else()\n    set_target_properties(${STATICLIBRARY} PROPERTIES\n      OUTPUT_NAME \"cmark-gfm\"\n      VERSION ${PROJECT_VERSION})\n  endif(MSVC)\n\n  if (NOT CMARK_SHARED)\n    generate_export_header(${STATICLIBRARY}\n      BASE_NAME ${PROJECT_NAME})\n  endif()\n\n  list(APPEND CMARK_INSTALL ${STATICLIBRARY})\nendif()\n\nif (MSVC)\n  set_property(TARGET ${PROGRAM}\n    APPEND PROPERTY LINK_FLAGS /INCREMENTAL:NO)\nendif(MSVC)\n\nif(NOT MSVC OR CMAKE_HOST_SYSTEM_NAME STREQUAL Windows)\n  set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS ON)\n  include(InstallRequiredSystemLibraries)\nendif()\n\nset(libdir lib${LIB_SUFFIX})\n\ninstall(TARGETS ${PROGRAM} ${CMARK_INSTALL}\n  EXPORT cmark-gfm\n  RUNTIME DESTINATION bin\n  LIBRARY DESTINATION ${libdir}\n  ARCHIVE DESTINATION ${libdir}\n  )\n\nif(CMARK_SHARED OR CMARK_STATIC)\n  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libcmark-gfm.pc.in\n    ${CMAKE_CURRENT_BINARY_DIR}/libcmark-gfm.pc @ONLY)\n  install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libcmark-gfm.pc\n    DESTINATION ${libdir}/pkgconfig)\n\n  install(FILES\n    cmark-gfm.h\n    cmark-gfm-extension_api.h\n    ${CMAKE_CURRENT_BINARY_DIR}/cmark-gfm_export.h\n    ${CMAKE_CURRENT_BINARY_DIR}/cmark-gfm_version.h\n    DESTINATION include\n    )\n\n  install(EXPORT cmark-gfm DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake)\nendif()\n\n# Feature tests\ninclude(CheckIncludeFile)\ninclude(CheckCSourceCompiles)\ninclude(CheckCSourceRuns)\ninclude(CheckSymbolExists)\nCHECK_INCLUDE_FILE(stdbool.h HAVE_STDBOOL_H)\nCHECK_C_SOURCE_COMPILES(\n  \"int main() { __builtin_expect(0,0); return 0; }\"\n  HAVE___BUILTIN_EXPECT)\nCHECK_C_SOURCE_COMPILES(\"\n  int f(void) __attribute__ (());\n  int main() { return 0; }\n\" HAVE___ATTRIBUTE__)\n\nCONFIGURE_FILE(\n  ${CMAKE_CURRENT_SOURCE_DIR}/config.h.in\n  ${CMAKE_CURRENT_BINARY_DIR}/config.h)\n\n# Always compile with warnings\nif(MSVC)\n  # Force to always compile with W4\n  if(CMAKE_CXX_FLAGS MATCHES \"/W[0-4]\")\n    string(REGEX REPLACE \"/W[0-4]\" \"/W4\" CMAKE_C_FLAGS \"${CMAKE_C_FLAGS}\")\n  else()\n    set(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} /W4\")\n  endif()\n  set(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} /WX /wd4706 /wd4204 /wd4221 /wd4100 /D_CRT_SECURE_NO_WARNINGS\")\nelseif(CMAKE_COMPILER_IS_GNUCC OR \"${CMAKE_CXX_COMPILER_ID}\" STREQUAL \"Clang\")\n  set(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} -Wall -Wextra -Wno-unused-parameter -std=c99 -pedantic\")\nendif()\n\n# Compile as C++ under MSVC older than 12.0\nif(MSVC AND MSVC_VERSION LESS 1800)\n  set(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} /TP\")\nendif()\n\nif(CMAKE_BUILD_TYPE STREQUAL \"Ubsan\")\n  set(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} -fsanitize=undefined\")\nendif()\n\nif(CMARK_LIB_FUZZER)\n  set(FUZZ_HARNESS \"cmark-fuzz\")\n  add_executable(${FUZZ_HARNESS} ../test/cmark-fuzz.c ${LIBRARY_SOURCES})\n  target_link_libraries(${FUZZ_HARNESS} \"${CMAKE_LIB_FUZZER_PATH}\")\n  set(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} -fsanitize-coverage=trace-pc-guard\")\n\n  # cmark is written in C but the libFuzzer runtime is written in C++ which\n  # needs to link against the C++ runtime. Explicitly link it into cmark-fuzz\n  set_target_properties(${FUZZ_HARNESS} PROPERTIES LINK_FLAGS \"-lstdc++\")\nendif()\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/arena.c",
    "content": "#include <stdlib.h>\n#include <string.h>\n#include <stdint.h>\n#include \"cmark-gfm.h\"\n#include \"cmark-gfm-extension_api.h\"\n\nstatic struct arena_chunk {\n  size_t sz, used;\n  uint8_t push_point;\n  void *ptr;\n  struct arena_chunk *prev;\n} *A = NULL;\n\nstatic struct arena_chunk *alloc_arena_chunk(size_t sz, struct arena_chunk *prev) {\n  struct arena_chunk *c = (struct arena_chunk *)calloc(1, sizeof(*c));\n  if (!c)\n    abort();\n  c->sz = sz;\n  c->ptr = calloc(1, sz);\n  if (!c->ptr)\n    abort();\n  c->prev = prev;\n  return c;\n}\n\nvoid cmark_arena_push(void) {\n  if (!A)\n    return;\n  A->push_point = 1;\n  A = alloc_arena_chunk(10240, A);\n}\n\nint cmark_arena_pop(void) {\n  if (!A)\n    return 0;\n  while (A && !A->push_point) {\n    free(A->ptr);\n    struct arena_chunk *n = A->prev;\n    free(A);\n    A = n;\n  }\n  if (A)\n    A->push_point = 0;\n  return 1;\n}\n\nstatic void init_arena(void) {\n  A = alloc_arena_chunk(4 * 1048576, NULL);\n}\n\nvoid cmark_arena_reset(void) {\n  while (A) {\n    free(A->ptr);\n    struct arena_chunk *n = A->prev;\n    free(A);\n    A = n;\n  }\n}\n\nstatic void *arena_calloc(size_t nmem, size_t size) {\n  if (!A)\n    init_arena();\n\n  size_t sz = nmem * size + sizeof(size_t);\n\n  // Round allocation sizes to largest integer size to\n  // ensure returned memory is correctly aligned\n  const size_t align = sizeof(size_t) - 1;\n  sz = (sz + align) & ~align;\n\n  struct arena_chunk *chunk;\n  if (sz > A->sz) {\n    A->prev = chunk = alloc_arena_chunk(sz, A->prev);\n  } else if (sz > A->sz - A->used) {\n    A = chunk = alloc_arena_chunk(A->sz + A->sz / 2, A);\n  } else {\n    chunk = A;\n  }\n  void *ptr = (uint8_t *) chunk->ptr + chunk->used;\n  chunk->used += sz;\n  *((size_t *) ptr) = sz - sizeof(size_t);\n  return (uint8_t *) ptr + sizeof(size_t);\n}\n\nstatic void *arena_realloc(void *ptr, size_t size) {\n  if (!A)\n    init_arena();\n\n  void *new_ptr = arena_calloc(1, size);\n  if (ptr)\n    memcpy(new_ptr, ptr, ((size_t *) ptr)[-1]);\n  return new_ptr;\n}\n\nstatic void arena_free(void *ptr) {\n  (void) ptr;\n  /* no-op */\n}\n\ncmark_mem CMARK_ARENA_MEM_ALLOCATOR = {arena_calloc, arena_realloc, arena_free};\n\ncmark_mem *cmark_get_arena_mem_allocator(void) {\n  return &CMARK_ARENA_MEM_ALLOCATOR;\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/blocks.c",
    "content": "/**\n * Block parsing implementation.\n *\n * For a high-level overview of the block parsing process,\n * see http://spec.commonmark.org/0.24/#phase-1-block-structure\n */\n\n#include <stdlib.h>\n#include <assert.h>\n#include <stdio.h>\n#include <limits.h>\n\n#include \"cmark_ctype.h\"\n#include \"syntax_extension.h\"\n#include \"config.h\"\n#include \"parser.h\"\n#include \"cmark-gfm.h\"\n#include \"node.h\"\n#include \"references.h\"\n#include \"utf8.h\"\n#include \"scanners.h\"\n#include \"inlines.h\"\n#include \"houdini.h\"\n#include \"buffer.h\"\n#include \"footnotes.h\"\n\n#define CODE_INDENT 4\n#define TAB_STOP 4\n\n/**\n * Very deeply nested lists can cause quadratic performance issues.\n * This constant is used in open_new_blocks() to limit the nesting\n * depth. It is unlikely that a non-contrived markdown document will\n * be nested this deeply.\n */\n#define MAX_LIST_DEPTH 100\n\n#ifndef MIN\n#define MIN(x, y) ((x < y) ? x : y)\n#endif\n\n#define peek_at(i, n) (i)->data[n]\n\nstatic bool S_last_line_blank(const cmark_node *node) {\n  return (node->flags & CMARK_NODE__LAST_LINE_BLANK) != 0;\n}\n\nstatic bool S_last_line_checked(const cmark_node *node) {\n  return (node->flags & CMARK_NODE__LAST_LINE_CHECKED) != 0;\n}\n\nstatic CMARK_INLINE cmark_node_type S_type(const cmark_node *node) {\n  return (cmark_node_type)node->type;\n}\n\nstatic void S_set_last_line_blank(cmark_node *node, bool is_blank) {\n  if (is_blank)\n    node->flags |= CMARK_NODE__LAST_LINE_BLANK;\n  else\n    node->flags &= ~CMARK_NODE__LAST_LINE_BLANK;\n}\n\nstatic void S_set_last_line_checked(cmark_node *node) {\n  node->flags |= CMARK_NODE__LAST_LINE_CHECKED;\n}\n\nstatic CMARK_INLINE bool S_is_line_end_char(char c) {\n  return (c == '\\n' || c == '\\r');\n}\n\nstatic CMARK_INLINE bool S_is_space_or_tab(char c) {\n  return (c == ' ' || c == '\\t');\n}\n\nstatic void S_parser_feed(cmark_parser *parser, const unsigned char *buffer,\n                          size_t len, bool eof);\n\nstatic void S_process_line(cmark_parser *parser, const unsigned char *buffer,\n                           bufsize_t bytes);\n\nstatic cmark_node *make_block(cmark_mem *mem, cmark_node_type tag,\n                              int start_line, int start_column) {\n  cmark_node *e;\n\n  e = (cmark_node *)mem->calloc(1, sizeof(*e));\n  cmark_strbuf_init(mem, &e->content, 32);\n  e->type = (uint16_t)tag;\n  e->flags = CMARK_NODE__OPEN;\n  e->start_line = start_line;\n  e->start_column = start_column;\n  e->end_line = start_line;\n\n  return e;\n}\n\n// Create a root document node.\nstatic cmark_node *make_document(cmark_mem *mem) {\n  cmark_node *e = make_block(mem, CMARK_NODE_DOCUMENT, 1, 1);\n  return e;\n}\n\nint cmark_parser_attach_syntax_extension(cmark_parser *parser,\n                                         cmark_syntax_extension *extension) {\n  parser->syntax_extensions = cmark_llist_append(parser->mem, parser->syntax_extensions, extension);\n  if (extension->match_inline || extension->insert_inline_from_delim) {\n    parser->inline_syntax_extensions = cmark_llist_append(\n      parser->mem, parser->inline_syntax_extensions, extension);\n  }\n\n  return 1;\n}\n\nstatic void cmark_parser_dispose(cmark_parser *parser) {\n  if (parser->root)\n    cmark_node_free(parser->root);\n\n  if (parser->refmap)\n    cmark_map_free(parser->refmap);\n}\n\nstatic void cmark_parser_reset(cmark_parser *parser) {\n  cmark_llist *saved_exts = parser->syntax_extensions;\n  cmark_llist *saved_inline_exts = parser->inline_syntax_extensions;\n  int saved_options = parser->options;\n  cmark_mem *saved_mem = parser->mem;\n\n  cmark_parser_dispose(parser);\n\n  memset(parser, 0, sizeof(cmark_parser));\n  parser->mem = saved_mem;\n\n  cmark_strbuf_init(parser->mem, &parser->curline, 256);\n  cmark_strbuf_init(parser->mem, &parser->linebuf, 0);\n\n  cmark_node *document = make_document(parser->mem);\n\n  parser->refmap = cmark_reference_map_new(parser->mem);\n  parser->root = document;\n  parser->current = document;\n\n  parser->syntax_extensions = saved_exts;\n  parser->inline_syntax_extensions = saved_inline_exts;\n  parser->options = saved_options;\n}\n\ncmark_parser *cmark_parser_new_with_mem(int options, cmark_mem *mem) {\n  cmark_parser *parser = (cmark_parser *)mem->calloc(1, sizeof(cmark_parser));\n  parser->mem = mem;\n  parser->options = options;\n  cmark_parser_reset(parser);\n  return parser;\n}\n\ncmark_parser *cmark_parser_new(int options) {\n  extern cmark_mem CMARK_DEFAULT_MEM_ALLOCATOR;\n  return cmark_parser_new_with_mem(options, &CMARK_DEFAULT_MEM_ALLOCATOR);\n}\n\nvoid cmark_parser_free(cmark_parser *parser) {\n  cmark_mem *mem = parser->mem;\n  cmark_parser_dispose(parser);\n  cmark_strbuf_free(&parser->curline);\n  cmark_strbuf_free(&parser->linebuf);\n  cmark_llist_free(parser->mem, parser->syntax_extensions);\n  cmark_llist_free(parser->mem, parser->inline_syntax_extensions);\n  mem->free(parser);\n}\n\nstatic cmark_node *finalize(cmark_parser *parser, cmark_node *b);\n\n// Returns true if line has only space characters, else false.\nstatic bool is_blank(cmark_strbuf *s, bufsize_t offset) {\n  while (offset < s->size) {\n    switch (s->ptr[offset]) {\n    case '\\r':\n    case '\\n':\n      return true;\n    case ' ':\n      offset++;\n      break;\n    case '\\t':\n      offset++;\n      break;\n    default:\n      return false;\n    }\n  }\n\n  return true;\n}\n\nstatic CMARK_INLINE bool accepts_lines(cmark_node_type block_type) {\n  return (block_type == CMARK_NODE_PARAGRAPH ||\n          block_type == CMARK_NODE_HEADING ||\n          block_type == CMARK_NODE_CODE_BLOCK);\n}\n\nstatic CMARK_INLINE bool contains_inlines(cmark_node *node) {\n  if (node->extension && node->extension->contains_inlines_func) {\n    return node->extension->contains_inlines_func(node->extension, node) != 0;\n  }\n\n  return (node->type == CMARK_NODE_PARAGRAPH ||\n          node->type == CMARK_NODE_HEADING);\n}\n\nstatic void add_line(cmark_node *node, cmark_chunk *ch, cmark_parser *parser) {\n  int chars_to_tab;\n  int i;\n  assert(node->flags & CMARK_NODE__OPEN);\n  if (parser->partially_consumed_tab) {\n    parser->offset += 1; // skip over tab\n    // add space characters:\n    chars_to_tab = TAB_STOP - (parser->column % TAB_STOP);\n    for (i = 0; i < chars_to_tab; i++) {\n      cmark_strbuf_putc(&node->content, ' ');\n    }\n  }\n  cmark_strbuf_put(&node->content, ch->data + parser->offset,\n                   ch->len - parser->offset);\n}\n\nstatic void remove_trailing_blank_lines(cmark_strbuf *ln) {\n  bufsize_t i;\n  unsigned char c;\n\n  for (i = ln->size - 1; i >= 0; --i) {\n    c = ln->ptr[i];\n\n    if (c != ' ' && c != '\\t' && !S_is_line_end_char(c))\n      break;\n  }\n\n  if (i < 0) {\n    cmark_strbuf_clear(ln);\n    return;\n  }\n\n  for (; i < ln->size; ++i) {\n    c = ln->ptr[i];\n\n    if (!S_is_line_end_char(c))\n      continue;\n\n    cmark_strbuf_truncate(ln, i);\n    break;\n  }\n}\n\n// Check to see if a node ends with a blank line, descending\n// if needed into lists and sublists.\nstatic bool S_ends_with_blank_line(cmark_node *node) {\n  if (S_last_line_checked(node)) {\n    return(S_last_line_blank(node));\n  } else if ((S_type(node) == CMARK_NODE_LIST ||\n              S_type(node) == CMARK_NODE_ITEM) && node->last_child) {\n    S_set_last_line_checked(node);\n    return(S_ends_with_blank_line(node->last_child));\n  } else {\n    S_set_last_line_checked(node);\n    return (S_last_line_blank(node));\n  }\n}\n\n// returns true if content remains after link defs are resolved.\nstatic bool resolve_reference_link_definitions(\n\t\tcmark_parser *parser,\n                cmark_node *b) {\n  bufsize_t pos;\n  cmark_strbuf *node_content = &b->content;\n  cmark_chunk chunk = {node_content->ptr, node_content->size, 0};\n  while (chunk.len && chunk.data[0] == '[' &&\n         (pos = cmark_parse_reference_inline(parser->mem, &chunk,\n\t\t\t\t\t     parser->refmap))) {\n\n    chunk.data += pos;\n    chunk.len -= pos;\n  }\n  cmark_strbuf_drop(node_content, (node_content->size - chunk.len));\n  return !is_blank(&b->content, 0);\n}\n\nstatic cmark_node *finalize(cmark_parser *parser, cmark_node *b) {\n  bufsize_t pos;\n  cmark_node *item;\n  cmark_node *subitem;\n  cmark_node *parent;\n  bool has_content;\n\n  parent = b->parent;\n  assert(b->flags &\n         CMARK_NODE__OPEN); // shouldn't call finalize on closed blocks\n  b->flags &= ~CMARK_NODE__OPEN;\n\n  if (parser->curline.size == 0) {\n    // end of input - line number has not been incremented\n    b->end_line = parser->line_number;\n    b->end_column = parser->last_line_length;\n  } else if (S_type(b) == CMARK_NODE_DOCUMENT ||\n             (S_type(b) == CMARK_NODE_CODE_BLOCK && b->as.code.fenced) ||\n             (S_type(b) == CMARK_NODE_HEADING && b->as.heading.setext)) {\n    b->end_line = parser->line_number;\n    b->end_column = parser->curline.size;\n    if (b->end_column && parser->curline.ptr[b->end_column - 1] == '\\n')\n      b->end_column -= 1;\n    if (b->end_column && parser->curline.ptr[b->end_column - 1] == '\\r')\n      b->end_column -= 1;\n  } else {\n    b->end_line = parser->line_number - 1;\n    b->end_column = parser->last_line_length;\n  }\n\n  cmark_strbuf *node_content = &b->content;\n\n  switch (S_type(b)) {\n  case CMARK_NODE_PARAGRAPH:\n  {\n    has_content = resolve_reference_link_definitions(parser, b);\n    if (!has_content) {\n      // remove blank node (former reference def)\n      cmark_node_free(b);\n    }\n    break;\n  }\n\n  case CMARK_NODE_CODE_BLOCK:\n    if (!b->as.code.fenced) { // indented code\n      remove_trailing_blank_lines(node_content);\n      cmark_strbuf_putc(node_content, '\\n');\n    } else {\n      // first line of contents becomes info\n      for (pos = 0; pos < node_content->size; ++pos) {\n        if (S_is_line_end_char(node_content->ptr[pos]))\n          break;\n      }\n      assert(pos < node_content->size);\n\n      cmark_strbuf tmp = CMARK_BUF_INIT(parser->mem);\n      houdini_unescape_html_f(&tmp, node_content->ptr, pos);\n      cmark_strbuf_trim(&tmp);\n      cmark_strbuf_unescape(&tmp);\n      b->as.code.info = cmark_chunk_buf_detach(&tmp);\n\n      if (node_content->ptr[pos] == '\\r')\n        pos += 1;\n      if (node_content->ptr[pos] == '\\n')\n        pos += 1;\n      cmark_strbuf_drop(node_content, pos);\n    }\n    b->as.code.literal = cmark_chunk_buf_detach(node_content);\n    break;\n\n  case CMARK_NODE_HTML_BLOCK:\n    b->as.literal = cmark_chunk_buf_detach(node_content);\n    break;\n\n  case CMARK_NODE_LIST:      // determine tight/loose status\n    b->as.list.tight = true; // tight by default\n    item = b->first_child;\n\n    while (item) {\n      // check for non-final non-empty list item ending with blank line:\n      if (S_last_line_blank(item) && item->next) {\n        b->as.list.tight = false;\n        break;\n      }\n      // recurse into children of list item, to see if there are\n      // spaces between them:\n      subitem = item->first_child;\n      while (subitem) {\n        if ((item->next || subitem->next) &&\n            S_ends_with_blank_line(subitem)) {\n          b->as.list.tight = false;\n          break;\n        }\n        subitem = subitem->next;\n      }\n      if (!(b->as.list.tight)) {\n        break;\n      }\n      item = item->next;\n    }\n\n    break;\n\n  default:\n    break;\n  }\n\n  return parent;\n}\n\n// Add a node as child of another.  Return pointer to child.\nstatic cmark_node *add_child(cmark_parser *parser, cmark_node *parent,\n                             cmark_node_type block_type, int start_column) {\n  assert(parent);\n\n  // if 'parent' isn't the kind of node that can accept this child,\n  // then back up til we hit a node that can.\n  while (!cmark_node_can_contain_type(parent, block_type)) {\n    parent = finalize(parser, parent);\n  }\n\n  cmark_node *child =\n      make_block(parser->mem, block_type, parser->line_number, start_column);\n  child->parent = parent;\n\n  if (parent->last_child) {\n    parent->last_child->next = child;\n    child->prev = parent->last_child;\n  } else {\n    parent->first_child = child;\n    child->prev = NULL;\n  }\n  parent->last_child = child;\n  return child;\n}\n\nvoid cmark_manage_extensions_special_characters(cmark_parser *parser, int add) {\n  cmark_llist *tmp_ext;\n\n  for (tmp_ext = parser->inline_syntax_extensions; tmp_ext; tmp_ext=tmp_ext->next) {\n    cmark_syntax_extension *ext = (cmark_syntax_extension *) tmp_ext->data;\n    cmark_llist *tmp_char;\n    for (tmp_char = ext->special_inline_chars; tmp_char; tmp_char=tmp_char->next) {\n      unsigned char c = (unsigned char)(size_t)tmp_char->data;\n      if (add)\n        cmark_inlines_add_special_character(c, ext->emphasis);\n      else\n        cmark_inlines_remove_special_character(c, ext->emphasis);\n    }\n  }\n}\n\n// Walk through node and all children, recursively, parsing\n// string content into inline content where appropriate.\nstatic void process_inlines(cmark_parser *parser,\n                            cmark_map *refmap, int options) {\n  cmark_iter *iter = cmark_iter_new(parser->root);\n  cmark_node *cur;\n  cmark_event_type ev_type;\n\n  cmark_manage_extensions_special_characters(parser, true);\n\n  while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {\n    cur = cmark_iter_get_node(iter);\n    if (ev_type == CMARK_EVENT_ENTER) {\n      if (contains_inlines(cur)) {\n        cmark_parse_inlines(parser, cur, refmap, options);\n      }\n    }\n  }\n\n  cmark_manage_extensions_special_characters(parser, false);\n\n  cmark_iter_free(iter);\n}\n\nstatic int sort_footnote_by_ix(const void *_a, const void *_b) {\n  cmark_footnote *a = *(cmark_footnote **)_a;\n  cmark_footnote *b = *(cmark_footnote **)_b;\n  return (int)a->ix - (int)b->ix;\n}\n\nstatic void process_footnotes(cmark_parser *parser) {\n  // * Collect definitions in a map.\n  // * Iterate the references in the document in order, assigning indices to\n  //   definitions in the order they're seen.\n  // * Write out the footnotes at the bottom of the document in index order.\n\n  cmark_map *map = cmark_footnote_map_new(parser->mem);\n\n  cmark_iter *iter = cmark_iter_new(parser->root);\n  cmark_node *cur;\n  cmark_event_type ev_type;\n\n  while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {\n    cur = cmark_iter_get_node(iter);\n    if (ev_type == CMARK_EVENT_EXIT && cur->type == CMARK_NODE_FOOTNOTE_DEFINITION) {\n      cmark_footnote_create(map, cur);\n    }\n  }\n\n  cmark_iter_free(iter);\n  iter = cmark_iter_new(parser->root);\n  unsigned int ix = 0;\n\n  while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {\n    cur = cmark_iter_get_node(iter);\n    if (ev_type == CMARK_EVENT_EXIT && cur->type == CMARK_NODE_FOOTNOTE_REFERENCE) {\n      cmark_footnote *footnote = (cmark_footnote *)cmark_map_lookup(map, &cur->as.literal);\n      if (footnote) {\n        if (!footnote->ix)\n          footnote->ix = ++ix;\n\n        // store a reference to this footnote reference's footnote definition\n        // this is used by renderers when generating label ids\n        cur->parent_footnote_def = footnote->node;\n\n        // keep track of a) count of how many times this footnote def has been\n        // referenced, and b) which reference index this footnote ref is at.\n        // this is used by renderers when generating links and backreferences.\n        cur->footnote.ref_ix = ++footnote->node->footnote.def_count;\n\n        char n[32];\n        snprintf(n, sizeof(n), \"%d\", footnote->ix);\n        cmark_chunk_free(parser->mem, &cur->as.literal);\n        cmark_strbuf buf = CMARK_BUF_INIT(parser->mem);\n        cmark_strbuf_puts(&buf, n);\n\n        cur->as.literal = cmark_chunk_buf_detach(&buf);\n      } else if ((parser->options & CMARK_OPT_FOOTNOTES_WITHOUT_DEFINITION)) {\n          cur->footnote.ref_ix = ++ix;\n      } else {\n        cmark_node *text = (cmark_node *)parser->mem->calloc(1, sizeof(*text));\n        cmark_strbuf_init(parser->mem, &text->content, 0);\n        text->type = (uint16_t) CMARK_NODE_TEXT;\n\n        cmark_strbuf buf = CMARK_BUF_INIT(parser->mem);\n        cmark_strbuf_puts(&buf, \"[^\");\n        cmark_strbuf_put(&buf, cur->as.literal.data, cur->as.literal.len);\n        cmark_strbuf_putc(&buf, ']');\n\n        text->as.literal = cmark_chunk_buf_detach(&buf);\n        cmark_node_insert_after(cur, text);\n        cmark_node_free(cur);\n      }\n    }\n  }\n\n  cmark_iter_free(iter);\n\n  if (map->sorted) {\n    qsort(map->sorted, map->size, sizeof(cmark_map_entry *), sort_footnote_by_ix);\n    for (unsigned int i = 0; i < map->size; ++i) {\n      cmark_footnote *footnote = (cmark_footnote *)map->sorted[i];\n      if (!footnote->ix) {\n        cmark_node_unlink(footnote->node);\n        continue;\n      }\n      cmark_node_append_child(parser->root, footnote->node);\n      footnote->node = NULL;\n    }\n  }\n\n  cmark_unlink_footnotes_map(map);\n  cmark_map_free(map);\n}\n\n// Attempts to parse a list item marker (bullet or enumerated).\n// On success, returns length of the marker, and populates\n// data with the details.  On failure, returns 0.\nstatic bufsize_t parse_list_marker(cmark_mem *mem, cmark_chunk *input,\n                                   bufsize_t pos, bool interrupts_paragraph,\n                                   cmark_list **dataptr) {\n  unsigned char c;\n  bufsize_t startpos;\n  cmark_list *data;\n  bufsize_t i;\n\n  startpos = pos;\n  c = peek_at(input, pos);\n\n  if (c == '*' || c == '-' || c == '+') {\n    pos++;\n    if (!cmark_isspace(peek_at(input, pos))) {\n      return 0;\n    }\n\n    if (interrupts_paragraph) {\n      i = pos;\n      // require non-blank content after list marker:\n      while (S_is_space_or_tab(peek_at(input, i))) {\n        i++;\n      }\n      if (peek_at(input, i) == '\\n') {\n        return 0;\n      }\n    }\n\n    data = (cmark_list *)mem->calloc(1, sizeof(*data));\n    data->marker_offset = 0; // will be adjusted later\n    data->list_type = CMARK_BULLET_LIST;\n    data->bullet_char = c;\n    data->start = 0;\n    data->delimiter = CMARK_NO_DELIM;\n    data->tight = false;\n  } else if (cmark_isdigit(c)) {\n    int start = 0;\n    int digits = 0;\n\n    do {\n      start = (10 * start) + (peek_at(input, pos) - '0');\n      pos++;\n      digits++;\n      // We limit to 9 digits to avoid overflow,\n      // assuming max int is 2^31 - 1\n      // This also seems to be the limit for 'start' in some browsers.\n    } while (digits < 9 && cmark_isdigit(peek_at(input, pos)));\n\n    if (interrupts_paragraph && start != 1) {\n      return 0;\n    }\n    c = peek_at(input, pos);\n    if (c == '.' || c == ')') {\n      pos++;\n      if (!cmark_isspace(peek_at(input, pos))) {\n        return 0;\n      }\n      if (interrupts_paragraph) {\n        // require non-blank content after list marker:\n        i = pos;\n        while (S_is_space_or_tab(peek_at(input, i))) {\n          i++;\n        }\n        if (S_is_line_end_char(peek_at(input, i))) {\n          return 0;\n        }\n      }\n\n      data = (cmark_list *)mem->calloc(1, sizeof(*data));\n      data->marker_offset = 0; // will be adjusted later\n      data->list_type = CMARK_ORDERED_LIST;\n      data->bullet_char = 0;\n      data->start = start;\n      data->delimiter = (c == '.' ? CMARK_PERIOD_DELIM : CMARK_PAREN_DELIM);\n      data->tight = false;\n    } else {\n      return 0;\n    }\n  } else {\n    return 0;\n  }\n\n  *dataptr = data;\n  return (pos - startpos);\n}\n\n// Return 1 if list item belongs in list, else 0.\nstatic int lists_match(cmark_list *list_data, cmark_list *item_data) {\n  return (list_data->list_type == item_data->list_type &&\n          list_data->delimiter == item_data->delimiter &&\n          // list_data->marker_offset == item_data.marker_offset &&\n          list_data->bullet_char == item_data->bullet_char);\n}\n\nstatic cmark_node *finalize_document(cmark_parser *parser) {\n  while (parser->current != parser->root) {\n    parser->current = finalize(parser, parser->current);\n  }\n\n  finalize(parser, parser->root);\n\n  // Limit total size of extra content created from reference links to\n  // document size to avoid superlinear growth. Always allow 100KB.\n  if (parser->total_size > 100000)\n    parser->refmap->max_ref_size = parser->total_size;\n  else\n    parser->refmap->max_ref_size = 100000;\n\n  process_inlines(parser, parser->refmap, parser->options);\n  if (parser->options & CMARK_OPT_FOOTNOTES)\n    process_footnotes(parser);\n\n  return parser->root;\n}\n\ncmark_node *cmark_parse_file(FILE *f, int options) {\n  unsigned char buffer[4096];\n  cmark_parser *parser = cmark_parser_new(options);\n  size_t bytes;\n  cmark_node *document;\n\n  while ((bytes = fread(buffer, 1, sizeof(buffer), f)) > 0) {\n    bool eof = bytes < sizeof(buffer);\n    S_parser_feed(parser, buffer, bytes, eof);\n    if (eof) {\n      break;\n    }\n  }\n\n  document = cmark_parser_finish(parser);\n  cmark_parser_free(parser);\n  return document;\n}\n\ncmark_node *cmark_parse_document(const char *buffer, size_t len, int options) {\n    cmark_parser *parser = cmark_parser_new(options);\n    cmark_parser_attach_syntax_extension(parser, cmark_find_syntax_extension(\"table\"));\n  // cmark_parser_attach_syntax_extension(parser, cmark_find_syntax_extension(\"autolink\"));\n    cmark_parser_attach_syntax_extension(parser, cmark_find_syntax_extension(\"strikethrough\"));\n    cmark_parser_attach_syntax_extension(parser, cmark_find_syntax_extension(\"tagfilter\"));\n    cmark_parser_attach_syntax_extension(parser, cmark_find_syntax_extension(\"math\"));\n    cmark_parser_attach_syntax_extension(parser, cmark_find_syntax_extension(\"emoji\"));\n    \n    cmark_parser_attach_syntax_extension(parser, cmark_find_syntax_extension(\"tasklist\"));\n   \n    cmark_node *document;\n\n    S_parser_feed(parser, (const unsigned char *)buffer, len, true);\n\n    document = cmark_parser_finish(parser);\n    cmark_parser_free(parser);\n    return document;\n}\n\nvoid cmark_parser_feed(cmark_parser *parser, const char *buffer, size_t len) {\n  S_parser_feed(parser, (const unsigned char *)buffer, len, false);\n}\n\nvoid cmark_parser_feed_reentrant(cmark_parser *parser, const char *buffer, size_t len) {\n  cmark_strbuf saved_linebuf;\n\n  cmark_strbuf_init(parser->mem, &saved_linebuf, 0);\n  cmark_strbuf_puts(&saved_linebuf, cmark_strbuf_cstr(&parser->linebuf));\n  cmark_strbuf_clear(&parser->linebuf);\n\n  S_parser_feed(parser, (const unsigned char *)buffer, len, true);\n\n  cmark_strbuf_sets(&parser->linebuf, cmark_strbuf_cstr(&saved_linebuf));\n  cmark_strbuf_free(&saved_linebuf);\n}\n\nstatic void S_parser_feed(cmark_parser *parser, const unsigned char *buffer,\n                          size_t len, bool eof) {\n  const unsigned char *end = buffer + len;\n  static const uint8_t repl[] = {239, 191, 189};\n\n  if (len > UINT_MAX - parser->total_size)\n    parser->total_size = UINT_MAX;\n  else\n    parser->total_size += len;\n\n  if (parser->last_buffer_ended_with_cr && *buffer == '\\n') {\n    // skip NL if last buffer ended with CR ; see #117\n    buffer++;\n  }\n  parser->last_buffer_ended_with_cr = false;\n  while (buffer < end) {\n    const unsigned char *eol;\n    bufsize_t chunk_len;\n    bool process = false;\n    for (eol = buffer; eol < end; ++eol) {\n      if (S_is_line_end_char(*eol)) {\n        process = true;\n        break;\n      }\n      if (*eol == '\\0' && eol < end) {\n        break;\n      }\n    }\n    if (eol >= end && eof) {\n      process = true;\n    }\n\n    chunk_len = (bufsize_t)(eol - buffer);\n    if (process) {\n      if (parser->linebuf.size > 0) {\n        cmark_strbuf_put(&parser->linebuf, buffer, chunk_len);\n        S_process_line(parser, parser->linebuf.ptr, parser->linebuf.size);\n        cmark_strbuf_clear(&parser->linebuf);\n      } else {\n        S_process_line(parser, buffer, chunk_len);\n      }\n    } else {\n      if (eol < end && *eol == '\\0') {\n        // omit NULL byte\n        cmark_strbuf_put(&parser->linebuf, buffer, chunk_len);\n        // add replacement character\n        cmark_strbuf_put(&parser->linebuf, repl, 3);\n      } else {\n        cmark_strbuf_put(&parser->linebuf, buffer, chunk_len);\n      }\n    }\n\n    buffer += chunk_len;\n    if (buffer < end) {\n      if (*buffer == '\\0') {\n        // skip over NULL\n        buffer++;\n      } else {\n        // skip over line ending characters\n        if (*buffer == '\\r') {\n          buffer++;\n          if (buffer == end)\n            parser->last_buffer_ended_with_cr = true;\n        }\n        if (buffer < end && *buffer == '\\n')\n          buffer++;\n      }\n    }\n  }\n}\n\nstatic void chop_trailing_hashtags(cmark_chunk *ch) {\n  bufsize_t n, orig_n;\n\n  cmark_chunk_rtrim(ch);\n  orig_n = n = ch->len - 1;\n\n  // if string ends in space followed by #s, remove these:\n  while (n >= 0 && peek_at(ch, n) == '#')\n    n--;\n\n  // Check for a space before the final #s:\n  if (n != orig_n && n >= 0 && S_is_space_or_tab(peek_at(ch, n))) {\n    ch->len = n;\n    cmark_chunk_rtrim(ch);\n  }\n}\n\n// Check for thematic break.  On failure, return 0 and update\n// thematic_break_kill_pos with the index at which the\n// parse fails.  On success, return length of match.\n// \"...three or more hyphens, asterisks,\n// or underscores on a line by themselves. If you wish, you may use\n// spaces between the hyphens or asterisks.\"\nstatic int S_scan_thematic_break(cmark_parser *parser, cmark_chunk *input,\n                                 bufsize_t offset) {\n  bufsize_t i;\n  char c;\n  char nextc = '\\0';\n  int count;\n  i = offset;\n  c = peek_at(input, i);\n  if (!(c == '*' || c == '_' || c == '-')) {\n    parser->thematic_break_kill_pos = i;\n    return 0;\n  }\n  count = 1;\n  while ((nextc = peek_at(input, ++i))) {\n    if (nextc == c) {\n      count++;\n    } else if (nextc != ' ' && nextc != '\\t') {\n      break;\n    }\n  }\n  if (count >= 3 && (nextc == '\\r' || nextc == '\\n')) {\n    return (i - offset) + 1;\n  } else {\n    parser->thematic_break_kill_pos = i;\n    return 0;\n  }\n}\n\n// Find first nonspace character from current offset, setting\n// parser->first_nonspace, parser->first_nonspace_column,\n// parser->indent, and parser->blank. Does not advance parser->offset.\nstatic void S_find_first_nonspace(cmark_parser *parser, cmark_chunk *input) {\n  char c;\n  int chars_to_tab = TAB_STOP - (parser->column % TAB_STOP);\n\n  if (parser->first_nonspace <= parser->offset) {\n    parser->first_nonspace = parser->offset;\n    parser->first_nonspace_column = parser->column;\n    while ((c = peek_at(input, parser->first_nonspace))) {\n      if (c == ' ') {\n        parser->first_nonspace += 1;\n        parser->first_nonspace_column += 1;\n        chars_to_tab = chars_to_tab - 1;\n        if (chars_to_tab == 0) {\n          chars_to_tab = TAB_STOP;\n        }\n      } else if (c == '\\t') {\n        parser->first_nonspace += 1;\n        parser->first_nonspace_column += chars_to_tab;\n        chars_to_tab = TAB_STOP;\n      } else {\n        break;\n      }\n    }\n  }\n\n  parser->indent = parser->first_nonspace_column - parser->column;\n  parser->blank = S_is_line_end_char(peek_at(input, parser->first_nonspace));\n}\n\n// Advance parser->offset and parser->column.  parser->offset is the\n// byte position in input; parser->column is a virtual column number\n// that takes into account tabs. (Multibyte characters are not taken\n// into account, because the Markdown line prefixes we are interested in\n// analyzing are entirely ASCII.)  The count parameter indicates\n// how far to advance the offset.  If columns is true, then count\n// indicates a number of columns; otherwise, a number of bytes.\n// If advancing a certain number of columns partially consumes\n// a tab character, parser->partially_consumed_tab is set to true.\nstatic void S_advance_offset(cmark_parser *parser, cmark_chunk *input,\n                             bufsize_t count, bool columns) {\n  char c;\n  int chars_to_tab;\n  int chars_to_advance;\n  while (count > 0 && (c = peek_at(input, parser->offset))) {\n    if (c == '\\t') {\n      chars_to_tab = TAB_STOP - (parser->column % TAB_STOP);\n      if (columns) {\n        parser->partially_consumed_tab = chars_to_tab > count;\n        chars_to_advance = MIN(count, chars_to_tab);\n        parser->column += chars_to_advance;\n        parser->offset += (parser->partially_consumed_tab ? 0 : 1);\n        count -= chars_to_advance;\n      } else {\n        parser->partially_consumed_tab = false;\n        parser->column += chars_to_tab;\n        parser->offset += 1;\n        count -= 1;\n      }\n    } else {\n      parser->partially_consumed_tab = false;\n      parser->offset += 1;\n      parser->column += 1; // assume ascii; block starts are ascii\n      count -= 1;\n    }\n  }\n}\n\nstatic bool S_last_child_is_open(cmark_node *container) {\n  return container->last_child &&\n         (container->last_child->flags & CMARK_NODE__OPEN);\n}\n\nstatic bool parse_block_quote_prefix(cmark_parser *parser, cmark_chunk *input) {\n  bool res = false;\n  bufsize_t matched = 0;\n\n  matched =\n      parser->indent <= 3 && peek_at(input, parser->first_nonspace) == '>';\n  if (matched) {\n\n    S_advance_offset(parser, input, parser->indent + 1, true);\n\n    if (S_is_space_or_tab(peek_at(input, parser->offset))) {\n      S_advance_offset(parser, input, 1, true);\n    }\n\n    res = true;\n  }\n  return res;\n}\n\nstatic bool parse_footnote_definition_block_prefix(cmark_parser *parser, cmark_chunk *input,\n                                                   cmark_node *container) {\n  if (parser->indent >= 4) {\n    S_advance_offset(parser, input, 4, true);\n    return true;\n  } else if (input->len > 0 && (input->data[0] == '\\n' || (input->data[0] == '\\r' && input->data[1] == '\\n'))) {\n    return true;\n  }\n\n  return false;\n}\n\nstatic bool parse_node_item_prefix(cmark_parser *parser, cmark_chunk *input,\n                                   cmark_node *container) {\n  bool res = false;\n\n  if (parser->indent >=\n      container->as.list.marker_offset + container->as.list.padding) {\n    S_advance_offset(parser, input, container->as.list.marker_offset +\n                                        container->as.list.padding,\n                     true);\n    res = true;\n  } else if (parser->blank && container->first_child != NULL) {\n    // if container->first_child is NULL, then the opening line\n    // of the list item was blank after the list marker; in this\n    // case, we are done with the list item.\n    S_advance_offset(parser, input, parser->first_nonspace - parser->offset,\n                     false);\n    res = true;\n  }\n  return res;\n}\n\nstatic bool parse_code_block_prefix(cmark_parser *parser, cmark_chunk *input,\n                                    cmark_node *container,\n                                    bool *should_continue) {\n  bool res = false;\n\n  if (!container->as.code.fenced) { // indented\n    if (parser->indent >= CODE_INDENT) {\n      S_advance_offset(parser, input, CODE_INDENT, true);\n      res = true;\n    } else if (parser->blank) {\n      S_advance_offset(parser, input, parser->first_nonspace - parser->offset,\n                       false);\n      res = true;\n    }\n  } else { // fenced\n    bufsize_t matched = 0;\n\n    if (parser->indent <= 3 && (peek_at(input, parser->first_nonspace) ==\n                                container->as.code.fence_char)) {\n      matched = scan_close_code_fence(input, parser->first_nonspace);\n    }\n\n    if (matched >= container->as.code.fence_length) {\n      // closing fence - and since we're at\n      // the end of a line, we can stop processing it:\n      *should_continue = false;\n      S_advance_offset(parser, input, matched, false);\n      parser->current = finalize(parser, container);\n    } else {\n      // skip opt. spaces of fence parser->offset\n      int i = container->as.code.fence_offset;\n\n      while (i > 0 && S_is_space_or_tab(peek_at(input, parser->offset))) {\n        S_advance_offset(parser, input, 1, true);\n        i--;\n      }\n      res = true;\n    }\n  }\n\n  return res;\n}\n\nstatic bool parse_html_block_prefix(cmark_parser *parser,\n                                    cmark_node *container) {\n  bool res = false;\n  int html_block_type = container->as.html_block_type;\n\n  assert(html_block_type >= 1 && html_block_type <= 7);\n  switch (html_block_type) {\n  case 1:\n  case 2:\n  case 3:\n  case 4:\n  case 5:\n    // these types of blocks can accept blanks\n    res = true;\n    break;\n  case 6:\n  case 7:\n    res = !parser->blank;\n    break;\n  }\n\n  return res;\n}\n\nstatic bool parse_extension_block(cmark_parser *parser,\n                                  cmark_node *container,\n                                  cmark_chunk *input)\n{\n  bool res = false;\n\n  if (container->extension->last_block_matches) {\n    if (container->extension->last_block_matches(\n        container->extension, parser, input->data, input->len, container))\n      res = true;\n  }\n\n  return res;\n}\n\n/**\n * For each containing node, try to parse the associated line start.\n *\n * Will not close unmatched blocks, as we may have a lazy continuation\n * line -> http://spec.commonmark.org/0.24/#lazy-continuation-line\n *\n * Returns: The last matching node, or NULL\n */\nstatic cmark_node *check_open_blocks(cmark_parser *parser, cmark_chunk *input,\n                                     bool *all_matched) {\n  bool should_continue = true;\n  *all_matched = false;\n  cmark_node *container = parser->root;\n  cmark_node_type cont_type;\n\n  while (S_last_child_is_open(container)) {\n    container = container->last_child;\n    cont_type = S_type(container);\n\n    S_find_first_nonspace(parser, input);\n\n    if (container->extension) {\n      if (!parse_extension_block(parser, container, input))\n        goto done;\n      continue;\n    }\n\n    switch (cont_type) {\n    case CMARK_NODE_BLOCK_QUOTE:\n      if (!parse_block_quote_prefix(parser, input))\n        goto done;\n      break;\n    case CMARK_NODE_ITEM:\n      if (!parse_node_item_prefix(parser, input, container))\n        goto done;\n      break;\n    case CMARK_NODE_CODE_BLOCK:\n      if (!parse_code_block_prefix(parser, input, container, &should_continue))\n        goto done;\n      break;\n    case CMARK_NODE_HEADING:\n      // a heading can never contain more than one line\n      goto done;\n    case CMARK_NODE_HTML_BLOCK:\n      if (!parse_html_block_prefix(parser, container))\n        goto done;\n      break;\n    case CMARK_NODE_PARAGRAPH:\n      if (parser->blank)\n        goto done;\n      break;\n\t\tcase CMARK_NODE_FOOTNOTE_DEFINITION:\n\t\t\tif (!parse_footnote_definition_block_prefix(parser, input, container))\n\t\t\t\tgoto done;\n\t\t\tbreak;\n    default:\n      break;\n    }\n  }\n\n  *all_matched = true;\n\ndone:\n  if (!*all_matched) {\n    container = container->parent; // back up to last matching node\n  }\n\n  if (!should_continue) {\n    container = NULL;\n  }\n\n  return container;\n}\n\nstatic void open_new_blocks(cmark_parser *parser, cmark_node **container,\n                            cmark_chunk *input, bool all_matched) {\n  bool indented;\n  cmark_list *data = NULL;\n  bool maybe_lazy = S_type(parser->current) == CMARK_NODE_PARAGRAPH;\n  cmark_node_type cont_type = S_type(*container);\n  bufsize_t matched = 0;\n  int lev = 0;\n  bool save_partially_consumed_tab;\n  bool has_content;\n  int save_offset;\n  int save_column;\n  size_t depth = 0;\n\n  while (cont_type != CMARK_NODE_CODE_BLOCK &&\n         cont_type != CMARK_NODE_HTML_BLOCK) {\n    depth++;\n    S_find_first_nonspace(parser, input);\n    indented = parser->indent >= CODE_INDENT;\n\n    if (!indented && peek_at(input, parser->first_nonspace) == '>') {\n\n      bufsize_t blockquote_startpos = parser->first_nonspace;\n\n      S_advance_offset(parser, input,\n                       parser->first_nonspace + 1 - parser->offset, false);\n      // optional following character\n      if (S_is_space_or_tab(peek_at(input, parser->offset))) {\n        S_advance_offset(parser, input, 1, true);\n      }\n      *container = add_child(parser, *container, CMARK_NODE_BLOCK_QUOTE,\n                             blockquote_startpos + 1);\n\n    } else if (!indented && (matched = scan_atx_heading_start(\n                                 input, parser->first_nonspace))) {\n      bufsize_t hashpos;\n      int level = 0;\n      bufsize_t heading_startpos = parser->first_nonspace;\n\n      S_advance_offset(parser, input,\n                       parser->first_nonspace + matched - parser->offset,\n                       false);\n      *container = add_child(parser, *container, CMARK_NODE_HEADING,\n                             heading_startpos + 1);\n\n      hashpos = cmark_chunk_strchr(input, '#', parser->first_nonspace);\n\n      while (peek_at(input, hashpos) == '#') {\n        level++;\n        hashpos++;\n      }\n\n      (*container)->as.heading.level = level;\n      (*container)->as.heading.setext = false;\n      (*container)->internal_offset = matched;\n\n    } else if (!indented && (matched = scan_open_code_fence(\n                                 input, parser->first_nonspace))) {\n      *container = add_child(parser, *container, CMARK_NODE_CODE_BLOCK,\n                             parser->first_nonspace + 1);\n      (*container)->as.code.fenced = true;\n      (*container)->as.code.fence_char = peek_at(input, parser->first_nonspace);\n      (*container)->as.code.fence_length = (matched > 255) ? 255 : (uint8_t)matched;\n      (*container)->as.code.fence_offset =\n          (int8_t)(parser->first_nonspace - parser->offset);\n      (*container)->as.code.info = cmark_chunk_literal(\"\");\n      S_advance_offset(parser, input,\n                       parser->first_nonspace + matched - parser->offset,\n                       false);\n\n    } else if (!indented && ((matched = scan_html_block_start(\n                                  input, parser->first_nonspace)) ||\n                             (cont_type != CMARK_NODE_PARAGRAPH &&\n                              (matched = scan_html_block_start_7(\n                                   input, parser->first_nonspace))))) {\n      *container = add_child(parser, *container, CMARK_NODE_HTML_BLOCK,\n                             parser->first_nonspace + 1);\n      (*container)->as.html_block_type = matched;\n      // note, we don't adjust parser->offset because the tag is part of the\n      // text\n    } else if (!indented && cont_type == CMARK_NODE_PARAGRAPH &&\n               (lev =\n                    scan_setext_heading_line(input, parser->first_nonspace))) {\n      // finalize paragraph, resolving reference links\n      has_content = resolve_reference_link_definitions(parser, *container);\n\n      if (has_content) {\n\n        (*container)->type = (uint16_t)CMARK_NODE_HEADING;\n        (*container)->as.heading.level = lev;\n        (*container)->as.heading.setext = true;\n        S_advance_offset(parser, input, input->len - 1 - parser->offset, false);\n      }\n    } else if (!indented &&\n               !(cont_type == CMARK_NODE_PARAGRAPH && !all_matched) &&\n\t       (parser->thematic_break_kill_pos <= parser->first_nonspace) &&\n               (matched = S_scan_thematic_break(parser, input, parser->first_nonspace))) {\n      // it's only now that we know the line is not part of a setext heading:\n      *container = add_child(parser, *container, CMARK_NODE_THEMATIC_BREAK,\n                             parser->first_nonspace + 1);\n      S_advance_offset(parser, input, input->len - 1 - parser->offset, false);\n    } else if (!indented &&\n               (parser->options & CMARK_OPT_FOOTNOTES) &&\n               depth < MAX_LIST_DEPTH &&\n               (matched = scan_footnote_definition(input, parser->first_nonspace))) {\n      cmark_chunk c = cmark_chunk_dup(input, parser->first_nonspace + 2, matched - 2);\n\n      while (c.data[c.len - 1] != ']')\n        --c.len;\n      --c.len;\n\n      cmark_chunk_to_cstr(parser->mem, &c);\n\n      S_advance_offset(parser, input, parser->first_nonspace + matched - parser->offset, false);\n      *container = add_child(parser, *container, CMARK_NODE_FOOTNOTE_DEFINITION, parser->first_nonspace + matched + 1);\n      (*container)->as.literal = c;\n\n      (*container)->internal_offset = matched;\n    } else if ((!indented || cont_type == CMARK_NODE_LIST) &&\n\t       parser->indent < 4 &&\n               depth < MAX_LIST_DEPTH &&\n               (matched = parse_list_marker(\n                    parser->mem, input, parser->first_nonspace,\n                    (*container)->type == CMARK_NODE_PARAGRAPH, &data))) {\n\n      // Note that we can have new list items starting with >= 4\n      // spaces indent, as long as the list container is still open.\n      int i = 0;\n\n      // compute padding:\n      S_advance_offset(parser, input,\n                       parser->first_nonspace + matched - parser->offset,\n                       false);\n\n      save_partially_consumed_tab = parser->partially_consumed_tab;\n      save_offset = parser->offset;\n      save_column = parser->column;\n\n      while (parser->column - save_column <= 5 &&\n             S_is_space_or_tab(peek_at(input, parser->offset))) {\n        S_advance_offset(parser, input, 1, true);\n      }\n\n      i = parser->column - save_column;\n      if (i >= 5 || i < 1 ||\n          // only spaces after list marker:\n          S_is_line_end_char(peek_at(input, parser->offset))) {\n        data->padding = matched + 1;\n        parser->offset = save_offset;\n        parser->column = save_column;\n        parser->partially_consumed_tab = save_partially_consumed_tab;\n        if (i > 0) {\n          S_advance_offset(parser, input, 1, true);\n        }\n      } else {\n        data->padding = matched + i;\n      }\n\n      // check container; if it's a list, see if this list item\n      // can continue the list; otherwise, create a list container.\n\n      data->marker_offset = parser->indent;\n\n      if (cont_type != CMARK_NODE_LIST ||\n          !lists_match(&((*container)->as.list), data)) {\n        *container = add_child(parser, *container, CMARK_NODE_LIST,\n                               parser->first_nonspace + 1);\n\n        memcpy(&((*container)->as.list), data, sizeof(*data));\n      }\n\n      // add the list item\n      *container = add_child(parser, *container, CMARK_NODE_ITEM,\n                             parser->first_nonspace + 1);\n      /* TODO: static */\n      memcpy(&((*container)->as.list), data, sizeof(*data));\n      parser->mem->free(data);\n    } else if (indented && !maybe_lazy && !parser->blank) {\n      S_advance_offset(parser, input, CODE_INDENT, true);\n      *container = add_child(parser, *container, CMARK_NODE_CODE_BLOCK,\n                             parser->offset + 1);\n      (*container)->as.code.fenced = false;\n      (*container)->as.code.fence_char = 0;\n      (*container)->as.code.fence_length = 0;\n      (*container)->as.code.fence_offset = 0;\n      (*container)->as.code.info = cmark_chunk_literal(\"\");\n    } else {\n      cmark_llist *tmp;\n      cmark_node *new_container = NULL;\n\n      for (tmp = parser->syntax_extensions; tmp; tmp=tmp->next) {\n        cmark_syntax_extension *ext = (cmark_syntax_extension *) tmp->data;\n\n        if (ext->try_opening_block) {\n          new_container = ext->try_opening_block(\n              ext, indented, parser, *container, input->data, input->len);\n\n          if (new_container) {\n            *container = new_container;\n            break;\n          }\n        }\n      }\n\n      if (!new_container) {\n        break;\n      }\n    }\n\n    if (accepts_lines(S_type(*container))) {\n      // if it's a line container, it can't contain other containers\n      break;\n    }\n\n    cont_type = S_type(*container);\n    maybe_lazy = false;\n  }\n}\n\nstatic void add_text_to_container(cmark_parser *parser, cmark_node *container,\n                                  cmark_node *last_matched_container,\n                                  cmark_chunk *input) {\n  cmark_node *tmp;\n  // what remains at parser->offset is a text line.  add the text to the\n  // appropriate container.\n\n  S_find_first_nonspace(parser, input);\n\n  if (parser->blank && container->last_child)\n    S_set_last_line_blank(container->last_child, true);\n\n  // block quote lines are never blank as they start with >\n  // and we don't count blanks in fenced code for purposes of tight/loose\n  // lists or breaking out of lists.  we also don't set last_line_blank\n  // on an empty list item.\n  const cmark_node_type ctype = S_type(container);\n  const bool last_line_blank =\n      (parser->blank && ctype != CMARK_NODE_BLOCK_QUOTE &&\n       ctype != CMARK_NODE_HEADING && ctype != CMARK_NODE_THEMATIC_BREAK &&\n       !(ctype == CMARK_NODE_CODE_BLOCK && container->as.code.fenced) &&\n       !(ctype == CMARK_NODE_ITEM && container->first_child == NULL &&\n         container->start_line == parser->line_number));\n\n  S_set_last_line_blank(container, last_line_blank);\n\n  tmp = container;\n  while (tmp->parent) {\n    S_set_last_line_blank(tmp->parent, false);\n    tmp = tmp->parent;\n  }\n\n  // If the last line processed belonged to a paragraph node,\n  // and we didn't match all of the line prefixes for the open containers,\n  // and we didn't start any new containers,\n  // and the line isn't blank,\n  // then treat this as a \"lazy continuation line\" and add it to\n  // the open paragraph.\n  if (parser->current != last_matched_container &&\n      container == last_matched_container && !parser->blank &&\n      S_type(parser->current) == CMARK_NODE_PARAGRAPH) {\n    add_line(parser->current, input, parser);\n  } else { // not a lazy continuation\n    // Finalize any blocks that were not matched and set cur to container:\n    while (parser->current != last_matched_container) {\n      parser->current = finalize(parser, parser->current);\n      assert(parser->current != NULL);\n    }\n\n    if (S_type(container) == CMARK_NODE_CODE_BLOCK) {\n      add_line(container, input, parser);\n    } else if (S_type(container) == CMARK_NODE_HTML_BLOCK) {\n      add_line(container, input, parser);\n\n      int matches_end_condition;\n      switch (container->as.html_block_type) {\n      case 1:\n        // </script>, </style>, </pre>\n        matches_end_condition =\n            scan_html_block_end_1(input, parser->first_nonspace);\n        break;\n      case 2:\n        // -->\n        matches_end_condition =\n            scan_html_block_end_2(input, parser->first_nonspace);\n        break;\n      case 3:\n        // ?>\n        matches_end_condition =\n            scan_html_block_end_3(input, parser->first_nonspace);\n        break;\n      case 4:\n        // >\n        matches_end_condition =\n            scan_html_block_end_4(input, parser->first_nonspace);\n        break;\n      case 5:\n        // ]]>\n        matches_end_condition =\n            scan_html_block_end_5(input, parser->first_nonspace);\n        break;\n      default:\n        matches_end_condition = 0;\n        break;\n      }\n\n      if (matches_end_condition) {\n        container = finalize(parser, container);\n        assert(parser->current != NULL);\n      }\n    } else if (parser->blank) {\n      // ??? do nothing\n    } else if (accepts_lines(S_type(container))) {\n      if (S_type(container) == CMARK_NODE_HEADING &&\n          container->as.heading.setext == false) {\n        chop_trailing_hashtags(input);\n      }\n      S_advance_offset(parser, input, parser->first_nonspace - parser->offset,\n                       false);\n      add_line(container, input, parser);\n    } else {\n      // create paragraph container for line\n      container = add_child(parser, container, CMARK_NODE_PARAGRAPH,\n                            parser->first_nonspace + 1);\n      S_advance_offset(parser, input, parser->first_nonspace - parser->offset,\n                       false);\n      add_line(container, input, parser);\n    }\n\n    parser->current = container;\n  }\n}\n\n/* See http://spec.commonmark.org/0.24/#phase-1-block-structure */\nstatic void S_process_line(cmark_parser *parser, const unsigned char *buffer,\n                           bufsize_t bytes) {\n  cmark_node *last_matched_container;\n  bool all_matched = true;\n  cmark_node *container;\n  cmark_chunk input;\n  cmark_node *current;\n\n  cmark_strbuf_clear(&parser->curline);\n\n  if (parser->options & CMARK_OPT_VALIDATE_UTF8)\n    cmark_utf8proc_check(&parser->curline, buffer, bytes);\n  else\n    cmark_strbuf_put(&parser->curline, buffer, bytes);\n\n  bytes = parser->curline.size;\n\n  // ensure line ends with a newline:\n  if (bytes == 0 || !S_is_line_end_char(parser->curline.ptr[bytes - 1]))\n    cmark_strbuf_putc(&parser->curline, '\\n');\n\n  parser->offset = 0;\n  parser->column = 0;\n  parser->first_nonspace = 0;\n  parser->first_nonspace_column = 0;\n  parser->thematic_break_kill_pos = 0;\n  parser->indent = 0;\n  parser->blank = false;\n  parser->partially_consumed_tab = false;\n\n  input.data = parser->curline.ptr;\n  input.len = parser->curline.size;\n  input.alloc = 0;\n\n  // Skip UTF-8 BOM.\n  if (parser->line_number == 0 &&\n      input.len >= 3 &&\n      memcmp(input.data, \"\\xef\\xbb\\xbf\", 3) == 0)\n    parser->offset += 3;\n\n  parser->line_number++;\n\n  last_matched_container = check_open_blocks(parser, &input, &all_matched);\n\n  if (!last_matched_container)\n    goto finished;\n\n  container = last_matched_container;\n\n  current = parser->current;\n\n  open_new_blocks(parser, &container, &input, all_matched);\n\n  /* parser->current might have changed if feed_reentrant was called */\n  if (current == parser->current)\n  add_text_to_container(parser, container, last_matched_container, &input);\n\nfinished:\n  parser->last_line_length = input.len;\n  if (parser->last_line_length &&\n      input.data[parser->last_line_length - 1] == '\\n')\n    parser->last_line_length -= 1;\n  if (parser->last_line_length &&\n      input.data[parser->last_line_length - 1] == '\\r')\n    parser->last_line_length -= 1;\n\n  cmark_strbuf_clear(&parser->curline);\n}\n\ncmark_node *cmark_parser_finish(cmark_parser *parser) {\n  cmark_node *res;\n  cmark_llist *extensions;\n\n  /* Parser was already finished once */\n  if (parser->root == NULL)\n    return NULL;\n\n  if (parser->linebuf.size) {\n    S_process_line(parser, parser->linebuf.ptr, parser->linebuf.size);\n    cmark_strbuf_clear(&parser->linebuf);\n  }\n\n  finalize_document(parser);\n\n  cmark_consolidate_text_nodes(parser->root);\n\n  cmark_strbuf_free(&parser->curline);\n  cmark_strbuf_free(&parser->linebuf);\n\n#if CMARK_DEBUG_NODES\n  if (cmark_node_check(parser->root, stderr)) {\n    abort();\n  }\n#endif\n\n  for (extensions = parser->syntax_extensions; extensions; extensions = extensions->next) {\n    cmark_syntax_extension *ext = (cmark_syntax_extension *) extensions->data;\n    if (ext->postprocess_func) {\n      cmark_node *processed = ext->postprocess_func(ext, parser, parser->root);\n      if (processed)\n        parser->root = processed;\n    }\n  }\n\n  res = parser->root;\n  parser->root = NULL;\n\n  cmark_parser_reset(parser);\n\n  return res;\n}\n\nint cmark_parser_get_line_number(cmark_parser *parser) {\n  return parser->line_number;\n}\n\nbufsize_t cmark_parser_get_offset(cmark_parser *parser) {\n  return parser->offset;\n}\n\nbufsize_t cmark_parser_get_column(cmark_parser *parser) {\n  return parser->column;\n}\n\nint cmark_parser_get_first_nonspace(cmark_parser *parser) {\n  return parser->first_nonspace;\n}\n\nint cmark_parser_get_first_nonspace_column(cmark_parser *parser) {\n  return parser->first_nonspace_column;\n}\n\nint cmark_parser_get_indent(cmark_parser *parser) {\n  return parser->indent;\n}\n\nint cmark_parser_is_blank(cmark_parser *parser) {\n  return parser->blank;\n}\n\nint cmark_parser_has_partially_consumed_tab(cmark_parser *parser) {\n  return parser->partially_consumed_tab;\n}\n\nint cmark_parser_get_last_line_length(cmark_parser *parser) {\n  return parser->last_line_length;\n}\n\ncmark_node *cmark_parser_add_child(cmark_parser *parser,\n                                   cmark_node   *parent,\n                                   cmark_node_type block_type,\n                                   int start_column) {\n  return add_child(parser, parent, block_type, start_column);\n}\n\nvoid cmark_parser_advance_offset(cmark_parser *parser,\n                                 const char *input,\n                                 int count,\n                                 int columns) {\n  cmark_chunk input_chunk = cmark_chunk_literal(input);\n\n  S_advance_offset(parser, &input_chunk, count, columns != 0);\n}\n\nvoid cmark_parser_set_backslash_ispunct_func(cmark_parser *parser,\n                                             cmark_ispunct_func func) {\n  parser->backslash_ispunct = func;\n}\n\ncmark_llist *cmark_parser_get_syntax_extensions(cmark_parser *parser) {\n  return parser->syntax_extensions;\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/buffer.c",
    "content": "#include <stdarg.h>\n#include <string.h>\n#include <assert.h>\n#include <string.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <stdint.h>\n#include <limits.h>\n\n#include \"config.h\"\n#include \"cmark_ctype.h\"\n#include \"buffer.h\"\n\n/* Used as default value for cmark_strbuf->ptr so that people can always\n * assume ptr is non-NULL and zero terminated even for new cmark_strbufs.\n */\nunsigned char cmark_strbuf__initbuf[1];\n\n#ifndef MIN\n#define MIN(x, y) ((x < y) ? x : y)\n#endif\n\nvoid cmark_strbuf_init(cmark_mem *mem, cmark_strbuf *buf,\n                       bufsize_t initial_size) {\n  buf->mem = mem;\n  buf->asize = 0;\n  buf->size = 0;\n  buf->ptr = cmark_strbuf__initbuf;\n\n  if (initial_size > 0)\n    cmark_strbuf_grow(buf, initial_size);\n}\n\nstatic CMARK_INLINE void S_strbuf_grow_by(cmark_strbuf *buf, bufsize_t add) {\n  cmark_strbuf_grow(buf, buf->size + add);\n}\n\nvoid cmark_strbuf_grow(cmark_strbuf *buf, bufsize_t target_size) {\n  assert(target_size > 0);\n\n  if (target_size < buf->asize)\n    return;\n\n  if (target_size > (bufsize_t)(INT32_MAX / 2)) {\n    fprintf(stderr,\n      \"[cmark] cmark_strbuf_grow requests buffer with size > %d, aborting\\n\",\n         (INT32_MAX / 2));\n    abort();\n  }\n\n  /* Oversize the buffer by 50% to guarantee amortized linear time\n   * complexity on append operations. */\n  bufsize_t new_size = target_size + target_size / 2;\n  new_size += 1;\n  new_size = (new_size + 7) & ~7;\n\n  buf->ptr = (unsigned char *)buf->mem->realloc(buf->asize ? buf->ptr : NULL,\n                                                new_size);\n  buf->asize = new_size;\n}\n\nbufsize_t cmark_strbuf_len(const cmark_strbuf *buf) { return buf->size; }\n\nvoid cmark_strbuf_free(cmark_strbuf *buf) {\n  if (!buf)\n    return;\n\n  if (buf->ptr != cmark_strbuf__initbuf)\n    buf->mem->free(buf->ptr);\n\n  cmark_strbuf_init(buf->mem, buf, 0);\n}\n\nvoid cmark_strbuf_clear(cmark_strbuf *buf) {\n  buf->size = 0;\n\n  if (buf->asize > 0)\n    buf->ptr[0] = '\\0';\n}\n\nvoid cmark_strbuf_set(cmark_strbuf *buf, const unsigned char *data,\n                      bufsize_t len) {\n  if (len <= 0 || data == NULL) {\n    cmark_strbuf_clear(buf);\n  } else {\n    if (data != buf->ptr) {\n      if (len >= buf->asize)\n        cmark_strbuf_grow(buf, len);\n      memmove(buf->ptr, data, len);\n    }\n    buf->size = len;\n    buf->ptr[buf->size] = '\\0';\n  }\n}\n\nvoid cmark_strbuf_sets(cmark_strbuf *buf, const char *string) {\n  cmark_strbuf_set(buf, (const unsigned char *)string,\n                   string ? (bufsize_t)strlen(string) : 0);\n}\n\nvoid cmark_strbuf_putc(cmark_strbuf *buf, int c) {\n  S_strbuf_grow_by(buf, 1);\n  buf->ptr[buf->size++] = (unsigned char)(c & 0xFF);\n  buf->ptr[buf->size] = '\\0';\n}\n\nvoid cmark_strbuf_put(cmark_strbuf *buf, const unsigned char *data,\n                      bufsize_t len) {\n  if (len <= 0)\n    return;\n\n  S_strbuf_grow_by(buf, len);\n  memmove(buf->ptr + buf->size, data, len);\n  buf->size += len;\n  buf->ptr[buf->size] = '\\0';\n}\n\nvoid cmark_strbuf_puts(cmark_strbuf *buf, const char *string) {\n  cmark_strbuf_put(buf, (const unsigned char *)string, (bufsize_t)strlen(string));\n}\n\nvoid cmark_strbuf_copy_cstr(char *data, bufsize_t datasize,\n                            const cmark_strbuf *buf) {\n  bufsize_t copylen;\n\n  assert(buf);\n  if (!data || datasize <= 0)\n    return;\n\n  data[0] = '\\0';\n\n  if (buf->size == 0 || buf->asize <= 0)\n    return;\n\n  copylen = buf->size;\n  if (copylen > datasize - 1)\n    copylen = datasize - 1;\n  memmove(data, buf->ptr, copylen);\n  data[copylen] = '\\0';\n}\n\nvoid cmark_strbuf_swap(cmark_strbuf *buf_a, cmark_strbuf *buf_b) {\n  cmark_strbuf t = *buf_a;\n  *buf_a = *buf_b;\n  *buf_b = t;\n}\n\nunsigned char *cmark_strbuf_detach(cmark_strbuf *buf) {\n  unsigned char *data = buf->ptr;\n\n  if (buf->asize == 0) {\n    /* return an empty string */\n    return (unsigned char *)buf->mem->calloc(1, 1);\n  }\n\n  cmark_strbuf_init(buf->mem, buf, 0);\n  return data;\n}\n\nint cmark_strbuf_cmp(const cmark_strbuf *a, const cmark_strbuf *b) {\n  int result = memcmp(a->ptr, b->ptr, MIN(a->size, b->size));\n  return (result != 0) ? result\n                       : (a->size < b->size) ? -1 : (a->size > b->size) ? 1 : 0;\n}\n\nbufsize_t cmark_strbuf_strchr(const cmark_strbuf *buf, int c, bufsize_t pos) {\n  if (pos >= buf->size)\n    return -1;\n  if (pos < 0)\n    pos = 0;\n\n  const unsigned char *p =\n      (unsigned char *)memchr(buf->ptr + pos, c, buf->size - pos);\n  if (!p)\n    return -1;\n\n  return (bufsize_t)(p - (const unsigned char *)buf->ptr);\n}\n\nbufsize_t cmark_strbuf_strrchr(const cmark_strbuf *buf, int c, bufsize_t pos) {\n  if (pos < 0 || buf->size == 0)\n    return -1;\n  if (pos >= buf->size)\n    pos = buf->size - 1;\n\n  bufsize_t i;\n  for (i = pos; i >= 0; i--) {\n    if (buf->ptr[i] == (unsigned char)c)\n      return i;\n  }\n\n  return -1;\n}\n\nvoid cmark_strbuf_truncate(cmark_strbuf *buf, bufsize_t len) {\n  if (len < 0)\n    len = 0;\n\n  if (len < buf->size) {\n    buf->size = len;\n    buf->ptr[buf->size] = '\\0';\n  }\n}\n\nvoid cmark_strbuf_drop(cmark_strbuf *buf, bufsize_t n) {\n  if (n > 0) {\n    if (n > buf->size)\n      n = buf->size;\n    buf->size = buf->size - n;\n    if (buf->size)\n      memmove(buf->ptr, buf->ptr + n, buf->size);\n\n    buf->ptr[buf->size] = '\\0';\n  }\n}\n\nvoid cmark_strbuf_rtrim(cmark_strbuf *buf) {\n  if (!buf->size)\n    return;\n\n  while (buf->size > 0) {\n    if (!cmark_isspace(buf->ptr[buf->size - 1]))\n      break;\n\n    buf->size--;\n  }\n\n  buf->ptr[buf->size] = '\\0';\n}\n\nvoid cmark_strbuf_trim(cmark_strbuf *buf) {\n  bufsize_t i = 0;\n\n  if (!buf->size)\n    return;\n\n  while (i < buf->size && cmark_isspace(buf->ptr[i]))\n    i++;\n\n  cmark_strbuf_drop(buf, i);\n\n  cmark_strbuf_rtrim(buf);\n}\n\n// Destructively modify string, collapsing consecutive\n// space and newline characters into a single space.\nvoid cmark_strbuf_normalize_whitespace(cmark_strbuf *s) {\n  bool last_char_was_space = false;\n  bufsize_t r, w;\n\n  for (r = 0, w = 0; r < s->size; ++r) {\n    if (cmark_isspace(s->ptr[r])) {\n      if (!last_char_was_space) {\n        s->ptr[w++] = ' ';\n        last_char_was_space = true;\n      }\n    } else {\n      s->ptr[w++] = s->ptr[r];\n      last_char_was_space = false;\n    }\n  }\n\n  cmark_strbuf_truncate(s, w);\n}\n\n// Destructively unescape a string: remove backslashes before punctuation chars.\nextern void cmark_strbuf_unescape(cmark_strbuf *buf) {\n  bufsize_t r, w;\n\n  for (r = 0, w = 0; r < buf->size; ++r) {\n    if (buf->ptr[r] == '\\\\' && cmark_ispunct(buf->ptr[r + 1]))\n      r++;\n\n    buf->ptr[w++] = buf->ptr[r];\n  }\n\n  cmark_strbuf_truncate(buf, w);\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/buffer.h",
    "content": "#ifndef CMARK_BUFFER_H\n#define CMARK_BUFFER_H\n\n#include <stddef.h>\n#include <stdarg.h>\n#include <string.h>\n#include <limits.h>\n#include <stdint.h>\n#include \"config.h\"\n#include \"cmark-gfm.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\ntypedef struct {\n  cmark_mem *mem;\n  unsigned char *ptr;\n  bufsize_t asize, size;\n} cmark_strbuf;\n\nextern unsigned char cmark_strbuf__initbuf[];\n\n#define CMARK_BUF_INIT(mem)                                                    \\\n  { mem, cmark_strbuf__initbuf, 0, 0 }\n\n/**\n * Initialize a cmark_strbuf structure.\n *\n * For the cases where CMARK_BUF_INIT cannot be used to do static\n * initialization.\n */\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_init(cmark_mem *mem, cmark_strbuf *buf,\n                       bufsize_t initial_size);\n\n/**\n * Grow the buffer to hold at least `target_size` bytes.\n */\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_grow(cmark_strbuf *buf, bufsize_t target_size);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_free(cmark_strbuf *buf);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_swap(cmark_strbuf *buf_a, cmark_strbuf *buf_b);\n\nCMARK_GFM_EXPORT\nbufsize_t cmark_strbuf_len(const cmark_strbuf *buf);\n\nCMARK_GFM_EXPORT\nint cmark_strbuf_cmp(const cmark_strbuf *a, const cmark_strbuf *b);\n\nCMARK_GFM_EXPORT\nunsigned char *cmark_strbuf_detach(cmark_strbuf *buf);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_copy_cstr(char *data, bufsize_t datasize,\n                            const cmark_strbuf *buf);\n\nstatic CMARK_INLINE const char *cmark_strbuf_cstr(const cmark_strbuf *buf) {\n  return (char *)buf->ptr;\n}\n\n#define cmark_strbuf_at(buf, n) ((buf)->ptr[n])\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_set(cmark_strbuf *buf, const unsigned char *data,\n                      bufsize_t len);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_sets(cmark_strbuf *buf, const char *string);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_putc(cmark_strbuf *buf, int c);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_put(cmark_strbuf *buf, const unsigned char *data,\n                      bufsize_t len);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_puts(cmark_strbuf *buf, const char *string);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_clear(cmark_strbuf *buf);\n\nCMARK_GFM_EXPORT\nbufsize_t cmark_strbuf_strchr(const cmark_strbuf *buf, int c, bufsize_t pos);\n\nCMARK_GFM_EXPORT\nbufsize_t cmark_strbuf_strrchr(const cmark_strbuf *buf, int c, bufsize_t pos);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_drop(cmark_strbuf *buf, bufsize_t n);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_truncate(cmark_strbuf *buf, bufsize_t len);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_rtrim(cmark_strbuf *buf);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_trim(cmark_strbuf *buf);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_normalize_whitespace(cmark_strbuf *s);\n\nCMARK_GFM_EXPORT\nvoid cmark_strbuf_unescape(cmark_strbuf *s);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/case_fold_switch.inc",
    "content": "    switch (c) {\n      case 0x0041:\n        bufpush(0x0061);\n        break;\n      case 0x0042:\n        bufpush(0x0062);\n        break;\n      case 0x0043:\n        bufpush(0x0063);\n        break;\n      case 0x0044:\n        bufpush(0x0064);\n        break;\n      case 0x0045:\n        bufpush(0x0065);\n        break;\n      case 0x0046:\n        bufpush(0x0066);\n        break;\n      case 0x0047:\n        bufpush(0x0067);\n        break;\n      case 0x0048:\n        bufpush(0x0068);\n        break;\n      case 0x0049:\n        bufpush(0x0069);\n        break;\n      case 0x004A:\n        bufpush(0x006A);\n        break;\n      case 0x004B:\n        bufpush(0x006B);\n        break;\n      case 0x004C:\n        bufpush(0x006C);\n        break;\n      case 0x004D:\n        bufpush(0x006D);\n        break;\n      case 0x004E:\n        bufpush(0x006E);\n        break;\n      case 0x004F:\n        bufpush(0x006F);\n        break;\n      case 0x0050:\n        bufpush(0x0070);\n        break;\n      case 0x0051:\n        bufpush(0x0071);\n        break;\n      case 0x0052:\n        bufpush(0x0072);\n        break;\n      case 0x0053:\n        bufpush(0x0073);\n        break;\n      case 0x0054:\n        bufpush(0x0074);\n        break;\n      case 0x0055:\n        bufpush(0x0075);\n        break;\n      case 0x0056:\n        bufpush(0x0076);\n        break;\n      case 0x0057:\n        bufpush(0x0077);\n        break;\n      case 0x0058:\n        bufpush(0x0078);\n        break;\n      case 0x0059:\n        bufpush(0x0079);\n        break;\n      case 0x005A:\n        bufpush(0x007A);\n        break;\n      case 0x00B5:\n        bufpush(0x03BC);\n        break;\n      case 0x00C0:\n        bufpush(0x00E0);\n        break;\n      case 0x00C1:\n        bufpush(0x00E1);\n        break;\n      case 0x00C2:\n        bufpush(0x00E2);\n        break;\n      case 0x00C3:\n        bufpush(0x00E3);\n        break;\n      case 0x00C4:\n        bufpush(0x00E4);\n        break;\n      case 0x00C5:\n        bufpush(0x00E5);\n        break;\n      case 0x00C6:\n        bufpush(0x00E6);\n        break;\n      case 0x00C7:\n        bufpush(0x00E7);\n        break;\n      case 0x00C8:\n        bufpush(0x00E8);\n        break;\n      case 0x00C9:\n        bufpush(0x00E9);\n        break;\n      case 0x00CA:\n        bufpush(0x00EA);\n        break;\n      case 0x00CB:\n        bufpush(0x00EB);\n        break;\n      case 0x00CC:\n        bufpush(0x00EC);\n        break;\n      case 0x00CD:\n        bufpush(0x00ED);\n        break;\n      case 0x00CE:\n        bufpush(0x00EE);\n        break;\n      case 0x00CF:\n        bufpush(0x00EF);\n        break;\n      case 0x00D0:\n        bufpush(0x00F0);\n        break;\n      case 0x00D1:\n        bufpush(0x00F1);\n        break;\n      case 0x00D2:\n        bufpush(0x00F2);\n        break;\n      case 0x00D3:\n        bufpush(0x00F3);\n        break;\n      case 0x00D4:\n        bufpush(0x00F4);\n        break;\n      case 0x00D5:\n        bufpush(0x00F5);\n        break;\n      case 0x00D6:\n        bufpush(0x00F6);\n        break;\n      case 0x00D8:\n        bufpush(0x00F8);\n        break;\n      case 0x00D9:\n        bufpush(0x00F9);\n        break;\n      case 0x00DA:\n        bufpush(0x00FA);\n        break;\n      case 0x00DB:\n        bufpush(0x00FB);\n        break;\n      case 0x00DC:\n        bufpush(0x00FC);\n        break;\n      case 0x00DD:\n        bufpush(0x00FD);\n        break;\n      case 0x00DE:\n        bufpush(0x00FE);\n        break;\n      case 0x00DF:\n        bufpush(0x0073);\n        bufpush(0x0073);\n        break;\n      case 0x0100:\n        bufpush(0x0101);\n        break;\n      case 0x0102:\n        bufpush(0x0103);\n        break;\n      case 0x0104:\n        bufpush(0x0105);\n        break;\n      case 0x0106:\n        bufpush(0x0107);\n        break;\n      case 0x0108:\n        bufpush(0x0109);\n        break;\n      case 0x010A:\n        bufpush(0x010B);\n        break;\n      case 0x010C:\n        bufpush(0x010D);\n        break;\n      case 0x010E:\n        bufpush(0x010F);\n        break;\n      case 0x0110:\n        bufpush(0x0111);\n        break;\n      case 0x0112:\n        bufpush(0x0113);\n        break;\n      case 0x0114:\n        bufpush(0x0115);\n        break;\n      case 0x0116:\n        bufpush(0x0117);\n        break;\n      case 0x0118:\n        bufpush(0x0119);\n        break;\n      case 0x011A:\n        bufpush(0x011B);\n        break;\n      case 0x011C:\n        bufpush(0x011D);\n        break;\n      case 0x011E:\n        bufpush(0x011F);\n        break;\n      case 0x0120:\n        bufpush(0x0121);\n        break;\n      case 0x0122:\n        bufpush(0x0123);\n        break;\n      case 0x0124:\n        bufpush(0x0125);\n        break;\n      case 0x0126:\n        bufpush(0x0127);\n        break;\n      case 0x0128:\n        bufpush(0x0129);\n        break;\n      case 0x012A:\n        bufpush(0x012B);\n        break;\n      case 0x012C:\n        bufpush(0x012D);\n        break;\n      case 0x012E:\n        bufpush(0x012F);\n        break;\n      case 0x0130:\n        bufpush(0x0069);\n        bufpush(0x0307);\n        break;\n      case 0x0132:\n        bufpush(0x0133);\n        break;\n      case 0x0134:\n        bufpush(0x0135);\n        break;\n      case 0x0136:\n        bufpush(0x0137);\n        break;\n      case 0x0139:\n        bufpush(0x013A);\n        break;\n      case 0x013B:\n        bufpush(0x013C);\n        break;\n      case 0x013D:\n        bufpush(0x013E);\n        break;\n      case 0x013F:\n        bufpush(0x0140);\n        break;\n      case 0x0141:\n        bufpush(0x0142);\n        break;\n      case 0x0143:\n        bufpush(0x0144);\n        break;\n      case 0x0145:\n        bufpush(0x0146);\n        break;\n      case 0x0147:\n        bufpush(0x0148);\n        break;\n      case 0x0149:\n        bufpush(0x02BC);\n        bufpush(0x006E);\n        break;\n      case 0x014A:\n        bufpush(0x014B);\n        break;\n      case 0x014C:\n        bufpush(0x014D);\n        break;\n      case 0x014E:\n        bufpush(0x014F);\n        break;\n      case 0x0150:\n        bufpush(0x0151);\n        break;\n      case 0x0152:\n        bufpush(0x0153);\n        break;\n      case 0x0154:\n        bufpush(0x0155);\n        break;\n      case 0x0156:\n        bufpush(0x0157);\n        break;\n      case 0x0158:\n        bufpush(0x0159);\n        break;\n      case 0x015A:\n        bufpush(0x015B);\n        break;\n      case 0x015C:\n        bufpush(0x015D);\n        break;\n      case 0x015E:\n        bufpush(0x015F);\n        break;\n      case 0x0160:\n        bufpush(0x0161);\n        break;\n      case 0x0162:\n        bufpush(0x0163);\n        break;\n      case 0x0164:\n        bufpush(0x0165);\n        break;\n      case 0x0166:\n        bufpush(0x0167);\n        break;\n      case 0x0168:\n        bufpush(0x0169);\n        break;\n      case 0x016A:\n        bufpush(0x016B);\n        break;\n      case 0x016C:\n        bufpush(0x016D);\n        break;\n      case 0x016E:\n        bufpush(0x016F);\n        break;\n      case 0x0170:\n        bufpush(0x0171);\n        break;\n      case 0x0172:\n        bufpush(0x0173);\n        break;\n      case 0x0174:\n        bufpush(0x0175);\n        break;\n      case 0x0176:\n        bufpush(0x0177);\n        break;\n      case 0x0178:\n        bufpush(0x00FF);\n        break;\n      case 0x0179:\n        bufpush(0x017A);\n        break;\n      case 0x017B:\n        bufpush(0x017C);\n        break;\n      case 0x017D:\n        bufpush(0x017E);\n        break;\n      case 0x017F:\n        bufpush(0x0073);\n        break;\n      case 0x0181:\n        bufpush(0x0253);\n        break;\n      case 0x0182:\n        bufpush(0x0183);\n        break;\n      case 0x0184:\n        bufpush(0x0185);\n        break;\n      case 0x0186:\n        bufpush(0x0254);\n        break;\n      case 0x0187:\n        bufpush(0x0188);\n        break;\n      case 0x0189:\n        bufpush(0x0256);\n        break;\n      case 0x018A:\n        bufpush(0x0257);\n        break;\n      case 0x018B:\n        bufpush(0x018C);\n        break;\n      case 0x018E:\n        bufpush(0x01DD);\n        break;\n      case 0x018F:\n        bufpush(0x0259);\n        break;\n      case 0x0190:\n        bufpush(0x025B);\n        break;\n      case 0x0191:\n        bufpush(0x0192);\n        break;\n      case 0x0193:\n        bufpush(0x0260);\n        break;\n      case 0x0194:\n        bufpush(0x0263);\n        break;\n      case 0x0196:\n        bufpush(0x0269);\n        break;\n      case 0x0197:\n        bufpush(0x0268);\n        break;\n      case 0x0198:\n        bufpush(0x0199);\n        break;\n      case 0x019C:\n        bufpush(0x026F);\n        break;\n      case 0x019D:\n        bufpush(0x0272);\n        break;\n      case 0x019F:\n        bufpush(0x0275);\n        break;\n      case 0x01A0:\n        bufpush(0x01A1);\n        break;\n      case 0x01A2:\n        bufpush(0x01A3);\n        break;\n      case 0x01A4:\n        bufpush(0x01A5);\n        break;\n      case 0x01A6:\n        bufpush(0x0280);\n        break;\n      case 0x01A7:\n        bufpush(0x01A8);\n        break;\n      case 0x01A9:\n        bufpush(0x0283);\n        break;\n      case 0x01AC:\n        bufpush(0x01AD);\n        break;\n      case 0x01AE:\n        bufpush(0x0288);\n        break;\n      case 0x01AF:\n        bufpush(0x01B0);\n        break;\n      case 0x01B1:\n        bufpush(0x028A);\n        break;\n      case 0x01B2:\n        bufpush(0x028B);\n        break;\n      case 0x01B3:\n        bufpush(0x01B4);\n        break;\n      case 0x01B5:\n        bufpush(0x01B6);\n        break;\n      case 0x01B7:\n        bufpush(0x0292);\n        break;\n      case 0x01B8:\n        bufpush(0x01B9);\n        break;\n      case 0x01BC:\n        bufpush(0x01BD);\n        break;\n      case 0x01C4:\n        bufpush(0x01C6);\n        break;\n      case 0x01C5:\n        bufpush(0x01C6);\n        break;\n      case 0x01C7:\n        bufpush(0x01C9);\n        break;\n      case 0x01C8:\n        bufpush(0x01C9);\n        break;\n      case 0x01CA:\n        bufpush(0x01CC);\n        break;\n      case 0x01CB:\n        bufpush(0x01CC);\n        break;\n      case 0x01CD:\n        bufpush(0x01CE);\n        break;\n      case 0x01CF:\n        bufpush(0x01D0);\n        break;\n      case 0x01D1:\n        bufpush(0x01D2);\n        break;\n      case 0x01D3:\n        bufpush(0x01D4);\n        break;\n      case 0x01D5:\n        bufpush(0x01D6);\n        break;\n      case 0x01D7:\n        bufpush(0x01D8);\n        break;\n      case 0x01D9:\n        bufpush(0x01DA);\n        break;\n      case 0x01DB:\n        bufpush(0x01DC);\n        break;\n      case 0x01DE:\n        bufpush(0x01DF);\n        break;\n      case 0x01E0:\n        bufpush(0x01E1);\n        break;\n      case 0x01E2:\n        bufpush(0x01E3);\n        break;\n      case 0x01E4:\n        bufpush(0x01E5);\n        break;\n      case 0x01E6:\n        bufpush(0x01E7);\n        break;\n      case 0x01E8:\n        bufpush(0x01E9);\n        break;\n      case 0x01EA:\n        bufpush(0x01EB);\n        break;\n      case 0x01EC:\n        bufpush(0x01ED);\n        break;\n      case 0x01EE:\n        bufpush(0x01EF);\n        break;\n      case 0x01F0:\n        bufpush(0x006A);\n        bufpush(0x030C);\n        break;\n      case 0x01F1:\n        bufpush(0x01F3);\n        break;\n      case 0x01F2:\n        bufpush(0x01F3);\n        break;\n      case 0x01F4:\n        bufpush(0x01F5);\n        break;\n      case 0x01F6:\n        bufpush(0x0195);\n        break;\n      case 0x01F7:\n        bufpush(0x01BF);\n        break;\n      case 0x01F8:\n        bufpush(0x01F9);\n        break;\n      case 0x01FA:\n        bufpush(0x01FB);\n        break;\n      case 0x01FC:\n        bufpush(0x01FD);\n        break;\n      case 0x01FE:\n        bufpush(0x01FF);\n        break;\n      case 0x0200:\n        bufpush(0x0201);\n        break;\n      case 0x0202:\n        bufpush(0x0203);\n        break;\n      case 0x0204:\n        bufpush(0x0205);\n        break;\n      case 0x0206:\n        bufpush(0x0207);\n        break;\n      case 0x0208:\n        bufpush(0x0209);\n        break;\n      case 0x020A:\n        bufpush(0x020B);\n        break;\n      case 0x020C:\n        bufpush(0x020D);\n        break;\n      case 0x020E:\n        bufpush(0x020F);\n        break;\n      case 0x0210:\n        bufpush(0x0211);\n        break;\n      case 0x0212:\n        bufpush(0x0213);\n        break;\n      case 0x0214:\n        bufpush(0x0215);\n        break;\n      case 0x0216:\n        bufpush(0x0217);\n        break;\n      case 0x0218:\n        bufpush(0x0219);\n        break;\n      case 0x021A:\n        bufpush(0x021B);\n        break;\n      case 0x021C:\n        bufpush(0x021D);\n        break;\n      case 0x021E:\n        bufpush(0x021F);\n        break;\n      case 0x0220:\n        bufpush(0x019E);\n        break;\n      case 0x0222:\n        bufpush(0x0223);\n        break;\n      case 0x0224:\n        bufpush(0x0225);\n        break;\n      case 0x0226:\n        bufpush(0x0227);\n        break;\n      case 0x0228:\n        bufpush(0x0229);\n        break;\n      case 0x022A:\n        bufpush(0x022B);\n        break;\n      case 0x022C:\n        bufpush(0x022D);\n        break;\n      case 0x022E:\n        bufpush(0x022F);\n        break;\n      case 0x0230:\n        bufpush(0x0231);\n        break;\n      case 0x0232:\n        bufpush(0x0233);\n        break;\n      case 0x023A:\n        bufpush(0x2C65);\n        break;\n      case 0x023B:\n        bufpush(0x023C);\n        break;\n      case 0x023D:\n        bufpush(0x019A);\n        break;\n      case 0x023E:\n        bufpush(0x2C66);\n        break;\n      case 0x0241:\n        bufpush(0x0242);\n        break;\n      case 0x0243:\n        bufpush(0x0180);\n        break;\n      case 0x0244:\n        bufpush(0x0289);\n        break;\n      case 0x0245:\n        bufpush(0x028C);\n        break;\n      case 0x0246:\n        bufpush(0x0247);\n        break;\n      case 0x0248:\n        bufpush(0x0249);\n        break;\n      case 0x024A:\n        bufpush(0x024B);\n        break;\n      case 0x024C:\n        bufpush(0x024D);\n        break;\n      case 0x024E:\n        bufpush(0x024F);\n        break;\n      case 0x0345:\n        bufpush(0x03B9);\n        break;\n      case 0x0370:\n        bufpush(0x0371);\n        break;\n      case 0x0372:\n        bufpush(0x0373);\n        break;\n      case 0x0376:\n        bufpush(0x0377);\n        break;\n      case 0x037F:\n        bufpush(0x03F3);\n        break;\n      case 0x0386:\n        bufpush(0x03AC);\n        break;\n      case 0x0388:\n        bufpush(0x03AD);\n        break;\n      case 0x0389:\n        bufpush(0x03AE);\n        break;\n      case 0x038A:\n        bufpush(0x03AF);\n        break;\n      case 0x038C:\n        bufpush(0x03CC);\n        break;\n      case 0x038E:\n        bufpush(0x03CD);\n        break;\n      case 0x038F:\n        bufpush(0x03CE);\n        break;\n      case 0x0390:\n        bufpush(0x03B9);\n        bufpush(0x0308);\n        bufpush(0x0301);\n        break;\n      case 0x0391:\n        bufpush(0x03B1);\n        break;\n      case 0x0392:\n        bufpush(0x03B2);\n        break;\n      case 0x0393:\n        bufpush(0x03B3);\n        break;\n      case 0x0394:\n        bufpush(0x03B4);\n        break;\n      case 0x0395:\n        bufpush(0x03B5);\n        break;\n      case 0x0396:\n        bufpush(0x03B6);\n        break;\n      case 0x0397:\n        bufpush(0x03B7);\n        break;\n      case 0x0398:\n        bufpush(0x03B8);\n        break;\n      case 0x0399:\n        bufpush(0x03B9);\n        break;\n      case 0x039A:\n        bufpush(0x03BA);\n        break;\n      case 0x039B:\n        bufpush(0x03BB);\n        break;\n      case 0x039C:\n        bufpush(0x03BC);\n        break;\n      case 0x039D:\n        bufpush(0x03BD);\n        break;\n      case 0x039E:\n        bufpush(0x03BE);\n        break;\n      case 0x039F:\n        bufpush(0x03BF);\n        break;\n      case 0x03A0:\n        bufpush(0x03C0);\n        break;\n      case 0x03A1:\n        bufpush(0x03C1);\n        break;\n      case 0x03A3:\n        bufpush(0x03C3);\n        break;\n      case 0x03A4:\n        bufpush(0x03C4);\n        break;\n      case 0x03A5:\n        bufpush(0x03C5);\n        break;\n      case 0x03A6:\n        bufpush(0x03C6);\n        break;\n      case 0x03A7:\n        bufpush(0x03C7);\n        break;\n      case 0x03A8:\n        bufpush(0x03C8);\n        break;\n      case 0x03A9:\n        bufpush(0x03C9);\n        break;\n      case 0x03AA:\n        bufpush(0x03CA);\n        break;\n      case 0x03AB:\n        bufpush(0x03CB);\n        break;\n      case 0x03B0:\n        bufpush(0x03C5);\n        bufpush(0x0308);\n        bufpush(0x0301);\n        break;\n      case 0x03C2:\n        bufpush(0x03C3);\n        break;\n      case 0x03CF:\n        bufpush(0x03D7);\n        break;\n      case 0x03D0:\n        bufpush(0x03B2);\n        break;\n      case 0x03D1:\n        bufpush(0x03B8);\n        break;\n      case 0x03D5:\n        bufpush(0x03C6);\n        break;\n      case 0x03D6:\n        bufpush(0x03C0);\n        break;\n      case 0x03D8:\n        bufpush(0x03D9);\n        break;\n      case 0x03DA:\n        bufpush(0x03DB);\n        break;\n      case 0x03DC:\n        bufpush(0x03DD);\n        break;\n      case 0x03DE:\n        bufpush(0x03DF);\n        break;\n      case 0x03E0:\n        bufpush(0x03E1);\n        break;\n      case 0x03E2:\n        bufpush(0x03E3);\n        break;\n      case 0x03E4:\n        bufpush(0x03E5);\n        break;\n      case 0x03E6:\n        bufpush(0x03E7);\n        break;\n      case 0x03E8:\n        bufpush(0x03E9);\n        break;\n      case 0x03EA:\n        bufpush(0x03EB);\n        break;\n      case 0x03EC:\n        bufpush(0x03ED);\n        break;\n      case 0x03EE:\n        bufpush(0x03EF);\n        break;\n      case 0x03F0:\n        bufpush(0x03BA);\n        break;\n      case 0x03F1:\n        bufpush(0x03C1);\n        break;\n      case 0x03F4:\n        bufpush(0x03B8);\n        break;\n      case 0x03F5:\n        bufpush(0x03B5);\n        break;\n      case 0x03F7:\n        bufpush(0x03F8);\n        break;\n      case 0x03F9:\n        bufpush(0x03F2);\n        break;\n      case 0x03FA:\n        bufpush(0x03FB);\n        break;\n      case 0x03FD:\n        bufpush(0x037B);\n        break;\n      case 0x03FE:\n        bufpush(0x037C);\n        break;\n      case 0x03FF:\n        bufpush(0x037D);\n        break;\n      case 0x0400:\n        bufpush(0x0450);\n        break;\n      case 0x0401:\n        bufpush(0x0451);\n        break;\n      case 0x0402:\n        bufpush(0x0452);\n        break;\n      case 0x0403:\n        bufpush(0x0453);\n        break;\n      case 0x0404:\n        bufpush(0x0454);\n        break;\n      case 0x0405:\n        bufpush(0x0455);\n        break;\n      case 0x0406:\n        bufpush(0x0456);\n        break;\n      case 0x0407:\n        bufpush(0x0457);\n        break;\n      case 0x0408:\n        bufpush(0x0458);\n        break;\n      case 0x0409:\n        bufpush(0x0459);\n        break;\n      case 0x040A:\n        bufpush(0x045A);\n        break;\n      case 0x040B:\n        bufpush(0x045B);\n        break;\n      case 0x040C:\n        bufpush(0x045C);\n        break;\n      case 0x040D:\n        bufpush(0x045D);\n        break;\n      case 0x040E:\n        bufpush(0x045E);\n        break;\n      case 0x040F:\n        bufpush(0x045F);\n        break;\n      case 0x0410:\n        bufpush(0x0430);\n        break;\n      case 0x0411:\n        bufpush(0x0431);\n        break;\n      case 0x0412:\n        bufpush(0x0432);\n        break;\n      case 0x0413:\n        bufpush(0x0433);\n        break;\n      case 0x0414:\n        bufpush(0x0434);\n        break;\n      case 0x0415:\n        bufpush(0x0435);\n        break;\n      case 0x0416:\n        bufpush(0x0436);\n        break;\n      case 0x0417:\n        bufpush(0x0437);\n        break;\n      case 0x0418:\n        bufpush(0x0438);\n        break;\n      case 0x0419:\n        bufpush(0x0439);\n        break;\n      case 0x041A:\n        bufpush(0x043A);\n        break;\n      case 0x041B:\n        bufpush(0x043B);\n        break;\n      case 0x041C:\n        bufpush(0x043C);\n        break;\n      case 0x041D:\n        bufpush(0x043D);\n        break;\n      case 0x041E:\n        bufpush(0x043E);\n        break;\n      case 0x041F:\n        bufpush(0x043F);\n        break;\n      case 0x0420:\n        bufpush(0x0440);\n        break;\n      case 0x0421:\n        bufpush(0x0441);\n        break;\n      case 0x0422:\n        bufpush(0x0442);\n        break;\n      case 0x0423:\n        bufpush(0x0443);\n        break;\n      case 0x0424:\n        bufpush(0x0444);\n        break;\n      case 0x0425:\n        bufpush(0x0445);\n        break;\n      case 0x0426:\n        bufpush(0x0446);\n        break;\n      case 0x0427:\n        bufpush(0x0447);\n        break;\n      case 0x0428:\n        bufpush(0x0448);\n        break;\n      case 0x0429:\n        bufpush(0x0449);\n        break;\n      case 0x042A:\n        bufpush(0x044A);\n        break;\n      case 0x042B:\n        bufpush(0x044B);\n        break;\n      case 0x042C:\n        bufpush(0x044C);\n        break;\n      case 0x042D:\n        bufpush(0x044D);\n        break;\n      case 0x042E:\n        bufpush(0x044E);\n        break;\n      case 0x042F:\n        bufpush(0x044F);\n        break;\n      case 0x0460:\n        bufpush(0x0461);\n        break;\n      case 0x0462:\n        bufpush(0x0463);\n        break;\n      case 0x0464:\n        bufpush(0x0465);\n        break;\n      case 0x0466:\n        bufpush(0x0467);\n        break;\n      case 0x0468:\n        bufpush(0x0469);\n        break;\n      case 0x046A:\n        bufpush(0x046B);\n        break;\n      case 0x046C:\n        bufpush(0x046D);\n        break;\n      case 0x046E:\n        bufpush(0x046F);\n        break;\n      case 0x0470:\n        bufpush(0x0471);\n        break;\n      case 0x0472:\n        bufpush(0x0473);\n        break;\n      case 0x0474:\n        bufpush(0x0475);\n        break;\n      case 0x0476:\n        bufpush(0x0477);\n        break;\n      case 0x0478:\n        bufpush(0x0479);\n        break;\n      case 0x047A:\n        bufpush(0x047B);\n        break;\n      case 0x047C:\n        bufpush(0x047D);\n        break;\n      case 0x047E:\n        bufpush(0x047F);\n        break;\n      case 0x0480:\n        bufpush(0x0481);\n        break;\n      case 0x048A:\n        bufpush(0x048B);\n        break;\n      case 0x048C:\n        bufpush(0x048D);\n        break;\n      case 0x048E:\n        bufpush(0x048F);\n        break;\n      case 0x0490:\n        bufpush(0x0491);\n        break;\n      case 0x0492:\n        bufpush(0x0493);\n        break;\n      case 0x0494:\n        bufpush(0x0495);\n        break;\n      case 0x0496:\n        bufpush(0x0497);\n        break;\n      case 0x0498:\n        bufpush(0x0499);\n        break;\n      case 0x049A:\n        bufpush(0x049B);\n        break;\n      case 0x049C:\n        bufpush(0x049D);\n        break;\n      case 0x049E:\n        bufpush(0x049F);\n        break;\n      case 0x04A0:\n        bufpush(0x04A1);\n        break;\n      case 0x04A2:\n        bufpush(0x04A3);\n        break;\n      case 0x04A4:\n        bufpush(0x04A5);\n        break;\n      case 0x04A6:\n        bufpush(0x04A7);\n        break;\n      case 0x04A8:\n        bufpush(0x04A9);\n        break;\n      case 0x04AA:\n        bufpush(0x04AB);\n        break;\n      case 0x04AC:\n        bufpush(0x04AD);\n        break;\n      case 0x04AE:\n        bufpush(0x04AF);\n        break;\n      case 0x04B0:\n        bufpush(0x04B1);\n        break;\n      case 0x04B2:\n        bufpush(0x04B3);\n        break;\n      case 0x04B4:\n        bufpush(0x04B5);\n        break;\n      case 0x04B6:\n        bufpush(0x04B7);\n        break;\n      case 0x04B8:\n        bufpush(0x04B9);\n        break;\n      case 0x04BA:\n        bufpush(0x04BB);\n        break;\n      case 0x04BC:\n        bufpush(0x04BD);\n        break;\n      case 0x04BE:\n        bufpush(0x04BF);\n        break;\n      case 0x04C0:\n        bufpush(0x04CF);\n        break;\n      case 0x04C1:\n        bufpush(0x04C2);\n        break;\n      case 0x04C3:\n        bufpush(0x04C4);\n        break;\n      case 0x04C5:\n        bufpush(0x04C6);\n        break;\n      case 0x04C7:\n        bufpush(0x04C8);\n        break;\n      case 0x04C9:\n        bufpush(0x04CA);\n        break;\n      case 0x04CB:\n        bufpush(0x04CC);\n        break;\n      case 0x04CD:\n        bufpush(0x04CE);\n        break;\n      case 0x04D0:\n        bufpush(0x04D1);\n        break;\n      case 0x04D2:\n        bufpush(0x04D3);\n        break;\n      case 0x04D4:\n        bufpush(0x04D5);\n        break;\n      case 0x04D6:\n        bufpush(0x04D7);\n        break;\n      case 0x04D8:\n        bufpush(0x04D9);\n        break;\n      case 0x04DA:\n        bufpush(0x04DB);\n        break;\n      case 0x04DC:\n        bufpush(0x04DD);\n        break;\n      case 0x04DE:\n        bufpush(0x04DF);\n        break;\n      case 0x04E0:\n        bufpush(0x04E1);\n        break;\n      case 0x04E2:\n        bufpush(0x04E3);\n        break;\n      case 0x04E4:\n        bufpush(0x04E5);\n        break;\n      case 0x04E6:\n        bufpush(0x04E7);\n        break;\n      case 0x04E8:\n        bufpush(0x04E9);\n        break;\n      case 0x04EA:\n        bufpush(0x04EB);\n        break;\n      case 0x04EC:\n        bufpush(0x04ED);\n        break;\n      case 0x04EE:\n        bufpush(0x04EF);\n        break;\n      case 0x04F0:\n        bufpush(0x04F1);\n        break;\n      case 0x04F2:\n        bufpush(0x04F3);\n        break;\n      case 0x04F4:\n        bufpush(0x04F5);\n        break;\n      case 0x04F6:\n        bufpush(0x04F7);\n        break;\n      case 0x04F8:\n        bufpush(0x04F9);\n        break;\n      case 0x04FA:\n        bufpush(0x04FB);\n        break;\n      case 0x04FC:\n        bufpush(0x04FD);\n        break;\n      case 0x04FE:\n        bufpush(0x04FF);\n        break;\n      case 0x0500:\n        bufpush(0x0501);\n        break;\n      case 0x0502:\n        bufpush(0x0503);\n        break;\n      case 0x0504:\n        bufpush(0x0505);\n        break;\n      case 0x0506:\n        bufpush(0x0507);\n        break;\n      case 0x0508:\n        bufpush(0x0509);\n        break;\n      case 0x050A:\n        bufpush(0x050B);\n        break;\n      case 0x050C:\n        bufpush(0x050D);\n        break;\n      case 0x050E:\n        bufpush(0x050F);\n        break;\n      case 0x0510:\n        bufpush(0x0511);\n        break;\n      case 0x0512:\n        bufpush(0x0513);\n        break;\n      case 0x0514:\n        bufpush(0x0515);\n        break;\n      case 0x0516:\n        bufpush(0x0517);\n        break;\n      case 0x0518:\n        bufpush(0x0519);\n        break;\n      case 0x051A:\n        bufpush(0x051B);\n        break;\n      case 0x051C:\n        bufpush(0x051D);\n        break;\n      case 0x051E:\n        bufpush(0x051F);\n        break;\n      case 0x0520:\n        bufpush(0x0521);\n        break;\n      case 0x0522:\n        bufpush(0x0523);\n        break;\n      case 0x0524:\n        bufpush(0x0525);\n        break;\n      case 0x0526:\n        bufpush(0x0527);\n        break;\n      case 0x0528:\n        bufpush(0x0529);\n        break;\n      case 0x052A:\n        bufpush(0x052B);\n        break;\n      case 0x052C:\n        bufpush(0x052D);\n        break;\n      case 0x052E:\n        bufpush(0x052F);\n        break;\n      case 0x0531:\n        bufpush(0x0561);\n        break;\n      case 0x0532:\n        bufpush(0x0562);\n        break;\n      case 0x0533:\n        bufpush(0x0563);\n        break;\n      case 0x0534:\n        bufpush(0x0564);\n        break;\n      case 0x0535:\n        bufpush(0x0565);\n        break;\n      case 0x0536:\n        bufpush(0x0566);\n        break;\n      case 0x0537:\n        bufpush(0x0567);\n        break;\n      case 0x0538:\n        bufpush(0x0568);\n        break;\n      case 0x0539:\n        bufpush(0x0569);\n        break;\n      case 0x053A:\n        bufpush(0x056A);\n        break;\n      case 0x053B:\n        bufpush(0x056B);\n        break;\n      case 0x053C:\n        bufpush(0x056C);\n        break;\n      case 0x053D:\n        bufpush(0x056D);\n        break;\n      case 0x053E:\n        bufpush(0x056E);\n        break;\n      case 0x053F:\n        bufpush(0x056F);\n        break;\n      case 0x0540:\n        bufpush(0x0570);\n        break;\n      case 0x0541:\n        bufpush(0x0571);\n        break;\n      case 0x0542:\n        bufpush(0x0572);\n        break;\n      case 0x0543:\n        bufpush(0x0573);\n        break;\n      case 0x0544:\n        bufpush(0x0574);\n        break;\n      case 0x0545:\n        bufpush(0x0575);\n        break;\n      case 0x0546:\n        bufpush(0x0576);\n        break;\n      case 0x0547:\n        bufpush(0x0577);\n        break;\n      case 0x0548:\n        bufpush(0x0578);\n        break;\n      case 0x0549:\n        bufpush(0x0579);\n        break;\n      case 0x054A:\n        bufpush(0x057A);\n        break;\n      case 0x054B:\n        bufpush(0x057B);\n        break;\n      case 0x054C:\n        bufpush(0x057C);\n        break;\n      case 0x054D:\n        bufpush(0x057D);\n        break;\n      case 0x054E:\n        bufpush(0x057E);\n        break;\n      case 0x054F:\n        bufpush(0x057F);\n        break;\n      case 0x0550:\n        bufpush(0x0580);\n        break;\n      case 0x0551:\n        bufpush(0x0581);\n        break;\n      case 0x0552:\n        bufpush(0x0582);\n        break;\n      case 0x0553:\n        bufpush(0x0583);\n        break;\n      case 0x0554:\n        bufpush(0x0584);\n        break;\n      case 0x0555:\n        bufpush(0x0585);\n        break;\n      case 0x0556:\n        bufpush(0x0586);\n        break;\n      case 0x0587:\n        bufpush(0x0565);\n        bufpush(0x0582);\n        break;\n      case 0x10A0:\n        bufpush(0x2D00);\n        break;\n      case 0x10A1:\n        bufpush(0x2D01);\n        break;\n      case 0x10A2:\n        bufpush(0x2D02);\n        break;\n      case 0x10A3:\n        bufpush(0x2D03);\n        break;\n      case 0x10A4:\n        bufpush(0x2D04);\n        break;\n      case 0x10A5:\n        bufpush(0x2D05);\n        break;\n      case 0x10A6:\n        bufpush(0x2D06);\n        break;\n      case 0x10A7:\n        bufpush(0x2D07);\n        break;\n      case 0x10A8:\n        bufpush(0x2D08);\n        break;\n      case 0x10A9:\n        bufpush(0x2D09);\n        break;\n      case 0x10AA:\n        bufpush(0x2D0A);\n        break;\n      case 0x10AB:\n        bufpush(0x2D0B);\n        break;\n      case 0x10AC:\n        bufpush(0x2D0C);\n        break;\n      case 0x10AD:\n        bufpush(0x2D0D);\n        break;\n      case 0x10AE:\n        bufpush(0x2D0E);\n        break;\n      case 0x10AF:\n        bufpush(0x2D0F);\n        break;\n      case 0x10B0:\n        bufpush(0x2D10);\n        break;\n      case 0x10B1:\n        bufpush(0x2D11);\n        break;\n      case 0x10B2:\n        bufpush(0x2D12);\n        break;\n      case 0x10B3:\n        bufpush(0x2D13);\n        break;\n      case 0x10B4:\n        bufpush(0x2D14);\n        break;\n      case 0x10B5:\n        bufpush(0x2D15);\n        break;\n      case 0x10B6:\n        bufpush(0x2D16);\n        break;\n      case 0x10B7:\n        bufpush(0x2D17);\n        break;\n      case 0x10B8:\n        bufpush(0x2D18);\n        break;\n      case 0x10B9:\n        bufpush(0x2D19);\n        break;\n      case 0x10BA:\n        bufpush(0x2D1A);\n        break;\n      case 0x10BB:\n        bufpush(0x2D1B);\n        break;\n      case 0x10BC:\n        bufpush(0x2D1C);\n        break;\n      case 0x10BD:\n        bufpush(0x2D1D);\n        break;\n      case 0x10BE:\n        bufpush(0x2D1E);\n        break;\n      case 0x10BF:\n        bufpush(0x2D1F);\n        break;\n      case 0x10C0:\n        bufpush(0x2D20);\n        break;\n      case 0x10C1:\n        bufpush(0x2D21);\n        break;\n      case 0x10C2:\n        bufpush(0x2D22);\n        break;\n      case 0x10C3:\n        bufpush(0x2D23);\n        break;\n      case 0x10C4:\n        bufpush(0x2D24);\n        break;\n      case 0x10C5:\n        bufpush(0x2D25);\n        break;\n      case 0x10C7:\n        bufpush(0x2D27);\n        break;\n      case 0x10CD:\n        bufpush(0x2D2D);\n        break;\n      case 0x13F8:\n        bufpush(0x13F0);\n        break;\n      case 0x13F9:\n        bufpush(0x13F1);\n        break;\n      case 0x13FA:\n        bufpush(0x13F2);\n        break;\n      case 0x13FB:\n        bufpush(0x13F3);\n        break;\n      case 0x13FC:\n        bufpush(0x13F4);\n        break;\n      case 0x13FD:\n        bufpush(0x13F5);\n        break;\n      case 0x1C80:\n        bufpush(0x0432);\n        break;\n      case 0x1C81:\n        bufpush(0x0434);\n        break;\n      case 0x1C82:\n        bufpush(0x043E);\n        break;\n      case 0x1C83:\n        bufpush(0x0441);\n        break;\n      case 0x1C84:\n        bufpush(0x0442);\n        break;\n      case 0x1C85:\n        bufpush(0x0442);\n        break;\n      case 0x1C86:\n        bufpush(0x044A);\n        break;\n      case 0x1C87:\n        bufpush(0x0463);\n        break;\n      case 0x1C88:\n        bufpush(0xA64B);\n        break;\n      case 0x1E00:\n        bufpush(0x1E01);\n        break;\n      case 0x1E02:\n        bufpush(0x1E03);\n        break;\n      case 0x1E04:\n        bufpush(0x1E05);\n        break;\n      case 0x1E06:\n        bufpush(0x1E07);\n        break;\n      case 0x1E08:\n        bufpush(0x1E09);\n        break;\n      case 0x1E0A:\n        bufpush(0x1E0B);\n        break;\n      case 0x1E0C:\n        bufpush(0x1E0D);\n        break;\n      case 0x1E0E:\n        bufpush(0x1E0F);\n        break;\n      case 0x1E10:\n        bufpush(0x1E11);\n        break;\n      case 0x1E12:\n        bufpush(0x1E13);\n        break;\n      case 0x1E14:\n        bufpush(0x1E15);\n        break;\n      case 0x1E16:\n        bufpush(0x1E17);\n        break;\n      case 0x1E18:\n        bufpush(0x1E19);\n        break;\n      case 0x1E1A:\n        bufpush(0x1E1B);\n        break;\n      case 0x1E1C:\n        bufpush(0x1E1D);\n        break;\n      case 0x1E1E:\n        bufpush(0x1E1F);\n        break;\n      case 0x1E20:\n        bufpush(0x1E21);\n        break;\n      case 0x1E22:\n        bufpush(0x1E23);\n        break;\n      case 0x1E24:\n        bufpush(0x1E25);\n        break;\n      case 0x1E26:\n        bufpush(0x1E27);\n        break;\n      case 0x1E28:\n        bufpush(0x1E29);\n        break;\n      case 0x1E2A:\n        bufpush(0x1E2B);\n        break;\n      case 0x1E2C:\n        bufpush(0x1E2D);\n        break;\n      case 0x1E2E:\n        bufpush(0x1E2F);\n        break;\n      case 0x1E30:\n        bufpush(0x1E31);\n        break;\n      case 0x1E32:\n        bufpush(0x1E33);\n        break;\n      case 0x1E34:\n        bufpush(0x1E35);\n        break;\n      case 0x1E36:\n        bufpush(0x1E37);\n        break;\n      case 0x1E38:\n        bufpush(0x1E39);\n        break;\n      case 0x1E3A:\n        bufpush(0x1E3B);\n        break;\n      case 0x1E3C:\n        bufpush(0x1E3D);\n        break;\n      case 0x1E3E:\n        bufpush(0x1E3F);\n        break;\n      case 0x1E40:\n        bufpush(0x1E41);\n        break;\n      case 0x1E42:\n        bufpush(0x1E43);\n        break;\n      case 0x1E44:\n        bufpush(0x1E45);\n        break;\n      case 0x1E46:\n        bufpush(0x1E47);\n        break;\n      case 0x1E48:\n        bufpush(0x1E49);\n        break;\n      case 0x1E4A:\n        bufpush(0x1E4B);\n        break;\n      case 0x1E4C:\n        bufpush(0x1E4D);\n        break;\n      case 0x1E4E:\n        bufpush(0x1E4F);\n        break;\n      case 0x1E50:\n        bufpush(0x1E51);\n        break;\n      case 0x1E52:\n        bufpush(0x1E53);\n        break;\n      case 0x1E54:\n        bufpush(0x1E55);\n        break;\n      case 0x1E56:\n        bufpush(0x1E57);\n        break;\n      case 0x1E58:\n        bufpush(0x1E59);\n        break;\n      case 0x1E5A:\n        bufpush(0x1E5B);\n        break;\n      case 0x1E5C:\n        bufpush(0x1E5D);\n        break;\n      case 0x1E5E:\n        bufpush(0x1E5F);\n        break;\n      case 0x1E60:\n        bufpush(0x1E61);\n        break;\n      case 0x1E62:\n        bufpush(0x1E63);\n        break;\n      case 0x1E64:\n        bufpush(0x1E65);\n        break;\n      case 0x1E66:\n        bufpush(0x1E67);\n        break;\n      case 0x1E68:\n        bufpush(0x1E69);\n        break;\n      case 0x1E6A:\n        bufpush(0x1E6B);\n        break;\n      case 0x1E6C:\n        bufpush(0x1E6D);\n        break;\n      case 0x1E6E:\n        bufpush(0x1E6F);\n        break;\n      case 0x1E70:\n        bufpush(0x1E71);\n        break;\n      case 0x1E72:\n        bufpush(0x1E73);\n        break;\n      case 0x1E74:\n        bufpush(0x1E75);\n        break;\n      case 0x1E76:\n        bufpush(0x1E77);\n        break;\n      case 0x1E78:\n        bufpush(0x1E79);\n        break;\n      case 0x1E7A:\n        bufpush(0x1E7B);\n        break;\n      case 0x1E7C:\n        bufpush(0x1E7D);\n        break;\n      case 0x1E7E:\n        bufpush(0x1E7F);\n        break;\n      case 0x1E80:\n        bufpush(0x1E81);\n        break;\n      case 0x1E82:\n        bufpush(0x1E83);\n        break;\n      case 0x1E84:\n        bufpush(0x1E85);\n        break;\n      case 0x1E86:\n        bufpush(0x1E87);\n        break;\n      case 0x1E88:\n        bufpush(0x1E89);\n        break;\n      case 0x1E8A:\n        bufpush(0x1E8B);\n        break;\n      case 0x1E8C:\n        bufpush(0x1E8D);\n        break;\n      case 0x1E8E:\n        bufpush(0x1E8F);\n        break;\n      case 0x1E90:\n        bufpush(0x1E91);\n        break;\n      case 0x1E92:\n        bufpush(0x1E93);\n        break;\n      case 0x1E94:\n        bufpush(0x1E95);\n        break;\n      case 0x1E96:\n        bufpush(0x0068);\n        bufpush(0x0331);\n        break;\n      case 0x1E97:\n        bufpush(0x0074);\n        bufpush(0x0308);\n        break;\n      case 0x1E98:\n        bufpush(0x0077);\n        bufpush(0x030A);\n        break;\n      case 0x1E99:\n        bufpush(0x0079);\n        bufpush(0x030A);\n        break;\n      case 0x1E9A:\n        bufpush(0x0061);\n        bufpush(0x02BE);\n        break;\n      case 0x1E9B:\n        bufpush(0x1E61);\n        break;\n      case 0x1E9E:\n        bufpush(0x0073);\n        bufpush(0x0073);\n        break;\n      case 0x1EA0:\n        bufpush(0x1EA1);\n        break;\n      case 0x1EA2:\n        bufpush(0x1EA3);\n        break;\n      case 0x1EA4:\n        bufpush(0x1EA5);\n        break;\n      case 0x1EA6:\n        bufpush(0x1EA7);\n        break;\n      case 0x1EA8:\n        bufpush(0x1EA9);\n        break;\n      case 0x1EAA:\n        bufpush(0x1EAB);\n        break;\n      case 0x1EAC:\n        bufpush(0x1EAD);\n        break;\n      case 0x1EAE:\n        bufpush(0x1EAF);\n        break;\n      case 0x1EB0:\n        bufpush(0x1EB1);\n        break;\n      case 0x1EB2:\n        bufpush(0x1EB3);\n        break;\n      case 0x1EB4:\n        bufpush(0x1EB5);\n        break;\n      case 0x1EB6:\n        bufpush(0x1EB7);\n        break;\n      case 0x1EB8:\n        bufpush(0x1EB9);\n        break;\n      case 0x1EBA:\n        bufpush(0x1EBB);\n        break;\n      case 0x1EBC:\n        bufpush(0x1EBD);\n        break;\n      case 0x1EBE:\n        bufpush(0x1EBF);\n        break;\n      case 0x1EC0:\n        bufpush(0x1EC1);\n        break;\n      case 0x1EC2:\n        bufpush(0x1EC3);\n        break;\n      case 0x1EC4:\n        bufpush(0x1EC5);\n        break;\n      case 0x1EC6:\n        bufpush(0x1EC7);\n        break;\n      case 0x1EC8:\n        bufpush(0x1EC9);\n        break;\n      case 0x1ECA:\n        bufpush(0x1ECB);\n        break;\n      case 0x1ECC:\n        bufpush(0x1ECD);\n        break;\n      case 0x1ECE:\n        bufpush(0x1ECF);\n        break;\n      case 0x1ED0:\n        bufpush(0x1ED1);\n        break;\n      case 0x1ED2:\n        bufpush(0x1ED3);\n        break;\n      case 0x1ED4:\n        bufpush(0x1ED5);\n        break;\n      case 0x1ED6:\n        bufpush(0x1ED7);\n        break;\n      case 0x1ED8:\n        bufpush(0x1ED9);\n        break;\n      case 0x1EDA:\n        bufpush(0x1EDB);\n        break;\n      case 0x1EDC:\n        bufpush(0x1EDD);\n        break;\n      case 0x1EDE:\n        bufpush(0x1EDF);\n        break;\n      case 0x1EE0:\n        bufpush(0x1EE1);\n        break;\n      case 0x1EE2:\n        bufpush(0x1EE3);\n        break;\n      case 0x1EE4:\n        bufpush(0x1EE5);\n        break;\n      case 0x1EE6:\n        bufpush(0x1EE7);\n        break;\n      case 0x1EE8:\n        bufpush(0x1EE9);\n        break;\n      case 0x1EEA:\n        bufpush(0x1EEB);\n        break;\n      case 0x1EEC:\n        bufpush(0x1EED);\n        break;\n      case 0x1EEE:\n        bufpush(0x1EEF);\n        break;\n      case 0x1EF0:\n        bufpush(0x1EF1);\n        break;\n      case 0x1EF2:\n        bufpush(0x1EF3);\n        break;\n      case 0x1EF4:\n        bufpush(0x1EF5);\n        break;\n      case 0x1EF6:\n        bufpush(0x1EF7);\n        break;\n      case 0x1EF8:\n        bufpush(0x1EF9);\n        break;\n      case 0x1EFA:\n        bufpush(0x1EFB);\n        break;\n      case 0x1EFC:\n        bufpush(0x1EFD);\n        break;\n      case 0x1EFE:\n        bufpush(0x1EFF);\n        break;\n      case 0x1F08:\n        bufpush(0x1F00);\n        break;\n      case 0x1F09:\n        bufpush(0x1F01);\n        break;\n      case 0x1F0A:\n        bufpush(0x1F02);\n        break;\n      case 0x1F0B:\n        bufpush(0x1F03);\n        break;\n      case 0x1F0C:\n        bufpush(0x1F04);\n        break;\n      case 0x1F0D:\n        bufpush(0x1F05);\n        break;\n      case 0x1F0E:\n        bufpush(0x1F06);\n        break;\n      case 0x1F0F:\n        bufpush(0x1F07);\n        break;\n      case 0x1F18:\n        bufpush(0x1F10);\n        break;\n      case 0x1F19:\n        bufpush(0x1F11);\n        break;\n      case 0x1F1A:\n        bufpush(0x1F12);\n        break;\n      case 0x1F1B:\n        bufpush(0x1F13);\n        break;\n      case 0x1F1C:\n        bufpush(0x1F14);\n        break;\n      case 0x1F1D:\n        bufpush(0x1F15);\n        break;\n      case 0x1F28:\n        bufpush(0x1F20);\n        break;\n      case 0x1F29:\n        bufpush(0x1F21);\n        break;\n      case 0x1F2A:\n        bufpush(0x1F22);\n        break;\n      case 0x1F2B:\n        bufpush(0x1F23);\n        break;\n      case 0x1F2C:\n        bufpush(0x1F24);\n        break;\n      case 0x1F2D:\n        bufpush(0x1F25);\n        break;\n      case 0x1F2E:\n        bufpush(0x1F26);\n        break;\n      case 0x1F2F:\n        bufpush(0x1F27);\n        break;\n      case 0x1F38:\n        bufpush(0x1F30);\n        break;\n      case 0x1F39:\n        bufpush(0x1F31);\n        break;\n      case 0x1F3A:\n        bufpush(0x1F32);\n        break;\n      case 0x1F3B:\n        bufpush(0x1F33);\n        break;\n      case 0x1F3C:\n        bufpush(0x1F34);\n        break;\n      case 0x1F3D:\n        bufpush(0x1F35);\n        break;\n      case 0x1F3E:\n        bufpush(0x1F36);\n        break;\n      case 0x1F3F:\n        bufpush(0x1F37);\n        break;\n      case 0x1F48:\n        bufpush(0x1F40);\n        break;\n      case 0x1F49:\n        bufpush(0x1F41);\n        break;\n      case 0x1F4A:\n        bufpush(0x1F42);\n        break;\n      case 0x1F4B:\n        bufpush(0x1F43);\n        break;\n      case 0x1F4C:\n        bufpush(0x1F44);\n        break;\n      case 0x1F4D:\n        bufpush(0x1F45);\n        break;\n      case 0x1F50:\n        bufpush(0x03C5);\n        bufpush(0x0313);\n        break;\n      case 0x1F52:\n        bufpush(0x03C5);\n        bufpush(0x0313);\n        bufpush(0x0300);\n        break;\n      case 0x1F54:\n        bufpush(0x03C5);\n        bufpush(0x0313);\n        bufpush(0x0301);\n        break;\n      case 0x1F56:\n        bufpush(0x03C5);\n        bufpush(0x0313);\n        bufpush(0x0342);\n        break;\n      case 0x1F59:\n        bufpush(0x1F51);\n        break;\n      case 0x1F5B:\n        bufpush(0x1F53);\n        break;\n      case 0x1F5D:\n        bufpush(0x1F55);\n        break;\n      case 0x1F5F:\n        bufpush(0x1F57);\n        break;\n      case 0x1F68:\n        bufpush(0x1F60);\n        break;\n      case 0x1F69:\n        bufpush(0x1F61);\n        break;\n      case 0x1F6A:\n        bufpush(0x1F62);\n        break;\n      case 0x1F6B:\n        bufpush(0x1F63);\n        break;\n      case 0x1F6C:\n        bufpush(0x1F64);\n        break;\n      case 0x1F6D:\n        bufpush(0x1F65);\n        break;\n      case 0x1F6E:\n        bufpush(0x1F66);\n        break;\n      case 0x1F6F:\n        bufpush(0x1F67);\n        break;\n      case 0x1F80:\n        bufpush(0x1F00);\n        bufpush(0x03B9);\n        break;\n      case 0x1F81:\n        bufpush(0x1F01);\n        bufpush(0x03B9);\n        break;\n      case 0x1F82:\n        bufpush(0x1F02);\n        bufpush(0x03B9);\n        break;\n      case 0x1F83:\n        bufpush(0x1F03);\n        bufpush(0x03B9);\n        break;\n      case 0x1F84:\n        bufpush(0x1F04);\n        bufpush(0x03B9);\n        break;\n      case 0x1F85:\n        bufpush(0x1F05);\n        bufpush(0x03B9);\n        break;\n      case 0x1F86:\n        bufpush(0x1F06);\n        bufpush(0x03B9);\n        break;\n      case 0x1F87:\n        bufpush(0x1F07);\n        bufpush(0x03B9);\n        break;\n      case 0x1F88:\n        bufpush(0x1F00);\n        bufpush(0x03B9);\n        break;\n      case 0x1F89:\n        bufpush(0x1F01);\n        bufpush(0x03B9);\n        break;\n      case 0x1F8A:\n        bufpush(0x1F02);\n        bufpush(0x03B9);\n        break;\n      case 0x1F8B:\n        bufpush(0x1F03);\n        bufpush(0x03B9);\n        break;\n      case 0x1F8C:\n        bufpush(0x1F04);\n        bufpush(0x03B9);\n        break;\n      case 0x1F8D:\n        bufpush(0x1F05);\n        bufpush(0x03B9);\n        break;\n      case 0x1F8E:\n        bufpush(0x1F06);\n        bufpush(0x03B9);\n        break;\n      case 0x1F8F:\n        bufpush(0x1F07);\n        bufpush(0x03B9);\n        break;\n      case 0x1F90:\n        bufpush(0x1F20);\n        bufpush(0x03B9);\n        break;\n      case 0x1F91:\n        bufpush(0x1F21);\n        bufpush(0x03B9);\n        break;\n      case 0x1F92:\n        bufpush(0x1F22);\n        bufpush(0x03B9);\n        break;\n      case 0x1F93:\n        bufpush(0x1F23);\n        bufpush(0x03B9);\n        break;\n      case 0x1F94:\n        bufpush(0x1F24);\n        bufpush(0x03B9);\n        break;\n      case 0x1F95:\n        bufpush(0x1F25);\n        bufpush(0x03B9);\n        break;\n      case 0x1F96:\n        bufpush(0x1F26);\n        bufpush(0x03B9);\n        break;\n      case 0x1F97:\n        bufpush(0x1F27);\n        bufpush(0x03B9);\n        break;\n      case 0x1F98:\n        bufpush(0x1F20);\n        bufpush(0x03B9);\n        break;\n      case 0x1F99:\n        bufpush(0x1F21);\n        bufpush(0x03B9);\n        break;\n      case 0x1F9A:\n        bufpush(0x1F22);\n        bufpush(0x03B9);\n        break;\n      case 0x1F9B:\n        bufpush(0x1F23);\n        bufpush(0x03B9);\n        break;\n      case 0x1F9C:\n        bufpush(0x1F24);\n        bufpush(0x03B9);\n        break;\n      case 0x1F9D:\n        bufpush(0x1F25);\n        bufpush(0x03B9);\n        break;\n      case 0x1F9E:\n        bufpush(0x1F26);\n        bufpush(0x03B9);\n        break;\n      case 0x1F9F:\n        bufpush(0x1F27);\n        bufpush(0x03B9);\n        break;\n      case 0x1FA0:\n        bufpush(0x1F60);\n        bufpush(0x03B9);\n        break;\n      case 0x1FA1:\n        bufpush(0x1F61);\n        bufpush(0x03B9);\n        break;\n      case 0x1FA2:\n        bufpush(0x1F62);\n        bufpush(0x03B9);\n        break;\n      case 0x1FA3:\n        bufpush(0x1F63);\n        bufpush(0x03B9);\n        break;\n      case 0x1FA4:\n        bufpush(0x1F64);\n        bufpush(0x03B9);\n        break;\n      case 0x1FA5:\n        bufpush(0x1F65);\n        bufpush(0x03B9);\n        break;\n      case 0x1FA6:\n        bufpush(0x1F66);\n        bufpush(0x03B9);\n        break;\n      case 0x1FA7:\n        bufpush(0x1F67);\n        bufpush(0x03B9);\n        break;\n      case 0x1FA8:\n        bufpush(0x1F60);\n        bufpush(0x03B9);\n        break;\n      case 0x1FA9:\n        bufpush(0x1F61);\n        bufpush(0x03B9);\n        break;\n      case 0x1FAA:\n        bufpush(0x1F62);\n        bufpush(0x03B9);\n        break;\n      case 0x1FAB:\n        bufpush(0x1F63);\n        bufpush(0x03B9);\n        break;\n      case 0x1FAC:\n        bufpush(0x1F64);\n        bufpush(0x03B9);\n        break;\n      case 0x1FAD:\n        bufpush(0x1F65);\n        bufpush(0x03B9);\n        break;\n      case 0x1FAE:\n        bufpush(0x1F66);\n        bufpush(0x03B9);\n        break;\n      case 0x1FAF:\n        bufpush(0x1F67);\n        bufpush(0x03B9);\n        break;\n      case 0x1FB2:\n        bufpush(0x1F70);\n        bufpush(0x03B9);\n        break;\n      case 0x1FB3:\n        bufpush(0x03B1);\n        bufpush(0x03B9);\n        break;\n      case 0x1FB4:\n        bufpush(0x03AC);\n        bufpush(0x03B9);\n        break;\n      case 0x1FB6:\n        bufpush(0x03B1);\n        bufpush(0x0342);\n        break;\n      case 0x1FB7:\n        bufpush(0x03B1);\n        bufpush(0x0342);\n        bufpush(0x03B9);\n        break;\n      case 0x1FB8:\n        bufpush(0x1FB0);\n        break;\n      case 0x1FB9:\n        bufpush(0x1FB1);\n        break;\n      case 0x1FBA:\n        bufpush(0x1F70);\n        break;\n      case 0x1FBB:\n        bufpush(0x1F71);\n        break;\n      case 0x1FBC:\n        bufpush(0x03B1);\n        bufpush(0x03B9);\n        break;\n      case 0x1FBE:\n        bufpush(0x03B9);\n        break;\n      case 0x1FC2:\n        bufpush(0x1F74);\n        bufpush(0x03B9);\n        break;\n      case 0x1FC3:\n        bufpush(0x03B7);\n        bufpush(0x03B9);\n        break;\n      case 0x1FC4:\n        bufpush(0x03AE);\n        bufpush(0x03B9);\n        break;\n      case 0x1FC6:\n        bufpush(0x03B7);\n        bufpush(0x0342);\n        break;\n      case 0x1FC7:\n        bufpush(0x03B7);\n        bufpush(0x0342);\n        bufpush(0x03B9);\n        break;\n      case 0x1FC8:\n        bufpush(0x1F72);\n        break;\n      case 0x1FC9:\n        bufpush(0x1F73);\n        break;\n      case 0x1FCA:\n        bufpush(0x1F74);\n        break;\n      case 0x1FCB:\n        bufpush(0x1F75);\n        break;\n      case 0x1FCC:\n        bufpush(0x03B7);\n        bufpush(0x03B9);\n        break;\n      case 0x1FD2:\n        bufpush(0x03B9);\n        bufpush(0x0308);\n        bufpush(0x0300);\n        break;\n      case 0x1FD3:\n        bufpush(0x03B9);\n        bufpush(0x0308);\n        bufpush(0x0301);\n        break;\n      case 0x1FD6:\n        bufpush(0x03B9);\n        bufpush(0x0342);\n        break;\n      case 0x1FD7:\n        bufpush(0x03B9);\n        bufpush(0x0308);\n        bufpush(0x0342);\n        break;\n      case 0x1FD8:\n        bufpush(0x1FD0);\n        break;\n      case 0x1FD9:\n        bufpush(0x1FD1);\n        break;\n      case 0x1FDA:\n        bufpush(0x1F76);\n        break;\n      case 0x1FDB:\n        bufpush(0x1F77);\n        break;\n      case 0x1FE2:\n        bufpush(0x03C5);\n        bufpush(0x0308);\n        bufpush(0x0300);\n        break;\n      case 0x1FE3:\n        bufpush(0x03C5);\n        bufpush(0x0308);\n        bufpush(0x0301);\n        break;\n      case 0x1FE4:\n        bufpush(0x03C1);\n        bufpush(0x0313);\n        break;\n      case 0x1FE6:\n        bufpush(0x03C5);\n        bufpush(0x0342);\n        break;\n      case 0x1FE7:\n        bufpush(0x03C5);\n        bufpush(0x0308);\n        bufpush(0x0342);\n        break;\n      case 0x1FE8:\n        bufpush(0x1FE0);\n        break;\n      case 0x1FE9:\n        bufpush(0x1FE1);\n        break;\n      case 0x1FEA:\n        bufpush(0x1F7A);\n        break;\n      case 0x1FEB:\n        bufpush(0x1F7B);\n        break;\n      case 0x1FEC:\n        bufpush(0x1FE5);\n        break;\n      case 0x1FF2:\n        bufpush(0x1F7C);\n        bufpush(0x03B9);\n        break;\n      case 0x1FF3:\n        bufpush(0x03C9);\n        bufpush(0x03B9);\n        break;\n      case 0x1FF4:\n        bufpush(0x03CE);\n        bufpush(0x03B9);\n        break;\n      case 0x1FF6:\n        bufpush(0x03C9);\n        bufpush(0x0342);\n        break;\n      case 0x1FF7:\n        bufpush(0x03C9);\n        bufpush(0x0342);\n        bufpush(0x03B9);\n        break;\n      case 0x1FF8:\n        bufpush(0x1F78);\n        break;\n      case 0x1FF9:\n        bufpush(0x1F79);\n        break;\n      case 0x1FFA:\n        bufpush(0x1F7C);\n        break;\n      case 0x1FFB:\n        bufpush(0x1F7D);\n        break;\n      case 0x1FFC:\n        bufpush(0x03C9);\n        bufpush(0x03B9);\n        break;\n      case 0x2126:\n        bufpush(0x03C9);\n        break;\n      case 0x212A:\n        bufpush(0x006B);\n        break;\n      case 0x212B:\n        bufpush(0x00E5);\n        break;\n      case 0x2132:\n        bufpush(0x214E);\n        break;\n      case 0x2160:\n        bufpush(0x2170);\n        break;\n      case 0x2161:\n        bufpush(0x2171);\n        break;\n      case 0x2162:\n        bufpush(0x2172);\n        break;\n      case 0x2163:\n        bufpush(0x2173);\n        break;\n      case 0x2164:\n        bufpush(0x2174);\n        break;\n      case 0x2165:\n        bufpush(0x2175);\n        break;\n      case 0x2166:\n        bufpush(0x2176);\n        break;\n      case 0x2167:\n        bufpush(0x2177);\n        break;\n      case 0x2168:\n        bufpush(0x2178);\n        break;\n      case 0x2169:\n        bufpush(0x2179);\n        break;\n      case 0x216A:\n        bufpush(0x217A);\n        break;\n      case 0x216B:\n        bufpush(0x217B);\n        break;\n      case 0x216C:\n        bufpush(0x217C);\n        break;\n      case 0x216D:\n        bufpush(0x217D);\n        break;\n      case 0x216E:\n        bufpush(0x217E);\n        break;\n      case 0x216F:\n        bufpush(0x217F);\n        break;\n      case 0x2183:\n        bufpush(0x2184);\n        break;\n      case 0x24B6:\n        bufpush(0x24D0);\n        break;\n      case 0x24B7:\n        bufpush(0x24D1);\n        break;\n      case 0x24B8:\n        bufpush(0x24D2);\n        break;\n      case 0x24B9:\n        bufpush(0x24D3);\n        break;\n      case 0x24BA:\n        bufpush(0x24D4);\n        break;\n      case 0x24BB:\n        bufpush(0x24D5);\n        break;\n      case 0x24BC:\n        bufpush(0x24D6);\n        break;\n      case 0x24BD:\n        bufpush(0x24D7);\n        break;\n      case 0x24BE:\n        bufpush(0x24D8);\n        break;\n      case 0x24BF:\n        bufpush(0x24D9);\n        break;\n      case 0x24C0:\n        bufpush(0x24DA);\n        break;\n      case 0x24C1:\n        bufpush(0x24DB);\n        break;\n      case 0x24C2:\n        bufpush(0x24DC);\n        break;\n      case 0x24C3:\n        bufpush(0x24DD);\n        break;\n      case 0x24C4:\n        bufpush(0x24DE);\n        break;\n      case 0x24C5:\n        bufpush(0x24DF);\n        break;\n      case 0x24C6:\n        bufpush(0x24E0);\n        break;\n      case 0x24C7:\n        bufpush(0x24E1);\n        break;\n      case 0x24C8:\n        bufpush(0x24E2);\n        break;\n      case 0x24C9:\n        bufpush(0x24E3);\n        break;\n      case 0x24CA:\n        bufpush(0x24E4);\n        break;\n      case 0x24CB:\n        bufpush(0x24E5);\n        break;\n      case 0x24CC:\n        bufpush(0x24E6);\n        break;\n      case 0x24CD:\n        bufpush(0x24E7);\n        break;\n      case 0x24CE:\n        bufpush(0x24E8);\n        break;\n      case 0x24CF:\n        bufpush(0x24E9);\n        break;\n      case 0x2C00:\n        bufpush(0x2C30);\n        break;\n      case 0x2C01:\n        bufpush(0x2C31);\n        break;\n      case 0x2C02:\n        bufpush(0x2C32);\n        break;\n      case 0x2C03:\n        bufpush(0x2C33);\n        break;\n      case 0x2C04:\n        bufpush(0x2C34);\n        break;\n      case 0x2C05:\n        bufpush(0x2C35);\n        break;\n      case 0x2C06:\n        bufpush(0x2C36);\n        break;\n      case 0x2C07:\n        bufpush(0x2C37);\n        break;\n      case 0x2C08:\n        bufpush(0x2C38);\n        break;\n      case 0x2C09:\n        bufpush(0x2C39);\n        break;\n      case 0x2C0A:\n        bufpush(0x2C3A);\n        break;\n      case 0x2C0B:\n        bufpush(0x2C3B);\n        break;\n      case 0x2C0C:\n        bufpush(0x2C3C);\n        break;\n      case 0x2C0D:\n        bufpush(0x2C3D);\n        break;\n      case 0x2C0E:\n        bufpush(0x2C3E);\n        break;\n      case 0x2C0F:\n        bufpush(0x2C3F);\n        break;\n      case 0x2C10:\n        bufpush(0x2C40);\n        break;\n      case 0x2C11:\n        bufpush(0x2C41);\n        break;\n      case 0x2C12:\n        bufpush(0x2C42);\n        break;\n      case 0x2C13:\n        bufpush(0x2C43);\n        break;\n      case 0x2C14:\n        bufpush(0x2C44);\n        break;\n      case 0x2C15:\n        bufpush(0x2C45);\n        break;\n      case 0x2C16:\n        bufpush(0x2C46);\n        break;\n      case 0x2C17:\n        bufpush(0x2C47);\n        break;\n      case 0x2C18:\n        bufpush(0x2C48);\n        break;\n      case 0x2C19:\n        bufpush(0x2C49);\n        break;\n      case 0x2C1A:\n        bufpush(0x2C4A);\n        break;\n      case 0x2C1B:\n        bufpush(0x2C4B);\n        break;\n      case 0x2C1C:\n        bufpush(0x2C4C);\n        break;\n      case 0x2C1D:\n        bufpush(0x2C4D);\n        break;\n      case 0x2C1E:\n        bufpush(0x2C4E);\n        break;\n      case 0x2C1F:\n        bufpush(0x2C4F);\n        break;\n      case 0x2C20:\n        bufpush(0x2C50);\n        break;\n      case 0x2C21:\n        bufpush(0x2C51);\n        break;\n      case 0x2C22:\n        bufpush(0x2C52);\n        break;\n      case 0x2C23:\n        bufpush(0x2C53);\n        break;\n      case 0x2C24:\n        bufpush(0x2C54);\n        break;\n      case 0x2C25:\n        bufpush(0x2C55);\n        break;\n      case 0x2C26:\n        bufpush(0x2C56);\n        break;\n      case 0x2C27:\n        bufpush(0x2C57);\n        break;\n      case 0x2C28:\n        bufpush(0x2C58);\n        break;\n      case 0x2C29:\n        bufpush(0x2C59);\n        break;\n      case 0x2C2A:\n        bufpush(0x2C5A);\n        break;\n      case 0x2C2B:\n        bufpush(0x2C5B);\n        break;\n      case 0x2C2C:\n        bufpush(0x2C5C);\n        break;\n      case 0x2C2D:\n        bufpush(0x2C5D);\n        break;\n      case 0x2C2E:\n        bufpush(0x2C5E);\n        break;\n      case 0x2C60:\n        bufpush(0x2C61);\n        break;\n      case 0x2C62:\n        bufpush(0x026B);\n        break;\n      case 0x2C63:\n        bufpush(0x1D7D);\n        break;\n      case 0x2C64:\n        bufpush(0x027D);\n        break;\n      case 0x2C67:\n        bufpush(0x2C68);\n        break;\n      case 0x2C69:\n        bufpush(0x2C6A);\n        break;\n      case 0x2C6B:\n        bufpush(0x2C6C);\n        break;\n      case 0x2C6D:\n        bufpush(0x0251);\n        break;\n      case 0x2C6E:\n        bufpush(0x0271);\n        break;\n      case 0x2C6F:\n        bufpush(0x0250);\n        break;\n      case 0x2C70:\n        bufpush(0x0252);\n        break;\n      case 0x2C72:\n        bufpush(0x2C73);\n        break;\n      case 0x2C75:\n        bufpush(0x2C76);\n        break;\n      case 0x2C7E:\n        bufpush(0x023F);\n        break;\n      case 0x2C7F:\n        bufpush(0x0240);\n        break;\n      case 0x2C80:\n        bufpush(0x2C81);\n        break;\n      case 0x2C82:\n        bufpush(0x2C83);\n        break;\n      case 0x2C84:\n        bufpush(0x2C85);\n        break;\n      case 0x2C86:\n        bufpush(0x2C87);\n        break;\n      case 0x2C88:\n        bufpush(0x2C89);\n        break;\n      case 0x2C8A:\n        bufpush(0x2C8B);\n        break;\n      case 0x2C8C:\n        bufpush(0x2C8D);\n        break;\n      case 0x2C8E:\n        bufpush(0x2C8F);\n        break;\n      case 0x2C90:\n        bufpush(0x2C91);\n        break;\n      case 0x2C92:\n        bufpush(0x2C93);\n        break;\n      case 0x2C94:\n        bufpush(0x2C95);\n        break;\n      case 0x2C96:\n        bufpush(0x2C97);\n        break;\n      case 0x2C98:\n        bufpush(0x2C99);\n        break;\n      case 0x2C9A:\n        bufpush(0x2C9B);\n        break;\n      case 0x2C9C:\n        bufpush(0x2C9D);\n        break;\n      case 0x2C9E:\n        bufpush(0x2C9F);\n        break;\n      case 0x2CA0:\n        bufpush(0x2CA1);\n        break;\n      case 0x2CA2:\n        bufpush(0x2CA3);\n        break;\n      case 0x2CA4:\n        bufpush(0x2CA5);\n        break;\n      case 0x2CA6:\n        bufpush(0x2CA7);\n        break;\n      case 0x2CA8:\n        bufpush(0x2CA9);\n        break;\n      case 0x2CAA:\n        bufpush(0x2CAB);\n        break;\n      case 0x2CAC:\n        bufpush(0x2CAD);\n        break;\n      case 0x2CAE:\n        bufpush(0x2CAF);\n        break;\n      case 0x2CB0:\n        bufpush(0x2CB1);\n        break;\n      case 0x2CB2:\n        bufpush(0x2CB3);\n        break;\n      case 0x2CB4:\n        bufpush(0x2CB5);\n        break;\n      case 0x2CB6:\n        bufpush(0x2CB7);\n        break;\n      case 0x2CB8:\n        bufpush(0x2CB9);\n        break;\n      case 0x2CBA:\n        bufpush(0x2CBB);\n        break;\n      case 0x2CBC:\n        bufpush(0x2CBD);\n        break;\n      case 0x2CBE:\n        bufpush(0x2CBF);\n        break;\n      case 0x2CC0:\n        bufpush(0x2CC1);\n        break;\n      case 0x2CC2:\n        bufpush(0x2CC3);\n        break;\n      case 0x2CC4:\n        bufpush(0x2CC5);\n        break;\n      case 0x2CC6:\n        bufpush(0x2CC7);\n        break;\n      case 0x2CC8:\n        bufpush(0x2CC9);\n        break;\n      case 0x2CCA:\n        bufpush(0x2CCB);\n        break;\n      case 0x2CCC:\n        bufpush(0x2CCD);\n        break;\n      case 0x2CCE:\n        bufpush(0x2CCF);\n        break;\n      case 0x2CD0:\n        bufpush(0x2CD1);\n        break;\n      case 0x2CD2:\n        bufpush(0x2CD3);\n        break;\n      case 0x2CD4:\n        bufpush(0x2CD5);\n        break;\n      case 0x2CD6:\n        bufpush(0x2CD7);\n        break;\n      case 0x2CD8:\n        bufpush(0x2CD9);\n        break;\n      case 0x2CDA:\n        bufpush(0x2CDB);\n        break;\n      case 0x2CDC:\n        bufpush(0x2CDD);\n        break;\n      case 0x2CDE:\n        bufpush(0x2CDF);\n        break;\n      case 0x2CE0:\n        bufpush(0x2CE1);\n        break;\n      case 0x2CE2:\n        bufpush(0x2CE3);\n        break;\n      case 0x2CEB:\n        bufpush(0x2CEC);\n        break;\n      case 0x2CED:\n        bufpush(0x2CEE);\n        break;\n      case 0x2CF2:\n        bufpush(0x2CF3);\n        break;\n      case 0xA640:\n        bufpush(0xA641);\n        break;\n      case 0xA642:\n        bufpush(0xA643);\n        break;\n      case 0xA644:\n        bufpush(0xA645);\n        break;\n      case 0xA646:\n        bufpush(0xA647);\n        break;\n      case 0xA648:\n        bufpush(0xA649);\n        break;\n      case 0xA64A:\n        bufpush(0xA64B);\n        break;\n      case 0xA64C:\n        bufpush(0xA64D);\n        break;\n      case 0xA64E:\n        bufpush(0xA64F);\n        break;\n      case 0xA650:\n        bufpush(0xA651);\n        break;\n      case 0xA652:\n        bufpush(0xA653);\n        break;\n      case 0xA654:\n        bufpush(0xA655);\n        break;\n      case 0xA656:\n        bufpush(0xA657);\n        break;\n      case 0xA658:\n        bufpush(0xA659);\n        break;\n      case 0xA65A:\n        bufpush(0xA65B);\n        break;\n      case 0xA65C:\n        bufpush(0xA65D);\n        break;\n      case 0xA65E:\n        bufpush(0xA65F);\n        break;\n      case 0xA660:\n        bufpush(0xA661);\n        break;\n      case 0xA662:\n        bufpush(0xA663);\n        break;\n      case 0xA664:\n        bufpush(0xA665);\n        break;\n      case 0xA666:\n        bufpush(0xA667);\n        break;\n      case 0xA668:\n        bufpush(0xA669);\n        break;\n      case 0xA66A:\n        bufpush(0xA66B);\n        break;\n      case 0xA66C:\n        bufpush(0xA66D);\n        break;\n      case 0xA680:\n        bufpush(0xA681);\n        break;\n      case 0xA682:\n        bufpush(0xA683);\n        break;\n      case 0xA684:\n        bufpush(0xA685);\n        break;\n      case 0xA686:\n        bufpush(0xA687);\n        break;\n      case 0xA688:\n        bufpush(0xA689);\n        break;\n      case 0xA68A:\n        bufpush(0xA68B);\n        break;\n      case 0xA68C:\n        bufpush(0xA68D);\n        break;\n      case 0xA68E:\n        bufpush(0xA68F);\n        break;\n      case 0xA690:\n        bufpush(0xA691);\n        break;\n      case 0xA692:\n        bufpush(0xA693);\n        break;\n      case 0xA694:\n        bufpush(0xA695);\n        break;\n      case 0xA696:\n        bufpush(0xA697);\n        break;\n      case 0xA698:\n        bufpush(0xA699);\n        break;\n      case 0xA69A:\n        bufpush(0xA69B);\n        break;\n      case 0xA722:\n        bufpush(0xA723);\n        break;\n      case 0xA724:\n        bufpush(0xA725);\n        break;\n      case 0xA726:\n        bufpush(0xA727);\n        break;\n      case 0xA728:\n        bufpush(0xA729);\n        break;\n      case 0xA72A:\n        bufpush(0xA72B);\n        break;\n      case 0xA72C:\n        bufpush(0xA72D);\n        break;\n      case 0xA72E:\n        bufpush(0xA72F);\n        break;\n      case 0xA732:\n        bufpush(0xA733);\n        break;\n      case 0xA734:\n        bufpush(0xA735);\n        break;\n      case 0xA736:\n        bufpush(0xA737);\n        break;\n      case 0xA738:\n        bufpush(0xA739);\n        break;\n      case 0xA73A:\n        bufpush(0xA73B);\n        break;\n      case 0xA73C:\n        bufpush(0xA73D);\n        break;\n      case 0xA73E:\n        bufpush(0xA73F);\n        break;\n      case 0xA740:\n        bufpush(0xA741);\n        break;\n      case 0xA742:\n        bufpush(0xA743);\n        break;\n      case 0xA744:\n        bufpush(0xA745);\n        break;\n      case 0xA746:\n        bufpush(0xA747);\n        break;\n      case 0xA748:\n        bufpush(0xA749);\n        break;\n      case 0xA74A:\n        bufpush(0xA74B);\n        break;\n      case 0xA74C:\n        bufpush(0xA74D);\n        break;\n      case 0xA74E:\n        bufpush(0xA74F);\n        break;\n      case 0xA750:\n        bufpush(0xA751);\n        break;\n      case 0xA752:\n        bufpush(0xA753);\n        break;\n      case 0xA754:\n        bufpush(0xA755);\n        break;\n      case 0xA756:\n        bufpush(0xA757);\n        break;\n      case 0xA758:\n        bufpush(0xA759);\n        break;\n      case 0xA75A:\n        bufpush(0xA75B);\n        break;\n      case 0xA75C:\n        bufpush(0xA75D);\n        break;\n      case 0xA75E:\n        bufpush(0xA75F);\n        break;\n      case 0xA760:\n        bufpush(0xA761);\n        break;\n      case 0xA762:\n        bufpush(0xA763);\n        break;\n      case 0xA764:\n        bufpush(0xA765);\n        break;\n      case 0xA766:\n        bufpush(0xA767);\n        break;\n      case 0xA768:\n        bufpush(0xA769);\n        break;\n      case 0xA76A:\n        bufpush(0xA76B);\n        break;\n      case 0xA76C:\n        bufpush(0xA76D);\n        break;\n      case 0xA76E:\n        bufpush(0xA76F);\n        break;\n      case 0xA779:\n        bufpush(0xA77A);\n        break;\n      case 0xA77B:\n        bufpush(0xA77C);\n        break;\n      case 0xA77D:\n        bufpush(0x1D79);\n        break;\n      case 0xA77E:\n        bufpush(0xA77F);\n        break;\n      case 0xA780:\n        bufpush(0xA781);\n        break;\n      case 0xA782:\n        bufpush(0xA783);\n        break;\n      case 0xA784:\n        bufpush(0xA785);\n        break;\n      case 0xA786:\n        bufpush(0xA787);\n        break;\n      case 0xA78B:\n        bufpush(0xA78C);\n        break;\n      case 0xA78D:\n        bufpush(0x0265);\n        break;\n      case 0xA790:\n        bufpush(0xA791);\n        break;\n      case 0xA792:\n        bufpush(0xA793);\n        break;\n      case 0xA796:\n        bufpush(0xA797);\n        break;\n      case 0xA798:\n        bufpush(0xA799);\n        break;\n      case 0xA79A:\n        bufpush(0xA79B);\n        break;\n      case 0xA79C:\n        bufpush(0xA79D);\n        break;\n      case 0xA79E:\n        bufpush(0xA79F);\n        break;\n      case 0xA7A0:\n        bufpush(0xA7A1);\n        break;\n      case 0xA7A2:\n        bufpush(0xA7A3);\n        break;\n      case 0xA7A4:\n        bufpush(0xA7A5);\n        break;\n      case 0xA7A6:\n        bufpush(0xA7A7);\n        break;\n      case 0xA7A8:\n        bufpush(0xA7A9);\n        break;\n      case 0xA7AA:\n        bufpush(0x0266);\n        break;\n      case 0xA7AB:\n        bufpush(0x025C);\n        break;\n      case 0xA7AC:\n        bufpush(0x0261);\n        break;\n      case 0xA7AD:\n        bufpush(0x026C);\n        break;\n      case 0xA7AE:\n        bufpush(0x026A);\n        break;\n      case 0xA7B0:\n        bufpush(0x029E);\n        break;\n      case 0xA7B1:\n        bufpush(0x0287);\n        break;\n      case 0xA7B2:\n        bufpush(0x029D);\n        break;\n      case 0xA7B3:\n        bufpush(0xAB53);\n        break;\n      case 0xA7B4:\n        bufpush(0xA7B5);\n        break;\n      case 0xA7B6:\n        bufpush(0xA7B7);\n        break;\n      case 0xAB70:\n        bufpush(0x13A0);\n        break;\n      case 0xAB71:\n        bufpush(0x13A1);\n        break;\n      case 0xAB72:\n        bufpush(0x13A2);\n        break;\n      case 0xAB73:\n        bufpush(0x13A3);\n        break;\n      case 0xAB74:\n        bufpush(0x13A4);\n        break;\n      case 0xAB75:\n        bufpush(0x13A5);\n        break;\n      case 0xAB76:\n        bufpush(0x13A6);\n        break;\n      case 0xAB77:\n        bufpush(0x13A7);\n        break;\n      case 0xAB78:\n        bufpush(0x13A8);\n        break;\n      case 0xAB79:\n        bufpush(0x13A9);\n        break;\n      case 0xAB7A:\n        bufpush(0x13AA);\n        break;\n      case 0xAB7B:\n        bufpush(0x13AB);\n        break;\n      case 0xAB7C:\n        bufpush(0x13AC);\n        break;\n      case 0xAB7D:\n        bufpush(0x13AD);\n        break;\n      case 0xAB7E:\n        bufpush(0x13AE);\n        break;\n      case 0xAB7F:\n        bufpush(0x13AF);\n        break;\n      case 0xAB80:\n        bufpush(0x13B0);\n        break;\n      case 0xAB81:\n        bufpush(0x13B1);\n        break;\n      case 0xAB82:\n        bufpush(0x13B2);\n        break;\n      case 0xAB83:\n        bufpush(0x13B3);\n        break;\n      case 0xAB84:\n        bufpush(0x13B4);\n        break;\n      case 0xAB85:\n        bufpush(0x13B5);\n        break;\n      case 0xAB86:\n        bufpush(0x13B6);\n        break;\n      case 0xAB87:\n        bufpush(0x13B7);\n        break;\n      case 0xAB88:\n        bufpush(0x13B8);\n        break;\n      case 0xAB89:\n        bufpush(0x13B9);\n        break;\n      case 0xAB8A:\n        bufpush(0x13BA);\n        break;\n      case 0xAB8B:\n        bufpush(0x13BB);\n        break;\n      case 0xAB8C:\n        bufpush(0x13BC);\n        break;\n      case 0xAB8D:\n        bufpush(0x13BD);\n        break;\n      case 0xAB8E:\n        bufpush(0x13BE);\n        break;\n      case 0xAB8F:\n        bufpush(0x13BF);\n        break;\n      case 0xAB90:\n        bufpush(0x13C0);\n        break;\n      case 0xAB91:\n        bufpush(0x13C1);\n        break;\n      case 0xAB92:\n        bufpush(0x13C2);\n        break;\n      case 0xAB93:\n        bufpush(0x13C3);\n        break;\n      case 0xAB94:\n        bufpush(0x13C4);\n        break;\n      case 0xAB95:\n        bufpush(0x13C5);\n        break;\n      case 0xAB96:\n        bufpush(0x13C6);\n        break;\n      case 0xAB97:\n        bufpush(0x13C7);\n        break;\n      case 0xAB98:\n        bufpush(0x13C8);\n        break;\n      case 0xAB99:\n        bufpush(0x13C9);\n        break;\n      case 0xAB9A:\n        bufpush(0x13CA);\n        break;\n      case 0xAB9B:\n        bufpush(0x13CB);\n        break;\n      case 0xAB9C:\n        bufpush(0x13CC);\n        break;\n      case 0xAB9D:\n        bufpush(0x13CD);\n        break;\n      case 0xAB9E:\n        bufpush(0x13CE);\n        break;\n      case 0xAB9F:\n        bufpush(0x13CF);\n        break;\n      case 0xABA0:\n        bufpush(0x13D0);\n        break;\n      case 0xABA1:\n        bufpush(0x13D1);\n        break;\n      case 0xABA2:\n        bufpush(0x13D2);\n        break;\n      case 0xABA3:\n        bufpush(0x13D3);\n        break;\n      case 0xABA4:\n        bufpush(0x13D4);\n        break;\n      case 0xABA5:\n        bufpush(0x13D5);\n        break;\n      case 0xABA6:\n        bufpush(0x13D6);\n        break;\n      case 0xABA7:\n        bufpush(0x13D7);\n        break;\n      case 0xABA8:\n        bufpush(0x13D8);\n        break;\n      case 0xABA9:\n        bufpush(0x13D9);\n        break;\n      case 0xABAA:\n        bufpush(0x13DA);\n        break;\n      case 0xABAB:\n        bufpush(0x13DB);\n        break;\n      case 0xABAC:\n        bufpush(0x13DC);\n        break;\n      case 0xABAD:\n        bufpush(0x13DD);\n        break;\n      case 0xABAE:\n        bufpush(0x13DE);\n        break;\n      case 0xABAF:\n        bufpush(0x13DF);\n        break;\n      case 0xABB0:\n        bufpush(0x13E0);\n        break;\n      case 0xABB1:\n        bufpush(0x13E1);\n        break;\n      case 0xABB2:\n        bufpush(0x13E2);\n        break;\n      case 0xABB3:\n        bufpush(0x13E3);\n        break;\n      case 0xABB4:\n        bufpush(0x13E4);\n        break;\n      case 0xABB5:\n        bufpush(0x13E5);\n        break;\n      case 0xABB6:\n        bufpush(0x13E6);\n        break;\n      case 0xABB7:\n        bufpush(0x13E7);\n        break;\n      case 0xABB8:\n        bufpush(0x13E8);\n        break;\n      case 0xABB9:\n        bufpush(0x13E9);\n        break;\n      case 0xABBA:\n        bufpush(0x13EA);\n        break;\n      case 0xABBB:\n        bufpush(0x13EB);\n        break;\n      case 0xABBC:\n        bufpush(0x13EC);\n        break;\n      case 0xABBD:\n        bufpush(0x13ED);\n        break;\n      case 0xABBE:\n        bufpush(0x13EE);\n        break;\n      case 0xABBF:\n        bufpush(0x13EF);\n        break;\n      case 0xFB00:\n        bufpush(0x0066);\n        bufpush(0x0066);\n        break;\n      case 0xFB01:\n        bufpush(0x0066);\n        bufpush(0x0069);\n        break;\n      case 0xFB02:\n        bufpush(0x0066);\n        bufpush(0x006C);\n        break;\n      case 0xFB03:\n        bufpush(0x0066);\n        bufpush(0x0066);\n        bufpush(0x0069);\n        break;\n      case 0xFB04:\n        bufpush(0x0066);\n        bufpush(0x0066);\n        bufpush(0x006C);\n        break;\n      case 0xFB05:\n        bufpush(0x0073);\n        bufpush(0x0074);\n        break;\n      case 0xFB06:\n        bufpush(0x0073);\n        bufpush(0x0074);\n        break;\n      case 0xFB13:\n        bufpush(0x0574);\n        bufpush(0x0576);\n        break;\n      case 0xFB14:\n        bufpush(0x0574);\n        bufpush(0x0565);\n        break;\n      case 0xFB15:\n        bufpush(0x0574);\n        bufpush(0x056B);\n        break;\n      case 0xFB16:\n        bufpush(0x057E);\n        bufpush(0x0576);\n        break;\n      case 0xFB17:\n        bufpush(0x0574);\n        bufpush(0x056D);\n        break;\n      case 0xFF21:\n        bufpush(0xFF41);\n        break;\n      case 0xFF22:\n        bufpush(0xFF42);\n        break;\n      case 0xFF23:\n        bufpush(0xFF43);\n        break;\n      case 0xFF24:\n        bufpush(0xFF44);\n        break;\n      case 0xFF25:\n        bufpush(0xFF45);\n        break;\n      case 0xFF26:\n        bufpush(0xFF46);\n        break;\n      case 0xFF27:\n        bufpush(0xFF47);\n        break;\n      case 0xFF28:\n        bufpush(0xFF48);\n        break;\n      case 0xFF29:\n        bufpush(0xFF49);\n        break;\n      case 0xFF2A:\n        bufpush(0xFF4A);\n        break;\n      case 0xFF2B:\n        bufpush(0xFF4B);\n        break;\n      case 0xFF2C:\n        bufpush(0xFF4C);\n        break;\n      case 0xFF2D:\n        bufpush(0xFF4D);\n        break;\n      case 0xFF2E:\n        bufpush(0xFF4E);\n        break;\n      case 0xFF2F:\n        bufpush(0xFF4F);\n        break;\n      case 0xFF30:\n        bufpush(0xFF50);\n        break;\n      case 0xFF31:\n        bufpush(0xFF51);\n        break;\n      case 0xFF32:\n        bufpush(0xFF52);\n        break;\n      case 0xFF33:\n        bufpush(0xFF53);\n        break;\n      case 0xFF34:\n        bufpush(0xFF54);\n        break;\n      case 0xFF35:\n        bufpush(0xFF55);\n        break;\n      case 0xFF36:\n        bufpush(0xFF56);\n        break;\n      case 0xFF37:\n        bufpush(0xFF57);\n        break;\n      case 0xFF38:\n        bufpush(0xFF58);\n        break;\n      case 0xFF39:\n        bufpush(0xFF59);\n        break;\n      case 0xFF3A:\n        bufpush(0xFF5A);\n        break;\n      case 0x10400:\n        bufpush(0x10428);\n        break;\n      case 0x10401:\n        bufpush(0x10429);\n        break;\n      case 0x10402:\n        bufpush(0x1042A);\n        break;\n      case 0x10403:\n        bufpush(0x1042B);\n        break;\n      case 0x10404:\n        bufpush(0x1042C);\n        break;\n      case 0x10405:\n        bufpush(0x1042D);\n        break;\n      case 0x10406:\n        bufpush(0x1042E);\n        break;\n      case 0x10407:\n        bufpush(0x1042F);\n        break;\n      case 0x10408:\n        bufpush(0x10430);\n        break;\n      case 0x10409:\n        bufpush(0x10431);\n        break;\n      case 0x1040A:\n        bufpush(0x10432);\n        break;\n      case 0x1040B:\n        bufpush(0x10433);\n        break;\n      case 0x1040C:\n        bufpush(0x10434);\n        break;\n      case 0x1040D:\n        bufpush(0x10435);\n        break;\n      case 0x1040E:\n        bufpush(0x10436);\n        break;\n      case 0x1040F:\n        bufpush(0x10437);\n        break;\n      case 0x10410:\n        bufpush(0x10438);\n        break;\n      case 0x10411:\n        bufpush(0x10439);\n        break;\n      case 0x10412:\n        bufpush(0x1043A);\n        break;\n      case 0x10413:\n        bufpush(0x1043B);\n        break;\n      case 0x10414:\n        bufpush(0x1043C);\n        break;\n      case 0x10415:\n        bufpush(0x1043D);\n        break;\n      case 0x10416:\n        bufpush(0x1043E);\n        break;\n      case 0x10417:\n        bufpush(0x1043F);\n        break;\n      case 0x10418:\n        bufpush(0x10440);\n        break;\n      case 0x10419:\n        bufpush(0x10441);\n        break;\n      case 0x1041A:\n        bufpush(0x10442);\n        break;\n      case 0x1041B:\n        bufpush(0x10443);\n        break;\n      case 0x1041C:\n        bufpush(0x10444);\n        break;\n      case 0x1041D:\n        bufpush(0x10445);\n        break;\n      case 0x1041E:\n        bufpush(0x10446);\n        break;\n      case 0x1041F:\n        bufpush(0x10447);\n        break;\n      case 0x10420:\n        bufpush(0x10448);\n        break;\n      case 0x10421:\n        bufpush(0x10449);\n        break;\n      case 0x10422:\n        bufpush(0x1044A);\n        break;\n      case 0x10423:\n        bufpush(0x1044B);\n        break;\n      case 0x10424:\n        bufpush(0x1044C);\n        break;\n      case 0x10425:\n        bufpush(0x1044D);\n        break;\n      case 0x10426:\n        bufpush(0x1044E);\n        break;\n      case 0x10427:\n        bufpush(0x1044F);\n        break;\n      case 0x104B0:\n        bufpush(0x104D8);\n        break;\n      case 0x104B1:\n        bufpush(0x104D9);\n        break;\n      case 0x104B2:\n        bufpush(0x104DA);\n        break;\n      case 0x104B3:\n        bufpush(0x104DB);\n        break;\n      case 0x104B4:\n        bufpush(0x104DC);\n        break;\n      case 0x104B5:\n        bufpush(0x104DD);\n        break;\n      case 0x104B6:\n        bufpush(0x104DE);\n        break;\n      case 0x104B7:\n        bufpush(0x104DF);\n        break;\n      case 0x104B8:\n        bufpush(0x104E0);\n        break;\n      case 0x104B9:\n        bufpush(0x104E1);\n        break;\n      case 0x104BA:\n        bufpush(0x104E2);\n        break;\n      case 0x104BB:\n        bufpush(0x104E3);\n        break;\n      case 0x104BC:\n        bufpush(0x104E4);\n        break;\n      case 0x104BD:\n        bufpush(0x104E5);\n        break;\n      case 0x104BE:\n        bufpush(0x104E6);\n        break;\n      case 0x104BF:\n        bufpush(0x104E7);\n        break;\n      case 0x104C0:\n        bufpush(0x104E8);\n        break;\n      case 0x104C1:\n        bufpush(0x104E9);\n        break;\n      case 0x104C2:\n        bufpush(0x104EA);\n        break;\n      case 0x104C3:\n        bufpush(0x104EB);\n        break;\n      case 0x104C4:\n        bufpush(0x104EC);\n        break;\n      case 0x104C5:\n        bufpush(0x104ED);\n        break;\n      case 0x104C6:\n        bufpush(0x104EE);\n        break;\n      case 0x104C7:\n        bufpush(0x104EF);\n        break;\n      case 0x104C8:\n        bufpush(0x104F0);\n        break;\n      case 0x104C9:\n        bufpush(0x104F1);\n        break;\n      case 0x104CA:\n        bufpush(0x104F2);\n        break;\n      case 0x104CB:\n        bufpush(0x104F3);\n        break;\n      case 0x104CC:\n        bufpush(0x104F4);\n        break;\n      case 0x104CD:\n        bufpush(0x104F5);\n        break;\n      case 0x104CE:\n        bufpush(0x104F6);\n        break;\n      case 0x104CF:\n        bufpush(0x104F7);\n        break;\n      case 0x104D0:\n        bufpush(0x104F8);\n        break;\n      case 0x104D1:\n        bufpush(0x104F9);\n        break;\n      case 0x104D2:\n        bufpush(0x104FA);\n        break;\n      case 0x104D3:\n        bufpush(0x104FB);\n        break;\n      case 0x10C80:\n        bufpush(0x10CC0);\n        break;\n      case 0x10C81:\n        bufpush(0x10CC1);\n        break;\n      case 0x10C82:\n        bufpush(0x10CC2);\n        break;\n      case 0x10C83:\n        bufpush(0x10CC3);\n        break;\n      case 0x10C84:\n        bufpush(0x10CC4);\n        break;\n      case 0x10C85:\n        bufpush(0x10CC5);\n        break;\n      case 0x10C86:\n        bufpush(0x10CC6);\n        break;\n      case 0x10C87:\n        bufpush(0x10CC7);\n        break;\n      case 0x10C88:\n        bufpush(0x10CC8);\n        break;\n      case 0x10C89:\n        bufpush(0x10CC9);\n        break;\n      case 0x10C8A:\n        bufpush(0x10CCA);\n        break;\n      case 0x10C8B:\n        bufpush(0x10CCB);\n        break;\n      case 0x10C8C:\n        bufpush(0x10CCC);\n        break;\n      case 0x10C8D:\n        bufpush(0x10CCD);\n        break;\n      case 0x10C8E:\n        bufpush(0x10CCE);\n        break;\n      case 0x10C8F:\n        bufpush(0x10CCF);\n        break;\n      case 0x10C90:\n        bufpush(0x10CD0);\n        break;\n      case 0x10C91:\n        bufpush(0x10CD1);\n        break;\n      case 0x10C92:\n        bufpush(0x10CD2);\n        break;\n      case 0x10C93:\n        bufpush(0x10CD3);\n        break;\n      case 0x10C94:\n        bufpush(0x10CD4);\n        break;\n      case 0x10C95:\n        bufpush(0x10CD5);\n        break;\n      case 0x10C96:\n        bufpush(0x10CD6);\n        break;\n      case 0x10C97:\n        bufpush(0x10CD7);\n        break;\n      case 0x10C98:\n        bufpush(0x10CD8);\n        break;\n      case 0x10C99:\n        bufpush(0x10CD9);\n        break;\n      case 0x10C9A:\n        bufpush(0x10CDA);\n        break;\n      case 0x10C9B:\n        bufpush(0x10CDB);\n        break;\n      case 0x10C9C:\n        bufpush(0x10CDC);\n        break;\n      case 0x10C9D:\n        bufpush(0x10CDD);\n        break;\n      case 0x10C9E:\n        bufpush(0x10CDE);\n        break;\n      case 0x10C9F:\n        bufpush(0x10CDF);\n        break;\n      case 0x10CA0:\n        bufpush(0x10CE0);\n        break;\n      case 0x10CA1:\n        bufpush(0x10CE1);\n        break;\n      case 0x10CA2:\n        bufpush(0x10CE2);\n        break;\n      case 0x10CA3:\n        bufpush(0x10CE3);\n        break;\n      case 0x10CA4:\n        bufpush(0x10CE4);\n        break;\n      case 0x10CA5:\n        bufpush(0x10CE5);\n        break;\n      case 0x10CA6:\n        bufpush(0x10CE6);\n        break;\n      case 0x10CA7:\n        bufpush(0x10CE7);\n        break;\n      case 0x10CA8:\n        bufpush(0x10CE8);\n        break;\n      case 0x10CA9:\n        bufpush(0x10CE9);\n        break;\n      case 0x10CAA:\n        bufpush(0x10CEA);\n        break;\n      case 0x10CAB:\n        bufpush(0x10CEB);\n        break;\n      case 0x10CAC:\n        bufpush(0x10CEC);\n        break;\n      case 0x10CAD:\n        bufpush(0x10CED);\n        break;\n      case 0x10CAE:\n        bufpush(0x10CEE);\n        break;\n      case 0x10CAF:\n        bufpush(0x10CEF);\n        break;\n      case 0x10CB0:\n        bufpush(0x10CF0);\n        break;\n      case 0x10CB1:\n        bufpush(0x10CF1);\n        break;\n      case 0x10CB2:\n        bufpush(0x10CF2);\n        break;\n      case 0x118A0:\n        bufpush(0x118C0);\n        break;\n      case 0x118A1:\n        bufpush(0x118C1);\n        break;\n      case 0x118A2:\n        bufpush(0x118C2);\n        break;\n      case 0x118A3:\n        bufpush(0x118C3);\n        break;\n      case 0x118A4:\n        bufpush(0x118C4);\n        break;\n      case 0x118A5:\n        bufpush(0x118C5);\n        break;\n      case 0x118A6:\n        bufpush(0x118C6);\n        break;\n      case 0x118A7:\n        bufpush(0x118C7);\n        break;\n      case 0x118A8:\n        bufpush(0x118C8);\n        break;\n      case 0x118A9:\n        bufpush(0x118C9);\n        break;\n      case 0x118AA:\n        bufpush(0x118CA);\n        break;\n      case 0x118AB:\n        bufpush(0x118CB);\n        break;\n      case 0x118AC:\n        bufpush(0x118CC);\n        break;\n      case 0x118AD:\n        bufpush(0x118CD);\n        break;\n      case 0x118AE:\n        bufpush(0x118CE);\n        break;\n      case 0x118AF:\n        bufpush(0x118CF);\n        break;\n      case 0x118B0:\n        bufpush(0x118D0);\n        break;\n      case 0x118B1:\n        bufpush(0x118D1);\n        break;\n      case 0x118B2:\n        bufpush(0x118D2);\n        break;\n      case 0x118B3:\n        bufpush(0x118D3);\n        break;\n      case 0x118B4:\n        bufpush(0x118D4);\n        break;\n      case 0x118B5:\n        bufpush(0x118D5);\n        break;\n      case 0x118B6:\n        bufpush(0x118D6);\n        break;\n      case 0x118B7:\n        bufpush(0x118D7);\n        break;\n      case 0x118B8:\n        bufpush(0x118D8);\n        break;\n      case 0x118B9:\n        bufpush(0x118D9);\n        break;\n      case 0x118BA:\n        bufpush(0x118DA);\n        break;\n      case 0x118BB:\n        bufpush(0x118DB);\n        break;\n      case 0x118BC:\n        bufpush(0x118DC);\n        break;\n      case 0x118BD:\n        bufpush(0x118DD);\n        break;\n      case 0x118BE:\n        bufpush(0x118DE);\n        break;\n      case 0x118BF:\n        bufpush(0x118DF);\n        break;\n      case 0x1E900:\n        bufpush(0x1E922);\n        break;\n      case 0x1E901:\n        bufpush(0x1E923);\n        break;\n      case 0x1E902:\n        bufpush(0x1E924);\n        break;\n      case 0x1E903:\n        bufpush(0x1E925);\n        break;\n      case 0x1E904:\n        bufpush(0x1E926);\n        break;\n      case 0x1E905:\n        bufpush(0x1E927);\n        break;\n      case 0x1E906:\n        bufpush(0x1E928);\n        break;\n      case 0x1E907:\n        bufpush(0x1E929);\n        break;\n      case 0x1E908:\n        bufpush(0x1E92A);\n        break;\n      case 0x1E909:\n        bufpush(0x1E92B);\n        break;\n      case 0x1E90A:\n        bufpush(0x1E92C);\n        break;\n      case 0x1E90B:\n        bufpush(0x1E92D);\n        break;\n      case 0x1E90C:\n        bufpush(0x1E92E);\n        break;\n      case 0x1E90D:\n        bufpush(0x1E92F);\n        break;\n      case 0x1E90E:\n        bufpush(0x1E930);\n        break;\n      case 0x1E90F:\n        bufpush(0x1E931);\n        break;\n      case 0x1E910:\n        bufpush(0x1E932);\n        break;\n      case 0x1E911:\n        bufpush(0x1E933);\n        break;\n      case 0x1E912:\n        bufpush(0x1E934);\n        break;\n      case 0x1E913:\n        bufpush(0x1E935);\n        break;\n      case 0x1E914:\n        bufpush(0x1E936);\n        break;\n      case 0x1E915:\n        bufpush(0x1E937);\n        break;\n      case 0x1E916:\n        bufpush(0x1E938);\n        break;\n      case 0x1E917:\n        bufpush(0x1E939);\n        break;\n      case 0x1E918:\n        bufpush(0x1E93A);\n        break;\n      case 0x1E919:\n        bufpush(0x1E93B);\n        break;\n      case 0x1E91A:\n        bufpush(0x1E93C);\n        break;\n      case 0x1E91B:\n        bufpush(0x1E93D);\n        break;\n      case 0x1E91C:\n        bufpush(0x1E93E);\n        break;\n      case 0x1E91D:\n        bufpush(0x1E93F);\n        break;\n      case 0x1E91E:\n        bufpush(0x1E940);\n        break;\n      case 0x1E91F:\n        bufpush(0x1E941);\n        break;\n      case 0x1E920:\n        bufpush(0x1E942);\n        break;\n      case 0x1E921:\n        bufpush(0x1E943);\n        break;\n      default:\n        bufpush(c);\n    }\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/chunk.h",
    "content": "#ifndef CMARK_CHUNK_H\n#define CMARK_CHUNK_H\n\n#include <string.h>\n#include <stdlib.h>\n#include <assert.h>\n#include \"cmark-gfm.h\"\n#include \"buffer.h\"\n#include \"cmark_ctype.h\"\n\n#define CMARK_CHUNK_EMPTY                                                      \\\n  { NULL, 0, 0 }\n\ntypedef struct cmark_chunk {\n  unsigned char *data;\n  bufsize_t len;\n  bufsize_t alloc; // also implies a NULL-terminated string\n} cmark_chunk;\n\nstatic CMARK_INLINE void cmark_chunk_free(cmark_mem *mem, cmark_chunk *c) {\n  if (c->alloc)\n    mem->free(c->data);\n\n  c->data = NULL;\n  c->alloc = 0;\n  c->len = 0;\n}\n\nstatic CMARK_INLINE void cmark_chunk_ltrim(cmark_chunk *c) {\n  assert(!c->alloc);\n\n  while (c->len && cmark_isspace(c->data[0])) {\n    c->data++;\n    c->len--;\n  }\n}\n\nstatic CMARK_INLINE void cmark_chunk_rtrim(cmark_chunk *c) {\n  assert(!c->alloc);\n\n  while (c->len > 0) {\n    if (!cmark_isspace(c->data[c->len - 1]))\n      break;\n\n    c->len--;\n  }\n}\n\nstatic CMARK_INLINE void cmark_chunk_trim(cmark_chunk *c) {\n  cmark_chunk_ltrim(c);\n  cmark_chunk_rtrim(c);\n}\n\nstatic CMARK_INLINE bufsize_t cmark_chunk_strchr(cmark_chunk *ch, int c,\n                                                 bufsize_t offset) {\n  const unsigned char *p =\n      (unsigned char *)memchr(ch->data + offset, c, ch->len - offset);\n  return p ? (bufsize_t)(p - ch->data) : ch->len;\n}\n\nstatic CMARK_INLINE const char *cmark_chunk_to_cstr(cmark_mem *mem,\n                                                    cmark_chunk *c) {\n  unsigned char *str;\n\n  if (c->alloc) {\n    return (char *)c->data;\n  }\n  str = (unsigned char *)mem->calloc(c->len + 1, 1);\n  if (c->len > 0) {\n    memcpy(str, c->data, c->len);\n  }\n  str[c->len] = 0;\n  c->data = str;\n  c->alloc = 1;\n\n  return (char *)str;\n}\n\nstatic CMARK_INLINE void cmark_chunk_set_cstr(cmark_mem *mem, cmark_chunk *c,\n                                              const char *str) {\n  unsigned char *old = c->alloc ? c->data : NULL;\n  if (str == NULL) {\n    c->len = 0;\n    c->data = NULL;\n    c->alloc = 0;\n  } else {\n    c->len = (bufsize_t)strlen(str);\n    c->data = (unsigned char *)mem->calloc(c->len + 1, 1);\n    c->alloc = 1;\n    memcpy(c->data, str, c->len + 1);\n  }\n  if (old != NULL) {\n    mem->free(old);\n  }\n}\n\nstatic CMARK_INLINE cmark_chunk cmark_chunk_literal(const char *data) {\n  bufsize_t len = data ? (bufsize_t)strlen(data) : 0;\n  cmark_chunk c = {(unsigned char *)data, len, 0};\n  return c;\n}\n\nstatic CMARK_INLINE cmark_chunk cmark_chunk_dup(const cmark_chunk *ch,\n                                                bufsize_t pos, bufsize_t len) {\n  cmark_chunk c = {ch->data + pos, len, 0};\n  return c;\n}\n\nstatic CMARK_INLINE cmark_chunk cmark_chunk_buf_detach(cmark_strbuf *buf) {\n  cmark_chunk c;\n\n  c.len = buf->size;\n  c.data = cmark_strbuf_detach(buf);\n  c.alloc = 1;\n\n  return c;\n}\n\n/* trim_new variants are to be used when the source chunk may or may not be\n * allocated; forces a newly allocated chunk. */\nstatic CMARK_INLINE cmark_chunk cmark_chunk_ltrim_new(cmark_mem *mem, cmark_chunk *c) {\n  cmark_chunk r = cmark_chunk_dup(c, 0, c->len);\n  cmark_chunk_ltrim(&r);\n  cmark_chunk_to_cstr(mem, &r);\n  return r;\n}\n\nstatic CMARK_INLINE cmark_chunk cmark_chunk_rtrim_new(cmark_mem *mem, cmark_chunk *c) {\n  cmark_chunk r = cmark_chunk_dup(c, 0, c->len);\n  cmark_chunk_rtrim(&r);\n  cmark_chunk_to_cstr(mem, &r);\n  return r;\n}\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/cmark-gfm-extension_api.h",
    "content": "#ifndef CMARK_GFM_EXTENSION_API_H\n#define CMARK_GFM_EXTENSION_API_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"cmark-gfm.h\"\n\nstruct cmark_renderer;\nstruct cmark_html_renderer;\nstruct cmark_chunk;\n\n/**\n * ## Extension Support\n *\n * While the \"core\" of libcmark is strictly compliant with the\n * specification, an API is provided for extension writers to\n * hook into the parsing process.\n *\n * It should be noted that the cmark_node API already offers\n * room for customization, with methods offered to traverse and\n * modify the AST, and even define custom blocks.\n * When the desired customization is achievable in an error-proof\n * way using that API, it should be the preferred method.\n *\n * The following API requires a more in-depth understanding\n * of libcmark's parsing strategy, which is exposed\n * [here](http://spec.commonmark.org/0.24/#appendix-a-parsing-strategy).\n *\n * It should be used when \"a posteriori\" modification of the AST\n * proves to be too difficult / impossible to implement correctly.\n *\n * It can also serve as an intermediary step before extending\n * the specification, as an extension implemented using this API\n * will be trivially integrated in the core if it proves to be\n * desirable.\n */\n\ntypedef struct cmark_plugin cmark_plugin;\n\n/** A syntax extension that can be attached to a cmark_parser\n * with cmark_parser_attach_syntax_extension().\n *\n * Extension writers should assign functions matching\n * the signature of the following 'virtual methods' to\n * implement new functionality.\n *\n * Their calling order and expected behaviour match the procedure outlined\n * at <http://spec.commonmark.org/0.24/#phase-1-block-structure>:\n *\n * During step 1, cmark will call the function provided through\n * 'cmark_syntax_extension_set_match_block_func' when it\n * iterates over an open block created by this extension,\n * to determine  whether it could contain the new line.\n * If no function was provided, cmark will close the block.\n *\n * During step 2, if and only if the new line doesn't match any\n * of the standard syntax rules, cmark will call the function\n * provided through 'cmark_syntax_extension_set_open_block_func'\n * to let the extension determine whether that new line matches\n * one of its syntax rules.\n * It is the responsibility of the parser to create and add the\n * new block with cmark_parser_make_block and cmark_parser_add_child.\n * If no function was provided is NULL, the extension will have\n * no effect at all on the final block structure of the AST.\n *\n * #### Inline parsing phase hooks\n *\n * For each character provided by the extension through\n * 'cmark_syntax_extension_set_special_inline_chars',\n * the function provided by the extension through\n * 'cmark_syntax_extension_set_match_inline_func'\n * will get called, it is the responsibility of the extension\n * to scan the characters located at the current inline parsing offset\n * with the cmark_inline_parser API.\n *\n * Depending on the type of the extension, it can either:\n *\n * * Scan forward, determine that the syntax matches and return\n *   a newly-created inline node with the appropriate type.\n *   This is the technique that would be used if inline code\n *   (with backticks) was implemented as an extension.\n * * Scan only the character(s) that its syntax rules require\n *   for opening and closing nodes, push a delimiter on the\n *   delimiter stack, and return a simple text node with its\n *   contents set to the character(s) consumed.\n *   This is the technique that would be used if emphasis\n *   inlines were implemented as an extension.\n *\n * When an extension has pushed delimiters on the stack,\n * the function provided through\n * 'cmark_syntax_extension_set_inline_from_delim_func'\n * will get called in a latter phase,\n * when the inline parser has matched opener and closer delimiters\n * created by the extension together.\n *\n * It is then the responsibility of the extension to modify\n * and populate the opener inline text node, and to remove\n * the necessary delimiters from the delimiter stack.\n *\n * Finally, the extension should return NULL if its scan didn't\n * match its syntax rules.\n *\n * The extension can store whatever private data it might need\n * with 'cmark_syntax_extension_set_private',\n * and optionally define a free function for this data.\n */\ntypedef struct subject cmark_inline_parser;\n\n/** Exposed raw for now */\n\ntypedef struct delimiter {\n  struct delimiter *previous;\n  struct delimiter *next;\n  cmark_node *inl_text;\n  bufsize_t position;\n  bufsize_t length;\n  unsigned char delim_char;\n  int can_open;\n  int can_close;\n} delimiter;\n\n/**\n * ### Plugin API.\n *\n * Extensions should be distributed as dynamic libraries,\n * with a single exported function named after the distributed\n * filename.\n *\n * When discovering extensions (see cmark_init), cmark will\n * try to load a symbol named \"init_{{filename}}\" in all the\n * dynamic libraries it encounters.\n *\n * For example, given a dynamic library named myextension.so\n * (or myextension.dll), cmark will try to load the symbol\n * named \"init_myextension\". This means that the filename\n * must lend itself to forming a valid C identifier, with\n * the notable exception of dashes, which will be translated\n * to underscores, which means cmark will look for a function\n * named \"init_my_extension\" if it encounters a dynamic library\n * named \"my-extension.so\".\n *\n * See the 'cmark_plugin_init_func' typedef for the exact prototype\n * this function should follow.\n *\n * For now the extensibility of cmark is not complete, as\n * it only offers API to hook into the block parsing phase\n * (<http://spec.commonmark.org/0.24/#phase-1-block-structure>).\n *\n * See 'cmark_plugin_register_syntax_extension' for more information.\n */\n\n/** The prototype plugins' init function should follow.\n */\ntypedef int (*cmark_plugin_init_func)(cmark_plugin *plugin);\n\n/** Register a syntax 'extension' with the 'plugin', it will be made\n * available as an extension and, if attached to a cmark_parser\n * with 'cmark_parser_attach_syntax_extension', it will contribute\n * to the block parsing process.\n *\n * See the documentation for 'cmark_syntax_extension' for information\n * on how to implement one.\n *\n * This function will typically be called from the init function\n * of external modules.\n *\n * This takes ownership of 'extension', one should not call\n * 'cmark_syntax_extension_free' on a registered extension.\n */\nCMARK_GFM_EXPORT\nint cmark_plugin_register_syntax_extension(cmark_plugin *plugin,\n                                            cmark_syntax_extension *extension);\n\n/** This will search for the syntax extension named 'name' among the\n *  registered syntax extensions.\n *\n *  It can then be attached to a cmark_parser\n *  with the cmark_parser_attach_syntax_extension method.\n */\nCMARK_GFM_EXPORT\ncmark_syntax_extension *cmark_find_syntax_extension(const char *name);\n\n/** Should create and add a new open block to 'parent_container' if\n * 'input' matches a syntax rule for that block type. It is allowed\n * to modify the type of 'parent_container'.\n *\n * Should return the newly created block if there is one, or\n * 'parent_container' if its type was modified, or NULL.\n */\ntypedef cmark_node * (*cmark_open_block_func) (cmark_syntax_extension *extension,\n                                       int indented,\n                                       cmark_parser *parser,\n                                       cmark_node *parent_container,\n                                       unsigned char *input,\n                                       int len);\n\ntypedef cmark_node *(*cmark_match_inline_func)(cmark_syntax_extension *extension,\n                                       cmark_parser *parser,\n                                       cmark_node *parent,\n                                       unsigned char character,\n                                       cmark_inline_parser *inline_parser);\n\ntypedef delimiter *(*cmark_inline_from_delim_func)(cmark_syntax_extension *extension,\n                                           cmark_parser *parser,\n                                           cmark_inline_parser *inline_parser,\n                                           delimiter *opener,\n                                           delimiter *closer);\n\n/** Should return 'true' if 'input' can be contained in 'container',\n *  'false' otherwise.\n */\ntypedef int (*cmark_match_block_func)        (cmark_syntax_extension *extension,\n                                       cmark_parser *parser,\n                                       unsigned char *input,\n                                       int len,\n                                       cmark_node *container);\n\ntypedef const char *(*cmark_get_type_string_func) (cmark_syntax_extension *extension,\n                                                   cmark_node *node);\n\ntypedef int (*cmark_can_contain_func) (cmark_syntax_extension *extension,\n                                       cmark_node *node,\n                                       cmark_node_type child);\n\ntypedef int (*cmark_contains_inlines_func) (cmark_syntax_extension *extension,\n                                            cmark_node *node);\n\ntypedef void (*cmark_common_render_func) (cmark_syntax_extension *extension,\n                                          struct cmark_renderer *renderer,\n                                          cmark_node *node,\n                                          cmark_event_type ev_type,\n                                          int options);\n\ntypedef int (*cmark_commonmark_escape_func) (cmark_syntax_extension *extension,\n                                              cmark_node *node,\n                                              int c);\n\ntypedef const char* (*cmark_xml_attr_func) (cmark_syntax_extension *extension,\n                                            cmark_node *node);\n\ntypedef void (*cmark_html_render_func) (cmark_syntax_extension *extension,\n                                        struct cmark_html_renderer *renderer,\n                                        cmark_node *node,\n                                        cmark_event_type ev_type,\n                                        int options);\n\ntypedef int (*cmark_html_filter_func) (cmark_syntax_extension *extension,\n                                       const unsigned char *tag,\n                                       size_t tag_len);\n\ntypedef cmark_node *(*cmark_postprocess_func) (cmark_syntax_extension *extension,\n                                               cmark_parser *parser,\n                                               cmark_node *root);\n\ntypedef int (*cmark_ispunct_func) (char c);\n\ntypedef void (*cmark_opaque_alloc_func) (cmark_syntax_extension *extension,\n                                         cmark_mem *mem,\n                                         cmark_node *node);\n\ntypedef void (*cmark_opaque_free_func) (cmark_syntax_extension *extension,\n                                        cmark_mem *mem,\n                                        cmark_node *node);\n\n/** Free a cmark_syntax_extension.\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_free               (cmark_mem *mem, cmark_syntax_extension *extension);\n\n/** Return a newly-constructed cmark_syntax_extension, named 'name'.\n */\nCMARK_GFM_EXPORT\ncmark_syntax_extension *cmark_syntax_extension_new (const char *name);\n\nCMARK_GFM_EXPORT\ncmark_node_type cmark_syntax_extension_add_node(int is_inline);\n\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_emphasis(cmark_syntax_extension *extension, int emphasis);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_open_block_func(cmark_syntax_extension *extension,\n                                                cmark_open_block_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_match_block_func(cmark_syntax_extension *extension,\n                                                 cmark_match_block_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_match_inline_func(cmark_syntax_extension *extension,\n                                                  cmark_match_inline_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_inline_from_delim_func(cmark_syntax_extension *extension,\n                                                       cmark_inline_from_delim_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_special_inline_chars(cmark_syntax_extension *extension,\n                                                     cmark_llist *special_chars);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_get_type_string_func(cmark_syntax_extension *extension,\n                                                     cmark_get_type_string_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_can_contain_func(cmark_syntax_extension *extension,\n                                                 cmark_can_contain_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_contains_inlines_func(cmark_syntax_extension *extension,\n                                                      cmark_contains_inlines_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_commonmark_render_func(cmark_syntax_extension *extension,\n                                                       cmark_common_render_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_plaintext_render_func(cmark_syntax_extension *extension,\n                                                      cmark_common_render_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_latex_render_func(cmark_syntax_extension *extension,\n                                                  cmark_common_render_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_xml_attr_func(cmark_syntax_extension *extension,\n                                              cmark_xml_attr_func func);\n\n  /** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_man_render_func(cmark_syntax_extension *extension,\n                                                cmark_common_render_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_html_render_func(cmark_syntax_extension *extension,\n                                                 cmark_html_render_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_html_filter_func(cmark_syntax_extension *extension,\n                                                 cmark_html_filter_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_commonmark_escape_func(cmark_syntax_extension *extension,\n                                                       cmark_commonmark_escape_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_private(cmark_syntax_extension *extension,\n                                        void *priv,\n                                        cmark_free_func free_func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid *cmark_syntax_extension_get_private(cmark_syntax_extension *extension);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_postprocess_func(cmark_syntax_extension *extension,\n                                                 cmark_postprocess_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_opaque_alloc_func(cmark_syntax_extension *extension,\n                                                  cmark_opaque_alloc_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_syntax_extension_set_opaque_free_func(cmark_syntax_extension *extension,\n                                                 cmark_opaque_free_func func);\n\n/** See the documentation for 'cmark_syntax_extension'\n */\nCMARK_GFM_EXPORT\nvoid cmark_parser_set_backslash_ispunct_func(cmark_parser *parser,\n                                             cmark_ispunct_func func);\n\n/** Return the index of the line currently being parsed, starting with 1.\n */\nCMARK_GFM_EXPORT\nint cmark_parser_get_line_number(cmark_parser *parser);\n\n/** Return the offset in bytes in the line being processed.\n *\n * Example:\n *\n * ### foo\n *\n * Here, offset will first be 0, then 5 (the index of the 'f' character).\n */\nCMARK_GFM_EXPORT\nint cmark_parser_get_offset(cmark_parser *parser);\n\n/**\n * Return the offset in 'columns' in the line being processed.\n *\n * This value may differ from the value returned by\n * cmark_parser_get_offset() in that it accounts for tabs,\n * and as such should not be used as an index in the current line's\n * buffer.\n *\n * Example:\n *\n * cmark_parser_advance_offset() can be called to advance the\n * offset by a number of columns, instead of a number of bytes.\n *\n * In that case, if offset falls \"in the middle\" of a tab\n * character, 'column' and offset will differ.\n *\n * ```\n * foo                 \\t bar\n * ^                   ^^\n * offset (0)          20\n * ```\n *\n * If cmark_parser_advance_offset is called here with 'columns'\n * set to 'true' and 'offset' set to 22, cmark_parser_get_offset()\n * will return 20, whereas cmark_parser_get_column() will return\n * 22.\n *\n * Additionally, as tabs expand to the next multiple of 4 column,\n * cmark_parser_has_partially_consumed_tab() will now return\n * 'true'.\n */\nCMARK_GFM_EXPORT\nint cmark_parser_get_column(cmark_parser *parser);\n\n/** Return the absolute index in bytes of the first nonspace\n * character coming after the offset as returned by\n * cmark_parser_get_offset() in the line currently being processed.\n *\n * Example:\n *\n * ```\n *   foo        bar            baz  \\n\n * ^               ^           ^\n * 0            offset (16) first_nonspace (28)\n * ```\n */\nCMARK_GFM_EXPORT\nint cmark_parser_get_first_nonspace(cmark_parser *parser);\n\n/** Return the absolute index of the first nonspace column coming after 'offset'\n * in the line currently being processed, counting tabs as multiple\n * columns as appropriate.\n *\n * See the documentation for cmark_parser_get_first_nonspace() and\n * cmark_parser_get_column() for more information.\n */\nCMARK_GFM_EXPORT\nint cmark_parser_get_first_nonspace_column(cmark_parser *parser);\n\n/** Return the difference between the values returned by\n * cmark_parser_get_first_nonspace_column() and\n * cmark_parser_get_column().\n *\n * This is not a byte offset, as it can count one tab as multiple\n * characters.\n */\nCMARK_GFM_EXPORT\nint cmark_parser_get_indent(cmark_parser *parser);\n\n/** Return 'true' if the line currently being processed has been entirely\n * consumed, 'false' otherwise.\n *\n * Example:\n *\n * ```\n *   foo        bar            baz  \\n\n * ^\n * offset\n * ```\n *\n * This function will return 'false' here.\n *\n * ```\n *   foo        bar            baz  \\n\n *                 ^\n *              offset\n * ```\n * This function will still return 'false'.\n *\n * ```\n *   foo        bar            baz  \\n\n *                                ^\n *                             offset\n * ```\n *\n * At this point, this function will now return 'true'.\n */\nCMARK_GFM_EXPORT\nint cmark_parser_is_blank(cmark_parser *parser);\n\n/** Return 'true' if the value returned by cmark_parser_get_offset()\n * is 'inside' an expanded tab.\n *\n * See the documentation for cmark_parser_get_column() for more\n * information.\n */\nCMARK_GFM_EXPORT\nint cmark_parser_has_partially_consumed_tab(cmark_parser *parser);\n\n/** Return the length in bytes of the previously processed line, excluding potential\n * newline (\\n) and carriage return (\\r) trailing characters.\n */\nCMARK_GFM_EXPORT\nint cmark_parser_get_last_line_length(cmark_parser *parser);\n\n/** Add a child to 'parent' during the parsing process.\n *\n * If 'parent' isn't the kind of node that can accept this child,\n * this function will back up till it hits a node that can, closing\n * blocks as appropriate.\n */\nCMARK_GFM_EXPORT\ncmark_node*cmark_parser_add_child(cmark_parser *parser,\n                                  cmark_node *parent,\n                                  cmark_node_type block_type,\n                                  int start_column);\n\n/** Advance the 'offset' of the parser in the current line.\n *\n * See the documentation of cmark_parser_get_offset() and\n * cmark_parser_get_column() for more information.\n */\nCMARK_GFM_EXPORT\nvoid cmark_parser_advance_offset(cmark_parser *parser,\n                                 const char *input,\n                                 int count,\n                                 int columns);\n\n\nCMARK_GFM_EXPORT\nvoid cmark_parser_feed_reentrant(cmark_parser *parser, const char *buffer, size_t len);\n\n/** Attach the syntax 'extension' to the 'parser', to provide extra syntax\n *  rules.\n *  See the documentation for cmark_syntax_extension for more information.\n *\n *  Returns 'true' if the 'extension' was successfully attached,\n *  'false' otherwise.\n */\nCMARK_GFM_EXPORT\nint cmark_parser_attach_syntax_extension(cmark_parser *parser, cmark_syntax_extension *extension);\n\n/** Change the type of 'node'.\n *\n * Return 0 if the type could be changed, 1 otherwise.\n */\nCMARK_GFM_EXPORT int cmark_node_set_type(cmark_node *node, cmark_node_type type);\n\n/** Return the string content for all types of 'node'.\n *  The pointer stays valid as long as 'node' isn't freed.\n */\nCMARK_GFM_EXPORT const char *cmark_node_get_string_content(cmark_node *node);\n\n/** Set the string 'content' for all types of 'node'.\n *  Copies 'content'.\n */\nCMARK_GFM_EXPORT int cmark_node_set_string_content(cmark_node *node, const char *content);\n\n/** Get the syntax extension responsible for the creation of 'node'.\n *  Return NULL if 'node' was created because it matched standard syntax rules.\n */\nCMARK_GFM_EXPORT cmark_syntax_extension *cmark_node_get_syntax_extension(cmark_node *node);\n\n/** Set the syntax extension responsible for creating 'node'.\n */\nCMARK_GFM_EXPORT int cmark_node_set_syntax_extension(cmark_node *node,\n                                                  cmark_syntax_extension *extension);\n\n/**\n * ## Inline syntax extension helpers\n *\n * The inline parsing process is described in detail at\n * <http://spec.commonmark.org/0.24/#phase-2-inline-structure>\n */\n\n/** Should return 'true' if the predicate matches 'c', 'false' otherwise\n */\ntypedef int (*cmark_inline_predicate)(int c);\n\n/** Advance the current inline parsing offset */\nCMARK_GFM_EXPORT\nvoid cmark_inline_parser_advance_offset(cmark_inline_parser *parser);\n\n/** Get the current inline parsing offset */\nCMARK_GFM_EXPORT\nint cmark_inline_parser_get_offset(cmark_inline_parser *parser);\n\n/** Set the offset in bytes in the chunk being processed by the given inline parser.\n */\nCMARK_GFM_EXPORT\nvoid cmark_inline_parser_set_offset(cmark_inline_parser *parser, int offset);\n\n/** Gets the cmark_chunk being operated on by the given inline parser.\n * Use cmark_inline_parser_get_offset to get our current position in the chunk.\n */\nCMARK_GFM_EXPORT\nstruct cmark_chunk *cmark_inline_parser_get_chunk(cmark_inline_parser *parser);\n\n/** Returns 1 if the inline parser is currently in a bracket; pass 1 for 'image'\n * if you want to know about an image-type bracket, 0 for link-type. */\nCMARK_GFM_EXPORT\nint cmark_inline_parser_in_bracket(cmark_inline_parser *parser, int image);\n\n/** Remove the last n characters from the last child of the given node.\n * This only works where all n characters are in the single last child, and the last\n * child is CMARK_NODE_TEXT.\n */\nCMARK_GFM_EXPORT\nvoid cmark_node_unput(cmark_node *node, int n);\n\n\n/** Get the character located at the current inline parsing offset\n */\nCMARK_GFM_EXPORT\nunsigned char cmark_inline_parser_peek_char(cmark_inline_parser *parser);\n\n/** Get the character located 'pos' bytes in the current line.\n */\nCMARK_GFM_EXPORT\nunsigned char cmark_inline_parser_peek_at(cmark_inline_parser *parser, int pos);\n\n/** Whether the inline parser has reached the end of the current line\n */\nCMARK_GFM_EXPORT\nint cmark_inline_parser_is_eof(cmark_inline_parser *parser);\n\n/** Get the characters located after the current inline parsing offset\n * while 'pred' matches. Free after usage.\n */\nCMARK_GFM_EXPORT\nchar *cmark_inline_parser_take_while(cmark_inline_parser *parser, cmark_inline_predicate pred);\n\n/** Push a delimiter on the delimiter stack.\n * See <<http://spec.commonmark.org/0.24/#phase-2-inline-structure> for\n * more information on the parameters\n */\nCMARK_GFM_EXPORT\nvoid cmark_inline_parser_push_delimiter(cmark_inline_parser *parser,\n                                  unsigned char c,\n                                  int can_open,\n                                  int can_close,\n                                  cmark_node *inl_text);\n\n/** Remove 'delim' from the delimiter stack\n */\nCMARK_GFM_EXPORT\nvoid cmark_inline_parser_remove_delimiter(cmark_inline_parser *parser, delimiter *delim);\n\nCMARK_GFM_EXPORT\ndelimiter *cmark_inline_parser_get_last_delimiter(cmark_inline_parser *parser);\n\nCMARK_GFM_EXPORT\nint cmark_inline_parser_get_line(cmark_inline_parser *parser);\n\nCMARK_GFM_EXPORT\nint cmark_inline_parser_get_column(cmark_inline_parser *parser);\n\n/** Convenience function to scan a given delimiter.\n *\n * 'left_flanking' and 'right_flanking' will be set to true if they\n * respectively precede and follow a non-space, non-punctuation\n * character.\n *\n * Additionally, 'punct_before' and 'punct_after' will respectively be set\n * if the preceding or following character is a punctuation character.\n *\n * Note that 'left_flanking' and 'right_flanking' can both be 'true'.\n *\n * Returns the number of delimiters encountered, in the limit\n * of 'max_delims', and advances the inline parsing offset.\n */\nCMARK_GFM_EXPORT\nint cmark_inline_parser_scan_delimiters(cmark_inline_parser *parser,\n                                  int max_delims,\n                                  unsigned char c,\n                                  int *left_flanking,\n                                  int *right_flanking,\n                                  int *punct_before,\n                                  int *punct_after);\n\nCMARK_GFM_EXPORT\nint cmark_inline_parser_get_offset(cmark_inline_parser *parser);\n\nCMARK_GFM_EXPORT\nstruct cmark_chunk *cmark_inline_parser_get_chunk(cmark_inline_parser *parser);\n\nCMARK_GFM_EXPORT\nvoid cmark_manage_extensions_special_characters(cmark_parser *parser, int add);\n\nCMARK_GFM_EXPORT\ncmark_llist *cmark_parser_get_syntax_extensions(cmark_parser *parser);\n\nCMARK_GFM_EXPORT\nvoid cmark_arena_push(void);\n\nCMARK_GFM_EXPORT\nint cmark_arena_pop(void);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/cmark-gfm.h",
    "content": "#ifndef CMARK_GFM_H\n#define CMARK_GFM_H\n\n#include <stdio.h>\n#include <stdint.h>\n#include \"cmark-gfm_export.h\"\n#include \"cmark-gfm_version.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/** # NAME\n *\n * **cmark-gfm** - CommonMark parsing, manipulating, and rendering\n */\n\n/** # DESCRIPTION\n *\n * ## Simple Interface\n */\n\n/** Convert 'text' (assumed to be a UTF-8 encoded string with length\n * 'len') from CommonMark Markdown to HTML, returning a null-terminated,\n * UTF-8-encoded string. It is the caller's responsibility\n * to free the returned buffer.\n */\nCMARK_GFM_EXPORT\nchar *cmark_markdown_to_html(const char *text, size_t len, int options);\n\n/** ## Node Structure\n */\n\n#define CMARK_NODE_TYPE_PRESENT (0x8000)\n#define CMARK_NODE_TYPE_BLOCK (CMARK_NODE_TYPE_PRESENT | 0x0000)\n#define CMARK_NODE_TYPE_INLINE (CMARK_NODE_TYPE_PRESENT | 0x4000)\n#define CMARK_NODE_TYPE_MASK (0xc000)\n#define CMARK_NODE_VALUE_MASK (0x3fff)\n\ntypedef enum {\n  /* Error status */\n  CMARK_NODE_NONE = 0x0000,\n\n  /* Block */\n  CMARK_NODE_DOCUMENT       = CMARK_NODE_TYPE_BLOCK | 0x0001,\n  CMARK_NODE_BLOCK_QUOTE    = CMARK_NODE_TYPE_BLOCK | 0x0002,\n  CMARK_NODE_LIST           = CMARK_NODE_TYPE_BLOCK | 0x0003,\n  CMARK_NODE_ITEM           = CMARK_NODE_TYPE_BLOCK | 0x0004,\n  CMARK_NODE_CODE_BLOCK     = CMARK_NODE_TYPE_BLOCK | 0x0005,\n  CMARK_NODE_HTML_BLOCK     = CMARK_NODE_TYPE_BLOCK | 0x0006,\n  CMARK_NODE_CUSTOM_BLOCK   = CMARK_NODE_TYPE_BLOCK | 0x0007,\n  CMARK_NODE_PARAGRAPH      = CMARK_NODE_TYPE_BLOCK | 0x0008,\n  CMARK_NODE_HEADING        = CMARK_NODE_TYPE_BLOCK | 0x0009,\n  CMARK_NODE_THEMATIC_BREAK = CMARK_NODE_TYPE_BLOCK | 0x000a,\n  CMARK_NODE_FOOTNOTE_DEFINITION = CMARK_NODE_TYPE_BLOCK | 0x000b,\n\n  /* Inline */\n  CMARK_NODE_TEXT          = CMARK_NODE_TYPE_INLINE | 0x0001,\n  CMARK_NODE_SOFTBREAK     = CMARK_NODE_TYPE_INLINE | 0x0002,\n  CMARK_NODE_LINEBREAK     = CMARK_NODE_TYPE_INLINE | 0x0003,\n  CMARK_NODE_CODE          = CMARK_NODE_TYPE_INLINE | 0x0004,\n  CMARK_NODE_HTML_INLINE   = CMARK_NODE_TYPE_INLINE | 0x0005,\n  CMARK_NODE_CUSTOM_INLINE = CMARK_NODE_TYPE_INLINE | 0x0006,\n  CMARK_NODE_EMPH          = CMARK_NODE_TYPE_INLINE | 0x0007,\n  CMARK_NODE_STRONG        = CMARK_NODE_TYPE_INLINE | 0x0008,\n  CMARK_NODE_LINK          = CMARK_NODE_TYPE_INLINE | 0x0009,\n  CMARK_NODE_IMAGE         = CMARK_NODE_TYPE_INLINE | 0x000a,\n  CMARK_NODE_FOOTNOTE_REFERENCE = CMARK_NODE_TYPE_INLINE | 0x000b,\n} cmark_node_type;\n\nextern cmark_node_type CMARK_NODE_LAST_BLOCK;\nextern cmark_node_type CMARK_NODE_LAST_INLINE;\n\n/* For backwards compatibility: */\n#define CMARK_NODE_HEADER CMARK_NODE_HEADING\n#define CMARK_NODE_HRULE CMARK_NODE_THEMATIC_BREAK\n#define CMARK_NODE_HTML CMARK_NODE_HTML_BLOCK\n#define CMARK_NODE_INLINE_HTML CMARK_NODE_HTML_INLINE\n\ntypedef enum {\n  CMARK_NO_LIST,\n  CMARK_BULLET_LIST,\n  CMARK_ORDERED_LIST\n} cmark_list_type;\n\ntypedef enum {\n  CMARK_NO_DELIM,\n  CMARK_PERIOD_DELIM,\n  CMARK_PAREN_DELIM\n} cmark_delim_type;\n\ntypedef struct cmark_node cmark_node;\ntypedef struct cmark_parser cmark_parser;\ntypedef struct cmark_iter cmark_iter;\ntypedef struct cmark_syntax_extension cmark_syntax_extension;\n\n/**\n * ## Custom memory allocator support\n */\n\n/** Defines the memory allocation functions to be used by CMark\n * when parsing and allocating a document tree\n */\ntypedef struct cmark_mem {\n  void *(*calloc)(size_t, size_t);\n  void *(*realloc)(void *, size_t);\n  void (*free)(void *);\n} cmark_mem;\n\n/** The default memory allocator; uses the system's calloc,\n * realloc and free.\n */\nCMARK_GFM_EXPORT\ncmark_mem *cmark_get_default_mem_allocator(void);\n\n/** An arena allocator; uses system calloc to allocate large\n * slabs of memory.  Memory in these slabs is not reused at all.\n */\nCMARK_GFM_EXPORT\ncmark_mem *cmark_get_arena_mem_allocator(void);\n\n/** Resets the arena allocator, quickly returning all used memory\n * to the operating system.\n */\nCMARK_GFM_EXPORT\nvoid cmark_arena_reset(void);\n\n/** Callback for freeing user data with a 'cmark_mem' context.\n */\ntypedef void (*cmark_free_func) (cmark_mem *mem, void *user_data);\n\n\n/*\n * ## Basic data structures\n *\n * To keep dependencies to the strict minimum, libcmark implements\n * its own versions of \"classic\" data structures.\n */\n\n/**\n * ### Linked list\n */\n\n/** A generic singly linked list.\n */\ntypedef struct _cmark_llist\n{\n  struct _cmark_llist *next;\n  void         *data;\n} cmark_llist;\n\n/** Append an element to the linked list, return the possibly modified\n * head of the list.\n */\nCMARK_GFM_EXPORT\ncmark_llist * cmark_llist_append    (cmark_mem         * mem,\n                                     cmark_llist       * head,\n                                     void              * data);\n\n/** Free the list starting with 'head', calling 'free_func' with the\n *  data pointer of each of its elements\n */\nCMARK_GFM_EXPORT\nvoid          cmark_llist_free_full (cmark_mem         * mem,\n                                     cmark_llist       * head,\n                                     cmark_free_func     free_func);\n\n/** Free the list starting with 'head'\n */\nCMARK_GFM_EXPORT\nvoid          cmark_llist_free      (cmark_mem         * mem,\n                                     cmark_llist       * head);\n\n/**\n * ## Creating and Destroying Nodes\n */\n\n/** Creates a new node of type 'type'.  Note that the node may have\n * other required properties, which it is the caller's responsibility\n * to assign.\n */\nCMARK_GFM_EXPORT cmark_node *cmark_node_new(cmark_node_type type);\n\n/** Same as `cmark_node_new`, but explicitly listing the memory\n * allocator used to allocate the node.  Note:  be sure to use the same\n * allocator for every node in a tree, or bad things can happen.\n */\nCMARK_GFM_EXPORT cmark_node *cmark_node_new_with_mem(cmark_node_type type,\n                                                 cmark_mem *mem);\n\nCMARK_GFM_EXPORT cmark_node *cmark_node_new_with_ext(cmark_node_type type,\n                                                cmark_syntax_extension *extension);\n\nCMARK_GFM_EXPORT cmark_node *cmark_node_new_with_mem_and_ext(cmark_node_type type,\n                                                cmark_mem *mem,\n                                                cmark_syntax_extension *extension);\n\n/** Frees the memory allocated for a node and any children.\n */\nCMARK_GFM_EXPORT void cmark_node_free(cmark_node *node);\n\n/**\n * ## Tree Traversal\n */\n\n/** Returns the next node in the sequence after 'node', or NULL if\n * there is none.\n */\nCMARK_GFM_EXPORT cmark_node *cmark_node_next(cmark_node *node);\n\n/** Returns the previous node in the sequence after 'node', or NULL if\n * there is none.\n */\nCMARK_GFM_EXPORT cmark_node *cmark_node_previous(cmark_node *node);\n\n/** Returns the parent of 'node', or NULL if there is none.\n */\nCMARK_GFM_EXPORT cmark_node *cmark_node_parent(cmark_node *node);\n\n/** Returns the first child of 'node', or NULL if 'node' has no children.\n */\nCMARK_GFM_EXPORT cmark_node *cmark_node_first_child(cmark_node *node);\n\n/** Returns the last child of 'node', or NULL if 'node' has no children.\n */\nCMARK_GFM_EXPORT cmark_node *cmark_node_last_child(cmark_node *node);\n\n/** Returns the footnote reference of 'node', or NULL if 'node' doesn't have a\n * footnote reference.\n */\nCMARK_GFM_EXPORT cmark_node *cmark_node_parent_footnote_def(cmark_node *node);\n\nCMARK_GFM_EXPORT int cmark_node_get_footnote_idx(cmark_node *node);\n\n/**\n * ## Iterator\n *\n * An iterator will walk through a tree of nodes, starting from a root\n * node, returning one node at a time, together with information about\n * whether the node is being entered or exited.  The iterator will\n * first descend to a child node, if there is one.  When there is no\n * child, the iterator will go to the next sibling.  When there is no\n * next sibling, the iterator will return to the parent (but with\n * a 'cmark_event_type' of `CMARK_EVENT_EXIT`).  The iterator will\n * return `CMARK_EVENT_DONE` when it reaches the root node again.\n * One natural application is an HTML renderer, where an `ENTER` event\n * outputs an open tag and an `EXIT` event outputs a close tag.\n * An iterator might also be used to transform an AST in some systematic\n * way, for example, turning all level-3 headings into regular paragraphs.\n *\n *     void\n *     usage_example(cmark_node *root) {\n *         cmark_event_type ev_type;\n *         cmark_iter *iter = cmark_iter_new(root);\n *\n *         while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {\n *             cmark_node *cur = cmark_iter_get_node(iter);\n *             // Do something with `cur` and `ev_type`\n *         }\n *\n *         cmark_iter_free(iter);\n *     }\n *\n * Iterators will never return `EXIT` events for leaf nodes, which are nodes\n * of type:\n *\n * * CMARK_NODE_HTML_BLOCK\n * * CMARK_NODE_THEMATIC_BREAK\n * * CMARK_NODE_CODE_BLOCK\n * * CMARK_NODE_TEXT\n * * CMARK_NODE_SOFTBREAK\n * * CMARK_NODE_LINEBREAK\n * * CMARK_NODE_CODE\n * * CMARK_NODE_HTML_INLINE\n *\n * Nodes must only be modified after an `EXIT` event, or an `ENTER` event for\n * leaf nodes.\n */\n\ntypedef enum {\n  CMARK_EVENT_NONE,\n  CMARK_EVENT_DONE,\n  CMARK_EVENT_ENTER,\n  CMARK_EVENT_EXIT\n} cmark_event_type;\n\n/** Creates a new iterator starting at 'root'.  The current node and event\n * type are undefined until 'cmark_iter_next' is called for the first time.\n * The memory allocated for the iterator should be released using\n * 'cmark_iter_free' when it is no longer needed.\n */\nCMARK_GFM_EXPORT\ncmark_iter *cmark_iter_new(cmark_node *root);\n\n/** Frees the memory allocated for an iterator.\n */\nCMARK_GFM_EXPORT\nvoid cmark_iter_free(cmark_iter *iter);\n\n/** Advances to the next node and returns the event type (`CMARK_EVENT_ENTER`,\n * `CMARK_EVENT_EXIT` or `CMARK_EVENT_DONE`).\n */\nCMARK_GFM_EXPORT\ncmark_event_type cmark_iter_next(cmark_iter *iter);\n\n/** Returns the current node.\n */\nCMARK_GFM_EXPORT\ncmark_node *cmark_iter_get_node(cmark_iter *iter);\n\n/** Returns the current event type.\n */\nCMARK_GFM_EXPORT\ncmark_event_type cmark_iter_get_event_type(cmark_iter *iter);\n\n/** Returns the root node.\n */\nCMARK_GFM_EXPORT\ncmark_node *cmark_iter_get_root(cmark_iter *iter);\n\n/** Resets the iterator so that the current node is 'current' and\n * the event type is 'event_type'.  The new current node must be a\n * descendant of the root node or the root node itself.\n */\nCMARK_GFM_EXPORT\nvoid cmark_iter_reset(cmark_iter *iter, cmark_node *current,\n                      cmark_event_type event_type);\n\n/**\n * ## Accessors\n */\n\n/** Returns the user data of 'node'.\n */\nCMARK_GFM_EXPORT void *cmark_node_get_user_data(cmark_node *node);\n\n/** Sets arbitrary user data for 'node'.  Returns 1 on success,\n * 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_set_user_data(cmark_node *node, void *user_data);\n\n/** Set free function for user data */\nCMARK_GFM_EXPORT\nint cmark_node_set_user_data_free_func(cmark_node *node,\n                                        cmark_free_func free_func);\n\n/** Returns the type of 'node', or `CMARK_NODE_NONE` on error.\n */\nCMARK_GFM_EXPORT cmark_node_type cmark_node_get_type(cmark_node *node);\n\n/** Like 'cmark_node_get_type', but returns a string representation\n    of the type, or `\"<unknown>\"`.\n */\nCMARK_GFM_EXPORT\nconst char *cmark_node_get_type_string(cmark_node *node);\n\n/** Returns the string contents of 'node', or an empty\n    string if none is set.  Returns NULL if called on a\n    node that does not have string content.\n */\nCMARK_GFM_EXPORT const char *cmark_node_get_literal(cmark_node *node);\n\n/** Sets the string contents of 'node'.  Returns 1 on success,\n * 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_set_literal(cmark_node *node, const char *content);\n\n/** Returns the heading level of 'node', or 0 if 'node' is not a heading.\n */\nCMARK_GFM_EXPORT int cmark_node_get_heading_level(cmark_node *node);\n\n/* For backwards compatibility */\n#define cmark_node_get_header_level cmark_node_get_heading_level\n#define cmark_node_set_header_level cmark_node_set_heading_level\n\n/** Sets the heading level of 'node', returning 1 on success and 0 on error.\n */\nCMARK_GFM_EXPORT int cmark_node_set_heading_level(cmark_node *node, int level);\n\n/** Returns the list type of 'node', or `CMARK_NO_LIST` if 'node'\n * is not a list.\n */\nCMARK_GFM_EXPORT cmark_list_type cmark_node_get_list_type(cmark_node *node);\n\n/** Sets the list type of 'node', returning 1 on success and 0 on error.\n */\nCMARK_GFM_EXPORT int cmark_node_set_list_type(cmark_node *node,\n                                          cmark_list_type type);\n\nCMARK_GFM_EXPORT int cmark_node_get_checked(cmark_node *node);\n\nCMARK_GFM_EXPORT int cmark_node_get_is_checkbox(cmark_node *node);\n\n/** Returns the list delimiter type of 'node', or `CMARK_NO_DELIM` if 'node'\n * is not a list.\n */\nCMARK_GFM_EXPORT cmark_delim_type cmark_node_get_list_delim(cmark_node *node);\n\n/** Sets the list delimiter type of 'node', returning 1 on success and 0\n * on error.\n */\nCMARK_GFM_EXPORT int cmark_node_set_list_delim(cmark_node *node,\n                                           cmark_delim_type delim);\n\n/** Returns starting number of 'node', if it is an ordered list, otherwise 0.\n */\nCMARK_GFM_EXPORT int cmark_node_get_list_start(cmark_node *node);\n\n/** Sets starting number of 'node', if it is an ordered list. Returns 1\n * on success, 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_set_list_start(cmark_node *node, int start);\n\n/** Returns 1 if 'node' is a tight list, 0 otherwise.\n */\nCMARK_GFM_EXPORT int cmark_node_get_list_tight(cmark_node *node);\n\n/** Sets the \"tightness\" of a list.  Returns 1 on success, 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_set_list_tight(cmark_node *node, int tight);\n\n/**\n * Returns item index of 'node'. This is only used when rendering output\n * formats such as commonmark, which need to output the index. It is not\n * required for formats such as html or latex.\n */\nCMARK_GFM_EXPORT int cmark_node_get_item_index(cmark_node *node);\n\n/** Sets item index of 'node'. Returns 1 on success, 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_set_item_index(cmark_node *node, int idx);\n\n/** Returns the info string from a fenced code block.\n */\nCMARK_GFM_EXPORT const char *cmark_node_get_fence_info(cmark_node *node);\n\n/** Sets the info string in a fenced code block, returning 1 on\n * success and 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_set_fence_info(cmark_node *node, const char *info);\n\n/** Sets code blocks fencing details\n */\nCMARK_GFM_EXPORT int cmark_node_set_fenced(cmark_node * node, int fenced,\n    int length, int offset, char character);\n\n/** Returns code blocks fencing details\n */\nCMARK_GFM_EXPORT int cmark_node_get_fenced(cmark_node *node, int *length, int *offset, char *character);\n\n/** Returns the URL of a link or image 'node', or an empty string\n    if no URL is set.  Returns NULL if called on a node that is\n    not a link or image.\n */\nCMARK_GFM_EXPORT const char *cmark_node_get_url(cmark_node *node);\n\n/** Sets the URL of a link or image 'node'. Returns 1 on success,\n * 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_set_url(cmark_node *node, const char *url);\n\n/** Returns the title of a link or image 'node', or an empty\n    string if no title is set.  Returns NULL if called on a node\n    that is not a link or image.\n */\nCMARK_GFM_EXPORT const char *cmark_node_get_title(cmark_node *node);\n\n/** Sets the title of a link or image 'node'. Returns 1 on success,\n * 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_set_title(cmark_node *node, const char *title);\n\n/** Returns the literal \"on enter\" text for a custom 'node', or\n    an empty string if no on_enter is set.  Returns NULL if called\n    on a non-custom node.\n */\nCMARK_GFM_EXPORT const char *cmark_node_get_on_enter(cmark_node *node);\n\n/** Sets the literal text to render \"on enter\" for a custom 'node'.\n    Any children of the node will be rendered after this text.\n    Returns 1 on success 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_set_on_enter(cmark_node *node,\n                                         const char *on_enter);\n\n/** Returns the literal \"on exit\" text for a custom 'node', or\n    an empty string if no on_exit is set.  Returns NULL if\n    called on a non-custom node.\n */\nCMARK_GFM_EXPORT const char *cmark_node_get_on_exit(cmark_node *node);\n\n/** Sets the literal text to render \"on exit\" for a custom 'node'.\n    Any children of the node will be rendered before this text.\n    Returns 1 on success 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_set_on_exit(cmark_node *node, const char *on_exit);\n\n/** Returns the line on which 'node' begins.\n */\nCMARK_GFM_EXPORT int cmark_node_get_start_line(cmark_node *node);\n\n/** Returns the column at which 'node' begins.\n */\nCMARK_GFM_EXPORT int cmark_node_get_start_column(cmark_node *node);\n\n/** Returns the line on which 'node' ends.\n */\nCMARK_GFM_EXPORT int cmark_node_get_end_line(cmark_node *node);\n\n/** Returns the column at which 'node' ends.\n */\nCMARK_GFM_EXPORT int cmark_node_get_end_column(cmark_node *node);\n\n/**\n * ## Tree Manipulation\n */\n\n/** Unlinks a 'node', removing it from the tree, but not freeing its\n * memory.  (Use 'cmark_node_free' for that.)\n */\nCMARK_GFM_EXPORT void cmark_node_unlink(cmark_node *node);\n\n/** Inserts 'sibling' before 'node'.  Returns 1 on success, 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_insert_before(cmark_node *node,\n                                          cmark_node *sibling);\n\n/** Inserts 'sibling' after 'node'. Returns 1 on success, 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_insert_after(cmark_node *node, cmark_node *sibling);\n\n/** Replaces 'oldnode' with 'newnode' and unlinks 'oldnode' (but does\n * not free its memory).\n * Returns 1 on success, 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_replace(cmark_node *oldnode, cmark_node *newnode);\n\n/** Adds 'child' to the beginning of the children of 'node'.\n * Returns 1 on success, 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_prepend_child(cmark_node *node, cmark_node *child);\n\n/** Adds 'child' to the end of the children of 'node'.\n * Returns 1 on success, 0 on failure.\n */\nCMARK_GFM_EXPORT int cmark_node_append_child(cmark_node *node, cmark_node *child);\n\n/** Consolidates adjacent text nodes.\n */\nCMARK_GFM_EXPORT void cmark_consolidate_text_nodes(cmark_node *root);\n\n/** Ensures a node and all its children own their own chunk memory.\n */\nCMARK_GFM_EXPORT void cmark_node_own(cmark_node *root);\n\n/**\n * ## Parsing\n *\n * Simple interface:\n *\n *     cmark_node *document = cmark_parse_document(\"Hello *world*\", 13,\n *                                                 CMARK_OPT_DEFAULT);\n *\n * Streaming interface:\n *\n *     cmark_parser *parser = cmark_parser_new(CMARK_OPT_DEFAULT);\n *     FILE *fp = fopen(\"myfile.md\", \"rb\");\n *     while ((bytes = fread(buffer, 1, sizeof(buffer), fp)) > 0) {\n *     \t   cmark_parser_feed(parser, buffer, bytes);\n *     \t   if (bytes < sizeof(buffer)) {\n *     \t       break;\n *     \t   }\n *     }\n *     document = cmark_parser_finish(parser);\n *     cmark_parser_free(parser);\n */\n\n/** Creates a new parser object.\n */\nCMARK_GFM_EXPORT\ncmark_parser *cmark_parser_new(int options);\n\n/** Creates a new parser object with the given memory allocator\n */\nCMARK_GFM_EXPORT\ncmark_parser *cmark_parser_new_with_mem(int options, cmark_mem *mem);\n\n/** Frees memory allocated for a parser object.\n */\nCMARK_GFM_EXPORT\nvoid cmark_parser_free(cmark_parser *parser);\n\n/** Feeds a string of length 'len' to 'parser'.\n */\nCMARK_GFM_EXPORT\nvoid cmark_parser_feed(cmark_parser *parser, const char *buffer, size_t len);\n\n/** Finish parsing and return a pointer to a tree of nodes.\n */\nCMARK_GFM_EXPORT\ncmark_node *cmark_parser_finish(cmark_parser *parser);\n\n/** Parse a CommonMark document in 'buffer' of length 'len'.\n * Returns a pointer to a tree of nodes.  The memory allocated for\n * the node tree should be released using 'cmark_node_free'\n * when it is no longer needed.\n */\nCMARK_GFM_EXPORT\ncmark_node *cmark_parse_document(const char *buffer, size_t len, int options);\n\n/** Parse a CommonMark document in file 'f', returning a pointer to\n * a tree of nodes.  The memory allocated for the node tree should be\n * released using 'cmark_node_free' when it is no longer needed.\n */\nCMARK_GFM_EXPORT\ncmark_node *cmark_parse_file(FILE *f, int options);\n\n/**\n * ## Rendering\n */\n\n/** Render a 'node' tree as XML.  It is the caller's responsibility\n * to free the returned buffer.\n */\nCMARK_GFM_EXPORT\nchar *cmark_render_xml(cmark_node *root, int options);\n\n/** As for 'cmark_render_xml', but specifying the allocator to use for\n * the resulting string.\n */\nCMARK_GFM_EXPORT\nchar *cmark_render_xml_with_mem(cmark_node *root, int options, cmark_mem *mem);\n\n/** Render a 'node' tree as an HTML fragment.  It is up to the user\n * to add an appropriate header and footer. It is the caller's\n * responsibility to free the returned buffer.\n */\nCMARK_GFM_EXPORT\nchar *cmark_render_html(cmark_node *root, int options, cmark_llist *extensions);\n\n/** As for 'cmark_render_html', but specifying the allocator to use for\n * the resulting string.\n */\nCMARK_GFM_EXPORT\nchar *cmark_render_html_with_mem(cmark_node *root, int options, cmark_llist *extensions, cmark_mem *mem);\n\n/** Render a 'node' tree as a groff man page, without the header.\n * It is the caller's responsibility to free the returned buffer.\n */\nCMARK_GFM_EXPORT\nchar *cmark_render_man(cmark_node *root, int options, int width);\n\n/** As for 'cmark_render_man', but specifying the allocator to use for\n * the resulting string.\n */\nCMARK_GFM_EXPORT\nchar *cmark_render_man_with_mem(cmark_node *root, int options, int width, cmark_mem *mem);\n\n/** Render a 'node' tree as a commonmark document.\n * It is the caller's responsibility to free the returned buffer.\n */\nCMARK_GFM_EXPORT\nchar *cmark_render_commonmark(cmark_node *root, int options, int width);\n\n/** As for 'cmark_render_commonmark', but specifying the allocator to use for\n * the resulting string.\n */\nCMARK_GFM_EXPORT\nchar *cmark_render_commonmark_with_mem(cmark_node *root, int options, int width, cmark_mem *mem);\n\n/** Render a 'node' tree as a plain text document.\n * It is the caller's responsibility to free the returned buffer.\n */\nCMARK_GFM_EXPORT\nchar *cmark_render_plaintext(cmark_node *root, int options, int width);\n\n/** As for 'cmark_render_plaintext', but specifying the allocator to use for\n * the resulting string.\n */\nCMARK_GFM_EXPORT\nchar *cmark_render_plaintext_with_mem(cmark_node *root, int options, int width, cmark_mem *mem);\n\n/** Render a 'node' tree as a LaTeX document.\n * It is the caller's responsibility to free the returned buffer.\n */\nCMARK_GFM_EXPORT\nchar *cmark_render_latex(cmark_node *root, int options, int width);\n\n/** As for 'cmark_render_latex', but specifying the allocator to use for\n * the resulting string.\n */\nCMARK_GFM_EXPORT\nchar *cmark_render_latex_with_mem(cmark_node *root, int options, int width, cmark_mem *mem);\n\n/**\n * ## Options\n */\n\n/** Default options.\n */\n#define CMARK_OPT_DEFAULT 0\n\n/**\n * ### Options affecting rendering\n */\n\n/** Include a `data-sourcepos` attribute on all block elements.\n */\n#define CMARK_OPT_SOURCEPOS (1 << 1)\n\n/** Render `softbreak` elements as hard line breaks.\n */\n#define CMARK_OPT_HARDBREAKS (1 << 2)\n\n/** `CMARK_OPT_SAFE` is defined here for API compatibility,\n    but it no longer has any effect. \"Safe\" mode is now the default:\n    set `CMARK_OPT_UNSAFE` to disable it.\n */\n#define CMARK_OPT_SAFE (1 << 3)\n\n/** Render raw HTML and unsafe links (`javascript:`, `vbscript:`,\n * `file:`, and `data:`, except for `image/png`, `image/gif`,\n * `image/jpeg`, or `image/webp` mime types).  By default,\n * raw HTML is replaced by a placeholder HTML comment. Unsafe\n * links are replaced by empty strings.\n */\n#define CMARK_OPT_UNSAFE (1 << 17)\n\n/** Render `softbreak` elements as spaces.\n */\n#define CMARK_OPT_NOBREAKS (1 << 4)\n\n/**\n * ### Options affecting parsing\n */\n\n/** Legacy option (no effect).\n */\n#define CMARK_OPT_NORMALIZE (1 << 8)\n\n/** Validate UTF-8 in the input before parsing, replacing illegal\n * sequences with the replacement character U+FFFD.\n */\n#define CMARK_OPT_VALIDATE_UTF8 (1 << 9)\n\n/** Convert straight quotes to curly, --- to em dashes, -- to en dashes.\n */\n#define CMARK_OPT_SMART (1 << 10)\n\n/** Use GitHub-style <pre lang=\"x\"> tags for code blocks instead of <pre><code\n * class=\"language-x\">.\n */\n#define CMARK_OPT_GITHUB_PRE_LANG (1 << 11)\n\n/** Be liberal in interpreting inline HTML tags.\n */\n#define CMARK_OPT_LIBERAL_HTML_TAG (1 << 12)\n\n/** Parse footnotes.\n */\n#define CMARK_OPT_FOOTNOTES (1 << 13)\n\n/** Only parse strikethroughs if surrounded by exactly 2 tildes.\n * Gives some compatibility with redcarpet.\n */\n#define CMARK_OPT_STRIKETHROUGH_DOUBLE_TILDE (1 << 14)\n\n/** Use style attributes to align table cells instead of align attributes.\n */\n#define CMARK_OPT_TABLE_PREFER_STYLE_ATTRIBUTES (1 << 15)\n\n/** Include the remainder of the info string in code blocks in\n * a separate attribute.\n */\n#define CMARK_OPT_FULL_INFO_STRING (1 << 16)\n\n#define CMARK_OPT_FOOTNOTES_WITHOUT_DEFINITION (1 << 18)\nextern int oneEnterNewlineEnable;\n/**\n * ## Version information\n */\n\n/** The library version as integer for runtime checks. Also available as\n * macro CMARK_VERSION for compile time checks.\n *\n * * Bits 16-23 contain the major version.\n * * Bits 8-15 contain the minor version.\n * * Bits 0-7 contain the patchlevel.\n *\n * In hexadecimal format, the number 0x010203 represents version 1.2.3.\n */\nCMARK_GFM_EXPORT\nint cmark_version(void);\n\n/** The library version string for runtime checks. Also available as\n * macro CMARK_VERSION_STRING for compile time checks.\n */\nCMARK_GFM_EXPORT\nconst char *cmark_version_string(void);\n\n/** # AUTHORS\n *\n * John MacFarlane, Vicent Marti,  Kārlis Gaņģis, Nick Wellnhofer.\n */\n\n#ifndef CMARK_NO_SHORT_NAMES\n#define NODE_DOCUMENT CMARK_NODE_DOCUMENT\n#define NODE_BLOCK_QUOTE CMARK_NODE_BLOCK_QUOTE\n#define NODE_LIST CMARK_NODE_LIST\n#define NODE_ITEM CMARK_NODE_ITEM\n#define NODE_CODE_BLOCK CMARK_NODE_CODE_BLOCK\n#define NODE_HTML_BLOCK CMARK_NODE_HTML_BLOCK\n#define NODE_CUSTOM_BLOCK CMARK_NODE_CUSTOM_BLOCK\n#define NODE_PARAGRAPH CMARK_NODE_PARAGRAPH\n#define NODE_HEADING CMARK_NODE_HEADING\n#define NODE_HEADER CMARK_NODE_HEADER\n#define NODE_THEMATIC_BREAK CMARK_NODE_THEMATIC_BREAK\n#define NODE_HRULE CMARK_NODE_HRULE\n#define NODE_TEXT CMARK_NODE_TEXT\n#define NODE_SOFTBREAK CMARK_NODE_SOFTBREAK\n#define NODE_LINEBREAK CMARK_NODE_LINEBREAK\n#define NODE_CODE CMARK_NODE_CODE\n#define NODE_HTML_INLINE CMARK_NODE_HTML_INLINE\n#define NODE_CUSTOM_INLINE CMARK_NODE_CUSTOM_INLINE\n#define NODE_EMPH CMARK_NODE_EMPH\n#define NODE_STRONG CMARK_NODE_STRONG\n#define NODE_LINK CMARK_NODE_LINK\n#define NODE_IMAGE CMARK_NODE_IMAGE\n#define BULLET_LIST CMARK_BULLET_LIST\n#define ORDERED_LIST CMARK_ORDERED_LIST\n#define PERIOD_DELIM CMARK_PERIOD_DELIM\n#define PAREN_DELIM CMARK_PAREN_DELIM\n#endif\n\ntypedef int32_t bufsize_t;\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/cmark-gfm_version.h.in",
    "content": "#ifndef CMARK_GFM_VERSION_H\n#define CMARK_GFM_VERSION_H\n\n#define CMARK_GFM_VERSION ((@PROJECT_VERSION_MAJOR@ << 24) | (@PROJECT_VERSION_MINOR@ << 16) | (@PROJECT_VERSION_PATCH@ << 8) | @PROJECT_VERSION_GFM@)\n#define CMARK_GFM_VERSION_STRING \"@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@.@PROJECT_VERSION_PATCH@.gfm.@PROJECT_VERSION_GFM@\"\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/cmark.c",
    "content": "#include <stdlib.h>\n#include <assert.h>\n#include <stdio.h>\n#include \"registry.h\"\n#include \"node.h\"\n#include \"houdini.h\"\n#include \"cmark-gfm.h\"\n#include \"buffer.h\"\n\ncmark_node_type CMARK_NODE_LAST_BLOCK = CMARK_NODE_FOOTNOTE_DEFINITION;\ncmark_node_type CMARK_NODE_LAST_INLINE = CMARK_NODE_FOOTNOTE_REFERENCE;\nint oneEnterNewlineEnable = false;\n\nint cmark_version(void) { return CMARK_GFM_VERSION; }\n\nconst char *cmark_version_string(void) { return CMARK_GFM_VERSION_STRING; }\n\nstatic void *xcalloc(size_t nmem, size_t size) {\n  void *ptr = calloc(nmem, size);\n  if (!ptr) {\n    fprintf(stderr, \"[cmark] calloc returned null pointer, aborting\\n\");\n    abort();\n  }\n  return ptr;\n}\n\nstatic void *xrealloc(void *ptr, size_t size) {\n  void *new_ptr = realloc(ptr, size);\n  if (!new_ptr) {\n    fprintf(stderr, \"[cmark] realloc returned null pointer, aborting\\n\");\n    abort();\n  }\n  return new_ptr;\n}\n\nstatic void xfree(void *ptr) {\n  free(ptr);\n}\n\ncmark_mem CMARK_DEFAULT_MEM_ALLOCATOR = {xcalloc, xrealloc, xfree};\n\ncmark_mem *cmark_get_default_mem_allocator(void) {\n  return &CMARK_DEFAULT_MEM_ALLOCATOR;\n}\n\nchar *cmark_markdown_to_html(const char *text, size_t len, int options) {\n  cmark_node *doc;\n  char *result;\n\n  doc = cmark_parse_document(text, len, options);\n\n  result = cmark_render_html(doc, options, NULL);\n  cmark_node_free(doc);\n\n  return result;\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/cmark_ctype.c",
    "content": "#include <stdint.h>\n\n#include \"cmark_ctype.h\"\n\n/** 1 = space, 2 = punct, 3 = digit, 4 = alpha, 0 = other\n */\nstatic const uint8_t cmark_ctype_class[256] = {\n    /*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f */\n    /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,\n    /* 1 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    /* 2 */ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n    /* 3 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2,\n    /* 4 */ 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n    /* 5 */ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2,\n    /* 6 */ 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n    /* 7 */ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0,\n    /* 8 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    /* 9 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    /* a */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    /* b */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    /* c */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    /* d */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    /* e */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    /* f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};\n\n/**\n * Returns 1 if c is a \"whitespace\" character as defined by the spec.\n */\nint cmark_isspace(char c) { return cmark_ctype_class[(uint8_t)c] == 1; }\n\n/**\n * Returns 1 if c is an ascii punctuation character.\n */\nint cmark_ispunct(char c) { return cmark_ctype_class[(uint8_t)c] == 2; }\n\nint cmark_isalnum(char c) {\n  uint8_t result;\n  result = cmark_ctype_class[(uint8_t)c];\n  return (result == 3 || result == 4);\n}\n\nint cmark_isdigit(char c) { return cmark_ctype_class[(uint8_t)c] == 3; }\n\nint cmark_isalpha(char c) { return cmark_ctype_class[(uint8_t)c] == 4; }\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/cmark_ctype.h",
    "content": "#ifndef CMARK_CMARK_CTYPE_H\n#define CMARK_CMARK_CTYPE_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"cmark-gfm_export.h\"\n\n/** Locale-independent versions of functions from ctype.h.\n * We want cmark to behave the same no matter what the system locale.\n */\n\nCMARK_GFM_EXPORT\nint cmark_isspace(char c);\n\nCMARK_GFM_EXPORT\nint cmark_ispunct(char c);\n\nCMARK_GFM_EXPORT\nint cmark_isalnum(char c);\n\nCMARK_GFM_EXPORT\nint cmark_isdigit(char c);\n\nCMARK_GFM_EXPORT\nint cmark_isalpha(char c);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/commonmark.c",
    "content": "#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <stdint.h>\n#include <assert.h>\n\n#include \"config.h\"\n#include \"cmark-gfm.h\"\n#include \"node.h\"\n#include \"buffer.h\"\n#include \"utf8.h\"\n#include \"scanners.h\"\n#include \"render.h\"\n#include \"syntax_extension.h\"\n\n#define OUT(s, wrap, escaping) renderer->out(renderer, node, s, wrap, escaping)\n#define LIT(s) renderer->out(renderer, node, s, false, LITERAL)\n#define CR() renderer->cr(renderer)\n#define BLANKLINE() renderer->blankline(renderer)\n#define ENCODED_SIZE 20\n#define LISTMARKER_SIZE 20\n\n// Functions to convert cmark_nodes to commonmark strings.\n\nstatic CMARK_INLINE void outc(cmark_renderer *renderer, cmark_node *node, \n                              cmark_escaping escape,\n                              int32_t c, unsigned char nextc) {\n  bool needs_escaping = false;\n  bool follows_digit =\n      renderer->buffer->size > 0 &&\n      cmark_isdigit(renderer->buffer->ptr[renderer->buffer->size - 1]);\n  char encoded[ENCODED_SIZE];\n\n  needs_escaping =\n      c < 0x80 && escape != LITERAL &&\n      ((escape == NORMAL &&\n        (c < 0x20 ||\n\t c == '*' || c == '_' || c == '[' || c == ']' || c == '#' || c == '<' ||\n         c == '>' || c == '\\\\' || c == '`' || c == '~' || c == '!' ||\n         (c == '&' && cmark_isalpha(nextc)) || (c == '!' && nextc == '[') ||\n         (renderer->begin_content && (c == '-' || c == '+' || c == '=') &&\n          // begin_content doesn't get set to false til we've passed digits\n          // at the beginning of line, so...\n          !follows_digit) ||\n         (renderer->begin_content && (c == '.' || c == ')') && follows_digit &&\n          (nextc == 0 || cmark_isspace(nextc))))) ||\n       (escape == URL &&\n        (c == '`' || c == '<' || c == '>' || cmark_isspace((char)c) || c == '\\\\' ||\n         c == ')' || c == '(')) ||\n       (escape == TITLE &&\n        (c == '`' || c == '<' || c == '>' || c == '\"' || c == '\\\\')));\n\n  if (needs_escaping) {\n    if (escape == URL && cmark_isspace((char)c)) {\n      // use percent encoding for spaces\n      snprintf(encoded, ENCODED_SIZE, \"%%%2X\", c);\n      cmark_strbuf_puts(renderer->buffer, encoded);\n      renderer->column += 3;\n    } else if (cmark_ispunct((char)c)) {\n      cmark_render_ascii(renderer, \"\\\\\");\n      cmark_render_code_point(renderer, c);\n    } else { // render as entity\n      snprintf(encoded, ENCODED_SIZE, \"&#%d;\", c);\n      cmark_strbuf_puts(renderer->buffer, encoded);\n      renderer->column += (int)strlen(encoded);\n    }\n  } else {\n    cmark_render_code_point(renderer, c);\n  }\n}\n\nstatic int longest_backtick_sequence(const char *code) {\n  int longest = 0;\n  int current = 0;\n  size_t i = 0;\n  size_t code_len = strlen(code);\n  while (i <= code_len) {\n    if (code[i] == '`') {\n      current++;\n    } else {\n      if (current > longest) {\n        longest = current;\n      }\n      current = 0;\n    }\n    i++;\n  }\n  return longest;\n}\n\nstatic int shortest_unused_backtick_sequence(const char *code) {\n  // note: if the shortest sequence is >= 32, this returns 32\n  // so as not to overflow the bit array.\n  uint32_t used = 1;\n  int current = 0;\n  size_t i = 0;\n  size_t code_len = strlen(code);\n  while (i <= code_len) {\n    if (code[i] == '`') {\n      current++;\n    } else {\n      if (current > 0 && current < 32) {\n        used |= (1U << current);\n      }\n      current = 0;\n    }\n    i++;\n  }\n  // return number of first bit that is 0:\n  i = 0;\n  while (i < 32 && used & 1) {\n    used = used >> 1;\n    i++;\n  }\n  return (int)i;\n}\n\nstatic bool is_autolink(cmark_node *node) {\n  cmark_chunk *title;\n  cmark_chunk *url;\n  cmark_node *link_text;\n  char *realurl;\n  int realurllen;\n\n  if (node->type != CMARK_NODE_LINK) {\n    return false;\n  }\n\n  url = &node->as.link.url;\n  if (url->len == 0 || scan_scheme(url, 0) == 0) {\n    return false;\n  }\n\n  title = &node->as.link.title;\n  // if it has a title, we can't treat it as an autolink:\n  if (title->len > 0) {\n    return false;\n  }\n\n  link_text = node->first_child;\n  if (link_text == NULL) {\n    return false;\n  }\n  cmark_consolidate_text_nodes(link_text);\n  realurl = (char *)url->data;\n  realurllen = url->len;\n  if (strncmp(realurl, \"mailto:\", 7) == 0) {\n    realurl += 7;\n    realurllen -= 7;\n  }\n  return (realurllen == link_text->as.literal.len &&\n          strncmp(realurl, (char *)link_text->as.literal.data,\n                  link_text->as.literal.len) == 0);\n}\n\nstatic int S_render_node(cmark_renderer *renderer, cmark_node *node,\n                         cmark_event_type ev_type, int options) {\n  int list_number;\n  cmark_delim_type list_delim;\n  int numticks;\n  bool extra_spaces;\n  int i;\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n  const char *info, *code, *title;\n  char fencechar[2] = {'\\0', '\\0'};\n  size_t info_len, code_len;\n  char listmarker[LISTMARKER_SIZE];\n  const char *emph_delim;\n  bool first_in_list_item;\n  bufsize_t marker_width;\n  bool allow_wrap = renderer->width > 0 && !(CMARK_OPT_NOBREAKS & options) &&\n                    !(CMARK_OPT_HARDBREAKS & options);\n\n  // Don't adjust tight list status til we've started the list.\n  // Otherwise we loose the blank line between a paragraph and\n  // a following list.\n  if (entering) {\n    if (node->parent && node->parent->type == CMARK_NODE_ITEM) {\n      renderer->in_tight_list_item = node->parent->parent->as.list.tight;\n    }\n  } else {\n    if (node->type == CMARK_NODE_LIST) {\n      renderer->in_tight_list_item =\n        node->parent &&\n        node->parent->type == CMARK_NODE_ITEM &&\n        node->parent->parent->as.list.tight;\n    }\n  }\n\n  if (node->extension && node->extension->commonmark_render_func) {\n    node->extension->commonmark_render_func(node->extension, renderer, node, ev_type, options);\n    return 1;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_DOCUMENT:\n    break;\n\n  case CMARK_NODE_BLOCK_QUOTE:\n    if (entering) {\n      LIT(\"> \");\n      renderer->begin_content = true;\n      cmark_strbuf_puts(renderer->prefix, \"> \");\n    } else {\n      cmark_strbuf_truncate(renderer->prefix, renderer->prefix->size - 2);\n      BLANKLINE();\n    }\n    break;\n\n  case CMARK_NODE_LIST:\n    if (!entering && node->next && (node->next->type == CMARK_NODE_CODE_BLOCK ||\n                                    node->next->type == CMARK_NODE_LIST)) {\n      // this ensures that a following indented code block or list will be\n      // inteprereted correctly.\n      CR();\n      LIT(\"<!-- end list -->\");\n      BLANKLINE();\n    }\n    break;\n\n  case CMARK_NODE_ITEM:\n    if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {\n      marker_width = 4;\n    } else {\n      list_number = cmark_node_get_item_index(node);\n      list_delim = cmark_node_get_list_delim(node->parent);\n      // we ensure a width of at least 4 so\n      // we get nice transition from single digits\n      // to double\n      snprintf(listmarker, LISTMARKER_SIZE, \"%d%s%s\", list_number,\n               list_delim == CMARK_PAREN_DELIM ? \")\" : \".\",\n               list_number < 10 ? \"  \" : \" \");\n      marker_width = (bufsize_t)strlen(listmarker);\n    }\n    if (entering) {\n      if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {\n        LIT(\"  - \");\n        renderer->begin_content = true;\n      } else {\n        LIT(listmarker);\n        renderer->begin_content = true;\n      }\n      for (i = marker_width; i--;) {\n        cmark_strbuf_putc(renderer->prefix, ' ');\n      }\n    } else {\n      cmark_strbuf_truncate(renderer->prefix,\n                            renderer->prefix->size - marker_width);\n      CR();\n    }\n    break;\n\n  case CMARK_NODE_HEADING:\n    if (entering) {\n      for (i = cmark_node_get_heading_level(node); i > 0; i--) {\n        LIT(\"#\");\n      }\n      LIT(\" \");\n      renderer->begin_content = true;\n      renderer->no_linebreaks = true;\n    } else {\n      renderer->no_linebreaks = false;\n      BLANKLINE();\n    }\n    break;\n\n  case CMARK_NODE_CODE_BLOCK:\n    first_in_list_item = node->prev == NULL && node->parent &&\n                         node->parent->type == CMARK_NODE_ITEM;\n\n    if (!first_in_list_item) {\n      BLANKLINE();\n    }\n    info = cmark_node_get_fence_info(node);\n    info_len = strlen(info);\n    fencechar[0] = strchr(info, '`') == NULL ? '`' : '~';\n    code = cmark_node_get_literal(node);\n    code_len = strlen(code);\n    // use indented form if no info, and code doesn't\n    // begin or end with a blank line, and code isn't\n    // first thing in a list item\n    if (info_len == 0 && (code_len > 2 && !cmark_isspace(code[0]) &&\n                          !(cmark_isspace(code[code_len - 1]) &&\n                            cmark_isspace(code[code_len - 2]))) &&\n        !first_in_list_item) {\n      LIT(\"    \");\n      cmark_strbuf_puts(renderer->prefix, \"    \");\n      OUT(cmark_node_get_literal(node), false, LITERAL);\n      cmark_strbuf_truncate(renderer->prefix, renderer->prefix->size - 4);\n    } else {\n      numticks = longest_backtick_sequence(code) + 1;\n      if (numticks < 3) {\n        numticks = 3;\n      }\n      for (i = 0; i < numticks; i++) {\n        LIT(fencechar);\n      }\n      LIT(\" \");\n      OUT(info, false, LITERAL);\n      CR();\n      OUT(cmark_node_get_literal(node), false, LITERAL);\n      CR();\n      for (i = 0; i < numticks; i++) {\n        LIT(fencechar);\n      }\n    }\n    BLANKLINE();\n    break;\n\n  case CMARK_NODE_HTML_BLOCK:\n    BLANKLINE();\n    OUT(cmark_node_get_literal(node), false, LITERAL);\n    BLANKLINE();\n    break;\n\n  case CMARK_NODE_CUSTOM_BLOCK:\n    BLANKLINE();\n    OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node),\n        false, LITERAL);\n    BLANKLINE();\n    break;\n\n  case CMARK_NODE_THEMATIC_BREAK:\n    BLANKLINE();\n    LIT(\"-----\");\n    BLANKLINE();\n    break;\n\n  case CMARK_NODE_PARAGRAPH:\n    if (!entering) {\n      BLANKLINE();\n    }\n    break;\n\n  case CMARK_NODE_TEXT:\n    OUT(cmark_node_get_literal(node), allow_wrap, NORMAL);\n    break;\n\n  case CMARK_NODE_LINEBREAK:\n    if (!(CMARK_OPT_HARDBREAKS & options)) {\n      LIT(\"  \");\n    }\n    CR();\n    break;\n\n  case CMARK_NODE_SOFTBREAK:\n    if (CMARK_OPT_HARDBREAKS & options) {\n      LIT(\"  \");\n      CR();\n    } else if (!renderer->no_linebreaks && renderer->width == 0 &&\n               !(CMARK_OPT_HARDBREAKS & options) &&\n               !(CMARK_OPT_NOBREAKS & options)) {\n      CR();\n    } else {\n      OUT(\" \", allow_wrap, LITERAL);\n    }\n    break;\n\n  case CMARK_NODE_CODE:\n    code = cmark_node_get_literal(node);\n    code_len = strlen(code);\n    numticks = shortest_unused_backtick_sequence(code);\n    extra_spaces = code_len == 0 ||\n\t    code[0] == '`' || code[code_len - 1] == '`' ||\n\t    code[0] == ' ' || code[code_len - 1] == ' ';\n    for (i = 0; i < numticks; i++) {\n      LIT(\"`\");\n    }\n    if (extra_spaces) {\n      LIT(\" \");\n    }\n    OUT(cmark_node_get_literal(node), allow_wrap, LITERAL);\n    if (extra_spaces) {\n      LIT(\" \");\n    }\n    for (i = 0; i < numticks; i++) {\n      LIT(\"`\");\n    }\n    break;\n\n  case CMARK_NODE_HTML_INLINE:\n    OUT(cmark_node_get_literal(node), false, LITERAL);\n    break;\n\n  case CMARK_NODE_CUSTOM_INLINE:\n    OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node),\n        false, LITERAL);\n    break;\n\n  case CMARK_NODE_STRONG:\n    if (node->parent == NULL || node->parent->type != CMARK_NODE_STRONG) {\n      if (entering) {\n        LIT(\"**\");\n      } else {\n        LIT(\"**\");\n      }\n    }\n    break;\n\n  case CMARK_NODE_EMPH:\n    // If we have EMPH(EMPH(x)), we need to use *_x_*\n    // because **x** is STRONG(x):\n    if (node->parent && node->parent->type == CMARK_NODE_EMPH &&\n        node->next == NULL && node->prev == NULL) {\n      emph_delim = \"_\";\n    } else {\n      emph_delim = \"*\";\n    }\n    if (entering) {\n      LIT(emph_delim);\n    } else {\n      LIT(emph_delim);\n    }\n    break;\n\n  case CMARK_NODE_LINK:\n    if (is_autolink(node)) {\n      if (entering) {\n        LIT(\"<\");\n        if (strncmp(cmark_node_get_url(node), \"mailto:\", 7) == 0) {\n          LIT((const char *)cmark_node_get_url(node) + 7);\n        } else {\n          LIT((const char *)cmark_node_get_url(node));\n        }\n        LIT(\">\");\n        // return signal to skip contents of node...\n        return 0;\n      }\n    } else {\n      if (entering) {\n        LIT(\"[\");\n      } else {\n        LIT(\"](\");\n        OUT(cmark_node_get_url(node), false, URL);\n        title = cmark_node_get_title(node);\n        if (strlen(title) > 0) {\n          LIT(\" \\\"\");\n          OUT(title, false, TITLE);\n          LIT(\"\\\"\");\n        }\n        LIT(\")\");\n      }\n    }\n    break;\n\n  case CMARK_NODE_IMAGE:\n    if (entering) {\n      LIT(\"![\");\n    } else {\n      LIT(\"](\");\n      OUT(cmark_node_get_url(node), false, URL);\n      title = cmark_node_get_title(node);\n      if (strlen(title) > 0) {\n        OUT(\" \\\"\", allow_wrap, LITERAL);\n        OUT(title, false, TITLE);\n        LIT(\"\\\"\");\n      }\n      LIT(\")\");\n    }\n    break;\n\n  case CMARK_NODE_FOOTNOTE_REFERENCE:\n    if (entering) {\n      LIT(\"[^\");\n\n      char *footnote_label = renderer->mem->calloc(node->parent_footnote_def->as.literal.len + 1, sizeof(char));\n      memmove(footnote_label, node->parent_footnote_def->as.literal.data, node->parent_footnote_def->as.literal.len);\n\n      OUT(footnote_label, false, LITERAL);\n      renderer->mem->free(footnote_label);\n\n      LIT(\"]\");\n    }\n    break;\n\n  case CMARK_NODE_FOOTNOTE_DEFINITION:\n    if (entering) {\n      renderer->footnote_ix += 1;\n      LIT(\"[^\");\n\n      char *footnote_label = renderer->mem->calloc(node->as.literal.len + 1, sizeof(char));\n      memmove(footnote_label, node->as.literal.data, node->as.literal.len);\n\n      OUT(footnote_label, false, LITERAL);\n      renderer->mem->free(footnote_label);\n\n      LIT(\"]:\\n\");\n\n      cmark_strbuf_puts(renderer->prefix, \"    \");\n    } else {\n      cmark_strbuf_truncate(renderer->prefix, renderer->prefix->size - 4);\n    }\n    break;\n\n  default:\n    assert(false);\n    break;\n  }\n\n  return 1;\n}\n\nchar *cmark_render_commonmark(cmark_node *root, int options, int width) {\n  return cmark_render_commonmark_with_mem(root, options, width, cmark_node_mem(root));\n}\n\nchar *cmark_render_commonmark_with_mem(cmark_node *root, int options, int width, cmark_mem *mem) {\n  if (options & CMARK_OPT_HARDBREAKS) {\n    // disable breaking on width, since it has\n    // a different meaning with OPT_HARDBREAKS\n    width = 0;\n  }\n  return cmark_render(mem, root, options, width, outc, S_render_node);\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/config.h.in",
    "content": "#ifndef CMARK_CONFIG_H\n#define CMARK_CONFIG_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#cmakedefine HAVE_STDBOOL_H\n\n#ifdef HAVE_STDBOOL_H\n  #include <stdbool.h>\n#elif !defined(__cplusplus)\n  typedef char bool;\n#endif\n\n#cmakedefine HAVE___BUILTIN_EXPECT\n\n#cmakedefine HAVE___ATTRIBUTE__\n\n#ifdef HAVE___ATTRIBUTE__\n  #define CMARK_ATTRIBUTE(list) __attribute__ (list)\n#else\n  #define CMARK_ATTRIBUTE(list)\n#endif\n\n#ifndef CMARK_INLINE\n  #if defined(_MSC_VER) && !defined(__cplusplus)\n    #define CMARK_INLINE __inline\n  #else\n    #define CMARK_INLINE inline\n  #endif\n#endif\n\n/* snprintf and vsnprintf fallbacks for MSVC before 2015,\n   due to Valentin Milea http://stackoverflow.com/questions/2915672/\n*/\n\n#if defined(_MSC_VER) && _MSC_VER < 1900\n\n#include <stdio.h>\n#include <stdarg.h>\n\n#define snprintf c99_snprintf\n#define vsnprintf c99_vsnprintf\n\nCMARK_INLINE int c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap)\n{\n    int count = -1;\n\n    if (size != 0)\n        count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);\n    if (count == -1)\n        count = _vscprintf(format, ap);\n\n    return count;\n}\n\nCMARK_INLINE int c99_snprintf(char *outBuf, size_t size, const char *format, ...)\n{\n    int count;\n    va_list ap;\n\n    va_start(ap, format);\n    count = c99_vsnprintf(outBuf, size, format, ap);\n    va_end(ap);\n\n    return count;\n}\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/entities.inc",
    "content": "/* Autogenerated by tools/make_headers_inc.py */\n\nstruct cmark_entity_node {\n\tunsigned char *entity;\n        unsigned char bytes[8];\n};\n\n#define CMARK_ENTITY_MIN_LENGTH 2\n#define CMARK_ENTITY_MAX_LENGTH 32\n#define CMARK_NUM_ENTITIES 2125\n\nstatic const struct cmark_entity_node cmark_entities[] = {\n{(unsigned char*)\"AElig\", {195, 134, 0}},\n{(unsigned char*)\"AMP\", {38, 0}},\n{(unsigned char*)\"Aacute\", {195, 129, 0}},\n{(unsigned char*)\"Abreve\", {196, 130, 0}},\n{(unsigned char*)\"Acirc\", {195, 130, 0}},\n{(unsigned char*)\"Acy\", {208, 144, 0}},\n{(unsigned char*)\"Afr\", {240, 157, 148, 132, 0}},\n{(unsigned char*)\"Agrave\", {195, 128, 0}},\n{(unsigned char*)\"Alpha\", {206, 145, 0}},\n{(unsigned char*)\"Amacr\", {196, 128, 0}},\n{(unsigned char*)\"And\", {226, 169, 147, 0}},\n{(unsigned char*)\"Aogon\", {196, 132, 0}},\n{(unsigned char*)\"Aopf\", {240, 157, 148, 184, 0}},\n{(unsigned char*)\"ApplyFunction\", {226, 129, 161, 0}},\n{(unsigned char*)\"Aring\", {195, 133, 0}},\n{(unsigned char*)\"Ascr\", {240, 157, 146, 156, 0}},\n{(unsigned char*)\"Assign\", {226, 137, 148, 0}},\n{(unsigned char*)\"Atilde\", {195, 131, 0}},\n{(unsigned char*)\"Auml\", {195, 132, 0}},\n{(unsigned char*)\"Backslash\", {226, 136, 150, 0}},\n{(unsigned char*)\"Barv\", {226, 171, 167, 0}},\n{(unsigned char*)\"Barwed\", {226, 140, 134, 0}},\n{(unsigned char*)\"Bcy\", {208, 145, 0}},\n{(unsigned char*)\"Because\", {226, 136, 181, 0}},\n{(unsigned char*)\"Bernoullis\", {226, 132, 172, 0}},\n{(unsigned char*)\"Beta\", {206, 146, 0}},\n{(unsigned char*)\"Bfr\", {240, 157, 148, 133, 0}},\n{(unsigned char*)\"Bopf\", {240, 157, 148, 185, 0}},\n{(unsigned char*)\"Breve\", {203, 152, 0}},\n{(unsigned char*)\"Bscr\", {226, 132, 172, 0}},\n{(unsigned char*)\"Bumpeq\", {226, 137, 142, 0}},\n{(unsigned char*)\"CHcy\", {208, 167, 0}},\n{(unsigned char*)\"COPY\", {194, 169, 0}},\n{(unsigned char*)\"Cacute\", {196, 134, 0}},\n{(unsigned char*)\"Cap\", {226, 139, 146, 0}},\n{(unsigned char*)\"CapitalDifferentialD\", {226, 133, 133, 0}},\n{(unsigned char*)\"Cayleys\", {226, 132, 173, 0}},\n{(unsigned char*)\"Ccaron\", {196, 140, 0}},\n{(unsigned char*)\"Ccedil\", {195, 135, 0}},\n{(unsigned char*)\"Ccirc\", {196, 136, 0}},\n{(unsigned char*)\"Cconint\", {226, 136, 176, 0}},\n{(unsigned char*)\"Cdot\", {196, 138, 0}},\n{(unsigned char*)\"Cedilla\", {194, 184, 0}},\n{(unsigned char*)\"CenterDot\", {194, 183, 0}},\n{(unsigned char*)\"Cfr\", {226, 132, 173, 0}},\n{(unsigned char*)\"Chi\", {206, 167, 0}},\n{(unsigned char*)\"CircleDot\", {226, 138, 153, 0}},\n{(unsigned char*)\"CircleMinus\", {226, 138, 150, 0}},\n{(unsigned char*)\"CirclePlus\", {226, 138, 149, 0}},\n{(unsigned char*)\"CircleTimes\", {226, 138, 151, 0}},\n{(unsigned char*)\"ClockwiseContourIntegral\", {226, 136, 178, 0}},\n{(unsigned char*)\"CloseCurlyDoubleQuote\", {226, 128, 157, 0}},\n{(unsigned char*)\"CloseCurlyQuote\", {226, 128, 153, 0}},\n{(unsigned char*)\"Colon\", {226, 136, 183, 0}},\n{(unsigned char*)\"Colone\", {226, 169, 180, 0}},\n{(unsigned char*)\"Congruent\", {226, 137, 161, 0}},\n{(unsigned char*)\"Conint\", {226, 136, 175, 0}},\n{(unsigned char*)\"ContourIntegral\", {226, 136, 174, 0}},\n{(unsigned char*)\"Copf\", {226, 132, 130, 0}},\n{(unsigned char*)\"Coproduct\", {226, 136, 144, 0}},\n{(unsigned char*)\"CounterClockwiseContourIntegral\", {226, 136, 179, 0}},\n{(unsigned char*)\"Cross\", {226, 168, 175, 0}},\n{(unsigned char*)\"Cscr\", {240, 157, 146, 158, 0}},\n{(unsigned char*)\"Cup\", {226, 139, 147, 0}},\n{(unsigned char*)\"CupCap\", {226, 137, 141, 0}},\n{(unsigned char*)\"DD\", {226, 133, 133, 0}},\n{(unsigned char*)\"DDotrahd\", {226, 164, 145, 0}},\n{(unsigned char*)\"DJcy\", {208, 130, 0}},\n{(unsigned char*)\"DScy\", {208, 133, 0}},\n{(unsigned char*)\"DZcy\", {208, 143, 0}},\n{(unsigned char*)\"Dagger\", {226, 128, 161, 0}},\n{(unsigned char*)\"Darr\", {226, 134, 161, 0}},\n{(unsigned char*)\"Dashv\", {226, 171, 164, 0}},\n{(unsigned char*)\"Dcaron\", {196, 142, 0}},\n{(unsigned char*)\"Dcy\", {208, 148, 0}},\n{(unsigned char*)\"Del\", {226, 136, 135, 0}},\n{(unsigned char*)\"Delta\", {206, 148, 0}},\n{(unsigned char*)\"Dfr\", {240, 157, 148, 135, 0}},\n{(unsigned char*)\"DiacriticalAcute\", {194, 180, 0}},\n{(unsigned char*)\"DiacriticalDot\", {203, 153, 0}},\n{(unsigned char*)\"DiacriticalDoubleAcute\", {203, 157, 0}},\n{(unsigned char*)\"DiacriticalGrave\", {96, 0}},\n{(unsigned char*)\"DiacriticalTilde\", {203, 156, 0}},\n{(unsigned char*)\"Diamond\", {226, 139, 132, 0}},\n{(unsigned char*)\"DifferentialD\", {226, 133, 134, 0}},\n{(unsigned char*)\"Dopf\", {240, 157, 148, 187, 0}},\n{(unsigned char*)\"Dot\", {194, 168, 0}},\n{(unsigned char*)\"DotDot\", {226, 131, 156, 0}},\n{(unsigned char*)\"DotEqual\", {226, 137, 144, 0}},\n{(unsigned char*)\"DoubleContourIntegral\", {226, 136, 175, 0}},\n{(unsigned char*)\"DoubleDot\", {194, 168, 0}},\n{(unsigned char*)\"DoubleDownArrow\", {226, 135, 147, 0}},\n{(unsigned char*)\"DoubleLeftArrow\", {226, 135, 144, 0}},\n{(unsigned char*)\"DoubleLeftRightArrow\", {226, 135, 148, 0}},\n{(unsigned char*)\"DoubleLeftTee\", {226, 171, 164, 0}},\n{(unsigned char*)\"DoubleLongLeftArrow\", {226, 159, 184, 0}},\n{(unsigned char*)\"DoubleLongLeftRightArrow\", {226, 159, 186, 0}},\n{(unsigned char*)\"DoubleLongRightArrow\", {226, 159, 185, 0}},\n{(unsigned char*)\"DoubleRightArrow\", {226, 135, 146, 0}},\n{(unsigned char*)\"DoubleRightTee\", {226, 138, 168, 0}},\n{(unsigned char*)\"DoubleUpArrow\", {226, 135, 145, 0}},\n{(unsigned char*)\"DoubleUpDownArrow\", {226, 135, 149, 0}},\n{(unsigned char*)\"DoubleVerticalBar\", {226, 136, 165, 0}},\n{(unsigned char*)\"DownArrow\", {226, 134, 147, 0}},\n{(unsigned char*)\"DownArrowBar\", {226, 164, 147, 0}},\n{(unsigned char*)\"DownArrowUpArrow\", {226, 135, 181, 0}},\n{(unsigned char*)\"DownBreve\", {204, 145, 0}},\n{(unsigned char*)\"DownLeftRightVector\", {226, 165, 144, 0}},\n{(unsigned char*)\"DownLeftTeeVector\", {226, 165, 158, 0}},\n{(unsigned char*)\"DownLeftVector\", {226, 134, 189, 0}},\n{(unsigned char*)\"DownLeftVectorBar\", {226, 165, 150, 0}},\n{(unsigned char*)\"DownRightTeeVector\", {226, 165, 159, 0}},\n{(unsigned char*)\"DownRightVector\", {226, 135, 129, 0}},\n{(unsigned char*)\"DownRightVectorBar\", {226, 165, 151, 0}},\n{(unsigned char*)\"DownTee\", {226, 138, 164, 0}},\n{(unsigned char*)\"DownTeeArrow\", {226, 134, 167, 0}},\n{(unsigned char*)\"Downarrow\", {226, 135, 147, 0}},\n{(unsigned char*)\"Dscr\", {240, 157, 146, 159, 0}},\n{(unsigned char*)\"Dstrok\", {196, 144, 0}},\n{(unsigned char*)\"ENG\", {197, 138, 0}},\n{(unsigned char*)\"ETH\", {195, 144, 0}},\n{(unsigned char*)\"Eacute\", {195, 137, 0}},\n{(unsigned char*)\"Ecaron\", {196, 154, 0}},\n{(unsigned char*)\"Ecirc\", {195, 138, 0}},\n{(unsigned char*)\"Ecy\", {208, 173, 0}},\n{(unsigned char*)\"Edot\", {196, 150, 0}},\n{(unsigned char*)\"Efr\", {240, 157, 148, 136, 0}},\n{(unsigned char*)\"Egrave\", {195, 136, 0}},\n{(unsigned char*)\"Element\", {226, 136, 136, 0}},\n{(unsigned char*)\"Emacr\", {196, 146, 0}},\n{(unsigned char*)\"EmptySmallSquare\", {226, 151, 187, 0}},\n{(unsigned char*)\"EmptyVerySmallSquare\", {226, 150, 171, 0}},\n{(unsigned char*)\"Eogon\", {196, 152, 0}},\n{(unsigned char*)\"Eopf\", {240, 157, 148, 188, 0}},\n{(unsigned char*)\"Epsilon\", {206, 149, 0}},\n{(unsigned char*)\"Equal\", {226, 169, 181, 0}},\n{(unsigned char*)\"EqualTilde\", {226, 137, 130, 0}},\n{(unsigned char*)\"Equilibrium\", {226, 135, 140, 0}},\n{(unsigned char*)\"Escr\", {226, 132, 176, 0}},\n{(unsigned char*)\"Esim\", {226, 169, 179, 0}},\n{(unsigned char*)\"Eta\", {206, 151, 0}},\n{(unsigned char*)\"Euml\", {195, 139, 0}},\n{(unsigned char*)\"Exists\", {226, 136, 131, 0}},\n{(unsigned char*)\"ExponentialE\", {226, 133, 135, 0}},\n{(unsigned char*)\"Fcy\", {208, 164, 0}},\n{(unsigned char*)\"Ffr\", {240, 157, 148, 137, 0}},\n{(unsigned char*)\"FilledSmallSquare\", {226, 151, 188, 0}},\n{(unsigned char*)\"FilledVerySmallSquare\", {226, 150, 170, 0}},\n{(unsigned char*)\"Fopf\", {240, 157, 148, 189, 0}},\n{(unsigned char*)\"ForAll\", {226, 136, 128, 0}},\n{(unsigned char*)\"Fouriertrf\", {226, 132, 177, 0}},\n{(unsigned char*)\"Fscr\", {226, 132, 177, 0}},\n{(unsigned char*)\"GJcy\", {208, 131, 0}},\n{(unsigned char*)\"GT\", {62, 0}},\n{(unsigned char*)\"Gamma\", {206, 147, 0}},\n{(unsigned char*)\"Gammad\", {207, 156, 0}},\n{(unsigned char*)\"Gbreve\", {196, 158, 0}},\n{(unsigned char*)\"Gcedil\", {196, 162, 0}},\n{(unsigned char*)\"Gcirc\", {196, 156, 0}},\n{(unsigned char*)\"Gcy\", {208, 147, 0}},\n{(unsigned char*)\"Gdot\", {196, 160, 0}},\n{(unsigned char*)\"Gfr\", {240, 157, 148, 138, 0}},\n{(unsigned char*)\"Gg\", {226, 139, 153, 0}},\n{(unsigned char*)\"Gopf\", {240, 157, 148, 190, 0}},\n{(unsigned char*)\"GreaterEqual\", {226, 137, 165, 0}},\n{(unsigned char*)\"GreaterEqualLess\", {226, 139, 155, 0}},\n{(unsigned char*)\"GreaterFullEqual\", {226, 137, 167, 0}},\n{(unsigned char*)\"GreaterGreater\", {226, 170, 162, 0}},\n{(unsigned char*)\"GreaterLess\", {226, 137, 183, 0}},\n{(unsigned char*)\"GreaterSlantEqual\", {226, 169, 190, 0}},\n{(unsigned char*)\"GreaterTilde\", {226, 137, 179, 0}},\n{(unsigned char*)\"Gscr\", {240, 157, 146, 162, 0}},\n{(unsigned char*)\"Gt\", {226, 137, 171, 0}},\n{(unsigned char*)\"HARDcy\", {208, 170, 0}},\n{(unsigned char*)\"Hacek\", {203, 135, 0}},\n{(unsigned char*)\"Hat\", {94, 0}},\n{(unsigned char*)\"Hcirc\", {196, 164, 0}},\n{(unsigned char*)\"Hfr\", {226, 132, 140, 0}},\n{(unsigned char*)\"HilbertSpace\", {226, 132, 139, 0}},\n{(unsigned char*)\"Hopf\", {226, 132, 141, 0}},\n{(unsigned char*)\"HorizontalLine\", {226, 148, 128, 0}},\n{(unsigned char*)\"Hscr\", {226, 132, 139, 0}},\n{(unsigned char*)\"Hstrok\", {196, 166, 0}},\n{(unsigned char*)\"HumpDownHump\", {226, 137, 142, 0}},\n{(unsigned char*)\"HumpEqual\", {226, 137, 143, 0}},\n{(unsigned char*)\"IEcy\", {208, 149, 0}},\n{(unsigned char*)\"IJlig\", {196, 178, 0}},\n{(unsigned char*)\"IOcy\", {208, 129, 0}},\n{(unsigned char*)\"Iacute\", {195, 141, 0}},\n{(unsigned char*)\"Icirc\", {195, 142, 0}},\n{(unsigned char*)\"Icy\", {208, 152, 0}},\n{(unsigned char*)\"Idot\", {196, 176, 0}},\n{(unsigned char*)\"Ifr\", {226, 132, 145, 0}},\n{(unsigned char*)\"Igrave\", {195, 140, 0}},\n{(unsigned char*)\"Im\", {226, 132, 145, 0}},\n{(unsigned char*)\"Imacr\", {196, 170, 0}},\n{(unsigned char*)\"ImaginaryI\", {226, 133, 136, 0}},\n{(unsigned char*)\"Implies\", {226, 135, 146, 0}},\n{(unsigned char*)\"Int\", {226, 136, 172, 0}},\n{(unsigned char*)\"Integral\", {226, 136, 171, 0}},\n{(unsigned char*)\"Intersection\", {226, 139, 130, 0}},\n{(unsigned char*)\"InvisibleComma\", {226, 129, 163, 0}},\n{(unsigned char*)\"InvisibleTimes\", {226, 129, 162, 0}},\n{(unsigned char*)\"Iogon\", {196, 174, 0}},\n{(unsigned char*)\"Iopf\", {240, 157, 149, 128, 0}},\n{(unsigned char*)\"Iota\", {206, 153, 0}},\n{(unsigned char*)\"Iscr\", {226, 132, 144, 0}},\n{(unsigned char*)\"Itilde\", {196, 168, 0}},\n{(unsigned char*)\"Iukcy\", {208, 134, 0}},\n{(unsigned char*)\"Iuml\", {195, 143, 0}},\n{(unsigned char*)\"Jcirc\", {196, 180, 0}},\n{(unsigned char*)\"Jcy\", {208, 153, 0}},\n{(unsigned char*)\"Jfr\", {240, 157, 148, 141, 0}},\n{(unsigned char*)\"Jopf\", {240, 157, 149, 129, 0}},\n{(unsigned char*)\"Jscr\", {240, 157, 146, 165, 0}},\n{(unsigned char*)\"Jsercy\", {208, 136, 0}},\n{(unsigned char*)\"Jukcy\", {208, 132, 0}},\n{(unsigned char*)\"KHcy\", {208, 165, 0}},\n{(unsigned char*)\"KJcy\", {208, 140, 0}},\n{(unsigned char*)\"Kappa\", {206, 154, 0}},\n{(unsigned char*)\"Kcedil\", {196, 182, 0}},\n{(unsigned char*)\"Kcy\", {208, 154, 0}},\n{(unsigned char*)\"Kfr\", {240, 157, 148, 142, 0}},\n{(unsigned char*)\"Kopf\", {240, 157, 149, 130, 0}},\n{(unsigned char*)\"Kscr\", {240, 157, 146, 166, 0}},\n{(unsigned char*)\"LJcy\", {208, 137, 0}},\n{(unsigned char*)\"LT\", {60, 0}},\n{(unsigned char*)\"Lacute\", {196, 185, 0}},\n{(unsigned char*)\"Lambda\", {206, 155, 0}},\n{(unsigned char*)\"Lang\", {226, 159, 170, 0}},\n{(unsigned char*)\"Laplacetrf\", {226, 132, 146, 0}},\n{(unsigned char*)\"Larr\", {226, 134, 158, 0}},\n{(unsigned char*)\"Lcaron\", {196, 189, 0}},\n{(unsigned char*)\"Lcedil\", {196, 187, 0}},\n{(unsigned char*)\"Lcy\", {208, 155, 0}},\n{(unsigned char*)\"LeftAngleBracket\", {226, 159, 168, 0}},\n{(unsigned char*)\"LeftArrow\", {226, 134, 144, 0}},\n{(unsigned char*)\"LeftArrowBar\", {226, 135, 164, 0}},\n{(unsigned char*)\"LeftArrowRightArrow\", {226, 135, 134, 0}},\n{(unsigned char*)\"LeftCeiling\", {226, 140, 136, 0}},\n{(unsigned char*)\"LeftDoubleBracket\", {226, 159, 166, 0}},\n{(unsigned char*)\"LeftDownTeeVector\", {226, 165, 161, 0}},\n{(unsigned char*)\"LeftDownVector\", {226, 135, 131, 0}},\n{(unsigned char*)\"LeftDownVectorBar\", {226, 165, 153, 0}},\n{(unsigned char*)\"LeftFloor\", {226, 140, 138, 0}},\n{(unsigned char*)\"LeftRightArrow\", {226, 134, 148, 0}},\n{(unsigned char*)\"LeftRightVector\", {226, 165, 142, 0}},\n{(unsigned char*)\"LeftTee\", {226, 138, 163, 0}},\n{(unsigned char*)\"LeftTeeArrow\", {226, 134, 164, 0}},\n{(unsigned char*)\"LeftTeeVector\", {226, 165, 154, 0}},\n{(unsigned char*)\"LeftTriangle\", {226, 138, 178, 0}},\n{(unsigned char*)\"LeftTriangleBar\", {226, 167, 143, 0}},\n{(unsigned char*)\"LeftTriangleEqual\", {226, 138, 180, 0}},\n{(unsigned char*)\"LeftUpDownVector\", {226, 165, 145, 0}},\n{(unsigned char*)\"LeftUpTeeVector\", {226, 165, 160, 0}},\n{(unsigned char*)\"LeftUpVector\", {226, 134, 191, 0}},\n{(unsigned char*)\"LeftUpVectorBar\", {226, 165, 152, 0}},\n{(unsigned char*)\"LeftVector\", {226, 134, 188, 0}},\n{(unsigned char*)\"LeftVectorBar\", {226, 165, 146, 0}},\n{(unsigned char*)\"Leftarrow\", {226, 135, 144, 0}},\n{(unsigned char*)\"Leftrightarrow\", {226, 135, 148, 0}},\n{(unsigned char*)\"LessEqualGreater\", {226, 139, 154, 0}},\n{(unsigned char*)\"LessFullEqual\", {226, 137, 166, 0}},\n{(unsigned char*)\"LessGreater\", {226, 137, 182, 0}},\n{(unsigned char*)\"LessLess\", {226, 170, 161, 0}},\n{(unsigned char*)\"LessSlantEqual\", {226, 169, 189, 0}},\n{(unsigned char*)\"LessTilde\", {226, 137, 178, 0}},\n{(unsigned char*)\"Lfr\", {240, 157, 148, 143, 0}},\n{(unsigned char*)\"Ll\", {226, 139, 152, 0}},\n{(unsigned char*)\"Lleftarrow\", {226, 135, 154, 0}},\n{(unsigned char*)\"Lmidot\", {196, 191, 0}},\n{(unsigned char*)\"LongLeftArrow\", {226, 159, 181, 0}},\n{(unsigned char*)\"LongLeftRightArrow\", {226, 159, 183, 0}},\n{(unsigned char*)\"LongRightArrow\", {226, 159, 182, 0}},\n{(unsigned char*)\"Longleftarrow\", {226, 159, 184, 0}},\n{(unsigned char*)\"Longleftrightarrow\", {226, 159, 186, 0}},\n{(unsigned char*)\"Longrightarrow\", {226, 159, 185, 0}},\n{(unsigned char*)\"Lopf\", {240, 157, 149, 131, 0}},\n{(unsigned char*)\"LowerLeftArrow\", {226, 134, 153, 0}},\n{(unsigned char*)\"LowerRightArrow\", {226, 134, 152, 0}},\n{(unsigned char*)\"Lscr\", {226, 132, 146, 0}},\n{(unsigned char*)\"Lsh\", {226, 134, 176, 0}},\n{(unsigned char*)\"Lstrok\", {197, 129, 0}},\n{(unsigned char*)\"Lt\", {226, 137, 170, 0}},\n{(unsigned char*)\"Map\", {226, 164, 133, 0}},\n{(unsigned char*)\"Mcy\", {208, 156, 0}},\n{(unsigned char*)\"MediumSpace\", {226, 129, 159, 0}},\n{(unsigned char*)\"Mellintrf\", {226, 132, 179, 0}},\n{(unsigned char*)\"Mfr\", {240, 157, 148, 144, 0}},\n{(unsigned char*)\"MinusPlus\", {226, 136, 147, 0}},\n{(unsigned char*)\"Mopf\", {240, 157, 149, 132, 0}},\n{(unsigned char*)\"Mscr\", {226, 132, 179, 0}},\n{(unsigned char*)\"Mu\", {206, 156, 0}},\n{(unsigned char*)\"NJcy\", {208, 138, 0}},\n{(unsigned char*)\"Nacute\", {197, 131, 0}},\n{(unsigned char*)\"Ncaron\", {197, 135, 0}},\n{(unsigned char*)\"Ncedil\", {197, 133, 0}},\n{(unsigned char*)\"Ncy\", {208, 157, 0}},\n{(unsigned char*)\"NegativeMediumSpace\", {226, 128, 139, 0}},\n{(unsigned char*)\"NegativeThickSpace\", {226, 128, 139, 0}},\n{(unsigned char*)\"NegativeThinSpace\", {226, 128, 139, 0}},\n{(unsigned char*)\"NegativeVeryThinSpace\", {226, 128, 139, 0}},\n{(unsigned char*)\"NestedGreaterGreater\", {226, 137, 171, 0}},\n{(unsigned char*)\"NestedLessLess\", {226, 137, 170, 0}},\n{(unsigned char*)\"NewLine\", {10, 0}},\n{(unsigned char*)\"Nfr\", {240, 157, 148, 145, 0}},\n{(unsigned char*)\"NoBreak\", {226, 129, 160, 0}},\n{(unsigned char*)\"NonBreakingSpace\", {194, 160, 0}},\n{(unsigned char*)\"Nopf\", {226, 132, 149, 0}},\n{(unsigned char*)\"Not\", {226, 171, 172, 0}},\n{(unsigned char*)\"NotCongruent\", {226, 137, 162, 0}},\n{(unsigned char*)\"NotCupCap\", {226, 137, 173, 0}},\n{(unsigned char*)\"NotDoubleVerticalBar\", {226, 136, 166, 0}},\n{(unsigned char*)\"NotElement\", {226, 136, 137, 0}},\n{(unsigned char*)\"NotEqual\", {226, 137, 160, 0}},\n{(unsigned char*)\"NotEqualTilde\", {226, 137, 130, 204, 184, 0}},\n{(unsigned char*)\"NotExists\", {226, 136, 132, 0}},\n{(unsigned char*)\"NotGreater\", {226, 137, 175, 0}},\n{(unsigned char*)\"NotGreaterEqual\", {226, 137, 177, 0}},\n{(unsigned char*)\"NotGreaterFullEqual\", {226, 137, 167, 204, 184, 0}},\n{(unsigned char*)\"NotGreaterGreater\", {226, 137, 171, 204, 184, 0}},\n{(unsigned char*)\"NotGreaterLess\", {226, 137, 185, 0}},\n{(unsigned char*)\"NotGreaterSlantEqual\", {226, 169, 190, 204, 184, 0}},\n{(unsigned char*)\"NotGreaterTilde\", {226, 137, 181, 0}},\n{(unsigned char*)\"NotHumpDownHump\", {226, 137, 142, 204, 184, 0}},\n{(unsigned char*)\"NotHumpEqual\", {226, 137, 143, 204, 184, 0}},\n{(unsigned char*)\"NotLeftTriangle\", {226, 139, 170, 0}},\n{(unsigned char*)\"NotLeftTriangleBar\", {226, 167, 143, 204, 184, 0}},\n{(unsigned char*)\"NotLeftTriangleEqual\", {226, 139, 172, 0}},\n{(unsigned char*)\"NotLess\", {226, 137, 174, 0}},\n{(unsigned char*)\"NotLessEqual\", {226, 137, 176, 0}},\n{(unsigned char*)\"NotLessGreater\", {226, 137, 184, 0}},\n{(unsigned char*)\"NotLessLess\", {226, 137, 170, 204, 184, 0}},\n{(unsigned char*)\"NotLessSlantEqual\", {226, 169, 189, 204, 184, 0}},\n{(unsigned char*)\"NotLessTilde\", {226, 137, 180, 0}},\n{(unsigned char*)\"NotNestedGreaterGreater\", {226, 170, 162, 204, 184, 0}},\n{(unsigned char*)\"NotNestedLessLess\", {226, 170, 161, 204, 184, 0}},\n{(unsigned char*)\"NotPrecedes\", {226, 138, 128, 0}},\n{(unsigned char*)\"NotPrecedesEqual\", {226, 170, 175, 204, 184, 0}},\n{(unsigned char*)\"NotPrecedesSlantEqual\", {226, 139, 160, 0}},\n{(unsigned char*)\"NotReverseElement\", {226, 136, 140, 0}},\n{(unsigned char*)\"NotRightTriangle\", {226, 139, 171, 0}},\n{(unsigned char*)\"NotRightTriangleBar\", {226, 167, 144, 204, 184, 0}},\n{(unsigned char*)\"NotRightTriangleEqual\", {226, 139, 173, 0}},\n{(unsigned char*)\"NotSquareSubset\", {226, 138, 143, 204, 184, 0}},\n{(unsigned char*)\"NotSquareSubsetEqual\", {226, 139, 162, 0}},\n{(unsigned char*)\"NotSquareSuperset\", {226, 138, 144, 204, 184, 0}},\n{(unsigned char*)\"NotSquareSupersetEqual\", {226, 139, 163, 0}},\n{(unsigned char*)\"NotSubset\", {226, 138, 130, 226, 131, 146, 0}},\n{(unsigned char*)\"NotSubsetEqual\", {226, 138, 136, 0}},\n{(unsigned char*)\"NotSucceeds\", {226, 138, 129, 0}},\n{(unsigned char*)\"NotSucceedsEqual\", {226, 170, 176, 204, 184, 0}},\n{(unsigned char*)\"NotSucceedsSlantEqual\", {226, 139, 161, 0}},\n{(unsigned char*)\"NotSucceedsTilde\", {226, 137, 191, 204, 184, 0}},\n{(unsigned char*)\"NotSuperset\", {226, 138, 131, 226, 131, 146, 0}},\n{(unsigned char*)\"NotSupersetEqual\", {226, 138, 137, 0}},\n{(unsigned char*)\"NotTilde\", {226, 137, 129, 0}},\n{(unsigned char*)\"NotTildeEqual\", {226, 137, 132, 0}},\n{(unsigned char*)\"NotTildeFullEqual\", {226, 137, 135, 0}},\n{(unsigned char*)\"NotTildeTilde\", {226, 137, 137, 0}},\n{(unsigned char*)\"NotVerticalBar\", {226, 136, 164, 0}},\n{(unsigned char*)\"Nscr\", {240, 157, 146, 169, 0}},\n{(unsigned char*)\"Ntilde\", {195, 145, 0}},\n{(unsigned char*)\"Nu\", {206, 157, 0}},\n{(unsigned char*)\"OElig\", {197, 146, 0}},\n{(unsigned char*)\"Oacute\", {195, 147, 0}},\n{(unsigned char*)\"Ocirc\", {195, 148, 0}},\n{(unsigned char*)\"Ocy\", {208, 158, 0}},\n{(unsigned char*)\"Odblac\", {197, 144, 0}},\n{(unsigned char*)\"Ofr\", {240, 157, 148, 146, 0}},\n{(unsigned char*)\"Ograve\", {195, 146, 0}},\n{(unsigned char*)\"Omacr\", {197, 140, 0}},\n{(unsigned char*)\"Omega\", {206, 169, 0}},\n{(unsigned char*)\"Omicron\", {206, 159, 0}},\n{(unsigned char*)\"Oopf\", {240, 157, 149, 134, 0}},\n{(unsigned char*)\"OpenCurlyDoubleQuote\", {226, 128, 156, 0}},\n{(unsigned char*)\"OpenCurlyQuote\", {226, 128, 152, 0}},\n{(unsigned char*)\"Or\", {226, 169, 148, 0}},\n{(unsigned char*)\"Oscr\", {240, 157, 146, 170, 0}},\n{(unsigned char*)\"Oslash\", {195, 152, 0}},\n{(unsigned char*)\"Otilde\", {195, 149, 0}},\n{(unsigned char*)\"Otimes\", {226, 168, 183, 0}},\n{(unsigned char*)\"Ouml\", {195, 150, 0}},\n{(unsigned char*)\"OverBar\", {226, 128, 190, 0}},\n{(unsigned char*)\"OverBrace\", {226, 143, 158, 0}},\n{(unsigned char*)\"OverBracket\", {226, 142, 180, 0}},\n{(unsigned char*)\"OverParenthesis\", {226, 143, 156, 0}},\n{(unsigned char*)\"PartialD\", {226, 136, 130, 0}},\n{(unsigned char*)\"Pcy\", {208, 159, 0}},\n{(unsigned char*)\"Pfr\", {240, 157, 148, 147, 0}},\n{(unsigned char*)\"Phi\", {206, 166, 0}},\n{(unsigned char*)\"Pi\", {206, 160, 0}},\n{(unsigned char*)\"PlusMinus\", {194, 177, 0}},\n{(unsigned char*)\"Poincareplane\", {226, 132, 140, 0}},\n{(unsigned char*)\"Popf\", {226, 132, 153, 0}},\n{(unsigned char*)\"Pr\", {226, 170, 187, 0}},\n{(unsigned char*)\"Precedes\", {226, 137, 186, 0}},\n{(unsigned char*)\"PrecedesEqual\", {226, 170, 175, 0}},\n{(unsigned char*)\"PrecedesSlantEqual\", {226, 137, 188, 0}},\n{(unsigned char*)\"PrecedesTilde\", {226, 137, 190, 0}},\n{(unsigned char*)\"Prime\", {226, 128, 179, 0}},\n{(unsigned char*)\"Product\", {226, 136, 143, 0}},\n{(unsigned char*)\"Proportion\", {226, 136, 183, 0}},\n{(unsigned char*)\"Proportional\", {226, 136, 157, 0}},\n{(unsigned char*)\"Pscr\", {240, 157, 146, 171, 0}},\n{(unsigned char*)\"Psi\", {206, 168, 0}},\n{(unsigned char*)\"QUOT\", {34, 0}},\n{(unsigned char*)\"Qfr\", {240, 157, 148, 148, 0}},\n{(unsigned char*)\"Qopf\", {226, 132, 154, 0}},\n{(unsigned char*)\"Qscr\", {240, 157, 146, 172, 0}},\n{(unsigned char*)\"RBarr\", {226, 164, 144, 0}},\n{(unsigned char*)\"REG\", {194, 174, 0}},\n{(unsigned char*)\"Racute\", {197, 148, 0}},\n{(unsigned char*)\"Rang\", {226, 159, 171, 0}},\n{(unsigned char*)\"Rarr\", {226, 134, 160, 0}},\n{(unsigned char*)\"Rarrtl\", {226, 164, 150, 0}},\n{(unsigned char*)\"Rcaron\", {197, 152, 0}},\n{(unsigned char*)\"Rcedil\", {197, 150, 0}},\n{(unsigned char*)\"Rcy\", {208, 160, 0}},\n{(unsigned char*)\"Re\", {226, 132, 156, 0}},\n{(unsigned char*)\"ReverseElement\", {226, 136, 139, 0}},\n{(unsigned char*)\"ReverseEquilibrium\", {226, 135, 139, 0}},\n{(unsigned char*)\"ReverseUpEquilibrium\", {226, 165, 175, 0}},\n{(unsigned char*)\"Rfr\", {226, 132, 156, 0}},\n{(unsigned char*)\"Rho\", {206, 161, 0}},\n{(unsigned char*)\"RightAngleBracket\", {226, 159, 169, 0}},\n{(unsigned char*)\"RightArrow\", {226, 134, 146, 0}},\n{(unsigned char*)\"RightArrowBar\", {226, 135, 165, 0}},\n{(unsigned char*)\"RightArrowLeftArrow\", {226, 135, 132, 0}},\n{(unsigned char*)\"RightCeiling\", {226, 140, 137, 0}},\n{(unsigned char*)\"RightDoubleBracket\", {226, 159, 167, 0}},\n{(unsigned char*)\"RightDownTeeVector\", {226, 165, 157, 0}},\n{(unsigned char*)\"RightDownVector\", {226, 135, 130, 0}},\n{(unsigned char*)\"RightDownVectorBar\", {226, 165, 149, 0}},\n{(unsigned char*)\"RightFloor\", {226, 140, 139, 0}},\n{(unsigned char*)\"RightTee\", {226, 138, 162, 0}},\n{(unsigned char*)\"RightTeeArrow\", {226, 134, 166, 0}},\n{(unsigned char*)\"RightTeeVector\", {226, 165, 155, 0}},\n{(unsigned char*)\"RightTriangle\", {226, 138, 179, 0}},\n{(unsigned char*)\"RightTriangleBar\", {226, 167, 144, 0}},\n{(unsigned char*)\"RightTriangleEqual\", {226, 138, 181, 0}},\n{(unsigned char*)\"RightUpDownVector\", {226, 165, 143, 0}},\n{(unsigned char*)\"RightUpTeeVector\", {226, 165, 156, 0}},\n{(unsigned char*)\"RightUpVector\", {226, 134, 190, 0}},\n{(unsigned char*)\"RightUpVectorBar\", {226, 165, 148, 0}},\n{(unsigned char*)\"RightVector\", {226, 135, 128, 0}},\n{(unsigned char*)\"RightVectorBar\", {226, 165, 147, 0}},\n{(unsigned char*)\"Rightarrow\", {226, 135, 146, 0}},\n{(unsigned char*)\"Ropf\", {226, 132, 157, 0}},\n{(unsigned char*)\"RoundImplies\", {226, 165, 176, 0}},\n{(unsigned char*)\"Rrightarrow\", {226, 135, 155, 0}},\n{(unsigned char*)\"Rscr\", {226, 132, 155, 0}},\n{(unsigned char*)\"Rsh\", {226, 134, 177, 0}},\n{(unsigned char*)\"RuleDelayed\", {226, 167, 180, 0}},\n{(unsigned char*)\"SHCHcy\", {208, 169, 0}},\n{(unsigned char*)\"SHcy\", {208, 168, 0}},\n{(unsigned char*)\"SOFTcy\", {208, 172, 0}},\n{(unsigned char*)\"Sacute\", {197, 154, 0}},\n{(unsigned char*)\"Sc\", {226, 170, 188, 0}},\n{(unsigned char*)\"Scaron\", {197, 160, 0}},\n{(unsigned char*)\"Scedil\", {197, 158, 0}},\n{(unsigned char*)\"Scirc\", {197, 156, 0}},\n{(unsigned char*)\"Scy\", {208, 161, 0}},\n{(unsigned char*)\"Sfr\", {240, 157, 148, 150, 0}},\n{(unsigned char*)\"ShortDownArrow\", {226, 134, 147, 0}},\n{(unsigned char*)\"ShortLeftArrow\", {226, 134, 144, 0}},\n{(unsigned char*)\"ShortRightArrow\", {226, 134, 146, 0}},\n{(unsigned char*)\"ShortUpArrow\", {226, 134, 145, 0}},\n{(unsigned char*)\"Sigma\", {206, 163, 0}},\n{(unsigned char*)\"SmallCircle\", {226, 136, 152, 0}},\n{(unsigned char*)\"Sopf\", {240, 157, 149, 138, 0}},\n{(unsigned char*)\"Sqrt\", {226, 136, 154, 0}},\n{(unsigned char*)\"Square\", {226, 150, 161, 0}},\n{(unsigned char*)\"SquareIntersection\", {226, 138, 147, 0}},\n{(unsigned char*)\"SquareSubset\", {226, 138, 143, 0}},\n{(unsigned char*)\"SquareSubsetEqual\", {226, 138, 145, 0}},\n{(unsigned char*)\"SquareSuperset\", {226, 138, 144, 0}},\n{(unsigned char*)\"SquareSupersetEqual\", {226, 138, 146, 0}},\n{(unsigned char*)\"SquareUnion\", {226, 138, 148, 0}},\n{(unsigned char*)\"Sscr\", {240, 157, 146, 174, 0}},\n{(unsigned char*)\"Star\", {226, 139, 134, 0}},\n{(unsigned char*)\"Sub\", {226, 139, 144, 0}},\n{(unsigned char*)\"Subset\", {226, 139, 144, 0}},\n{(unsigned char*)\"SubsetEqual\", {226, 138, 134, 0}},\n{(unsigned char*)\"Succeeds\", {226, 137, 187, 0}},\n{(unsigned char*)\"SucceedsEqual\", {226, 170, 176, 0}},\n{(unsigned char*)\"SucceedsSlantEqual\", {226, 137, 189, 0}},\n{(unsigned char*)\"SucceedsTilde\", {226, 137, 191, 0}},\n{(unsigned char*)\"SuchThat\", {226, 136, 139, 0}},\n{(unsigned char*)\"Sum\", {226, 136, 145, 0}},\n{(unsigned char*)\"Sup\", {226, 139, 145, 0}},\n{(unsigned char*)\"Superset\", {226, 138, 131, 0}},\n{(unsigned char*)\"SupersetEqual\", {226, 138, 135, 0}},\n{(unsigned char*)\"Supset\", {226, 139, 145, 0}},\n{(unsigned char*)\"THORN\", {195, 158, 0}},\n{(unsigned char*)\"TRADE\", {226, 132, 162, 0}},\n{(unsigned char*)\"TSHcy\", {208, 139, 0}},\n{(unsigned char*)\"TScy\", {208, 166, 0}},\n{(unsigned char*)\"Tab\", {9, 0}},\n{(unsigned char*)\"Tau\", {206, 164, 0}},\n{(unsigned char*)\"Tcaron\", {197, 164, 0}},\n{(unsigned char*)\"Tcedil\", {197, 162, 0}},\n{(unsigned char*)\"Tcy\", {208, 162, 0}},\n{(unsigned char*)\"Tfr\", {240, 157, 148, 151, 0}},\n{(unsigned char*)\"Therefore\", {226, 136, 180, 0}},\n{(unsigned char*)\"Theta\", {206, 152, 0}},\n{(unsigned char*)\"ThickSpace\", {226, 129, 159, 226, 128, 138, 0}},\n{(unsigned char*)\"ThinSpace\", {226, 128, 137, 0}},\n{(unsigned char*)\"Tilde\", {226, 136, 188, 0}},\n{(unsigned char*)\"TildeEqual\", {226, 137, 131, 0}},\n{(unsigned char*)\"TildeFullEqual\", {226, 137, 133, 0}},\n{(unsigned char*)\"TildeTilde\", {226, 137, 136, 0}},\n{(unsigned char*)\"Topf\", {240, 157, 149, 139, 0}},\n{(unsigned char*)\"TripleDot\", {226, 131, 155, 0}},\n{(unsigned char*)\"Tscr\", {240, 157, 146, 175, 0}},\n{(unsigned char*)\"Tstrok\", {197, 166, 0}},\n{(unsigned char*)\"Uacute\", {195, 154, 0}},\n{(unsigned char*)\"Uarr\", {226, 134, 159, 0}},\n{(unsigned char*)\"Uarrocir\", {226, 165, 137, 0}},\n{(unsigned char*)\"Ubrcy\", {208, 142, 0}},\n{(unsigned char*)\"Ubreve\", {197, 172, 0}},\n{(unsigned char*)\"Ucirc\", {195, 155, 0}},\n{(unsigned char*)\"Ucy\", {208, 163, 0}},\n{(unsigned char*)\"Udblac\", {197, 176, 0}},\n{(unsigned char*)\"Ufr\", {240, 157, 148, 152, 0}},\n{(unsigned char*)\"Ugrave\", {195, 153, 0}},\n{(unsigned char*)\"Umacr\", {197, 170, 0}},\n{(unsigned char*)\"UnderBar\", {95, 0}},\n{(unsigned char*)\"UnderBrace\", {226, 143, 159, 0}},\n{(unsigned char*)\"UnderBracket\", {226, 142, 181, 0}},\n{(unsigned char*)\"UnderParenthesis\", {226, 143, 157, 0}},\n{(unsigned char*)\"Union\", {226, 139, 131, 0}},\n{(unsigned char*)\"UnionPlus\", {226, 138, 142, 0}},\n{(unsigned char*)\"Uogon\", {197, 178, 0}},\n{(unsigned char*)\"Uopf\", {240, 157, 149, 140, 0}},\n{(unsigned char*)\"UpArrow\", {226, 134, 145, 0}},\n{(unsigned char*)\"UpArrowBar\", {226, 164, 146, 0}},\n{(unsigned char*)\"UpArrowDownArrow\", {226, 135, 133, 0}},\n{(unsigned char*)\"UpDownArrow\", {226, 134, 149, 0}},\n{(unsigned char*)\"UpEquilibrium\", {226, 165, 174, 0}},\n{(unsigned char*)\"UpTee\", {226, 138, 165, 0}},\n{(unsigned char*)\"UpTeeArrow\", {226, 134, 165, 0}},\n{(unsigned char*)\"Uparrow\", {226, 135, 145, 0}},\n{(unsigned char*)\"Updownarrow\", {226, 135, 149, 0}},\n{(unsigned char*)\"UpperLeftArrow\", {226, 134, 150, 0}},\n{(unsigned char*)\"UpperRightArrow\", {226, 134, 151, 0}},\n{(unsigned char*)\"Upsi\", {207, 146, 0}},\n{(unsigned char*)\"Upsilon\", {206, 165, 0}},\n{(unsigned char*)\"Uring\", {197, 174, 0}},\n{(unsigned char*)\"Uscr\", {240, 157, 146, 176, 0}},\n{(unsigned char*)\"Utilde\", {197, 168, 0}},\n{(unsigned char*)\"Uuml\", {195, 156, 0}},\n{(unsigned char*)\"VDash\", {226, 138, 171, 0}},\n{(unsigned char*)\"Vbar\", {226, 171, 171, 0}},\n{(unsigned char*)\"Vcy\", {208, 146, 0}},\n{(unsigned char*)\"Vdash\", {226, 138, 169, 0}},\n{(unsigned char*)\"Vdashl\", {226, 171, 166, 0}},\n{(unsigned char*)\"Vee\", {226, 139, 129, 0}},\n{(unsigned char*)\"Verbar\", {226, 128, 150, 0}},\n{(unsigned char*)\"Vert\", {226, 128, 150, 0}},\n{(unsigned char*)\"VerticalBar\", {226, 136, 163, 0}},\n{(unsigned char*)\"VerticalLine\", {124, 0}},\n{(unsigned char*)\"VerticalSeparator\", {226, 157, 152, 0}},\n{(unsigned char*)\"VerticalTilde\", {226, 137, 128, 0}},\n{(unsigned char*)\"VeryThinSpace\", {226, 128, 138, 0}},\n{(unsigned char*)\"Vfr\", {240, 157, 148, 153, 0}},\n{(unsigned char*)\"Vopf\", {240, 157, 149, 141, 0}},\n{(unsigned char*)\"Vscr\", {240, 157, 146, 177, 0}},\n{(unsigned char*)\"Vvdash\", {226, 138, 170, 0}},\n{(unsigned char*)\"Wcirc\", {197, 180, 0}},\n{(unsigned char*)\"Wedge\", {226, 139, 128, 0}},\n{(unsigned char*)\"Wfr\", {240, 157, 148, 154, 0}},\n{(unsigned char*)\"Wopf\", {240, 157, 149, 142, 0}},\n{(unsigned char*)\"Wscr\", {240, 157, 146, 178, 0}},\n{(unsigned char*)\"Xfr\", {240, 157, 148, 155, 0}},\n{(unsigned char*)\"Xi\", {206, 158, 0}},\n{(unsigned char*)\"Xopf\", {240, 157, 149, 143, 0}},\n{(unsigned char*)\"Xscr\", {240, 157, 146, 179, 0}},\n{(unsigned char*)\"YAcy\", {208, 175, 0}},\n{(unsigned char*)\"YIcy\", {208, 135, 0}},\n{(unsigned char*)\"YUcy\", {208, 174, 0}},\n{(unsigned char*)\"Yacute\", {195, 157, 0}},\n{(unsigned char*)\"Ycirc\", {197, 182, 0}},\n{(unsigned char*)\"Ycy\", {208, 171, 0}},\n{(unsigned char*)\"Yfr\", {240, 157, 148, 156, 0}},\n{(unsigned char*)\"Yopf\", {240, 157, 149, 144, 0}},\n{(unsigned char*)\"Yscr\", {240, 157, 146, 180, 0}},\n{(unsigned char*)\"Yuml\", {197, 184, 0}},\n{(unsigned char*)\"ZHcy\", {208, 150, 0}},\n{(unsigned char*)\"Zacute\", {197, 185, 0}},\n{(unsigned char*)\"Zcaron\", {197, 189, 0}},\n{(unsigned char*)\"Zcy\", {208, 151, 0}},\n{(unsigned char*)\"Zdot\", {197, 187, 0}},\n{(unsigned char*)\"ZeroWidthSpace\", {226, 128, 139, 0}},\n{(unsigned char*)\"Zeta\", {206, 150, 0}},\n{(unsigned char*)\"Zfr\", {226, 132, 168, 0}},\n{(unsigned char*)\"Zopf\", {226, 132, 164, 0}},\n{(unsigned char*)\"Zscr\", {240, 157, 146, 181, 0}},\n{(unsigned char*)\"aacute\", {195, 161, 0}},\n{(unsigned char*)\"abreve\", {196, 131, 0}},\n{(unsigned char*)\"ac\", {226, 136, 190, 0}},\n{(unsigned char*)\"acE\", {226, 136, 190, 204, 179, 0}},\n{(unsigned char*)\"acd\", {226, 136, 191, 0}},\n{(unsigned char*)\"acirc\", {195, 162, 0}},\n{(unsigned char*)\"acute\", {194, 180, 0}},\n{(unsigned char*)\"acy\", {208, 176, 0}},\n{(unsigned char*)\"aelig\", {195, 166, 0}},\n{(unsigned char*)\"af\", {226, 129, 161, 0}},\n{(unsigned char*)\"afr\", {240, 157, 148, 158, 0}},\n{(unsigned char*)\"agrave\", {195, 160, 0}},\n{(unsigned char*)\"alefsym\", {226, 132, 181, 0}},\n{(unsigned char*)\"aleph\", {226, 132, 181, 0}},\n{(unsigned char*)\"alpha\", {206, 177, 0}},\n{(unsigned char*)\"amacr\", {196, 129, 0}},\n{(unsigned char*)\"amalg\", {226, 168, 191, 0}},\n{(unsigned char*)\"amp\", {38, 0}},\n{(unsigned char*)\"and\", {226, 136, 167, 0}},\n{(unsigned char*)\"andand\", {226, 169, 149, 0}},\n{(unsigned char*)\"andd\", {226, 169, 156, 0}},\n{(unsigned char*)\"andslope\", {226, 169, 152, 0}},\n{(unsigned char*)\"andv\", {226, 169, 154, 0}},\n{(unsigned char*)\"ang\", {226, 136, 160, 0}},\n{(unsigned char*)\"ange\", {226, 166, 164, 0}},\n{(unsigned char*)\"angle\", {226, 136, 160, 0}},\n{(unsigned char*)\"angmsd\", {226, 136, 161, 0}},\n{(unsigned char*)\"angmsdaa\", {226, 166, 168, 0}},\n{(unsigned char*)\"angmsdab\", {226, 166, 169, 0}},\n{(unsigned char*)\"angmsdac\", {226, 166, 170, 0}},\n{(unsigned char*)\"angmsdad\", {226, 166, 171, 0}},\n{(unsigned char*)\"angmsdae\", {226, 166, 172, 0}},\n{(unsigned char*)\"angmsdaf\", {226, 166, 173, 0}},\n{(unsigned char*)\"angmsdag\", {226, 166, 174, 0}},\n{(unsigned char*)\"angmsdah\", {226, 166, 175, 0}},\n{(unsigned char*)\"angrt\", {226, 136, 159, 0}},\n{(unsigned char*)\"angrtvb\", {226, 138, 190, 0}},\n{(unsigned char*)\"angrtvbd\", {226, 166, 157, 0}},\n{(unsigned char*)\"angsph\", {226, 136, 162, 0}},\n{(unsigned char*)\"angst\", {195, 133, 0}},\n{(unsigned char*)\"angzarr\", {226, 141, 188, 0}},\n{(unsigned char*)\"aogon\", {196, 133, 0}},\n{(unsigned char*)\"aopf\", {240, 157, 149, 146, 0}},\n{(unsigned char*)\"ap\", {226, 137, 136, 0}},\n{(unsigned char*)\"apE\", {226, 169, 176, 0}},\n{(unsigned char*)\"apacir\", {226, 169, 175, 0}},\n{(unsigned char*)\"ape\", {226, 137, 138, 0}},\n{(unsigned char*)\"apid\", {226, 137, 139, 0}},\n{(unsigned char*)\"apos\", {39, 0}},\n{(unsigned char*)\"approx\", {226, 137, 136, 0}},\n{(unsigned char*)\"approxeq\", {226, 137, 138, 0}},\n{(unsigned char*)\"aring\", {195, 165, 0}},\n{(unsigned char*)\"ascr\", {240, 157, 146, 182, 0}},\n{(unsigned char*)\"ast\", {42, 0}},\n{(unsigned char*)\"asymp\", {226, 137, 136, 0}},\n{(unsigned char*)\"asympeq\", {226, 137, 141, 0}},\n{(unsigned char*)\"atilde\", {195, 163, 0}},\n{(unsigned char*)\"auml\", {195, 164, 0}},\n{(unsigned char*)\"awconint\", {226, 136, 179, 0}},\n{(unsigned char*)\"awint\", {226, 168, 145, 0}},\n{(unsigned char*)\"bNot\", {226, 171, 173, 0}},\n{(unsigned char*)\"backcong\", {226, 137, 140, 0}},\n{(unsigned char*)\"backepsilon\", {207, 182, 0}},\n{(unsigned char*)\"backprime\", {226, 128, 181, 0}},\n{(unsigned char*)\"backsim\", {226, 136, 189, 0}},\n{(unsigned char*)\"backsimeq\", {226, 139, 141, 0}},\n{(unsigned char*)\"barvee\", {226, 138, 189, 0}},\n{(unsigned char*)\"barwed\", {226, 140, 133, 0}},\n{(unsigned char*)\"barwedge\", {226, 140, 133, 0}},\n{(unsigned char*)\"bbrk\", {226, 142, 181, 0}},\n{(unsigned char*)\"bbrktbrk\", {226, 142, 182, 0}},\n{(unsigned char*)\"bcong\", {226, 137, 140, 0}},\n{(unsigned char*)\"bcy\", {208, 177, 0}},\n{(unsigned char*)\"bdquo\", {226, 128, 158, 0}},\n{(unsigned char*)\"becaus\", {226, 136, 181, 0}},\n{(unsigned char*)\"because\", {226, 136, 181, 0}},\n{(unsigned char*)\"bemptyv\", {226, 166, 176, 0}},\n{(unsigned char*)\"bepsi\", {207, 182, 0}},\n{(unsigned char*)\"bernou\", {226, 132, 172, 0}},\n{(unsigned char*)\"beta\", {206, 178, 0}},\n{(unsigned char*)\"beth\", {226, 132, 182, 0}},\n{(unsigned char*)\"between\", {226, 137, 172, 0}},\n{(unsigned char*)\"bfr\", {240, 157, 148, 159, 0}},\n{(unsigned char*)\"bigcap\", {226, 139, 130, 0}},\n{(unsigned char*)\"bigcirc\", {226, 151, 175, 0}},\n{(unsigned char*)\"bigcup\", {226, 139, 131, 0}},\n{(unsigned char*)\"bigodot\", {226, 168, 128, 0}},\n{(unsigned char*)\"bigoplus\", {226, 168, 129, 0}},\n{(unsigned char*)\"bigotimes\", {226, 168, 130, 0}},\n{(unsigned char*)\"bigsqcup\", {226, 168, 134, 0}},\n{(unsigned char*)\"bigstar\", {226, 152, 133, 0}},\n{(unsigned char*)\"bigtriangledown\", {226, 150, 189, 0}},\n{(unsigned char*)\"bigtriangleup\", {226, 150, 179, 0}},\n{(unsigned char*)\"biguplus\", {226, 168, 132, 0}},\n{(unsigned char*)\"bigvee\", {226, 139, 129, 0}},\n{(unsigned char*)\"bigwedge\", {226, 139, 128, 0}},\n{(unsigned char*)\"bkarow\", {226, 164, 141, 0}},\n{(unsigned char*)\"blacklozenge\", {226, 167, 171, 0}},\n{(unsigned char*)\"blacksquare\", {226, 150, 170, 0}},\n{(unsigned char*)\"blacktriangle\", {226, 150, 180, 0}},\n{(unsigned char*)\"blacktriangledown\", {226, 150, 190, 0}},\n{(unsigned char*)\"blacktriangleleft\", {226, 151, 130, 0}},\n{(unsigned char*)\"blacktriangleright\", {226, 150, 184, 0}},\n{(unsigned char*)\"blank\", {226, 144, 163, 0}},\n{(unsigned char*)\"blk12\", {226, 150, 146, 0}},\n{(unsigned char*)\"blk14\", {226, 150, 145, 0}},\n{(unsigned char*)\"blk34\", {226, 150, 147, 0}},\n{(unsigned char*)\"block\", {226, 150, 136, 0}},\n{(unsigned char*)\"bne\", {61, 226, 131, 165, 0}},\n{(unsigned char*)\"bnequiv\", {226, 137, 161, 226, 131, 165, 0}},\n{(unsigned char*)\"bnot\", {226, 140, 144, 0}},\n{(unsigned char*)\"bopf\", {240, 157, 149, 147, 0}},\n{(unsigned char*)\"bot\", {226, 138, 165, 0}},\n{(unsigned char*)\"bottom\", {226, 138, 165, 0}},\n{(unsigned char*)\"bowtie\", {226, 139, 136, 0}},\n{(unsigned char*)\"boxDL\", {226, 149, 151, 0}},\n{(unsigned char*)\"boxDR\", {226, 149, 148, 0}},\n{(unsigned char*)\"boxDl\", {226, 149, 150, 0}},\n{(unsigned char*)\"boxDr\", {226, 149, 147, 0}},\n{(unsigned char*)\"boxH\", {226, 149, 144, 0}},\n{(unsigned char*)\"boxHD\", {226, 149, 166, 0}},\n{(unsigned char*)\"boxHU\", {226, 149, 169, 0}},\n{(unsigned char*)\"boxHd\", {226, 149, 164, 0}},\n{(unsigned char*)\"boxHu\", {226, 149, 167, 0}},\n{(unsigned char*)\"boxUL\", {226, 149, 157, 0}},\n{(unsigned char*)\"boxUR\", {226, 149, 154, 0}},\n{(unsigned char*)\"boxUl\", {226, 149, 156, 0}},\n{(unsigned char*)\"boxUr\", {226, 149, 153, 0}},\n{(unsigned char*)\"boxV\", {226, 149, 145, 0}},\n{(unsigned char*)\"boxVH\", {226, 149, 172, 0}},\n{(unsigned char*)\"boxVL\", {226, 149, 163, 0}},\n{(unsigned char*)\"boxVR\", {226, 149, 160, 0}},\n{(unsigned char*)\"boxVh\", {226, 149, 171, 0}},\n{(unsigned char*)\"boxVl\", {226, 149, 162, 0}},\n{(unsigned char*)\"boxVr\", {226, 149, 159, 0}},\n{(unsigned char*)\"boxbox\", {226, 167, 137, 0}},\n{(unsigned char*)\"boxdL\", {226, 149, 149, 0}},\n{(unsigned char*)\"boxdR\", {226, 149, 146, 0}},\n{(unsigned char*)\"boxdl\", {226, 148, 144, 0}},\n{(unsigned char*)\"boxdr\", {226, 148, 140, 0}},\n{(unsigned char*)\"boxh\", {226, 148, 128, 0}},\n{(unsigned char*)\"boxhD\", {226, 149, 165, 0}},\n{(unsigned char*)\"boxhU\", {226, 149, 168, 0}},\n{(unsigned char*)\"boxhd\", {226, 148, 172, 0}},\n{(unsigned char*)\"boxhu\", {226, 148, 180, 0}},\n{(unsigned char*)\"boxminus\", {226, 138, 159, 0}},\n{(unsigned char*)\"boxplus\", {226, 138, 158, 0}},\n{(unsigned char*)\"boxtimes\", {226, 138, 160, 0}},\n{(unsigned char*)\"boxuL\", {226, 149, 155, 0}},\n{(unsigned char*)\"boxuR\", {226, 149, 152, 0}},\n{(unsigned char*)\"boxul\", {226, 148, 152, 0}},\n{(unsigned char*)\"boxur\", {226, 148, 148, 0}},\n{(unsigned char*)\"boxv\", {226, 148, 130, 0}},\n{(unsigned char*)\"boxvH\", {226, 149, 170, 0}},\n{(unsigned char*)\"boxvL\", {226, 149, 161, 0}},\n{(unsigned char*)\"boxvR\", {226, 149, 158, 0}},\n{(unsigned char*)\"boxvh\", {226, 148, 188, 0}},\n{(unsigned char*)\"boxvl\", {226, 148, 164, 0}},\n{(unsigned char*)\"boxvr\", {226, 148, 156, 0}},\n{(unsigned char*)\"bprime\", {226, 128, 181, 0}},\n{(unsigned char*)\"breve\", {203, 152, 0}},\n{(unsigned char*)\"brvbar\", {194, 166, 0}},\n{(unsigned char*)\"bscr\", {240, 157, 146, 183, 0}},\n{(unsigned char*)\"bsemi\", {226, 129, 143, 0}},\n{(unsigned char*)\"bsim\", {226, 136, 189, 0}},\n{(unsigned char*)\"bsime\", {226, 139, 141, 0}},\n{(unsigned char*)\"bsol\", {92, 0}},\n{(unsigned char*)\"bsolb\", {226, 167, 133, 0}},\n{(unsigned char*)\"bsolhsub\", {226, 159, 136, 0}},\n{(unsigned char*)\"bull\", {226, 128, 162, 0}},\n{(unsigned char*)\"bullet\", {226, 128, 162, 0}},\n{(unsigned char*)\"bump\", {226, 137, 142, 0}},\n{(unsigned char*)\"bumpE\", {226, 170, 174, 0}},\n{(unsigned char*)\"bumpe\", {226, 137, 143, 0}},\n{(unsigned char*)\"bumpeq\", {226, 137, 143, 0}},\n{(unsigned char*)\"cacute\", {196, 135, 0}},\n{(unsigned char*)\"cap\", {226, 136, 169, 0}},\n{(unsigned char*)\"capand\", {226, 169, 132, 0}},\n{(unsigned char*)\"capbrcup\", {226, 169, 137, 0}},\n{(unsigned char*)\"capcap\", {226, 169, 139, 0}},\n{(unsigned char*)\"capcup\", {226, 169, 135, 0}},\n{(unsigned char*)\"capdot\", {226, 169, 128, 0}},\n{(unsigned char*)\"caps\", {226, 136, 169, 239, 184, 128, 0}},\n{(unsigned char*)\"caret\", {226, 129, 129, 0}},\n{(unsigned char*)\"caron\", {203, 135, 0}},\n{(unsigned char*)\"ccaps\", {226, 169, 141, 0}},\n{(unsigned char*)\"ccaron\", {196, 141, 0}},\n{(unsigned char*)\"ccedil\", {195, 167, 0}},\n{(unsigned char*)\"ccirc\", {196, 137, 0}},\n{(unsigned char*)\"ccups\", {226, 169, 140, 0}},\n{(unsigned char*)\"ccupssm\", {226, 169, 144, 0}},\n{(unsigned char*)\"cdot\", {196, 139, 0}},\n{(unsigned char*)\"cedil\", {194, 184, 0}},\n{(unsigned char*)\"cemptyv\", {226, 166, 178, 0}},\n{(unsigned char*)\"cent\", {194, 162, 0}},\n{(unsigned char*)\"centerdot\", {194, 183, 0}},\n{(unsigned char*)\"cfr\", {240, 157, 148, 160, 0}},\n{(unsigned char*)\"chcy\", {209, 135, 0}},\n{(unsigned char*)\"check\", {226, 156, 147, 0}},\n{(unsigned char*)\"checkmark\", {226, 156, 147, 0}},\n{(unsigned char*)\"chi\", {207, 135, 0}},\n{(unsigned char*)\"cir\", {226, 151, 139, 0}},\n{(unsigned char*)\"cirE\", {226, 167, 131, 0}},\n{(unsigned char*)\"circ\", {203, 134, 0}},\n{(unsigned char*)\"circeq\", {226, 137, 151, 0}},\n{(unsigned char*)\"circlearrowleft\", {226, 134, 186, 0}},\n{(unsigned char*)\"circlearrowright\", {226, 134, 187, 0}},\n{(unsigned char*)\"circledR\", {194, 174, 0}},\n{(unsigned char*)\"circledS\", {226, 147, 136, 0}},\n{(unsigned char*)\"circledast\", {226, 138, 155, 0}},\n{(unsigned char*)\"circledcirc\", {226, 138, 154, 0}},\n{(unsigned char*)\"circleddash\", {226, 138, 157, 0}},\n{(unsigned char*)\"cire\", {226, 137, 151, 0}},\n{(unsigned char*)\"cirfnint\", {226, 168, 144, 0}},\n{(unsigned char*)\"cirmid\", {226, 171, 175, 0}},\n{(unsigned char*)\"cirscir\", {226, 167, 130, 0}},\n{(unsigned char*)\"clubs\", {226, 153, 163, 0}},\n{(unsigned char*)\"clubsuit\", {226, 153, 163, 0}},\n{(unsigned char*)\"colon\", {58, 0}},\n{(unsigned char*)\"colone\", {226, 137, 148, 0}},\n{(unsigned char*)\"coloneq\", {226, 137, 148, 0}},\n{(unsigned char*)\"comma\", {44, 0}},\n{(unsigned char*)\"commat\", {64, 0}},\n{(unsigned char*)\"comp\", {226, 136, 129, 0}},\n{(unsigned char*)\"compfn\", {226, 136, 152, 0}},\n{(unsigned char*)\"complement\", {226, 136, 129, 0}},\n{(unsigned char*)\"complexes\", {226, 132, 130, 0}},\n{(unsigned char*)\"cong\", {226, 137, 133, 0}},\n{(unsigned char*)\"congdot\", {226, 169, 173, 0}},\n{(unsigned char*)\"conint\", {226, 136, 174, 0}},\n{(unsigned char*)\"copf\", {240, 157, 149, 148, 0}},\n{(unsigned char*)\"coprod\", {226, 136, 144, 0}},\n{(unsigned char*)\"copy\", {194, 169, 0}},\n{(unsigned char*)\"copysr\", {226, 132, 151, 0}},\n{(unsigned char*)\"crarr\", {226, 134, 181, 0}},\n{(unsigned char*)\"cross\", {226, 156, 151, 0}},\n{(unsigned char*)\"cscr\", {240, 157, 146, 184, 0}},\n{(unsigned char*)\"csub\", {226, 171, 143, 0}},\n{(unsigned char*)\"csube\", {226, 171, 145, 0}},\n{(unsigned char*)\"csup\", {226, 171, 144, 0}},\n{(unsigned char*)\"csupe\", {226, 171, 146, 0}},\n{(unsigned char*)\"ctdot\", {226, 139, 175, 0}},\n{(unsigned char*)\"cudarrl\", {226, 164, 184, 0}},\n{(unsigned char*)\"cudarrr\", {226, 164, 181, 0}},\n{(unsigned char*)\"cuepr\", {226, 139, 158, 0}},\n{(unsigned char*)\"cuesc\", {226, 139, 159, 0}},\n{(unsigned char*)\"cularr\", {226, 134, 182, 0}},\n{(unsigned char*)\"cularrp\", {226, 164, 189, 0}},\n{(unsigned char*)\"cup\", {226, 136, 170, 0}},\n{(unsigned char*)\"cupbrcap\", {226, 169, 136, 0}},\n{(unsigned char*)\"cupcap\", {226, 169, 134, 0}},\n{(unsigned char*)\"cupcup\", {226, 169, 138, 0}},\n{(unsigned char*)\"cupdot\", {226, 138, 141, 0}},\n{(unsigned char*)\"cupor\", {226, 169, 133, 0}},\n{(unsigned char*)\"cups\", {226, 136, 170, 239, 184, 128, 0}},\n{(unsigned char*)\"curarr\", {226, 134, 183, 0}},\n{(unsigned char*)\"curarrm\", {226, 164, 188, 0}},\n{(unsigned char*)\"curlyeqprec\", {226, 139, 158, 0}},\n{(unsigned char*)\"curlyeqsucc\", {226, 139, 159, 0}},\n{(unsigned char*)\"curlyvee\", {226, 139, 142, 0}},\n{(unsigned char*)\"curlywedge\", {226, 139, 143, 0}},\n{(unsigned char*)\"curren\", {194, 164, 0}},\n{(unsigned char*)\"curvearrowleft\", {226, 134, 182, 0}},\n{(unsigned char*)\"curvearrowright\", {226, 134, 183, 0}},\n{(unsigned char*)\"cuvee\", {226, 139, 142, 0}},\n{(unsigned char*)\"cuwed\", {226, 139, 143, 0}},\n{(unsigned char*)\"cwconint\", {226, 136, 178, 0}},\n{(unsigned char*)\"cwint\", {226, 136, 177, 0}},\n{(unsigned char*)\"cylcty\", {226, 140, 173, 0}},\n{(unsigned char*)\"dArr\", {226, 135, 147, 0}},\n{(unsigned char*)\"dHar\", {226, 165, 165, 0}},\n{(unsigned char*)\"dagger\", {226, 128, 160, 0}},\n{(unsigned char*)\"daleth\", {226, 132, 184, 0}},\n{(unsigned char*)\"darr\", {226, 134, 147, 0}},\n{(unsigned char*)\"dash\", {226, 128, 144, 0}},\n{(unsigned char*)\"dashv\", {226, 138, 163, 0}},\n{(unsigned char*)\"dbkarow\", {226, 164, 143, 0}},\n{(unsigned char*)\"dblac\", {203, 157, 0}},\n{(unsigned char*)\"dcaron\", {196, 143, 0}},\n{(unsigned char*)\"dcy\", {208, 180, 0}},\n{(unsigned char*)\"dd\", {226, 133, 134, 0}},\n{(unsigned char*)\"ddagger\", {226, 128, 161, 0}},\n{(unsigned char*)\"ddarr\", {226, 135, 138, 0}},\n{(unsigned char*)\"ddotseq\", {226, 169, 183, 0}},\n{(unsigned char*)\"deg\", {194, 176, 0}},\n{(unsigned char*)\"delta\", {206, 180, 0}},\n{(unsigned char*)\"demptyv\", {226, 166, 177, 0}},\n{(unsigned char*)\"dfisht\", {226, 165, 191, 0}},\n{(unsigned char*)\"dfr\", {240, 157, 148, 161, 0}},\n{(unsigned char*)\"dharl\", {226, 135, 131, 0}},\n{(unsigned char*)\"dharr\", {226, 135, 130, 0}},\n{(unsigned char*)\"diam\", {226, 139, 132, 0}},\n{(unsigned char*)\"diamond\", {226, 139, 132, 0}},\n{(unsigned char*)\"diamondsuit\", {226, 153, 166, 0}},\n{(unsigned char*)\"diams\", {226, 153, 166, 0}},\n{(unsigned char*)\"die\", {194, 168, 0}},\n{(unsigned char*)\"digamma\", {207, 157, 0}},\n{(unsigned char*)\"disin\", {226, 139, 178, 0}},\n{(unsigned char*)\"div\", {195, 183, 0}},\n{(unsigned char*)\"divide\", {195, 183, 0}},\n{(unsigned char*)\"divideontimes\", {226, 139, 135, 0}},\n{(unsigned char*)\"divonx\", {226, 139, 135, 0}},\n{(unsigned char*)\"djcy\", {209, 146, 0}},\n{(unsigned char*)\"dlcorn\", {226, 140, 158, 0}},\n{(unsigned char*)\"dlcrop\", {226, 140, 141, 0}},\n{(unsigned char*)\"dollar\", {36, 0}},\n{(unsigned char*)\"dopf\", {240, 157, 149, 149, 0}},\n{(unsigned char*)\"dot\", {203, 153, 0}},\n{(unsigned char*)\"doteq\", {226, 137, 144, 0}},\n{(unsigned char*)\"doteqdot\", {226, 137, 145, 0}},\n{(unsigned char*)\"dotminus\", {226, 136, 184, 0}},\n{(unsigned char*)\"dotplus\", {226, 136, 148, 0}},\n{(unsigned char*)\"dotsquare\", {226, 138, 161, 0}},\n{(unsigned char*)\"doublebarwedge\", {226, 140, 134, 0}},\n{(unsigned char*)\"downarrow\", {226, 134, 147, 0}},\n{(unsigned char*)\"downdownarrows\", {226, 135, 138, 0}},\n{(unsigned char*)\"downharpoonleft\", {226, 135, 131, 0}},\n{(unsigned char*)\"downharpoonright\", {226, 135, 130, 0}},\n{(unsigned char*)\"drbkarow\", {226, 164, 144, 0}},\n{(unsigned char*)\"drcorn\", {226, 140, 159, 0}},\n{(unsigned char*)\"drcrop\", {226, 140, 140, 0}},\n{(unsigned char*)\"dscr\", {240, 157, 146, 185, 0}},\n{(unsigned char*)\"dscy\", {209, 149, 0}},\n{(unsigned char*)\"dsol\", {226, 167, 182, 0}},\n{(unsigned char*)\"dstrok\", {196, 145, 0}},\n{(unsigned char*)\"dtdot\", {226, 139, 177, 0}},\n{(unsigned char*)\"dtri\", {226, 150, 191, 0}},\n{(unsigned char*)\"dtrif\", {226, 150, 190, 0}},\n{(unsigned char*)\"duarr\", {226, 135, 181, 0}},\n{(unsigned char*)\"duhar\", {226, 165, 175, 0}},\n{(unsigned char*)\"dwangle\", {226, 166, 166, 0}},\n{(unsigned char*)\"dzcy\", {209, 159, 0}},\n{(unsigned char*)\"dzigrarr\", {226, 159, 191, 0}},\n{(unsigned char*)\"eDDot\", {226, 169, 183, 0}},\n{(unsigned char*)\"eDot\", {226, 137, 145, 0}},\n{(unsigned char*)\"eacute\", {195, 169, 0}},\n{(unsigned char*)\"easter\", {226, 169, 174, 0}},\n{(unsigned char*)\"ecaron\", {196, 155, 0}},\n{(unsigned char*)\"ecir\", {226, 137, 150, 0}},\n{(unsigned char*)\"ecirc\", {195, 170, 0}},\n{(unsigned char*)\"ecolon\", {226, 137, 149, 0}},\n{(unsigned char*)\"ecy\", {209, 141, 0}},\n{(unsigned char*)\"edot\", {196, 151, 0}},\n{(unsigned char*)\"ee\", {226, 133, 135, 0}},\n{(unsigned char*)\"efDot\", {226, 137, 146, 0}},\n{(unsigned char*)\"efr\", {240, 157, 148, 162, 0}},\n{(unsigned char*)\"eg\", {226, 170, 154, 0}},\n{(unsigned char*)\"egrave\", {195, 168, 0}},\n{(unsigned char*)\"egs\", {226, 170, 150, 0}},\n{(unsigned char*)\"egsdot\", {226, 170, 152, 0}},\n{(unsigned char*)\"el\", {226, 170, 153, 0}},\n{(unsigned char*)\"elinters\", {226, 143, 167, 0}},\n{(unsigned char*)\"ell\", {226, 132, 147, 0}},\n{(unsigned char*)\"els\", {226, 170, 149, 0}},\n{(unsigned char*)\"elsdot\", {226, 170, 151, 0}},\n{(unsigned char*)\"emacr\", {196, 147, 0}},\n{(unsigned char*)\"empty\", {226, 136, 133, 0}},\n{(unsigned char*)\"emptyset\", {226, 136, 133, 0}},\n{(unsigned char*)\"emptyv\", {226, 136, 133, 0}},\n{(unsigned char*)\"emsp\", {226, 128, 131, 0}},\n{(unsigned char*)\"emsp13\", {226, 128, 132, 0}},\n{(unsigned char*)\"emsp14\", {226, 128, 133, 0}},\n{(unsigned char*)\"eng\", {197, 139, 0}},\n{(unsigned char*)\"ensp\", {226, 128, 130, 0}},\n{(unsigned char*)\"eogon\", {196, 153, 0}},\n{(unsigned char*)\"eopf\", {240, 157, 149, 150, 0}},\n{(unsigned char*)\"epar\", {226, 139, 149, 0}},\n{(unsigned char*)\"eparsl\", {226, 167, 163, 0}},\n{(unsigned char*)\"eplus\", {226, 169, 177, 0}},\n{(unsigned char*)\"epsi\", {206, 181, 0}},\n{(unsigned char*)\"epsilon\", {206, 181, 0}},\n{(unsigned char*)\"epsiv\", {207, 181, 0}},\n{(unsigned char*)\"eqcirc\", {226, 137, 150, 0}},\n{(unsigned char*)\"eqcolon\", {226, 137, 149, 0}},\n{(unsigned char*)\"eqsim\", {226, 137, 130, 0}},\n{(unsigned char*)\"eqslantgtr\", {226, 170, 150, 0}},\n{(unsigned char*)\"eqslantless\", {226, 170, 149, 0}},\n{(unsigned char*)\"equals\", {61, 0}},\n{(unsigned char*)\"equest\", {226, 137, 159, 0}},\n{(unsigned char*)\"equiv\", {226, 137, 161, 0}},\n{(unsigned char*)\"equivDD\", {226, 169, 184, 0}},\n{(unsigned char*)\"eqvparsl\", {226, 167, 165, 0}},\n{(unsigned char*)\"erDot\", {226, 137, 147, 0}},\n{(unsigned char*)\"erarr\", {226, 165, 177, 0}},\n{(unsigned char*)\"escr\", {226, 132, 175, 0}},\n{(unsigned char*)\"esdot\", {226, 137, 144, 0}},\n{(unsigned char*)\"esim\", {226, 137, 130, 0}},\n{(unsigned char*)\"eta\", {206, 183, 0}},\n{(unsigned char*)\"eth\", {195, 176, 0}},\n{(unsigned char*)\"euml\", {195, 171, 0}},\n{(unsigned char*)\"euro\", {226, 130, 172, 0}},\n{(unsigned char*)\"excl\", {33, 0}},\n{(unsigned char*)\"exist\", {226, 136, 131, 0}},\n{(unsigned char*)\"expectation\", {226, 132, 176, 0}},\n{(unsigned char*)\"exponentiale\", {226, 133, 135, 0}},\n{(unsigned char*)\"fallingdotseq\", {226, 137, 146, 0}},\n{(unsigned char*)\"fcy\", {209, 132, 0}},\n{(unsigned char*)\"female\", {226, 153, 128, 0}},\n{(unsigned char*)\"ffilig\", {239, 172, 131, 0}},\n{(unsigned char*)\"fflig\", {239, 172, 128, 0}},\n{(unsigned char*)\"ffllig\", {239, 172, 132, 0}},\n{(unsigned char*)\"ffr\", {240, 157, 148, 163, 0}},\n{(unsigned char*)\"filig\", {239, 172, 129, 0}},\n{(unsigned char*)\"fjlig\", {102, 106, 0}},\n{(unsigned char*)\"flat\", {226, 153, 173, 0}},\n{(unsigned char*)\"fllig\", {239, 172, 130, 0}},\n{(unsigned char*)\"fltns\", {226, 150, 177, 0}},\n{(unsigned char*)\"fnof\", {198, 146, 0}},\n{(unsigned char*)\"fopf\", {240, 157, 149, 151, 0}},\n{(unsigned char*)\"forall\", {226, 136, 128, 0}},\n{(unsigned char*)\"fork\", {226, 139, 148, 0}},\n{(unsigned char*)\"forkv\", {226, 171, 153, 0}},\n{(unsigned char*)\"fpartint\", {226, 168, 141, 0}},\n{(unsigned char*)\"frac12\", {194, 189, 0}},\n{(unsigned char*)\"frac13\", {226, 133, 147, 0}},\n{(unsigned char*)\"frac14\", {194, 188, 0}},\n{(unsigned char*)\"frac15\", {226, 133, 149, 0}},\n{(unsigned char*)\"frac16\", {226, 133, 153, 0}},\n{(unsigned char*)\"frac18\", {226, 133, 155, 0}},\n{(unsigned char*)\"frac23\", {226, 133, 148, 0}},\n{(unsigned char*)\"frac25\", {226, 133, 150, 0}},\n{(unsigned char*)\"frac34\", {194, 190, 0}},\n{(unsigned char*)\"frac35\", {226, 133, 151, 0}},\n{(unsigned char*)\"frac38\", {226, 133, 156, 0}},\n{(unsigned char*)\"frac45\", {226, 133, 152, 0}},\n{(unsigned char*)\"frac56\", {226, 133, 154, 0}},\n{(unsigned char*)\"frac58\", {226, 133, 157, 0}},\n{(unsigned char*)\"frac78\", {226, 133, 158, 0}},\n{(unsigned char*)\"frasl\", {226, 129, 132, 0}},\n{(unsigned char*)\"frown\", {226, 140, 162, 0}},\n{(unsigned char*)\"fscr\", {240, 157, 146, 187, 0}},\n{(unsigned char*)\"gE\", {226, 137, 167, 0}},\n{(unsigned char*)\"gEl\", {226, 170, 140, 0}},\n{(unsigned char*)\"gacute\", {199, 181, 0}},\n{(unsigned char*)\"gamma\", {206, 179, 0}},\n{(unsigned char*)\"gammad\", {207, 157, 0}},\n{(unsigned char*)\"gap\", {226, 170, 134, 0}},\n{(unsigned char*)\"gbreve\", {196, 159, 0}},\n{(unsigned char*)\"gcirc\", {196, 157, 0}},\n{(unsigned char*)\"gcy\", {208, 179, 0}},\n{(unsigned char*)\"gdot\", {196, 161, 0}},\n{(unsigned char*)\"ge\", {226, 137, 165, 0}},\n{(unsigned char*)\"gel\", {226, 139, 155, 0}},\n{(unsigned char*)\"geq\", {226, 137, 165, 0}},\n{(unsigned char*)\"geqq\", {226, 137, 167, 0}},\n{(unsigned char*)\"geqslant\", {226, 169, 190, 0}},\n{(unsigned char*)\"ges\", {226, 169, 190, 0}},\n{(unsigned char*)\"gescc\", {226, 170, 169, 0}},\n{(unsigned char*)\"gesdot\", {226, 170, 128, 0}},\n{(unsigned char*)\"gesdoto\", {226, 170, 130, 0}},\n{(unsigned char*)\"gesdotol\", {226, 170, 132, 0}},\n{(unsigned char*)\"gesl\", {226, 139, 155, 239, 184, 128, 0}},\n{(unsigned char*)\"gesles\", {226, 170, 148, 0}},\n{(unsigned char*)\"gfr\", {240, 157, 148, 164, 0}},\n{(unsigned char*)\"gg\", {226, 137, 171, 0}},\n{(unsigned char*)\"ggg\", {226, 139, 153, 0}},\n{(unsigned char*)\"gimel\", {226, 132, 183, 0}},\n{(unsigned char*)\"gjcy\", {209, 147, 0}},\n{(unsigned char*)\"gl\", {226, 137, 183, 0}},\n{(unsigned char*)\"glE\", {226, 170, 146, 0}},\n{(unsigned char*)\"gla\", {226, 170, 165, 0}},\n{(unsigned char*)\"glj\", {226, 170, 164, 0}},\n{(unsigned char*)\"gnE\", {226, 137, 169, 0}},\n{(unsigned char*)\"gnap\", {226, 170, 138, 0}},\n{(unsigned char*)\"gnapprox\", {226, 170, 138, 0}},\n{(unsigned char*)\"gne\", {226, 170, 136, 0}},\n{(unsigned char*)\"gneq\", {226, 170, 136, 0}},\n{(unsigned char*)\"gneqq\", {226, 137, 169, 0}},\n{(unsigned char*)\"gnsim\", {226, 139, 167, 0}},\n{(unsigned char*)\"gopf\", {240, 157, 149, 152, 0}},\n{(unsigned char*)\"grave\", {96, 0}},\n{(unsigned char*)\"gscr\", {226, 132, 138, 0}},\n{(unsigned char*)\"gsim\", {226, 137, 179, 0}},\n{(unsigned char*)\"gsime\", {226, 170, 142, 0}},\n{(unsigned char*)\"gsiml\", {226, 170, 144, 0}},\n{(unsigned char*)\"gt\", {62, 0}},\n{(unsigned char*)\"gtcc\", {226, 170, 167, 0}},\n{(unsigned char*)\"gtcir\", {226, 169, 186, 0}},\n{(unsigned char*)\"gtdot\", {226, 139, 151, 0}},\n{(unsigned char*)\"gtlPar\", {226, 166, 149, 0}},\n{(unsigned char*)\"gtquest\", {226, 169, 188, 0}},\n{(unsigned char*)\"gtrapprox\", {226, 170, 134, 0}},\n{(unsigned char*)\"gtrarr\", {226, 165, 184, 0}},\n{(unsigned char*)\"gtrdot\", {226, 139, 151, 0}},\n{(unsigned char*)\"gtreqless\", {226, 139, 155, 0}},\n{(unsigned char*)\"gtreqqless\", {226, 170, 140, 0}},\n{(unsigned char*)\"gtrless\", {226, 137, 183, 0}},\n{(unsigned char*)\"gtrsim\", {226, 137, 179, 0}},\n{(unsigned char*)\"gvertneqq\", {226, 137, 169, 239, 184, 128, 0}},\n{(unsigned char*)\"gvnE\", {226, 137, 169, 239, 184, 128, 0}},\n{(unsigned char*)\"hArr\", {226, 135, 148, 0}},\n{(unsigned char*)\"hairsp\", {226, 128, 138, 0}},\n{(unsigned char*)\"half\", {194, 189, 0}},\n{(unsigned char*)\"hamilt\", {226, 132, 139, 0}},\n{(unsigned char*)\"hardcy\", {209, 138, 0}},\n{(unsigned char*)\"harr\", {226, 134, 148, 0}},\n{(unsigned char*)\"harrcir\", {226, 165, 136, 0}},\n{(unsigned char*)\"harrw\", {226, 134, 173, 0}},\n{(unsigned char*)\"hbar\", {226, 132, 143, 0}},\n{(unsigned char*)\"hcirc\", {196, 165, 0}},\n{(unsigned char*)\"hearts\", {226, 153, 165, 0}},\n{(unsigned char*)\"heartsuit\", {226, 153, 165, 0}},\n{(unsigned char*)\"hellip\", {226, 128, 166, 0}},\n{(unsigned char*)\"hercon\", {226, 138, 185, 0}},\n{(unsigned char*)\"hfr\", {240, 157, 148, 165, 0}},\n{(unsigned char*)\"hksearow\", {226, 164, 165, 0}},\n{(unsigned char*)\"hkswarow\", {226, 164, 166, 0}},\n{(unsigned char*)\"hoarr\", {226, 135, 191, 0}},\n{(unsigned char*)\"homtht\", {226, 136, 187, 0}},\n{(unsigned char*)\"hookleftarrow\", {226, 134, 169, 0}},\n{(unsigned char*)\"hookrightarrow\", {226, 134, 170, 0}},\n{(unsigned char*)\"hopf\", {240, 157, 149, 153, 0}},\n{(unsigned char*)\"horbar\", {226, 128, 149, 0}},\n{(unsigned char*)\"hscr\", {240, 157, 146, 189, 0}},\n{(unsigned char*)\"hslash\", {226, 132, 143, 0}},\n{(unsigned char*)\"hstrok\", {196, 167, 0}},\n{(unsigned char*)\"hybull\", {226, 129, 131, 0}},\n{(unsigned char*)\"hyphen\", {226, 128, 144, 0}},\n{(unsigned char*)\"iacute\", {195, 173, 0}},\n{(unsigned char*)\"ic\", {226, 129, 163, 0}},\n{(unsigned char*)\"icirc\", {195, 174, 0}},\n{(unsigned char*)\"icy\", {208, 184, 0}},\n{(unsigned char*)\"iecy\", {208, 181, 0}},\n{(unsigned char*)\"iexcl\", {194, 161, 0}},\n{(unsigned char*)\"iff\", {226, 135, 148, 0}},\n{(unsigned char*)\"ifr\", {240, 157, 148, 166, 0}},\n{(unsigned char*)\"igrave\", {195, 172, 0}},\n{(unsigned char*)\"ii\", {226, 133, 136, 0}},\n{(unsigned char*)\"iiiint\", {226, 168, 140, 0}},\n{(unsigned char*)\"iiint\", {226, 136, 173, 0}},\n{(unsigned char*)\"iinfin\", {226, 167, 156, 0}},\n{(unsigned char*)\"iiota\", {226, 132, 169, 0}},\n{(unsigned char*)\"ijlig\", {196, 179, 0}},\n{(unsigned char*)\"imacr\", {196, 171, 0}},\n{(unsigned char*)\"image\", {226, 132, 145, 0}},\n{(unsigned char*)\"imagline\", {226, 132, 144, 0}},\n{(unsigned char*)\"imagpart\", {226, 132, 145, 0}},\n{(unsigned char*)\"imath\", {196, 177, 0}},\n{(unsigned char*)\"imof\", {226, 138, 183, 0}},\n{(unsigned char*)\"imped\", {198, 181, 0}},\n{(unsigned char*)\"in\", {226, 136, 136, 0}},\n{(unsigned char*)\"incare\", {226, 132, 133, 0}},\n{(unsigned char*)\"infin\", {226, 136, 158, 0}},\n{(unsigned char*)\"infintie\", {226, 167, 157, 0}},\n{(unsigned char*)\"inodot\", {196, 177, 0}},\n{(unsigned char*)\"int\", {226, 136, 171, 0}},\n{(unsigned char*)\"intcal\", {226, 138, 186, 0}},\n{(unsigned char*)\"integers\", {226, 132, 164, 0}},\n{(unsigned char*)\"intercal\", {226, 138, 186, 0}},\n{(unsigned char*)\"intlarhk\", {226, 168, 151, 0}},\n{(unsigned char*)\"intprod\", {226, 168, 188, 0}},\n{(unsigned char*)\"iocy\", {209, 145, 0}},\n{(unsigned char*)\"iogon\", {196, 175, 0}},\n{(unsigned char*)\"iopf\", {240, 157, 149, 154, 0}},\n{(unsigned char*)\"iota\", {206, 185, 0}},\n{(unsigned char*)\"iprod\", {226, 168, 188, 0}},\n{(unsigned char*)\"iquest\", {194, 191, 0}},\n{(unsigned char*)\"iscr\", {240, 157, 146, 190, 0}},\n{(unsigned char*)\"isin\", {226, 136, 136, 0}},\n{(unsigned char*)\"isinE\", {226, 139, 185, 0}},\n{(unsigned char*)\"isindot\", {226, 139, 181, 0}},\n{(unsigned char*)\"isins\", {226, 139, 180, 0}},\n{(unsigned char*)\"isinsv\", {226, 139, 179, 0}},\n{(unsigned char*)\"isinv\", {226, 136, 136, 0}},\n{(unsigned char*)\"it\", {226, 129, 162, 0}},\n{(unsigned char*)\"itilde\", {196, 169, 0}},\n{(unsigned char*)\"iukcy\", {209, 150, 0}},\n{(unsigned char*)\"iuml\", {195, 175, 0}},\n{(unsigned char*)\"jcirc\", {196, 181, 0}},\n{(unsigned char*)\"jcy\", {208, 185, 0}},\n{(unsigned char*)\"jfr\", {240, 157, 148, 167, 0}},\n{(unsigned char*)\"jmath\", {200, 183, 0}},\n{(unsigned char*)\"jopf\", {240, 157, 149, 155, 0}},\n{(unsigned char*)\"jscr\", {240, 157, 146, 191, 0}},\n{(unsigned char*)\"jsercy\", {209, 152, 0}},\n{(unsigned char*)\"jukcy\", {209, 148, 0}},\n{(unsigned char*)\"kappa\", {206, 186, 0}},\n{(unsigned char*)\"kappav\", {207, 176, 0}},\n{(unsigned char*)\"kcedil\", {196, 183, 0}},\n{(unsigned char*)\"kcy\", {208, 186, 0}},\n{(unsigned char*)\"kfr\", {240, 157, 148, 168, 0}},\n{(unsigned char*)\"kgreen\", {196, 184, 0}},\n{(unsigned char*)\"khcy\", {209, 133, 0}},\n{(unsigned char*)\"kjcy\", {209, 156, 0}},\n{(unsigned char*)\"kopf\", {240, 157, 149, 156, 0}},\n{(unsigned char*)\"kscr\", {240, 157, 147, 128, 0}},\n{(unsigned char*)\"lAarr\", {226, 135, 154, 0}},\n{(unsigned char*)\"lArr\", {226, 135, 144, 0}},\n{(unsigned char*)\"lAtail\", {226, 164, 155, 0}},\n{(unsigned char*)\"lBarr\", {226, 164, 142, 0}},\n{(unsigned char*)\"lE\", {226, 137, 166, 0}},\n{(unsigned char*)\"lEg\", {226, 170, 139, 0}},\n{(unsigned char*)\"lHar\", {226, 165, 162, 0}},\n{(unsigned char*)\"lacute\", {196, 186, 0}},\n{(unsigned char*)\"laemptyv\", {226, 166, 180, 0}},\n{(unsigned char*)\"lagran\", {226, 132, 146, 0}},\n{(unsigned char*)\"lambda\", {206, 187, 0}},\n{(unsigned char*)\"lang\", {226, 159, 168, 0}},\n{(unsigned char*)\"langd\", {226, 166, 145, 0}},\n{(unsigned char*)\"langle\", {226, 159, 168, 0}},\n{(unsigned char*)\"lap\", {226, 170, 133, 0}},\n{(unsigned char*)\"laquo\", {194, 171, 0}},\n{(unsigned char*)\"larr\", {226, 134, 144, 0}},\n{(unsigned char*)\"larrb\", {226, 135, 164, 0}},\n{(unsigned char*)\"larrbfs\", {226, 164, 159, 0}},\n{(unsigned char*)\"larrfs\", {226, 164, 157, 0}},\n{(unsigned char*)\"larrhk\", {226, 134, 169, 0}},\n{(unsigned char*)\"larrlp\", {226, 134, 171, 0}},\n{(unsigned char*)\"larrpl\", {226, 164, 185, 0}},\n{(unsigned char*)\"larrsim\", {226, 165, 179, 0}},\n{(unsigned char*)\"larrtl\", {226, 134, 162, 0}},\n{(unsigned char*)\"lat\", {226, 170, 171, 0}},\n{(unsigned char*)\"latail\", {226, 164, 153, 0}},\n{(unsigned char*)\"late\", {226, 170, 173, 0}},\n{(unsigned char*)\"lates\", {226, 170, 173, 239, 184, 128, 0}},\n{(unsigned char*)\"lbarr\", {226, 164, 140, 0}},\n{(unsigned char*)\"lbbrk\", {226, 157, 178, 0}},\n{(unsigned char*)\"lbrace\", {123, 0}},\n{(unsigned char*)\"lbrack\", {91, 0}},\n{(unsigned char*)\"lbrke\", {226, 166, 139, 0}},\n{(unsigned char*)\"lbrksld\", {226, 166, 143, 0}},\n{(unsigned char*)\"lbrkslu\", {226, 166, 141, 0}},\n{(unsigned char*)\"lcaron\", {196, 190, 0}},\n{(unsigned char*)\"lcedil\", {196, 188, 0}},\n{(unsigned char*)\"lceil\", {226, 140, 136, 0}},\n{(unsigned char*)\"lcub\", {123, 0}},\n{(unsigned char*)\"lcy\", {208, 187, 0}},\n{(unsigned char*)\"ldca\", {226, 164, 182, 0}},\n{(unsigned char*)\"ldquo\", {226, 128, 156, 0}},\n{(unsigned char*)\"ldquor\", {226, 128, 158, 0}},\n{(unsigned char*)\"ldrdhar\", {226, 165, 167, 0}},\n{(unsigned char*)\"ldrushar\", {226, 165, 139, 0}},\n{(unsigned char*)\"ldsh\", {226, 134, 178, 0}},\n{(unsigned char*)\"le\", {226, 137, 164, 0}},\n{(unsigned char*)\"leftarrow\", {226, 134, 144, 0}},\n{(unsigned char*)\"leftarrowtail\", {226, 134, 162, 0}},\n{(unsigned char*)\"leftharpoondown\", {226, 134, 189, 0}},\n{(unsigned char*)\"leftharpoonup\", {226, 134, 188, 0}},\n{(unsigned char*)\"leftleftarrows\", {226, 135, 135, 0}},\n{(unsigned char*)\"leftrightarrow\", {226, 134, 148, 0}},\n{(unsigned char*)\"leftrightarrows\", {226, 135, 134, 0}},\n{(unsigned char*)\"leftrightharpoons\", {226, 135, 139, 0}},\n{(unsigned char*)\"leftrightsquigarrow\", {226, 134, 173, 0}},\n{(unsigned char*)\"leftthreetimes\", {226, 139, 139, 0}},\n{(unsigned char*)\"leg\", {226, 139, 154, 0}},\n{(unsigned char*)\"leq\", {226, 137, 164, 0}},\n{(unsigned char*)\"leqq\", {226, 137, 166, 0}},\n{(unsigned char*)\"leqslant\", {226, 169, 189, 0}},\n{(unsigned char*)\"les\", {226, 169, 189, 0}},\n{(unsigned char*)\"lescc\", {226, 170, 168, 0}},\n{(unsigned char*)\"lesdot\", {226, 169, 191, 0}},\n{(unsigned char*)\"lesdoto\", {226, 170, 129, 0}},\n{(unsigned char*)\"lesdotor\", {226, 170, 131, 0}},\n{(unsigned char*)\"lesg\", {226, 139, 154, 239, 184, 128, 0}},\n{(unsigned char*)\"lesges\", {226, 170, 147, 0}},\n{(unsigned char*)\"lessapprox\", {226, 170, 133, 0}},\n{(unsigned char*)\"lessdot\", {226, 139, 150, 0}},\n{(unsigned char*)\"lesseqgtr\", {226, 139, 154, 0}},\n{(unsigned char*)\"lesseqqgtr\", {226, 170, 139, 0}},\n{(unsigned char*)\"lessgtr\", {226, 137, 182, 0}},\n{(unsigned char*)\"lesssim\", {226, 137, 178, 0}},\n{(unsigned char*)\"lfisht\", {226, 165, 188, 0}},\n{(unsigned char*)\"lfloor\", {226, 140, 138, 0}},\n{(unsigned char*)\"lfr\", {240, 157, 148, 169, 0}},\n{(unsigned char*)\"lg\", {226, 137, 182, 0}},\n{(unsigned char*)\"lgE\", {226, 170, 145, 0}},\n{(unsigned char*)\"lhard\", {226, 134, 189, 0}},\n{(unsigned char*)\"lharu\", {226, 134, 188, 0}},\n{(unsigned char*)\"lharul\", {226, 165, 170, 0}},\n{(unsigned char*)\"lhblk\", {226, 150, 132, 0}},\n{(unsigned char*)\"ljcy\", {209, 153, 0}},\n{(unsigned char*)\"ll\", {226, 137, 170, 0}},\n{(unsigned char*)\"llarr\", {226, 135, 135, 0}},\n{(unsigned char*)\"llcorner\", {226, 140, 158, 0}},\n{(unsigned char*)\"llhard\", {226, 165, 171, 0}},\n{(unsigned char*)\"lltri\", {226, 151, 186, 0}},\n{(unsigned char*)\"lmidot\", {197, 128, 0}},\n{(unsigned char*)\"lmoust\", {226, 142, 176, 0}},\n{(unsigned char*)\"lmoustache\", {226, 142, 176, 0}},\n{(unsigned char*)\"lnE\", {226, 137, 168, 0}},\n{(unsigned char*)\"lnap\", {226, 170, 137, 0}},\n{(unsigned char*)\"lnapprox\", {226, 170, 137, 0}},\n{(unsigned char*)\"lne\", {226, 170, 135, 0}},\n{(unsigned char*)\"lneq\", {226, 170, 135, 0}},\n{(unsigned char*)\"lneqq\", {226, 137, 168, 0}},\n{(unsigned char*)\"lnsim\", {226, 139, 166, 0}},\n{(unsigned char*)\"loang\", {226, 159, 172, 0}},\n{(unsigned char*)\"loarr\", {226, 135, 189, 0}},\n{(unsigned char*)\"lobrk\", {226, 159, 166, 0}},\n{(unsigned char*)\"longleftarrow\", {226, 159, 181, 0}},\n{(unsigned char*)\"longleftrightarrow\", {226, 159, 183, 0}},\n{(unsigned char*)\"longmapsto\", {226, 159, 188, 0}},\n{(unsigned char*)\"longrightarrow\", {226, 159, 182, 0}},\n{(unsigned char*)\"looparrowleft\", {226, 134, 171, 0}},\n{(unsigned char*)\"looparrowright\", {226, 134, 172, 0}},\n{(unsigned char*)\"lopar\", {226, 166, 133, 0}},\n{(unsigned char*)\"lopf\", {240, 157, 149, 157, 0}},\n{(unsigned char*)\"loplus\", {226, 168, 173, 0}},\n{(unsigned char*)\"lotimes\", {226, 168, 180, 0}},\n{(unsigned char*)\"lowast\", {226, 136, 151, 0}},\n{(unsigned char*)\"lowbar\", {95, 0}},\n{(unsigned char*)\"loz\", {226, 151, 138, 0}},\n{(unsigned char*)\"lozenge\", {226, 151, 138, 0}},\n{(unsigned char*)\"lozf\", {226, 167, 171, 0}},\n{(unsigned char*)\"lpar\", {40, 0}},\n{(unsigned char*)\"lparlt\", {226, 166, 147, 0}},\n{(unsigned char*)\"lrarr\", {226, 135, 134, 0}},\n{(unsigned char*)\"lrcorner\", {226, 140, 159, 0}},\n{(unsigned char*)\"lrhar\", {226, 135, 139, 0}},\n{(unsigned char*)\"lrhard\", {226, 165, 173, 0}},\n{(unsigned char*)\"lrm\", {226, 128, 142, 0}},\n{(unsigned char*)\"lrtri\", {226, 138, 191, 0}},\n{(unsigned char*)\"lsaquo\", {226, 128, 185, 0}},\n{(unsigned char*)\"lscr\", {240, 157, 147, 129, 0}},\n{(unsigned char*)\"lsh\", {226, 134, 176, 0}},\n{(unsigned char*)\"lsim\", {226, 137, 178, 0}},\n{(unsigned char*)\"lsime\", {226, 170, 141, 0}},\n{(unsigned char*)\"lsimg\", {226, 170, 143, 0}},\n{(unsigned char*)\"lsqb\", {91, 0}},\n{(unsigned char*)\"lsquo\", {226, 128, 152, 0}},\n{(unsigned char*)\"lsquor\", {226, 128, 154, 0}},\n{(unsigned char*)\"lstrok\", {197, 130, 0}},\n{(unsigned char*)\"lt\", {60, 0}},\n{(unsigned char*)\"ltcc\", {226, 170, 166, 0}},\n{(unsigned char*)\"ltcir\", {226, 169, 185, 0}},\n{(unsigned char*)\"ltdot\", {226, 139, 150, 0}},\n{(unsigned char*)\"lthree\", {226, 139, 139, 0}},\n{(unsigned char*)\"ltimes\", {226, 139, 137, 0}},\n{(unsigned char*)\"ltlarr\", {226, 165, 182, 0}},\n{(unsigned char*)\"ltquest\", {226, 169, 187, 0}},\n{(unsigned char*)\"ltrPar\", {226, 166, 150, 0}},\n{(unsigned char*)\"ltri\", {226, 151, 131, 0}},\n{(unsigned char*)\"ltrie\", {226, 138, 180, 0}},\n{(unsigned char*)\"ltrif\", {226, 151, 130, 0}},\n{(unsigned char*)\"lurdshar\", {226, 165, 138, 0}},\n{(unsigned char*)\"luruhar\", {226, 165, 166, 0}},\n{(unsigned char*)\"lvertneqq\", {226, 137, 168, 239, 184, 128, 0}},\n{(unsigned char*)\"lvnE\", {226, 137, 168, 239, 184, 128, 0}},\n{(unsigned char*)\"mDDot\", {226, 136, 186, 0}},\n{(unsigned char*)\"macr\", {194, 175, 0}},\n{(unsigned char*)\"male\", {226, 153, 130, 0}},\n{(unsigned char*)\"malt\", {226, 156, 160, 0}},\n{(unsigned char*)\"maltese\", {226, 156, 160, 0}},\n{(unsigned char*)\"map\", {226, 134, 166, 0}},\n{(unsigned char*)\"mapsto\", {226, 134, 166, 0}},\n{(unsigned char*)\"mapstodown\", {226, 134, 167, 0}},\n{(unsigned char*)\"mapstoleft\", {226, 134, 164, 0}},\n{(unsigned char*)\"mapstoup\", {226, 134, 165, 0}},\n{(unsigned char*)\"marker\", {226, 150, 174, 0}},\n{(unsigned char*)\"mcomma\", {226, 168, 169, 0}},\n{(unsigned char*)\"mcy\", {208, 188, 0}},\n{(unsigned char*)\"mdash\", {226, 128, 148, 0}},\n{(unsigned char*)\"measuredangle\", {226, 136, 161, 0}},\n{(unsigned char*)\"mfr\", {240, 157, 148, 170, 0}},\n{(unsigned char*)\"mho\", {226, 132, 167, 0}},\n{(unsigned char*)\"micro\", {194, 181, 0}},\n{(unsigned char*)\"mid\", {226, 136, 163, 0}},\n{(unsigned char*)\"midast\", {42, 0}},\n{(unsigned char*)\"midcir\", {226, 171, 176, 0}},\n{(unsigned char*)\"middot\", {194, 183, 0}},\n{(unsigned char*)\"minus\", {226, 136, 146, 0}},\n{(unsigned char*)\"minusb\", {226, 138, 159, 0}},\n{(unsigned char*)\"minusd\", {226, 136, 184, 0}},\n{(unsigned char*)\"minusdu\", {226, 168, 170, 0}},\n{(unsigned char*)\"mlcp\", {226, 171, 155, 0}},\n{(unsigned char*)\"mldr\", {226, 128, 166, 0}},\n{(unsigned char*)\"mnplus\", {226, 136, 147, 0}},\n{(unsigned char*)\"models\", {226, 138, 167, 0}},\n{(unsigned char*)\"mopf\", {240, 157, 149, 158, 0}},\n{(unsigned char*)\"mp\", {226, 136, 147, 0}},\n{(unsigned char*)\"mscr\", {240, 157, 147, 130, 0}},\n{(unsigned char*)\"mstpos\", {226, 136, 190, 0}},\n{(unsigned char*)\"mu\", {206, 188, 0}},\n{(unsigned char*)\"multimap\", {226, 138, 184, 0}},\n{(unsigned char*)\"mumap\", {226, 138, 184, 0}},\n{(unsigned char*)\"nGg\", {226, 139, 153, 204, 184, 0}},\n{(unsigned char*)\"nGt\", {226, 137, 171, 226, 131, 146, 0}},\n{(unsigned char*)\"nGtv\", {226, 137, 171, 204, 184, 0}},\n{(unsigned char*)\"nLeftarrow\", {226, 135, 141, 0}},\n{(unsigned char*)\"nLeftrightarrow\", {226, 135, 142, 0}},\n{(unsigned char*)\"nLl\", {226, 139, 152, 204, 184, 0}},\n{(unsigned char*)\"nLt\", {226, 137, 170, 226, 131, 146, 0}},\n{(unsigned char*)\"nLtv\", {226, 137, 170, 204, 184, 0}},\n{(unsigned char*)\"nRightarrow\", {226, 135, 143, 0}},\n{(unsigned char*)\"nVDash\", {226, 138, 175, 0}},\n{(unsigned char*)\"nVdash\", {226, 138, 174, 0}},\n{(unsigned char*)\"nabla\", {226, 136, 135, 0}},\n{(unsigned char*)\"nacute\", {197, 132, 0}},\n{(unsigned char*)\"nang\", {226, 136, 160, 226, 131, 146, 0}},\n{(unsigned char*)\"nap\", {226, 137, 137, 0}},\n{(unsigned char*)\"napE\", {226, 169, 176, 204, 184, 0}},\n{(unsigned char*)\"napid\", {226, 137, 139, 204, 184, 0}},\n{(unsigned char*)\"napos\", {197, 137, 0}},\n{(unsigned char*)\"napprox\", {226, 137, 137, 0}},\n{(unsigned char*)\"natur\", {226, 153, 174, 0}},\n{(unsigned char*)\"natural\", {226, 153, 174, 0}},\n{(unsigned char*)\"naturals\", {226, 132, 149, 0}},\n{(unsigned char*)\"nbsp\", {194, 160, 0}},\n{(unsigned char*)\"nbump\", {226, 137, 142, 204, 184, 0}},\n{(unsigned char*)\"nbumpe\", {226, 137, 143, 204, 184, 0}},\n{(unsigned char*)\"ncap\", {226, 169, 131, 0}},\n{(unsigned char*)\"ncaron\", {197, 136, 0}},\n{(unsigned char*)\"ncedil\", {197, 134, 0}},\n{(unsigned char*)\"ncong\", {226, 137, 135, 0}},\n{(unsigned char*)\"ncongdot\", {226, 169, 173, 204, 184, 0}},\n{(unsigned char*)\"ncup\", {226, 169, 130, 0}},\n{(unsigned char*)\"ncy\", {208, 189, 0}},\n{(unsigned char*)\"ndash\", {226, 128, 147, 0}},\n{(unsigned char*)\"ne\", {226, 137, 160, 0}},\n{(unsigned char*)\"neArr\", {226, 135, 151, 0}},\n{(unsigned char*)\"nearhk\", {226, 164, 164, 0}},\n{(unsigned char*)\"nearr\", {226, 134, 151, 0}},\n{(unsigned char*)\"nearrow\", {226, 134, 151, 0}},\n{(unsigned char*)\"nedot\", {226, 137, 144, 204, 184, 0}},\n{(unsigned char*)\"nequiv\", {226, 137, 162, 0}},\n{(unsigned char*)\"nesear\", {226, 164, 168, 0}},\n{(unsigned char*)\"nesim\", {226, 137, 130, 204, 184, 0}},\n{(unsigned char*)\"nexist\", {226, 136, 132, 0}},\n{(unsigned char*)\"nexists\", {226, 136, 132, 0}},\n{(unsigned char*)\"nfr\", {240, 157, 148, 171, 0}},\n{(unsigned char*)\"ngE\", {226, 137, 167, 204, 184, 0}},\n{(unsigned char*)\"nge\", {226, 137, 177, 0}},\n{(unsigned char*)\"ngeq\", {226, 137, 177, 0}},\n{(unsigned char*)\"ngeqq\", {226, 137, 167, 204, 184, 0}},\n{(unsigned char*)\"ngeqslant\", {226, 169, 190, 204, 184, 0}},\n{(unsigned char*)\"nges\", {226, 169, 190, 204, 184, 0}},\n{(unsigned char*)\"ngsim\", {226, 137, 181, 0}},\n{(unsigned char*)\"ngt\", {226, 137, 175, 0}},\n{(unsigned char*)\"ngtr\", {226, 137, 175, 0}},\n{(unsigned char*)\"nhArr\", {226, 135, 142, 0}},\n{(unsigned char*)\"nharr\", {226, 134, 174, 0}},\n{(unsigned char*)\"nhpar\", {226, 171, 178, 0}},\n{(unsigned char*)\"ni\", {226, 136, 139, 0}},\n{(unsigned char*)\"nis\", {226, 139, 188, 0}},\n{(unsigned char*)\"nisd\", {226, 139, 186, 0}},\n{(unsigned char*)\"niv\", {226, 136, 139, 0}},\n{(unsigned char*)\"njcy\", {209, 154, 0}},\n{(unsigned char*)\"nlArr\", {226, 135, 141, 0}},\n{(unsigned char*)\"nlE\", {226, 137, 166, 204, 184, 0}},\n{(unsigned char*)\"nlarr\", {226, 134, 154, 0}},\n{(unsigned char*)\"nldr\", {226, 128, 165, 0}},\n{(unsigned char*)\"nle\", {226, 137, 176, 0}},\n{(unsigned char*)\"nleftarrow\", {226, 134, 154, 0}},\n{(unsigned char*)\"nleftrightarrow\", {226, 134, 174, 0}},\n{(unsigned char*)\"nleq\", {226, 137, 176, 0}},\n{(unsigned char*)\"nleqq\", {226, 137, 166, 204, 184, 0}},\n{(unsigned char*)\"nleqslant\", {226, 169, 189, 204, 184, 0}},\n{(unsigned char*)\"nles\", {226, 169, 189, 204, 184, 0}},\n{(unsigned char*)\"nless\", {226, 137, 174, 0}},\n{(unsigned char*)\"nlsim\", {226, 137, 180, 0}},\n{(unsigned char*)\"nlt\", {226, 137, 174, 0}},\n{(unsigned char*)\"nltri\", {226, 139, 170, 0}},\n{(unsigned char*)\"nltrie\", {226, 139, 172, 0}},\n{(unsigned char*)\"nmid\", {226, 136, 164, 0}},\n{(unsigned char*)\"nopf\", {240, 157, 149, 159, 0}},\n{(unsigned char*)\"not\", {194, 172, 0}},\n{(unsigned char*)\"notin\", {226, 136, 137, 0}},\n{(unsigned char*)\"notinE\", {226, 139, 185, 204, 184, 0}},\n{(unsigned char*)\"notindot\", {226, 139, 181, 204, 184, 0}},\n{(unsigned char*)\"notinva\", {226, 136, 137, 0}},\n{(unsigned char*)\"notinvb\", {226, 139, 183, 0}},\n{(unsigned char*)\"notinvc\", {226, 139, 182, 0}},\n{(unsigned char*)\"notni\", {226, 136, 140, 0}},\n{(unsigned char*)\"notniva\", {226, 136, 140, 0}},\n{(unsigned char*)\"notnivb\", {226, 139, 190, 0}},\n{(unsigned char*)\"notnivc\", {226, 139, 189, 0}},\n{(unsigned char*)\"npar\", {226, 136, 166, 0}},\n{(unsigned char*)\"nparallel\", {226, 136, 166, 0}},\n{(unsigned char*)\"nparsl\", {226, 171, 189, 226, 131, 165, 0}},\n{(unsigned char*)\"npart\", {226, 136, 130, 204, 184, 0}},\n{(unsigned char*)\"npolint\", {226, 168, 148, 0}},\n{(unsigned char*)\"npr\", {226, 138, 128, 0}},\n{(unsigned char*)\"nprcue\", {226, 139, 160, 0}},\n{(unsigned char*)\"npre\", {226, 170, 175, 204, 184, 0}},\n{(unsigned char*)\"nprec\", {226, 138, 128, 0}},\n{(unsigned char*)\"npreceq\", {226, 170, 175, 204, 184, 0}},\n{(unsigned char*)\"nrArr\", {226, 135, 143, 0}},\n{(unsigned char*)\"nrarr\", {226, 134, 155, 0}},\n{(unsigned char*)\"nrarrc\", {226, 164, 179, 204, 184, 0}},\n{(unsigned char*)\"nrarrw\", {226, 134, 157, 204, 184, 0}},\n{(unsigned char*)\"nrightarrow\", {226, 134, 155, 0}},\n{(unsigned char*)\"nrtri\", {226, 139, 171, 0}},\n{(unsigned char*)\"nrtrie\", {226, 139, 173, 0}},\n{(unsigned char*)\"nsc\", {226, 138, 129, 0}},\n{(unsigned char*)\"nsccue\", {226, 139, 161, 0}},\n{(unsigned char*)\"nsce\", {226, 170, 176, 204, 184, 0}},\n{(unsigned char*)\"nscr\", {240, 157, 147, 131, 0}},\n{(unsigned char*)\"nshortmid\", {226, 136, 164, 0}},\n{(unsigned char*)\"nshortparallel\", {226, 136, 166, 0}},\n{(unsigned char*)\"nsim\", {226, 137, 129, 0}},\n{(unsigned char*)\"nsime\", {226, 137, 132, 0}},\n{(unsigned char*)\"nsimeq\", {226, 137, 132, 0}},\n{(unsigned char*)\"nsmid\", {226, 136, 164, 0}},\n{(unsigned char*)\"nspar\", {226, 136, 166, 0}},\n{(unsigned char*)\"nsqsube\", {226, 139, 162, 0}},\n{(unsigned char*)\"nsqsupe\", {226, 139, 163, 0}},\n{(unsigned char*)\"nsub\", {226, 138, 132, 0}},\n{(unsigned char*)\"nsubE\", {226, 171, 133, 204, 184, 0}},\n{(unsigned char*)\"nsube\", {226, 138, 136, 0}},\n{(unsigned char*)\"nsubset\", {226, 138, 130, 226, 131, 146, 0}},\n{(unsigned char*)\"nsubseteq\", {226, 138, 136, 0}},\n{(unsigned char*)\"nsubseteqq\", {226, 171, 133, 204, 184, 0}},\n{(unsigned char*)\"nsucc\", {226, 138, 129, 0}},\n{(unsigned char*)\"nsucceq\", {226, 170, 176, 204, 184, 0}},\n{(unsigned char*)\"nsup\", {226, 138, 133, 0}},\n{(unsigned char*)\"nsupE\", {226, 171, 134, 204, 184, 0}},\n{(unsigned char*)\"nsupe\", {226, 138, 137, 0}},\n{(unsigned char*)\"nsupset\", {226, 138, 131, 226, 131, 146, 0}},\n{(unsigned char*)\"nsupseteq\", {226, 138, 137, 0}},\n{(unsigned char*)\"nsupseteqq\", {226, 171, 134, 204, 184, 0}},\n{(unsigned char*)\"ntgl\", {226, 137, 185, 0}},\n{(unsigned char*)\"ntilde\", {195, 177, 0}},\n{(unsigned char*)\"ntlg\", {226, 137, 184, 0}},\n{(unsigned char*)\"ntriangleleft\", {226, 139, 170, 0}},\n{(unsigned char*)\"ntrianglelefteq\", {226, 139, 172, 0}},\n{(unsigned char*)\"ntriangleright\", {226, 139, 171, 0}},\n{(unsigned char*)\"ntrianglerighteq\", {226, 139, 173, 0}},\n{(unsigned char*)\"nu\", {206, 189, 0}},\n{(unsigned char*)\"num\", {35, 0}},\n{(unsigned char*)\"numero\", {226, 132, 150, 0}},\n{(unsigned char*)\"numsp\", {226, 128, 135, 0}},\n{(unsigned char*)\"nvDash\", {226, 138, 173, 0}},\n{(unsigned char*)\"nvHarr\", {226, 164, 132, 0}},\n{(unsigned char*)\"nvap\", {226, 137, 141, 226, 131, 146, 0}},\n{(unsigned char*)\"nvdash\", {226, 138, 172, 0}},\n{(unsigned char*)\"nvge\", {226, 137, 165, 226, 131, 146, 0}},\n{(unsigned char*)\"nvgt\", {62, 226, 131, 146, 0}},\n{(unsigned char*)\"nvinfin\", {226, 167, 158, 0}},\n{(unsigned char*)\"nvlArr\", {226, 164, 130, 0}},\n{(unsigned char*)\"nvle\", {226, 137, 164, 226, 131, 146, 0}},\n{(unsigned char*)\"nvlt\", {60, 226, 131, 146, 0}},\n{(unsigned char*)\"nvltrie\", {226, 138, 180, 226, 131, 146, 0}},\n{(unsigned char*)\"nvrArr\", {226, 164, 131, 0}},\n{(unsigned char*)\"nvrtrie\", {226, 138, 181, 226, 131, 146, 0}},\n{(unsigned char*)\"nvsim\", {226, 136, 188, 226, 131, 146, 0}},\n{(unsigned char*)\"nwArr\", {226, 135, 150, 0}},\n{(unsigned char*)\"nwarhk\", {226, 164, 163, 0}},\n{(unsigned char*)\"nwarr\", {226, 134, 150, 0}},\n{(unsigned char*)\"nwarrow\", {226, 134, 150, 0}},\n{(unsigned char*)\"nwnear\", {226, 164, 167, 0}},\n{(unsigned char*)\"oS\", {226, 147, 136, 0}},\n{(unsigned char*)\"oacute\", {195, 179, 0}},\n{(unsigned char*)\"oast\", {226, 138, 155, 0}},\n{(unsigned char*)\"ocir\", {226, 138, 154, 0}},\n{(unsigned char*)\"ocirc\", {195, 180, 0}},\n{(unsigned char*)\"ocy\", {208, 190, 0}},\n{(unsigned char*)\"odash\", {226, 138, 157, 0}},\n{(unsigned char*)\"odblac\", {197, 145, 0}},\n{(unsigned char*)\"odiv\", {226, 168, 184, 0}},\n{(unsigned char*)\"odot\", {226, 138, 153, 0}},\n{(unsigned char*)\"odsold\", {226, 166, 188, 0}},\n{(unsigned char*)\"oelig\", {197, 147, 0}},\n{(unsigned char*)\"ofcir\", {226, 166, 191, 0}},\n{(unsigned char*)\"ofr\", {240, 157, 148, 172, 0}},\n{(unsigned char*)\"ogon\", {203, 155, 0}},\n{(unsigned char*)\"ograve\", {195, 178, 0}},\n{(unsigned char*)\"ogt\", {226, 167, 129, 0}},\n{(unsigned char*)\"ohbar\", {226, 166, 181, 0}},\n{(unsigned char*)\"ohm\", {206, 169, 0}},\n{(unsigned char*)\"oint\", {226, 136, 174, 0}},\n{(unsigned char*)\"olarr\", {226, 134, 186, 0}},\n{(unsigned char*)\"olcir\", {226, 166, 190, 0}},\n{(unsigned char*)\"olcross\", {226, 166, 187, 0}},\n{(unsigned char*)\"oline\", {226, 128, 190, 0}},\n{(unsigned char*)\"olt\", {226, 167, 128, 0}},\n{(unsigned char*)\"omacr\", {197, 141, 0}},\n{(unsigned char*)\"omega\", {207, 137, 0}},\n{(unsigned char*)\"omicron\", {206, 191, 0}},\n{(unsigned char*)\"omid\", {226, 166, 182, 0}},\n{(unsigned char*)\"ominus\", {226, 138, 150, 0}},\n{(unsigned char*)\"oopf\", {240, 157, 149, 160, 0}},\n{(unsigned char*)\"opar\", {226, 166, 183, 0}},\n{(unsigned char*)\"operp\", {226, 166, 185, 0}},\n{(unsigned char*)\"oplus\", {226, 138, 149, 0}},\n{(unsigned char*)\"or\", {226, 136, 168, 0}},\n{(unsigned char*)\"orarr\", {226, 134, 187, 0}},\n{(unsigned char*)\"ord\", {226, 169, 157, 0}},\n{(unsigned char*)\"order\", {226, 132, 180, 0}},\n{(unsigned char*)\"orderof\", {226, 132, 180, 0}},\n{(unsigned char*)\"ordf\", {194, 170, 0}},\n{(unsigned char*)\"ordm\", {194, 186, 0}},\n{(unsigned char*)\"origof\", {226, 138, 182, 0}},\n{(unsigned char*)\"oror\", {226, 169, 150, 0}},\n{(unsigned char*)\"orslope\", {226, 169, 151, 0}},\n{(unsigned char*)\"orv\", {226, 169, 155, 0}},\n{(unsigned char*)\"oscr\", {226, 132, 180, 0}},\n{(unsigned char*)\"oslash\", {195, 184, 0}},\n{(unsigned char*)\"osol\", {226, 138, 152, 0}},\n{(unsigned char*)\"otilde\", {195, 181, 0}},\n{(unsigned char*)\"otimes\", {226, 138, 151, 0}},\n{(unsigned char*)\"otimesas\", {226, 168, 182, 0}},\n{(unsigned char*)\"ouml\", {195, 182, 0}},\n{(unsigned char*)\"ovbar\", {226, 140, 189, 0}},\n{(unsigned char*)\"par\", {226, 136, 165, 0}},\n{(unsigned char*)\"para\", {194, 182, 0}},\n{(unsigned char*)\"parallel\", {226, 136, 165, 0}},\n{(unsigned char*)\"parsim\", {226, 171, 179, 0}},\n{(unsigned char*)\"parsl\", {226, 171, 189, 0}},\n{(unsigned char*)\"part\", {226, 136, 130, 0}},\n{(unsigned char*)\"pcy\", {208, 191, 0}},\n{(unsigned char*)\"percnt\", {37, 0}},\n{(unsigned char*)\"period\", {46, 0}},\n{(unsigned char*)\"permil\", {226, 128, 176, 0}},\n{(unsigned char*)\"perp\", {226, 138, 165, 0}},\n{(unsigned char*)\"pertenk\", {226, 128, 177, 0}},\n{(unsigned char*)\"pfr\", {240, 157, 148, 173, 0}},\n{(unsigned char*)\"phi\", {207, 134, 0}},\n{(unsigned char*)\"phiv\", {207, 149, 0}},\n{(unsigned char*)\"phmmat\", {226, 132, 179, 0}},\n{(unsigned char*)\"phone\", {226, 152, 142, 0}},\n{(unsigned char*)\"pi\", {207, 128, 0}},\n{(unsigned char*)\"pitchfork\", {226, 139, 148, 0}},\n{(unsigned char*)\"piv\", {207, 150, 0}},\n{(unsigned char*)\"planck\", {226, 132, 143, 0}},\n{(unsigned char*)\"planckh\", {226, 132, 142, 0}},\n{(unsigned char*)\"plankv\", {226, 132, 143, 0}},\n{(unsigned char*)\"plus\", {43, 0}},\n{(unsigned char*)\"plusacir\", {226, 168, 163, 0}},\n{(unsigned char*)\"plusb\", {226, 138, 158, 0}},\n{(unsigned char*)\"pluscir\", {226, 168, 162, 0}},\n{(unsigned char*)\"plusdo\", {226, 136, 148, 0}},\n{(unsigned char*)\"plusdu\", {226, 168, 165, 0}},\n{(unsigned char*)\"pluse\", {226, 169, 178, 0}},\n{(unsigned char*)\"plusmn\", {194, 177, 0}},\n{(unsigned char*)\"plussim\", {226, 168, 166, 0}},\n{(unsigned char*)\"plustwo\", {226, 168, 167, 0}},\n{(unsigned char*)\"pm\", {194, 177, 0}},\n{(unsigned char*)\"pointint\", {226, 168, 149, 0}},\n{(unsigned char*)\"popf\", {240, 157, 149, 161, 0}},\n{(unsigned char*)\"pound\", {194, 163, 0}},\n{(unsigned char*)\"pr\", {226, 137, 186, 0}},\n{(unsigned char*)\"prE\", {226, 170, 179, 0}},\n{(unsigned char*)\"prap\", {226, 170, 183, 0}},\n{(unsigned char*)\"prcue\", {226, 137, 188, 0}},\n{(unsigned char*)\"pre\", {226, 170, 175, 0}},\n{(unsigned char*)\"prec\", {226, 137, 186, 0}},\n{(unsigned char*)\"precapprox\", {226, 170, 183, 0}},\n{(unsigned char*)\"preccurlyeq\", {226, 137, 188, 0}},\n{(unsigned char*)\"preceq\", {226, 170, 175, 0}},\n{(unsigned char*)\"precnapprox\", {226, 170, 185, 0}},\n{(unsigned char*)\"precneqq\", {226, 170, 181, 0}},\n{(unsigned char*)\"precnsim\", {226, 139, 168, 0}},\n{(unsigned char*)\"precsim\", {226, 137, 190, 0}},\n{(unsigned char*)\"prime\", {226, 128, 178, 0}},\n{(unsigned char*)\"primes\", {226, 132, 153, 0}},\n{(unsigned char*)\"prnE\", {226, 170, 181, 0}},\n{(unsigned char*)\"prnap\", {226, 170, 185, 0}},\n{(unsigned char*)\"prnsim\", {226, 139, 168, 0}},\n{(unsigned char*)\"prod\", {226, 136, 143, 0}},\n{(unsigned char*)\"profalar\", {226, 140, 174, 0}},\n{(unsigned char*)\"profline\", {226, 140, 146, 0}},\n{(unsigned char*)\"profsurf\", {226, 140, 147, 0}},\n{(unsigned char*)\"prop\", {226, 136, 157, 0}},\n{(unsigned char*)\"propto\", {226, 136, 157, 0}},\n{(unsigned char*)\"prsim\", {226, 137, 190, 0}},\n{(unsigned char*)\"prurel\", {226, 138, 176, 0}},\n{(unsigned char*)\"pscr\", {240, 157, 147, 133, 0}},\n{(unsigned char*)\"psi\", {207, 136, 0}},\n{(unsigned char*)\"puncsp\", {226, 128, 136, 0}},\n{(unsigned char*)\"qfr\", {240, 157, 148, 174, 0}},\n{(unsigned char*)\"qint\", {226, 168, 140, 0}},\n{(unsigned char*)\"qopf\", {240, 157, 149, 162, 0}},\n{(unsigned char*)\"qprime\", {226, 129, 151, 0}},\n{(unsigned char*)\"qscr\", {240, 157, 147, 134, 0}},\n{(unsigned char*)\"quaternions\", {226, 132, 141, 0}},\n{(unsigned char*)\"quatint\", {226, 168, 150, 0}},\n{(unsigned char*)\"quest\", {63, 0}},\n{(unsigned char*)\"questeq\", {226, 137, 159, 0}},\n{(unsigned char*)\"quot\", {34, 0}},\n{(unsigned char*)\"rAarr\", {226, 135, 155, 0}},\n{(unsigned char*)\"rArr\", {226, 135, 146, 0}},\n{(unsigned char*)\"rAtail\", {226, 164, 156, 0}},\n{(unsigned char*)\"rBarr\", {226, 164, 143, 0}},\n{(unsigned char*)\"rHar\", {226, 165, 164, 0}},\n{(unsigned char*)\"race\", {226, 136, 189, 204, 177, 0}},\n{(unsigned char*)\"racute\", {197, 149, 0}},\n{(unsigned char*)\"radic\", {226, 136, 154, 0}},\n{(unsigned char*)\"raemptyv\", {226, 166, 179, 0}},\n{(unsigned char*)\"rang\", {226, 159, 169, 0}},\n{(unsigned char*)\"rangd\", {226, 166, 146, 0}},\n{(unsigned char*)\"range\", {226, 166, 165, 0}},\n{(unsigned char*)\"rangle\", {226, 159, 169, 0}},\n{(unsigned char*)\"raquo\", {194, 187, 0}},\n{(unsigned char*)\"rarr\", {226, 134, 146, 0}},\n{(unsigned char*)\"rarrap\", {226, 165, 181, 0}},\n{(unsigned char*)\"rarrb\", {226, 135, 165, 0}},\n{(unsigned char*)\"rarrbfs\", {226, 164, 160, 0}},\n{(unsigned char*)\"rarrc\", {226, 164, 179, 0}},\n{(unsigned char*)\"rarrfs\", {226, 164, 158, 0}},\n{(unsigned char*)\"rarrhk\", {226, 134, 170, 0}},\n{(unsigned char*)\"rarrlp\", {226, 134, 172, 0}},\n{(unsigned char*)\"rarrpl\", {226, 165, 133, 0}},\n{(unsigned char*)\"rarrsim\", {226, 165, 180, 0}},\n{(unsigned char*)\"rarrtl\", {226, 134, 163, 0}},\n{(unsigned char*)\"rarrw\", {226, 134, 157, 0}},\n{(unsigned char*)\"ratail\", {226, 164, 154, 0}},\n{(unsigned char*)\"ratio\", {226, 136, 182, 0}},\n{(unsigned char*)\"rationals\", {226, 132, 154, 0}},\n{(unsigned char*)\"rbarr\", {226, 164, 141, 0}},\n{(unsigned char*)\"rbbrk\", {226, 157, 179, 0}},\n{(unsigned char*)\"rbrace\", {125, 0}},\n{(unsigned char*)\"rbrack\", {93, 0}},\n{(unsigned char*)\"rbrke\", {226, 166, 140, 0}},\n{(unsigned char*)\"rbrksld\", {226, 166, 142, 0}},\n{(unsigned char*)\"rbrkslu\", {226, 166, 144, 0}},\n{(unsigned char*)\"rcaron\", {197, 153, 0}},\n{(unsigned char*)\"rcedil\", {197, 151, 0}},\n{(unsigned char*)\"rceil\", {226, 140, 137, 0}},\n{(unsigned char*)\"rcub\", {125, 0}},\n{(unsigned char*)\"rcy\", {209, 128, 0}},\n{(unsigned char*)\"rdca\", {226, 164, 183, 0}},\n{(unsigned char*)\"rdldhar\", {226, 165, 169, 0}},\n{(unsigned char*)\"rdquo\", {226, 128, 157, 0}},\n{(unsigned char*)\"rdquor\", {226, 128, 157, 0}},\n{(unsigned char*)\"rdsh\", {226, 134, 179, 0}},\n{(unsigned char*)\"real\", {226, 132, 156, 0}},\n{(unsigned char*)\"realine\", {226, 132, 155, 0}},\n{(unsigned char*)\"realpart\", {226, 132, 156, 0}},\n{(unsigned char*)\"reals\", {226, 132, 157, 0}},\n{(unsigned char*)\"rect\", {226, 150, 173, 0}},\n{(unsigned char*)\"reg\", {194, 174, 0}},\n{(unsigned char*)\"rfisht\", {226, 165, 189, 0}},\n{(unsigned char*)\"rfloor\", {226, 140, 139, 0}},\n{(unsigned char*)\"rfr\", {240, 157, 148, 175, 0}},\n{(unsigned char*)\"rhard\", {226, 135, 129, 0}},\n{(unsigned char*)\"rharu\", {226, 135, 128, 0}},\n{(unsigned char*)\"rharul\", {226, 165, 172, 0}},\n{(unsigned char*)\"rho\", {207, 129, 0}},\n{(unsigned char*)\"rhov\", {207, 177, 0}},\n{(unsigned char*)\"rightarrow\", {226, 134, 146, 0}},\n{(unsigned char*)\"rightarrowtail\", {226, 134, 163, 0}},\n{(unsigned char*)\"rightharpoondown\", {226, 135, 129, 0}},\n{(unsigned char*)\"rightharpoonup\", {226, 135, 128, 0}},\n{(unsigned char*)\"rightleftarrows\", {226, 135, 132, 0}},\n{(unsigned char*)\"rightleftharpoons\", {226, 135, 140, 0}},\n{(unsigned char*)\"rightrightarrows\", {226, 135, 137, 0}},\n{(unsigned char*)\"rightsquigarrow\", {226, 134, 157, 0}},\n{(unsigned char*)\"rightthreetimes\", {226, 139, 140, 0}},\n{(unsigned char*)\"ring\", {203, 154, 0}},\n{(unsigned char*)\"risingdotseq\", {226, 137, 147, 0}},\n{(unsigned char*)\"rlarr\", {226, 135, 132, 0}},\n{(unsigned char*)\"rlhar\", {226, 135, 140, 0}},\n{(unsigned char*)\"rlm\", {226, 128, 143, 0}},\n{(unsigned char*)\"rmoust\", {226, 142, 177, 0}},\n{(unsigned char*)\"rmoustache\", {226, 142, 177, 0}},\n{(unsigned char*)\"rnmid\", {226, 171, 174, 0}},\n{(unsigned char*)\"roang\", {226, 159, 173, 0}},\n{(unsigned char*)\"roarr\", {226, 135, 190, 0}},\n{(unsigned char*)\"robrk\", {226, 159, 167, 0}},\n{(unsigned char*)\"ropar\", {226, 166, 134, 0}},\n{(unsigned char*)\"ropf\", {240, 157, 149, 163, 0}},\n{(unsigned char*)\"roplus\", {226, 168, 174, 0}},\n{(unsigned char*)\"rotimes\", {226, 168, 181, 0}},\n{(unsigned char*)\"rpar\", {41, 0}},\n{(unsigned char*)\"rpargt\", {226, 166, 148, 0}},\n{(unsigned char*)\"rppolint\", {226, 168, 146, 0}},\n{(unsigned char*)\"rrarr\", {226, 135, 137, 0}},\n{(unsigned char*)\"rsaquo\", {226, 128, 186, 0}},\n{(unsigned char*)\"rscr\", {240, 157, 147, 135, 0}},\n{(unsigned char*)\"rsh\", {226, 134, 177, 0}},\n{(unsigned char*)\"rsqb\", {93, 0}},\n{(unsigned char*)\"rsquo\", {226, 128, 153, 0}},\n{(unsigned char*)\"rsquor\", {226, 128, 153, 0}},\n{(unsigned char*)\"rthree\", {226, 139, 140, 0}},\n{(unsigned char*)\"rtimes\", {226, 139, 138, 0}},\n{(unsigned char*)\"rtri\", {226, 150, 185, 0}},\n{(unsigned char*)\"rtrie\", {226, 138, 181, 0}},\n{(unsigned char*)\"rtrif\", {226, 150, 184, 0}},\n{(unsigned char*)\"rtriltri\", {226, 167, 142, 0}},\n{(unsigned char*)\"ruluhar\", {226, 165, 168, 0}},\n{(unsigned char*)\"rx\", {226, 132, 158, 0}},\n{(unsigned char*)\"sacute\", {197, 155, 0}},\n{(unsigned char*)\"sbquo\", {226, 128, 154, 0}},\n{(unsigned char*)\"sc\", {226, 137, 187, 0}},\n{(unsigned char*)\"scE\", {226, 170, 180, 0}},\n{(unsigned char*)\"scap\", {226, 170, 184, 0}},\n{(unsigned char*)\"scaron\", {197, 161, 0}},\n{(unsigned char*)\"sccue\", {226, 137, 189, 0}},\n{(unsigned char*)\"sce\", {226, 170, 176, 0}},\n{(unsigned char*)\"scedil\", {197, 159, 0}},\n{(unsigned char*)\"scirc\", {197, 157, 0}},\n{(unsigned char*)\"scnE\", {226, 170, 182, 0}},\n{(unsigned char*)\"scnap\", {226, 170, 186, 0}},\n{(unsigned char*)\"scnsim\", {226, 139, 169, 0}},\n{(unsigned char*)\"scpolint\", {226, 168, 147, 0}},\n{(unsigned char*)\"scsim\", {226, 137, 191, 0}},\n{(unsigned char*)\"scy\", {209, 129, 0}},\n{(unsigned char*)\"sdot\", {226, 139, 133, 0}},\n{(unsigned char*)\"sdotb\", {226, 138, 161, 0}},\n{(unsigned char*)\"sdote\", {226, 169, 166, 0}},\n{(unsigned char*)\"seArr\", {226, 135, 152, 0}},\n{(unsigned char*)\"searhk\", {226, 164, 165, 0}},\n{(unsigned char*)\"searr\", {226, 134, 152, 0}},\n{(unsigned char*)\"searrow\", {226, 134, 152, 0}},\n{(unsigned char*)\"sect\", {194, 167, 0}},\n{(unsigned char*)\"semi\", {59, 0}},\n{(unsigned char*)\"seswar\", {226, 164, 169, 0}},\n{(unsigned char*)\"setminus\", {226, 136, 150, 0}},\n{(unsigned char*)\"setmn\", {226, 136, 150, 0}},\n{(unsigned char*)\"sext\", {226, 156, 182, 0}},\n{(unsigned char*)\"sfr\", {240, 157, 148, 176, 0}},\n{(unsigned char*)\"sfrown\", {226, 140, 162, 0}},\n{(unsigned char*)\"sharp\", {226, 153, 175, 0}},\n{(unsigned char*)\"shchcy\", {209, 137, 0}},\n{(unsigned char*)\"shcy\", {209, 136, 0}},\n{(unsigned char*)\"shortmid\", {226, 136, 163, 0}},\n{(unsigned char*)\"shortparallel\", {226, 136, 165, 0}},\n{(unsigned char*)\"shy\", {194, 173, 0}},\n{(unsigned char*)\"sigma\", {207, 131, 0}},\n{(unsigned char*)\"sigmaf\", {207, 130, 0}},\n{(unsigned char*)\"sigmav\", {207, 130, 0}},\n{(unsigned char*)\"sim\", {226, 136, 188, 0}},\n{(unsigned char*)\"simdot\", {226, 169, 170, 0}},\n{(unsigned char*)\"sime\", {226, 137, 131, 0}},\n{(unsigned char*)\"simeq\", {226, 137, 131, 0}},\n{(unsigned char*)\"simg\", {226, 170, 158, 0}},\n{(unsigned char*)\"simgE\", {226, 170, 160, 0}},\n{(unsigned char*)\"siml\", {226, 170, 157, 0}},\n{(unsigned char*)\"simlE\", {226, 170, 159, 0}},\n{(unsigned char*)\"simne\", {226, 137, 134, 0}},\n{(unsigned char*)\"simplus\", {226, 168, 164, 0}},\n{(unsigned char*)\"simrarr\", {226, 165, 178, 0}},\n{(unsigned char*)\"slarr\", {226, 134, 144, 0}},\n{(unsigned char*)\"smallsetminus\", {226, 136, 150, 0}},\n{(unsigned char*)\"smashp\", {226, 168, 179, 0}},\n{(unsigned char*)\"smeparsl\", {226, 167, 164, 0}},\n{(unsigned char*)\"smid\", {226, 136, 163, 0}},\n{(unsigned char*)\"smile\", {226, 140, 163, 0}},\n{(unsigned char*)\"smt\", {226, 170, 170, 0}},\n{(unsigned char*)\"smte\", {226, 170, 172, 0}},\n{(unsigned char*)\"smtes\", {226, 170, 172, 239, 184, 128, 0}},\n{(unsigned char*)\"softcy\", {209, 140, 0}},\n{(unsigned char*)\"sol\", {47, 0}},\n{(unsigned char*)\"solb\", {226, 167, 132, 0}},\n{(unsigned char*)\"solbar\", {226, 140, 191, 0}},\n{(unsigned char*)\"sopf\", {240, 157, 149, 164, 0}},\n{(unsigned char*)\"spades\", {226, 153, 160, 0}},\n{(unsigned char*)\"spadesuit\", {226, 153, 160, 0}},\n{(unsigned char*)\"spar\", {226, 136, 165, 0}},\n{(unsigned char*)\"sqcap\", {226, 138, 147, 0}},\n{(unsigned char*)\"sqcaps\", {226, 138, 147, 239, 184, 128, 0}},\n{(unsigned char*)\"sqcup\", {226, 138, 148, 0}},\n{(unsigned char*)\"sqcups\", {226, 138, 148, 239, 184, 128, 0}},\n{(unsigned char*)\"sqsub\", {226, 138, 143, 0}},\n{(unsigned char*)\"sqsube\", {226, 138, 145, 0}},\n{(unsigned char*)\"sqsubset\", {226, 138, 143, 0}},\n{(unsigned char*)\"sqsubseteq\", {226, 138, 145, 0}},\n{(unsigned char*)\"sqsup\", {226, 138, 144, 0}},\n{(unsigned char*)\"sqsupe\", {226, 138, 146, 0}},\n{(unsigned char*)\"sqsupset\", {226, 138, 144, 0}},\n{(unsigned char*)\"sqsupseteq\", {226, 138, 146, 0}},\n{(unsigned char*)\"squ\", {226, 150, 161, 0}},\n{(unsigned char*)\"square\", {226, 150, 161, 0}},\n{(unsigned char*)\"squarf\", {226, 150, 170, 0}},\n{(unsigned char*)\"squf\", {226, 150, 170, 0}},\n{(unsigned char*)\"srarr\", {226, 134, 146, 0}},\n{(unsigned char*)\"sscr\", {240, 157, 147, 136, 0}},\n{(unsigned char*)\"ssetmn\", {226, 136, 150, 0}},\n{(unsigned char*)\"ssmile\", {226, 140, 163, 0}},\n{(unsigned char*)\"sstarf\", {226, 139, 134, 0}},\n{(unsigned char*)\"star\", {226, 152, 134, 0}},\n{(unsigned char*)\"starf\", {226, 152, 133, 0}},\n{(unsigned char*)\"straightepsilon\", {207, 181, 0}},\n{(unsigned char*)\"straightphi\", {207, 149, 0}},\n{(unsigned char*)\"strns\", {194, 175, 0}},\n{(unsigned char*)\"sub\", {226, 138, 130, 0}},\n{(unsigned char*)\"subE\", {226, 171, 133, 0}},\n{(unsigned char*)\"subdot\", {226, 170, 189, 0}},\n{(unsigned char*)\"sube\", {226, 138, 134, 0}},\n{(unsigned char*)\"subedot\", {226, 171, 131, 0}},\n{(unsigned char*)\"submult\", {226, 171, 129, 0}},\n{(unsigned char*)\"subnE\", {226, 171, 139, 0}},\n{(unsigned char*)\"subne\", {226, 138, 138, 0}},\n{(unsigned char*)\"subplus\", {226, 170, 191, 0}},\n{(unsigned char*)\"subrarr\", {226, 165, 185, 0}},\n{(unsigned char*)\"subset\", {226, 138, 130, 0}},\n{(unsigned char*)\"subseteq\", {226, 138, 134, 0}},\n{(unsigned char*)\"subseteqq\", {226, 171, 133, 0}},\n{(unsigned char*)\"subsetneq\", {226, 138, 138, 0}},\n{(unsigned char*)\"subsetneqq\", {226, 171, 139, 0}},\n{(unsigned char*)\"subsim\", {226, 171, 135, 0}},\n{(unsigned char*)\"subsub\", {226, 171, 149, 0}},\n{(unsigned char*)\"subsup\", {226, 171, 147, 0}},\n{(unsigned char*)\"succ\", {226, 137, 187, 0}},\n{(unsigned char*)\"succapprox\", {226, 170, 184, 0}},\n{(unsigned char*)\"succcurlyeq\", {226, 137, 189, 0}},\n{(unsigned char*)\"succeq\", {226, 170, 176, 0}},\n{(unsigned char*)\"succnapprox\", {226, 170, 186, 0}},\n{(unsigned char*)\"succneqq\", {226, 170, 182, 0}},\n{(unsigned char*)\"succnsim\", {226, 139, 169, 0}},\n{(unsigned char*)\"succsim\", {226, 137, 191, 0}},\n{(unsigned char*)\"sum\", {226, 136, 145, 0}},\n{(unsigned char*)\"sung\", {226, 153, 170, 0}},\n{(unsigned char*)\"sup\", {226, 138, 131, 0}},\n{(unsigned char*)\"sup1\", {194, 185, 0}},\n{(unsigned char*)\"sup2\", {194, 178, 0}},\n{(unsigned char*)\"sup3\", {194, 179, 0}},\n{(unsigned char*)\"supE\", {226, 171, 134, 0}},\n{(unsigned char*)\"supdot\", {226, 170, 190, 0}},\n{(unsigned char*)\"supdsub\", {226, 171, 152, 0}},\n{(unsigned char*)\"supe\", {226, 138, 135, 0}},\n{(unsigned char*)\"supedot\", {226, 171, 132, 0}},\n{(unsigned char*)\"suphsol\", {226, 159, 137, 0}},\n{(unsigned char*)\"suphsub\", {226, 171, 151, 0}},\n{(unsigned char*)\"suplarr\", {226, 165, 187, 0}},\n{(unsigned char*)\"supmult\", {226, 171, 130, 0}},\n{(unsigned char*)\"supnE\", {226, 171, 140, 0}},\n{(unsigned char*)\"supne\", {226, 138, 139, 0}},\n{(unsigned char*)\"supplus\", {226, 171, 128, 0}},\n{(unsigned char*)\"supset\", {226, 138, 131, 0}},\n{(unsigned char*)\"supseteq\", {226, 138, 135, 0}},\n{(unsigned char*)\"supseteqq\", {226, 171, 134, 0}},\n{(unsigned char*)\"supsetneq\", {226, 138, 139, 0}},\n{(unsigned char*)\"supsetneqq\", {226, 171, 140, 0}},\n{(unsigned char*)\"supsim\", {226, 171, 136, 0}},\n{(unsigned char*)\"supsub\", {226, 171, 148, 0}},\n{(unsigned char*)\"supsup\", {226, 171, 150, 0}},\n{(unsigned char*)\"swArr\", {226, 135, 153, 0}},\n{(unsigned char*)\"swarhk\", {226, 164, 166, 0}},\n{(unsigned char*)\"swarr\", {226, 134, 153, 0}},\n{(unsigned char*)\"swarrow\", {226, 134, 153, 0}},\n{(unsigned char*)\"swnwar\", {226, 164, 170, 0}},\n{(unsigned char*)\"szlig\", {195, 159, 0}},\n{(unsigned char*)\"target\", {226, 140, 150, 0}},\n{(unsigned char*)\"tau\", {207, 132, 0}},\n{(unsigned char*)\"tbrk\", {226, 142, 180, 0}},\n{(unsigned char*)\"tcaron\", {197, 165, 0}},\n{(unsigned char*)\"tcedil\", {197, 163, 0}},\n{(unsigned char*)\"tcy\", {209, 130, 0}},\n{(unsigned char*)\"tdot\", {226, 131, 155, 0}},\n{(unsigned char*)\"telrec\", {226, 140, 149, 0}},\n{(unsigned char*)\"tfr\", {240, 157, 148, 177, 0}},\n{(unsigned char*)\"there4\", {226, 136, 180, 0}},\n{(unsigned char*)\"therefore\", {226, 136, 180, 0}},\n{(unsigned char*)\"theta\", {206, 184, 0}},\n{(unsigned char*)\"thetasym\", {207, 145, 0}},\n{(unsigned char*)\"thetav\", {207, 145, 0}},\n{(unsigned char*)\"thickapprox\", {226, 137, 136, 0}},\n{(unsigned char*)\"thicksim\", {226, 136, 188, 0}},\n{(unsigned char*)\"thinsp\", {226, 128, 137, 0}},\n{(unsigned char*)\"thkap\", {226, 137, 136, 0}},\n{(unsigned char*)\"thksim\", {226, 136, 188, 0}},\n{(unsigned char*)\"thorn\", {195, 190, 0}},\n{(unsigned char*)\"tilde\", {203, 156, 0}},\n{(unsigned char*)\"times\", {195, 151, 0}},\n{(unsigned char*)\"timesb\", {226, 138, 160, 0}},\n{(unsigned char*)\"timesbar\", {226, 168, 177, 0}},\n{(unsigned char*)\"timesd\", {226, 168, 176, 0}},\n{(unsigned char*)\"tint\", {226, 136, 173, 0}},\n{(unsigned char*)\"toea\", {226, 164, 168, 0}},\n{(unsigned char*)\"top\", {226, 138, 164, 0}},\n{(unsigned char*)\"topbot\", {226, 140, 182, 0}},\n{(unsigned char*)\"topcir\", {226, 171, 177, 0}},\n{(unsigned char*)\"topf\", {240, 157, 149, 165, 0}},\n{(unsigned char*)\"topfork\", {226, 171, 154, 0}},\n{(unsigned char*)\"tosa\", {226, 164, 169, 0}},\n{(unsigned char*)\"tprime\", {226, 128, 180, 0}},\n{(unsigned char*)\"trade\", {226, 132, 162, 0}},\n{(unsigned char*)\"triangle\", {226, 150, 181, 0}},\n{(unsigned char*)\"triangledown\", {226, 150, 191, 0}},\n{(unsigned char*)\"triangleleft\", {226, 151, 131, 0}},\n{(unsigned char*)\"trianglelefteq\", {226, 138, 180, 0}},\n{(unsigned char*)\"triangleq\", {226, 137, 156, 0}},\n{(unsigned char*)\"triangleright\", {226, 150, 185, 0}},\n{(unsigned char*)\"trianglerighteq\", {226, 138, 181, 0}},\n{(unsigned char*)\"tridot\", {226, 151, 172, 0}},\n{(unsigned char*)\"trie\", {226, 137, 156, 0}},\n{(unsigned char*)\"triminus\", {226, 168, 186, 0}},\n{(unsigned char*)\"triplus\", {226, 168, 185, 0}},\n{(unsigned char*)\"trisb\", {226, 167, 141, 0}},\n{(unsigned char*)\"tritime\", {226, 168, 187, 0}},\n{(unsigned char*)\"trpezium\", {226, 143, 162, 0}},\n{(unsigned char*)\"tscr\", {240, 157, 147, 137, 0}},\n{(unsigned char*)\"tscy\", {209, 134, 0}},\n{(unsigned char*)\"tshcy\", {209, 155, 0}},\n{(unsigned char*)\"tstrok\", {197, 167, 0}},\n{(unsigned char*)\"twixt\", {226, 137, 172, 0}},\n{(unsigned char*)\"twoheadleftarrow\", {226, 134, 158, 0}},\n{(unsigned char*)\"twoheadrightarrow\", {226, 134, 160, 0}},\n{(unsigned char*)\"uArr\", {226, 135, 145, 0}},\n{(unsigned char*)\"uHar\", {226, 165, 163, 0}},\n{(unsigned char*)\"uacute\", {195, 186, 0}},\n{(unsigned char*)\"uarr\", {226, 134, 145, 0}},\n{(unsigned char*)\"ubrcy\", {209, 158, 0}},\n{(unsigned char*)\"ubreve\", {197, 173, 0}},\n{(unsigned char*)\"ucirc\", {195, 187, 0}},\n{(unsigned char*)\"ucy\", {209, 131, 0}},\n{(unsigned char*)\"udarr\", {226, 135, 133, 0}},\n{(unsigned char*)\"udblac\", {197, 177, 0}},\n{(unsigned char*)\"udhar\", {226, 165, 174, 0}},\n{(unsigned char*)\"ufisht\", {226, 165, 190, 0}},\n{(unsigned char*)\"ufr\", {240, 157, 148, 178, 0}},\n{(unsigned char*)\"ugrave\", {195, 185, 0}},\n{(unsigned char*)\"uharl\", {226, 134, 191, 0}},\n{(unsigned char*)\"uharr\", {226, 134, 190, 0}},\n{(unsigned char*)\"uhblk\", {226, 150, 128, 0}},\n{(unsigned char*)\"ulcorn\", {226, 140, 156, 0}},\n{(unsigned char*)\"ulcorner\", {226, 140, 156, 0}},\n{(unsigned char*)\"ulcrop\", {226, 140, 143, 0}},\n{(unsigned char*)\"ultri\", {226, 151, 184, 0}},\n{(unsigned char*)\"umacr\", {197, 171, 0}},\n{(unsigned char*)\"uml\", {194, 168, 0}},\n{(unsigned char*)\"uogon\", {197, 179, 0}},\n{(unsigned char*)\"uopf\", {240, 157, 149, 166, 0}},\n{(unsigned char*)\"uparrow\", {226, 134, 145, 0}},\n{(unsigned char*)\"updownarrow\", {226, 134, 149, 0}},\n{(unsigned char*)\"upharpoonleft\", {226, 134, 191, 0}},\n{(unsigned char*)\"upharpoonright\", {226, 134, 190, 0}},\n{(unsigned char*)\"uplus\", {226, 138, 142, 0}},\n{(unsigned char*)\"upsi\", {207, 133, 0}},\n{(unsigned char*)\"upsih\", {207, 146, 0}},\n{(unsigned char*)\"upsilon\", {207, 133, 0}},\n{(unsigned char*)\"upuparrows\", {226, 135, 136, 0}},\n{(unsigned char*)\"urcorn\", {226, 140, 157, 0}},\n{(unsigned char*)\"urcorner\", {226, 140, 157, 0}},\n{(unsigned char*)\"urcrop\", {226, 140, 142, 0}},\n{(unsigned char*)\"uring\", {197, 175, 0}},\n{(unsigned char*)\"urtri\", {226, 151, 185, 0}},\n{(unsigned char*)\"uscr\", {240, 157, 147, 138, 0}},\n{(unsigned char*)\"utdot\", {226, 139, 176, 0}},\n{(unsigned char*)\"utilde\", {197, 169, 0}},\n{(unsigned char*)\"utri\", {226, 150, 181, 0}},\n{(unsigned char*)\"utrif\", {226, 150, 180, 0}},\n{(unsigned char*)\"uuarr\", {226, 135, 136, 0}},\n{(unsigned char*)\"uuml\", {195, 188, 0}},\n{(unsigned char*)\"uwangle\", {226, 166, 167, 0}},\n{(unsigned char*)\"vArr\", {226, 135, 149, 0}},\n{(unsigned char*)\"vBar\", {226, 171, 168, 0}},\n{(unsigned char*)\"vBarv\", {226, 171, 169, 0}},\n{(unsigned char*)\"vDash\", {226, 138, 168, 0}},\n{(unsigned char*)\"vangrt\", {226, 166, 156, 0}},\n{(unsigned char*)\"varepsilon\", {207, 181, 0}},\n{(unsigned char*)\"varkappa\", {207, 176, 0}},\n{(unsigned char*)\"varnothing\", {226, 136, 133, 0}},\n{(unsigned char*)\"varphi\", {207, 149, 0}},\n{(unsigned char*)\"varpi\", {207, 150, 0}},\n{(unsigned char*)\"varpropto\", {226, 136, 157, 0}},\n{(unsigned char*)\"varr\", {226, 134, 149, 0}},\n{(unsigned char*)\"varrho\", {207, 177, 0}},\n{(unsigned char*)\"varsigma\", {207, 130, 0}},\n{(unsigned char*)\"varsubsetneq\", {226, 138, 138, 239, 184, 128, 0}},\n{(unsigned char*)\"varsubsetneqq\", {226, 171, 139, 239, 184, 128, 0}},\n{(unsigned char*)\"varsupsetneq\", {226, 138, 139, 239, 184, 128, 0}},\n{(unsigned char*)\"varsupsetneqq\", {226, 171, 140, 239, 184, 128, 0}},\n{(unsigned char*)\"vartheta\", {207, 145, 0}},\n{(unsigned char*)\"vartriangleleft\", {226, 138, 178, 0}},\n{(unsigned char*)\"vartriangleright\", {226, 138, 179, 0}},\n{(unsigned char*)\"vcy\", {208, 178, 0}},\n{(unsigned char*)\"vdash\", {226, 138, 162, 0}},\n{(unsigned char*)\"vee\", {226, 136, 168, 0}},\n{(unsigned char*)\"veebar\", {226, 138, 187, 0}},\n{(unsigned char*)\"veeeq\", {226, 137, 154, 0}},\n{(unsigned char*)\"vellip\", {226, 139, 174, 0}},\n{(unsigned char*)\"verbar\", {124, 0}},\n{(unsigned char*)\"vert\", {124, 0}},\n{(unsigned char*)\"vfr\", {240, 157, 148, 179, 0}},\n{(unsigned char*)\"vltri\", {226, 138, 178, 0}},\n{(unsigned char*)\"vnsub\", {226, 138, 130, 226, 131, 146, 0}},\n{(unsigned char*)\"vnsup\", {226, 138, 131, 226, 131, 146, 0}},\n{(unsigned char*)\"vopf\", {240, 157, 149, 167, 0}},\n{(unsigned char*)\"vprop\", {226, 136, 157, 0}},\n{(unsigned char*)\"vrtri\", {226, 138, 179, 0}},\n{(unsigned char*)\"vscr\", {240, 157, 147, 139, 0}},\n{(unsigned char*)\"vsubnE\", {226, 171, 139, 239, 184, 128, 0}},\n{(unsigned char*)\"vsubne\", {226, 138, 138, 239, 184, 128, 0}},\n{(unsigned char*)\"vsupnE\", {226, 171, 140, 239, 184, 128, 0}},\n{(unsigned char*)\"vsupne\", {226, 138, 139, 239, 184, 128, 0}},\n{(unsigned char*)\"vzigzag\", {226, 166, 154, 0}},\n{(unsigned char*)\"wcirc\", {197, 181, 0}},\n{(unsigned char*)\"wedbar\", {226, 169, 159, 0}},\n{(unsigned char*)\"wedge\", {226, 136, 167, 0}},\n{(unsigned char*)\"wedgeq\", {226, 137, 153, 0}},\n{(unsigned char*)\"weierp\", {226, 132, 152, 0}},\n{(unsigned char*)\"wfr\", {240, 157, 148, 180, 0}},\n{(unsigned char*)\"wopf\", {240, 157, 149, 168, 0}},\n{(unsigned char*)\"wp\", {226, 132, 152, 0}},\n{(unsigned char*)\"wr\", {226, 137, 128, 0}},\n{(unsigned char*)\"wreath\", {226, 137, 128, 0}},\n{(unsigned char*)\"wscr\", {240, 157, 147, 140, 0}},\n{(unsigned char*)\"xcap\", {226, 139, 130, 0}},\n{(unsigned char*)\"xcirc\", {226, 151, 175, 0}},\n{(unsigned char*)\"xcup\", {226, 139, 131, 0}},\n{(unsigned char*)\"xdtri\", {226, 150, 189, 0}},\n{(unsigned char*)\"xfr\", {240, 157, 148, 181, 0}},\n{(unsigned char*)\"xhArr\", {226, 159, 186, 0}},\n{(unsigned char*)\"xharr\", {226, 159, 183, 0}},\n{(unsigned char*)\"xi\", {206, 190, 0}},\n{(unsigned char*)\"xlArr\", {226, 159, 184, 0}},\n{(unsigned char*)\"xlarr\", {226, 159, 181, 0}},\n{(unsigned char*)\"xmap\", {226, 159, 188, 0}},\n{(unsigned char*)\"xnis\", {226, 139, 187, 0}},\n{(unsigned char*)\"xodot\", {226, 168, 128, 0}},\n{(unsigned char*)\"xopf\", {240, 157, 149, 169, 0}},\n{(unsigned char*)\"xoplus\", {226, 168, 129, 0}},\n{(unsigned char*)\"xotime\", {226, 168, 130, 0}},\n{(unsigned char*)\"xrArr\", {226, 159, 185, 0}},\n{(unsigned char*)\"xrarr\", {226, 159, 182, 0}},\n{(unsigned char*)\"xscr\", {240, 157, 147, 141, 0}},\n{(unsigned char*)\"xsqcup\", {226, 168, 134, 0}},\n{(unsigned char*)\"xuplus\", {226, 168, 132, 0}},\n{(unsigned char*)\"xutri\", {226, 150, 179, 0}},\n{(unsigned char*)\"xvee\", {226, 139, 129, 0}},\n{(unsigned char*)\"xwedge\", {226, 139, 128, 0}},\n{(unsigned char*)\"yacute\", {195, 189, 0}},\n{(unsigned char*)\"yacy\", {209, 143, 0}},\n{(unsigned char*)\"ycirc\", {197, 183, 0}},\n{(unsigned char*)\"ycy\", {209, 139, 0}},\n{(unsigned char*)\"yen\", {194, 165, 0}},\n{(unsigned char*)\"yfr\", {240, 157, 148, 182, 0}},\n{(unsigned char*)\"yicy\", {209, 151, 0}},\n{(unsigned char*)\"yopf\", {240, 157, 149, 170, 0}},\n{(unsigned char*)\"yscr\", {240, 157, 147, 142, 0}},\n{(unsigned char*)\"yucy\", {209, 142, 0}},\n{(unsigned char*)\"yuml\", {195, 191, 0}},\n{(unsigned char*)\"zacute\", {197, 186, 0}},\n{(unsigned char*)\"zcaron\", {197, 190, 0}},\n{(unsigned char*)\"zcy\", {208, 183, 0}},\n{(unsigned char*)\"zdot\", {197, 188, 0}},\n{(unsigned char*)\"zeetrf\", {226, 132, 168, 0}},\n{(unsigned char*)\"zeta\", {206, 182, 0}},\n{(unsigned char*)\"zfr\", {240, 157, 148, 183, 0}},\n{(unsigned char*)\"zhcy\", {208, 182, 0}},\n{(unsigned char*)\"zigrarr\", {226, 135, 157, 0}},\n{(unsigned char*)\"zopf\", {240, 157, 149, 171, 0}},\n{(unsigned char*)\"zscr\", {240, 157, 147, 143, 0}},\n{(unsigned char*)\"zwj\", {226, 128, 141, 0}},\n{(unsigned char*)\"zwnj\", {226, 128, 140, 0}},\n};\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/footnotes.c",
    "content": "#include \"cmark-gfm.h\"\n#include \"parser.h\"\n#include \"footnotes.h\"\n#include \"inlines.h\"\n#include \"chunk.h\"\n\nstatic void footnote_free(cmark_map *map, cmark_map_entry *_ref) {\n  cmark_footnote *ref = (cmark_footnote *)_ref;\n  cmark_mem *mem = map->mem;\n  if (ref != NULL) {\n    mem->free(ref->entry.label);\n    if (ref->node)\n      cmark_node_free(ref->node);\n    mem->free(ref);\n  }\n}\n\nvoid cmark_footnote_create(cmark_map *map, cmark_node *node) {\n  cmark_footnote *ref;\n  unsigned char *reflabel = normalize_map_label(map->mem, &node->as.literal);\n\n  /* empty footnote name, or composed from only whitespace */\n  if (reflabel == NULL)\n    return;\n\n  assert(map->sorted == NULL);\n\n  ref = (cmark_footnote *)map->mem->calloc(1, sizeof(*ref));\n  ref->entry.label = reflabel;\n  ref->node = node;\n  ref->entry.age = map->size;\n  ref->entry.next = map->refs;\n\n  map->refs = (cmark_map_entry *)ref;\n  map->size++;\n}\n\ncmark_map *cmark_footnote_map_new(cmark_mem *mem) {\n  return cmark_map_new(mem, footnote_free);\n}\n\n// Before calling `cmark_map_free` on a map with `cmark_footnotes`, first\n// unlink all of the footnote nodes before freeing their memory.\n//\n// Sometimes, two (unused) footnote nodes can end up referencing each other,\n// which as they get freed up by calling `cmark_map_free` -> `footnote_free` ->\n// etc, can lead to a use-after-free error.\n//\n// Better to `unlink` every footnote node first, setting their next, prev, and\n// parent pointers to NULL, and only then walk thru & free them up.\nvoid cmark_unlink_footnotes_map(cmark_map *map) {\n  cmark_map_entry *ref;\n  cmark_map_entry *next;\n\n  ref = map->refs;\n  while(ref) {\n    next = ref->next;\n    if (((cmark_footnote *)ref)->node) {\n      cmark_node_unlink(((cmark_footnote *)ref)->node);\n    }\n    ref = next;\n  }\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/footnotes.h",
    "content": "#ifndef CMARK_FOOTNOTES_H\n#define CMARK_FOOTNOTES_H\n\n#include \"map.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nstruct cmark_footnote {\n  cmark_map_entry entry;\n  cmark_node *node;\n  unsigned int ix;\n};\n\ntypedef struct cmark_footnote cmark_footnote;\n\nvoid cmark_footnote_create(cmark_map *map, cmark_node *node);\ncmark_map *cmark_footnote_map_new(cmark_mem *mem);\n\nvoid cmark_unlink_footnotes_map(cmark_map *map);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/houdini.h",
    "content": "#ifndef CMARK_HOUDINI_H\n#define CMARK_HOUDINI_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n#include \"config.h\"\n#include \"buffer.h\"\n\n#ifdef HAVE___BUILTIN_EXPECT\n#define likely(x) __builtin_expect((x), 1)\n#define unlikely(x) __builtin_expect((x), 0)\n#else\n#define likely(x) (x)\n#define unlikely(x) (x)\n#endif\n\n#ifdef HOUDINI_USE_LOCALE\n#define _isxdigit(c) isxdigit(c)\n#define _isdigit(c) isdigit(c)\n#else\n/*\n * Helper _isdigit methods -- do not trust the current locale\n * */\n#define _isxdigit(c) (strchr(\"0123456789ABCDEFabcdef\", (c)) != NULL)\n#define _isdigit(c) ((c) >= '0' && (c) <= '9')\n#endif\n\n#define HOUDINI_ESCAPED_SIZE(x) (((x)*12) / 10)\n#define HOUDINI_UNESCAPED_SIZE(x) (x)\n\nCMARK_GFM_EXPORT\nbufsize_t houdini_unescape_ent(cmark_strbuf *ob, const uint8_t *src,\n                                      bufsize_t size);\nCMARK_GFM_EXPORT\nint houdini_escape_html(cmark_strbuf *ob, const uint8_t *src,\n                               bufsize_t size);\nCMARK_GFM_EXPORT\nint houdini_escape_html0(cmark_strbuf *ob, const uint8_t *src,\n                                bufsize_t size, int secure);\nCMARK_GFM_EXPORT\nint houdini_unescape_html(cmark_strbuf *ob, const uint8_t *src,\n                                 bufsize_t size);\nCMARK_GFM_EXPORT\nvoid houdini_unescape_html_f(cmark_strbuf *ob, const uint8_t *src,\n                                    bufsize_t size);\nCMARK_GFM_EXPORT\nint houdini_escape_href(cmark_strbuf *ob, const uint8_t *src,\n                               bufsize_t size);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/houdini_href_e.c",
    "content": "#include <assert.h>\n#include <stdio.h>\n#include <string.h>\n\n#include \"houdini.h\"\n\n/*\n * The following characters will not be escaped:\n *\n *\t\t-_.+!*'(),%#@?=;:/,+&$~ alphanum\n *\n * Note that this character set is the addition of:\n *\n *\t- The characters which are safe to be in an URL\n *\t- The characters which are *not* safe to be in\n *\tan URL because they are RESERVED characters.\n *\n * We assume (lazily) that any RESERVED char that\n * appears inside an URL is actually meant to\n * have its native function (i.e. as an URL\n * component/separator) and hence needs no escaping.\n *\n * There are two exceptions: the chacters & (amp)\n * and ' (single quote) do not appear in the table.\n * They are meant to appear in the URL as components,\n * yet they require special HTML-entity escaping\n * to generate valid HTML markup.\n *\n * All other characters will be escaped to %XX.\n *\n */\nstatic const char HREF_SAFE[] = {\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,\n    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,\n    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n    1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n};\n\nint houdini_escape_href(cmark_strbuf *ob, const uint8_t *src, bufsize_t size) {\n  static const uint8_t hex_chars[] = \"0123456789ABCDEF\";\n  bufsize_t i = 0, org;\n  uint8_t hex_str[3];\n\n  hex_str[0] = '%';\n\n  while (i < size) {\n    org = i;\n    while (i < size && HREF_SAFE[src[i]] != 0)\n      i++;\n\n    if (likely(i > org))\n      cmark_strbuf_put(ob, src + org, i - org);\n\n    /* escaping */\n    if (i >= size)\n      break;\n\n    switch (src[i]) {\n    /* amp appears all the time in URLs, but needs\n     * HTML-entity escaping to be inside an href */\n    case '&':\n      cmark_strbuf_puts(ob, \"&amp;\");\n      break;\n\n    /* the single quote is a valid URL character\n     * according to the standard; it needs HTML\n     * entity escaping too */\n    case '\\'':\n      cmark_strbuf_puts(ob, \"&#x27;\");\n      break;\n\n/* the space can be escaped to %20 or a plus\n * sign. we're going with the generic escape\n * for now. the plus thing is more commonly seen\n * when building GET strings */\n#if 0\n\t\tcase ' ':\n\t\t\tcmark_strbuf_putc(ob, '+');\n\t\t\tbreak;\n#endif\n\n    /* every other character goes with a %XX escaping */\n    default:\n      hex_str[1] = hex_chars[(src[i] >> 4) & 0xF];\n      hex_str[2] = hex_chars[src[i] & 0xF];\n      cmark_strbuf_put(ob, hex_str, 3);\n    }\n\n    i++;\n  }\n\n  return 1;\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/houdini_html_e.c",
    "content": "#include <assert.h>\n#include <stdio.h>\n#include <string.h>\n\n#include \"houdini.h\"\n\n/**\n * According to the OWASP rules:\n *\n * & --> &amp;\n * < --> &lt;\n * > --> &gt;\n * \" --> &quot;\n * ' --> &#x27;     &apos; is not recommended\n * / --> &#x2F;     forward slash is included as it helps end an HTML entity\n *\n */\nstatic const char HTML_ESCAPE_TABLE[] = {\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 4,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n};\n\nstatic const char *HTML_ESCAPES[] = {\"\",      \"&quot;\", \"&amp;\", \"&#39;\",\n                                     \"&#47;\", \"&lt;\",   \"&gt;\"};\n\nint houdini_escape_html0(cmark_strbuf *ob, const uint8_t *src, bufsize_t size,\n                         int secure) {\n  bufsize_t i = 0, org, esc = 0;\n\n  while (i < size) {\n    org = i;\n    while (i < size && (esc = HTML_ESCAPE_TABLE[src[i]]) == 0)\n      i++;\n\n    if (i > org)\n      cmark_strbuf_put(ob, src + org, i - org);\n\n    /* escaping */\n    if (unlikely(i >= size))\n      break;\n\n    /* The forward slash and single quote are only escaped in secure mode */\n    if ((src[i] == '/' || src[i] == '\\'') && !secure) {\n      cmark_strbuf_putc(ob, src[i]);\n    } else {\n      cmark_strbuf_puts(ob, HTML_ESCAPES[esc]);\n    }\n\n    i++;\n  }\n\n  return 1;\n}\n\nint houdini_escape_html(cmark_strbuf *ob, const uint8_t *src, bufsize_t size) {\n  return houdini_escape_html0(ob, src, size, 1);\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/houdini_html_u.c",
    "content": "#include <assert.h>\n#include <stdio.h>\n#include <string.h>\n\n#include \"buffer.h\"\n#include \"houdini.h\"\n#include \"utf8.h\"\n#include \"entities.inc\"\n\n/* Binary tree lookup code for entities added by JGM */\n\nstatic const unsigned char *S_lookup(int i, int low, int hi,\n                                     const unsigned char *s, int len) {\n  int j;\n  int cmp =\n      strncmp((const char *)s, (const char *)cmark_entities[i].entity, len);\n  if (cmp == 0 && cmark_entities[i].entity[len] == 0) {\n    return (const unsigned char *)cmark_entities[i].bytes;\n  } else if (cmp <= 0 && i > low) {\n    j = i - ((i - low) / 2);\n    if (j == i)\n      j -= 1;\n    return S_lookup(j, low, i - 1, s, len);\n  } else if (cmp > 0 && i < hi) {\n    j = i + ((hi - i) / 2);\n    if (j == i)\n      j += 1;\n    return S_lookup(j, i + 1, hi, s, len);\n  } else {\n    return NULL;\n  }\n}\n\nstatic const unsigned char *S_lookup_entity(const unsigned char *s, int len) {\n  return S_lookup(CMARK_NUM_ENTITIES / 2, 0, CMARK_NUM_ENTITIES - 1, s, len);\n}\n\nbufsize_t houdini_unescape_ent(cmark_strbuf *ob, const uint8_t *src,\n                               bufsize_t size) {\n  bufsize_t i = 0;\n\n  if (size >= 3 && src[0] == '#') {\n    int codepoint = 0;\n    int num_digits = 0;\n\n    if (_isdigit(src[1])) {\n      for (i = 1; i < size && _isdigit(src[i]); ++i) {\n        codepoint = (codepoint * 10) + (src[i] - '0');\n\n        if (codepoint >= 0x110000) {\n          // Keep counting digits but\n          // avoid integer overflow.\n          codepoint = 0x110000;\n        }\n      }\n\n      num_digits = i - 1;\n    }\n\n    else if (src[1] == 'x' || src[1] == 'X') {\n      for (i = 2; i < size && _isxdigit(src[i]); ++i) {\n        codepoint = (codepoint * 16) + ((src[i] | 32) % 39 - 9);\n\n        if (codepoint >= 0x110000) {\n          // Keep counting digits but\n          // avoid integer overflow.\n          codepoint = 0x110000;\n        }\n      }\n\n      num_digits = i - 2;\n    }\n\n    if (num_digits >= 1 && num_digits <= 8 && i < size && src[i] == ';') {\n      if (codepoint == 0 || (codepoint >= 0xD800 && codepoint < 0xE000) ||\n          codepoint >= 0x110000) {\n        codepoint = 0xFFFD;\n      }\n      cmark_utf8proc_encode_char(codepoint, ob);\n      return i + 1;\n    }\n  }\n\n  else {\n    if (size > CMARK_ENTITY_MAX_LENGTH)\n      size = CMARK_ENTITY_MAX_LENGTH;\n\n    for (i = CMARK_ENTITY_MIN_LENGTH; i < size; ++i) {\n      if (src[i] == ' ')\n        break;\n\n      if (src[i] == ';') {\n        const unsigned char *entity = S_lookup_entity(src, i);\n\n        if (entity != NULL) {\n          cmark_strbuf_puts(ob, (const char *)entity);\n          return i + 1;\n        }\n\n        break;\n      }\n    }\n  }\n\n  return 0;\n}\n\nint houdini_unescape_html(cmark_strbuf *ob, const uint8_t *src,\n                          bufsize_t size) {\n  bufsize_t i = 0, org, ent;\n\n  while (i < size) {\n    org = i;\n    while (i < size && src[i] != '&')\n      i++;\n\n    if (likely(i > org)) {\n      if (unlikely(org == 0)) {\n        if (i >= size)\n          return 0;\n\n        cmark_strbuf_grow(ob, HOUDINI_UNESCAPED_SIZE(size));\n      }\n\n      cmark_strbuf_put(ob, src + org, i - org);\n    }\n\n    /* escaping */\n    if (i >= size)\n      break;\n\n    i++;\n\n    ent = houdini_unescape_ent(ob, src + i, size - i);\n    i += ent;\n\n    /* not really an entity */\n    if (ent == 0)\n      cmark_strbuf_putc(ob, '&');\n  }\n\n  return 1;\n}\n\nvoid houdini_unescape_html_f(cmark_strbuf *ob, const uint8_t *src,\n                             bufsize_t size) {\n  if (!houdini_unescape_html(ob, src, size))\n    cmark_strbuf_put(ob, src, size);\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/html.c",
    "content": "#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <assert.h>\n#include \"cmark_ctype.h\"\n#include \"config.h\"\n#include \"cmark-gfm.h\"\n#include \"houdini.h\"\n#include \"scanners.h\"\n#include \"syntax_extension.h\"\n#include \"html.h\"\n#include \"render.h\"\n\n// Functions to convert cmark_nodes to HTML strings.\n\nstatic void escape_html(cmark_strbuf *dest, const unsigned char *source,\n                        bufsize_t length) {\n  houdini_escape_html0(dest, source, length, 0);\n}\n\nstatic void filter_html_block(cmark_html_renderer *renderer, uint8_t *data, size_t len) {\n  cmark_strbuf *html = renderer->html;\n  cmark_llist *it;\n  cmark_syntax_extension *ext;\n  bool filtered;\n  uint8_t *match;\n\n  while (len) {\n    match = (uint8_t *) memchr(data, '<', len);\n    if (!match)\n      break;\n\n    if (match != data) {\n      cmark_strbuf_put(html, data, (bufsize_t)(match - data));\n      len -= (match - data);\n      data = match;\n    }\n\n    filtered = false;\n    for (it = renderer->filter_extensions; it; it = it->next) {\n      ext = ((cmark_syntax_extension *) it->data);\n      if (!ext->html_filter_func(ext, data, len)) {\n        filtered = true;\n        break;\n      }\n    }\n\n    if (!filtered) {\n      cmark_strbuf_putc(html, '<');\n    } else {\n      cmark_strbuf_puts(html, \"&lt;\");\n    }\n\n    ++data;\n    --len;\n  }\n\n  if (len)\n    cmark_strbuf_put(html, data, (bufsize_t)len);\n}\n\nstatic bool S_put_footnote_backref(cmark_html_renderer *renderer, cmark_strbuf *html, cmark_node *node) {\n  if (renderer->written_footnote_ix >= renderer->footnote_ix)\n    return false;\n  renderer->written_footnote_ix = renderer->footnote_ix;\n  char m[32];\n  snprintf(m, sizeof(m), \"%d\", renderer->written_footnote_ix);\n\n  cmark_strbuf_puts(html, \"<a href=\\\"#fnref-\");\n  houdini_escape_href(html, node->as.literal.data, node->as.literal.len);\n  cmark_strbuf_puts(html, \"\\\" class=\\\"footnote-backref\\\" data-footnote-backref data-footnote-backref-idx=\\\"\");\n  cmark_strbuf_puts(html, m);\n  cmark_strbuf_puts(html, \"\\\" aria-label=\\\"Back to reference \");\n  cmark_strbuf_puts(html, m);\n  cmark_strbuf_puts(html, \"\\\">↩</a>\");\n\n  if (node->footnote.def_count > 1)\n  {\n    for(int i = 2; i <= node->footnote.def_count; i++) {\n      char n[32];\n      snprintf(n, sizeof(n), \"%d\", i);\n\n      cmark_strbuf_puts(html, \" <a href=\\\"#fnref-\");\n      houdini_escape_href(html, node->as.literal.data, node->as.literal.len);\n      cmark_strbuf_puts(html, \"-\");\n      cmark_strbuf_puts(html, n);\n      cmark_strbuf_puts(html, \"\\\" class=\\\"footnote-backref\\\" data-footnote-backref data-footnote-backref-idx=\\\"\");\n      cmark_strbuf_puts(html, m);\n      cmark_strbuf_puts(html, \"-\");\n      cmark_strbuf_puts(html, n);\n      cmark_strbuf_puts(html, \"\\\" aria-label=\\\"Back to reference \");\n      cmark_strbuf_puts(html, m);\n      cmark_strbuf_puts(html, \"-\");\n      cmark_strbuf_puts(html, n);\n      cmark_strbuf_puts(html, \"\\\">↩<sup class=\\\"footnote-ref\\\">\");\n      cmark_strbuf_puts(html, n);\n      cmark_strbuf_puts(html, \"</sup></a>\");\n    }\n  }\n\n  return true;\n}\n\nstatic int S_render_node(cmark_html_renderer *renderer, cmark_node *node,\n                         cmark_event_type ev_type, int options) {\n  cmark_node *parent;\n  cmark_node *grandparent;\n  cmark_strbuf *html = renderer->html;\n  cmark_llist *it;\n  cmark_syntax_extension *ext;\n  char start_heading[] = \"<h0\";\n  char end_heading[] = \"</h0\";\n  bool tight;\n  bool filtered;\n  char buffer[BUFFER_SIZE];\n\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n\n  if (renderer->plain == node) { // back at original node\n    renderer->plain = NULL;\n  }\n\n  if (renderer->plain != NULL) {\n    switch (node->type) {\n    case CMARK_NODE_TEXT:\n    case CMARK_NODE_CODE:\n    case CMARK_NODE_HTML_INLINE:\n      escape_html(html, node->as.literal.data, node->as.literal.len);\n      break;\n\n    case CMARK_NODE_LINEBREAK:\n    case CMARK_NODE_SOFTBREAK:\n      cmark_strbuf_putc(html, ' ');\n      break;\n\n    default:\n      break;\n    }\n    return 1;\n  }\n\n  if (node->extension && node->extension->html_render_func) {\n    node->extension->html_render_func(node->extension, renderer, node, ev_type, options);\n    return 1;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_DOCUMENT:\n    break;\n\n  case CMARK_NODE_BLOCK_QUOTE:\n    if (entering) {\n      cmark_html_render_cr(html);\n      cmark_strbuf_puts(html, \"<blockquote\");\n      cmark_html_render_sourcepos(node, html, options);\n      cmark_strbuf_puts(html, \">\\n\");\n    } else {\n      cmark_html_render_cr(html);\n      cmark_strbuf_puts(html, \"</blockquote>\\n\");\n    }\n    break;\n\n  case CMARK_NODE_LIST: {\n    cmark_list_type list_type = node->as.list.list_type;\n    int start = node->as.list.start;\n\n    if (entering) {\n      cmark_html_render_cr(html);\n      if (list_type == CMARK_BULLET_LIST) {\n        cmark_strbuf_puts(html, \"<ul\");\n        cmark_html_render_sourcepos(node, html, options);\n        cmark_strbuf_puts(html, \">\\n\");\n      } else if (start == 1) {\n        cmark_strbuf_puts(html, \"<ol\");\n        cmark_html_render_sourcepos(node, html, options);\n        cmark_strbuf_puts(html, \">\\n\");\n      } else {\n        snprintf(buffer, BUFFER_SIZE, \"<ol start=\\\"%d\\\"\", start);\n        cmark_strbuf_puts(html, buffer);\n        cmark_html_render_sourcepos(node, html, options);\n        cmark_strbuf_puts(html, \">\\n\");\n      }\n    } else {\n      cmark_strbuf_puts(html,\n                        list_type == CMARK_BULLET_LIST ? \"</ul>\\n\" : \"</ol>\\n\");\n    }\n    break;\n  }\n\n  case CMARK_NODE_ITEM:\n    if (entering) {\n      cmark_html_render_cr(html);\n      cmark_strbuf_puts(html, \"<li\");\n      cmark_html_render_sourcepos(node, html, options);\n      cmark_strbuf_putc(html, '>');\n    } else {\n      cmark_strbuf_puts(html, \"</li>\\n\");\n    }\n    break;\n\n  case CMARK_NODE_HEADING:\n    if (entering) {\n      cmark_html_render_cr(html);\n      start_heading[2] = (char)('0' + node->as.heading.level);\n      cmark_strbuf_puts(html, start_heading);\n      cmark_html_render_sourcepos(node, html, options);\n      cmark_strbuf_putc(html, '>');\n    } else {\n      end_heading[3] = (char)('0' + node->as.heading.level);\n      cmark_strbuf_puts(html, end_heading);\n      cmark_strbuf_puts(html, \">\\n\");\n    }\n    break;\n\n  case CMARK_NODE_CODE_BLOCK:\n    cmark_html_render_cr(html);\n\n    if (node->as.code.info.len == 0) {\n      cmark_strbuf_puts(html, \"<pre\");\n      cmark_html_render_sourcepos(node, html, options);\n      cmark_strbuf_puts(html, \"><code>\");\n    } else {\n      bufsize_t first_tag = 0;\n      while (first_tag < node->as.code.info.len &&\n             !cmark_isspace(node->as.code.info.data[first_tag])) {\n        first_tag += 1;\n      }\n\n      if (options & CMARK_OPT_GITHUB_PRE_LANG) {\n        cmark_strbuf_puts(html, \"<pre\");\n        cmark_html_render_sourcepos(node, html, options);\n        cmark_strbuf_puts(html, \" lang=\\\"\");\n        escape_html(html, node->as.code.info.data, first_tag);\n        if (first_tag < node->as.code.info.len && (options & CMARK_OPT_FULL_INFO_STRING)) {\n          cmark_strbuf_puts(html, \"\\\" data-meta=\\\"\");\n          escape_html(html, node->as.code.info.data + first_tag + 1, node->as.code.info.len - first_tag - 1);\n        }\n        cmark_strbuf_puts(html, \"\\\"><code>\");\n      } else {\n        cmark_strbuf_puts(html, \"<pre\");\n        cmark_html_render_sourcepos(node, html, options);\n        cmark_strbuf_puts(html, \"><code class=\\\"language-\");\n        escape_html(html, node->as.code.info.data, first_tag);\n        if (first_tag < node->as.code.info.len && (options & CMARK_OPT_FULL_INFO_STRING)) {\n          cmark_strbuf_puts(html, \"\\\" data-meta=\\\"\");\n          escape_html(html, node->as.code.info.data + first_tag + 1, node->as.code.info.len - first_tag - 1);\n        }\n        cmark_strbuf_puts(html, \"\\\">\");\n      }\n    }\n\n    escape_html(html, node->as.code.literal.data, node->as.code.literal.len);\n    cmark_strbuf_puts(html, \"</code></pre>\\n\");\n    break;\n\n  case CMARK_NODE_HTML_BLOCK:\n    cmark_html_render_cr(html);\n    if (!(options & CMARK_OPT_UNSAFE)) {\n      cmark_strbuf_puts(html, \"<!-- raw HTML omitted -->\");\n    } else if (renderer->filter_extensions) {\n      filter_html_block(renderer, node->as.literal.data, node->as.literal.len);\n    } else {\n      cmark_strbuf_put(html, node->as.literal.data, node->as.literal.len);\n    }\n    cmark_html_render_cr(html);\n    break;\n\n  case CMARK_NODE_CUSTOM_BLOCK:\n    cmark_html_render_cr(html);\n    if (entering) {\n      cmark_strbuf_put(html, node->as.custom.on_enter.data,\n                       node->as.custom.on_enter.len);\n    } else {\n      cmark_strbuf_put(html, node->as.custom.on_exit.data,\n                       node->as.custom.on_exit.len);\n    }\n    cmark_html_render_cr(html);\n    break;\n\n  case CMARK_NODE_THEMATIC_BREAK:\n    cmark_html_render_cr(html);\n    cmark_strbuf_puts(html, \"<hr\");\n    cmark_html_render_sourcepos(node, html, options);\n    cmark_strbuf_puts(html, \" />\\n\");\n    break;\n\n  case CMARK_NODE_PARAGRAPH:\n    parent = cmark_node_parent(node);\n    grandparent = cmark_node_parent(parent);\n    if (grandparent != NULL && grandparent->type == CMARK_NODE_LIST) {\n      tight = grandparent->as.list.tight;\n    } else {\n      tight = false;\n    }\n    if (!tight) {\n      if (entering) {\n        cmark_html_render_cr(html);\n        cmark_strbuf_puts(html, \"<p\");\n        cmark_html_render_sourcepos(node, html, options);\n        cmark_strbuf_putc(html, '>');\n      } else {\n        if (parent->type == CMARK_NODE_FOOTNOTE_DEFINITION && node->next == NULL) {\n          cmark_strbuf_putc(html, ' ');\n          S_put_footnote_backref(renderer, html, parent);\n        }\n        cmark_strbuf_puts(html, \"</p>\\n\");\n      }\n    }\n    break;\n\n  case CMARK_NODE_TEXT:\n    escape_html(html, node->as.literal.data, node->as.literal.len);\n    break;\n\n  case CMARK_NODE_LINEBREAK:\n    cmark_strbuf_puts(html, \"<br />\\n\");\n    break;\n\n  case CMARK_NODE_SOFTBREAK:\n    if (options & CMARK_OPT_HARDBREAKS) {\n      cmark_strbuf_puts(html, \"<br />\\n\");\n    } else if (options & CMARK_OPT_NOBREAKS) {\n      cmark_strbuf_putc(html, ' ');\n    } else {\n      cmark_strbuf_putc(html, '\\n');\n    }\n    break;\n\n  case CMARK_NODE_CODE:\n    cmark_strbuf_puts(html, \"<code>\");\n    escape_html(html, node->as.literal.data, node->as.literal.len);\n    cmark_strbuf_puts(html, \"</code>\");\n    break;\n\n  case CMARK_NODE_HTML_INLINE:\n    if (!(options & CMARK_OPT_UNSAFE)) {\n      cmark_strbuf_puts(html, \"<!-- raw HTML omitted -->\");\n    } else {\n      filtered = false;\n      for (it = renderer->filter_extensions; it; it = it->next) {\n        ext = (cmark_syntax_extension *) it->data;\n        if (!ext->html_filter_func(ext, node->as.literal.data, node->as.literal.len)) {\n          filtered = true;\n          break;\n        }\n      }\n      if (!filtered) {\n        cmark_strbuf_put(html, node->as.literal.data, node->as.literal.len);\n      } else {\n        cmark_strbuf_puts(html, \"&lt;\");\n        cmark_strbuf_put(html, node->as.literal.data + 1, node->as.literal.len - 1);\n      }\n    }\n    break;\n\n  case CMARK_NODE_CUSTOM_INLINE:\n    if (entering) {\n      cmark_strbuf_put(html, node->as.custom.on_enter.data,\n                       node->as.custom.on_enter.len);\n    } else {\n      cmark_strbuf_put(html, node->as.custom.on_exit.data,\n                       node->as.custom.on_exit.len);\n    }\n    break;\n\n  case CMARK_NODE_STRONG:\n    if (node->parent == NULL || node->parent->type != CMARK_NODE_STRONG) {\n      if (entering) {\n        cmark_strbuf_puts(html, \"<strong>\");\n      } else {\n        cmark_strbuf_puts(html, \"</strong>\");\n      }\n    }\n    break;\n\n  case CMARK_NODE_EMPH:\n    if (entering) {\n      cmark_strbuf_puts(html, \"<em>\");\n    } else {\n      cmark_strbuf_puts(html, \"</em>\");\n    }\n    break;\n\n  case CMARK_NODE_LINK:\n    if (entering) {\n      cmark_strbuf_puts(html, \"<a href=\\\"\");\n      if ((options & CMARK_OPT_UNSAFE) ||\n            !(scan_dangerous_url(&node->as.link.url, 0))) {\n        houdini_escape_href(html, node->as.link.url.data,\n                            node->as.link.url.len);\n      }\n      if (node->as.link.title.len) {\n        cmark_strbuf_puts(html, \"\\\" title=\\\"\");\n        escape_html(html, node->as.link.title.data, node->as.link.title.len);\n      }\n      cmark_strbuf_puts(html, \"\\\">\");\n    } else {\n      cmark_strbuf_puts(html, \"</a>\");\n    }\n    break;\n\n  case CMARK_NODE_IMAGE:\n    if (entering) {\n      cmark_strbuf_puts(html, \"<img src=\\\"\");\n      if ((options & CMARK_OPT_UNSAFE) ||\n            !(scan_dangerous_url(&node->as.link.url, 0))) {\n        houdini_escape_href(html, node->as.link.url.data,\n                            node->as.link.url.len);\n      }\n      cmark_strbuf_puts(html, \"\\\" alt=\\\"\");\n      renderer->plain = node;\n    } else {\n      if (node->as.link.title.len) {\n        cmark_strbuf_puts(html, \"\\\" title=\\\"\");\n        escape_html(html, node->as.link.title.data, node->as.link.title.len);\n      }\n\n      cmark_strbuf_puts(html, \"\\\" />\");\n    }\n    break;\n\n  case CMARK_NODE_FOOTNOTE_DEFINITION:\n    if (entering) {\n      if (renderer->footnote_ix == 0) {\n        cmark_strbuf_puts(html, \"<section class=\\\"footnotes\\\" data-footnotes>\\n<ol>\\n\");\n      }\n      ++renderer->footnote_ix;\n\n      cmark_strbuf_puts(html, \"<li id=\\\"fn-\");\n      houdini_escape_href(html, node->as.literal.data, node->as.literal.len);\n      cmark_strbuf_puts(html, \"\\\">\\n\");\n    } else {\n      if (S_put_footnote_backref(renderer, html, node)) {\n        cmark_strbuf_putc(html, '\\n');\n      }\n      cmark_strbuf_puts(html, \"</li>\\n\");\n    }\n    break;\n\n  case CMARK_NODE_FOOTNOTE_REFERENCE:\n    if (entering) {\n      cmark_strbuf_puts(html, \"<sup class=\\\"footnote-ref\\\"><a href=\\\"#fn-\");\n      houdini_escape_href(html, node->parent_footnote_def->as.literal.data, node->parent_footnote_def->as.literal.len);\n      cmark_strbuf_puts(html, \"\\\" id=\\\"fnref-\");\n      houdini_escape_href(html, node->parent_footnote_def->as.literal.data, node->parent_footnote_def->as.literal.len);\n\n      if (node->footnote.ref_ix > 1) {\n        char n[32];\n        snprintf(n, sizeof(n), \"%d\", node->footnote.ref_ix);\n        cmark_strbuf_puts(html, \"-\");\n        cmark_strbuf_puts(html, n);\n      }\n\n      cmark_strbuf_puts(html, \"\\\" data-footnote-ref>\");\n      houdini_escape_href(html, node->as.literal.data, node->as.literal.len);\n      cmark_strbuf_puts(html, \"</a></sup>\");\n    }\n    break;\n\n  default:\n    assert(false);\n    break;\n  }\n\n  return 1;\n}\n\nchar *cmark_render_html(cmark_node *root, int options, cmark_llist *extensions) {\n  return cmark_render_html_with_mem(root, options, extensions, cmark_node_mem(root));\n}\n\nchar *cmark_render_html_with_mem(cmark_node *root, int options, cmark_llist *extensions, cmark_mem *mem) {\n  char *result;\n  cmark_strbuf html = CMARK_BUF_INIT(mem);\n  cmark_event_type ev_type;\n  cmark_node *cur;\n  cmark_html_renderer renderer = {&html, NULL, NULL, 0, 0, NULL};\n  cmark_iter *iter = cmark_iter_new(root);\n\n  for (; extensions; extensions = extensions->next)\n    if (((cmark_syntax_extension *) extensions->data)->html_filter_func)\n      renderer.filter_extensions = cmark_llist_append(\n          mem,\n          renderer.filter_extensions,\n          (cmark_syntax_extension *) extensions->data);\n\n  while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {\n    cur = cmark_iter_get_node(iter);\n    S_render_node(&renderer, cur, ev_type, options);\n  }\n\n  if (renderer.footnote_ix) {\n    cmark_strbuf_puts(&html, \"</ol>\\n</section>\\n\");\n  }\n\n  result = (char *)cmark_strbuf_detach(&html);\n\n  cmark_llist_free(mem, renderer.filter_extensions);\n\n  cmark_iter_free(iter);\n  return result;\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/html.h",
    "content": "#ifndef CMARK_HTML_H\n#define CMARK_HTML_H\n\n#include \"buffer.h\"\n#include \"node.h\"\n\nCMARK_INLINE\nstatic void cmark_html_render_cr(cmark_strbuf *html) {\n  if (html->size && html->ptr[html->size - 1] != '\\n')\n    cmark_strbuf_putc(html, '\\n');\n}\n\n#define BUFFER_SIZE 100\n\nCMARK_INLINE \nstatic void cmark_html_render_sourcepos(cmark_node *node, cmark_strbuf *html, int options) {\n  char buffer[BUFFER_SIZE];\n  if (CMARK_OPT_SOURCEPOS & options) {\n    snprintf(buffer, BUFFER_SIZE, \" data-sourcepos=\\\"%d:%d-%d:%d\\\"\",\n             cmark_node_get_start_line(node), cmark_node_get_start_column(node),\n             cmark_node_get_end_line(node), cmark_node_get_end_column(node));\n    cmark_strbuf_puts(html, buffer);\n  }\n}\n\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/inlines.c",
    "content": "#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n\n#include \"cmark_ctype.h\"\n#include \"config.h\"\n#include \"node.h\"\n#include \"parser.h\"\n#include \"references.h\"\n#include \"cmark-gfm.h\"\n#include \"houdini.h\"\n#include \"utf8.h\"\n#include \"scanners.h\"\n#include \"inlines.h\"\n#include \"syntax_extension.h\"\n\nstatic const char *EMDASH = \"\\xE2\\x80\\x94\";\nstatic const char *ENDASH = \"\\xE2\\x80\\x93\";\nstatic const char *ELLIPSES = \"\\xE2\\x80\\xA6\";\nstatic const char *LEFTDOUBLEQUOTE = \"\\xE2\\x80\\x9C\";\nstatic const char *RIGHTDOUBLEQUOTE = \"\\xE2\\x80\\x9D\";\nstatic const char *LEFTSINGLEQUOTE = \"\\xE2\\x80\\x98\";\nstatic const char *RIGHTSINGLEQUOTE = \"\\xE2\\x80\\x99\";\n\n// Macros for creating various kinds of simple.\n#define make_str(subj, sc, ec, s) make_literal(subj, CMARK_NODE_TEXT, sc, ec, s)\n#define make_code(subj, sc, ec, s) make_literal(subj, CMARK_NODE_CODE, sc, ec, s)\n#define make_raw_html(subj, sc, ec, s) make_literal(subj, CMARK_NODE_HTML_INLINE, sc, ec, s)\n#define make_linebreak(mem) make_simple(mem, CMARK_NODE_LINEBREAK)\n#define make_softbreak(mem) make_simple(mem, CMARK_NODE_SOFTBREAK)\n#define make_emph(mem) make_simple(mem, CMARK_NODE_EMPH)\n#define make_strong(mem) make_simple(mem, CMARK_NODE_STRONG)\n\n#define MAXBACKTICKS 80\n\ntypedef struct bracket {\n  struct bracket *previous;\n  cmark_node *inl_text;\n  bufsize_t position;\n  bool image;\n  bool active;\n  bool bracket_after;\n  bool in_bracket_image0;\n  bool in_bracket_image1;\n} bracket;\n\n#define FLAG_SKIP_HTML_CDATA        (1u << 0)\n#define FLAG_SKIP_HTML_DECLARATION  (1u << 1)\n#define FLAG_SKIP_HTML_PI           (1u << 2)\n#define FLAG_SKIP_HTML_COMMENT      (1u << 3)\n\ntypedef struct subject{\n  cmark_mem *mem;\n  cmark_chunk input;\n  unsigned flags;\n  int line;\n  bufsize_t pos;\n  int block_offset;\n  int column_offset;\n  cmark_map *refmap;\n  delimiter *last_delim;\n  bracket *last_bracket;\n  bufsize_t backticks[MAXBACKTICKS + 1];\n  bool scanned_for_backticks;\n  bool no_link_openers;\n} subject;\n\n// Extensions may populate this.\nstatic int8_t SKIP_CHARS[256];\n\nstatic CMARK_INLINE bool S_is_line_end_char(char c) {\n  return (c == '\\n' || c == '\\r');\n}\n\nstatic delimiter *S_insert_emph(subject *subj, delimiter *opener,\n                                delimiter *closer);\n\nstatic int parse_inline(cmark_parser *parser, subject *subj, cmark_node *parent, int options);\n\nstatic void subject_from_buf(cmark_mem *mem, int line_number, int block_offset, subject *e,\n                             cmark_chunk *buffer, cmark_map *refmap);\nstatic bufsize_t subject_find_special_char(subject *subj, int options);\n\n// Create an inline with a literal string value.\nstatic CMARK_INLINE cmark_node *make_literal(subject *subj, cmark_node_type t,\n                                             int start_column, int end_column,\n                                             cmark_chunk s) {\n  cmark_node *e = (cmark_node *)subj->mem->calloc(1, sizeof(*e));\n  cmark_strbuf_init(subj->mem, &e->content, 0);\n  e->type = (uint16_t)t;\n  e->as.literal = s;\n  e->start_line = e->end_line = subj->line;\n  // columns are 1 based.\n  e->start_column = start_column + 1 + subj->column_offset + subj->block_offset;\n  e->end_column = end_column + 1 + subj->column_offset + subj->block_offset;\n  return e;\n}\n\n// Create an inline with no value.\nstatic CMARK_INLINE cmark_node *make_simple(cmark_mem *mem, cmark_node_type t) {\n  cmark_node *e = (cmark_node *)mem->calloc(1, sizeof(*e));\n  cmark_strbuf_init(mem, &e->content, 0);\n  e->type = (uint16_t)t;\n  return e;\n}\n\n// Like make_str, but parses entities.\nstatic cmark_node *make_str_with_entities(subject *subj,\n                                          int start_column, int end_column,\n                                          cmark_chunk *content) {\n  cmark_strbuf unescaped = CMARK_BUF_INIT(subj->mem);\n\n  if (houdini_unescape_html(&unescaped, content->data, content->len)) {\n    return make_str(subj, start_column, end_column, cmark_chunk_buf_detach(&unescaped));\n  } else {\n    return make_str(subj, start_column, end_column, *content);\n  }\n}\n\n// Like cmark_node_append_child but without costly sanity checks.\n// Assumes that child was newly created.\nstatic void append_child(cmark_node *node, cmark_node *child) {\n  cmark_node *old_last_child = node->last_child;\n\n  child->next = NULL;\n  child->prev = old_last_child;\n  child->parent = node;\n  node->last_child = child;\n\n  if (old_last_child) {\n    old_last_child->next = child;\n  } else {\n    // Also set first_child if node previously had no children.\n    node->first_child = child;\n  }\n}\n\n// Duplicate a chunk by creating a copy of the buffer not by reusing the\n// buffer like cmark_chunk_dup does.\nstatic cmark_chunk chunk_clone(cmark_mem *mem, cmark_chunk *src) {\n  cmark_chunk c;\n  bufsize_t len = src->len;\n\n  c.len = len;\n  c.data = (unsigned char *)mem->calloc(len + 1, 1);\n  c.alloc = 1;\n  if (len)\n    memcpy(c.data, src->data, len);\n  c.data[len] = '\\0';\n\n  return c;\n}\n\nstatic cmark_chunk cmark_clean_autolink(cmark_mem *mem, cmark_chunk *url,\n                                        int is_email) {\n  cmark_strbuf buf = CMARK_BUF_INIT(mem);\n\n  cmark_chunk_trim(url);\n\n  if (url->len == 0) {\n    cmark_chunk result = CMARK_CHUNK_EMPTY;\n    return result;\n  }\n\n  if (is_email)\n    cmark_strbuf_puts(&buf, \"mailto:\");\n\n  houdini_unescape_html_f(&buf, url->data, url->len);\n  return cmark_chunk_buf_detach(&buf);\n}\n\nstatic CMARK_INLINE cmark_node *make_autolink(subject *subj,\n                                              int start_column, int end_column,\n                                              cmark_chunk url, int is_email) {\n  cmark_node *link = make_simple(subj->mem, CMARK_NODE_LINK);\n  link->as.link.url = cmark_clean_autolink(subj->mem, &url, is_email);\n  link->as.link.title = cmark_chunk_literal(\"\");\n  link->start_line = link->end_line = subj->line;\n  link->start_column = start_column + 1;\n  link->end_column = end_column + 1;\n  append_child(link, make_str_with_entities(subj, start_column + 1, end_column - 1, &url));\n  return link;\n}\n\nstatic void subject_from_buf(cmark_mem *mem, int line_number, int block_offset, subject *e,\n                             cmark_chunk *chunk, cmark_map *refmap) {\n  int i;\n  e->mem = mem;\n  e->input = *chunk;\n  e->flags = 0;\n  e->line = line_number;\n  e->pos = 0;\n  e->block_offset = block_offset;\n  e->column_offset = 0;\n  e->refmap = refmap;\n  e->last_delim = NULL;\n  e->last_bracket = NULL;\n  for (i = 0; i <= MAXBACKTICKS; i++) {\n    e->backticks[i] = 0;\n  }\n  e->scanned_for_backticks = false;\n  e->no_link_openers = true;\n}\n\nstatic CMARK_INLINE int isbacktick(int c) { return (c == '`'); }\n\nstatic CMARK_INLINE unsigned char peek_char_n(subject *subj, bufsize_t n) {\n  // NULL bytes should have been stripped out by now.  If they're\n  // present, it's a programming error:\n  assert(!(subj->pos + n < subj->input.len && subj->input.data[subj->pos + n] == 0));\n  return (subj->pos + n < subj->input.len) ? subj->input.data[subj->pos + n] : 0;\n}\n\nstatic CMARK_INLINE unsigned char peek_char(subject *subj) {\n  return peek_char_n(subj, 0);\n}\n\nstatic CMARK_INLINE unsigned char peek_at(subject *subj, bufsize_t pos) {\n  return subj->input.data[pos];\n}\n\n// Return true if there are more characters in the subject.\nstatic CMARK_INLINE int is_eof(subject *subj) {\n  return (subj->pos >= subj->input.len);\n}\n\n// Advance the subject.  Doesn't check for eof.\n#define advance(subj) (subj)->pos += 1\n\nstatic CMARK_INLINE bool skip_spaces(subject *subj) {\n  bool skipped = false;\n  while (peek_char(subj) == ' ' || peek_char(subj) == '\\t') {\n    advance(subj);\n    skipped = true;\n  }\n  return skipped;\n}\n\nstatic CMARK_INLINE bool skip_line_end(subject *subj) {\n  bool seen_line_end_char = false;\n  if (peek_char(subj) == '\\r') {\n    advance(subj);\n    seen_line_end_char = true;\n  }\n  if (peek_char(subj) == '\\n') {\n    advance(subj);\n    seen_line_end_char = true;\n  }\n  return seen_line_end_char || is_eof(subj);\n}\n\n// Take characters while a predicate holds, and return a string.\nstatic CMARK_INLINE cmark_chunk take_while(subject *subj, int (*f)(int)) {\n  unsigned char c;\n  bufsize_t startpos = subj->pos;\n  bufsize_t len = 0;\n\n  while ((c = peek_char(subj)) && (*f)(c)) {\n    advance(subj);\n    len++;\n  }\n\n  return cmark_chunk_dup(&subj->input, startpos, len);\n}\n\n// Return the number of newlines in a given span of text in a subject.  If\n// the number is greater than zero, also return the number of characters\n// between the last newline and the end of the span in `since_newline`.\nstatic int count_newlines(subject *subj, bufsize_t from, bufsize_t len, int *since_newline) {\n  int nls = 0;\n  int since_nl = 0;\n\n  while (len--) {\n    if (subj->input.data[from++] == '\\n') {\n      ++nls;\n      since_nl = 0;\n    } else {\n      ++since_nl;\n    }\n  }\n\n  if (!nls)\n    return 0;\n\n  *since_newline = since_nl;\n  return nls;\n}\n\n// Adjust `node`'s `end_line`, `end_column`, and `subj`'s `line` and\n// `column_offset` according to the number of newlines in a just-matched span\n// of text in `subj`.\nstatic void adjust_subj_node_newlines(subject *subj, cmark_node *node, int matchlen, int extra, int options) {\n  if (!(options & CMARK_OPT_SOURCEPOS)) {\n    return;\n  }\n\n  int since_newline;\n  int newlines = count_newlines(subj, subj->pos - matchlen - extra, matchlen, &since_newline);\n  if (newlines) {\n    subj->line += newlines;\n    node->end_line += newlines;\n    node->end_column = since_newline;\n    subj->column_offset = -subj->pos + since_newline + extra;\n  }\n}\n\n// Try to process a backtick code span that began with a\n// span of ticks of length openticklength length (already\n// parsed).  Return 0 if you don't find matching closing\n// backticks, otherwise return the position in the subject\n// after the closing backticks.\nstatic bufsize_t scan_to_closing_backticks(subject *subj,\n                                           bufsize_t openticklength) {\n\n  bool found = false;\n  if (openticklength > MAXBACKTICKS) {\n    // we limit backtick string length because of the array subj->backticks:\n    return 0;\n  }\n  if (subj->scanned_for_backticks &&\n      subj->backticks[openticklength] <= subj->pos) {\n    // return if we already know there's no closer\n    return 0;\n  }\n  while (!found) {\n    // read non backticks\n    unsigned char c;\n    while ((c = peek_char(subj)) && c != '`') {\n      advance(subj);\n    }\n    if (is_eof(subj)) {\n      break;\n    }\n    bufsize_t numticks = 0;\n    while (peek_char(subj) == '`') {\n      advance(subj);\n      numticks++;\n    }\n    // store position of ender\n    if (numticks <= MAXBACKTICKS) {\n      subj->backticks[numticks] = subj->pos - numticks;\n    }\n    if (numticks == openticklength) {\n      return (subj->pos);\n    }\n  }\n  // got through whole input without finding closer\n  subj->scanned_for_backticks = true;\n  return 0;\n}\n\n// Destructively modify string, converting newlines to\n// spaces, then removing a single leading + trailing space,\n// unless the code span consists entirely of space characters.\nstatic void S_normalize_code(cmark_strbuf *s) {\n  bufsize_t r, w;\n  bool contains_nonspace = false;\n\n  for (r = 0, w = 0; r < s->size; ++r) {\n    switch (s->ptr[r]) {\n    case '\\r':\n      if (s->ptr[r + 1] != '\\n') {\n\ts->ptr[w++] = ' ';\n      }\n      break;\n    case '\\n':\n      s->ptr[w++] = ' ';\n      break;\n    default:\n      s->ptr[w++] = s->ptr[r];\n    }\n    if (s->ptr[r] != ' ') {\n      contains_nonspace = true;\n    }\n  }\n\n  // begins and ends with space?\n  if (contains_nonspace &&\n      s->ptr[0] == ' ' && s->ptr[w - 1] == ' ') {\n    cmark_strbuf_drop(s, 1);\n    cmark_strbuf_truncate(s, w - 2);\n  } else {\n    cmark_strbuf_truncate(s, w);\n  }\n\n}\n\n\n// Parse backtick code section or raw backticks, return an inline.\n// Assumes that the subject has a backtick at the current position.\nstatic cmark_node *handle_backticks(subject *subj, int options) {\n  cmark_chunk openticks = take_while(subj, isbacktick);\n  bufsize_t startpos = subj->pos;\n  bufsize_t endpos = scan_to_closing_backticks(subj, openticks.len);\n\n  if (endpos == 0) {      // not found\n    subj->pos = startpos; // rewind\n    return make_str(subj, subj->pos, subj->pos, openticks);\n  } else {\n    cmark_strbuf buf = CMARK_BUF_INIT(subj->mem);\n\n    cmark_strbuf_set(&buf, subj->input.data + startpos,\n                     endpos - startpos - openticks.len);\n    S_normalize_code(&buf);\n\n    cmark_node *node = make_code(subj, startpos, endpos - openticks.len - 1, cmark_chunk_buf_detach(&buf));\n    adjust_subj_node_newlines(subj, node, endpos - startpos, openticks.len, options);\n    return node;\n  }\n}\n\n\n// Scan ***, **, or * and return number scanned, or 0.\n// Advances position.\nstatic int scan_delims(subject *subj, unsigned char c, bool *can_open,\n                       bool *can_close) {\n  int numdelims = 0;\n  bufsize_t before_char_pos, after_char_pos;\n  int32_t after_char = 0;\n  int32_t before_char = 0;\n  int len;\n  bool left_flanking, right_flanking;\n\n  if (subj->pos == 0) {\n    before_char = 10;\n  } else {\n    before_char_pos = subj->pos - 1;\n    // walk back to the beginning of the UTF_8 sequence:\n    while ((peek_at(subj, before_char_pos) >> 6 == 2 || SKIP_CHARS[peek_at(subj, before_char_pos)]) && before_char_pos > 0) {\n      before_char_pos -= 1;\n    }\n    len = cmark_utf8proc_iterate(subj->input.data + before_char_pos,\n                                 subj->pos - before_char_pos, &before_char);\n    if (len == -1 || (before_char < 256 && SKIP_CHARS[(unsigned char) before_char])) {\n      before_char = 10;\n    }\n  }\n\n  if (c == '\\'' || c == '\"') {\n    numdelims++;\n    advance(subj); // limit to 1 delim for quotes\n  } else {\n    while (peek_char(subj) == c) {\n      numdelims++;\n      advance(subj);\n    }\n  }\n\n  if (subj->pos == subj->input.len) {\n    after_char = 10;\n  } else {\n    after_char_pos = subj->pos;\n    while (SKIP_CHARS[peek_at(subj, after_char_pos)] && after_char_pos < subj->input.len) {\n      after_char_pos += 1;\n    }\n    len = cmark_utf8proc_iterate(subj->input.data + after_char_pos,\n                                 subj->input.len - after_char_pos, &after_char);\n    if (len == -1 || (after_char < 256 && SKIP_CHARS[(unsigned char) after_char])) {\n    after_char = 10;\n  }\n  }\n\n  left_flanking = numdelims > 0 && !cmark_utf8proc_is_space(after_char) &&\n                  (!cmark_utf8proc_is_punctuation(after_char) ||\n                   cmark_utf8proc_is_space(before_char) ||\n                   cmark_utf8proc_is_punctuation(before_char));\n  right_flanking = numdelims > 0 && !cmark_utf8proc_is_space(before_char) &&\n                   (!cmark_utf8proc_is_punctuation(before_char) ||\n                    cmark_utf8proc_is_space(after_char) ||\n                    cmark_utf8proc_is_punctuation(after_char));\n  if (c == '_') {\n    *can_open = left_flanking &&\n                (!right_flanking || cmark_utf8proc_is_punctuation(before_char));\n    *can_close = right_flanking &&\n                 (!left_flanking || cmark_utf8proc_is_punctuation(after_char));\n  } else if (c == '\\'' || c == '\"') {\n    *can_open = left_flanking && !right_flanking &&\n\t         before_char != ']' && before_char != ')';\n    *can_close = right_flanking;\n  } else {\n    *can_open = left_flanking;\n    *can_close = right_flanking;\n  }\n  return numdelims;\n}\n\n/*\nstatic void print_delimiters(subject *subj)\n{\n        delimiter *delim;\n        delim = subj->last_delim;\n        while (delim != NULL) {\n                printf(\"Item at stack pos %p: %d %d %d next(%p) prev(%p)\\n\",\n                       (void*)delim, delim->delim_char,\n                       delim->can_open, delim->can_close,\n                       (void*)delim->next, (void*)delim->previous);\n                delim = delim->previous;\n        }\n}\n*/\n\nstatic void remove_delimiter(subject *subj, delimiter *delim) {\n  if (delim == NULL)\n    return;\n  if (delim->next == NULL) {\n    // end of list:\n    assert(delim == subj->last_delim);\n    subj->last_delim = delim->previous;\n  } else {\n    delim->next->previous = delim->previous;\n  }\n  if (delim->previous != NULL) {\n    delim->previous->next = delim->next;\n  }\n  subj->mem->free(delim);\n}\n\nstatic void pop_bracket(subject *subj) {\n  bracket *b;\n  if (subj->last_bracket == NULL)\n    return;\n  b = subj->last_bracket;\n  subj->last_bracket = subj->last_bracket->previous;\n  subj->mem->free(b);\n}\n\nstatic void push_delimiter(subject *subj, unsigned char c, bool can_open,\n                           bool can_close, cmark_node *inl_text) {\n  delimiter *delim = (delimiter *)subj->mem->calloc(1, sizeof(delimiter));\n  delim->delim_char = c;\n  delim->can_open = can_open;\n  delim->can_close = can_close;\n  delim->inl_text = inl_text;\n  delim->position = subj->pos;\n  delim->length = inl_text->as.literal.len;\n  delim->previous = subj->last_delim;\n  delim->next = NULL;\n  if (delim->previous != NULL) {\n    delim->previous->next = delim;\n  }\n  subj->last_delim = delim;\n}\n\nstatic void push_bracket(subject *subj, bool image, cmark_node *inl_text) {\n  bracket *b = (bracket *)subj->mem->calloc(1, sizeof(bracket));\n  if (subj->last_bracket != NULL) {\n    subj->last_bracket->bracket_after = true;\n    b->in_bracket_image0 = subj->last_bracket->in_bracket_image0;\n    b->in_bracket_image1 = subj->last_bracket->in_bracket_image1;\n  }\n  b->image = image;\n  b->active = true;\n  b->inl_text = inl_text;\n  b->previous = subj->last_bracket;\n  b->position = subj->pos;\n  b->bracket_after = false;\n  if (image) {\n    b->in_bracket_image1 = true;\n  } else {\n    b->in_bracket_image0 = true;\n  }\n  subj->last_bracket = b;\n  if (!image) {\n    subj->no_link_openers = false;\n  }\n}\n\n// Assumes the subject has a c at the current position.\nstatic cmark_node *handle_delim(subject *subj, unsigned char c, bool smart) {\n  bufsize_t numdelims;\n  cmark_node *inl_text;\n  bool can_open, can_close;\n  cmark_chunk contents;\n\n  numdelims = scan_delims(subj, c, &can_open, &can_close);\n\n  if (c == '\\'' && smart) {\n    contents = cmark_chunk_literal(RIGHTSINGLEQUOTE);\n  } else if (c == '\"' && smart) {\n    contents =\n        cmark_chunk_literal(can_close ? RIGHTDOUBLEQUOTE : LEFTDOUBLEQUOTE);\n  } else {\n    contents = cmark_chunk_dup(&subj->input, subj->pos - numdelims, numdelims);\n  }\n\n  inl_text = make_str(subj, subj->pos - numdelims, subj->pos - 1, contents);\n\n  if ((can_open || can_close) && (!(c == '\\'' || c == '\"') || smart)) {\n    push_delimiter(subj, c, can_open, can_close, inl_text);\n  }\n\n  return inl_text;\n}\n\n// Assumes we have a hyphen at the current position.\nstatic cmark_node *handle_hyphen(subject *subj, bool smart) {\n  int startpos = subj->pos;\n\n  advance(subj);\n\n  if (!smart || peek_char(subj) != '-') {\n    return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal(\"-\"));\n  }\n\n  while (smart && peek_char(subj) == '-') {\n    advance(subj);\n  }\n\n  int numhyphens = subj->pos - startpos;\n  int en_count = 0;\n  int em_count = 0;\n  int i;\n  cmark_strbuf buf = CMARK_BUF_INIT(subj->mem);\n\n  if (numhyphens % 3 == 0) { // if divisible by 3, use all em dashes\n    em_count = numhyphens / 3;\n  } else if (numhyphens % 2 == 0) { // if divisible by 2, use all en dashes\n    en_count = numhyphens / 2;\n  } else if (numhyphens % 3 == 2) { // use one en dash at end\n    en_count = 1;\n    em_count = (numhyphens - 2) / 3;\n  } else { // use two en dashes at the end\n    en_count = 2;\n    em_count = (numhyphens - 4) / 3;\n  }\n\n  for (i = em_count; i > 0; i--) {\n    cmark_strbuf_puts(&buf, EMDASH);\n  }\n\n  for (i = en_count; i > 0; i--) {\n    cmark_strbuf_puts(&buf, ENDASH);\n  }\n\n  return make_str(subj, startpos, subj->pos - 1, cmark_chunk_buf_detach(&buf));\n}\n\n// Assumes we have a period at the current position.\nstatic cmark_node *handle_period(subject *subj, bool smart) {\n  advance(subj);\n  if (smart && peek_char(subj) == '.') {\n    advance(subj);\n    if (peek_char(subj) == '.') {\n      advance(subj);\n      return make_str(subj, subj->pos - 3, subj->pos - 1, cmark_chunk_literal(ELLIPSES));\n    } else {\n      return make_str(subj, subj->pos - 2, subj->pos - 1, cmark_chunk_literal(\"..\"));\n    }\n  } else {\n    return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal(\".\"));\n  }\n}\n\nstatic cmark_syntax_extension *get_extension_for_special_char(cmark_parser *parser, unsigned char c) {\n  cmark_llist *tmp_ext;\n\n  for (tmp_ext = parser->inline_syntax_extensions; tmp_ext; tmp_ext=tmp_ext->next) {\n    cmark_syntax_extension *ext = (cmark_syntax_extension *) tmp_ext->data;\n    cmark_llist *tmp_char;\n    for (tmp_char = ext->special_inline_chars; tmp_char; tmp_char=tmp_char->next) {\n      unsigned char tmp_c = (unsigned char)(size_t)tmp_char->data;\n\n      if (tmp_c == c) {\n        return ext;\n      }\n    }\n  }\n\n  return NULL;\n}\n\nstatic void process_emphasis(cmark_parser *parser, subject *subj, bufsize_t stack_bottom) {\n  delimiter *candidate;\n  delimiter *closer = NULL;\n  delimiter *opener;\n  delimiter *old_closer;\n  bool opener_found;\n  bufsize_t openers_bottom[3][128];\n  int i;\n\n  // initialize openers_bottom:\n  memset(&openers_bottom, 0, sizeof(openers_bottom));\n  for (i=0; i < 3; i++) {\n    openers_bottom[i]['*'] = stack_bottom;\n    openers_bottom[i]['_'] = stack_bottom;\n    openers_bottom[i]['\\''] = stack_bottom;\n    openers_bottom[i]['\"'] = stack_bottom;\n  }\n\n  // move back to first relevant delim.\n  candidate = subj->last_delim;\n  while (candidate != NULL && candidate->position >= stack_bottom) {\n    closer = candidate;\n    candidate = candidate->previous;\n  }\n\n  // now move forward, looking for closers, and handling each\n  while (closer != NULL) {\n    cmark_syntax_extension *extension = get_extension_for_special_char(parser, closer->delim_char);\n    if (closer->can_close) {\n      // Now look backwards for first matching opener:\n      opener = closer->previous;\n      opener_found = false;\n      while (opener != NULL && opener->position >= stack_bottom &&\n             opener->position >= openers_bottom[closer->length % 3][closer->delim_char]) {\n        if (opener->can_open && opener->delim_char == closer->delim_char) {\n          // interior closer of size 2 can't match opener of size 1\n          // or of size 1 can't match 2\n          if (!(closer->can_open || opener->can_close) ||\n\t      closer->length % 3 == 0 ||\n              (opener->length + closer->length) % 3 != 0) {\n            opener_found = true;\n            break;\n          }\n        }\n        opener = opener->previous;\n      }\n      old_closer = closer;\n\n      if (extension) {\n        if (opener_found)\n          closer = extension->insert_inline_from_delim(extension, parser, subj, opener, closer);\n        else\n          closer = closer->next;\n      } else if (closer->delim_char == '*' || closer->delim_char == '_') {\n        if (opener_found) {\n          closer = S_insert_emph(subj, opener, closer);\n        } else {\n          closer = closer->next;\n        }\n      } else if (closer->delim_char == '\\'' || closer->delim_char == '\"') {\n        cmark_chunk_free(subj->mem, &closer->inl_text->as.literal);\n        if (closer->delim_char == '\\'') {\n          closer->inl_text->as.literal = cmark_chunk_literal(RIGHTSINGLEQUOTE);\n        } else {\n          closer->inl_text->as.literal = cmark_chunk_literal(RIGHTDOUBLEQUOTE);\n        }\n        closer = closer->next;\n        if (opener_found) {\n          cmark_chunk_free(subj->mem, &opener->inl_text->as.literal);\n          if (old_closer->delim_char == '\\'') {\n            opener->inl_text->as.literal = cmark_chunk_literal(LEFTSINGLEQUOTE);\n          } else {\n            opener->inl_text->as.literal = cmark_chunk_literal(LEFTDOUBLEQUOTE);\n          }\n          remove_delimiter(subj, opener);\n          remove_delimiter(subj, old_closer);\n        }\n      }\n      if (!opener_found) {\n        // set lower bound for future searches for openers\n        openers_bottom[old_closer->length % 3][old_closer->delim_char] =\n\t\told_closer->position;\n        if (!old_closer->can_open) {\n          // we can remove a closer that can't be an\n          // opener, once we've seen there's no\n          // matching opener:\n          remove_delimiter(subj, old_closer);\n        }\n      }\n    } else {\n      closer = closer->next;\n    }\n  }\n  // free all delimiters in list until stack_bottom:\n  while (subj->last_delim != NULL &&\n         subj->last_delim->position >= stack_bottom) {\n    remove_delimiter(subj, subj->last_delim);\n  }\n}\n\nstatic delimiter *S_insert_emph(subject *subj, delimiter *opener,\n                                delimiter *closer) {\n  delimiter *delim, *tmp_delim;\n  bufsize_t use_delims;\n  cmark_node *opener_inl = opener->inl_text;\n  cmark_node *closer_inl = closer->inl_text;\n  bufsize_t opener_num_chars = opener_inl->as.literal.len;\n  bufsize_t closer_num_chars = closer_inl->as.literal.len;\n  cmark_node *tmp, *tmpnext, *emph;\n\n  // calculate the actual number of characters used from this closer\n  use_delims = (closer_num_chars >= 2 && opener_num_chars >= 2) ? 2 : 1;\n\n  // remove used characters from associated inlines.\n  opener_num_chars -= use_delims;\n  closer_num_chars -= use_delims;\n  opener_inl->as.literal.len = opener_num_chars;\n  closer_inl->as.literal.len = closer_num_chars;\n\n  // free delimiters between opener and closer\n  delim = closer->previous;\n  while (delim != NULL && delim != opener) {\n    tmp_delim = delim->previous;\n    remove_delimiter(subj, delim);\n    delim = tmp_delim;\n  }\n\n  // create new emph or strong, and splice it in to our inlines\n  // between the opener and closer\n  emph = use_delims == 1 ? make_emph(subj->mem) : make_strong(subj->mem);\n\n  tmp = opener_inl->next;\n  while (tmp && tmp != closer_inl) {\n    tmpnext = tmp->next;\n    cmark_node_unlink(tmp);\n    append_child(emph, tmp);\n    tmp = tmpnext;\n  }\n  cmark_node_insert_after(opener_inl, emph);\n\n  emph->start_line = opener_inl->start_line;\n  emph->end_line = closer_inl->end_line;\n  emph->start_column = opener_inl->start_column;\n  emph->end_column = closer_inl->end_column;\n\n  // if opener has 0 characters, remove it and its associated inline\n  if (opener_num_chars == 0) {\n    cmark_node_free(opener_inl);\n    remove_delimiter(subj, opener);\n  }\n\n  // if closer has 0 characters, remove it and its associated inline\n  if (closer_num_chars == 0) {\n    // remove empty closer inline\n    cmark_node_free(closer_inl);\n    // remove closer from list\n    tmp_delim = closer->next;\n    remove_delimiter(subj, closer);\n    closer = tmp_delim;\n  }\n\n  return closer;\n}\n\n// Parse backslash-escape or just a backslash, returning an inline.\nstatic cmark_node *handle_backslash(cmark_parser *parser, subject *subj) {\n  advance(subj);\n  unsigned char nextchar = peek_char(subj);\n  if ((parser->backslash_ispunct ? parser->backslash_ispunct : cmark_ispunct)(nextchar)) {\n    // only ascii symbols and newline can be escaped\n    advance(subj);\n    return make_str(subj, subj->pos - 2, subj->pos - 1, cmark_chunk_dup(&subj->input, subj->pos - 1, 1));\n  } else if (!is_eof(subj) && skip_line_end(subj)) {\n    return make_linebreak(subj->mem);\n  } else {\n    return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal(\"\\\\\"));\n  }\n}\n\n// Parse an entity or a regular \"&\" string.\n// Assumes the subject has an '&' character at the current position.\nstatic cmark_node *handle_entity(subject *subj) {\n  cmark_strbuf ent = CMARK_BUF_INIT(subj->mem);\n  bufsize_t len;\n\n  advance(subj);\n\n  len = houdini_unescape_ent(&ent, subj->input.data + subj->pos,\n                             subj->input.len - subj->pos);\n\n  if (len == 0)\n    return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal(\"&\"));\n\n  subj->pos += len;\n  return make_str(subj, subj->pos - 1 - len, subj->pos - 1, cmark_chunk_buf_detach(&ent));\n}\n\n// Clean a URL: remove surrounding whitespace, and remove \\ that escape\n// punctuation.\ncmark_chunk cmark_clean_url(cmark_mem *mem, cmark_chunk *url) {\n  cmark_strbuf buf = CMARK_BUF_INIT(mem);\n\n  cmark_chunk_trim(url);\n\n  if (url->len == 0) {\n    cmark_chunk result = CMARK_CHUNK_EMPTY;\n    return result;\n  }\n\n  houdini_unescape_html_f(&buf, url->data, url->len);\n\n  cmark_strbuf_unescape(&buf);\n  return cmark_chunk_buf_detach(&buf);\n}\n\ncmark_chunk cmark_clean_title(cmark_mem *mem, cmark_chunk *title) {\n  cmark_strbuf buf = CMARK_BUF_INIT(mem);\n  unsigned char first, last;\n\n  if (title->len == 0) {\n    cmark_chunk result = CMARK_CHUNK_EMPTY;\n    return result;\n  }\n\n  first = title->data[0];\n  last = title->data[title->len - 1];\n\n  // remove surrounding quotes if any:\n  if ((first == '\\'' && last == '\\'') || (first == '(' && last == ')') ||\n      (first == '\"' && last == '\"')) {\n    houdini_unescape_html_f(&buf, title->data + 1, title->len - 2);\n  } else {\n    houdini_unescape_html_f(&buf, title->data, title->len);\n  }\n\n  cmark_strbuf_unescape(&buf);\n  return cmark_chunk_buf_detach(&buf);\n}\n\n// Parse an autolink or HTML tag.\n// Assumes the subject has a '<' character at the current position.\nstatic cmark_node *handle_pointy_brace(subject *subj, int options) {\n  bufsize_t matchlen = 0;\n  cmark_chunk contents;\n\n  advance(subj); // advance past first <\n\n  // first try to match a URL autolink\n  matchlen = scan_autolink_uri(&subj->input, subj->pos);\n  if (matchlen > 0) {\n    contents = cmark_chunk_dup(&subj->input, subj->pos, matchlen - 1);\n    subj->pos += matchlen;\n\n    return make_autolink(subj, subj->pos - 1 - matchlen, subj->pos - 1, contents, 0);\n  }\n\n  // next try to match an email autolink\n  matchlen = scan_autolink_email(&subj->input, subj->pos);\n  if (matchlen > 0) {\n    contents = cmark_chunk_dup(&subj->input, subj->pos, matchlen - 1);\n    subj->pos += matchlen;\n\n    return make_autolink(subj, subj->pos - 1 - matchlen, subj->pos - 1, contents, 1);\n  }\n\n  // finally, try to match an html tag\n  if (subj->pos + 2 <= subj->input.len) {\n    int c = subj->input.data[subj->pos];\n    if (c == '!' && (subj->flags & FLAG_SKIP_HTML_COMMENT) == 0) {\n      c = subj->input.data[subj->pos+1];\n      if (c == '-' && subj->input.data[subj->pos+2] == '-') {\n        if (subj->input.data[subj->pos+3] == '>') {\n          matchlen = 4;\n        } else if (subj->input.data[subj->pos+3] == '-' &&\n                   subj->input.data[subj->pos+4] == '>') {\n          matchlen = 5;\n        } else {\n          matchlen = scan_html_comment(&subj->input, subj->pos + 1);\n          if (matchlen > 0) {\n            matchlen += 1; // prefix \"<\"\n          } else { // no match through end of input: set a flag so\n                   // we don't reparse looking for -->:\n            subj->flags |= FLAG_SKIP_HTML_COMMENT;\n          }\n        }\n      } else if (c == '[') {\n        if ((subj->flags & FLAG_SKIP_HTML_CDATA) == 0) {\n          matchlen = scan_html_cdata(&subj->input, subj->pos + 2);\n          if (matchlen > 0) {\n            // The regex doesn't require the final \"]]>\". But if we're not at\n            // the end of input, it must come after the match. Otherwise,\n            // disable subsequent scans to avoid quadratic behavior.\n            matchlen += 5; // prefix \"![\", suffix \"]]>\"\n            if (subj->pos + matchlen > subj->input.len) {\n              subj->flags |= FLAG_SKIP_HTML_CDATA;\n              matchlen = 0;\n            }\n          }\n        }\n      } else if ((subj->flags & FLAG_SKIP_HTML_DECLARATION) == 0) {\n        matchlen = scan_html_declaration(&subj->input, subj->pos + 1);\n        if (matchlen > 0) {\n          matchlen += 2; // prefix \"!\", suffix \">\"\n          if (subj->pos + matchlen > subj->input.len) {\n            subj->flags |= FLAG_SKIP_HTML_DECLARATION;\n            matchlen = 0;\n          }\n        }\n      }\n    } else if (c == '?') {\n      if ((subj->flags & FLAG_SKIP_HTML_PI) == 0) {\n        // Note that we allow an empty match.\n        matchlen = scan_html_pi(&subj->input, subj->pos + 1);\n        matchlen += 3; // prefix \"?\", suffix \"?>\"\n        if (subj->pos + matchlen > subj->input.len) {\n          subj->flags |= FLAG_SKIP_HTML_PI;\n          matchlen = 0;\n        }\n      }\n    } else {\n      matchlen = scan_html_tag(&subj->input, subj->pos);\n    }\n  }\n  if (matchlen > 0) {\n    contents = cmark_chunk_dup(&subj->input, subj->pos - 1, matchlen + 1);\n    subj->pos += matchlen;\n    cmark_node *node = make_raw_html(subj, subj->pos - matchlen - 1, subj->pos - 1, contents);\n    adjust_subj_node_newlines(subj, node, matchlen, 1, options);\n    return node;\n  }\n\n  if (options & CMARK_OPT_LIBERAL_HTML_TAG) {\n    matchlen = scan_liberal_html_tag(&subj->input, subj->pos);\n    if (matchlen > 0) {\n      contents = cmark_chunk_dup(&subj->input, subj->pos - 1, matchlen + 1);\n      subj->pos += matchlen;\n      cmark_node *node = make_raw_html(subj, subj->pos - matchlen - 1, subj->pos - 1, contents);\n      adjust_subj_node_newlines(subj, node, matchlen, 1, options);\n      return node;\n    }\n  }\n\n  // if nothing matches, just return the opening <:\n  return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal(\"<\"));\n}\n\n// Parse a link label.  Returns 1 if successful.\n// Note:  unescaped brackets are not allowed in labels.\n// The label begins with `[` and ends with the first `]` character\n// encountered.  Backticks in labels do not start code spans.\nstatic int link_label(subject *subj, cmark_chunk *raw_label) {\n  bufsize_t startpos = subj->pos;\n  int length = 0;\n  unsigned char c;\n\n  // advance past [\n  if (peek_char(subj) == '[') {\n    advance(subj);\n  } else {\n    return 0;\n  }\n\n  while ((c = peek_char(subj)) && c != '[' && c != ']') {\n    if (c == '\\\\') {\n      advance(subj);\n      length++;\n      if (cmark_ispunct(peek_char(subj))) {\n        advance(subj);\n        length++;\n      }\n    } else {\n      advance(subj);\n      length++;\n    }\n    if (length > MAX_LINK_LABEL_LENGTH) {\n      goto noMatch;\n    }\n  }\n\n  if (c == ']') { // match found\n    *raw_label =\n        cmark_chunk_dup(&subj->input, startpos + 1, subj->pos - (startpos + 1));\n    cmark_chunk_trim(raw_label);\n    advance(subj); // advance past ]\n    return 1;\n  }\n\nnoMatch:\n  subj->pos = startpos; // rewind\n  return 0;\n}\n\nstatic bufsize_t manual_scan_link_url_2(cmark_chunk *input, bufsize_t offset,\n                                        cmark_chunk *output) {\n  bufsize_t i = offset;\n  size_t nb_p = 0;\n\n  while (i < input->len) {\n    if (input->data[i] == '\\\\' &&\n        i + 1 < input-> len &&\n        cmark_ispunct(input->data[i+1]))\n      i += 2;\n    else if (input->data[i] == '(') {\n      ++nb_p;\n      ++i;\n      if (nb_p > 32)\n        return -1;\n    } else if (input->data[i] == ')') {\n      if (nb_p == 0)\n        break;\n      --nb_p;\n      ++i;\n    } else if (cmark_isspace(input->data[i])) {\n      if (i == offset) {\n        return -1;\n      }\n      break;\n    } else {\n      ++i;\n    }\n  }\n\n  if (i >= input->len)\n    return -1;\n\n  {\n    cmark_chunk result = {input->data + offset, i - offset, 0};\n    *output = result;\n  }\n  return i - offset;\n}\n\nstatic bufsize_t manual_scan_link_url(cmark_chunk *input, bufsize_t offset,\n                                      cmark_chunk *output) {\n  bufsize_t i = offset;\n\n  if (i < input->len && input->data[i] == '<') {\n    ++i;\n    while (i < input->len) {\n      if (input->data[i] == '>') {\n        ++i;\n        break;\n      } else if (input->data[i] == '\\\\')\n        i += 2;\n      else if (input->data[i] == '\\n' || input->data[i] == '<')\n        return -1;\n      else\n        ++i;\n    }\n  } else {\n    return manual_scan_link_url_2(input, offset, output);\n  }\n\n  if (i >= input->len)\n    return -1;\n\n  {\n    cmark_chunk result = {input->data + offset + 1, i - 2 - offset, 0};\n    *output = result;\n  }\n  return i - offset;\n}\n\n// Return a link, an image, or a literal close bracket.\nstatic cmark_node *handle_close_bracket(cmark_parser *parser, subject *subj) {\n  bufsize_t initial_pos, after_link_text_pos;\n  bufsize_t endurl, starttitle, endtitle, endall;\n  bufsize_t sps, n;\n  cmark_reference *ref = NULL;\n  cmark_chunk url_chunk, title_chunk;\n  cmark_chunk url, title;\n  bracket *opener;\n  cmark_node *inl;\n  cmark_chunk raw_label;\n  int found_label;\n  cmark_node *tmp, *tmpnext;\n  bool is_image;\n\n  advance(subj); // advance past ]\n  initial_pos = subj->pos;\n\n  // get last [ or ![\n  opener = subj->last_bracket;\n\n  if (opener == NULL) {\n    return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal(\"]\"));\n  }\n\n  // If we got here, we matched a potential link/image text.\n  // Now we check to see if it's a link/image.\n  is_image = opener->image;\n\n  if (!is_image && subj->no_link_openers) {\n    // take delimiter off stack\n    pop_bracket(subj);\n    return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal(\"]\"));\n  }\n\n  after_link_text_pos = subj->pos;\n\n  // First, look for an inline link.\n  if (peek_char(subj) == '(' &&\n      ((sps = scan_spacechars(&subj->input, subj->pos + 1)) > -1) &&\n      ((n = manual_scan_link_url(&subj->input, subj->pos + 1 + sps,\n                                 &url_chunk)) > -1)) {\n\n    // try to parse an explicit link:\n    endurl = subj->pos + 1 + sps + n;\n    starttitle = endurl + scan_spacechars(&subj->input, endurl);\n\n    // ensure there are spaces btw url and title\n    endtitle = (starttitle == endurl)\n                   ? starttitle\n                   : starttitle + scan_link_title(&subj->input, starttitle);\n\n    endall = endtitle + scan_spacechars(&subj->input, endtitle);\n\n    if (peek_at(subj, endall) == ')') {\n      subj->pos = endall + 1;\n\n      title_chunk =\n          cmark_chunk_dup(&subj->input, starttitle, endtitle - starttitle);\n      url = cmark_clean_url(subj->mem, &url_chunk);\n      title = cmark_clean_title(subj->mem, &title_chunk);\n      cmark_chunk_free(subj->mem, &url_chunk);\n      cmark_chunk_free(subj->mem, &title_chunk);\n      goto match;\n\n    } else {\n      // it could still be a shortcut reference link\n      subj->pos = after_link_text_pos;\n    }\n  }\n\n  // Next, look for a following [link label] that matches in refmap.\n  // skip spaces\n  raw_label = cmark_chunk_literal(\"\");\n  found_label = link_label(subj, &raw_label);\n  if (!found_label) {\n    // If we have a shortcut reference link, back up\n    // to before the spacse we skipped.\n    subj->pos = initial_pos;\n  }\n\n  if ((!found_label || raw_label.len == 0) && !opener->bracket_after) {\n    cmark_chunk_free(subj->mem, &raw_label);\n    raw_label = cmark_chunk_dup(&subj->input, opener->position,\n                                initial_pos - opener->position - 1);\n    found_label = true;\n  }\n\n  if (found_label) {\n    ref = (cmark_reference *)cmark_map_lookup(subj->refmap, &raw_label);\n    cmark_chunk_free(subj->mem, &raw_label);\n  }\n\n  if (ref != NULL) { // found\n    url = chunk_clone(subj->mem, &ref->url);\n    title = chunk_clone(subj->mem, &ref->title);\n    goto match;\n  } else {\n    goto noMatch;\n  }\n\nnoMatch:\n  // If we fall through to here, it means we didn't match a link.\n  // What if we're a footnote link?\n  if (parser->options & CMARK_OPT_FOOTNOTES &&\n      opener->inl_text->next &&\n      opener->inl_text->next->type == CMARK_NODE_TEXT) {\n\n    cmark_chunk *literal = &opener->inl_text->next->as.literal;\n\n    // look back to the opening '[', and skip ahead to the next character\n    // if we're looking at a '[^' sequence, and there is other text or nodes\n    // after the ^, let's call it a footnote reference.\n    if ((literal->len > 0 && literal->data[0] == '^') && (literal->len > 1 || opener->inl_text->next->next)) {\n\n      // Before we got this far, the `handle_close_bracket` function may have\n      // advanced the current state beyond our footnote's actual closing\n      // bracket, ie if it went looking for a `link_label`.\n      // Let's just rewind the subject's position:\n      subj->pos = initial_pos;\n\n      cmark_node *fnref = make_simple(subj->mem, CMARK_NODE_FOOTNOTE_REFERENCE);\n\n      // the start and end of the footnote ref is the opening and closing brace\n      // i.e. the subject's current position, and the opener's start_column\n      int fnref_end_column = subj->pos + subj->column_offset + subj->block_offset;\n      int fnref_start_column = opener->inl_text->start_column;\n\n      // any given node delineates a substring of the line being processed,\n      // with the remainder of the line being pointed to thru its 'literal'\n      // struct member.\n      // here, we copy the literal's pointer, moving it past the '^' character\n      // for a length equal to the size of footnote reference text.\n      // i.e. end_col minus start_col, minus the [ and the ^ characters\n      //\n      // this copies the footnote reference string, even if between the\n      // `opener` and the subject's current position there are other nodes\n      //\n      // (first, check for underflows)\n      if ((fnref_start_column + 2) <= fnref_end_column) {\n        fnref->as.literal = cmark_chunk_dup(literal, 1, (fnref_end_column - fnref_start_column) - 2);\n      } else {\n        fnref->as.literal = cmark_chunk_dup(literal, 1, 0);\n      }\n\n      fnref->start_line = fnref->end_line = subj->line;\n      fnref->start_column = fnref_start_column;\n      fnref->end_column = fnref_end_column;\n\n      // we then replace the opener with this new fnref node, the net effect\n      // being replacing the opening '[' text node with a `^footnote-ref]` node.\n      cmark_node_insert_before(opener->inl_text, fnref);\n\n      process_emphasis(parser, subj, opener->position);\n      // sometimes, the footnote reference text gets parsed into multiple nodes\n      // i.e. '[^example]' parsed into '[', '^exam', 'ple]'.\n      // this happens for ex with the autolink extension. when the autolinker\n      // finds the 'w' character, it will split the text into multiple nodes\n      // in hopes of being able to match a 'www.' substring.\n      //\n      // because this function is called one character at a time via the\n      // `parse_inlines` function, and the current subj->pos is pointing at the\n      // closing ] brace, and because we copy all the text between the [ ]\n      // braces, we should be able to safely ignore and delete any nodes after\n      // the opener->inl_text->next.\n      //\n      // therefore, here we walk thru the list and free them all up\n      cmark_node *next_node;\n      cmark_node *current_node = opener->inl_text->next;\n      while(current_node) {\n        next_node = current_node->next;\n        cmark_node_free(current_node);\n        current_node = next_node;\n      }\n\n      cmark_node_free(opener->inl_text);\n\n      pop_bracket(subj);\n      return NULL;\n    }\n  }\n\n  pop_bracket(subj); // remove this opener from delimiter list\n  subj->pos = initial_pos;\n  return make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal(\"]\"));\n\nmatch:\n  inl = make_simple(subj->mem, is_image ? CMARK_NODE_IMAGE : CMARK_NODE_LINK);\n  inl->as.link.url = url;\n  inl->as.link.title = title;\n  inl->start_line = inl->end_line = subj->line;\n  inl->start_column = opener->inl_text->start_column;\n  inl->end_column = subj->pos + subj->column_offset + subj->block_offset;\n  cmark_node_insert_before(opener->inl_text, inl);\n  // Add link text:\n  tmp = opener->inl_text->next;\n  while (tmp) {\n    tmpnext = tmp->next;\n    cmark_node_unlink(tmp);\n    append_child(inl, tmp);\n    tmp = tmpnext;\n  }\n\n  // Free the bracket [:\n  cmark_node_free(opener->inl_text);\n\n  process_emphasis(parser, subj, opener->position);\n  pop_bracket(subj);\n\n  // Now, if we have a link, we also want to deactivate links until\n  // we get a new opener. (This code can be removed if we decide to allow links\n  // inside links.)\n  if (!is_image) {\n    subj->no_link_openers = true;\n  }\n\n  return NULL;\n}\n\n// Parse a hard or soft linebreak, returning an inline.\n// Assumes the subject has a cr or newline at the current position.\nstatic cmark_node *handle_newline(subject *subj) {\n  bufsize_t nlpos = subj->pos;\n  // skip over cr, crlf, or lf:\n  if (peek_at(subj, subj->pos) == '\\r') {\n    advance(subj);\n  }\n  if (peek_at(subj, subj->pos) == '\\n') {\n    advance(subj);\n  }\n  ++subj->line;\n  subj->column_offset = -subj->pos;\n  // skip spaces at beginning of line\n  skip_spaces(subj);\n  if (nlpos > 1 && peek_at(subj, nlpos - 1) == ' ' &&\n      peek_at(subj, nlpos - 2) == ' ') {\n    return make_linebreak(subj->mem);\n  } else if (oneEnterNewlineEnable == 1 && nlpos > 1 && peek_at(subj, nlpos - 1) != '\\n' &&\n        peek_at(subj, nlpos + 1) != '\\n') {\n      return make_linebreak(subj->mem);\n    } else {\n    return make_softbreak(subj->mem);\n  }\n}\n\n// \"\\r\\n\\\\`&_*[]<!\"\nstatic int8_t SPECIAL_CHARS[256] = {\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1,\n      1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};\n\n// \" ' . -\nstatic char SMART_PUNCT_CHARS[] = {\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n};\n\nstatic bufsize_t subject_find_special_char(subject *subj, int options) {\n  bufsize_t n = subj->pos + 1;\n\n  while (n < subj->input.len) {\n    if (SPECIAL_CHARS[subj->input.data[n]])\n      return n;\n    if (options & CMARK_OPT_SMART && SMART_PUNCT_CHARS[subj->input.data[n]])\n      return n;\n    n++;\n  }\n\n  return subj->input.len;\n}\n\nvoid cmark_inlines_add_special_character(unsigned char c, bool emphasis) {\n  SPECIAL_CHARS[c] = 1;\n  if (emphasis)\n    SKIP_CHARS[c] = 1;\n}\n\nvoid cmark_inlines_remove_special_character(unsigned char c, bool emphasis) {\n  SPECIAL_CHARS[c] = 0;\n  if (emphasis)\n    SKIP_CHARS[c] = 0;\n}\n\nstatic cmark_node *try_extensions(cmark_parser *parser,\n                                  cmark_node *parent,\n                                  unsigned char c,\n                                  subject *subj) {\n  cmark_node *res = NULL;\n  cmark_llist *tmp;\n\n  for (tmp = parser->inline_syntax_extensions; tmp; tmp = tmp->next) {\n    cmark_syntax_extension *ext = (cmark_syntax_extension *) tmp->data;\n    res = ext->match_inline(ext, parser, parent, c, subj);\n\n    if (res)\n      break;\n  }\n\n  return res;\n}\n\n// Parse an inline, advancing subject, and add it as a child of parent.\n// Return 0 if no inline can be parsed, 1 otherwise.\nstatic int parse_inline(cmark_parser *parser, subject *subj, cmark_node *parent, int options) {\n  cmark_node *new_inl = NULL;\n  cmark_chunk contents;\n  unsigned char c;\n  bufsize_t startpos, endpos;\n  c = peek_char(subj);\n  if (c == 0) {\n    return 0;\n  }\n  switch (c) {\n  case '\\r':\n  case '\\n':\n    new_inl = handle_newline(subj);\n    break;\n  case '`':\n    new_inl = handle_backticks(subj, options);\n    break;\n  case '\\\\':\n    new_inl = try_extensions(parser, parent, c, subj);\n    if (new_inl != NULL)\n        break;\n    new_inl = handle_backslash(parser, subj);\n    break;\n  case '&':\n    new_inl = handle_entity(subj);\n    break;\n  case '<':\n    new_inl = handle_pointy_brace(subj, options);\n    break;\n  case '*':\n  case '_':\n  case '\\'':\n  case '\"':\n    new_inl = handle_delim(subj, c, (options & CMARK_OPT_SMART) != 0);\n    break;\n  case '-':\n    new_inl = handle_hyphen(subj, (options & CMARK_OPT_SMART) != 0);\n    break;\n  case '.':\n    new_inl = handle_period(subj, (options & CMARK_OPT_SMART) != 0);\n    break;\n  case '[':\n    advance(subj);\n    new_inl = make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal(\"[\"));\n    push_bracket(subj, false, new_inl);\n    break;\n  case ']':\n    new_inl = handle_close_bracket(parser, subj);\n    break;\n  case '!':\n    advance(subj);\n    if (peek_char(subj) == '[' && peek_char_n(subj, 1) != '^') {\n      advance(subj);\n      new_inl = make_str(subj, subj->pos - 2, subj->pos - 1, cmark_chunk_literal(\"![\"));\n      push_bracket(subj, true, new_inl);\n    } else {\n      new_inl = make_str(subj, subj->pos - 1, subj->pos - 1, cmark_chunk_literal(\"!\"));\n    }\n    break;\n  default:\n    new_inl = try_extensions(parser, parent, c, subj);\n    if (new_inl != NULL)\n      break;\n\n    endpos = subject_find_special_char(subj, options);\n    contents = cmark_chunk_dup(&subj->input, subj->pos, endpos - subj->pos);\n    startpos = subj->pos;\n    subj->pos = endpos;\n\n    // if we're at a newline, strip trailing spaces.\n    if (S_is_line_end_char(peek_char(subj))) {\n      cmark_chunk_rtrim(&contents);\n    }\n\n    new_inl = make_str(subj, startpos, endpos - 1, contents);\n  }\n  if (new_inl != NULL) {\n    append_child(parent, new_inl);\n  }\n\n  return 1;\n}\n\n// Parse inlines from parent's string_content, adding as children of parent.\nvoid cmark_parse_inlines(cmark_parser *parser,\n                         cmark_node *parent,\n                         cmark_map *refmap,\n                         int options) {\n  subject subj;\n  cmark_chunk content = {parent->content.ptr, parent->content.size, 0};\n  subject_from_buf(parser->mem, parent->start_line, parent->start_column - 1 + parent->internal_offset, &subj, &content, refmap);\n  cmark_chunk_rtrim(&subj.input);\n\n  while (!is_eof(&subj) && parse_inline(parser, &subj, parent, options))\n    ;\n\n  process_emphasis(parser, &subj, 0);\n  // free bracket and delim stack\n  while (subj.last_delim) {\n    remove_delimiter(&subj, subj.last_delim);\n  }\n  while (subj.last_bracket) {\n    pop_bracket(&subj);\n  }\n}\n\n// Parse zero or more space characters, including at most one newline.\nstatic void spnl(subject *subj) {\n  skip_spaces(subj);\n  if (skip_line_end(subj)) {\n    skip_spaces(subj);\n  }\n}\n\n// Parse reference.  Assumes string begins with '[' character.\n// Modify refmap if a reference is encountered.\n// Return 0 if no reference found, otherwise position of subject\n// after reference is parsed.\nbufsize_t cmark_parse_reference_inline(cmark_mem *mem, cmark_chunk *input,\n                                       cmark_map *refmap) {\n  subject subj;\n\n  cmark_chunk lab;\n  cmark_chunk url;\n  cmark_chunk title;\n\n  bufsize_t matchlen = 0;\n  bufsize_t beforetitle;\n\n  subject_from_buf(mem, -1, 0, &subj, input, NULL);\n\n  // parse label:\n  if (!link_label(&subj, &lab) || lab.len == 0)\n    return 0;\n\n  // colon:\n  if (peek_char(&subj) == ':') {\n    advance(&subj);\n  } else {\n    return 0;\n  }\n\n  // parse link url:\n  spnl(&subj);\n  if ((matchlen = manual_scan_link_url(&subj.input, subj.pos, &url)) > -1) {\n    subj.pos += matchlen;\n  } else {\n    return 0;\n  }\n\n  // parse optional link_title\n  beforetitle = subj.pos;\n  spnl(&subj);\n  matchlen = subj.pos == beforetitle ? 0 : scan_link_title(&subj.input, subj.pos);\n  if (matchlen) {\n    title = cmark_chunk_dup(&subj.input, subj.pos, matchlen);\n    subj.pos += matchlen;\n  } else {\n    subj.pos = beforetitle;\n    title = cmark_chunk_literal(\"\");\n  }\n\n  // parse final spaces and newline:\n  skip_spaces(&subj);\n  if (!skip_line_end(&subj)) {\n    if (matchlen) { // try rewinding before title\n      subj.pos = beforetitle;\n      skip_spaces(&subj);\n      if (!skip_line_end(&subj)) {\n        return 0;\n      }\n    } else {\n      return 0;\n    }\n  }\n  // insert reference into refmap\n  cmark_reference_create(refmap, &lab, &url, &title);\n  return subj.pos;\n}\n\nunsigned char cmark_inline_parser_peek_char(cmark_inline_parser *parser) {\n  return peek_char(parser);\n}\n\nunsigned char cmark_inline_parser_peek_at(cmark_inline_parser *parser, bufsize_t pos) {\n  return peek_at(parser, pos);\n}\n\nint cmark_inline_parser_is_eof(cmark_inline_parser *parser) {\n  return is_eof(parser);\n}\n\nstatic char *\nmy_strndup (const char *s, size_t n)\n{\n  char *result;\n  size_t len = strlen (s);\n\n  if (n < len)\n    len = n;\n\n  result = (char *) malloc (len + 1);\n  if (!result)\n    return 0;\n\n  result[len] = '\\0';\n  return (char *) memcpy (result, s, len);\n}\n\nchar *cmark_inline_parser_take_while(cmark_inline_parser *parser, cmark_inline_predicate pred) {\n  unsigned char c;\n  bufsize_t startpos = parser->pos;\n  bufsize_t len = 0;\n\n  while ((c = peek_char(parser)) && (*pred)(c)) {\n    advance(parser);\n    len++;\n  }\n\n  return my_strndup((const char *) parser->input.data + startpos, len);\n}\n\nvoid cmark_inline_parser_push_delimiter(cmark_inline_parser *parser,\n                                  unsigned char c,\n                                  int can_open,\n                                  int can_close,\n                                  cmark_node *inl_text) {\n  push_delimiter(parser, c, can_open != 0, can_close != 0, inl_text);\n}\n\nvoid cmark_inline_parser_remove_delimiter(cmark_inline_parser *parser, delimiter *delim) {\n  remove_delimiter(parser, delim);\n}\n\nint cmark_inline_parser_scan_delimiters(cmark_inline_parser *parser,\n                                  int max_delims,\n                                  unsigned char c,\n                                  int *left_flanking,\n                                  int *right_flanking,\n                                  int *punct_before,\n                                  int *punct_after) {\n  int numdelims = 0;\n  bufsize_t before_char_pos;\n  int32_t after_char = 0;\n  int32_t before_char = 0;\n  int len;\n  bool space_before, space_after;\n\n  if (parser->pos == 0) {\n    before_char = 10;\n  } else {\n    before_char_pos = parser->pos - 1;\n    // walk back to the beginning of the UTF_8 sequence:\n    while (peek_at(parser, before_char_pos) >> 6 == 2 && before_char_pos > 0) {\n      before_char_pos -= 1;\n    }\n    len = cmark_utf8proc_iterate(parser->input.data + before_char_pos,\n                                 parser->pos - before_char_pos, &before_char);\n    if (len == -1) {\n      before_char = 10;\n    }\n  }\n\n  while (peek_char(parser) == c && numdelims < max_delims) {\n    numdelims++;\n    advance(parser);\n  }\n\n  len = cmark_utf8proc_iterate(parser->input.data + parser->pos,\n                               parser->input.len - parser->pos, &after_char);\n  if (len == -1) {\n    after_char = 10;\n  }\n\n  *punct_before = cmark_utf8proc_is_punctuation(before_char);\n  *punct_after = cmark_utf8proc_is_punctuation(after_char);\n  space_before = cmark_utf8proc_is_space(before_char) != 0;\n  space_after = cmark_utf8proc_is_space(after_char) != 0;\n\n  *left_flanking = numdelims > 0 && !cmark_utf8proc_is_space(after_char) &&\n                  !(*punct_after && !space_before && !*punct_before);\n  *right_flanking = numdelims > 0 && !cmark_utf8proc_is_space(before_char) &&\n                  !(*punct_before && !space_after && !*punct_after);\n\n  return numdelims;\n}\n\nvoid cmark_inline_parser_advance_offset(cmark_inline_parser *parser) {\n  advance(parser);\n}\n\nint cmark_inline_parser_get_offset(cmark_inline_parser *parser) {\n  return parser->pos;\n}\n\nvoid cmark_inline_parser_set_offset(cmark_inline_parser *parser, int offset) {\n  parser->pos = offset;\n}\n\nint cmark_inline_parser_get_column(cmark_inline_parser *parser) {\n  return parser->pos + 1 + parser->column_offset + parser->block_offset;\n}\n\ncmark_chunk *cmark_inline_parser_get_chunk(cmark_inline_parser *parser) {\n  return &parser->input;\n}\n\nint cmark_inline_parser_in_bracket(cmark_inline_parser *parser, int image) {\n  bracket *b = parser->last_bracket;\n  if (!b) {\n    return 0;\n  }\n  if (image != 0) {\n    return b->in_bracket_image1;\n  } else {\n    return b->in_bracket_image0;\n  }\n}\n\nvoid cmark_node_unput(cmark_node *node, int n) {\n\tnode = node->last_child;\n\twhile (n > 0 && node && node->type == CMARK_NODE_TEXT) {\n\t\tif (node->as.literal.len < n) {\n\t\t\tn -= node->as.literal.len;\n\t\t\tnode->as.literal.len = 0;\n\t\t} else {\n\t\t\tnode->as.literal.len -= n;\n\t\t\tn = 0;\n\t\t}\n\t\tnode = node->prev;\n\t}\n}\n\ndelimiter *cmark_inline_parser_get_last_delimiter(cmark_inline_parser *parser) {\n  return parser->last_delim;\n}\n\nint cmark_inline_parser_get_line(cmark_inline_parser *parser) {\n  return parser->line;\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/inlines.h",
    "content": "#ifndef CMARK_INLINES_H\n#define CMARK_INLINES_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"references.h\"\n\ncmark_chunk cmark_clean_url(cmark_mem *mem, cmark_chunk *url);\ncmark_chunk cmark_clean_title(cmark_mem *mem, cmark_chunk *title);\n\nCMARK_GFM_EXPORT\nvoid cmark_parse_inlines(cmark_parser *parser,\n                         cmark_node *parent,\n                         cmark_map *refmap,\n                         int options);\n\nbufsize_t cmark_parse_reference_inline(cmark_mem *mem, cmark_chunk *input,\n                                       cmark_map *refmap);\n\nvoid cmark_inlines_add_special_character(unsigned char c, bool emphasis);\nvoid cmark_inlines_remove_special_character(unsigned char c, bool emphasis);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/iterator.c",
    "content": "#include <assert.h>\n#include <stdlib.h>\n\n#include \"config.h\"\n#include \"node.h\"\n#include \"cmark-gfm.h\"\n#include \"iterator.h\"\n\ncmark_iter *cmark_iter_new(cmark_node *root) {\n  if (root == NULL) {\n    return NULL;\n  }\n  cmark_mem *mem = root->content.mem;\n  cmark_iter *iter = (cmark_iter *)mem->calloc(1, sizeof(cmark_iter));\n  iter->mem = mem;\n  iter->root = root;\n  iter->cur.ev_type = CMARK_EVENT_NONE;\n  iter->cur.node = NULL;\n  iter->next.ev_type = CMARK_EVENT_ENTER;\n  iter->next.node = root;\n  return iter;\n}\n\nvoid cmark_iter_free(cmark_iter *iter) { iter->mem->free(iter); }\n\nstatic bool S_is_leaf(cmark_node *node) {\n  switch (node->type) {\n  case CMARK_NODE_HTML_BLOCK:\n  case CMARK_NODE_THEMATIC_BREAK:\n  case CMARK_NODE_CODE_BLOCK:\n  case CMARK_NODE_TEXT:\n  case CMARK_NODE_SOFTBREAK:\n  case CMARK_NODE_LINEBREAK:\n  case CMARK_NODE_CODE:\n  case CMARK_NODE_HTML_INLINE:\n    return 1;\n  }\n  return 0;\n}\n\ncmark_event_type cmark_iter_next(cmark_iter *iter) {\n  cmark_event_type ev_type = iter->next.ev_type;\n  cmark_node *node = iter->next.node;\n\n  iter->cur.ev_type = ev_type;\n  iter->cur.node = node;\n\n  if (ev_type == CMARK_EVENT_DONE) {\n    return ev_type;\n  }\n\n  /* roll forward to next item, setting both fields */\n  if (ev_type == CMARK_EVENT_ENTER && !S_is_leaf(node)) {\n    if (node->first_child == NULL) {\n      /* stay on this node but exit */\n      iter->next.ev_type = CMARK_EVENT_EXIT;\n    } else {\n      iter->next.ev_type = CMARK_EVENT_ENTER;\n      iter->next.node = node->first_child;\n    }\n  } else if (node == iter->root) {\n    /* don't move past root */\n    iter->next.ev_type = CMARK_EVENT_DONE;\n    iter->next.node = NULL;\n  } else if (node->next) {\n    iter->next.ev_type = CMARK_EVENT_ENTER;\n    iter->next.node = node->next;\n  } else if (node->parent) {\n    iter->next.ev_type = CMARK_EVENT_EXIT;\n    iter->next.node = node->parent;\n  } else {\n    assert(false);\n    iter->next.ev_type = CMARK_EVENT_DONE;\n    iter->next.node = NULL;\n  }\n\n  return ev_type;\n}\n\nvoid cmark_iter_reset(cmark_iter *iter, cmark_node *current,\n                      cmark_event_type event_type) {\n  iter->next.ev_type = event_type;\n  iter->next.node = current;\n  cmark_iter_next(iter);\n}\n\ncmark_node *cmark_iter_get_node(cmark_iter *iter) { return iter->cur.node; }\n\ncmark_event_type cmark_iter_get_event_type(cmark_iter *iter) {\n  return iter->cur.ev_type;\n}\n\ncmark_node *cmark_iter_get_root(cmark_iter *iter) { return iter->root; }\n\nvoid cmark_consolidate_text_nodes(cmark_node *root) {\n  if (root == NULL) {\n    return;\n  }\n  cmark_iter *iter = cmark_iter_new(root);\n  cmark_strbuf buf = CMARK_BUF_INIT(iter->mem);\n  cmark_event_type ev_type;\n  cmark_node *cur, *tmp, *next;\n\n  while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {\n    cur = cmark_iter_get_node(iter);\n    if (ev_type == CMARK_EVENT_ENTER && cur->type == CMARK_NODE_TEXT &&\n        cur->next && cur->next->type == CMARK_NODE_TEXT) {\n      cmark_strbuf_clear(&buf);\n      cmark_strbuf_put(&buf, cur->as.literal.data, cur->as.literal.len);\n      tmp = cur->next;\n      while (tmp && tmp->type == CMARK_NODE_TEXT) {\n        cmark_iter_next(iter); // advance pointer\n        cmark_strbuf_put(&buf, tmp->as.literal.data, tmp->as.literal.len);\n        cur->end_column = tmp->end_column;\n        next = tmp->next;\n        cmark_node_free(tmp);\n        tmp = next;\n      }\n      cmark_chunk_free(iter->mem, &cur->as.literal);\n      cur->as.literal = cmark_chunk_buf_detach(&buf);\n    }\n  }\n\n  cmark_strbuf_free(&buf);\n  cmark_iter_free(iter);\n}\n\nvoid cmark_node_own(cmark_node *root) {\n  if (root == NULL) {\n    return;\n  }\n  cmark_iter *iter = cmark_iter_new(root);\n  cmark_event_type ev_type;\n  cmark_node *cur;\n\n  while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {\n    cur = cmark_iter_get_node(iter);\n    if (ev_type == CMARK_EVENT_ENTER) {\n      switch (cur->type) {\n      case CMARK_NODE_TEXT:\n      case CMARK_NODE_HTML_INLINE:\n      case CMARK_NODE_CODE:\n      case CMARK_NODE_HTML_BLOCK:\n        cmark_chunk_to_cstr(iter->mem, &cur->as.literal);\n        break;\n      case CMARK_NODE_LINK:\n        cmark_chunk_to_cstr(iter->mem, &cur->as.link.url);\n        cmark_chunk_to_cstr(iter->mem, &cur->as.link.title);\n        break;\n      case CMARK_NODE_CUSTOM_INLINE:\n        cmark_chunk_to_cstr(iter->mem, &cur->as.custom.on_enter);\n        cmark_chunk_to_cstr(iter->mem, &cur->as.custom.on_exit);\n        break;\n      }\n    }\n  }\n\n  cmark_iter_free(iter);\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/iterator.h",
    "content": "#ifndef CMARK_ITERATOR_H\n#define CMARK_ITERATOR_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"cmark-gfm.h\"\n\ntypedef struct {\n  cmark_event_type ev_type;\n  cmark_node *node;\n} cmark_iter_state;\n\nstruct cmark_iter {\n  cmark_mem *mem;\n  cmark_node *root;\n  cmark_iter_state cur;\n  cmark_iter_state next;\n};\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/latex.c",
    "content": "#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <assert.h>\n\n#include \"config.h\"\n#include \"cmark-gfm.h\"\n#include \"node.h\"\n#include \"buffer.h\"\n#include \"utf8.h\"\n#include \"scanners.h\"\n#include \"render.h\"\n#include \"syntax_extension.h\"\n\n#define OUT(s, wrap, escaping) renderer->out(renderer, node, s, wrap, escaping)\n#define LIT(s) renderer->out(renderer, node, s, false, LITERAL)\n#define CR() renderer->cr(renderer)\n#define BLANKLINE() renderer->blankline(renderer)\n#define LIST_NUMBER_STRING_SIZE 20\n\nstatic CMARK_INLINE void outc(cmark_renderer *renderer, cmark_node *node,\n                              cmark_escaping escape,\n                              int32_t c, unsigned char nextc) {\n  if (escape == LITERAL) {\n    cmark_render_code_point(renderer, c);\n    return;\n  }\n\n  switch (c) {\n  case 123: // '{'\n  case 125: // '}'\n  case 35:  // '#'\n  case 37:  // '%'\n  case 38:  // '&'\n    cmark_render_ascii(renderer, \"\\\\\");\n    cmark_render_code_point(renderer, c);\n    break;\n  case 36: // '$'\n  case 95: // '_'\n    if (escape == NORMAL) {\n      cmark_render_ascii(renderer, \"\\\\\");\n    }\n    cmark_render_code_point(renderer, c);\n    break;\n  case 45:             // '-'\n    if (nextc == 45) { // prevent ligature\n      cmark_render_ascii(renderer, \"-{}\");\n    } else {\n      cmark_render_ascii(renderer, \"-\");\n    }\n    break;\n  case 126: // '~'\n    if (escape == NORMAL) {\n      cmark_render_ascii(renderer, \"\\\\textasciitilde{}\");\n    } else {\n      cmark_render_code_point(renderer, c);\n    }\n    break;\n  case 94: // '^'\n    cmark_render_ascii(renderer, \"\\\\^{}\");\n    break;\n  case 92: // '\\\\'\n    if (escape == URL) {\n      // / acts as path sep even on windows:\n      cmark_render_ascii(renderer, \"/\");\n    } else {\n      cmark_render_ascii(renderer, \"\\\\textbackslash{}\");\n    }\n    break;\n  case 124: // '|'\n    cmark_render_ascii(renderer, \"\\\\textbar{}\");\n    break;\n  case 60: // '<'\n    cmark_render_ascii(renderer, \"\\\\textless{}\");\n    break;\n  case 62: // '>'\n    cmark_render_ascii(renderer, \"\\\\textgreater{}\");\n    break;\n  case 91: // '['\n  case 93: // ']'\n    cmark_render_ascii(renderer, \"{\");\n    cmark_render_code_point(renderer, c);\n    cmark_render_ascii(renderer, \"}\");\n    break;\n  case 34: // '\"'\n    cmark_render_ascii(renderer, \"\\\\textquotedbl{}\");\n    // requires \\usepackage[T1]{fontenc}\n    break;\n  case 39: // '\\''\n    cmark_render_ascii(renderer, \"\\\\textquotesingle{}\");\n    // requires \\usepackage{textcomp}\n    break;\n  case 160: // nbsp\n    cmark_render_ascii(renderer, \"~\");\n    break;\n  case 8230: // hellip\n    cmark_render_ascii(renderer, \"\\\\ldots{}\");\n    break;\n  case 8216: // lsquo\n    if (escape == NORMAL) {\n      cmark_render_ascii(renderer, \"`\");\n    } else {\n      cmark_render_code_point(renderer, c);\n    }\n    break;\n  case 8217: // rsquo\n    if (escape == NORMAL) {\n      cmark_render_ascii(renderer, \"\\'\");\n    } else {\n      cmark_render_code_point(renderer, c);\n    }\n    break;\n  case 8220: // ldquo\n    if (escape == NORMAL) {\n      cmark_render_ascii(renderer, \"``\");\n    } else {\n      cmark_render_code_point(renderer, c);\n    }\n    break;\n  case 8221: // rdquo\n    if (escape == NORMAL) {\n      cmark_render_ascii(renderer, \"''\");\n    } else {\n      cmark_render_code_point(renderer, c);\n    }\n    break;\n  case 8212: // emdash\n    if (escape == NORMAL) {\n      cmark_render_ascii(renderer, \"---\");\n    } else {\n      cmark_render_code_point(renderer, c);\n    }\n    break;\n  case 8211: // endash\n    if (escape == NORMAL) {\n      cmark_render_ascii(renderer, \"--\");\n    } else {\n      cmark_render_code_point(renderer, c);\n    }\n    break;\n  default:\n    cmark_render_code_point(renderer, c);\n  }\n}\n\ntypedef enum {\n  NO_LINK,\n  URL_AUTOLINK,\n  EMAIL_AUTOLINK,\n  NORMAL_LINK,\n  INTERNAL_LINK\n} link_type;\n\nstatic link_type get_link_type(cmark_node *node) {\n  size_t title_len, url_len;\n  cmark_node *link_text;\n  char *realurl;\n  int realurllen;\n  bool isemail = false;\n\n  if (node->type != CMARK_NODE_LINK) {\n    return NO_LINK;\n  }\n\n  const char *url = cmark_node_get_url(node);\n  cmark_chunk url_chunk = cmark_chunk_literal(url);\n\n  if (url && *url == '#') {\n    return INTERNAL_LINK;\n  }\n\n  url_len = strlen(url);\n  if (url_len == 0 || scan_scheme(&url_chunk, 0) == 0) {\n    return NO_LINK;\n  }\n\n  const char *title = cmark_node_get_title(node);\n  title_len = strlen(title);\n  // if it has a title, we can't treat it as an autolink:\n  if (title_len == 0) {\n\n    link_text = node->first_child;\n    cmark_consolidate_text_nodes(link_text);\n\n    if (!link_text)\n      return NO_LINK;\n\n    realurl = (char *)url;\n    realurllen = (int)url_len;\n    if (strncmp(realurl, \"mailto:\", 7) == 0) {\n      realurl += 7;\n      realurllen -= 7;\n      isemail = true;\n    }\n    if (realurllen == link_text->as.literal.len &&\n        strncmp(realurl, (char *)link_text->as.literal.data,\n                link_text->as.literal.len) == 0) {\n      if (isemail) {\n        return EMAIL_AUTOLINK;\n      } else {\n        return URL_AUTOLINK;\n      }\n    }\n  }\n\n  return NORMAL_LINK;\n}\n\nstatic int S_get_enumlevel(cmark_node *node) {\n  int enumlevel = 0;\n  cmark_node *tmp = node;\n  while (tmp) {\n    if (tmp->type == CMARK_NODE_LIST &&\n        cmark_node_get_list_type(node) == CMARK_ORDERED_LIST) {\n      enumlevel++;\n    }\n    tmp = tmp->parent;\n  }\n  return enumlevel;\n}\n\nstatic int S_render_node(cmark_renderer *renderer, cmark_node *node,\n                         cmark_event_type ev_type, int options) {\n  int list_number;\n  int enumlevel;\n  char list_number_string[LIST_NUMBER_STRING_SIZE];\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n  cmark_list_type list_type;\n  bool allow_wrap = renderer->width > 0 && !(CMARK_OPT_NOBREAKS & options);\n\n  if (node->extension && node->extension->latex_render_func) {\n    node->extension->latex_render_func(node->extension, renderer, node, ev_type, options);\n    return 1;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_DOCUMENT:\n    break;\n\n  case CMARK_NODE_BLOCK_QUOTE:\n    if (entering) {\n      LIT(\"\\\\begin{quote}\");\n      CR();\n    } else {\n      LIT(\"\\\\end{quote}\");\n      BLANKLINE();\n    }\n    break;\n\n  case CMARK_NODE_LIST:\n    list_type = cmark_node_get_list_type(node);\n    if (entering) {\n      LIT(\"\\\\begin{\");\n      LIT(list_type == CMARK_ORDERED_LIST ? \"enumerate\" : \"itemize\");\n      LIT(\"}\");\n      CR();\n      list_number = cmark_node_get_list_start(node);\n      if (list_number > 1) {\n        enumlevel = S_get_enumlevel(node);\n        // latex normally supports only five levels\n        if (enumlevel >= 1 && enumlevel <= 5) {\n          snprintf(list_number_string, LIST_NUMBER_STRING_SIZE, \"%d\",\n                   list_number);\n          LIT(\"\\\\setcounter{enum\");\n          switch (enumlevel) {\n          case 1: LIT(\"i\"); break;\n          case 2: LIT(\"ii\"); break;\n          case 3: LIT(\"iii\"); break;\n          case 4: LIT(\"iv\"); break;\n          case 5: LIT(\"v\"); break;\n          default: LIT(\"i\"); break;\n\t  }\n          LIT(\"}{\");\n          OUT(list_number_string, false, NORMAL);\n          LIT(\"}\");\n        }\n        CR();\n      }\n    } else {\n      LIT(\"\\\\end{\");\n      LIT(list_type == CMARK_ORDERED_LIST ? \"enumerate\" : \"itemize\");\n      LIT(\"}\");\n      BLANKLINE();\n    }\n    break;\n\n  case CMARK_NODE_ITEM:\n    if (entering) {\n      LIT(\"\\\\item \");\n    } else {\n      CR();\n    }\n    break;\n\n  case CMARK_NODE_HEADING:\n    if (entering) {\n      switch (cmark_node_get_heading_level(node)) {\n      case 1:\n        LIT(\"\\\\section\");\n        break;\n      case 2:\n        LIT(\"\\\\subsection\");\n        break;\n      case 3:\n        LIT(\"\\\\subsubsection\");\n        break;\n      case 4:\n        LIT(\"\\\\paragraph\");\n        break;\n      case 5:\n        LIT(\"\\\\subparagraph\");\n        break;\n      }\n      LIT(\"{\");\n    } else {\n      LIT(\"}\");\n      BLANKLINE();\n    }\n    break;\n\n  case CMARK_NODE_CODE_BLOCK:\n    CR();\n    LIT(\"\\\\begin{verbatim}\");\n    CR();\n    OUT(cmark_node_get_literal(node), false, LITERAL);\n    CR();\n    LIT(\"\\\\end{verbatim}\");\n    BLANKLINE();\n    break;\n\n  case CMARK_NODE_HTML_BLOCK:\n    break;\n\n  case CMARK_NODE_CUSTOM_BLOCK:\n    CR();\n    OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node),\n        false, LITERAL);\n    CR();\n    break;\n\n  case CMARK_NODE_THEMATIC_BREAK:\n    BLANKLINE();\n    LIT(\"\\\\begin{center}\\\\rule{0.5\\\\linewidth}{\\\\linethickness}\\\\end{center}\");\n    BLANKLINE();\n    break;\n\n  case CMARK_NODE_PARAGRAPH:\n    if (!entering) {\n      BLANKLINE();\n    }\n    break;\n\n  case CMARK_NODE_TEXT:\n    OUT(cmark_node_get_literal(node), allow_wrap, NORMAL);\n    break;\n\n  case CMARK_NODE_LINEBREAK:\n    LIT(\"\\\\\\\\\");\n    CR();\n    break;\n\n  case CMARK_NODE_SOFTBREAK:\n    if (options & CMARK_OPT_HARDBREAKS) {\n      LIT(\"\\\\\\\\\");\n      CR();\n    } else if (renderer->width == 0 && !(CMARK_OPT_NOBREAKS & options)) {\n      CR();\n    } else {\n      OUT(\" \", allow_wrap, NORMAL);\n    }\n    break;\n\n  case CMARK_NODE_CODE:\n    LIT(\"\\\\texttt{\");\n    OUT(cmark_node_get_literal(node), false, NORMAL);\n    LIT(\"}\");\n    break;\n\n  case CMARK_NODE_HTML_INLINE:\n    break;\n\n  case CMARK_NODE_CUSTOM_INLINE:\n    OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node),\n        false, LITERAL);\n    break;\n\n  case CMARK_NODE_STRONG:\n    if (node->parent == NULL || node->parent->type != CMARK_NODE_STRONG) {\n      if (entering) {\n        LIT(\"\\\\textbf{\");\n      } else {\n        LIT(\"}\");\n      }\n    }\n    break;\n\n  case CMARK_NODE_EMPH:\n    if (entering) {\n      LIT(\"\\\\emph{\");\n    } else {\n      LIT(\"}\");\n    }\n    break;\n\n  case CMARK_NODE_LINK:\n    if (entering) {\n      const char *url = cmark_node_get_url(node);\n      // requires \\usepackage{hyperref}\n      switch (get_link_type(node)) {\n      case URL_AUTOLINK:\n        LIT(\"\\\\url{\");\n        OUT(url, false, URL);\n        LIT(\"}\");\n        return 0; // Don't process further nodes to avoid double-rendering artefacts\n      case EMAIL_AUTOLINK:\n        LIT(\"\\\\href{\");\n        OUT(url, false, URL);\n        LIT(\"}\\\\nolinkurl{\");\n        break;\n      case NORMAL_LINK:\n        LIT(\"\\\\href{\");\n        OUT(url, false, URL);\n        LIT(\"}{\");\n        break;\n      case INTERNAL_LINK:\n        LIT(\"\\\\protect\\\\hyperlink{\");\n        OUT(url + 1, false, URL);\n        LIT(\"}{\");\n        break;\n      case NO_LINK:\n        LIT(\"{\"); // error?\n      }\n    } else {\n      LIT(\"}\");\n    }\n\n    break;\n\n  case CMARK_NODE_IMAGE:\n    if (entering) {\n      LIT(\"\\\\protect\\\\includegraphics{\");\n      // requires \\include{graphicx}\n      OUT(cmark_node_get_url(node), false, URL);\n      LIT(\"}\");\n      return 0;\n    }\n    break;\n\n  case CMARK_NODE_FOOTNOTE_DEFINITION:\n  case CMARK_NODE_FOOTNOTE_REFERENCE:\n    // TODO\n    break;\n\n  default:\n    assert(false);\n    break;\n  }\n\n  return 1;\n}\n\nchar *cmark_render_latex(cmark_node *root, int options, int width) {\n  return cmark_render_latex_with_mem(root, options, width, cmark_node_mem(root));\n}\n\nchar *cmark_render_latex_with_mem(cmark_node *root, int options, int width, cmark_mem *mem) {\n  return cmark_render(mem, root, options, width, outc, S_render_node);\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/libcmark-gfm.pc.in",
    "content": "prefix=@CMAKE_INSTALL_PREFIX@\nexec_prefix=@CMAKE_INSTALL_PREFIX@\nlibdir=@CMAKE_INSTALL_PREFIX@/@libdir@\nincludedir=@CMAKE_INSTALL_PREFIX@/include\n\nName: libcmark-gfm\nDescription: CommonMark parsing, rendering, and manipulation with GitHub Flavored Markdown extensions\nVersion: @PROJECT_VERSION@\nLibs: -L${libdir} -lcmark-gfm -lcmark-gfm-extensions\nCflags: -I${includedir}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/linked_list.c",
    "content": "#include <stdlib.h>\n\n#include \"cmark-gfm.h\"\n\ncmark_llist *cmark_llist_append(cmark_mem *mem, cmark_llist *head, void *data) {\n  cmark_llist *tmp;\n  cmark_llist *new_node = (cmark_llist *) mem->calloc(1, sizeof(cmark_llist));\n\n  new_node->data = data;\n  new_node->next = NULL;\n\n  if (!head)\n    return new_node;\n\n  for (tmp = head; tmp->next; tmp=tmp->next);\n\n  tmp->next = new_node;\n\n  return head;\n}\n\nvoid cmark_llist_free_full(cmark_mem *mem, cmark_llist *head, cmark_free_func free_func) {\n  cmark_llist *tmp, *prev;\n\n  for (tmp = head; tmp;) {\n    if (free_func)\n      free_func(mem, tmp->data);\n\n    prev = tmp;\n    tmp = tmp->next;\n    mem->free(prev);\n  }\n}\n\nvoid cmark_llist_free(cmark_mem *mem, cmark_llist *head) {\n  cmark_llist_free_full(mem, head, NULL);\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/man.c",
    "content": "#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <assert.h>\n\n#include \"config.h\"\n#include \"cmark-gfm.h\"\n#include \"node.h\"\n#include \"buffer.h\"\n#include \"utf8.h\"\n#include \"render.h\"\n#include \"syntax_extension.h\"\n\n#define OUT(s, wrap, escaping) renderer->out(renderer, node, s, wrap, escaping)\n#define LIT(s) renderer->out(renderer, node, s, false, LITERAL)\n#define CR() renderer->cr(renderer)\n#define BLANKLINE() renderer->blankline(renderer)\n#define LIST_NUMBER_SIZE 20\n\n// Functions to convert cmark_nodes to groff man strings.\nstatic void S_outc(cmark_renderer *renderer, cmark_node *node, \n                   cmark_escaping escape, int32_t c,\n                   unsigned char nextc) {\n  (void)(nextc);\n\n  if (escape == LITERAL) {\n    cmark_render_code_point(renderer, c);\n    return;\n  }\n\n  switch (c) {\n  case 46:\n    if (renderer->begin_line) {\n      cmark_render_ascii(renderer, \"\\\\&.\");\n    } else {\n      cmark_render_code_point(renderer, c);\n    }\n    break;\n  case 39:\n    if (renderer->begin_line) {\n      cmark_render_ascii(renderer, \"\\\\&'\");\n    } else {\n      cmark_render_code_point(renderer, c);\n    }\n    break;\n  case 45:\n    cmark_render_ascii(renderer, \"\\\\-\");\n    break;\n  case 92:\n    cmark_render_ascii(renderer, \"\\\\e\");\n    break;\n  case 8216: // left single quote\n    cmark_render_ascii(renderer, \"\\\\[oq]\");\n    break;\n  case 8217: // right single quote\n    cmark_render_ascii(renderer, \"\\\\[cq]\");\n    break;\n  case 8220: // left double quote\n    cmark_render_ascii(renderer, \"\\\\[lq]\");\n    break;\n  case 8221: // right double quote\n    cmark_render_ascii(renderer, \"\\\\[rq]\");\n    break;\n  case 8212: // em dash\n    cmark_render_ascii(renderer, \"\\\\[em]\");\n    break;\n  case 8211: // en dash\n    cmark_render_ascii(renderer, \"\\\\[en]\");\n    break;\n  default:\n    cmark_render_code_point(renderer, c);\n  }\n}\n\nstatic int S_render_node(cmark_renderer *renderer, cmark_node *node,\n                         cmark_event_type ev_type, int options) {\n  int list_number;\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n  bool allow_wrap = renderer->width > 0 && !(CMARK_OPT_NOBREAKS & options);\n\n  if (node->extension && node->extension->man_render_func) {\n    node->extension->man_render_func(node->extension, renderer, node, ev_type, options);\n    return 1;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_DOCUMENT:\n    if (entering) {\n      /* Define a strikethrough macro */\n      /* Commenting out because this makes tests fail\n      LIT(\".de ST\");\n      CR();\n      LIT(\".nr ww \\\\w'\\\\\\\\$1'\");\n      CR();\n      LIT(\"\\\\Z@\\\\v'-.25m'\\\\l'\\\\\\\\n[ww]u'@\\\\\\\\$1\");\n      CR();\n      LIT(\"..\");\n      CR();\n      */\n    }\n    break;\n\n  case CMARK_NODE_BLOCK_QUOTE:\n    if (entering) {\n      CR();\n      LIT(\".RS\");\n      CR();\n    } else {\n      CR();\n      LIT(\".RE\");\n      CR();\n    }\n    break;\n\n  case CMARK_NODE_LIST:\n    break;\n\n  case CMARK_NODE_ITEM:\n    if (entering) {\n      CR();\n      LIT(\".IP \");\n      if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {\n        LIT(\"\\\\[bu] 2\");\n      } else {\n        list_number = cmark_node_get_item_index(node);\n        char list_number_s[LIST_NUMBER_SIZE];\n        snprintf(list_number_s, LIST_NUMBER_SIZE, \"\\\"%d.\\\" 4\", list_number);\n        LIT(list_number_s);\n      }\n      CR();\n    } else {\n      CR();\n    }\n    break;\n\n  case CMARK_NODE_HEADING:\n    if (entering) {\n      CR();\n      LIT(cmark_node_get_heading_level(node) == 1 ? \".SH\" : \".SS\");\n      CR();\n    } else {\n      CR();\n    }\n    break;\n\n  case CMARK_NODE_CODE_BLOCK:\n    CR();\n    LIT(\".IP\\n.nf\\n\\\\f[C]\\n\");\n    OUT(cmark_node_get_literal(node), false, NORMAL);\n    CR();\n    LIT(\"\\\\f[]\\n.fi\");\n    CR();\n    break;\n\n  case CMARK_NODE_HTML_BLOCK:\n    break;\n\n  case CMARK_NODE_CUSTOM_BLOCK:\n    CR();\n    OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node),\n        false, LITERAL);\n    CR();\n    break;\n\n  case CMARK_NODE_THEMATIC_BREAK:\n    CR();\n    LIT(\".PP\\n  *  *  *  *  *\");\n    CR();\n    break;\n\n  case CMARK_NODE_PARAGRAPH:\n    if (entering) {\n      // no blank line if first paragraph in list:\n      if (node->parent && node->parent->type == CMARK_NODE_ITEM &&\n          node->prev == NULL) {\n        // no blank line or .PP\n      } else {\n        CR();\n        LIT(\".PP\");\n        CR();\n      }\n    } else {\n      CR();\n    }\n    break;\n\n  case CMARK_NODE_TEXT:\n    OUT(cmark_node_get_literal(node), allow_wrap, NORMAL);\n    break;\n\n  case CMARK_NODE_LINEBREAK:\n    LIT(\".PD 0\\n.P\\n.PD\");\n    CR();\n    break;\n\n  case CMARK_NODE_SOFTBREAK:\n    if (options & CMARK_OPT_HARDBREAKS) {\n      LIT(\".PD 0\\n.P\\n.PD\");\n      CR();\n    } else if (renderer->width == 0 && !(CMARK_OPT_NOBREAKS & options)) {\n      CR();\n    } else {\n      OUT(\" \", allow_wrap, LITERAL);\n    }\n    break;\n\n  case CMARK_NODE_CODE:\n    LIT(\"\\\\f[C]\");\n    OUT(cmark_node_get_literal(node), allow_wrap, NORMAL);\n    LIT(\"\\\\f[]\");\n    break;\n\n  case CMARK_NODE_HTML_INLINE:\n    break;\n\n  case CMARK_NODE_CUSTOM_INLINE:\n    OUT(entering ? cmark_node_get_on_enter(node) : cmark_node_get_on_exit(node),\n        false, LITERAL);\n    break;\n\n  case CMARK_NODE_STRONG:\n    if (node->parent == NULL || node->parent->type != CMARK_NODE_STRONG) {\n      if (entering) {\n        LIT(\"\\\\f[B]\");\n      } else {\n        LIT(\"\\\\f[]\");\n      }\n    }\n    break;\n\n  case CMARK_NODE_EMPH:\n    if (entering) {\n      LIT(\"\\\\f[I]\");\n    } else {\n      LIT(\"\\\\f[]\");\n    }\n    break;\n\n  case CMARK_NODE_LINK:\n    if (!entering) {\n      LIT(\" (\");\n      OUT(cmark_node_get_url(node), allow_wrap, URL);\n      LIT(\")\");\n    }\n    break;\n\n  case CMARK_NODE_IMAGE:\n    if (entering) {\n      LIT(\"[IMAGE: \");\n    } else {\n      LIT(\"]\");\n    }\n    break;\n\n  case CMARK_NODE_FOOTNOTE_DEFINITION:\n  case CMARK_NODE_FOOTNOTE_REFERENCE:\n    // TODO\n    break;\n\n  default:\n    assert(false);\n    break;\n  }\n\n  return 1;\n}\n\nchar *cmark_render_man(cmark_node *root, int options, int width) {\n  return cmark_render_man_with_mem(root, options, width, cmark_node_mem(root));\n}\n\nchar *cmark_render_man_with_mem(cmark_node *root, int options, int width, cmark_mem *mem) {\n  return cmark_render(mem, root, options, width, S_outc, S_render_node);\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/map.c",
    "content": "#include \"map.h\"\n#include \"utf8.h\"\n#include \"parser.h\"\n\n// normalize map label:  collapse internal whitespace to single space,\n// remove leading/trailing whitespace, case fold\n// Return NULL if the label is actually empty (i.e. composed solely from\n// whitespace)\nunsigned char *normalize_map_label(cmark_mem *mem, cmark_chunk *ref) {\n  cmark_strbuf normalized = CMARK_BUF_INIT(mem);\n  unsigned char *result;\n\n  if (ref == NULL)\n    return NULL;\n\n  if (ref->len == 0)\n    return NULL;\n\n  cmark_utf8proc_case_fold(&normalized, ref->data, ref->len);\n  cmark_strbuf_trim(&normalized);\n  cmark_strbuf_normalize_whitespace(&normalized);\n\n  result = cmark_strbuf_detach(&normalized);\n  assert(result);\n\n  if (result[0] == '\\0') {\n    mem->free(result);\n    return NULL;\n  }\n\n  return result;\n}\n\nstatic int\nlabelcmp(const unsigned char *a, const unsigned char *b) {\n  return strcmp((const char *)a, (const char *)b);\n}\n\nstatic int\nrefcmp(const void *p1, const void *p2) {\n  cmark_map_entry *r1 = *(cmark_map_entry **)p1;\n  cmark_map_entry *r2 = *(cmark_map_entry **)p2;\n  int res = labelcmp(r1->label, r2->label);\n  return res ? res : ((int)r1->age - (int)r2->age);\n}\n\nstatic int\nrefsearch(const void *label, const void *p2) {\n  cmark_map_entry *ref = *(cmark_map_entry **)p2;\n  return labelcmp((const unsigned char *)label, ref->label);\n}\n\nstatic void sort_map(cmark_map *map) {\n  size_t i = 0, last = 0, size = map->size;\n  cmark_map_entry *r = map->refs, **sorted = NULL;\n\n  sorted = (cmark_map_entry **)map->mem->calloc(size, sizeof(cmark_map_entry *));\n  while (r) {\n    sorted[i++] = r;\n    r = r->next;\n  }\n\n  qsort(sorted, size, sizeof(cmark_map_entry *), refcmp);\n\n  for (i = 1; i < size; i++) {\n    if (labelcmp(sorted[i]->label, sorted[last]->label) != 0)\n      sorted[++last] = sorted[i];\n  }\n\n  map->sorted = sorted;\n  map->size = last + 1;\n}\n\ncmark_map_entry *cmark_map_lookup(cmark_map *map, cmark_chunk *label) {\n  cmark_map_entry **ref = NULL;\n  cmark_map_entry *r = NULL;\n  unsigned char *norm;\n\n  if (label->len < 1 || label->len > MAX_LINK_LABEL_LENGTH)\n    return NULL;\n\n  if (map == NULL || !map->size)\n    return NULL;\n\n  norm = normalize_map_label(map->mem, label);\n  if (norm == NULL)\n    return NULL;\n\n  if (!map->sorted)\n    sort_map(map);\n\n  ref = (cmark_map_entry **)bsearch(norm, map->sorted, map->size, sizeof(cmark_map_entry *), refsearch);\n  map->mem->free(norm);\n\n  if (ref != NULL) {\n    r = ref[0];\n    /* Check for expansion limit */\n    if (r->size > map->max_ref_size - map->ref_size)\n      return NULL;\n    map->ref_size += r->size;\n  }\n\n  return r;\n}\n\nvoid cmark_map_free(cmark_map *map) {\n  cmark_map_entry *ref;\n\n  if (map == NULL)\n    return;\n\n  ref = map->refs;\n  while (ref) {\n    cmark_map_entry *next = ref->next;\n    map->free(map, ref);\n    ref = next;\n  }\n\n  map->mem->free(map->sorted);\n  map->mem->free(map);\n}\n\ncmark_map *cmark_map_new(cmark_mem *mem, cmark_map_free_f free) {\n  cmark_map *map = (cmark_map *)mem->calloc(1, sizeof(cmark_map));\n  map->mem = mem;\n  map->free = free;\n  map->max_ref_size = UINT_MAX;\n  return map;\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/map.h",
    "content": "#ifndef CMARK_MAP_H\n#define CMARK_MAP_H\n\n#include \"chunk.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nstruct cmark_map_entry {\n  struct cmark_map_entry *next;\n  unsigned char *label;\n  size_t age;\n  size_t size;\n};\n\ntypedef struct cmark_map_entry cmark_map_entry;\n\nstruct cmark_map;\n\ntypedef void (*cmark_map_free_f)(struct cmark_map *, cmark_map_entry *);\n\nstruct cmark_map {\n  cmark_mem *mem;\n  cmark_map_entry *refs;\n  cmark_map_entry **sorted;\n  size_t size;\n  size_t ref_size;\n  size_t max_ref_size;\n  cmark_map_free_f free;\n};\n\ntypedef struct cmark_map cmark_map;\n\nunsigned char *normalize_map_label(cmark_mem *mem, cmark_chunk *ref);\ncmark_map *cmark_map_new(cmark_mem *mem, cmark_map_free_f free);\nvoid cmark_map_free(cmark_map *map);\ncmark_map_entry *cmark_map_lookup(cmark_map *map, cmark_chunk *label);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/node.c",
    "content": "#include <stdlib.h>\n#include <string.h>\n\n#include \"config.h\"\n#include \"node.h\"\n#include \"syntax_extension.h\"\n\n/**\n * Expensive safety checks are off by default, but can be enabled\n * by calling cmark_enable_safety_checks().\n */\nstatic bool enable_safety_checks = false;\n\nvoid cmark_enable_safety_checks(bool enable) {\n  enable_safety_checks = enable;\n}\n\nstatic void S_node_unlink(cmark_node *node);\n\n#define NODE_MEM(node) cmark_node_mem(node)\n\nvoid cmark_register_node_flag(cmark_node_internal_flags *flags) {\n  static cmark_node_internal_flags nextflag = CMARK_NODE__REGISTER_FIRST;\n\n  // flags should be a pointer to a global variable and this function\n  // should only be called once to initialize its value.\n  if (*flags) {\n    fprintf(stderr, \"flag initialization error in cmark_register_node_flag\\n\");\n    abort();\n  }\n\n  // Check that we haven't run out of bits.\n  if (nextflag == 0) {\n    fprintf(stderr, \"too many flags in cmark_register_node_flag\\n\");\n    abort();\n  }\n\n  *flags = nextflag;\n  nextflag <<= 1;\n}\n\nvoid cmark_init_standard_node_flags(void) {}\n\nbool cmark_node_can_contain_type(cmark_node *node, cmark_node_type child_type) {\n  if (child_type == CMARK_NODE_DOCUMENT) {\n      return false;\n    }\n\n  if (node->extension && node->extension->can_contain_func) {\n    return node->extension->can_contain_func(node->extension, node, child_type) != 0;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_DOCUMENT:\n  case CMARK_NODE_BLOCK_QUOTE:\n  case CMARK_NODE_FOOTNOTE_DEFINITION:\n  case CMARK_NODE_ITEM:\n    return CMARK_NODE_TYPE_BLOCK_P(child_type) && child_type != CMARK_NODE_ITEM;\n\n  case CMARK_NODE_LIST:\n    return child_type == CMARK_NODE_ITEM;\n\n  case CMARK_NODE_CUSTOM_BLOCK:\n    return true;\n\n  case CMARK_NODE_PARAGRAPH:\n  case CMARK_NODE_HEADING:\n  case CMARK_NODE_EMPH:\n  case CMARK_NODE_STRONG:\n  case CMARK_NODE_LINK:\n  case CMARK_NODE_IMAGE:\n  case CMARK_NODE_CUSTOM_INLINE:\n    return CMARK_NODE_TYPE_INLINE_P(child_type);\n\n  default:\n    break;\n  }\n\n  return false;\n}\n\nstatic bool S_can_contain(cmark_node *node, cmark_node *child) {\n  if (node == NULL || child == NULL) {\n    return false;\n  }\n  if (NODE_MEM(node) != NODE_MEM(child)) {\n    return 0;\n  }\n\n  if (enable_safety_checks) {\n    // Verify that child is not an ancestor of node or equal to node.\n    cmark_node *cur = node;\n    do {\n      if (cur == child) {\n        return false;\n      }\n      cur = cur->parent;\n    } while (cur != NULL);\n  }\n\n  return cmark_node_can_contain_type(node, (cmark_node_type) child->type);\n}\n\ncmark_node *cmark_node_new_with_mem_and_ext(cmark_node_type type, cmark_mem *mem, cmark_syntax_extension *extension) {\n  cmark_node *node = (cmark_node *)mem->calloc(1, sizeof(*node));\n  cmark_strbuf_init(mem, &node->content, 0);\n  node->type = (uint16_t)type;\n  node->extension = extension;\n\n  switch (node->type) {\n  case CMARK_NODE_HEADING:\n    node->as.heading.level = 1;\n    break;\n\n  case CMARK_NODE_LIST: {\n    cmark_list *list = &node->as.list;\n    list->list_type = CMARK_BULLET_LIST;\n    list->start = 0;\n    list->tight = false;\n    break;\n  }\n\n  default:\n    break;\n  }\n\n  if (node->extension && node->extension->opaque_alloc_func) {\n    node->extension->opaque_alloc_func(node->extension, mem, node);\n  }\n\n  return node;\n}\n\ncmark_node *cmark_node_new_with_ext(cmark_node_type type, cmark_syntax_extension *extension) {\n  extern cmark_mem CMARK_DEFAULT_MEM_ALLOCATOR;\n  return cmark_node_new_with_mem_and_ext(type, &CMARK_DEFAULT_MEM_ALLOCATOR, extension);\n}\n\ncmark_node *cmark_node_new_with_mem(cmark_node_type type, cmark_mem *mem)\n{\n  return cmark_node_new_with_mem_and_ext(type, mem, NULL);\n}\n\ncmark_node *cmark_node_new(cmark_node_type type) {\n  return cmark_node_new_with_ext(type, NULL);\n}\n\nstatic void free_node_as(cmark_node *node) {\n  switch (node->type) {\n    case CMARK_NODE_CODE_BLOCK:\n    cmark_chunk_free(NODE_MEM(node), &node->as.code.info);\n    cmark_chunk_free(NODE_MEM(node), &node->as.code.literal);\n      break;\n    case CMARK_NODE_TEXT:\n    case CMARK_NODE_HTML_INLINE:\n    case CMARK_NODE_CODE:\n    case CMARK_NODE_HTML_BLOCK:\n    case CMARK_NODE_FOOTNOTE_REFERENCE:\n    case CMARK_NODE_FOOTNOTE_DEFINITION:\n    cmark_chunk_free(NODE_MEM(node), &node->as.literal);\n      break;\n    case CMARK_NODE_LINK:\n    case CMARK_NODE_IMAGE:\n    cmark_chunk_free(NODE_MEM(node), &node->as.link.url);\n    cmark_chunk_free(NODE_MEM(node), &node->as.link.title);\n      break;\n    case CMARK_NODE_CUSTOM_BLOCK:\n    case CMARK_NODE_CUSTOM_INLINE:\n    cmark_chunk_free(NODE_MEM(node), &node->as.custom.on_enter);\n    cmark_chunk_free(NODE_MEM(node), &node->as.custom.on_exit);\n      break;\n    default:\n      break;\n    }\n}\n\n// Free a cmark_node list and any children.\nstatic void S_free_nodes(cmark_node *e) {\n  cmark_node *next;\n  while (e != NULL) {\n    cmark_strbuf_free(&e->content);\n\n    if (e->user_data && e->user_data_free_func)\n      e->user_data_free_func(NODE_MEM(e), e->user_data);\n\n    if (e->as.opaque && e->extension && e->extension->opaque_free_func)\n      e->extension->opaque_free_func(e->extension, NODE_MEM(e), e);\n\n    free_node_as(e);\n\n    if (e->last_child) {\n      // Splice children into list\n      e->last_child->next = e->next;\n      e->next = e->first_child;\n    }\n    next = e->next;\n    NODE_MEM(e)->free(e);\n    e = next;\n  }\n}\n\nvoid cmark_node_free(cmark_node *node) {\n  S_node_unlink(node);\n  node->next = NULL;\n  S_free_nodes(node);\n}\n\ncmark_node_type cmark_node_get_type(cmark_node *node) {\n  if (node == NULL) {\n    return CMARK_NODE_NONE;\n  } else {\n    return (cmark_node_type)node->type;\n  }\n}\n\nint cmark_node_set_type(cmark_node * node, cmark_node_type type) {\n  cmark_node_type initial_type;\n\n  if (type == node->type)\n    return 1;\n\n  initial_type = (cmark_node_type) node->type;\n  node->type = (uint16_t)type;\n\n  if (!S_can_contain(node->parent, node)) {\n    node->type = (uint16_t)initial_type;\n    return 0;\n  }\n\n  /* We rollback the type to free the union members appropriately */\n  node->type = (uint16_t)initial_type;\n  free_node_as(node);\n\n  node->type = (uint16_t)type;\n\n  return 1;\n}\n\nconst char *cmark_node_get_type_string(cmark_node *node) {\n  if (node == NULL) {\n    return \"NONE\";\n  }\n\n  if (node->extension && node->extension->get_type_string_func) {\n    return node->extension->get_type_string_func(node->extension, node);\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_NONE:\n    return \"none\";\n  case CMARK_NODE_DOCUMENT:\n    return \"document\";\n  case CMARK_NODE_BLOCK_QUOTE:\n    return \"block_quote\";\n  case CMARK_NODE_LIST:\n    return \"list\";\n  case CMARK_NODE_ITEM:\n    return \"item\";\n  case CMARK_NODE_CODE_BLOCK:\n    return \"code_block\";\n  case CMARK_NODE_HTML_BLOCK:\n    return \"html_block\";\n  case CMARK_NODE_CUSTOM_BLOCK:\n    return \"custom_block\";\n  case CMARK_NODE_PARAGRAPH:\n    return \"paragraph\";\n  case CMARK_NODE_HEADING:\n    return \"heading\";\n  case CMARK_NODE_THEMATIC_BREAK:\n    return \"thematic_break\";\n  case CMARK_NODE_TEXT:\n    return \"text\";\n  case CMARK_NODE_SOFTBREAK:\n    return \"softbreak\";\n  case CMARK_NODE_LINEBREAK:\n    return \"linebreak\";\n  case CMARK_NODE_CODE:\n    return \"code\";\n  case CMARK_NODE_HTML_INLINE:\n    return \"html_inline\";\n  case CMARK_NODE_CUSTOM_INLINE:\n    return \"custom_inline\";\n  case CMARK_NODE_EMPH:\n    return \"emph\";\n  case CMARK_NODE_STRONG:\n    return \"strong\";\n  case CMARK_NODE_LINK:\n    return \"link\";\n  case CMARK_NODE_IMAGE:\n    return \"image\";\n  case CMARK_NODE_FOOTNOTE_REFERENCE:\n    return \"foot_note_ref\";\n  case CMARK_NODE_FOOTNOTE_DEFINITION:\n    return \"foot_note_def\";\n  }\n\n  return \"<unknown>\";\n}\n\ncmark_node *cmark_node_next(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  } else {\n    return node->next;\n  }\n}\n\ncmark_node *cmark_node_previous(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  } else {\n    return node->prev;\n  }\n}\n\ncmark_node *cmark_node_parent(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  } else {\n    return node->parent;\n  }\n}\n\ncmark_node *cmark_node_first_child(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  } else {\n    return node->first_child;\n  }\n}\n\ncmark_node *cmark_node_last_child(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  } else {\n    return node->last_child;\n  }\n}\n\ncmark_node *cmark_node_parent_footnote_def(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  } else {\n    return node->parent_footnote_def;\n  }\n}\n\nint cmark_node_get_footnote_idx(cmark_node *node) {\n  if (node == NULL) {\n    return 0;\n  } else {\n    return node->footnote.ref_ix;\n  }\n}\n\nvoid *cmark_node_get_user_data(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  } else {\n    return node->user_data;\n  }\n}\n\nint cmark_node_set_user_data(cmark_node *node, void *user_data) {\n  if (node == NULL) {\n    return 0;\n  }\n  node->user_data = user_data;\n  return 1;\n}\n\nint cmark_node_set_user_data_free_func(cmark_node *node,\n                                        cmark_free_func free_func) {\n  if (node == NULL) {\n    return 0;\n  }\n  node->user_data_free_func = free_func;\n  return 1;\n}\n\nconst char *cmark_node_get_literal(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_HTML_BLOCK:\n  case CMARK_NODE_TEXT:\n  case CMARK_NODE_HTML_INLINE:\n  case CMARK_NODE_CODE:\n  case CMARK_NODE_FOOTNOTE_REFERENCE:\n  case CMARK_NODE_FOOTNOTE_DEFINITION:\n    return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.literal);\n\n  case CMARK_NODE_CODE_BLOCK:\n    return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.code.literal);\n\n  default:\n    break;\n  }\n\n  return NULL;\n}\n\nint cmark_node_set_literal(cmark_node *node, const char *content) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_HTML_BLOCK:\n  case CMARK_NODE_TEXT:\n  case CMARK_NODE_HTML_INLINE:\n  case CMARK_NODE_CODE:\n  case CMARK_NODE_FOOTNOTE_REFERENCE:\n    cmark_chunk_set_cstr(NODE_MEM(node), &node->as.literal, content);\n    return 1;\n\n  case CMARK_NODE_CODE_BLOCK:\n    cmark_chunk_set_cstr(NODE_MEM(node), &node->as.code.literal, content);\n    return 1;\n\n  default:\n    break;\n  }\n\n  return 0;\n}\n\nconst char *cmark_node_get_string_content(cmark_node *node) {\n  return (char *) node->content.ptr;\n}\n\nint cmark_node_set_string_content(cmark_node *node, const char *content) {\n  cmark_strbuf_sets(&node->content, content);\n  return true;\n}\n\nint cmark_node_get_heading_level(cmark_node *node) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_HEADING:\n    return node->as.heading.level;\n\n  default:\n    break;\n  }\n\n  return 0;\n}\n\nint cmark_node_set_heading_level(cmark_node *node, int level) {\n  if (node == NULL || level < 1 || level > 6) {\n    return 0;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_HEADING:\n    node->as.heading.level = level;\n    return 1;\n\n  default:\n    break;\n  }\n\n  return 0;\n}\n\ncmark_list_type cmark_node_get_list_type(cmark_node *node) {\n  if (node == NULL) {\n    return CMARK_NO_LIST;\n  }\n\n  if (node->type == CMARK_NODE_LIST) {\n    return node->as.list.list_type;\n  } else {\n    return CMARK_NO_LIST;\n  }\n}\n\nint cmark_node_set_list_type(cmark_node *node, cmark_list_type type) {\n  if (!(type == CMARK_BULLET_LIST || type == CMARK_ORDERED_LIST)) {\n    return 0;\n  }\n\n  if (node == NULL) {\n    return 0;\n  }\n\n  if (node->type == CMARK_NODE_LIST) {\n    node->as.list.list_type = type;\n    return 1;\n  } else {\n    return 0;\n  }\n}\n\nint cmark_node_get_checked(cmark_node *node) {\n    if (node == NULL) {\n        return false;\n    }\n    return node->as.list.checked ? 1 : 0;\n}\n\nint cmark_node_get_is_checkbox(cmark_node *node) {\n    if (node == NULL) {\n        return false;\n    }\n    return node->as.list.is_check_box ? 1 : 0;\n}\n\ncmark_delim_type cmark_node_get_list_delim(cmark_node *node) {\n  if (node == NULL) {\n    return CMARK_NO_DELIM;\n  }\n\n  if (node->type == CMARK_NODE_LIST) {\n    return node->as.list.delimiter;\n  } else {\n    return CMARK_NO_DELIM;\n  }\n}\n\nint cmark_node_set_list_delim(cmark_node *node, cmark_delim_type delim) {\n  if (!(delim == CMARK_PERIOD_DELIM || delim == CMARK_PAREN_DELIM)) {\n    return 0;\n  }\n\n  if (node == NULL) {\n    return 0;\n  }\n\n  if (node->type == CMARK_NODE_LIST) {\n    node->as.list.delimiter = delim;\n    return 1;\n  } else {\n    return 0;\n  }\n}\n\nint cmark_node_get_list_start(cmark_node *node) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  if (node->type == CMARK_NODE_LIST) {\n    return node->as.list.start;\n  } else {\n    return 0;\n  }\n}\n\nint cmark_node_set_list_start(cmark_node *node, int start) {\n  if (node == NULL || start < 0) {\n    return 0;\n  }\n\n  if (node->type == CMARK_NODE_LIST) {\n    node->as.list.start = start;\n    return 1;\n  } else {\n    return 0;\n  }\n}\n\nint cmark_node_get_list_tight(cmark_node *node) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  if (node->type == CMARK_NODE_LIST) {\n    return node->as.list.tight;\n  } else {\n    return 0;\n  }\n}\n\nint cmark_node_set_list_tight(cmark_node *node, int tight) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  if (node->type == CMARK_NODE_LIST) {\n    node->as.list.tight = tight == 1;\n    return 1;\n  } else {\n    return 0;\n  }\n}\n\nint cmark_node_get_item_index(cmark_node *node) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  if (node->type == CMARK_NODE_ITEM) {\n    return node->as.list.start;\n  } else {\n    return 0;\n  }\n}\n\nint cmark_node_set_item_index(cmark_node *node, int idx) {\n  if (node == NULL || idx < 0) {\n    return 0;\n  }\n\n  if (node->type == CMARK_NODE_ITEM) {\n    node->as.list.start = idx;\n    return 1;\n  } else {\n    return 0;\n  }\n}\n\nconst char *cmark_node_get_fence_info(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  }\n\n  if (node->type == CMARK_NODE_CODE_BLOCK) {\n    return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.code.info);\n  } else {\n    return NULL;\n  }\n}\n\nint cmark_node_set_fence_info(cmark_node *node, const char *info) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  if (node->type == CMARK_NODE_CODE_BLOCK) {\n    cmark_chunk_set_cstr(NODE_MEM(node), &node->as.code.info, info);\n    return 1;\n  } else {\n    return 0;\n  }\n}\n\nint cmark_node_get_fenced(cmark_node *node, int *length, int *offset, char *character) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  if (node->type == CMARK_NODE_CODE_BLOCK) {\n    *length = node->as.code.fence_length;\n    *offset = node->as.code.fence_offset;\n    *character = node->as.code.fence_char;\n    return node->as.code.fenced;\n  } else {\n    return 0;\n  }\n}\n\nint cmark_node_set_fenced(cmark_node * node, int fenced,\n    int length, int offset, char character) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  if (node->type == CMARK_NODE_CODE_BLOCK) {\n    node->as.code.fenced = (int8_t)fenced;\n    node->as.code.fence_length = (uint8_t)length;\n    node->as.code.fence_offset = (uint8_t)offset;\n    node->as.code.fence_char = character;\n    return 1;\n  } else {\n    return 0;\n  }\n}\n\nconst char *cmark_node_get_url(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_LINK:\n  case CMARK_NODE_IMAGE:\n    return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.link.url);\n  default:\n    break;\n  }\n\n  return NULL;\n}\n\nint cmark_node_set_url(cmark_node *node, const char *url) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_LINK:\n  case CMARK_NODE_IMAGE:\n    cmark_chunk_set_cstr(NODE_MEM(node), &node->as.link.url, url);\n    return 1;\n  default:\n    break;\n  }\n\n  return 0;\n}\n\nconst char *cmark_node_get_title(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_LINK:\n  case CMARK_NODE_IMAGE:\n    return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.link.title);\n  default:\n    break;\n  }\n\n  return NULL;\n}\n\nint cmark_node_set_title(cmark_node *node, const char *title) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_LINK:\n  case CMARK_NODE_IMAGE:\n    cmark_chunk_set_cstr(NODE_MEM(node), &node->as.link.title, title);\n    return 1;\n  default:\n    break;\n  }\n\n  return 0;\n}\n\nconst char *cmark_node_get_on_enter(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_CUSTOM_INLINE:\n  case CMARK_NODE_CUSTOM_BLOCK:\n    return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.custom.on_enter);\n  default:\n    break;\n  }\n\n  return NULL;\n}\n\nint cmark_node_set_on_enter(cmark_node *node, const char *on_enter) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_CUSTOM_INLINE:\n  case CMARK_NODE_CUSTOM_BLOCK:\n    cmark_chunk_set_cstr(NODE_MEM(node), &node->as.custom.on_enter, on_enter);\n    return 1;\n  default:\n    break;\n  }\n\n  return 0;\n}\n\nconst char *cmark_node_get_on_exit(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_CUSTOM_INLINE:\n  case CMARK_NODE_CUSTOM_BLOCK:\n    return cmark_chunk_to_cstr(NODE_MEM(node), &node->as.custom.on_exit);\n  default:\n    break;\n  }\n\n  return NULL;\n}\n\nint cmark_node_set_on_exit(cmark_node *node, const char *on_exit) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_CUSTOM_INLINE:\n  case CMARK_NODE_CUSTOM_BLOCK:\n    cmark_chunk_set_cstr(NODE_MEM(node), &node->as.custom.on_exit, on_exit);\n    return 1;\n  default:\n    break;\n  }\n\n  return 0;\n}\n\ncmark_syntax_extension *cmark_node_get_syntax_extension(cmark_node *node) {\n  if (node == NULL) {\n    return NULL;\n  }\n\n  return node->extension;\n}\n\nint cmark_node_set_syntax_extension(cmark_node *node, cmark_syntax_extension *extension) {\n  if (node == NULL) {\n    return 0;\n  }\n\n  node->extension = extension;\n  return 1;\n}\n\nint cmark_node_get_start_line(cmark_node *node) {\n  if (node == NULL) {\n    return 0;\n  }\n  return node->start_line;\n}\n\nint cmark_node_get_start_column(cmark_node *node) {\n  if (node == NULL) {\n    return 0;\n  }\n  return node->start_column;\n}\n\nint cmark_node_get_end_line(cmark_node *node) {\n  if (node == NULL) {\n    return 0;\n  }\n  return node->end_line;\n}\n\nint cmark_node_get_end_column(cmark_node *node) {\n  if (node == NULL) {\n    return 0;\n  }\n  return node->end_column;\n}\n\n// Unlink a node without adjusting its next, prev, and parent pointers.\nstatic void S_node_unlink(cmark_node *node) {\n  if (node == NULL) {\n    return;\n  }\n\n  if (node->prev) {\n    node->prev->next = node->next;\n  }\n  if (node->next) {\n    node->next->prev = node->prev;\n  }\n\n  // Adjust first_child and last_child of parent.\n  cmark_node *parent = node->parent;\n  if (parent) {\n    if (parent->first_child == node) {\n      parent->first_child = node->next;\n    }\n    if (parent->last_child == node) {\n      parent->last_child = node->prev;\n    }\n  }\n}\n\nvoid cmark_node_unlink(cmark_node *node) {\n  S_node_unlink(node);\n\n  node->next = NULL;\n  node->prev = NULL;\n  node->parent = NULL;\n}\n\nint cmark_node_insert_before(cmark_node *node, cmark_node *sibling) {\n  if (node == NULL || sibling == NULL) {\n    return 0;\n  }\n\n  if (!node->parent || !S_can_contain(node->parent, sibling)) {\n    return 0;\n  }\n\n  S_node_unlink(sibling);\n\n  cmark_node *old_prev = node->prev;\n\n  // Insert 'sibling' between 'old_prev' and 'node'.\n  if (old_prev) {\n    old_prev->next = sibling;\n  }\n  sibling->prev = old_prev;\n  sibling->next = node;\n  node->prev = sibling;\n\n  // Set new parent.\n  cmark_node *parent = node->parent;\n  sibling->parent = parent;\n\n  // Adjust first_child of parent if inserted as first child.\n  if (parent && !old_prev) {\n    parent->first_child = sibling;\n  }\n\n  return 1;\n}\n\nint cmark_node_insert_after(cmark_node *node, cmark_node *sibling) {\n  if (node == NULL || sibling == NULL) {\n    return 0;\n  }\n\n  if (!node->parent || !S_can_contain(node->parent, sibling)) {\n    return 0;\n  }\n\n  S_node_unlink(sibling);\n\n  cmark_node *old_next = node->next;\n\n  // Insert 'sibling' between 'node' and 'old_next'.\n  if (old_next) {\n    old_next->prev = sibling;\n  }\n  sibling->next = old_next;\n  sibling->prev = node;\n  node->next = sibling;\n\n  // Set new parent.\n  cmark_node *parent = node->parent;\n  sibling->parent = parent;\n\n  // Adjust last_child of parent if inserted as last child.\n  if (parent && !old_next) {\n    parent->last_child = sibling;\n  }\n\n  return 1;\n}\n\nint cmark_node_replace(cmark_node *oldnode, cmark_node *newnode) {\n  if (!cmark_node_insert_before(oldnode, newnode)) {\n    return 0;\n  }\n  cmark_node_unlink(oldnode);\n  return 1;\n}\n\nint cmark_node_prepend_child(cmark_node *node, cmark_node *child) {\n  if (!S_can_contain(node, child)) {\n    return 0;\n  }\n\n  S_node_unlink(child);\n\n  cmark_node *old_first_child = node->first_child;\n\n  child->next = old_first_child;\n  child->prev = NULL;\n  child->parent = node;\n  node->first_child = child;\n\n  if (old_first_child) {\n    old_first_child->prev = child;\n  } else {\n    // Also set last_child if node previously had no children.\n    node->last_child = child;\n  }\n\n  return 1;\n}\n\nint cmark_node_append_child(cmark_node *node, cmark_node *child) {\n  if (!S_can_contain(node, child)) {\n    return 0;\n  }\n\n  S_node_unlink(child);\n\n  cmark_node *old_last_child = node->last_child;\n\n  child->next = NULL;\n  child->prev = old_last_child;\n  child->parent = node;\n  node->last_child = child;\n\n  if (old_last_child) {\n    old_last_child->next = child;\n  } else {\n    // Also set first_child if node previously had no children.\n    node->first_child = child;\n  }\n\n  return 1;\n}\n\nstatic void S_print_error(FILE *out, cmark_node *node, const char *elem) {\n  if (out == NULL) {\n    return;\n  }\n  fprintf(out, \"Invalid '%s' in node type %s at %d:%d\\n\", elem,\n          cmark_node_get_type_string(node), node->start_line,\n          node->start_column);\n}\n\nint cmark_node_check(cmark_node *node, FILE *out) {\n  cmark_node *cur;\n  int errors = 0;\n\n  if (!node) {\n    return 0;\n  }\n\n  cur = node;\n  for (;;) {\n    if (cur->first_child) {\n      if (cur->first_child->prev != NULL) {\n        S_print_error(out, cur->first_child, \"prev\");\n        cur->first_child->prev = NULL;\n        ++errors;\n      }\n      if (cur->first_child->parent != cur) {\n        S_print_error(out, cur->first_child, \"parent\");\n        cur->first_child->parent = cur;\n        ++errors;\n      }\n      cur = cur->first_child;\n      continue;\n    }\n\n  next_sibling:\n    if (cur == node) {\n      break;\n    }\n    if (cur->next) {\n      if (cur->next->prev != cur) {\n        S_print_error(out, cur->next, \"prev\");\n        cur->next->prev = cur;\n        ++errors;\n      }\n      if (cur->next->parent != cur->parent) {\n        S_print_error(out, cur->next, \"parent\");\n        cur->next->parent = cur->parent;\n        ++errors;\n      }\n      cur = cur->next;\n      continue;\n    }\n\n    if (cur->parent->last_child != cur) {\n      S_print_error(out, cur->parent, \"last_child\");\n      cur->parent->last_child = cur;\n      ++errors;\n    }\n    cur = cur->parent;\n    goto next_sibling;\n  }\n\n  return errors;\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/node.h",
    "content": "#ifndef CMARK_NODE_H\n#define CMARK_NODE_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdio.h>\n#include <stdint.h>\n\n#include \"cmark-gfm.h\"\n#include \"cmark-gfm-extension_api.h\"\n#include \"buffer.h\"\n#include \"chunk.h\"\n\ntypedef struct {\n  cmark_list_type list_type;\n  int marker_offset;\n  int padding;\n  int start;\n  cmark_delim_type delimiter;\n  unsigned char bullet_char;\n  bool tight;\n  bool checked; // For task list extension\n  bool is_check_box;\n} cmark_list;\n\ntypedef struct {\n  cmark_chunk info;\n  cmark_chunk literal;\n  uint8_t fence_length;\n  uint8_t fence_offset;\n  unsigned char fence_char;\n  int8_t fenced;\n} cmark_code;\n\ntypedef struct {\n  int level;\n  bool setext;\n} cmark_heading;\n\ntypedef struct {\n  cmark_chunk url;\n  cmark_chunk title;\n} cmark_link;\n\ntypedef struct {\n  cmark_chunk on_enter;\n  cmark_chunk on_exit;\n} cmark_custom;\n\nenum cmark_node__internal_flags {\n  CMARK_NODE__OPEN = (1 << 0),\n  CMARK_NODE__LAST_LINE_BLANK = (1 << 1),\n  CMARK_NODE__LAST_LINE_CHECKED = (1 << 2),\n\n  // Extensions can register custom flags by calling `cmark_register_node_flag`.\n  // This is the starting value for the custom flags.\n  CMARK_NODE__REGISTER_FIRST = (1 << 3),\n};\n\ntypedef uint16_t cmark_node_internal_flags;\n\nstruct cmark_node {\n  cmark_strbuf content;\n\n  struct cmark_node *next;\n  struct cmark_node *prev;\n  struct cmark_node *parent;\n  struct cmark_node *first_child;\n  struct cmark_node *last_child;\n\n  void *user_data;\n  cmark_free_func user_data_free_func;\n\n  int start_line;\n  int start_column;\n  int end_line;\n  int end_column;\n  int internal_offset;\n  uint16_t type;\n  cmark_node_internal_flags flags;\n\n  cmark_syntax_extension *extension;\n\n  /**\n   * Used during cmark_render() to cache the most recent non-NULL\n   * extension, if you go up the parent chain like this:\n   *\n   * node->parent->...parent->extension\n   */\n  cmark_syntax_extension *ancestor_extension;\n\n  union {\n    int ref_ix;\n    int def_count;\n  } footnote;\n\n  cmark_node *parent_footnote_def;\n\n  union {\n    cmark_chunk literal;\n    cmark_list list;\n    cmark_code code;\n    cmark_heading heading;\n    cmark_link link;\n    cmark_custom custom;\n    int html_block_type;\n    int cell_index; // For keeping track of TABLE_CELL table alignments\n    void *opaque;\n  } as;\n};\n\n/**\n * Syntax extensions can use this function to register a custom node\n * flag. The flags are stored in the `flags` field of the `cmark_node`\n * struct. The `flags` parameter should be the address of a global variable\n * which will store the flag value.\n */\nCMARK_GFM_EXPORT\nvoid cmark_register_node_flag(cmark_node_internal_flags *flags);\n\n/**\n * DEPRECATED.\n *\n * This function was added in cmark-gfm version 0.29.0.gfm.7, and was\n * required to be called at program start time, which caused\n * backwards-compatibility issues in applications that use cmark-gfm as a\n * library. It is now a no-op.\n */\nCMARK_GFM_EXPORT\nvoid cmark_init_standard_node_flags(void);\n\nstatic CMARK_INLINE cmark_mem *cmark_node_mem(cmark_node *node) {\n  return node->content.mem;\n}\nCMARK_GFM_EXPORT int cmark_node_check(cmark_node *node, FILE *out);\n\nstatic CMARK_INLINE bool CMARK_NODE_TYPE_BLOCK_P(cmark_node_type node_type) {\n\treturn (node_type & CMARK_NODE_TYPE_MASK) == CMARK_NODE_TYPE_BLOCK;\n}\n\nstatic CMARK_INLINE bool CMARK_NODE_BLOCK_P(cmark_node *node) {\n\treturn node != NULL && CMARK_NODE_TYPE_BLOCK_P((cmark_node_type) node->type);\n}\n\nstatic CMARK_INLINE bool CMARK_NODE_TYPE_INLINE_P(cmark_node_type node_type) {\n\treturn (node_type & CMARK_NODE_TYPE_MASK) == CMARK_NODE_TYPE_INLINE;\n}\n\nstatic CMARK_INLINE bool CMARK_NODE_INLINE_P(cmark_node *node) {\n\treturn node != NULL && CMARK_NODE_TYPE_INLINE_P((cmark_node_type) node->type);\n}\n\nCMARK_GFM_EXPORT bool cmark_node_can_contain_type(cmark_node *node, cmark_node_type child_type);\n\n/**\n * Enable (or disable) extra safety checks. These extra checks cause\n * extra performance overhead (in some cases quadratic), so they are only\n * intended to be used during testing.\n */\nCMARK_GFM_EXPORT void cmark_enable_safety_checks(bool enable);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/parser.h",
    "content": "#ifndef CMARK_PARSER_H\n#define CMARK_PARSER_H\n\n#include <stdio.h>\n#include \"references.h\"\n#include \"node.h\"\n#include \"buffer.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define MAX_LINK_LABEL_LENGTH 1000\n\nstruct cmark_parser {\n  struct cmark_mem *mem;\n  /* A hashtable of urls in the current document for cross-references */\n  struct cmark_map *refmap;\n  /* The root node of the parser, always a CMARK_NODE_DOCUMENT */\n  struct cmark_node *root;\n  /* The last open block after a line is fully processed */\n  struct cmark_node *current;\n  /* See the documentation for cmark_parser_get_line_number() in cmark.h */\n  int line_number;\n  /* See the documentation for cmark_parser_get_offset() in cmark.h */\n  bufsize_t offset;\n  /* See the documentation for cmark_parser_get_column() in cmark.h */\n  bufsize_t column;\n  /* See the documentation for cmark_parser_get_first_nonspace() in cmark.h */\n  bufsize_t first_nonspace;\n  /* See the documentation for cmark_parser_get_first_nonspace_column() in cmark.h */\n  bufsize_t first_nonspace_column;\n  bufsize_t thematic_break_kill_pos;\n  /* See the documentation for cmark_parser_get_indent() in cmark.h */\n  int indent;\n  /* See the documentation for cmark_parser_is_blank() in cmark.h */\n  bool blank;\n  /* See the documentation for cmark_parser_has_partially_consumed_tab() in cmark.h */\n  bool partially_consumed_tab;\n  /* Contains the currently processed line */\n  cmark_strbuf curline;\n  /* See the documentation for cmark_parser_get_last_line_length() in cmark.h */\n  bufsize_t last_line_length;\n  /* FIXME: not sure about the difference with curline */\n  cmark_strbuf linebuf;\n  /* Options set by the user, see the Options section in cmark.h */\n  int options;\n  bool last_buffer_ended_with_cr;\n  size_t total_size;\n  cmark_llist *syntax_extensions;\n  cmark_llist *inline_syntax_extensions;\n  cmark_ispunct_func backslash_ispunct;\n};\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/plaintext.c",
    "content": "#include \"node.h\"\n#include \"syntax_extension.h\"\n#include \"render.h\"\n\n#define OUT(s, wrap, escaping) renderer->out(renderer, node, s, wrap, escaping)\n#define LIT(s) renderer->out(renderer, node, s, false, LITERAL)\n#define CR() renderer->cr(renderer)\n#define BLANKLINE() renderer->blankline(renderer)\n#define LISTMARKER_SIZE 20\n\n// Functions to convert cmark_nodes to plain text strings.\n\nstatic CMARK_INLINE void outc(cmark_renderer *renderer, cmark_node *node, \n                              cmark_escaping escape,\n                              int32_t c, unsigned char nextc) {\n  cmark_render_code_point(renderer, c);\n}\n\nstatic int S_render_node(cmark_renderer *renderer, cmark_node *node,\n                         cmark_event_type ev_type, int options) {\n  int list_number;\n  cmark_delim_type list_delim;\n  int i;\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n  char listmarker[LISTMARKER_SIZE];\n  bool first_in_list_item;\n  bufsize_t marker_width;\n  bool allow_wrap = renderer->width > 0 && !(CMARK_OPT_NOBREAKS & options) &&\n                    !(CMARK_OPT_HARDBREAKS & options);\n\n  // Don't adjust tight list status til we've started the list.\n  // Otherwise we loose the blank line between a paragraph and\n  // a following list.\n  if (entering) {\n    if (node->parent && node->parent->type == CMARK_NODE_ITEM) {\n      renderer->in_tight_list_item = node->parent->parent->as.list.tight;\n    }\n  } else {\n    if (node->type == CMARK_NODE_LIST) {\n      renderer->in_tight_list_item =\n        node->parent &&\n        node->parent->type == CMARK_NODE_ITEM &&\n        node->parent->parent->as.list.tight;\n    }\n  }\n\n  if (node->extension && node->extension->plaintext_render_func) {\n    node->extension->plaintext_render_func(node->extension, renderer, node, ev_type, options);\n    return 1;\n  }\n\n  switch (node->type) {\n  case CMARK_NODE_DOCUMENT:\n    break;\n\n  case CMARK_NODE_BLOCK_QUOTE:\n    break;\n\n  case CMARK_NODE_LIST:\n    if (!entering && node->next && (node->next->type == CMARK_NODE_CODE_BLOCK ||\n                                    node->next->type == CMARK_NODE_LIST)) {\n      CR();\n    }\n    break;\n\n  case CMARK_NODE_ITEM:\n    if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {\n      marker_width = 4;\n    } else {\n      list_number = cmark_node_get_item_index(node);\n      list_delim = cmark_node_get_list_delim(node->parent);\n      // we ensure a width of at least 4 so\n      // we get nice transition from single digits\n      // to double\n      snprintf(listmarker, LISTMARKER_SIZE, \"%d%s%s\", list_number,\n               list_delim == CMARK_PAREN_DELIM ? \")\" : \".\",\n               list_number < 10 ? \"  \" : \" \");\n      marker_width = (bufsize_t)strlen(listmarker);\n    }\n    if (entering) {\n      if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {\n        LIT(\"  - \");\n        renderer->begin_content = true;\n      } else {\n        LIT(listmarker);\n        renderer->begin_content = true;\n      }\n      for (i = marker_width; i--;) {\n        cmark_strbuf_putc(renderer->prefix, ' ');\n      }\n    } else {\n      cmark_strbuf_truncate(renderer->prefix,\n                            renderer->prefix->size - marker_width);\n      CR();\n    }\n    break;\n\n  case CMARK_NODE_HEADING:\n    if (entering) {\n      renderer->begin_content = true;\n      renderer->no_linebreaks = true;\n    } else {\n      renderer->no_linebreaks = false;\n      BLANKLINE();\n    }\n    break;\n\n  case CMARK_NODE_CODE_BLOCK:\n    first_in_list_item = node->prev == NULL && node->parent &&\n                         node->parent->type == CMARK_NODE_ITEM;\n\n    if (!first_in_list_item) {\n      BLANKLINE();\n    }\n    OUT(cmark_node_get_literal(node), false, LITERAL);\n    BLANKLINE();\n    break;\n\n  case CMARK_NODE_HTML_BLOCK:\n    break;\n\n  case CMARK_NODE_CUSTOM_BLOCK:\n    break;\n\n  case CMARK_NODE_THEMATIC_BREAK:\n    BLANKLINE();\n    break;\n\n  case CMARK_NODE_PARAGRAPH:\n    if (!entering) {\n      BLANKLINE();\n    }\n    break;\n\n  case CMARK_NODE_TEXT:\n    OUT(cmark_node_get_literal(node), allow_wrap, NORMAL);\n    break;\n\n  case CMARK_NODE_LINEBREAK:\n    CR();\n    break;\n\n  case CMARK_NODE_SOFTBREAK:\n    if (CMARK_OPT_HARDBREAKS & options) {\n      CR();\n    } else if (!renderer->no_linebreaks && renderer->width == 0 &&\n               !(CMARK_OPT_HARDBREAKS & options) &&\n               !(CMARK_OPT_NOBREAKS & options)) {\n      CR();\n    } else {\n      OUT(\" \", allow_wrap, LITERAL);\n    }\n    break;\n\n  case CMARK_NODE_CODE:\n    OUT(cmark_node_get_literal(node), allow_wrap, LITERAL);\n    break;\n\n  case CMARK_NODE_HTML_INLINE:\n    break;\n\n  case CMARK_NODE_CUSTOM_INLINE:\n    break;\n\n  case CMARK_NODE_STRONG:\n    break;\n\n  case CMARK_NODE_EMPH:\n    break;\n\n  case CMARK_NODE_LINK:\n    break;\n\n  case CMARK_NODE_IMAGE:\n    break;\n\n  case CMARK_NODE_FOOTNOTE_REFERENCE:\n    if (entering) {\n      LIT(\"[^\");\n      OUT(cmark_chunk_to_cstr(renderer->mem, &node->as.literal), false, LITERAL);\n      LIT(\"]\");\n    }\n    break;\n\n  case CMARK_NODE_FOOTNOTE_DEFINITION:\n    if (entering) {\n      renderer->footnote_ix += 1;\n      LIT(\"[^\");\n      char n[32];\n      snprintf(n, sizeof(n), \"%d\", renderer->footnote_ix);\n      OUT(n, false, LITERAL);\n      LIT(\"]: \");\n\n      cmark_strbuf_puts(renderer->prefix, \"    \");\n    } else {\n      cmark_strbuf_truncate(renderer->prefix, renderer->prefix->size - 4);\n    }\n    break;\n  default:\n    assert(false);\n    break;\n  }\n\n  return 1;\n}\n\nchar *cmark_render_plaintext(cmark_node *root, int options, int width) {\n  return cmark_render_plaintext_with_mem(root, options, width, cmark_node_mem(root));\n}\n\nchar *cmark_render_plaintext_with_mem(cmark_node *root, int options, int width, cmark_mem *mem) {\n  if (options & CMARK_OPT_HARDBREAKS) {\n    // disable breaking on width, since it has\n    // a different meaning with OPT_HARDBREAKS\n    width = 0;\n  }\n  return cmark_render(mem, root, options, width, outc, S_render_node);\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/plugin.c",
    "content": "#include <stdlib.h>\n\n#include \"plugin.h\"\n\nextern cmark_mem CMARK_DEFAULT_MEM_ALLOCATOR;\n\nint cmark_plugin_register_syntax_extension(cmark_plugin    * plugin,\n                                        cmark_syntax_extension * extension) {\n  plugin->syntax_extensions = cmark_llist_append(&CMARK_DEFAULT_MEM_ALLOCATOR, plugin->syntax_extensions, extension);\n  return 1;\n}\n\ncmark_plugin *\ncmark_plugin_new(void) {\n  cmark_plugin *res = (cmark_plugin *) CMARK_DEFAULT_MEM_ALLOCATOR.calloc(1, sizeof(cmark_plugin));\n\n  res->syntax_extensions = NULL;\n\n  return res;\n}\n\nvoid\ncmark_plugin_free(cmark_plugin *plugin) {\n  cmark_llist_free_full(&CMARK_DEFAULT_MEM_ALLOCATOR,\n                        plugin->syntax_extensions,\n                        (cmark_free_func) cmark_syntax_extension_free);\n  CMARK_DEFAULT_MEM_ALLOCATOR.free(plugin);\n}\n\ncmark_llist *\ncmark_plugin_steal_syntax_extensions(cmark_plugin *plugin) {\n  cmark_llist *res = plugin->syntax_extensions;\n\n  plugin->syntax_extensions = NULL;\n  return res;\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/plugin.h",
    "content": "#ifndef CMARK_PLUGIN_H\n#define CMARK_PLUGIN_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"cmark-gfm.h\"\n#include \"cmark-gfm-extension_api.h\"\n\n/**\n * cmark_plugin:\n *\n * A plugin structure, which should be filled by plugin's\n * init functions.\n */\nstruct cmark_plugin {\n  cmark_llist *syntax_extensions;\n};\n\ncmark_llist *\ncmark_plugin_steal_syntax_extensions(cmark_plugin *plugin);\n\ncmark_plugin *\ncmark_plugin_new(void);\n\nvoid\ncmark_plugin_free(cmark_plugin *plugin);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/references.c",
    "content": "#include \"cmark-gfm.h\"\n#include \"parser.h\"\n#include \"references.h\"\n#include \"inlines.h\"\n#include \"chunk.h\"\n\nstatic void reference_free(cmark_map *map, cmark_map_entry *_ref) {\n  cmark_reference *ref = (cmark_reference *)_ref;\n  cmark_mem *mem = map->mem;\n  if (ref != NULL) {\n    mem->free(ref->entry.label);\n    cmark_chunk_free(mem, &ref->url);\n    cmark_chunk_free(mem, &ref->title);\n    mem->free(ref);\n  }\n}\n\nvoid cmark_reference_create(cmark_map *map, cmark_chunk *label,\n                            cmark_chunk *url, cmark_chunk *title) {\n  cmark_reference *ref;\n  unsigned char *reflabel = normalize_map_label(map->mem, label);\n\n  /* empty reference name, or composed from only whitespace */\n  if (reflabel == NULL)\n    return;\n\n  assert(map->sorted == NULL);\n\n  ref = (cmark_reference *)map->mem->calloc(1, sizeof(*ref));\n  ref->entry.label = reflabel;\n  ref->url = cmark_clean_url(map->mem, url);\n  ref->title = cmark_clean_title(map->mem, title);\n  ref->entry.age = map->size;\n  ref->entry.next = map->refs;\n  ref->entry.size = ref->url.len + ref->title.len;\n\n  map->refs = (cmark_map_entry *)ref;\n  map->size++;\n}\n\ncmark_map *cmark_reference_map_new(cmark_mem *mem) {\n  return cmark_map_new(mem, reference_free);\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/references.h",
    "content": "#ifndef CMARK_REFERENCES_H\n#define CMARK_REFERENCES_H\n\n#include \"map.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nstruct cmark_reference {\n  cmark_map_entry entry;\n  cmark_chunk url;\n  cmark_chunk title;\n};\n\ntypedef struct cmark_reference cmark_reference;\n\nvoid cmark_reference_create(cmark_map *map, cmark_chunk *label,\n                            cmark_chunk *url, cmark_chunk *title);\ncmark_map *cmark_reference_map_new(cmark_mem *mem);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/registry.c",
    "content": "#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include \"config.h\"\n#include \"cmark-gfm.h\"\n#include \"syntax_extension.h\"\n#include \"registry.h\"\n#include \"plugin.h\"\n\nextern cmark_mem CMARK_DEFAULT_MEM_ALLOCATOR;\n\nstatic cmark_llist *syntax_extensions = NULL;\n\nvoid cmark_register_plugin(cmark_plugin_init_func reg_fn) {\n  cmark_plugin *plugin = cmark_plugin_new();\n\n  if (!reg_fn(plugin)) {\n    cmark_plugin_free(plugin);\n    return;\n  }\n\n  cmark_llist *syntax_extensions_list = cmark_plugin_steal_syntax_extensions(plugin),\n              *it;\n\n  for (it = syntax_extensions_list; it; it = it->next) {\n    syntax_extensions = cmark_llist_append(&CMARK_DEFAULT_MEM_ALLOCATOR, syntax_extensions, it->data);\n  }\n\n  cmark_llist_free(&CMARK_DEFAULT_MEM_ALLOCATOR, syntax_extensions_list);\n  cmark_plugin_free(plugin);\n}\n\nvoid cmark_release_plugins(void) {\n  if (syntax_extensions) {\n    cmark_llist_free_full(\n        &CMARK_DEFAULT_MEM_ALLOCATOR,\n        syntax_extensions,\n        (cmark_free_func) cmark_syntax_extension_free);\n    syntax_extensions = NULL;\n  }\n}\n\ncmark_llist *cmark_list_syntax_extensions(cmark_mem *mem) {\n  cmark_llist *it;\n  cmark_llist *res = NULL;\n\n  for (it = syntax_extensions; it; it = it->next) {\n    res = cmark_llist_append(mem, res, it->data);\n  }\n  return res;\n}\n\ncmark_syntax_extension *cmark_find_syntax_extension(const char *name) {\n  cmark_llist *tmp;\n\n  for (tmp = syntax_extensions; tmp; tmp = tmp->next) {\n    cmark_syntax_extension *ext = (cmark_syntax_extension *) tmp->data;\n    if (!strcmp(ext->name, name))\n      return ext;\n  }\n  return NULL;\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/registry.h",
    "content": "#ifndef CMARK_REGISTRY_H\n#define CMARK_REGISTRY_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"cmark-gfm.h\"\n#include \"plugin.h\"\n\nCMARK_GFM_EXPORT\nvoid cmark_register_plugin(cmark_plugin_init_func reg_fn);\n\nCMARK_GFM_EXPORT\nvoid cmark_release_plugins(void);\n\nCMARK_GFM_EXPORT\ncmark_llist *cmark_list_syntax_extensions(cmark_mem *mem);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/render.c",
    "content": "#include <stdlib.h>\n#include \"buffer.h\"\n#include \"chunk.h\"\n#include \"cmark-gfm.h\"\n#include \"utf8.h\"\n#include \"render.h\"\n#include \"node.h\"\n#include \"syntax_extension.h\"\n\nstatic CMARK_INLINE void S_cr(cmark_renderer *renderer) {\n  if (renderer->need_cr < 1) {\n    renderer->need_cr = 1;\n  }\n}\n\nstatic CMARK_INLINE void S_blankline(cmark_renderer *renderer) {\n  if (renderer->need_cr < 2) {\n    renderer->need_cr = 2;\n  }\n}\n\nstatic void S_out(cmark_renderer *renderer, cmark_node *node,\n                  const char *source, bool wrap,\n                  cmark_escaping escape) {\n  int length = (int)strlen(source);\n  unsigned char nextc;\n  int32_t c;\n  int i = 0;\n  int last_nonspace;\n  int len;\n  cmark_chunk remainder = cmark_chunk_literal(\"\");\n  int k = renderer->buffer->size - 1;\n\n  cmark_syntax_extension *ext = node->ancestor_extension;\n  if (ext && !ext->commonmark_escape_func)\n    ext = NULL;\n\n  wrap = wrap && !renderer->no_linebreaks;\n\n  if (renderer->in_tight_list_item && renderer->need_cr > 1) {\n    renderer->need_cr = 1;\n  }\n  while (renderer->need_cr) {\n    if (k < 0 || renderer->buffer->ptr[k] == '\\n') {\n      k -= 1;\n    } else {\n      cmark_strbuf_putc(renderer->buffer, '\\n');\n      if (renderer->need_cr > 1) {\n        cmark_strbuf_put(renderer->buffer, renderer->prefix->ptr,\n                         renderer->prefix->size);\n      }\n    }\n    renderer->column = 0;\n    renderer->last_breakable = 0;\n    renderer->begin_line = true;\n    renderer->begin_content = true;\n    renderer->need_cr -= 1;\n  }\n\n  while (i < length) {\n    if (renderer->begin_line) {\n      cmark_strbuf_put(renderer->buffer, renderer->prefix->ptr,\n                       renderer->prefix->size);\n      // note: this assumes prefix is ascii:\n      renderer->column = renderer->prefix->size;\n    }\n\n    len = cmark_utf8proc_iterate((const uint8_t *)source + i, length - i, &c);\n    if (len == -1) { // error condition\n      return;        // return without rendering rest of string\n    }\n\n    if (ext && ext->commonmark_escape_func(ext, node, c))\n      cmark_strbuf_putc(renderer->buffer, '\\\\');\n\n    nextc = source[i + len];\n    if (c == 32 && wrap) {\n      if (!renderer->begin_line) {\n        last_nonspace = renderer->buffer->size;\n        cmark_strbuf_putc(renderer->buffer, ' ');\n        renderer->column += 1;\n        renderer->begin_line = false;\n        renderer->begin_content = false;\n        // skip following spaces\n        while (source[i + 1] == ' ') {\n          i++;\n        }\n        // We don't allow breaks that make a digit the first character\n        // because this causes problems with commonmark output.\n        if (!cmark_isdigit(source[i + 1])) {\n          renderer->last_breakable = last_nonspace;\n        }\n      }\n\n    } else if (escape == LITERAL) {\n      if (c == 10) {\n        cmark_strbuf_putc(renderer->buffer, '\\n');\n        renderer->column = 0;\n        renderer->begin_line = true;\n        renderer->begin_content = true;\n        renderer->last_breakable = 0;\n      } else {\n        cmark_render_code_point(renderer, c);\n        renderer->begin_line = false;\n        // we don't set 'begin_content' to false til we've\n        // finished parsing a digit.  Reason:  in commonmark\n        // we need to escape a potential list marker after\n        // a digit:\n        renderer->begin_content =\n            renderer->begin_content && cmark_isdigit((char)c) == 1;\n      }\n    } else {\n      (renderer->outc)(renderer, node, escape, c, nextc);\n      renderer->begin_line = false;\n      renderer->begin_content =\n          renderer->begin_content && cmark_isdigit((char)c) == 1;\n    }\n\n    // If adding the character went beyond width, look for an\n    // earlier place where the line could be broken:\n    if (renderer->width > 0 && renderer->column > renderer->width &&\n        !renderer->begin_line && renderer->last_breakable > 0) {\n\n      // copy from last_breakable to remainder\n      cmark_chunk_set_cstr(renderer->mem, &remainder,\n                           (char *)renderer->buffer->ptr +\n                               renderer->last_breakable + 1);\n      // truncate at last_breakable\n      cmark_strbuf_truncate(renderer->buffer, renderer->last_breakable);\n      // add newline, prefix, and remainder\n      cmark_strbuf_putc(renderer->buffer, '\\n');\n      cmark_strbuf_put(renderer->buffer, renderer->prefix->ptr,\n                       renderer->prefix->size);\n      cmark_strbuf_put(renderer->buffer, remainder.data, remainder.len);\n      renderer->column = renderer->prefix->size + remainder.len;\n      cmark_chunk_free(renderer->mem, &remainder);\n      renderer->last_breakable = 0;\n      renderer->begin_line = false;\n      renderer->begin_content = false;\n    }\n\n    i += len;\n  }\n}\n\n// Assumes no newlines, assumes ascii content:\nvoid cmark_render_ascii(cmark_renderer *renderer, const char *s) {\n  int origsize = renderer->buffer->size;\n  cmark_strbuf_puts(renderer->buffer, s);\n  renderer->column += renderer->buffer->size - origsize;\n}\n\nvoid cmark_render_code_point(cmark_renderer *renderer, uint32_t c) {\n  cmark_utf8proc_encode_char(c, renderer->buffer);\n  renderer->column += 1;\n}\n\nchar *cmark_render(cmark_mem *mem, cmark_node *root, int options, int width,\n                   void (*outc)(cmark_renderer *, cmark_node *,\n                                cmark_escaping, int32_t,\n                                unsigned char),\n                   int (*render_node)(cmark_renderer *renderer,\n                                      cmark_node *node,\n                                      cmark_event_type ev_type, int options)) {\n  cmark_strbuf pref = CMARK_BUF_INIT(mem);\n  cmark_strbuf buf = CMARK_BUF_INIT(mem);\n  cmark_node *cur;\n  cmark_event_type ev_type;\n  char *result;\n  cmark_iter *iter = cmark_iter_new(root);\n\n  cmark_renderer renderer = {mem,   &buf, &pref, 0,           width,\n                             0,     0,    true,  true,        false,\n                             false, outc, S_cr,  S_blankline, S_out,\n                             0};\n\n  while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {\n    cur = cmark_iter_get_node(iter);\n    if (cur->extension) {\n      cur->ancestor_extension = cur->extension;\n    } else if (cur->parent) {\n      cur->ancestor_extension = cur->parent->ancestor_extension;\n    }\n    if (cur->type == CMARK_NODE_ITEM) {\n      // Calculate the list item's index, for the benefit of output formats\n      // like commonmark and plaintext.\n      if (cur->prev) {\n        cmark_node_set_item_index(cur, 1 + cmark_node_get_item_index(cur->prev));\n      } else {\n        cmark_node_set_item_index(cur, cmark_node_get_list_start(cur->parent));\n      }\n    }\n    if (!render_node(&renderer, cur, ev_type, options)) {\n      // a false value causes us to skip processing\n      // the node's contents.  this is used for\n      // autolinks.\n      cmark_iter_reset(iter, cur, CMARK_EVENT_EXIT);\n    }\n  }\n\n  // ensure final newline\n  if (renderer.buffer->size == 0 || renderer.buffer->ptr[renderer.buffer->size - 1] != '\\n') {\n    cmark_strbuf_putc(renderer.buffer, '\\n');\n  }\n\n  result = (char *)cmark_strbuf_detach(renderer.buffer);\n\n  cmark_iter_free(iter);\n  cmark_strbuf_free(renderer.prefix);\n  cmark_strbuf_free(renderer.buffer);\n\n  return result;\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/render.h",
    "content": "#ifndef CMARK_RENDER_H\n#define CMARK_RENDER_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdlib.h>\n#include \"buffer.h\"\n#include \"chunk.h\"\n\ntypedef enum { LITERAL, NORMAL, TITLE, URL } cmark_escaping;\n\nstruct cmark_renderer {\n  cmark_mem *mem;\n  cmark_strbuf *buffer;\n  cmark_strbuf *prefix;\n  int column;\n  int width;\n  int need_cr;\n  bufsize_t last_breakable;\n  bool begin_line;\n  bool begin_content;\n  bool no_linebreaks;\n  bool in_tight_list_item;\n  void (*outc)(struct cmark_renderer *, cmark_node *, cmark_escaping, int32_t, unsigned char);\n  void (*cr)(struct cmark_renderer *);\n  void (*blankline)(struct cmark_renderer *);\n  void (*out)(struct cmark_renderer *, cmark_node *, const char *, bool, cmark_escaping);\n  unsigned int footnote_ix;\n};\n\ntypedef struct cmark_renderer cmark_renderer;\n\nstruct cmark_html_renderer {\n  cmark_strbuf *html;\n  cmark_node *plain;\n  cmark_llist *filter_extensions;\n  unsigned int footnote_ix;\n  unsigned int written_footnote_ix;\n  void *opaque;\n};\n\ntypedef struct cmark_html_renderer cmark_html_renderer;\n\nvoid cmark_render_ascii(cmark_renderer *renderer, const char *s);\n\nvoid cmark_render_code_point(cmark_renderer *renderer, uint32_t c);\n\nchar *cmark_render(cmark_mem *mem, cmark_node *root, int options, int width,\n                   void (*outc)(cmark_renderer *, cmark_node *,\n                                cmark_escaping, int32_t,\n                                unsigned char),\n                   int (*render_node)(cmark_renderer *renderer,\n                                      cmark_node *node,\n                                      cmark_event_type ev_type, int options));\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/scanners.c",
    "content": "/* Generated by re2c 3.0 */\n#include \"scanners.h\"\n#include \"chunk.h\"\n#include <stdlib.h>\n\nbufsize_t _scan_at(bufsize_t (*scanner)(const unsigned char *), cmark_chunk *c,\n                   bufsize_t offset) {\n  bufsize_t res;\n  unsigned char *ptr = (unsigned char *)c->data;\n\n  if (ptr == NULL || offset > c->len) {\n    return 0;\n  } else {\n    unsigned char lim = ptr[c->len];\n\n    ptr[c->len] = '\\0';\n    res = scanner(ptr + offset);\n    ptr[c->len] = lim;\n  }\n\n  return res;\n}\n\n// Try to match a scheme including colon.\nbufsize_t _scan_scheme(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    yych = *p;\n    if (yych <= '@')\n      goto yy1;\n    if (yych <= 'Z')\n      goto yy3;\n    if (yych <= '`')\n      goto yy1;\n    if (yych <= 'z')\n      goto yy3;\n  yy1:\n    ++p;\n  yy2 : { return 0; }\n  yy3:\n    yych = *(marker = ++p);\n    if (yych <= '/') {\n      if (yych <= '+') {\n        if (yych <= '*')\n          goto yy2;\n      } else {\n        if (yych <= ',')\n          goto yy2;\n        if (yych >= '/')\n          goto yy2;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '9')\n          goto yy4;\n        if (yych <= '@')\n          goto yy2;\n      } else {\n        if (yych <= '`')\n          goto yy2;\n        if (yych >= '{')\n          goto yy2;\n      }\n    }\n  yy4:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych == '+')\n          goto yy6;\n      } else {\n        if (yych != '/')\n          goto yy6;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych >= 'A')\n          goto yy6;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych <= 'z')\n          goto yy6;\n      }\n    }\n  yy5:\n    p = marker;\n    goto yy2;\n  yy6:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych == '+')\n          goto yy8;\n        goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n        goto yy8;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n        goto yy8;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych <= 'z')\n          goto yy8;\n        goto yy5;\n      }\n    }\n  yy7:\n    ++p;\n    { return (bufsize_t)(p - start); }\n  yy8:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy5;\n      } else {\n        if (yych == '/')\n          goto yy5;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy7;\n        if (yych <= '@')\n          goto yy5;\n      } else {\n        if (yych <= '`')\n          goto yy5;\n        if (yych >= '{')\n          goto yy5;\n      }\n    }\n    yych = *++p;\n    if (yych == ':')\n      goto yy7;\n    goto yy5;\n  }\n}\n\n// Try to match URI autolink after first <, returning number of chars matched.\nbufsize_t _scan_autolink_uri(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    static const unsigned char yybm[] = {\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 0,   128, 0,   128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,\n    };\n    yych = *p;\n    if (yych <= '@')\n      goto yy10;\n    if (yych <= 'Z')\n      goto yy12;\n    if (yych <= '`')\n      goto yy10;\n    if (yych <= 'z')\n      goto yy12;\n  yy10:\n    ++p;\n  yy11 : { return 0; }\n  yy12:\n    yych = *(marker = ++p);\n    if (yych <= '/') {\n      if (yych <= '+') {\n        if (yych <= '*')\n          goto yy11;\n      } else {\n        if (yych <= ',')\n          goto yy11;\n        if (yych >= '/')\n          goto yy11;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '9')\n          goto yy13;\n        if (yych <= '@')\n          goto yy11;\n      } else {\n        if (yych <= '`')\n          goto yy11;\n        if (yych >= '{')\n          goto yy11;\n      }\n    }\n  yy13:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych == '+')\n          goto yy15;\n      } else {\n        if (yych != '/')\n          goto yy15;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych >= 'A')\n          goto yy15;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych <= 'z')\n          goto yy15;\n      }\n    }\n  yy14:\n    p = marker;\n    goto yy11;\n  yy15:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych == '+')\n          goto yy17;\n        goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n        goto yy17;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n        goto yy17;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych <= 'z')\n          goto yy17;\n        goto yy14;\n      }\n    }\n  yy16:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy16;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '<')\n          goto yy14;\n        if (yych <= '>')\n          goto yy18;\n        goto yy14;\n      } else {\n        if (yych <= 0xDF)\n          goto yy19;\n        if (yych <= 0xE0)\n          goto yy20;\n        goto yy21;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy22;\n        if (yych <= 0xEF)\n          goto yy21;\n        goto yy23;\n      } else {\n        if (yych <= 0xF3)\n          goto yy24;\n        if (yych <= 0xF4)\n          goto yy25;\n        goto yy14;\n      }\n    }\n  yy17:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych == '+')\n          goto yy26;\n        goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n        goto yy26;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n        goto yy26;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych <= 'z')\n          goto yy26;\n        goto yy14;\n      }\n    }\n  yy18:\n    ++p;\n    { return (bufsize_t)(p - start); }\n  yy19:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy14;\n    if (yych <= 0xBF)\n      goto yy16;\n    goto yy14;\n  yy20:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy14;\n    if (yych <= 0xBF)\n      goto yy19;\n    goto yy14;\n  yy21:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy14;\n    if (yych <= 0xBF)\n      goto yy19;\n    goto yy14;\n  yy22:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy14;\n    if (yych <= 0x9F)\n      goto yy19;\n    goto yy14;\n  yy23:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy14;\n    if (yych <= 0xBF)\n      goto yy21;\n    goto yy14;\n  yy24:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy14;\n    if (yych <= 0xBF)\n      goto yy21;\n    goto yy14;\n  yy25:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy14;\n    if (yych <= 0x8F)\n      goto yy21;\n    goto yy14;\n  yy26:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych <= ',') {\n        if (yych != '+')\n          goto yy14;\n      } else {\n        if (yych == '/')\n          goto yy14;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= ':')\n          goto yy16;\n        if (yych <= '@')\n          goto yy14;\n      } else {\n        if (yych <= '`')\n          goto yy14;\n        if (yych >= '{')\n          goto yy14;\n      }\n    }\n    yych = *++p;\n    if (yych == ':')\n      goto yy16;\n    goto yy14;\n  }\n}\n\n// Try to match email autolink after first <, returning num of chars matched.\nbufsize_t _scan_autolink_email(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    static const unsigned char yybm[] = {\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   128, 0,   128, 128, 128, 128, 128, 0,   0,\n        128, 128, 0,   128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 0,   0,   0,   128, 0,   128, 0,   128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 0,   0,   0,   128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,\n    };\n    yych = *p;\n    if (yych <= '9') {\n      if (yych <= '\\'') {\n        if (yych == '!')\n          goto yy30;\n        if (yych >= '#')\n          goto yy30;\n      } else {\n        if (yych <= ')')\n          goto yy28;\n        if (yych != ',')\n          goto yy30;\n      }\n    } else {\n      if (yych <= '?') {\n        if (yych == '=')\n          goto yy30;\n        if (yych >= '?')\n          goto yy30;\n      } else {\n        if (yych <= 'Z') {\n          if (yych >= 'A')\n            goto yy30;\n        } else {\n          if (yych <= ']')\n            goto yy28;\n          if (yych <= '~')\n            goto yy30;\n        }\n      }\n    }\n  yy28:\n    ++p;\n  yy29 : { return 0; }\n  yy30:\n    yych = *(marker = ++p);\n    if (yych <= ',') {\n      if (yych <= '\"') {\n        if (yych == '!')\n          goto yy32;\n        goto yy29;\n      } else {\n        if (yych <= '\\'')\n          goto yy32;\n        if (yych <= ')')\n          goto yy29;\n        if (yych <= '+')\n          goto yy32;\n        goto yy29;\n      }\n    } else {\n      if (yych <= '>') {\n        if (yych <= '9')\n          goto yy32;\n        if (yych == '=')\n          goto yy32;\n        goto yy29;\n      } else {\n        if (yych <= 'Z')\n          goto yy32;\n        if (yych <= ']')\n          goto yy29;\n        if (yych <= '~')\n          goto yy32;\n        goto yy29;\n      }\n    }\n  yy31:\n    yych = *++p;\n  yy32:\n    if (yybm[0 + yych] & 128) {\n      goto yy31;\n    }\n    if (yych <= '>')\n      goto yy33;\n    if (yych <= '@')\n      goto yy34;\n  yy33:\n    p = marker;\n    goto yy29;\n  yy34:\n    yych = *++p;\n    if (yych <= '@') {\n      if (yych <= '/')\n        goto yy33;\n      if (yych >= ':')\n        goto yy33;\n    } else {\n      if (yych <= 'Z')\n        goto yy35;\n      if (yych <= '`')\n        goto yy33;\n      if (yych >= '{')\n        goto yy33;\n    }\n  yy35:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy36;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy36;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy36;\n        goto yy33;\n      }\n    }\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy38;\n      if (yych <= '/')\n        goto yy33;\n      goto yy39;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy39;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy39;\n        goto yy33;\n      }\n    }\n  yy36:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych <= '-')\n          goto yy38;\n        goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy39;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy39;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy39;\n        goto yy33;\n      }\n    }\n  yy37:\n    ++p;\n    { return (bufsize_t)(p - start); }\n  yy38:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy40;\n      if (yych <= '/')\n        goto yy33;\n      goto yy41;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy41;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy41;\n        goto yy33;\n      }\n    }\n  yy39:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy41;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy41;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy41;\n        goto yy33;\n      }\n    }\n  yy40:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy42;\n      if (yych <= '/')\n        goto yy33;\n      goto yy43;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy43;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy43;\n        goto yy33;\n      }\n    }\n  yy41:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy43;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy43;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy43;\n        goto yy33;\n      }\n    }\n  yy42:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy44;\n      if (yych <= '/')\n        goto yy33;\n      goto yy45;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy45;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy45;\n        goto yy33;\n      }\n    }\n  yy43:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy45;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy45;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy45;\n        goto yy33;\n      }\n    }\n  yy44:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy46;\n      if (yych <= '/')\n        goto yy33;\n      goto yy47;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy47;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy47;\n        goto yy33;\n      }\n    }\n  yy45:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy47;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy47;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy47;\n        goto yy33;\n      }\n    }\n  yy46:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy48;\n      if (yych <= '/')\n        goto yy33;\n      goto yy49;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy49;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy49;\n        goto yy33;\n      }\n    }\n  yy47:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy49;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy49;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy49;\n        goto yy33;\n      }\n    }\n  yy48:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy50;\n      if (yych <= '/')\n        goto yy33;\n      goto yy51;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy51;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy51;\n        goto yy33;\n      }\n    }\n  yy49:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy51;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy51;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy51;\n        goto yy33;\n      }\n    }\n  yy50:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy52;\n      if (yych <= '/')\n        goto yy33;\n      goto yy53;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy53;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy53;\n        goto yy33;\n      }\n    }\n  yy51:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy53;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy53;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy53;\n        goto yy33;\n      }\n    }\n  yy52:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy54;\n      if (yych <= '/')\n        goto yy33;\n      goto yy55;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy55;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy55;\n        goto yy33;\n      }\n    }\n  yy53:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy55;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy55;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy55;\n        goto yy33;\n      }\n    }\n  yy54:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy56;\n      if (yych <= '/')\n        goto yy33;\n      goto yy57;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy57;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy57;\n        goto yy33;\n      }\n    }\n  yy55:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy57;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy57;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy57;\n        goto yy33;\n      }\n    }\n  yy56:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy58;\n      if (yych <= '/')\n        goto yy33;\n      goto yy59;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy59;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy59;\n        goto yy33;\n      }\n    }\n  yy57:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy59;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy59;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy59;\n        goto yy33;\n      }\n    }\n  yy58:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy60;\n      if (yych <= '/')\n        goto yy33;\n      goto yy61;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy61;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy61;\n        goto yy33;\n      }\n    }\n  yy59:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy61;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy61;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy61;\n        goto yy33;\n      }\n    }\n  yy60:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy62;\n      if (yych <= '/')\n        goto yy33;\n      goto yy63;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy63;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy63;\n        goto yy33;\n      }\n    }\n  yy61:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy63;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy63;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy63;\n        goto yy33;\n      }\n    }\n  yy62:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy64;\n      if (yych <= '/')\n        goto yy33;\n      goto yy65;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy65;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy65;\n        goto yy33;\n      }\n    }\n  yy63:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy65;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy65;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy65;\n        goto yy33;\n      }\n    }\n  yy64:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy66;\n      if (yych <= '/')\n        goto yy33;\n      goto yy67;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy67;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy67;\n        goto yy33;\n      }\n    }\n  yy65:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy67;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy67;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy67;\n        goto yy33;\n      }\n    }\n  yy66:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy68;\n      if (yych <= '/')\n        goto yy33;\n      goto yy69;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy69;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy69;\n        goto yy33;\n      }\n    }\n  yy67:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy69;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy69;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy69;\n        goto yy33;\n      }\n    }\n  yy68:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy70;\n      if (yych <= '/')\n        goto yy33;\n      goto yy71;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy71;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy71;\n        goto yy33;\n      }\n    }\n  yy69:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy71;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy71;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy71;\n        goto yy33;\n      }\n    }\n  yy70:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy72;\n      if (yych <= '/')\n        goto yy33;\n      goto yy73;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy73;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy73;\n        goto yy33;\n      }\n    }\n  yy71:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy73;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy73;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy73;\n        goto yy33;\n      }\n    }\n  yy72:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy74;\n      if (yych <= '/')\n        goto yy33;\n      goto yy75;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy75;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy75;\n        goto yy33;\n      }\n    }\n  yy73:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy75;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy75;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy75;\n        goto yy33;\n      }\n    }\n  yy74:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy76;\n      if (yych <= '/')\n        goto yy33;\n      goto yy77;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy77;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy77;\n        goto yy33;\n      }\n    }\n  yy75:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy77;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy77;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy77;\n        goto yy33;\n      }\n    }\n  yy76:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy78;\n      if (yych <= '/')\n        goto yy33;\n      goto yy79;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy79;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy79;\n        goto yy33;\n      }\n    }\n  yy77:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy79;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy79;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy79;\n        goto yy33;\n      }\n    }\n  yy78:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy80;\n      if (yych <= '/')\n        goto yy33;\n      goto yy81;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy81;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy81;\n        goto yy33;\n      }\n    }\n  yy79:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy81;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy81;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy81;\n        goto yy33;\n      }\n    }\n  yy80:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy82;\n      if (yych <= '/')\n        goto yy33;\n      goto yy83;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy83;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy83;\n        goto yy33;\n      }\n    }\n  yy81:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy83;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy83;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy83;\n        goto yy33;\n      }\n    }\n  yy82:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy84;\n      if (yych <= '/')\n        goto yy33;\n      goto yy85;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy85;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy85;\n        goto yy33;\n      }\n    }\n  yy83:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy85;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy85;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy85;\n        goto yy33;\n      }\n    }\n  yy84:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy86;\n      if (yych <= '/')\n        goto yy33;\n      goto yy87;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy87;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy87;\n        goto yy33;\n      }\n    }\n  yy85:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy87;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy87;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy87;\n        goto yy33;\n      }\n    }\n  yy86:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy88;\n      if (yych <= '/')\n        goto yy33;\n      goto yy89;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy89;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy89;\n        goto yy33;\n      }\n    }\n  yy87:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy89;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy89;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy89;\n        goto yy33;\n      }\n    }\n  yy88:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy90;\n      if (yych <= '/')\n        goto yy33;\n      goto yy91;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy91;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy91;\n        goto yy33;\n      }\n    }\n  yy89:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy91;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy91;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy91;\n        goto yy33;\n      }\n    }\n  yy90:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy92;\n      if (yych <= '/')\n        goto yy33;\n      goto yy93;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy93;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy93;\n        goto yy33;\n      }\n    }\n  yy91:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy93;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy93;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy93;\n        goto yy33;\n      }\n    }\n  yy92:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy94;\n      if (yych <= '/')\n        goto yy33;\n      goto yy95;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy95;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy95;\n        goto yy33;\n      }\n    }\n  yy93:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy95;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy95;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy95;\n        goto yy33;\n      }\n    }\n  yy94:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy96;\n      if (yych <= '/')\n        goto yy33;\n      goto yy97;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy97;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy97;\n        goto yy33;\n      }\n    }\n  yy95:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy97;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy97;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy97;\n        goto yy33;\n      }\n    }\n  yy96:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy98;\n      if (yych <= '/')\n        goto yy33;\n      goto yy99;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy99;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy99;\n        goto yy33;\n      }\n    }\n  yy97:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy99;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy99;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy99;\n        goto yy33;\n      }\n    }\n  yy98:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy100;\n      if (yych <= '/')\n        goto yy33;\n      goto yy101;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy101;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy101;\n        goto yy33;\n      }\n    }\n  yy99:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy101;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy101;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy101;\n        goto yy33;\n      }\n    }\n  yy100:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy102;\n      if (yych <= '/')\n        goto yy33;\n      goto yy103;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy103;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy103;\n        goto yy33;\n      }\n    }\n  yy101:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy103;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy103;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy103;\n        goto yy33;\n      }\n    }\n  yy102:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy104;\n      if (yych <= '/')\n        goto yy33;\n      goto yy105;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy105;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy105;\n        goto yy33;\n      }\n    }\n  yy103:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy105;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy105;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy105;\n        goto yy33;\n      }\n    }\n  yy104:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy106;\n      if (yych <= '/')\n        goto yy33;\n      goto yy107;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy107;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy107;\n        goto yy33;\n      }\n    }\n  yy105:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy107;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy107;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy107;\n        goto yy33;\n      }\n    }\n  yy106:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy108;\n      if (yych <= '/')\n        goto yy33;\n      goto yy109;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy109;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy109;\n        goto yy33;\n      }\n    }\n  yy107:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy109;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy109;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy109;\n        goto yy33;\n      }\n    }\n  yy108:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy110;\n      if (yych <= '/')\n        goto yy33;\n      goto yy111;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy111;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy111;\n        goto yy33;\n      }\n    }\n  yy109:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy111;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy111;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy111;\n        goto yy33;\n      }\n    }\n  yy110:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy112;\n      if (yych <= '/')\n        goto yy33;\n      goto yy113;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy113;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy113;\n        goto yy33;\n      }\n    }\n  yy111:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy113;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy113;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy113;\n        goto yy33;\n      }\n    }\n  yy112:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy114;\n      if (yych <= '/')\n        goto yy33;\n      goto yy115;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy115;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy115;\n        goto yy33;\n      }\n    }\n  yy113:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy115;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy115;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy115;\n        goto yy33;\n      }\n    }\n  yy114:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy116;\n      if (yych <= '/')\n        goto yy33;\n      goto yy117;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy117;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy117;\n        goto yy33;\n      }\n    }\n  yy115:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy117;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy117;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy117;\n        goto yy33;\n      }\n    }\n  yy116:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy118;\n      if (yych <= '/')\n        goto yy33;\n      goto yy119;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy119;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy119;\n        goto yy33;\n      }\n    }\n  yy117:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy119;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy119;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy119;\n        goto yy33;\n      }\n    }\n  yy118:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy120;\n      if (yych <= '/')\n        goto yy33;\n      goto yy121;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy121;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy121;\n        goto yy33;\n      }\n    }\n  yy119:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy121;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy121;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy121;\n        goto yy33;\n      }\n    }\n  yy120:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy122;\n      if (yych <= '/')\n        goto yy33;\n      goto yy123;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy123;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy123;\n        goto yy33;\n      }\n    }\n  yy121:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy123;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy123;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy123;\n        goto yy33;\n      }\n    }\n  yy122:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy124;\n      if (yych <= '/')\n        goto yy33;\n      goto yy125;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy125;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy125;\n        goto yy33;\n      }\n    }\n  yy123:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy125;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy125;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy125;\n        goto yy33;\n      }\n    }\n  yy124:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy126;\n      if (yych <= '/')\n        goto yy33;\n      goto yy127;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy127;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy127;\n        goto yy33;\n      }\n    }\n  yy125:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy127;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy127;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy127;\n        goto yy33;\n      }\n    }\n  yy126:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy128;\n      if (yych <= '/')\n        goto yy33;\n      goto yy129;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy129;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy129;\n        goto yy33;\n      }\n    }\n  yy127:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy129;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy129;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy129;\n        goto yy33;\n      }\n    }\n  yy128:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy130;\n      if (yych <= '/')\n        goto yy33;\n      goto yy131;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy131;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy131;\n        goto yy33;\n      }\n    }\n  yy129:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy131;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy131;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy131;\n        goto yy33;\n      }\n    }\n  yy130:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy132;\n      if (yych <= '/')\n        goto yy33;\n      goto yy133;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy133;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy133;\n        goto yy33;\n      }\n    }\n  yy131:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy133;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy133;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy133;\n        goto yy33;\n      }\n    }\n  yy132:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy134;\n      if (yych <= '/')\n        goto yy33;\n      goto yy135;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy135;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy135;\n        goto yy33;\n      }\n    }\n  yy133:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy135;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy135;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy135;\n        goto yy33;\n      }\n    }\n  yy134:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy136;\n      if (yych <= '/')\n        goto yy33;\n      goto yy137;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy137;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy137;\n        goto yy33;\n      }\n    }\n  yy135:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy137;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy137;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy137;\n        goto yy33;\n      }\n    }\n  yy136:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy138;\n      if (yych <= '/')\n        goto yy33;\n      goto yy139;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy139;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy139;\n        goto yy33;\n      }\n    }\n  yy137:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy139;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy139;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy139;\n        goto yy33;\n      }\n    }\n  yy138:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy140;\n      if (yych <= '/')\n        goto yy33;\n      goto yy141;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy141;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy141;\n        goto yy33;\n      }\n    }\n  yy139:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy141;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy141;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy141;\n        goto yy33;\n      }\n    }\n  yy140:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy142;\n      if (yych <= '/')\n        goto yy33;\n      goto yy143;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy143;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy143;\n        goto yy33;\n      }\n    }\n  yy141:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy143;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy143;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy143;\n        goto yy33;\n      }\n    }\n  yy142:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy144;\n      if (yych <= '/')\n        goto yy33;\n      goto yy145;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy145;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy145;\n        goto yy33;\n      }\n    }\n  yy143:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy145;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy145;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy145;\n        goto yy33;\n      }\n    }\n  yy144:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy146;\n      if (yych <= '/')\n        goto yy33;\n      goto yy147;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy147;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy147;\n        goto yy33;\n      }\n    }\n  yy145:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy147;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy147;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy147;\n        goto yy33;\n      }\n    }\n  yy146:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy148;\n      if (yych <= '/')\n        goto yy33;\n      goto yy149;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy149;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy149;\n        goto yy33;\n      }\n    }\n  yy147:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy149;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy149;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy149;\n        goto yy33;\n      }\n    }\n  yy148:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy150;\n      if (yych <= '/')\n        goto yy33;\n      goto yy151;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy151;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy151;\n        goto yy33;\n      }\n    }\n  yy149:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy151;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy151;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy151;\n        goto yy33;\n      }\n    }\n  yy150:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy152;\n      if (yych <= '/')\n        goto yy33;\n      goto yy153;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy153;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy153;\n        goto yy33;\n      }\n    }\n  yy151:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy153;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy153;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy153;\n        goto yy33;\n      }\n    }\n  yy152:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy154;\n      if (yych <= '/')\n        goto yy33;\n      goto yy155;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy155;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy155;\n        goto yy33;\n      }\n    }\n  yy153:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy155;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy155;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy155;\n        goto yy33;\n      }\n    }\n  yy154:\n    yych = *++p;\n    if (yych <= '9') {\n      if (yych == '-')\n        goto yy156;\n      if (yych <= '/')\n        goto yy33;\n      goto yy157;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy33;\n        goto yy157;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy157;\n        goto yy33;\n      }\n    }\n  yy155:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= ',')\n          goto yy33;\n        if (yych >= '.')\n          goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych <= '9')\n          goto yy157;\n        goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n        goto yy157;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych <= 'z')\n          goto yy157;\n        goto yy33;\n      }\n    }\n  yy156:\n    yych = *++p;\n    if (yych <= '@') {\n      if (yych <= '/')\n        goto yy33;\n      if (yych <= '9')\n        goto yy158;\n      goto yy33;\n    } else {\n      if (yych <= 'Z')\n        goto yy158;\n      if (yych <= '`')\n        goto yy33;\n      if (yych <= 'z')\n        goto yy158;\n      goto yy33;\n    }\n  yy157:\n    yych = *++p;\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych <= '-')\n          goto yy33;\n        goto yy34;\n      } else {\n        if (yych <= '/')\n          goto yy33;\n        if (yych >= ':')\n          goto yy33;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy37;\n        if (yych <= '@')\n          goto yy33;\n      } else {\n        if (yych <= '`')\n          goto yy33;\n        if (yych >= '{')\n          goto yy33;\n      }\n    }\n  yy158:\n    yych = *++p;\n    if (yych == '.')\n      goto yy34;\n    if (yych == '>')\n      goto yy37;\n    goto yy33;\n  }\n}\n\n// Try to match an HTML tag after first <, returning num of chars matched.\nbufsize_t _scan_html_tag(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    static const unsigned char yybm[] = {\n        0,   224, 224, 224, 224, 224, 224, 224, 224, 200, 200, 200, 200, 200,\n        224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224,\n        224, 224, 224, 224, 200, 224, 128, 224, 224, 224, 224, 64,  224, 224,\n        224, 224, 224, 244, 240, 224, 244, 244, 244, 244, 244, 244, 244, 244,\n        244, 244, 240, 224, 192, 192, 192, 224, 224, 244, 244, 244, 244, 244,\n        244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244,\n        244, 244, 244, 244, 244, 244, 244, 224, 224, 224, 224, 240, 192, 244,\n        244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244,\n        244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 224, 224, 224,\n        224, 224, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,\n    };\n    yych = *p;\n    if (yych <= '@') {\n      if (yych == '/')\n        goto yy162;\n    } else {\n      if (yych <= 'Z')\n        goto yy163;\n      if (yych <= '`')\n        goto yy160;\n      if (yych <= 'z')\n        goto yy163;\n    }\n  yy160:\n    ++p;\n  yy161 : { return 0; }\n  yy162:\n    yych = *(marker = ++p);\n    if (yych <= '@')\n      goto yy161;\n    if (yych <= 'Z')\n      goto yy164;\n    if (yych <= '`')\n      goto yy161;\n    if (yych <= 'z')\n      goto yy164;\n    goto yy161;\n  yy163:\n    yych = *(marker = ++p);\n    if (yych <= '.') {\n      if (yych <= 0x1F) {\n        if (yych <= 0x08)\n          goto yy161;\n        if (yych <= '\\r')\n          goto yy168;\n        goto yy161;\n      } else {\n        if (yych <= ' ')\n          goto yy168;\n        if (yych == '-')\n          goto yy168;\n        goto yy161;\n      }\n    } else {\n      if (yych <= '@') {\n        if (yych <= '9')\n          goto yy168;\n        if (yych == '>')\n          goto yy168;\n        goto yy161;\n      } else {\n        if (yych <= 'Z')\n          goto yy168;\n        if (yych <= '`')\n          goto yy161;\n        if (yych <= 'z')\n          goto yy168;\n        goto yy161;\n      }\n    }\n  yy164:\n    yych = *++p;\n    if (yybm[0 + yych] & 4) {\n      goto yy164;\n    }\n    if (yych <= 0x1F) {\n      if (yych <= 0x08)\n        goto yy165;\n      if (yych <= '\\r')\n        goto yy171;\n    } else {\n      if (yych <= ' ')\n        goto yy171;\n      if (yych == '>')\n        goto yy170;\n    }\n  yy165:\n    p = marker;\n    goto yy161;\n  yy166:\n    yych = *++p;\n    if (yybm[0 + yych] & 8) {\n      goto yy166;\n    }\n    if (yych <= '>') {\n      if (yych <= '9') {\n        if (yych == '/')\n          goto yy169;\n        goto yy165;\n      } else {\n        if (yych <= ':')\n          goto yy172;\n        if (yych <= '=')\n          goto yy165;\n        goto yy170;\n      }\n    } else {\n      if (yych <= '^') {\n        if (yych <= '@')\n          goto yy165;\n        if (yych <= 'Z')\n          goto yy172;\n        goto yy165;\n      } else {\n        if (yych == '`')\n          goto yy165;\n        if (yych <= 'z')\n          goto yy172;\n        goto yy165;\n      }\n    }\n  yy167:\n    yych = *++p;\n  yy168:\n    if (yybm[0 + yych] & 8) {\n      goto yy166;\n    }\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych == '-')\n          goto yy167;\n        goto yy165;\n      } else {\n        if (yych <= '/')\n          goto yy169;\n        if (yych <= '9')\n          goto yy167;\n        goto yy165;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy170;\n        if (yych <= '@')\n          goto yy165;\n        goto yy167;\n      } else {\n        if (yych <= '`')\n          goto yy165;\n        if (yych <= 'z')\n          goto yy167;\n        goto yy165;\n      }\n    }\n  yy169:\n    yych = *++p;\n    if (yych != '>')\n      goto yy165;\n  yy170:\n    ++p;\n    { return (bufsize_t)(p - start); }\n  yy171:\n    yych = *++p;\n    if (yych <= 0x1F) {\n      if (yych <= 0x08)\n        goto yy165;\n      if (yych <= '\\r')\n        goto yy171;\n      goto yy165;\n    } else {\n      if (yych <= ' ')\n        goto yy171;\n      if (yych == '>')\n        goto yy170;\n      goto yy165;\n    }\n  yy172:\n    yych = *++p;\n    if (yybm[0 + yych] & 16) {\n      goto yy172;\n    }\n    if (yych <= ',') {\n      if (yych <= '\\r') {\n        if (yych <= 0x08)\n          goto yy165;\n      } else {\n        if (yych != ' ')\n          goto yy165;\n      }\n    } else {\n      if (yych <= '<') {\n        if (yych <= '/')\n          goto yy169;\n        goto yy165;\n      } else {\n        if (yych <= '=')\n          goto yy174;\n        if (yych <= '>')\n          goto yy170;\n        goto yy165;\n      }\n    }\n  yy173:\n    yych = *++p;\n    if (yych <= '<') {\n      if (yych <= ' ') {\n        if (yych <= 0x08)\n          goto yy165;\n        if (yych <= '\\r')\n          goto yy173;\n        if (yych <= 0x1F)\n          goto yy165;\n        goto yy173;\n      } else {\n        if (yych <= '/') {\n          if (yych <= '.')\n            goto yy165;\n          goto yy169;\n        } else {\n          if (yych == ':')\n            goto yy172;\n          goto yy165;\n        }\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '=')\n          goto yy174;\n        if (yych <= '>')\n          goto yy170;\n        if (yych <= '@')\n          goto yy165;\n        goto yy172;\n      } else {\n        if (yych <= '_') {\n          if (yych <= '^')\n            goto yy165;\n          goto yy172;\n        } else {\n          if (yych <= '`')\n            goto yy165;\n          if (yych <= 'z')\n            goto yy172;\n          goto yy165;\n        }\n      }\n    }\n  yy174:\n    yych = *++p;\n    if (yybm[0 + yych] & 32) {\n      goto yy175;\n    }\n    if (yych <= 0xE0) {\n      if (yych <= '\"') {\n        if (yych <= 0x00)\n          goto yy165;\n        if (yych <= ' ')\n          goto yy174;\n        goto yy176;\n      } else {\n        if (yych <= '\\'')\n          goto yy177;\n        if (yych <= 0xC1)\n          goto yy165;\n        if (yych <= 0xDF)\n          goto yy178;\n        goto yy179;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy181;\n        goto yy180;\n      } else {\n        if (yych <= 0xF0)\n          goto yy182;\n        if (yych <= 0xF3)\n          goto yy183;\n        if (yych <= 0xF4)\n          goto yy184;\n        goto yy165;\n      }\n    }\n  yy175:\n    yych = *++p;\n    if (yybm[0 + yych] & 32) {\n      goto yy175;\n    }\n    if (yych <= 0xE0) {\n      if (yych <= '=') {\n        if (yych <= 0x00)\n          goto yy165;\n        if (yych <= ' ')\n          goto yy166;\n        goto yy165;\n      } else {\n        if (yych <= '>')\n          goto yy170;\n        if (yych <= 0xC1)\n          goto yy165;\n        if (yych <= 0xDF)\n          goto yy178;\n        goto yy179;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy181;\n        goto yy180;\n      } else {\n        if (yych <= 0xF0)\n          goto yy182;\n        if (yych <= 0xF3)\n          goto yy183;\n        if (yych <= 0xF4)\n          goto yy184;\n        goto yy165;\n      }\n    }\n  yy176:\n    yych = *++p;\n    if (yybm[0 + yych] & 64) {\n      goto yy176;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= 0x00)\n          goto yy165;\n        if (yych <= '\"')\n          goto yy185;\n        goto yy165;\n      } else {\n        if (yych <= 0xDF)\n          goto yy186;\n        if (yych <= 0xE0)\n          goto yy187;\n        goto yy188;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy189;\n        if (yych <= 0xEF)\n          goto yy188;\n        goto yy190;\n      } else {\n        if (yych <= 0xF3)\n          goto yy191;\n        if (yych <= 0xF4)\n          goto yy192;\n        goto yy165;\n      }\n    }\n  yy177:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy177;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= 0x00)\n          goto yy165;\n        if (yych <= '\\'')\n          goto yy185;\n        goto yy165;\n      } else {\n        if (yych <= 0xDF)\n          goto yy193;\n        if (yych <= 0xE0)\n          goto yy194;\n        goto yy195;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy196;\n        if (yych <= 0xEF)\n          goto yy195;\n        goto yy197;\n      } else {\n        if (yych <= 0xF3)\n          goto yy198;\n        if (yych <= 0xF4)\n          goto yy199;\n        goto yy165;\n      }\n    }\n  yy178:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy175;\n    goto yy165;\n  yy179:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy178;\n    goto yy165;\n  yy180:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy178;\n    goto yy165;\n  yy181:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0x9F)\n      goto yy178;\n    goto yy165;\n  yy182:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy180;\n    goto yy165;\n  yy183:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy180;\n    goto yy165;\n  yy184:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0x8F)\n      goto yy180;\n    goto yy165;\n  yy185:\n    yych = *++p;\n    if (yybm[0 + yych] & 8) {\n      goto yy166;\n    }\n    if (yych == '/')\n      goto yy169;\n    if (yych == '>')\n      goto yy170;\n    goto yy165;\n  yy186:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy176;\n    goto yy165;\n  yy187:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy186;\n    goto yy165;\n  yy188:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy186;\n    goto yy165;\n  yy189:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0x9F)\n      goto yy186;\n    goto yy165;\n  yy190:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy188;\n    goto yy165;\n  yy191:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy188;\n    goto yy165;\n  yy192:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0x8F)\n      goto yy188;\n    goto yy165;\n  yy193:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy177;\n    goto yy165;\n  yy194:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy193;\n    goto yy165;\n  yy195:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy193;\n    goto yy165;\n  yy196:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0x9F)\n      goto yy193;\n    goto yy165;\n  yy197:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy195;\n    goto yy165;\n  yy198:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0xBF)\n      goto yy195;\n    goto yy165;\n  yy199:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy165;\n    if (yych <= 0x8F)\n      goto yy195;\n    goto yy165;\n  }\n}\n\n// Try to (liberally) match an HTML tag after first <, returning num of chars\n// matched.\nbufsize_t _scan_liberal_html_tag(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    unsigned int yyaccept = 0;\n    static const unsigned char yybm[] = {\n        0,  64, 64, 64, 64, 64, 64, 64, 64,  64, 0,  64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 128, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,\n    };\n    yych = *p;\n    if (yych <= 0xE0) {\n      if (yych <= '\\n') {\n        if (yych <= 0x00)\n          goto yy201;\n        if (yych <= '\\t')\n          goto yy203;\n      } else {\n        if (yych <= 0x7F)\n          goto yy203;\n        if (yych <= 0xC1)\n          goto yy201;\n        if (yych <= 0xDF)\n          goto yy204;\n        goto yy205;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy207;\n        goto yy206;\n      } else {\n        if (yych <= 0xF0)\n          goto yy208;\n        if (yych <= 0xF3)\n          goto yy209;\n        if (yych <= 0xF4)\n          goto yy210;\n      }\n    }\n  yy201:\n    ++p;\n  yy202 : { return 0; }\n  yy203:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= '\\n') {\n      if (yych <= 0x00)\n        goto yy202;\n      if (yych <= '\\t')\n        goto yy212;\n      goto yy202;\n    } else {\n      if (yych <= 0x7F)\n        goto yy212;\n      if (yych <= 0xC1)\n        goto yy202;\n      if (yych <= 0xF4)\n        goto yy212;\n      goto yy202;\n    }\n  yy204:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy202;\n    if (yych <= 0xBF)\n      goto yy211;\n    goto yy202;\n  yy205:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x9F)\n      goto yy202;\n    if (yych <= 0xBF)\n      goto yy216;\n    goto yy202;\n  yy206:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy202;\n    if (yych <= 0xBF)\n      goto yy216;\n    goto yy202;\n  yy207:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy202;\n    if (yych <= 0x9F)\n      goto yy216;\n    goto yy202;\n  yy208:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x8F)\n      goto yy202;\n    if (yych <= 0xBF)\n      goto yy218;\n    goto yy202;\n  yy209:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy202;\n    if (yych <= 0xBF)\n      goto yy218;\n    goto yy202;\n  yy210:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy202;\n    if (yych <= 0x8F)\n      goto yy218;\n    goto yy202;\n  yy211:\n    yych = *++p;\n  yy212:\n    if (yybm[0 + yych] & 64) {\n      goto yy211;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy213;\n        if (yych <= '>')\n          goto yy214;\n      } else {\n        if (yych <= 0xDF)\n          goto yy216;\n        if (yych <= 0xE0)\n          goto yy217;\n        goto yy218;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy219;\n        if (yych <= 0xEF)\n          goto yy218;\n        goto yy220;\n      } else {\n        if (yych <= 0xF3)\n          goto yy221;\n        if (yych <= 0xF4)\n          goto yy222;\n      }\n    }\n  yy213:\n    p = marker;\n    if (yyaccept == 0) {\n      goto yy202;\n    } else {\n      goto yy215;\n    }\n  yy214:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 64) {\n      goto yy211;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy215;\n        if (yych <= '>')\n          goto yy214;\n      } else {\n        if (yych <= 0xDF)\n          goto yy216;\n        if (yych <= 0xE0)\n          goto yy217;\n        goto yy218;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy219;\n        if (yych <= 0xEF)\n          goto yy218;\n        goto yy220;\n      } else {\n        if (yych <= 0xF3)\n          goto yy221;\n        if (yych <= 0xF4)\n          goto yy222;\n      }\n    }\n  yy215 : { return (bufsize_t)(p - start); }\n  yy216:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy213;\n    if (yych <= 0xBF)\n      goto yy211;\n    goto yy213;\n  yy217:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy213;\n    if (yych <= 0xBF)\n      goto yy216;\n    goto yy213;\n  yy218:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy213;\n    if (yych <= 0xBF)\n      goto yy216;\n    goto yy213;\n  yy219:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy213;\n    if (yych <= 0x9F)\n      goto yy216;\n    goto yy213;\n  yy220:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy213;\n    if (yych <= 0xBF)\n      goto yy218;\n    goto yy213;\n  yy221:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy213;\n    if (yych <= 0xBF)\n      goto yy218;\n    goto yy213;\n  yy222:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy213;\n    if (yych <= 0x8F)\n      goto yy218;\n    goto yy213;\n  }\n}\n\nbufsize_t _scan_html_comment(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    static const unsigned char yybm[] = {\n        0,   128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 0,   128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,\n    };\n    yych = *p;\n    if (yych == '-')\n      goto yy225;\n    ++p;\n  yy224 : { return 0; }\n  yy225:\n    yych = *(marker = ++p);\n    if (yych != '-')\n      goto yy224;\n  yy226:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy226;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= 0x00)\n          goto yy227;\n        if (yych <= '-')\n          goto yy228;\n      } else {\n        if (yych <= 0xDF)\n          goto yy229;\n        if (yych <= 0xE0)\n          goto yy230;\n        goto yy231;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy232;\n        if (yych <= 0xEF)\n          goto yy231;\n        goto yy233;\n      } else {\n        if (yych <= 0xF3)\n          goto yy234;\n        if (yych <= 0xF4)\n          goto yy235;\n      }\n    }\n  yy227:\n    p = marker;\n    goto yy224;\n  yy228:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy226;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= 0x00)\n          goto yy227;\n        if (yych <= '-')\n          goto yy236;\n        goto yy227;\n      } else {\n        if (yych <= 0xDF)\n          goto yy229;\n        if (yych <= 0xE0)\n          goto yy230;\n        goto yy231;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy232;\n        if (yych <= 0xEF)\n          goto yy231;\n        goto yy233;\n      } else {\n        if (yych <= 0xF3)\n          goto yy234;\n        if (yych <= 0xF4)\n          goto yy235;\n        goto yy227;\n      }\n    }\n  yy229:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy227;\n    if (yych <= 0xBF)\n      goto yy226;\n    goto yy227;\n  yy230:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy227;\n    if (yych <= 0xBF)\n      goto yy229;\n    goto yy227;\n  yy231:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy227;\n    if (yych <= 0xBF)\n      goto yy229;\n    goto yy227;\n  yy232:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy227;\n    if (yych <= 0x9F)\n      goto yy229;\n    goto yy227;\n  yy233:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy227;\n    if (yych <= 0xBF)\n      goto yy231;\n    goto yy227;\n  yy234:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy227;\n    if (yych <= 0xBF)\n      goto yy231;\n    goto yy227;\n  yy235:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy227;\n    if (yych <= 0x8F)\n      goto yy231;\n    goto yy227;\n  yy236:\n    yych = *++p;\n    if (yych <= 0xE0) {\n      if (yych <= '>') {\n        if (yych <= 0x00)\n          goto yy227;\n        if (yych <= '=')\n          goto yy226;\n      } else {\n        if (yych <= 0x7F)\n          goto yy226;\n        if (yych <= 0xC1)\n          goto yy227;\n        if (yych <= 0xDF)\n          goto yy229;\n        goto yy230;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy232;\n        goto yy231;\n      } else {\n        if (yych <= 0xF0)\n          goto yy233;\n        if (yych <= 0xF3)\n          goto yy234;\n        if (yych <= 0xF4)\n          goto yy235;\n        goto yy227;\n      }\n    }\n    ++p;\n    { return (bufsize_t)(p - start); }\n  }\n}\n\nbufsize_t _scan_html_pi(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    unsigned int yyaccept = 0;\n    static const unsigned char yybm[] = {\n        0,   128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 0,   128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,\n    };\n    yych = *p;\n    if (yybm[0 + yych] & 128) {\n      goto yy240;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= 0x00)\n          goto yy238;\n        if (yych <= '?')\n          goto yy243;\n      } else {\n        if (yych <= 0xDF)\n          goto yy244;\n        if (yych <= 0xE0)\n          goto yy245;\n        goto yy246;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy247;\n        if (yych <= 0xEF)\n          goto yy246;\n        goto yy248;\n      } else {\n        if (yych <= 0xF3)\n          goto yy249;\n        if (yych <= 0xF4)\n          goto yy250;\n      }\n    }\n  yy238:\n    ++p;\n  yy239 : { return 0; }\n  yy240:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n  yy241:\n    if (yybm[0 + yych] & 128) {\n      goto yy240;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= 0x00)\n          goto yy242;\n        if (yych <= '?')\n          goto yy251;\n      } else {\n        if (yych <= 0xDF)\n          goto yy253;\n        if (yych <= 0xE0)\n          goto yy254;\n        goto yy255;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy256;\n        if (yych <= 0xEF)\n          goto yy255;\n        goto yy257;\n      } else {\n        if (yych <= 0xF3)\n          goto yy258;\n        if (yych <= 0xF4)\n          goto yy259;\n      }\n    }\n  yy242 : { return (bufsize_t)(p - start); }\n  yy243:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yych <= '?') {\n      if (yych <= 0x00)\n        goto yy239;\n      if (yych <= '=')\n        goto yy241;\n      if (yych <= '>')\n        goto yy239;\n      goto yy240;\n    } else {\n      if (yych <= 0x7F)\n        goto yy241;\n      if (yych <= 0xC1)\n        goto yy239;\n      if (yych <= 0xF4)\n        goto yy241;\n      goto yy239;\n    }\n  yy244:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy239;\n    if (yych <= 0xBF)\n      goto yy240;\n    goto yy239;\n  yy245:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yych <= 0x9F)\n      goto yy239;\n    if (yych <= 0xBF)\n      goto yy253;\n    goto yy239;\n  yy246:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy239;\n    if (yych <= 0xBF)\n      goto yy253;\n    goto yy239;\n  yy247:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy239;\n    if (yych <= 0x9F)\n      goto yy253;\n    goto yy239;\n  yy248:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yych <= 0x8F)\n      goto yy239;\n    if (yych <= 0xBF)\n      goto yy255;\n    goto yy239;\n  yy249:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy239;\n    if (yych <= 0xBF)\n      goto yy255;\n    goto yy239;\n  yy250:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy239;\n    if (yych <= 0x8F)\n      goto yy255;\n    goto yy239;\n  yy251:\n    yych = *++p;\n    if (yych <= 0xE0) {\n      if (yych <= '>') {\n        if (yych <= 0x00)\n          goto yy252;\n        if (yych <= '=')\n          goto yy240;\n      } else {\n        if (yych <= 0x7F)\n          goto yy240;\n        if (yych <= 0xC1)\n          goto yy252;\n        if (yych <= 0xDF)\n          goto yy253;\n        goto yy254;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy256;\n        goto yy255;\n      } else {\n        if (yych <= 0xF0)\n          goto yy257;\n        if (yych <= 0xF3)\n          goto yy258;\n        if (yych <= 0xF4)\n          goto yy259;\n      }\n    }\n  yy252:\n    p = marker;\n    if (yyaccept == 0) {\n      goto yy242;\n    } else {\n      goto yy239;\n    }\n  yy253:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy252;\n    if (yych <= 0xBF)\n      goto yy240;\n    goto yy252;\n  yy254:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy252;\n    if (yych <= 0xBF)\n      goto yy253;\n    goto yy252;\n  yy255:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy252;\n    if (yych <= 0xBF)\n      goto yy253;\n    goto yy252;\n  yy256:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy252;\n    if (yych <= 0x9F)\n      goto yy253;\n    goto yy252;\n  yy257:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy252;\n    if (yych <= 0xBF)\n      goto yy255;\n    goto yy252;\n  yy258:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy252;\n    if (yych <= 0xBF)\n      goto yy255;\n    goto yy252;\n  yy259:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy252;\n    if (yych <= 0x8F)\n      goto yy255;\n    goto yy252;\n  }\n}\n\nbufsize_t _scan_html_declaration(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    unsigned int yyaccept = 0;\n    static const unsigned char yybm[] = {\n        0,   64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,\n        64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,\n        64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,\n        64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,\n        64,  64,  64,  64,  64,  64,  0,   64,  64,  192, 192, 192, 192, 192,\n        192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,\n        192, 192, 192, 192, 192, 192, 192, 64,  64,  64,  64,  64,  64,  64,\n        64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,\n        64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,  64,\n        64,  64,  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,\n    };\n    yych = *p;\n    if (yych <= '@')\n      goto yy261;\n    if (yych <= 'Z')\n      goto yy263;\n  yy261:\n    ++p;\n  yy262 : { return 0; }\n  yy263:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 128) {\n      goto yy266;\n    }\n    if (yych <= 0x08)\n      goto yy262;\n    if (yych <= '\\r')\n      goto yy264;\n    if (yych != ' ')\n      goto yy262;\n  yy264:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 64) {\n      goto yy264;\n    }\n    if (yych <= 0xED) {\n      if (yych <= 0xDF) {\n        if (yych >= 0xC2)\n          goto yy268;\n      } else {\n        if (yych <= 0xE0)\n          goto yy269;\n        if (yych <= 0xEC)\n          goto yy270;\n        goto yy271;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xEF)\n          goto yy270;\n        goto yy272;\n      } else {\n        if (yych <= 0xF3)\n          goto yy273;\n        if (yych <= 0xF4)\n          goto yy274;\n      }\n    }\n  yy265 : { return (bufsize_t)(p - start); }\n  yy266:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy266;\n    }\n    if (yych <= 0x08)\n      goto yy267;\n    if (yych <= '\\r')\n      goto yy264;\n    if (yych == ' ')\n      goto yy264;\n  yy267:\n    p = marker;\n    if (yyaccept == 0) {\n      goto yy262;\n    } else {\n      goto yy265;\n    }\n  yy268:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy267;\n    if (yych <= 0xBF)\n      goto yy264;\n    goto yy267;\n  yy269:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy267;\n    if (yych <= 0xBF)\n      goto yy268;\n    goto yy267;\n  yy270:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy267;\n    if (yych <= 0xBF)\n      goto yy268;\n    goto yy267;\n  yy271:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy267;\n    if (yych <= 0x9F)\n      goto yy268;\n    goto yy267;\n  yy272:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy267;\n    if (yych <= 0xBF)\n      goto yy270;\n    goto yy267;\n  yy273:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy267;\n    if (yych <= 0xBF)\n      goto yy270;\n    goto yy267;\n  yy274:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy267;\n    if (yych <= 0x8F)\n      goto yy270;\n    goto yy267;\n  }\n}\n\nbufsize_t _scan_html_cdata(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    unsigned int yyaccept = 0;\n    static const unsigned char yybm[] = {\n        0,   128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 0,   128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,\n    };\n    yych = *p;\n    if (yych == 'C')\n      goto yy277;\n    if (yych == 'c')\n      goto yy277;\n    ++p;\n  yy276 : { return 0; }\n  yy277:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych == 'D')\n      goto yy278;\n    if (yych != 'd')\n      goto yy276;\n  yy278:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy280;\n    if (yych == 'a')\n      goto yy280;\n  yy279:\n    p = marker;\n    if (yyaccept == 0) {\n      goto yy276;\n    } else {\n      goto yy284;\n    }\n  yy280:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy281;\n    if (yych != 't')\n      goto yy279;\n  yy281:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy282;\n    if (yych != 'a')\n      goto yy279;\n  yy282:\n    yych = *++p;\n    if (yych != '[')\n      goto yy279;\n  yy283:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 128) {\n      goto yy283;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= 0x00)\n          goto yy284;\n        if (yych <= ']')\n          goto yy285;\n      } else {\n        if (yych <= 0xDF)\n          goto yy286;\n        if (yych <= 0xE0)\n          goto yy287;\n        goto yy288;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy289;\n        if (yych <= 0xEF)\n          goto yy288;\n        goto yy290;\n      } else {\n        if (yych <= 0xF3)\n          goto yy291;\n        if (yych <= 0xF4)\n          goto yy292;\n      }\n    }\n  yy284 : { return (bufsize_t)(p - start); }\n  yy285:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy283;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= 0x00)\n          goto yy279;\n        if (yych <= ']')\n          goto yy293;\n        goto yy279;\n      } else {\n        if (yych <= 0xDF)\n          goto yy286;\n        if (yych <= 0xE0)\n          goto yy287;\n        goto yy288;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy289;\n        if (yych <= 0xEF)\n          goto yy288;\n        goto yy290;\n      } else {\n        if (yych <= 0xF3)\n          goto yy291;\n        if (yych <= 0xF4)\n          goto yy292;\n        goto yy279;\n      }\n    }\n  yy286:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy279;\n    if (yych <= 0xBF)\n      goto yy283;\n    goto yy279;\n  yy287:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy279;\n    if (yych <= 0xBF)\n      goto yy286;\n    goto yy279;\n  yy288:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy279;\n    if (yych <= 0xBF)\n      goto yy286;\n    goto yy279;\n  yy289:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy279;\n    if (yych <= 0x9F)\n      goto yy286;\n    goto yy279;\n  yy290:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy279;\n    if (yych <= 0xBF)\n      goto yy288;\n    goto yy279;\n  yy291:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy279;\n    if (yych <= 0xBF)\n      goto yy288;\n    goto yy279;\n  yy292:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy279;\n    if (yych <= 0x8F)\n      goto yy288;\n    goto yy279;\n  yy293:\n    yych = *++p;\n    if (yych <= 0xE0) {\n      if (yych <= '>') {\n        if (yych <= 0x00)\n          goto yy279;\n        if (yych <= '=')\n          goto yy283;\n        goto yy279;\n      } else {\n        if (yych <= 0x7F)\n          goto yy283;\n        if (yych <= 0xC1)\n          goto yy279;\n        if (yych <= 0xDF)\n          goto yy286;\n        goto yy287;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy289;\n        goto yy288;\n      } else {\n        if (yych <= 0xF0)\n          goto yy290;\n        if (yych <= 0xF3)\n          goto yy291;\n        if (yych <= 0xF4)\n          goto yy292;\n        goto yy279;\n      }\n    }\n  }\n}\n\n// Try to match an HTML block tag start line, returning\n// an integer code for the type of block (1-6, matching the spec).\n// #7 is handled by a separate function, below.\nbufsize_t _scan_html_block_start(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n\n  {\n    unsigned char yych;\n    yych = *p;\n    if (yych == '<')\n      goto yy296;\n    ++p;\n  yy295 : { return 0; }\n  yy296:\n    yych = *(marker = ++p);\n    switch (yych) {\n    case '!':\n      goto yy297;\n    case '/':\n      goto yy299;\n    case '?':\n      goto yy300;\n    case 'A':\n    case 'a':\n      goto yy301;\n    case 'B':\n    case 'b':\n      goto yy302;\n    case 'C':\n    case 'c':\n      goto yy303;\n    case 'D':\n    case 'd':\n      goto yy304;\n    case 'F':\n    case 'f':\n      goto yy305;\n    case 'H':\n    case 'h':\n      goto yy306;\n    case 'I':\n    case 'i':\n      goto yy307;\n    case 'L':\n    case 'l':\n      goto yy308;\n    case 'M':\n    case 'm':\n      goto yy309;\n    case 'N':\n    case 'n':\n      goto yy310;\n    case 'O':\n    case 'o':\n      goto yy311;\n    case 'P':\n    case 'p':\n      goto yy312;\n    case 'S':\n    case 's':\n      goto yy313;\n    case 'T':\n    case 't':\n      goto yy314;\n    case 'U':\n    case 'u':\n      goto yy315;\n    default:\n      goto yy295;\n    }\n  yy297:\n    yych = *++p;\n    if (yych <= '@') {\n      if (yych == '-')\n        goto yy316;\n    } else {\n      if (yych <= 'Z')\n        goto yy317;\n      if (yych <= '[')\n        goto yy318;\n    }\n  yy298:\n    p = marker;\n    goto yy295;\n  yy299:\n    yych = *++p;\n    switch (yych) {\n    case 'A':\n    case 'a':\n      goto yy301;\n    case 'B':\n    case 'b':\n      goto yy302;\n    case 'C':\n    case 'c':\n      goto yy303;\n    case 'D':\n    case 'd':\n      goto yy304;\n    case 'F':\n    case 'f':\n      goto yy305;\n    case 'H':\n    case 'h':\n      goto yy306;\n    case 'I':\n    case 'i':\n      goto yy307;\n    case 'L':\n    case 'l':\n      goto yy308;\n    case 'M':\n    case 'm':\n      goto yy309;\n    case 'N':\n    case 'n':\n      goto yy310;\n    case 'O':\n    case 'o':\n      goto yy311;\n    case 'P':\n    case 'p':\n      goto yy319;\n    case 'S':\n    case 's':\n      goto yy320;\n    case 'T':\n    case 't':\n      goto yy321;\n    case 'U':\n    case 'u':\n      goto yy315;\n    default:\n      goto yy298;\n    }\n  yy300:\n    ++p;\n    { return 3; }\n  yy301:\n    yych = *++p;\n    if (yych <= 'S') {\n      if (yych <= 'D') {\n        if (yych <= 'C')\n          goto yy298;\n        goto yy322;\n      } else {\n        if (yych <= 'Q')\n          goto yy298;\n        if (yych <= 'R')\n          goto yy323;\n        goto yy324;\n      }\n    } else {\n      if (yych <= 'q') {\n        if (yych == 'd')\n          goto yy322;\n        goto yy298;\n      } else {\n        if (yych <= 'r')\n          goto yy323;\n        if (yych <= 's')\n          goto yy324;\n        goto yy298;\n      }\n    }\n  yy302:\n    yych = *++p;\n    if (yych <= 'O') {\n      if (yych <= 'K') {\n        if (yych == 'A')\n          goto yy325;\n        goto yy298;\n      } else {\n        if (yych <= 'L')\n          goto yy326;\n        if (yych <= 'N')\n          goto yy298;\n        goto yy327;\n      }\n    } else {\n      if (yych <= 'k') {\n        if (yych == 'a')\n          goto yy325;\n        goto yy298;\n      } else {\n        if (yych <= 'l')\n          goto yy326;\n        if (yych == 'o')\n          goto yy327;\n        goto yy298;\n      }\n    }\n  yy303:\n    yych = *++p;\n    if (yych <= 'O') {\n      if (yych <= 'D') {\n        if (yych == 'A')\n          goto yy328;\n        goto yy298;\n      } else {\n        if (yych <= 'E')\n          goto yy329;\n        if (yych <= 'N')\n          goto yy298;\n        goto yy330;\n      }\n    } else {\n      if (yych <= 'd') {\n        if (yych == 'a')\n          goto yy328;\n        goto yy298;\n      } else {\n        if (yych <= 'e')\n          goto yy329;\n        if (yych == 'o')\n          goto yy330;\n        goto yy298;\n      }\n    }\n  yy304:\n    yych = *++p;\n    switch (yych) {\n    case 'D':\n    case 'L':\n    case 'T':\n    case 'd':\n    case 'l':\n    case 't':\n      goto yy331;\n    case 'E':\n    case 'e':\n      goto yy332;\n    case 'I':\n    case 'i':\n      goto yy333;\n    default:\n      goto yy298;\n    }\n  yy305:\n    yych = *++p;\n    if (yych <= 'R') {\n      if (yych <= 'N') {\n        if (yych == 'I')\n          goto yy334;\n        goto yy298;\n      } else {\n        if (yych <= 'O')\n          goto yy335;\n        if (yych <= 'Q')\n          goto yy298;\n        goto yy336;\n      }\n    } else {\n      if (yych <= 'n') {\n        if (yych == 'i')\n          goto yy334;\n        goto yy298;\n      } else {\n        if (yych <= 'o')\n          goto yy335;\n        if (yych == 'r')\n          goto yy336;\n        goto yy298;\n      }\n    }\n  yy306:\n    yych = *++p;\n    if (yych <= 'S') {\n      if (yych <= 'D') {\n        if (yych <= '0')\n          goto yy298;\n        if (yych <= '6')\n          goto yy331;\n        goto yy298;\n      } else {\n        if (yych <= 'E')\n          goto yy337;\n        if (yych == 'R')\n          goto yy331;\n        goto yy298;\n      }\n    } else {\n      if (yych <= 'q') {\n        if (yych <= 'T')\n          goto yy338;\n        if (yych == 'e')\n          goto yy337;\n        goto yy298;\n      } else {\n        if (yych <= 'r')\n          goto yy331;\n        if (yych == 't')\n          goto yy338;\n        goto yy298;\n      }\n    }\n  yy307:\n    yych = *++p;\n    if (yych == 'F')\n      goto yy339;\n    if (yych == 'f')\n      goto yy339;\n    goto yy298;\n  yy308:\n    yych = *++p;\n    if (yych <= 'I') {\n      if (yych == 'E')\n        goto yy340;\n      if (yych <= 'H')\n        goto yy298;\n      goto yy341;\n    } else {\n      if (yych <= 'e') {\n        if (yych <= 'd')\n          goto yy298;\n        goto yy340;\n      } else {\n        if (yych == 'i')\n          goto yy341;\n        goto yy298;\n      }\n    }\n  yy309:\n    yych = *++p;\n    if (yych <= 'E') {\n      if (yych == 'A')\n        goto yy342;\n      if (yych <= 'D')\n        goto yy298;\n      goto yy343;\n    } else {\n      if (yych <= 'a') {\n        if (yych <= '`')\n          goto yy298;\n        goto yy342;\n      } else {\n        if (yych == 'e')\n          goto yy343;\n        goto yy298;\n      }\n    }\n  yy310:\n    yych = *++p;\n    if (yych <= 'O') {\n      if (yych == 'A')\n        goto yy344;\n      if (yych <= 'N')\n        goto yy298;\n      goto yy345;\n    } else {\n      if (yych <= 'a') {\n        if (yych <= '`')\n          goto yy298;\n        goto yy344;\n      } else {\n        if (yych == 'o')\n          goto yy345;\n        goto yy298;\n      }\n    }\n  yy311:\n    yych = *++p;\n    if (yych <= 'P') {\n      if (yych == 'L')\n        goto yy331;\n      if (yych <= 'O')\n        goto yy298;\n      goto yy346;\n    } else {\n      if (yych <= 'l') {\n        if (yych <= 'k')\n          goto yy298;\n        goto yy331;\n      } else {\n        if (yych == 'p')\n          goto yy346;\n        goto yy298;\n      }\n    }\n  yy312:\n    yych = *++p;\n    if (yych <= '>') {\n      if (yych <= ' ') {\n        if (yych <= 0x08)\n          goto yy298;\n        if (yych <= '\\r')\n          goto yy347;\n        if (yych <= 0x1F)\n          goto yy298;\n        goto yy347;\n      } else {\n        if (yych == '/')\n          goto yy348;\n        if (yych <= '=')\n          goto yy298;\n        goto yy347;\n      }\n    } else {\n      if (yych <= 'R') {\n        if (yych == 'A')\n          goto yy349;\n        if (yych <= 'Q')\n          goto yy298;\n        goto yy350;\n      } else {\n        if (yych <= 'a') {\n          if (yych <= '`')\n            goto yy298;\n          goto yy349;\n        } else {\n          if (yych == 'r')\n            goto yy350;\n          goto yy298;\n        }\n      }\n    }\n  yy313:\n    yych = *++p;\n    switch (yych) {\n    case 'C':\n    case 'c':\n      goto yy351;\n    case 'E':\n    case 'e':\n      goto yy352;\n    case 'O':\n    case 'o':\n      goto yy353;\n    case 'T':\n    case 't':\n      goto yy354;\n    case 'U':\n    case 'u':\n      goto yy355;\n    default:\n      goto yy298;\n    }\n  yy314:\n    yych = *++p;\n    switch (yych) {\n    case 'A':\n    case 'a':\n      goto yy356;\n    case 'B':\n    case 'b':\n      goto yy357;\n    case 'D':\n    case 'd':\n      goto yy331;\n    case 'E':\n    case 'e':\n      goto yy358;\n    case 'F':\n    case 'f':\n      goto yy359;\n    case 'H':\n    case 'h':\n      goto yy360;\n    case 'I':\n    case 'i':\n      goto yy361;\n    case 'R':\n    case 'r':\n      goto yy362;\n    default:\n      goto yy298;\n    }\n  yy315:\n    yych = *++p;\n    if (yych == 'L')\n      goto yy331;\n    if (yych == 'l')\n      goto yy331;\n    goto yy298;\n  yy316:\n    yych = *++p;\n    if (yych == '-')\n      goto yy363;\n    goto yy298;\n  yy317:\n    ++p;\n    { return 4; }\n  yy318:\n    yych = *++p;\n    if (yych == 'C')\n      goto yy364;\n    if (yych == 'c')\n      goto yy364;\n    goto yy298;\n  yy319:\n    yych = *++p;\n    if (yych <= '/') {\n      if (yych <= 0x1F) {\n        if (yych <= 0x08)\n          goto yy298;\n        if (yych <= '\\r')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= ' ')\n          goto yy347;\n        if (yych <= '.')\n          goto yy298;\n        goto yy348;\n      }\n    } else {\n      if (yych <= '@') {\n        if (yych == '>')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= 'A')\n          goto yy349;\n        if (yych == 'a')\n          goto yy349;\n        goto yy298;\n      }\n    }\n  yy320:\n    yych = *++p;\n    if (yych <= 'U') {\n      if (yych <= 'N') {\n        if (yych == 'E')\n          goto yy352;\n        goto yy298;\n      } else {\n        if (yych <= 'O')\n          goto yy353;\n        if (yych <= 'T')\n          goto yy298;\n        goto yy355;\n      }\n    } else {\n      if (yych <= 'n') {\n        if (yych == 'e')\n          goto yy352;\n        goto yy298;\n      } else {\n        if (yych <= 'o')\n          goto yy353;\n        if (yych == 'u')\n          goto yy355;\n        goto yy298;\n      }\n    }\n  yy321:\n    yych = *++p;\n    switch (yych) {\n    case 'A':\n    case 'a':\n      goto yy356;\n    case 'B':\n    case 'b':\n      goto yy357;\n    case 'D':\n    case 'd':\n      goto yy331;\n    case 'F':\n    case 'f':\n      goto yy359;\n    case 'H':\n    case 'h':\n      goto yy360;\n    case 'I':\n    case 'i':\n      goto yy361;\n    case 'R':\n    case 'r':\n      goto yy362;\n    default:\n      goto yy298;\n    }\n  yy322:\n    yych = *++p;\n    if (yych == 'D')\n      goto yy365;\n    if (yych == 'd')\n      goto yy365;\n    goto yy298;\n  yy323:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy366;\n    if (yych == 't')\n      goto yy366;\n    goto yy298;\n  yy324:\n    yych = *++p;\n    if (yych == 'I')\n      goto yy367;\n    if (yych == 'i')\n      goto yy367;\n    goto yy298;\n  yy325:\n    yych = *++p;\n    if (yych == 'S')\n      goto yy368;\n    if (yych == 's')\n      goto yy368;\n    goto yy298;\n  yy326:\n    yych = *++p;\n    if (yych == 'O')\n      goto yy369;\n    if (yych == 'o')\n      goto yy369;\n    goto yy298;\n  yy327:\n    yych = *++p;\n    if (yych == 'D')\n      goto yy370;\n    if (yych == 'd')\n      goto yy370;\n    goto yy298;\n  yy328:\n    yych = *++p;\n    if (yych == 'P')\n      goto yy371;\n    if (yych == 'p')\n      goto yy371;\n    goto yy298;\n  yy329:\n    yych = *++p;\n    if (yych == 'N')\n      goto yy372;\n    if (yych == 'n')\n      goto yy372;\n    goto yy298;\n  yy330:\n    yych = *++p;\n    if (yych == 'L')\n      goto yy373;\n    if (yych == 'l')\n      goto yy373;\n    goto yy298;\n  yy331:\n    yych = *++p;\n    if (yych <= ' ') {\n      if (yych <= 0x08)\n        goto yy298;\n      if (yych <= '\\r')\n        goto yy347;\n      if (yych <= 0x1F)\n        goto yy298;\n      goto yy347;\n    } else {\n      if (yych <= '/') {\n        if (yych <= '.')\n          goto yy298;\n        goto yy348;\n      } else {\n        if (yych == '>')\n          goto yy347;\n        goto yy298;\n      }\n    }\n  yy332:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy374;\n    if (yych == 't')\n      goto yy374;\n    goto yy298;\n  yy333:\n    yych = *++p;\n    if (yych <= 'V') {\n      if (yych <= 'Q') {\n        if (yych == 'A')\n          goto yy375;\n        goto yy298;\n      } else {\n        if (yych <= 'R')\n          goto yy331;\n        if (yych <= 'U')\n          goto yy298;\n        goto yy331;\n      }\n    } else {\n      if (yych <= 'q') {\n        if (yych == 'a')\n          goto yy375;\n        goto yy298;\n      } else {\n        if (yych <= 'r')\n          goto yy331;\n        if (yych == 'v')\n          goto yy331;\n        goto yy298;\n      }\n    }\n  yy334:\n    yych = *++p;\n    if (yych <= 'G') {\n      if (yych == 'E')\n        goto yy376;\n      if (yych <= 'F')\n        goto yy298;\n      goto yy377;\n    } else {\n      if (yych <= 'e') {\n        if (yych <= 'd')\n          goto yy298;\n        goto yy376;\n      } else {\n        if (yych == 'g')\n          goto yy377;\n        goto yy298;\n      }\n    }\n  yy335:\n    yych = *++p;\n    if (yych <= 'R') {\n      if (yych == 'O')\n        goto yy372;\n      if (yych <= 'Q')\n        goto yy298;\n      goto yy378;\n    } else {\n      if (yych <= 'o') {\n        if (yych <= 'n')\n          goto yy298;\n        goto yy372;\n      } else {\n        if (yych == 'r')\n          goto yy378;\n        goto yy298;\n      }\n    }\n  yy336:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy379;\n    if (yych == 'a')\n      goto yy379;\n    goto yy298;\n  yy337:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy380;\n    if (yych == 'a')\n      goto yy380;\n    goto yy298;\n  yy338:\n    yych = *++p;\n    if (yych == 'M')\n      goto yy315;\n    if (yych == 'm')\n      goto yy315;\n    goto yy298;\n  yy339:\n    yych = *++p;\n    if (yych == 'R')\n      goto yy381;\n    if (yych == 'r')\n      goto yy381;\n    goto yy298;\n  yy340:\n    yych = *++p;\n    if (yych == 'G')\n      goto yy382;\n    if (yych == 'g')\n      goto yy382;\n    goto yy298;\n  yy341:\n    yych = *++p;\n    if (yych <= '/') {\n      if (yych <= 0x1F) {\n        if (yych <= 0x08)\n          goto yy298;\n        if (yych <= '\\r')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= ' ')\n          goto yy347;\n        if (yych <= '.')\n          goto yy298;\n        goto yy348;\n      }\n    } else {\n      if (yych <= 'M') {\n        if (yych == '>')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= 'N')\n          goto yy383;\n        if (yych == 'n')\n          goto yy383;\n        goto yy298;\n      }\n    }\n  yy342:\n    yych = *++p;\n    if (yych == 'I')\n      goto yy384;\n    if (yych == 'i')\n      goto yy384;\n    goto yy298;\n  yy343:\n    yych = *++p;\n    if (yych == 'N')\n      goto yy385;\n    if (yych == 'n')\n      goto yy385;\n    goto yy298;\n  yy344:\n    yych = *++p;\n    if (yych == 'V')\n      goto yy331;\n    if (yych == 'v')\n      goto yy331;\n    goto yy298;\n  yy345:\n    yych = *++p;\n    if (yych == 'F')\n      goto yy386;\n    if (yych == 'f')\n      goto yy386;\n    goto yy298;\n  yy346:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy387;\n    if (yych == 't')\n      goto yy387;\n    goto yy298;\n  yy347:\n    ++p;\n    { return 6; }\n  yy348:\n    yych = *++p;\n    if (yych == '>')\n      goto yy347;\n    goto yy298;\n  yy349:\n    yych = *++p;\n    if (yych == 'R')\n      goto yy388;\n    if (yych == 'r')\n      goto yy388;\n    goto yy298;\n  yy350:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy389;\n    if (yych == 'e')\n      goto yy389;\n    goto yy298;\n  yy351:\n    yych = *++p;\n    if (yych == 'R')\n      goto yy390;\n    if (yych == 'r')\n      goto yy390;\n    goto yy298;\n  yy352:\n    yych = *++p;\n    if (yych == 'C')\n      goto yy371;\n    if (yych == 'c')\n      goto yy371;\n    goto yy298;\n  yy353:\n    yych = *++p;\n    if (yych == 'U')\n      goto yy391;\n    if (yych == 'u')\n      goto yy391;\n    goto yy298;\n  yy354:\n    yych = *++p;\n    if (yych == 'Y')\n      goto yy392;\n    if (yych == 'y')\n      goto yy392;\n    goto yy298;\n  yy355:\n    yych = *++p;\n    if (yych == 'M')\n      goto yy393;\n    if (yych == 'm')\n      goto yy393;\n    goto yy298;\n  yy356:\n    yych = *++p;\n    if (yych == 'B')\n      goto yy394;\n    if (yych == 'b')\n      goto yy394;\n    goto yy298;\n  yy357:\n    yych = *++p;\n    if (yych == 'O')\n      goto yy327;\n    if (yych == 'o')\n      goto yy327;\n    goto yy298;\n  yy358:\n    yych = *++p;\n    if (yych == 'X')\n      goto yy395;\n    if (yych == 'x')\n      goto yy395;\n    goto yy298;\n  yy359:\n    yych = *++p;\n    if (yych == 'O')\n      goto yy396;\n    if (yych == 'o')\n      goto yy396;\n    goto yy298;\n  yy360:\n    yych = *++p;\n    if (yych <= '/') {\n      if (yych <= 0x1F) {\n        if (yych <= 0x08)\n          goto yy298;\n        if (yych <= '\\r')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= ' ')\n          goto yy347;\n        if (yych <= '.')\n          goto yy298;\n        goto yy348;\n      }\n    } else {\n      if (yych <= 'D') {\n        if (yych == '>')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= 'E')\n          goto yy397;\n        if (yych == 'e')\n          goto yy397;\n        goto yy298;\n      }\n    }\n  yy361:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy394;\n    if (yych == 't')\n      goto yy394;\n    goto yy298;\n  yy362:\n    yych = *++p;\n    if (yych <= '/') {\n      if (yych <= 0x1F) {\n        if (yych <= 0x08)\n          goto yy298;\n        if (yych <= '\\r')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= ' ')\n          goto yy347;\n        if (yych <= '.')\n          goto yy298;\n        goto yy348;\n      }\n    } else {\n      if (yych <= '@') {\n        if (yych == '>')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= 'A')\n          goto yy398;\n        if (yych == 'a')\n          goto yy398;\n        goto yy298;\n      }\n    }\n  yy363:\n    ++p;\n    { return 2; }\n  yy364:\n    yych = *++p;\n    if (yych == 'D')\n      goto yy399;\n    if (yych == 'd')\n      goto yy399;\n    goto yy298;\n  yy365:\n    yych = *++p;\n    if (yych == 'R')\n      goto yy400;\n    if (yych == 'r')\n      goto yy400;\n    goto yy298;\n  yy366:\n    yych = *++p;\n    if (yych == 'I')\n      goto yy401;\n    if (yych == 'i')\n      goto yy401;\n    goto yy298;\n  yy367:\n    yych = *++p;\n    if (yych == 'D')\n      goto yy402;\n    if (yych == 'd')\n      goto yy402;\n    goto yy298;\n  yy368:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy403;\n    if (yych == 'e')\n      goto yy403;\n    goto yy298;\n  yy369:\n    yych = *++p;\n    if (yych == 'C')\n      goto yy404;\n    if (yych == 'c')\n      goto yy404;\n    goto yy298;\n  yy370:\n    yych = *++p;\n    if (yych == 'Y')\n      goto yy331;\n    if (yych == 'y')\n      goto yy331;\n    goto yy298;\n  yy371:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy405;\n    if (yych == 't')\n      goto yy405;\n    goto yy298;\n  yy372:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy406;\n    if (yych == 't')\n      goto yy406;\n    goto yy298;\n  yy373:\n    yych = *++p;\n    if (yych <= '/') {\n      if (yych <= 0x1F) {\n        if (yych <= 0x08)\n          goto yy298;\n        if (yych <= '\\r')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= ' ')\n          goto yy347;\n        if (yych <= '.')\n          goto yy298;\n        goto yy348;\n      }\n    } else {\n      if (yych <= 'F') {\n        if (yych == '>')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= 'G')\n          goto yy407;\n        if (yych == 'g')\n          goto yy407;\n        goto yy298;\n      }\n    }\n  yy374:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy408;\n    if (yych == 'a')\n      goto yy408;\n    goto yy298;\n  yy375:\n    yych = *++p;\n    if (yych == 'L')\n      goto yy409;\n    if (yych == 'l')\n      goto yy409;\n    goto yy298;\n  yy376:\n    yych = *++p;\n    if (yych == 'L')\n      goto yy410;\n    if (yych == 'l')\n      goto yy410;\n    goto yy298;\n  yy377:\n    yych = *++p;\n    if (yych <= 'U') {\n      if (yych == 'C')\n        goto yy411;\n      if (yych <= 'T')\n        goto yy298;\n      goto yy412;\n    } else {\n      if (yych <= 'c') {\n        if (yych <= 'b')\n          goto yy298;\n        goto yy411;\n      } else {\n        if (yych == 'u')\n          goto yy412;\n        goto yy298;\n      }\n    }\n  yy378:\n    yych = *++p;\n    if (yych == 'M')\n      goto yy331;\n    if (yych == 'm')\n      goto yy331;\n    goto yy298;\n  yy379:\n    yych = *++p;\n    if (yych == 'M')\n      goto yy413;\n    if (yych == 'm')\n      goto yy413;\n    goto yy298;\n  yy380:\n    yych = *++p;\n    if (yych == 'D')\n      goto yy414;\n    if (yych == 'd')\n      goto yy414;\n    goto yy298;\n  yy381:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy415;\n    if (yych == 'a')\n      goto yy415;\n    goto yy298;\n  yy382:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy416;\n    if (yych == 'e')\n      goto yy416;\n    goto yy298;\n  yy383:\n    yych = *++p;\n    if (yych == 'K')\n      goto yy331;\n    if (yych == 'k')\n      goto yy331;\n    goto yy298;\n  yy384:\n    yych = *++p;\n    if (yych == 'N')\n      goto yy331;\n    if (yych == 'n')\n      goto yy331;\n    goto yy298;\n  yy385:\n    yych = *++p;\n    if (yych == 'U')\n      goto yy417;\n    if (yych == 'u')\n      goto yy417;\n    goto yy298;\n  yy386:\n    yych = *++p;\n    if (yych == 'R')\n      goto yy418;\n    if (yych == 'r')\n      goto yy418;\n    goto yy298;\n  yy387:\n    yych = *++p;\n    if (yych <= 'I') {\n      if (yych == 'G')\n        goto yy407;\n      if (yych <= 'H')\n        goto yy298;\n      goto yy419;\n    } else {\n      if (yych <= 'g') {\n        if (yych <= 'f')\n          goto yy298;\n        goto yy407;\n      } else {\n        if (yych == 'i')\n          goto yy419;\n        goto yy298;\n      }\n    }\n  yy388:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy378;\n    if (yych == 'a')\n      goto yy378;\n    goto yy298;\n  yy389:\n    yych = *++p;\n    if (yych <= 0x1F) {\n      if (yych <= 0x08)\n        goto yy298;\n      if (yych <= '\\r')\n        goto yy420;\n      goto yy298;\n    } else {\n      if (yych <= ' ')\n        goto yy420;\n      if (yych == '>')\n        goto yy420;\n      goto yy298;\n    }\n  yy390:\n    yych = *++p;\n    if (yych == 'I')\n      goto yy421;\n    if (yych == 'i')\n      goto yy421;\n    goto yy298;\n  yy391:\n    yych = *++p;\n    if (yych == 'R')\n      goto yy422;\n    if (yych == 'r')\n      goto yy422;\n    goto yy298;\n  yy392:\n    yych = *++p;\n    if (yych == 'L')\n      goto yy350;\n    if (yych == 'l')\n      goto yy350;\n    goto yy298;\n  yy393:\n    yych = *++p;\n    if (yych == 'M')\n      goto yy423;\n    if (yych == 'm')\n      goto yy423;\n    goto yy298;\n  yy394:\n    yych = *++p;\n    if (yych == 'L')\n      goto yy402;\n    if (yych == 'l')\n      goto yy402;\n    goto yy298;\n  yy395:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy424;\n    if (yych == 't')\n      goto yy424;\n    goto yy298;\n  yy396:\n    yych = *++p;\n    if (yych == 'O')\n      goto yy425;\n    if (yych == 'o')\n      goto yy425;\n    goto yy298;\n  yy397:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy426;\n    if (yych == 'a')\n      goto yy426;\n    goto yy298;\n  yy398:\n    yych = *++p;\n    if (yych == 'C')\n      goto yy383;\n    if (yych == 'c')\n      goto yy383;\n    goto yy298;\n  yy399:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy427;\n    if (yych == 'a')\n      goto yy427;\n    goto yy298;\n  yy400:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy428;\n    if (yych == 'e')\n      goto yy428;\n    goto yy298;\n  yy401:\n    yych = *++p;\n    if (yych == 'C')\n      goto yy394;\n    if (yych == 'c')\n      goto yy394;\n    goto yy298;\n  yy402:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy331;\n    if (yych == 'e')\n      goto yy331;\n    goto yy298;\n  yy403:\n    yych = *++p;\n    if (yych <= '/') {\n      if (yych <= 0x1F) {\n        if (yych <= 0x08)\n          goto yy298;\n        if (yych <= '\\r')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= ' ')\n          goto yy347;\n        if (yych <= '.')\n          goto yy298;\n        goto yy348;\n      }\n    } else {\n      if (yych <= 'E') {\n        if (yych == '>')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= 'F')\n          goto yy429;\n        if (yych == 'f')\n          goto yy429;\n        goto yy298;\n      }\n    }\n  yy404:\n    yych = *++p;\n    if (yych == 'K')\n      goto yy430;\n    if (yych == 'k')\n      goto yy430;\n    goto yy298;\n  yy405:\n    yych = *++p;\n    if (yych == 'I')\n      goto yy419;\n    if (yych == 'i')\n      goto yy419;\n    goto yy298;\n  yy406:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy431;\n    if (yych == 'e')\n      goto yy431;\n    goto yy298;\n  yy407:\n    yych = *++p;\n    if (yych == 'R')\n      goto yy432;\n    if (yych == 'r')\n      goto yy432;\n    goto yy298;\n  yy408:\n    yych = *++p;\n    if (yych == 'I')\n      goto yy433;\n    if (yych == 'i')\n      goto yy433;\n    goto yy298;\n  yy409:\n    yych = *++p;\n    if (yych == 'O')\n      goto yy434;\n    if (yych == 'o')\n      goto yy434;\n    goto yy298;\n  yy410:\n    yych = *++p;\n    if (yych == 'D')\n      goto yy435;\n    if (yych == 'd')\n      goto yy435;\n    goto yy298;\n  yy411:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy328;\n    if (yych == 'a')\n      goto yy328;\n    goto yy298;\n  yy412:\n    yych = *++p;\n    if (yych == 'R')\n      goto yy402;\n    if (yych == 'r')\n      goto yy402;\n    goto yy298;\n  yy413:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy436;\n    if (yych == 'e')\n      goto yy436;\n    goto yy298;\n  yy414:\n    yych = *++p;\n    if (yych <= '/') {\n      if (yych <= 0x1F) {\n        if (yych <= 0x08)\n          goto yy298;\n        if (yych <= '\\r')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= ' ')\n          goto yy347;\n        if (yych <= '.')\n          goto yy298;\n        goto yy348;\n      }\n    } else {\n      if (yych <= 'D') {\n        if (yych == '>')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= 'E')\n          goto yy431;\n        if (yych == 'e')\n          goto yy431;\n        goto yy298;\n      }\n    }\n  yy415:\n    yych = *++p;\n    if (yych == 'M')\n      goto yy402;\n    if (yych == 'm')\n      goto yy402;\n    goto yy298;\n  yy416:\n    yych = *++p;\n    if (yych == 'N')\n      goto yy426;\n    if (yych == 'n')\n      goto yy426;\n    goto yy298;\n  yy417:\n    yych = *++p;\n    if (yych <= '/') {\n      if (yych <= 0x1F) {\n        if (yych <= 0x08)\n          goto yy298;\n        if (yych <= '\\r')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= ' ')\n          goto yy347;\n        if (yych <= '.')\n          goto yy298;\n        goto yy348;\n      }\n    } else {\n      if (yych <= 'H') {\n        if (yych == '>')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= 'I')\n          goto yy437;\n        if (yych == 'i')\n          goto yy437;\n        goto yy298;\n      }\n    }\n  yy418:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy438;\n    if (yych == 'a')\n      goto yy438;\n    goto yy298;\n  yy419:\n    yych = *++p;\n    if (yych == 'O')\n      goto yy384;\n    if (yych == 'o')\n      goto yy384;\n    goto yy298;\n  yy420:\n    ++p;\n    { return 1; }\n  yy421:\n    yych = *++p;\n    if (yych == 'P')\n      goto yy439;\n    if (yych == 'p')\n      goto yy439;\n    goto yy298;\n  yy422:\n    yych = *++p;\n    if (yych == 'C')\n      goto yy402;\n    if (yych == 'c')\n      goto yy402;\n    goto yy298;\n  yy423:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy440;\n    if (yych == 'a')\n      goto yy440;\n    goto yy298;\n  yy424:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy441;\n    if (yych == 'a')\n      goto yy441;\n    goto yy298;\n  yy425:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy331;\n    if (yych == 't')\n      goto yy331;\n    goto yy298;\n  yy426:\n    yych = *++p;\n    if (yych == 'D')\n      goto yy331;\n    if (yych == 'd')\n      goto yy331;\n    goto yy298;\n  yy427:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy442;\n    if (yych == 't')\n      goto yy442;\n    goto yy298;\n  yy428:\n    yych = *++p;\n    if (yych == 'S')\n      goto yy443;\n    if (yych == 's')\n      goto yy443;\n    goto yy298;\n  yy429:\n    yych = *++p;\n    if (yych == 'O')\n      goto yy444;\n    if (yych == 'o')\n      goto yy444;\n    goto yy298;\n  yy430:\n    yych = *++p;\n    if (yych == 'Q')\n      goto yy445;\n    if (yych == 'q')\n      goto yy445;\n    goto yy298;\n  yy431:\n    yych = *++p;\n    if (yych == 'R')\n      goto yy331;\n    if (yych == 'r')\n      goto yy331;\n    goto yy298;\n  yy432:\n    yych = *++p;\n    if (yych == 'O')\n      goto yy446;\n    if (yych == 'o')\n      goto yy446;\n    goto yy298;\n  yy433:\n    yych = *++p;\n    if (yych == 'L')\n      goto yy443;\n    if (yych == 'l')\n      goto yy443;\n    goto yy298;\n  yy434:\n    yych = *++p;\n    if (yych == 'G')\n      goto yy331;\n    if (yych == 'g')\n      goto yy331;\n    goto yy298;\n  yy435:\n    yych = *++p;\n    if (yych == 'S')\n      goto yy447;\n    if (yych == 's')\n      goto yy447;\n    goto yy298;\n  yy436:\n    yych = *++p;\n    if (yych <= '/') {\n      if (yych <= 0x1F) {\n        if (yych <= 0x08)\n          goto yy298;\n        if (yych <= '\\r')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= ' ')\n          goto yy347;\n        if (yych <= '.')\n          goto yy298;\n        goto yy348;\n      }\n    } else {\n      if (yych <= 'R') {\n        if (yych == '>')\n          goto yy347;\n        goto yy298;\n      } else {\n        if (yych <= 'S')\n          goto yy447;\n        if (yych == 's')\n          goto yy447;\n        goto yy298;\n      }\n    }\n  yy437:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy448;\n    if (yych == 't')\n      goto yy448;\n    goto yy298;\n  yy438:\n    yych = *++p;\n    if (yych == 'M')\n      goto yy449;\n    if (yych == 'm')\n      goto yy449;\n    goto yy298;\n  yy439:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy389;\n    if (yych == 't')\n      goto yy389;\n    goto yy298;\n  yy440:\n    yych = *++p;\n    if (yych == 'R')\n      goto yy370;\n    if (yych == 'r')\n      goto yy370;\n    goto yy298;\n  yy441:\n    yych = *++p;\n    if (yych == 'R')\n      goto yy450;\n    if (yych == 'r')\n      goto yy450;\n    goto yy298;\n  yy442:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy451;\n    if (yych == 'a')\n      goto yy451;\n    goto yy298;\n  yy443:\n    yych = *++p;\n    if (yych == 'S')\n      goto yy331;\n    if (yych == 's')\n      goto yy331;\n    goto yy298;\n  yy444:\n    yych = *++p;\n    if (yych == 'N')\n      goto yy425;\n    if (yych == 'n')\n      goto yy425;\n    goto yy298;\n  yy445:\n    yych = *++p;\n    if (yych == 'U')\n      goto yy452;\n    if (yych == 'u')\n      goto yy452;\n    goto yy298;\n  yy446:\n    yych = *++p;\n    if (yych == 'U')\n      goto yy453;\n    if (yych == 'u')\n      goto yy453;\n    goto yy298;\n  yy447:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy425;\n    if (yych == 'e')\n      goto yy425;\n    goto yy298;\n  yy448:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy378;\n    if (yych == 'e')\n      goto yy378;\n    goto yy298;\n  yy449:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy443;\n    if (yych == 'e')\n      goto yy443;\n    goto yy298;\n  yy450:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy454;\n    if (yych == 'e')\n      goto yy454;\n    goto yy298;\n  yy451:\n    yych = *++p;\n    if (yych == '[')\n      goto yy455;\n    goto yy298;\n  yy452:\n    yych = *++p;\n    if (yych == 'O')\n      goto yy456;\n    if (yych == 'o')\n      goto yy456;\n    goto yy298;\n  yy453:\n    yych = *++p;\n    if (yych == 'P')\n      goto yy331;\n    if (yych == 'p')\n      goto yy331;\n    goto yy298;\n  yy454:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy389;\n    if (yych == 'a')\n      goto yy389;\n    goto yy298;\n  yy455:\n    ++p;\n    { return 5; }\n  yy456:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy402;\n    if (yych == 't')\n      goto yy402;\n    goto yy298;\n  }\n}\n\n// Try to match an HTML block tag start line of type 7, returning\n// 7 if successful, 0 if not.\nbufsize_t _scan_html_block_start_7(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n\n  {\n    unsigned char yych;\n    unsigned int yyaccept = 0;\n    static const unsigned char yybm[] = {\n        0,   224, 224, 224, 224, 224, 224, 224, 224, 198, 210, 194, 198, 194,\n        224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224,\n        224, 224, 224, 224, 198, 224, 128, 224, 224, 224, 224, 64,  224, 224,\n        224, 224, 224, 233, 232, 224, 233, 233, 233, 233, 233, 233, 233, 233,\n        233, 233, 232, 224, 192, 192, 192, 224, 224, 233, 233, 233, 233, 233,\n        233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233,\n        233, 233, 233, 233, 233, 233, 233, 224, 224, 224, 224, 232, 192, 233,\n        233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233,\n        233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 224, 224, 224,\n        224, 224, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,\n    };\n    yych = *p;\n    if (yych == '<')\n      goto yy459;\n    ++p;\n  yy458 : { return 0; }\n  yy459:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= '@') {\n      if (yych != '/')\n        goto yy458;\n    } else {\n      if (yych <= 'Z')\n        goto yy461;\n      if (yych <= '`')\n        goto yy458;\n      if (yych <= 'z')\n        goto yy461;\n      goto yy458;\n    }\n    yych = *++p;\n    if (yych <= '@')\n      goto yy460;\n    if (yych <= 'Z')\n      goto yy462;\n    if (yych <= '`')\n      goto yy460;\n    if (yych <= 'z')\n      goto yy462;\n  yy460:\n    p = marker;\n    if (yyaccept == 0) {\n      goto yy458;\n    } else {\n      goto yy469;\n    }\n  yy461:\n    yych = *++p;\n    if (yybm[0 + yych] & 2) {\n      goto yy463;\n    }\n    if (yych <= '=') {\n      if (yych <= '.') {\n        if (yych == '-')\n          goto yy461;\n        goto yy460;\n      } else {\n        if (yych <= '/')\n          goto yy464;\n        if (yych <= '9')\n          goto yy461;\n        goto yy460;\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '>')\n          goto yy465;\n        if (yych <= '@')\n          goto yy460;\n        goto yy461;\n      } else {\n        if (yych <= '`')\n          goto yy460;\n        if (yych <= 'z')\n          goto yy461;\n        goto yy460;\n      }\n    }\n  yy462:\n    yych = *++p;\n    if (yych <= '/') {\n      if (yych <= 0x1F) {\n        if (yych <= 0x08)\n          goto yy460;\n        if (yych <= '\\r')\n          goto yy466;\n        goto yy460;\n      } else {\n        if (yych <= ' ')\n          goto yy466;\n        if (yych == '-')\n          goto yy462;\n        goto yy460;\n      }\n    } else {\n      if (yych <= '@') {\n        if (yych <= '9')\n          goto yy462;\n        if (yych == '>')\n          goto yy465;\n        goto yy460;\n      } else {\n        if (yych <= 'Z')\n          goto yy462;\n        if (yych <= '`')\n          goto yy460;\n        if (yych <= 'z')\n          goto yy462;\n        goto yy460;\n      }\n    }\n  yy463:\n    yych = *++p;\n    if (yybm[0 + yych] & 2) {\n      goto yy463;\n    }\n    if (yych <= '>') {\n      if (yych <= '9') {\n        if (yych != '/')\n          goto yy460;\n      } else {\n        if (yych <= ':')\n          goto yy467;\n        if (yych <= '=')\n          goto yy460;\n        goto yy465;\n      }\n    } else {\n      if (yych <= '^') {\n        if (yych <= '@')\n          goto yy460;\n        if (yych <= 'Z')\n          goto yy467;\n        goto yy460;\n      } else {\n        if (yych == '`')\n          goto yy460;\n        if (yych <= 'z')\n          goto yy467;\n        goto yy460;\n      }\n    }\n  yy464:\n    yych = *++p;\n    if (yych != '>')\n      goto yy460;\n  yy465:\n    yych = *++p;\n    if (yybm[0 + yych] & 4) {\n      goto yy465;\n    }\n    if (yych <= 0x08)\n      goto yy460;\n    if (yych <= '\\n')\n      goto yy468;\n    if (yych <= '\\v')\n      goto yy460;\n    if (yych <= '\\r')\n      goto yy470;\n    goto yy460;\n  yy466:\n    yych = *++p;\n    if (yych <= 0x1F) {\n      if (yych <= 0x08)\n        goto yy460;\n      if (yych <= '\\r')\n        goto yy466;\n      goto yy460;\n    } else {\n      if (yych <= ' ')\n        goto yy466;\n      if (yych == '>')\n        goto yy465;\n      goto yy460;\n    }\n  yy467:\n    yych = *++p;\n    if (yybm[0 + yych] & 8) {\n      goto yy467;\n    }\n    if (yych <= ',') {\n      if (yych <= '\\r') {\n        if (yych <= 0x08)\n          goto yy460;\n        goto yy471;\n      } else {\n        if (yych == ' ')\n          goto yy471;\n        goto yy460;\n      }\n    } else {\n      if (yych <= '<') {\n        if (yych <= '/')\n          goto yy464;\n        goto yy460;\n      } else {\n        if (yych <= '=')\n          goto yy472;\n        if (yych <= '>')\n          goto yy465;\n        goto yy460;\n      }\n    }\n  yy468:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 4) {\n      goto yy465;\n    }\n    if (yych <= 0x08)\n      goto yy469;\n    if (yych <= '\\n')\n      goto yy468;\n    if (yych <= '\\v')\n      goto yy469;\n    if (yych <= '\\r')\n      goto yy470;\n  yy469 : { return 7; }\n  yy470:\n    ++p;\n    goto yy469;\n  yy471:\n    yych = *++p;\n    if (yych <= '<') {\n      if (yych <= ' ') {\n        if (yych <= 0x08)\n          goto yy460;\n        if (yych <= '\\r')\n          goto yy471;\n        if (yych <= 0x1F)\n          goto yy460;\n        goto yy471;\n      } else {\n        if (yych <= '/') {\n          if (yych <= '.')\n            goto yy460;\n          goto yy464;\n        } else {\n          if (yych == ':')\n            goto yy467;\n          goto yy460;\n        }\n      }\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '=')\n          goto yy472;\n        if (yych <= '>')\n          goto yy465;\n        if (yych <= '@')\n          goto yy460;\n        goto yy467;\n      } else {\n        if (yych <= '_') {\n          if (yych <= '^')\n            goto yy460;\n          goto yy467;\n        } else {\n          if (yych <= '`')\n            goto yy460;\n          if (yych <= 'z')\n            goto yy467;\n          goto yy460;\n        }\n      }\n    }\n  yy472:\n    yych = *++p;\n    if (yybm[0 + yych] & 32) {\n      goto yy473;\n    }\n    if (yych <= 0xE0) {\n      if (yych <= '\"') {\n        if (yych <= 0x00)\n          goto yy460;\n        if (yych <= ' ')\n          goto yy472;\n        goto yy474;\n      } else {\n        if (yych <= '\\'')\n          goto yy475;\n        if (yych <= 0xC1)\n          goto yy460;\n        if (yych <= 0xDF)\n          goto yy476;\n        goto yy477;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy479;\n        goto yy478;\n      } else {\n        if (yych <= 0xF0)\n          goto yy480;\n        if (yych <= 0xF3)\n          goto yy481;\n        if (yych <= 0xF4)\n          goto yy482;\n        goto yy460;\n      }\n    }\n  yy473:\n    yych = *++p;\n    if (yybm[0 + yych] & 32) {\n      goto yy473;\n    }\n    if (yych <= 0xE0) {\n      if (yych <= '=') {\n        if (yych <= 0x00)\n          goto yy460;\n        if (yych <= ' ')\n          goto yy463;\n        goto yy460;\n      } else {\n        if (yych <= '>')\n          goto yy465;\n        if (yych <= 0xC1)\n          goto yy460;\n        if (yych <= 0xDF)\n          goto yy476;\n        goto yy477;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy479;\n        goto yy478;\n      } else {\n        if (yych <= 0xF0)\n          goto yy480;\n        if (yych <= 0xF3)\n          goto yy481;\n        if (yych <= 0xF4)\n          goto yy482;\n        goto yy460;\n      }\n    }\n  yy474:\n    yych = *++p;\n    if (yybm[0 + yych] & 64) {\n      goto yy474;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= 0x00)\n          goto yy460;\n        if (yych <= '\"')\n          goto yy483;\n        goto yy460;\n      } else {\n        if (yych <= 0xDF)\n          goto yy484;\n        if (yych <= 0xE0)\n          goto yy485;\n        goto yy486;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy487;\n        if (yych <= 0xEF)\n          goto yy486;\n        goto yy488;\n      } else {\n        if (yych <= 0xF3)\n          goto yy489;\n        if (yych <= 0xF4)\n          goto yy490;\n        goto yy460;\n      }\n    }\n  yy475:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy475;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= 0x00)\n          goto yy460;\n        if (yych <= '\\'')\n          goto yy483;\n        goto yy460;\n      } else {\n        if (yych <= 0xDF)\n          goto yy491;\n        if (yych <= 0xE0)\n          goto yy492;\n        goto yy493;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy494;\n        if (yych <= 0xEF)\n          goto yy493;\n        goto yy495;\n      } else {\n        if (yych <= 0xF3)\n          goto yy496;\n        if (yych <= 0xF4)\n          goto yy497;\n        goto yy460;\n      }\n    }\n  yy476:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy473;\n    goto yy460;\n  yy477:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy476;\n    goto yy460;\n  yy478:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy476;\n    goto yy460;\n  yy479:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0x9F)\n      goto yy476;\n    goto yy460;\n  yy480:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy478;\n    goto yy460;\n  yy481:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy478;\n    goto yy460;\n  yy482:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0x8F)\n      goto yy478;\n    goto yy460;\n  yy483:\n    yych = *++p;\n    if (yybm[0 + yych] & 2) {\n      goto yy463;\n    }\n    if (yych == '/')\n      goto yy464;\n    if (yych == '>')\n      goto yy465;\n    goto yy460;\n  yy484:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy474;\n    goto yy460;\n  yy485:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy484;\n    goto yy460;\n  yy486:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy484;\n    goto yy460;\n  yy487:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0x9F)\n      goto yy484;\n    goto yy460;\n  yy488:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy486;\n    goto yy460;\n  yy489:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy486;\n    goto yy460;\n  yy490:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0x8F)\n      goto yy486;\n    goto yy460;\n  yy491:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy475;\n    goto yy460;\n  yy492:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy491;\n    goto yy460;\n  yy493:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy491;\n    goto yy460;\n  yy494:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0x9F)\n      goto yy491;\n    goto yy460;\n  yy495:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy493;\n    goto yy460;\n  yy496:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0xBF)\n      goto yy493;\n    goto yy460;\n  yy497:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy460;\n    if (yych <= 0x8F)\n      goto yy493;\n    goto yy460;\n  }\n}\n\n// Try to match an HTML block end line of type 1\nbufsize_t _scan_html_block_end_1(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    unsigned int yyaccept = 0;\n    static const unsigned char yybm[] = {\n        0,  64, 64, 64, 64, 64, 64,  64, 64, 64, 0,  64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 128, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,\n    };\n    yych = *p;\n    if (yych <= 0xDF) {\n      if (yych <= ';') {\n        if (yych <= 0x00)\n          goto yy499;\n        if (yych != '\\n')\n          goto yy501;\n      } else {\n        if (yych <= '<')\n          goto yy502;\n        if (yych <= 0x7F)\n          goto yy501;\n        if (yych >= 0xC2)\n          goto yy503;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych <= 0xE0)\n          goto yy504;\n        if (yych == 0xED)\n          goto yy506;\n        goto yy505;\n      } else {\n        if (yych <= 0xF0)\n          goto yy507;\n        if (yych <= 0xF3)\n          goto yy508;\n        if (yych <= 0xF4)\n          goto yy509;\n      }\n    }\n  yy499:\n    ++p;\n  yy500 : { return 0; }\n  yy501:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= '\\n') {\n      if (yych <= 0x00)\n        goto yy500;\n      if (yych <= '\\t')\n        goto yy511;\n      goto yy500;\n    } else {\n      if (yych <= 0x7F)\n        goto yy511;\n      if (yych <= 0xC1)\n        goto yy500;\n      if (yych <= 0xF4)\n        goto yy511;\n      goto yy500;\n    }\n  yy502:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= '.') {\n      if (yych <= 0x00)\n        goto yy500;\n      if (yych == '\\n')\n        goto yy500;\n      goto yy511;\n    } else {\n      if (yych <= 0x7F) {\n        if (yych <= '/')\n          goto yy521;\n        goto yy511;\n      } else {\n        if (yych <= 0xC1)\n          goto yy500;\n        if (yych <= 0xF4)\n          goto yy511;\n        goto yy500;\n      }\n    }\n  yy503:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy500;\n    if (yych <= 0xBF)\n      goto yy510;\n    goto yy500;\n  yy504:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x9F)\n      goto yy500;\n    if (yych <= 0xBF)\n      goto yy514;\n    goto yy500;\n  yy505:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy500;\n    if (yych <= 0xBF)\n      goto yy514;\n    goto yy500;\n  yy506:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy500;\n    if (yych <= 0x9F)\n      goto yy514;\n    goto yy500;\n  yy507:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x8F)\n      goto yy500;\n    if (yych <= 0xBF)\n      goto yy516;\n    goto yy500;\n  yy508:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy500;\n    if (yych <= 0xBF)\n      goto yy516;\n    goto yy500;\n  yy509:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy500;\n    if (yych <= 0x8F)\n      goto yy516;\n    goto yy500;\n  yy510:\n    yych = *++p;\n  yy511:\n    if (yybm[0 + yych] & 64) {\n      goto yy510;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy512;\n        if (yych <= '<')\n          goto yy513;\n      } else {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        goto yy516;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy517;\n        if (yych <= 0xEF)\n          goto yy516;\n        goto yy518;\n      } else {\n        if (yych <= 0xF3)\n          goto yy519;\n        if (yych <= 0xF4)\n          goto yy520;\n      }\n    }\n  yy512:\n    p = marker;\n    if (yyaccept == 0) {\n      goto yy500;\n    } else {\n      goto yy534;\n    }\n  yy513:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xDF) {\n      if (yych <= '.') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= '/')\n          goto yy521;\n        if (yych <= 0x7F)\n          goto yy510;\n        if (yych <= 0xC1)\n          goto yy512;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych == 0xED)\n          goto yy517;\n        goto yy516;\n      } else {\n        if (yych <= 0xF0)\n          goto yy518;\n        if (yych <= 0xF3)\n          goto yy519;\n        if (yych <= 0xF4)\n          goto yy520;\n        goto yy512;\n      }\n    }\n  yy514:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy512;\n    if (yych <= 0xBF)\n      goto yy510;\n    goto yy512;\n  yy515:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy512;\n    if (yych <= 0xBF)\n      goto yy514;\n    goto yy512;\n  yy516:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy512;\n    if (yych <= 0xBF)\n      goto yy514;\n    goto yy512;\n  yy517:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy512;\n    if (yych <= 0x9F)\n      goto yy514;\n    goto yy512;\n  yy518:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy512;\n    if (yych <= 0xBF)\n      goto yy516;\n    goto yy512;\n  yy519:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy512;\n    if (yych <= 0xBF)\n      goto yy516;\n    goto yy512;\n  yy520:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy512;\n    if (yych <= 0x8F)\n      goto yy516;\n    goto yy512;\n  yy521:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 's') {\n      if (yych <= 'R') {\n        if (yych <= '\\n') {\n          if (yych <= 0x00)\n            goto yy512;\n          if (yych <= '\\t')\n            goto yy510;\n          goto yy512;\n        } else {\n          if (yych != 'P')\n            goto yy510;\n        }\n      } else {\n        if (yych <= 'o') {\n          if (yych <= 'S')\n            goto yy523;\n          if (yych <= 'T')\n            goto yy524;\n          goto yy510;\n        } else {\n          if (yych <= 'p')\n            goto yy522;\n          if (yych <= 'r')\n            goto yy510;\n          goto yy523;\n        }\n      }\n    } else {\n      if (yych <= 0xEC) {\n        if (yych <= 0xC1) {\n          if (yych <= 't')\n            goto yy524;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        } else {\n          if (yych <= 0xDF)\n            goto yy514;\n          if (yych <= 0xE0)\n            goto yy515;\n          goto yy516;\n        }\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xED)\n            goto yy517;\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy522:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= 'Q') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= 'q') {\n          if (yych <= 'R')\n            goto yy525;\n          goto yy510;\n        } else {\n          if (yych <= 'r')\n            goto yy525;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy523:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 't') {\n      if (yych <= 'C') {\n        if (yych <= '\\t') {\n          if (yych <= 0x00)\n            goto yy512;\n          goto yy510;\n        } else {\n          if (yych <= '\\n')\n            goto yy512;\n          if (yych <= 'B')\n            goto yy510;\n          goto yy526;\n        }\n      } else {\n        if (yych <= 'b') {\n          if (yych == 'T')\n            goto yy527;\n          goto yy510;\n        } else {\n          if (yych <= 'c')\n            goto yy526;\n          if (yych <= 's')\n            goto yy510;\n          goto yy527;\n        }\n      }\n    } else {\n      if (yych <= 0xEC) {\n        if (yych <= 0xC1) {\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        } else {\n          if (yych <= 0xDF)\n            goto yy514;\n          if (yych <= 0xE0)\n            goto yy515;\n          goto yy516;\n        }\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xED)\n            goto yy517;\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy524:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= 'D') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= 'd') {\n          if (yych <= 'E')\n            goto yy528;\n          goto yy510;\n        } else {\n          if (yych <= 'e')\n            goto yy528;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy525:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= 'D') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= 'd') {\n          if (yych <= 'E')\n            goto yy529;\n          goto yy510;\n        } else {\n          if (yych <= 'e')\n            goto yy529;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy526:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= 'Q') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= 'q') {\n          if (yych <= 'R')\n            goto yy530;\n          goto yy510;\n        } else {\n          if (yych <= 'r')\n            goto yy530;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy527:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= 'X') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= 'x') {\n          if (yych <= 'Y')\n            goto yy531;\n          goto yy510;\n        } else {\n          if (yych <= 'y')\n            goto yy531;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy528:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= 'W') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= 'w') {\n          if (yych <= 'X')\n            goto yy532;\n          goto yy510;\n        } else {\n          if (yych <= 'x')\n            goto yy532;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy529:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xDF) {\n      if (yych <= '=') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= '>')\n          goto yy533;\n        if (yych <= 0x7F)\n          goto yy510;\n        if (yych <= 0xC1)\n          goto yy512;\n        goto yy514;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych == 0xED)\n          goto yy517;\n        goto yy516;\n      } else {\n        if (yych <= 0xF0)\n          goto yy518;\n        if (yych <= 0xF3)\n          goto yy519;\n        if (yych <= 0xF4)\n          goto yy520;\n        goto yy512;\n      }\n    }\n  yy530:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= 'H') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= 'h') {\n          if (yych <= 'I')\n            goto yy535;\n          goto yy510;\n        } else {\n          if (yych <= 'i')\n            goto yy535;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy531:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= 'K') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= 'k') {\n          if (yych <= 'L')\n            goto yy525;\n          goto yy510;\n        } else {\n          if (yych <= 'l')\n            goto yy525;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy532:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= 'S') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= 's') {\n          if (yych <= 'T')\n            goto yy536;\n          goto yy510;\n        } else {\n          if (yych <= 't')\n            goto yy536;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy533:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 64) {\n      goto yy510;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy534;\n        if (yych <= '<')\n          goto yy513;\n      } else {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        goto yy516;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy517;\n        if (yych <= 0xEF)\n          goto yy516;\n        goto yy518;\n      } else {\n        if (yych <= 0xF3)\n          goto yy519;\n        if (yych <= 0xF4)\n          goto yy520;\n      }\n    }\n  yy534 : { return (bufsize_t)(p - start); }\n  yy535:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= 'O') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= 'o') {\n          if (yych <= 'P')\n            goto yy537;\n          goto yy510;\n        } else {\n          if (yych <= 'p')\n            goto yy537;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy536:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= '@') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= '`') {\n          if (yych <= 'A')\n            goto yy538;\n          goto yy510;\n        } else {\n          if (yych <= 'a')\n            goto yy538;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy537:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= 'S') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= 's') {\n          if (yych <= 'T')\n            goto yy529;\n          goto yy510;\n        } else {\n          if (yych <= 't')\n            goto yy529;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy538:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= 'Q') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= 'q') {\n          if (yych >= 'S')\n            goto yy510;\n        } else {\n          if (yych <= 'r')\n            goto yy539;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy539:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= 'D') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= 'd') {\n          if (yych >= 'F')\n            goto yy510;\n        } else {\n          if (yych <= 'e')\n            goto yy540;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  yy540:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy513;\n    }\n    if (yych <= 0xC1) {\n      if (yych <= '@') {\n        if (yych <= 0x00)\n          goto yy512;\n        if (yych == '\\n')\n          goto yy512;\n        goto yy510;\n      } else {\n        if (yych <= '`') {\n          if (yych <= 'A')\n            goto yy529;\n          goto yy510;\n        } else {\n          if (yych <= 'a')\n            goto yy529;\n          if (yych <= 0x7F)\n            goto yy510;\n          goto yy512;\n        }\n      }\n    } else {\n      if (yych <= 0xED) {\n        if (yych <= 0xDF)\n          goto yy514;\n        if (yych <= 0xE0)\n          goto yy515;\n        if (yych <= 0xEC)\n          goto yy516;\n        goto yy517;\n      } else {\n        if (yych <= 0xF0) {\n          if (yych <= 0xEF)\n            goto yy516;\n          goto yy518;\n        } else {\n          if (yych <= 0xF3)\n            goto yy519;\n          if (yych <= 0xF4)\n            goto yy520;\n          goto yy512;\n        }\n      }\n    }\n  }\n}\n\n// Try to match an HTML block end line of type 2\nbufsize_t _scan_html_block_end_2(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    unsigned int yyaccept = 0;\n    static const unsigned char yybm[] = {\n        0,  64, 64, 64, 64, 64, 64, 64, 64, 64,  0,  64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64, 128, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,\n    };\n    yych = *p;\n    if (yych <= 0xDF) {\n      if (yych <= ',') {\n        if (yych <= 0x00)\n          goto yy542;\n        if (yych != '\\n')\n          goto yy544;\n      } else {\n        if (yych <= '-')\n          goto yy545;\n        if (yych <= 0x7F)\n          goto yy544;\n        if (yych >= 0xC2)\n          goto yy546;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych <= 0xE0)\n          goto yy547;\n        if (yych == 0xED)\n          goto yy549;\n        goto yy548;\n      } else {\n        if (yych <= 0xF0)\n          goto yy550;\n        if (yych <= 0xF3)\n          goto yy551;\n        if (yych <= 0xF4)\n          goto yy552;\n      }\n    }\n  yy542:\n    ++p;\n  yy543 : { return 0; }\n  yy544:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= '\\n') {\n      if (yych <= 0x00)\n        goto yy543;\n      if (yych <= '\\t')\n        goto yy554;\n      goto yy543;\n    } else {\n      if (yych <= 0x7F)\n        goto yy554;\n      if (yych <= 0xC1)\n        goto yy543;\n      if (yych <= 0xF4)\n        goto yy554;\n      goto yy543;\n    }\n  yy545:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 128) {\n      goto yy564;\n    }\n    if (yych <= '\\n') {\n      if (yych <= 0x00)\n        goto yy543;\n      if (yych <= '\\t')\n        goto yy554;\n      goto yy543;\n    } else {\n      if (yych <= 0x7F)\n        goto yy554;\n      if (yych <= 0xC1)\n        goto yy543;\n      if (yych <= 0xF4)\n        goto yy554;\n      goto yy543;\n    }\n  yy546:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy543;\n    if (yych <= 0xBF)\n      goto yy553;\n    goto yy543;\n  yy547:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x9F)\n      goto yy543;\n    if (yych <= 0xBF)\n      goto yy557;\n    goto yy543;\n  yy548:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy543;\n    if (yych <= 0xBF)\n      goto yy557;\n    goto yy543;\n  yy549:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy543;\n    if (yych <= 0x9F)\n      goto yy557;\n    goto yy543;\n  yy550:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x8F)\n      goto yy543;\n    if (yych <= 0xBF)\n      goto yy559;\n    goto yy543;\n  yy551:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy543;\n    if (yych <= 0xBF)\n      goto yy559;\n    goto yy543;\n  yy552:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy543;\n    if (yych <= 0x8F)\n      goto yy559;\n    goto yy543;\n  yy553:\n    yych = *++p;\n  yy554:\n    if (yybm[0 + yych] & 64) {\n      goto yy553;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy555;\n        if (yych <= '-')\n          goto yy556;\n      } else {\n        if (yych <= 0xDF)\n          goto yy557;\n        if (yych <= 0xE0)\n          goto yy558;\n        goto yy559;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy560;\n        if (yych <= 0xEF)\n          goto yy559;\n        goto yy561;\n      } else {\n        if (yych <= 0xF3)\n          goto yy562;\n        if (yych <= 0xF4)\n          goto yy563;\n      }\n    }\n  yy555:\n    p = marker;\n    if (yyaccept == 0) {\n      goto yy543;\n    } else {\n      goto yy566;\n    }\n  yy556:\n    yych = *++p;\n    if (yybm[0 + yych] & 64) {\n      goto yy553;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy555;\n        if (yych <= '-')\n          goto yy564;\n        goto yy555;\n      } else {\n        if (yych <= 0xDF)\n          goto yy557;\n        if (yych <= 0xE0)\n          goto yy558;\n        goto yy559;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy560;\n        if (yych <= 0xEF)\n          goto yy559;\n        goto yy561;\n      } else {\n        if (yych <= 0xF3)\n          goto yy562;\n        if (yych <= 0xF4)\n          goto yy563;\n        goto yy555;\n      }\n    }\n  yy557:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy555;\n    if (yych <= 0xBF)\n      goto yy553;\n    goto yy555;\n  yy558:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy555;\n    if (yych <= 0xBF)\n      goto yy557;\n    goto yy555;\n  yy559:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy555;\n    if (yych <= 0xBF)\n      goto yy557;\n    goto yy555;\n  yy560:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy555;\n    if (yych <= 0x9F)\n      goto yy557;\n    goto yy555;\n  yy561:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy555;\n    if (yych <= 0xBF)\n      goto yy559;\n    goto yy555;\n  yy562:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy555;\n    if (yych <= 0xBF)\n      goto yy559;\n    goto yy555;\n  yy563:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy555;\n    if (yych <= 0x8F)\n      goto yy559;\n    goto yy555;\n  yy564:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy564;\n    }\n    if (yych <= 0xDF) {\n      if (yych <= '=') {\n        if (yych <= 0x00)\n          goto yy555;\n        if (yych == '\\n')\n          goto yy555;\n        goto yy553;\n      } else {\n        if (yych <= '>')\n          goto yy565;\n        if (yych <= 0x7F)\n          goto yy553;\n        if (yych <= 0xC1)\n          goto yy555;\n        goto yy557;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych <= 0xE0)\n          goto yy558;\n        if (yych == 0xED)\n          goto yy560;\n        goto yy559;\n      } else {\n        if (yych <= 0xF0)\n          goto yy561;\n        if (yych <= 0xF3)\n          goto yy562;\n        if (yych <= 0xF4)\n          goto yy563;\n        goto yy555;\n      }\n    }\n  yy565:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 64) {\n      goto yy553;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy566;\n        if (yych <= '-')\n          goto yy556;\n      } else {\n        if (yych <= 0xDF)\n          goto yy557;\n        if (yych <= 0xE0)\n          goto yy558;\n        goto yy559;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy560;\n        if (yych <= 0xEF)\n          goto yy559;\n        goto yy561;\n      } else {\n        if (yych <= 0xF3)\n          goto yy562;\n        if (yych <= 0xF4)\n          goto yy563;\n      }\n    }\n  yy566 : { return (bufsize_t)(p - start); }\n  }\n}\n\n// Try to match an HTML block end line of type 3\nbufsize_t _scan_html_block_end_3(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    unsigned int yyaccept = 0;\n    static const unsigned char yybm[] = {\n        0,  64, 64, 64, 64, 64, 64, 64, 64, 64,  0,  64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64, 128, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,\n    };\n    yych = *p;\n    if (yych <= 0xDF) {\n      if (yych <= '>') {\n        if (yych <= 0x00)\n          goto yy568;\n        if (yych != '\\n')\n          goto yy570;\n      } else {\n        if (yych <= '?')\n          goto yy571;\n        if (yych <= 0x7F)\n          goto yy570;\n        if (yych >= 0xC2)\n          goto yy572;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych <= 0xE0)\n          goto yy573;\n        if (yych == 0xED)\n          goto yy575;\n        goto yy574;\n      } else {\n        if (yych <= 0xF0)\n          goto yy576;\n        if (yych <= 0xF3)\n          goto yy577;\n        if (yych <= 0xF4)\n          goto yy578;\n      }\n    }\n  yy568:\n    ++p;\n  yy569 : { return 0; }\n  yy570:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= '\\n') {\n      if (yych <= 0x00)\n        goto yy569;\n      if (yych <= '\\t')\n        goto yy580;\n      goto yy569;\n    } else {\n      if (yych <= 0x7F)\n        goto yy580;\n      if (yych <= 0xC1)\n        goto yy569;\n      if (yych <= 0xF4)\n        goto yy580;\n      goto yy569;\n    }\n  yy571:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= '=') {\n      if (yych <= 0x00)\n        goto yy569;\n      if (yych == '\\n')\n        goto yy569;\n      goto yy580;\n    } else {\n      if (yych <= 0x7F) {\n        if (yych <= '>')\n          goto yy590;\n        goto yy580;\n      } else {\n        if (yych <= 0xC1)\n          goto yy569;\n        if (yych <= 0xF4)\n          goto yy580;\n        goto yy569;\n      }\n    }\n  yy572:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy569;\n    if (yych <= 0xBF)\n      goto yy579;\n    goto yy569;\n  yy573:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x9F)\n      goto yy569;\n    if (yych <= 0xBF)\n      goto yy583;\n    goto yy569;\n  yy574:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy569;\n    if (yych <= 0xBF)\n      goto yy583;\n    goto yy569;\n  yy575:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy569;\n    if (yych <= 0x9F)\n      goto yy583;\n    goto yy569;\n  yy576:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x8F)\n      goto yy569;\n    if (yych <= 0xBF)\n      goto yy585;\n    goto yy569;\n  yy577:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy569;\n    if (yych <= 0xBF)\n      goto yy585;\n    goto yy569;\n  yy578:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy569;\n    if (yych <= 0x8F)\n      goto yy585;\n    goto yy569;\n  yy579:\n    yych = *++p;\n  yy580:\n    if (yybm[0 + yych] & 64) {\n      goto yy579;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy581;\n        if (yych <= '?')\n          goto yy582;\n      } else {\n        if (yych <= 0xDF)\n          goto yy583;\n        if (yych <= 0xE0)\n          goto yy584;\n        goto yy585;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy586;\n        if (yych <= 0xEF)\n          goto yy585;\n        goto yy587;\n      } else {\n        if (yych <= 0xF3)\n          goto yy588;\n        if (yych <= 0xF4)\n          goto yy589;\n      }\n    }\n  yy581:\n    p = marker;\n    if (yyaccept == 0) {\n      goto yy569;\n    } else {\n      goto yy591;\n    }\n  yy582:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy582;\n    }\n    if (yych <= 0xDF) {\n      if (yych <= '=') {\n        if (yych <= 0x00)\n          goto yy581;\n        if (yych == '\\n')\n          goto yy581;\n        goto yy579;\n      } else {\n        if (yych <= '>')\n          goto yy590;\n        if (yych <= 0x7F)\n          goto yy579;\n        if (yych <= 0xC1)\n          goto yy581;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych <= 0xE0)\n          goto yy584;\n        if (yych == 0xED)\n          goto yy586;\n        goto yy585;\n      } else {\n        if (yych <= 0xF0)\n          goto yy587;\n        if (yych <= 0xF3)\n          goto yy588;\n        if (yych <= 0xF4)\n          goto yy589;\n        goto yy581;\n      }\n    }\n  yy583:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy581;\n    if (yych <= 0xBF)\n      goto yy579;\n    goto yy581;\n  yy584:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy581;\n    if (yych <= 0xBF)\n      goto yy583;\n    goto yy581;\n  yy585:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy581;\n    if (yych <= 0xBF)\n      goto yy583;\n    goto yy581;\n  yy586:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy581;\n    if (yych <= 0x9F)\n      goto yy583;\n    goto yy581;\n  yy587:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy581;\n    if (yych <= 0xBF)\n      goto yy585;\n    goto yy581;\n  yy588:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy581;\n    if (yych <= 0xBF)\n      goto yy585;\n    goto yy581;\n  yy589:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy581;\n    if (yych <= 0x8F)\n      goto yy585;\n    goto yy581;\n  yy590:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 64) {\n      goto yy579;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy591;\n        if (yych <= '?')\n          goto yy582;\n      } else {\n        if (yych <= 0xDF)\n          goto yy583;\n        if (yych <= 0xE0)\n          goto yy584;\n        goto yy585;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy586;\n        if (yych <= 0xEF)\n          goto yy585;\n        goto yy587;\n      } else {\n        if (yych <= 0xF3)\n          goto yy588;\n        if (yych <= 0xF4)\n          goto yy589;\n      }\n    }\n  yy591 : { return (bufsize_t)(p - start); }\n  }\n}\n\n// Try to match an HTML block end line of type 4\nbufsize_t _scan_html_block_end_4(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    unsigned int yyaccept = 0;\n    static const unsigned char yybm[] = {\n        0,   128, 128, 128, 128, 128, 128, 128, 128, 128, 0,   128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 64,  128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,\n        128, 128, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,\n    };\n    yych = *p;\n    if (yybm[0 + yych] & 64) {\n      goto yy596;\n    }\n    if (yych <= 0xE0) {\n      if (yych <= '\\n') {\n        if (yych <= 0x00)\n          goto yy593;\n        if (yych <= '\\t')\n          goto yy595;\n      } else {\n        if (yych <= 0x7F)\n          goto yy595;\n        if (yych <= 0xC1)\n          goto yy593;\n        if (yych <= 0xDF)\n          goto yy598;\n        goto yy599;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy601;\n        goto yy600;\n      } else {\n        if (yych <= 0xF0)\n          goto yy602;\n        if (yych <= 0xF3)\n          goto yy603;\n        if (yych <= 0xF4)\n          goto yy604;\n      }\n    }\n  yy593:\n    ++p;\n  yy594 : { return 0; }\n  yy595:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= '\\n') {\n      if (yych <= 0x00)\n        goto yy594;\n      if (yych <= '\\t')\n        goto yy606;\n      goto yy594;\n    } else {\n      if (yych <= 0x7F)\n        goto yy606;\n      if (yych <= 0xC1)\n        goto yy594;\n      if (yych <= 0xF4)\n        goto yy606;\n      goto yy594;\n    }\n  yy596:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 128) {\n      goto yy605;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy597;\n        if (yych <= '>')\n          goto yy596;\n      } else {\n        if (yych <= 0xDF)\n          goto yy608;\n        if (yych <= 0xE0)\n          goto yy609;\n        goto yy610;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy611;\n        if (yych <= 0xEF)\n          goto yy610;\n        goto yy612;\n      } else {\n        if (yych <= 0xF3)\n          goto yy613;\n        if (yych <= 0xF4)\n          goto yy614;\n      }\n    }\n  yy597 : { return (bufsize_t)(p - start); }\n  yy598:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy594;\n    if (yych <= 0xBF)\n      goto yy605;\n    goto yy594;\n  yy599:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x9F)\n      goto yy594;\n    if (yych <= 0xBF)\n      goto yy608;\n    goto yy594;\n  yy600:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy594;\n    if (yych <= 0xBF)\n      goto yy608;\n    goto yy594;\n  yy601:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy594;\n    if (yych <= 0x9F)\n      goto yy608;\n    goto yy594;\n  yy602:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x8F)\n      goto yy594;\n    if (yych <= 0xBF)\n      goto yy610;\n    goto yy594;\n  yy603:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy594;\n    if (yych <= 0xBF)\n      goto yy610;\n    goto yy594;\n  yy604:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy594;\n    if (yych <= 0x8F)\n      goto yy610;\n    goto yy594;\n  yy605:\n    yych = *++p;\n  yy606:\n    if (yybm[0 + yych] & 128) {\n      goto yy605;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy607;\n        if (yych <= '>')\n          goto yy596;\n      } else {\n        if (yych <= 0xDF)\n          goto yy608;\n        if (yych <= 0xE0)\n          goto yy609;\n        goto yy610;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy611;\n        if (yych <= 0xEF)\n          goto yy610;\n        goto yy612;\n      } else {\n        if (yych <= 0xF3)\n          goto yy613;\n        if (yych <= 0xF4)\n          goto yy614;\n      }\n    }\n  yy607:\n    p = marker;\n    if (yyaccept == 0) {\n      goto yy594;\n    } else {\n      goto yy597;\n    }\n  yy608:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy607;\n    if (yych <= 0xBF)\n      goto yy605;\n    goto yy607;\n  yy609:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy607;\n    if (yych <= 0xBF)\n      goto yy608;\n    goto yy607;\n  yy610:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy607;\n    if (yych <= 0xBF)\n      goto yy608;\n    goto yy607;\n  yy611:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy607;\n    if (yych <= 0x9F)\n      goto yy608;\n    goto yy607;\n  yy612:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy607;\n    if (yych <= 0xBF)\n      goto yy610;\n    goto yy607;\n  yy613:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy607;\n    if (yych <= 0xBF)\n      goto yy610;\n    goto yy607;\n  yy614:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy607;\n    if (yych <= 0x8F)\n      goto yy610;\n    goto yy607;\n  }\n}\n\n// Try to match an HTML block end line of type 5\nbufsize_t _scan_html_block_end_5(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    unsigned int yyaccept = 0;\n    static const unsigned char yybm[] = {\n        0,  64, 64, 64,  64, 64, 64, 64, 64, 64, 0,  64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 128, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 64, 64,  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,\n        64, 64, 0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        0,  0,  0,  0,\n    };\n    yych = *p;\n    if (yych <= 0xDF) {\n      if (yych <= '\\\\') {\n        if (yych <= 0x00)\n          goto yy616;\n        if (yych != '\\n')\n          goto yy618;\n      } else {\n        if (yych <= ']')\n          goto yy619;\n        if (yych <= 0x7F)\n          goto yy618;\n        if (yych >= 0xC2)\n          goto yy620;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych <= 0xE0)\n          goto yy621;\n        if (yych == 0xED)\n          goto yy623;\n        goto yy622;\n      } else {\n        if (yych <= 0xF0)\n          goto yy624;\n        if (yych <= 0xF3)\n          goto yy625;\n        if (yych <= 0xF4)\n          goto yy626;\n      }\n    }\n  yy616:\n    ++p;\n  yy617 : { return 0; }\n  yy618:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= '\\n') {\n      if (yych <= 0x00)\n        goto yy617;\n      if (yych <= '\\t')\n        goto yy628;\n      goto yy617;\n    } else {\n      if (yych <= 0x7F)\n        goto yy628;\n      if (yych <= 0xC1)\n        goto yy617;\n      if (yych <= 0xF4)\n        goto yy628;\n      goto yy617;\n    }\n  yy619:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 128) {\n      goto yy638;\n    }\n    if (yych <= '\\n') {\n      if (yych <= 0x00)\n        goto yy617;\n      if (yych <= '\\t')\n        goto yy628;\n      goto yy617;\n    } else {\n      if (yych <= 0x7F)\n        goto yy628;\n      if (yych <= 0xC1)\n        goto yy617;\n      if (yych <= 0xF4)\n        goto yy628;\n      goto yy617;\n    }\n  yy620:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy617;\n    if (yych <= 0xBF)\n      goto yy627;\n    goto yy617;\n  yy621:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x9F)\n      goto yy617;\n    if (yych <= 0xBF)\n      goto yy631;\n    goto yy617;\n  yy622:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy617;\n    if (yych <= 0xBF)\n      goto yy631;\n    goto yy617;\n  yy623:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy617;\n    if (yych <= 0x9F)\n      goto yy631;\n    goto yy617;\n  yy624:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x8F)\n      goto yy617;\n    if (yych <= 0xBF)\n      goto yy633;\n    goto yy617;\n  yy625:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy617;\n    if (yych <= 0xBF)\n      goto yy633;\n    goto yy617;\n  yy626:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x7F)\n      goto yy617;\n    if (yych <= 0x8F)\n      goto yy633;\n    goto yy617;\n  yy627:\n    yych = *++p;\n  yy628:\n    if (yybm[0 + yych] & 64) {\n      goto yy627;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy629;\n        if (yych <= ']')\n          goto yy630;\n      } else {\n        if (yych <= 0xDF)\n          goto yy631;\n        if (yych <= 0xE0)\n          goto yy632;\n        goto yy633;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy634;\n        if (yych <= 0xEF)\n          goto yy633;\n        goto yy635;\n      } else {\n        if (yych <= 0xF3)\n          goto yy636;\n        if (yych <= 0xF4)\n          goto yy637;\n      }\n    }\n  yy629:\n    p = marker;\n    if (yyaccept == 0) {\n      goto yy617;\n    } else {\n      goto yy640;\n    }\n  yy630:\n    yych = *++p;\n    if (yybm[0 + yych] & 64) {\n      goto yy627;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy629;\n        if (yych <= ']')\n          goto yy638;\n        goto yy629;\n      } else {\n        if (yych <= 0xDF)\n          goto yy631;\n        if (yych <= 0xE0)\n          goto yy632;\n        goto yy633;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy634;\n        if (yych <= 0xEF)\n          goto yy633;\n        goto yy635;\n      } else {\n        if (yych <= 0xF3)\n          goto yy636;\n        if (yych <= 0xF4)\n          goto yy637;\n        goto yy629;\n      }\n    }\n  yy631:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy629;\n    if (yych <= 0xBF)\n      goto yy627;\n    goto yy629;\n  yy632:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy629;\n    if (yych <= 0xBF)\n      goto yy631;\n    goto yy629;\n  yy633:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy629;\n    if (yych <= 0xBF)\n      goto yy631;\n    goto yy629;\n  yy634:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy629;\n    if (yych <= 0x9F)\n      goto yy631;\n    goto yy629;\n  yy635:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy629;\n    if (yych <= 0xBF)\n      goto yy633;\n    goto yy629;\n  yy636:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy629;\n    if (yych <= 0xBF)\n      goto yy633;\n    goto yy629;\n  yy637:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy629;\n    if (yych <= 0x8F)\n      goto yy633;\n    goto yy629;\n  yy638:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy638;\n    }\n    if (yych <= 0xDF) {\n      if (yych <= '=') {\n        if (yych <= 0x00)\n          goto yy629;\n        if (yych == '\\n')\n          goto yy629;\n        goto yy627;\n      } else {\n        if (yych <= '>')\n          goto yy639;\n        if (yych <= 0x7F)\n          goto yy627;\n        if (yych <= 0xC1)\n          goto yy629;\n        goto yy631;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych <= 0xE0)\n          goto yy632;\n        if (yych == 0xED)\n          goto yy634;\n        goto yy633;\n      } else {\n        if (yych <= 0xF0)\n          goto yy635;\n        if (yych <= 0xF3)\n          goto yy636;\n        if (yych <= 0xF4)\n          goto yy637;\n        goto yy629;\n      }\n    }\n  yy639:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 64) {\n      goto yy627;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= '\\n')\n          goto yy640;\n        if (yych <= ']')\n          goto yy630;\n      } else {\n        if (yych <= 0xDF)\n          goto yy631;\n        if (yych <= 0xE0)\n          goto yy632;\n        goto yy633;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy634;\n        if (yych <= 0xEF)\n          goto yy633;\n        goto yy635;\n      } else {\n        if (yych <= 0xF3)\n          goto yy636;\n        if (yych <= 0xF4)\n          goto yy637;\n      }\n    }\n  yy640 : { return (bufsize_t)(p - start); }\n  }\n}\n\n// Try to match a link title (in single quotes, in double quotes, or\n// in parentheses), returning number of chars matched.  Allow one\n// level of internal nesting (quotes within quotes).\nbufsize_t _scan_link_title(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    unsigned int yyaccept = 0;\n    static const unsigned char yybm[] = {\n        0,   208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208,\n        208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208,\n        208, 208, 208, 208, 208, 208, 192, 208, 208, 208, 208, 144, 80,  80,\n        208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208,\n        208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208,\n        208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208,\n        208, 208, 208, 208, 208, 208, 208, 208, 32,  208, 208, 208, 208, 208,\n        208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208,\n        208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208,\n        208, 208, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,\n    };\n    yych = *p;\n    if (yych <= '&') {\n      if (yych == '\"')\n        goto yy643;\n    } else {\n      if (yych <= '\\'')\n        goto yy644;\n      if (yych <= '(')\n        goto yy645;\n    }\n    ++p;\n  yy642 : { return 0; }\n  yy643:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x00)\n      goto yy642;\n    if (yych <= 0x7F)\n      goto yy647;\n    if (yych <= 0xC1)\n      goto yy642;\n    if (yych <= 0xF4)\n      goto yy647;\n    goto yy642;\n  yy644:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= 0x00)\n      goto yy642;\n    if (yych <= 0x7F)\n      goto yy660;\n    if (yych <= 0xC1)\n      goto yy642;\n    if (yych <= 0xF4)\n      goto yy660;\n    goto yy642;\n  yy645:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych <= '(') {\n      if (yych <= 0x00)\n        goto yy642;\n      if (yych <= '\\'')\n        goto yy672;\n      goto yy642;\n    } else {\n      if (yych <= 0x7F)\n        goto yy672;\n      if (yych <= 0xC1)\n        goto yy642;\n      if (yych <= 0xF4)\n        goto yy672;\n      goto yy642;\n    }\n  yy646:\n    yych = *++p;\n  yy647:\n    if (yybm[0 + yych] & 16) {\n      goto yy646;\n    }\n    if (yych <= 0xE0) {\n      if (yych <= '\\\\') {\n        if (yych <= 0x00)\n          goto yy648;\n        if (yych <= '\"')\n          goto yy649;\n        goto yy651;\n      } else {\n        if (yych <= 0xC1)\n          goto yy648;\n        if (yych <= 0xDF)\n          goto yy652;\n        goto yy653;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy655;\n        goto yy654;\n      } else {\n        if (yych <= 0xF0)\n          goto yy656;\n        if (yych <= 0xF3)\n          goto yy657;\n        if (yych <= 0xF4)\n          goto yy658;\n      }\n    }\n  yy648:\n    p = marker;\n    if (yyaccept <= 1) {\n      if (yyaccept == 0) {\n        goto yy642;\n      } else {\n        goto yy650;\n      }\n    } else {\n      if (yyaccept == 2) {\n        goto yy662;\n      } else {\n        goto yy674;\n      }\n    }\n  yy649:\n    ++p;\n  yy650 : { return (bufsize_t)(p - start); }\n  yy651:\n    yych = *++p;\n    if (yybm[0 + yych] & 16) {\n      goto yy646;\n    }\n    if (yych <= 0xE0) {\n      if (yych <= '\\\\') {\n        if (yych <= 0x00)\n          goto yy648;\n        if (yych <= '\"')\n          goto yy683;\n        goto yy651;\n      } else {\n        if (yych <= 0xC1)\n          goto yy648;\n        if (yych >= 0xE0)\n          goto yy653;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy655;\n        goto yy654;\n      } else {\n        if (yych <= 0xF0)\n          goto yy656;\n        if (yych <= 0xF3)\n          goto yy657;\n        if (yych <= 0xF4)\n          goto yy658;\n        goto yy648;\n      }\n    }\n  yy652:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy646;\n    goto yy648;\n  yy653:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy652;\n    goto yy648;\n  yy654:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy652;\n    goto yy648;\n  yy655:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0x9F)\n      goto yy652;\n    goto yy648;\n  yy656:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy654;\n    goto yy648;\n  yy657:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy654;\n    goto yy648;\n  yy658:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0x8F)\n      goto yy654;\n    goto yy648;\n  yy659:\n    yych = *++p;\n  yy660:\n    if (yybm[0 + yych] & 64) {\n      goto yy659;\n    }\n    if (yych <= 0xE0) {\n      if (yych <= '\\\\') {\n        if (yych <= 0x00)\n          goto yy648;\n        if (yych >= '(')\n          goto yy663;\n      } else {\n        if (yych <= 0xC1)\n          goto yy648;\n        if (yych <= 0xDF)\n          goto yy664;\n        goto yy665;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy667;\n        goto yy666;\n      } else {\n        if (yych <= 0xF0)\n          goto yy668;\n        if (yych <= 0xF3)\n          goto yy669;\n        if (yych <= 0xF4)\n          goto yy670;\n        goto yy648;\n      }\n    }\n  yy661:\n    ++p;\n  yy662 : { return (bufsize_t)(p - start); }\n  yy663:\n    yych = *++p;\n    if (yybm[0 + yych] & 64) {\n      goto yy659;\n    }\n    if (yych <= 0xE0) {\n      if (yych <= '\\\\') {\n        if (yych <= 0x00)\n          goto yy648;\n        if (yych <= '\\'')\n          goto yy684;\n        goto yy663;\n      } else {\n        if (yych <= 0xC1)\n          goto yy648;\n        if (yych >= 0xE0)\n          goto yy665;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy667;\n        goto yy666;\n      } else {\n        if (yych <= 0xF0)\n          goto yy668;\n        if (yych <= 0xF3)\n          goto yy669;\n        if (yych <= 0xF4)\n          goto yy670;\n        goto yy648;\n      }\n    }\n  yy664:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy659;\n    goto yy648;\n  yy665:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy664;\n    goto yy648;\n  yy666:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy664;\n    goto yy648;\n  yy667:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0x9F)\n      goto yy664;\n    goto yy648;\n  yy668:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy666;\n    goto yy648;\n  yy669:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy666;\n    goto yy648;\n  yy670:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0x8F)\n      goto yy666;\n    goto yy648;\n  yy671:\n    yych = *++p;\n  yy672:\n    if (yybm[0 + yych] & 128) {\n      goto yy671;\n    }\n    if (yych <= 0xE0) {\n      if (yych <= '\\\\') {\n        if (yych <= '(')\n          goto yy648;\n        if (yych >= '*')\n          goto yy675;\n      } else {\n        if (yych <= 0xC1)\n          goto yy648;\n        if (yych <= 0xDF)\n          goto yy676;\n        goto yy677;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy679;\n        goto yy678;\n      } else {\n        if (yych <= 0xF0)\n          goto yy680;\n        if (yych <= 0xF3)\n          goto yy681;\n        if (yych <= 0xF4)\n          goto yy682;\n        goto yy648;\n      }\n    }\n  yy673:\n    ++p;\n  yy674 : { return (bufsize_t)(p - start); }\n  yy675:\n    yych = *++p;\n    if (yych <= 0xDF) {\n      if (yych <= '[') {\n        if (yych <= 0x00)\n          goto yy648;\n        if (yych == ')')\n          goto yy685;\n        goto yy671;\n      } else {\n        if (yych <= '\\\\')\n          goto yy675;\n        if (yych <= 0x7F)\n          goto yy671;\n        if (yych <= 0xC1)\n          goto yy648;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych <= 0xE0)\n          goto yy677;\n        if (yych == 0xED)\n          goto yy679;\n        goto yy678;\n      } else {\n        if (yych <= 0xF0)\n          goto yy680;\n        if (yych <= 0xF3)\n          goto yy681;\n        if (yych <= 0xF4)\n          goto yy682;\n        goto yy648;\n      }\n    }\n  yy676:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy671;\n    goto yy648;\n  yy677:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy676;\n    goto yy648;\n  yy678:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy676;\n    goto yy648;\n  yy679:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0x9F)\n      goto yy676;\n    goto yy648;\n  yy680:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy678;\n    goto yy648;\n  yy681:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0xBF)\n      goto yy678;\n    goto yy648;\n  yy682:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy648;\n    if (yych <= 0x8F)\n      goto yy678;\n    goto yy648;\n  yy683:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 16) {\n      goto yy646;\n    }\n    if (yych <= 0xE0) {\n      if (yych <= '\\\\') {\n        if (yych <= 0x00)\n          goto yy650;\n        if (yych <= '\"')\n          goto yy649;\n        goto yy651;\n      } else {\n        if (yych <= 0xC1)\n          goto yy650;\n        if (yych <= 0xDF)\n          goto yy652;\n        goto yy653;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy655;\n        goto yy654;\n      } else {\n        if (yych <= 0xF0)\n          goto yy656;\n        if (yych <= 0xF3)\n          goto yy657;\n        if (yych <= 0xF4)\n          goto yy658;\n        goto yy650;\n      }\n    }\n  yy684:\n    yyaccept = 2;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 64) {\n      goto yy659;\n    }\n    if (yych <= 0xE0) {\n      if (yych <= '\\\\') {\n        if (yych <= 0x00)\n          goto yy662;\n        if (yych <= '\\'')\n          goto yy661;\n        goto yy663;\n      } else {\n        if (yych <= 0xC1)\n          goto yy662;\n        if (yych <= 0xDF)\n          goto yy664;\n        goto yy665;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy667;\n        goto yy666;\n      } else {\n        if (yych <= 0xF0)\n          goto yy668;\n        if (yych <= 0xF3)\n          goto yy669;\n        if (yych <= 0xF4)\n          goto yy670;\n        goto yy662;\n      }\n    }\n  yy685:\n    yyaccept = 3;\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 128) {\n      goto yy671;\n    }\n    if (yych <= 0xE0) {\n      if (yych <= '\\\\') {\n        if (yych <= '(')\n          goto yy674;\n        if (yych <= ')')\n          goto yy673;\n        goto yy675;\n      } else {\n        if (yych <= 0xC1)\n          goto yy674;\n        if (yych <= 0xDF)\n          goto yy676;\n        goto yy677;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych == 0xED)\n          goto yy679;\n        goto yy678;\n      } else {\n        if (yych <= 0xF0)\n          goto yy680;\n        if (yych <= 0xF3)\n          goto yy681;\n        if (yych <= 0xF4)\n          goto yy682;\n        goto yy674;\n      }\n    }\n  }\n}\n\n// Match space characters, including newlines.\nbufsize_t _scan_spacechars(const unsigned char *p) {\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    static const unsigned char yybm[] = {\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   128, 0,   0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0,   0,   0,   0, 0,\n    };\n    yych = *p;\n    if (yybm[0 + yych] & 128) {\n      goto yy687;\n    }\n    ++p;\n    { return 0; }\n  yy687:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy687;\n    }\n    { return (bufsize_t)(p - start); }\n  }\n}\n\n// Match ATX heading start.\nbufsize_t _scan_atx_heading_start(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    static const unsigned char yybm[] = {\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0,   0, 0, 0,\n    };\n    yych = *p;\n    if (yych == '#')\n      goto yy690;\n    ++p;\n  yy689 : { return 0; }\n  yy690:\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 128) {\n      goto yy691;\n    }\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy689;\n      if (yych <= '\\n')\n        goto yy693;\n      goto yy689;\n    } else {\n      if (yych <= '\\r')\n        goto yy693;\n      if (yych == '#')\n        goto yy694;\n      goto yy689;\n    }\n  yy691:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy691;\n    }\n  yy692 : { return (bufsize_t)(p - start); }\n  yy693:\n    ++p;\n    goto yy692;\n  yy694:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy691;\n    }\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy695;\n      if (yych <= '\\n')\n        goto yy693;\n    } else {\n      if (yych <= '\\r')\n        goto yy693;\n      if (yych == '#')\n        goto yy696;\n    }\n  yy695:\n    p = marker;\n    goto yy689;\n  yy696:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy691;\n    }\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy695;\n      if (yych <= '\\n')\n        goto yy693;\n      goto yy695;\n    } else {\n      if (yych <= '\\r')\n        goto yy693;\n      if (yych != '#')\n        goto yy695;\n    }\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy691;\n    }\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy695;\n      if (yych <= '\\n')\n        goto yy693;\n      goto yy695;\n    } else {\n      if (yych <= '\\r')\n        goto yy693;\n      if (yych != '#')\n        goto yy695;\n    }\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy691;\n    }\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy695;\n      if (yych <= '\\n')\n        goto yy693;\n      goto yy695;\n    } else {\n      if (yych <= '\\r')\n        goto yy693;\n      if (yych != '#')\n        goto yy695;\n    }\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy691;\n    }\n    if (yych <= 0x08)\n      goto yy695;\n    if (yych <= '\\n')\n      goto yy693;\n    if (yych == '\\r')\n      goto yy693;\n    goto yy695;\n  }\n}\n\n// Match setext heading line.  Return 1 for level-1 heading,\n// 2 for level-2, 0 for no match.\nbufsize_t _scan_setext_heading_line(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n\n  {\n    unsigned char yych;\n    static const unsigned char yybm[] = {\n        0, 0,  0, 0, 0, 0, 0, 0, 0, 32, 0,  0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0,\n        0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  32, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0,\n        0, 64, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0,\n        0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0,\n        0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0,\n        0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0,\n        0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0,\n        0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0,\n        0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0,\n        0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0,\n        0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0,\n        0, 0,  0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0, 0,\n    };\n    yych = *p;\n    if (yych == '-')\n      goto yy699;\n    if (yych == '=')\n      goto yy700;\n    ++p;\n  yy698 : { return 0; }\n  yy699:\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 64) {\n      goto yy705;\n    }\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy698;\n      if (yych <= '\\n')\n        goto yy702;\n      goto yy698;\n    } else {\n      if (yych <= '\\r')\n        goto yy702;\n      if (yych == ' ')\n        goto yy702;\n      goto yy698;\n    }\n  yy700:\n    yych = *(marker = ++p);\n    if (yybm[0 + yych] & 128) {\n      goto yy709;\n    }\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy698;\n      if (yych <= '\\n')\n        goto yy707;\n      goto yy698;\n    } else {\n      if (yych <= '\\r')\n        goto yy707;\n      if (yych == ' ')\n        goto yy707;\n      goto yy698;\n    }\n  yy701:\n    yych = *++p;\n  yy702:\n    if (yybm[0 + yych] & 32) {\n      goto yy701;\n    }\n    if (yych <= 0x08)\n      goto yy703;\n    if (yych <= '\\n')\n      goto yy704;\n    if (yych == '\\r')\n      goto yy704;\n  yy703:\n    p = marker;\n    goto yy698;\n  yy704:\n    ++p;\n    { return 2; }\n  yy705:\n    yych = *++p;\n    if (yybm[0 + yych] & 32) {\n      goto yy701;\n    }\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy703;\n      if (yych <= '\\n')\n        goto yy704;\n      goto yy703;\n    } else {\n      if (yych <= '\\r')\n        goto yy704;\n      if (yych == '-')\n        goto yy705;\n      goto yy703;\n    }\n  yy706:\n    yych = *++p;\n  yy707:\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy703;\n      if (yych <= '\\t')\n        goto yy706;\n      if (yych >= '\\v')\n        goto yy703;\n    } else {\n      if (yych <= '\\r')\n        goto yy708;\n      if (yych == ' ')\n        goto yy706;\n      goto yy703;\n    }\n  yy708:\n    ++p;\n    { return 1; }\n  yy709:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy709;\n    }\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy703;\n      if (yych <= '\\t')\n        goto yy706;\n      if (yych <= '\\n')\n        goto yy708;\n      goto yy703;\n    } else {\n      if (yych <= '\\r')\n        goto yy708;\n      if (yych == ' ')\n        goto yy706;\n      goto yy703;\n    }\n  }\n}\n\n// Scan an opening code fence.\nbufsize_t _scan_open_code_fence(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    static const unsigned char yybm[] = {\n        0,   192, 192, 192, 192, 192, 192, 192, 192, 192, 0,   192, 192, 0,\n        192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,\n        192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,\n        192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,\n        192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,\n        192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,\n        192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 144, 192,\n        192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,\n        192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,\n        224, 192, 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n        0,   0,   0,   0,\n    };\n    yych = *p;\n    if (yych == '`')\n      goto yy712;\n    if (yych == '~')\n      goto yy713;\n    ++p;\n  yy711 : { return 0; }\n  yy712:\n    yych = *(marker = ++p);\n    if (yych == '`')\n      goto yy714;\n    goto yy711;\n  yy713:\n    yych = *(marker = ++p);\n    if (yych == '~')\n      goto yy716;\n    goto yy711;\n  yy714:\n    yych = *++p;\n    if (yybm[0 + yych] & 16) {\n      goto yy717;\n    }\n  yy715:\n    p = marker;\n    goto yy711;\n  yy716:\n    yych = *++p;\n    if (yybm[0 + yych] & 32) {\n      goto yy718;\n    }\n    goto yy715;\n  yy717:\n    yych = *++p;\n    if (yybm[0 + yych] & 16) {\n      goto yy717;\n    }\n    if (yych <= 0xDF) {\n      if (yych <= '\\f') {\n        if (yych <= 0x00)\n          goto yy715;\n        if (yych == '\\n') {\n          marker = p;\n          goto yy720;\n        }\n        marker = p;\n        goto yy719;\n      } else {\n        if (yych <= '\\r') {\n          marker = p;\n          goto yy720;\n        }\n        if (yych <= 0x7F) {\n          marker = p;\n          goto yy719;\n        }\n        if (yych <= 0xC1)\n          goto yy715;\n        marker = p;\n        goto yy721;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych <= 0xE0) {\n          marker = p;\n          goto yy722;\n        }\n        if (yych == 0xED) {\n          marker = p;\n          goto yy724;\n        }\n        marker = p;\n        goto yy723;\n      } else {\n        if (yych <= 0xF0) {\n          marker = p;\n          goto yy725;\n        }\n        if (yych <= 0xF3) {\n          marker = p;\n          goto yy726;\n        }\n        if (yych <= 0xF4) {\n          marker = p;\n          goto yy727;\n        }\n        goto yy715;\n      }\n    }\n  yy718:\n    yych = *++p;\n    if (yybm[0 + yych] & 32) {\n      goto yy718;\n    }\n    if (yych <= 0xDF) {\n      if (yych <= '\\f') {\n        if (yych <= 0x00)\n          goto yy715;\n        if (yych == '\\n') {\n          marker = p;\n          goto yy729;\n        }\n        marker = p;\n        goto yy728;\n      } else {\n        if (yych <= '\\r') {\n          marker = p;\n          goto yy729;\n        }\n        if (yych <= 0x7F) {\n          marker = p;\n          goto yy728;\n        }\n        if (yych <= 0xC1)\n          goto yy715;\n        marker = p;\n        goto yy730;\n      }\n    } else {\n      if (yych <= 0xEF) {\n        if (yych <= 0xE0) {\n          marker = p;\n          goto yy731;\n        }\n        if (yych == 0xED) {\n          marker = p;\n          goto yy733;\n        }\n        marker = p;\n        goto yy732;\n      } else {\n        if (yych <= 0xF0) {\n          marker = p;\n          goto yy734;\n        }\n        if (yych <= 0xF3) {\n          marker = p;\n          goto yy735;\n        }\n        if (yych <= 0xF4) {\n          marker = p;\n          goto yy736;\n        }\n        goto yy715;\n      }\n    }\n  yy719:\n    yych = *++p;\n    if (yybm[0 + yych] & 64) {\n      goto yy719;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= 0x00)\n          goto yy715;\n        if (yych >= 0x0E)\n          goto yy715;\n      } else {\n        if (yych <= 0xDF)\n          goto yy721;\n        if (yych <= 0xE0)\n          goto yy722;\n        goto yy723;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy724;\n        if (yych <= 0xEF)\n          goto yy723;\n        goto yy725;\n      } else {\n        if (yych <= 0xF3)\n          goto yy726;\n        if (yych <= 0xF4)\n          goto yy727;\n        goto yy715;\n      }\n    }\n  yy720:\n    ++p;\n    p = marker;\n    { return (bufsize_t)(p - start); }\n  yy721:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy715;\n    if (yych <= 0xBF)\n      goto yy719;\n    goto yy715;\n  yy722:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy715;\n    if (yych <= 0xBF)\n      goto yy721;\n    goto yy715;\n  yy723:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy715;\n    if (yych <= 0xBF)\n      goto yy721;\n    goto yy715;\n  yy724:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy715;\n    if (yych <= 0x9F)\n      goto yy721;\n    goto yy715;\n  yy725:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy715;\n    if (yych <= 0xBF)\n      goto yy723;\n    goto yy715;\n  yy726:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy715;\n    if (yych <= 0xBF)\n      goto yy723;\n    goto yy715;\n  yy727:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy715;\n    if (yych <= 0x8F)\n      goto yy723;\n    goto yy715;\n  yy728:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy728;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= 0x00)\n          goto yy715;\n        if (yych >= 0x0E)\n          goto yy715;\n      } else {\n        if (yych <= 0xDF)\n          goto yy730;\n        if (yych <= 0xE0)\n          goto yy731;\n        goto yy732;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy733;\n        if (yych <= 0xEF)\n          goto yy732;\n        goto yy734;\n      } else {\n        if (yych <= 0xF3)\n          goto yy735;\n        if (yych <= 0xF4)\n          goto yy736;\n        goto yy715;\n      }\n    }\n  yy729:\n    ++p;\n    p = marker;\n    { return (bufsize_t)(p - start); }\n  yy730:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy715;\n    if (yych <= 0xBF)\n      goto yy728;\n    goto yy715;\n  yy731:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy715;\n    if (yych <= 0xBF)\n      goto yy730;\n    goto yy715;\n  yy732:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy715;\n    if (yych <= 0xBF)\n      goto yy730;\n    goto yy715;\n  yy733:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy715;\n    if (yych <= 0x9F)\n      goto yy730;\n    goto yy715;\n  yy734:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy715;\n    if (yych <= 0xBF)\n      goto yy732;\n    goto yy715;\n  yy735:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy715;\n    if (yych <= 0xBF)\n      goto yy732;\n    goto yy715;\n  yy736:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy715;\n    if (yych <= 0x8F)\n      goto yy732;\n    goto yy715;\n  }\n}\n\n// Scan a closing code fence with length at least len.\nbufsize_t _scan_close_code_fence(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    static const unsigned char yybm[] = {\n        0, 0, 0, 0, 0, 0, 0, 0, 0,  128, 0,   0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0,  0,   128, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0,  0,   0,   0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0,  0,   0,   0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 32, 0,   0,   0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0,  0,   0,   0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0,  0,   0,   0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0,  0,   0,   0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0,  0,   0,   0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0,  0,   0,   0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0,  0,   0,   0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0,  0,   0,   0, 0, 0,\n    };\n    yych = *p;\n    if (yych == '`')\n      goto yy739;\n    if (yych == '~')\n      goto yy740;\n    ++p;\n  yy738 : { return 0; }\n  yy739:\n    yych = *(marker = ++p);\n    if (yych == '`')\n      goto yy741;\n    goto yy738;\n  yy740:\n    yych = *(marker = ++p);\n    if (yych == '~')\n      goto yy743;\n    goto yy738;\n  yy741:\n    yych = *++p;\n    if (yybm[0 + yych] & 32) {\n      goto yy744;\n    }\n  yy742:\n    p = marker;\n    goto yy738;\n  yy743:\n    yych = *++p;\n    if (yybm[0 + yych] & 64) {\n      goto yy745;\n    }\n    goto yy742;\n  yy744:\n    yych = *++p;\n    if (yybm[0 + yych] & 32) {\n      goto yy744;\n    }\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy742;\n      if (yych <= '\\t') {\n        marker = p;\n        goto yy746;\n      }\n      if (yych <= '\\n') {\n        marker = p;\n        goto yy747;\n      }\n      goto yy742;\n    } else {\n      if (yych <= '\\r') {\n        marker = p;\n        goto yy747;\n      }\n      if (yych == ' ') {\n        marker = p;\n        goto yy746;\n      }\n      goto yy742;\n    }\n  yy745:\n    yych = *++p;\n    if (yybm[0 + yych] & 64) {\n      goto yy745;\n    }\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy742;\n      if (yych <= '\\t') {\n        marker = p;\n        goto yy748;\n      }\n      if (yych <= '\\n') {\n        marker = p;\n        goto yy749;\n      }\n      goto yy742;\n    } else {\n      if (yych <= '\\r') {\n        marker = p;\n        goto yy749;\n      }\n      if (yych == ' ') {\n        marker = p;\n        goto yy748;\n      }\n      goto yy742;\n    }\n  yy746:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy746;\n    }\n    if (yych <= 0x08)\n      goto yy742;\n    if (yych <= '\\n')\n      goto yy747;\n    if (yych != '\\r')\n      goto yy742;\n  yy747:\n    ++p;\n    p = marker;\n    { return (bufsize_t)(p - start); }\n  yy748:\n    yych = *++p;\n    if (yych <= '\\f') {\n      if (yych <= 0x08)\n        goto yy742;\n      if (yych <= '\\t')\n        goto yy748;\n      if (yych >= '\\v')\n        goto yy742;\n    } else {\n      if (yych <= '\\r')\n        goto yy749;\n      if (yych == ' ')\n        goto yy748;\n      goto yy742;\n    }\n  yy749:\n    ++p;\n    p = marker;\n    { return (bufsize_t)(p - start); }\n  }\n}\n\n// Scans an entity.\n// Returns number of chars matched.\nbufsize_t _scan_entity(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    yych = *p;\n    if (yych == '&')\n      goto yy752;\n    ++p;\n  yy751 : { return 0; }\n  yy752:\n    yych = *(marker = ++p);\n    if (yych <= '@') {\n      if (yych != '#')\n        goto yy751;\n    } else {\n      if (yych <= 'Z')\n        goto yy754;\n      if (yych <= '`')\n        goto yy751;\n      if (yych <= 'z')\n        goto yy754;\n      goto yy751;\n    }\n    yych = *++p;\n    if (yych <= 'W') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy755;\n    } else {\n      if (yych <= 'X')\n        goto yy756;\n      if (yych == 'x')\n        goto yy756;\n    }\n  yy753:\n    p = marker;\n    goto yy751;\n  yy754:\n    yych = *++p;\n    if (yych <= '@') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy757;\n      goto yy753;\n    } else {\n      if (yych <= 'Z')\n        goto yy757;\n      if (yych <= '`')\n        goto yy753;\n      if (yych <= 'z')\n        goto yy757;\n      goto yy753;\n    }\n  yy755:\n    yych = *++p;\n    if (yych <= '/')\n      goto yy753;\n    if (yych <= '9')\n      goto yy758;\n    if (yych == ';')\n      goto yy759;\n    goto yy753;\n  yy756:\n    yych = *++p;\n    if (yych <= '@') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy760;\n      goto yy753;\n    } else {\n      if (yych <= 'F')\n        goto yy760;\n      if (yych <= '`')\n        goto yy753;\n      if (yych <= 'f')\n        goto yy760;\n      goto yy753;\n    }\n  yy757:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy761;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n        goto yy761;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych <= 'z')\n          goto yy761;\n        goto yy753;\n      }\n    }\n  yy758:\n    yych = *++p;\n    if (yych <= '/')\n      goto yy753;\n    if (yych <= '9')\n      goto yy762;\n    if (yych != ';')\n      goto yy753;\n  yy759:\n    ++p;\n    { return (bufsize_t)(p - start); }\n  yy760:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy763;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'F') {\n        if (yych <= '@')\n          goto yy753;\n        goto yy763;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych <= 'f')\n          goto yy763;\n        goto yy753;\n      }\n    }\n  yy761:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy764;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n        goto yy764;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych <= 'z')\n          goto yy764;\n        goto yy753;\n      }\n    }\n  yy762:\n    yych = *++p;\n    if (yych <= '/')\n      goto yy753;\n    if (yych <= '9')\n      goto yy765;\n    if (yych == ';')\n      goto yy759;\n    goto yy753;\n  yy763:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy766;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'F') {\n        if (yych <= '@')\n          goto yy753;\n        goto yy766;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych <= 'f')\n          goto yy766;\n        goto yy753;\n      }\n    }\n  yy764:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy767;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n        goto yy767;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych <= 'z')\n          goto yy767;\n        goto yy753;\n      }\n    }\n  yy765:\n    yych = *++p;\n    if (yych <= '/')\n      goto yy753;\n    if (yych <= '9')\n      goto yy768;\n    if (yych == ';')\n      goto yy759;\n    goto yy753;\n  yy766:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy769;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'F') {\n        if (yych <= '@')\n          goto yy753;\n        goto yy769;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych <= 'f')\n          goto yy769;\n        goto yy753;\n      }\n    }\n  yy767:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy770;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n        goto yy770;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych <= 'z')\n          goto yy770;\n        goto yy753;\n      }\n    }\n  yy768:\n    yych = *++p;\n    if (yych <= '/')\n      goto yy753;\n    if (yych <= '9')\n      goto yy771;\n    if (yych == ';')\n      goto yy759;\n    goto yy753;\n  yy769:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy772;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'F') {\n        if (yych <= '@')\n          goto yy753;\n        goto yy772;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych <= 'f')\n          goto yy772;\n        goto yy753;\n      }\n    }\n  yy770:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy773;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n        goto yy773;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych <= 'z')\n          goto yy773;\n        goto yy753;\n      }\n    }\n  yy771:\n    yych = *++p;\n    if (yych <= '/')\n      goto yy753;\n    if (yych <= '9')\n      goto yy774;\n    if (yych == ';')\n      goto yy759;\n    goto yy753;\n  yy772:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy774;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'F') {\n        if (yych <= '@')\n          goto yy753;\n        goto yy774;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych <= 'f')\n          goto yy774;\n        goto yy753;\n      }\n    }\n  yy773:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy775;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n        goto yy775;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych <= 'z')\n          goto yy775;\n        goto yy753;\n      }\n    }\n  yy774:\n    yych = *++p;\n    if (yych == ';')\n      goto yy759;\n    goto yy753;\n  yy775:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy776;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy776:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy777;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy777:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy778;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy778:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy779;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy779:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy780;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy780:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy781;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy781:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy782;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy782:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy783;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy783:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy784;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy784:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy785;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy785:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy786;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy786:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy787;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy787:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy788;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy788:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy789;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy789:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy790;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy790:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy791;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy791:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy792;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy792:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy793;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy793:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy794;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy794:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy795;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy795:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy796;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy796:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy797;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy797:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy798;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych >= '{')\n          goto yy753;\n      }\n    }\n  yy798:\n    yych = *++p;\n    if (yych <= ';') {\n      if (yych <= '/')\n        goto yy753;\n      if (yych <= '9')\n        goto yy774;\n      if (yych <= ':')\n        goto yy753;\n      goto yy759;\n    } else {\n      if (yych <= 'Z') {\n        if (yych <= '@')\n          goto yy753;\n        goto yy774;\n      } else {\n        if (yych <= '`')\n          goto yy753;\n        if (yych <= 'z')\n          goto yy774;\n        goto yy753;\n      }\n    }\n  }\n}\n\n// Returns positive value if a URL begins in a way that is potentially\n// dangerous, with javascript:, vbscript:, file:, or data:, otherwise 0.\nbufsize_t _scan_dangerous_url(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    unsigned int yyaccept = 0;\n    yych = *p;\n    if (yych <= 'V') {\n      if (yych <= 'F') {\n        if (yych == 'D')\n          goto yy801;\n        if (yych >= 'F')\n          goto yy802;\n      } else {\n        if (yych == 'J')\n          goto yy803;\n        if (yych >= 'V')\n          goto yy804;\n      }\n    } else {\n      if (yych <= 'f') {\n        if (yych == 'd')\n          goto yy801;\n        if (yych >= 'f')\n          goto yy802;\n      } else {\n        if (yych <= 'j') {\n          if (yych >= 'j')\n            goto yy803;\n        } else {\n          if (yych == 'v')\n            goto yy804;\n        }\n      }\n    }\n    ++p;\n  yy800 : { return 0; }\n  yy801:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych == 'A')\n      goto yy805;\n    if (yych == 'a')\n      goto yy805;\n    goto yy800;\n  yy802:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych == 'I')\n      goto yy807;\n    if (yych == 'i')\n      goto yy807;\n    goto yy800;\n  yy803:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych == 'A')\n      goto yy808;\n    if (yych == 'a')\n      goto yy808;\n    goto yy800;\n  yy804:\n    yyaccept = 0;\n    yych = *(marker = ++p);\n    if (yych == 'B')\n      goto yy809;\n    if (yych == 'b')\n      goto yy809;\n    goto yy800;\n  yy805:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy810;\n    if (yych == 't')\n      goto yy810;\n  yy806:\n    p = marker;\n    if (yyaccept == 0) {\n      goto yy800;\n    } else {\n      goto yy818;\n    }\n  yy807:\n    yych = *++p;\n    if (yych == 'L')\n      goto yy811;\n    if (yych == 'l')\n      goto yy811;\n    goto yy806;\n  yy808:\n    yych = *++p;\n    if (yych == 'V')\n      goto yy812;\n    if (yych == 'v')\n      goto yy812;\n    goto yy806;\n  yy809:\n    yych = *++p;\n    if (yych == 'S')\n      goto yy813;\n    if (yych == 's')\n      goto yy813;\n    goto yy806;\n  yy810:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy814;\n    if (yych == 'a')\n      goto yy814;\n    goto yy806;\n  yy811:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy815;\n    if (yych == 'e')\n      goto yy815;\n    goto yy806;\n  yy812:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy809;\n    if (yych == 'a')\n      goto yy809;\n    goto yy806;\n  yy813:\n    yych = *++p;\n    if (yych == 'C')\n      goto yy816;\n    if (yych == 'c')\n      goto yy816;\n    goto yy806;\n  yy814:\n    yych = *++p;\n    if (yych == ':')\n      goto yy817;\n    goto yy806;\n  yy815:\n    yych = *++p;\n    if (yych == ':')\n      goto yy819;\n    goto yy806;\n  yy816:\n    yych = *++p;\n    if (yych == 'R')\n      goto yy820;\n    if (yych == 'r')\n      goto yy820;\n    goto yy806;\n  yy817:\n    yyaccept = 1;\n    yych = *(marker = ++p);\n    if (yych == 'I')\n      goto yy821;\n    if (yych == 'i')\n      goto yy821;\n  yy818 : { return (bufsize_t)(p - start); }\n  yy819:\n    ++p;\n    goto yy818;\n  yy820:\n    yych = *++p;\n    if (yych == 'I')\n      goto yy822;\n    if (yych == 'i')\n      goto yy822;\n    goto yy806;\n  yy821:\n    yych = *++p;\n    if (yych == 'M')\n      goto yy823;\n    if (yych == 'm')\n      goto yy823;\n    goto yy806;\n  yy822:\n    yych = *++p;\n    if (yych == 'P')\n      goto yy824;\n    if (yych == 'p')\n      goto yy824;\n    goto yy806;\n  yy823:\n    yych = *++p;\n    if (yych == 'A')\n      goto yy825;\n    if (yych == 'a')\n      goto yy825;\n    goto yy806;\n  yy824:\n    yych = *++p;\n    if (yych == 'T')\n      goto yy815;\n    if (yych == 't')\n      goto yy815;\n    goto yy806;\n  yy825:\n    yych = *++p;\n    if (yych == 'G')\n      goto yy826;\n    if (yych != 'g')\n      goto yy806;\n  yy826:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy827;\n    if (yych != 'e')\n      goto yy806;\n  yy827:\n    yych = *++p;\n    if (yych != '/')\n      goto yy806;\n    yych = *++p;\n    if (yych <= 'W') {\n      if (yych <= 'J') {\n        if (yych == 'G')\n          goto yy828;\n        if (yych <= 'I')\n          goto yy806;\n        goto yy829;\n      } else {\n        if (yych == 'P')\n          goto yy830;\n        if (yych <= 'V')\n          goto yy806;\n        goto yy831;\n      }\n    } else {\n      if (yych <= 'j') {\n        if (yych == 'g')\n          goto yy828;\n        if (yych <= 'i')\n          goto yy806;\n        goto yy829;\n      } else {\n        if (yych <= 'p') {\n          if (yych <= 'o')\n            goto yy806;\n          goto yy830;\n        } else {\n          if (yych == 'w')\n            goto yy831;\n          goto yy806;\n        }\n      }\n    }\n  yy828:\n    yych = *++p;\n    if (yych == 'I')\n      goto yy832;\n    if (yych == 'i')\n      goto yy832;\n    goto yy806;\n  yy829:\n    yych = *++p;\n    if (yych == 'P')\n      goto yy833;\n    if (yych == 'p')\n      goto yy833;\n    goto yy806;\n  yy830:\n    yych = *++p;\n    if (yych == 'N')\n      goto yy834;\n    if (yych == 'n')\n      goto yy834;\n    goto yy806;\n  yy831:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy835;\n    if (yych == 'e')\n      goto yy835;\n    goto yy806;\n  yy832:\n    yych = *++p;\n    if (yych == 'F')\n      goto yy836;\n    if (yych == 'f')\n      goto yy836;\n    goto yy806;\n  yy833:\n    yych = *++p;\n    if (yych == 'E')\n      goto yy834;\n    if (yych != 'e')\n      goto yy806;\n  yy834:\n    yych = *++p;\n    if (yych == 'G')\n      goto yy836;\n    if (yych == 'g')\n      goto yy836;\n    goto yy806;\n  yy835:\n    yych = *++p;\n    if (yych == 'B')\n      goto yy837;\n    if (yych == 'b')\n      goto yy837;\n    goto yy806;\n  yy836:\n    ++p;\n    { return 0; }\n  yy837:\n    yych = *++p;\n    if (yych == 'P')\n      goto yy836;\n    if (yych == 'p')\n      goto yy836;\n    goto yy806;\n  }\n}\n\n// Scans a footnote definition opening.\nbufsize_t _scan_footnote_definition(const unsigned char *p) {\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n\n  {\n    unsigned char yych;\n    static const unsigned char yybm[] = {\n        0,   64, 64, 64, 64, 64, 64, 64, 64, 128, 0,  64, 64, 0,  64, 64,\n        64,  64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64,\n        128, 64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64,\n        64,  64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64,\n        64,  64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64,\n        64,  64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 0,  64, 64,\n        64,  64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64,\n        64,  64, 64, 64, 64, 64, 64, 64, 64, 64,  64, 64, 64, 64, 64, 64,\n        0,   0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,\n        0,   0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,\n        0,   0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,\n        0,   0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,\n        0,   0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,\n        0,   0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,\n        0,   0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,\n        0,   0,  0,  0,  0,  0,  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,\n    };\n    yych = *p;\n    if (yych == '[')\n      goto yy840;\n    ++p;\n  yy839 : { return 0; }\n  yy840:\n    yych = *(marker = ++p);\n    if (yych != '^')\n      goto yy839;\n    yych = *++p;\n    if (yych != ']')\n      goto yy843;\n  yy841:\n    p = marker;\n    goto yy839;\n  yy842:\n    yych = *++p;\n  yy843:\n    if (yybm[0 + yych] & 64) {\n      goto yy842;\n    }\n    if (yych <= 0xEC) {\n      if (yych <= 0xC1) {\n        if (yych <= ' ')\n          goto yy841;\n        if (yych <= ']')\n          goto yy851;\n        goto yy841;\n      } else {\n        if (yych <= 0xDF)\n          goto yy844;\n        if (yych <= 0xE0)\n          goto yy845;\n        goto yy846;\n      }\n    } else {\n      if (yych <= 0xF0) {\n        if (yych <= 0xED)\n          goto yy847;\n        if (yych <= 0xEF)\n          goto yy846;\n        goto yy848;\n      } else {\n        if (yych <= 0xF3)\n          goto yy849;\n        if (yych <= 0xF4)\n          goto yy850;\n        goto yy841;\n      }\n    }\n  yy844:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy841;\n    if (yych <= 0xBF)\n      goto yy842;\n    goto yy841;\n  yy845:\n    yych = *++p;\n    if (yych <= 0x9F)\n      goto yy841;\n    if (yych <= 0xBF)\n      goto yy844;\n    goto yy841;\n  yy846:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy841;\n    if (yych <= 0xBF)\n      goto yy844;\n    goto yy841;\n  yy847:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy841;\n    if (yych <= 0x9F)\n      goto yy844;\n    goto yy841;\n  yy848:\n    yych = *++p;\n    if (yych <= 0x8F)\n      goto yy841;\n    if (yych <= 0xBF)\n      goto yy846;\n    goto yy841;\n  yy849:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy841;\n    if (yych <= 0xBF)\n      goto yy846;\n    goto yy841;\n  yy850:\n    yych = *++p;\n    if (yych <= 0x7F)\n      goto yy841;\n    if (yych <= 0x8F)\n      goto yy846;\n    goto yy841;\n  yy851:\n    yych = *++p;\n    if (yych != ':')\n      goto yy841;\n  yy852:\n    yych = *++p;\n    if (yybm[0 + yych] & 128) {\n      goto yy852;\n    }\n    { return (bufsize_t)(p - start); }\n  }\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/scanners.h",
    "content": "#ifndef CMARK_SCANNERS_H\n#define CMARK_SCANNERS_H\n\n#include \"cmark-gfm.h\"\n#include \"chunk.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nbufsize_t _scan_at(bufsize_t (*scanner)(const unsigned char *), cmark_chunk *c,\n                   bufsize_t offset);\nbufsize_t _scan_scheme(const unsigned char *p);\nbufsize_t _scan_autolink_uri(const unsigned char *p);\nbufsize_t _scan_autolink_email(const unsigned char *p);\nbufsize_t _scan_html_tag(const unsigned char *p);\nbufsize_t _scan_liberal_html_tag(const unsigned char *p);\nbufsize_t _scan_html_comment(const unsigned char *p);\nbufsize_t _scan_html_pi(const unsigned char *p);\nbufsize_t _scan_html_declaration(const unsigned char *p);\nbufsize_t _scan_html_cdata(const unsigned char *p);\nbufsize_t _scan_html_block_start(const unsigned char *p);\nbufsize_t _scan_html_block_start_7(const unsigned char *p);\nbufsize_t _scan_html_block_end_1(const unsigned char *p);\nbufsize_t _scan_html_block_end_2(const unsigned char *p);\nbufsize_t _scan_html_block_end_3(const unsigned char *p);\nbufsize_t _scan_html_block_end_4(const unsigned char *p);\nbufsize_t _scan_html_block_end_5(const unsigned char *p);\nbufsize_t _scan_link_title(const unsigned char *p);\nbufsize_t _scan_spacechars(const unsigned char *p);\nbufsize_t _scan_atx_heading_start(const unsigned char *p);\nbufsize_t _scan_setext_heading_line(const unsigned char *p);\nbufsize_t _scan_open_code_fence(const unsigned char *p);\nbufsize_t _scan_close_code_fence(const unsigned char *p);\nbufsize_t _scan_entity(const unsigned char *p);\nbufsize_t _scan_dangerous_url(const unsigned char *p);\nbufsize_t _scan_footnote_definition(const unsigned char *p);\n\n#define scan_scheme(c, n) _scan_at(&_scan_scheme, c, n)\n#define scan_autolink_uri(c, n) _scan_at(&_scan_autolink_uri, c, n)\n#define scan_autolink_email(c, n) _scan_at(&_scan_autolink_email, c, n)\n#define scan_html_tag(c, n) _scan_at(&_scan_html_tag, c, n)\n#define scan_liberal_html_tag(c, n) _scan_at(&_scan_liberal_html_tag, c, n)\n#define scan_html_comment(c, n) _scan_at(&_scan_html_comment, c, n)\n#define scan_html_pi(c, n) _scan_at(&_scan_html_pi, c, n)\n#define scan_html_declaration(c, n) _scan_at(&_scan_html_declaration, c, n)\n#define scan_html_cdata(c, n) _scan_at(&_scan_html_cdata, c, n)\n#define scan_html_block_start(c, n) _scan_at(&_scan_html_block_start, c, n)\n#define scan_html_block_start_7(c, n) _scan_at(&_scan_html_block_start_7, c, n)\n#define scan_html_block_end_1(c, n) _scan_at(&_scan_html_block_end_1, c, n)\n#define scan_html_block_end_2(c, n) _scan_at(&_scan_html_block_end_2, c, n)\n#define scan_html_block_end_3(c, n) _scan_at(&_scan_html_block_end_3, c, n)\n#define scan_html_block_end_4(c, n) _scan_at(&_scan_html_block_end_4, c, n)\n#define scan_html_block_end_5(c, n) _scan_at(&_scan_html_block_end_5, c, n)\n#define scan_link_title(c, n) _scan_at(&_scan_link_title, c, n)\n#define scan_spacechars(c, n) _scan_at(&_scan_spacechars, c, n)\n#define scan_atx_heading_start(c, n) _scan_at(&_scan_atx_heading_start, c, n)\n#define scan_setext_heading_line(c, n)                                         \\\n  _scan_at(&_scan_setext_heading_line, c, n)\n#define scan_open_code_fence(c, n) _scan_at(&_scan_open_code_fence, c, n)\n#define scan_close_code_fence(c, n) _scan_at(&_scan_close_code_fence, c, n)\n#define scan_entity(c, n) _scan_at(&_scan_entity, c, n)\n#define scan_dangerous_url(c, n) _scan_at(&_scan_dangerous_url, c, n)\n#define scan_footnote_definition(c, n) _scan_at(&_scan_footnote_definition, c, n)\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/scanners.re",
    "content": "#include <stdlib.h>\n#include \"chunk.h\"\n#include \"scanners.h\"\n\nbufsize_t _scan_at(bufsize_t (*scanner)(const unsigned char *), cmark_chunk *c, bufsize_t offset)\n{\n\tbufsize_t res;\n\tunsigned char *ptr = (unsigned char *)c->data;\n\n        if (ptr == NULL || offset > c->len) {\n          return 0;\n        } else {\n\t  unsigned char lim = ptr[c->len];\n\n\t  ptr[c->len] = '\\0';\n\t  res = scanner(ptr + offset);\n\t  ptr[c->len] = lim;\n        }\n\n\treturn res;\n}\n\n/*!re2c\n  re2c:define:YYCTYPE  = \"unsigned char\";\n  re2c:define:YYCURSOR = p;\n  re2c:define:YYMARKER = marker;\n  re2c:define:YYCTXMARKER = marker;\n  re2c:yyfill:enable = 0;\n\n  wordchar = [^\\x00-\\x20];\n\n  spacechar = [ \\t\\v\\f\\r\\n];\n\n  reg_char     = [^\\\\()\\x00-\\x20];\n\n  escaped_char = [\\\\][!\"#$%&'()*+,./:;<=>?@[\\\\\\]^_`{|}~-];\n\n  tagname = [A-Za-z][A-Za-z0-9-]*;\n\n  blocktagname = 'address'|'article'|'aside'|'base'|'basefont'|'blockquote'|'body'|'caption'|'center'|'col'|'colgroup'|'dd'|'details'|'dialog'|'dir'|'div'|'dl'|'dt'|'fieldset'|'figcaption'|'figure'|'footer'|'form'|'frame'|'frameset'|'h1'|'h2'|'h3'|'h4'|'h5'|'h6'|'head'|'header'|'hr'|'html'|'iframe'|'legend'|'li'|'link'|'main'|'menu'|'menuitem'|'nav'|'noframes'|'ol'|'optgroup'|'option'|'p'|'param'|'section'|'source'|'title'|'summary'|'table'|'tbody'|'td'|'tfoot'|'th'|'thead'|'title'|'tr'|'track'|'ul';\n\n  attributename = [a-zA-Z_:][a-zA-Z0-9:._-]*;\n\n  unquotedvalue = [^ \\t\\r\\n\\v\\f\"'=<>`\\x00]+;\n  singlequotedvalue = ['][^'\\x00]*['];\n  doublequotedvalue = [\"][^\"\\x00]*[\"];\n\n  attributevalue = unquotedvalue | singlequotedvalue | doublequotedvalue;\n\n  attributevaluespec = spacechar* [=] spacechar* attributevalue;\n\n  attribute = spacechar+ attributename attributevaluespec?;\n\n  opentag = tagname attribute* spacechar* [/]? [>];\n  closetag = [/] tagname spacechar* [>];\n\n  htmlcomment = \"--\" ([^\\x00-]+ | \"-\" [^\\x00-] | \"--\" [^\\x00>])* \"-->\";\n\n  processinginstruction = ([^?>\\x00]+ | [?][^>\\x00] | [>])+;\n\n  declaration = [A-Z]+ spacechar+ [^>\\x00]*;\n\n  cdata = \"CDATA[\" ([^\\]\\x00]+ | \"]\" [^\\]\\x00] | \"]]\" [^>\\x00])*;\n\n  htmltag = opentag | closetag;\n\n  in_parens_nosp   = [(] (reg_char|escaped_char|[\\\\])* [)];\n\n  in_double_quotes = [\"] (escaped_char|[^\"\\x00])* [\"];\n  in_single_quotes = ['] (escaped_char|[^'\\x00])* ['];\n  in_parens        = [(] (escaped_char|[^)\\x00])* [)];\n\n  scheme           = [A-Za-z][A-Za-z0-9.+-]{1,31};\n*/\n\n// Try to match a scheme including colon.\nbufsize_t _scan_scheme(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  scheme [:] { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Try to match URI autolink after first <, returning number of chars matched.\nbufsize_t _scan_autolink_uri(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  scheme [:][^\\x00-\\x20<>]*[>]  { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Try to match email autolink after first <, returning num of chars matched.\nbufsize_t _scan_autolink_email(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  [a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+\n    [@]\n    [a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\n    ([.][a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\n    [>] { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Try to match an HTML tag after first <, returning num of chars matched.\nbufsize_t _scan_html_tag(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  htmltag { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Try to (liberally) match an HTML tag after first <, returning num of chars matched.\nbufsize_t _scan_liberal_html_tag(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  [^\\n\\x00]+ [>] { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\nbufsize_t _scan_html_comment(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  htmlcomment { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\nbufsize_t _scan_html_pi(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  processinginstruction { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\nbufsize_t _scan_html_declaration(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  declaration { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\nbufsize_t _scan_html_cdata(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  cdata { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Try to match an HTML block tag start line, returning\n// an integer code for the type of block (1-6, matching the spec).\n// #7 is handled by a separate function, below.\nbufsize_t _scan_html_block_start(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n/*!re2c\n  [<] ('script'|'pre'|'textarea'|'style') (spacechar | [>]) { return 1; }\n  '<!--' { return 2; }\n  '<?' { return 3; }\n  '<!' [A-Z] { return 4; }\n  '<![CDATA[' { return 5; }\n  [<] [/]? blocktagname (spacechar | [/]? [>])  { return 6; }\n  * { return 0; }\n*/\n}\n\n// Try to match an HTML block tag start line of type 7, returning\n// 7 if successful, 0 if not.\nbufsize_t _scan_html_block_start_7(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n/*!re2c\n  [<] (opentag | closetag) [\\t\\n\\f ]* [\\r\\n] { return 7; }\n  * { return 0; }\n*/\n}\n\n// Try to match an HTML block end line of type 1\nbufsize_t _scan_html_block_end_1(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  [^\\n\\x00]* [<] [/] ('script'|'pre'|'textarea'|'style') [>] { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Try to match an HTML block end line of type 2\nbufsize_t _scan_html_block_end_2(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  [^\\n\\x00]* '-->' { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Try to match an HTML block end line of type 3\nbufsize_t _scan_html_block_end_3(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  [^\\n\\x00]* '?>' { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Try to match an HTML block end line of type 4\nbufsize_t _scan_html_block_end_4(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  [^\\n\\x00]* '>' { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Try to match an HTML block end line of type 5\nbufsize_t _scan_html_block_end_5(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  [^\\n\\x00]* ']]>' { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Try to match a link title (in single quotes, in double quotes, or\n// in parentheses), returning number of chars matched.  Allow one\n// level of internal nesting (quotes within quotes).\nbufsize_t _scan_link_title(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  [\"] (escaped_char|[^\"\\x00])* [\"]   { return (bufsize_t)(p - start); }\n  ['] (escaped_char|[^'\\x00])* ['] { return (bufsize_t)(p - start); }\n  [(] (escaped_char|[^()\\x00])* [)]  { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Match space characters, including newlines.\nbufsize_t _scan_spacechars(const unsigned char *p)\n{\n  const unsigned char *start = p; \\\n/*!re2c\n  [ \\t\\v\\f\\r\\n]+ { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Match ATX heading start.\nbufsize_t _scan_atx_heading_start(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  [#]{1,6} ([ \\t]+|[\\r\\n])  { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Match setext heading line.  Return 1 for level-1 heading,\n// 2 for level-2, 0 for no match.\nbufsize_t _scan_setext_heading_line(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n/*!re2c\n  [=]+ [ \\t]* [\\r\\n] { return 1; }\n  [-]+ [ \\t]* [\\r\\n] { return 2; }\n  * { return 0; }\n*/\n}\n\n// Scan an opening code fence.\nbufsize_t _scan_open_code_fence(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  [`]{3,} / [^`\\r\\n\\x00]*[\\r\\n] { return (bufsize_t)(p - start); }\n  [~]{3,} / [^\\r\\n\\x00]*[\\r\\n] { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Scan a closing code fence with length at least len.\nbufsize_t _scan_close_code_fence(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  [`]{3,} / [ \\t]*[\\r\\n] { return (bufsize_t)(p - start); }\n  [~]{3,} / [ \\t]*[\\r\\n] { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Scans an entity.\n// Returns number of chars matched.\nbufsize_t _scan_entity(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  [&] ([#] ([Xx][A-Fa-f0-9]{1,6}|[0-9]{1,7}) |[A-Za-z][A-Za-z0-9]{1,31} ) [;]\n     { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Returns positive value if a URL begins in a way that is potentially\n// dangerous, with javascript:, vbscript:, file:, or data:, otherwise 0.\nbufsize_t _scan_dangerous_url(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  'data:image/' ('png'|'gif'|'jpeg'|'webp') { return 0; }\n  'javascript:' | 'vbscript:' | 'file:' | 'data:' { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n\n// Scans a footnote definition opening.\nbufsize_t _scan_footnote_definition(const unsigned char *p)\n{\n  const unsigned char *marker = NULL;\n  const unsigned char *start = p;\n/*!re2c\n  '[^' ([^\\] \\r\\n\\x00\\t]+) ']:' [ \\t]* { return (bufsize_t)(p - start); }\n  * { return 0; }\n*/\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/syntax_extension.c",
    "content": "#include <stdlib.h>\n#include <assert.h>\n\n#include \"cmark-gfm.h\"\n#include \"syntax_extension.h\"\n#include \"buffer.h\"\n\nextern cmark_mem CMARK_DEFAULT_MEM_ALLOCATOR;\n\nstatic cmark_mem *_mem = &CMARK_DEFAULT_MEM_ALLOCATOR;\n\nvoid cmark_syntax_extension_free(cmark_mem *mem, cmark_syntax_extension *extension) {\n  if (extension->free_function && extension->priv) {\n    extension->free_function(mem, extension->priv);\n  }\n\n  cmark_llist_free(mem, extension->special_inline_chars);\n  mem->free(extension->name);\n  mem->free(extension);\n}\n\ncmark_syntax_extension *cmark_syntax_extension_new(const char *name) {\n  cmark_syntax_extension *res = (cmark_syntax_extension *) _mem->calloc(1, sizeof(cmark_syntax_extension));\n  res->name = (char *) _mem->calloc(1, sizeof(char) * (strlen(name)) + 1);\n  strcpy(res->name, name);\n  return res;\n}\n\ncmark_node_type cmark_syntax_extension_add_node(int is_inline) {\n  cmark_node_type *ref = !is_inline ? &CMARK_NODE_LAST_BLOCK : &CMARK_NODE_LAST_INLINE;\n\n  if ((*ref & CMARK_NODE_VALUE_MASK) == CMARK_NODE_VALUE_MASK) {\n    assert(false);\n    return (cmark_node_type) 0;\n  }\n\n  return *ref = (cmark_node_type) ((int) *ref + 1);\n}\n\nvoid cmark_syntax_extension_set_emphasis(cmark_syntax_extension *extension,\n                                         int emphasis) {\n  extension->emphasis = emphasis == 1;\n}\n\nvoid cmark_syntax_extension_set_open_block_func(cmark_syntax_extension *extension,\n                                                cmark_open_block_func func) {\n  extension->try_opening_block = func;\n}\n\nvoid cmark_syntax_extension_set_match_block_func(cmark_syntax_extension *extension,\n                                                 cmark_match_block_func func) {\n  extension->last_block_matches = func;\n}\n\nvoid cmark_syntax_extension_set_match_inline_func(cmark_syntax_extension *extension,\n                                                  cmark_match_inline_func func) {\n  extension->match_inline = func;\n}\n\nvoid cmark_syntax_extension_set_inline_from_delim_func(cmark_syntax_extension *extension,\n                                                       cmark_inline_from_delim_func func) {\n  extension->insert_inline_from_delim = func;\n}\n\nvoid cmark_syntax_extension_set_special_inline_chars(cmark_syntax_extension *extension,\n                                                     cmark_llist *special_chars) {\n  extension->special_inline_chars = special_chars;\n}\n\nvoid cmark_syntax_extension_set_get_type_string_func(cmark_syntax_extension *extension,\n                                                     cmark_get_type_string_func func) {\n  extension->get_type_string_func = func;\n}\n\nvoid cmark_syntax_extension_set_can_contain_func(cmark_syntax_extension *extension,\n                                                 cmark_can_contain_func func) {\n  extension->can_contain_func = func;\n}\n\nvoid cmark_syntax_extension_set_contains_inlines_func(cmark_syntax_extension *extension,\n                                                      cmark_contains_inlines_func func) {\n  extension->contains_inlines_func = func;\n}\n\nvoid cmark_syntax_extension_set_commonmark_render_func(cmark_syntax_extension *extension,\n                                                       cmark_common_render_func func) {\n  extension->commonmark_render_func = func;\n}\n\nvoid cmark_syntax_extension_set_plaintext_render_func(cmark_syntax_extension *extension,\n                                                      cmark_common_render_func func) {\n  extension->plaintext_render_func = func;\n}\n\nvoid cmark_syntax_extension_set_latex_render_func(cmark_syntax_extension *extension,\n                                                  cmark_common_render_func func) {\n  extension->latex_render_func = func;\n}\n\nvoid cmark_syntax_extension_set_xml_attr_func(cmark_syntax_extension *extension,\n                                              cmark_xml_attr_func func) {\n  extension->xml_attr_func = func;\n}\n\nvoid cmark_syntax_extension_set_man_render_func(cmark_syntax_extension *extension,\n                                                cmark_common_render_func func) {\n  extension->man_render_func = func;\n}\n\nvoid cmark_syntax_extension_set_html_render_func(cmark_syntax_extension *extension,\n                                                 cmark_html_render_func func) {\n  extension->html_render_func = func;\n}\n\nvoid cmark_syntax_extension_set_html_filter_func(cmark_syntax_extension *extension,\n                                                 cmark_html_filter_func func) {\n  extension->html_filter_func = func;\n}\n\nvoid cmark_syntax_extension_set_postprocess_func(cmark_syntax_extension *extension,\n                                                 cmark_postprocess_func func) {\n  extension->postprocess_func = func;\n}\n\nvoid cmark_syntax_extension_set_private(cmark_syntax_extension *extension,\n                                        void *priv,\n                                        cmark_free_func free_func) {\n  extension->priv = priv;\n  extension->free_function = free_func;\n}\n\nvoid *cmark_syntax_extension_get_private(cmark_syntax_extension *extension) {\n    return extension->priv;\n}\n\nvoid cmark_syntax_extension_set_opaque_alloc_func(cmark_syntax_extension *extension,\n                                                  cmark_opaque_alloc_func func) {\n  extension->opaque_alloc_func = func;\n}\n\nvoid cmark_syntax_extension_set_opaque_free_func(cmark_syntax_extension *extension,\n                                                 cmark_opaque_free_func func) {\n  extension->opaque_free_func = func;\n}\n\nvoid cmark_syntax_extension_set_commonmark_escape_func(cmark_syntax_extension *extension,\n                                                       cmark_commonmark_escape_func func) {\n  extension->commonmark_escape_func = func;\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/syntax_extension.h",
    "content": "#ifndef CMARK_SYNTAX_EXTENSION_H\n#define CMARK_SYNTAX_EXTENSION_H\n\n#include \"cmark-gfm.h\"\n#include \"cmark-gfm-extension_api.h\"\n#include \"config.h\"\n\nstruct cmark_syntax_extension {\n  cmark_match_block_func          last_block_matches;\n  cmark_open_block_func           try_opening_block;\n  cmark_match_inline_func         match_inline;\n  cmark_inline_from_delim_func    insert_inline_from_delim;\n  cmark_llist                   * special_inline_chars;\n  char                          * name;\n  void                          * priv;\n  bool                            emphasis;\n  cmark_free_func                 free_function;\n  cmark_get_type_string_func      get_type_string_func;\n  cmark_can_contain_func          can_contain_func;\n  cmark_contains_inlines_func     contains_inlines_func;\n  cmark_common_render_func        commonmark_render_func;\n  cmark_common_render_func        plaintext_render_func;\n  cmark_common_render_func        latex_render_func;\n  cmark_xml_attr_func             xml_attr_func;\n  cmark_common_render_func        man_render_func;\n  cmark_html_render_func          html_render_func;\n  cmark_html_filter_func          html_filter_func;\n  cmark_postprocess_func          postprocess_func;\n  cmark_opaque_alloc_func         opaque_alloc_func;\n  cmark_opaque_free_func          opaque_free_func;\n  cmark_commonmark_escape_func    commonmark_escape_func;\n};\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/utf8.c",
    "content": "#include <stdlib.h>\n#include <stdint.h>\n#include <assert.h>\n\n#include \"cmark_ctype.h\"\n#include \"utf8.h\"\n\nstatic const int8_t utf8proc_utf8class[256] = {\n    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n    1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n    2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n    4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0};\n\nstatic void encode_unknown(cmark_strbuf *buf) {\n  static const uint8_t repl[] = {239, 191, 189};\n  cmark_strbuf_put(buf, repl, 3);\n}\n\nstatic int utf8proc_charlen(const uint8_t *str, bufsize_t str_len) {\n  int length, i;\n\n  if (!str_len)\n    return 0;\n\n  length = utf8proc_utf8class[str[0]];\n\n  if (!length)\n    return -1;\n\n  if (str_len >= 0 && (bufsize_t)length > str_len)\n    return -str_len;\n\n  for (i = 1; i < length; i++) {\n    if ((str[i] & 0xC0) != 0x80)\n      return -i;\n  }\n\n  return length;\n}\n\n// Validate a single UTF-8 character according to RFC 3629.\nstatic int utf8proc_valid(const uint8_t *str, bufsize_t str_len) {\n  int length = utf8proc_utf8class[str[0]];\n\n  if (!length)\n    return -1;\n\n  if ((bufsize_t)length > str_len)\n    return -str_len;\n\n  switch (length) {\n  case 2:\n    if ((str[1] & 0xC0) != 0x80)\n      return -1;\n    if (str[0] < 0xC2) {\n      // Overlong\n      return -length;\n    }\n    break;\n\n  case 3:\n    if ((str[1] & 0xC0) != 0x80)\n      return -1;\n    if ((str[2] & 0xC0) != 0x80)\n      return -2;\n    if (str[0] == 0xE0) {\n      if (str[1] < 0xA0) {\n        // Overlong\n        return -length;\n      }\n    } else if (str[0] == 0xED) {\n      if (str[1] >= 0xA0) {\n        // Surrogate\n        return -length;\n      }\n    }\n    break;\n\n  case 4:\n    if ((str[1] & 0xC0) != 0x80)\n      return -1;\n    if ((str[2] & 0xC0) != 0x80)\n      return -2;\n    if ((str[3] & 0xC0) != 0x80)\n      return -3;\n    if (str[0] == 0xF0) {\n      if (str[1] < 0x90) {\n        // Overlong\n        return -length;\n      }\n    } else if (str[0] >= 0xF4) {\n      if (str[0] > 0xF4 || str[1] >= 0x90) {\n        // Above 0x10FFFF\n        return -length;\n      }\n    }\n    break;\n  }\n\n  return length;\n}\n\nvoid cmark_utf8proc_check(cmark_strbuf *ob, const uint8_t *line,\n                          bufsize_t size) {\n  bufsize_t i = 0;\n\n  while (i < size) {\n    bufsize_t org = i;\n    int charlen = 0;\n\n    while (i < size) {\n      if (line[i] < 0x80 && line[i] != 0) {\n        i++;\n      } else if (line[i] >= 0x80) {\n        charlen = utf8proc_valid(line + i, size - i);\n        if (charlen < 0) {\n          charlen = -charlen;\n          break;\n        }\n        i += charlen;\n      } else if (line[i] == 0) {\n        // ASCII NUL is technically valid but rejected\n        // for security reasons.\n        charlen = 1;\n        break;\n      }\n    }\n\n    if (i > org) {\n      cmark_strbuf_put(ob, line + org, i - org);\n    }\n\n    if (i >= size) {\n      break;\n    } else {\n      // Invalid UTF-8\n      encode_unknown(ob);\n      i += charlen;\n    }\n  }\n}\n\nint cmark_utf8proc_iterate(const uint8_t *str, bufsize_t str_len,\n                           int32_t *dst) {\n  int length;\n  int32_t uc = -1;\n\n  *dst = -1;\n  length = utf8proc_charlen(str, str_len);\n  if (length < 0)\n    return -1;\n\n  switch (length) {\n  case 1:\n    uc = str[0];\n    break;\n  case 2:\n    uc = ((str[0] & 0x1F) << 6) + (str[1] & 0x3F);\n    if (uc < 0x80)\n      uc = -1;\n    break;\n  case 3:\n    uc = ((str[0] & 0x0F) << 12) + ((str[1] & 0x3F) << 6) + (str[2] & 0x3F);\n    if (uc < 0x800 || (uc >= 0xD800 && uc < 0xE000))\n      uc = -1;\n    break;\n  case 4:\n    uc = ((str[0] & 0x07) << 18) + ((str[1] & 0x3F) << 12) +\n         ((str[2] & 0x3F) << 6) + (str[3] & 0x3F);\n    if (uc < 0x10000 || uc >= 0x110000)\n      uc = -1;\n    break;\n  }\n\n  if (uc < 0)\n    return -1;\n\n  *dst = uc;\n  return length;\n}\n\nvoid cmark_utf8proc_encode_char(int32_t uc, cmark_strbuf *buf) {\n  uint8_t dst[4];\n  bufsize_t len = 0;\n\n  assert(uc >= 0);\n\n  if (uc < 0x80) {\n    dst[0] = (uint8_t)(uc);\n    len = 1;\n  } else if (uc < 0x800) {\n    dst[0] = (uint8_t)(0xC0 + (uc >> 6));\n    dst[1] = 0x80 + (uc & 0x3F);\n    len = 2;\n  } else if (uc == 0xFFFF) {\n    dst[0] = 0xFF;\n    len = 1;\n  } else if (uc == 0xFFFE) {\n    dst[0] = 0xFE;\n    len = 1;\n  } else if (uc < 0x10000) {\n    dst[0] = (uint8_t)(0xE0 + (uc >> 12));\n    dst[1] = 0x80 + ((uc >> 6) & 0x3F);\n    dst[2] = 0x80 + (uc & 0x3F);\n    len = 3;\n  } else if (uc < 0x110000) {\n    dst[0] = (uint8_t)(0xF0 + (uc >> 18));\n    dst[1] = 0x80 + ((uc >> 12) & 0x3F);\n    dst[2] = 0x80 + ((uc >> 6) & 0x3F);\n    dst[3] = 0x80 + (uc & 0x3F);\n    len = 4;\n  } else {\n    encode_unknown(buf);\n    return;\n  }\n\n  cmark_strbuf_put(buf, dst, len);\n}\n\nvoid cmark_utf8proc_case_fold(cmark_strbuf *dest, const uint8_t *str,\n                              bufsize_t len) {\n  int32_t c;\n\n#define bufpush(x) cmark_utf8proc_encode_char(x, dest)\n\n  while (len > 0) {\n    bufsize_t char_len = cmark_utf8proc_iterate(str, len, &c);\n\n    if (char_len >= 0) {\n#include \"case_fold_switch.inc\"\n    } else {\n      encode_unknown(dest);\n      char_len = -char_len;\n    }\n\n    str += char_len;\n    len -= char_len;\n  }\n}\n\n// matches anything in the Zs class, plus LF, CR, TAB, FF.\nint cmark_utf8proc_is_space(int32_t uc) {\n  return (uc == 9 || uc == 10 || uc == 12 || uc == 13 || uc == 32 ||\n          uc == 160 || uc == 5760 || (uc >= 8192 && uc <= 8202) || uc == 8239 ||\n          uc == 8287 || uc == 12288);\n}\n\n// matches anything in the P[cdefios] classes.\nint cmark_utf8proc_is_punctuation(int32_t uc) {\n  return (\n      (uc < 128 && cmark_ispunct((char)uc)) || uc == 161 || uc == 167 ||\n      uc == 171 || uc == 182 || uc == 183 || uc == 187 || uc == 191 ||\n      uc == 894 || uc == 903 || (uc >= 1370 && uc <= 1375) || uc == 1417 ||\n      uc == 1418 || uc == 1470 || uc == 1472 || uc == 1475 || uc == 1478 ||\n      uc == 1523 || uc == 1524 || uc == 1545 || uc == 1546 || uc == 1548 ||\n      uc == 1549 || uc == 1563 || uc == 1566 || uc == 1567 ||\n      (uc >= 1642 && uc <= 1645) || uc == 1748 || (uc >= 1792 && uc <= 1805) ||\n      (uc >= 2039 && uc <= 2041) || (uc >= 2096 && uc <= 2110) || uc == 2142 ||\n      uc == 2404 || uc == 2405 || uc == 2416 || uc == 2800 || uc == 3572 ||\n      uc == 3663 || uc == 3674 || uc == 3675 || (uc >= 3844 && uc <= 3858) ||\n      uc == 3860 || (uc >= 3898 && uc <= 3901) || uc == 3973 ||\n      (uc >= 4048 && uc <= 4052) || uc == 4057 || uc == 4058 ||\n      (uc >= 4170 && uc <= 4175) || uc == 4347 || (uc >= 4960 && uc <= 4968) ||\n      uc == 5120 || uc == 5741 || uc == 5742 || uc == 5787 || uc == 5788 ||\n      (uc >= 5867 && uc <= 5869) || uc == 5941 || uc == 5942 ||\n      (uc >= 6100 && uc <= 6102) || (uc >= 6104 && uc <= 6106) ||\n      (uc >= 6144 && uc <= 6154) || uc == 6468 || uc == 6469 || uc == 6686 ||\n      uc == 6687 || (uc >= 6816 && uc <= 6822) || (uc >= 6824 && uc <= 6829) ||\n      (uc >= 7002 && uc <= 7008) || (uc >= 7164 && uc <= 7167) ||\n      (uc >= 7227 && uc <= 7231) || uc == 7294 || uc == 7295 ||\n      (uc >= 7360 && uc <= 7367) || uc == 7379 || (uc >= 8208 && uc <= 8231) ||\n      (uc >= 8240 && uc <= 8259) || (uc >= 8261 && uc <= 8273) ||\n      (uc >= 8275 && uc <= 8286) || uc == 8317 || uc == 8318 || uc == 8333 ||\n      uc == 8334 || (uc >= 8968 && uc <= 8971) || uc == 9001 || uc == 9002 ||\n      (uc >= 10088 && uc <= 10101) || uc == 10181 || uc == 10182 ||\n      (uc >= 10214 && uc <= 10223) || (uc >= 10627 && uc <= 10648) ||\n      (uc >= 10712 && uc <= 10715) || uc == 10748 || uc == 10749 ||\n      (uc >= 11513 && uc <= 11516) || uc == 11518 || uc == 11519 ||\n      uc == 11632 || (uc >= 11776 && uc <= 11822) ||\n      (uc >= 11824 && uc <= 11842) || (uc >= 12289 && uc <= 12291) ||\n      (uc >= 12296 && uc <= 12305) || (uc >= 12308 && uc <= 12319) ||\n      uc == 12336 || uc == 12349 || uc == 12448 || uc == 12539 || uc == 42238 ||\n      uc == 42239 || (uc >= 42509 && uc <= 42511) || uc == 42611 ||\n      uc == 42622 || (uc >= 42738 && uc <= 42743) ||\n      (uc >= 43124 && uc <= 43127) || uc == 43214 || uc == 43215 ||\n      (uc >= 43256 && uc <= 43258) || uc == 43310 || uc == 43311 ||\n      uc == 43359 || (uc >= 43457 && uc <= 43469) || uc == 43486 ||\n      uc == 43487 || (uc >= 43612 && uc <= 43615) || uc == 43742 ||\n      uc == 43743 || uc == 43760 || uc == 43761 || uc == 44011 || uc == 64830 ||\n      uc == 64831 || (uc >= 65040 && uc <= 65049) ||\n      (uc >= 65072 && uc <= 65106) || (uc >= 65108 && uc <= 65121) ||\n      uc == 65123 || uc == 65128 || uc == 65130 || uc == 65131 ||\n      (uc >= 65281 && uc <= 65283) || (uc >= 65285 && uc <= 65290) ||\n      (uc >= 65292 && uc <= 65295) || uc == 65306 || uc == 65307 ||\n      uc == 65311 || uc == 65312 || (uc >= 65339 && uc <= 65341) ||\n      uc == 65343 || uc == 65371 || uc == 65373 ||\n      (uc >= 65375 && uc <= 65381) || (uc >= 65792 && uc <= 65794) ||\n      uc == 66463 || uc == 66512 || uc == 66927 || uc == 67671 || uc == 67871 ||\n      uc == 67903 || (uc >= 68176 && uc <= 68184) || uc == 68223 ||\n      (uc >= 68336 && uc <= 68342) || (uc >= 68409 && uc <= 68415) ||\n      (uc >= 68505 && uc <= 68508) || (uc >= 69703 && uc <= 69709) ||\n      uc == 69819 || uc == 69820 || (uc >= 69822 && uc <= 69825) ||\n      (uc >= 69952 && uc <= 69955) || uc == 70004 || uc == 70005 ||\n      (uc >= 70085 && uc <= 70088) || uc == 70093 ||\n      (uc >= 70200 && uc <= 70205) || uc == 70854 ||\n      (uc >= 71105 && uc <= 71113) || (uc >= 71233 && uc <= 71235) ||\n      (uc >= 74864 && uc <= 74868) || uc == 92782 || uc == 92783 ||\n      uc == 92917 || (uc >= 92983 && uc <= 92987) || uc == 92996 ||\n      uc == 113823);\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/utf8.h",
    "content": "#ifndef CMARK_UTF8_H\n#define CMARK_UTF8_H\n\n#include <stdint.h>\n#include \"buffer.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nCMARK_GFM_EXPORT\nvoid cmark_utf8proc_case_fold(cmark_strbuf *dest, const uint8_t *str,\n                              bufsize_t len);\n\nCMARK_GFM_EXPORT\nvoid cmark_utf8proc_encode_char(int32_t uc, cmark_strbuf *buf);\n\nCMARK_GFM_EXPORT\nint cmark_utf8proc_iterate(const uint8_t *str, bufsize_t str_len, int32_t *dst);\n\nCMARK_GFM_EXPORT\nvoid cmark_utf8proc_check(cmark_strbuf *dest, const uint8_t *line,\n                          bufsize_t size);\n\nCMARK_GFM_EXPORT\nint cmark_utf8proc_is_space(int32_t uc);\n\nCMARK_GFM_EXPORT\nint cmark_utf8proc_is_punctuation(int32_t uc);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/cmark-gfm/src/xml.c",
    "content": "#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <assert.h>\n\n#include \"config.h\"\n#include \"cmark-gfm.h\"\n#include \"node.h\"\n#include \"buffer.h\"\n#include \"houdini.h\"\n#include \"syntax_extension.h\"\n\n#define BUFFER_SIZE 100\n#define MAX_INDENT 40\n\n// Functions to convert cmark_nodes to XML strings.\n\nstatic void escape_xml(cmark_strbuf *dest, const unsigned char *source,\n                       bufsize_t length) {\n  houdini_escape_html0(dest, source, length, 0);\n}\n\nstruct render_state {\n  cmark_strbuf *xml;\n  int indent;\n};\n\nstatic CMARK_INLINE void indent(struct render_state *state) {\n  int i;\n  for (i = 0; i < state->indent && i < MAX_INDENT; i++) {\n    cmark_strbuf_putc(state->xml, ' ');\n  }\n}\n\nstatic int S_render_node(cmark_node *node, cmark_event_type ev_type,\n                         struct render_state *state, int options) {\n  cmark_strbuf *xml = state->xml;\n  bool literal = false;\n  cmark_delim_type delim;\n  bool entering = (ev_type == CMARK_EVENT_ENTER);\n  char buffer[BUFFER_SIZE];\n\n  if (entering) {\n    indent(state);\n    cmark_strbuf_putc(xml, '<');\n    cmark_strbuf_puts(xml, cmark_node_get_type_string(node));\n\n    if (options & CMARK_OPT_SOURCEPOS && node->start_line != 0) {\n      snprintf(buffer, BUFFER_SIZE, \" sourcepos=\\\"%d:%d-%d:%d\\\"\",\n               node->start_line, node->start_column, node->end_line,\n               node->end_column);\n      cmark_strbuf_puts(xml, buffer);\n    }\n\n    if (node->extension && node->extension->xml_attr_func) {\n      const char* r = node->extension->xml_attr_func(node->extension, node);\n      if (r != NULL)\n        cmark_strbuf_puts(xml, r);\n    }\n\n    literal = false;\n\n    switch (node->type) {\n    case CMARK_NODE_DOCUMENT:\n      cmark_strbuf_puts(xml, \" xmlns=\\\"http://commonmark.org/xml/1.0\\\"\");\n      break;\n    case CMARK_NODE_TEXT:\n    case CMARK_NODE_CODE:\n    case CMARK_NODE_HTML_BLOCK:\n    case CMARK_NODE_HTML_INLINE:\n      cmark_strbuf_puts(xml, \" xml:space=\\\"preserve\\\">\");\n      escape_xml(xml, node->as.literal.data, node->as.literal.len);\n      cmark_strbuf_puts(xml, \"</\");\n      cmark_strbuf_puts(xml, cmark_node_get_type_string(node));\n      literal = true;\n      break;\n    case CMARK_NODE_LIST:\n      switch (cmark_node_get_list_type(node)) {\n      case CMARK_ORDERED_LIST:\n        cmark_strbuf_puts(xml, \" type=\\\"ordered\\\"\");\n        snprintf(buffer, BUFFER_SIZE, \" start=\\\"%d\\\"\",\n                 cmark_node_get_list_start(node));\n        cmark_strbuf_puts(xml, buffer);\n        delim = cmark_node_get_list_delim(node);\n        if (delim == CMARK_PAREN_DELIM) {\n          cmark_strbuf_puts(xml, \" delim=\\\"paren\\\"\");\n        } else if (delim == CMARK_PERIOD_DELIM) {\n          cmark_strbuf_puts(xml, \" delim=\\\"period\\\"\");\n        }\n        break;\n      case CMARK_BULLET_LIST:\n        cmark_strbuf_puts(xml, \" type=\\\"bullet\\\"\");\n        break;\n      default:\n        break;\n      }\n      snprintf(buffer, BUFFER_SIZE, \" tight=\\\"%s\\\"\",\n               (cmark_node_get_list_tight(node) ? \"true\" : \"false\"));\n      cmark_strbuf_puts(xml, buffer);\n      break;\n    case CMARK_NODE_HEADING:\n      snprintf(buffer, BUFFER_SIZE, \" level=\\\"%d\\\"\", node->as.heading.level);\n      cmark_strbuf_puts(xml, buffer);\n      break;\n    case CMARK_NODE_CODE_BLOCK:\n      if (node->as.code.info.len > 0) {\n        cmark_strbuf_puts(xml, \" info=\\\"\");\n        escape_xml(xml, node->as.code.info.data, node->as.code.info.len);\n        cmark_strbuf_putc(xml, '\"');\n      }\n      cmark_strbuf_puts(xml, \" xml:space=\\\"preserve\\\">\");\n      escape_xml(xml, node->as.code.literal.data, node->as.code.literal.len);\n      cmark_strbuf_puts(xml, \"</\");\n      cmark_strbuf_puts(xml, cmark_node_get_type_string(node));\n      literal = true;\n      break;\n    case CMARK_NODE_CUSTOM_BLOCK:\n    case CMARK_NODE_CUSTOM_INLINE:\n      cmark_strbuf_puts(xml, \" on_enter=\\\"\");\n      escape_xml(xml, node->as.custom.on_enter.data,\n                 node->as.custom.on_enter.len);\n      cmark_strbuf_putc(xml, '\"');\n      cmark_strbuf_puts(xml, \" on_exit=\\\"\");\n      escape_xml(xml, node->as.custom.on_exit.data,\n                 node->as.custom.on_exit.len);\n      cmark_strbuf_putc(xml, '\"');\n      break;\n    case CMARK_NODE_LINK:\n    case CMARK_NODE_IMAGE:\n      cmark_strbuf_puts(xml, \" destination=\\\"\");\n      escape_xml(xml, node->as.link.url.data, node->as.link.url.len);\n      cmark_strbuf_putc(xml, '\"');\n      cmark_strbuf_puts(xml, \" title=\\\"\");\n      escape_xml(xml, node->as.link.title.data, node->as.link.title.len);\n      cmark_strbuf_putc(xml, '\"');\n      break;\n    default:\n      break;\n    }\n    if (node->first_child) {\n      state->indent += 2;\n    } else if (!literal) {\n      cmark_strbuf_puts(xml, \" /\");\n    }\n    cmark_strbuf_puts(xml, \">\\n\");\n\n  } else if (node->first_child) {\n    state->indent -= 2;\n    indent(state);\n    cmark_strbuf_puts(xml, \"</\");\n    cmark_strbuf_puts(xml, cmark_node_get_type_string(node));\n    cmark_strbuf_puts(xml, \">\\n\");\n  }\n\n  return 1;\n}\n\nchar *cmark_render_xml(cmark_node *root, int options) {\n  return cmark_render_xml_with_mem(root, options, cmark_node_mem(root));\n}\n\nchar *cmark_render_xml_with_mem(cmark_node *root, int options, cmark_mem *mem) {\n  char *result;\n  cmark_strbuf xml = CMARK_BUF_INIT(mem);\n  cmark_event_type ev_type;\n  cmark_node *cur;\n  struct render_state state = {&xml, 0};\n\n  cmark_iter *iter = cmark_iter_new(root);\n\n  cmark_strbuf_puts(state.xml, \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n\");\n  cmark_strbuf_puts(state.xml,\n                    \"<!DOCTYPE document SYSTEM \\\"CommonMark.dtd\\\">\\n\");\n  while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {\n    cur = cmark_iter_get_node(iter);\n    S_render_node(cur, ev_type, &state, options);\n  }\n  result = (char *)cmark_strbuf_detach(&xml);\n\n  cmark_iter_free(iter);\n  return result;\n}\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/IosMath.h",
    "content": "//\n//  IosMath.h\n//  iosMath\n//\n//  Created by MARIO ANDHIKA on 8/28/15.\n//  Copyright (C) 2015 MathChat\n//   \n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n\n#if __has_include(<IosMath/MTMathListDisplay.h>)\n#import <IosMath/MTMathUILabel.h>\n#import <IosMath/MTMathListDisplay.h>\n#import <IosMath/MTMathList.h>\n#import <IosMath/MTMathListBuilder.h>\n#else\n#import \"MTMathUILabel.h\"\n#import \"MTMathListDisplay.h\"\n#import \"MTMathList.h\"\n#import \"MTMathListBuilder.h\"\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/lib/MTMathAtomFactory.h",
    "content": "//\n//  MathAtomFactory.h\n//  iosMath\n//\n//  Created by Kostub Deshmukh on 8/28/13.\n//  Copyright (C) 2013 MathChat\n//   \n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n#import <Foundation/Foundation.h>\n\n#import \"MTMathList.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\nFOUNDATION_EXPORT NSString *const MTSymbolMultiplication;\nFOUNDATION_EXPORT NSString *const MTSymbolDivision;\nFOUNDATION_EXPORT NSString *const MTSymbolFractionSlash;\nFOUNDATION_EXPORT NSString *const MTSymbolWhiteSquare;\nFOUNDATION_EXPORT NSString *const MTSymbolBlackSquare;\nFOUNDATION_EXPORT NSString *const MTSymbolLessEqual;\nFOUNDATION_EXPORT NSString *const MTSymbolGreaterEqual;\nFOUNDATION_EXPORT NSString *const MTSymbolNotEqual;\nFOUNDATION_EXPORT NSString *const MTSymbolSquareRoot;\nFOUNDATION_EXPORT NSString *const MTSymbolCubeRoot;\nFOUNDATION_EXPORT NSString *const MTSymbolInfinity;\nFOUNDATION_EXPORT NSString *const MTSymbolAngle;\nFOUNDATION_EXPORT NSString *const MTSymbolDegree;\n\n/** A factory to create commonly used MTMathAtoms. */\n@interface MTMathAtomFactory : NSObject\n\n/** Returns an atom for the multiplication sign. */\n+ (MTMathAtom*) times;    // \\times or *\n\n/** Returns an atom for the division sign. */\n+ (MTMathAtom*) divide; // \\div or /\n\n#pragma mark - Placeholders\n\n/** Returns an atom which is a placeholder square. */\n+ (MTMathAtom*) placeholder;\n\n/** Returns a fraction with a placeholder for the numerator and denominator */\n+ (MTFraction*) placeholderFraction;\n\n/** Returns a square root with a placeholder as the radicand. */\n+ (MTRadical *)placeholderSquareRoot;\n\n/** Returns a radical with a placeholder as the radicand. */\n+ (MTRadical*) placeholderRadical;\n\n#pragma mark -\n\n/** Gets the atom with the right type for the given character. If an atom\n cannot be determined for a given character this returns nil. \n This function follows latex conventions for assigning types to the atoms.\n The following characters are not supported and will return nil:\n - Any non-ascii character.\n - Any control character or spaces (< 0x21)\n - Latex control chars: $ % # & ~ '\n - Chars with special meaning in latex: ^ _ { } \\\n All other characters will have a non-nil atom returned.\n */\n+ (nullable MTMathAtom*) atomForCharacter:(unichar) ch;\n\n/** Returns a `MTMathList` with one atom per character in the given string. This function\n does not do any LaTeX conversion or interpretation. It simply uses `atomForCharacter` to\n convert the characters to atoms. Any character that cannot be converted is ignored. */\n+ (MTMathList*) mathListForCharacters:(NSString*) chars;\n\n/** Creates a MTMathList representing the \\pmod command with the given modulus.\n This generates a math list that displays \"(mod m)\" where m is the given modulus.\n The \"mod\" text is displayed in roman font style.\n \n @param mod The modulus to be displayed after \"mod\". If nil or empty string, only \"(mod )\" will be displayed.\n @return A MTMathList representing the \\pmod command with the given modulus.\n */\n+ (MTMathList *)pmod:(NSString *)mod;\n\n/** Returns an atom with the right type for a given latex symbol (e.g. theta)\n If the latex symbol is unknown this will return nil. This supports LaTeX aliases as well.\n */\n+ (nullable MTMathAtom*) atomForLatexSymbolName:(NSString*) symbolName;\n\n/** Finds the name of the LaTeX symbol name for the given atom. This function is a reverse\n of the above function. If no latex symbol name corresponds to the atom, then this returns `nil`\n If nucleus of the atom is empty, then this will return `nil`.\n @note: This is not an exact reverse of the above in the case of aliases. If an LaTeX alias\n points to a given symbol, then this function will return the original symbol name and not the\n alias.\n @note: This function does not convert MathSpaces to latex command names either.\n */\n+ (nullable NSString*) latexSymbolNameForAtom:(MTMathAtom*) atom;\n\n/** Define a latex symbol for rendering. This function allows defining custom symbols that are\n not already present in the default set, or override existing symbols with new meaning.\n e.g. to define a symbol for \"lcm\" one can call:\n `[MTMathAtomFactory addLatexSymbol:@\"lcm\" value:[MTMathAtomFactory operatorWithName:@\"lcm\" limits:NO]]` */\n+ (void) addLatexSymbol:(NSString*) name value:(MTMathAtom*) atom;\n\n/** Returns a list of all supported lated symbols names. */\n+ (NSArray<NSString*>*) supportedLatexSymbolNames;\n\n/** Returns a large opertor for the given name. If limits is true, limits are set up on\n the operator and displyed differently. */\n+ (MTLargeOperator *)operatorWithName:(NSString *)name limits:(bool) limits;\n\n/** Returns an accent with the given name. The name of the accent is the LaTeX name\n such as `grave`, `hat` etc. If the name is not a recognized accent name, this\n returns nil. The `innerList` of the returned `MTAccent` is nil.\n */\n+ (nullable MTAccent*) accentWithName:(NSString*) accentName;\n\n/** Returns the accent name for the given accent. This is the reverse of the above\n function. */\n+(NSString*) accentName:(MTAccent*) accent;\n\n/** Creates a new boundary atom for the given delimiter name. If the delimiter name\n is not recognized it returns nil. A delimiter name can be a single character such\n as '(' or a latex command such as 'uparrow'. \n @note In order to distinguish between the delimiter '|' and the delimiter '\\|' the delimiter '\\|'\n the has been renamed to '||'.\n */\n+(nullable MTMathAtom*) boundaryAtomForDelimiterName:(NSString*) delimiterName;\n\n/** Returns the delimiter name for a boundary atom. This is a reverse of the above function.\n If the atom is not a boundary atom or if the delimiter value is unknown this returns `nil`.\n @note This is not an exact reverse of the above function. Some delimiters have two names (e.g.\n `<` and `langle`) and this function always returns the shorter name.\n */\n+ (nullable NSString*) delimiterNameForBoundaryAtom:(MTMathAtom*) boundary;\n\n/** Returns a font style associated with the name. If none is found returns NSNotFound. */\n+ (MTFontStyle) fontStyleWithName:(NSString*) fontName;\n\n/** Returns the latex font name for a given style. */\n+ (NSString*) fontNameForStyle:(MTFontStyle) fontStyle;\n\n/** Returns a fraction with the given numerator and denominator. */\n+ (MTFraction*) fractionWithNumerator:(MTMathList*) num denominator:(MTMathList*) denom;\n\n/** Simplification of above function when numerator and denominator are simple strings.\n This function uses `mathListForCharacters` to convert the strings to `MTMathList`s. */\n+ (MTFraction*) fractionWithNumeratorStr:(NSString*) numStr denominatorStr:(NSString*) denomStr;\n\n/** Builds a table for a given environment with the given rows. Returns a `MTMathAtom` containing the\n table and any other atoms necessary for the given environment. Returns nil and sets error\n if the table could not be built.\n @param env The environment to use to build the table. If the env is nil, then the default table is built.\n @note The reason this function returns a `MTMathAtom` and not a `MTMathTable` is because some\n matrix environments are have builtin delimiters added to the table and hence are returned as inner atoms.\n */\n+ (nullable MTMathAtom*) tableWithEnvironment:(nullable NSString*)env config:(nullable MTMathList*)config rows:(NSArray<NSArray<MTMathList*>*>*) rows error:(NSError**) error;\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/lib/MTMathAtomFactory.m",
    "content": "//\n//  MathAtomFactory.m\n//  iosMath\n//\n//  Created by Kostub Deshmukh on 8/28/13.\n//  Copyright (C) 2013 MathChat\n//   \n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n#import \"MTMathAtomFactory.h\"\n#import \"MTMathListBuilder.h\"\n\n\nNSString *const MTSymbolMultiplication = @\"\\u00D7\";\nNSString *const MTSymbolDivision = @\"\\u00F7\";\nNSString *const MTSymbolFractionSlash = @\"\\u2044\";\nNSString *const MTSymbolWhiteSquare = @\"\\u25A1\";\nNSString *const MTSymbolBlackSquare = @\"\\u25A0\";\nNSString *const MTSymbolLessEqual = @\"\\u2264\";\nNSString *const MTSymbolGreaterEqual = @\"\\u2265\";\nNSString *const MTSymbolNotEqual = @\"\\u2260\";\nNSString *const MTSymbolSquareRoot = @\"\\u221A\"; // \\sqrt\nNSString *const MTSymbolCubeRoot = @\"\\u221B\";\nNSString *const MTSymbolInfinity = @\"\\u221E\"; // \\infty\nNSString *const MTSymbolAngle = @\"\\u2220\"; // \\angle\nNSString *const MTSymbolDegree = @\"\\u00B0\"; // \\circ\n\n@implementation MTMathAtomFactory\n\n+ (MTMathAtom *)times\n{\n    return [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:MTSymbolMultiplication];\n}\n\n+ (MTMathAtom *)divide\n{\n    return [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:MTSymbolDivision];\n}\n\n+ (MTMathAtom *)placeholder\n{\n    return [MTMathAtom atomWithType:kMTMathAtomPlaceholder value:MTSymbolWhiteSquare];\n}\n\n+ (MTFraction *)placeholderFraction\n{\n    MTFraction *frac = [MTFraction new];\n    frac.numerator = [MTMathList new];\n    [frac.numerator addAtom:[self placeholder]];\n    frac.denominator = [MTMathList new];\n    [frac.denominator addAtom:[self placeholder]];\n    return frac;\n}\n\n+ (MTRadical*) placeholderRadical\n{\n    MTRadical* rad = [MTRadical new];\n    rad.degree = [MTMathList new];\n    rad.radicand = [MTMathList new];\n    [rad.degree addAtom:self.placeholder];\n    [rad.radicand addAtom:self.placeholder];\n    return rad;\n}\n\n+ (MTMathAtom *)placeholderSquareRoot\n{\n    MTRadical *rad = [MTRadical new];\n    rad.radicand = [MTMathList new];\n    [rad.radicand addAtom:[self placeholder]];\n    return rad;\n}\n\n+ (MTLargeOperator *)operatorWithName:(NSString *)name limits:(bool) limits\n{\n    return [[MTLargeOperator alloc] initWithValue:name limits:limits];\n}\n\n+ (nullable MTMathAtom *)atomForCharacter:(unichar)ch\n{\n    NSString *chStr = [NSString stringWithCharacters:&ch length:1];\n    if (ch > 0x0410 && ch < 0x044F){\n        // show basic cyrillic alphabet. Latin Modern Math font is not good for cyrillic symbols\n        return [MTMathAtom atomWithType:kMTMathAtomOrdinary value:chStr];\n    } else if (ch < 0x21 || ch > 0x7E) {\n        if (0x4E00 <= ch && ch <= 0x9FA5) {\n            return [MTMathAtom atomWithType:kMTMathAtomVariable value:chStr];\n        }\n        // skip non ascii characters and spaces\n        return nil;\n    } else if (ch == '$' || ch == '%' || ch == '#' || ch == '&' || ch == '~' || ch == '\\'') {\n        // These are latex control characters that have special meanings. We don't support them.\n        return nil;\n    } else if (ch == '^' || ch == '_' || ch == '{' || ch == '}' || ch == '\\\\') {\n        // more special characters for Latex.\n        return nil;\n    } else if (ch == '(' || ch == '[') {\n        return [MTMathAtom atomWithType:kMTMathAtomOpen value:chStr];\n    } else if (ch == ')' || ch == ']' || ch == '!' || ch == '?') {\n        return [MTMathAtom atomWithType:kMTMathAtomClose value:chStr];\n    } else if (ch == ',' || ch == ';') {\n        return [MTMathAtom atomWithType:kMTMathAtomPunctuation value:chStr];\n    } else if (ch == '=' || ch == '>' || ch == '<') {\n        return [MTMathAtom atomWithType:kMTMathAtomRelation value:chStr];\n    } else if (ch == ':') {\n        // Math colon is ratio. Regular colon is \\colon\n        return [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2236\"];\n    } else if (ch == '-') {\n        // Use the math minus sign\n        return [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u2212\"];\n    } else if (ch == '+' || ch == '*') {\n        return [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:chStr];\n    } else if (ch == '.' || (ch >= '0' && ch <= '9')) {\n        return [MTMathAtom atomWithType:kMTMathAtomNumber value:chStr];\n    } else if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {\n        return [MTMathAtom atomWithType:kMTMathAtomVariable value:chStr];\n    } else if (ch == '\"' || ch == '/' || ch == '@' || ch == '`' || ch == '|') {\n        // just an ordinary character. The following are allowed ordinary chars\n        // | / ` @ \"\n        return [MTMathAtom atomWithType:kMTMathAtomOrdinary value:chStr];\n    } else {\n        NSAssert(false, @\"Unknown ascii character %@. Should have been accounted for.\", @(ch));\n        return nil;\n    }\n}\n\n+ (MTMathList *)mathListForCharacters:(NSString *)chars\n{\n    NSParameterAssert(chars);\n    NSInteger len = chars.length;\n    unichar buff[len];\n    [chars getCharacters:buff range:NSMakeRange(0, len)];\n    MTMathList* list = [[MTMathList alloc] init];\n    for (NSInteger i = 0; i < len; i++) {\n        MTMathAtom* atom = [self atomForCharacter:buff[i]];\n        if (atom) {\n            [list addAtom:atom];\n        }\n    }\n    return list;\n}\n\n+ (MTMathList *)pmod:(NSString *)mod\n{\n    MTMathList *list = [MTMathList new];\n    MTMathAtom *op = [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\"];\n    [list addAtom:op];\n    MTMathAtom *leftParen = [MTMathAtom atomWithType:kMTMathAtomOpen value:@\"(\"];\n    [list addAtom:leftParen];\n    MTMathAtom *m = [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"m\"];\n    MTMathAtom *o = [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"o\"];\n    MTMathAtom *d = [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"d\"];\n    m.fontStyle = kMTFontStyleRoman;\n    o.fontStyle = kMTFontStyleRoman;\n    d.fontStyle = kMTFontStyleRoman;\n    [list addAtom:m];\n    [list addAtom:o];\n    [list addAtom:d];\n    MTMathSpace *space = [[MTMathSpace alloc] initWithSpace:3];\n    [list addAtom:space];\n    if (mod.length > 0) {\n        for (NSUInteger i = 0; i < mod.length; i++) {\n            unichar ch = [mod characterAtIndex:i];\n            MTMathAtom *atom = [MTMathAtomFactory atomForCharacter:ch];\n            if (atom) {\n                [list addAtom:atom];\n            }\n        }\n    }\n    MTMathAtom *rightParen = [MTMathAtom atomWithType:kMTMathAtomClose value:@\")\"];\n    [list addAtom:rightParen];\n    return list;\n}\n\n+ (nullable MTMathAtom *)atomForLatexSymbolName:(NSString *)symbolName\n{\n    NSParameterAssert(symbolName);\n    NSDictionary* aliases = [MTMathAtomFactory aliases];\n    // First check if this is an alias\n    NSString* canonicalName = aliases[symbolName];\n    if (canonicalName) {\n        // Switch to the canonical name\n        symbolName = canonicalName;\n    }\n    \n    NSDictionary* commands = [self supportedLatexSymbols];\n    MTMathAtom* atom = commands[symbolName];\n    if (atom) {\n        // Return a copy of the atom since atoms are mutable.\n        return [atom copy];\n    }\n    return nil;\n}\n\n+ (nullable NSString*) latexSymbolNameForAtom:(MTMathAtom*) atom\n{\n    if (atom.nucleus.length == 0) {\n        return nil;\n    }\n    NSDictionary* dict = [MTMathAtomFactory textToLatexSymbolNames];\n    return dict[atom.nucleus];\n}\n\n+ (void)addLatexSymbol:(NSString *)name value:(MTMathAtom *)atom\n{\n    NSParameterAssert(name);\n    NSParameterAssert(atom);\n    NSMutableDictionary<NSString*, MTMathAtom*>* commands = [self supportedLatexSymbols];\n    commands[name] = atom;\n    if (atom.nucleus.length != 0) {\n        NSMutableDictionary<NSString*, NSString*>* dict = [self textToLatexSymbolNames];\n        dict[atom.nucleus] = name;\n    }\n}\n\n+ (NSArray<NSString *> *)supportedLatexSymbolNames\n{\n    NSDictionary<NSString*, MTMathAtom*>* commands = [MTMathAtomFactory supportedLatexSymbols];\n    return commands.allKeys;\n}\n\n+ (nullable MTAccent*) accentWithName:(NSString*) accentName\n{\n    NSDictionary<NSString*, NSString*> *accents = [MTMathAtomFactory accents];\n    NSString* accentValue = accents[accentName];\n    if (accentValue) {\n        return [[MTAccent alloc] initWithValue:accentValue];\n    } else {\n        return nil;\n    }\n}\n\n+(NSString*) accentName:(MTAccent*) accent\n{\n    NSDictionary* dict = [MTMathAtomFactory accentValueToName];\n    return dict[accent.nucleus];\n}\n\n+ (nullable MTMathAtom *)boundaryAtomForDelimiterName:(NSString *)delimName\n{\n    NSDictionary<NSString*, NSString*>* delims = [MTMathAtomFactory delimiters];\n    NSString* delimValue = delims[delimName];\n    if (!delimValue) {\n        return nil;\n    }\n    return [MTMathAtom atomWithType:kMTMathAtomBoundary value:delimValue];\n}\n\n+ (NSString*) delimiterNameForBoundaryAtom:(MTMathAtom*) boundary\n{\n    if (boundary.type != kMTMathAtomBoundary) {\n        return nil;\n    }\n    NSDictionary* dict = [self delimValueToName];\n    return dict[boundary.nucleus];\n}\n\n+ (MTFontStyle)fontStyleWithName:(NSString *)fontName {\n    NSDictionary<NSString*, NSNumber*>* fontStyles = [self fontStyles];\n    NSNumber* style = fontStyles[fontName];\n    if (style == nil) {\n        return NSNotFound;\n    }\n    return style.integerValue;\n}\n\n+ (NSString *)fontNameForStyle:(MTFontStyle)fontStyle\n{\n    switch (fontStyle) {\n        case kMTFontStyleDefault:\n            return @\"mathnormal\";\n\n        case kMTFontStyleRoman:\n            return @\"mathrm\";\n\n        case kMTFontStyleBold:\n            return @\"mathbf\";\n\n        case kMTFontStyleFraktur:\n            return @\"mathfrak\";\n\n        case kMTFontStyleCaligraphic:\n            return @\"mathcal\";\n\n        case kMTFontStyleItalic:\n            return @\"mathit\";\n\n        case kMTFontStyleSansSerif:\n            return @\"mathsf\";\n\n        case kMTFontStyleBlackboard:\n            return @\"mathbb\";\n\n        case kMTFontStyleTypewriter:\n            return @\"mathtt\";\n\n        case kMTFontStyleBoldItalic:\n            return @\"bm\";\n    }\n}\n\n+ (MTFraction *)fractionWithNumerator:(MTMathList *)num denominator:(MTMathList *)denom\n{\n    MTFraction *frac = [[MTFraction alloc] init];\n    frac.numerator = num;\n    frac.denominator = denom;\n    return frac;\n}\n\n+ (MTFraction *)fractionWithNumeratorStr:(NSString *)numStr denominatorStr:(NSString *)denomStr\n{\n    MTMathList* num = [self mathListForCharacters:numStr];\n    MTMathList* denom = [self mathListForCharacters:denomStr];\n    return [self fractionWithNumerator:num denominator:denom];\n}\n\n+ (nullable MTMathAtom *)tableWithEnvironment:(NSString *)env config:(MTMathList *)config rows:(NSArray<NSArray<MTMathList *> *> *)rows error:(NSError * _Nullable __autoreleasing *)error\n{\n    MTMathTable* table = [[MTMathTable alloc] initWithEnvironment:env];\n    table.envConfig = config;\n    for (int i = 0; i < rows.count; i++) {\n        NSArray<MTMathList*>* row = rows[i];\n        for (int j = 0; j < row.count; j++) {\n            [table setCell:row[j] forRow:i column:j];\n        }\n    }\n    static NSDictionary<NSString*, NSArray*>* matrixEnvs = nil;\n    if (!matrixEnvs) {\n        matrixEnvs = @{ @\"matrix\" : @[],\n                        @\"smallmatrix\": @[],\n                        @\"pmatrix\" : @[ @\"(\", @\")\"],\n                        @\"bmatrix\" : @[ @\"[\", @\"]\"],\n                        @\"Bmatrix\" : @[ @\"{\", @\"}\"],\n                        @\"vmatrix\" : @[ @\"vert\", @\"vert\"],\n                        @\"Vmatrix\" : @[ @\"Vert\", @\"Vert\"], };\n    }\n    if ([matrixEnvs objectForKey:env]) {\n        // it is set to matrix as the delimiters are converted to latex outside the table.\n        table.environment = @\"matrix\";\n        table.interRowAdditionalSpacing = 0;\n        table.interColumnSpacing = 18;\n        if ([env isEqualToString:@\"smallmatrix\"]) {\n            table.interColumnSpacing = 9;\n        }\n        \n        // All the lists are in textstyle\n        MTMathAtom* style = [[MTMathStyle alloc] initWithStyle:kMTLineStyleText];\n        for (int i = 0; i < table.cells.count; i++) {\n            NSArray<MTMathList*>* row = table.cells[i];\n            for (int j = 0; j < row.count; j++) {\n                [row[j] insertAtom:style atIndex:0];\n            }\n        }\n        // Add delimiters\n        NSArray* delims = [matrixEnvs objectForKey:env];\n        if (delims.count == 2) {\n            MTInner* inner = [[MTInner alloc] init];\n            inner.leftBoundary = [self boundaryAtomForDelimiterName:delims[0]];\n            inner.rightBoundary = [self boundaryAtomForDelimiterName:delims[1]];\n            inner.innerList = [MTMathList mathListWithAtoms:table, nil];\n            return inner;\n        } else {\n            return table;\n        }\n    } else if (!env) {\n        // The default env.\n        table.interRowAdditionalSpacing = 1;\n        table.interColumnSpacing = 0;\n        NSInteger cols = table.numColumns;\n        for (int i = 0; i < cols; i++) {\n            [table setAlignment:kMTColumnAlignmentLeft forColumn:i];\n        }\n        return table;\n    } else if ([env isEqualToString:@\"eqalign\"] || [env isEqualToString:@\"split\"] || [env isEqualToString:@\"aligned\"] || [env isEqualToString:@\"align\"]) {\n        if (table.numColumns != 1 && table.numColumns != 2) {\n            NSString* message = [NSString stringWithFormat:@\"%@ environment can only have 2 columns\", env];\n            if (error != nil) {\n                *error = [NSError errorWithDomain:MTParseError code:MTParseErrorInvalidNumColumns userInfo:@{ NSLocalizedDescriptionKey : message }];\n            }\n            return nil;\n        }\n        // Add a spacer before each of the second column elements. This is to create the correct spacing for = and other releations.\n        MTMathAtom* spacer = [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\"];\n        for (int i = 0; i < table.cells.count; i++) {\n            NSArray<MTMathList*>* row = table.cells[i];\n            if (row.count > 1) {\n                [row[1] insertAtom:spacer atIndex:0];\n            }\n        }\n        table.interRowAdditionalSpacing = 1;\n        table.interColumnSpacing = 0;\n        [table setAlignment:kMTColumnAlignmentRight forColumn:0];\n        if (table.numColumns == 2) {\n            [table setAlignment:kMTColumnAlignmentLeft forColumn:1];\n        }\n        return table;\n    } else if ([env isEqualToString:@\"displaylines\"] || [env isEqualToString:@\"gather\"] || [env isEqualToString:@\"gathered\"]) {\n        if (table.numColumns != 1) {\n            NSString* message = [NSString stringWithFormat:@\"%@ environment can only have 1 column\", env];\n            if (error != nil) {\n                *error = [NSError errorWithDomain:MTParseError code:MTParseErrorInvalidNumColumns userInfo:@{ NSLocalizedDescriptionKey : message }];\n            }\n            return nil;\n        }\n        table.interRowAdditionalSpacing = 1;\n        table.interColumnSpacing = 0;\n        [table setAlignment:kMTColumnAlignmentCenter forColumn:0];\n        return table;\n    } else if ([env isEqualToString:@\"eqnarray\"]) {\n        if (table.numColumns != 3) {\n            NSString* message = @\"eqnarray environment can only have 3 columns\";\n            if (error != nil) {\n                *error = [NSError errorWithDomain:MTParseError code:MTParseErrorInvalidNumColumns userInfo:@{ NSLocalizedDescriptionKey : message }];\n            }\n            return nil;\n        }\n        table.interRowAdditionalSpacing = 1;\n        table.interColumnSpacing = 18;\n        return table;\n    }  else if ([env isEqualToString:@\"array\"]) {\n        NSUInteger numCols = table.numColumns;\n        table.interRowAdditionalSpacing = 1;\n        table.interColumnSpacing = 18;\n        for (int i = 0; i < numCols; i++) {\n            // set c as default value\n            [table setAlignment:kMTColumnAlignmentCenter forColumn:i];\n        }\n        return table;\n    } else if ([env isEqualToString:@\"cases\"]) {\n        if (table.numColumns != 1 && table.numColumns != 2) {\n            NSString* message = @\"cases environment can only have 1 or 2 columns\";\n            if (error != nil) {\n                *error = [NSError errorWithDomain:MTParseError code:MTParseErrorInvalidNumColumns userInfo:@{ NSLocalizedDescriptionKey : message }];\n            }\n            return nil;\n        }\n        table.interRowAdditionalSpacing = 0;\n        [table setAlignment:kMTColumnAlignmentLeft forColumn:0];\n        if (table.numColumns == 2) {\n            [table setAlignment:kMTColumnAlignmentLeft forColumn:1];\n        }\n        // All the lists are in textstyle\n        MTMathAtom* style = [[MTMathStyle alloc] initWithStyle:kMTLineStyleText];\n        for (int i = 0; i < table.cells.count; i++) {\n            NSArray<MTMathList*>* row = table.cells[i];\n            for (int j = 0; j < row.count; j++) {\n                [row[j] insertAtom:style atIndex:0];\n            }\n        }\n        // Add delimiters\n        MTInner* inner = [[MTInner alloc] init];\n        inner.leftBoundary = [self boundaryAtomForDelimiterName:@\"{\"];\n        inner.rightBoundary = [self boundaryAtomForDelimiterName:@\".\"];\n        MTMathAtom* space = [self atomForLatexSymbolName:@\",\"];\n        inner.innerList = [MTMathList mathListWithAtoms:space, table, nil];\n        return inner;\n    }\n    if (error) {\n        NSString* message = [NSString stringWithFormat:@\"Unknown environment: %@\", env];\n        *error = [NSError errorWithDomain:MTParseError code:MTParseErrorInvalidEnv userInfo:@{ NSLocalizedDescriptionKey : message }];\n    }\n    return nil;\n}\n\n+ (NSMutableDictionary<NSString*, MTMathAtom*>*) supportedLatexSymbols\n{\n    static NSMutableDictionary<NSString*, MTMathAtom*>* commands = nil;\n    if (!commands) {\n        commands = [NSMutableDictionary dictionaryWithDictionary:@{\n                     @\"square\" : [MTMathAtomFactory placeholder],\n                     \n                     // Greek characters\n                     @\"alpha\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03B1\"],\n                     @\"beta\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03B2\"],\n                     @\"gamma\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03B3\"],\n                     @\"delta\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03B4\"],\n                     @\"varepsilon\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03B5\"],\n                     @\"zeta\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03B6\"],\n                     @\"eta\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03B7\"],\n                     @\"theta\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03B8\"],\n                     @\"iota\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03B9\"],\n                     @\"kappa\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03BA\"],\n                     @\"lambda\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03BB\"],\n                     @\"mu\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03BC\"],\n                     @\"nu\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03BD\"],\n                     @\"xi\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03BE\"],\n                     @\"omicron\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03BF\"],\n                     @\"pi\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03C0\"],\n                     @\"rho\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03C1\"],\n                     @\"varsigma\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03C2\"],\n                     @\"sigma\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03C3\"],\n                     @\"tau\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03C4\"],\n                     @\"upsilon\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03C5\"],\n                     @\"varphi\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03C6\"],\n                     @\"chi\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03C7\"],\n                     @\"psi\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03C8\"],\n                     @\"omega\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03C9\"],\n\n                     @\"vartheta\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03D1\"],\n                     @\"phi\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03D5\"],\n                     @\"varpi\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03D6\"],\n                     @\"varkappa\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03F0\"],\n                     @\"varrho\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03F1\"],\n                     @\"epsilon\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03F5\"],\n                     \n                     // Custome greek characters\n                     @\"digamma\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03DD\"],\n                     @\"varcoppa\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03D9\"],\n                     @\"stigma\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03DB\"],\n                     @\"varbeta\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03D0\"],\n\n                     // Capital greek characters\n                     @\"Alpha\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u0391\"],\n                     @\"Beta\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u0392\"],\n                     @\"Epsilon\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u0395\"],\n                     @\"Zeta\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u0396\"],\n                     @\"Eta\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u0397\"],\n                     @\"Iota\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u0399\"],\n                     @\"Kappa\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u039A\"],\n                     @\"Mu\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u039C\"],\n                     @\"Nu\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u039D\"],\n                     @\"Omicron\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u039F\"],\n                     @\"Rho\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03A1\"],\n                     @\"Tau\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03A4\"],\n                     @\"Chi\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03A7\"],\n                     @\"Gamma\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u0393\"],\n                     @\"Delta\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u0394\"],\n                     @\"Theta\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u0398\"],\n                     @\"Lambda\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u039B\"],\n                     @\"Xi\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u039E\"],\n                     @\"Pi\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03A0\"],\n                     @\"Sigma\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03A3\"],\n                     @\"Upsilon\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03A5\"],\n                     @\"Phi\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03A6\"],\n                     @\"Psi\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03A8\"],\n                     @\"Omega\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u03A9\"],\n                     \n                     // Open\n                     @\"lceil\" : [MTMathAtom atomWithType:kMTMathAtomOpen value:@\"\\u2308\"],\n                     @\"lfloor\" : [MTMathAtom atomWithType:kMTMathAtomOpen value:@\"\\u230A\"],\n                     @\"langle\" : [MTMathAtom atomWithType:kMTMathAtomOpen value:@\"\\u27E8\"],\n                     @\"lgroup\" : [MTMathAtom atomWithType:kMTMathAtomOpen value:@\"\\u27EE\"],\n                     \n                     // Close\n                     @\"rceil\" : [MTMathAtom atomWithType:kMTMathAtomClose value:@\"\\u2309\"],\n                     @\"rfloor\" : [MTMathAtom atomWithType:kMTMathAtomClose value:@\"\\u230B\"],\n                     @\"rangle\" : [MTMathAtom atomWithType:kMTMathAtomClose value:@\"\\u27E9\"],\n                     @\"rgroup\" : [MTMathAtom atomWithType:kMTMathAtomClose value:@\"\\u27EF\"],\n                     \n                     // Arrows\n                     @\"leftarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2190\"],\n                     @\"uparrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2191\"],\n                     @\"rightarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2192\"],\n                     @\"downarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2193\"],\n                     @\"leftrightarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2194\"],\n                     @\"updownarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2195\"],\n                     @\"nwarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2196\"],\n                     @\"nearrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2197\"],\n                     @\"searrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2198\"],\n                     @\"swarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2199\"],\n                     @\"mapsto\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21A6\"],\n                     @\"Leftarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21D0\"],\n                     @\"Uparrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21D1\"],\n                     @\"Rightarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21D2\"],\n                     @\"Downarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21D3\"],\n                     @\"Leftrightarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21D4\"],\n                     @\"Updownarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21D5\"],\n                     @\"longleftarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u27F5\"],\n                     @\"longrightarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u27F6\"],\n                     @\"longleftrightarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u27F7\"],\n                     @\"Longleftarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u27F8\"],\n                     @\"Longrightarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u27F9\"],\n                     @\"Longleftrightarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u27FA\"],\n                     @\"longmapsto\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u27FC\"],\n                     @\"hookleftarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21A9\"],\n                     @\"hookrightarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21AA\"],\n                     @\"leftharpoonup\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21BC\"],\n                     @\"leftharpoondown\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21BD\"],\n                     @\"rightharpoonup\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21C0\"],\n                     @\"rightharpoondown\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21C1\"],\n                     @\"rightleftharpoons\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21CC\"],\n                     @\"leadsto\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21DD\"],\n                     @\"curvearrowleft\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21B6\"],\n                     @\"curvearrowright\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21B7\"],\n                     @\"circlearrowleft\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21BA\"],\n                     @\"circlearrowright\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21BB\"],\n                     @\"looparrowleft\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21AB\"],\n                     @\"looparrowright\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21AC\"],\n                     @\"leftleftarrows\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21C7\"],\n                     @\"rightrightarrows\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21C9\"],\n                     @\"leftrightarrows\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21C6\"],\n                     @\"rightleftarrows\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21C4\"],\n                     @\"Lleftarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21DA\"],\n                     @\"Rrightarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21DB\"],\n                     @\"twoheadleftarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u219E\"],\n                     @\"twoheadrightarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21A0\"],\n                     @\"nleftarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u219A\"],\n                     @\"nrightarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u219B\"],\n                     @\"nLeftarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21CD\"],\n                     @\"nRightarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21CF\"],\n                     @\"nleftrightarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21AE\"],\n                     @\"nLeftrightarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21CE\"],\n                     @\"dashleftarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21E0\"],\n                     @\"dashrightarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21E2\"],\n                     @\"leftarrowtail\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21A2\"],\n                     @\"rightarrowtail\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21A3\"],\n                     @\"leftrightsquigarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21AD\"],\n                     @\"rightsquigarrow\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21DD\"],\n                     @\"downharpoonleft\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21C3\"],\n                     @\"downharpoonright\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21C2\"],\n                     @\"upharpoonleft\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21BF\"],\n                     @\"upharpoonright\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21BE\"],\n                     \n                     \n                     // Relations\n                     @\"leq\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:MTSymbolLessEqual],\n                     @\"geq\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:MTSymbolGreaterEqual],\n                     @\"neq\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:MTSymbolNotEqual],\n                     @\"in\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2208\"],\n                     @\"notin\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2209\"],\n                     @\"nin\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2209\"],\n                     @\"ni\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u220B\"],\n                     @\"propto\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u221D\"],\n                     @\"mid\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2223\"],\n                     @\"parallel\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2225\"],\n                     @\"sim\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u223C\"],\n                     @\"simeq\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2243\"],\n                     @\"cong\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2245\"],\n                     @\"approx\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2248\"],\n                     @\"asymp\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u224D\"],\n                     @\"doteq\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2250\"],\n                     @\"equiv\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2261\"],\n                     @\"geqslant\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2A7E\"],\n                     @\"leqslant\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2A7D\"],\n                     @\"gg\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u226B\"],\n                     @\"ll\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u226A\"],\n                     @\"prec\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u227A\"],\n                     @\"succ\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u227B\"],\n                     @\"subset\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2282\"],\n                     @\"supset\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2283\"],\n                     @\"nsubset\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2284\"],\n                     @\"nsupset\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2285\"],\n                     @\"subseteq\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2286\"],\n                     @\"supseteq\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2287\"],\n                     @\"nsubseteq\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2288\"],\n                     @\"nsupseteq\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2289\"], // 既不是超集也不等于 (⊉)\n                     @\"subsetneq\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u228A\"], // 真正子集 (⊊)\n                     @\"supsetneq\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u228B\"], // 真正超集 (⊋)\n                     @\"sqsubset\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u228F\"], // 方形子集 (⊏)\n                     @\"sqsupset\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2290\"],\n                     @\"sqsubseteq\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2291\"],\n                     @\"sqsupseteq\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2292\"],\n                     @\"models\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u22A7\"],\n                     @\"perp\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u27C2\"],\n                     \n                     // operators\n                     @\"times\" : [MTMathAtomFactory times],\n                     @\"div\"   : [MTMathAtomFactory divide],\n                     @\"pm\"    : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u00B1\"],\n                     @\"dagger\" : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u2020\"],\n                     @\"ddagger\" : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u2021\"],\n                     @\"mp\"    : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u2213\"],\n                     @\"setminus\" : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u2216\"],\n                     @\"ast\"   : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u2217\"],\n                     @\"circ\"  : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u2218\"],\n                     @\"bullet\" : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u2219\"],\n                     @\"wedge\" : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u2227\"],\n                     @\"vee\" : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u2228\"],\n                     @\"cap\" : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u2229\"],\n                     @\"cup\" : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u222A\"],\n                     @\"wr\" : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u2240\"],\n                     @\"multisetmultiplication\" : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u228C\"], // 多重集合乘法 (⊌)\n                     @\"multisetaddition\" : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u228D\"], // 多重集合加法 (⊍)\n                     @\"uplus\" : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u228E\"],\n                     @\"sqcap\" : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u2293\"],\n                     @\"sqcup\" : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u2294\"],\n                     @\"oplus\" : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u2295\"],\n                     @\"ominus\" : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u2296\"],\n                     @\"otimes\" : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u2297\"],\n                     @\"oslash\" : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u2298\"],\n                     @\"odot\" : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u2299\"],\n                     @\"star\"  : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u22C6\"],\n                     @\"cdot\"  : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u22C5\"],\n                     @\"amalg\" : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u2A3F\"],\n                     \n                     // No limit operators\n                     @\"log\" : [MTMathAtomFactory operatorWithName:@\"log\" limits:NO],\n                     @\"lg\" : [MTMathAtomFactory operatorWithName:@\"lg\" limits:NO],\n                     @\"ln\" : [MTMathAtomFactory operatorWithName:@\"ln\" limits:NO],\n                     @\"sin\" : [MTMathAtomFactory operatorWithName:@\"sin\" limits:NO],\n                     @\"arcsin\" : [MTMathAtomFactory operatorWithName:@\"arcsin\" limits:NO],\n                     @\"sinh\" : [MTMathAtomFactory operatorWithName:@\"sinh\" limits:NO],\n                     @\"cos\" : [MTMathAtomFactory operatorWithName:@\"cos\" limits:NO],\n                     @\"arccos\" : [MTMathAtomFactory operatorWithName:@\"arccos\" limits:NO],\n                     @\"cosh\" : [MTMathAtomFactory operatorWithName:@\"cosh\" limits:NO],\n                     @\"tan\" : [MTMathAtomFactory operatorWithName:@\"tan\" limits:NO],\n                     @\"arctan\" : [MTMathAtomFactory operatorWithName:@\"arctan\" limits:NO],\n                     @\"tanh\" : [MTMathAtomFactory operatorWithName:@\"tanh\" limits:NO],\n                     @\"cot\" : [MTMathAtomFactory operatorWithName:@\"cot\" limits:NO],\n                     @\"coth\" : [MTMathAtomFactory operatorWithName:@\"coth\" limits:NO],\n                     @\"sec\" : [MTMathAtomFactory operatorWithName:@\"sec\" limits:NO],\n                     @\"csc\" : [MTMathAtomFactory operatorWithName:@\"csc\" limits:NO],\n                     @\"arg\" : [MTMathAtomFactory operatorWithName:@\"arg\" limits:NO],\n                     @\"ker\" : [MTMathAtomFactory operatorWithName:@\"ker\" limits:NO],\n                     @\"dim\" : [MTMathAtomFactory operatorWithName:@\"dim\" limits:NO],\n                     @\"hom\" : [MTMathAtomFactory operatorWithName:@\"hom\" limits:NO],\n                     @\"exp\" : [MTMathAtomFactory operatorWithName:@\"exp\" limits:NO],\n                     @\"deg\" : [MTMathAtomFactory operatorWithName:@\"deg\" limits:NO],\n                     @\"mod\" : [MTMathAtomFactory operatorWithName:@\"mod\" limits:NO],\n                     @\"bmod\" : [MTMathAtomFactory operatorWithName:@\"mod\" limits:NO],\n                     \n                     // Limit operators\n                     @\"lim\" : [MTMathAtomFactory operatorWithName:@\"lim\" limits:YES],\n                     @\"limsup\" : [MTMathAtomFactory operatorWithName:@\"lim sup\" limits:YES],\n                     @\"liminf\" : [MTMathAtomFactory operatorWithName:@\"lim inf\" limits:YES],\n                     @\"max\" : [MTMathAtomFactory operatorWithName:@\"max\" limits:YES],\n                     @\"min\" : [MTMathAtomFactory operatorWithName:@\"min\" limits:YES],\n                     @\"sup\" : [MTMathAtomFactory operatorWithName:@\"sup\" limits:YES],\n                     @\"inf\" : [MTMathAtomFactory operatorWithName:@\"inf\" limits:YES],\n                     @\"det\" : [MTMathAtomFactory operatorWithName:@\"det\" limits:YES],\n                     @\"Pr\" : [MTMathAtomFactory operatorWithName:@\"Pr\" limits:YES],\n                     @\"gcd\" : [MTMathAtomFactory operatorWithName:@\"gcd\" limits:YES],\n                     \n                     // Large operators\n                     @\"prod\" : [MTMathAtomFactory operatorWithName:@\"\\u220F\" limits:YES],\n                     @\"coprod\" : [MTMathAtomFactory operatorWithName:@\"\\u2210\" limits:YES],\n                     @\"sum\" : [MTMathAtomFactory operatorWithName:@\"\\u2211\" limits:YES],\n                     @\"int\" : [MTMathAtomFactory operatorWithName:@\"\\u222B\" limits:NO],\n                     @\"iint\" : [MTMathAtomFactory operatorWithName:@\"\\u222C\" limits:NO],            // 双重积分\n                     @\"iiint\" : [MTMathAtomFactory operatorWithName:@\"\\u222D\" limits:NO],           // 三重积分\n                     @\"oint\" : [MTMathAtomFactory operatorWithName:@\"\\u222E\" limits:NO],\n                     @\"oiint\" : [MTMathAtomFactory operatorWithName:@\"\\u222F\" limits:NO],\n                     @\"oiiint\" : [MTMathAtomFactory operatorWithName:@\"\\u2230\" limits:NO],\n                     @\"bigwedge\" : [MTMathAtomFactory operatorWithName:@\"\\u22C0\" limits:YES],\n                     @\"bigvee\" : [MTMathAtomFactory operatorWithName:@\"\\u22C1\" limits:YES],\n                     @\"bigcap\" : [MTMathAtomFactory operatorWithName:@\"\\u22C2\" limits:YES],\n                     @\"bigcup\" : [MTMathAtomFactory operatorWithName:@\"\\u22C3\" limits:YES],\n                     @\"bigodot\" : [MTMathAtomFactory operatorWithName:@\"\\u2A00\" limits:YES],\n                     @\"bigoplus\" : [MTMathAtomFactory operatorWithName:@\"\\u2A01\" limits:YES],\n                     @\"bigotimes\" : [MTMathAtomFactory operatorWithName:@\"\\u2A02\" limits:YES],\n                     @\"biguplus\" : [MTMathAtomFactory operatorWithName:@\"\\u2A04\" limits:YES],\n                     @\"bigsqcup\" : [MTMathAtomFactory operatorWithName:@\"\\u2A06\" limits:YES],\n                     \n                     // Latex command characters\n                     @\"{\" : [MTMathAtom atomWithType:kMTMathAtomOpen value:@\"{\"],\n                     @\"}\" : [MTMathAtom atomWithType:kMTMathAtomClose value:@\"}\"],\n                     @\"$\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"$\"],\n                     @\"&\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"&\"],\n                     @\"#\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"#\"],\n                     @\"%\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"%\"],\n                     @\"_\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"_\"],\n                     @\" \" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\" \"],\n                     @\"backslash\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\\\\"],\n                     \n                     // Punctuation\n                     // Note: \\colon is different from : which is a relation\n                     @\"colon\" : [MTMathAtom atomWithType:kMTMathAtomPunctuation value:@\":\"],\n                     @\"cdotp\" : [MTMathAtom atomWithType:kMTMathAtomPunctuation value:@\"\\u00B7\"],\n                     \n                     // Other symbols\n                     @\"degree\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u00B0\"],\n                     @\"neg\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u00AC\"],\n                     @\"angstrom\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u00C5\"],\n                     @\"eth\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u00F0\"],\n                     @\"|\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u2016\"],\n                     @\"vert\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"|\"],\n                     @\"ldots\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u2026\"],\n                     @\"prime\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u2032\"],\n                     @\"hbar\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u210F\"],\n                     @\"Im\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u2111\"],\n                     @\"ell\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u2113\"],\n                     @\"wp\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u2118\"],\n                     @\"Re\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u211C\"],\n                     @\"mho\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u2127\"],\n                     @\"hslash\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u210F\"],\n                     @\"aleph\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u2135\"],\n                     @\"forall\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u2200\"],\n                     @\"exists\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u2203\"],\n                     @\"emptyset\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u2205\"],\n                     @\"nabla\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u2207\"],\n                     @\"infty\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u221E\"],\n                     @\"angle\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u2220\"],\n                     @\"top\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u22A4\"],\n                     @\"bot\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u22A5\"],\n                     @\"vdots\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u22EE\"],\n                     @\"cdots\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u22EF\"],\n                     @\"dots\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u22EF\"],\n                     @\"ddots\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u22F1\"],\n                     @\"triangle\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u25B3\"],\n                     @\"imath\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\U0001D6A4\"],\n                     @\"jmath\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\U0001D6A5\"],\n                     @\"partial\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\U0001D715\"],\n                     @\"nmid\": [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u2224\"],\n                     @\"triangleq\": [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u225C\"],\n                     @\"hslash\": [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u210f\"],\n                     @\"eth\": [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u00f0\"],\n                     @\"vDash\": [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u22a8\"],\n                     @\"geqslant\": [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u2265\"],\n                     @\"leqslant\": [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u2264\"],\n                     \n                     // Spacing\n                     @\",\" : [[MTMathSpace alloc] initWithSpace:3],\n                     @\">\" : [[MTMathSpace alloc] initWithSpace:4],\n                     @\";\" : [[MTMathSpace alloc] initWithSpace:5],\n                     @\"!\" : [[MTMathSpace alloc] initWithSpace:-3],\n                     @\"quad\" : [[MTMathSpace alloc] initWithSpace:18],  // quad = 1em = 18mu\n                     @\"qquad\" : [[MTMathSpace alloc] initWithSpace:36], // qquad = 2em\n                     \n                     // Style\n                     @\"displaystyle\" : [[MTMathStyle alloc] initWithStyle:kMTLineStyleDisplay],\n                     @\"textstyle\" : [[MTMathStyle alloc] initWithStyle:kMTLineStyleText],\n                     @\"scriptstyle\" : [[MTMathStyle alloc] initWithStyle:kMTLineStyleScript],\n                     @\"scriptscriptstyle\" : [[MTMathStyle alloc] initWithStyle:kMTLineStyleScriptScript],\n                     @\"big\" : [[MTMathStyle alloc] initWithStyle:kMTLineStylebig],\n                     @\"Big\" : [[MTMathStyle alloc] initWithStyle:kMTLineStyleBig],\n                     @\"bigg\" : [[MTMathStyle alloc] initWithStyle:kMTLineStylebigg],\n                     @\"Bigg\" : [[MTMathStyle alloc] initWithStyle:kMTLineStyleBigg],\n                     \n                     // custome\n                     @\"because\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2235\"],\n                     @\"therefore\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2234\"],\n                     @\"land\" : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u2227\"],\n                     @\"iff\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u21D4\"],\n                     @\"lor\" : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u2228\"],\n                     @\"nexists\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u2204\"],\n                     @\"vdash\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u22A2\"],\n                     @\"vDash\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u22A8\"],\n                     @\"dashv\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u22A3\"],\n                     @\"varnothing\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u2205\"],\n                     @\"smallsetminus\" : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u2216\"],\n                     @\"triangleleft\" : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u25C3\"],\n                     @\"triangleright\" : [MTMathAtom atomWithType:kMTMathAtomBinaryOperator value:@\"\\u25B9\"],\n                     @\"surd\" : [MTMathAtom atomWithType:kMTMathAtomLargeOperator value:@\"\\u221A\"],\n                     @\"flat\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u266D\"],\n                     @\"natural\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u266E\"],\n                     @\"sharp\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u266F\"],\n                     @\"Box\" : [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u25A1\"],\n                     @\"clubsuit\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u2663\"],\n                     @\"diamondsuit\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u2662\"],\n                     @\"heartsuit\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u2661\"],\n                     @\"spadesuit\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u2660\"],\n                     @\"measuredangle\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u2221\"],\n                     @\"lozenge\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u25CA\"],\n                     @\"circledS\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u24C8\"],\n                     @\"bigstar\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u2605\"],\n                     @\"blacksquare\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u25A0\"],\n                     @\"blacktriangle\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u25B2\"],\n                     @\"blacktriangledown\" : [MTMathAtom atomWithType:kMTMathAtomVariable value:@\"\\u25BC\"],\n                     @\"preceq\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2AAF\"],\n                     @\"succeq\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2AB0\"],\n                     @\"bowtie\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u22C8\"],\n                     @\"Join\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u22C9\"],\n                     @\"smile\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2323\"],\n                     @\"frown\" : [MTMathAtom atomWithType:kMTMathAtomRelation value:@\"\\u2322\"],\n                     }];\n        \n    }\n    return commands;\n}\n\n+ (NSDictionary*) aliases\n{\n    static NSDictionary* aliases = nil;\n    if (!aliases) {\n        aliases = @{\n                    @\"lnot\" : @\"neg\",\n                    @\"land\" : @\"wedge\",\n                    @\"lor\" : @\"vee\",\n                    @\"ne\" : @\"neq\",\n                    @\"le\" : @\"leq\",\n                    @\"ge\" : @\"geq\",\n                    @\"lbrace\" : @\"{\",\n                    @\"rbrace\" : @\"}\",\n                    @\"Vert\" : @\"|\",\n                    @\"gets\" : @\"leftarrow\",\n                    @\"to\" : @\"rightarrow\",\n                    @\"iff\" : @\"Longleftrightarrow\",\n                    @\"AA\" : @\"angstrom\",\n                    };\n    }\n    return aliases;\n}\n\n+ (NSMutableDictionary<NSString*, NSString*>*) textToLatexSymbolNames\n{\n    static NSMutableDictionary<NSString*, NSString*>* textToCommands = nil;\n    if (!textToCommands) {\n        NSDictionary* commands = [self supportedLatexSymbols];\n        textToCommands = [NSMutableDictionary dictionaryWithCapacity:commands.count];\n        for (NSString* command in commands) {\n            MTMathAtom* atom = commands[command];\n            if (atom.nucleus.length == 0) {\n                continue;\n            }\n            \n            NSString* existingCommand = textToCommands[atom.nucleus];\n            if (existingCommand) {\n                // If there are 2 commands for the same symbol, choose one deterministically.\n                if (command.length > existingCommand.length) {\n                    // Keep the shorter command\n                    continue;\n                } else if (command.length == existingCommand.length) {\n                    // If the length is the same, keep the alphabetically first\n                    if ([command compare:existingCommand] == NSOrderedDescending) {\n                        continue;\n                    }\n                }\n            }\n            // In other cases replace the command.\n            textToCommands[atom.nucleus] = command;\n        }\n    }\n    return textToCommands;\n}\n\n+ (NSDictionary<NSString*, NSString*>*) accents\n{\n    static NSDictionary* accents = nil;\n    if (!accents) {\n        accents = @{\n                    @\"grave\" : @\"\\u0300\",\n                    @\"acute\" : @\"\\u0301\",\n                    @\"hat\" : @\"\\u0302\",  // In our implementation hat and widehat behave the same.\n                    @\"tilde\" : @\"\\u0303\", // In our implementation tilde and widetilde behave the same.\n                    @\"bar\" : @\"\\u0304\",\n                    @\"breve\" : @\"\\u0306\",\n                    @\"dot\" : @\"\\u0307\",\n                    @\"ddot\" : @\"\\u0308\",\n                    @\"check\" : @\"\\u030C\",\n                    @\"vec\" : @\"\\u20D7\",\n                    @\"widehat\" : @\"\\u0302\",\n                    @\"widetilde\" : @\"\\u0303\",\n                    };\n    }\n    return accents;\n}\n\n+ (NSDictionary*) accentValueToName\n{\n    static NSDictionary* accentToCommands = nil;\n    if (!accentToCommands) {\n        NSDictionary* accents = [self accents];\n        NSMutableDictionary* mutableDict = [NSMutableDictionary dictionaryWithCapacity:accents.count];\n        for (NSString* command in accents) {\n            NSString* acc = accents[command];\n            NSString* existingCommand = mutableDict[acc];\n            if (existingCommand) {\n                if (command.length > existingCommand.length) {\n                    // Keep the shorter command\n                    continue;\n                } else if (command.length == existingCommand.length) {\n                    // If the length is the same, keep the alphabetically first\n                    if ([command compare:existingCommand] == NSOrderedDescending) {\n                        continue;\n                    }\n                }\n            }\n            // In other cases replace the command.\n            mutableDict[acc] = command;\n        }\n        accentToCommands = [mutableDict copy];\n    }\n    return accentToCommands;\n}\n\n+(NSDictionary<NSString*, NSString*> *) delimiters\n{\n    static NSDictionary* delims = nil;\n    if (!delims) {\n        delims = @{\n                   @\".\" : @\"\", // . means no delimiter\n                   @\"(\" : @\"(\",\n                   @\")\" : @\")\",\n                   @\"[\" : @\"[\",\n                   @\"]\" : @\"]\",\n                   @\"<\" : @\"\\u2329\",\n                   @\">\" : @\"\\u232A\",\n                   @\"/\" : @\"/\",\n                   @\"\\\\\" : @\"\\\\\",\n                   @\"|\" : @\"|\",\n                   @\"lgroup\" : @\"\\u27EE\",\n                   @\"rgroup\" : @\"\\u27EF\",\n                   @\"||\" : @\"\\u2016\",\n                   @\"Vert\" : @\"\\u2016\",\n                   @\"vert\" : @\"|\",\n                   @\"uparrow\" : @\"\\u2191\",\n                   @\"downarrow\" : @\"\\u2193\",\n                   @\"updownarrow\" : @\"\\u2195\",\n                   @\"Uparrow\" : @\"21D1\",\n                   @\"Downarrow\" : @\"21D3\",\n                   @\"Updownarrow\" : @\"21D5\",\n                   @\"backslash\" : @\"\\\\\",\n                   @\"rangle\" : @\"\\u232A\",\n                   @\"langle\" : @\"\\u2329\",\n                   @\"rbrace\" : @\"}\",\n                   @\"}\" : @\"}\",\n                   @\"{\" : @\"{\",\n                   @\"lbrace\" : @\"{\",\n                   @\"lceil\" : @\"\\u2308\",\n                   @\"rceil\" : @\"\\u2309\",\n                   @\"lfloor\" : @\"\\u230A\",\n                   @\"rfloor\" : @\"\\u230B\",\n                   };\n    }\n    return delims;\n}\n\n+ (NSDictionary*) delimValueToName\n{\n    static NSDictionary* delimToCommands = nil;\n    if (!delimToCommands) {\n        NSDictionary* delims = [self delimiters];\n        NSMutableDictionary* mutableDict = [NSMutableDictionary dictionaryWithCapacity:delims.count];\n        for (NSString* command in delims) {\n            NSString* delim = delims[command];\n            NSString* existingCommand = mutableDict[delim];\n            if (existingCommand) {\n                if (command.length > existingCommand.length) {\n                    // Keep the shorter command\n                    continue;\n                } else if (command.length == existingCommand.length) {\n                    // If the length is the same, keep the alphabetically first\n                    if ([command compare:existingCommand] == NSOrderedDescending) {\n                        continue;\n                    }\n                }\n            }\n            // In other cases replace the command.\n            mutableDict[delim] = command;\n        }\n        delimToCommands = [mutableDict copy];\n    }\n    return delimToCommands;\n}\n\n\n+(NSDictionary<NSString*, NSNumber*> *) fontStyles\n{\n    static NSDictionary<NSString*, NSNumber*>* fontStyles = nil;\n    if (!fontStyles) {\n        fontStyles = @{\n                       @\"mathnormal\" : @(kMTFontStyleDefault),\n                       @\"mathrm\": @(kMTFontStyleRoman),\n                       @\"textrm\": @(kMTFontStyleRoman),\n                       @\"rm\": @(kMTFontStyleRoman),\n                       @\"mathbf\": @(kMTFontStyleBold),\n                       // 粗体\n                       @\"bf\": @(kMTFontStyleBold),\n                       // 等线体\n                       @\"sf\": @(kMTFontStyleSansSerif),\n                       // 打印机字体\n                       @\"tt\": @(kMTFontStyleTypewriter),\n                       // 黑板字体\n                       @\"Bbb\": @(kMTFontStyleBlackboard),\n                       @\"it\": @(kMTFontStyleItalic),\n                       @\"textbf\": @(kMTFontStyleBold),\n                       @\"mathcal\": @(kMTFontStyleCaligraphic),\n                       @\"cal\": @(kMTFontStyleCaligraphic),\n                       @\"mathtt\": @(kMTFontStyleTypewriter),\n                       @\"texttt\": @(kMTFontStyleTypewriter),\n                       @\"mathit\": @(kMTFontStyleItalic),\n                       @\"textit\": @(kMTFontStyleItalic),\n                       @\"mit\": @(kMTFontStyleItalic),\n                       @\"mathsf\": @(kMTFontStyleSansSerif),\n                       @\"textsf\": @(kMTFontStyleSansSerif),\n                       @\"mathfrak\": @(kMTFontStyleFraktur),\n                       @\"frak\": @(kMTFontStyleFraktur),\n                       @\"mathbb\": @(kMTFontStyleBlackboard),\n                       @\"mathbfit\": @(kMTFontStyleBoldItalic),\n                       @\"bm\": @(kMTFontStyleBoldItalic),\n                       @\"text\": @(kMTFontStyleRoman),\n                   };\n    }\n    return fontStyles;\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/lib/MTMathList.h",
    "content": "//\n//  MathList.h\n//  iosMath\n//\n//  Created by Kostub Deshmukh on 8/26/13.\n//  Copyright (C) 2013 MathChat\n//   \n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n@import Foundation;\n@import CoreGraphics;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n @typedef MTLineStyle\n @brief Styling of a line of math\n */\ntypedef NS_ENUM(unsigned int, MTLineStyle)  {\n    /// Display style\n    kMTLineStyleDisplay,\n    /// Text style (inline)\n    kMTLineStyleText,\n    /// Script style (for sub/super scripts)\n    kMTLineStyleScript,\n    /// Script script style (for scripts of scripts)\n    kMTLineStyleScriptScript,\n    \n    /// Script script style (for scripts of scripts)\n    kMTLineStylebig,\n    /// Script script style (for scripts of scripts)\n    kMTLineStyleBig,\n    /// Script script style (for scripts of scripts)\n    kMTLineStylebigg,\n    /// Script script style (for scripts of scripts)\n    kMTLineStyleBigg\n};\n\ntypedef NS_ENUM(NSUInteger, MTSizeType)\n{\n    MTSizeTypeDefault = 0,\n    MTSizeTypebig,\n    MTSizeTypeBig,\n    MTSizeTypebigg,\n    MTSizeTypeBigg,\n    MTSizeTypeSmall,\n    MTSizeTypelarge,\n    MTSizeTypeLarge,\n    MTSizeTypeLARGE\n};\n\n@class MTMathList;\n\n/**\n @typedef MTMathAtomType\n @brief The type of atom in a `MTMathList`.\n \n The type of the atom determines how it is rendered, and spacing between the atoms.\n */\ntypedef NS_ENUM(NSUInteger, MTMathAtomType)\n{\n    /// A number or text in ordinary format - Ord in TeX\n    kMTMathAtomOrdinary = 1,\n    /// A number - Does not exist in TeX\n    kMTMathAtomNumber,\n    /// A variable (i.e. text in italic format) - Does not exist in TeX\n    kMTMathAtomVariable,\n    /// A large operator such as (sin/cos, integral etc.) - Op in TeX\n    kMTMathAtomLargeOperator,\n    /// A binary operator - Bin in TeX\n    kMTMathAtomBinaryOperator,\n    /// A unary operator - Does not exist in TeX.\n    kMTMathAtomUnaryOperator,\n    /// A relation, e.g. = > < etc. - Rel in TeX\n    kMTMathAtomRelation,\n    /// Open brackets - Open in TeX\n    kMTMathAtomOpen,\n    /// Close brackets - Close in TeX\n    kMTMathAtomClose,\n    /// An fraction e.g 1/2 - generalized fraction noad in TeX\n    kMTMathAtomFraction,\n    /// A radical operator e.g. sqrt(2)\n    kMTMathAtomRadical,\n    /// Punctuation such as , - Punct in TeX\n    kMTMathAtomPunctuation,\n    /// A placeholder square for future input. Does not exist in TeX\n    kMTMathAtomPlaceholder,\n    /// An inner atom, i.e. an embedded math list - Inner in TeX\n    kMTMathAtomInner,\n    /// An Adaptive atom\n    kMTMathAtomAdaptive,\n    /// An underlined atom - Under in TeX\n    kMTMathAtomUnderline,\n    /// An overlined atom - Over in TeX\n    kMTMathAtomOverline,\n    /// An hlined atom - hline in Tex\n    kMTMathAtomHline,\n    kMTMathAtomOverbrace,\n    kMTmathAtomUnderbrace,\n    /// An accented atom - Accent in TeX\n    kMTMathAtomAccent,\n    \n    // Atoms after this point do not support subscripts or superscripts\n    \n    /// A left atom - Left & Right in TeX. We don't need two since we track boundaries separately.\n    kMTMathAtomBoundary = 101,\n    \n    // Atoms after this are non-math TeX nodes that are still useful in math mode. They do not have\n    // the usual structure.\n    \n    /// Spacing between math atoms. This denotes both glue and kern for TeX. We do not\n    /// distinguish between glue and kern.\n    kMTMathAtomSpace = 201,\n    /// Denotes style changes during rendering.\n    kMTMathAtomStyle,\n    kMTMathAtomColor,\n    kMTMathAtomColorbox,\n    kMTMathAtomBoxed,\n    KMTMathAtomTag, \n    \n    // Atoms after this point are not part of TeX and do not have the usual structure.\n    \n    /// An table atom. This atom does not exist in TeX. It is equivalent to the TeX command\n    /// halign which is handled outside of the TeX math rendering engine. We bring it into our\n    /// math typesetting to handle matrices and other tables.\n    kMTMathAtomTable = 1001,\n};\n\n/**\n @typedef MTFontStyle\n @brief The font style of a character.\n\n The fontstyle of the atom determines what style the character is rendered in. This only applies to atoms\n of type kMTMathAtomVariable and kMTMathAtomNumber. None of the other atom types change their font style.\n */\ntypedef NS_ENUM(NSUInteger, MTFontStyle)\n{\n    /// The default latex rendering style. i.e. variables are italic and numbers are roman.\n    kMTFontStyleDefault = 0,\n    /// Roman font style i.e. \\mathrm\n    kMTFontStyleRoman,\n    /// Bold font style i.e. \\mathbf\n    kMTFontStyleBold,\n    /// Caligraphic font style i.e. \\mathcal\n    kMTFontStyleCaligraphic,\n    /// Typewriter (monospace) style i.e. \\mathtt\n    kMTFontStyleTypewriter,\n    /// Italic style i.e. \\mathit\n    kMTFontStyleItalic,\n    /// San-serif font i.e. \\mathss\n    kMTFontStyleSansSerif,\n    /// Fractur font i.e \\mathfrak\n    kMTFontStyleFraktur,\n    /// Blackboard font i.e. \\mathbb\n    kMTFontStyleBlackboard,\n    /// Bold italic\n    kMTFontStyleBoldItalic,\n};\n\n/** A `MTMathAtom` is the basic unit of a math list. Each atom represents a single character\n or mathematical operator in a list. However certain atoms can represent more complex structures\n such as fractions and radicals. Each atom has a type which determines how the atom is rendered and\n a nucleus. The nucleus contains the character(s) that need to be rendered. However the nucleus may\n be empty for certain types of atoms. An atom has an optional subscript or superscript which represents\n the subscript or superscript that is to be rendered.\n \n Certain types of atoms inherit from `MTMathAtom` and may have additional fields.\n */\n@interface MTMathAtom : NSObject<NSCopying>\n\n/// Do not use init. Use `atomWithType:value:` to instantiate atoms.\n- (instancetype)init NS_UNAVAILABLE;\n\n/** Factory function to create an atom with a given type and value.\n @param type The type of the atom to instantiate.\n @param value The value of the atoms nucleus. The value is ignored for fractions and radicals.\n */\n+ (instancetype) atomWithType: (MTMathAtomType) type value:(NSString*) value;\n\n/** Returns a string representation of the MTMathAtom */\n@property (nonatomic, readonly) NSString *stringValue;\n\n/** The type of the atom. */\n@property (nonatomic) MTMathAtomType type;\n/** The nucleus of the atom. */\n@property (nonatomic, copy) NSString* nucleus;\n/** An optional superscript. */\n@property (nonatomic, nullable) MTMathList* superScript;\n/** An optional subscript. */\n@property (nonatomic, nullable) MTMathList* subScript;\n/** The font style to be used for the atom. */\n@property (nonatomic) MTFontStyle fontStyle;\n\n@property (nonatomic, assign) MTSizeType sizeType;\n\n- (void)updateSizeTypeWithStyle:(MTLineStyle)style;\n\n/** Returns true if this atom allows scripts (sub or super). */\n- (bool) scriptsAllowed;\n\n/// If this atom was formed by fusion of multiple atoms, then this stores the list of atoms that were fused to create this one.\n/// This is used in the finalizing and preprocessing steps.\n@property (nonatomic, readonly, nullable) NSArray<MTMathAtom*>* fusedAtoms;\n\n/// The index range in the MTMathList this MTMathAtom tracks. This is used by the finalizing and preprocessing steps\n/// which fuse MTMathAtoms to track the position of the current MTMathAtom in the original list.\n@property (nonatomic, readonly) NSRange indexRange;\n\n/// Fuse the given atom with this one by combining their nucleii.\n- (void) fuse:(MTMathAtom*) atom;\n\n/// Makes a deep copy of the atom\n- (id)copyWithZone:(nullable NSZone *)zone;\n\n/// Returns a finalized copy of the atom\n- (instancetype) finalized;\n\n@end\n\n/** An atom of type fraction. This atom has a numerator and denominator. */\n@interface MTFraction : MTMathAtom\n\n/// Creates an empty fraction with a rule.\n- (instancetype)init;\n\n/// Creates an empty fraction with the given value of hasRule.\n- (instancetype)initWithRule:(BOOL) hasRule NS_DESIGNATED_INITIALIZER;\n\n/// Numerator of the fraction\n@property (nonatomic) MTMathList* numerator;\n/// Denominator of the fraction\n@property (nonatomic) MTMathList* denominator;\n\n@property (nonatomic) BOOL isCfrac;\n\n/**If true, the fraction has a rule (i.e. a line) between the numerator and denominator.\n The default value is true. */\n@property (nonatomic, readonly) BOOL hasRule;\n\n/** An optional delimiter for a fraction on the left. */\n@property (nonatomic, nullable) NSString* leftDelimiter;\n/** An optional delimiter for a fraction on the right. */\n@property (nonatomic, nullable) NSString* rightDelimiter;\n\n@end\n\n/** An atom of type radical (square root). */\n@interface MTRadical : MTMathAtom\n\n/// Creates an empty radical\n- (instancetype)init NS_DESIGNATED_INITIALIZER;\n\n/// Denotes the term under the square root sign\n@property (nonatomic, nullable) MTMathList* radicand;\n\n/// Denotes the degree of the radical, i.e. the value to the top left of the radical sign\n/// This can be null if there is no degree.\n@property (nonatomic, nullable) MTMathList* degree;\n\n@end\n\n/** A `MTMathAtom` of type `kMTMathAtomLargeOperator`. */\n@interface MTLargeOperator : MTMathAtom\n\n/** Designated initializer. Initialize a large operator with the given\n value and setting for limits.\n */\n- (instancetype) initWithValue:(NSString*) value limits:(BOOL) limits NS_DESIGNATED_INITIALIZER;\n\n/** Indicates whether the limits (if present) should be displayed\n above and below the operator in display mode.  If limits is false\n then the limits (if present) and displayed like a regular subscript/superscript.\n */\n@property (nonatomic) BOOL limits;\n\n@end\n\n/** An inner atom. This denotes an atom which contains a math list inside it. An inner atom\n has optional boundaries. Note: Only one boundary may be present, it is not required to have\n both. */\n@interface MTInner : MTMathAtom\n\n/// Creates an empty inner\n- (instancetype)init NS_DESIGNATED_INITIALIZER;\n\n/// The inner math list\n@property (nonatomic, nullable) MTMathList* innerList;\n/// The left boundary atom. This must be a node of type kMTMathAtomBoundary\n@property (nonatomic, nullable) MTMathAtom* leftBoundary;\n/// The right boundary atom. This must be a node of type kMTMathAtomBoundary\n@property (nonatomic, nullable) MTMathAtom* rightBoundary;\n\n@end\n\n/**\n 数学公式中的自适应元素，比如「\\middle|」：表示自适应高度的｜\n */\n@interface MTAdaptive : MTMathAtom\n\n/// Creates an empty inner\n- (instancetype)init NS_DESIGNATED_INITIALIZER;\n\n/// The boundary atom. This must be a node of type kMTMathAtomBoundary\n@property (nonatomic, nullable) MTMathAtom* boundary;\n/// 每个adaptive的id\n@property (nonatomic, nullable) NSString *adaptiveID;\n\n@end\n\n/** An atom with a line over the contained math list. */\n@interface MTOverLine : MTMathAtom\n\n/// Creates an empty over\n- (instancetype)init NS_DESIGNATED_INITIALIZER;\n\n/// The inner math list\n@property (nonatomic, nullable) MTMathList* innerList;\n\n@property (nonatomic, assign) BOOL useArrow;\n\n@end\n\n/** An atom with a line under the contained math list. */\n@interface MTUnderLine : MTMathAtom\n\n/// Creates an empty under\n- (instancetype)init NS_DESIGNATED_INITIALIZER;\n\n/// The inner math list\n@property (nonatomic, nullable) MTMathList* innerList;\n\n@end\n\n@interface MTHLine : MTMathAtom\n\n/// Creates an empty under\n- (instancetype)init NS_DESIGNATED_INITIALIZER;\n\n@end\n\n@interface MTOverbrace : MTMathAtom\n\n/// Creates an empty under\n- (instancetype)init NS_DESIGNATED_INITIALIZER;\n\n/// 内容\n@property (nonatomic, nullable) MTMathList *contentor;\n/// 标签\n@property (nonatomic, nullable) MTMathList *labelor;\n\n@end\n\n@interface MTUnderbrace : MTMathAtom\n\n/// Creates an empty under\n- (instancetype)init NS_DESIGNATED_INITIALIZER;\n\n/// 内容\n@property (nonatomic, nullable) MTMathList *contentor;\n/// 标签\n@property (nonatomic, nullable) MTMathList *labelor;\n\n@end\n\n/** An atom with an accent. */\n@interface MTAccent : MTMathAtom\n\n/** Creates a new `MTAccent` with the given value as the accent.\n */\n- (instancetype)initWithValue:(NSString*) value NS_DESIGNATED_INITIALIZER;\n\n/// The mathlist under the accent.\n@property (nonatomic, nullable) MTMathList* innerList;\n\n@end\n\n/** An atom representing space.\n @note None of the usual fields of the `MTMathAtom` apply even though this\n class inherits from `MTMathAtom`. i.e. it is meaningless to have a value\n in the nucleus, subscript or superscript fields. */\n@interface MTMathSpace : MTMathAtom\n\n/** Creates a new `MTMathSpace` with the given spacing.\n @param space The amount of space in mu units.\n */\n- (instancetype) initWithSpace:(CGFloat) space NS_DESIGNATED_INITIALIZER;\n\n/** The amount of space represented by this object in mu units. */\n@property (nonatomic, readonly) CGFloat space;\n\n@end\n\n/** An atom representing a style change.\n @note None of the usual fields of the `MTMathAtom` apply even though this\n class inherits from `MTMathAtom`. i.e. it is meaningless to have a value\n in the nucleus, subscript or superscript fields. */\n@interface MTMathStyle : MTMathAtom\n\n/** Creates a new `MTMathStyle` with the given style.\n @param style The style to be applied to the rest of the list.\n */\n- (instancetype) initWithStyle:(MTLineStyle) style NS_DESIGNATED_INITIALIZER;\n\n/** The style represented by this object. */\n@property (nonatomic, readonly) MTLineStyle style;\n\n@end\n\n/** An atom representing an color element.\n @note None of the usual fields of the `MTMathAtom` apply even though this\n class inherits from `MTMathAtom`. i.e. it is meaningless to have a value\n in the nucleus, subscript or superscript fields. */\n@interface MTMathColor : MTMathAtom\n\n/// Creates an empty color with a nil environment\n- (instancetype) init NS_DESIGNATED_INITIALIZER;\n\n/** The style represented by this object. */\n@property (nonatomic, nullable) NSString* colorString;\n\n/// The inner math list\n@property (nonatomic, nullable) MTMathList* innerList;\n\n@end\n\n/** An atom representing an colorbox element.\n @note None of the usual fields of the `MTMathAtom` apply even though this\n class inherits from `MTMathAtom`. i.e. it is meaningless to have a value\n in the nucleus, subscript or superscript fields. */\n@interface MTMathColorbox : MTMathAtom\n\n/// Creates an empty color with a nil environment\n- (instancetype) init NS_DESIGNATED_INITIALIZER;\n\n/** The style represented by this object. */\n@property (nonatomic, nullable) NSString* colorString;\n\n/// The inner math list\n@property (nonatomic, nullable) MTMathList* innerList;\n\n@end\n\n\n/** An atom representing a boxed element.\n * This class handles both \\boxed and \\fbox LaTeX commands, which draw a rectangle\n * around their contents.\n *\n * @note None of the usual fields of the `MTMathAtom` apply even though this\n * class inherits from `MTMathAtom`. i.e. it is meaningless to have a value\n * in the nucleus, subscript or superscript fields.\n */\n@interface MTBoxed : MTMathAtom\n\n/// The inner math list\n@property (nonatomic, nullable) MTMathList* innerList;\n\n/** Determines whether this is a math mode box (\\boxed) or text mode box (\\fbox).\n * When YES, represents \\boxed command which is designed for math mode with appropriate spacing.\n * When NO, represents \\fbox command which is designed for text mode.\n */\n@property (nonatomic, assign) BOOL isMathMode;\n\n/**\n * Creates a new boxed atom\n */\n- (instancetype)init NS_DESIGNATED_INITIALIZER;\n\n@end\n\n\n@interface MTMathTag : MTMathAtom\n\n@property (nonatomic, nullable) NSAttributedString* tagStr;\n\n@property (nonatomic, nullable) MTMathList* innerList;\n\n\n/**\n * Creates a new boxed atom\n */\n- (instancetype)init NS_DESIGNATED_INITIALIZER;\n\n@end\n\n/** An atom representing an table element. This atom is not like other\n atoms and is not present in TeX. We use it to represent the `\\halign` command\n in TeX with some simplifications. This is used for matrices, equation\n alignments and other uses of multiline environments.\n \n The cells in the table are represented as a two dimensional array of\n `MTMathList` objects. The `MTMathList`s could be empty to denote a missing\n value in the cell. Additionally an array of alignments indicates how each\n column will be aligned.\n */\n@interface MTMathTable : MTMathAtom\n\n/**\n @typedef MTColumnAlignment\n @brief Alignment for a column of MTMathTable\n */\ntypedef NS_ENUM(NSInteger, MTColumnAlignment) {\n    /// Align left.\n    kMTColumnAlignmentLeft,\n    /// Align center.\n    kMTColumnAlignmentCenter,\n    /// Align right.\n    kMTColumnAlignmentRight,\n};\n\n/// Creates an empty table with a nil environment\n- (instancetype)init;\n\n/// Creates a table with a given environment\n- (instancetype)initWithEnvironment:(nullable NSString*) env NS_DESIGNATED_INITIALIZER;\n\n/// The alignment for each column (left, right, center). The default alignment\n/// for a column (if not set) is center.\n@property (nonatomic, nonnull, readonly) NSArray<NSNumber*>* alignments;\n/// The cells in the table as a two dimensional array.\n@property (nonatomic, nonnull, readonly) NSArray<NSArray<MTMathList*>*>* cells;\n/// The name of the environment that this table denotes.\n@property (nonatomic, nullable) NSString* environment;\n\n@property (nonatomic, nullable, copy) MTMathList *envConfig;\n\n@property (nonatomic) CGFloat tableWidth;\n\n/// Spacing between each column in mu units.\n@property (nonatomic) CGFloat interColumnSpacing;\n/// Additional spacing between rows in jots (one jot is 0.3 times font size).\n/// If the additional spacing is 0, then normal row spacing is used are used.\n@property (nonatomic) CGFloat interRowAdditionalSpacing;\n\n/// Set the value of a given cell. The table is automatically resized to contain this cell.\n- (void) setCell:(MTMathList*) list forRow:(NSInteger) row column:(NSInteger) column;\n\n/// Set the alignment of a particular column. The table is automatically resized to\n/// contain this column and any new columns added have their alignment set to center.\n- (void) setAlignment:(MTColumnAlignment) alignment forColumn:(NSInteger) column;\n\n/// Gets the alignment for a given column. If the alignment is not specified it defaults\n/// to center.\n- (MTColumnAlignment) getAlignmentForColumn:(NSInteger) column;\n\n/// Number of columns in the table.\n- (NSUInteger) numColumns;\n\n/// Number of rows in the table.\n- (NSUInteger) numRows;\n\n@end\n\n/** A representation of a list of math objects.\n\n    This list can be constructed directly or built with\n    the help of the MTMathListBuilder. It is not required that the mathematics represented make sense\n    (i.e. this can represent something like \"x 2 = +\". This list can be used for display using MTLine\n    or can be a list of tokens to be used by a parser after finalizedMathList is called.\n \n    @note This class is for ADVANCED usage only.\n */\n@interface MTMathList : NSObject<NSCopying>\n\n/** Create a `MTMathList` given a list of atoms. The list of atoms should be\n terminated by `nil`.\n */\n+ (instancetype) mathListWithAtoms:(MTMathAtom*) firstAtom, ... NS_REQUIRES_NIL_TERMINATION;\n\n/** Create a `MTMathList` given a list of atoms. */\n+ (instancetype) mathListWithAtomsArray:(NSArray<MTMathAtom*>*) atoms;\n\n/// A list of MathAtoms\n@property (nonatomic, readonly) NSArray<__kindof MTMathAtom*>* atoms;\n\n/** Initializes an empty math list. */\n- (instancetype) init NS_DESIGNATED_INITIALIZER;\n\n/** Add an atom to the end of the list.\n @param atom The atom to be inserted. This cannot be `nil` and cannot have the type `kMTMathAtomBoundary`.\n @throws NSException if the atom is of type `kMTMathAtomBoundary`\n @throws NSInvalidArgumentException if the atom is `nil` */\n- (void) addAtom:(MTMathAtom*) atom;\n\n/** Inserts an atom at the given index. If index is already occupied, the objects at index and beyond are \n shifted by adding 1 to their indices to make room.\n \n @param atom The atom to be inserted. This cannot be `nil` and cannot have the type `kMTMathAtomBoundary`.\n @param index The index where the atom is to be inserted. The index should be less than or equal to the\n number of elements in the math list.\n @throws NSException if the atom is of type kMTMathAtomBoundary\n @throws NSInvalidArgumentException if the atom is nil\n @throws NSRangeException if the index is greater than the number of atoms in the math list. */\n- (void) insertAtom:(MTMathAtom *)atom atIndex:(NSUInteger) index;\n\n/** Append the given list to the end of the current list.\n @param list The list to append.\n */\n- (void) append:(MTMathList*) list;\n\n/** Removes the last atom from the math list. If there are no atoms in the list this does nothing. */\n- (void) removeLastAtom;\n\n/** Removes the atom at the given index.\n @param index The index at which to remove the atom. Must be less than the number of atoms\n in the list.\n */\n- (void) removeAtomAtIndex:(NSUInteger) index;\n\n/** Removes all the atoms within the given range. */\n- (void) removeAtomsInRange:(NSRange) range;\n\n/// converts the MTMathList to a string form. Note: This is not the LaTeX form.\n@property (nonatomic, readonly) NSString *stringValue;\n\n/// Create a new math list as a final expression and update atoms\n/// by combining like atoms that occur together and converting unary operators to binary operators.\n/// This function does not modify the current MTMathList\n- (MTMathList*) finalized;\n\n/// Makes a deep copy of the list\n- (id)copyWithZone:(nullable NSZone *)zone;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/lib/MTMathList.m",
    "content": "//\n//  MathList.m\n//  iosMath\n//\n//  Created by Kostub Deshmukh on 8/26/13.\n//  Copyright (C) 2013 MathChat\n//   \n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n#import \"MTMathList.h\"\n\n// Returns true if the current binary operator is not really binary.\nstatic BOOL isNotBinaryOperator(MTMathAtom* prevNode)\n{\n    if (!prevNode) {\n        return true;\n    }\n    \n    if (prevNode.type == kMTMathAtomBinaryOperator || prevNode.type == kMTMathAtomRelation || prevNode.type == kMTMathAtomOpen || prevNode.type == kMTMathAtomPunctuation || prevNode.type == kMTMathAtomLargeOperator) {\n        return true;\n    }\n    return false;\n}\n\nstatic NSString* typeToText(MTMathAtomType type) {\n    switch (type) {\n        case kMTMathAtomOrdinary:\n            return @\"Ordinary\";\n        case kMTMathAtomNumber:\n            return @\"Number\";\n        case kMTMathAtomVariable:\n            return @\"Variable\";\n        case kMTMathAtomBinaryOperator:\n            return @\"Binary Operator\";\n        case kMTMathAtomUnaryOperator:\n            return @\"Unary Operator\";\n        case kMTMathAtomRelation:\n            return @\"Relation\";\n        case kMTMathAtomOpen:\n            return @\"Open\";\n        case kMTMathAtomClose:\n            return @\"Close\";\n        case kMTMathAtomFraction:\n            return @\"Fraction\";\n        case kMTMathAtomRadical:\n            return @\"Radical\";\n        case kMTMathAtomPunctuation:\n            return @\"Punctuation\";\n        case kMTMathAtomPlaceholder:\n            return @\"Placeholder\";\n        case kMTMathAtomLargeOperator:\n            return @\"Large Operator\";\n        case kMTMathAtomInner:\n            return @\"Inner\";\n        case kMTMathAtomUnderline:\n            return @\"Underline\";\n        case kMTMathAtomOverline:\n            return @\"Overline\";\n        case kMTMathAtomAccent:\n            return @\"Accent\";\n        case kMTMathAtomBoundary:\n            return @\"Boundary\";\n        case kMTMathAtomSpace:\n            return @\"Space\";\n        case kMTMathAtomStyle:\n            return @\"Style\";\n        case kMTMathAtomColor:\n            return @\"Color\";\n        case kMTMathAtomColorbox:\n            return @\"Colorbox\";\n        case kMTMathAtomBoxed:\n            return @\"Boxed\";\n        case kMTMathAtomTable:\n            return @\"Table\";\n        case kMTMathAtomHline:\n            return @\"Hline\";\n    }\n}\n\n#pragma mark - MTMathAtom\n\n@interface MTMathAtom ()\n\n@property (nonatomic) NSRange indexRange;\n\n- (instancetype)initWithType:(MTMathAtomType)type value:(NSString *)value NS_DESIGNATED_INITIALIZER;\n\n@end\n\n@implementation MTMathAtom {\n    NSMutableArray* _fusedAtoms;\n}\n\n+ (instancetype)atomWithType:(MTMathAtomType)type value:(NSString *)value\n{\n    switch (type) {\n        case kMTMathAtomFraction:\n            return [[MTFraction alloc] init];\n            \n        case kMTMathAtomPlaceholder:\n            // A placeholder is created with a white square.\n            return [[[self class] alloc] initWithType:kMTMathAtomPlaceholder value:@\"\\u25A1\"];\n            \n        case kMTMathAtomRadical:\n            return [[MTRadical alloc] init];\n            \n        case kMTMathAtomLargeOperator:\n            // Default setting of limits is true\n            return [[MTLargeOperator alloc] initWithValue:value limits:YES];\n            \n        case kMTMathAtomInner:\n            return [[MTInner alloc] init];\n            \n        case kMTMathAtomOverline:\n            return [[MTOverLine alloc] init];\n            \n        case kMTMathAtomUnderline:\n            return [[MTUnderLine alloc] init];\n        case kMTMathAtomHline:\n            return [[MTHLine alloc] init];\n            \n        case kMTMathAtomAccent:\n            return [[MTAccent alloc] initWithValue:value];\n            \n        case kMTMathAtomSpace:\n            return [[MTMathSpace alloc] initWithSpace:0];\n        \n        case kMTMathAtomColor:\n            return [[MTMathColor alloc] init];\n            \n        case kMTMathAtomColorbox:\n            return [[MTMathColorbox alloc] init];\n        default:\n            return [[MTMathAtom alloc] initWithType:type value:value];\n    }\n}\n\n- (instancetype)initWithType:(MTMathAtomType)type value:(NSString *)value\n{\n    self = [super init];\n    if (self) {\n        _type = type;\n        _nucleus = [value copy];\n        _sizeType = MTSizeTypeDefault;\n    }\n    return self;\n}\n\n- (instancetype)init\n{\n    @throw [NSException exceptionWithName:@\"InvalidMethod\"\n                                   reason:@\"[MTMathAtom init] cannot be called. Use [MTMathAtom initWithType:value:] instead.\"\n                                 userInfo:nil];\n    return nil;\n}\n\n- (NSString *)stringValue\n{\n    NSMutableString* str = [NSMutableString stringWithString:self.nucleus];\n    if (self.superScript) {\n        [str appendFormat:@\"^{%@}\", self.superScript.stringValue];\n    }\n    if (self.subScript) {\n        [str appendFormat:@\"_{%@}\", self.subScript.stringValue];\n    }\n    return str;\n}\n\n// Note this is a deep copy.\n- (id)copyWithZone:(NSZone *)zone\n{\n    MTMathAtom* atom = [[[self class] allocWithZone:zone] initWithType:self.type value:self.nucleus];\n    atom.type = self.type;\n    atom.nucleus = self.nucleus;\n    atom.subScript = [self.subScript copyWithZone:zone];\n    atom.superScript = [self.superScript copyWithZone:zone];\n    atom.indexRange = self.indexRange;\n    atom.fontStyle = self.fontStyle;\n    atom.sizeType = self.sizeType;\n    return atom;\n}\n\n- (bool)scriptsAllowed\n{\n    return (self.type < kMTMathAtomBoundary);\n}\n\n- (void)setSubScript:(MTMathList *)subScript\n{\n    if (subScript && !self.scriptsAllowed) {\n        @throw [[NSException alloc] initWithName:@\"Error\"\n                                          reason:[NSString stringWithFormat:@\"Subscripts not allowed for atom of type %@\", typeToText(self.type)]\n                                        userInfo:nil];\n    }\n    _subScript = subScript;\n}\n\n- (void)setSuperScript:(MTMathList *)superScript\n{\n    if (superScript && !self.scriptsAllowed) {\n        @throw [[NSException alloc] initWithName:@\"Error\"\n                                          reason:[NSString stringWithFormat:@\"Superscripts not allowed for atom of type %@\", typeToText(self.type)]\n                                        userInfo:nil];\n    }\n    _superScript = superScript;\n}\n\n- (NSString *)description\n{\n    NSMutableString* str = [NSMutableString stringWithString:typeToText(self.type)];\n    [str appendFormat:@\": %@\", self.stringValue];\n    return str;\n}\n\n- (void)fuse:(MTMathAtom *)atom\n{\n    NSAssert(!self.subScript, @\"Cannot fuse into an atom which has a subscript: %@\", self);\n    NSAssert(!self.superScript, @\"Cannot fuse into an atom which has a superscript: %@\", self);\n    NSAssert(atom.type == self.type, @\"Only atoms of the same type can be fused. %@, %@\", self, atom);\n    \n    // Update the fused atoms list\n    if (!_fusedAtoms) {\n        _fusedAtoms = [NSMutableArray arrayWithObject:[self copy]];\n    }\n    if (atom.fusedAtoms) {\n        [_fusedAtoms addObjectsFromArray:atom.fusedAtoms];\n    } else {\n        [_fusedAtoms addObject:atom];\n    }    \n    \n    // Update the nucleus\n    NSMutableString* str = self.nucleus.mutableCopy;\n    [str appendString:atom.nucleus];\n    self.nucleus = str;\n    \n    // Update the range\n    NSRange newRange = self.indexRange;\n    newRange.length += atom.indexRange.length;\n    self.indexRange = newRange;\n    \n    // Update super/sub scripts\n    self.subScript = atom.subScript;\n    self.superScript = atom.superScript;\n}\n\n- (instancetype)finalized\n{\n    MTMathAtom* newNode = [self copy];\n    if (newNode.superScript) {\n        newNode.superScript = newNode.superScript.finalized;\n    }\n    if (newNode.subScript) {\n        newNode.subScript = newNode.subScript.finalized;\n    }\n    return newNode;\n}\n\n- (void)updateSizeTypeWithStyle:(MTLineStyle)style {\n    if (style == kMTLineStylebig) {\n        self.sizeType = MTSizeTypebig;\n    } else if (style == kMTLineStyleBig) {\n        self.sizeType = MTSizeTypeBig;\n    } else if (style == kMTLineStylebigg) {\n        self.sizeType = MTSizeTypebigg;\n    } else if (style == kMTLineStyleBigg) {\n        self.sizeType = MTSizeTypeBigg;\n    } else {\n        self.sizeType = MTSizeTypeDefault;\n    }\n}\n\n@end\n\n#pragma mark - MTFraction\n\n@implementation MTFraction\n\n- (instancetype)init\n{\n    return [self initWithRule:true];\n}\n\n- (instancetype)initWithType:(MTMathAtomType)type value:(NSString *)value\n{\n    if (type == kMTMathAtomFraction) {\n        return [self init];\n    }\n    @throw [NSException exceptionWithName:@\"InvalidMethod\"\n                                   reason:@\"[MTFraction initWithType:value:] cannot be called. Use [MTFraction init] instead.\"\n                                 userInfo:nil];\n    return nil;\n}\n\n- (instancetype)initWithRule:(BOOL)hasRule\n{\n    // fractions have no nucleus\n    self = [super initWithType:kMTMathAtomFraction value:@\"\"];\n    if (self) {\n        _hasRule = hasRule;\n    }\n    return self;\n}\n\n- (NSString *)stringValue\n{\n    NSMutableString* str = [[NSMutableString alloc] init];\n    if (self.hasRule) {\n        [str appendString:@\"\\\\atop\"];\n    } else {\n        [str appendString:@\"\\\\frac\"];\n    }\n    if (self.leftDelimiter || self.rightDelimiter) {\n        [str appendFormat:@\"[%@][%@]\", self.leftDelimiter, self.rightDelimiter];\n    }\n    \n    [str appendFormat:@\"{%@}{%@}\", self.numerator.stringValue, self.denominator.stringValue];\n    if (self.superScript) {\n        [str appendFormat:@\"^{%@}\", self.superScript.stringValue];\n    }\n    if (self.subScript) {\n        [str appendFormat:@\"_{%@}\", self.subScript.stringValue];\n    }\n    return str;\n}\n\n- (id)copyWithZone:(NSZone *)zone\n{\n    MTFraction* frac = [super copyWithZone:zone];\n    frac.numerator = [self.numerator copyWithZone:zone];\n    frac.denominator = [self.denominator copyWithZone:zone];\n    frac->_hasRule = self.hasRule;\n    frac.leftDelimiter = [self.leftDelimiter copyWithZone:zone];\n    frac.isCfrac = self.isCfrac;\n    return frac;\n}\n\n- (instancetype)finalized\n{\n    MTFraction* newFrac = [super finalized];\n    newFrac.isCfrac = self.isCfrac;\n    newFrac.numerator = newFrac.numerator.finalized;\n    newFrac.denominator = newFrac.denominator.finalized;\n    return newFrac;\n}\n\n@end\n\n#pragma mark - MTRadical\n\n@implementation MTRadical\n\n- (instancetype)init\n{\n    // radicals have no nucleus\n    self = [super initWithType:kMTMathAtomRadical value:@\"\"];\n    return self;\n}\n\n- (instancetype)initWithType:(MTMathAtomType)type value:(NSString *)value\n{\n    if (type == kMTMathAtomRadical) {\n        return [self init];\n    }\n    @throw [NSException exceptionWithName:@\"InvalidMethod\"\n                                   reason:@\"[MTRadical initWithType:value:] cannot be called. Use [MTRadical init] instead.\"\n                                 userInfo:nil];\n    return nil;\n}\n\n- (NSString *)stringValue\n{\n    NSMutableString* str = [NSMutableString stringWithString:@\"\\\\sqrt\"];\n    if (self.degree) {\n        [str appendFormat:@\"[%@]\", self.degree.stringValue];\n    }\n    [str appendFormat:@\"{%@}\", self.radicand.stringValue];\n\n    if (self.superScript) {\n        [str appendFormat:@\"^{%@}\", self.superScript.stringValue];\n    }\n    if (self.subScript) {\n        [str appendFormat:@\"_{%@}\", self.subScript.stringValue];\n    }\n    return str;\n}\n\n- (id)copyWithZone:(NSZone *)zone\n{\n    MTRadical* rad = [super copyWithZone:zone];\n    rad.radicand = [self.radicand copyWithZone:zone];\n    rad.degree = [self.degree copyWithZone:zone];\n    return rad;\n}\n\n- (instancetype)finalized\n{\n    MTRadical* newRad = [super finalized];\n    newRad.radicand = newRad.radicand.finalized;\n    newRad.degree = newRad.degree.finalized;\n    return newRad;\n}\n\n@end\n\n#pragma mark - MTLargeOperator\n\n@implementation MTLargeOperator\n\n- (instancetype) initWithValue:(NSString*) value limits:(BOOL) limits\n{\n    self = [super initWithType:kMTMathAtomLargeOperator value:value];\n    if (self) {\n        _limits = limits;\n    }\n    return self;\n}\n\n- (instancetype)initWithType:(MTMathAtomType)type value:(NSString *)value\n{\n    if (type == kMTMathAtomLargeOperator) {\n        return [self initWithValue:value limits:false];\n    }\n    @throw [NSException exceptionWithName:@\"InvalidMethod\"\n                                   reason:@\"[MTLargeOperator initWithType:value:] cannot be called. Use [MTLargeOperator initWithValue:limits:] instead.\"\n                                 userInfo:nil];\n    return nil;\n}\n\n- (id)copyWithZone:(NSZone *)zone\n{\n    MTLargeOperator* op = [super copyWithZone:zone];\n    op->_limits = self.limits;\n    return op;\n}\n\n@end\n\n#pragma mark - MTInner\n\n@implementation MTInner\n\n- (instancetype)init\n{\n    // inner atoms have no nucleus\n    self = [super initWithType:kMTMathAtomInner value:@\"\"];\n    return self;\n}\n\n- (instancetype)initWithType:(MTMathAtomType)type value:(NSString *)value\n{\n    if (type == kMTMathAtomInner) {\n        return [self init];\n    }\n    @throw [NSException exceptionWithName:@\"InvalidMethod\"\n                                   reason:@\"[MTInner initWithType:value:] cannot be called. Use [MTInner init] instead.\"\n                                 userInfo:nil];\n    return nil;\n}\n\n- (void)setLeftBoundary:(MTMathAtom *)leftBoundary\n{\n    if (leftBoundary && leftBoundary.type != kMTMathAtomBoundary) {\n        @throw [[NSException alloc] initWithName:@\"Error\"\n                                          reason:[NSString stringWithFormat:@\"Left boundary must be of type kMTMathAtomBoundary\"]\n                                        userInfo:nil];\n    }\n    _leftBoundary = leftBoundary;\n}\n\n- (void)setRightBoundary:(MTMathAtom *)rightBoundary\n{\n    if (rightBoundary && rightBoundary.type != kMTMathAtomBoundary) {\n        @throw [[NSException alloc] initWithName:@\"Error\"\n                                          reason:[NSString stringWithFormat:@\"Left boundary must be of type kMTMathAtomBoundary\"]\n                                        userInfo:nil];\n    }\n    _rightBoundary = rightBoundary;\n}\n\n- (NSString *)stringValue\n{\n    NSMutableString* str = [NSMutableString stringWithString:@\"\\\\inner\"];\n    if (self.leftBoundary) {\n        [str appendFormat:@\"[%@]\", self.leftBoundary.nucleus];\n    }\n    [str appendFormat:@\"{%@}\", self.innerList.stringValue];\n    if (self.rightBoundary) {\n        [str appendFormat:@\"[%@]\", self.rightBoundary.nucleus];\n    }\n    \n    if (self.superScript) {\n        [str appendFormat:@\"^{%@}\", self.superScript.stringValue];\n    }\n    if (self.subScript) {\n        [str appendFormat:@\"_{%@}\", self.subScript.stringValue];\n    }\n    return str;\n}\n\n- (id)copyWithZone:(NSZone *)zone\n{\n    MTInner* inner = [super copyWithZone:zone];\n    inner.innerList = [self.innerList copyWithZone:zone];\n    inner.leftBoundary = [self.leftBoundary copyWithZone:zone];\n    inner.rightBoundary = [self.rightBoundary copyWithZone:zone];\n    return inner;\n}\n\n- (instancetype)finalized\n{\n    MTInner *newInner = [super finalized];\n    newInner.innerList = newInner.innerList.finalized;\n    return newInner;\n}\n\n@end\n\n#pragma mark - MTAdaptive\n\n@implementation MTAdaptive\n\n- (instancetype)init\n{\n    self = [super initWithType:kMTMathAtomAdaptive value:@\"\"];\n    return self;\n}\n\n- (instancetype)initWithType:(MTMathAtomType)type value:(NSString *)value\n{\n    if (type == kMTMathAtomAdaptive) {\n        return [self init];\n    }\n    @throw [NSException exceptionWithName:@\"InvalidMethod\"\n                                   reason:@\"[MTAdaptive initWithType:value:] cannot be called. Use [MTAdaptive init] instead.\"\n                                 userInfo:nil];\n    return nil;\n}\n\n- (void)setBoundary:(MTMathAtom *)boundary\n{\n    if (boundary && boundary.type != kMTMathAtomBoundary) {\n        @throw [[NSException alloc] initWithName:@\"Error\"\n                                          reason:[NSString stringWithFormat:@\"boundary must be of type kMTMathAtomBoundary\"]\n                                        userInfo:nil];\n    }\n    _boundary = boundary;\n}\n\n- (NSString *)stringValue\n{\n    NSMutableString* str = [NSMutableString stringWithString:@\"\\\\adaptive\"];\n    if (self.boundary) {\n        [str appendFormat:@\"[%@]\", self.boundary.nucleus];\n    }\n    \n    if (self.superScript) {\n        [str appendFormat:@\"^{%@}\", self.superScript.stringValue];\n    }\n    if (self.subScript) {\n        [str appendFormat:@\"_{%@}\", self.subScript.stringValue];\n    }\n    return str;\n}\n\n- (NSString *)adaptiveID\n{\n    if (!_adaptiveID) {\n        _adaptiveID = [NSUUID UUID].UUIDString;\n    }\n    return _adaptiveID;\n}\n\n- (id)copyWithZone:(NSZone *)zone\n{\n    MTAdaptive* adaptive = [super copyWithZone:zone];\n    adaptive.boundary = [self.boundary copyWithZone:zone];\n    adaptive.adaptiveID = self.adaptiveID;\n    return adaptive;\n}\n\n- (instancetype)finalized\n{\n    MTAdaptive *newAdaptive = [super finalized];\n    return newAdaptive;\n}\n\n@end\n\n#pragma mark - MTOverline\n\n@implementation MTOverLine\n\n- (instancetype)init\n{\n    self = [super initWithType:kMTMathAtomOverline value:@\"\"];\n    return self;\n}\n\n- (instancetype)initWithType:(MTMathAtomType)type value:(NSString *)value\n{\n    if (type == kMTMathAtomOverline) {\n        return [self init];\n    }\n    @throw [NSException exceptionWithName:@\"InvalidMethod\"\n                                   reason:@\"[MTOverline initWithType:value:] cannot be called. Use [MTOverline init] instead.\"\n                                 userInfo:nil];\n    return nil;\n}\n\n- (id)copyWithZone:(NSZone *)zone\n{\n    MTOverLine* op = [super copyWithZone:zone];\n    op.innerList = [self.innerList copyWithZone:zone];\n    op.useArrow = self.useArrow;\n    return op;\n}\n\n- (instancetype)finalized\n{\n    MTOverLine* newOverline = [super finalized];\n    newOverline.innerList = newOverline.innerList.finalized;\n    newOverline.useArrow = self.useArrow;\n    return newOverline;\n}\n\n@end\n\n#pragma mark - MTUnderline\n\n@implementation MTUnderLine\n\n- (instancetype)init\n{\n    self = [super initWithType:kMTMathAtomUnderline value:@\"\"];\n    return self;\n}\n\n- (instancetype)initWithType:(MTMathAtomType)type value:(NSString *)value\n{\n    if (type == kMTMathAtomUnderline) {\n        return [self init];\n    }\n    @throw [NSException exceptionWithName:@\"InvalidMethod\"\n                                   reason:@\"[MTUnderline initWithType:value:] cannot be called. Use [MTUnderline init] instead.\"\n                                 userInfo:nil];\n    return nil;\n}\n\n- (id)copyWithZone:(NSZone *)zone\n{\n    MTUnderLine* op = [super copyWithZone:zone];\n    op.innerList = [self.innerList copyWithZone:zone];\n    return op;\n}\n\n- (instancetype)finalized\n{\n    MTUnderLine* newUnderline = [super finalized];\n    newUnderline.innerList = newUnderline.innerList.finalized;\n    return newUnderline;\n}\n\n@end\n\n#pragma mark - MTMiddleLine\n\n@implementation MTHLine\n\n- (instancetype)init\n{\n    self = [super initWithType:kMTMathAtomHline value:@\"\"];\n    return self;\n}\n\n- (instancetype)initWithType:(MTMathAtomType)type value:(NSString *)value\n{\n    if (type == kMTMathAtomHline) {\n        return [self init];\n    }\n    @throw [NSException exceptionWithName:@\"InvalidMethod\"\n                                   reason:@\"[MTHline initWithType:value:] cannot be called. Use [MTHline init] instead.\"\n                                 userInfo:nil];\n    return nil;\n}\n\n- (id)copyWithZone:(NSZone *)zone\n{\n    MTHLine* hline = [super copyWithZone:zone];\n    return hline;\n}\n\n- (instancetype)finalized\n{\n    MTHLine* hline = [super finalized];\n    return hline;\n}\n\n@end\n\n@implementation MTOverbrace\n\n- (instancetype)init\n{\n    self = [super initWithType:kMTMathAtomOverbrace value:@\"\"];\n    return self;\n}\n\n- (instancetype)initWithType:(MTMathAtomType)type value:(NSString *)value\n{\n    if (type == kMTMathAtomOverbrace) {\n        return [self init];\n    }\n    @throw [NSException exceptionWithName:@\"InvalidMethod\"\n                                   reason:@\"[MTHline initWithType:value:] cannot be called. Use [MTHline init] instead.\"\n                                 userInfo:nil];\n    return nil;\n}\n\n- (id)copyWithZone:(NSZone *)zone\n{\n    MTOverbrace* overbrace = [super copyWithZone:zone];\n    overbrace.contentor = [self.contentor copyWithZone:zone];\n    overbrace.labelor = [self.labelor copyWithZone:zone];\n    return overbrace;\n}\n\n- (instancetype)finalized\n{\n    MTOverbrace* overbrace = [super finalized];\n    overbrace.contentor = overbrace.contentor.finalized;\n    overbrace.labelor = overbrace.labelor.finalized;\n    return overbrace;\n}\n\n@end\n\n@implementation MTUnderbrace\n\n- (instancetype)init\n{\n    self = [super initWithType:kMTmathAtomUnderbrace value:@\"\"];\n    return self;\n}\n\n- (instancetype)initWithType:(MTMathAtomType)type value:(NSString *)value\n{\n    if (type == kMTmathAtomUnderbrace) {\n        return [self init];\n    }\n    @throw [NSException exceptionWithName:@\"InvalidMethod\"\n                                   reason:@\"[MTHline initWithType:value:] cannot be called. Use [MTHline init] instead.\"\n                                 userInfo:nil];\n    return nil;\n}\n\n- (id)copyWithZone:(NSZone *)zone\n{\n    MTUnderbrace* underbrace = [super copyWithZone:zone];\n    underbrace.contentor = [self.contentor copyWithZone:zone];\n    underbrace.labelor = [self.labelor copyWithZone:zone];\n    return underbrace;\n}\n\n- (instancetype)finalized\n{\n    MTUnderbrace* underbrace = [super finalized];\n    underbrace.contentor = underbrace.contentor.finalized;\n    underbrace.labelor = underbrace.labelor.finalized;\n    return underbrace;\n}\n\n@end\n\n\n\n#pragma mark - MTAccent\n\n@implementation MTAccent\n\n- (instancetype)initWithValue:(NSString *)value\n{\n    self = [super initWithType:kMTMathAtomAccent value:value];\n    return self;\n}\n\n- (instancetype)initWithType:(MTMathAtomType)type value:(NSString *)value\n{\n    if (type == kMTMathAtomAccent) {\n        return [self initWithValue:value];\n    }\n    @throw [NSException exceptionWithName:@\"InvalidMethod\"\n                                   reason:@\"[MTAccent initWithType:value:] cannot be called. Use [MTAccent initWithValue:] instead.\"\n                                 userInfo:nil];\n    return nil;\n}\n\n- (id)copyWithZone:(NSZone *)zone\n{\n    MTAccent* op = [super copyWithZone:zone];\n    op.innerList = [self.innerList copyWithZone:zone];\n    return op;\n}\n\n- (instancetype)finalized\n{\n    MTAccent* newAccent = [super finalized];\n    newAccent.innerList = newAccent.innerList.finalized;\n    return newAccent;\n}\n\n@end\n\n#pragma mark - MTMathSpace\n\n@implementation MTMathSpace\n\n- (instancetype)initWithSpace:(CGFloat)space\n{\n    self = [super initWithType:kMTMathAtomSpace value:@\"\"];\n    if (self) {\n        _space = space;\n    }\n    return self;\n}\n\n- (instancetype)initWithType:(MTMathAtomType)type value:(NSString *)value\n{\n    if (type == kMTMathAtomSpace) {\n        return [self initWithSpace:0];\n    }\n    @throw [NSException exceptionWithName:@\"InvalidMethod\"\n                                   reason:@\"[MTMathSpace initWithType:value:] cannot be called. Use [MTMathSpace initWithSpace:] instead.\"\n                                 userInfo:nil];\n    return nil;\n}\n\n- (id)copyWithZone:(NSZone *)zone\n{\n    MTMathSpace* op = [super copyWithZone:zone];\n    op->_space = self.space;\n    return op;\n}\n\n@end\n\n#pragma mark - MTMathStyle\n\n@implementation MTMathStyle\n\n- (instancetype)initWithStyle:(MTLineStyle)style\n{\n    self = [super initWithType:kMTMathAtomStyle value:@\"\"];\n    if (self) {\n        _style = style;\n    }\n    return self;\n}\n\n- (instancetype)initWithType:(MTMathAtomType)type value:(NSString *)value\n{\n    if (type == kMTMathAtomStyle) {\n        return [self initWithStyle:kMTLineStyleDisplay];\n    }\n    @throw [NSException exceptionWithName:@\"InvalidMethod\"\n                                   reason:@\"[MTMathStyle initWithType:value:] cannot be called. Use [MTMathStyle initWithStyle:] instead.\"\n                                 userInfo:nil];\n    return nil;\n}\n\n- (id)copyWithZone:(NSZone *)zone\n{\n    MTMathStyle* op = [super copyWithZone:zone];\n    op->_style = self.style;\n    return op;\n}\n\n@end\n\n#pragma mark - MTMathColor\n\n@implementation MTMathColor\n\n\n- (instancetype)init\n{\n    self = [super initWithType:kMTMathAtomColor value:@\"\"];\n    return self;\n}\n\n- (instancetype)initWithType:(MTMathAtomType)type value:(NSString *)value\n{\n    if (type == kMTMathAtomColor) {\n        return [self init];\n    }\n    @throw [NSException exceptionWithName:@\"InvalidMethod\"\n                                   reason:@\"[MTMathColor initWithType:value:] cannot be called. Use [MTMathColor init] instead.\"\n                                 userInfo:nil];\n    return nil;\n}\n\n- (NSString *)stringValue\n{\n    NSMutableString* str = [NSMutableString stringWithString:@\"\\\\color\"];\n    [str appendFormat:@\"{%@}{%@}\", self.colorString, self.innerList.stringValue];\n    return str;\n}\n\n- (id)copyWithZone:(NSZone *)zone\n{\n    MTMathColor* op = [super copyWithZone:zone];\n    op.innerList = [self.innerList copyWithZone:zone];\n    op->_colorString = self.colorString;\n    return op;\n}\n\n- (instancetype)finalized\n{\n    MTMathColor *newInner = [super finalized];\n    newInner.innerList = newInner.innerList.finalized;\n    return newInner;\n}\n\n@end\n\n#pragma mark - MTMathColorbox\n\n@implementation MTMathColorbox\n\n\n- (instancetype)init\n{\n    self = [super initWithType:kMTMathAtomColorbox value:@\"\"];\n    return self;\n}\n\n- (instancetype)initWithType:(MTMathAtomType)type value:(NSString *)value\n{\n    if (type == kMTMathAtomColorbox) {\n        return [self init];\n    }\n    @throw [NSException exceptionWithName:@\"InvalidMethod\"\n                                   reason:@\"[MTMathColorbox initWithType:value:] cannot be called. Use [MTMathColorbox init] instead.\"\n                                 userInfo:nil];\n    return nil;\n}\n\n- (NSString *)stringValue\n{\n    NSMutableString* str = [NSMutableString stringWithString:@\"\\\\colorbox\"];\n    [str appendFormat:@\"{%@}{%@}\", self.colorString, self.innerList.stringValue];\n    return str;\n}\n\n- (id)copyWithZone:(NSZone *)zone\n{\n    MTMathColorbox* op = [super copyWithZone:zone];\n    op.innerList = [self.innerList copyWithZone:zone];\n    op->_colorString = self.colorString;\n    return op;\n}\n\n- (instancetype)finalized\n{\n    MTMathColorbox *newInner = [super finalized];\n    newInner.innerList = newInner.innerList.finalized;\n    return newInner;\n}\n\n@end\n\n#pragma mark - MTBoxed\n\n@implementation MTBoxed\n\n- (instancetype)init\n{\n    self = [super initWithType:kMTMathAtomBoxed value:@\"\"];\n    if (self) {\n        self.type = kMTMathAtomBoxed;\n        self.innerList = nil;\n        self.isMathMode = YES;\n    }\n    return self;\n}\n\n- (instancetype)initWithType:(MTMathAtomType)type value:(NSString *)value\n{\n    if (type == kMTMathAtomBoxed) {\n        return [self init];\n    }\n    @throw [NSException exceptionWithName:@\"InvalidMethod\"\n                                   reason:@\"[MTBoxed initWithType:value:] cannot be called. Use [MTBoxed init] instead.\"\n                                 userInfo:nil];\n    return nil;\n}\n\n- (id)copyWithZone:(NSZone *)zone\n{\n    MTBoxed* op = [super copyWithZone:zone];\n    op.innerList = [self.innerList copyWithZone:zone];\n    op->_isMathMode = self.isMathMode;\n    return op;\n}\n\n- (instancetype)finalized\n{\n    MTBoxed *newInner = [super finalized];\n    newInner.innerList = newInner.innerList.finalized;\n    return newInner;\n}\n@end\n\n\n#pragma mark - MTMathTag\n// 布局在外部处理拿不到contex的宽度，放到内部实现\n@implementation MTMathTag\n\n- (instancetype)init\n{\n    self = [super initWithType:KMTMathAtomTag value:@\"\"];\n    if (self) {\n        self.type = KMTMathAtomTag;\n        self.tagStr = nil;\n    }\n    return self;\n}\n\n- (instancetype)initWithType:(MTMathAtomType)type value:(NSString *)value\n{\n    if (type == KMTMathAtomTag) {\n        return [self init];\n    }\n    @throw [NSException exceptionWithName:@\"InvalidMethod\"\n                                   reason:@\"[MTBoxed initWithType:value:] cannot be called. Use [MTBoxed init] instead.\"\n                                 userInfo:nil];\n    return nil;\n}\n\n- (id)copyWithZone:(NSZone *)zone\n{\n    MTMathTag* op = [super copyWithZone:zone];\n    op.innerList = [self.innerList copyWithZone:zone];\n    op.tagStr = [self.tagStr copyWithZone:zone];\n    return op;\n}\n\n- (instancetype)finalized\n{\n    MTMathTag *newInner = [super finalized];\n    newInner.innerList = newInner.innerList.finalized;\n    return newInner;\n}\n@end\n\n\n#pragma mark - MTMathTable\n\n@interface MTMathTable ()\n\n@property (nonatomic, nonnull) NSMutableArray<NSNumber*>* alignments;\n@property (nonatomic, nonnull) NSMutableArray<NSMutableArray<MTMathList*>*>* cells;\n\n@end\n\n@implementation MTMathTable\n\n- (instancetype)initWithEnvironment:(NSString *)env\n{\n    self = [super initWithType:kMTMathAtomTable value:@\"\"];\n    if (self) {\n        self.alignments = [NSMutableArray array];\n        self.cells = [NSMutableArray array];\n        self.interRowAdditionalSpacing = 0;\n        self.interColumnSpacing = 0;\n        _environment = env;\n    }\n    return self;\n}\n\n- (instancetype)init\n{\n    return [self initWithEnvironment:nil];\n}\n\n- (instancetype)initWithType:(MTMathAtomType)type value:(NSString *)value\n{\n    if (type == kMTMathAtomTable) {\n        return [self init];\n    }\n    @throw [NSException exceptionWithName:@\"InvalidMethod\"\n                                   reason:@\"[MTMathTable initWithType:value:] cannot be called. Use [MTMathTable init] instead.\"\n                                 userInfo:nil];\n    return nil;\n}\n\n- (id)copyWithZone:(NSZone *)zone\n{\n    MTMathTable* op = [super copyWithZone:zone];\n    op.interRowAdditionalSpacing = self.interRowAdditionalSpacing;\n    op.interColumnSpacing = self.interColumnSpacing;\n    op->_environment = self.environment;\n    op->_envConfig = self.envConfig;\n    op.alignments = [NSMutableArray arrayWithArray:self.alignments];\n    // Perform a deep copy of the cells.\n    NSMutableArray* cellCopy = [NSMutableArray arrayWithCapacity:self.cells.count];\n    for (NSMutableArray* row in self.cells) {\n        [cellCopy addObject:[[NSMutableArray alloc] initWithArray:row copyItems:YES]];\n    }\n    op.cells = cellCopy;\n    return op;\n}\n\n- (instancetype)finalized\n{\n    MTMathTable* table = [super finalized];\n    for (NSMutableArray<MTMathList*>* row in table.cells) {\n        for (int i = 0; i < row.count; i++) {\n            row[i] = row[i].finalized;\n        }\n    }\n    table.environment = self.environment;\n    table.envConfig = self.envConfig;\n    return table;\n}\n\n- (void)setCell:(MTMathList *)list forRow:(NSInteger)row column:(NSInteger)column\n{\n    NSParameterAssert(list);\n    \n    if (self.cells.count <= row) {\n        // Add more rows\n        for (NSInteger i = self.cells.count;  i <= row; i++) {\n            _cells[i] = [NSMutableArray array];\n        }\n    }\n    NSMutableArray<MTMathList*> *rowArray = _cells[row];\n    if (rowArray.count <= column) {\n        // Add more columns\n        for (NSInteger i = rowArray.count;  i < column; i++) {\n            rowArray[i] = [[MTMathList alloc] init];\n        }\n    }\n    rowArray[column] = list;\n}\n\n- (void)setAlignment:(MTColumnAlignment)alignment forColumn:(NSInteger)column\n{\n    if (self.alignments.count < column) {\n        // Add more columns\n        for (NSInteger i = self.alignments.count; i < column; i++) {\n            _alignments[i] = @(kMTColumnAlignmentCenter);\n        }\n    }\n    _alignments[column] = @(alignment);\n}\n\n- (MTColumnAlignment)getAlignmentForColumn:(NSInteger)column\n{\n    if (self.alignments.count <= column) {\n        return kMTColumnAlignmentCenter;\n    } else {\n        return self.alignments[column].integerValue;\n    }\n}\n\n- (NSUInteger) numColumns\n{\n    NSUInteger numColumns = 0;\n    for (NSArray* row in self.cells) {\n        numColumns = MAX(numColumns, row.count);\n    }\n    return numColumns;\n}\n\n- (NSUInteger) numRows\n{\n    return self.cells.count;\n}\n\n@end\n\n#pragma mark - MTMathList\n\n@implementation MTMathList {\n    NSMutableArray* _atoms;\n}\n\n+ (instancetype)mathListWithAtoms:(MTMathAtom *)firstAtom, ...\n{\n    MTMathList* list = [[MTMathList alloc] init];\n    va_list args;\n    va_start(args, firstAtom);\n    for (MTMathAtom* atom = firstAtom; atom != nil; atom = va_arg(args, MTMathAtom*))\n    {\n        [list addAtom:atom];\n    }\n    va_end(args);\n    return list;\n}\n\n+ (instancetype)mathListWithAtomsArray:(NSArray<MTMathAtom *> *)atoms\n{\n    MTMathList* list = [[MTMathList alloc] init];\n    [list->_atoms addObjectsFromArray:atoms];\n    return list;\n}\n\n- (instancetype)init\n{\n    self = [super init];\n    if (self) {\n        _atoms = [NSMutableArray array];\n    }\n    return self;\n}\n\n- (bool) isAtomAllowed:(MTMathAtom*) atom\n{\n    return atom.type != kMTMathAtomBoundary;\n}\n\n- (void)addAtom:(MTMathAtom *)atom\n{\n    NSParameterAssert(atom);\n    if (![self isAtomAllowed:atom]) {\n        @throw [[NSException alloc] initWithName:@\"Error\"\n                                          reason:[NSString stringWithFormat:@\"Cannot add atom of type %@ in a mathlist\", typeToText(atom.type)]\n                                        userInfo:nil];\n    }\n    [_atoms addObject:atom];\n}\n\n- (void)insertAtom:(MTMathAtom *)atom atIndex:(NSUInteger) index\n{\n    if (![self isAtomAllowed:atom]) {\n        @throw [[NSException alloc] initWithName:@\"Error\"\n                                          reason:[NSString stringWithFormat:@\"Cannot add atom of type %@ in a mathlist\", typeToText(atom.type)]\n                                        userInfo:nil];\n    }\n    [_atoms insertObject:atom atIndex:index];\n}\n\n- (void)append:(MTMathList *)list\n{\n    [_atoms addObjectsFromArray:list.atoms];\n}\n\n- (void)removeLastAtom\n{\n    if (_atoms.count > 0) {\n        [_atoms removeLastObject];\n    }\n}\n\n- (void) removeAtomAtIndex:(NSUInteger)index\n{\n    [_atoms removeObjectAtIndex:index];\n}\n\n- (void) removeAtomsInRange:(NSRange) range\n{\n    [_atoms removeObjectsInRange:range];\n}\n\n- (NSString *)stringValue\n{\n    NSMutableString* str = [NSMutableString string];\n    for (MTMathAtom* atom in self.atoms) {\n        [str appendString:atom.stringValue];\n    }\n    return str;\n}\n\n- (NSString *)description\n{\n    return self.atoms.description;\n}\n\n- (MTMathList *)finalized\n{\n    MTMathList* finalized = [MTMathList new];\n    NSRange zeroRange = NSMakeRange(0, 0);\n    \n    MTMathAtom* prevNode = nil;\n    for (MTMathAtom* atom in self.atoms) {\n        MTMathAtom* newNode = [atom finalized];\n        // Each character is given a separate index.\n        if (NSEqualRanges(zeroRange, atom.indexRange)) {\n            NSUInteger index = (prevNode == nil) ? 0 : prevNode.indexRange.location + prevNode.indexRange.length;\n            newNode.indexRange = NSMakeRange(index, 1);\n        }\n\n        switch (newNode.type) {\n            case kMTMathAtomBinaryOperator: {\n                if (isNotBinaryOperator(prevNode)) {\n                    newNode.type = kMTMathAtomUnaryOperator;\n                }\n                break;\n            }\n            case kMTMathAtomRelation:\n            case kMTMathAtomPunctuation:\n            case kMTMathAtomClose:\n                if (prevNode && prevNode.type == kMTMathAtomBinaryOperator) {\n                    prevNode.type = kMTMathAtomUnaryOperator;\n                }\n                break;\n                \n            case kMTMathAtomNumber:\n                // combine numbers together\n                if (prevNode && prevNode.type == kMTMathAtomNumber && !prevNode.subScript && !prevNode.superScript) {\n                    [prevNode fuse:newNode];\n                    // skip the current node, we are done here.\n                    continue;\n                }\n                break;\n            case kMTMathAtomTable:\n                [(MTMathTable *)newNode setEnvConfig:[(MTMathTable *)atom envConfig]];\n                break;\n            case kMTMathAtomFraction:\n                ((MTFraction *)newNode).isCfrac = ((MTFraction *)atom).isCfrac;\n                break;\n            default:\n                break;\n        }\n        [finalized addAtom:newNode];\n        prevNode = newNode;\n    }\n    if (prevNode && prevNode.type == kMTMathAtomBinaryOperator) {\n        // it isn't a binary since there is noting after it. Make it a unary\n        prevNode.type = kMTMathAtomUnaryOperator;\n    }\n    return finalized;\n}\n\n#pragma mark NSCopying\n\n// Makes a deep copy of the list\n- (id)copyWithZone:(NSZone *)zone\n{\n    MTMathList* list = [[[self class] allocWithZone:zone] init];\n    list->_atoms = [[NSMutableArray alloc] initWithArray:self.atoms copyItems:YES];\n    return list;\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/lib/MTMathListBuilder.h",
    "content": "//\n//  MTMathListBuilder.h\n//  iosMath\n//\n//  Created by Kostub Deshmukh on 8/28/13.\n//  Copyright (C) 2013 MathChat\n//   \n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n@import Foundation;\n\n#import \"MTMathList.h\"\n\nFOUNDATION_EXPORT NSString *const _Nonnull MTParseError;\n\n/** `MTMathListBuilder` is a class for parsing LaTeX into an `MTMathList` that\n can be rendered and processed mathematically.\n */\n@interface MTMathListBuilder : NSObject\n\n/** Contains any error that occurred during parsing. */\n@property (nonatomic, readonly, nullable) NSError* error;\n\n/** Create a `MTMathListBuilder` for the given string. After instantiating the\n    `MTMathListBuilder, use `build` to build the mathlist. Create a new `MTMathListBuilder`\n    for each string that needs to be parsed. Do not reuse the object.\n    @param str The LaTeX string to be used to build the `MTMathList`\n */\n- (nonnull instancetype) initWithString:(nonnull NSString*) str NS_DESIGNATED_INITIALIZER;\n- (nonnull instancetype) init NS_UNAVAILABLE;\n\n/// Builds a mathlist from the given string. Returns nil if there is an error.\n- (nullable MTMathList*) build;\n\n/** Construct a math list from a given string. If there is parse error, returns\n nil. To retrieve the error use the function `[MTMathListBuilder buildFromString:error:]`.\n */\n+ (nullable MTMathList*) buildFromString:(nonnull NSString*) str;\n\n/** Construct a math list from a given string. If there is an error while\n constructing the string, this returns nil. The error is returned in the\n `error` parameter.\n */\n+ (nullable MTMathList*) buildFromString:(nonnull NSString*) str error:( NSError* _Nullable * _Nullable) error;\n\n/// This converts the MTMathList to LaTeX.\n+ (nonnull NSString*) mathListToString:(nonnull MTMathList*) ml;\n\n/**\n @typedef MTParseErrors\n @brief The error encountered when parsing a LaTeX string.\n \n The `code` in the `NSError` is one of the following indiciating why the LaTeX string\n could not be parsed.\n */\ntypedef NS_ENUM(NSUInteger, MTParseErrors) {\n    /// The braces { } do not match.\n    MTParseErrorMismatchBraces = 1,\n    /// A command in the string is not recognized.\n    MTParseErrorInvalidCommand,\n    /// An expected character such as ] was not found.\n    MTParseErrorCharacterNotFound,\n    /// The \\left or \\right command was not followed by a delimiter.\n    MTParseErrorMissingDelimiter,\n    /// The delimiter following \\left or \\right was not a valid delimiter.\n    MTParseErrorInvalidDelimiter,\n    /// There is no \\right corresponding to the \\left command.\n    MTParseErrorMissingRight,\n    /// There is no \\left corresponding to the \\right command.\n    MTParseErrorMissingLeft,\n    /// The environment given to the \\begin command is not recognized\n    MTParseErrorInvalidEnv,\n    /// A command is used which is only valid inside a \\begin,\\end environment\n    MTParseErrorMissingEnv,\n    /// There is no \\begin corresponding to the \\end command.\n    MTParseErrorMissingBegin,\n    /// There is no \\end corresponding to the \\begin command.\n    MTParseErrorMissingEnd,\n    /// The number of columns do not match the environment\n    MTParseErrorInvalidNumColumns,\n    /// Internal error, due to a programming mistake.\n    MTParseErrorInternalError,\n    /// Limit control applied incorrectly\n    MTParseErrorInvalidLimits,\n};\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/lib/MTMathListBuilder.m",
    "content": "//\n//  MTMathListBuilder.m\n//  iosMath\n//\n//  Created by Kostub Deshmukh on 8/28/13.\n//  Copyright (C) 2013 MathChat\n//   \n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n#import \"MTMathListBuilder.h\"\n#import \"MTMathAtomFactory.h\"\n\nstatic NSInteger kMT_Cmd_ColorStrLen_Short = 3;\n\nNSString *const MTParseError = @\"ParseError\";\n\n@interface MTEnvProperties : NSObject\n\n@property (nonatomic, readonly) NSString* envName;\n@property (nonatomic, readonly) NSString* envConfig;\n@property (nonatomic) BOOL ended;\n@property (nonatomic) NSInteger numRows;\n\n@end\n\n@implementation MTEnvProperties\n\n- (instancetype)initWithName:(NSString*) name config:(NSString *)config\n{\n    self = [super init];\n    if (self) {\n        _envName = name;\n        _numRows = 0;\n        _ended = NO;\n        _envConfig = config;\n    }\n    return self;\n}\n\n@end\n\n\n@implementation MTMathListBuilder {\n    unichar* _chars;\n    int _currentChar;\n    NSUInteger _length;\n    MTInner* _currentInnerAtom;\n    MTEnvProperties* _currentEnv;\n    MTFontStyle _currentFontStyle;\n    BOOL _spacesAllowed;\n    BOOL _notCommand;\n    NSString *_nowSizedCommand;\n    BOOL _isInlineStyle;\n}\n\n- (instancetype)initWithString:(NSString *)str\n{\n    self = [super init];\n    if (self) {\n        _error = nil;\n        _isInlineStyle = ![str hasPrefix:@\"$$\"];\n        _chars = malloc(sizeof(unichar)*str.length);\n        _length = str.length;\n        [str getCharacters:_chars range:NSMakeRange(0, str.length)];\n        _currentChar = 0;\n        _currentFontStyle = kMTFontStyleDefault;\n    }\n    return self;\n}\n\n- (void)dealloc\n{\n    free(_chars);\n}\n\n- (BOOL) hasCharacters\n{\n    return _currentChar < _length;\n}\n\n// gets the next character and moves the pointer ahead\n- (unichar) getCurrentCharacter\n{\n    NSAssert([self hasCharacters], @\"Retrieving character at index %d beyond length %lu\", _currentChar, (unsigned long)_length);\n    return _chars[_currentChar];\n}\n\n// gets the next character and moves the pointer ahead\n- (unichar) getNextCharacter\n{\n    NSAssert([self hasCharacters], @\"Retrieving character at index %d beyond length %lu\", _currentChar, (unsigned long)_length);\n    return _chars[_currentChar++];\n}\n\n- (void) unlookCharacter\n{\n    NSAssert(_currentChar > 0, @\"Unlooking when at the first character.\");\n    _currentChar--;\n}\n\n- (MTMathList *)build\n{\n    MTMathList* list = [self buildInternal:false];\n    if ([self hasCharacters] && !_error) {\n        // something went wrong most likely braces mismatched\n        NSString* errorMessage = [NSString stringWithFormat:@\"Mismatched braces: %@\", [NSString stringWithCharacters:_chars length:_length]];\n        [self setError:MTParseErrorMismatchBraces message:errorMessage];\n    }\n    if (_error) {\n        return nil;\n    }\n    return list;\n}\n\n- (MTMathList*) buildInternal:(BOOL) oneCharOnly\n{\n    return [self buildInternal:oneCharOnly stopChar:0];\n}\n\n- (MTMathList*)buildInternal:(BOOL) oneCharOnly stopChar:(unichar) stop\n{\n    MTMathList* list = [MTMathList new];\n    NSAssert(!(oneCharOnly && (stop > 0)), @\"Cannot set both oneCharOnly and stopChar.\");\n    MTMathAtom* prevAtom = nil;\n    while([self hasCharacters]) {\n        if (_error) {\n            // If there is an error thus far then bail out.\n            return nil;\n        }\n        MTMathAtom* atom = nil;\n        unichar ch = [self getNextCharacter];\n        if (oneCharOnly) {\n            if (ch == '^' || ch == '}' || ch == '_' || ch == '&') {\n                // this is not the character we are looking for.\n                // They are meant for the caller to look at.\n                [self unlookCharacter];\n                return list;\n            }\n        }\n        // If there is a stop character, keep scanning till we find it\n        if (stop > 0 && ch == stop) {\n            return list;\n        }\n        \n        if (ch == '^') {\n            NSAssert(!oneCharOnly, @\"This should have been handled before\");\n            \n            if (!prevAtom || prevAtom.superScript || !prevAtom.scriptsAllowed) {\n                // If there is no previous atom, or if it already has a superscript\n                // or if scripts are not allowed for it, then add an empty node.\n                prevAtom = [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\"];\n                [list addAtom:prevAtom];\n            }\n            // this is a superscript for the previous atom\n            // note: if the next char is the stopChar it will be consumed by the ^ and so it doesn't count as stop\n            prevAtom.superScript = [self buildInternal:true];\n            continue;\n        } else if (ch == '_') {\n            NSAssert(!oneCharOnly, @\"This should have been handled before\");\n            \n            if (!prevAtom || prevAtom.subScript || !prevAtom.scriptsAllowed) {\n                // If there is no previous atom, or if it already has a subcript\n                // or if scripts are not allowed for it, then add an empty node.\n                prevAtom = [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\"];\n                [list addAtom:prevAtom];\n            }\n            // this is a subscript for the previous atom\n            // note: if the next char is the stopChar it will be consumed by the _ and so it doesn't count as stop\n            prevAtom.subScript = [self buildInternal:true];\n            continue;\n        } else if (ch == '{') {\n            // this puts us in a recursive routine, and sets oneCharOnly to false and no stop character\n            MTMathList* sublist = [self buildInternal:false stopChar:'}'];\n            prevAtom = [sublist.atoms lastObject];\n            [list append:sublist];\n            if (oneCharOnly) {\n                return list;\n            }\n            continue;\n        } else if (ch == '}') {\n            NSAssert(!oneCharOnly, @\"This should have been handled before\");\n            NSAssert(stop == 0, @\"This should have been handled before\");\n            // We encountered a closing brace when there is no stop set, that means there was no\n            // corresponding opening brace.\n            NSString* errorMessage = @\"Mismatched braces.\";\n            [self setError:MTParseErrorMismatchBraces message:errorMessage];\n            return nil;\n        } else if (ch == '\\\\') {\n            // \\ means a command\n            NSString* command = [self readCommand];\n            if ([command isEqualToString:@\"not\"]) {\n                // flexible way using not\n                _notCommand = YES;\n                continue;\n            }\n            if (_notCommand && command && command.length > 0) {\n                command = [NSString stringWithFormat:@\"n%@\", command];\n                _notCommand = NO;\n            }\n            NSArray *sizeCommand = [self sizedCommands];\n            if ([sizeCommand containsObject:command]) {\n                _nowSizedCommand = command;\n                atom = [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\"];\n            }\n            MTMathList* done = [self stopCommand:command list:list stopChar:stop];\n            if (done) {\n                return done;\n            } else if (_error) {\n                return nil;\n            }\n            if ([self applyModifier:command atom:prevAtom]) {\n                continue;\n            }\n            MTFontStyle fontStyle = [MTMathAtomFactory fontStyleWithName:command];\n            if (fontStyle != NSNotFound) {\n                BOOL oldSpacesAllowed = _spacesAllowed;\n                // Text has special consideration where it allows spaces without escaping.\n                _spacesAllowed = [command isEqualToString:@\"text\"];\n                MTFontStyle oldFontStyle = _currentFontStyle;\n                _currentFontStyle = fontStyle;\n                MTMathList* sublist = [self buildInternal:true];\n                // Restore the font style.\n                _currentFontStyle = oldFontStyle;\n                _spacesAllowed = oldSpacesAllowed;\n\n                prevAtom = [sublist.atoms lastObject];\n                [list append:sublist];\n                if (oneCharOnly) {\n                    return list;\n                }\n                continue;\n            }\n            atom = [self atomForCommand:command];\n            if (prevAtom != nil && prevAtom.type == kMTMathAtomStyle) {\n                [atom updateSizeTypeWithStyle:((MTMathStyle *)prevAtom).style];\n            }\n           \n            if (atom == nil) {\n                // this was an unknown command,\n                // we flag an error and return\n                // (note setError will not set the error if there is already one, so we flag internal error\n                // in the odd case that an _error is not set.\n                [self setError:MTParseErrorInternalError message:@\"Internal error\"];\n                return nil;\n            }\n        } else if (ch == '&') {\n            // used for column separation in tables\n            NSAssert(!oneCharOnly, @\"This should have been handled before\");\n            if (_currentEnv) {\n                return list;\n            } else {\n                // Create a new table with the current list and a default env\n                MTMathAtom* table = [self buildTable:nil firstList:list row:NO envConfig:nil];\n                return [MTMathList mathListWithAtoms:table, nil];\n            }\n        } else if (_spacesAllowed && ch == ' ') {\n            // If spaces are allowed then spaces do not need escaping with a \\ before being used.\n            atom = [MTMathAtomFactory atomForLatexSymbolName:@\" \"];\n        } else {\n            atom = [MTMathAtomFactory atomForCharacter:ch];\n            if (!atom) {\n                // Not a recognized character\n                continue;\n            }\n            if (prevAtom != nil && prevAtom.type == kMTMathAtomStyle) {\n                [atom updateSizeTypeWithStyle:((MTMathStyle *)prevAtom).style];\n            }\n        }\n        NSAssert(atom != nil, @\"Atom shouldn't be nil\");\n        atom.fontStyle = _currentFontStyle;\n        if ([_nowSizedCommand isEqualToString:@\"small\"]) {\n            atom.sizeType = MTSizeTypeSmall;\n        } else if ([_nowSizedCommand isEqualToString:@\"large\"]) {\n            atom.sizeType = MTSizeTypelarge;\n        } else if ([_nowSizedCommand isEqualToString:@\"Large\"]) {\n            atom.sizeType = MTSizeTypeLarge;\n        } else if ([_nowSizedCommand isEqualToString:@\"LARGE\"]) {\n            atom.sizeType = MTSizeTypeLARGE;\n        }\n        [list addAtom:atom];\n        prevAtom = atom;\n        \n        if (oneCharOnly) {\n            // we consumed our onechar\n            return list;\n        }\n    }\n    if (stop > 0) {\n        if (stop == '}') {\n            // We did not find a corresponding closing brace.\n            [self setError:MTParseErrorMismatchBraces message:@\"Missing closing brace\"];\n        } else {\n            // we never found our stop character\n            NSString* errorMessage = [NSString stringWithFormat:@\"Expected character not found: %d\", stop];\n            [self setError:MTParseErrorCharacterNotFound message:errorMessage];\n        }\n    }\n    return list;\n}\n\n- (NSString*) readString\n{\n    // a string of all upper and lower case characters.\n    NSMutableString* mutable = [NSMutableString string];\n    while([self hasCharacters]) {\n        unichar ch = [self getNextCharacter];\n        if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {\n            [mutable appendString:[NSString stringWithCharacters:&ch length:1]];\n        } else {\n            // we went too far\n            [self unlookCharacter];\n            break;\n        }\n    }\n    return mutable;\n}\n\n- (NSString*) readStringWithExpectChars:(NSString *)chars\n{\n    // a string of all upper and lower case characters.\n    NSMutableString* mutable = [NSMutableString string];\n    while([self hasCharacters]) {\n        unichar ch = [self getNextCharacter];\n        if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || [chars containsString:[NSString stringWithCString:(const char *)&ch encoding:NSUTF8StringEncoding]]) {\n            [mutable appendString:[NSString stringWithCharacters:&ch length:1]];\n        } else {\n            // we went too far\n            [self unlookCharacter];\n            break;\n        }\n    }\n    return mutable;\n}\n\n- (NSString*) readColor\n{\n    if (![self expectCharacter:'{']) {\n        // We didn't find an opening brace, so no env found.\n        [self setError:MTParseErrorCharacterNotFound message:@\"Missing {\"];\n        return nil;\n    }\n    \n    // Ignore spaces and nonascii.\n    [self skipSpaces];\n\n    // a string of all upper and lower case characters.\n    NSMutableString* mutable = [NSMutableString string];\n    BOOL colorExtendSyntaxEnabled = YES;\n    BOOL colorNameFormat = colorExtendSyntaxEnabled ? ([self hasCharacters] ? ([self getCurrentCharacter] != '#') : NO) : NO;\n    while([self hasCharacters]) {\n        unichar ch = [self getNextCharacter];\n        if (ch == '#' ||\n            (ch >= 'A' && ch <= 'F') ||\n            (ch >= 'a' && ch <= 'f') ||\n            (ch >= '0' && ch <= '9') ||\n            (colorNameFormat && ch >= 'a' && ch <= 'z')) {\n            [mutable appendString:[NSString stringWithCharacters:&ch length:1]];\n        } else {\n            // we went too far\n            [self unlookCharacter];\n            break;\n        }\n    }\n\n    if (![self expectCharacter:'}']) {\n        // We didn't find an closing brace, so invalid format.\n        [self setError:MTParseErrorCharacterNotFound message:@\"Missing }\"];\n        return nil;\n    }\n    if (colorExtendSyntaxEnabled) {\n        if (colorNameFormat) {\n            return [self colorString:mutable];\n        } else if (mutable.length == kMT_Cmd_ColorStrLen_Short + 1) {\n            NSString *temp = mutable.copy;\n            NSString *mulFinal = @\"#\".mutableCopy;\n            for (NSInteger index = 1; index < temp.length; ++index) {\n                NSString *subString = [temp substringWithRange:NSMakeRange(index, 1)];\n                mulFinal = [mulFinal stringByAppendingFormat:@\"%@%@\", subString, subString];\n            }\n            return mulFinal;\n        }\n    }\n\n    return mutable;\n}\n\n- (void) skipSpaces\n{\n    while ([self hasCharacters]) {\n        unichar ch = [self getNextCharacter];\n        if (ch < 0x21 || ch > 0x7E) {\n            // skip non ascii characters and spaces\n            continue;\n        } else {\n            [self unlookCharacter];\n            return;\n        }\n    }\n}\n\n#define MTAssertNotSpace(ch) NSAssert((ch) >= 0x21 && (ch) <= 0x7E, @\"Expected non space character %c\", (ch));\n\n- (BOOL) expectCharacter:(unichar) ch\n{\n    MTAssertNotSpace(ch);\n    [self skipSpaces];\n    \n    if ([self hasCharacters]) {\n        unichar c = [self getNextCharacter];\n        MTAssertNotSpace(c);\n        if (c == ch) {\n            return YES;\n        } else {\n            [self unlookCharacter];\n            return NO;\n        }\n    }\n    return NO;\n}\n\n- (NSString*) readCommand\n{\n    static NSSet<NSNumber*>* singleCharCommands = nil;\n    if (!singleCharCommands) {\n        NSArray* singleChars = @[ @'{', @'}', @'$', @'#', @'%', @'_', @'|', @' ', @',', @'>', @';', @'!', @'\\\\'];\n        singleChars = [singleChars arrayByAddingObject:@':'];\n        singleCharCommands = [[NSSet alloc] initWithArray:singleChars];\n    }\n    if ([self hasCharacters]) {\n        // Check if we have a single character command.\n        unichar ch = [self getNextCharacter];\n        // Single char commands\n        if ([singleCharCommands containsObject:@(ch)]) {\n            return [NSString stringWithCharacters:&ch length:1];\n        } else {\n            // not a known single character command\n            [self unlookCharacter];\n        }\n    }\n    // otherwise a command is a string of all upper and lower case characters.\n    return [self readString];\n}\n\n- (NSString*) readDelimiter\n{\n    // Ignore spaces and nonascii.\n    [self skipSpaces];\n    while([self hasCharacters]) {\n        unichar ch = [self getNextCharacter];\n        MTAssertNotSpace(ch);\n        if (ch == '\\\\') {\n            // \\ means a command\n            NSString* command = [self readCommand];\n            if ([command isEqualToString:@\"|\"]) {\n                // | is a command and also a regular delimiter. We use the || command to\n                // distinguish between the 2 cases for the caller.\n                return @\"||\";\n            }\n            return command;\n        } else {\n            return [NSString stringWithCharacters:&ch length:1];\n        }\n    }\n    // We ran out of characters for delimiter\n    return nil;\n}\n\n- (NSString*) readEnvironment\n{\n    if (![self expectCharacter:'{']) {\n        // We didn't find an opening brace, so no env found.\n        [self setError:MTParseErrorCharacterNotFound message:@\"Missing {\"];\n        return nil;\n    }\n    \n    // Ignore spaces and nonascii.\n    [self skipSpaces];\n    NSString* env = [self readString];\n    \n    if (![self expectCharacter:'}']) {\n        // We didn't find an closing brace, so invalid format.\n        [self setError:MTParseErrorCharacterNotFound message:@\"Missing }\"];\n        return nil;\n    }\n    return env;\n}\n\n- (NSString*) readEnvironmentConfig\n{\n    if (![self expectCharacter:'{']) {\n        return nil;\n    }\n    [self skipSpaces];\n    NSMutableString* mutable = [NSMutableString string];\n    NSInteger left = 1;\n    while([self hasCharacters]) {\n        unichar ch = [self getNextCharacter];\n        if (ch == '{') {\n            left += 1;\n            [mutable appendString:[NSString stringWithCharacters:&ch length:1]];\n        } else if (ch == '}') {\n            left -= 1;\n            if (left > 0) {\n                [mutable appendString:[NSString stringWithCharacters:&ch length:1]];\n            }\n        } else {\n            [mutable appendString:[NSString stringWithCharacters:&ch length:1]];\n        }\n        if (left <= 0) {\n            break;\n        }\n    }\n    if (left > 0) {\n        return nil;\n    }\n    return mutable;\n}\n\n- (MTMathAtom*) getBoundaryAtom:(NSString*) delimiterType\n{\n    NSString* delim = [self readDelimiter];\n    if (!delim) {\n        NSString* errorMessage = [NSString stringWithFormat:@\"Missing delimiter for \\\\%@\", delimiterType];\n        [self setError:MTParseErrorMissingDelimiter message:errorMessage];\n        return nil;\n    }\n    MTMathAtom* boundary = [MTMathAtomFactory boundaryAtomForDelimiterName:delim];\n    if (!boundary) {\n        NSString* errorMessage = [NSString stringWithFormat:@\"Invalid delimiter for \\\\%@: %@\", delimiterType, delim];\n        [self setError:MTParseErrorInvalidDelimiter message:errorMessage];\n        return nil;\n    }\n    return boundary;\n}\n\n- (MTMathAtom*) atomForCommand:(NSString*) command\n{\n    MTMathAtom *atom = [MTMathAtomFactory atomForLatexSymbolName:command];\n    if (atom) {\n        return atom;\n    }\n    MTAccent* accent = [MTMathAtomFactory accentWithName:command];\n    if (accent) {\n        // The command is an accent\n        accent.innerList = [self buildInternal:true];\n        return accent;\n    } else if ([command isEqualToString:@\"frac\"]||[command isEqualToString:@\"dfrac\"]) {\n        // A fraction command has 2 arguments\n        MTFraction* frac = [MTFraction new];\n        frac.numerator = [self buildInternal:true];\n        frac.denominator = [self buildInternal:true];\n        return frac;\n    } else if ([command isEqualToString:@\"tfrac\"]) { // NOTE: 暂时先用frac代替\n        // A fraction command has 2 arguments\n        MTFraction* frac = [MTFraction new];\n        frac.numerator = [self buildInternal:true];\n        frac.denominator = [self buildInternal:true];\n        return frac;\n    }else if ([command isEqualToString:@\"cfrac\"]) {\n        // A fraction command has 2 arguments\n        MTFraction* frac = [MTFraction new];\n        frac.isCfrac = YES;\n        frac.numerator = [self buildInternal:true];\n        frac.denominator = [self buildInternal:true];\n        return frac;\n    } else if ([command isEqualToString:@\"binom\"]) {\n        // A binom command has 2 arguments\n        MTFraction* frac = [[MTFraction alloc] initWithRule:NO];\n        frac.numerator = [self buildInternal:true];\n        frac.denominator = [self buildInternal:true];\n        frac.leftDelimiter = @\"(\";\n        frac.rightDelimiter = @\")\";\n        return frac;\n    } else if ([command isEqualToString:@\"sqrt\"]) {\n        // A sqrt command with one argument\n        MTRadical* rad = [MTRadical new];\n        unichar ch = [self getNextCharacter];\n        if (ch == '[') {\n            // special handling for sqrt[degree]{radicand}\n            rad.degree = [self buildInternal:false stopChar:']'];\n            rad.radicand = [self buildInternal:true];\n        } else {\n            [self unlookCharacter];\n            rad.radicand = [self buildInternal:true];\n        }\n        return rad;\n    } else if ([command isEqualToString:@\"left\"] || [command isEqualToString:@\"bigl\"]) {\n        // Save the current inner while a new one gets built.\n        MTInner* oldInner = _currentInnerAtom;\n        _currentInnerAtom = [MTInner new];\n        _currentInnerAtom.leftBoundary = [self getBoundaryAtom:@\"left\"];\n        if (!_currentInnerAtom.leftBoundary) {\n            return nil;\n        }\n        _currentInnerAtom.innerList = [self buildInternal:false];\n        if (!_currentInnerAtom.rightBoundary) {\n            // A right node would have set the right boundary so we must be missing the right node.\n            NSString* errorMessage = @\"Missing \\\\right\";\n            [self setError:MTParseErrorMissingRight message:errorMessage];\n            return nil;\n        }\n        // reinstate the old inner atom.\n        MTInner* newInner = _currentInnerAtom;\n        _currentInnerAtom = oldInner;\n        return newInner;\n    } else if ([command isEqualToString:@\"middle\"]) {\n        if (!_currentInnerAtom.leftBoundary) {\n            // middle node必须被包围在left和right中\n            NSString* errorMessage = @\"Missing \\\\left\";\n            [self setError:MTParseErrorMissingLeft message:errorMessage];\n            return nil;\n        }\n        \n        MTAdaptive* adaptive = [MTAdaptive new];\n        adaptive.boundary = [self getBoundaryAtom:@\"middle\"];\n        return adaptive;\n    } else if ([command isEqualToString:@\"overline\"]) {\n        // The overline command has 1 arguments\n        MTOverLine* over = [MTOverLine new];\n        over.innerList = [self buildInternal:true];\n        return over;\n    } else if ([command isEqualToString:@\"underline\"]) {\n        // The underline command has 1 arguments\n        MTUnderLine* under = [MTUnderLine new];\n        under.innerList = [self buildInternal:true];\n        return under;\n    } else if ([command isEqualToString:@\"begin\"]) {\n        NSString* env = [self readEnvironment];\n        NSString* envConfig = [self readEnvironmentConfig];\n        \n        if (!env) {\n            return nil;\n        }\n        MTMathAtom* table = [self buildTable:env firstList:nil row:NO envConfig:envConfig];\n        return table;\n    } else if ([command isEqualToString:@\"color\"] ||\n               [command isEqualToString:@\"textcolor\"]) {\n        // A color command has 2 arguments\n        MTMathColor* mathColor = [[MTMathColor alloc] init];\n        mathColor.colorString = [self readColor];\n        mathColor.innerList = [self buildInternal:true];\n        return mathColor;\n    } else if ([command isEqualToString:@\"colorbox\"]) {\n        // A color command has 2 arguments\n        MTMathColorbox* mathColorbox = [[MTMathColorbox alloc] init];\n        mathColorbox.colorString = [self readColor];\n        mathColorbox.innerList = [self buildInternal:true];\n        return mathColorbox;\n    } else if ([command isEqualToString:@\"boxed\"]) {\n        // \\boxed command for math mode\n        MTBoxed* boxed = [[MTBoxed alloc] init];\n        boxed.isMathMode = YES;\n        boxed.innerList = [self buildInternal:false];\n        return boxed;\n    } else if ([command isEqualToString:@\"fbox\"]) {\n        // \\fbox command for text mode\n        MTBoxed* boxed = [[MTBoxed alloc] init];\n        boxed.isMathMode = NO;\n        boxed.innerList = [self buildInternal:false];\n        return boxed;\n    } else if ([command isEqualToString:@\"pmod\"]) {\n        MTMathList *modList = [self buildInternal:true];\n        NSMutableString *modString = [NSMutableString string];\n        for (MTMathAtom *atom in modList.atoms) {\n            if (atom.nucleus.length > 0) {\n                [modString appendString:atom.nucleus];\n            }\n        }\n        MTMathList *pmodList = [MTMathAtomFactory pmod:modString];\n        MTInner *inner = [MTInner new];\n        inner.innerList = pmodList;\n        inner.leftBoundary = [MTMathAtom atomWithType:kMTMathAtomBoundary value:@\"\"];\n        inner.rightBoundary = [MTMathAtom atomWithType:kMTMathAtomBoundary value:@\"\"];\n        return inner;\n    } else if ([command isEqualToString:@\"operatorname\"]) {\n        MTMathList *modList = [self buildInternal:true];\n        NSMutableString *modStr = [NSMutableString string];\n        for (MTMathAtom *atom in modList.atoms) {\n            if (atom.nucleus.length > 0) {\n                [modStr appendString:atom.nucleus];\n            }\n        }\n        return [MTMathAtom atomWithType:kMTMathAtomOrdinary value:modStr];\n    } else if ([command isEqualToString:@\"tag\"]) {\n        BOOL notUseParentheses = [self expectCharacter:'*'];\n        MTMathList *modList = [self buildInternal:true];\n        NSMutableString *modStr = [NSMutableString string];\n        notUseParentheses ? @\"\" : [modStr appendString:@\"(\"];\n        for (MTMathAtom *atom in modList.atoms) {\n            if (atom.nucleus.length > 0) {\n                [modStr appendString:atom.nucleus];\n            }\n        }\n        notUseParentheses ? @\"\" : [modStr appendString:@\")\"];\n        if (_isInlineStyle) {\n            // inline style wont deal tag\n            return [MTMathAtom atomWithType:kMTMathAtomNumber value:@\"\"];\n        }\n        MTMathTag *tag = [[MTMathTag alloc] init];\n        tag.tagStr = [[NSAttributedString alloc] initWithString:modStr];\n        tag.innerList = modList;\n        return tag;\n    } else if ([command isEqualToString:@\":\"]) {\n        return [[MTMathSpace alloc] initWithSpace:4];\n    } else if ([command isEqualToString:@\"hline\"]) {\n        MTHLine* hline = [[MTHLine alloc] init];\n        return hline;\n    } else if ([command isEqualToString:@\"overbrace\"]) {\n        MTOverbrace *overbrace = [[MTOverbrace alloc] init];\n        overbrace.contentor = [self buildBrace:true stopChar:0];\n        overbrace.labelor = [self buildBrace:true stopChar:0];\n        return overbrace;\n    } else if ([command isEqualToString:@\"underbrace\"]) {\n        MTUnderbrace *underbrace = [[MTUnderbrace alloc] init];\n        underbrace.contentor = [self buildBrace:true stopChar:0];\n        underbrace.labelor = [self buildBrace:true stopChar:0];\n        return underbrace;\n    } else if ([command isEqualToString:@\"renewcommand\"] || [command isEqualToString:@\"arraystretch\"]) {\n        return [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\"];\n    } else if ([command isEqualToString:@\"diagbox\"]) {\n        NSString *columNum = [self readEnvironment];\n        NSString *config = [self readEnvironment];\n        return [MTMathAtom atomWithType:kMTMathAtomOrdinary value:[NSString stringWithFormat:@\"%@\\%@\", columNum, config]];\n    } else if ([command isEqualToString:@\"lVert\"] || [command isEqualToString:@\"rVert\"]) {\n        return [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\\u2016\"];\n    } else if ([command isEqualToString:@\"overrightarrow\"]) {\n        MTOverLine *overline = [[MTOverLine alloc] init];\n        overline.useArrow = YES;\n        MTMathList *list = [self buildInternal:YES];\n        overline.innerList = list;\n        return overline;\n    } else if ([[self sizedCommands] containsObject:command]) {\n        return [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\"];\n    } else {\n        NSString* errorMessage = [NSString stringWithFormat:@\"Invalid command \\\\%@\", command];\n        [self setError:MTParseErrorInvalidCommand message:errorMessage];\n        return nil;\n    }\n}\n\n- (MTMathList*) stopCommand:(NSString*) command list:(MTMathList*) list stopChar:(unichar) stopChar\n{\n    static NSDictionary<NSString*, NSArray*>* fractionCommands = nil;\n    if (!fractionCommands) {\n        fractionCommands = @{ @\"over\" : @[],\n                              @\"atop\" : @[],\n                              @\"choose\" : @[ @\"(\", @\")\"],\n                              @\"brack\" : @[ @\"[\", @\"]\"],\n                              @\"brace\" : @[ @\"{\", @\"}\"]};\n    }\n    if ([command isEqualToString:@\"right\"] || [command isEqualToString:@\"bigr\"]) {\n        if (!_currentInnerAtom) {\n            NSString* errorMessage = @\"Missing \\\\left\";\n            [self setError:MTParseErrorMissingLeft message:errorMessage];\n            return nil;\n        }\n        _currentInnerAtom.rightBoundary = [self getBoundaryAtom:command];\n        if (!_currentInnerAtom.rightBoundary) {\n            return nil;\n        }\n        // return the list read so far.\n        return list;\n    } else if ([fractionCommands objectForKey:command]) {\n        MTFraction* frac = nil;\n        if ([command isEqualToString:@\"over\"]) {\n            frac = [[MTFraction alloc] init];\n        } else {\n            frac = [[MTFraction alloc] initWithRule:NO];\n        }\n        NSArray* delims = [fractionCommands objectForKey:command];\n        if (delims.count == 2) {\n            frac.leftDelimiter = delims[0];\n            frac.rightDelimiter = delims[1];\n        }\n        frac.numerator = list;\n        frac.denominator = [self buildInternal:NO stopChar:stopChar];\n        if (_error) {\n            return nil;\n        }\n        MTMathList* fracList = [MTMathList new];\n        [fracList addAtom:frac];\n        return fracList;\n    } else if ([command isEqualToString:@\"\\\\\"] || [command isEqualToString:@\"cr\"]) {\n        if (_currentEnv) {\n            // Stop the current list and increment the row count\n            _currentEnv.numRows++;\n            return list;\n        } else {\n            // Create a new table with the current list and a default env\n            MTMathAtom* table = [self buildTable:nil firstList:list row:YES envConfig:nil];\n            return [MTMathList mathListWithAtoms:table, nil];\n        }\n    } else if ([command isEqualToString:@\"end\"]) {\n        if (!_currentEnv) {\n            NSString* errorMessage = @\"Missing \\\\begin\";\n            [self setError:MTParseErrorMissingBegin message:errorMessage];\n            return nil;\n        }\n        NSString* env = [self readEnvironment];\n        if (!env) {\n            return nil;\n        }\n        if (![env isEqualToString:_currentEnv.envName])\n        {\n            NSString* errorMessage = [NSString stringWithFormat:@\"Begin environment name %@ does not match end name: %@\", _currentEnv.envName, env];\n            [self setError:MTParseErrorInvalidEnv message:errorMessage];\n            return nil;\n        }\n        // Finish the current environment.\n        _currentEnv.ended = YES;\n        return list;\n    }\n    return nil;\n}\n\n// Applies the modifier to the atom. Returns true if modifier applied.\n- (BOOL) applyModifier:(NSString*) modifier atom:(MTMathAtom*) atom\n{\n    if ([modifier isEqualToString:@\"limits\"]) {\n        if (atom.type != kMTMathAtomLargeOperator) {\n            NSString* errorMessage = [NSString stringWithFormat:@\"limits can only be applied to an operator.\"];\n            [self setError:MTParseErrorInvalidLimits message:errorMessage];\n        } else {\n            MTLargeOperator* op = (MTLargeOperator*) atom;\n            op.limits = YES;\n        }\n        return true;\n    } else if ([modifier isEqualToString:@\"nolimits\"]) {\n        if (atom.type != kMTMathAtomLargeOperator) {\n            NSString* errorMessage = [NSString stringWithFormat:@\"nolimits can only be applied to an operator.\"];\n            [self setError:MTParseErrorInvalidLimits message:errorMessage];\n            return YES;\n        } else {\n            MTLargeOperator* op = (MTLargeOperator*) atom;\n            op.limits = NO;\n        }\n        return true;\n    }\n    return false;\n}\n\n- (void) setError:(MTParseErrors) code message:(NSString*) message\n{\n    // Only record the first error.\n    if (!_error) {\n        _error = [NSError errorWithDomain:MTParseError code:code userInfo:@{ NSLocalizedDescriptionKey : message }];\n    }\n}\n\n- (MTMathAtom*) buildTable:(NSString*) env firstList:(MTMathList*) firstList row:(BOOL) isRow envConfig:(NSString *)envConfig\n{\n    // Save the current env till an new one gets built.\n    MTEnvProperties* oldEnv = _currentEnv;\n    _currentEnv = [[MTEnvProperties alloc] initWithName:env config:envConfig];\n    \n    NSError *err = nil;\n    MTMathList *bd = [MTMathListBuilder buildFromString:envConfig ?: @\"\"\n                                                            error:&err];\n    NSInteger currentRow = 0;\n    NSInteger currentCol = 0;\n    NSMutableArray<NSMutableArray<MTMathList*>*>* rows = [NSMutableArray array];\n    rows[0] = [NSMutableArray array];\n    if (firstList) {\n        rows[currentRow][currentCol] = firstList;\n        if (isRow) {\n            _currentEnv.numRows++;\n            currentRow++;\n            rows[currentRow] = [NSMutableArray array];\n        } else {\n            currentCol++;\n        }\n    }\n    while (!_currentEnv.ended && [self hasCharacters]) {\n        MTMathList* list = [self buildInternal:NO];\n        if (!list) {\n            // If there is an error building the list, bail out early.\n            return nil;\n        }\n        rows[currentRow][currentCol] = list;\n        currentCol++;\n        if (_currentEnv.numRows > currentRow) {\n            currentRow = _currentEnv.numRows;\n            if (rows.count > currentRow) {\n                rows[currentRow] = [NSMutableArray array];\n            } else {\n                [rows addObject:[NSMutableArray array]];\n            }\n            currentCol = 0;\n        }\n    }\n    if (!_currentEnv.ended && _currentEnv.envName) {\n        [self setError:MTParseErrorMissingEnd message:@\"Missing \\\\end\"];\n        return nil;\n    }\n    NSError* error;\n    MTMathAtom* table = [MTMathAtomFactory tableWithEnvironment:_currentEnv.envName config:bd rows:rows error:&error];\n    if (!table && !_error) {\n        _error = error;\n        return nil;\n    }\n    // reinstate the old env.\n    _currentEnv = oldEnv;\n    return table;\n}\n\n+ (NSDictionary*) spaceToCommands\n{\n    static NSDictionary* spaceToCommands = nil;\n    if (!spaceToCommands) {\n        spaceToCommands = @{\n                            @3 : @\",\",\n                            @4 : @\">\",\n                            @5 : @\";\",\n                            @(-3) : @\"!\",\n                            @18 : @\"quad\",\n                            @36 : @\"qquad\",\n                    };\n    }\n    return spaceToCommands;\n}\n\n+ (NSDictionary*) styleToCommands\n{\n    static NSDictionary* styleToCommands = nil;\n    if (!styleToCommands) {\n        styleToCommands = @{\n                            @(kMTLineStyleDisplay) : @\"displaystyle\",\n                            @(kMTLineStyleText) : @\"textstyle\",\n                            @(kMTLineStyleScript) : @\"scriptstyle\",\n                            @(kMTLineStyleScriptScript) : @\"scriptscriptstyle\",\n                            @(kMTLineStylebig) : @\"big\",\n                            @(kMTLineStyleBig) : @\"Big\",\n                            @(kMTLineStylebigg) : @\"bigg\",\n                            @(kMTLineStyleBigg) : @\"Bigg\"\n                            };\n    }\n    return styleToCommands;\n}\n\n+ (MTMathList *)buildFromString:(NSString *)str\n{\n    MTMathListBuilder* builder = [[MTMathListBuilder alloc] initWithString:str];\n    return builder.build;\n}\n\n+ (MTMathList *)buildFromString:(NSString *)str error:(NSError *__autoreleasing *)error\n{\n    MTMathListBuilder* builder = [[MTMathListBuilder alloc] initWithString:str];\n    MTMathList* output = [builder build];\n    if (builder.error) {\n        if (error) {\n            *error = builder.error;\n        }\n        return nil;\n    }\n    return output;\n}\n\n+ (NSString*) delimToString:(MTMathAtom*) delim\n{\n    NSString* command = [MTMathAtomFactory delimiterNameForBoundaryAtom:delim];\n    if (command) {\n        NSArray<NSString*>* singleChars = @[ @\"(\", @\")\", @\"[\", @\"]\", @\"<\", @\">\", @\"|\", @\".\", @\"/\"];\n        if ([singleChars containsObject:command]) {\n            return command;\n        } else if ([command isEqualToString:@\"||\"]) {\n            return @\"\\\\|\"; // special case for ||\n        } else {\n            return [NSString stringWithFormat:@\"\\\\%@\", command];\n        }\n    }\n    return @\"\";\n}\n\n+ (NSString *)mathListToString:(MTMathList *)ml\n{\n    NSMutableString* str = [NSMutableString string];\n    MTFontStyle currentfontStyle = kMTFontStyleDefault;\n    for (MTMathAtom* atom in ml.atoms) {\n        if (currentfontStyle != atom.fontStyle) {\n            if (currentfontStyle != kMTFontStyleDefault) {\n                // close the previous font style.\n                [str appendString:@\"}\"];\n            }\n            if (atom.fontStyle != kMTFontStyleDefault) {\n                // open new font style\n                NSString* fontStyleName = [MTMathAtomFactory fontNameForStyle:atom.fontStyle];\n                [str appendFormat:@\"\\\\%@{\", fontStyleName];\n            }\n            currentfontStyle = atom.fontStyle;\n        }\n        if (atom.type == kMTMathAtomFraction) {\n            MTFraction* frac = (MTFraction*) atom;\n            if (frac.hasRule) {\n                [str appendFormat:@\"\\\\frac{%@}{%@}\", [self mathListToString:frac.numerator], [self mathListToString:frac.denominator]];\n            } else {\n                NSString* command = nil;\n                if (!frac.leftDelimiter && !frac.rightDelimiter) {\n                    command = @\"atop\";\n                } else if ([frac.leftDelimiter isEqualToString:@\"(\"] && [frac.rightDelimiter isEqualToString:@\")\"]) {\n                    command = @\"choose\";\n                } else if ([frac.leftDelimiter isEqualToString:@\"{\"] && [frac.rightDelimiter isEqualToString:@\"}\"]) {\n                    command = @\"brace\";\n                } else if ([frac.leftDelimiter isEqualToString:@\"[\"] && [frac.rightDelimiter isEqualToString:@\"]\"]) {\n                    command = @\"brack\";\n                } else {\n                    command = [NSString stringWithFormat:@\"atopwithdelims%@%@\", frac.leftDelimiter, frac.rightDelimiter];\n                }\n                [str appendFormat:@\"{%@ \\\\%@ %@}\", [self mathListToString:frac.numerator], command, [self mathListToString:frac.denominator]];\n            }\n        } else if (atom.type == kMTMathAtomRadical) {\n            [str appendString:@\"\\\\sqrt\"];\n            MTRadical* rad = (MTRadical*) atom;\n            if (rad.degree) {\n                [str appendFormat:@\"[%@]\", [self mathListToString:rad.degree]];\n            }\n            [str appendFormat:@\"{%@}\", [self mathListToString:rad.radicand]];\n        } else if (atom.type == kMTMathAtomInner) {\n            MTInner* inner = (MTInner*) atom;\n            if (inner.leftBoundary || inner.rightBoundary) {\n                if (inner.leftBoundary) {\n                    [str appendFormat:@\"\\\\left%@ \", [self delimToString:inner.leftBoundary]];\n                } else {\n                    [str appendString:@\"\\\\left. \"];\n                }\n                [str appendString:[self mathListToString:inner.innerList]];\n                if (inner.rightBoundary) {\n                    [str appendFormat:@\"\\\\right%@ \", [self delimToString:inner.rightBoundary]];\n                } else {\n                    [str appendString:@\"\\\\right. \"];\n                }\n            } else {\n                [str appendFormat:@\"{%@}\", [self mathListToString:inner.innerList]];\n            }\n        } else if (atom.type == kMTMathAtomTable) {\n            MTMathTable* table = (MTMathTable*) atom;\n            if (table.environment) {\n                [str appendFormat:@\"\\\\begin{%@}\", table.environment];\n            }\n            for (int i = 0; i < table.numRows; i++) {\n                NSArray<MTMathList*>* row = table.cells[i];\n                for (int j = 0; j < row.count; j++) {\n                    MTMathList* cell = row[j];\n                    if ([table.environment isEqualToString:@\"matrix\"]) {\n                        if (cell.atoms.count >= 1 && cell.atoms[0].type == kMTMathAtomStyle) {\n                            // remove the first atom.\n                            NSArray* atoms = [cell.atoms subarrayWithRange:NSMakeRange(1, cell.atoms.count-1)];\n                            cell = [MTMathList mathListWithAtomsArray:atoms];\n                        }\n                    }\n                    if ([table.environment isEqualToString:@\"eqalign\"] || [table.environment isEqualToString:@\"aligned\"] || [table.environment isEqualToString:@\"split\"]) {\n                        if (j == 1 && cell.atoms.count >= 1 && cell.atoms[0].type == kMTMathAtomOrdinary && cell.atoms[0].nucleus.length == 0) {\n                            // Empty nucleus added for spacing. Remove it.\n                            NSArray* atoms = [cell.atoms subarrayWithRange:NSMakeRange(1, cell.atoms.count-1)];\n                            cell = [MTMathList mathListWithAtomsArray:atoms];\n                        }\n                    }\n                    [str appendString:[self mathListToString:cell]];\n                    if (j < row.count - 1) {\n                        [str appendString:@\"&\"];\n                    }\n                }\n                if (i < table.numRows - 1) {\n                    [str appendString:@\"\\\\\\\\ \"];\n                }\n            }\n            if (table.environment) {\n                [str appendFormat:@\"\\\\end{%@}\", table.environment];\n            }\n        } else if (atom.type == kMTMathAtomOverline) {\n            [str appendString:@\"\\\\overline\"];\n            MTOverLine* over = (MTOverLine*) atom;\n            [str appendFormat:@\"{%@}\", [self mathListToString:over.innerList]];\n        } else if (atom.type == kMTMathAtomUnderline) {\n            [str appendString:@\"\\\\underline\"];\n            MTUnderLine* under = (MTUnderLine*) atom;\n            [str appendFormat:@\"{%@}\", [self mathListToString:under.innerList]];\n        } else if (atom.type == kMTMathAtomAccent) {\n            MTAccent* accent = (MTAccent*) atom;\n            [str appendFormat:@\"\\\\%@{%@}\", [MTMathAtomFactory accentName:accent], [self mathListToString:accent.innerList]];\n        } else if (atom.type == kMTMathAtomLargeOperator) {\n            MTLargeOperator* op = (MTLargeOperator*) atom;\n            NSString* command = [MTMathAtomFactory latexSymbolNameForAtom:atom];\n            MTLargeOperator* originalOp = (MTLargeOperator*) [MTMathAtomFactory atomForLatexSymbolName:command];\n            [str appendFormat:@\"\\\\%@ \", command];\n            if (originalOp.limits != op.limits) {\n                if (op.limits) {\n                    [str appendString:@\"\\\\limits \"];\n                } else {\n                    [str appendString:@\"\\\\nolimits \"];\n                }\n            }\n        } else if (atom.type == kMTMathAtomSpace) {\n            MTMathSpace* space = (MTMathSpace*) atom;\n            NSDictionary* spaceToCommands = [MTMathListBuilder spaceToCommands];\n            NSString* command = spaceToCommands[@(space.space)];\n            if (command) {\n                [str appendFormat:@\"\\\\%@ \", command];\n            } else {\n                [str appendFormat:@\"\\\\mkern%.1fmu\", space.space];\n            }\n        } else if (atom.type == kMTMathAtomStyle) {\n            MTMathStyle* style = (MTMathStyle*) atom;\n            NSDictionary* styleToCommands = [MTMathListBuilder styleToCommands];\n            NSString* command = styleToCommands[@(style.style)];\n            [str appendFormat:@\"\\\\%@ \", command];\n        } else if (atom.nucleus.length == 0) {\n            [str appendString:@\"{}\"];\n        } else if ([atom.nucleus isEqualToString:@\"\\u2236\"]) {\n            // math colon\n            [str appendString:@\":\"];\n        } else if ([atom.nucleus isEqualToString:@\"\\u2212\"]) {\n            // math minus\n            [str appendString:@\"-\"];\n        } else {\n            NSString* command = [MTMathAtomFactory latexSymbolNameForAtom:atom];\n            if (command) {\n                [str appendFormat:@\"\\\\%@ \", command];\n            } else {\n                [str appendString:atom.nucleus];\n            }\n        }\n\n        if (atom.superScript) {\n            [str appendFormat:@\"^{%@}\", [self mathListToString:atom.superScript]];\n        }\n        \n        if (atom.subScript) {\n            [str appendFormat:@\"_{%@}\", [self mathListToString:atom.subScript]];\n        }\n    }\n    if (currentfontStyle != kMTFontStyleDefault) {\n        [str appendString:@\"}\"];\n    }\n    return [str copy];\n}\n\n/// 括号解析\n- (MTMathList *)buildBrace:(BOOL)oneCharOnly stopChar:(unichar)stop\n{\n    MTMathList* list = [MTMathList new];\n    NSAssert(!(oneCharOnly && (stop > 0)), @\"Cannot set both oneCharOnly and stopChar.\");\n    MTMathAtom* prevAtom = nil;\n    while([self hasCharacters]) {\n        if (_error) {\n            return nil;\n        }\n        MTMathAtom* atom = nil;\n        unichar ch = [self getNextCharacter];\n        if (oneCharOnly) {\n            if (ch == '^' || ch == '}' || ch == '_' || ch == '&') {\n                // for overbrace/underbrace\n                if (ch == '^' || ch == '_') {\n                    if ([self getNextCharacter] == '{') {\n                        [self unlookCharacter];\n                        continue;\n                    }\n                }\n                [self unlookCharacter];\n                return list;\n            }\n        }\n        if (stop > 0 && ch == stop) {\n            return list;\n        }\n        \n        if (ch == '^') {\n            NSAssert(!oneCharOnly, @\"This should have been handled before\");\n            \n            if (!prevAtom || prevAtom.superScript || !prevAtom.scriptsAllowed) {\n                prevAtom = [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\"];\n                [list addAtom:prevAtom];\n            }\n            prevAtom.superScript = [self buildBrace:YES stopChar:0];\n            continue;\n        } else if (ch == '_') {\n            NSAssert(!oneCharOnly, @\"This should have been handled before\");\n            \n            if (!prevAtom || prevAtom.subScript || !prevAtom.scriptsAllowed) {\n                prevAtom = [MTMathAtom atomWithType:kMTMathAtomOrdinary value:@\"\"];\n                [list addAtom:prevAtom];\n            }\n            prevAtom.subScript = [self buildBrace:YES stopChar:0];\n            continue;\n        } else if (ch == '{') {\n            MTMathList* sublist = [self buildBrace:false stopChar:'}'];\n            prevAtom = [sublist.atoms lastObject];\n            [list append:sublist];\n            if (oneCharOnly) {\n                return list;\n            }\n            continue;\n        } else if (ch == '}') {\n            NSAssert(!oneCharOnly, @\"This should have been handled before\");\n            NSAssert(stop == 0, @\"This should have been handled before\");\n            NSString* errorMessage = @\"Mismatched braces.\";\n            [self setError:MTParseErrorMismatchBraces message:errorMessage];\n            return nil;\n        } else if (ch == '\\\\') {\n            NSString* command = [self readCommand];\n            if ([command isEqualToString:@\"not\"]) {\n                _notCommand = YES;\n                continue;\n            }\n            if (_notCommand && command && command.length > 0) {\n                command = [NSString stringWithFormat:@\"n%@\", command];\n                _notCommand = NO;\n            }\n            NSArray *sizeCommand = [self sizedCommands];\n            if ([sizeCommand containsObject:command]) {\n                _nowSizedCommand = command;\n            }\n            MTMathList* done = [self stopCommand:command list:list stopChar:stop];\n            if (done) {\n                return done;\n            } else if (_error) {\n                return nil;\n            }\n            if ([self applyModifier:command atom:prevAtom]) {\n                continue;\n            }\n            MTFontStyle fontStyle = [MTMathAtomFactory fontStyleWithName:command];\n            if (fontStyle != NSNotFound) {\n                BOOL oldSpacesAllowed = _spacesAllowed;\n                _spacesAllowed = [command isEqualToString:@\"text\"];\n                MTFontStyle oldFontStyle = _currentFontStyle;\n                _currentFontStyle = fontStyle;\n                MTMathList* sublist = [self buildBrace:true stopChar:0];\n                _currentFontStyle = oldFontStyle;\n                _spacesAllowed = oldSpacesAllowed;\n\n                prevAtom = [sublist.atoms lastObject];\n                [list append:sublist];\n                if (oneCharOnly) {\n                    return list;\n                }\n                continue;\n            }\n            atom = [self atomForCommand:command];\n            if (prevAtom != nil && prevAtom.type == kMTMathAtomStyle) {\n                [atom updateSizeTypeWithStyle:((MTMathStyle *)prevAtom).style];\n            }\n           \n            if (atom == nil) {\n                [self setError:MTParseErrorInternalError message:@\"Internal error\"];\n                return nil;\n            }\n        } else if (ch == '&') {\n            NSAssert(!oneCharOnly, @\"This should have been handled before\");\n            if (_currentEnv) {\n                return list;\n            } else {\n                MTMathAtom* table = [self buildTable:nil firstList:list row:NO envConfig:nil];\n                return [MTMathList mathListWithAtoms:table, nil];\n            }\n        } else if (_spacesAllowed && ch == ' ') {\n            atom = [MTMathAtomFactory atomForLatexSymbolName:@\" \"];\n        } else {\n            atom = [MTMathAtomFactory atomForCharacter:ch];\n            if (!atom) {\n                continue;\n            }\n            if (prevAtom != nil && prevAtom.type == kMTMathAtomStyle) {\n                [atom updateSizeTypeWithStyle:((MTMathStyle *)prevAtom).style];\n            }\n        }\n        NSAssert(atom != nil, @\"Atom shouldn't be nil\");\n        atom.fontStyle = _currentFontStyle;\n        if ([_nowSizedCommand isEqualToString:@\"small\"]) {\n            atom.sizeType = MTSizeTypeSmall;\n        } else if ([_nowSizedCommand isEqualToString:@\"large\"]) {\n            atom.sizeType = MTSizeTypelarge;\n        } else if ([_nowSizedCommand isEqualToString:@\"Large\"]) {\n            atom.sizeType = MTSizeTypeLarge;\n        } else if ([_nowSizedCommand isEqualToString:@\"LARGE\"]) {\n            atom.sizeType = MTSizeTypeLARGE;\n        }\n        [list addAtom:atom];\n        prevAtom = atom;\n        \n        if (oneCharOnly) {\n            return list;\n        }\n    }\n    if (stop > 0) {\n        if (stop == '}') {\n            [self setError:MTParseErrorMismatchBraces message:@\"Missing closing brace\"];\n        } else {\n            NSString* errorMessage = [NSString stringWithFormat:@\"Expected character not found: %d\", stop];\n            [self setError:MTParseErrorCharacterNotFound message:errorMessage];\n        }\n    }\n    return list;\n}\n\n//MARK : Color Util\n\n- (NSString *)colorString:(NSString *)name {\n    if ([name isKindOfClass:NSString.class] && name.length > 0) {\n        NSDictionary<NSString *, NSString *> *colorHexMap = @{\n            @\"black\"            : @\"#000000\",\n            @\"white\"            : @\"#ffffff\",\n            @\"red\"              : @\"#ff0000\",\n            @\"green\"            : @\"#00ff00\",\n            @\"blue\"             : @\"#0000ff\",\n            @\"cyan\"             : @\"#00ffff\",\n            @\"magenta\"          : @\"#ff00ff\",\n            @\"yellow\"           : @\"#ffff00\",\n            @\"greenyellow\"      : @\"#d9ff4f\",\n            @\"goldenrod\"        : @\"#ffe629\",\n            @\"dandelion\"        : @\"#ffb529\",\n            @\"apricot\"          : @\"#ffad7a\",\n            @\"peach\"            : @\"#ff804d\",\n            @\"melon\"            : @\"#ff8a80\",\n            @\"yelloworange\"     : @\"#ff9400\",\n            @\"orange\"           : @\"#ff6321\",\n            @\"burntorange\"      : @\"#ff7d00\",\n            @\"bittersweet\"      : @\"#c23000\",\n            @\"redorange\"        : @\"#ff3b21\",\n            @\"mahogany\"         : @\"#a61916\",\n            @\"maroon\"           : @\"#ad1737\",\n            @\"brickred\"         : @\"#b8140b\",\n            @\"orangered\"        : @\"#ff0080\",\n            @\"rubinered\"        : @\"#ff00de\",\n            @\"wildstrawberry\"   : @\"#ff0a9c\",\n            @\"salmon\"           : @\"#ff789e\",\n            @\"carnationpink\"    : @\"#ff5eff\",\n            @\"violetred\"        : @\"#ff30ff\",\n            @\"rhodamine\"        : @\"#ff2eff\",\n            @\"mulberry\"         : @\"#a519fa\",\n            @\"redviolet\"        : @\"#9d11a8\",\n            @\"fuchsia\"          : @\"#7c15eb\",\n            @\"lavender\"         : @\"#ff85ff\",\n            @\"thistle\"          : @\"#e069ff\",\n            @\"orchid\"           : @\"#ad5cff\",\n            @\"darkorchid\"       : @\"#9933cc\",\n            @\"purple\"           : @\"#8c24ff\",\n            @\"plum\"             : @\"#8000ff\",\n            @\"violet\"           : @\"#361fff\",\n            @\"royalpurple\"      : @\"#4019ff\",\n            @\"blueviolet\"       : @\"#2216f5\",\n            @\"periwinkle\"       : @\"#6e73ff\",\n            @\"cadetblue\"        : @\"#616ec4\",\n            @\"cornflowerblue\"   : @\"#59deff\",\n            @\"midnightblue\"     : @\"#037e91\",\n            @\"navyblue\"         : @\"#0f75ff\",\n            @\"royalblue\"        : @\"#0080ff\",\n            @\"cerulean\"         : @\"#0fe3ff\",\n            @\"processblue\"      : @\"#0affff\",\n            @\"skyblue\"          : @\"#61ffe0\",\n            @\"turquoise\"        : @\"#26ffcc\",\n            @\"tealblue\"         : @\"#23faa5\",\n            @\"aquamarine\"       : @\"#2effb3\",\n            @\"bluegreen\"        : @\"#26ffab\",\n            @\"emerald\"          : @\"#00ff80\",\n            @\"junglegreen\"      : @\"#03ff7a\",\n            @\"seagreen\"         : @\"#4fff80\",\n            @\"forestgreen\"      : @\"#14e01b\",\n            @\"pinegreen\"        : @\"#0fbf4e\",\n            @\"limegreen\"        : @\"#80ff00\",\n            @\"lime\"             : @\"#80ff00\",\n            @\"yellowgreen\"      : @\"#8fff42\",\n            @\"springgreen\"      : @\"#bdff3d\",\n            @\"olivegreen\"       : @\"#379908\",\n            @\"rawsienna\"        : @\"#8c2700\",\n            @\"sepia\"            : @\"#4d0d00\",\n            @\"brown\"            : @\"#661300\",\n            @\"tan\"              : @\"#db9470\",\n            @\"gray\"             : @\"#808080\"\n        };\n        return colorHexMap[name];\n    }\n    return nil;\n}\n\n- (NSArray *)sizedCommands {\n    return @[@\"small\", @\"large\", @\"Large\", @\"LARGE\"];\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/lib/MTMathListIndex.h",
    "content": "//\n//  MTMathListIndex.h\n//\n//  Created by Kostub Deshmukh on 9/6/13.\n//  Copyright (C) 2013 MathChat\n//   \n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n@import Foundation;\n\n/** \n * An index that points to a particular character in the MTMathList. The index is a LinkedList that represents\n * a path from the beginning of the MTMathList to reach a particular atom in the list. The next node of the path\n * is represented by the subIndex. The path terminates when the subIndex is nil.\n *\n * If there is a subIndex, the subIndexType denotes what branch the path takes (i.e. superscript, subscript, \n * numerator, denominator etc.).\n * e.g in the expression 25^{2/4} the index of the character 4 is represented as:\n * (1, superscript) -> (0, denominator) -> (0, none)\n * This can be interpreted as start at index 1 (i.e. the 5) go up to the superscript.\n * Then look at index 0 (i.e. 2/4) and go to the denominator. Then look up index 0 (i.e. the 4) which this final\n * index.\n * \n * The level of an index is the number of nodes in the LinkedList to get to the final path.\n */\n@interface MTMathListIndex : NSObject\n\n/**\n @typedef MTMathListSubIndexType\n @brief The type of the subindex.\n \n The type of the subindex denotes what branch the path to the atom that this index points to takes.\n */\ntypedef NS_ENUM(unsigned int, MTMathListSubIndexType) {\n    /// The index denotes the whole atom, subIndex is nil.\n    kMTSubIndexTypeNone  = 0,\n    /// The position in the subindex is an index into the nucleus\n    kMTSubIndexTypeNucleus,\n    /// The subindex indexes into the superscript.\n    kMTSubIndexTypeSuperscript,\n    /// The subindex indexes into the subscript\n    kMTSubIndexTypeSubscript,\n    /// The subindex indexes into the numerator (only valid for fractions)\n    kMTSubIndexTypeNumerator,\n    /// The subindex indexes into the denominator (only valid for fractions)\n    kMTSubIndexTypeDenominator,\n    /// The subindex indexes into the radicand (only valid for radicals)\n    kMTSubIndexTypeRadicand,\n    /// The subindex indexes into the degree (only valid for radicals)\n    kMTSubIndexTypeDegree,\n    /// The subindex indexes into the inner list (only valid for inner)\n    kMTSubIndexTypeInner\n};\n\n\n/// The index of the associated atom.\n@property (nonatomic, readonly) NSUInteger atomIndex;\n/// The type of subindex, e.g. superscript, numerator etc.\n@property (nonatomic, readonly) MTMathListSubIndexType subIndexType;\n/// The index into the sublist.\n@property (nonatomic, readonly, nullable) MTMathListIndex* subIndex;\n\n/// Returns the previous index if present. Returns `nil` if there is no previous index.\n- (nullable MTMathListIndex*) previous;\n/// Returns the next index.\n- (nonnull MTMathListIndex*) next;\n\n/** \n * Returns true if this index represents the beginning of a line. Note there may be multiple lines in a MTMathList,\n * e.g. a superscript or a fraction numerator. This returns true if the innermost subindex points to the beginning of a\n * line.\n */\n- (BOOL) isAtBeginningOfLine;\n\n/** Returns the type of the innermost sub index. */\n- (MTMathListSubIndexType) finalSubIndexType;\n\n/** Returns true if any of the subIndexes of this index have the given type. */\n- (BOOL) hasSubIndexOfType:(MTMathListSubIndexType) subIndexType;\n\n/** Creates a new index by attaching this index at the end of the current one. */\n- (nonnull MTMathListIndex*) levelUpWithSubIndex:(nullable MTMathListIndex*) subIndex type:(MTMathListSubIndexType) type;\n/** Creates a new index by removing the last index item. If this is the last one, then returns nil. */\n- (nullable MTMathListIndex*) levelDown;\n\n- (nonnull instancetype)init NS_UNAVAILABLE;\n- (BOOL)isEqual:(nullable id)object;\n- (NSUInteger)hash;\n- (nonnull NSString *)description;\n\n/** Factory function to create a `MTMathListIndex` with no subindexes.\n    @param index The index of the atom that the `MTMathListIndex` points at.\n */\n+ (nonnull instancetype) level0Index:(NSUInteger) index;\n\n/** Factory function to create at `MTMathListIndex` with a given subIndex.\n    @param location The location at which the subIndex should is present.\n    @param subIndex The subIndex to be added. Can be nil.\n    @param type The type of the subIndex.\n */\n+ (nonnull instancetype) indexAtLocation:(NSUInteger) location withSubIndex:(nullable MTMathListIndex*) subIndex type:(MTMathListSubIndexType) type;\n\n@end\n\n/** A range of atoms in an `MTMathList`. This is similar to `NSRange` with a start and length, except that \n    the starting location is defined by a `MTMathListIndex` rather than an ordinary integer.\n */\n@interface  MTMathListRange : NSObject\n\n- (nonnull instancetype)init NS_UNAVAILABLE;\n\n/// Creates a valid range.\n+ (nonnull MTMathListRange*) makeRange:(nonnull MTMathListIndex*) start length:(NSUInteger) length;\n/// Creates a range at level 0 from the give range.\n+ (nonnull MTMathListRange *)makeRangeForRange:(NSRange)range;\n/// Makes a range of length 1\n+ (nonnull MTMathListRange*) makeRange:(nonnull MTMathListIndex*) start;\n/// Makes a range of length 1 at the level 0 index start\n+ (nonnull MTMathListRange*) makeRangeForIndex:(NSUInteger) start;\n\n/// The starting location of the range. Cannot be `nil`.\n@property (nonatomic, readonly, nonnull) MTMathListIndex* start;\n/// The size of the range.\n@property (nonatomic, readonly) NSUInteger length;\n\n- (nullable MTMathListRange*) subIndexRange;\n/// Appends the current range to range and returns the resulting range. Any elements between the two are included in the range.\n- (nullable MTMathListRange*) unionRange:(nonnull MTMathListRange*) range;\n/// Unions all ranges in the given array of ranges\n+ (nullable MTMathListRange*) unionRanges:(nonnull NSArray<MTMathListRange*>*) ranges;\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/lib/MTMathListIndex.m",
    "content": "//\n//  MTMathListIndex.m\n//\n//  Created by Kostub Deshmukh on 9/6/13.\n//  Copyright (C) 2013 MathChat\n//   \n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n#import \"MTMathListIndex.h\"\n\n#pragma mark - MTMathListIndex\n\n@interface MTMathListIndex ()\n\n@property (nonatomic, readwrite) NSUInteger atomIndex;\n@property (nonatomic, readwrite) MTMathListSubIndexType subIndexType;\n@property (nonatomic, readwrite, nullable) MTMathListIndex* subIndex;\n\n@end\n\n@implementation MTMathListIndex\n\n+ (id)level0Index:(NSUInteger)index\n{\n    MTMathListIndex* mlIndex = [MTMathListIndex new];\n    mlIndex.atomIndex = index;\n    return mlIndex;\n}\n\n+ (instancetype)indexAtLocation:(NSUInteger)location withSubIndex:(MTMathListIndex *)subIndex type:(MTMathListSubIndexType)type\n{\n    MTMathListIndex* index = [self level0Index:location];\n    index.subIndexType = type;\n    index.subIndex = subIndex;\n    return index;\n}\n\n- (MTMathListIndex *)levelUpWithSubIndex:(MTMathListIndex *)subIndex type:(MTMathListSubIndexType)type\n{\n    if (self.subIndexType == kMTSubIndexTypeNone) {\n        return [MTMathListIndex indexAtLocation:self.atomIndex withSubIndex:subIndex type:type];\n    }\n    // we have to recurse\n    return [MTMathListIndex indexAtLocation:self.atomIndex withSubIndex:[self.subIndex levelUpWithSubIndex:subIndex type:type] type:self.subIndexType];\n}\n\n- (MTMathListIndex *)levelDown\n{\n    if (self.subIndexType == kMTSubIndexTypeNone) {\n        return nil;\n    }\n    // recurse\n    MTMathListIndex* subIndexDown = self.subIndex.levelDown;\n    if (subIndexDown) {\n        return [MTMathListIndex indexAtLocation:self.atomIndex withSubIndex:subIndexDown type:self.subIndexType];\n    } else {\n        return [MTMathListIndex level0Index:self.atomIndex];\n    }\n}\n\n- (MTMathListIndex *)previous\n{\n    if (self.subIndexType == kMTSubIndexTypeNone) {\n        if (self.atomIndex > 0) {\n            return [MTMathListIndex level0Index:self.atomIndex - 1];\n        }\n    } else {\n        MTMathListIndex* prevSubIndex = self.subIndex.previous;\n        if (prevSubIndex) {\n            return [MTMathListIndex indexAtLocation:self.atomIndex withSubIndex:prevSubIndex type:self.subIndexType];\n        }\n    }\n    return nil;\n}\n\n- (MTMathListIndex *)next\n{\n    if (self.subIndexType == kMTSubIndexTypeNone) {\n        return [MTMathListIndex level0Index:self.atomIndex + 1];\n    } else if (self.subIndexType == kMTSubIndexTypeNucleus) {\n        return [MTMathListIndex indexAtLocation:self.atomIndex + 1 withSubIndex:self.subIndex type:self.subIndexType];\n    } else {\n        return [MTMathListIndex indexAtLocation:self.atomIndex withSubIndex:self.subIndex.next type:self.subIndexType];\n    }\n}\n\n- (BOOL)hasSubIndexOfType:(MTMathListSubIndexType)subIndexType\n{\n    if (self.subIndexType == subIndexType) {\n        return true;\n    } else {\n        return [self.subIndex hasSubIndexOfType:subIndexType];\n    }\n}\n\n- (BOOL) isAtBeginningOfLine\n{\n    return (self.finalIndex == 0);\n}\n\n\n- (BOOL)isAtSameLevel:(MTMathListIndex *)other\n{\n    if (self.subIndexType != other.subIndexType) {\n        return false;\n    } else if (self.subIndexType == kMTSubIndexTypeNone) {\n        // No subindexes, they are at the same level.\n        return true;\n    } else if (self.atomIndex != other.atomIndex) {\n        // the subindexes are used in different atoms\n        return false;\n    } else {\n        return [self.subIndex isAtSameLevel:other.subIndex];\n    }\n}\n\n- (NSUInteger) finalIndex\n{\n    if (self.subIndexType == kMTSubIndexTypeNone) {\n        return self.atomIndex;\n    } else {\n        return self.subIndex.finalIndex;\n    }\n}\n\n- (MTMathListSubIndexType) finalSubIndexType\n{\n    if (self.subIndex.subIndex) {\n        return [self.subIndex finalSubIndexType];\n    } else {\n        return self.subIndexType;\n    }\n}\n\n- (NSString *)description\n{\n    if (self.subIndex) {\n        return [NSString stringWithFormat:@\"[%lu, %d:%@]\", (unsigned long)self.atomIndex, self.subIndexType, self.subIndex];\n    }\n    return [NSString stringWithFormat:@\"[%lu]\", (unsigned long)self.atomIndex];\n}\n\n- (BOOL)isEqualToIndex:(MTMathListIndex *)index\n{\n    if (self.atomIndex != index.atomIndex || self.subIndexType != index.subIndexType) {\n        return NO;\n    }\n    if (self.subIndex) {\n        return [self.subIndex isEqual:index.subIndex];\n    } else {\n        return (index.subIndex == nil);\n    }\n}\n\n- (BOOL) isEqual:(id) anObject\n{\n    if (self == anObject) {\n        return YES;\n    }\n    if (!anObject || ![anObject isKindOfClass:[self class]]) {\n        return NO;\n    }\n    return [self isEqualToIndex:anObject];\n}\n\n- (NSUInteger) hash\n{\n    const int prime = 31;\n    NSUInteger hash = self.atomIndex;\n    hash = hash * prime + self.subIndexType;\n    hash = hash * prime + self.subIndex.hash;\n    return hash;\n}\n\n@end\n\n@interface MTMathListRange ()\n\n- (instancetype)initWithStart:(MTMathListIndex*) start length:(NSUInteger) length NS_DESIGNATED_INITIALIZER;\n\n@end\n\n@implementation MTMathListRange\n\n- (instancetype)initWithStart:(MTMathListIndex*) start length:(NSUInteger) length\n{\n    self = [super init];\n    if (self) {\n        _start = start;\n        _length = length;\n    }\n    return self;\n}\n\n+ (MTMathListRange *)makeRange:(MTMathListIndex *)start length:(NSUInteger)length\n{\n    return [[MTMathListRange alloc] initWithStart:start length:length];\n}\n\n+ (MTMathListRange *)makeRange:(MTMathListIndex *)start\n{\n    return [self makeRange:start length:1];\n}\n\n+ (MTMathListRange *)makeRangeForIndex:(NSUInteger)start\n{\n    return [self makeRange:[MTMathListIndex level0Index:start]];\n}\n\n+ (MTMathListRange *)makeRangeForRange:(NSRange)range\n{\n    return [self makeRange:[MTMathListIndex level0Index:range.location] length:range.length];\n}\n\n- (NSString *)description\n{\n    return [NSString stringWithFormat:@\"(%@, %lu)\", self.start, (unsigned long)self.length];\n}\n\n- (MTMathListRange *)subIndexRange\n{\n    if (self.start.subIndexType != kMTSubIndexTypeNone) {\n        return [MTMathListRange makeRange:self.start.subIndex length:self.length];\n    }\n    return nil;\n}\n\n- (NSRange) finalRange\n{\n    return NSMakeRange(self.start.finalIndex, self.length);\n}\n\n- (MTMathListRange *)unionRange:(MTMathListRange *)range\n{\n    if (![self.start isAtSameLevel:range.start]) {\n        NSAssert(false, @\"Cannot union ranges at different levels: %@, %@\", self, range);\n        return nil;\n    }\n    \n    NSRange r1 = self.finalRange;\n    NSRange r2 = range.finalRange;\n    NSRange unionRange = NSUnionRange(r1, r2);\n    MTMathListIndex* start;\n    if (unionRange.location == r1.location) {\n        start = self.start;\n    } else {\n        assert(unionRange.location == r2.location);\n        start = range.start;\n    }\n    return [MTMathListRange makeRange:start length:unionRange.length];\n}\n\n+ (MTMathListRange *)unionRanges:(NSArray *)ranges\n{\n    NSAssert((ranges.count > 0), @\"Need to union at least one range\");\n    \n    MTMathListRange* unioned = ranges[0];\n    for (int i = 1; i < ranges.count; i++) {\n        MTMathListRange* next = ranges[i];\n        [unioned unionRange:next];\n    }\n    return unioned;\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/lib/MTUnicode.h",
    "content": "//\n//  MTUnicode.h\n//  iosMath\n//\n//  Created by Kostub Deshmukh on 8/16/14.\n//  Copyright (C) 2013 MathChat\n//   \n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n#import <Foundation/Foundation.h>\n\n\n@interface NSString (Unicode)\n\n- (NSUInteger) unicodeLength;\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/lib/MTUnicode.m",
    "content": "//\n//  MTUnicode.m\n//  iosMath\n//\n//  Created by Kostub Deshmukh on 8/16/14.\n//  Copyright (C) 2013 MathChat\n//   \n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n#import \"MTUnicode.h\"\n\n@implementation NSString (Unicode)\n\n\n- (NSUInteger)unicodeLength\n{\n    // Each unicode char is represented as 4 bytes in utf-32.\n    return [self lengthOfBytesUsingEncoding:NSUTF32StringEncoding] / 4;\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/render/MTConfig.h",
    "content": "//\n//  MTConfig.h\n//  MacOSMath\n//\n//  Created by 安志钢 on 17-01-09.\n//\n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n// Make TARGET_OS_IPHONE macro visible.\n#include <TargetConditionals.h>\n\n// Type definitions.\n#if TARGET_OS_IPHONE\n// TARGET_OS_MAC is defined as 1 for both Mac OS and iOS,\n// so TARGET_OS_IPHONE is reliable.\n@import UIKit;\n#import \"UIColor+HexString.h\"\n\ntypedef UIView          MTView;\ntypedef UIColor         MTColor;\ntypedef UIBezierPath    MTBezierPath;\ntypedef UIEdgeInsets    MTEdgeInsets;\ntypedef UILabel         MTLabel;\ntypedef CGRect          MTRect;\n\n#define MTEdgeInsetsZero UIEdgeInsetsZero\n#define MTGraphicsGetCurrentContext() UIGraphicsGetCurrentContext()\n\n#else\n@import AppKit;\n#import \"NSBezierPath+addLineToPoint.h\"\n#import \"NSView+backgroundColor.h\"\n#import \"NSColor+HexString.h\"\n#import \"MTLabel.h\"\n\ntypedef NSView          MTView;\ntypedef NSColor         MTColor;\ntypedef NSBezierPath    MTBezierPath;\ntypedef NSEdgeInsets    MTEdgeInsets;\ntypedef NSRect          MTRect;\n\n// For backward compatibility, DO NOT use NSEdgeInsetsZero (Available from OS X 10.10).\n#define MTEdgeInsetsZero (NSEdgeInsetsMake(0.0f, 0.0f, 0.0f, 0.0f));\n#define MTGraphicsGetCurrentContext() ([[NSGraphicsContext currentContext] graphicsPort])\n\n#endif  // TARGET_OS_IPHONE\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/render/MTFont.h",
    "content": "//\n//  MTFont.h\n//  iosMath\n//\n//  Created by Kostub Deshmukh on 5/18/16.\n//\n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n@import CoreText;\n@import CoreGraphics;\n@import Foundation;\n\n/** MTFont wraps the inconvenient distinction between CTFont and CGFont as well\n as the data loaded from the math table.\n */\n@interface MTFont : NSObject\n\n/** Returns a copy of this font but with a different size. */\n- (nonnull MTFont*) copyFontWithSize:(CGFloat) size;\n\n/** The size of this font in points. */\n@property (nonatomic, readonly) CGFloat fontSize;\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/render/MTFont.m",
    "content": "//\n//  MTFont.m\n//  iosMath\n//\n//  Created by Kostub Deshmukh on 5/18/16.\n//\n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n#import \"MTFont.h\"\n#import \"MTFont+Internal.h\"\n\n@interface MTFont ()\n\n@property (nonatomic, assign) CGFontRef defaultCGFont;\n@property (nonatomic, assign) CTFontRef ctFont;\n@property (nonatomic, strong) MTFontMathTable* mathTable;\n@property (nonatomic, strong) NSDictionary* rawMathTable;\n\n@end\n\n@implementation MTFont\n\n- (instancetype)initFontWithName:(NSString *)name size:(CGFloat)size\n{\n    self = [super init];\n    if (self != nil) {\n        // CTFontCreateWithName does not load the complete math font, it only has about half the glyphs of the full math font.\n        // In particular it does not have the math italic characters which breaks our variable rendering.\n        // So we first load a CGFont from the file and then convert it to a CTFont.\n\n        NSBundle* bundle = [MTFont fontBundle];\n        NSString* fontPath = [bundle pathForResource:name ofType:@\"otf\"];\n        CGDataProviderRef fontDataProvider = CGDataProviderCreateWithFilename(fontPath.UTF8String);\n        _defaultCGFont = CGFontCreateWithDataProvider(fontDataProvider);\n        CFRelease(fontDataProvider);\n\n        _ctFont = CTFontCreateWithGraphicsFont(self.defaultCGFont, size, nil, nil);\n\n        NSString* mathTablePlist = [bundle pathForResource:name ofType:@\"plist\"];\n        NSDictionary* dict = [NSDictionary dictionaryWithContentsOfFile:mathTablePlist];\n        self.rawMathTable = dict;\n        self.mathTable = [[MTFontMathTable alloc] initWithFont:self mathTable:_rawMathTable];\n    }\n    return self;\n}\n\n- (void)setDefaultCGFont:(CGFontRef)defaultCGFont\n{\n    if (_defaultCGFont != nil) {\n        CFRelease(_defaultCGFont);\n    }\n    if (defaultCGFont != nil) {\n        CFRetain(defaultCGFont);\n    }\n    _defaultCGFont = defaultCGFont;\n}\n\n- (void)setCtFont:(CTFontRef)ctFont {\n    if (_ctFont != nil) {\n        CFRelease(_ctFont);\n    }\n    if (ctFont != nil) {\n        CFRetain(ctFont);\n    }\n    _ctFont = ctFont;\n}\n\n+ (NSBundle*) fontBundle\n{\n    // Uses bundle for class so that this can be access by the unit tests.\n    return [NSBundle bundleWithURL:[[NSBundle bundleForClass:[self class]] URLForResource:@\"mathFonts\" withExtension:@\"bundle\"]];\n}\n\n- (MTFont *)copyFontWithSize:(CGFloat)size\n{\n    MTFont* copyFont = [[[self class] alloc] init];\n    copyFont.defaultCGFont = self.defaultCGFont;\n    CTFontRef newCtFont = CTFontCreateWithGraphicsFont(self.defaultCGFont, size, nil, nil);\n    copyFont.ctFont = newCtFont;\n    copyFont.rawMathTable = self.rawMathTable;\n    copyFont.mathTable = [[MTFontMathTable alloc] initWithFont:copyFont mathTable:copyFont.rawMathTable];\n    CFRelease(newCtFont);\n    return copyFont;\n}\n\n-(NSString*) getGlyphName:(CGGlyph) glyph\n{\n    NSString* name = CFBridgingRelease(CGFontCopyGlyphNameForGlyph(self.defaultCGFont, glyph));\n    return name;\n}\n\n- (CGGlyph)getGlyphWithName:(NSString *)glyphName\n{\n    return CGFontGetGlyphWithGlyphName(self.defaultCGFont, (__bridge CFStringRef) glyphName);\n}\n\n- (CGFloat)fontSize\n{\n    return CTFontGetSize(self.ctFont);\n}\n\n- (void)dealloc\n{\n    self.defaultCGFont=nil;\n    self.ctFont=nil;\n}\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/render/MTFontManager.h",
    "content": "//\n//  MTFontManager.h\n//  iosMath\n//\n//  Created by Kostub Deshmukh on 8/30/13.\n//  Copyright (C) 2013 MathChat\n//   \n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//  \n\n@import Foundation;\n\n#import \"MTFont.h\"\n\n/** A manager to load font files from disc and keep them\n in memory. */\n@interface MTFontManager : NSObject\n\n/** Get the singleton instance of MTFontManager. */\n+ (nonnull instancetype) fontManager;\n\n/** Returns the default font, which is Latin Modern Math with 20pt */\n- (nonnull MTFont*) defaultFont;\n\n/** Load a font with the given name. For the font to load, there\n must be a .otf file with the given name and a .plist file containing\n the math table data. The math table can be extracted using math_table_to_plist\n python script.\n @param name The name of the font file.\n @param size The size of the font to return.\n */\n- (nonnull MTFont*) fontWithName:(nonnull NSString*) name size:(CGFloat) size;\n\n/** Helper function to return the Xits Math font. */\n- (nonnull MTFont*) xitsFontWithSize:(CGFloat) size;\n\n/** Helper function to return the Tex Gyre Termes Math font. */\n- (nonnull MTFont*) termesFontWithSize:(CGFloat) size;\n\n/** Helper function to return the Latin Modern Math font. */\n- (nonnull MTFont*) latinModernFontWithSize:(CGFloat) size;\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/render/MTFontManager.m",
    "content": "//\n//  MTFontManager.m\n//  iosMath\n//\n//  Created by Kostub Deshmukh on 8/30/13.\n//  Copyright (C) 2013 MathChat\n//   \n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n#import \"MTFontManager.h\"\n#import \"MTFont+Internal.h\"\n\nconst int kDefaultFontSize = 20;\n\n@interface MTFontManager ()\n\n@property (nonatomic, nonnull) NSMutableDictionary<NSString*, MTFont*>* nameToFontMap;\n\n@end\n\n@implementation MTFontManager\n\n+ (instancetype) fontManager\n{\n    static MTFontManager* manager = nil;\n    if (manager == nil) {\n        manager = [MTFontManager new];\n    }\n    return manager;\n}\n\n- (instancetype)init\n{\n    self = [super init];\n    if (self) {\n        self.nameToFontMap = [[NSMutableDictionary alloc] init];\n    }\n    return self;\n}\n\n- (MTFont *)fontWithName:(NSString *)name size:(CGFloat)size\n{\n    MTFont* f = self.nameToFontMap[name];\n    if (!f) {\n        f = [[MTFont alloc] initFontWithName:name size:size];\n        self.nameToFontMap[name] = f;\n    }\n    if (f.fontSize == size) {\n        return f;\n    } else {\n        return [f copyFontWithSize:size];\n    }\n}\n\n- (MTFont *)latinModernFontWithSize:(CGFloat)size\n{\n    return [self fontWithName:@\"latinmodern-math\" size:size];\n}\n\n- (MTFont *)xitsFontWithSize:(CGFloat)size\n{\n    return [self fontWithName:@\"xits-math\" size:size];\n}\n\n- (MTFont *)termesFontWithSize:(CGFloat)size\n{\n    return [self fontWithName:@\"texgyretermes-math\" size:size];\n}\n\n- (MTFont *)defaultFont\n{\n    return [self latinModernFontWithSize:kDefaultFontSize];\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/render/MTLabel.h",
    "content": "//\n//  MTLabel.h\n//  MacOSMath\n//\n//  Created by 安志钢 on 17-01-09.\n//\n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n#include <TargetConditionals.h>\n\n#if !TARGET_OS_IPHONE\n@import AppKit;\n\n@interface MTLabel : NSTextField\n\n@property (strong) NSString *text;\n\n@end\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/render/MTLabel.m",
    "content": "//\n//  MTLabel.m\n//  MacOSMath\n//\n//  Created by 安志钢 on 17-01-09.\n//\n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n#import \"MTLabel.h\"\n\n#if !TARGET_OS_IPHONE\n@implementation MTLabel\n\n@synthesize bezeled, drawsBackground, editable, selectable, stringValue;\n\n- (instancetype)init\n{\n    self = [super init];\n\n    if (self != nil) {\n        super.bezeled = NO;\n        super.drawsBackground = NO;\n        super.editable = NO;\n        super.selectable = NO;\n    }\n    \n    return self;\n}\n\n#pragma mark - Customized getter and setter methods for property text.\n- (NSString *)text\n{\n    return super.stringValue;\n}\n\n- (void)setText:(NSString *)text\n{\n    super.stringValue = text;\n}\n\n@end\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/render/MTMathListDisplay.h",
    "content": "//\n//  MTLine.h\n//  iosMath\n//\n//  Created by Kostub Deshmukh on 8/27/13.\n//  Copyright (C) 2013 MathChat\n//\n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n@import Foundation;\n@import QuartzCore;\n\n// This header file is imported by Foudation.\n//#include <TargetConditionals.h>\n\n#import \"MTConfig.h\"\n\n#import \"MTFont.h\"\n#import \"MTMathList.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// The base class for rendering a math equation.\n@interface MTDisplay : NSObject\n\n/// Draws itself in the given graphics context.\n- (void) draw:(CGContextRef) context;\n/// Gets the bounding rectangle for the MTDisplay\n- (CGRect) displayBounds;\n\n/// For debugging. Shows the object in quick look in Xcode.\n#if TARGET_OS_IPHONE\n- (id) debugQuickLookObject;\n#endif\n\n/// The distance from the axis to the top of the display\n@property (nonatomic, readonly) CGFloat ascent;\n/// The distance from the axis to the bottom of the display\n@property (nonatomic, readonly) CGFloat descent;\n/// The width of the display\n@property (nonatomic, readonly) CGFloat width;\n/// Position of the display with respect to the parent view or display.\n@property (nonatomic) CGPoint position;\n/// The range of characters supported by this item\n@property (nonatomic, readonly) NSRange range;\n/// Whether the display has a subscript/superscript following it.\n@property (nonatomic, readonly) BOOL hasScript;\n/// The text color for this display\n@property (nonatomic, nullable) MTColor *textColor;\n// The local color, if the color was mutated local with the color\n// command\n@property (nonatomic, nullable) MTColor *localTextColor;\n/// The background color for this display.\n@property (nonatomic, nullable) MTColor *localBackgroundColor;\n@end\n\n/// A rendering of a single CTLine as an MTDisplay\n@interface MTCTLineDisplay : MTDisplay\n\n- (instancetype)init NS_UNAVAILABLE;\n\n/// The CTLine being displayed\n@property (nonatomic, readonly) CTLineRef line;\n/// The attributed string used to generate the CTLineRef. Note setting this does not reset the dimensions of\n/// the display. So set only when\n@property (nonatomic) NSAttributedString* attributedString;\n\n/// An array of MTMathAtoms that this CTLine displays. Used for indexing back into the MTMathList\n@property (nonatomic, readonly) NSArray<MTMathAtom*>* atoms;\n\n@end\n\n\n@interface MTSeparatorDisplay : MTDisplay\n\n@property (nonatomic) CGFloat bottomY;\n@property (nonatomic) CGFloat sepLen;\n\n- (instancetype)init NS_UNAVAILABLE;\n\n- (instancetype)initWithRect:(CGRect )rect color:(MTColor *)color;\n- (CGRect)getBounds;\n\n@end\n\n/// An MTLine is a rendered form of MTMathList in one line.\n/// It can render itself using the draw method.\n@interface MTMathListDisplay : MTDisplay\n\n- (instancetype)init NS_UNAVAILABLE;\n\n/**\n @typedef MTLinePosition\n @brief The type of position for a line, i.e. subscript/superscript or regular.\n */\ntypedef NS_ENUM(unsigned int, MTLinePosition)  {\n    /// Regular\n    kMTLinePositionRegular,\n    /// Positioned at a subscript\n    kMTLinePositionSubscript,\n    /// Positioned at a superscript\n    kMTLinePositionSuperscript,\n    /// Positioned at an inner\n    kMTLinePositionInner\n};\n\n/// Where the line is positioned\n@property (nonatomic, readonly) MTLinePosition type;\n/// An array of MTDisplays which are positioned relative to the position of the\n/// the current display.\n@property (nonatomic, readonly) NSArray<MTDisplay*>* subDisplays;\n/// If a subscript or superscript this denotes the location in the parent MTList. For a\n/// regular list this is NSNotFound\n@property (nonatomic, readonly) NSUInteger index;\n\n@end\n\n/// Rendering of an MTFraction as an MTDisplay\n@interface MTFractionDisplay : MTDisplay\n\n- (instancetype)init NS_UNAVAILABLE;\n\n/** A display representing the numerator of the fraction. It's position is relative\n to the parent and is not treated as a sub-display.\n */\n@property (nonatomic, readonly) MTMathListDisplay* numerator;\n/** A display representing the denominator of the fraction. It's position is relative\n to the parent is not treated as a sub-display.\n */\n@property (nonatomic, readonly) MTMathListDisplay* denominator;\n\n@end\n\n/// Rendering of an MTRadical as an MTDisplay\n@interface MTRadicalDisplay : MTDisplay\n\n- (instancetype)init NS_UNAVAILABLE;\n\n/** A display representing the radicand of the radical. It's position is relative\n to the parent is not treated as a sub-display.\n */\n@property (nonatomic, readonly) MTMathListDisplay* radicand;\n/** A display representing the degree of the radical. It's position is relative\n to the parent is not treated as a sub-display.\n */\n@property (nonatomic, readonly, nullable) MTMathListDisplay* degree;\n\n@end\n\n/// Rendering a glyph as a display\n@interface MTGlyphDisplay : MTDisplay\n\n- (instancetype)init NS_UNAVAILABLE;\n\n@end\n\n/// Rendering a large operator with limits as an MTDisplay\n@interface MTLargeOpLimitsDisplay : MTDisplay\n\n- (instancetype)init NS_UNAVAILABLE;\n\n/** A display representing the upper limit of the large operator. It's position is relative\n to the parent is not treated as a sub-display.\n */\n@property (nonatomic, readonly, nullable) MTMathListDisplay* upperLimit;\n/** A display representing the lower limit of the large operator. It's position is relative\n to the parent is not treated as a sub-display.\n */\n@property (nonatomic, readonly, nullable) MTMathListDisplay* lowerLimit;\n\n@end\n\n/// Rendering of an list with an overline or underline\n@interface MTLineDisplay : MTDisplay\n\n- (instancetype)init NS_UNAVAILABLE;\n\n/** A display representing the inner list that is underlined. It's position is relative\n to the parent is not treated as a sub-display.\n */\n\n@property (nonatomic, assign) BOOL useArrow;\n\n@property (nonatomic, readonly) MTMathListDisplay* inner;\n\n@end\n\n/// Rendering of an list with an middleline\n@interface MTHLineDisplay : MTDisplay\n\n- (instancetype)init NS_UNAVAILABLE;\n\n@end\n\n@interface MTOverbraceDisplay : MTDisplay\n\n- (instancetype)init NS_UNAVAILABLE;\n\n/** A display representing the contentor. It's position is relative\n to the parent is not treated as a sub-display.\n */\n@property (nonatomic, readonly) MTMathListDisplay* contentor;\n/** A display representing the label. It's position is relative\n to the parent is not treated as a sub-display.\n */\n@property (nonatomic, readonly) MTMathListDisplay* labelor;\n\n@end\n\n@interface MTUnderbraceDisplay : MTDisplay\n\n- (instancetype)init NS_UNAVAILABLE;\n\n/** A display representing the contentor. It's position is relative\n to the parent is not treated as a sub-display.\n */\n@property (nonatomic, readonly) MTMathListDisplay* contentor;\n/** A display representing the label. It's position is relative\n to the parent is not treated as a sub-display.\n */\n@property (nonatomic, readonly) MTMathListDisplay* labelor;\n\n@end\n\n/// Rendering an accent as a display\n@interface MTAccentDisplay : MTDisplay\n\n- (instancetype)init NS_UNAVAILABLE;\n\n/** A display representing the inner list that is accented. It's position is relative\n to the parent is not treated as a sub-display.\n */\n@property (nonatomic, readonly) MTMathListDisplay* accentee;\n\n/** A display representing the accent. It's position is relative to the current display.\n */\n@property (nonatomic, readonly) MTGlyphDisplay* accent;\n\n@end\n\n/// Rendering of an list with delimiters\n@interface MTInnerDisplay : MTDisplay\n\n- (instancetype)init NS_UNAVAILABLE;\n\n/** A display representing the inner list that can be wrapped in delimiters.\n It's position is relative to the parent is not treated as a sub-display.\n */\n@property (nonatomic, readonly) MTMathListDisplay* inner;\n\n/** A display representing the delimiters. Their position is relative\n to the parent are not treated as a sub-display.\n */\n@property (nonatomic, readonly, nullable) MTDisplay* leftDelimiter;\n@property (nonatomic, readonly, nullable) MTDisplay* rightDelimiter;\n\n/// Denotes the location in the parent MTList.\n@property (nonatomic, readonly) NSUInteger index;\n\n@end\n\n/// Rendering  a delimiter in current line\n@interface MTAdaptiveDisplay : MTDisplay\n\n- (instancetype)init NS_UNAVAILABLE;\n\n/** A display representing the delimiters. Their position is relative\n to the parent are not treated as a sub-display.\n */\n@property (nonatomic, readonly, nullable) MTDisplay* delimiter;\n\n@end\n\n@interface MTBoxedDisplay : MTDisplay\n\n@property (nonatomic, strong) MTMathListDisplay *inner;\n@property (nonatomic) CGFloat lineThickness;\n@property (nonatomic) CGFloat horizontalPadding;\n@property (nonatomic) CGFloat verticalPadding;\n\n- (instancetype)initWithInner:(MTMathListDisplay *)inner lineThickness:(CGFloat)lineThickness;\n\n@end\n\n@interface MTMathTagDisplay : MTDisplay\n\n- (instancetype)init NS_UNAVAILABLE;\n- (instancetype)initWithString:(NSAttributedString*) attrString position:(CGPoint)position range:(NSRange) range font:(MTFont*) font atoms:(NSArray<MTMathAtom*>*) atoms;\n/// The CTLine being displayed\n@property (nonatomic, readonly) CTLineRef line;\n/// The attributed string used to generate the CTLineRef. Note setting this does not reset the dimensions of\n/// the display. So set only when\n@property (nonatomic) NSAttributedString* attributedString;\n\n/// An array of MTMathAtoms that this CTLine displays. Used for indexing back into the MTMathList\n@property (nonatomic, readonly) NSArray<MTMathAtom*>* atoms;\n\n@end\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/render/MTMathListDisplay.m",
    "content": "//\n//  MTLine.m\n//  iosMath\n//\n//  Created by Kostub Deshmukh on 8/27/13.\n//  Copyright (C) 2013 MathChat\n//\n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n#import <CoreText/CoreText.h>\n#include <sys/param.h>\n#include <sys/sysctl.h>\n\n#import \"MTMathListDisplay.h\"\n#import \"MTFontMathTable.h\"\n#import \"MTFontManager.h\"\n#import \"MTFont+Internal.h\"\n#import \"MTMathListDisplayInternal.h\"\n\nstatic BOOL isIos6Supported() {\n    static BOOL initialized = false;\n    static BOOL supported = false;\n    if (!initialized) {\n#if TARGET_OS_IPHONE\n        NSString *reqSysVer = @\"6.0\";\n        NSString *currSysVer = [UIDevice currentDevice].systemVersion;\n        \n        if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending) {\n            supported = true;\n        }\n#else\n        supported = true;\n#endif\n        \n        initialized = true;\n    }\n    return supported;\n}\n\n#pragma mark MTDisplay\n\n@implementation MTDisplay\n\n- (void)draw:(CGContextRef)context\n{\n    if (self.localBackgroundColor != nil) {\n        CGContextSaveGState(context);\n        CGContextSetBlendMode(context, kCGBlendModeNormal);\n        CGContextSetFillColorWithColor(context, self.localBackgroundColor.CGColor);\n        CGContextFillRect(context, [self displayBounds]);\n        CGContextRestoreGState(context);\n    }\n    \n}\n\n- (CGRect) displayBounds\n{\n    return CGRectMake(self.position.x, self.position.y - self.descent, self.width, self.ascent + self.descent);\n}\n\n// Debug method skipped for MAC.\n#if TARGET_OS_IPHONE\n- (id)debugQuickLookObject\n{\n    CGSize size = CGSizeMake(self.width, self.ascent + self.descent);\n    UIGraphicsBeginImageContext(size);\n    \n    // get a reference to that context we created\n    CGContextRef context = UIGraphicsGetCurrentContext();\n    // translate/flip the graphics context (for transforming from CG* coords to UI* coords\n    CGContextTranslateCTM(context, 0, size.height);\n    CGContextScaleCTM(context, 1.0, -1.0);\n    // move the position to (0,0)\n    CGContextTranslateCTM(context, -self.position.x, -self.position.y);\n    \n    // Move the line up by self.descent\n    CGContextTranslateCTM(context, 0, self.descent);\n    // Draw self on context\n    [self draw:context];\n    \n    // generate a new UIImage from the graphics context we drew onto\n    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();\n    return img;\n}\n#endif\n\n@end\n\n#pragma mark - MTCTLine\n\n@implementation MTCTLineDisplay\n\n- (instancetype)initWithString:(NSAttributedString*) attrString position:(CGPoint)position range:(NSRange) range font:(MTFont*) font atoms:(NSArray<MTMathAtom*>*) atoms\n{\n    self = [super init];\n    if (self) {\n        self.position = position;\n        self.attributedString = attrString;\n        self.range = range;\n        _atoms = atoms;\n        // We can't use typographic bounds here as the ascent and descent returned are for the font and not for the line.\n        self.width = CTLineGetTypographicBounds(_line, NULL, NULL, NULL);\n        if (isIos6Supported()) {\n            CGRect bounds = CTLineGetBoundsWithOptions(_line, kCTLineBoundsUseGlyphPathBounds);\n            self.ascent = MAX(0, CGRectGetMaxY(bounds) - 0);\n            self.descent = MAX(0, 0 - CGRectGetMinY(bounds));\n            // TODO: Should we use this width vs the typographic width? They are slightly different. Don't know why.\n            // _width = CGRectGetMaxX(bounds);\n        } else {\n            // Our own implementation of the ios6 function to get glyph path bounds.\n            [self computeDimensions:font];\n        }\n    }\n    return self;\n}\n\n- (void) setAttributedString:(NSAttributedString*) attrString\n{\n    if (_line) {\n        CFRelease(_line);\n    }\n    _attributedString = [attrString copy];\n    _line = CTLineCreateWithAttributedString((__bridge CFAttributedStringRef)(_attributedString));\n}\n\n- (void)setTextColor:(MTColor *)textColor\n{\n    [super setTextColor:textColor];\n    NSMutableAttributedString* attrStr = self.attributedString.mutableCopy;\n    [attrStr addAttribute:(NSString*)kCTForegroundColorAttributeName value:(id)self.textColor.CGColor\n                    range:NSMakeRange(0, attrStr.length)];\n    self.attributedString = attrStr;\n}\n\n- (void) computeDimensions:(MTFont*) font\n{\n    NSArray* runs = (__bridge NSArray *)(CTLineGetGlyphRuns(_line));\n    for (id obj in runs) {\n        CTRunRef run = (__bridge CTRunRef)(obj);\n        CFIndex numGlyphs = CTRunGetGlyphCount(run);\n        CGGlyph glyphs[numGlyphs];\n        CTRunGetGlyphs(run, CFRangeMake(0, numGlyphs), glyphs);\n        CGRect bounds = CTFontGetBoundingRectsForGlyphs(font.ctFont, kCTFontHorizontalOrientation, glyphs, NULL, numGlyphs);\n        CGFloat ascent = MAX(0, CGRectGetMaxY(bounds) - 0);\n        // Descent is how much the line goes below the origin. However if the line is all above the origin, then descent can't be negative.\n        CGFloat descent = MAX(0, 0 - CGRectGetMinY(bounds));\n        if (ascent > self.ascent) {\n            self.ascent = ascent;\n        }\n        if (descent > self.descent) {\n            self.descent = descent;\n        }\n    }\n}\n\n- (void)dealloc\n{\n    CFRelease(_line);\n}\n\n- (void)draw:(CGContextRef)context\n{\n    [super draw:context];\n    CGContextSaveGState(context);\n    \n    CGContextSetTextPosition(context, self.position.x, self.position.y);\n    CTLineDraw(_line, context);\n    \n    CGContextRestoreGState(context);\n}\n\n@end\n\n#pragma mark - MTSeparatorDisplay\n\n@implementation MTSeparatorDisplay {\n    CGRect _rect;\n    MTColor *_color;\n}\n\n- (instancetype)initWithRect:(CGRect )rect color:(MTColor *)color\n{\n    self = [super init];\n    if (self) {\n        _rect = rect;\n        _color = color;\n    }\n    return self;\n}\n\n\n- (void)draw:(CGContextRef)context\n{\n    [super draw:context];\n    \n    CGContextSaveGState(context);\n    MTBezierPath* path = [MTBezierPath bezierPathWithRect:CGRectMake(_rect.origin.x, _rect.origin.y - self.bottomY, _rect.size.width, self.sepLen)];\n    [_color setFill];\n    [path fill];\n    \n \n    CGContextRestoreGState(context);\n}\n\n- (CGRect)getBounds\n{\n    return _rect;\n}\n\n@end\n\n#pragma mark - MTLine\n\n@implementation MTMathListDisplay {\n    NSUInteger _index;\n}\n\n\n- (instancetype) initWithDisplays:(NSArray<MTDisplay*>*) displays range:(NSRange) range\n{\n    self = [super init];\n    if (self) {\n        _subDisplays = [displays copy];\n        self.position = CGPointZero;\n        _type = kMTLinePositionRegular;\n        _index = NSNotFound;\n        self.range = range;\n        [self recomputeDimensions];\n    }\n    return self;\n}\n\n- (void) setType:(MTLinePosition) type\n{\n    _type = type;\n}\n\n- (void) setIndex:(NSUInteger) index\n{\n    _index = index;\n}\n\n- (void)setTextColor:(MTColor *)textColor\n{\n    // Set the color on all subdisplays\n    [super setTextColor:textColor];\n    for (MTDisplay* displayAtom in self.subDisplays) {\n        // set the global color, if there is no local color\n        if(displayAtom.localTextColor == nil) {\n            displayAtom.textColor = textColor;\n        } else {\n            displayAtom.textColor = displayAtom.localTextColor;\n        }\n        \n    }\n}\n\n- (void)draw:(CGContextRef)context\n{\n    [super draw:context];\n    CGContextSaveGState(context);\n    \n    // Make the current position the origin as all the positions of the sub atoms are relative to the origin.\n    CGContextTranslateCTM(context, self.position.x, self.position.y);\n    CGContextSetTextPosition(context, 0, 0);\n    \n    // draw each atom separately\n    for (MTDisplay* displayAtom in self.subDisplays) {\n        [displayAtom draw:context];\n    }\n    \n    CGContextRestoreGState(context);\n}\n\n- (void) recomputeDimensions\n{\n    CGFloat max_ascent = 0;\n    CGFloat max_descent = 0;\n    CGFloat max_width = 0;\n    for (MTDisplay* atom in self.subDisplays) {\n        CGFloat ascent = MAX(0, atom.position.y + atom.ascent);\n        if (ascent > max_ascent) {\n            max_ascent = ascent;\n        }\n        \n        CGFloat descent = MAX(0, 0 - (atom.position.y - atom.descent));\n        if (descent > max_descent) {\n            max_descent = descent;\n        }\n        CGFloat width = atom.width + atom.position.x;\n        if (width > max_width) {\n            max_width = width;\n        }\n    }\n    self.ascent = max_ascent;\n    self.descent = max_descent;\n    self.width = max_width;\n}\n\n\n@end\n\n#pragma mark - MTFractionDisplay\n\n@implementation MTFractionDisplay\n\n- (instancetype)initWithNumerator:(MTMathListDisplay*) numerator denominator:(MTMathListDisplay*) denominator position:(CGPoint) position range:(NSRange) range\n{\n    self = [super init];\n    if (self) {\n        _numerator = numerator;\n        _denominator = denominator;\n        self.position = position;\n        self.range = range;\n        NSAssert(self.range.length == 1, @\"Fraction range length not 1 - range (%lu, %lu)\", (unsigned long)range.location, (unsigned long)range.length);\n    }\n    return self;\n}\n\n- (CGFloat)ascent\n{\n    return _numerator.ascent + self.numeratorUp;\n}\n\n- (CGFloat)descent\n{\n    return _denominator.descent + self.denominatorDown;\n}\n\n- (CGFloat)width\n{\n    return MAX(_numerator.width, _denominator.width);\n}\n\n- (void)setDenominatorDown:(CGFloat)denominatorDown\n{\n    _denominatorDown = denominatorDown;\n    [self updateDenominatorPosition];\n}\n\n- (void) setNumeratorUp:(CGFloat)numeratorUp\n{\n    _numeratorUp = numeratorUp;\n    [self updateNumeratorPosition];\n}\n\n- (void) updateDenominatorPosition\n{\n    _denominator.position = CGPointMake(self.position.x + (self.width - _denominator.width)/2, self.position.y - self.denominatorDown);\n}\n\n- (void) updateNumeratorPosition\n{\n    _numerator.position = CGPointMake(self.position.x + (self.width - _numerator.width)/2, self.position.y + self.numeratorUp);\n}\n\n- (void) setPosition:(CGPoint)position\n{\n    super.position = position;\n    [self updateDenominatorPosition];\n    [self updateNumeratorPosition];\n}\n\n- (void)setTextColor:(MTColor *)textColor\n{\n    [super setTextColor:textColor];\n    _numerator.textColor = textColor;\n    _denominator.textColor = textColor;\n}\n\n- (void)draw:(CGContextRef)context\n{\n    [super draw:context];\n    [_numerator draw:context];\n    [_denominator draw:context];\n    \n    CGContextSaveGState(context);\n    \n    [self.textColor setStroke];\n    \n    // draw the horizontal line\n    MTBezierPath* path = [MTBezierPath bezierPath];\n    [path moveToPoint:CGPointMake(self.position.x, self.position.y + self.linePosition)];\n    [path addLineToPoint:CGPointMake(self.position.x + self.width, self.position.y + self.linePosition)];\n    path.lineWidth = self.lineThickness;\n    [path stroke];\n    \n    CGContextRestoreGState(context);\n}\n\n@end\n\n#pragma mark - MTRadicalDisplay\n\n@implementation MTRadicalDisplay {\n    MTDisplay* _radicalGlyph;\n    CGFloat _radicalShift;\n}\n\n- (instancetype)initWitRadicand:(MTMathListDisplay*) radicand glpyh:(MTDisplay*) glyph position:(CGPoint) position range:(NSRange) range\n{\n    self = [super init];\n    if (self) {\n        _radicand = radicand;\n        _radicalGlyph = glyph;\n        _radicalShift = 0;\n        \n        self.position = position;\n        self.range = range;\n    }\n    return self;\n}\n\n- (void) setDegree:(MTMathListDisplay *)degree fontMetrics:(MTFontMathTable*) fontMetrics\n{\n    // sets up the degree of the radical\n    CGFloat kernBefore = fontMetrics.radicalKernBeforeDegree;\n    CGFloat kernAfter = fontMetrics.radicalKernAfterDegree;\n    CGFloat raise = fontMetrics.radicalDegreeBottomRaisePercent * (self.ascent - self.descent);\n    \n    // The layout is:\n    // kernBefore, raise, degree, kernAfter, radical\n    _degree = degree;\n    \n    // the radical is now shifted by kernBefore + degree.width + kernAfter\n    _radicalShift = kernBefore + degree.width + kernAfter;\n    if (_radicalShift < 0) {\n        // we can't have the radical shift backwards, so instead we increase the kernBefore such\n        // that _radicalShift will be 0.\n        kernBefore -= _radicalShift;\n        _radicalShift = 0;\n    }\n    \n    // Note: position of degree is relative to parent.\n    self.degree.position = CGPointMake(self.position.x + kernBefore, self.position.y + raise);\n    // Update the width by the _radicalShift\n    self.width = _radicalShift + _radicalGlyph.width + self.radicand.width;\n    // update the position of the radicand\n    [self updateRadicandPosition];\n}\n\n- (void) setPosition:(CGPoint)position\n{\n    super.position = position;\n    [self updateRadicandPosition];\n}\n\n- (void) updateRadicandPosition\n{\n    // The position of the radicand includes the position of the MTRadicalDisplay\n    // This is to make the positioning of the radical consistent with fractions and\n    // have the cursor position finding algorithm work correctly.\n    // move the radicand by the width of the radical sign\n    self.radicand.position = CGPointMake(self.position.x + _radicalShift + _radicalGlyph.width, self.position.y);\n}\n\n- (void)setTextColor:(MTColor *)textColor\n{\n    [super setTextColor:textColor];\n    self.radicand.textColor = textColor;\n    self.degree.textColor = textColor;\n}\n\n- (void)draw:(CGContextRef)context\n{\n    [super draw:context];\n    // draw the radicand & degree at its position\n    [self.radicand draw:context];\n    [self.degree draw:context];\n    \n    CGContextSaveGState(context);\n    [self.textColor setStroke];\n    [self.textColor setFill];\n    \n    // Make the current position the origin as all the positions of the sub atoms are relative to the origin.\n    CGContextTranslateCTM(context, self.position.x + _radicalShift, self.position.y);\n    CGContextSetTextPosition(context, 0, 0);\n    \n    // Draw the glyph.\n    [_radicalGlyph draw:context];\n    \n    // Draw the VBOX\n    // for the kern of, we don't need to draw anything.\n    CGFloat heightFromTop = _topKern;\n    \n    // draw the horizontal line with the given thickness\n    MTBezierPath* path = [MTBezierPath bezierPath];\n    CGPoint lineStart = CGPointMake(_radicalGlyph.width, self.ascent - heightFromTop - self.lineThickness / 2); // subtract half the line thickness to center the line\n    CGPoint lineEnd = CGPointMake(lineStart.x + self.radicand.width, lineStart.y);\n    [path moveToPoint:lineStart];\n    [path addLineToPoint:lineEnd];\n    path.lineWidth = _lineThickness;\n    path.lineCapStyle = kCGLineCapRound;\n    [path stroke];\n    \n    CGContextRestoreGState(context);\n}\n\n@end\n\n#pragma mark - MTGlyphDisplay\n\n@implementation MTGlyphDisplay {\n    CGGlyph _glyph;\n    MTFont* _font;\n}\n\n@synthesize shiftDown;\n\n- (instancetype)initWithGlpyh:(CGGlyph) glyph range:(NSRange) range font:(MTFont*) font\n{\n    self = [super init];\n    if (self) {\n        _font = font;\n        _glyph = glyph;\n        \n        self.position = CGPointZero;\n        self.range = range;\n    }\n    return self;\n}\n\n- (void)draw:(CGContextRef)context\n{\n    [super draw:context];\n    CGContextSaveGState(context);\n    \n    [self.textColor setFill];\n    \n    // Make the current position the origin as all the positions of the sub atoms are relative to the origin.\n    CGContextTranslateCTM(context, self.position.x, self.position.y - self.shiftDown);\n    CGContextSetTextPosition(context, 0, 0);\n    \n    CTFontDrawGlyphs(_font.ctFont, &_glyph, &CGPointZero, 1, context);\n    \n    CGContextRestoreGState(context);\n}\n\n- (CGFloat)ascent\n{\n    return super.ascent - self.shiftDown;\n}\n\n- (CGFloat)descent\n{\n    return super.descent + self.shiftDown;\n}\n\n@end\n\n#pragma mark - MTGlyphConstructionDisplay\n\n@implementation MTGlyphConstructionDisplay {\n    CGGlyph *_glyphs;\n    CGPoint *_positions;\n    MTFont* _font;\n    NSInteger _numGlyphs;\n}\n\n@synthesize shiftDown;\n\n- (instancetype)initWithGlyphs:(NSArray<NSNumber *> *)glyphs offsets:(NSArray<NSNumber *> *)offsets font:(MTFont *)font\n{\n    self = [super init];\n    if (self) {\n        NSAssert(glyphs.count == offsets.count, @\"Glyphs and offsets need to match\");\n        _numGlyphs = glyphs.count;\n        _glyphs = malloc(sizeof(CGGlyph) * _numGlyphs);\n        _positions = malloc(sizeof(CGPoint) * _numGlyphs);\n        for (int i = 0; i < _numGlyphs; i++) {\n            _glyphs[i] = glyphs[i].shortValue;\n            _positions[i] = CGPointMake(0, offsets[i].floatValue);\n        }\n        _font = font;\n        self.position = CGPointZero;\n    }\n    return self;\n}\n\n- (void)draw:(CGContextRef)context\n{\n    [super draw:context];\n    CGContextSaveGState(context);\n    \n    [self.textColor setFill];\n    \n    // Make the current position the origin as all the positions of the sub atoms are relative to the origin.\n    CGContextTranslateCTM(context, self.position.x, self.position.y - self.shiftDown);\n    CGContextSetTextPosition(context, 0, 0);\n    \n    // Draw the glyphs.\n    CTFontDrawGlyphs(_font.ctFont, _glyphs, _positions, _numGlyphs, context);\n    \n    CGContextRestoreGState(context);\n}\n\n- (CGFloat)ascent\n{\n    return super.ascent - self.shiftDown;\n}\n\n- (CGFloat)descent\n{\n    return super.descent + self.shiftDown;\n}\n\n- (void)dealloc\n{\n    free(_glyphs);\n    free(_positions);\n}\n\n@end\n\n#pragma mark - MTLargeOpLimitsDisplay\n\n@implementation MTLargeOpLimitsDisplay {\n    CGFloat _limitShift;\n    CGFloat _upperLimitGap;\n    CGFloat _lowerLimitGap;\n    CGFloat _extraPadding;\n    \n    MTDisplay *_nucleus;\n}\n\n- (instancetype) initWithNucleus:(MTDisplay*) nucleus upperLimit:(MTMathListDisplay*) upperLimit lowerLimit:(MTMathListDisplay*) lowerLimit limitShift:(CGFloat) limitShift extraPadding:(CGFloat) extraPadding\n{\n    self = [super init];\n    if (self) {\n        _upperLimit = upperLimit;\n        _lowerLimit = lowerLimit;\n        _nucleus = nucleus;\n        \n        CGFloat maxWidth = MAX(nucleus.width, upperLimit.width);\n        maxWidth = MAX(maxWidth, lowerLimit.width);\n        \n        _limitShift = limitShift;\n        _upperLimitGap = 0;\n        _lowerLimitGap = 0;\n        _extraPadding = extraPadding;  // corresponds to \\xi_13 in TeX\n        self.width = maxWidth;\n    }\n    return self;\n}\n\n- (CGFloat)ascent\n{\n    if (self.upperLimit) {\n        return _nucleus.ascent + _extraPadding + self.upperLimit.ascent + _upperLimitGap + self.upperLimit.descent;\n    } else {\n        return _nucleus.ascent;\n    }\n}\n\n- (CGFloat)descent\n{\n    if (self.lowerLimit) {\n        return _nucleus.descent + _extraPadding + _lowerLimitGap + self.lowerLimit.descent + self.lowerLimit.ascent;\n    } else {\n        return _nucleus.descent;\n    }\n}\n\n- (void)setLowerLimitGap:(CGFloat)lowerLimitGap\n{\n    _lowerLimitGap = lowerLimitGap;\n    [self updateLowerLimitPosition];\n}\n\n- (void) setUpperLimitGap:(CGFloat)upperLimitGap\n{\n    _upperLimitGap = upperLimitGap;\n    [self updateUpperLimitPosition];\n}\n\n- (void)setPosition:(CGPoint)position\n{\n    super.position = position;\n    [self updateLowerLimitPosition];\n    [self updateUpperLimitPosition];\n    [self updateNucleusPosition];\n}\n\n- (void) updateLowerLimitPosition\n{\n    if (self.lowerLimit) {\n        // The position of the lower limit includes the position of the MTLargeOpLimitsDisplay\n        // This is to make the positioning of the radical consistent with fractions and radicals\n        // Move the starting point to below the nucleus leaving a gap of _lowerLimitGap and subtract\n        // the ascent to to get the baseline. Also center and shift it to the left by _limitShift.\n        self.lowerLimit.position = CGPointMake(self.position.x - _limitShift + (self.width - _lowerLimit.width)/2,\n                                               self.position.y - _nucleus.descent - _lowerLimitGap - self.lowerLimit.ascent);\n    }\n}\n\n- (void) updateUpperLimitPosition\n{\n    if (self.upperLimit) {\n        // The position of the upper limit includes the position of the MTLargeOpLimitsDisplay\n        // This is to make the positioning of the radical consistent with fractions and radicals\n        // Move the starting point to above the nucleus leaving a gap of _upperLimitGap and add\n        // the descent to to get the baseline. Also center and shift it to the right by _limitShift.\n        self.upperLimit.position = CGPointMake(self.position.x + _limitShift + (self.width - self.upperLimit.width)/2,\n                                               self.position.y + _nucleus.ascent + _upperLimitGap + self.upperLimit.descent);\n    }\n}\n\n- (void) updateNucleusPosition\n{\n    // Center the nucleus\n    _nucleus.position = CGPointMake(self.position.x + (self.width - _nucleus.width)/2, self.position.y);\n}\n\n- (void)setTextColor:(MTColor *)textColor\n{\n    [super setTextColor:textColor];\n    self.upperLimit.textColor = textColor;\n    self.lowerLimit.textColor = textColor;\n    _nucleus.textColor = textColor;\n}\n\n- (void)draw:(CGContextRef)context\n{\n    [super draw:context];\n    // Draw the elements.\n    [self.upperLimit draw:context];\n    [self.lowerLimit draw:context];\n    [_nucleus draw:context];\n}\n\n@end\n\n#pragma mark - MTLineDisplay\n\n@implementation MTLineDisplay\n\n- (instancetype)initWithInner:(MTMathListDisplay *)inner position:(CGPoint) position range:(NSRange)range\n{\n    self = [super init];\n    if (self) {\n        _inner = inner;\n        \n        self.position = position;\n        self.range = range;\n    }\n    return self;\n}\n\n- (void)setTextColor:(MTColor *)textColor\n{\n    [super setTextColor:textColor];\n    _inner.textColor = textColor;\n}\n\n- (void)draw:(CGContextRef)context\n{\n    [super draw:context];\n    [self.inner draw:context];\n    \n    CGContextSaveGState(context);\n    \n    [self.textColor setStroke];\n    \n    // draw the horizontal line\n    MTBezierPath* path = [MTBezierPath bezierPath];\n    CGPoint lineStart = CGPointMake(self.position.x, self.position.y + self.lineShiftUp);\n    CGPoint lineEnd = CGPointMake(lineStart.x + self.inner.width, lineStart.y);\n    [path moveToPoint:lineStart];\n    [path addLineToPoint:lineEnd];\n    if (self.useArrow) {\n        [path addLineToPoint:CGPointMake(lineEnd.x - 3, lineEnd.y + 1.7)];\n        [path addLineToPoint:lineEnd];\n        [path addLineToPoint:CGPointMake(lineEnd.x - 3, lineEnd.y - 1.7)];\n    }\n    path.lineWidth = self.lineThickness;\n    [path stroke];\n    \n    CGContextRestoreGState(context);\n}\n\n- (void) setPosition:(CGPoint)position\n{\n    super.position = position;\n    [self updateInnerPosition];\n}\n\n- (void) updateInnerPosition\n{\n    self.inner.position = CGPointMake(self.position.x, self.position.y);\n}\n\n@end\n\n#pragma mark - MTHLineDisplay\n@implementation MTHLineDisplay\n\n- (instancetype)initWithPosition:(CGPoint) position\n{\n    self = [super init];\n    if (self) {\n        self.position = position;\n    }\n    return self;\n}\n\n- (void)draw:(CGContextRef)context\n{\n    [super draw:context];\n    CGContextSaveGState(context);\n    \n    CGContextTranslateCTM(context, self.position.x, 0);\n    MTBezierPath* path = [MTBezierPath bezierPath];\n    CGPoint lineStart = CGPointMake(self.position.x, self.position.y);\n    CGPoint lineEnd = CGPointMake(self.width, lineStart.y);\n    [path moveToPoint:lineStart];\n    [path addLineToPoint:lineEnd];\n    path.lineWidth = self.lineHeight;\n    [path stroke];\n    \n    CGContextRestoreGState(context);\n}\n\n@end\n\n#pragma mark - MTOverbraceDisplay\n\n@implementation MTOverbraceDisplay\n\n- (instancetype)initWithOverbraceContentor:(MTMathListDisplay *)contentor\n                                   labelor:(MTMathListDisplay *)labelor\n                                  position:(CGPoint) position\n{\n    if (self = [super init]) {\n        _contentor = contentor;\n        _labelor = labelor;\n        self.position = position;\n    }\n    return self;\n}\n\n- (void)setContentorOffsetY:(CGFloat)contentorOffsetY\n{\n    _contentorOffsetY = contentorOffsetY;\n    [self updateContentorPosition];\n}\n\n- (void) setLabelorOffsetY:(CGFloat)labelorOffsetY\n{\n    _labelorOffsetY = labelorOffsetY;\n    [self updateLabelorPosition];\n}\n\n- (void) updateLabelorPosition\n{\n    _labelor.position = CGPointMake(self.position.x + (self.width - self.labelor.width)/2, self.position.y + self.labelorOffsetY);\n}\n\n- (void) updateContentorPosition\n{\n    _contentor.position = CGPointMake(self.position.x + (self.width - self.contentor.width)/2, self.position.y - self.contentorOffsetY);\n}\n\n- (void) setPosition:(CGPoint)position\n{\n    super.position = position;\n    [self updateContentorPosition];\n    [self updateLabelorPosition];\n}\n\n- (void)draw:(CGContextRef)context\n{\n    [super draw:context];\n    [self.labelor draw:context];\n    [self.contentor draw:context];\n    \n    CGContextSaveGState(context);\n    UIBezierPath *path = [UIBezierPath bezierPath];\n    \n    CGFloat tail = 2;\n    CGFloat margin = 0;\n    CGFloat arrowDown = NO;\n    CGFloat marginTop = -2;\n    CGFloat height = 7;\n    CGFloat braceWidth = self.contentor.width < 20 ? 20 : self.contentor.width;\n    CGFloat left = (self.width - braceWidth) / 2 + self.position.x;\n    CGRect braceRct = CGRectMake(margin + self.position.x, marginTop, braceWidth, height);\n    CGPoint startPoint = CGPointMake(margin + left, arrowDown ? CGRectGetMaxY(braceRct) : CGRectGetMinY(braceRct));\n    \n    [path moveToPoint:startPoint];\n    [path addLineToPoint:CGPointMake(startPoint.x + tail, startPoint.y + (arrowDown ? -tail : tail))];\n    [path addLineToPoint:CGPointMake(CGRectGetWidth(braceRct) / 2 - tail - margin + left, startPoint.y + (arrowDown ? -tail : tail))];\n    [path addLineToPoint:CGPointMake(CGRectGetWidth(braceRct) / 2 - margin + left, arrowDown ? CGRectGetMinY(braceRct) : CGRectGetMaxY(braceRct))];\n    [path addLineToPoint:CGPointMake(CGRectGetWidth(braceRct) / 2 + tail - margin + left, startPoint.y + (arrowDown ? -tail : tail))];\n    [path addLineToPoint:CGPointMake(CGRectGetWidth(braceRct) - tail - margin + left, startPoint.y + (arrowDown ? -tail : tail))];\n    [path addLineToPoint:CGPointMake(CGRectGetWidth(braceRct) - margin + left, arrowDown ? CGRectGetMaxY(braceRct) : CGRectGetMinY(braceRct))];\n    [UIColor.blackColor setStroke];\n    path.lineWidth = 1;\n    path.lineCapStyle = kCGLineCapRound;\n    // 执行绘制\n    [path stroke];\n    // 恢复上下文状态\n    CGContextRestoreGState(context);\n}\n\n@end\n\n#pragma mark - MTUnderbraceDisplay\n\n@implementation MTUnderbraceDisplay\n{\n    CGFloat _braceHeight;\n}\n\n- (instancetype)initWithUnderbraceContentor:(MTMathListDisplay *)contentor labelor:(MTMathListDisplay *)labelor position:(CGPoint)position\n{\n    if (self = [super init]) {\n        _contentor = contentor;\n        _labelor = labelor;\n        self.position = position;\n        _braceHeight = 7;\n    }\n    return self;\n}\n\n- (void)setContentorOffsetY:(CGFloat)contentorOffsetY\n{\n    _contentorOffsetY = contentorOffsetY;\n    [self updateContentorPosition];\n}\n\n- (void) setLabelorOffsetY:(CGFloat)labelorOffsetY\n{\n    _labelorOffsetY = labelorOffsetY;\n    [self updateLabelorPosition];\n}\n\n- (void) updateLabelorPosition\n{\n    _labelor.position = CGPointMake(self.position.x + (self.width - self.labelor.width)/2, self.position.y - (CGRectGetMaxY(self.contentor.displayBounds) + _braceHeight + self.labelor.ascent));\n}\n\n- (void) updateContentorPosition\n{\n    _contentor.position = CGPointMake(self.position.x + (self.width - self.contentor.width)/2, self.position.y + self.contentorOffsetY);\n}\n\n- (void) setPosition:(CGPoint)position\n{\n    super.position = position;\n    [self updateContentorPosition];\n    [self updateLabelorPosition];\n}\n\n- (void)draw:(CGContextRef)context\n{\n    [super draw:context];\n    [self.labelor draw:context];\n    [self.contentor draw:context];\n\n    CGContextSaveGState(context);\n    UIBezierPath *path = [UIBezierPath bezierPath];\n    CGFloat tail = 2;\n    CGFloat margin = 0;\n    CGFloat arrowDown = YES;\n    CGFloat marginTop = -(CGRectGetMaxY(self.contentor.displayBounds));\n    CGFloat braceWidth = self.contentor.width < 20 ? 20 : self.contentor.width;\n    CGFloat left = (self.width - braceWidth) / 2 + self.position.x;\n    CGRect braceRct = CGRectMake(margin + self.position.x, marginTop, braceWidth, _braceHeight);\n    CGPoint startPoint = CGPointMake(margin + left, arrowDown ? CGRectGetMaxY(braceRct) : CGRectGetMinY(braceRct));\n    [path moveToPoint:startPoint];\n    [path addLineToPoint:CGPointMake(startPoint.x + tail, startPoint.y + (arrowDown ? -tail : tail))];\n    [path addLineToPoint:CGPointMake(CGRectGetWidth(braceRct) / 2 - tail - margin + left, startPoint.y + (arrowDown ? -tail : tail))];\n    [path addLineToPoint:CGPointMake(CGRectGetWidth(braceRct) / 2 - margin + left, arrowDown ? CGRectGetMinY(braceRct) : CGRectGetMaxY(braceRct))];\n    [path addLineToPoint:CGPointMake(CGRectGetWidth(braceRct) / 2 + tail - margin + left, startPoint.y + (arrowDown ? -tail : tail))];\n    [path addLineToPoint:CGPointMake(CGRectGetWidth(braceRct) - tail - margin + left, startPoint.y + (arrowDown ? -tail : tail))];\n    [path addLineToPoint:CGPointMake(CGRectGetWidth(braceRct) - margin + left, arrowDown ? CGRectGetMaxY(braceRct) : CGRectGetMinY(braceRct))];\n    [UIColor.blackColor setStroke];\n    path.lineWidth = 1;\n    path.lineCapStyle = kCGLineCapRound;\n    // 执行绘制\n    [path stroke];\n\n    // 恢复上下文状态\n    CGContextRestoreGState(context);\n}\n\n\n@end\n\n#pragma mark - MTAccentDisplay\n\n@implementation MTAccentDisplay\n\n- (instancetype)initWithAccent:(MTGlyphDisplay*) glyph accentee:(MTMathListDisplay*) accentee range:(NSRange) range\n{\n    self = [super init];\n    if (self) {\n        _accent = glyph;\n        _accentee = accentee;\n        _accentee.position = CGPointZero;\n        self.range = range;\n    }\n    return self;\n}\n\n- (void)setTextColor:(MTColor *)textColor\n{\n    [super setTextColor:textColor];\n    _accentee.textColor = textColor;\n    _accent.textColor = textColor;\n}\n\n- (void) setPosition:(CGPoint)position\n{\n    super.position = position;\n    [self updateAccenteePosition];\n}\n\n- (void) updateAccenteePosition\n{\n    self.accentee.position = CGPointMake(self.position.x, self.position.y);\n}\n\n- (void)draw:(CGContextRef)context\n{\n    [super draw:context];\n    [self.accentee draw:context];\n    \n    CGContextSaveGState(context);\n    CGContextTranslateCTM(context, self.position.x, self.position.y);\n    CGContextSetTextPosition(context, 0, 0);\n    \n    [self.accent draw:context];\n    \n    \n    CGContextRestoreGState(context);\n}\n@end\n\n#pragma mark - MTInnerDisplay\n\n@implementation MTInnerDisplay {\n  MTMathListDisplay *_inner;\n}\n\n- (instancetype) initWithInner:(MTMathListDisplay*) inner leftDelimiter:(MTDisplay*) leftDelimiter rightDelimiter:(MTDisplay*) rightDelimiter atIndex:(NSUInteger) index\n{\n  self = [super init];\n  if (self) {\n    _leftDelimiter = leftDelimiter;\n    _rightDelimiter = rightDelimiter;\n    _inner = inner;\n    _index = index;\n    self.range = NSMakeRange(_index, 1);\n    \n    self.width = leftDelimiter.width + inner.width + rightDelimiter.width;\n  }\n  return self;\n}\n\n- (void)setPosition:(CGPoint)position\n{\n  super.position = position;\n  [self updateLeftDelimiterPosition];\n  [self updateInnerPosition];\n  [self updateRightDelimiterPosition];\n}\n\n- (void) updateLeftDelimiterPosition\n{\n  if (_leftDelimiter) {\n    _leftDelimiter.position = self.position;\n  }\n}\n\n- (void) updateRightDelimiterPosition\n{\n  if (_rightDelimiter) {\n    _rightDelimiter.position = CGPointMake(_inner.position.x + _inner.width, self.position.y);    \n  }\n}\n\n- (void) updateInnerPosition\n{\n  if (_leftDelimiter) {\n    _inner.position = CGPointMake(_leftDelimiter.position.x + _leftDelimiter.width, self.position.y);\n  } else {\n    _inner.position = self.position;\n  }\n}\n\n- (CGFloat)ascent\n{\n    CGFloat maxAscent = 0;\n    \n    if (_leftDelimiter) {\n        maxAscent = MAX(_leftDelimiter.ascent, maxAscent);\n    }\n    \n    if (_rightDelimiter) {\n        maxAscent = MAX(_rightDelimiter.ascent, maxAscent);\n    }\n    \n    maxAscent = MAX(_inner.ascent, maxAscent);\n    \n  return maxAscent;\n}\n\n- (CGFloat)descent\n{\n    CGFloat maxDescent = 0;\n    \n    if (_leftDelimiter) {\n        maxDescent = MAX(_leftDelimiter.ascent, maxDescent);\n    }\n    \n    if (_rightDelimiter) {\n        maxDescent = MAX(_rightDelimiter.ascent, maxDescent);\n    }\n    \n    maxDescent = MAX(_inner.ascent, maxDescent);\n    \n  return maxDescent;\n}\n\n- (CGFloat)width\n{\n  CGFloat w = _inner.width;\n  if (_leftDelimiter) {\n    w += _leftDelimiter.width;\n  }\n  if (_rightDelimiter) {\n    w += _rightDelimiter.width;\n  }\n  return w;\n}\n\n- (void)setTextColor:(MTColor *)textColor\n{\n  [super setTextColor:textColor];\n  self.leftDelimiter.textColor = textColor;\n  self.rightDelimiter.textColor = textColor;\n  _inner.textColor = textColor;\n}\n\n- (void)draw:(CGContextRef)context\n{\n  [super draw:context];\n  // Draw the elements.\n  [self.leftDelimiter draw:context];\n  [self.rightDelimiter draw:context];\n  [_inner draw:context];\n}\n\n@end\n\n#pragma mark - MTAdaptiveDisplay\n\n@implementation MTAdaptiveDisplay\n\n- (instancetype)initWithDelimiter:(MTDisplay *)delimiter range:(NSRange)range\n{\n    self = [super init];\n    if (self) {\n        _delimiter = delimiter;\n        self.range = range;\n        self.width = delimiter.width;\n    }\n    return self;\n}\n\n- (void)setPosition:(CGPoint)position\n{\n    super.position = position;\n    _delimiter.position = position;\n}\n\n- (CGFloat)ascent\n{\n    return _delimiter.ascent;\n}\n\n- (CGFloat)descent\n{\n    return _delimiter.descent;\n}\n\n- (CGFloat)width\n{\n    return _delimiter.width;\n}\n\n- (void)draw:(CGContextRef)context\n{\n    [super draw:context];\n    [self.delimiter draw:context];\n}\n\n@end\n\n#pragma mark - MTBoxedDisplay\n\n@implementation MTBoxedDisplay\n\n- (instancetype)initWithInner:(MTMathListDisplay *)inner lineThickness:(CGFloat)lineThickness\n{\n    self = [super init];\n    if (self) {\n        _inner = inner;\n        _lineThickness = lineThickness;\n        CGFloat horizontalPadding = 4.0;\n        CGFloat verticalPadding = 4.0;\n        self.width = inner.width + 2 * (lineThickness + horizontalPadding);\n        self.ascent = inner.ascent + lineThickness + verticalPadding;\n        self.descent = inner.descent + lineThickness + verticalPadding;\n        _horizontalPadding = horizontalPadding;\n        _verticalPadding = verticalPadding;\n    }\n    return self;\n}\n\n- (void)setPosition:(CGPoint)position\n{\n    super.position = position;\n    [self updateInnerPosition];\n}\n\n- (void)updateInnerPosition\n{\n    _inner.position = CGPointMake(self.position.x + self.lineThickness + _horizontalPadding, self.position.y);\n}\n\n- (void)setTextColor:(MTColor *)textColor\n{\n    [super setTextColor:textColor];\n    _inner.textColor = textColor;\n}\n\n- (void)draw:(CGContextRef)context\n{\n    [super draw:context];\n    [_inner draw:context];\n    CGContextSaveGState(context);\n    [self.textColor setStroke];\n    CGRect boxRect = CGRectMake(\n        self.position.x + self.lineThickness/2,\n        self.position.y - self.descent + self.lineThickness/2,\n        self.width - self.lineThickness,\n        self.ascent + self.descent - self.lineThickness\n    );\n    MTBezierPath* path = [MTBezierPath bezierPathWithRect:boxRect];\n    path.lineWidth = self.lineThickness;\n    [path stroke];\n    CGContextRestoreGState(context);\n}\n\n@end\n\n#pragma mark - MTMathTagDisplay\n\n@implementation MTMathTagDisplay\n\n\n- (instancetype)initWithString:(NSAttributedString*) attrString position:(CGPoint)position range:(NSRange) range font:(MTFont*) font atoms:(NSArray<MTMathAtom*>*) atoms\n{\n    self = [super init];\n    if (self) {\n        self.position = position;\n        self.attributedString = attrString;\n        self.range = range;\n        _atoms = atoms;\n        // We can't use typographic bounds here as the ascent and descent returned are for the font and not for the line.\n        self.width = CTLineGetTypographicBounds(_line, NULL, NULL, NULL);\n        if (isIos6Supported()) {\n            CGRect bounds = CTLineGetBoundsWithOptions(_line, kCTLineBoundsUseGlyphPathBounds);\n            self.ascent = MAX(0, CGRectGetMaxY(bounds) - 0);\n            self.descent = MAX(0, 0 - CGRectGetMinY(bounds));\n            // TODO: Should we use this width vs the typographic width? They are slightly different. Don't know why.\n            // _width = CGRectGetMaxX(bounds);\n        } else {\n            // Our own implementation of the ios6 function to get glyph path bounds.\n            [self computeDimensions:font];\n        }\n    }\n    return self;\n}\n\n- (void) setAttributedString:(NSAttributedString*) attrString\n{\n    if (_line) {\n        CFRelease(_line);\n    }\n    _attributedString = [attrString copy];\n    _line = CTLineCreateWithAttributedString((__bridge CFAttributedStringRef)(_attributedString));\n}\n\n- (void)setTextColor:(MTColor *)textColor\n{\n    [super setTextColor:textColor];\n    NSMutableAttributedString* attrStr = self.attributedString.mutableCopy;\n    [attrStr addAttribute:(NSString*)kCTForegroundColorAttributeName value:(id)self.textColor.CGColor\n                    range:NSMakeRange(0, attrStr.length)];\n    self.attributedString = attrStr;\n}\n\n- (void) computeDimensions:(MTFont*) font\n{\n    NSArray* runs = (__bridge NSArray *)(CTLineGetGlyphRuns(_line));\n    for (id obj in runs) {\n        CTRunRef run = (__bridge CTRunRef)(obj);\n        CFIndex numGlyphs = CTRunGetGlyphCount(run);\n        CGGlyph glyphs[numGlyphs];\n        CTRunGetGlyphs(run, CFRangeMake(0, numGlyphs), glyphs);\n        CGRect bounds = CTFontGetBoundingRectsForGlyphs(font.ctFont, kCTFontHorizontalOrientation, glyphs, NULL, numGlyphs);\n        CGFloat ascent = MAX(0, CGRectGetMaxY(bounds) - 0);\n        // Descent is how much the line goes below the origin. However if the line is all above the origin, then descent can't be negative.\n        CGFloat descent = MAX(0, 0 - CGRectGetMinY(bounds));\n        if (ascent > self.ascent) {\n            self.ascent = ascent;\n        }\n        if (descent > self.descent) {\n            self.descent = descent;\n        }\n    }\n}\n\n- (void)dealloc\n{\n    CFRelease(_line);\n}\n\n- (void)draw:(CGContextRef)context\n{\n    [super draw:context];\n    CGContextSaveGState(context);\n    CGRect rect = CGContextGetClipBoundingBox(context);\n    CGContextSetTextPosition(context, rect.size.width - 12 - self.width, self.position.y);\n    CTLineDraw(self.line, context);\n    \n    CGContextRestoreGState(context);\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/render/MTMathUILabel.h",
    "content": "//\n//  MathUILabel.h\n//  iosMath\n//\n//  Created by Kostub Deshmukh on 8/26/13.\n//  Copyright (C) 2013 MathChat\n//\n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n@import CoreText;\n\n// Compatibility of iOS and Mac OS.\n#import \"MTConfig.h\"\n\n#import \"MTFont.h\"\n#import \"MTMathList.h\"\n#import \"MTMathListDisplay.h\"\n\n/**\n @typedef MTMathUILabelMode\n @brief Different display styles supported by the `MTMathUILabel`.\n \n @note: The only significant difference between the two modes is how fractions\n and limits on large operators are displayed.\n */\ntypedef NS_ENUM(unsigned int, MTMathUILabelMode) {\n    /// Display mode. Equivalent to $$ in TeX\n    kMTMathUILabelModeDisplay,\n    /// Text mode. Equivalent to $ in TeX.\n    kMTMathUILabelModeText\n};\n\n/**\n @typedef MTTextAlignment\n @brief Horizontal text alignment for `MTMathUILabel`.\n */\ntypedef NS_ENUM(unsigned int, MTTextAlignment) {\n    /// Align left.\n    kMTTextAlignmentLeft,\n    /// Align center.\n    kMTTextAlignmentCenter,\n    /// Align right.\n    kMTTextAlignmentRight,\n};\n\n/** The main view for rendering math.\n \n `MTMathLabel` accepts either a string in LaTeX or an `MTMathList` to display. Use\n `MTMathList` directly only if you are building it programmatically (e.g. using an\n editor), otherwise using LaTeX is the preferable method.\n \n The math display is centered vertically in the label. The default horizontal alignment is\n is left. This can be changed by setting `textAlignment`. The math is default displayed in\n *Display* mode. This can be changed using `labelMode`.\n \n When created it uses `[MTFontManager defaultFont]` as its font. This can be changed using\n the `font` parameter.\n */\nIB_DESIGNABLE @interface MTMathUILabel : MTView\n\n/** The `MTMathList` to render. Setting this will remove any\n `latex` that has already been set. If `latex` has been set, this will\n return the parsed `MTMathList` if the `latex` parses successfully. Use this\n setting if the `MTMathList` has been programmatically constructed, otherwise it\n is preferred to use `latex`.\n */\n@property (nonatomic, nullable) MTMathList* mathList;\n\n/** The latex string to be displayed. Setting this will remove any `mathList` that\n has been set. If latex has not been set, this will return the latex output for the\n `mathList` that is set.\n @see error */\n@property (nonatomic, nullable) IBInspectable NSString* latex;\n\n/** This contains any error that occurred when parsing the latex. */\n@property (nonatomic, readonly, nullable) NSError* error;\n\n/** If true, if there is an error it displays the error message inline. Default true. */\n@property (nonatomic) BOOL displayErrorInline;\n\n/** The MTFont to use for rendering. */\n@property (nonatomic, nonnull) MTFont* font;\n\n/** Convenience method to just set the size of the font without changing the fontface. */\n@property (nonatomic) IBInspectable CGFloat fontSize;\n\n/** This sets the text color of the rendered math formula. The default color is black. */\n@property (nonatomic, nonnull) IBInspectable MTColor* textColor;\n\n/** The minimum distance from the margin of the view to the rendered math. This value is\n `UIEdgeInsetsZero` by default. This is useful if you need some padding between the math and\n the border/background color. sizeThatFits: will have its returned size increased by these insets.\n */\n@property (nonatomic) IBInspectable MTEdgeInsets contentInsets;\n\n/** The Label mode for the label. The default mode is Display */\n@property (nonatomic) MTMathUILabelMode labelMode;\n\n/** Horizontal alignment for the text. The default is align left. */\n@property (nonatomic) MTTextAlignment textAlignment;\n\n/** The internal display of the MTMathUILabel. This is for advanced use only. */\n@property (nonatomic, readonly, nullable) MTMathListDisplay* displayList;\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/render/MTMathUILabel.m",
    "content": "//\n//  MathUILabel.m\n//  iosMath\n//\n//  Created by Kostub Deshmukh on 8/26/13.\n//  Copyright (C) 2013 MathChat\n//\n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n#import \"MTMathUILabel.h\"\n#import \"MTMathListDisplay.h\"\n#import \"MTFontManager.h\"\n#import \"MTMathListBuilder.h\"\n#import \"MTTypesetter.h\"\n\n@implementation MTMathUILabel {\n    MTLabel* _errorLabel;\n}\n\n- (instancetype)initWithFrame:(CGRect)frame\n{\n    self = [super initWithFrame:frame];\n    if (self) {\n        [self initCommon];\n    }\n    return self;\n}\n\n- (instancetype)initWithCoder:(NSCoder *)aDecoder\n{\n    self = [super initWithCoder:aDecoder];\n    if (self) {\n        [self initCommon];\n    }\n    return self;\n}\n\n- (void) initCommon\n{\n    self.layer.geometryFlipped = YES;  // For ease of interaction with the CoreText coordinate system.\n    // default font size\n    _fontSize = 20;\n    _contentInsets = MTEdgeInsetsZero;\n    _labelMode = kMTMathUILabelModeDisplay;\n    MTFont* font = [MTFontManager fontManager].defaultFont;\n    self.font = font;\n    _textAlignment = kMTTextAlignmentLeft;\n    _displayList = nil;\n    _displayErrorInline = true;\n    self.backgroundColor = [MTColor clearColor];\n    \n    _textColor = [MTColor blackColor];\n    _errorLabel = [[MTLabel alloc] init];\n    _errorLabel.hidden = YES;\n    _errorLabel.layer.geometryFlipped = YES;\n    _errorLabel.textColor = [MTColor redColor];\n    [self addSubview:_errorLabel];\n}\n\n#if !TARGET_OS_IPHONE\n- (void)setNeedsLayout\n{\n    [self setNeedsLayout:YES];\n}\n\n- (void)setNeedsDisplay\n{\n    [self setNeedsDisplay:YES];\n}\n\n- (BOOL)isFlipped\n{\n    return NO;\n}\n#endif\n\n- (void)setFont:(MTFont*)font\n{\n    NSParameterAssert(font);\n    _font = font;\n    [self invalidateIntrinsicContentSize];\n    [self setNeedsLayout];\n}\n\n- (void)setFontSize:(CGFloat)fontSize\n{\n    _fontSize = fontSize;\n    MTFont* font = [_font copyFontWithSize:_fontSize];\n    self.font = font;\n}\n\n- (void)setContentInsets:(MTEdgeInsets)contentInsets\n{\n    _contentInsets = contentInsets;\n    [self invalidateIntrinsicContentSize];\n    [self setNeedsLayout];\n}\n\n- (void) setMathList:(MTMathList *)mathList\n{\n    _mathList = mathList;\n    _error = nil;\n    _latex = [MTMathListBuilder mathListToString:mathList];\n    [self invalidateIntrinsicContentSize];\n    [self setNeedsLayout];\n}\n\n- (void)setLatex:(NSString *)latex\n{\n    _latex = latex;\n    _error = nil;\n    NSError* error = nil;\n    _mathList = [MTMathListBuilder buildFromString:latex error:&error];\n    if (error) {\n        _mathList = nil;\n        _error = error;\n        _errorLabel.text = error.localizedDescription;\n        _errorLabel.frame = self.bounds;\n        _errorLabel.hidden = !self.displayErrorInline;\n    } else {\n        _errorLabel.hidden = YES;\n    }\n    [self invalidateIntrinsicContentSize];\n    [self setNeedsLayout];\n}\n\n- (void)setLabelMode:(MTMathUILabelMode)labelMode\n{\n    _labelMode = labelMode;\n    [self invalidateIntrinsicContentSize];\n    [self setNeedsLayout];\n}\n\n- (void)setTextColor:(MTColor *)textColor\n{\n    NSParameterAssert(textColor);\n    _textColor = textColor;\n    _displayList.textColor = textColor;\n    [self setNeedsDisplay];\n}\n\n- (void)setTextAlignment:(MTTextAlignment)textAlignment\n{\n    _textAlignment = textAlignment;\n    [self invalidateIntrinsicContentSize];\n    [self setNeedsLayout];\n}\n\n- (MTLineStyle) currentStyle\n{\n    switch (_labelMode) {\n        case kMTMathUILabelModeDisplay:\n            return kMTLineStyleDisplay;\n        case kMTMathUILabelModeText:\n            return kMTLineStyleText;\n    }\n}\n\n// Only override drawRect: if you perform custom drawing.\n// An empty implementation adversely affects performance during animation.\n- (void)drawRect:(MTRect)rect\n{\n    [super drawRect:rect];\n    \n    if (!_mathList) {\n        return;\n    }\n    \n    // Drawing code\n    CGContextRef context = MTGraphicsGetCurrentContext();\n    CGContextSaveGState(context);\n    \n    [_displayList draw:context];\n    \n    CGContextRestoreGState(context);\n}\n\n- (void) layoutSubviews\n{\n    if (_mathList) {\n        _displayList = [MTTypesetter createLineForMathList:_mathList font:_font style:self.currentStyle];\n        _displayList.textColor = _textColor;\n        \n        // Determine x position based on alignment\n        CGFloat textX = 0;\n        switch (self.textAlignment) {\n            case kMTTextAlignmentLeft:\n                textX = self.contentInsets.left;\n                break;\n            case kMTTextAlignmentCenter:\n                textX = (self.bounds.size.width - self.contentInsets.left - self.contentInsets.right - _displayList.width) / 2 + self.contentInsets.left;\n                break;\n            case kMTTextAlignmentRight:\n                textX = (self.bounds.size.width - _displayList.width - self.contentInsets.right);\n                break;\n        }\n        \n        CGFloat availableHeight = self.bounds.size.height - self.contentInsets.bottom - self.contentInsets.top;\n        // center things vertically\n        CGFloat height = _displayList.ascent + _displayList.descent;\n        if (height < _fontSize/2) {\n            // Set the height to the half the size of the font\n            height = _fontSize/2;\n        }\n        CGFloat textY = (availableHeight - height) / 2 + _displayList.descent + self.contentInsets.bottom;\n        _displayList.position = CGPointMake(textX, textY);\n    } else {\n        _displayList = nil;\n    }\n    _errorLabel.frame = self.bounds;\n    [self setNeedsDisplay];\n}\n\n#if !TARGET_OS_IPHONE\n- (void)layout\n{\n    [self layoutSubviews];\n    [super layout];\n}\n#endif\n\n- (CGSize) sizeThatFits:(CGSize)size\n{\n    MTMathListDisplay* displayList = nil;\n    if (_mathList) {\n        displayList = [MTTypesetter createLineForMathList:_mathList font:_font style:self.currentStyle];\n    }\n    \n    size.width = displayList.width + self.contentInsets.left + self.contentInsets.right;\n    size.height = displayList.ascent + displayList.descent + self.contentInsets.top + self.contentInsets.bottom;\n    return size;\n}\n\n- (CGSize) intrinsicContentSize\n{\n    return [self sizeThatFits:CGSizeZero];\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/render/NSBezierPath+addLineToPoint.h",
    "content": "//\n//  NSBezierPath+addLineToPoint.h\n//  MacOSMath\n//\n//  Created by 安志钢 on 17-01-09.\n//\n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n#include <TargetConditionals.h>\n\n#if !TARGET_OS_IPHONE\n#import <Cocoa/Cocoa.h>\n\n@interface NSBezierPath (addLineToPoint)\n\n- (void)addLineToPoint:(CGPoint)point;\n\n@end\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/render/NSBezierPath+addLineToPoint.m",
    "content": "//\n//  NSBezierPath+addLineToPoint.m\n//  MacOSMath\n//\n//  Created by 安志钢 on 17-01-09.\n//\n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n#import \"NSBezierPath+addLineToPoint.h\"\n\n#if !TARGET_OS_IPHONE\n@implementation NSBezierPath (addLineToPoint)\n\n- (void)addLineToPoint:(CGPoint)point\n{\n    [self lineToPoint:point];\n}\n\n@end\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/render/NSColor+HexString.h",
    "content": "//\n//  NSColor+HexString.h\n//  iosMath\n//\n//  Created by Markus Sähn on 21/03/2017.\n//\n//\n\n#include <TargetConditionals.h>\n\n#if !TARGET_OS_IPHONE\n#import <Cocoa/Cocoa.h>\n\n@interface NSColor (HexString)\n\n+ (NSColor *)colorFromHexString:(NSString *)hexString;\n\n@end\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/render/NSColor+HexString.m",
    "content": "//\n//  NSColor+HexString.m\n//  iosMath\n//\n//  Created by Markus Sähn on 21/03/2017.\n//\n//\n\n#import \"NSColor+HexString.h\"\n\n#if !TARGET_OS_IPHONE\n@implementation NSColor (HexString)\n\n+ (NSColor *)colorFromHexString:(NSString *)hexString {\n    if ([hexString isEqualToString:@\"\"]) {\n        return nil;\n    }\n    \n    if ([hexString characterAtIndex:0] != '#') {\n        return nil;\n    }\n    \n    unsigned rgbValue = 0;\n    \n    NSScanner *scanner = [NSScanner scannerWithString:hexString];\n    if ([hexString characterAtIndex:0] == '#') {\n        [scanner setScanLocation:1];\n    }\n    \n    [scanner scanHexInt:&rgbValue];\n    // NOTE: red:green:blue:alpha: in AppKit/NSColor.h is NS_AVAILABLE_MAC(10_9), unavailable for macOS 10.8 .\n    // Older method name colorWithSRGBRed::green:blue:alpha: works.\n    return [NSColor colorWithSRGBRed:((rgbValue & 0xFF0000) >> 16)/255.0 green:((rgbValue & 0xFF00) >> 8)/255.0 blue:(rgbValue & 0xFF)/255.0 alpha:1.0];\n}\n\n@end\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/render/NSView+backgroundColor.h",
    "content": "//\n//  NSView+backgroundColor.h\n//  MacOSMath\n//\n//  Created by 安志钢 on 17-01-09.\n//\n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n#include <TargetConditionals.h>\n\n#if !TARGET_OS_IPHONE\n#import <Cocoa/Cocoa.h>\n\n@interface NSView (backgroundColor)\n\n@property (strong) NSColor *backgroundColor;\n\n@end\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/render/NSView+backgroundColor.m",
    "content": "//\n//  NSView+backgroundColor.m\n//  MacOSMath\n//\n//  Created by 安志钢 on 17-01-09.\n//\n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n#import \"NSView+backgroundColor.h\"\n\n#if !TARGET_OS_IPHONE\n@implementation NSView (backgroundColor)\n\n- (NSColor *)backgroundColor\n{\n\tif (self.layer.backgroundColor == nil) {\n\t\treturn [NSColor clearColor];\n\t}\n    return [NSColor colorWithCGColor:self.layer.backgroundColor];\n}\n\n- (void)setBackgroundColor:(NSColor *)backgroundColor\n{\n    self.layer.backgroundColor = [NSColor clearColor].CGColor;\n    [self setWantsLayer:YES];\n}\n\n@end\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/render/UIColor+HexString.h",
    "content": "//\n//  UIColor+HexString.h\n//  iosMath\n//\n//  Created by Markus Sähn on 21/03/2017.\n//\n//\n\n#if TARGET_OS_IPHONE\n\n@interface UIColor (HexString)\n\n+ (UIColor *)colorFromHexString:(NSString *)hexString;\n\n@end\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/render/UIColor+HexString.m",
    "content": "//\n//  UIColor+HexString.m\n//  iosMath\n//\n//  Created by Markus Sähn on 21/03/2017.\n//\n//\n\n#import \"UIColor+HexString.h\"\n\n#if TARGET_OS_IPHONE\n\n@implementation UIColor (HexString)\n\n+ (UIColor *)colorFromHexString:(NSString *)hexString {\n    if ([hexString isEqualToString:@\"\"]) {\n        return nil;\n    }\n    \n    if ([hexString characterAtIndex:0] != '#') {\n        return nil;\n    }\n    \n    unsigned rgbValue = 0;\n    \n    NSScanner *scanner = [NSScanner scannerWithString:hexString];\n    if ([hexString characterAtIndex:0] == '#') {\n        [scanner setScanLocation:1];\n    }\n    \n    [scanner scanHexInt:&rgbValue];\n    return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0 green:((rgbValue & 0xFF00) >> 8)/255.0 blue:(rgbValue & 0xFF)/255.0 alpha:1.0];\n}\n\n@end\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/render/internal/MTFont+Internal.h",
    "content": "//\n//  MTFont+Internal.h\n//  iosMath\n//\n//  Created by Kostub Deshmukh on 5/20/16.\n//\n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n#import \"MTFont.h\"\n#import \"MTFontMathTable.h\"\n\n/** This category add functions to MTFont that are meant to be internal\n to this library for rendering purposes. */\n@interface MTFont (Internal)\n\n/** Load the font with a given name. This is the designated initializer. */\n- (nonnull instancetype) initFontWithName:(nonnull NSString*) name size:(CGFloat) size;\n\n/** Access to the raw CTFontRef if needed. */\n@property (nonatomic, readonly, nonnull) CTFontRef ctFont;\n\n/** The font math table. */\n@property (nonatomic, readonly, nonnull) MTFontMathTable* mathTable;\n\n/** Returns the name of the given glyph or null if the glyph\n is not associated with the font. */\n- (nullable NSString*) getGlyphName:(CGGlyph) glyph;\n\n/** Returns a glyph associated with the given name. */\n- (CGGlyph) getGlyphWithName:(nonnull NSString*) glyphName;\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/render/internal/MTFontMathTable.h",
    "content": "//\n//  MTFontMathTable.h\n//  iosMath\n//\n//  Created by Kostub Deshmukh on 8/28/13.\n//  Copyright (C) 2013 MathChat\n//   \n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n@import Foundation;\n@import CoreText;\n\n@class MTFont;\n\n/** MTGlyphPart represents a part of a glyph used for assembling a large vertical or horizontal\n glyph. */\n@interface MTGlyphPart : NSObject\n\n/// The glyph that represents this part\n@property (nonatomic, readonly) CGGlyph glyph;\n\n/// Full advance width/height for this part, in the direction of the extension in points.\n@property (nonatomic, readonly) CGFloat fullAdvance;\n\n/// Advance width/ height of the straight bar connector material at the beginning of the glyph in points.\n@property (nonatomic, readonly) CGFloat startConnectorLength;\n\n/// Advance width/ height of the straight bar connector material at the end of the glyph in points.\n@property (nonatomic, readonly) CGFloat endConnectorLength;\n\n/// If this part is an extender. If set, the part can be skipped or repeated.\n@property (nonatomic, readonly) BOOL isExtender;\n\n@end\n\n/** This class represents the Math table of an open type font.\n \n The math table is documented here: https://www.microsoft.com/typography/otspec/math.htm\n \n How the constants in this class affect the display is documented here:\n http://www.tug.org/TUGboat/tb30-1/tb94vieth.pdf\n\n @note We don't parse the math table from the open type font. Rather we parse it\n in python and convert it to a .plist file which is easily consumed by this class.\n This approach is preferable to spending an inordinate amount of time figuring out\n how to parse the returned NSData object using the open type rules.\n \n @remark This class is not meant to be used outside of this library.\n */\n@interface MTFontMathTable : NSObject\n\n- (nonnull instancetype) initWithFont:(nonnull MTFont*) font mathTable:(nonnull NSDictionary*) mathTable NS_DESIGNATED_INITIALIZER;\n- (nonnull instancetype) init NS_UNAVAILABLE;\n\n/** MU unit in points */\n@property (nonatomic, readonly) CGFloat muUnit;\n\n// Math Font Metrics from the opentype specification\n#pragma mark Fractions\n@property (nonatomic, readonly) CGFloat fractionNumeratorDisplayStyleShiftUp;          // \\sigma_8 in TeX\n@property (nonatomic, readonly) CGFloat fractionNumeratorShiftUp;                      // \\sigma_9 in TeX\n@property (nonatomic, readonly) CGFloat fractionDenominatorDisplayStyleShiftDown;      // \\sigma_11 in TeX\n@property (nonatomic, readonly) CGFloat fractionDenominatorShiftDown;                  // \\sigma_12 in TeX\n@property (nonatomic, readonly) CGFloat fractionNumeratorDisplayStyleGapMin;           // 3 * \\xi_8 in TeX\n@property (nonatomic, readonly) CGFloat fractionNumeratorGapMin;                       // \\xi_8 in TeX\n@property (nonatomic, readonly) CGFloat fractionDenominatorDisplayStyleGapMin;         // 3 * \\xi_8 in TeX\n@property (nonatomic, readonly) CGFloat fractionDenominatorGapMin;                     // \\xi_8 in TeX\n@property (nonatomic, readonly) CGFloat fractionRuleThickness;                         // \\xi_8 in TeX\n@property (nonatomic, readonly) CGFloat fractionDelimiterDisplayStyleSize;             // \\sigma_20 in TeX\n@property (nonatomic, readonly) CGFloat fractionDelimiterSize;                         // \\sigma_21 in TeX\n\n#pragma mark Stacks\n@property (nonatomic, readonly) CGFloat stackTopDisplayStyleShiftUp;                   // \\sigma_8 in TeX\n@property (nonatomic, readonly) CGFloat stackTopShiftUp;                               // \\sigma_10 in TeX\n@property (nonatomic, readonly) CGFloat stackDisplayStyleGapMin;                       // 7 \\xi_8 in TeX\n@property (nonatomic, readonly) CGFloat stackGapMin;                                   // 3 \\xi_8 in TeX\n@property (nonatomic, readonly) CGFloat stackBottomDisplayStyleShiftDown;              // \\sigma_11 in TeX\n@property (nonatomic, readonly) CGFloat stackBottomShiftDown;                          // \\sigma_12 in TeX\n\n#pragma mark super/sub scripts\n\n@property (nonatomic, readonly) CGFloat superscriptShiftUp;                            // \\sigma_13, \\sigma_14 in TeX\n@property (nonatomic, readonly) CGFloat superscriptShiftUpCramped;                     // \\sigma_15 in TeX\n@property (nonatomic, readonly) CGFloat subscriptShiftDown;                            // \\sigma_16, \\sigma_17 in TeX\n@property (nonatomic, readonly) CGFloat superscriptBaselineDropMax;                    // \\sigma_18 in TeX\n@property (nonatomic, readonly) CGFloat subscriptBaselineDropMin;                      // \\sigma_19 in TeX\n@property (nonatomic, readonly) CGFloat superscriptBottomMin;                          // 1/4 \\sigma_5 in TeX\n@property (nonatomic, readonly) CGFloat subscriptTopMax;                               // 4/5 \\sigma_5 in TeX\n@property (nonatomic, readonly) CGFloat subSuperscriptGapMin;                          // 4 \\xi_8 in TeX\n@property (nonatomic, readonly) CGFloat superscriptBottomMaxWithSubscript;             // 4/5 \\sigma_5 in TeX\n\n@property (nonatomic, readonly) CGFloat spaceAfterScript;\n\n#pragma mark radicals\n@property (nonatomic, readonly) CGFloat radicalExtraAscender;                          // \\xi_8 in Tex\n@property (nonatomic, readonly) CGFloat radicalRuleThickness;                          // \\xi_8 in Tex\n@property (nonatomic, readonly) CGFloat radicalDisplayStyleVerticalGap;                // \\xi_8 + 1/4 \\sigma_5 in Tex\n@property (nonatomic, readonly) CGFloat radicalVerticalGap;                            // 5/4 \\xi_8 in Tex\n@property (nonatomic, readonly) CGFloat radicalKernBeforeDegree;                       // 5 mu in Tex\n@property (nonatomic, readonly) CGFloat radicalKernAfterDegree;                        // -10 mu in Tex\n@property (nonatomic, readonly) CGFloat radicalDegreeBottomRaisePercent;               // 60% in Tex\n\n#pragma mark Limits\n@property (nonatomic, readonly) CGFloat upperLimitBaselineRiseMin;                     // \\xi_11 in TeX\n@property (nonatomic, readonly) CGFloat upperLimitGapMin;                              // \\xi_9 in TeX\n@property (nonatomic, readonly) CGFloat lowerLimitGapMin;                              // \\xi_10 in TeX\n@property (nonatomic, readonly) CGFloat lowerLimitBaselineDropMin;                     // \\xi_12 in TeX\n@property (nonatomic, readonly) CGFloat limitExtraAscenderDescender;                   // \\xi_13 in TeX, not present in OpenType so we always set it to 0.\n\n#pragma mark Underline\n@property (nonatomic, readonly) CGFloat underbarVerticalGap;                           // 3 \\xi_8 in TeX\n@property (nonatomic, readonly) CGFloat underbarRuleThickness;                         // \\xi_8 in TeX\n@property (nonatomic, readonly) CGFloat underbarExtraDescender;                        // \\xi_8 in TeX\n\n#pragma mark Overline\n@property (nonatomic, readonly) CGFloat overbarVerticalGap;                            // 3 \\xi_8 in TeX\n@property (nonatomic, readonly) CGFloat overbarRuleThickness;                          // \\xi_8 in TeX\n@property (nonatomic, readonly) CGFloat overbarExtraAscender;                          // \\xi_8 in TeX\n\n#pragma mark Constants\n\n@property (nonatomic, readonly) CGFloat axisHeight;                                    // \\sigma_22 in TeX\n@property (nonatomic, readonly) CGFloat scriptScaleDown;\n@property (nonatomic, readonly) CGFloat scriptScriptScaleDown;\n\n#pragma mark Accent\n\n@property (nonatomic, readonly) CGFloat accentBaseHeight;                              // \\fontdimen5 in TeX (x-height)\n\n#pragma mark Variants\n\n/** Returns an NSArray of all the vertical variants of the glyph if any. If\n there are no variants for the glyph, the array contains the given glyph. */\n- (nonnull NSArray<NSNumber*>*) getVerticalVariantsForGlyph:(CGGlyph) glyph;\n\n/** Returns an NSArray of all the horizontal variants of the glyph if any. If\n there are no variants for the glyph, the array contains the given glyph. */\n- (nonnull NSArray<NSNumber*>*) getHorizontalVariantsForGlyph:(CGGlyph) glyph;\n\n/** Returns a larger vertical variant of the given glyph if any.\n If there is no larger version, this returns the current glyph.\n */\n- (CGGlyph) getLargerGlyph:(CGGlyph) glyph;\n\n#pragma mark Italic Correction\n\n/** Returns the italic correction for the given glyph if any. If there\n isn't any this returns 0. */\n- (CGFloat) getItalicCorrection:(CGGlyph) glyph;\n\n#pragma mark Accents\n\n/** Returns the adjustment to the top accent for the given glyph if any.\n If there isn't any this returns -1. */\n- (CGFloat) getTopAccentAdjustment:(CGGlyph) glyph;\n\n#pragma mark Glyph Construction\n\n/** Minimum overlap of connecting glyphs during glyph construction */\n@property (nonatomic, readonly) CGFloat minConnectorOverlap;\n\n/** Returns an array of the glyph parts to be used for constructing vertical variants\n of this glyph. If there is no glyph assembly defined, returns nil. */\n- (nullable NSArray<MTGlyphPart*>*) getVerticalGlyphAssemblyForGlyph:(CGGlyph) glyph;\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/render/internal/MTFontMathTable.m",
    "content": "//\n//  MTFontMathTable.m\n//  iosMath\n//\n//  Created by Kostub Deshmukh on 8/28/13.\n//  Copyright (C) 2013 MathChat\n//   \n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n#import \"MTFontMathTable.h\"\n#import \"MTFont.h\"\n#import \"MTFont+Internal.h\"\n\n\n@interface MTGlyphPart ()\n\n@property (nonatomic) CGGlyph glyph;\n@property (nonatomic) CGFloat fullAdvance;\n@property (nonatomic) CGFloat startConnectorLength;\n@property (nonatomic) CGFloat endConnectorLength;\n@property (nonatomic) BOOL isExtender;\n\n@end\n\n@implementation MTGlyphPart\n\n@end\n\n@interface MTFontMathTable ()\n\n// The font for this math table.\n@property (nonatomic, readonly, weak) MTFont* font;\n\n@end\n\n@implementation MTFontMathTable {\n    NSUInteger _unitsPerEm;\n    CGFloat _fontSize;\n    NSDictionary* _Nonnull _mathTable;\n}\n\n- (instancetype)initWithFont:(nonnull MTFont*) font mathTable:(nonnull NSDictionary*) mathTable\n{\n    self = [super init];\n    if (self) {\n        NSParameterAssert(font);\n        NSParameterAssert(font.ctFont);\n        _font = font;\n        // do domething with font\n        _unitsPerEm = CTFontGetUnitsPerEm(font.ctFont);\n        _fontSize = font.fontSize;\n        _mathTable = mathTable;\n        if (![@\"1.3\" isEqualToString:_mathTable[@\"version\"]]) {\n            // Invalid version\n            @throw [NSException exceptionWithName:NSInternalInconsistencyException\n                                           reason:[NSString stringWithFormat:@\"Invalid version of math table plist: %@\", _mathTable[@\"version\"]]\n                                         userInfo:nil];\n        }\n    }\n    return self;\n}\n\n- (CGFloat) fontUnitsToPt:(int) fontUnits\n{\n    return fontUnits * _fontSize / _unitsPerEm;\n}\n\n- (CGFloat)muUnit\n{\n    return _fontSize/18;\n}\n\nstatic NSString* const kConstants = @\"constants\";\n\n- (CGFloat) constantFromTable:(NSString*) constName\n{\n    NSDictionary* consts = (NSDictionary*) _mathTable[kConstants];\n    NSNumber* val = (NSNumber*)consts[constName];\n    return [self fontUnitsToPt:val.intValue];\n}\n\n- (CGFloat) percentFromTable:(NSString*) percentName\n{\n    NSDictionary* consts = (NSDictionary*) _mathTable[kConstants];\n    NSNumber* val = (NSNumber*)consts[percentName];\n    return val.floatValue / 100;\n}\n\n#pragma mark - Fractions\n- (CGFloat)fractionNumeratorDisplayStyleShiftUp\n{\n    return [self constantFromTable:@\"FractionNumeratorDisplayStyleShiftUp\"];\n}\n\n- (CGFloat)fractionNumeratorShiftUp\n{\n    return [self constantFromTable:@\"FractionNumeratorShiftUp\"];\n}\n\n- (CGFloat)fractionDenominatorDisplayStyleShiftDown\n{\n    return [self constantFromTable:@\"FractionDenominatorDisplayStyleShiftDown\"];\n}\n\n- (CGFloat)fractionDenominatorShiftDown\n{\n    return [self constantFromTable:@\"FractionDenominatorShiftDown\"];\n}\n\n- (CGFloat)fractionNumeratorDisplayStyleGapMin\n{\n    return [self constantFromTable:@\"FractionNumDisplayStyleGapMin\"];\n}\n\n- (CGFloat)fractionNumeratorGapMin\n{\n    return [self constantFromTable:@\"FractionNumeratorGapMin\"];\n}\n\n- (CGFloat)fractionDenominatorDisplayStyleGapMin\n{\n    return [self constantFromTable:@\"FractionDenomDisplayStyleGapMin\"];\n}\n\n- (CGFloat)fractionDenominatorGapMin\n{\n    return [self constantFromTable:@\"FractionDenominatorGapMin\"];\n}\n\n- (CGFloat)fractionRuleThickness\n{\n    return [self constantFromTable:@\"FractionRuleThickness\"];\n}\n\n- (CGFloat) skewedFractionHorizontalGap\n{\n    return [self constantFromTable:@\"SkewedFractionHorizontalGap\"];\n}\n\n- (CGFloat) skewedFractionVerticalGap\n{\n    return [self constantFromTable:@\"SkewedFractionVerticalGap\"];\n}\n\n#pragma mark Non-standard\n\n// FractionDelimiterSize and FractionDelimiterDisplayStyleSize are not constants\n// specified in the OpenType Math specification. Rather these are proposed LuaTeX extensions\n// for the TeX parameters \\sigma_20 (delim1) and \\sigma_21 (delim2). Since these do not\n// exist in the fonts that we have, we use the same approach as LuaTeX and use the fontSize\n// to determine these values. The constants used are the same as LuaTeX and KaTeX and match the\n// metrics values of the original TeX fonts.\n// Note: An alternative approach is to use DelimitedSubFormulaMinHeight for \\sigma21 and use a factor\n// of 2 to get \\sigma 20 as proposed in Vieth paper.\n// The XeTeX implementation sets \\sigma21 = fontSize and \\sigma20 = DelimitedSubFormulaMinHeight which\n// will produce smaller delimiters.\n// Of all the approaches we've implemented LuaTeX's approach since it mimics LaTeX most accurately.\n- (CGFloat) fractionDelimiterSize\n{\n    return 1.01 * _fontSize;\n}\n\n- (CGFloat) fractionDelimiterDisplayStyleSize\n{\n    // Modified constant from 2.4 to 2.39, it matches KaTeX and looks better.\n    return 2.39 * _fontSize;\n}\n\n#pragma mark - Sub/Superscripts\n\n- (CGFloat)superscriptShiftUp\n{\n    return [self constantFromTable:@\"SuperscriptShiftUp\"];\n}\n\n- (CGFloat)superscriptShiftUpCramped\n{\n    return [self constantFromTable:@\"SuperscriptShiftUpCramped\"];\n}\n\n- (CGFloat)subscriptShiftDown\n{\n    return [self constantFromTable:@\"SubscriptShiftDown\"];\n}\n\n- (CGFloat)superscriptBaselineDropMax\n{\n    return [self constantFromTable:@\"SuperscriptBaselineDropMax\"];\n}\n\n- (CGFloat)subscriptBaselineDropMin\n{\n    return [self constantFromTable:@\"SubscriptBaselineDropMin\"];\n}\n\n- (CGFloat)superscriptBottomMin\n{\n    return [self constantFromTable:@\"SuperscriptBottomMin\"];\n}\n\n- (CGFloat)subscriptTopMax\n{\n    return [self constantFromTable:@\"SubscriptTopMax\"];\n}\n\n- (CGFloat)subSuperscriptGapMin\n{\n    return [self constantFromTable:@\"SubSuperscriptGapMin\"];\n}\n\n- (CGFloat)superscriptBottomMaxWithSubscript\n{\n    return [self constantFromTable:@\"SuperscriptBottomMaxWithSubscript\"];\n}\n\n- (CGFloat) spaceAfterScript\n{\n    return [self constantFromTable:@\"SpaceAfterScript\"];\n}\n\n#pragma mark - Radicals\n\n- (CGFloat)radicalRuleThickness\n{\n    return [self constantFromTable:@\"RadicalRuleThickness\"];\n}\n\n- (CGFloat)radicalExtraAscender\n{\n    return [self constantFromTable:@\"RadicalExtraAscender\"];\n}\n\n- (CGFloat)radicalVerticalGap\n{\n    return [self constantFromTable:@\"RadicalVerticalGap\"];\n}\n\n- (CGFloat)radicalDisplayStyleVerticalGap\n{\n    return [self constantFromTable:@\"RadicalDisplayStyleVerticalGap\"];\n}\n\n- (CGFloat)radicalKernBeforeDegree\n{\n    return [self constantFromTable:@\"RadicalKernBeforeDegree\"];\n}\n\n- (CGFloat)radicalKernAfterDegree\n{\n    return [self constantFromTable:@\"RadicalKernAfterDegree\"];\n}\n\n- (CGFloat)radicalDegreeBottomRaisePercent\n{\n    return [self percentFromTable:@\"RadicalDegreeBottomRaisePercent\"];\n}\n\n#pragma mark - Limits\n\n- (CGFloat)upperLimitGapMin\n{\n    return [self constantFromTable:@\"UpperLimitGapMin\"];\n}\n\n- (CGFloat)upperLimitBaselineRiseMin\n{\n    return [self constantFromTable:@\"UpperLimitBaselineRiseMin\"];\n}\n\n- (CGFloat)lowerLimitGapMin\n{\n    return [self constantFromTable:@\"LowerLimitGapMin\"];\n}\n\n- (CGFloat)lowerLimitBaselineDropMin\n{\n    return [self constantFromTable:@\"LowerLimitBaselineDropMin\"];\n}\n\n- (CGFloat)limitExtraAscenderDescender\n{\n    // not present in OpenType fonts.\n    return 0;\n}\n\n#pragma mark - Constants\n\n-(CGFloat)axisHeight\n{\n    return [self constantFromTable:@\"AxisHeight\"];\n}\n\n- (CGFloat)scriptScaleDown\n{\n    return [self percentFromTable:@\"ScriptPercentScaleDown\"];\n}\n\n- (CGFloat)scriptScriptScaleDown\n{\n    return [self percentFromTable:@\"ScriptScriptPercentScaleDown\"];\n}\n\n- (CGFloat) mathLeading\n{\n    return [self constantFromTable:@\"MathLeading\"];\n}\n\n- (CGFloat) delimitedSubFormulaMinHeight\n{\n    return [self constantFromTable:@\"DelimitedSubFormulaMinHeight\"];\n}\n\n#pragma mark - Accents\n\n- (CGFloat) accentBaseHeight\n{\n    return [self constantFromTable:@\"AccentBaseHeight\"];\n}\n\n- (CGFloat) flattenedAccentBaseHeight\n{\n    return [self constantFromTable:@\"FlattenedAccentBaseHeight\"];\n}\n\n#pragma mark - Large Operators\n\n- (CGFloat) displayOperatorMinHeight\n{\n    return [self constantFromTable:@\"DisplayOperatorMinHeight\"];\n}\n\n#pragma mark - Over and Underbar\n\n- (CGFloat) overbarExtraAscender\n{\n    return [self constantFromTable:@\"OverbarExtraAscender\"];\n}\n\n- (CGFloat) overbarRuleThickness\n{\n    return [self constantFromTable:@\"OverbarRuleThickness\"];\n}\n\n- (CGFloat) overbarVerticalGap\n{\n    return [self constantFromTable:@\"OverbarVerticalGap\"];\n}\n\n- (CGFloat) underbarExtraDescender\n{\n    return [self constantFromTable:@\"UnderbarExtraDescender\"];\n}\n\n- (CGFloat) underbarRuleThickness\n{\n    return [self constantFromTable:@\"UnderbarRuleThickness\"];\n}\n\n- (CGFloat) underbarVerticalGap\n{\n    return [self constantFromTable:@\"UnderbarVerticalGap\"];\n}\n\n#pragma mark - Stacks\n\n-(CGFloat) stackBottomDisplayStyleShiftDown {\n    return [self constantFromTable:@\"StackBottomDisplayStyleShiftDown\"];\n}\n\n- (CGFloat) stackBottomShiftDown {\n    return [self constantFromTable:@\"StackBottomShiftDown\"];\n}\n            \n- (CGFloat) stackDisplayStyleGapMin {\n    return [self constantFromTable:@\"StackDisplayStyleGapMin\"];\n}\n            \n- (CGFloat) stackGapMin {\n    return [self constantFromTable:@\"StackGapMin\"];\n}\n\n- (CGFloat) stackTopDisplayStyleShiftUp {\n    return [self constantFromTable:@\"StackTopDisplayStyleShiftUp\"];\n}\n\n- (CGFloat) stackTopShiftUp {\n    return [self constantFromTable:@\"StackTopShiftUp\"];\n}\n\n- (CGFloat) stretchStackBottomShiftDown {\n    return [self constantFromTable:@\"StretchStackBottomShiftDown\"];\n}\n\n- (CGFloat) stretchStackGapAboveMin {\n    return [self constantFromTable:@\"StretchStackGapAboveMin\"];\n}\n\n- (CGFloat) stretchStackGapBelowMin {\n    return [self constantFromTable:@\"StretchStackGapBelowMin\"];\n}\n\n- (CGFloat) stretchStackTopShiftUp {\n    return [self constantFromTable:@\"StretchStackTopShiftUp\"];\n}\n\n#pragma mark - Variants\n\nstatic NSString* const kVertVariants = @\"v_variants\";\nstatic NSString* const kHorizVariants = @\"h_variants\";\n\n- (NSArray<NSNumber*>*) getVerticalVariantsForGlyph:(CGGlyph) glyph\n{\n    NSDictionary* variants = (NSDictionary*) _mathTable[kVertVariants];\n    return [self getVariantsForGlyph:glyph inDictionary:variants];\n}\n\n- (NSArray<NSNumber*>*) getHorizontalVariantsForGlyph:(CGGlyph) glyph\n{\n    NSDictionary* variants = (NSDictionary*) _mathTable[kHorizVariants];\n    return [self getVariantsForGlyph:glyph inDictionary:variants];\n}\n\n- (NSArray<NSNumber*>*) getVariantsForGlyph:(CGGlyph) glyph inDictionary:(NSDictionary*) variants\n{\n    NSString* glyphName = [self.font getGlyphName:glyph];\n    NSArray* variantGlyphs = (NSArray*) variants[glyphName];\n    NSMutableArray* glyphArray = [NSMutableArray arrayWithCapacity:variantGlyphs.count];\n    if (!variantGlyphs) {\n        // There are no extra variants, so just add the current glyph to it.\n        CGGlyph glyph = [self.font getGlyphWithName:glyphName];\n        [glyphArray addObject:@(glyph)];\n        return glyphArray;\n    }\n    for (NSString* glyphVariantName in variantGlyphs) {\n        CGGlyph variantGlyph = [self.font getGlyphWithName:glyphVariantName];\n        [glyphArray addObject:@(variantGlyph)];\n    }\n    return glyphArray;\n}\n\n- (CGGlyph) getLargerGlyph:(CGGlyph) glyph\n{\n    NSDictionary* variants = (NSDictionary*) _mathTable[kVertVariants];\n    NSString* glyphName = [self.font getGlyphName:glyph];\n    NSArray* variantGlyphs = (NSArray*) variants[glyphName];\n    if (!variantGlyphs) {\n        // There are no extra variants, so just returnt the current glyph.\n        return glyph;\n    }\n    // Find the first variant with a different name.\n    for (NSString* glyphVariantName in variantGlyphs) {\n        if (![glyphVariantName isEqualToString:glyphName]) {\n            CGGlyph variantGlyph = [self.font getGlyphWithName:glyphVariantName];\n            return variantGlyph;\n        }\n    }\n    // We did not find any variants of this glyph so return it.\n    return glyph;\n}\n\n#pragma mark - Italic Correction\n\nstatic NSString* const kItalic = @\"italic\";\n\n- (CGFloat)getItalicCorrection:(CGGlyph)glyph\n{\n    NSDictionary* italics = (NSDictionary*) _mathTable[kItalic];\n    NSString* glyphName = [self.font getGlyphName:glyph];\n    NSNumber* val = (NSNumber*) italics[glyphName];\n    // if val is nil, this returns 0.\n    return [self fontUnitsToPt:val.intValue];\n}\n\n#pragma mark - Top Accent Adjustment\n\nstatic NSString* const kAccents = @\"accents\";\n- (CGFloat) getTopAccentAdjustment:(CGGlyph) glyph\n{\n    NSDictionary* accents = (NSDictionary*) _mathTable[kAccents];\n    NSString* glyphName = [self.font getGlyphName:glyph];\n    NSNumber* val = (NSNumber*) accents[glyphName];\n    if (val != nil) {\n        return [self fontUnitsToPt:val.intValue];\n    } else {\n        // If no top accent is defined then it is the center of the advance width.\n        CGSize advances;\n        CTFontGetAdvancesForGlyphs(self.font.ctFont, kCTFontHorizontalOrientation, &glyph, &advances, 1);\n        return advances.width/2;\n    }\n}\n\n#pragma mark - Glyph Assembly\n\n- (CGFloat)minConnectorOverlap\n{\n    return [self constantFromTable:@\"MinConnectorOverlap\"];\n}\n\nstatic NSString* const kVertAssembly = @\"v_assembly\";\nstatic NSString* const kAssemblyParts = @\"parts\";\n\n- (NSArray<MTGlyphPart *> *)getVerticalGlyphAssemblyForGlyph:(CGGlyph)glyph\n{\n    NSDictionary* assemblyTable = (NSDictionary*) _mathTable[kVertAssembly];\n    NSString* glyphName = [self.font getGlyphName:glyph];\n    NSDictionary* assemblyInfo = (NSDictionary*) assemblyTable[glyphName];\n    if (!assemblyInfo) {\n        // No vertical assembly defined for glyph\n        return nil;\n    }\n    NSArray* parts = (NSArray*) assemblyInfo[kAssemblyParts];\n    if (!parts) {\n        // parts should always have been defined, but if it isn't return nil\n        return nil;\n    }\n    NSMutableArray<MTGlyphPart*>* rv = [NSMutableArray array];\n    for (NSDictionary* partInfo in parts) {\n        MTGlyphPart* part = [[MTGlyphPart alloc] init];\n        NSNumber* adv = (NSNumber*) partInfo[@\"advance\"];\n        part.fullAdvance = [self fontUnitsToPt:adv.intValue];\n        NSNumber* end = (NSNumber*) partInfo[@\"endConnector\"];\n        part.endConnectorLength = [self fontUnitsToPt:end.intValue];\n        NSNumber* start = (NSNumber*) partInfo[@\"startConnector\"];\n        part.startConnectorLength = [self fontUnitsToPt:start.intValue];\n        NSNumber* ext = (NSNumber*) partInfo[@\"extender\"];\n        part.isExtender = ext.boolValue;\n        NSString* glyphName = (NSString*) partInfo[@\"glyph\"];\n        part.glyph = [self.font getGlyphWithName:glyphName];\n        \n        [rv addObject:part];\n    }\n    return rv;\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/render/internal/MTMathListDisplayInternal.h",
    "content": "//\n//  MTMathListDisplay+Internal.h\n//  iosMath\n//\n//  Created by Kostub Deshmukh on 6/21/16.\n//\n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n#import \"MTMathListDisplay.h\"\n\n@interface MTDisplay ()\n\n@property (nonatomic) CGFloat ascent;\n@property (nonatomic) CGFloat descent;\n@property (nonatomic) CGFloat width;\n@property (nonatomic) NSRange range;\n@property (nonatomic) BOOL hasScript;\n\n@end\n\n// The Downshift protocol allows an MTDisplay to be shifted down by a given amount.\n@protocol DownShift <NSObject>\n\n@property (nonatomic) CGFloat shiftDown;\n\n@end\n\n@interface MTMathListDisplay ()\n\n- (instancetype)init NS_UNAVAILABLE;\n\n- (instancetype) initWithDisplays:(NSArray<MTDisplay*>*) displays range:(NSRange) range NS_DESIGNATED_INITIALIZER;\n\n@property (nonatomic, readwrite) MTLinePosition type;\n@property (nonatomic, readwrite) NSUInteger index;\n\n@end\n\n@interface MTCTLineDisplay ()\n\n- (instancetype)initWithString:(NSAttributedString*) attrString position:(CGPoint)position range:(NSRange) range font:(MTFont*) font atoms:(NSArray<MTMathAtom*>*) atoms NS_DESIGNATED_INITIALIZER;\n\n- (instancetype)init NS_UNAVAILABLE;\n\n@end\n\n@interface MTFractionDisplay ()\n\n- (instancetype)initWithNumerator:(MTMathListDisplay*) numerator denominator:(MTMathListDisplay*) denominator position:(CGPoint) position range:(NSRange) range NS_DESIGNATED_INITIALIZER;\n\n- (instancetype)init NS_UNAVAILABLE;\n\n@property (nonatomic) CGFloat numeratorUp;\n@property (nonatomic) CGFloat denominatorDown;\n@property (nonatomic) CGFloat linePosition;\n@property (nonatomic) CGFloat lineThickness;\n\n@end\n\n@interface MTRadicalDisplay ()\n\n- (instancetype)initWitRadicand:(MTMathListDisplay*) radicand glpyh:(MTDisplay*) glyph position:(CGPoint) position range:(NSRange) range NS_DESIGNATED_INITIALIZER;\n\n- (void) setDegree:(MTMathListDisplay *)degree fontMetrics:(MTFontMathTable*) fontMetrics;\n\n@property (nonatomic) CGFloat topKern;\n@property (nonatomic) CGFloat lineThickness;\n\n@end\n\n// Rendering of an large glyph as an MTDisplay\n@interface MTGlyphDisplay() <DownShift>\n\n- (instancetype)initWithGlpyh:(CGGlyph) glyph range:(NSRange) range font:(MTFont*) font NS_DESIGNATED_INITIALIZER;\n\n@end\n\n// Rendering of a constructed glyph as an MTDisplay\n@interface MTGlyphConstructionDisplay : MTDisplay<DownShift>\n\n- (instancetype) init NS_UNAVAILABLE;\n- (instancetype) initWithGlyphs:(NSArray<NSNumber*>*) glyphs offsets:(NSArray<NSNumber*>*) offsets font:(MTFont*) font NS_DESIGNATED_INITIALIZER;\n\n@end\n\n@interface MTLargeOpLimitsDisplay ()\n\n- (instancetype) initWithNucleus:(MTDisplay*) nucleus upperLimit:(MTMathListDisplay*) upperLimit lowerLimit:(MTMathListDisplay*) lowerLimit limitShift:(CGFloat) limitShift extraPadding:(CGFloat) extraPadding NS_DESIGNATED_INITIALIZER;\n\n- (instancetype)init NS_UNAVAILABLE;\n\n@property (nonatomic) CGFloat upperLimitGap;\n@property (nonatomic) CGFloat lowerLimitGap;\n\n@end\n\n@interface MTLineDisplay ()\n\n- (instancetype)initWithInner:(MTMathListDisplay*) inner position:(CGPoint) position range:(NSRange) range NS_DESIGNATED_INITIALIZER;\n\n// How much the line should be moved up.\n@property (nonatomic) CGFloat lineShiftUp;\n@property (nonatomic) CGFloat lineThickness;\n\n@end\n\n@interface MTOverbraceDisplay()\n\n- (instancetype)initWithOverbraceContentor:(MTMathListDisplay *)contentor\n                                   labelor:(MTMathListDisplay *)labelor\n                                  position:(CGPoint) position NS_DESIGNATED_INITIALIZER;\n/// 标签位置Y偏移量\n@property (nonatomic, assign) CGFloat labelorOffsetY;\n/// 内容位置Y偏移量\n@property (nonatomic, assign) CGFloat contentorOffsetY;\n\n@end\n\n@interface MTUnderbraceDisplay()\n\n- (instancetype)initWithUnderbraceContentor:(MTMathListDisplay *)contentor\n                                    labelor:(MTMathListDisplay *)labelor\n                                   position:(CGPoint) position NS_DESIGNATED_INITIALIZER;\n/// 标签位置Y偏移量\n@property (nonatomic, assign) CGFloat labelorOffsetY;\n/// 内容位置Y偏移量\n@property (nonatomic, assign) CGFloat contentorOffsetY;\n\n@end\n\n@interface MTHLineDisplay()\n\n- (instancetype)initWithPosition:(CGPoint) position NS_DESIGNATED_INITIALIZER;\n\n// How much the line should be moved up.\n@property (nonatomic, assign) CGFloat lineUp;\n/// line height\n@property (nonatomic, assign) CGFloat lineHeight;\n\n@end\n\n@interface MTAccentDisplay ()\n\n- (instancetype)initWithAccent:(MTGlyphDisplay*) glyph accentee:(MTMathListDisplay*) accentee range:(NSRange) range NS_DESIGNATED_INITIALIZER;\n\n@end\n\n\n@interface MTInnerDisplay ()\n\n- (instancetype) initWithInner:(MTMathListDisplay*) inner leftDelimiter:(MTDisplay*) leftDelimiter rightDelimiter:(MTDisplay*) rightDelimiter atIndex:(NSUInteger) index NS_DESIGNATED_INITIALIZER;\n\n@property (nonatomic) MTMathListDisplay* inner;\n\n@property (nonatomic, nullable) MTDisplay* leftDelimiter;\n@property (nonatomic, nullable) MTDisplay* rightDelimiter;\n\n@property (nonatomic) NSUInteger index;\n\n@end\n\n@interface MTAdaptiveDisplay ()\n\n- (instancetype)initWithDelimiter:(MTDisplay*)delimiter range:(NSRange)range NS_DESIGNATED_INITIALIZER;\n\n@property (nonatomic, nullable) MTDisplay* delimiter;\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/render/internal/MTTypesetter.h",
    "content": "//\n//  MTTypesetter.h\n//  iosMath\n//\n//  Created by Kostub Deshmukh on 6/21/16.\n//\n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n@import Foundation;\n\n#import \"MTMathListDisplay.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// This class does all the LaTeX typesetting logic.\n/// For ADVANCED use only.\n@interface MTTypesetter : NSObject\n\n/// Renders a MTMathList as a list of displays.\n+ (MTMathListDisplay*) createLineForMathList:(MTMathList*) mathList font:(MTFont*) font style:(MTLineStyle) style;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/External/iosMath/render/internal/MTTypesetter.m",
    "content": "//\n//  MTTypesetter.m\n//  iosMath\n//\n//  Created by Kostub Deshmukh on 6/21/16.\n//\n//  This software may be modified and distributed under the terms of the\n//  MIT license. See the LICENSE file for details.\n//\n\n#import \"MTTypesetter.h\"\n#import \"MTFont+Internal.h\"\n#import \"MTMathListDisplayInternal.h\"\n#import \"MTUnicode.h\"\n\n#pragma mark Inter Element Spacing\n\ntypedef NS_ENUM(int, MTInterElementSpaceType) {\n    kMTSpaceInvalid = -1,\n    kMTSpaceNone = 0,\n    kMTSpaceThin,\n    kMTSpaceNSThin,    // Thin but not in script mode\n    kMTSpaceNSMedium,\n    kMTSpaceNSThick,\n};\n\n\nNSArray* getInterElementSpaces(void) {\n    static NSArray* interElementSpaceArray = nil;\n    if (!interElementSpaceArray) {\n        interElementSpaceArray =\n        //   ordinary             operator             binary               relation            open                 close               punct               // fraction\n        @[ @[@(kMTSpaceNone),     @(kMTSpaceThin),     @(kMTSpaceNSMedium), @(kMTSpaceNSThick), @(kMTSpaceNone),     @(kMTSpaceNone),    @(kMTSpaceNone),    @(kMTSpaceNSThin)],    // ordinary\n           @[@(kMTSpaceThin),     @(kMTSpaceThin),     @(kMTSpaceInvalid),  @(kMTSpaceNSThick), @(kMTSpaceNone),     @(kMTSpaceNone),    @(kMTSpaceNone),    @(kMTSpaceNSThin)],    // operator\n           @[@(kMTSpaceNSMedium), @(kMTSpaceNSMedium), @(kMTSpaceInvalid),  @(kMTSpaceInvalid), @(kMTSpaceNSMedium), @(kMTSpaceInvalid), @(kMTSpaceInvalid), @(kMTSpaceNSMedium)],  // binary\n           @[@(kMTSpaceNSThick),  @(kMTSpaceNSThick),  @(kMTSpaceInvalid),  @(kMTSpaceNone),    @(kMTSpaceNSThick),  @(kMTSpaceNone),    @(kMTSpaceNone),    @(kMTSpaceNSThick)],   // relation\n           @[@(kMTSpaceNone),     @(kMTSpaceNone),     @(kMTSpaceInvalid),  @(kMTSpaceNone),    @(kMTSpaceNone),     @(kMTSpaceNone),    @(kMTSpaceNone),    @(kMTSpaceNone)],      // open\n           @[@(kMTSpaceNone),     @(kMTSpaceThin),     @(kMTSpaceNSMedium), @(kMTSpaceNSThick), @(kMTSpaceNone),     @(kMTSpaceNone),    @(kMTSpaceNone),    @(kMTSpaceNSThin)],    // close\n           @[@(kMTSpaceNSThin),   @(kMTSpaceNSThin),   @(kMTSpaceInvalid),  @(kMTSpaceNSThin),  @(kMTSpaceNSThin),   @(kMTSpaceNSThin),  @(kMTSpaceNSThin),  @(kMTSpaceNSThin)],    // punct\n           @[@(kMTSpaceNSThin),   @(kMTSpaceThin),     @(kMTSpaceNSMedium), @(kMTSpaceNSThick), @(kMTSpaceNSThin),   @(kMTSpaceNone),    @(kMTSpaceNSThin),  @(kMTSpaceNSThin)],    // fraction\n           @[@(kMTSpaceNSMedium), @(kMTSpaceNSThin),   @(kMTSpaceNSMedium), @(kMTSpaceNSThick), @(kMTSpaceNone),     @(kMTSpaceNone),    @(kMTSpaceNone),    @(kMTSpaceNSThin)]];   // radical\n    }\n    return interElementSpaceArray;\n}\n\n\n// Get's the index for the given type. If row is true, the index is for the row (i.e. left element) otherwise it is for the column (right element)\nNSUInteger getInterElementSpaceArrayIndexForType(MTMathAtomType type, BOOL row) {\n    switch (type) {\n        case kMTMathAtomColor:\n        case kMTMathAtomColorbox:\n        case kMTMathAtomOrdinary:\n        case kMTMathAtomPlaceholder:   // A placeholder is treated as ordinary\n            return 0;\n        case kMTMathAtomLargeOperator:\n            return 1;\n        case kMTMathAtomBinaryOperator:\n            return 2;\n        case kMTMathAtomRelation:\n            return 3;\n        case kMTMathAtomOpen:\n            return 4;\n        case kMTMathAtomClose:\n            return 5;\n        case kMTMathAtomPunctuation:\n            return 6;\n        case kMTMathAtomFraction:  // Fraction and inner are treated the same.\n        case kMTMathAtomInner:\n            return 7;\n        case kMTMathAtomRadical: {\n            if (row) {\n                // Radicals have inter element spaces only when on the left side.\n                // Note: This is a departure from latex but we don't want \\sqrt{4}4 to look weird so we put a space in between.\n                // They have the same spacing as ordinary except with ordinary.\n                return 8;\n            } else {\n                NSCAssert(false, @\"Interelement space undefined for radical on the right. Treat radical as ordinary.\");\n                return -1;\n            }\n        }\n        case kMTmathAtomUnderbrace:\n        case kMTMathAtomOverbrace:\n            return 0;\n        default:\n            NSCAssert(false, @\"Interelement space undefined for type %lu\", (unsigned long)type);\n            return -1;\n    }\n}\n\n#pragma mark - Font styles\n\nstatic const unichar kMTUnicodeGreekLowerStart = 0x03B1;\nstatic const unichar kMTUnicodeGreekLowerEnd = 0x03C9;\nstatic const unichar kMTUnicodeGreekCapitalStart = 0x0391;\nstatic const unichar kMTUnicodeGreekCapitalEnd = 0x03A9;\n\n#define IS_LOWER_EN(ch) ((ch) >= 'a' && (ch) <= 'z')\n#define IS_UPPER_EN(ch) ((ch) >= 'A' && (ch) <= 'Z')\n#define IS_NUMBER(ch) ((ch) >= '0' && (ch) <= '9')\n#define IS_LOWER_GREEK(ch) ((ch) >= kMTUnicodeGreekLowerStart && (ch) <= kMTUnicodeGreekLowerEnd)\n#define IS_CAPITAL_GREEK(ch) ((ch) >= kMTUnicodeGreekCapitalStart && (ch) <= kMTUnicodeGreekCapitalEnd)\n\n\nNSUInteger greekSymbolOrder(unichar ch) {\n    // These greek symbols that always appear in unicode in this particular order after the alphabet\n    // The symbols are epsilon, vartheta, varkappa, phi, varrho, varpi.\n    static NSArray* greekSymbols;\n    if (!greekSymbols) {\n        greekSymbols = @[@0x03F5, @0x03D1, @0x03F0, @0x03D5, @0x03F1, @0x03D6];\n    }\n    return [greekSymbols indexOfObject:@(ch)];\n}\n\n#define IS_GREEK_SYMBOL(ch) (greekSymbolOrder(ch) != NSNotFound)\n\nstatic const unichar kMTUnicodePlanksConstant = 0x210e;\nstatic const UTF32Char kMTUnicodeMathCapitalItalicStart = 0x1D434;\nstatic const UTF32Char kMTUnicodeMathLowerItalicStart = 0x1D44E;\nstatic const UTF32Char kMTUnicodeGreekCapitalItalicStart = 0x1D6E2;\nstatic const UTF32Char kMTUnicodeGreekLowerItalicStart = 0x1D6FC;\nstatic const UTF32Char kMTUnicodeGreekSymbolItalicStart = 0x1D716;\n\n// mathit\nUTF32Char getItalicized(unichar ch) {\n    UTF32Char unicode = ch;\n    // Special cases for italics\n    switch(ch) {\n        case 'h':\n            return kMTUnicodePlanksConstant;   // italic h (plank's constant)\n    }\n    \n    if (IS_UPPER_EN(ch)) {\n        unicode = kMTUnicodeMathCapitalItalicStart + (ch - 'A');\n    } else if (IS_LOWER_EN(ch)) {\n        unicode = kMTUnicodeMathLowerItalicStart + (ch - 'a');\n    } else if (IS_CAPITAL_GREEK(ch)) {\n        // Capital Greek characters\n        unicode = kMTUnicodeGreekCapitalItalicStart + (ch - kMTUnicodeGreekCapitalStart);\n    } else if (IS_LOWER_GREEK(ch)) {\n        // Greek characters\n        unicode = kMTUnicodeGreekLowerItalicStart + (ch - kMTUnicodeGreekLowerStart);\n    } else if (IS_GREEK_SYMBOL(ch)) {\n        return kMTUnicodeGreekSymbolItalicStart + (int)greekSymbolOrder(ch);\n    }\n    // Note there are no italicized numbers in unicode so we don't support italicizing numbers.\n    return unicode;\n}\n\nstatic const UTF32Char kMTUnicodeMathCapitalBoldStart = 0x1D400;\nstatic const UTF32Char kMTUnicodeMathLowerBoldStart = 0x1D41A;\nstatic const UTF32Char kMTUnicodeGreekCapitalBoldStart = 0x1D6A8;\nstatic const UTF32Char kMTUnicodeGreekLowerBoldStart = 0x1D6C2;\nstatic const UTF32Char kMTUnicodeGreekSymbolBoldStart = 0x1D6DC;\nstatic const UTF32Char kMTUnicodeNumberBoldStart = 0x1D7CE;\n\n// mathbf\nUTF32Char getBold(unichar ch) {\n    UTF32Char unicode = ch;\n    if (IS_UPPER_EN(ch)) {\n        unicode = kMTUnicodeMathCapitalBoldStart + (ch - 'A');\n    } else if (IS_LOWER_EN(ch)) {\n        unicode = kMTUnicodeMathLowerBoldStart + (ch - 'a');\n    } else if (IS_CAPITAL_GREEK(ch)) {\n        // Capital Greek characters\n        unicode = kMTUnicodeGreekCapitalBoldStart + (ch - kMTUnicodeGreekCapitalStart);\n    } else if (IS_LOWER_GREEK(ch)) {\n        // Greek characters\n        unicode = kMTUnicodeGreekLowerBoldStart + (ch - kMTUnicodeGreekLowerStart);\n    } else if (IS_GREEK_SYMBOL(ch)) {\n        return kMTUnicodeGreekSymbolBoldStart + (int)greekSymbolOrder(ch);\n    } else if (IS_NUMBER(ch)) {\n        unicode = kMTUnicodeNumberBoldStart + (ch - '0');\n    }\n    return unicode;\n}\n\nstatic const UTF32Char kMTUnicodeMathCapitalBoldItalicStart = 0x1D468;\nstatic const UTF32Char kMTUnicodeMathLowerBoldItalicStart = 0x1D482;\nstatic const UTF32Char kMTUnicodeGreekCapitalBoldItalicStart = 0x1D71C;\nstatic const UTF32Char kMTUnicodeGreekLowerBoldItalicStart = 0x1D736;\nstatic const UTF32Char kMTUnicodeGreekSymbolBoldItalicStart = 0x1D750;\n\n// mathbfit\nUTF32Char getBoldItalic(unichar ch) {\n    UTF32Char unicode = ch;\n    if (IS_UPPER_EN(ch)) {\n        unicode = kMTUnicodeMathCapitalBoldItalicStart + (ch - 'A');\n    } else if (IS_LOWER_EN(ch)) {\n        unicode = kMTUnicodeMathLowerBoldItalicStart + (ch - 'a');\n    } else if (IS_CAPITAL_GREEK(ch)) {\n        // Capital Greek characters\n        unicode = kMTUnicodeGreekCapitalBoldItalicStart + (ch - kMTUnicodeGreekCapitalStart);\n    } else if (IS_LOWER_GREEK(ch)) {\n        // Greek characters\n        unicode = kMTUnicodeGreekLowerBoldItalicStart + (ch - kMTUnicodeGreekLowerStart);\n    } else if (IS_GREEK_SYMBOL(ch)) {\n        return kMTUnicodeGreekSymbolBoldItalicStart + (int)greekSymbolOrder(ch);\n    } else if (IS_NUMBER(ch)) {\n        // No bold italic for numbers so we just bold them.\n        unicode = getBold(ch);\n    }\n    return unicode;\n}\n\n// LaTeX default\nUTF32Char getDefaultStyle(unichar ch) {\n    if (IS_LOWER_EN(ch) || IS_UPPER_EN(ch) || IS_LOWER_GREEK(ch) || IS_GREEK_SYMBOL(ch)) {\n        return getItalicized(ch);\n    } else if (IS_NUMBER(ch) || IS_CAPITAL_GREEK(ch)) {\n        // In the default style numbers and capital greek is roman\n        return ch;\n    } else if (ch == '.') {\n        // . is treated as a number in our code, but it doesn't change fonts.\n        return ch;\n    } else if (0x4E00 <= ch && ch <= 0x9FA5) {\n        // Chinese characters range\n        return ch;\n    } else if ((0x0080 <= ch && ch <= 0x00FF) ||   // Latin-1 Supplement (common symbols)\n               (0x2000 <= ch && ch <= 0x2BFF)) {   // Various special symbols, math symbols, arrows, etc.\n        // Keep various special symbols and math symbols as they are\n        return ch;\n    } else {\n        @throw [NSException exceptionWithName:@\"IllegalCharacter\"\n                                       reason:[NSString stringWithFormat:@\"Unknown character %d for default style.\", ch]\n                                     userInfo:nil];\n    }\n    return ch;\n}\n\nstatic const UTF32Char kMTUnicodeMathCapitalScriptStart = 0x1D49C;\n// TODO(kostub): Unused in Latin Modern Math - if another font is used determine if\n// this should be applicable.\n// static const UTF32Char kMTUnicodeMathLowerScriptStart = 0x1D4B6;\n\n// mathcal/mathscr (caligraphic or script)\nUTF32Char getCaligraphic(unichar ch) {\n    // Caligraphic has lots of exceptions:\n    switch(ch) {\n        case 'B':\n            return 0x212C;   // Script B (bernoulli)\n        case 'E':\n            return 0x2130;   // Script E (emf)\n        case 'F':\n            return 0x2131;   // Script F (fourier)\n        case 'H':\n            return 0x210B;   // Script H (hamiltonian)\n        case 'I':\n            return 0x2110;   // Script I\n        case 'L':\n            return 0x2112;   // Script L (laplace)\n        case 'M':\n            return 0x2133;   // Script M (M-matrix)\n        case 'R':\n            return 0x211B;   // Script R (Riemann integral)\n        case 'e':\n            return 0x212F;   // Script e (Natural exponent)\n        case 'g':\n            return 0x210A;   // Script g (real number)\n        case 'o':\n            return 0x2134;   // Script o (order)\n        default:\n            break;\n    }\n    UTF32Char unicode;\n    if (IS_UPPER_EN(ch)) {\n        unicode = kMTUnicodeMathCapitalScriptStart + (ch - 'A');\n    } else if (IS_LOWER_EN(ch)) {\n        // Latin Modern Math does not have lower case caligraphic characters, so we use\n        // the default style instead of showing a ?\n        unicode = getDefaultStyle(ch);\n    } else {\n        // Caligraphic characters don't exist for greek or numbers, we give them the\n        // default treatment.\n        unicode = getDefaultStyle(ch);\n    }\n    return unicode;\n}\n\nstatic const UTF32Char kMTUnicodeMathCapitalTTStart = 0x1D670;\nstatic const UTF32Char kMTUnicodeMathLowerTTStart = 0x1D68A;\nstatic const UTF32Char kMTUnicodeNumberTTStart = 0x1D7F6;\n\n// mathtt (monospace)\nUTF32Char getTypewriter(unichar ch) {\n    if (IS_UPPER_EN(ch)) {\n        return kMTUnicodeMathCapitalTTStart + (ch - 'A');\n    } else if (IS_LOWER_EN(ch)) {\n        return kMTUnicodeMathLowerTTStart + (ch - 'a');\n    } else if (IS_NUMBER(ch)) {\n        return kMTUnicodeNumberTTStart + (ch - '0');\n    }\n    // Monospace characters don't exist for greek, we give them the\n    // default treatment.\n    return getDefaultStyle(ch);\n}\n\nstatic const UTF32Char kMTUnicodeMathCapitalSansSerifStart = 0x1D5A0;\nstatic const UTF32Char kMTUnicodeMathLowerSansSerifStart = 0x1D5BA;\nstatic const UTF32Char kMTUnicodeNumberSansSerifStart = 0x1D7E2;\n\n// mathsf\nUTF32Char getSansSerif(unichar ch) {\n    if (IS_UPPER_EN(ch)) {\n        return kMTUnicodeMathCapitalSansSerifStart + (ch - 'A');\n    } else if (IS_LOWER_EN(ch)) {\n        return kMTUnicodeMathLowerSansSerifStart + (ch - 'a');\n    } else if (IS_NUMBER(ch)) {\n        return kMTUnicodeNumberSansSerifStart + (ch - '0');\n    }\n    // Sans-serif characters don't exist for greek, we give them the\n    // default treatment.\n    return getDefaultStyle(ch);\n}\n\nstatic const UTF32Char kMTUnicodeMathCapitalFrakturStart = 0x1D504;\nstatic const UTF32Char kMTUnicodeMathLowerFrakturStart = 0x1D51E;\n\n// mathfrak\nUTF32Char getFraktur(unichar ch) {\n    // Fraktur has exceptions:\n    switch(ch) {\n        case 'C':\n            return 0x212D;   // C Fraktur\n        case 'H':\n            return 0x210C;   // Hilbert space\n        case 'I':\n            return 0x2111;   // Imaginary\n        case 'R':\n            return 0x211C;   // Real\n        case 'Z':\n            return 0x2128;   // Z Fraktur\n        default:\n            break;\n    }\n    if (IS_UPPER_EN(ch)) {\n        return kMTUnicodeMathCapitalFrakturStart + (ch - 'A');\n    } else if (IS_LOWER_EN(ch)) {\n        return kMTUnicodeMathLowerFrakturStart + (ch - 'a');\n    }\n    // Fraktur characters don't exist for greek & numbers, we give them the\n    // default treatment.\n    return getDefaultStyle(ch);\n}\n\nstatic const UTF32Char kMTUnicodeMathCapitalBlackboardStart = 0x1D538;\nstatic const UTF32Char kMTUnicodeMathLowerBlackboardStart = 0x1D552;\nstatic const UTF32Char kMTUnicodeNumberBlackboardStart = 0x1D7D8;\n\n// mathbb (double struck)\nUTF32Char getBlackboard(unichar ch) {\n    // Blackboard has lots of exceptions:\n    switch(ch) {\n        case 'C':\n            return 0x2102;   // Complex numbers\n        case 'H':\n            return 0x210D;   // Quarternions\n        case 'N':\n            return 0x2115;   // Natural numbers\n        case 'P':\n            return 0x2119;   // Primes\n        case 'Q':\n            return 0x211A;   // Rationals\n        case 'R':\n            return 0x211D;   // Reals\n        case 'Z':\n            return 0x2124;   // Integers\n        default:\n            break;\n    }\n    if (IS_UPPER_EN(ch)) {\n        return kMTUnicodeMathCapitalBlackboardStart + (ch - 'A');\n    } else if (IS_LOWER_EN(ch)) {\n        return kMTUnicodeMathLowerBlackboardStart + (ch - 'a');\n    } else if (IS_NUMBER(ch)) {\n        return kMTUnicodeNumberBlackboardStart + (ch - '0');\n    }\n    // Blackboard characters don't exist for greek, we give them the\n    // default treatment.\n    return getDefaultStyle(ch);\n}\n\nstatic UTF32Char styleCharacter(unichar ch, MTFontStyle fontStyle)\n{\n    switch (fontStyle) {\n        case kMTFontStyleDefault:\n            return getDefaultStyle(ch);\n            \n        case kMTFontStyleRoman:\n            return ch;\n            \n        case kMTFontStyleBold:\n            return getBold(ch);\n            \n        case kMTFontStyleItalic:\n            return getItalicized(ch);\n            \n        case kMTFontStyleBoldItalic:\n            return getBoldItalic(ch);\n            \n        case kMTFontStyleCaligraphic:\n            return getCaligraphic(ch);\n            \n        case kMTFontStyleTypewriter:\n            return getTypewriter(ch);\n            \n        case kMTFontStyleSansSerif:\n            return getSansSerif(ch);\n            \n        case kMTFontStyleFraktur:\n            return getFraktur(ch);\n            \n        case kMTFontStyleBlackboard:\n            return getBlackboard(ch);\n            \n        default:\n            @throw [NSException exceptionWithName:@\"Invalid style\"\n                                           reason:[NSString stringWithFormat:@\"Unknown style %lu for font.\", (unsigned long)fontStyle]\n                                         userInfo:nil];\n    }\n    return ch;\n}\n\nstatic NSString* changeFont(NSString* str, MTFontStyle fontStyle) {\n    NSMutableString* retval = [NSMutableString stringWithCapacity:str.length];\n    unichar charBuffer[str.length];\n    [str getCharacters:charBuffer range:NSMakeRange(0, str.length)];\n    for (int i = 0; i < str.length; ++i) {\n        unichar ch = charBuffer[i];\n        UTF32Char unicode = styleCharacter(ch, fontStyle);\n        unicode = NSSwapHostIntToLittle(unicode);\n        NSString* charStr = [[NSString alloc] initWithBytes:&unicode length:sizeof(unicode) encoding:NSUTF32LittleEndianStringEncoding];\n        [retval appendString:charStr];\n    }\n    return retval;\n}\n\nstatic void getBboxDetails(CGRect bbox, CGFloat* ascent, CGFloat* descent)\n{\n    if (ascent) {\n        *ascent = MAX(0, CGRectGetMaxY(bbox) - 0);\n    }\n    \n    if (descent) {\n        // Descent is how much the line goes below the origin. However if the line is all above the origin, then descent can't be negative.\n        *descent = MAX(0, 0 - CGRectGetMinY(bbox));\n    }\n}\n\n#pragma mark - MTTypesetter\n// table width\nstatic CGFloat middlelineTableWidth = 0;\n\n@implementation MTTypesetter {\n    MTFont* _font;\n    NSMutableArray<MTDisplay *>* _displayAtoms;\n    CGPoint _currentPosition;\n    NSMutableAttributedString* _currentLine;\n    NSMutableArray* _currentAtoms;   // List of atoms that make the line\n    NSRange _currentLineIndexRange;\n    MTLineStyle _style;\n    MTFont* _styleFont;\n    BOOL _cramped;\n    BOOL _spaced;\n    BOOL _updateRightNow;\n    NSDictionary<NSString *, NSNumber *> *_adaptiveDict;\n}\n\n+ (MTMathListDisplay *)createLineForMathList:(MTMathList *)mathList font:(MTFont*)font style:(MTLineStyle)style\n{\n    MTMathList* finalizedList = mathList.finalized;\n    // default is not cramped\n    return [self createLineForMathList:finalizedList font:font style:style cramped:false];\n}\n\n// Internal\n+ (MTMathListDisplay *)createLineForMathList:(MTMathList *)mathList font:(MTFont*)font style:(MTLineStyle)style cramped:(BOOL) cramped\n{\n    return [self createLineForMathList:mathList font:font style:style cramped:cramped spaced:false];\n}\n\n// Internal\n+ (MTMathListDisplay *)createLineForMathList:(MTMathList *)mathList font:(MTFont*)font style:(MTLineStyle)style cramped:(BOOL) cramped spaced:(BOOL) spaced\n{\n    NSParameterAssert(font);\n    NSArray* preprocessedAtoms = [self preprocessMathList:mathList];\n    MTTypesetter *typesetter = [[MTTypesetter alloc] initWithFont:font style:style cramped:cramped spaced:spaced];\n    [typesetter createDisplayAtoms:preprocessedAtoms];\n    MTMathAtom* lastAtom = mathList.atoms.lastObject;\n    MTMathListDisplay* line = [[MTMathListDisplay alloc] initWithDisplays:typesetter->_displayAtoms range:NSMakeRange(0, NSMaxRange(lastAtom.indexRange))];\n    return line;\n}\n\n+ (MTColor*) placeholderColor\n{\n    return [MTColor blueColor];\n}\n\n- (instancetype)initWithFont:(MTFont*) font style:(MTLineStyle) style cramped:(BOOL) cramped spaced:(BOOL) spaced\n{\n    self = [super init];\n    if (self) {\n        _font = font;\n        _displayAtoms = [NSMutableArray array];\n        _currentPosition = CGPointZero;\n        _cramped = cramped;\n        _spaced = spaced;\n        _currentLine = [NSMutableAttributedString new];\n        _currentAtoms = [NSMutableArray array];\n        self.style = style;\n        _currentLineIndexRange = NSMakeRange(NSNotFound, NSNotFound);\n        _updateRightNow = NO;\n        _adaptiveDict = @{};\n    }\n    return self;\n}\n\n+ (NSArray*) preprocessMathList:(MTMathList*) ml\n{\n    // Note: Some of the preprocessing described by the TeX algorithm is done in the finalize method of MTMathList.\n    // Specifically rules 5 & 6 in Appendix G are handled by finalize.\n    // This function does not do a complete preprocessing as specified by TeX either. It removes any special atom types\n    // that are not included in TeX and applies Rule 14 to merge ordinary characters.\n    NSMutableArray* preprocessed = [NSMutableArray arrayWithCapacity:ml.atoms.count];\n    MTMathAtom* prevNode = nil;\n    MTSizeType lastSize = MTSizeTypeDefault;\n    for (MTMathAtom *atom in ml.atoms) {\n        if (atom.type == kMTMathAtomVariable || atom.type == kMTMathAtomNumber) {\n            // These are not a TeX type nodes. TeX does this during parsing the input.\n            // switch to using the font specified in the atom\n            NSString* newFont = changeFont(atom.nucleus, atom.fontStyle);\n            // We convert it to ordinary\n            atom.type = kMTMathAtomOrdinary;\n            atom.nucleus = newFont;\n        } else if (atom.type == kMTMathAtomUnaryOperator) {\n            // TeX treats these as Ordinary. So will we.\n            atom.type = kMTMathAtomOrdinary;\n        }\n        \n        if (atom.type == kMTMathAtomOrdinary) {\n            // This is Rule 14 to merge ordinary characters.\n            // combine ordinary atoms together\n            if (prevNode && prevNode.type == kMTMathAtomOrdinary && !prevNode.subScript && !prevNode.superScript && atom.sizeType == lastSize) {\n                [prevNode fuse:atom];\n                // skip the current node, we are done here.\n                continue;\n            }\n        }\n        lastSize = atom.sizeType;\n        // TODO: add italic correction here or in second pass?\n        prevNode = atom;\n        [preprocessed addObject:atom];\n    }\n    return preprocessed;\n}\n\n// returns the size of the font in this style\n+ (CGFloat) getStyleSize:(MTLineStyle) style font:(MTFont*) font\n{\n    CGFloat original = font.fontSize;\n    switch (style) {\n        case kMTLineStyleDisplay:\n        case kMTLineStyleText:\n            return original;\n            \n        case kMTLineStyleScript:\n            return original * font.mathTable.scriptScaleDown;\n            \n        case kMTLineStyleScriptScript:\n            return original * font.mathTable.scriptScriptScaleDown;\n    }\n    return 0;\n}\n\n- (void) setStyle:(MTLineStyle) style {\n    _style = style;\n    _styleFont = [_font copyFontWithSize:[[self class] getStyleSize:_style font:_font]];\n}\n\n- (void) addInterElementSpace:(MTMathAtom*) prevNode currentType:(MTMathAtomType) type\n{\n    CGFloat interElementSpace = 0;\n    if (prevNode) {\n        interElementSpace = [self getInterElementSpace:prevNode.type right:type];\n    } else if (_spaced) {\n        // For the first atom of a spaced list, treat it as if it is preceded by an open.\n        interElementSpace = [self getInterElementSpace:kMTMathAtomOpen right:type];\n    }\n    _currentPosition.x += interElementSpace;\n}\n\n- (void)handleAdaptiveAtomsWithPreprocessed:(NSArray *)preprocessed\n{\n    // 把adaptiveAtom移动到最后来计算\n    NSMutableDictionary<NSString *, NSNumber *> *adaptiveDict = @{}.mutableCopy;\n    NSMutableArray *mPreprocessed = preprocessed.mutableCopy;\n    NSMutableArray *mAdaptives = @[].mutableCopy;\n    NSInteger adaptiveIndex = 0; //最后需要插入到_displayAtoms中的index\n    __block BOOL updateRightNow = NO;\n    for (NSInteger index = 0; index < preprocessed.count; index++) {\n        MTMathAtom *atom = preprocessed[index];\n        if (atom.type == kMTMathAtomAdaptive) {\n            updateRightNow = YES;\n            MTAdaptive *adaptive = (MTAdaptive *)atom;\n            adaptiveDict[adaptive.adaptiveID] = @(adaptiveIndex);\n            [mPreprocessed removeObjectAtIndex:(index - mAdaptives.count)];\n            [mAdaptives addObject:atom];\n        }\n        if(atom.type == kMTMathAtomStyle || atom.type == kMTMathAtomSpace) {\n            continue;\n        }\n        adaptiveIndex++;\n        if (atom.subScript) {\n            adaptiveIndex++;\n        }\n        if (atom.superScript) {\n            adaptiveIndex++;\n        }\n    }\n    [mPreprocessed addObjectsFromArray:mAdaptives.copy];\n    preprocessed = mPreprocessed.copy;\n    _updateRightNow = updateRightNow;\n    _adaptiveDict = adaptiveDict;\n}\n\n- (void) createDisplayAtoms:(NSArray*) preprocessed\n{\n    [self handleAdaptiveAtomsWithPreprocessed:preprocessed];\n    \n    // items should contain all the nodes that need to be layed out.\n    // convert to a list of MTDisplayAtoms\n    MTMathAtom *prevNode = nil;\n    MTMathAtomType lastType = 0;\n    for (MTMathAtom* atom in preprocessed.copy) {\n        if ((atom.sizeType != MTSizeTypeDefault) &&\n            (atom.nucleus.length == 1)) {\n            // stash the existing layout\n            if (_currentLine.length > 0) {\n                [self addDisplayLine];\n            }\n            [self addInterElementSpace:prevNode currentType:atom.type];\n            MTDisplay *display = [self makeBiggerDisplay:atom];\n            [_displayAtoms addObject:display];\n            continue;\n        } else if (atom.sizeType > MTSizeTypeBigg && atom.sizeType <= MTSizeTypeLARGE) {\n            if (_currentLine.length > 0) {\n                [self addDisplayLine];\n            }\n            [self addInterElementSpace:prevNode currentType:atom.type];\n            MTDisplay *display = [self makeBiggerDisplay:atom];\n            [_displayAtoms addObject:display];\n            continue;\n        }\n        switch (atom.type) {\n            case kMTMathAtomNumber:\n            case kMTMathAtomVariable:\n            case kMTMathAtomUnaryOperator:\n                // These should never appear as they should have been removed by preprocessing\n                NSAssert(NO, @\"These types should never show here as they are removed by preprocessing.\");\n                break;\n                \n            case kMTMathAtomBoundary:\n                NSAssert(NO, @\"A boundary atom should never be inside a mathlist.\");\n                break;\n                \n            case kMTMathAtomSpace: {\n                // stash the existing layout\n                if (_currentLine.length > 0) {\n                    [self addDisplayLine];\n                }\n                MTMathSpace* space = (MTMathSpace*) atom;\n                // add the desired space\n                _currentPosition.x += space.space * _styleFont.mathTable.muUnit;\n                // Since this is extra space, the desired interelement space between the prevAtom\n                // and the next node is still preserved. To avoid resetting the prevAtom and lastType\n                // we skip to the next node.\n                continue;\n            }\n                \n            case kMTMathAtomStyle: {\n                // stash the existing layout\n                if (_currentLine.length > 0) {\n                    [self addDisplayLine];\n                }\n                MTMathStyle* style = (MTMathStyle*) atom;\n                self.style = style.style;\n                // We need to preserve the prevNode for any interelement space changes.\n                // so we skip to the next node.\n                continue;\n            }\n                \n            case kMTMathAtomColor: {\n                // stash the existing layout\n                if (_currentLine.length > 0) {\n                    [self addDisplayLine];\n                }\n                MTMathColor* colorAtom = (MTMathColor*) atom;\n                MTDisplay* display = [MTTypesetter createLineForMathList:colorAtom.innerList font:_font style:_style];\n                display.localTextColor = [MTColor colorFromHexString:colorAtom.colorString];\n                display.position = _currentPosition;\n                _currentPosition.x += display.width;\n                [_displayAtoms addObject:display];\n                break;\n            }\n                \n            case kMTMathAtomColorbox: {\n                // stash the existing layout\n                if (_currentLine.length > 0) {\n                    [self addDisplayLine];\n                }\n                MTMathColorbox* colorboxAtom = (MTMathColorbox*) atom;\n                MTDisplay* display = [MTTypesetter createLineForMathList:colorboxAtom.innerList font:_font style:_style];\n                \n                display.localBackgroundColor = [MTColor colorFromHexString:colorboxAtom.colorString];\n                display.position = _currentPosition;\n                _currentPosition.x += display.width;\n                [_displayAtoms addObject:display];\n                break;\n            }\n                \n            case kMTMathAtomBoxed: {\n                if (_currentLine.length > 0) {\n                    [self addDisplayLine];\n                }\n                MTBoxed* boxedAtom = (MTBoxed*) atom;\n                MTMathListDisplay* innerDisplay = [MTTypesetter createLineForMathList:boxedAtom.innerList font:_font style:_style];\n                \n                MTBoxedDisplay* display = [[MTBoxedDisplay alloc] initWithInner:innerDisplay lineThickness:0.5];\n                display.position = _currentPosition;\n                _currentPosition.x += display.width;\n                [_displayAtoms addObject:display];\n                break;\n            }\n            case KMTMathAtomTag: {\n                if (_currentLine.length > 0) {\n                    [self addDisplayLine];\n                }\n                MTMathTag* tagAtom = (MTMathTag*) atom;\n                MTMathTagDisplay *tagDisplay = [[MTMathTagDisplay alloc] initWithString:tagAtom.tagStr position:_currentPosition range:NSMakeRange(0, tagAtom.tagStr.length) font:_font atoms:tagAtom.innerList.atoms];\n                [_displayAtoms addObject:tagDisplay];\n                break;\n            }\n                \n            case kMTMathAtomRadical: {\n                // stash the existing layout\n                if (_currentLine.length > 0) {\n                    [self addDisplayLine];\n                }\n                MTRadical* rad = (MTRadical*) atom;\n                // Radicals are considered as Ord in rule 16.\n                [self addInterElementSpace:prevNode currentType:kMTMathAtomOrdinary];\n                MTRadicalDisplay* displayRad = [self makeRadical:rad.radicand range:rad.indexRange];\n                if (rad.degree) {\n                    // add the degree to the radical\n                    MTMathListDisplay* degree = [MTTypesetter createLineForMathList:rad.degree font:_font style:kMTLineStyleScriptScript];\n                    [displayRad setDegree:degree fontMetrics:_styleFont.mathTable];\n                }\n                [_displayAtoms addObject:displayRad];\n                _currentPosition.x += displayRad.width;\n                \n                // add super scripts || subscripts\n                if (atom.subScript || atom.superScript) {\n                    [self makeScripts:atom display:displayRad index:rad.indexRange.location delta:0];\n                }\n                // change type to ordinary\n                //atom.type = kMTMathAtomOrdinary;\n                break;\n            }\n                \n            case kMTMathAtomFraction: {\n                // stash the existing layout\n                if (_currentLine.length > 0) {\n                    [self addDisplayLine];\n                }\n                MTFraction* frac = (MTFraction*) atom;\n                [self addInterElementSpace:prevNode currentType:atom.type];\n                MTDisplay* display = [self makeFraction:frac];\n                [_displayAtoms addObject:display];\n                _currentPosition.x += display.width;\n                // add super scripts || subscripts\n                if (atom.subScript || atom.superScript) {\n                    [self makeScripts:atom display:display index:frac.indexRange.location delta:0];\n                }\n                break;\n            }\n                \n            case kMTMathAtomLargeOperator: {\n                // stash the existing layout\n                if (_currentLine.length > 0) {\n                    [self addDisplayLine];\n                }\n                [self addInterElementSpace:prevNode currentType:atom.type];\n                MTLargeOperator* op = (MTLargeOperator*) atom;\n                MTDisplay* display = [self makeLargeOp:op];\n                [_displayAtoms addObject:display];\n                break;\n            }\n                \n            case kMTMathAtomInner: {\n                // stash the existing layout\n                if (_currentLine.length > 0) {\n                    [self addDisplayLine];\n                }\n                [self addInterElementSpace:prevNode currentType:atom.type];\n                MTInner* inner = (MTInner*) atom;\n              MTInnerDisplay* display = [self makeInner:inner atIndex:atom.indexRange.location];\n                display.position = _currentPosition;\n                _currentPosition.x += display.width;\n                [_displayAtoms addObject:display];\n                // add super scripts || subscripts\n                if (atom.subScript || atom.superScript) {\n                    [self makeScripts:atom display:display index:atom.indexRange.location delta:0];\n                }\n                break;\n            }\n                \n            case kMTMathAtomAdaptive: {\n                // stash the existing layout\n                if (_currentLine.length > 0) {\n                    [self addDisplayLine];\n                }\n                MTAdaptive *adaptive = (MTAdaptive *)atom;\n                MTAdaptiveDisplay *display = [self makeAdaptive:adaptive];\n                \n                NSInteger index = _adaptiveDict[adaptive.adaptiveID].integerValue;\n                CGFloat space = 3 * _styleFont.mathTable.muUnit; //简单处理间距\n                if (index >= _displayAtoms.count) {\n                    _currentPosition.x += space;\n                    [_displayAtoms addObject:display];\n                    display.position = _currentPosition;\n                    _currentPosition.x += display.width;\n                } else {\n                    [_displayAtoms insertObject:display atIndex:index];\n                    MTDisplay *nextDisplay = _displayAtoms[index + 1];\n                    display.position = CGPointMake(nextDisplay.position.x, 0);\n                    //后面的display往后移「display.width + space」\n                    for (NSInteger idx = index + 1; idx < _displayAtoms.count; idx++) {\n                        _displayAtoms[idx].position = CGPointMake(display.width + space + _displayAtoms[idx].position.x, _displayAtoms[idx].position.y);\n                    }\n                    //更新_currentPosition\n                    MTDisplay *lastDisplay = _displayAtoms[_displayAtoms.count - 1];\n                    _currentPosition.x = lastDisplay.position.x + lastDisplay.width;\n                }\n                break;\n            }\n                \n            case kMTMathAtomUnderline: {\n                // stash the existing layout\n                if (_currentLine.length > 0) {\n                    [self addDisplayLine];\n                }\n                // Underline is considered as Ord in rule 16.\n                [self addInterElementSpace:prevNode currentType:kMTMathAtomOrdinary];\n                atom.type = kMTMathAtomOrdinary;\n                \n                MTUnderLine* under = (MTUnderLine*) atom;\n                MTDisplay* display = [self makeUnderline:under];\n                [_displayAtoms addObject:display];\n                _currentPosition.x += display.width;\n                // add super scripts || subscripts\n                if (atom.subScript || atom.superScript) {\n                    [self makeScripts:atom display:display index:atom.indexRange.location delta:0];\n                }\n                break;\n            }\n                \n            case kMTMathAtomOverline: {\n                // stash the existing layout\n                if (_currentLine.length > 0) {\n                    [self addDisplayLine];\n                }\n                // Overline is considered as Ord in rule 16.\n                [self addInterElementSpace:prevNode currentType:kMTMathAtomOrdinary];\n                atom.type = kMTMathAtomOrdinary;\n                \n                MTOverLine* over = (MTOverLine*) atom;\n                MTDisplay* display = [self makeOverline:over];\n                [_displayAtoms addObject:display];\n                _currentPosition.x += display.width;\n                // add super scripts || subscripts\n                if (atom.subScript || atom.superScript) {\n                    [self makeScripts:atom display:display index:atom.indexRange.location delta:0];\n                }\n                break;\n            }\n                \n            case kMTMathAtomHline: {\n                // stash the existing layout\n                if (_currentLine.length > 0) {\n                    [self addDisplayLine];\n                }\n                \n                [self addInterElementSpace:prevNode currentType:atom.type];\n                atom.type = kMTMathAtomOrdinary;\n                \n                MTHLine* hLine = (MTHLine*)atom;\n                MTHLineDisplay* display = [self makeHline:hLine];\n                [_displayAtoms addObject:display];\n                _currentPosition.x += display.width;\n                break;\n            }\n                \n            case kMTMathAtomOverbrace: {\n                // stash the existing layout\n                if (_currentLine.length > 0) {\n                    [self addDisplayLine];\n                }\n                \n                [self addInterElementSpace:prevNode currentType:atom.type];\n                atom.type = kMTMathAtomOrdinary;\n                \n                MTOverbrace* overbrace = (MTOverbrace*)atom;\n                MTDisplay* display = [self makeOverbrace:overbrace];\n                [_displayAtoms addObject:display];\n                _currentPosition.x += display.width;\n                break;\n            }\n                \n            case kMTmathAtomUnderbrace: {\n                // stash the existing layout\n                if (_currentLine.length > 0) {\n                    [self addDisplayLine];\n                }\n                \n                [self addInterElementSpace:prevNode currentType:atom.type];\n                atom.type = kMTMathAtomOrdinary;\n                \n                MTUnderbrace* underbrace = (MTUnderbrace*)atom;\n                MTDisplay* display = [self makeUnderbrace:underbrace];\n                [_displayAtoms addObject:display];\n                _currentPosition.x += display.width;\n                break;\n            }\n                \n            case kMTMathAtomAccent: {\n                // stash the existing layout\n                if (_currentLine.length > 0) {\n                    [self addDisplayLine];\n                }\n                // Accent is considered as Ord in rule 16.\n                [self addInterElementSpace:prevNode currentType:kMTMathAtomOrdinary];\n                atom.type = kMTMathAtomOrdinary;\n                \n                MTAccent* accent = (MTAccent*) atom;\n                MTDisplay* display = [self makeAccent:accent];\n                [_displayAtoms addObject:display];\n                _currentPosition.x += display.width;\n                \n                // add super scripts || subscripts\n                if (atom.subScript || atom.superScript) {\n                    [self makeScripts:atom display:display index:atom.indexRange.location delta:0];\n                }\n                break;\n            }\n                \n            case kMTMathAtomTable: {\n                // stash the existing layout\n                if (_currentLine.length > 0) {\n                    [self addDisplayLine];\n                }\n                // We will consider tables as inner\n                [self addInterElementSpace:prevNode currentType:kMTMathAtomInner];\n                atom.type = kMTMathAtomInner;\n                \n                MTMathTable* table = (MTMathTable*) atom;\n                MTDisplay* display = [self makeTable:table];\n                [_displayAtoms addObject:display];\n                _currentPosition.x += display.width;\n                // save table width\n                middlelineTableWidth = display.width;\n                // A table doesn't have subscripts or superscripts\n                break;\n            }\n                \n            case kMTMathAtomOrdinary:\n            case kMTMathAtomBinaryOperator:\n            case kMTMathAtomRelation:\n            case kMTMathAtomOpen:\n            case kMTMathAtomClose:\n            case kMTMathAtomPlaceholder:\n            case kMTMathAtomPunctuation: {\n                // the rendering for all the rest is pretty similar\n                // All we need is render the character and set the interelement space.\n                if (prevNode) {\n                    CGFloat interElementSpace = _updateRightNow ? 0 : [self getInterElementSpace:prevNode.type right:atom.type];\n                    if (_currentLine.length > 0) {\n                        if (interElementSpace > 0) {\n                            // add a kerning of that space to the previous character\n                            [_currentLine addAttribute:(NSString*) kCTKernAttributeName\n                                                 value:[NSNumber numberWithFloat:interElementSpace]\n                                                 range:[_currentLine.string rangeOfComposedCharacterSequenceAtIndex:_currentLine.length - 1]];\n                        }\n                    } else {\n                        // increase the space\n                        _currentPosition.x += interElementSpace;\n                    }\n                }\n\n                NSAttributedString* current = nil;\n                if (atom.type == kMTMathAtomPlaceholder) {\n                    MTColor* color = [MTTypesetter placeholderColor];\n                    current = [[NSAttributedString alloc] initWithString:atom.nucleus\n                                                              attributes:@{ (NSString*) kCTForegroundColorAttributeName : (id) color.CGColor }];\n                } else {\n                    current = [[NSAttributedString alloc] initWithString:atom.nucleus];\n                }\n             \n                [_currentLine appendAttributedString:current];\n                // add the atom to the current range\n                if (_currentLineIndexRange.location == NSNotFound) {\n                    _currentLineIndexRange = atom.indexRange;\n                } else {\n                    _currentLineIndexRange.length += atom.indexRange.length;\n                }\n                // add the fused atoms\n                if (atom.fusedAtoms) {\n                    [_currentAtoms addObjectsFromArray:atom.fusedAtoms];\n                } else {\n                    [_currentAtoms addObject:atom];\n                }\n                \n                // add super scripts || subscripts\n                if (atom.subScript || atom.superScript) {\n                    // stash the existing line\n                    // We don't check _currentLine.length here since we want to allow empty lines with super/sub scripts.\n                    MTCTLineDisplay* line = [self addDisplayLine];\n                    CGFloat delta = 0;\n                    if (atom.nucleus.length > 0) {\n                        // Use the italic correction of the last character.\n                        CGGlyph glyph = [self findGlyphForCharacterAtIndex:atom.nucleus.length - 1 inString:atom.nucleus];\n                        delta = [_styleFont.mathTable getItalicCorrection:glyph];\n                    }\n                    if (delta > 0 && !atom.subScript) {\n                        // Add a kern of delta\n                        _currentPosition.x += delta;\n                    }\n                    [self makeScripts:atom display:line index:NSMaxRange(atom.indexRange) - 1 delta:delta];\n                } else if (_updateRightNow) {\n                    if (_currentLine.length > 0) {\n                        [self addDisplayLine];\n                    }\n                }\n                break;\n            }\n        }\n        lastType = atom.type;\n        prevNode = atom;\n    }\n    if (_currentLine.length > 0) {\n        [self addDisplayLine];\n    }\n    if (_spaced && lastType) {\n        // If _spaced then add an interelement space between the last type and close\n        MTDisplay* display = [_displayAtoms lastObject];\n        CGFloat interElementSpace = [self getInterElementSpace:lastType right:kMTMathAtomClose];\n        display.width += interElementSpace;\n    }\n}\n\n- (MTCTLineDisplay*) addDisplayLine\n{\n    // add the font\n    [_currentLine addAttribute:(NSString *)kCTFontAttributeName value:(__bridge id)(_styleFont.ctFont) range:NSMakeRange(0, _currentLine.length)];\n    /*NSAssert(_currentLineIndexRange.length == numCodePoints(_currentLine.string),\n     @\"The length of the current line: %@ does not match the length of the range (%d, %d)\",\n     _currentLine, _currentLineIndexRange.location, _currentLineIndexRange.length);*/\n    \n    MTCTLineDisplay* displayAtom = [[MTCTLineDisplay alloc] initWithString:_currentLine position:_currentPosition range:_currentLineIndexRange font:_styleFont atoms:_currentAtoms];\n    [_displayAtoms addObject:displayAtom];\n    // update the position\n    _currentPosition.x += displayAtom.width;\n    // clear the string and the range\n    _currentLine = [NSMutableAttributedString new];\n    _currentAtoms = [NSMutableArray array];\n    _currentLineIndexRange = NSMakeRange(NSNotFound, NSNotFound);\n    return displayAtom;\n}\n\n#pragma mark Spacing\n\n// Returned in units of mu = 1/18 em.\n- (int) getSpacingInMu:(MTInterElementSpaceType) type\n{\n    switch (type) {\n        case kMTSpaceInvalid:\n            return -1;\n        case kMTSpaceNone:\n            return 0;\n        case kMTSpaceThin:\n            return 3;\n        case kMTSpaceNSThin:\n            return (_style < kMTLineStyleScript) ? 3 : 0;\n            \n        case kMTSpaceNSMedium:\n            return (_style < kMTLineStyleScript) ? 4 : 0;\n            \n        case kMTSpaceNSThick:\n            return (_style < kMTLineStyleScript) ? 5 : 0;\n    }\n}\n\n- (CGFloat) getInterElementSpace:(MTMathAtomType) left right:(MTMathAtomType) right\n{\n    NSUInteger leftIndex = getInterElementSpaceArrayIndexForType(left, true);\n    NSUInteger rightIndex = getInterElementSpaceArrayIndexForType(right, false);\n    NSArray* spaceArray = getInterElementSpaces()[leftIndex];\n    NSNumber* spaceTypeObj = spaceArray[rightIndex];\n    MTInterElementSpaceType spaceType = spaceTypeObj.intValue;\n    NSAssert(spaceType != kMTSpaceInvalid, @\"Invalid space between %lu and %lu\", (unsigned long)left, (unsigned long)right);\n    \n    int spaceMultipler = [self getSpacingInMu:spaceType];\n    if (spaceMultipler > 0) {\n        // 1 em = size of font in pt. space multipler is in multiples mu or 1/18 em\n        return spaceMultipler * _styleFont.mathTable.muUnit;\n    }\n    return 0;\n}\n\n\n#pragma mark Subscript/Superscript\n\n- (MTLineStyle) scriptStyle\n{\n    switch (_style) {\n        case kMTLineStyleDisplay:\n        case kMTLineStyleText:\n            return kMTLineStyleScript;\n        case kMTLineStyleScript:\n            return kMTLineStyleScriptScript;\n        case kMTLineStyleScriptScript:\n            return kMTLineStyleScriptScript;\n    }\n    return kMTLineStyleDisplay;\n}\n\n// subscript is always cramped\n- (BOOL) subscriptCramped\n{\n    return true;\n}\n\n// superscript is cramped only if the current style is cramped\n- (BOOL) superScriptCramped\n{\n    return _cramped;\n}\n\n- (CGFloat) superScriptShiftUp\n{\n    if (_cramped) {\n        return _styleFont.mathTable.superscriptShiftUpCramped;\n    } else {\n        return _styleFont.mathTable.superscriptShiftUp;\n    }\n}\n\n// make scripts for the last atom\n// index is the index of the element which is getting the sub/super scripts.\n- (void) makeScripts:(MTMathAtom*) atom display:(MTDisplay*) display index:(NSUInteger) index delta:(CGFloat) delta\n{\n    assert(atom.subScript || atom.superScript);\n    \n    double superScriptShiftUp = 0;\n    double subscriptShiftDown = 0;\n    \n    display.hasScript = YES;\n    if (![display isKindOfClass:[MTCTLineDisplay class]]) {\n        // get the font in script style\n        CGFloat scriptFontSize = [[self class] getStyleSize:self.scriptStyle font:_font];\n        MTFont* scriptFont = [_font copyFontWithSize:scriptFontSize];\n        MTFontMathTable *scriptFontMetrics = scriptFont.mathTable;\n        \n        // if it is not a simple line then\n        superScriptShiftUp = display.ascent - scriptFontMetrics.superscriptBaselineDropMax;\n        subscriptShiftDown = display.descent + scriptFontMetrics.subscriptBaselineDropMin;\n    }\n    \n    if (!atom.superScript) {\n        assert(atom.subScript);\n        MTMathListDisplay* subscript;\n        BOOL isLimitAtom = ([atom isKindOfClass:MTLargeOperator.class] && [atom.nucleus isEqualToString:@\"lim\"]);\n        \n        if (isLimitAtom) {\n            CGFloat scriptFontSize = [[self class] getStyleSize:kMTLineStyleScript font:_font];\n            MTFont* scriptFont = [_font copyFontWithSize:scriptFontSize];\n            subscript = [MTTypesetter createLineForMathList:atom.subScript\n                                                       font:scriptFont\n                                                      style:self.scriptStyle\n                                                    cramped:self.subscriptCramped];\n        } else {\n            subscript = [MTTypesetter createLineForMathList:atom.subScript\n                                                       font:_font\n                                                      style:self.scriptStyle\n                                                    cramped:self.subscriptCramped];\n        }\n        \n        // 下标极限判断\n        if (isLimitAtom && ((MTLargeOperator *)atom).limits) {\n            CGFloat originX = _currentPosition.x - display.width;\n            // add the subscript\n            CGFloat displayHeight = display.ascent + display.descent;\n            subscript.position = CGPointMake(originX, _currentPosition.y - displayHeight - subscriptShiftDown);\n            [_displayAtoms addObject:subscript];\n            // update the position\n            _currentPosition.x = originX + fmax(subscript.width, display.width);\n            return;\n        }\n        \n        subscript.type = kMTLinePositionSubscript;\n        subscript.index = index;\n        \n        subscriptShiftDown = fmax(subscriptShiftDown, _styleFont.mathTable.subscriptShiftDown);\n        subscriptShiftDown = fmax(subscriptShiftDown, subscript.ascent - _styleFont.mathTable.subscriptTopMax);\n        // add the subscript\n        subscript.position = CGPointMake(_currentPosition.x, _currentPosition.y - subscriptShiftDown);\n        [_displayAtoms addObject:subscript];\n        // update the position\n        _currentPosition.x += subscript.width + _styleFont.mathTable.spaceAfterScript;\n        return;\n    }\n    \n    MTMathListDisplay* superScript = [MTTypesetter createLineForMathList:atom.superScript font:_font style:self.scriptStyle cramped:self.superScriptCramped];\n    superScript.type = kMTLinePositionSuperscript;\n    superScript.index = index;\n    superScriptShiftUp = fmax(superScriptShiftUp, self.superScriptShiftUp);\n    superScriptShiftUp = fmax(superScriptShiftUp, superScript.descent + _styleFont.mathTable.superscriptBottomMin);\n    \n    if (!atom.subScript) {\n        superScript.position = CGPointMake(_currentPosition.x, _currentPosition.y + superScriptShiftUp);\n        [_displayAtoms addObject:superScript];\n        // update the position\n        _currentPosition.x += superScript.width + _styleFont.mathTable.spaceAfterScript;\n        return;\n    }\n    MTMathListDisplay* subscript = [MTTypesetter createLineForMathList:atom.subScript font:_font style:self.scriptStyle cramped:self.subscriptCramped];\n    subscript.type = kMTLinePositionSubscript;\n    subscript.index = index;\n    subscriptShiftDown = fmax(subscriptShiftDown, _styleFont.mathTable.subscriptShiftDown);\n    \n    // joint positioning of subscript & superscript\n    CGFloat subSuperScriptGap = (superScriptShiftUp - superScript.descent) + (subscriptShiftDown - subscript.ascent);\n    if (subSuperScriptGap < _styleFont.mathTable.subSuperscriptGapMin) {\n        // Set the gap to atleast as much\n        subscriptShiftDown += _styleFont.mathTable.subSuperscriptGapMin - subSuperScriptGap;\n        CGFloat superscriptBottomDelta = _styleFont.mathTable.superscriptBottomMaxWithSubscript - (superScriptShiftUp - superScript.descent);\n        if (superscriptBottomDelta > 0) {\n            // superscript is lower than the max allowed by the font with a subscript.\n            superScriptShiftUp += superscriptBottomDelta;\n            subscriptShiftDown -= superscriptBottomDelta;\n        }\n    }\n    // The delta is the italic correction above that shift superscript position\n    superScript.position = CGPointMake(_currentPosition.x + delta, _currentPosition.y + superScriptShiftUp);\n    [_displayAtoms addObject:superScript];\n    subscript.position = CGPointMake(_currentPosition.x, _currentPosition.y - subscriptShiftDown);\n    [_displayAtoms addObject:subscript];\n    _currentPosition.x += MAX(superScript.width + delta, subscript.width) + _styleFont.mathTable.spaceAfterScript;\n}\n\n#pragma mark - Fractions\n\n- (CGFloat) numeratorShiftUp:(BOOL) hasRule {\n    if (hasRule) {\n        if (_style == kMTLineStyleDisplay) {\n            return _styleFont.mathTable.fractionNumeratorDisplayStyleShiftUp;\n        } else {\n            return _styleFont.mathTable.fractionNumeratorShiftUp;\n        }\n    } else {\n        if (_style == kMTLineStyleDisplay) {\n            return _styleFont.mathTable.stackTopDisplayStyleShiftUp;\n        } else {\n            return _styleFont.mathTable.stackTopShiftUp;\n        }\n    }\n}\n\n- (CGFloat) numeratorGapMin {\n    if (_style == kMTLineStyleDisplay) {\n        return _styleFont.mathTable.fractionNumeratorDisplayStyleGapMin;\n    } else {\n        return _styleFont.mathTable.fractionNumeratorGapMin;\n    }\n}\n\n- (CGFloat) denominatorShiftDown:(BOOL) hasRule {\n    if (hasRule) {\n        if (_style == kMTLineStyleDisplay) {\n            return _styleFont.mathTable.fractionDenominatorDisplayStyleShiftDown;\n        } else {\n            return _styleFont.mathTable.fractionDenominatorShiftDown;\n        }\n    } else {\n        if (_style == kMTLineStyleDisplay) {\n            return _styleFont.mathTable.stackBottomDisplayStyleShiftDown;\n        } else {\n            return _styleFont.mathTable.stackBottomShiftDown;\n        }\n    }\n}\n\n- (CGFloat) denominatorGapMin {\n    if (_style == kMTLineStyleDisplay) {\n        return _styleFont.mathTable.fractionDenominatorDisplayStyleGapMin;\n    } else {\n        return _styleFont.mathTable.fractionDenominatorGapMin;\n    }\n}\n\n- (CGFloat) stackGapMin {\n    if (_style == kMTLineStyleDisplay) {\n        return _styleFont.mathTable.stackDisplayStyleGapMin;\n    } else {\n        return _styleFont.mathTable.stackGapMin;\n    }\n}\n\n- (CGFloat) fractionDelimiterHeight {\n    if (_style == kMTLineStyleDisplay) {\n        return _styleFont.mathTable.fractionDelimiterDisplayStyleSize;\n    } else {\n        return _styleFont.mathTable.fractionDelimiterSize;\n    }\n}\n\n- (MTLineStyle) fractionStyle\n{\n    if (_style == kMTLineStyleScriptScript) {\n        return kMTLineStyleScriptScript;\n    }\n    return _style + 1;\n}\n\n- (MTDisplay*) makeFraction:(MTFraction*) frac\n{\n    // lay out the parts of the fraction\n    MTLineStyle fractionStyle = frac.isCfrac ? kMTLineStyleText : self.fractionStyle;\n    MTMathListDisplay* numeratorDisplay = [MTTypesetter createLineForMathList:frac.numerator font:_font style:fractionStyle cramped:false];\n    MTMathListDisplay* denominatorDisplay = [MTTypesetter createLineForMathList:frac.denominator font:_font style:fractionStyle cramped:true];\n    \n    // determine the location of the numerator\n    CGFloat numeratorShiftUp = [self numeratorShiftUp:frac.hasRule];\n    CGFloat denominatorShiftDown = [self denominatorShiftDown:frac.hasRule];\n    CGFloat barLocation = _styleFont.mathTable.axisHeight;\n    CGFloat barThickness = (frac.hasRule) ? _styleFont.mathTable.fractionRuleThickness : 0;\n    \n    if (frac.hasRule) {\n        // This is the difference between the lowest edge of the numerator and the top edge of the fraction bar\n        CGFloat distanceFromNumeratorToBar = (numeratorShiftUp - numeratorDisplay.descent) - (barLocation + barThickness/2);\n        // The distance should at least be displayGap\n        CGFloat minNumeratorGap = self.numeratorGapMin;\n        if (distanceFromNumeratorToBar < minNumeratorGap) {\n            // This makes the distance between the bottom of the numerator and the top edge of the fraction bar\n            // at least minNumeratorGap.\n            numeratorShiftUp += (minNumeratorGap - distanceFromNumeratorToBar);\n        }\n        \n        // Do the same for the denominator\n        // This is the difference between the top edge of the denominator and the bottom edge of the fraction bar\n        CGFloat distanceFromDenominatorToBar = (barLocation - barThickness/2) - (denominatorDisplay.ascent - denominatorShiftDown);\n        // The distance should at least be denominator gap\n        CGFloat minDenominatorGap = self.denominatorGapMin;\n        if (distanceFromDenominatorToBar < minDenominatorGap) {\n            // This makes the distance between the top of the denominator and the bottom of the fraction bar to be exactly\n            // minDenominatorGap\n            denominatorShiftDown += (minDenominatorGap - distanceFromDenominatorToBar);\n        }\n    } else {\n        // This is the distance between the numerator and the denominator\n        CGFloat clearance = (numeratorShiftUp - numeratorDisplay.descent) - (denominatorDisplay.ascent - denominatorShiftDown);\n        // This is the minimum clearance between the numerator and denominator.\n        CGFloat minGap = self.stackGapMin;\n        if (clearance < minGap) {\n            numeratorShiftUp += (minGap - clearance)/2;\n            denominatorShiftDown += (minGap - clearance)/2;\n        }\n    }\n    \n    MTFractionDisplay *display = [[MTFractionDisplay alloc] initWithNumerator:numeratorDisplay denominator:denominatorDisplay\n                                                                     position:_currentPosition range:frac.indexRange];\n    \n    display.numeratorUp = numeratorShiftUp;\n    display.denominatorDown = denominatorShiftDown;\n    display.lineThickness = barThickness;\n    display.linePosition = barLocation;\n    if (!frac.leftDelimiter && !frac.rightDelimiter) {\n        return display;\n    } else {\n        return [self addDelimitersToFractionDisplay:display forFraction:frac];\n    }\n}\n\n- (MTDisplay*) addDelimitersToFractionDisplay:(MTFractionDisplay*)display forFraction:(MTFraction*) frac\n{\n    NSAssert(frac.leftDelimiter || frac.rightDelimiter, @\"Fraction should have a delimiters to call this function\");\n    \n    NSMutableArray* innerElements = [[NSMutableArray alloc] init];\n    CGFloat glyphHeight = self.fractionDelimiterHeight;\n    CGPoint position = CGPointZero;\n    if (frac.leftDelimiter.length > 0) {\n        MTDisplay* leftGlyph = [self findGlyphForBoundary:frac.leftDelimiter withHeight:glyphHeight];\n        leftGlyph.position = position;\n        position.x += leftGlyph.width;\n        [innerElements addObject:leftGlyph];\n    }\n    \n    display.position = position;\n    position.x += display.width;\n    [innerElements addObject:display];\n    \n    if (frac.rightDelimiter.length > 0) {\n        MTDisplay* rightGlyph = [self findGlyphForBoundary:frac.rightDelimiter withHeight:glyphHeight];\n        rightGlyph.position = position;\n        position.x += rightGlyph.width;\n        [innerElements addObject:rightGlyph];\n    }\n    MTMathListDisplay* innerDisplay = [[MTMathListDisplay alloc] initWithDisplays:innerElements range:frac.indexRange];\n    innerDisplay.position = _currentPosition;\n    return innerDisplay;\n}\n\n#pragma mark Radicals\n\n- (CGFloat) radicalVerticalGap\n{\n    if (_style == kMTLineStyleDisplay) {\n        return _styleFont.mathTable.radicalDisplayStyleVerticalGap;\n    } else {\n        return _styleFont.mathTable.radicalVerticalGap;\n    }\n}\n\n- (MTDisplay<DownShift>*)getRadicalGlyphWithHeight:(CGFloat)radicalHeight\n{\n    CGFloat glyphAscent, glyphDescent, glyphWidth;\n    \n    CGGlyph radicalGlyph = [self findGlyphForCharacterAtIndex:0 inString:@\"\\u221A\"];\n    CGGlyph glyph = [self findGlyph:radicalGlyph withHeight:radicalHeight glyphAscent:&glyphAscent glyphDescent:&glyphDescent glyphWidth:&glyphWidth];\n    \n    MTDisplay<DownShift>* glyphDisplay;\n    if (glyphAscent + glyphDescent < radicalHeight) {\n        // the glyphs is not as large as required. A glyph needs to be constructed using the extenders.\n        glyphDisplay = [self constructGlyph:radicalGlyph withHeight:radicalHeight];\n    }\n    \n    if (!glyphDisplay) {\n        // No constructed display so use the glyph we got.\n        glyphDisplay = [[MTGlyphDisplay alloc] initWithGlpyh:glyph range:NSMakeRange(NSNotFound, 0) font:_styleFont];\n        glyphDisplay.ascent = glyphAscent;\n        glyphDisplay.descent = glyphDescent;\n        glyphDisplay.width = glyphWidth;\n    }\n    return glyphDisplay;\n}\n\n- (MTRadicalDisplay*) makeRadical:(MTMathList*) radicand range:(NSRange) range\n{\n    MTMathListDisplay* innerDisplay = [MTTypesetter createLineForMathList:radicand font:_font style:_style cramped:YES];\n    CGFloat clearance = self.radicalVerticalGap;\n    CGFloat radicalRuleThickness = _styleFont.mathTable.radicalRuleThickness;\n    CGFloat radicalHeight = innerDisplay.ascent + innerDisplay.descent + clearance + radicalRuleThickness;\n    \n    MTDisplay<DownShift>* glyph = [self getRadicalGlyphWithHeight:radicalHeight];\n    \n    \n    // Note this is a departure from Latex. Latex assumes that glyphAscent == thickness.\n    // Open type math makes no such assumption, and ascent and descent are independent of the thickness.\n    // Latex computes delta as descent - (h(inner) + d(inner) + clearance)\n    // but since we may not have ascent == thickness, we modify the delta calculation slightly.\n    // If the font designer followes Latex conventions, it will be identical.\n    CGFloat delta = (glyph.descent + glyph.ascent) - (innerDisplay.ascent + innerDisplay.descent + clearance + radicalRuleThickness);\n    if (delta > 0) {\n        clearance += delta/2;  // increase the clearance to center the radicand inside the sign.\n    }\n    \n    // we need to shift the radical glyph up, to coincide with the baseline of inner.\n    // The new ascent of the radical glyph should be thickness + adjusted clearance + h(inner)\n    CGFloat radicalAscent = radicalRuleThickness + clearance + innerDisplay.ascent;\n    CGFloat shiftUp = radicalAscent - glyph.ascent;  // Note: if the font designer followed latex conventions, this is the same as glyphAscent == thickness.\n    glyph.shiftDown = -shiftUp;\n    \n    MTRadicalDisplay* radical = [[MTRadicalDisplay alloc] initWitRadicand:innerDisplay glpyh:glyph position:_currentPosition range:range];\n    radical.ascent = radicalAscent + _styleFont.mathTable.radicalExtraAscender;\n    radical.topKern = _styleFont.mathTable.radicalExtraAscender;\n    radical.lineThickness = radicalRuleThickness;\n    // Note: Until we have radical construction from parts, it is possible that glyphAscent+glyphDescent is less\n    // than the requested height of the glyph (i.e. radicalHeight), so in the case the innerDisplay has a larger\n    // descent we use the innerDisplay's descent.\n    radical.descent = MAX(glyph.ascent + glyph.descent  - radicalAscent, innerDisplay.descent);\n    radical.width = glyph.width + innerDisplay.width;\n    return radical;\n}\n\n#pragma mark Glyphs\n\n- (CGGlyph)findGlyphByDelimiter:(NSString*) delimiter\n                         sizeType:(MTSizeType)sizeType\n                      glyphAscent:(CGFloat *) glyphAscent\n                     glyphDescent:(CGFloat *) glyphDescent\n                       glyphWidth:(CGFloat *) glyphWidth {\n    CGGlyph glyph = [self findGlyphForCharacterAtIndex:0 inString:delimiter];\n    NSArray<NSNumber *> *variants = [_styleFont.mathTable getVerticalVariantsForGlyph:glyph];\n    \n    CFIndex numVariants = variants.count;\n    if (numVariants == 0) {\n        return glyph;\n    }\n    NSInteger index = (sizeType > numVariants - 1) ? numVariants - 1  : sizeType;\n    CGGlyph glyphs[1];\n    glyphs[0] = [variants[index] shortValue];\n   \n    CGRect bboxes[1];\n    CGSize advances[1];\n    \n    // Get the bounds for these glyphs\n    CTFontGetBoundingRectsForGlyphs(_styleFont.ctFont, kCTFontHorizontalOrientation, glyphs, bboxes, 1);\n    CTFontGetAdvancesForGlyphs(_styleFont.ctFont, kCTFontHorizontalOrientation, glyphs, advances, 1);\n    \n    CGFloat ascent = 0.0, descent = 0.0, width = 0.0;\n    CGRect bounds = bboxes[0];\n    width = advances[0].width;\n    getBboxDetails(bounds, &ascent, &descent);\n\n    *glyphAscent = ascent;\n    *glyphDescent = descent;\n    *glyphWidth = width;\n    return glyphs[0];\n}\n\n- (CGGlyph) findGlyph:(CGGlyph) glyph withHeight:(CGFloat) height glyphAscent:(CGFloat*) glyphAscent glyphDescent:(CGFloat*) glyphDescent glyphWidth:(CGFloat*) glyphWidth\n{\n    NSArray<NSNumber*>* variants = [_styleFont.mathTable getVerticalVariantsForGlyph:glyph];\n    CFIndex numVariants = variants.count;\n    CGGlyph glyphs[numVariants];\n    for (CFIndex i = 0; i < numVariants; i++) {\n        CGGlyph glyph = [variants[i] shortValue];\n        glyphs[i] = glyph;\n    }\n    \n    CGRect bboxes[numVariants];\n    CGSize advances[numVariants];\n    // Get the bounds for these glyphs\n    CTFontGetBoundingRectsForGlyphs(_styleFont.ctFont, kCTFontHorizontalOrientation, glyphs, bboxes, numVariants);\n    CTFontGetAdvancesForGlyphs(_styleFont.ctFont, kCTFontHorizontalOrientation, glyphs, advances, numVariants);\n    CGFloat ascent = 0.0, descent = 0.0, width = 0.0;\n    for (int i = 0; i < numVariants; i++) {\n        CGRect bounds = bboxes[i];\n        width = advances[i].width;\n        getBboxDetails(bounds, &ascent, &descent);\n        \n        if (ascent + descent >= height) {\n            *glyphAscent = ascent;\n            *glyphDescent = descent;\n            *glyphWidth = width;\n            return glyphs[i];\n        }\n    }\n    *glyphAscent = ascent;\n    *glyphDescent = descent;\n    *glyphWidth = width;\n    return glyphs[numVariants - 1];\n}\n\n- (MTGlyphConstructionDisplay*) constructGlyph:(CGGlyph) glyph withHeight:(CGFloat) glyphHeight\n{\n    NSArray<MTGlyphPart*>* parts = [_styleFont.mathTable getVerticalGlyphAssemblyForGlyph:glyph];\n    if (parts.count == 0) {\n        return nil;\n    }\n    NSArray<NSNumber*>* glyphs, *offsets;\n    CGFloat height;\n    [self constructGlyphWithParts:parts height:glyphHeight glyphs:&glyphs offsets:&offsets height:&height];\n    CGGlyph first = glyphs[0].shortValue;\n    CGFloat width = CTFontGetAdvancesForGlyphs(_styleFont.ctFont, kCTFontHorizontalOrientation, &first, NULL, 1);\n    MTGlyphConstructionDisplay* display = [[MTGlyphConstructionDisplay alloc] initWithGlyphs:glyphs offsets:offsets font:_styleFont];\n    display.width = width;\n    display.ascent = height;\n    display.descent = 0;   // it's upto the rendering to adjust the display up or down.\n    return display;\n}\n\n- (void) constructGlyphWithParts:(NSArray<MTGlyphPart*>*) parts height:(CGFloat) glyphHeight glyphs:(NSArray<NSNumber*>**) glyphs offsets:(NSArray<NSNumber*>**) offsets height:(CGFloat*) height\n{\n    NSParameterAssert(glyphs);\n    NSParameterAssert(offsets);\n    \n    for (int numExtenders = 0; true; numExtenders++) {\n        NSMutableArray<NSNumber*>* glyphsRv = [NSMutableArray array];\n        NSMutableArray<NSNumber*>* offsetsRv = [NSMutableArray array];\n        \n        MTGlyphPart* prev = nil;\n        CGFloat minDistance = _styleFont.mathTable.minConnectorOverlap;\n        CGFloat minOffset = 0;\n        CGFloat maxDelta = CGFLOAT_MAX;  // the maximum amount we can increase the offsets by\n        \n        for (MTGlyphPart* part in parts) {\n            int repeats = 1;\n            if (part.isExtender) {\n                repeats = numExtenders;\n            }\n            // add the extender num extender times\n            for (int i = 0; i < repeats; i++) {\n                [glyphsRv addObject:[NSNumber numberWithShort:part.glyph]];\n                if (prev) {\n                    CGFloat maxOverlap = MIN(prev.endConnectorLength, part.startConnectorLength);\n                    // the minimum amount we can add to the offset\n                    CGFloat minOffsetDelta = prev.fullAdvance - maxOverlap;\n                    // The maximum amount we can add to the offset.\n                    CGFloat maxOffsetDelta = prev.fullAdvance - minDistance;\n                    // we can increase the offsets by at most max - min.\n                    maxDelta = MIN(maxDelta, maxOffsetDelta - minOffsetDelta);\n                    minOffset = minOffset + minOffsetDelta;\n                }\n                [offsetsRv addObject:[NSNumber numberWithFloat:minOffset]];\n                prev = part;\n            }\n        }\n        \n        NSAssert(glyphsRv.count == offsetsRv.count, @\"Offsets should match the glyphs\");\n        if (!prev) {\n            continue;   // maybe only extenders\n        }\n        CGFloat minHeight = minOffset + prev.fullAdvance;\n        CGFloat maxHeight = minHeight + maxDelta * (glyphsRv.count - 1);\n        if (minHeight >= glyphHeight) {\n            // we are done\n            *glyphs = glyphsRv;\n            *offsets = offsetsRv;\n            *height = minHeight;\n            return;\n        } else if (glyphHeight <= maxHeight) {\n            // spread the delta equally between all the connectors\n            CGFloat delta = glyphHeight - minHeight;\n            CGFloat deltaIncrease = delta / (glyphsRv.count - 1);\n            CGFloat lastOffset = 0;\n            for (int i = 0; i < offsetsRv.count; i++) {\n                CGFloat offset = offsetsRv[i].floatValue + i*deltaIncrease;\n                offsetsRv[i] = [NSNumber numberWithFloat:offset];\n                lastOffset = offset;\n            }\n            // we are done\n            *glyphs = glyphsRv;\n            *offsets = offsetsRv;\n            *height = lastOffset + prev.fullAdvance;\n            return;\n        }\n    }\n}\n\n- (CGGlyph) findGlyphForCharacterAtIndex:(NSUInteger) index inString:(NSString*) str\n{\n    // Get the character at index taking into account UTF-32 characters\n    NSRange range = [str rangeOfComposedCharacterSequenceAtIndex:index];\n    unichar chars[range.length];\n    [str getCharacters:chars range:range];\n    \n    // Get the glyph fromt the font\n    CGGlyph glyph[range.length];\n    bool found = CTFontGetGlyphsForCharacters(_styleFont.ctFont, chars, glyph, range\n                                              .length);\n    if (!found) {\n        // the font did not contain a glyph for our character, so we just return 0 (notdef)\n        return 0;\n    }\n    return glyph[0];\n}\n\n#pragma mark Large Operators\n\n- (MTDisplay *)makeBiggerDisplay:(MTMathAtom *)atom\n{\n    if (atom.sizeType != MTSizeTypeDefault && atom.nucleus.length == 1 && atom.sizeType <= MTSizeTypeBigg) {\n        CGFloat ascent, descent, width;\n        CGGlyph glyph = [self findGlyphByDelimiter:atom.nucleus sizeType:atom.sizeType glyphAscent:&ascent glyphDescent:&descent glyphWidth:&width];\n        CGFloat shiftDown = 0.5 * (ascent - descent) - _styleFont.mathTable.axisHeight;\n        CGFloat delta = [_styleFont.mathTable getItalicCorrection:glyph];\n        MTGlyphDisplay *glyphDisplay = [[MTGlyphDisplay alloc] initWithGlpyh:glyph range:atom.indexRange font:_styleFont];\n        glyphDisplay.ascent = ascent;\n        glyphDisplay.descent = descent;\n        glyphDisplay.width = width;\n        glyphDisplay.shiftDown = shiftDown;\n        glyphDisplay.position = _currentPosition;\n        _currentPosition.x += glyphDisplay.width;\n        return glyphDisplay;\n    } else if (atom.sizeType > MTSizeTypeBigg && atom.sizeType <= MTSizeTypeLARGE) {\n        NSMutableAttributedString *line = [[NSMutableAttributedString alloc] initWithString:atom.nucleus];\n        // add the font\n        CGFloat rate = 1;\n        switch (atom.sizeType) {\n            case MTSizeTypeSmall:\n                rate = 0.8;\n                break;\n            case MTSizeTypelarge:\n                rate = 1.2;\n                break;\n            case MTSizeTypeLarge:\n                rate = 1.44;\n                break;\n            case MTSizeTypeLARGE:\n                rate = 1.7;\n                break;\n            default:\n                rate = 1;\n                break;\n        }\n        MTFont *ft = [_styleFont copyFontWithSize: _styleFont.fontSize * rate];\n        [line addAttribute:(NSString *)kCTFontAttributeName value:(__bridge id)(ft.ctFont) range:NSMakeRange(0, line.length)];\n        MTCTLineDisplay* displayAtom = [[MTCTLineDisplay alloc] initWithString:line position:_currentPosition range:atom.indexRange font:ft atoms:@[ atom ]];\n        _currentPosition.x += displayAtom.width;\n        return displayAtom;\n    } else {\n        // Create a regular node\n        NSMutableAttributedString *line = [[NSMutableAttributedString alloc] initWithString:atom.nucleus];\n        // add the font\n        [line addAttribute:(NSString *)kCTFontAttributeName value:(__bridge id)(_styleFont.ctFont) range:NSMakeRange(0, line.length)];\n        MTCTLineDisplay* displayAtom = [[MTCTLineDisplay alloc] initWithString:line position:_currentPosition range:atom.indexRange font:_styleFont atoms:@[ atom ]];\n        _currentPosition.x += displayAtom.width;\n        return displayAtom;\n    }\n}\n\n- (MTDisplay*) makeLargeOp:(MTLargeOperator*) op\n{\n    bool limits = (op.limits && _style == kMTLineStyleDisplay);\n    CGFloat delta = 0;\n    if (op.nucleus.length == 1) {\n        CGGlyph glyph = [self findGlyphForCharacterAtIndex:0 inString:op.nucleus];\n        if (_style == kMTLineStyleDisplay && glyph != 0) {\n            // Enlarge the character in display style.\n            glyph = [_styleFont.mathTable getLargerGlyph:glyph];\n        }\n        // This is be the italic correction of the character.\n        delta = [_styleFont.mathTable getItalicCorrection:glyph];\n        \n        // vertically center\n        CGRect bbox = CTFontGetBoundingRectsForGlyphs(_styleFont.ctFont, kCTFontHorizontalOrientation, &glyph, NULL, 1);\n        CGFloat width = CTFontGetAdvancesForGlyphs(_styleFont.ctFont, kCTFontHorizontalOrientation, &glyph, NULL, 1);\n        CGFloat ascent, descent;\n        getBboxDetails(bbox, &ascent, &descent);\n        CGFloat shiftDown = 0.5*(ascent - descent) - _styleFont.mathTable.axisHeight;\n        MTGlyphDisplay* glyphDisplay = [[MTGlyphDisplay alloc] initWithGlpyh:glyph range:op.indexRange font:_styleFont];\n        glyphDisplay.ascent = ascent;\n        glyphDisplay.descent = descent;\n        glyphDisplay.width = width;\n        if (op.subScript && !limits) {\n            // Remove italic correction from the width of the glyph if\n            // there is a subscript and limits is not set.\n            glyphDisplay.width -= delta;\n        }\n        glyphDisplay.shiftDown = shiftDown;\n        glyphDisplay.position = _currentPosition;\n        return [self addLimitsToDisplay:glyphDisplay forOperator:op delta:delta];\n    } else {\n        // Create a regular node\n        NSMutableAttributedString* line = [[NSMutableAttributedString alloc] initWithString:op.nucleus];\n        // add the font\n        [line addAttribute:(NSString *)kCTFontAttributeName value:(__bridge id)(_styleFont.ctFont) range:NSMakeRange(0, line.length)];\n        MTCTLineDisplay* displayAtom = [[MTCTLineDisplay alloc] initWithString:line position:_currentPosition range:op.indexRange font:_styleFont atoms:@[ op ]];\n        return [self addLimitsToDisplay:displayAtom forOperator:op delta:0];\n    }\n}\n\n- (MTDisplay*) addLimitsToDisplay:(MTDisplay*) display forOperator:(MTLargeOperator*) op delta:(CGFloat)delta\n{\n    // If there is no subscript or superscript, just return the current display\n    if (!op.subScript && !op.superScript) {\n        _currentPosition.x += display.width;\n        return display;\n    }\n    if (op.limits && _style == kMTLineStyleDisplay) {\n        // make limits\n        MTMathListDisplay *superScript = nil, *subScript = nil;\n        if (op.superScript) {\n            superScript = [MTTypesetter createLineForMathList:op.superScript font:_font style:self.scriptStyle cramped:self.superScriptCramped];\n        }\n        if (op.subScript) {\n            subScript = [MTTypesetter createLineForMathList:op.subScript font:_font style:self.scriptStyle cramped:self.subscriptCramped];\n        }\n        NSAssert(superScript || subScript, @\"Atleast one of superscript or subscript should have been present.\");\n        MTLargeOpLimitsDisplay* opsDisplay = [[MTLargeOpLimitsDisplay alloc] initWithNucleus:display upperLimit:superScript lowerLimit:subScript limitShift:delta/2 extraPadding:0];\n        if (superScript) {\n            CGFloat upperLimitGap = MAX(_styleFont.mathTable.upperLimitGapMin, _styleFont.mathTable.upperLimitBaselineRiseMin - superScript.descent);\n            opsDisplay.upperLimitGap = upperLimitGap;\n        }\n        if (subScript) {\n            CGFloat lowerLimitGap = MAX(_styleFont.mathTable.lowerLimitGapMin, _styleFont.mathTable.lowerLimitBaselineDropMin - subScript.ascent);\n            opsDisplay.lowerLimitGap = lowerLimitGap;\n        }\n        opsDisplay.position = _currentPosition;\n        opsDisplay.range = op.indexRange;\n        _currentPosition.x += opsDisplay.width;\n        return opsDisplay;\n    } else {\n        _currentPosition.x += display.width;\n        [self makeScripts:op display:display index:op.indexRange.location delta:delta];\n        return display;\n    }\n}\n\n#pragma mark Large delimiters\n\n- (MTDisplay*) findGlyphForBoundary:(NSString*) delimiter withHeight:(CGFloat) glyphHeight\n{\n    CGFloat glyphAscent, glyphDescent, glyphWidth;\n    CGGlyph leftGlyph = [self findGlyphForCharacterAtIndex:0 inString:delimiter];\n    CGGlyph glyph = [self findGlyph:leftGlyph withHeight:glyphHeight glyphAscent:&glyphAscent glyphDescent:&glyphDescent glyphWidth:&glyphWidth];\n    \n    MTDisplay<DownShift>* glyphDisplay;\n    if (glyphAscent + glyphDescent < glyphHeight) {\n        // we didn't find a pre-built glyph that is large enough\n        glyphDisplay = [self constructGlyph:leftGlyph withHeight:glyphHeight];\n    }\n    \n    if (!glyphDisplay) {\n        // Create a glyph display\n        glyphDisplay = [[MTGlyphDisplay alloc] initWithGlpyh:glyph range:NSMakeRange(NSNotFound, 0) font:_styleFont];\n        glyphDisplay.ascent = glyphAscent;\n        glyphDisplay.descent = glyphDescent;\n        glyphDisplay.width = glyphWidth;\n    }\n    // Center the glyph on the axis\n    CGFloat shiftDown = 0.5*(glyphDisplay.ascent - glyphDisplay.descent) - _styleFont.mathTable.axisHeight;\n    glyphDisplay.shiftDown = shiftDown;\n    return glyphDisplay;\n}\n\n#pragma mark Underline/Overline\n\n- (MTDisplay*) makeUnderline:(MTUnderLine*) under\n{\n    MTMathListDisplay* innerListDisplay = [MTTypesetter createLineForMathList:under.innerList font:_font style:_style cramped:_cramped];\n    MTLineDisplay* underDisplay = [[MTLineDisplay alloc] initWithInner:innerListDisplay position:_currentPosition range:under.indexRange];\n    // Move the line down by the vertical gap.\n    underDisplay.lineShiftUp = -(innerListDisplay.descent + _styleFont.mathTable.underbarVerticalGap);\n    underDisplay.lineThickness = _styleFont.mathTable.underbarRuleThickness;\n    underDisplay.ascent = innerListDisplay.ascent;\n    underDisplay.descent = innerListDisplay.descent + _styleFont.mathTable.underbarVerticalGap + _styleFont.mathTable.underbarRuleThickness + _styleFont.mathTable.underbarExtraDescender;\n    underDisplay.width = innerListDisplay.width;\n    return underDisplay;\n}\n\n- (MTDisplay*) makeOverline:(MTOverLine*) over\n{\n    MTMathListDisplay* innerListDisplay = [MTTypesetter createLineForMathList:over.innerList font:_font style:_style cramped:YES];\n    MTLineDisplay* overDisplay = [[MTLineDisplay alloc] initWithInner:innerListDisplay position:_currentPosition range:over.indexRange];\n    overDisplay.useArrow = over.useArrow;\n    overDisplay.lineShiftUp = innerListDisplay.ascent + _styleFont.mathTable.overbarVerticalGap;\n    overDisplay.lineThickness = _styleFont.mathTable.underbarRuleThickness;\n    overDisplay.ascent = innerListDisplay.ascent + _styleFont.mathTable.overbarVerticalGap + _styleFont.mathTable.overbarRuleThickness + _styleFont.mathTable.overbarExtraAscender;\n    overDisplay.descent = innerListDisplay.descent;\n    overDisplay.width = innerListDisplay.width;\n    return overDisplay;\n}\n\n/// Hline\n- (MTHLineDisplay *) makeHline:(MTHLine*) hline\n{\n    MTHLineDisplay *hlineDisplay = [[MTHLineDisplay alloc] initWithPosition:_currentPosition];\n    hlineDisplay.lineHeight = 0.8;\n    return hlineDisplay;\n}\n\n- (MTDisplay *) makeOverbrace:(MTOverbrace *)overbrace\n{\n    CGFloat scriptFontSize = [[self class] getStyleSize:self.scriptStyle font:_font];\n    MTFont* scriptFont = [_font copyFontWithSize:scriptFontSize];\n    MTMathListDisplay* contentorDisplay = [MTTypesetter createLineForMathList:overbrace.contentor font:_font style:_style cramped:false];\n    MTMathListDisplay* labelorDisplay = [MTTypesetter createLineForMathList:overbrace.labelor font:scriptFont style:_style cramped:false];\n    \n    MTOverbraceDisplay* overDisplay = [[MTOverbraceDisplay alloc] initWithOverbraceContentor:contentorDisplay labelor:labelorDisplay position:_currentPosition];\n    overDisplay.ascent = labelorDisplay.ascent + contentorDisplay.ascent;\n    overDisplay.descent = labelorDisplay.descent + contentorDisplay.descent + 16;\n    \n    CGFloat maxWidth = MAX(contentorDisplay.width, labelorDisplay.width);\n    overDisplay.width = maxWidth < 20 ? 20 : maxWidth;\n    overDisplay.labelorOffsetY = labelorDisplay.ascent;\n    overDisplay.contentorOffsetY = 16;\n    return overDisplay;\n}\n\n- (MTDisplay *) makeUnderbrace:(MTUnderbrace *)underbrace\n{\n    CGFloat scriptFontSize = [[self class] getStyleSize:self.scriptStyle font:_font];\n    MTFont* scriptFont = [_font copyFontWithSize:scriptFontSize];\n    MTMathListDisplay* contentorDisplay = [MTTypesetter createLineForMathList:underbrace.contentor font:_font style:_style cramped:false];\n    MTMathListDisplay* labelorDisplay = [MTTypesetter createLineForMathList:underbrace.labelor font:scriptFont style:_style cramped:false];\n    MTUnderbraceDisplay* underDisplay = [[MTUnderbraceDisplay alloc] initWithUnderbraceContentor:contentorDisplay labelor:labelorDisplay position:_currentPosition];\n    underDisplay.ascent = labelorDisplay.ascent + contentorDisplay.ascent;\n    underDisplay.descent = labelorDisplay.descent + contentorDisplay.descent + 22;\n    CGFloat maxWidth = MAX(contentorDisplay.width, labelorDisplay.width);\n    underDisplay.width = maxWidth < 20 ? 20 : maxWidth;\n    underDisplay.labelorOffsetY = 17;\n    underDisplay.contentorOffsetY = 4;\n    return underDisplay;\n}\n\n#pragma mark Accents\n\n- (BOOL) isSingleCharAccentee:(MTAccent*) accent\n{\n    if (accent.innerList.atoms.count != 1) {\n        // Not a single char list.\n        return 0;\n    }\n    MTMathAtom* innerAtom = accent.innerList.atoms[0];\n    if (innerAtom.nucleus.unicodeLength != 1) {\n        // A complex atom, not a simple char.\n        return NO;\n    }\n    if (innerAtom.subScript || innerAtom.superScript) {\n        return NO;\n    }\n    return YES;\n}\n\n// The distance the accent must be moved from the beginning.\n- (CGFloat) getSkew:(MTAccent*) accent accenteeWidth:(CGFloat) width accentGlyph:(CGGlyph) accentGlyph\n{\n    if (accent.nucleus.length == 0) {\n        // No accent\n        return 0;\n    }\n    CGFloat accentAdjustment = [_styleFont.mathTable getTopAccentAdjustment:accentGlyph];\n    CGFloat accenteeAdjustment = 0;\n    if (![self isSingleCharAccentee:accent]) {\n        // use the center of the accentee\n        accenteeAdjustment = width/2;\n    } else {\n        MTMathAtom* innerAtom = accent.innerList.atoms[0];\n        CGGlyph accenteeGlyph = [self findGlyphForCharacterAtIndex:innerAtom.nucleus.length - 1 inString:innerAtom.nucleus];\n        accenteeAdjustment = [_styleFont.mathTable getTopAccentAdjustment:accenteeGlyph];\n    }\n    // The adjustments need to aligned, so skew is just the difference.\n    return (accenteeAdjustment - accentAdjustment);\n}\n\n// Find the largest horizontal variant if exists, with width less than max width.\n- (CGGlyph) findVariantGlyph:(CGGlyph) glyph withMaxWidth:(CGFloat) maxWidth glyphAscent:(CGFloat*) glyphAscent glyphDescent:(CGFloat*) glyphDescent glyphWidth:(CGFloat*) glyphWidth\n{\n    NSArray<NSNumber*>* variants = [_styleFont.mathTable getHorizontalVariantsForGlyph:glyph];\n    CFIndex numVariants = variants.count;\n    NSAssert(numVariants > 0, @\"A glyph is always it's own variant, so number of variants should be > 0\");\n    CGGlyph glyphs[numVariants];\n    for (CFIndex i = 0; i < numVariants; i++) {\n        CGGlyph glyph = [variants[i] shortValue];\n        glyphs[i] = glyph;\n    }\n    \n    CGGlyph curGlyph = glyphs[0];  // if no other glyph is found, we'll return the first one.\n    CGRect bboxes[numVariants];\n    CGSize advances[numVariants];\n    // Get the bounds for these glyphs\n    CTFontGetBoundingRectsForGlyphs(_styleFont.ctFont, kCTFontHorizontalOrientation, glyphs, bboxes, numVariants);\n    CTFontGetAdvancesForGlyphs(_styleFont.ctFont, kCTFontHorizontalOrientation, glyphs, advances, numVariants);\n    for (int i = 0; i < numVariants; i++) {\n        CGRect bounds = bboxes[i];\n        CGFloat ascent, descent;\n        CGFloat width = CGRectGetMaxX(bounds);\n        getBboxDetails(bounds, &ascent, &descent);\n        \n        if (width > maxWidth) {\n            if (i == 0) {\n                // glyph dimensions are not yet set\n                *glyphWidth = advances[i].width;\n                *glyphAscent = ascent;\n                *glyphDescent = descent;\n            }\n            return curGlyph;\n        } else {\n            curGlyph = glyphs[i];\n            *glyphWidth = advances[i].width;\n            *glyphAscent = ascent;\n            *glyphDescent = descent;\n        }\n    }\n    // We exhausted all the variants and none was larger than the width, so we return the largest\n    return curGlyph;\n}\n\n- (MTDisplay*) makeAccent:(MTAccent*) accent\n{\n    MTMathListDisplay* accentee = [MTTypesetter createLineForMathList:accent.innerList font:_font style:_style cramped:YES];\n    if (accent.nucleus.length == 0) {\n        // no accent!\n        return accentee;\n    }\n    CGGlyph accentGlyph = [self findGlyphForCharacterAtIndex:accent.nucleus.length - 1 inString:accent.nucleus];\n    CGFloat accenteeWidth = accentee.width;\n    CGFloat glyphAscent, glyphDescent, glyphWidth;\n    accentGlyph = [self findVariantGlyph:accentGlyph withMaxWidth:accenteeWidth glyphAscent:&glyphAscent glyphDescent:&glyphDescent glyphWidth:&glyphWidth];\n    CGFloat delta = MIN(accentee.ascent, _styleFont.mathTable.accentBaseHeight);\n    \n    CGFloat skew = [self getSkew:accent accenteeWidth:accenteeWidth accentGlyph:accentGlyph];\n    CGFloat height = accentee.ascent - delta;  // This is always positive since delta <= height.\n    CGPoint accentPosition = CGPointMake(skew, height);\n    MTGlyphDisplay* accentGlyphDisplay = [[MTGlyphDisplay alloc] initWithGlpyh:accentGlyph range:accent.indexRange font:_styleFont];\n    accentGlyphDisplay.ascent = glyphAscent;\n    accentGlyphDisplay.descent = glyphDescent;\n    accentGlyphDisplay.width = glyphWidth;\n    accentGlyphDisplay.position = accentPosition;\n    \n    if ([self isSingleCharAccentee:accent] && (accent.subScript || accent.superScript)) {\n        // Attach the super/subscripts to the accentee instead of the accent.\n        MTMathAtom* innerAtom = accent.innerList.atoms[0];\n        innerAtom.superScript = accent.superScript;\n        innerAtom.subScript = accent.subScript;\n        accent.superScript = nil;\n        accent.subScript = nil;\n        // Remake the accentee (now with sub/superscripts)\n        // Note: Latex adjusts the heights in case the height of the char is different in non-cramped mode. However this shouldn't be the case since cramping\n        // only affects fractions and superscripts. We skip adjusting the heights.\n        accentee = [MTTypesetter createLineForMathList:accent.innerList font:_font style:_style cramped:_cramped];\n    }\n    \n    MTAccentDisplay* display = [[MTAccentDisplay alloc] initWithAccent:accentGlyphDisplay accentee:accentee range:accent.indexRange];\n    display.width = accentee.width;\n    display.descent = accentee.descent;\n    CGFloat ascent = accentee.ascent - delta + glyphAscent;\n    display.ascent = MAX(accentee.ascent, ascent);\n    display.position = _currentPosition;\n    \n    return display;\n}\n\n#pragma mark - Table\n\nstatic const CGFloat kBaseLineSkipMultiplier = 1.2;  // default base line stretch is 12 pt for 10pt font.\nstatic const CGFloat kLineSkipMultiplier = 0.1;  // default is 1pt for 10pt font.\nstatic const CGFloat kLineSkipLimitMultiplier = 0;\nstatic const CGFloat kJotMultiplier = 0.3; // A jot is 3pt for a 10pt font.\n\n- (MTDisplay*) makeTable:(MTMathTable*) table\n{\n    NSUInteger numColumns = table.numColumns;\n    if (numColumns == 0 || table.numRows == 0) {\n        // Empty table\n        return [[MTMathListDisplay alloc] initWithDisplays:[NSArray array] range:table.indexRange];\n    }\n    \n    CGFloat columnWidths[numColumns];\n    // NOTE: Using memset to initialize columnWidths array avoids\n    // Xcode Analyze \"Assigned value is garbage or undefined\".\n    // https://stackoverflow.com/questions/21191194/analyzer-warning-assigned-value-is-garbage-or-undefined\n    memset(columnWidths, 0, sizeof(columnWidths));\n    NSArray<NSArray<MTDisplay*>*>* displays = [self typesetCells:table columnWidths:columnWidths];\n    \n    // Position all the columns in each row\n    NSMutableArray<MTDisplay*>* rowDisplays = [NSMutableArray arrayWithCapacity:table.cells.count];\n    for (NSArray<MTDisplay*>* row in displays) {\n        MTMathListDisplay* rowDisplay = [self makeRowWithColumns:row forTable:table columnWidths:columnWidths];\n        if (rowDisplay) {\n            [rowDisplays addObject:rowDisplay];\n        }\n    }\n    // Position all the rows\n    [self positionRows:rowDisplays forTable:table];\n    MTMathListDisplay* tableDisplay = [[MTMathListDisplay alloc] initWithDisplays:rowDisplays range:table.indexRange];\n    tableDisplay.position = _currentPosition;\n    return tableDisplay;\n}\n\n// Typeset every cell in the table. As a side-effect calculate the max column width of each column.\n- (NSArray<NSArray<MTDisplay*>*>*) typesetCells:(MTMathTable*) table columnWidths:(CGFloat[]) columnWidths\n{\n    NSMutableArray<NSMutableArray<MTDisplay*>*> *displays = [NSMutableArray arrayWithCapacity:table.numRows];\n    \n    for(NSArray<MTMathList*>* row in table.cells) {\n        NSMutableArray<MTDisplay*>* colDisplays = [NSMutableArray arrayWithCapacity:row.count];\n        [displays addObject:colDisplays];\n        for (int i = 0; i < row.count; i++) {\n            MTMathListDisplay* disp = [MTTypesetter createLineForMathList:row[i] font:_font style:_style cramped:NO];\n            columnWidths[i] = MAX(disp.width, columnWidths[i]);\n            [colDisplays addObject:disp];\n        };\n    };\n    return displays;\n}\n\n- (MTMathListDisplay*) makeRowWithColumns:(NSArray<MTDisplay*>*) cols forTable:(MTMathTable*) table columnWidths:(CGFloat[]) columnWidths\n{\n    BOOL lastHline = NO;\n    if (cols.count < table.alignments.count) {\n        if (cols.count == 1) {\n            for (MTMathListDisplay *dislist in cols) {\n                for (MTDisplay *subDis in dislist.subDisplays) {\n                    if (![subDis isKindOfClass:[MTHLineDisplay class]]) {\n                        return nil;\n                    } else {\n                        lastHline = YES;\n                    }\n                }\n            }\n        } else {\n            return nil;\n        }\n    }\n    CGFloat columnStart = 0;\n    NSRange rowRange = NSMakeRange(NSNotFound, 0);\n    MTMathList *config = table.envConfig;\n    NSMutableArray<MTMathAtom *> *atoms = [[NSMutableArray alloc] initWithCapacity:cols.count];\n    CGFloat offsetRight = 0;\n    if ([config.atoms.firstObject.nucleus isEqualToString:@\"|\"]) {\n        offsetRight = table.interColumnSpacing * _styleFont.mathTable.muUnit / 2;\n    }\n    for (MTMathAtom *atom in config.atoms) {\n        if ([@\"clr\" containsString:atom.nucleus]) {\n            [atoms addObject:atom];\n        }\n    }\n    for (int i = 0; i < cols.count; i++) {\n        MTDisplay* col = cols[i];\n        unichar ch = [i < atoms.count ? atoms[i].nucleus : @\"c\" characterAtIndex:0];\n        CGFloat colWidth =  columnWidths[i];\n        MTColumnAlignment alignment = [table getAlignmentForColumn:i];\n        if (ch == 'c') {\n            alignment = kMTColumnAlignmentCenter;\n        } else if (ch == 'l') {\n            alignment = kMTColumnAlignmentLeft;\n        } else if (ch == 'r') {\n            alignment = kMTColumnAlignmentRight;\n        }\n        CGFloat cellPos = columnStart + offsetRight;\n        switch (alignment) {\n            case kMTColumnAlignmentRight:\n                cellPos += colWidth - col.width;\n                break;\n            case kMTColumnAlignmentCenter:\n                cellPos += (colWidth - col.width) / 2;\n                break;\n                \n            case kMTColumnAlignmentLeft:\n                // No changes if left aligned\n                break;\n        }\n        if (rowRange.location != NSNotFound) {\n            rowRange = NSUnionRange(rowRange, col.range);\n        } else {\n            rowRange = col.range;\n        }\n        col.position = CGPointMake(cellPos, 0);\n        columnStart += colWidth + table.interColumnSpacing * _styleFont.mathTable.muUnit;\n    };\n    table.tableWidth = MAX(table.tableWidth, columnStart);\n    // 只有hline的行不增加sep\n    NSArray *separators = !lastHline && YES ? [self makeSeparatorsforTable:table colCount:cols.count  columnWidths:columnWidths] : @[];\n    // Create a display for the row\n    MTMathListDisplay* rowDisplay = [[MTMathListDisplay alloc] initWithDisplays:[cols arrayByAddingObjectsFromArray:separators] range:rowRange];\n    return rowDisplay;\n}\n\n- (NSArray<MTSeparatorDisplay *> *) makeSeparatorsforTable:(MTMathTable*) table colCount:(NSUInteger)colCount columnWidths:(CGFloat[]) columnWidths\n{\n    CGFloat columnStart = 0;\n    NSMutableArray *colls = [[NSMutableArray alloc] init];\n    MTMathList *config = table.envConfig;\n    NSArray<MTMathAtom *> *atoms = config ? config.atoms : @[];\n    CGFloat firstLeft = table.interColumnSpacing * _styleFont.mathTable.muUnit / 2;\n    if ([atoms.firstObject.nucleus isEqualToString:@\"|\"]) {\n        firstLeft = 0;\n    }\n    int separatorOffset = 0;\n    for (int i = 0; i < atoms.count; i++) {\n        int j = i - separatorOffset;\n        unichar ch = [config.atoms[i].nucleus characterAtIndex:0];\n        if (separatorOffset > colCount) {\n            break;\n        }\n        if (ch == '|') {\n            MTSeparatorDisplay *line = [[MTSeparatorDisplay alloc] initWithRect:CGRectMake(columnStart, 0, 1, 1) color:UIColor.blackColor];\n            columnStart += 1;\n            [colls addObject:line];\n            separatorOffset += 1;\n        } else {\n            CGFloat colWidth = columnWidths[j];\n            if (colWidth < 0.01) {\n                break;\n            }\n            columnStart += colWidth + table.interColumnSpacing * _styleFont.mathTable.muUnit - (i==0 ? firstLeft : 0);\n        }\n        table.tableWidth = MAX(table.tableWidth, columnStart);\n    };\n    return colls;\n}\n\n- (void) positionRows:(NSArray<MTDisplay*>*) rows forTable:(MTMathTable*) table\n{\n    // Position the rows\n    // We will first position the rows starting from 0 and then in the second pass center the whole table vertically.\n    CGFloat currPos = 0;\n    CGFloat openup = table.interRowAdditionalSpacing * kJotMultiplier * _styleFont.fontSize;\n    CGFloat baselineSkip = openup + kBaseLineSkipMultiplier * _styleFont.fontSize;\n    CGFloat lineSkip = openup + kLineSkipMultiplier * _styleFont.fontSize;\n    CGFloat lineSkipLimit = openup + kLineSkipLimitMultiplier * _styleFont.fontSize;\n    CGFloat prevRowDescent = 0;\n    CGFloat ascent = 0;\n    BOOL first = true;\n    for (MTDisplay* row in rows) {\n        if (first) {\n            row.position = CGPointZero;\n            ascent += row.ascent;\n            first = false;\n        } else {\n            CGFloat skip = baselineSkip;\n            if (skip - (prevRowDescent + row.ascent) < lineSkipLimit) {\n                // rows are too close to each other. Space them apart further\n                skip = prevRowDescent + row.ascent + lineSkip;\n            }\n            // We are going down so we decrease the y value.\n            currPos -= skip;\n            row.position = CGPointMake(0, currPos);\n        }\n        prevRowDescent = row.descent;\n    }\n    BOOL firstIsSeparator = (table.envConfig != nil && table.envConfig.atoms.count > 0) ? [table.envConfig.atoms.firstObject.nucleus isEqualToString:@\"|\"] : NO;\n    // Vertically center the whole structure around the axis\n    // The descent of the structure is the position of the last row\n    // plus the descent of the last row.\n    CGFloat descent =  - currPos + prevRowDescent;\n    CGFloat shiftDown = 0.5*(ascent - descent) - _styleFont.mathTable.axisHeight;\n    CGFloat lastBottom = 0;\n    CGFloat lastDescent = 0;\n    CGFloat lastAsent = 0;\n    NSUInteger idx = 0;\n    for (MTDisplay* row in rows) {\n        row.position = CGPointMake(row.position.x, row.position.y - shiftDown);\n        lastBottom = row.position.y - shiftDown - baselineSkip;\n        if ([row isKindOfClass:[MTMathListDisplay class]]) {\n            for (MTDisplay*item in [(MTMathListDisplay *)row subDisplays]) {\n                if ([item isKindOfClass:[MTSeparatorDisplay class]]) {\n                    [(MTSeparatorDisplay *)item setSepLen: baselineSkip + row.ascent + row.descent];\n                    [(MTSeparatorDisplay *)item setBottomY: _styleFont.mathTable.axisHeight * 2];\n                }\n                if ([item isKindOfClass:[MTMathListDisplay class]]) {\n                    for (MTDisplay *subdis in [(MTMathListDisplay *)item subDisplays]) {\n                        if ([subdis isKindOfClass:[MTHLineDisplay class]]) {\n                            MTHLineDisplay *hline = (MTHLineDisplay *)subdis;\n                            hline.width = firstIsSeparator ? table.tableWidth + table.interColumnSpacing * _styleFont.mathTable.muUnit / 2 : table.tableWidth;\n                            // first line\n                            if (idx == 0) {\n                                hline.position = CGPointMake(row.position.x - table.interColumnSpacing * _styleFont.mathTable.muUnit / (firstIsSeparator ? 1 : 2), row.ascent);\n                            // last line\n                            } else if (idx == rows.count - 1 && rows.count > 2) {\n                                hline.position = CGPointMake(row.position.x - table.interColumnSpacing * _styleFont.mathTable.muUnit / (firstIsSeparator ? 1 : 2), baselineSkip / 2 + _styleFont.mathTable.axisHeight);\n                            } else {\n                                hline.position = CGPointMake(row.position.x - table.interColumnSpacing * _styleFont.mathTable.muUnit / (firstIsSeparator ? 1 : 2), row.ascent + _styleFont.mathTable.axisHeight + lastDescent / 3 + 1);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        idx += 1;\n        lastDescent = row.descent;\n        lastAsent = row.ascent;\n    }\n}\n\n#pragma mark inner\n\n// Delimiter shortfall from plain.tex\nstatic const NSInteger kDelimiterFactor = 901;\nstatic const NSInteger kDelimiterShortfallPoints = 5;\n\n- (MTInnerDisplay*) makeInner:(MTInner*) inner atIndex:(NSUInteger) index\n{\n  NSAssert(inner.leftBoundary || inner.rightBoundary, @\"Inner should have a boundary to call this function\");\n  \n  MTMathListDisplay* innerListDisplay = [MTTypesetter createLineForMathList:inner.innerList font:_font style:_style cramped:_cramped];\n  CGFloat axisHeight = _styleFont.mathTable.axisHeight;\n  // delta is the max distance from the axis\n  CGFloat delta = MAX(innerListDisplay.ascent - axisHeight, innerListDisplay.descent + axisHeight);\n  CGFloat d1 = (delta / 500) * kDelimiterFactor;  // This represents atleast 90% of the formula\n  CGFloat d2 = 2 * delta - kDelimiterShortfallPoints;  // This represents a shortfall of 5pt\n  // The size of the delimiter glyph should cover at least 90% of the formula or\n  // be at most 5pt short.\n  CGFloat glyphHeight = MAX(d1, d2);\n  \n  MTDisplay* leftDelimiter = nil;\n  if (inner.leftBoundary && inner.leftBoundary.nucleus.length > 0) {\n    MTDisplay* leftGlyph = [self findGlyphForBoundary:inner.leftBoundary.nucleus withHeight:glyphHeight];\n    if (leftGlyph) {\n      leftDelimiter = leftGlyph;\n    }\n  }\n  \n  MTDisplay* rightDelimiter = nil;\n  if (inner.rightBoundary && inner.rightBoundary.nucleus.length > 0) {\n    MTDisplay* rightGlyph = [self findGlyphForBoundary:inner.rightBoundary.nucleus withHeight:glyphHeight];\n    if (rightGlyph) {\n      rightDelimiter = rightGlyph;\n    }\n  }\n\n  MTInnerDisplay* innerDisplay = [[MTInnerDisplay alloc] initWithInner:innerListDisplay leftDelimiter:leftDelimiter rightDelimiter:rightDelimiter atIndex: index];\n  \n  return innerDisplay;\n}\n\n- (MTAdaptiveDisplay *)makeAdaptive:(MTAdaptive *)adaptive\n{\n    NSAssert(adaptive.boundary, @\"adaptive should have a boundary to call this function\");\n    CGFloat max_ascent = 0;\n    CGFloat max_descent = 0;\n    for (MTDisplay* atom in _displayAtoms) {\n        CGFloat ascent = MAX(0, atom.position.y + atom.ascent);\n        if (ascent > max_ascent) {\n            max_ascent = ascent;\n        }\n        \n        CGFloat descent = MAX(0, 0 - (atom.position.y - atom.descent));\n        if (descent > max_descent) {\n            max_descent = descent;\n        }\n    }\n    \n    CGFloat axisHeight = _styleFont.mathTable.axisHeight;\n    // delta is the max distance from the axis\n    CGFloat delta = MAX(max_ascent - axisHeight, max_descent + axisHeight);\n    CGFloat d1 = (delta / 500) * kDelimiterFactor;  // This represents atleast 90% of the formula\n    CGFloat d2 = 2 * delta - kDelimiterShortfallPoints;  // This represents a shortfall of 5pt\n    // The size of the delimiter glyph should cover at least 90% of the formula or\n    // be at most 5pt short.\n    CGFloat glyphHeight = MAX(d1, d2);\n    \n    MTDisplay* delimiter = nil;\n    if (adaptive.boundary && adaptive.boundary.nucleus.length > 0) {\n        MTDisplay* glyph = [self findGlyphForBoundary:adaptive.boundary.nucleus withHeight:glyphHeight];\n        if (glyph) {\n            delimiter = glyph;\n        }\n    }\n    \n    MTAdaptiveDisplay *display = [[MTAdaptiveDisplay alloc] initWithDelimiter:delimiter range:adaptive.indexRange];\n    \n    return display;\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMAttributedStringRenderer.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n\n#import <AntMarkdown/AMTextStyles.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMAttributedStringRenderer : CMAttributedStringRenderer\n@property (readonly) AMTextStyles *attributes;\n\n- (instancetype)initWithDocument:(CMDocument *)document attributes:(AMTextStyles *)attributes;\n\n- (instancetype)initWithDocument:(CMDocument *)document attributes:(AMTextStyles *)attributes delegate:(nullable id<CMAttributedStringRendererDelegate>)delegate;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMAttributedStringRenderer.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMAttributedStringRenderer.h\"\n#import \"CMNode+Table.h\"\n#import \"CMAttributedStringRenderer_Private.h\"\n\n#import \"AMTextStyles.h\"\n#import \"AMInlineMathAttachment.h\"\n#import \"AMBlockMathAttachment.h\"\n#import \"AMTableViewAttachment.h\"\n#import \"AMCodeViewAttachment.h\"\n#import \"AMImageTextAttachment.h\"\n#import \"AMIconAttachment.h\"\n#import \"AMHTMLTransformer.h\"\n#import \"AMUtils.h\"\n#import \"CMHTMLElement.h\"\n#import \"CMAttributeRun.h\"\n\n@implementation AMAttributedStringRenderer\n{\n    struct {\n        unsigned int isInTable:1;\n        unsigned int isInTableRow:1;\n        unsigned int isInTableCell:1;\n    } _flags;\n    \n    NSMutableArray<CMTableCell *> * _tableCells;\n    CMTable * _currentTable;\n    NSInteger   _listLevel;\n    NSInteger   _orderListLevel;\n    NSInteger   _unorderListLevel;\n    NSInteger  _parsingNodeType;// 1:order;2:unorder;\n    CMStack*     _indentStack;\n    CMImageTextAttachment* _currentImageAttachment;\n    CGFloat _listItemExtraIndent;\n}\n@dynamic attributes;\n\n- (instancetype)initWithDocument:(CMDocument *)document attributes:(AMTextStyles *)attributes\n{\n    self = [super initWithDocument:document attributes:attributes];\n    if (self) {\n        [self init:attributes];\n    }\n    return self;\n}\n- (instancetype)initWithDocument:(CMDocument *)document attributes:(AMTextStyles *)attributes delegate:(nullable id<CMAttributedStringRendererDelegate>)delegate\n{\n    self = [super initWithDocument:document attributes:attributes delegate:delegate];\n    if (self) {\n        [self init:attributes];\n    }\n    return self;\n}\n-(void)init:(AMTextStyles *)attributes {\n    [self registerHTMLElementTransformer:[[CMHTMLStrikethroughTransformer alloc] init]];\n    [self registerHTMLElementTransformer:[[CMHTMLSuperscriptTransformer alloc] init]];\n    [self registerHTMLElementTransformer:[[CMHTMLSubscriptTransformer alloc] init]];\n    [self registerHTMLElementTransformer:[[AMHTMLMarkTransformer alloc] initWithStyles:attributes]];\n    [self registerHTMLElementTransformer:[[AMHTMLSpanTransformer alloc] initWithStyles:attributes]];\n    [self registerHTMLElementTransformer:[[AMHTMLCiteTransformer alloc] initWithStyles:attributes]];\n    [self registerHTMLElementTransformer:[[AMHTMLDelTransformer alloc] initWithStyles:attributes]];\n    [self registerHTMLElementTransformer:[[AMHTMLFontTransformer alloc] initWithStyles:attributes]];\n    UIColor* underlineColor = attributes.underlineAttributes.stringAttributes[NSForegroundColorAttributeName] ? : [UIColor colorWithHex_ant_mark:0x521677FF];\n\n    CGFloat underLineWidth = attributes.underlineAttributes.stringAttributes[@\"lineWidth\"] ? [attributes.underlineAttributes.stringAttributes[@\"lineWidth\"] floatValue] : 6;\n    CGFloat underlineOffset = attributes.underlineAttributes.stringAttributes[@\"lineOffset\"] ? [attributes.underlineAttributes.stringAttributes[@\"lineOffset\"] floatValue] : 4;\n    [self registerHTMLElementTransformer:[[AMHTMLUnderlineTransformer alloc] initWithStyle:NSUnderlineStyleThick\n                                                                                     color:underlineColor\n                                                                                 lineWidth:underLineWidth\n                                                                                    offset:underlineOffset]];\n    [self registerHTMLElementTransformer:[[AMHTMLImgTransformer alloc] initWithStyles:attributes]];\n    [self registerHTMLElementTransformer:[[AMHTMLIconLinkTransformer alloc] initWithStyles:attributes]];\n    [self registerHTMLElementTransformer:[[AMHTMLIconTransformer alloc] initWithStyles:attributes]];\n    [attributes.elementTransformers enumerateObjectsUsingBlock:^(id<CMHTMLElementTransformer>  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {\n        [self registerHTMLElementTransformer:obj];\n    }];\n}\n- (NSTextAttachment *)imageAttachmentWithURL:(NSURL *)url title:(NSString *)title\n{\n    return [[AMImageTextAttachment alloc] initWithImageURL:url title:title];\n}\n\n- (void)appendString:(NSString *)string {\n    if (_tableCellBuffer) {\n        NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:string\n                                                                         attributes:self.attributeStack.cascadedAttributes];\n        [_tableCellBuffer appendAttributedString:attrString];\n    } else {\n        [super appendString:string];\n    }\n}\n\n- (void)appendAttributedString:(NSAttributedString *)attributedString {\n    if (_tableCellBuffer) {\n        [_tableCellBuffer appendAttributedString:attributedString];\n    } else {\n        [self.buffer appendAttributedString:attributedString];\n    }\n}\n\n- (void)appendBulletString:(NSString *)string\n{\n    if([string length] == 0)\n        return;\n    CMStyleAttributes *attr = self.attributes.listBulletAttributes;\n    if (attr) {\n        [self.attributeStack pushAttributes:self.attributes.listBulletAttributes];\n    }\n    [self appendString:string];\n    if (attr) {\n        [self.attributeStack pop];\n    }\n}\n\n@end\n\n@implementation AMAttributedStringRenderer (Parser)\n\n- (void)parserDidEndDocument:(CMParser *)parser\n{\n    if ([_buffer.mutableString hasPrefix:@\"\\t\"])\n    {\n        [super parserDidEndDocument:parser];\n        [_buffer.mutableString insertString:@\"\\t\" atIndex:0];\n    }\n    else if ([_buffer.mutableString hasPrefix:@\"\\u00A0\"])\n    {\n        NSAttributedString* spaceStr = [_buffer attributedSubstringFromRange:NSMakeRange(0, 1)];\n        [super parserDidEndDocument:parser];\n        [_buffer insertAttributedString:spaceStr atIndex:0];\n    }\n    else\n    {\n        [super parserDidEndDocument:parser];\n    }\n}\n\n- (void)parser:(CMParser *)parser foundText:(NSString *)text\n{\n    [super parser:parser foundText:text];\n    \n    // An image description text shall be set alt property\n    if (CMNodeTypeImage == parser.currentNode.parent.type)\n    {\n        if(_currentImageAttachment)\n        {\n            _currentImageAttachment.altText = text;\n        }\n    }\n}\n\n- (void)parser:(CMParser *)parser foundInlineMath:(NSString *)code {\n    AMMathStyle *style = [AMMathStyle defaultStyle];\n    NSDictionary<NSString *, id> *attributes = self.attributeStack.cascadedAttributes;\n    if ([attributes[NSFontAttributeName] isKindOfClass:[UIFont class]]) {\n        style.font = ((UIFont *)attributes[NSFontAttributeName]);\n    }\n    if ([attributes[NSForegroundColorAttributeName] isKindOfClass:[UIColor class]]) {\n        style.textColor = attributes[NSForegroundColorAttributeName];\n    }\n    [self appendAttributedString:[[AMInlineMathAttachment alloc] initWithText:code\n                                                                        style:style].attributedString];\n}\n\n- (void)parser:(CMParser *)parser foundMathBlock:(NSString *)code {\n    AMMathStyle *style = [AMMathStyle defaultBlockStyle];\n    style.horizontalAlignment = UIControlContentHorizontalAlignmentLeft;\n    NSDictionary<NSString *, id> *attributes = self.attributeStack.cascadedAttributes;\n    if ([attributes[NSFontAttributeName] isKindOfClass:[UIFont class]]) {\n        style.font = ((UIFont *)attributes[NSFontAttributeName]);\n    }\n    if ([attributes[NSForegroundColorAttributeName] isKindOfClass:[UIColor class]]) {\n        style.textColor = attributes[NSForegroundColorAttributeName];\n    }\n    \n    [self closeBlockOnly];\n    NSArray<AMBlockMathAttachment *> *mathAttachments = [AMBlockMathAttachment constructorBlockMathAttachmentWithText:code style:style];\n    for (AMBlockMathAttachment *mathAttachment in mathAttachments) {\n        NSMutableAttributedString* mathAttrStr = [mathAttachment.attributedString mutableCopy];\n        if(mathAttrStr.length > 0) {\n            [mathAttrStr addAttribute:NSParagraphStyleAttributeName value:style.paragraphStyle range:NSMakeRange(0, mathAttrStr.length)];\n        }\n        [self appendAttributedString:mathAttrStr];\n        [self closeBlockOnly];\n    }\n}\n\n- (void)closeBlockOnly\n{\n    if (![_buffer.string hasSuffix:@\"\\n\"])\n    {\n        [self appendString:@\"\\n\"];\n    }\n}\n\n- (void)parserDidStartStrikethrough:(CMParser *)parser\n{\n    [self.attributeStack pushAttributes:self.attributes.strikethroughAttributes];\n}\n\n- (void)parserDidEndStrikethrough:(CMParser *)parser\n{\n    [self.attributeStack pop];\n}\n\n- (void)parser:(CMParser *)parser foundCodeBlock:(NSString *)code info:(NSString *)info\n{\n    if ([code hasSuffix:@\"\\n\"]) {\n        code = [code substringToIndex:code.length - 1]; // Remove final \"\\n\"\n    }\n\n    info = [info lowercaseString];\n    \n    NSTextAttachment<AMViewAttachment> * attach = [self.attributes.codeBuilder buildWithCode:code\n                                                                                    language:info\n                                                                                      styles:self.attributes];\n    if (!attach) {\n        attach = [AMCodeViewAttachment attachmentWithCode:code\n                                                 language:info\n                                                   styles:self.attributes];\n    }\n    NSAttributedString *attr = nil;\n    if ([attach respondsToSelector:@selector(attributedString)]) {\n        attr = [attach attributedString];\n    }\n    if (!attr) {\n        attr = [NSAttributedString attributedStringWithAttachment:attach];\n    }\n    \n    [self appendAttributedString:attr];\n}\n\n- (void)parser:(CMParser *)parser foundInlineCode:(NSString *)code\n{\n    [self.attributeStack pushAttributes:_attributes.inlineCodeAttributes];\n    if(code && [code length] > 0)\n    {\n        NSString* codeStr = [NSString stringWithFormat:@\"\\u00A0%@\\u00A0\", code];\n        [self appendString:codeStr];\n        NSDictionary* spaceAttr = @{NSKernAttributeName:@(6),NSFontAttributeName:[UIFont systemFontOfSize:2.f]};\n        [self.buffer addAttributes:spaceAttr range:NSMakeRange(self.buffer.length - codeStr.length, 1)];\n        [self.buffer addAttributes:spaceAttr range:NSMakeRange(self.buffer.length - 1, 1)];\n    }\n    [self.attributeStack pop];\n}\n\n- (void)parser:(CMParser *)parser didStartTableWithNumberOfColumns:(NSUInteger)columns {\n    _flags.isInTable = true;\n    \n    _currentTable = [CMTable tableWithNumberOfColumns:columns];\n    [self.attributeStack pushAttributes:self.attributes.tableCellAttributes];\n}\n\n- (void)parser:(CMParser *)parser didEndTableWithNumberOfColumns:(NSUInteger)columns {\n    _flags.isInTable = false;\n    \n    if (_currentTable) {\n        NSTextAttachment<AMViewAttachment> * attach = [self.attributes.tableBuilder buildWithTable:_currentTable\n                                                                                            styles:self.attributes];\n        if (!attach) {\n            attach = [[AMTableViewAttachment alloc] initWithTable:_currentTable styles:self.attributes];\n        }\n        NSAttributedString *attr = nil;\n        if ([attach respondsToSelector:@selector(attributedString)]) {\n            attr = [attach attributedString];\n        }\n        if (!attr) {\n            attr = [NSAttributedString attributedStringWithAttachment:attach];\n        }\n        \n        [self.buffer appendAttributedString:attr];\n        [self.attributeStack pop];\n        _currentTable = nil;\n    }\n}\n\n- (void)parser:(CMParser *)parser didStartTableRowIsHeader:(BOOL)isHeader {\n    NSAssert(_flags.isInTable, @\"state is error\");\n    _flags.isInTableRow = true;\n    \n    if (isHeader) {\n        [self.attributeStack pushAttributes:self.attributes.tableHeaderAttributes];\n    }\n    [_currentTable push:[CMTableRow rowWithHeader:isHeader]];\n}\n\n- (void)parser:(CMParser *)parser didEndTableRowIsHeader:(BOOL)isHeader {\n    NSAssert(_flags.isInTable, @\"state is error\");\n    _flags.isInTableRow = false;\n    \n    if (isHeader) {\n        [self.attributeStack pop];\n    }\n}\n\n- (void)parser:(CMParser *)parser didStartTableCellWithAlignment:(NSTextAlignment)alignment {\n    NSAssert(_flags.isInTable && _flags.isInTableRow, @\"state is error\");\n    _flags.isInTableCell = true;\n    \n    _tableCellBuffer = [[NSMutableAttributedString alloc] init];\n}\n\n- (void)parser:(CMParser *)parser didEndTableCellWithAlignment:(NSTextAlignment)alignment {\n    NSAssert(_flags.isInTable && _flags.isInTableRow, @\"state is error\");\n    _flags.isInTableCell = false;\n    \n    [_currentTable.peekRow push:[CMTableCell cellWithContent:_tableCellBuffer\n                                                   alignment:alignment]];\n    _tableCellBuffer = nil;\n    \n}\n\n- (void)parser:(CMParser *)parser didStartImageWithURL:(NSURL *)URL title:(NSString *)title\n{\n    _currentImageAttachment = nil;\n    if (self.attributes.imageBuilder) {\n        NSTextAttachment * textAttachment = [self.attributes.imageBuilder buildWithURL:URL\n                                                                                 title:title\n                                                                                styles:self.attributes];\n        if([textAttachment isKindOfClass:[CMImageTextAttachment class]])\n        {\n            _currentImageAttachment = (CMImageTextAttachment*)textAttachment;\n        }\n        \n        NSAttributedString *attr = nil;\n        if ([textAttachment conformsToProtocol:@protocol(AMViewAttachment)] &&\n            [textAttachment respondsToSelector:@selector(attributedString)]) {\n            attr = [(id<AMViewAttachment>)textAttachment attributedString];\n        } else {\n            // Detect if an image has its own paragraph, in which cas we can apply specific attributes.\n            // (Note: This test also detect the case: image in link in paragraph)\n            CMNode* imageNode = parser.currentNode;\n            BOOL isInImageParagraph = ((imageNode.next == nil) && (imageNode.previous == nil)\n                                       && ((imageNode.parent.type == CMNodeTypeParagraph)\n                                           || ((imageNode.parent.next == nil) && (imageNode.parent.previous == nil) && (imageNode.parent.parent.type == CMNodeTypeParagraph))));\n            \n            CMStyleAttributes * imageAttachmentAttributes;\n            if (isInImageParagraph) {\n                imageAttachmentAttributes = _attributes.imageParagraphAttributes.copy;\n            }\n            else {\n                imageAttachmentAttributes = [CMStyleAttributes new];\n            }\n            imageAttachmentAttributes.stringAttributes[NSAttachmentAttributeName] = textAttachment;\n#if !TARGET_OS_IPHONE\n            CMNode *imageDescriptionNode = imageNode.firstChild;\n            if ((imageDescriptionNode.type == CMNodeTypeText) && (imageDescriptionNode.stringValue.length > 0)) {\n                imageAttachmentAttributes.stringAttributes [NSToolTipAttributeName] = imageDescriptionNode.stringValue;\n            }\n#endif\n            [self.attributeStack pushAttributes:imageAttachmentAttributes];\n            \n            const unichar attachmentChar = NSAttachmentCharacter;\n            [self appendString:[NSString stringWithCharacters:&attachmentChar length:1]];\n            \n            if (isInImageParagraph) {\n                [self closeBlockForNode:imageNode];\n            }\n            \n            [self.attributeStack pop];\n        }\n        if (attr) {\n            [self appendAttributedString:attr];\n        }\n        \n    } else {\n        [super parser:parser didStartImageWithURL:URL title:title];\n    }\n}\n\n- (void)parser:(CMParser *)parser didEndImageWithURL:(NSURL *)URL title:(NSString *)title\n{\n    _currentImageAttachment = nil;\n    if (self.attributes.imageBuilder) {\n        // nothing\n    } else {\n        [super parser:parser didEndImageWithURL:URL title:title];\n    }\n    [self addClickableObjects:CMNodeTypeImage data:URL.absoluteString tag:@\"\"];\n}\n\n- (void)parser:(CMParser *)parser didStartFootNoteRefIndex:(NSInteger)index title:(NSString *)title defination:(NSString *)content\n{\n    if (self.attributes.footnoteRefBuilder) {\n        NSAttributedString *attr = [self.attributes.footnoteRefBuilder buildWithReference:content\n                                                                                    title:title\n                                                                                    index:index\n                                                                                   styles:self.attributes];\n        CMHTMLElement *element = [_HTMLStack peek];\n        if (element) {\n            [element.buffer appendString:[NSString stringWithFormat:@\"[^%@]\", content]];\n        }else {\n            if (attr) {\n                [self appendAttributedString:attr];\n            }\n        }\n        \n    } else {\n        CMStyleAttributes *attributes = [self.attributes.footNoteRefAttributes copy];\n        attributes.stringAttributes[NSLinkAttributeName] = [NSString stringWithFormat:@\"#%@\", content];\n        [self.attributeStack pushAttributes:attributes];\n        [self appendString:title];\n    }\n}\n\n- (void)parser:(CMParser *)parser didEndFootNoteRefIndex:(NSInteger)index title:(NSString *)title defination:(NSString *)content\n{\n    if (self.attributes.footnoteRefBuilder) {\n        \n    } else {\n        [self.attributeStack pop];\n    }\n}\n\n- (void)parser:(CMParser *)parser didStartFootNoteDefination:(NSString *)content refCount:(NSInteger)index\n{\n    [self.attributeStack pushAttributes:self.attributes.footNoteAttributes];\n    [self appendString:[NSString stringWithFormat:@\"%@: \", content]];\n}\n\n- (void)parser:(CMParser *)parser didEndFootNoteDefination:(NSString *)content refCount:(NSInteger)index\n{\n    [self.attributeStack pop];\n}\n\n- (void)parser:(CMParser *)parser didStartOrderedListWithStartingNumber:(NSInteger)num tight:(BOOL)tight\n{\n    _parsingNodeType = 1;\n    _listLevel ++;\n    _orderListLevel++;\n    if (!_indentStack) {\n        _indentStack = [[CMStack alloc] init];\n    }\n    AMStyleProvider provider = self.attributes.ordererListAttributesProvider;\n    if (provider) {\n        CMStyleAttributes *attributes = provider(_listLevel);\n        if (_listLevel == 1) {\n            _listItemExtraIndent = [self.attributeStack.peek.attributes.paragraphStyleAttributes[CMParagraphStyleAttributeHeadExtraIndent] floatValue];\n        }\n        [self calListIndent:attributes parseTyle:_parsingNodeType];\n        attributes.stringAttributes[NSForegroundColorAttributeName] = self.attributes.paragraphAttributes.stringAttributes[NSForegroundColorAttributeName];\n        [self.attributeStack pushOrderedListAttributes:attributes withStartingNumber:num];\n    } else {\n        [super parser:parser didStartOrderedListWithStartingNumber:num tight:tight];\n    }\n}\n\n- (void)parser:(CMParser *)parser didEndOrderedListWithStartingNumber:(NSInteger)num tight:(BOOL)tight\n{\n    _listLevel --;\n    _orderListLevel--;\n    if (_indentStack) {\n        [_indentStack pop];\n        if (!_indentStack.objects.count) {\n            _indentStack = nil;\n        }\n    }\n    if (_listLevel == 0) {\n        _listItemExtraIndent = 0;\n    }\n    [super parser:parser didEndOrderedListWithStartingNumber:num tight:tight];\n}\n\n- (void)parser:(CMParser *)parser didStartUnorderedListWithTightness:(BOOL)tight\n{\n    _parsingNodeType = 2;\n    _listLevel ++;\n    _unorderListLevel++;\n    if (!_indentStack) {\n        _indentStack = [[CMStack alloc] init];\n    }\n    AMStyleProvider provider = self.attributes.unordererListAttributesProvider;\n    if (provider) {\n        CMStyleAttributes *attributes = provider(_listLevel);\n#if !TARGET_OS_IPHONE\n        CMNode *imageDescriptionNode = imageNode.firstChild;\n        if ((imageDescriptionNode.type == CMNodeTypeText) && (imageDescriptionNode.stringValue.length > 0)) {\n            imageAttachmentAttributes.stringAttributes [NSToolTipAttributeName] = imageDescriptionNode.stringValue;\n        }\n#endif\n        if (_listLevel == 1) {\n            _listItemExtraIndent = [self.attributeStack.peek.attributes.paragraphStyleAttributes[CMParagraphStyleAttributeHeadExtraIndent] floatValue];\n        }\n        \n        [self calListIndent:attributes parseTyle:_parsingNodeType];\n        attributes.stringAttributes[NSForegroundColorAttributeName] = self.attributes.paragraphAttributes.stringAttributes[NSForegroundColorAttributeName];\n        [self.attributeStack pushAttributes:attributes];\n    } else {\n        [super parser:parser didStartUnorderedListWithTightness:tight];\n    }\n}\n\n- (void)parser:(CMParser *)parser didEndUnorderedListWithTightness:(BOOL)tight\n{\n    _listLevel --;\n    _unorderListLevel--;\n    if (_indentStack) {\n        [_indentStack pop];\n        if (!_indentStack.objects.count) {\n            _indentStack = nil;\n        }\n    }\n    if (_listLevel == 0) {\n        _listItemExtraIndent = 0;\n    }\n    [super parser:parser didEndUnorderedListWithTightness:tight];\n}\n- (void)parserDidStartListItem:(CMParser *)parser\n{\n    \n    AMStyleProvider provider = nil;\n    CMNode *node = parser.currentNode.parent;\n    long number = 0;\n    if (node.listType == CMListTypeUnordered) {\n        provider = self.attributes.unordererListAttributesProvider;\n    } else if (node.listType == CMListTypeOrdered) {\n        provider = self.attributes.ordererListAttributesProvider;\n    }\n    NSInteger level = _listLevel;\n    NSString* path = CMParagraphStyleAttributeListItemLabelIcon;\n    NSString* tmpKey = nil;\n    if (provider) {\n        CMStyleAttributes *attributes = provider(level);\n        tmpKey = CMCustomListBullet;\n        // prefix image type\n        if (attributes.stringAttributes[path]) {\n            UIFont* font = nil;\n            if ([self.attributeStack.cascadedAttributes[NSFontAttributeName] isKindOfClass:[UIFont class]]) {\n                font = ((UIFont *)self.attributeStack.cascadedAttributes[NSFontAttributeName]);\n            }\n            if (!font) {\n                font = self.attributes.paragraphAttributes.stringAttributes[NSFontAttributeName];\n            }\n            if (!font) {\n                font = self.attributes.baseTextAttributes.stringAttributes[NSFontAttributeName];\n            }\n            AMIconAttachment* attachment = nil;\n            if (node.listType == CMListTypeUnordered) {\n                int size = [attributes.stringAttributes[CMParagraphStyleAttributeListItemLabelIconSize] floatValue];\n                attachment = [[AMIconAttachment alloc] init];\n                attachment.path = attributes.stringAttributes[path];\n                attachment.baseFont = font;\n                attachment.attachmentSize = CGSizeMake(size, size);\n            } else {\n                BOOL subTitleStyle = NO;\n                if ([attributes.stringAttributes[path] isEqualToString:@\"\"]) {\n                    subTitleStyle = YES;\n                }\n                number = (long)[super getOrderListNumber];\n                int iconSize = [attributes.stringAttributes[CMParagraphStyleAttributeListItemLabelIconSize] floatValue];\n                if (number > 9 && subTitleStyle) {\n                    iconSize = 24;\n                }\n                \n                attachment = [[AMIconAttachment alloc] init];\n                attachment.path = attributes.stringAttributes[path];\n                attachment.baseFont = font;\n                attachment.attachmentSize = CGSizeMake(iconSize, iconSize);\n                attachment.text = !subTitleStyle ? [NSString stringWithFormat:@\"%ld\", number] : [NSString stringWithFormat:@\"%ld.\", number];\n                attachment.textColor = !subTitleStyle ? attributes.stringAttributes[@\"iconTitleColor\"] : self.attributes.paragraphAttributes.stringAttributes[NSForegroundColorAttributeName];\n                attachment.textSize = !subTitleStyle ? 10 : font.pointSize;\n                attachment.textAlignment = !subTitleStyle ? NSTextAlignmentCenter : NSTextAlignmentLeft;\n                attachment.boldText = !subTitleStyle;\n  \n                if (number > 9 && subTitleStyle) {\n                    [self calOrderListTwoDigitIndent:attributes number:number size:iconSize subTitle:subTitleStyle];\n                }\n            }\n            if (!self.buffer || self.buffer.string.length == 0) {\n                const unichar attachmentChar = NSAttachmentCharacter;\n                NSAttributedString* holderStr = [[NSAttributedString alloc] initWithString:[NSString stringWithCharacters:&attachmentChar length:1] attributes:nil];\n                [self appendAttributedString:holderStr];\n            }\n            \n            [self appendString:[NSString stringWithFormat:@\"\\t\"]];\n            [self appendAttributedString:[NSAttributedString attributedStringWithAttachment:attachment]];\n            if (tmpKey) {\n                [self.attributes.paragraphAttributes.stringAttributes addEntriesFromDictionary:@{tmpKey:attributes.stringAttributes[path]}];\n            }\n        } else if (attributes.stringAttributes[CMListSingleDigitSize]) {\n            // prefix character type\n            number = (long)[super getOrderListNumber];\n            CGFloat digitSize = 0;\n            if (number > 9 && node.listType == CMListTypeOrdered) {\n                if (number > 9 && number < 100) {\n                    // 三位数indent处理\n                    digitSize = [attributes.stringAttributes[CMListTwoDigitSize] floatValue];\n                } else if (number > 100) {\n                    digitSize = [attributes.stringAttributes[CMListThreeDigitSize] floatValue];\n                }\n                NSMutableParagraphStyle* paraStyle = attributes.stringAttributes[NSParagraphStyleAttributeName];\n                NSMutableArray *mutableTabs = [paraStyle.tabStops mutableCopy];\n\n                if (mutableTabs.count > 0) {\n                \n                    NSTextTab *tab1 = (NSTextTab*)[mutableTabs objectAtIndex:0];\n                    CGFloat digitIndent = tab1.location + _listItemExtraIndent;\n                    CGFloat internal = [attributes.stringAttributes[CMListInternalSpace] floatValue];\n                    \n                    CGFloat textIndent = digitIndent + digitSize + internal + _listItemExtraIndent;\n                    NSTextTab *newTab1 = [[NSTextTab alloc]            initWithTextAlignment:NSTextAlignmentLeft\n                                                                         location:digitIndent\n                                                                                     options:@{}];\n                    NSTextTab *tab2 = [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentLeft\n                                                                      location:textIndent\n                                                                       options:@{}];\n                    [mutableTabs replaceObjectAtIndex:0 withObject:newTab1];\n                    [mutableTabs replaceObjectAtIndex:1 withObject:tab2];\n                    [paraStyle setValue:[mutableTabs copy] forKey:@\"tabStops\"];\n                    [paraStyle setValue:@(textIndent) forKey:@\"headIndent\"];\n                }\n                [_attributeStack pop];\n                [self.attributeStack pushOrderedListAttributes:attributes withStartingNumber:number];\n            }\n            \n        }\n    }\n    [super parserDidStartListItem:parser];\n    if (tmpKey) {\n        [self.attributes.paragraphAttributes.stringAttributes removeObjectForKey:tmpKey];\n    }\n    \n}\n- (void)parser:(CMParser *)parser didStartLinkWithURL:(NSURL *)URL title:(NSString *)title\n{\n    if (self.attributes.linkAttributes.stringAttributes[CMLinkIconPrefix]) {\n        UIFont* font = nil;\n        if ([self.attributeStack.cascadedAttributes[NSFontAttributeName] isKindOfClass:[UIFont class]]) {\n            font = ((UIFont *)self.attributeStack.cascadedAttributes[NSFontAttributeName]);\n        }\n        if (!font) {\n            font = self.attributes.paragraphAttributes.stringAttributes[NSFontAttributeName];\n        }\n        if (!font) {\n            font = self.attributes.baseTextAttributes.stringAttributes[NSFontAttributeName];\n        }\n        AMIconAttachment* attachment = [[AMIconAttachment alloc] init];\n        attachment.path = self.attributes.linkAttributes.stringAttributes[CMLinkIconPrefix];\n        attachment.baseFont = font;\n        attachment.attachmentSize = CGSizeZero;\n        attachment.marginRight = [self.attributes.linkAttributes.stringAttributes[CMLinkIconSpace] floatValue];\n        attachment.marginLeft = 0;\n        [self appendAttributedString:[NSAttributedString attributedStringWithAttachment:attachment]];\n    }\n    [super parser:parser didStartLinkWithURL:URL title:title];\n}\n- (void)parser:(CMParser *)parser didEndLinkWithURL:(NSURL *)URL title:(NSString *)title\n{\n    if (self.attributes.linkAttributes.stringAttributes[CMLinkIconSuffix]) {\n        UIFont* font = nil;\n        if ([self.attributeStack.cascadedAttributes[NSFontAttributeName] isKindOfClass:[UIFont class]]) {\n            font = ((UIFont *)self.attributeStack.cascadedAttributes[NSFontAttributeName]);\n        }\n        if (!font) {\n            font = self.attributes.paragraphAttributes.stringAttributes[NSFontAttributeName];\n        }\n        if (!font) {\n            font = self.attributes.baseTextAttributes.stringAttributes[NSFontAttributeName];\n        }\n        AMIconAttachment* attachment = [[AMIconAttachment alloc] init];\n        attachment.path = self.attributes.linkAttributes.stringAttributes[CMLinkIconSuffix];\n        attachment.baseFont = font;\n        attachment.attachmentSize = CGSizeZero;\n        attachment.marginLeft = [self.attributes.linkAttributes.stringAttributes[CMLinkIconSpace] floatValue];\n        attachment.marginRight = 0;\n        [self appendAttributedString:[NSAttributedString attributedStringWithAttachment:attachment]];\n    }\n    [super parser:parser didEndLinkWithURL:URL title:title];\n}\n-(void)calOrderListTwoDigitIndent:(CMStyleAttributes*)attributes number:(long)number size:(NSInteger)size subTitle:(BOOL)subTitle{\n    if (self.attributes.orderedListAttributes.stringAttributes[CMOrderListFirstLevelIndent]) {\n        NSInteger iconSize = size;\n        NSInteger extraIndent;\n        if (subTitle) {\n            extraIndent = [[_indentStack.objects objectAtIndex:(_indentStack.objects.count - 2)] floatValue];\n        } else {\n            [self.attributes.orderedListAttributes.stringAttributes[CMOrderListFirstLevelIndent] intValue];\n        }\n        NSTextAlignment alignment = NSTextAlignmentLeft;\n        NSInteger textExtraIndent = iconSize + [attributes.stringAttributes[CMListInternalSpace] intValue];\n        NSMutableParagraphStyle* paraStyle = attributes.stringAttributes[NSParagraphStyleAttributeName];\n        NSMutableArray *mutableTabs = [paraStyle.tabStops mutableCopy];\n\n        if (mutableTabs.count > 0) {\n            NSTextTab *newTab1;\n            newTab1 = [[NSTextTab alloc]            initWithTextAlignment:alignment\n                                                                 location:extraIndent\n                                                                             options:@{}];\n            NSTextTab *newTab2 = [[NSTextTab alloc]            initWithTextAlignment:NSTextAlignmentLeft\n                                                                            location:extraIndent + textExtraIndent\n                                                                             options:@{}];\n            [mutableTabs replaceObjectAtIndex:0 withObject:newTab1];\n            [mutableTabs replaceObjectAtIndex:1 withObject:newTab2];\n            [paraStyle setValue:[mutableTabs copy] forKey:@\"tabStops\"];\n            [paraStyle setValue:@(extraIndent + textExtraIndent) forKey:@\"headIndent\"];\n        }\n        [_attributeStack pop];\n        [self.attributeStack pushOrderedListAttributes:attributes withStartingNumber:number];\n    }\n}\n-(void)calListIndent:(CMStyleAttributes*)attributes parseTyle:(NSInteger)parseType{\n    if (attributes.stringAttributes[CMParagraphStyleAttributeListItemLabelIconSize]) {\n        int iconSize = [attributes.stringAttributes[CMParagraphStyleAttributeListItemLabelIconSize] floatValue];\n        CGFloat extraIndent = _indentStack.objects.count ? [_indentStack.peek floatValue] : 0;\n        if (attributes.stringAttributes[CMListLevelIndent]) {\n            extraIndent = [attributes.stringAttributes[CMListLevelIndent] floatValue];\n        }\n        extraIndent += _listLevel == 1 ? (1 + _listItemExtraIndent) : 0.5;\n        CGFloat iconIndent = extraIndent;\n        CGFloat textIndent = extraIndent + iconSize + [attributes.stringAttributes[CMListInternalSpace] intValue];\n        NSMutableParagraphStyle* paraStyle = attributes.stringAttributes[NSParagraphStyleAttributeName];\n        NSMutableArray *mutableTabs = [paraStyle.tabStops mutableCopy];\n\n        if (mutableTabs.count > 0) {\n            NSTextTab *newTab1;\n            newTab1 = [[NSTextTab alloc]            initWithTextAlignment:NSTextAlignmentLeft\n                                                                 location:iconIndent\n                                                                             options:@{}];\n            NSTextTab *newTab2 = [[NSTextTab alloc]            initWithTextAlignment:NSTextAlignmentLeft\n                                                                 location:textIndent\n                                                                             options:@{}];\n            [mutableTabs replaceObjectAtIndex:0 withObject:newTab1];\n            [mutableTabs replaceObjectAtIndex:1 withObject:newTab2];\n        }\n        [paraStyle setValue:[mutableTabs copy] forKey:@\"tabStops\"];\n        [paraStyle setValue:@(textIndent) forKey:@\"headIndent\"];\n        \n        [_indentStack push:@(textIndent)];\n    } else if (attributes.stringAttributes[CMListSingleDigitSize]) {\n        NSMutableParagraphStyle* paraStyle = attributes.stringAttributes[NSParagraphStyleAttributeName];\n        NSMutableArray *mutableTabs = [paraStyle.tabStops mutableCopy];\n\n        if (mutableTabs.count > 0) {\n        \n            NSTextTab *tab1 = (NSTextTab*)[mutableTabs objectAtIndex:0];\n            CGFloat digitIndent = tab1.location;\n            CGFloat internal = [attributes.stringAttributes[CMListInternalSpace] floatValue];\n            CGFloat digitSize = [attributes.stringAttributes[CMListSingleDigitSize] floatValue];\n            CGFloat iconIndent = digitIndent + _listItemExtraIndent + [attributes.stringAttributes[CMListLevelIndent] floatValue];;\n            CGFloat textIndent = digitIndent + digitSize + internal + _listItemExtraIndent + [attributes.stringAttributes[CMListLevelIndent] floatValue];;\n            NSTextTab *newTab1 = [[NSTextTab alloc]            initWithTextAlignment:NSTextAlignmentLeft\n                                                                 location:iconIndent\n                                                                             options:@{}];\n            NSTextTab *tab2 = [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentLeft\n                                                              location:textIndent\n                                                               options:@{}];\n            [mutableTabs replaceObjectAtIndex:0 withObject:newTab1];\n            [mutableTabs replaceObjectAtIndex:1 withObject:tab2];\n            [paraStyle setValue:[mutableTabs copy] forKey:@\"tabStops\"];\n            [paraStyle setValue:@(textIndent) forKey:@\"headIndent\"];\n        }\n    }\n    else {\n        if (_listItemExtraIndent != 0) {\n            NSMutableParagraphStyle* paraStyle = attributes.stringAttributes[NSParagraphStyleAttributeName];\n            NSMutableArray *mutableTabs = [paraStyle.tabStops mutableCopy];\n\n            if (mutableTabs.count > 0) {\n                CGFloat iconIndent = ((NSTextTab*)[mutableTabs objectAtIndex:0]).location + _listItemExtraIndent;\n                CGFloat textIndent = ((NSTextTab*)[mutableTabs objectAtIndex:1]).location + _listItemExtraIndent;\n                NSTextTab *newTab1;\n                newTab1 = [[NSTextTab alloc]            initWithTextAlignment:NSTextAlignmentLeft\n                                                                     location:iconIndent\n                                                                                 options:@{}];\n                NSTextTab *newTab2 = [[NSTextTab alloc]            initWithTextAlignment:NSTextAlignmentLeft\n                                                                     location:textIndent\n                                                                                 options:@{}];\n                [mutableTabs replaceObjectAtIndex:0 withObject:newTab1];\n                [mutableTabs replaceObjectAtIndex:1 withObject:newTab2];\n                [paraStyle setValue:[mutableTabs copy] forKey:@\"tabStops\"];\n                [paraStyle setValue:@(textIndent) forKey:@\"headIndent\"];\n            \n            }\n        }\n        \n    }\n}\n@end\n\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMBlockMathAttachment.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <AntMarkdown/CMBlockTextAttachment.h>\n#import <AntMarkdown/AMInlineMathAttachment.h>\n\nNS_ASSUME_NONNULL_BEGIN\n@class MTMathListDisplay;\n@class MTMathList;\n\n@interface AMBlockMathAttachment : CMBlockTextAttachment\n\n@property (nonatomic, nullable, strong) NSError *error;\n\n- (instancetype)initWithText:(nullable NSString *)text\n                       style:(nullable AMMathStyle *)style NS_DESIGNATED_INITIALIZER;\n\n- (instancetype)initWithDisplayList:(nullable MTMathListDisplay *)displayList style:(nullable AMMathStyle *)style NS_DESIGNATED_INITIALIZER;\n\n+ (NSArray<AMBlockMathAttachment *> *)constructorBlockMathAttachmentWithText:(NSString *)text style:(AMMathStyle *)style;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMBlockMathAttachment.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMBlockMathAttachment.h\"\n#import \"IosMath.h\"\n#import \"MTTypesetter.h\"\n#import \"MTFontManager.h\"\n#import \"AMUtils.h\"\n\n@implementation AMBlockMathAttachment\n{\n    MTMathList * _mathList;\n    MTMathListDisplay * _displayList;\n    AMMathStyle * _style;\n    BOOL  _isImageZeroSize;\n    NSAttributedString * _mathCodeAttrText;\n}\n\n- (instancetype)initWithData:(NSData *)contentData ofType:(NSString *)uti {\n    return [self initWithText:nil style:nil];\n}\n\n- (instancetype)initWithDisplayList:(nullable MTMathListDisplay *)displayList style:(nullable AMMathStyle *)style  {\n    displayList.textColor = style.textColor;\n    const CGFloat contentHeight = displayList.ascent + displayList.descent;\n    CGFloat totalHeight = style.height;\n    if (totalHeight <= 0) {\n        totalHeight = contentHeight;\n    }\n    self = [super initWithData:nil ofType:nil];\n    if (self) {\n        _displayList = displayList;\n        _style = style;\n  \n        self.bounds = CGRectMake(0, 0, displayList.width, totalHeight + 1.5);\n        \n        CGRect rect = self.bounds;\n        switch (style.verticalAlignment) {\n            case UIControlContentVerticalAlignmentCenter: {\n                rect.origin.y = -displayList.descent;\n            }\n                break;\n            case UIControlContentVerticalAlignmentBottom: {\n                rect.origin.y = -rect.size.height;\n            }\n                break;\n            case UIControlContentVerticalAlignmentTop: {\n                rect.origin.y = 0;\n            }\n                break;\n            default:\n                break;\n        }\n        self.bounds = rect;\n    }\n    return self;\n}\n\n- (instancetype)initWithText:(NSString *)text style:(AMMathStyle *)style {\n    NSError *error = nil;\n    NSMutableString *mathText = [text mutableCopy];\n    if ([mathText hasPrefix:@\"\\\\[\"]) {\n        [mathText deleteCharactersInRange:NSMakeRange(0, 2)];\n    }\n    if ([mathText hasSuffix:@\"\\\\]\"]) {\n        [mathText deleteCharactersInRange:NSMakeRange(mathText.length - 2, 2)];\n    }\n    MTMathList *mathList = [MTMathListBuilder buildFromString:mathText ?: @\"\"\n                                                        error:&error];\n    if (error) {\n        self = [super initWithData:nil ofType:nil];\n        if (self) {\n            self.text = text;\n            self.error = error;\n            AMLogDebug(@\"math parse error: %@\", error);\n        }\n        return self;\n    }\n    \n    style = style ?: [AMMathStyle defaultBlockStyle];\n    \n    @try {\n        MTMathListDisplay *displayList = [MTTypesetter createLineForMathList:mathList\n                                                                        font:[[MTFontManager fontManager] xitsFontWithSize:style.fontSize]\n                                                                       style:kMTLineStyleDisplay];\n        displayList.textColor = style.textColor;\n        \n        const CGFloat contentHeight = displayList.ascent + displayList.descent;\n        CGFloat totalHeight = style.height;\n        if (totalHeight <= 0) {\n            totalHeight = contentHeight;\n        }\n        \n        self = [super initWithData:nil ofType:nil];\n        if (self) {\n            self.text = text;\n            _mathList = mathList;\n            _displayList = displayList;\n            _style = style;\n            \n            self.bounds = CGRectMake(0, 0, displayList.width, totalHeight);\n            \n            CGRect rect = self.bounds;\n            switch (style.verticalAlignment) {\n                case UIControlContentVerticalAlignmentCenter: {\n                    rect.origin.y = -displayList.descent;\n                }\n                    break;\n                case UIControlContentVerticalAlignmentBottom: {\n                    rect.origin.y = -rect.size.height;\n                }\n                    break;\n                case UIControlContentVerticalAlignmentTop: {\n                    rect.origin.y = 0;\n                }\n                    break;\n                default:\n                    break;\n            }\n            self.bounds = rect;\n        }\n        return self;\n    } @catch (NSException *exception) {\n        self = [super initWithData:nil ofType:nil];\n        if (self) {\n            self.text = text;\n            self.error = [[NSError alloc] initWithDomain:@\"MathDisplayError\" code:404 userInfo:exception.userInfo];\n            AMLogDebug(@\"math display exception: %@,text = %@\", exception, text);\n        }\n        return self;\n    }\n}\n\n+ (NSArray<AMBlockMathAttachment *> *)constructorBlockMathAttachmentWithText:(NSString *)text style:(AMMathStyle *)style {\n    NSError *error = nil;\n    NSMutableArray<AMBlockMathAttachment *> * attachList = [NSMutableArray new];\n    NSMutableString *mathText = [text mutableCopy];\n    if ([mathText hasPrefix:@\"\\\\[\"]) {\n        [mathText deleteCharactersInRange:NSMakeRange(0, 2)];\n    }\n    if ([mathText hasSuffix:@\"\\\\]\"]) {\n        [mathText deleteCharactersInRange:NSMakeRange(mathText.length - 2, 2)];\n    }\n    MTMathList *totalMathList = [MTMathListBuilder buildFromString:mathText ?: @\"\"\n                                                             error:&error];\n    \n    if (error) {\n        AMBlockMathAttachment *attachment = [[self alloc] initWithText:text style:style];\n        return @[attachment];\n    }\n    \n    style = style ?: [AMMathStyle defaultBlockStyle];\n    \n    @try {\n        MTMathListDisplay *totalDisplayList = [MTTypesetter createLineForMathList:totalMathList\n                                                                             font:[[MTFontManager fontManager] xitsFontWithSize:style.fontSize]\n                                                                            style:kMTLineStyleDisplay];\n        CGFloat maxWidth = [UIScreen mainScreen].bounds.size.width - 65;\n        if (totalDisplayList.width <= maxWidth) {\n            AMBlockMathAttachment *attachment = [[self alloc] initWithDisplayList:totalDisplayList style:style];\n            return @[attachment];\n        }\n        NSArray<NSNumber *> *segIndexs = [self getSegIndexWithDispayList:totalDisplayList];\n        NSUInteger start = 0;\n        for (NSNumber *segIndex in segIndexs) {\n            NSUInteger index = [segIndex unsignedIntegerValue];\n            NSMutableArray<MTMathAtom *> *atoms = [NSMutableArray new];\n            for (NSUInteger i = start; i < index; i++) {\n                [atoms addObject:totalMathList.atoms[i]];\n            }\n            start = index;\n            MTMathList *realMathList = [MTMathList mathListWithAtomsArray:atoms];\n            MTMathListDisplay *realDisplayList = [MTTypesetter createLineForMathList:realMathList\n                                                                                font:[[MTFontManager fontManager] xitsFontWithSize:style.fontSize]\n                                                                               style:kMTLineStyleDisplay];\n            AMBlockMathAttachment *attachment = [[self alloc] initWithDisplayList:realDisplayList style:style];\n            [attachList addObject:attachment];\n        }\n\n        NSUInteger lastIndex = [segIndexs.lastObject unsignedIntValue];\n        if (lastIndex < totalMathList.atoms.count) {\n            NSMutableArray<MTMathAtom *> *atoms = [NSMutableArray new];\n            for (NSUInteger i = lastIndex; i < totalMathList.atoms.count; i++) {\n                [atoms addObject:totalMathList.atoms[i]];\n            }\n            MTMathList *realMathList = [MTMathList mathListWithAtomsArray:atoms];\n            MTMathListDisplay *realDisplayList = [MTTypesetter createLineForMathList:realMathList\n                                                                                font:[[MTFontManager fontManager] xitsFontWithSize:style.fontSize]\n                                                                               style:kMTLineStyleDisplay];\n            AMBlockMathAttachment *attachment = [[self alloc] initWithDisplayList:realDisplayList style:style];\n            [attachList addObject:attachment];\n        }\n        \n    } @catch (NSException *exception) {\n        AMBlockMathAttachment *attachment = [[self alloc] initWithText:text style:style];\n        return @[attachment];\n    }\n    return [attachList copy];\n}\n\n+ (NSArray<NSNumber *> *)getSegIndexWithDispayList:(MTMathListDisplay *)displayList {\n    NSMutableArray<NSNumber *> *segIndexs = [NSMutableArray new];\n    CGFloat maxWidth = [UIScreen mainScreen].bounds.size.width - 65;\n    MTDisplay *preDisplay = nil;\n    for (NSUInteger i = 0; i < displayList.subDisplays.count; i++) {\n        MTDisplay *display = displayList.subDisplays[i];\n        CGFloat currentDisplayEndPositionX = display.position.x + display.width;\n        if (currentDisplayEndPositionX >= maxWidth) {\n            [segIndexs addObject:@(preDisplay.range.location + preDisplay.range.length)];\n            maxWidth += maxWidth;\n        }\n        if (display.range.location != 0) {\n            preDisplay = display;\n        }\n    }\n    return [segIndexs copy];\n}\n\n- (void)drawImage:(CGSize)size {\n    \n    // 绘制图片使用新的API，防止size=0 Crash，并且部分场景复用绘制失败（首次绘制宽度为0）\n    UIGraphicsImageRenderer *re = [[UIGraphicsImageRenderer alloc] initWithSize:size];\n    self.image = [re imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) {\n        CGContextRef context = rendererContext.CGContext;\n\n        CGContextTranslateCTM(context, 0, size.height);\n        CGContextScaleCTM(context, 1.0, -1.0);\n        \n        CGFloat totalHeight = size.height;\n        CGFloat contentHeight = _displayList.ascent + _displayList.descent;\n        \n        CGFloat x = 0;\n        switch (_style.horizontalAlignment) {\n            case UIControlContentHorizontalAlignmentCenter:\n                x = (size.width - _displayList.width) / 2;\n                break;\n            case UIControlContentHorizontalAlignmentRight:\n                x = size.width - _displayList.width;\n                break;\n            case UIControlContentHorizontalAlignmentLeft:\n                x = 0;\n                break;\n            default:\n                break;\n        }\n        _displayList.position = CGPointMake(x, (totalHeight - contentHeight) / 2 + _displayList.descent);\n        [_displayList draw:context];\n    }];\n}\n\n- (UIImage *)imageForBounds:(CGRect)imageBounds\n              textContainer:(NSTextContainer *)textContainer\n             characterIndex:(NSUInteger)charIndex {\n    const CGFloat width = textContainer.size.width - textContainer.lineFragmentPadding * 2;\n    if (!self.image) {\n        [self drawImage:CGSizeMake(width, self.bounds.size.height)];\n    }\n    return self.image;\n}\n\n- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer \n                      proposedLineFragment:(CGRect)lineFrag\n                             glyphPosition:(CGPoint)position\n                            characterIndex:(NSUInteger)charIndex {\n    CGRect rect = [super attachmentBoundsForTextContainer:textContainer\n                                     proposedLineFragment:lineFrag\n                                            glyphPosition:position\n                                           characterIndex:charIndex];\n    \n    CGFloat yPos = MAX(0, rect.origin.y);\n    rect = CGRectMake(rect.origin.x, yPos, floor(rect.size.width), rect.size.height);\n        \n    const CGFloat width = textContainer.size.width - textContainer.lineFragmentPadding * 2;\n\n    if ((floor(width) != floor(self.image.size.width)) && [NSThread isMainThread]) {\n        [self drawImage:CGSizeMake(floor(width), self.bounds.size.height)];\n    }\n    \n    return rect;\n}\n\n- (NSAttributedString *)attributedString\n{\n    if (self.error) {\n        return [[NSAttributedString alloc] initWithString:self.text ?: @\"\" attributes:@{\n            NSForegroundColorAttributeName: _style.textColor ?: [UIColor blackColor],\n            NSFontAttributeName: _style.font ?: [UIFont systemFontOfSize:UIFont.systemFontSize],\n        }];\n    }\n    return [NSAttributedString attributedStringWithAttachment:self];\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMCodeHighlighter.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n\n@class AMTextStyles;\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMCodeHighlighter : NSObject\n\n- (instancetype)initWithStyles:(AMTextStyles *)styles;\n\n- (NSAttributedString *)highlightCodeString:(NSString *)code \n                                   language:(nullable NSString *)language;\n\n- (nullable NSAttributedString *)cachedAttributedCodeForCode:(NSString *)code\n                                                    language:(nullable NSString *)language;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMCodeHighlighter.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <JavaScriptCore/JavaScriptCore.h>\n\n#import \"AMCodeHighlighter.h\"\n#import \"AMTextStyles.h\"\n#import \"CMCascadingAttributeStack.h\"\n#import \"AMUtils.h\"\n\n@interface AMCodeHighlighter ()\n@property (nonatomic) JSVirtualMachine *vm;\n@property (nonatomic) JSContext *context;\n@property (nonatomic) NSString *stylesheet;\n@property (nonatomic) AMTextStyles *styles;\n@property (nonatomic) NSCache<NSString *, NSAttributedString *> *cachedAttributedText;\n@end\n\n@implementation AMCodeHighlighter\n\n+ (BOOL)isSupportCodeLan:(NSString *)codeLan\n{\n    if([codeLan length] == 0)\n        return NO;\n\n    static NSDictionary* codeLanDic;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        codeLanDic = @{\n            @\"bash\":@(YES),\n            @\"c\":@(YES),\n            @\"cpp\":@(YES),\n            @\"swift\":@(YES),\n            @\"csharp\":@(YES),\n            @\"css\":@(YES),\n            @\"go\":@(YES),\n            @\"java\":@(YES),\n            @\"javascript\":@(YES),\n            @\"json\":@(YES),\n            @\"kotlin\":@(YES),\n            @\"latex\":@(YES),\n            @\"markdown\":@(YES),\n            @\"objectivec\":@(YES),\n            @\"php\":@(YES),\n            @\"python\":@(YES),\n            @\"ruby\":@(YES),\n            @\"sql\":@(YES),\n            @\"typescript\":@(YES),\n            @\"xml\":@(YES),\n        };\n    });\n    id obj = [codeLanDic objectForKey:codeLan.lowercaseString];\n    return (obj != nil);\n}\n\n- (instancetype)initWithStyles:(AMTextStyles *)styles\n{\n    self = [super init];\n    if (self) {\n        self.styles = styles;\n        \n        self.cachedAttributedText = [[NSCache alloc] init];\n        self.cachedAttributedText.name = @\"Highlighted Code Cache\";\n        self.cachedAttributedText.totalCostLimit = 10 * 1024 * 1024;\n        \n        self.vm = [[JSVirtualMachine alloc] init];\n        self.context = [[JSContext alloc] initWithVirtualMachine:self.vm];\n        [self.context setExceptionHandler:^(JSContext *context, JSValue *exception) {\n            NSLog(@\"JS Exception: %@\", exception);\n        }];\n        \n        NSString *resourcePath = [[NSBundle bundleForClass:self.class] pathForResource:@\"highlightjs\" ofType:@\"bundle\"];\n        if (!resourcePath) {\n            resourcePath = [NSBundle.mainBundle pathForResource:@\"highlightjs\" ofType:@\"bundle\"];\n        }\n        NSBundle *resourceBundle = [NSBundle bundleWithPath:resourcePath];\n        NSURL *jsPath = [resourceBundle URLForResource:@\"highlight.min\" withExtension:@\"js\"];\n        NSURL *stylePath = [resourceBundle URLForResource:@\"default.min\" withExtension:@\"css\"];\n        self.stylesheet = [NSString stringWithContentsOfURL:stylePath encoding:NSUTF8StringEncoding error:nil];\n        NSString *code = [NSString stringWithContentsOfURL:jsPath encoding:NSUTF8StringEncoding error:nil];\n        [self.context evaluateScript:code withSourceURL:jsPath];\n    }\n    return self;\n}\n\n- (NSAttributedString *)highlightCodeString:(NSString *)code language:(NSString *)language\n{\n    NSAttributedString *attr = [self cachedAttributedCodeForCode:code language:language];\n    if (!attr) {\n        JSValue *hljs = self.context[@\"hljs\"];\n        JSValue *result = nil;\n        \n        if (language.length && [AMCodeHighlighter isSupportCodeLan:language]) {\n            result = [hljs invokeMethod:@\"highlight\" withArguments:@[code, @{\n                @\"language\": language\n            }]];\n        } else {\n            result = [hljs invokeMethod:@\"highlightAuto\" withArguments:@[code]];\n        }\n        NSString * value = [result[@\"value\"] toString];\n        \n        UIFont *font = self.styles.codeBlockAttributes.stringAttributes[NSFontAttributeName];\n        \n        if ([font isKindOfClass:[UIFont class]] && self.styles.codeBlockAttributes.fontAttributes.count > 0) {\n            font = [font fontByAddingCMAttributes:self.styles.codeBlockAttributes.fontAttributes];\n        }\n        \n        NSError *error = nil;\n        NSString *html = [NSString stringWithFormat:\n                          @\"<style>\"\n                          @\"code{font-size: %.2fpx}\"\n                          @\"%@\"\n                          @\"</style>\"\n                          @\"<pre><code class=\\\"hljs\\\">\"\n                          @\"%@\"\n                          @\"</code></pre>\", font ? font.pointSize : 13, self.stylesheet, value];\n        NSMutableAttributedString *attri = [[NSMutableAttributedString alloc] initWithData:[html dataUsingEncoding:NSUTF8StringEncoding]\n                                                                                   options:@{\n            NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,\n            NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding),\n        }\n                                                                        documentAttributes:nil\n                                                                                     error:&error];\n        if ([attri.mutableString hasSuffix:@\"\\n\"]) {\n            [attri.mutableString deleteCharactersInRange:NSMakeRange(attri.length - 1, 1)];\n        }\n        NSParagraphStyle *paragraph = [NSParagraphStyle paragraphStyleWithCMAttributes:self.styles.codeBlockAttributes.paragraphStyleAttributes];\n        if (paragraph) {\n            [attri addAttribute:NSParagraphStyleAttributeName value:paragraph range:NSMakeRange(0, attri.length)];\n        }\n        attr = [attri copy];\n        @synchronized (self) {\n            if (attr) {\n                NSString *cacheKey = [NSString stringWithFormat:@\"%@:%@\", language, code];\n                [self.cachedAttributedText setObject:attr\n                                              forKey:cacheKey\n                                                cost:attr.length];\n            } else {\n                AMLogDebug(@\"fail to highlight code: %@\", code);\n            }\n        }\n    }\n    return attr;\n}\n\n- (NSAttributedString *)cachedAttributedCodeForCode:(NSString *)code language:(NSString *)language\n{\n    NSString *cacheKey = [NSString stringWithFormat:@\"%@:%@\", language, code];\n    @synchronized (self) {\n        return [self.cachedAttributedText objectForKey:cacheKey];\n    }\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMCodeViewAttachment.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <AntMarkdown/AMViewAttachment.h>\n\n@class AMTextStyles;\n\nNS_ASSUME_NONNULL_BEGIN\n\n@protocol AMCodeView <NSObject>\n- (void)setPlainCodeText:(NSString *)codeText;\n- (void)setLanguage:(nullable NSString *)lang;\n- (void)setAttributedCodeText:(NSAttributedString *)codeText;\n\n@optional\n- (void)didCopyCode:(NSString *)code;\n\n- (instancetype)initWithStyles:(AMTextStyles *)styles;\n\n+ (CGSize)sizeThatFits:(CGSize)size\n                  code:(NSString *)code\n              language:(nullable NSString *)lang\n                styles:(AMTextStyles *)styles;\n\n@end\n\n@interface AMCodeViewAttachment : AMViewAttachment\n@property (nonatomic, readonly, nullable) UIView<AMCodeView> *view;\n@property (nonatomic) BOOL partialUpdate;\n@property (nonatomic, nullable) NSString *language;\n@property (nonatomic) NSString *code;\n\n+ (Class<AMCodeView>)codeViewClass;    // Default is AMMarkdownCodeView\n\n+ (instancetype)attachmentWithCode:(NSString *)code\n                          language:(nullable NSString *)hint\n                            styles:(nullable AMTextStyles *)styles;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMCodeViewAttachment.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMCodeViewAttachment.h\"\n#import \"AMMarkdownCodeView.h\"\n#import \"AMCodeHighlighter.h\"\n#import \"UITextView+AntMarkdown.h\"\n#import \"AMTextStyles.h\"\n#import \"AMUtils.h\"\n#import \"CMCascadingAttributeStack.h\"\n\n@implementation AMCodeViewAttachment\n{\n    AMTextStyles        * _styles;\n    UIView<AMCodeView>  * _codeView;\n}\n\n+ (instancetype)attachmentWithCode:(NSString *)code\n                          language:(NSString *)hint\n                            styles:(AMTextStyles *)styles\n{\n    AMCodeViewAttachment *a = [[self alloc] initWithStyles:styles];\n    \n    if (styles.highlightCodeOnRender) {\n        AMCodeHighlighter *highlighter = [self.class highlighterForStyles:styles];\n        [highlighter highlightCodeString:code language:hint];\n    }\n    \n    a.code = code;\n    a.language = hint;\n    return a;\n}\n\n+ (Class)codeViewClass\n{\n    return [AMMarkdownCodeView class];\n}\n\n- (instancetype)initWithStyles:(AMTextStyles *)styles\n{\n    self = [super init];\n    if (self) {\n        _styles = styles;\n    }\n    return self;\n}\n\n- (void)dealloc\n{\n    \n}\n\n+ (AMCodeHighlighter *)highlighterForStyles:(AMTextStyles *)styles {\n    static dispatch_once_t onceToken;\n    static NSCache<NSNumber *, AMCodeHighlighter *> * cached = nil;\n    dispatch_once(&onceToken, ^{\n        cached = [[NSCache alloc] init];\n    });\n    \n    AMCodeHighlighter *h = [cached objectForKey:@(styles.hash)];\n    if (!h) {\n        h = [[AMCodeHighlighter alloc] initWithStyles:styles];\n        AMLogDebug(@\"Create new highlighter with style: %@\", styles);\n        [cached setObject:h forKey:@(styles.hash)];\n    }\n    return h;\n}\n\n+ (dispatch_queue_t)highlighterQueue {\n    static dispatch_once_t onceToken;\n    static dispatch_queue_t _queue;\n    dispatch_once(&onceToken, ^{\n        _queue = dispatch_queue_create(\"Code Highlight Queue\", DISPATCH_QUEUE_SERIAL);\n    });\n    return _queue;\n}\n\n- (void)highlightCode {\n    @weakify(self);\n    dispatch_async([self.class highlighterQueue], ^{\n        @strongify(self);\n        if (!self) {\n            return;\n        }\n        AMCodeHighlighter *highlighter = [self.class highlighterForStyles:self->_styles];\n        NSAttributedString *attr = [highlighter highlightCodeString:self.code language:self.language];\n        if (self->_styles) {\n            if (self->_styles.codeBlockAttributes.stringAttributes[NSBackgroundColorAttributeName] && attr) {\n                NSMutableAttributedString* tmp = [[NSMutableAttributedString alloc] initWithAttributedString:attr];\n                [tmp addAttribute:NSBackgroundColorAttributeName value:self->_styles.codeBlockAttributes.stringAttributes[NSBackgroundColorAttributeName] range:NSMakeRange(0, attr.string.length)];\n                attr = tmp;\n            }\n        }\n        dispatch_async(dispatch_get_main_queue(), ^{\n            if (self) {\n                [self->_codeView setAttributedCodeText:attr];\n            }\n        });\n    });\n}\n\n- (void)setLanguage:(NSString *)language\n{\n    _language = language;\n    [_codeView setLanguage:language];\n}\n\n- (void)setCode:(NSString *)code\n{\n    if (![_code isEqualToString:code]) {\n        _code = code;\n        \n        [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(highlightCode) object:nil];\n        \n        AMCodeHighlighter *highlighter = [self.class highlighterForStyles:self->_styles];\n        NSAttributedString *attr = [highlighter cachedAttributedCodeForCode:code language:self.language];\n        if (attr) {\n            AMLogDebug(@\"hit highlighter cache on code setter\", nil);\n            [_codeView setAttributedCodeText:attr];\n        } else {\n            [_codeView setPlainCodeText:code];\n            [_codeView setLanguage:self.language];\n            [self performSelector:@selector(highlightCode) withObject:nil afterDelay:0.3];\n        }\n    }\n}\n\n- (CGSize)sizeThatFits:(CGSize)size\n{\n    if ([NSThread isMainThread] && [self viewIfLoaded]) {\n        return [self.view sizeThatFits:size];\n    } else {\n        Class<AMCodeView> cls = [self.class codeViewClass];\n        if ([cls respondsToSelector:@selector(sizeThatFits:code:language:styles:)]) {\n            return [cls sizeThatFits:size code:self.code language:self.language styles:_styles];\n        } else {\n            return [self.view sizeThatFits:size];\n        }\n    }\n}\n\n- (__kindof UIView *)view\n{\n    if (!_codeView) {\n        Class cls = [self.class codeViewClass];\n        if ([cls instancesRespondToSelector:@selector(initWithStyles:)]) {\n            _codeView = [[cls alloc] initWithStyles:self->_styles];\n        } else {\n            _codeView = [[cls alloc] init];\n        }\n        NSAssert([_codeView conformsToProtocol:@protocol(AMCodeView)], @\"Class %@ must confirms to AMCodeView\", cls);\n\n        [_codeView setLanguage:self.language];\n        \n        if ([_codeView isKindOfClass:[AMMarkdownCodeView class]]) {\n            ((AMMarkdownCodeView *)_codeView).partialUpdate = self.partialUpdate;\n        }\n        \n        AMCodeHighlighter *highlighter = [self.class highlighterForStyles:self->_styles];\n        NSAttributedString *attr = [highlighter cachedAttributedCodeForCode:self.code language:self.language];\n        if (attr) {\n            AMLogDebug(@\"hit highlighter cache on view create\", nil);\n            [_codeView setAttributedCodeText:attr];\n        } else {\n            [_codeView setPlainCodeText:self.code];\n        }\n    }\n    return _codeView;\n}\n\n- (__kindof UIView<AMAttachedView> *)viewIfLoaded\n{\n    return _codeView;\n}\n\n- (BOOL)isEqualToAttachment:(AMCodeViewAttachment *)attach\n{\n    return [self.language isEqualToString:attach.language]\n    && [self.code isEqualToString:attach.code];\n}\n\n- (void)updateAttachmentFromAttachment:(AMCodeViewAttachment *)attach\n{\n    [super updateAttachmentFromAttachment:attach];\n    self.partialUpdate = YES;\n    if ([_codeView isKindOfClass:[AMMarkdownCodeView class]]) {\n        ((AMMarkdownCodeView *)_codeView).partialUpdate = self.partialUpdate;\n    }\n    self.language = attach.language;\n    self.code = attach.code;\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMDrawable.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@protocol AMDrawable <NSObject>\n\n- (void)drawInRect:(CGRect)rect clipEdges:(UIRectEdge)edges;\n\n@optional\n- (BOOL)isInline;\n\n@end\n\n@protocol AMUnderlineDrawable <NSObject>\n\n- (void)drawInRect:(CGRect)rect underlineStyle:(NSUnderlineStyle)type baselineOffset:(CGFloat)offset;\n\n@end\n\n/**\n * value is any AMDrawable\n */\nUIKIT_EXTERN NSAttributedStringKey const AMBackgroundDrawableAttributeName;\nUIKIT_EXTERN NSAttributedStringKey const AMUnderlineDrawableAttributeName;\n\n@interface UIImage (AMDrawable) <AMDrawable>\n\n@end\n\n@interface UIColor (AMDrawable) <AMDrawable>\n\n@end\n\n@interface CALayer (AMDrawable) <AMDrawable>\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMDrawable.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n#import \"AMDrawable.h\"\n\nNSAttributedStringKey const AMBackgroundDrawableAttributeName = @\"AMBackgroundDrawableAttributeName\";\nNSAttributedStringKey const AMUnderlineDrawableAttributeName = @\"AMUnderlineDrawableAttributeName\";\n\n@implementation UIImage (AMDrawable)\n\n- (void)drawInRect:(CGRect)rect clipEdges:(UIRectEdge)edges {\n    [self drawInRect:rect];\n}\n\n@end\n\n@implementation UIColor (AMDrawable)\n\n- (void)drawInRect:(CGRect)rect clipEdges:(UIRectEdge)edges {\n    [self setFill];\n    CGContextFillRect(UIGraphicsGetCurrentContext(), rect);\n}\n\n@end\n\n@implementation CALayer (AMDrawable)\n\n- (void)drawInRect:(CGRect)rect clipEdges:(UIRectEdge)edges {\n    [self drawInContext:UIGraphicsGetCurrentContext()];\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMEmojiManager.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMEmojiManager : NSObject\n\n+ (instancetype)sharedManager;\n\n- (NSString *)emojiWithName:(NSString *)name;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMEmojiManager.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMEmojiManager.h\"\n\n@interface AMEmojiManager()\n\n@property (nonatomic, strong) NSDictionary *emojiMap;\n\n@end\n\n@implementation AMEmojiManager\n\n+ (instancetype)sharedManager {\n    static dispatch_once_t onceToken;\n    static AMEmojiManager *manager;\n    dispatch_once(&onceToken, ^{\n        manager = [AMEmojiManager new];\n    });\n    return manager;\n}\n\n- (instancetype)init {\n    if (self = [super init]) {\n        _emojiMap = @{\n            @\"curling_stone\" :@\"🥌\",\n            @\"dominican_republic\" :@\"🇩🇴\",\n            @\"heavy_heart_exclamation\" :@\"❣️\",\n            @\"global\" :@\"🌐\",\n            @\"cockroach\" :@\"🪳\",\n            @\"technologist\" :@\"🧑‍💻\",\n            @\"red_haired_man\" :@\"👨‍🦰\",\n            @\"corn\" :@\"🌽\",\n            @\"sync\" :@\"🔄\",\n            @\"next_track_button\" :@\"⏭️\",\n            @\"hot_face\" :@\"🥵\",\n            @\"rugby_football\" :@\"🏉\",\n            @\"children_crossing\" :@\"🚸\",\n            @\"vomiting_face\" :@\"🤮\",\n            @\"shiny\" :@\"✨\",\n            @\"clinking_glasses\" :@\"🥂\",\n            @\"ninja\" :@\"🥷\",\n            @\"milestone\" :@\"🏁\",\n            @\"red_car\" :@\"🚗\",\n            @\"retro\" :@\"👾\",\n            @\"liechtenstein\" :@\"🇱🇮\",\n            @\"clock930\" :@\"🕤\",\n            @\"spiral_calendar\" :@\"🗓️\",\n            @\"uzbekistan\" :@\"🇺🇿\",\n            @\"funeral_urn\" :@\"⚱️\",\n            @\"worm\" :@\"🪱\",\n            @\"passenger_ship\" :@\"🛳️\",\n            @\"monorail\" :@\"🚝\",\n            @\"flight_departure\" :@\"🛫\",\n            @\"earth_africa\" :@\"🌍\",\n            @\"chopsticks\" :@\"🥢\",\n            @\"rightwards_pushing_hand\" :@\"🫸\",\n            @\"design\" :@\"🎨\",\n            @\"rockstar\" :@\"👨‍🎤\",\n            @\"pencil\" :@\"📝\",\n            @\"arrow_down\" :@\"⬇️\",\n            @\"parachute\" :@\"🪂\",\n            @\"england\" :@\"🏴󠁧󠁢󠁥󠁮󠁧󠁿\",\n            @\"six_pointed_star\" :@\"🔯\",\n            @\"merman\" :@\"🧜‍♂️\",\n            @\"bridge_at_night\" :@\"🌉\",\n            @\"radio_button\" :@\"🔘\",\n            @\"turkmenistan\" :@\"🇹🇲\",\n            @\"giraffe\" :@\"🦒\",\n            @\"blond_haired_man\" :@\"👱‍♂️\",\n            @\"disapprove\" :@\"👎\",\n            @\"bearded_person\" :@\"🧔\",\n            @\"romania\" :@\"🇷🇴\",\n            @\"man_feeding_baby\" :@\"👨‍🍼\",\n            @\"macedonia\" :@\"🇲🇰\",\n            @\"japanese_ogre\" :@\"👹\",\n            @\"raised_back_of_hand\" :@\"🤚\",\n            @\"sing\" :@\"🎤\",\n            @\"stadium\" :@\"🏟️\",\n            @\"approve\" :@\"👍\",\n            @\"niue\" :@\"🇳🇺\",\n            @\"mailbox_with_no_mail\" :@\"📭\",\n            @\"information_source\" :@\"ℹ️\",\n            @\"vibration_mode\" :@\"📳\",\n            @\"silver\" :@\"🥈\",\n            @\"happy\" :@\"😀\",\n            @\"floppy_disk\" :@\"💾\",\n            @\"papua_new_guinea\" :@\"🇵🇬\",\n            @\"apple\" :@\"🍎\",\n            @\"flying_disc\" :@\"🥏\",\n            @\"prince\" :@\"🤴\",\n            @\"star2\" :@\"🌟\",\n            @\"beach_umbrella\" :@\"🏖️\",\n            @\"cutlery\" :@\"🍴\",\n            @\"see_no_evil\" :@\"🙈\",\n            @\"south_africa\" :@\"🇿🇦\",\n            @\"lithuania\" :@\"🇱🇹\",\n            @\"smartphone\" :@\"📱\",\n            @\"panama\" :@\"🇵🇦\",\n            @\"bacon\" :@\"🥓\",\n            @\"man_firefighter\" :@\"👨‍🚒\",\n            @\"kenya\" :@\"🇰🇪\",\n            @\"speechless\" :@\"😯\",\n            @\"owl\" :@\"🦉\",\n            @\"desert_island\" :@\"🏝️\",\n            @\"standing_man\" :@\"🧍‍♂️\",\n            @\"eight\" :@\"8️⃣\",\n            @\"tempura\" :@\"🍤\",\n            @\"u7121\" :@\"🈚\",\n            @\"fairy\" :@\"🧚\",\n            @\"haircut\" :@\"💇\",\n            @\"paw_prints\" :@\"🐾\",\n            @\"left_luggage\" :@\"🛅\",\n            @\"hut\" :@\"🛖\",\n            @\"place_of_worship\" :@\"🛐\",\n            @\"baby_symbol\" :@\"🚼\",\n            @\"camping\" :@\"🏕️\",\n            @\"mantelpiece_clock\" :@\"🕰️\",\n            @\"benin\" :@\"🇧🇯\",\n            @\"melon\" :@\"🍈\",\n            @\"office\" :@\"🏢\",\n            @\"tulip\" :@\"🌷\",\n            @\"ledger\" :@\"📒\",\n            @\"wrestling\" :@\"🤼\",\n            @\"mongolia\" :@\"🇲🇳\",\n            @\"new_moon_with_face\" :@\"🌚\",\n            @\"sunny\" :@\"☀️\",\n            @\"parking\" :@\"🅿️\",\n            @\"pool\" :@\"🎱\",\n            @\"syringe\" :@\"💉\",\n            @\"sewing_needle\" :@\"🪡\",\n            @\"space_invader\" :@\"👾\",\n            @\"compass\" :@\"🧭\",\n            @\"triumph\" :@\"😤\",\n            @\"couple_with_heart_man_man\" :@\"👨‍❤️‍👨\",\n            @\"pear\" :@\"🍐\",\n            @\"pleased\" :@\"😄\",\n            @\"tipping_hand_man\" :@\"💁‍♂️\",\n            @\"clock830\" :@\"🕣\",\n            @\"canoe\" :@\"🛶\",\n            @\"nervous\" :@\"😟\",\n            @\"trumpet\" :@\"🎺\",\n            @\"serbia\" :@\"🇷🇸\",\n            @\"cloud\" :@\"☁️\",\n            @\"skyline\" :@\"🏙️\",\n            @\"mouse\" :@\"🐭\",\n            @\"coffee\" :@\"☕\",\n            @\"woman_artist\" :@\"👩‍🎨\",\n            @\"heartpulse\" :@\"💗\",\n            @\"dagger\" :@\"🗡️\",\n            @\"jamaica\" :@\"🇯🇲\",\n            @\"flags\" :@\"🎏\",\n            @\"albania\" :@\"🇦🇱\",\n            @\"scientist\" :@\"🧑‍🔬\",\n            @\"goofy\" :@\"🤪\",\n            @\"clock1030\" :@\"🕥\",\n            @\"ram\" :@\"🐏\",\n            @\"sound\" :@\"👂\",\n            @\"fist_oncoming\" :@\"👊\",\n            @\"glasses\" :@\"🤓\",\n            @\"shrug\" :@\"🤷\",\n            @\"menorah\" :@\"🕎\",\n            @\"red_circle\" :@\"🔴\",\n            @\"sports\" :@\"⚽\",\n            @\"sled\" :@\"🛷\",\n            @\"family_woman_woman_boy\" :@\"👩‍👩‍👦\",\n            @\"poop\" :@\"💩\",\n            @\"restroom\" :@\"🚻\",\n            @\"interrobang\" :@\"⁉️\",\n            @\"walking_woman\" :@\"🚶‍♀️\",\n            @\"tristan_da_cunha\" :@\"🇹🇦\",\n            @\"rain\" :@\"🌂\",\n            @\"point_up_2\" :@\"👆\",\n            @\"motorway\" :@\"🛣️\",\n            @\"sauna_person\" :@\"🧖\",\n            @\"cricket_game\" :@\"🏏\",\n            @\"thunder\" :@\"⚡\",\n            @\"gorilla\" :@\"🦍\",\n            @\"sparkle\" :@\"❇️\",\n            @\"moneybag\" :@\"💰\",\n            @\"police_officer\" :@\"👮\",\n            @\"collision\" :@\"💥\",\n            @\"ophiuchus\" :@\"⛎\",\n            @\"wedding\" :@\"🤵\",\n            @\"crossed_swords\" :@\"⚔️\",\n            @\"kazakhstan\" :@\"🇰🇿\",\n            @\"wood\" :@\"🌲\",\n            @\"chart_with_downwards_trend\" :@\"📉\",\n            @\"curly_haired_woman\" :@\"👩‍🦱\",\n            @\"satisfied\" :@\"😆\",\n            @\"rat\" :@\"🐀\",\n            @\"umbrella\" :@\"☔\",\n            @\"dad\" :@\"👨\",\n            @\"invisible\" :@\"🫥\",\n            @\"motor_boat\" :@\"🛥️\",\n            @\"mermaid\" :@\"🧜‍♀️\",\n            @\"eject_button\" :@\"⏏️\",\n            @\"snowflake\" :@\"❄️\",\n            @\"kiribati\" :@\"🇰🇮\",\n            @\"tanabata_tree\" :@\"🎋\",\n            @\"sandwich\" :@\"🥪\",\n            @\"knot\" :@\"🪢\",\n            @\"gasp\" :@\"🫢\",\n            @\"top\" :@\"🔝\",\n            @\"woman_farmer\" :@\"👩‍🌾\",\n            @\"wavy_dash\" :@\"〰️\",\n            @\"emergency\" :@\"🚨\",\n            @\"man_mechanic\" :@\"👨‍🔧\",\n            @\"dinner\" :@\"🍽️\",\n            @\"open_mouth\" :@\"😮\",\n            @\"newborn\" :@\"👶\",\n            @\"monkey_face\" :@\"🐵\",\n            @\"haircut_man\" :@\"💇‍♂️\",\n            @\"no_mobile_phones\" :@\"📵\",\n            @\"cook_islands\" :@\"🇨🇰\",\n            @\"oncoming_police_car\" :@\"🚔\",\n            @\"frowning_person\" :@\"🙍\",\n            @\"golfing_woman\" :@\"🏌️‍♀️\",\n            @\"hamburger\" :@\"🍔\",\n            @\"potted_plant\" :@\"🪴\",\n            @\"cook\" :@\"🧑‍🍳\",\n            @\"couple\" :@\"🧑‍🤝‍🧑\",\n            @\"woman_playing_water_polo\" :@\"🤽‍♀️\",\n            @\"sponge\" :@\"🧽\",\n            @\"military_helmet\" :@\"🪖\",\n            @\"cool\" :@\"😎\",\n            @\"yen\" :@\"💴\",\n            @\"man_playing_water_polo\" :@\"🤽‍♂️\",\n            @\"fog\" :@\"🌫️\",\n            @\"roll_of_paper\" :@\"🧻\",\n            @\"family_woman_woman_boy_boy\" :@\"👩‍👩‍👦‍👦\",\n            @\"bhutan\" :@\"🇧🇹\",\n            @\"girl\" :@\"👧\",\n            @\"theater\" :@\"🎭\",\n            @\"postbox\" :@\"📮\",\n            @\"shopping\" :@\"🛍️\",\n            @\"beach\" :@\"🐚\",\n            @\"smoking\" :@\"🚬\",\n            @\"heart_hands\" :@\"🫶\",\n            @\"royal\" :@\"🤴\",\n            @\"policeman\" :@\"👮‍♂️\",\n            @\"911\" :@\"🚨\",\n            @\"dominica\" :@\"🇩🇲\",\n            @\"cloud_with_rain\" :@\"🌧️\",\n            @\"male_sign\" :@\"♂️\",\n            @\"germ\" :@\"🦠\",\n            @\"santa\" :@\"🎅\",\n            @\"tomato\" :@\"🍅\",\n            @\"cup_with_straw\" :@\"🥤\",\n            @\"no_bicycles\" :@\"🚳\",\n            @\"recorder\" :@\"🪈\",\n            @\"spaghetti\" :@\"🍝\",\n            @\"bicep\" :@\"💪\",\n            @\"kneeling_man\" :@\"🧎‍♂️\",\n            @\"trident\" :@\"🔱\",\n            @\"rage\" :@\"😡\",\n            @\"tm\" :@\"™️\",\n            @\"yes\" :@\"🆗\",\n            @\"clock730\" :@\"🕢\",\n            @\"directory\" :@\"📁\",\n            @\"mind\" :@\"🤯\",\n            @\"science\" :@\"🔬\",\n            @\"cote_divoire\" :@\"🇨🇮\",\n            @\"fountain_pen\" :@\"🖋️\",\n            @\"tr\" :@\"🇹🇷\",\n            @\"orthodox_cross\" :@\"☦️\",\n            @\"chipmunk\" :@\"🐿️\",\n            @\"clapper\" :@\"🎬\",\n            @\"ping_pong\" :@\"🏓\",\n            @\"large_blue_circle\" :@\"🔵\",\n            @\"man_cook\" :@\"👨‍🍳\",\n            @\"computer\" :@\"💻\",\n            @\"ireland\" :@\"🇮🇪\",\n            @\"martinique\" :@\"🇲🇶\",\n            @\"deer\" :@\"🦌\",\n            @\"tv\" :@\"📺\",\n            @\"motorized_wheelchair\" :@\"🦼\",\n            @\"knife\" :@\"🔪\",\n            @\"aland_islands\" :@\"🇦🇽\",\n            @\"guinea\" :@\"🇬🇳\",\n            @\"massage_woman\" :@\"💆‍♀️\",\n            @\"four_leaf_clover\" :@\"🍀\",\n            @\"biohazard\" :@\"☣️\",\n            @\"singapore\" :@\"🇸🇬\",\n            @\"bunny\" :@\"👯\",\n            @\"groggy\" :@\"🥴\",\n            @\"christmas\" :@\"🎅\",\n            @\"pregnant_woman\" :@\"🤰\",\n            @\"night\" :@\"🌙\",\n            @\"wastebasket\" :@\"🗑️\",\n            @\"sake\" :@\"🍶\",\n            @\"train\" :@\"🚂\",\n            @\"university\" :@\"🎓\",\n            @\"hungary\" :@\"🇭🇺\",\n            @\"blueberries\" :@\"🫐\",\n            @\"canada\" :@\"🫎\",\n            @\"large_orange_diamond\" :@\"🔶\",\n            @\"eggplant\" :@\"🍆\",\n            @\"reunion\" :@\"🇷🇪\",\n            @\"rice_cracker\" :@\"🍘\",\n            @\"australia\" :@\"🇦🇺\",\n            @\"horror\" :@\"😱\",\n            @\"cloud_with_snow\" :@\"🌨️\",\n            @\"united_arab_emirates\" :@\"🇦🇪\",\n            @\"full_moon_with_face\" :@\"🌝\",\n            @\"formal\" :@\"👔\",\n            @\"popcorn\" :@\"🍿\",\n            @\"weight_lifting\" :@\"🏋️\",\n            @\"swimmer\" :@\"🏊\",\n            @\"toothbrush\" :@\"🪥\",\n            @\"block\" :@\"🚫\",\n            @\"volleyball\" :@\"🏐\",\n            @\"lotus_position_man\" :@\"🧘‍♂️\",\n            @\"new_moon\" :@\"🌑\",\n            @\"butter\" :@\"🧈\",\n            @\"waning_crescent_moon\" :@\"🌘\",\n            @\"busstop\" :@\"🚏\",\n            @\"bubbly\" :@\"🍾\",\n            @\"china\" :@\"🇨🇳\",\n            @\"unicorn\" :@\"🦄\",\n            @\"barber\" :@\"💈\",\n            @\"croatia\" :@\"🇭🇷\",\n            @\"st_kitts_nevis\" :@\"🇰🇳\",\n            @\"female_detective\" :@\"🕵️‍♀️\",\n            @\"slovenia\" :@\"🇸🇮\",\n            @\"elephant\" :@\"🐘\",\n            @\"dice\" :@\"🎲\",\n            @\"teddy_bear\" :@\"🧸\",\n            @\"women_wrestling\" :@\"🤼‍♀️\",\n            @\"skier\" :@\"⛷️\",\n            @\"pink_heart\" :@\"🩷\",\n            @\"fr\" :@\"🇫🇷\",\n            @\"arrow_up_small\" :@\"🔼\",\n            @\"pager\" :@\"📟\",\n            @\"elf\" :@\"🧝\",\n            @\"game_die\" :@\"🎲\",\n            @\"heart_eyes_cat\" :@\"😻\",\n            @\"fu\" :@\"🖕\",\n            @\"stew\" :@\"🍲\",\n            @\"white_medium_square\" :@\"◻️\",\n            @\"college\" :@\"🎓\",\n            @\"genie\" :@\"🧞\",\n            @\"ignore\" :@\"🙈\",\n            @\"haiti\" :@\"🇭🇹\",\n            @\"palau\" :@\"🇵🇼\",\n            @\"wallis_futuna\" :@\"🇼🇫\",\n            @\"headphones\" :@\"🎧\",\n            @\"spa\" :@\"💆\",\n            @\"man_playing_handball\" :@\"🤾‍♂️\",\n            @\"point_down\" :@\"👇\",\n            @\"sao_tome_principe\" :@\"🇸🇹\",\n            @\"female_sign\" :@\"♀️\",\n            @\"salt\" :@\"🧂\",\n            @\"croissant\" :@\"🥐\",\n            @\"roll_eyes\" :@\"🙄\",\n            @\"whale2\" :@\"🐋\",\n            @\"womens\" :@\"🚺\",\n            @\"man_pilot\" :@\"👨‍✈️\",\n            @\"blonde_woman\" :@\"👱‍♀️\",\n            @\"transgender_flag\" :@\"🏳️‍⚧️\",\n            @\"fearful\" :@\"😨\",\n            @\"church\" :@\"⛪\",\n            @\"st_barthelemy\" :@\"🇧🇱\",\n            @\"traffic_light\" :@\"🚥\",\n            @\"duck\" :@\"🦆\",\n            @\"black_circle\" :@\"⚫\",\n            @\"spider_web\" :@\"🕸️\",\n            @\"key\" :@\"🔑\",\n            @\"moon_cake\" :@\"🥮\",\n            @\"policewoman\" :@\"👮‍♀️\",\n            @\"disco\" :@\"🪩\",\n            @\"melting_face\" :@\"🫠\",\n            @\"surfer\" :@\"🏄\",\n            @\"man_cartwheeling\" :@\"🤸‍♂️\",\n            @\"dizzy_face\" :@\"😵\",\n            @\"old_key\" :@\"🗝️\",\n            @\"grinning\" :@\"😀\",\n            @\"nesting_dolls\" :@\"🪆\",\n            @\"family_man_boy\" :@\"👨‍👦\",\n            @\"pushpin\" :@\"📌\",\n            @\"end\" :@\"🔚\",\n            @\"index_pointing_at_the_viewer\" :@\"🫵\",\n            @\"star_of_david\" :@\"✡️\",\n            @\"scroll\" :@\"📜\",\n            @\"argentina\" :@\"🇦🇷\",\n            @\"needle\" :@\"💉\",\n            @\"us_outlying_islands\" :@\"🇺🇲\",\n            @\"ice_skate\" :@\"⛸️\",\n            @\"archery\" :@\"🏹\",\n            @\"briefcase\" :@\"💼\",\n            @\"film\" :@\"🎥\",\n            @\"transgender_symbol\" :@\"⚧️\",\n            @\"black_small_square\" :@\"▪️\",\n            @\"clock630\" :@\"🕡\",\n            @\"praise\" :@\"👏\",\n            @\"massage\" :@\"💆\",\n            @\"tamale\" :@\"🫔\",\n            @\"burger\" :@\"🍔\",\n            @\"smirk\" :@\"😏\",\n            @\"greece\" :@\"🇬🇷\",\n            @\"diamond_shape_with_a_dot_inside\" :@\"💠\",\n            @\"bald_man\" :@\"👨‍🦲\",\n            @\"french_southern_territories\" :@\"🇹🇫\",\n            @\"woman_cartwheeling\" :@\"🤸‍♀️\",\n            @\"keeling\" :@\"🇨🇨\",\n            @\"anguilla\" :@\"🇦🇮\",\n            @\"thread\" :@\"🧵\",\n            @\"zany_face\" :@\"🤪\",\n            @\"sushi\" :@\"🍣\",\n            @\"weather\" :@\"☀️\",\n            @\"family\" :@\"👪\",\n            @\"hijab\" :@\"🧕\",\n            @\"mustache\" :@\"👨\",\n            @\"mens\" :@\"🚹\",\n            @\"maldives\" :@\"🇲🇻\",\n            @\"user\" :@\"👤\",\n            @\"manicure\" :@\"💅\",\n            @\"shower\" :@\"🛀\",\n            @\"cold\" :@\"❄️\",\n            @\"international\" :@\"🌍\",\n            @\"ring_buoy\" :@\"🛟\",\n            @\"snake\" :@\"🐍\",\n            @\"ideograph_advantage\" :@\"🉐\",\n            @\"fairy_man\" :@\"🧚‍♂️\",\n            @\"faroe_islands\" :@\"🇫🇴\",\n            @\"party\" :@\"🎂\",\n            @\"chocolates\" :@\"💝\",\n            @\"monaco\" :@\"🇲🇨\",\n            @\"mexico\" :@\"🇲🇽\",\n            @\"purse\" :@\"👛\",\n            @\"svalbard_jan_mayen\" :@\"🇸🇯\",\n            @\"two\" :@\"2️⃣\",\n            @\"proud\" :@\"😊\",\n            @\"uruguay\" :@\"🇺🇾\",\n            @\"outbox_tray\" :@\"📤\",\n            @\"flying_saucer\" :@\"🛸\",\n            @\"british_indian_ocean_territory\" :@\"🇮🇴\",\n            @\"suspension_railway\" :@\"🚟\",\n            @\"1234\" :@\"🔢\",\n            @\"mule\" :@\"🫏\",\n            @\"fresh\" :@\"🆕\",\n            @\"sleepy\" :@\"😪\",\n            @\"vampire_man\" :@\"🧛‍♂️\",\n            @\"control_knobs\" :@\"🎛️\",\n            @\"fondue\" :@\"🫕\",\n            @\"beginner\" :@\"🔰\",\n            @\"group\" :@\"👥\",\n            @\"tipping_hand_woman\" :@\"💁‍♀️\",\n            @\"100\" :@\"💯\",\n            @\"nut_and_bolt\" :@\"🔩\",\n            @\"blond_haired_woman\" :@\"👱‍♀️\",\n            @\"frowning_face\" :@\"☹️\",\n            @\"heart_decoration\" :@\"💟\",\n            @\"flamingo\" :@\"🦩\",\n            @\"chains\" :@\"⛓️\",\n            @\"bison\" :@\"🦬\",\n            @\"sweet_potato\" :@\"🍠\",\n            @\"tokelau\" :@\"🇹🇰\",\n            @\"man_with_gua_pi_mao\" :@\"👲\",\n            @\"flex\" :@\"💪\",\n            @\"afghanistan\" :@\"🇦🇫\",\n            @\"memo\" :@\"📝\",\n            @\"angel\" :@\"😇\",\n            @\"peacock\" :@\"🦚\",\n            @\"love\" :@\"🥰\",\n            @\"switzerland\" :@\"🇨🇭\",\n            @\"wolf\" :@\"🐺\",\n            @\"tracks\" :@\"👣\",\n            @\"spicy\" :@\"🌶️\",\n            @\"spain\" :@\"🇪🇸\",\n            @\"droplet\" :@\"💧\",\n            @\"british\" :@\"🇬🇧\",\n            @\"radioactive\" :@\"☢️\",\n            @\"smiley\" :@\"😃\",\n            @\"pilot\" :@\"🧑‍✈️\",\n            @\"trophy\" :@\"🏆\",\n            @\"milk_glass\" :@\"🥛\",\n            @\"malawi\" :@\"🇲🇼\",\n            @\"woman_beard\" :@\"🧔‍♀️\",\n            @\"bald_woman\" :@\"👩‍🦲\",\n            @\"rose\" :@\"🌹\",\n            @\"accordion\" :@\"🪗\",\n            @\"haircut_woman\" :@\"💇‍♀️\",\n            @\"accessibility\" :@\"♿\",\n            @\"cyprus\" :@\"🇨🇾\",\n            @\"falkland_islands\" :@\"🇫🇰\",\n            @\"wireless\" :@\"🛜\",\n            @\"quiet\" :@\"🤭\",\n            @\"closed_umbrella\" :@\"🌂\",\n            @\"leftwards_hand\" :@\"🫲\",\n            @\"hush\" :@\"🤐\",\n            @\"person_feeding_baby\" :@\"🧑‍🍼\",\n            @\"graph\" :@\"📈\",\n            @\"synagogue\" :@\"🕍\",\n            @\"dead\" :@\"💀\",\n            @\"kissing_heart\" :@\"😘\",\n            @\"elf_woman\" :@\"🧝‍♀️\",\n            @\"tooth\" :@\"🦷\",\n            @\"mali\" :@\"🇲🇱\",\n            @\"woman_scientist\" :@\"👩‍🔬\",\n            @\"bouldering\" :@\"🧗\",\n            @\"straight_ruler\" :@\"📏\",\n            @\"speed\" :@\"🐎\",\n            @\"sailboat\" :@\"⛵\",\n            @\"fortune\" :@\"🔮\",\n            @\"time\" :@\"⌛\",\n            @\"green\" :@\"🍵\",\n            @\"somalia\" :@\"🇸🇴\",\n            @\"users\" :@\"👥\",\n            @\"light_blue_heart\" :@\"🩵\",\n            @\"business\" :@\"👨‍💼\",\n            @\"ascension_island\" :@\"🇦🇨\",\n            @\"woman_factory_worker\" :@\"👩‍🏭\",\n            @\"deciduous_tree\" :@\"🌳\",\n            @\"milk\" :@\"🍼\",\n            @\"hash\" :@\"#️⃣\",\n            @\"sunglasses\" :@\"😎\",\n            @\"arrow_double_down\" :@\"⏬\",\n            @\"mailbox_with_mail\" :@\"📬\",\n            @\"burrito\" :@\"🌯\",\n            @\"deaf\" :@\"🙉\",\n            @\"cheers\" :@\"🥂\",\n            @\"goat\" :@\"🐐\",\n            @\"movie\" :@\"🎦\",\n            @\"biking_woman\" :@\"🚴‍♀️\",\n            @\"weary\" :@\"😩\",\n            @\"man_astronaut\" :@\"👨‍🚀\",\n            @\"kick_scooter\" :@\"🛴\",\n            @\"woman_pilot\" :@\"👩‍✈️\",\n            @\"clock530\" :@\"🕠\",\n            @\"controller\" :@\"🎮\",\n            @\"gambling\" :@\"🎲\",\n            @\"ok_person\" :@\"🙆\",\n            @\"arrow_down_small\" :@\"🔽\",\n            @\"madagascar\" :@\"🇲🇬\",\n            @\"fiji\" :@\"🇫🇯\",\n            @\"badminton\" :@\"🏸\",\n            @\"herb\" :@\"🌿\",\n            @\"cat2\" :@\"🐈\",\n            @\"amazed\" :@\"😲\",\n            @\"water_buffalo\" :@\"🐃\",\n            @\"older_woman\" :@\"👵\",\n            @\"horse\" :@\"🐴\",\n            @\"mountain_bicyclist\" :@\"🚵\",\n            @\"oil_drum\" :@\"🛢️\",\n            @\"golfing\" :@\"🏌️\",\n            @\"hocho\" :@\"🔪\",\n            @\"stop_button\" :@\"⏹️\",\n            @\"face_with_thermometer\" :@\"🤒\",\n            @\"dining\" :@\"🍽️\",\n            @\"light_rail\" :@\"🚈\",\n            @\"rowing_woman\" :@\"🚣‍♀️\",\n            @\"shoot\" :@\"🔫\",\n            @\"merperson\" :@\"🧜\",\n            @\"tent\" :@\"⛺\",\n            @\"paperclip\" :@\"📎\",\n            @\"goggles\" :@\"🥽\",\n            @\"graduation\" :@\"👨‍🎓\",\n            @\"otter\" :@\"🦦\",\n            @\"no_good_man\" :@\"🙅‍♂️\",\n            @\"mountain_railway\" :@\"🚞\",\n            @\"hammer\" :@\"🔨\",\n            @\"maple_leaf\" :@\"🍁\",\n            @\"garlic\" :@\"🧄\",\n            @\"waffle\" :@\"🧇\",\n            @\"ferris_wheel\" :@\"🎡\",\n            @\"deal\" :@\"🤝\",\n            @\"thinking\" :@\"🤔\",\n            @\"pizza\" :@\"🍕\",\n            @\"recycle\" :@\"♻️\",\n            @\"israel\" :@\"🇮🇱\",\n            @\"fallen_leaf\" :@\"🍂\",\n            @\"upside_down_face\" :@\"🙃\",\n            @\"anger\" :@\"💢\",\n            @\"low_brightness\" :@\"🔅\",\n            @\"couple_with_heart_woman_woman\" :@\"👩‍❤️‍👩\",\n            @\"espresso\" :@\"☕\",\n            @\"notebook_with_decorative_cover\" :@\"📔\",\n            @\"muscle\" :@\"💪\",\n            @\"part_alternation_mark\" :@\"〽️\",\n            @\"baggage_claim\" :@\"🛄\",\n            @\"shark\" :@\"🦈\",\n            @\"bag\" :@\"👜\",\n            @\"iran\" :@\"🇮🇷\",\n            @\"a\" :@\"🅰️\",\n            @\"man_in_tuxedo\" :@\"🤵‍♂️\",\n            @\"fire_extinguisher\" :@\"🧯\",\n            @\"b\" :@\"🅱️\",\n            @\"thanks\" :@\"🙇\",\n            @\"western_sahara\" :@\"🇪🇭\",\n            @\"numbers\" :@\"🔢\",\n            @\"ice\" :@\"🥶\",\n            @\"hippopotamus\" :@\"🦛\",\n            @\"drinks\" :@\"🍻\",\n            @\"vampire\" :@\"🧛\",\n            @\"thumbsup\" :@\"👍\",\n            @\"marshall_islands\" :@\"🇲🇭\",\n            @\"tuvalu\" :@\"🇹🇻\",\n            @\"norway\" :@\"🇳🇴\",\n            @\"8ball\" :@\"🎱\",\n            @\"blow\" :@\"💨\",\n            @\"rice\" :@\"🍚\",\n            @\"worried\" :@\"😟\",\n            @\"books\" :@\"📚\",\n            @\"lotus_position_woman\" :@\"🧘‍♀️\",\n            @\"wine_glass\" :@\"🍷\",\n            @\"morocco\" :@\"🇲🇦\",\n            @\"m\" :@\"Ⓜ️\",\n            @\"latvia\" :@\"🇱🇻\",\n            @\"wales\" :@\"🏴󠁧󠁢󠁷󠁬󠁳󠁿\",\n            @\"o\" :@\"⭕\",\n            @\"document\" :@\"📜\",\n            @\"billed_cap\" :@\"🧢\",\n            @\"iraq\" :@\"🇮🇶\",\n            @\"crossed_fingers\" :@\"🤞\",\n            @\"dog\" :@\"🐶\",\n            @\"bookmark_tabs\" :@\"📑\",\n            @\"game\" :@\"👾\",\n            @\"notes\" :@\"🎶\",\n            @\"woman_firefighter\" :@\"👩‍🚒\",\n            @\"calendar\" :@\"📅\",\n            @\"person_curly_hair\" :@\"🧑‍🦱\",\n            @\"v\" :@\"✌️\",\n            @\"search\" :@\"🔍\",\n            @\"x\" :@\"❌\",\n            @\"black_bird\" :@\"🐦‍⬛\",\n            @\"dumpling\" :@\"🥟\",\n            @\"rich\" :@\"🤑\",\n            @\"heavy_multiplication_x\" :@\"✖️\",\n            @\"greenland\" :@\"🇬🇱\",\n            @\"bow_and_arrow\" :@\"🏹\",\n            @\"star\" :@\"💫\",\n            @\"dollar\" :@\"💰\",\n            @\"belarus\" :@\"🇧🇾\",\n            @\"stats\" :@\"📊\",\n            @\"family_woman_boy_boy\" :@\"👩‍👦‍👦\",\n            @\"sunrise\" :@\"🌅\",\n            @\"frowning\" :@\"😦\",\n            @\"carrot\" :@\"🥕\",\n            @\"womans_hat\" :@\"👒\",\n            @\"flag\" :@\"🇩🇪\",\n            @\"clock430\" :@\"🕟\",\n            @\"man_in_motorized_wheelchair\" :@\"👨‍🦼\",\n            @\"cupcake\" :@\"🧁\",\n            @\"ok_woman\" :@\"🙆‍♀️\",\n            @\"bat\" :@\"🦇\",\n            @\"vacation\" :@\"🍹\",\n            @\"hamster\" :@\"🐹\",\n            @\"bamboo\" :@\"🎍\",\n            @\"pen\" :@\"🖊️\",\n            @\"flowers\" :@\"💐\",\n            @\"eyes\" :@\"🤩\",\n            @\"leafy_green\" :@\"🥬\",\n            @\"lungs\" :@\"🫁\",\n            @\"hooray\" :@\"🙌\",\n            @\"oyster\" :@\"🦪\",\n            @\"flute\" :@\"🪈\",\n            @\"pouting_face\" :@\"🙎\",\n            @\"ladder\" :@\"🪜\",\n            @\"japanese_goblin\" :@\"👺\",\n            @\"tiger2\" :@\"🐅\",\n            @\"arrow_up_down\" :@\"↕️\",\n            @\"cd\" :@\"💿\",\n            @\"family_man_man_boy\" :@\"👨‍👨‍👦\",\n            @\"nine\" :@\"9️⃣\",\n            @\"supervillain_woman\" :@\"🦹‍♀️\",\n            @\"white_haired_man\" :@\"👨‍🦳\",\n            @\"bosnia_herzegovina\" :@\"🇧🇦\",\n            @\"puerto_rico\" :@\"🇵🇷\",\n            @\"bath\" :@\"🛀\",\n            @\"jp\" :@\"🇯🇵\",\n            @\"superhero_woman\" :@\"🦸‍♀️\",\n            @\"hear_no_evil\" :@\"🙉\",\n            @\"door\" :@\"🚪\",\n            @\"no_good_woman\" :@\"🙅‍♀️\",\n            @\"raised_hand_with_fingers_splayed\" :@\"🖐️\",\n            @\"pet\" :@\"🐶\",\n            @\"firecracker\" :@\"🧨\",\n            @\"bed\" :@\"🛏️\",\n            @\"cl\" :@\"🆑\",\n            @\"sweat\" :@\"😥\",\n            @\"bee\" :@\"🐝\",\n            @\"aubergine\" :@\"🍆\",\n            @\"hurt\" :@\"🤕\",\n            @\"world_map\" :@\"🗺️\",\n            @\"flight\" :@\"✈️\",\n            @\"pineapple\" :@\"🍍\",\n            @\"crescent_moon\" :@\"🌙\",\n            @\"cn\" :@\"🇨🇳\",\n            @\"handball_person\" :@\"🤾\",\n            @\"yum\" :@\"😋\",\n            @\"plate_with_cutlery\" :@\"🍽️\",\n            @\"turks_caicos_islands\" :@\"🇹🇨\",\n            @\"man_health_worker\" :@\"👨‍⚕️\",\n            @\"frog\" :@\"🐸\",\n            @\"orange_heart\" :@\"🧡\",\n            @\"cherries\" :@\"🍒\",\n            @\"suspicious\" :@\"🤨\",\n            @\"firefighter\" :@\"🧑‍🚒\",\n            @\"headstone\" :@\"🪦\",\n            @\"troll\" :@\"🧌\",\n            @\"arrow_double_up\" :@\"⏫\",\n            @\"crossed_flags\" :@\"🎌\",\n            @\"basketball_woman\" :@\"⛹️‍♀️\",\n            @\"clock10\" :@\"🕙\",\n            @\"three\" :@\"3️⃣\",\n            @\"bride_with_veil\" :@\"👰‍♀️\",\n            @\"handshake\" :@\"🤝\",\n            @\"meat_on_bone\" :@\"🍖\",\n            @\"raised_hands\" :@\"🙌\",\n            @\"ocean\" :@\"🌊\",\n            @\"currency_exchange\" :@\"💱\",\n            @\"mailbox_closed\" :@\"📪\",\n            @\"spring\" :@\"🌸\",\n            @\"japan\" :@\"🗾\",\n            @\"ukraine\" :@\"🇺🇦\",\n            @\"crab\" :@\"🦀\",\n            @\"snowman\" :@\"⛄\",\n            @\"award\" :@\"🏆\",\n            @\"ballot_box\" :@\"🗳️\",\n            @\"zzz\" :@\"😴\",\n            @\"father\" :@\"👨\",\n            @\"cowboy_hat_face\" :@\"🤠\",\n            @\"rice_ball\" :@\"🍙\",\n            @\"polar_bear\" :@\"🐻‍❄️\",\n            @\"passport_control\" :@\"🛂\",\n            @\"safety_pin\" :@\"🧷\",\n            @\"shrimp\" :@\"🦐\",\n            @\"pie\" :@\"🥧\",\n            @\"black_cat\" :@\"🐈‍⬛\",\n            @\"zipper_mouth_face\" :@\"🤐\",\n            @\"st_vincent_grenadines\" :@\"🇻🇨\",\n            @\"earth_asia\" :@\"🌏\",\n            @\"person_red_hair\" :@\"🧑‍🦰\",\n            @\"hibiscus\" :@\"🌺\",\n            @\"surprise\" :@\"😮\",\n            @\"alien\" :@\"👽\",\n            @\"person_with_crown\" :@\"🫅\",\n            @\"card_index\" :@\"📇\",\n            @\"ethiopia\" :@\"🇪🇹\",\n            @\"pig\" :@\"🐷\",\n            @\"black_large_square\" :@\"⬛\",\n            @\"gabon\" :@\"🇬🇦\",\n            @\"wip\" :@\"🚧\",\n            @\"minibus\" :@\"🚐\",\n            @\"closed_book\" :@\"📕\",\n            @\"elevator\" :@\"🛗\",\n            @\"zombie\" :@\"🧟\",\n            @\"goose\" :@\"🪿\",\n            @\"tropical_drink\" :@\"🍹\",\n            @\"silly\" :@\"😜\",\n            @\"evergreen_tree\" :@\"🌲\",\n            @\"candle\" :@\"🕯️\",\n            @\"heavy_exclamation_mark\" :@\"❗\",\n            @\"st_lucia\" :@\"🇱🇨\",\n            @\"cityscape\" :@\"🏙️\",\n            @\"+1\" :@\"👍\",\n            @\"couplekiss_man_woman\" :@\"👩‍❤️‍💋‍👨\",\n            @\"burundi\" :@\"🇧🇮\",\n            @\"boomerang\" :@\"🪃\",\n            @\"dog2\" :@\"🐕\",\n            @\"railway_track\" :@\"🛤️\",\n            @\"purple_circle\" :@\"🟣\",\n            @\"artificial_satellite\" :@\"🛰️\",\n            @\"dancing_men\" :@\"👯‍♂️\",\n            @\"mosque\" :@\"🕌\",\n            @\"woman_with_turban\" :@\"👳‍♀️\",\n            @\"arrow_upper_right\" :@\"↗️\",\n            @\"white_haired_woman\" :@\"👩‍🦳\",\n            @\"deaf_person\" :@\"🧏\",\n            @\"saxophone\" :@\"🎷\",\n            @\"mechanical_arm\" :@\"🦾\",\n            @\"airport\" :@\"🛄\",\n            @\"low_battery\" :@\"🪫\",\n            @\"clock330\" :@\"🕞\",\n            @\"arrow_backward\" :@\"◀️\",\n            @\"coin\" :@\"🪙\",\n            @\"clock11\" :@\"🕚\",\n            @\"custard\" :@\"🍮\",\n            @\"abc\" :@\"🔤\",\n            @\"older_man\" :@\"👴\",\n            @\"secret\" :@\"㊙️\",\n            @\"finland\" :@\"🇫🇮\",\n            @\"exclamation\" :@\"❗\",\n            @\"hopeful\" :@\"🤞\",\n            @\"woman_mechanic\" :@\"👩‍🔧\",\n            @\"palm_down_hand\" :@\"🫳\",\n            @\"peace\" :@\"✌️\",\n            @\"sparkler\" :@\"🎇\",\n            @\"bird\" :@\"🐦\",\n            @\"round_pushpin\" :@\"📍\",\n            @\"pisces\" :@\"♓\",\n            @\"pinata\" :@\"🪅\",\n            @\"equatorial_guinea\" :@\"🇬🇶\",\n            @\"honduras\" :@\"🇭🇳\",\n            @\"people_holding_hands\" :@\"🧑‍🤝‍🧑\",\n            @\"cursing_face\" :@\"🤬\",\n            @\"victory\" :@\"✌️\",\n            @\"barbados\" :@\"🇧🇧\",\n            @\"white_small_square\" :@\"▫️\",\n            @\"do_not_litter\" :@\"🚯\",\n            @\"armenia\" :@\"🇦🇲\",\n            @\"aerial_tramway\" :@\"🚡\",\n            @\"stethoscope\" :@\"🩺\",\n            @\"slightly_smiling_face\" :@\"🙂\",\n            @\"blind\" :@\"🙈\",\n            @\"falafel\" :@\"🧆\",\n            @\"south_sudan\" :@\"🇸🇸\",\n            @\"diving_mask\" :@\"🤿\",\n            @\"tropical_fish\" :@\"🐠\",\n            @\"smirk_cat\" :@\"😼\",\n            @\"danger\" :@\"💀\",\n            @\"barf\" :@\"🤢\",\n            @\"upset\" :@\"😫\",\n            @\"forbidden\" :@\"🚫\",\n            @\"ticket\" :@\"🎫\",\n            @\"u5408\" :@\"🈴\",\n            @\"pray\" :@\"🙏\",\n            @\"persevere\" :@\"😣\",\n            @\"clown_face\" :@\"🤡\",\n            @\"off\" :@\"🔕\",\n            @\"neutral_face\" :@\"😐\",\n            @\"cyclone\" :@\"🌀\",\n            @\"smell\" :@\"👃\",\n            @\"turkey\" :@\"🦃\",\n            @\"console\" :@\"🎮\",\n            @\"no_entry\" :@\"⛔\",\n            @\"dolphin\" :@\"🐬\",\n            @\"antarctica\" :@\"🇦🇶\",\n            @\"printer\" :@\"🖨️\",\n            @\"pensive\" :@\"😔\",\n            @\"rosette\" :@\"🏵️\",\n            @\"mega\" :@\"📣\",\n            @\"crap\" :@\"💩\",\n            @\"peach\" :@\"🍑\",\n            @\"hair_pick\" :@\"🪮\",\n            @\"chestnut\" :@\"🌰\",\n            @\"love_letter\" :@\"💌\",\n            @\"clock12\" :@\"🕛\",\n            @\"olive\" :@\"🫒\",\n            @\"pouting_woman\" :@\"🙎‍♀️\",\n            @\"semaphore\" :@\"🚦\",\n            @\"non-potable_water\" :@\"🚱\",\n            @\"man_student\" :@\"👨‍🎓\",\n            @\"triangular_ruler\" :@\"📐\",\n            @\"lacrosse\" :@\"🥍\",\n            @\"black_heart\" :@\"🖤\",\n            @\"foul\" :@\"🤬\",\n            @\"face_with_diagonal_mouth\" :@\"🫤\",\n            @\"white_flag\" :@\"🏳️\",\n            @\"manual_wheelchair\" :@\"🦽\",\n            @\"man_judge\" :@\"👨‍⚖️\",\n            @\"fox_face\" :@\"🦊\",\n            @\"wave\" :@\"👋\",\n            @\"white_check_mark\" :@\"✅\",\n            @\"burn\" :@\"🔥\",\n            @\"nursing\" :@\"🤱\",\n            @\"evil\" :@\"😈\",\n            @\"pretzel\" :@\"🥨\",\n            @\"ear_of_rice\" :@\"🌾\",\n            @\"tunisia\" :@\"🇹🇳\",\n            @\"flushed\" :@\"😳\",\n            @\"beaver\" :@\"🦫\",\n            @\"mage\" :@\"🧙\",\n            @\"luck\" :@\"🤞\",\n            @\"coder\" :@\"👨‍💻\",\n            @\"pause_button\" :@\"⏸️\",\n            @\"thong_sandal\" :@\"🩴\",\n            @\"desktop_computer\" :@\"🖥️\",\n            @\"woman_in_motorized_wheelchair\" :@\"👩‍🦼\",\n            @\"performing_arts\" :@\"🎭\",\n            @\"clock230\" :@\"🕝\",\n            @\"hatching_chick\" :@\"🐣\",\n            @\"paperclips\" :@\"🖇️\",\n            @\"coral\" :@\"🪸\",\n            @\"negative_squared_cross_mark\" :@\"❎\",\n            @\"lick\" :@\"😋\",\n            @\"hand\" :@\"✋\",\n            @\"eight_pointed_black_star\" :@\"✴️\",\n            @\"mouse2\" :@\"🐁\",\n            @\"dango\" :@\"🍡\",\n            @\"arrow_right_hook\" :@\"↪️\",\n            @\"vhs\" :@\"📼\",\n            @\"clock1130\" :@\"🕦\",\n            @\"shaker\" :@\"🪇\",\n            @\"selfie\" :@\"🤳\",\n            @\"vanuatu\" :@\"🇻🇺\",\n            @\"goal_net\" :@\"🥅\",\n            @\"podcast\" :@\"🎙️\",\n            @\"chop\" :@\"🔪\",\n            @\"previous_track_button\" :@\"⏮️\",\n            @\"purple_square\" :@\"🟪\",\n            @\"globe\" :@\"🌍\",\n            @\"no_entry_sign\" :@\"🚫\",\n            @\"grey_question\" :@\"❔\",\n            @\"iceland\" :@\"🇮🇸\",\n            @\"four\" :@\"4️⃣\",\n            @\"factory_worker\" :@\"🧑‍🏭\",\n            @\"stuck_out_tongue_closed_eyes\" :@\"😝\",\n            @\"u6708\" :@\"🈷️\",\n            @\"running_man\" :@\"🏃‍♂️\",\n            @\"mountain_cableway\" :@\"🚠\",\n            @\"1st_place_medal\" :@\"🥇\",\n            @\"pound\" :@\"💷\",\n            @\"imp\" :@\"👿\",\n            @\"broccoli\" :@\"🥦\",\n            @\"grenada\" :@\"🇬🇩\",\n            @\"sparkles\" :@\"✨\",\n            @\"wheel\" :@\"🛞\",\n            @\"woman_astronaut\" :@\"👩‍🚀\",\n            @\"research\" :@\"👨‍🔬\",\n            @\"open_hands\" :@\"👐\",\n            @\"man_with_veil\" :@\"👰‍♂️\",\n            @\"u6709\" :@\"🈶\",\n            @\"wow\" :@\"😮\",\n            @\"last_quarter_moon_with_face\" :@\"🌜\",\n            @\"macau\" :@\"🇲🇴\",\n            @\"malaysia\" :@\"🇲🇾\",\n            @\"razor\" :@\"🪒\",\n            @\"calling\" :@\"📲\",\n            @\"flatbread\" :@\"🫓\",\n            @\"mammoth\" :@\"🦣\",\n            @\"st_martin\" :@\"🇲🇫\",\n            @\"kissing_smiling_eyes\" :@\"😙\",\n            @\"comoros\" :@\"🇰🇲\",\n            @\"snowboarder\" :@\"🏂\",\n            @\"screwdriver\" :@\"🪛\",\n            @\"pirate\" :@\"☠️\",\n            @\"question\" :@\"❓\",\n            @\"partying_face\" :@\"🥳\",\n            @\"radio\" :@\"📻\",\n            @\"uk\" :@\"🇬🇧\",\n            @\"family_man_girl\" :@\"👨‍👧\",\n            @\"shopping_cart\" :@\"🛒\",\n            @\"cry\" :@\"😢\",\n            @\"house_with_garden\" :@\"🏡\",\n            @\"costa_rica\" :@\"🇨🇷\",\n            @\"bury\" :@\"👎\",\n            @\"power\" :@\"✊\",\n            @\"mountain_snow\" :@\"🏔️\",\n            @\"dragon_face\" :@\"🐲\",\n            @\"bar_chart\" :@\"📊\",\n            @\"squid\" :@\"🦑\",\n            @\"up\" :@\"🆙\",\n            @\"european_post_office\" :@\"🏤\",\n            @\"railway_car\" :@\"🚃\",\n            @\"ng\" :@\"🆖\",\n            @\"japanese_castle\" :@\"🏯\",\n            @\"person_in_manual_wheelchair\" :@\"🧑‍🦽\",\n            @\"us\" :@\"🇺🇸\",\n            @\"pleading_face\" :@\"🥺\",\n            @\"building_construction\" :@\"🏗️\",\n            @\"laughing\" :@\"😆\",\n            @\"shuffle\" :@\"🔀\",\n            @\"gb\" :@\"🇬🇧\",\n            @\"person_bald\" :@\"🧑‍🦲\",\n            @\"myanmar\" :@\"🇲🇲\",\n            @\"musical_score\" :@\"🎼\",\n            @\"child\" :@\"👶\",\n            @\"kissing\" :@\"😗\",\n            @\"battery\" :@\"🔋\",\n            @\"el_salvador\" :@\"🇸🇻\",\n            @\"fountain\" :@\"⛲\",\n            @\"water\" :@\"💦\",\n            @\"heavy_dollar_sign\" :@\"💲\",\n            @\"volume\" :@\"🔇\",\n            @\"national_park\" :@\"🏞️\",\n            @\"adult\" :@\"🧑\",\n            @\"airplane\" :@\"✈️\",\n            @\"clock130\" :@\"🕜\",\n            @\"telephone\" :@\"☎️\",\n            @\"bulgaria\" :@\"🇧🇬\",\n            @\"congo_brazzaville\" :@\"🇨🇬\",\n            @\"high_heel\" :@\"👠\",\n            @\"chile\" :@\"🇨🇱\",\n            @\"kissing_closed_eyes\" :@\"😚\",\n            @\"leaf\" :@\"🍃\",\n            @\"metrics\" :@\"📈\",\n            @\"bouquet\" :@\"💐\",\n            @\"sick\" :@\"😷\",\n            @\"fire_engine\" :@\"🚒\",\n            @\"motorcycle\" :@\"🏍️\",\n            @\"video_camera\" :@\"📹\",\n            @\"computer_mouse\" :@\"🖱️\",\n            @\"file_cabinet\" :@\"🗄️\",\n            @\"weight_lifting_woman\" :@\"🏋️‍♀️\",\n            @\"socks\" :@\"🧦\",\n            @\"supervillain\" :@\"🦹\",\n            @\"launch\" :@\"🚀\",\n            @\"family_man_woman_boy\" :@\"👨‍👩‍👦\",\n            @\"suriname\" :@\"🇸🇷\",\n            @\"information_desk_person\" :@\"💁\",\n            @\"botswana\" :@\"🇧🇼\",\n            @\"one\" :@\"1️⃣\",\n            @\"piano\" :@\"🎹\",\n            @\"target\" :@\"🎯\",\n            @\"belgium\" :@\"🇧🇪\",\n            @\"steam_locomotive\" :@\"🚂\",\n            @\"newspaper_roll\" :@\"🗞️\",\n            @\"partly_sunny\" :@\"⛅\",\n            @\"facepalm\" :@\"🤦\",\n            @\"gem\" :@\"💎\",\n            @\"hospital\" :@\"🏥\",\n            @\"green_heart\" :@\"💚\",\n            @\"feet\" :@\"👣\",\n            @\"face_exhaling\" :@\"😮‍💨\",\n            @\"lightning\" :@\"⚡\",\n            @\"montenegro\" :@\"🇲🇪\",\n            @\"bow\" :@\"🙇\",\n            @\"tipping_hand_person\" :@\"💁\",\n            @\"caribbean_netherlands\" :@\"🇧🇶\",\n            @\"face_in_clouds\" :@\"😶‍🌫️\",\n            @\"sarcasm\" :@\"🫠\",\n            @\"new\" :@\"🆕\",\n            @\"rwanda\" :@\"🇷🇼\",\n            @\"diamond\" :@\"💎\",\n            @\"fireworks\" :@\"🎆\",\n            @\"boy\" :@\"👦\",\n            @\"small_airplane\" :@\"🛩️\",\n            @\"office_worker\" :@\"🧑‍💼\",\n            @\"confounded\" :@\"😖\",\n            @\"card_index_dividers\" :@\"🗂️\",\n            @\"black_medium_square\" :@\"◼️\",\n            @\"cape_verde\" :@\"🇨🇻\",\n            @\"aruba\" :@\"🇦🇼\",\n            @\"screen\" :@\"💻\",\n            @\"fried_egg\" :@\"🍳\",\n            @\"thumbsdown\" :@\"👎\",\n            @\"aries\" :@\"♈\",\n            @\"guinea_bissau\" :@\"🇬🇼\",\n            @\"laugh\" :@\"😄\",\n            @\"comet\" :@\"☄️\",\n            @\"triangular_flag_on_post\" :@\"🚩\",\n            @\"curry\" :@\"🥘\",\n            @\"keyboard\" :@\"⌨️\",\n            @\"notebook\" :@\"📓\",\n            @\"pitcairn_islands\" :@\"🇵🇳\",\n            @\"cancer\" :@\"♋\",\n            @\"yo_yo\" :@\"🪀\",\n            @\"chicken\" :@\"🐔\",\n            @\"scarf\" :@\"🧣\",\n            @\"articulated_lorry\" :@\"🚛\",\n            @\"respect\" :@\"🫡\",\n            @\"paraguay\" :@\"🇵🇾\",\n            @\"donkey\" :@\"🫏\",\n            @\"cartwheeling\" :@\"🤸\",\n            @\"mango\" :@\"🥭\",\n            @\"basketball_man\" :@\"⛹️‍♂️\",\n            @\"e-mail\" :@\"📧\",\n            @\"arrows_counterclockwise\" :@\"🔄\",\n            @\"ice_hockey\" :@\"🏒\",\n            @\"boar\" :@\"🐗\",\n            @\"superhero_man\" :@\"🦸‍♂️\",\n            @\"hindu_temple\" :@\"🛕\",\n            @\"look\" :@\"👀\",\n            @\"koko\" :@\"🈁\",\n            @\"wind_chime\" :@\"🎐\",\n            @\"isle_of_man\" :@\"🇮🇲\",\n            @\"hand_over_mouth\" :@\"🤭\",\n            @\"czech_republic\" :@\"🇨🇿\",\n            @\"venezuela\" :@\"🇻🇪\",\n            @\"stone\" :@\"🗿\",\n            @\"slightly_frowning_face\" :@\"🙁\",\n            @\"globe_with_meridians\" :@\"🌐\",\n            @\"bell_pepper\" :@\"🫑\",\n            @\"boat\" :@\"⛵\",\n            @\"cocktail\" :@\"🍸\",\n            @\"face_with_spiral_eyes\" :@\"😵‍💫\",\n            @\"woman_shrugging\" :@\"🤷‍♀️\",\n            @\"liar\" :@\"🤥\",\n            @\"grey_exclamation\" :@\"❕\",\n            @\"mount_fuji\" :@\"🗻\",\n            @\"woman_feeding_baby\" :@\"👩‍🍼\",\n            @\"djibouti\" :@\"🇩🇯\",\n            @\"white_large_square\" :@\"⬜\",\n            @\"factory\" :@\"🏭\",\n            @\"ribbon\" :@\"🎀\",\n            @\"family_man_woman_boy_boy\" :@\"👨‍👩‍👦‍👦\",\n            @\"roller_coaster\" :@\"🎢\",\n            @\"wish\" :@\"🙏\",\n            @\"montserrat\" :@\"🇲🇸\",\n            @\"family_man_man_girl_boy\" :@\"👨‍👨‍👧‍👦\",\n            @\"ng_man\" :@\"🙅‍♂️\",\n            @\"copyright\" :@\"©️\",\n            @\"bug\" :@\"🐛\",\n            @\"juggling_person\" :@\"🤹\",\n            @\"bust_in_silhouette\" :@\"👤\",\n            @\"hatched_chick\" :@\"🐥\",\n            @\"u7981\" :@\"🈲\",\n            @\"camel\" :@\"🐫\",\n            @\"yawning_face\" :@\"🥱\",\n            @\"mahjong\" :@\"🀄\",\n            @\"estonia\" :@\"🇪🇪\",\n            @\"new_zealand\" :@\"🇳🇿\",\n            @\"construction_worker_man\" :@\"👷‍♂️\",\n            @\"smiling_imp\" :@\"😈\",\n            @\"bookmark\" :@\"🔖\",\n            @\"spock\" :@\"🖖\",\n            @\"micronesia\" :@\"🇫🇲\",\n            @\"joystick\" :@\"🕹️\",\n            @\"black_medium_small_square\" :@\"◾\",\n            @\"person_fencing\" :@\"🤺\",\n            @\"return\" :@\"↩️\",\n            @\"loop\" :@\"🔁\",\n            @\"bang\" :@\"❗\",\n            @\"shirt\" :@\"👔\",\n            @\"tears\" :@\"😂\",\n            @\"woman_with_probing_cane\" :@\"👩‍🦯\",\n            @\"speak_no_evil\" :@\"🙊\",\n            @\"cut_of_meat\" :@\"🥩\",\n            @\"bread\" :@\"🍞\",\n            @\"wacky\" :@\"🤪\",\n            @\"bubble_tea\" :@\"🧋\",\n            @\"man_shrugging\" :@\"🤷‍♂️\",\n            @\"snail\" :@\"🐌\",\n            @\"high_brightness\" :@\"🔆\",\n            @\"help\" :@\"🆘\",\n            @\"mushroom\" :@\"🍄\",\n            @\"train2\" :@\"🚆\",\n            @\"bowing_woman\" :@\"🙇‍♀️\",\n            @\"burkina_faso\" :@\"🇧🇫\",\n            @\"egypt\" :@\"🇪🇬\",\n            @\"blue_heart\" :@\"💙\",\n            @\"pouting_cat\" :@\"😾\",\n            @\"white_flower\" :@\"💮\",\n            @\"sad\" :@\"😢\",\n            @\"school_satchel\" :@\"🎒\",\n            @\"dark_sunglasses\" :@\"🕶️\",\n            @\"blond_haired_person\" :@\"👱\",\n            @\"person_with_turban\" :@\"👳\",\n            @\"sneaker\" :@\"👟\",\n            @\"soccer\" :@\"⚽\",\n            @\"registered\" :@\"®️\",\n            @\"postal_horn\" :@\"📯\",\n            @\"hourglass\" :@\"⌛\",\n            @\"sheep\" :@\"🐑\",\n            @\"lobster\" :@\"🦞\",\n            @\"woman_teacher\" :@\"👩‍🏫\",\n            @\"shinto_shrine\" :@\"⛩️\",\n            @\"mechanical_leg\" :@\"🦿\",\n            @\"fork_and_knife\" :@\"🍴\",\n            @\"ant\" :@\"🐜\",\n            @\"spades\" :@\"♠️\",\n            @\"niger\" :@\"🇳🇪\",\n            @\"zap\" :@\"⚡\",\n            @\"bank\" :@\"🏦\",\n            @\"face_holding_back_tears\" :@\"🥹\",\n            @\"solomon_islands\" :@\"🇸🇧\",\n            @\"health\" :@\"💉\",\n            @\"construction\" :@\"🚧\",\n            @\"spider\" :@\"🕷️\",\n            @\"blue_square\" :@\"🟦\",\n            @\"bus\" :@\"🚌\",\n            @\"blush\" :@\"😊\",\n            @\"ivory\" :@\"🇨🇮\",\n            @\"seal\" :@\"🦭\",\n            @\"lizard\" :@\"🦎\",\n            @\"rainbow\" :@\"🌈\",\n            @\"walking\" :@\"🚶\",\n            @\"highfive\" :@\"✋\",\n            @\"halt\" :@\"🙅\",\n            @\"violin\" :@\"🎻\",\n            @\"relieved\" :@\"😌\",\n            @\"bolivia\" :@\"🇧🇴\",\n            @\"open_umbrella\" :@\"☂️\",\n            @\"small_red_triangle\" :@\"🔺\",\n            @\"teapot\" :@\"🫖\",\n            @\"brown_heart\" :@\"🤎\",\n            @\"peru\" :@\"🇵🇪\",\n            @\"syria\" :@\"🇸🇾\",\n            @\"field_hockey\" :@\"🏑\",\n            @\"america\" :@\"🇺🇸\",\n            @\"adhesive_bandage\" :@\"🩹\",\n            @\"sleeping\" :@\"😴\",\n            @\"name_badge\" :@\"📛\",\n            @\"mage_woman\" :@\"🧙‍♀️\",\n            @\"vietnam\" :@\"🇻🇳\",\n            @\"peace_symbol\" :@\"☮️\",\n            @\"tada\" :@\"🎉\",\n            @\"senegal\" :@\"🇸🇳\",\n            @\"sweating\" :@\"🥵\",\n            @\"oncoming_taxi\" :@\"🚖\",\n            @\"baseball\" :@\"⚾\",\n            @\"amphora\" :@\"🏺\",\n            @\"cactus\" :@\"🌵\",\n            @\"roller_skate\" :@\"🛼\",\n            @\"woman_judge\" :@\"👩‍⚖️\",\n            @\"takeout_box\" :@\"🥡\",\n            @\"disappointed_relieved\" :@\"😥\",\n            @\"lock_with_ink_pen\" :@\"🔏\",\n            @\"kosovo\" :@\"🇽🇰\",\n            @\"stars\" :@\"🌠\",\n            @\"pea_pod\" :@\"🫛\",\n            @\"astonished\" :@\"😲\",\n            @\"mosquito\" :@\"🦟\",\n            @\"oden\" :@\"🍢\",\n            @\"cocos_islands\" :@\"🇨🇨\",\n            @\"monocle_face\" :@\"🧐\",\n            @\"raising_hand\" :@\"🙋\",\n            @\"thailand\" :@\"🇹🇭\",\n            @\"sweat_smile\" :@\"😅\",\n            @\"impressed\" :@\"😮\",\n            @\"bulb\" :@\"💡\",\n            @\"plant\" :@\"🌱\",\n            @\"newspaper\" :@\"📰\",\n            @\"man_facepalming\" :@\"🤦‍♂️\",\n            @\"speaker\" :@\"🔈\",\n            @\"black_joker\" :@\"🃏\",\n            @\"arrow_up\" :@\"⬆️\",\n            @\"bahrain\" :@\"🇧🇭\",\n            @\"closed_lock_with_key\" :@\"🔐\",\n            @\"deaf_woman\" :@\"🧏‍♀️\",\n            @\"ferry\" :@\"⛴️\",\n            @\"sea\" :@\"🐳\",\n            @\"soon\" :@\"🔜\",\n            @\"watermelon\" :@\"🍉\",\n            @\"small_red_triangle_down\" :@\"🔻\",\n            @\"fist_raised\" :@\"✊\",\n            @\"u7533\" :@\"🈸\",\n            @\"poison\" :@\"💀\",\n            @\"seat\" :@\"💺\",\n            @\"woman\" :@\"👩\",\n            @\"koala\" :@\"🐨\",\n            @\"innocent\" :@\"😇\",\n            @\"qatar\" :@\"🇶🇦\",\n            @\"guide_dog\" :@\"🦮\",\n            @\"climbing\" :@\"🧗\",\n            @\"poland\" :@\"🇵🇱\",\n            @\"see\" :@\"👀\",\n            @\"climbing_man\" :@\"🧗‍♂️\",\n            @\"raised_eyebrow\" :@\"🤨\",\n            @\"scorpius\" :@\"♏\",\n            @\"softball\" :@\"🥎\",\n            @\"banjo\" :@\"🪕\",\n            @\"bellhop_bell\" :@\"🛎️\",\n            @\"ceuta_melilla\" :@\"🇪🇦\",\n            @\"art\" :@\"🎨\",\n            @\"vulcan_salute\" :@\"🖖\",\n            @\"hot_pepper\" :@\"🌶️\",\n            @\"winner\" :@\"🏆\",\n            @\"statue_of_liberty\" :@\"🗽\",\n            @\"law\" :@\"👮\",\n            @\"honey_pot\" :@\"🍯\",\n            @\"rewind\" :@\"⏪\",\n            @\"man_beard\" :@\"🧔‍♂️\",\n            @\"sun_behind_large_cloud\" :@\"🌥️\",\n            @\"timer_clock\" :@\"⏲️\",\n            @\"raccoon\" :@\"🦝\",\n            @\"stuffed_flatbread\" :@\"🥙\",\n            @\"rightwards_hand\" :@\"🫱\",\n            @\"cruise\" :@\"🛳️\",\n            @\"shallow_pan_of_food\" :@\"🥘\",\n            @\"travel\" :@\"🗺️\",\n            @\"hotsprings\" :@\"♨️\",\n            @\"runner\" :@\"🏃\",\n            @\"mauritius\" :@\"🇲🇺\",\n            @\"ear\" :@\"👂\",\n            @\"belize\" :@\"🇧🇿\",\n            @\"earphones\" :@\"🎧\",\n            @\"spiral_notepad\" :@\"🗒️\",\n            @\"atm\" :@\"🏧\",\n            @\"test_tube\" :@\"🧪\",\n            @\"plunger\" :@\"🪠\",\n            @\"alarm_clock\" :@\"⏰\",\n            @\"fist_right\" :@\"🤜\",\n            @\"nazar_amulet\" :@\"🧿\",\n            @\"gift\" :@\"🎁\",\n            @\"earth_americas\" :@\"🌎\",\n            @\"foggy\" :@\"🌁\",\n            @\"poultry_leg\" :@\"🍗\",\n            @\"racing_car\" :@\"🏎️\",\n            @\"geek\" :@\"🤓\",\n            @\"eight_spoked_asterisk\" :@\"✳️\",\n            @\"u6e80\" :@\"🈵\",\n            @\"family_woman_woman_girl_boy\" :@\"👩‍👩‍👧‍👦\",\n            @\"leg\" :@\"🦵\",\n            @\"gambia\" :@\"🇬🇲\",\n            @\"zimbabwe\" :@\"🇿🇼\",\n            @\"pants\" :@\"👖\",\n            @\"capital_abcd\" :@\"🔠\",\n            @\"teacher\" :@\"🧑‍🏫\",\n            @\"phone\" :@\"☎️\",\n            @\"family_man_woman_girl\" :@\"👨‍👩‍👧\",\n            @\"middle_finger\" :@\"🖕\",\n            @\"tongue\" :@\"😋\",\n            @\"ru\" :@\"🇷🇺\",\n            @\"sweden\" :@\"🇸🇪\",\n            @\"flashlight\" :@\"🔦\",\n            @\"musical_note\" :@\"🎵\",\n            @\"receipt\" :@\"🧾\",\n            @\"supervillain_man\" :@\"🦹‍♂️\",\n            @\"basketball\" :@\"⛹️\",\n            @\"badger\" :@\"🦡\",\n            @\"bouncing_ball_man\" :@\"⛹️‍♂️\",\n            @\"alphabet\" :@\"🔤\",\n            @\"letter\" :@\"✉️\",\n            @\"prank\" :@\"😜\",\n            @\"jack_o_lantern\" :@\"🎃\",\n            @\"de\" :@\"🇩🇪\",\n            @\"yellow_circle\" :@\"🟡\",\n            @\"world\" :@\"🌍\",\n            @\"cookie\" :@\"🍪\",\n            @\"haha\" :@\"😃\",\n            @\"bell\" :@\"🔔\",\n            @\"palm_up_hand\" :@\"🫴\",\n            @\"woman_technologist\" :@\"👩‍💻\",\n            @\"pouting_man\" :@\"🙎‍♂️\",\n            @\"accept\" :@\"🉑\",\n            @\"idea\" :@\"💡\",\n            @\"cinema\" :@\"🎦\",\n            @\"classical_building\" :@\"🏛️\",\n            @\"kr\" :@\"🇰🇷\",\n            @\"octopus\" :@\"🐙\",\n            @\"painter\" :@\"👨‍🎨\",\n            @\"heavy_division_sign\" :@\"➗\",\n            @\"date\" :@\"🧑‍🤝‍🧑\",\n            @\"note\" :@\"📝\",\n            @\"silence\" :@\"🤫\",\n            @\"annoyed\" :@\"😠\",\n            @\"leo\" :@\"♌\",\n            @\"bike\" :@\"🚲\",\n            @\"aquarius\" :@\"♒\",\n            @\"orange_book\" :@\"📙\",\n            @\"heavy_equals_sign\" :@\"🟰\",\n            @\"eritrea\" :@\"🇪🇷\",\n            @\"woman_with_veil\" :@\"👰‍♀️\",\n            @\"library\" :@\"📚\",\n            @\"bicycle\" :@\"🚲\",\n            @\"zoom\" :@\"🔍\",\n            @\"left_speech_bubble\" :@\"🗨️\",\n            @\"ballet_shoes\" :@\"🩰\",\n            @\"axe\" :@\"🪓\",\n            @\"heartbeat\" :@\"💓\",\n            @\"running_woman\" :@\"🏃‍♀️\",\n            @\"queen\" :@\"👑\",\n            @\"saluting_face\" :@\"🫡\",\n            @\"incoming_envelope\" :@\"📨\",\n            @\"volcano\" :@\"🌋\",\n            @\"pickup_truck\" :@\"🛻\",\n            @\"northern_mariana_islands\" :@\"🇲🇵\",\n            @\"crutch\" :@\"🩼\",\n            @\"infinity\" :@\"♾️\",\n            @\"dancer\" :@\"💃\",\n            @\"press\" :@\"📰\",\n            @\"surfing_man\" :@\"🏄‍♂️\",\n            @\"no_smoking\" :@\"🚭\",\n            @\"hyacinth\" :@\"🪻\",\n            @\"golfing_man\" :@\"🏌️‍♂️\",\n            @\"llama\" :@\"🦙\",\n            @\"family_woman_girl_boy\" :@\"👩‍👧‍👦\",\n            @\"blue_car\" :@\"🚙\",\n            @\"two_men_holding_hands\" :@\"👬\",\n            @\"tokyo_tower\" :@\"🗼\",\n            @\"magnet\" :@\"🧲\",\n            @\"grey_heart\" :@\"🩶\",\n            @\"last_quarter_moon\" :@\"🌗\",\n            @\"sneezing_face\" :@\"🤧\",\n            @\"rowing_man\" :@\"🚣‍♂️\",\n            @\"vampire_woman\" :@\"🧛‍♀️\",\n            @\"shell\" :@\"🐚\",\n            @\"white_circle\" :@\"⚪\",\n            @\"man_technologist\" :@\"👨‍💻\",\n            @\"arrow_heading_up\" :@\"⤴️\",\n            @\"musical_keyboard\" :@\"🎹\",\n            @\"hiking_boot\" :@\"🥾\",\n            @\"dancers\" :@\"👯\",\n            @\"candy\" :@\"🍬\",\n            @\"playground_slide\" :@\"🛝\",\n            @\"foot\" :@\"🦶\",\n            @\"disgusted\" :@\"🤢\",\n            @\"cucumber\" :@\"🥒\",\n            @\"horse_racing\" :@\"🏇\",\n            @\"egg\" :@\"🥚\",\n            @\"flight_arrival\" :@\"🛬\",\n            @\"carpentry_saw\" :@\"🪚\",\n            @\"taco\" :@\"🌮\",\n            @\"arrows_clockwise\" :@\"🔃\",\n            @\"couplekiss\" :@\"💏\",\n            @\"detective\" :@\"🕵️\",\n            @\"person_with_veil\" :@\"👰\",\n            @\"shocked\" :@\"😨\",\n            @\"watch\" :@\"👀\",\n            @\"deaf_man\" :@\"🧏‍♂️\",\n            @\"dinosaur\" :@\"🦕\",\n            @\"mage_man\" :@\"🧙‍♂️\",\n            @\"wilted_flower\" :@\"🥀\",\n            @\"location\" :@\"📌\",\n            @\"iphone\" :@\"📱\",\n            @\"gratitude\" :@\"🥹\",\n            @\"tophat\" :@\"🎩\",\n            @\"ecuador\" :@\"🇪🇨\",\n            @\"curacao\" :@\"🇨🇼\",\n            @\"bawling\" :@\"😭\",\n            @\"man_in_manual_wheelchair\" :@\"👨‍🦽\",\n            @\"anatomical_heart\" :@\"🫀\",\n            @\"tickets\" :@\"🎟️\",\n            @\"bowing_man\" :@\"🙇‍♂️\",\n            @\"schedule\" :@\"📅\",\n            @\"sunrise_over_mountains\" :@\"🌄\",\n            @\"nose\" :@\"👃\",\n            @\"fries\" :@\"🍟\",\n            @\"waxing_gibbous_moon\" :@\"🌔\",\n            @\"goodbye\" :@\"👋\",\n            @\"circus_tent\" :@\"🎪\",\n            @\"dragon\" :@\"🐉\",\n            @\"private\" :@\"🔒\",\n            @\"walking_man\" :@\"🚶‍♂️\",\n            @\"tornado\" :@\"🌪️\",\n            @\"family_man_man_girl_girl\" :@\"👨‍👨‍👧‍👧\",\n            @\"green_salad\" :@\"🥗\",\n            @\"ski\" :@\"🎿\",\n            @\"clamp\" :@\"🗜️\",\n            @\"monkey\" :@\"🙈\",\n            @\"probing_cane\" :@\"🦯\",\n            @\"chart\" :@\"💹\",\n            @\"halloween\" :@\"👻\",\n            @\"fly\" :@\"🪽\",\n            @\"envelope\" :@\"💌\",\n            @\"sparkling_heart\" :@\"💖\",\n            @\"nepal\" :@\"🇳🇵\",\n            @\"kyrgyzstan\" :@\"🇰🇬\",\n            @\"norfolk_island\" :@\"🇳🇫\",\n            @\"kiwi_fruit\" :@\"🥝\",\n            @\"dash\" :@\"💨\",\n            @\"stuck_out_tongue_winking_eye\" :@\"😜\",\n            @\"breakfast\" :@\"🍳\",\n            @\"azerbaijan\" :@\"🇦🇿\",\n            @\"turtle\" :@\"🐢\",\n            @\"coat\" :@\"🧥\",\n            @\"mrs_claus\" :@\"🤶\",\n            @\"six\" :@\"6️⃣\",\n            @\"cambodia\" :@\"🇰🇭\",\n            @\"attack\" :@\"👊\",\n            @\"rescue_worker_helmet\" :@\"⛑️\",\n            @\"monster\" :@\"👹\",\n            @\"gun\" :@\"🔫\",\n            @\"cow2\" :@\"🐄\",\n            @\"mountain\" :@\"⛰️\",\n            @\"punch\" :@\"👊\",\n            @\"engaged\" :@\"💍\",\n            @\"kite\" :@\"🪁\",\n            @\"woman_facepalming\" :@\"🤦‍♀️\",\n            @\"music\" :@\"🎶\",\n            @\"moon\" :@\"🌔\",\n            @\"confetti_ball\" :@\"🎊\",\n            @\"pig2\" :@\"🐖\",\n            @\"green_circle\" :@\"🟢\",\n            @\"free\" :@\"🆓\",\n            @\"lipstick\" :@\"💋\",\n            @\"yellow_heart\" :@\"💛\",\n            @\"convenience_store\" :@\"🏪\",\n            @\"person_with_probing_cane\" :@\"🧑‍🦯\",\n            @\"united_nations\" :@\"🇺🇳\",\n            @\"meat\" :@\"🍗\",\n            @\"celebration\" :@\"🥳\",\n            @\"ice_cube\" :@\"🧊\",\n            @\"arrow_forward\" :@\"▶️\",\n            @\"wind\" :@\"💨\",\n            @\"yellow_square\" :@\"🟨\",\n            @\"cupid\" :@\"💘\",\n            @\"fist_left\" :@\"🤛\",\n            @\"nigeria\" :@\"🇳🇬\",\n            @\"exercise\" :@\"🏃\",\n            @\"balance_scale\" :@\"⚖️\",\n            @\"blowfish\" :@\"🐡\",\n            @\"bullettrain_side\" :@\"🚄\",\n            @\"u5272\" :@\"🈹\",\n            @\"nauru\" :@\"🇳🇷\",\n            @\"business_suit_levitating\" :@\"🕴️\",\n            @\"biting_lip\" :@\"🫦\",\n            @\"basket\" :@\"🧺\",\n            @\"carousel_horse\" :@\"🎠\",\n            @\"o2\" :@\"🅾️\",\n            @\"crystal_ball\" :@\"🔮\",\n            @\"small_blue_diamond\" :@\"🔹\",\n            @\"video\" :@\"🎥\",\n            @\"netherlands\" :@\"🇳🇱\",\n            @\"kimono\" :@\"👘\",\n            @\"scorpion\" :@\"🦂\",\n            @\"white_heart\" :@\"🤍\",\n            @\"announcement\" :@\"📢\",\n            @\"couple_with_heart_woman_man\" :@\"👩‍❤️‍👨\",\n            @\"eagle\" :@\"🦅\",\n            @\"cherry_blossom\" :@\"🌸\",\n            @\"zebra\" :@\"🦓\",\n            @\"keycap_ten\" :@\"🔟\",\n            @\"green_square\" :@\"🟩\",\n            @\"pakistan\" :@\"🇵🇰\",\n            @\"love_you_gesture\" :@\"🤟\",\n            @\"city_sunset\" :@\"🌆\",\n            @\"page_facing_up\" :@\"📄\",\n            @\"tired\" :@\"😪\",\n            @\"wing\" :@\"🪽\",\n            @\"couplekiss_woman_woman\" :@\"👩‍❤️‍💋‍👩\",\n            @\"dizzy\" :@\"💫\",\n            @\"eye_speech_bubble\" :@\"👁️‍🗨️\",\n            @\"disappointed\" :@\"😞\",\n            @\"letters\" :@\"🔠\",\n            @\"korea\" :@\"🇰🇷\",\n            @\"sob\" :@\"😭\",\n            @\"paintbrush\" :@\"🖌️\",\n            @\"speaking_head\" :@\"🗣️\",\n            @\"arrow_right\" :@\"➡️\",\n            @\"leopard\" :@\"🐆\",\n            @\"arrow_left\" :@\"⬅️\",\n            @\"smile_cat\" :@\"😸\",\n            @\"family_woman_girl_girl\" :@\"👩‍👧‍👧\",\n            @\"petri_dish\" :@\"🧫\",\n            @\"sudan\" :@\"🇸🇩\",\n            @\"moldova\" :@\"🇲🇩\",\n            @\"dodo\" :@\"🦤\",\n            @\"dromedary_camel\" :@\"🐪\",\n            @\"algeria\" :@\"🇩🇿\",\n            @\"helicopter\" :@\"🚁\",\n            @\"shorts\" :@\"🩳\",\n            @\"window\" :@\"🪟\",\n            @\"woozy_face\" :@\"🥴\",\n            @\"dancing_women\" :@\"👯‍♀️\",\n            @\"notification\" :@\"🔔\",\n            @\"french_polynesia\" :@\"🇵🇫\",\n            @\"strong\" :@\"💪\",\n            @\"bubbles\" :@\"🫧\",\n            @\"wink\" :@\"😉\",\n            @\"credit_card\" :@\"💳\",\n            @\"team\" :@\"👥\",\n            @\"pregnant_man\" :@\"🫃\",\n            @\"elf_man\" :@\"🧝‍♂️\",\n            @\"orange_circle\" :@\"🟠\",\n            @\"lesotho\" :@\"🇱🇸\",\n            @\"frowning_man\" :@\"🙍‍♂️\",\n            @\"mandarin\" :@\"🍊\",\n            @\"smiling_face_with_three_hearts\" :@\"🥰\",\n            @\"fish_cake\" :@\"🍥\",\n            @\"white_square_button\" :@\"🔳\",\n            @\"slovakia\" :@\"🇸🇰\",\n            @\"scream\" :@\"😱\",\n            @\"hugs\" :@\"🤗\",\n            @\"rainbow_flag\" :@\"🏳️‍🌈\",\n            @\"investigate\" :@\"🔬\",\n            @\"guadeloupe\" :@\"🇬🇵\",\n            @\"st_helena\" :@\"🇸🇭\",\n            @\"seven\" :@\"7️⃣\",\n            @\"izakaya_lantern\" :@\"🏮\",\n            @\"beetle\" :@\"🪲\",\n            @\"money_with_wings\" :@\"💸\",\n            @\"gym\" :@\"🏋️\",\n            @\"shaking_face\" :@\"🫨\",\n            @\"revolving_hearts\" :@\"💞\",\n            @\"potable_water\" :@\"🚰\",\n            @\"nicaragua\" :@\"🇳🇮\",\n            @\"canary_islands\" :@\"🇮🇨\",\n            @\"blown\" :@\"🤯\",\n            @\"lotus_position\" :@\"🧘\",\n            @\"leaves\" :@\"🍃\",\n            @\"houses\" :@\"🏘️\",\n            @\"man_artist\" :@\"👨‍🎨\",\n            @\"movie_camera\" :@\"🎥\",\n            @\"lollipop\" :@\"🍭\",\n            @\"video_game\" :@\"🎮\",\n            @\"burma\" :@\"🇲🇲\",\n            @\"nerd_face\" :@\"🤓\",\n            @\"woman_in_manual_wheelchair\" :@\"👩‍🦽\",\n            @\"shock\" :@\"🫢\",\n            @\"sport\" :@\"👟\",\n            @\"tool\" :@\"🔨\",\n            @\"honeybee\" :@\"🐝\",\n            @\"angry\" :@\"😡\",\n            @\"paella\" :@\"🥘\",\n            @\"jeans\" :@\"👖\",\n            @\"broken_heart\" :@\"💔\",\n            @\"orange\" :@\"🍊\",\n            @\"man_factory_worker\" :@\"👨‍🏭\",\n            @\"light\" :@\"💡\",\n            @\"pill\" :@\"💊\",\n            @\"clock1230\" :@\"🕧\",\n            @\"grin\" :@\"😁\",\n            @\"tear\" :@\"😢\",\n            @\"snowman_with_snow\" :@\"☃️\",\n            @\"tanzania\" :@\"🇹🇿\",\n            @\"red_envelope\" :@\"🧧\",\n            @\"rofl\" :@\"🤣\",\n            @\"heavy_plus_sign\" :@\"➕\",\n            @\"sos\" :@\"🆘\",\n            @\"family_woman_woman_girl_girl\" :@\"👩‍👩‍👧‍👧\",\n            @\"bucket\" :@\"🪣\",\n            @\"no_bell\" :@\"🔕\",\n            @\"devil\" :@\"😈\",\n            @\"beauty\" :@\"💅\",\n            @\"lol\" :@\"🤣\",\n            @\"jar\" :@\"🫙\",\n            @\"winter\" :@\"❄️\",\n            @\"crying_cat_face\" :@\"😿\",\n            @\"surfing_woman\" :@\"🏄‍♀️\",\n            @\"gemini\" :@\"♊\",\n            @\"signal_strength\" :@\"📶\",\n            @\"nest_with_eggs\" :@\"🪺\",\n            @\"chef\" :@\"👨‍🍳\",\n            @\"orangutan\" :@\"🦧\",\n            @\"first_quarter_moon\" :@\"🌓\",\n            @\"night_with_stars\" :@\"🌃\",\n            @\"gloves\" :@\"🧤\",\n            @\"asterisk\" :@\"*️⃣\",\n            @\"sint_maarten\" :@\"🇸🇽\",\n            @\"bowl_with_spoon\" :@\"🥣\",\n            @\"hushed\" :@\"😯\",\n            @\"atom_symbol\" :@\"⚛️\",\n            @\"dotted_line_face\" :@\"🫥\",\n            @\"whisky\" :@\"🥃\",\n            @\"pinching_hand\" :@\"🤏\",\n            @\"health_worker\" :@\"🧑‍⚕️\",\n            @\"diego_garcia\" :@\"🇩🇬\",\n            @\"saudi_arabia\" :@\"🇸🇦\",\n            @\"right_anger_bubble\" :@\"🗯️\",\n            @\"swirl\" :@\"🌀\",\n            @\"guam\" :@\"🇬🇺\",\n            @\"georgia\" :@\"🇬🇪\",\n            @\"athletic_shoe\" :@\"👟\",\n            @\"strawberry\" :@\"🍓\",\n            @\"tajikistan\" :@\"🇹🇯\",\n            @\"christmas_tree\" :@\"🎄\",\n            @\"city_sunrise\" :@\"🌇\",\n            @\"bento\" :@\"🍱\",\n            @\"autumn\" :@\"🍂\",\n            @\"placard\" :@\"🪧\",\n            @\"vs\" :@\"🆚\",\n            @\"mayotte\" :@\"🇾🇹\",\n            @\"dart\" :@\"🎯\",\n            @\"repeat_one\" :@\"🔂\",\n            @\"money\" :@\"💵\",\n            @\"car\" :@\"🚗\",\n            @\"mortar_board\" :@\"🎓\",\n            @\"ok\" :@\"👍\",\n            @\"yin_yang\" :@\"☯️\",\n            @\"red_haired_woman\" :@\"👩‍🦰\",\n            @\"mending_heart\" :@\"❤️‍🩹\",\n            @\"moose\" :@\"🫎\",\n            @\"medal_military\" :@\"🎖️\",\n            @\"checkered_flag\" :@\"🏁\",\n            @\"european_union\" :@\"🇪🇺\",\n            @\"sauna_man\" :@\"🧖‍♂️\",\n            @\"label\" :@\"🏷️\",\n            @\"om\" :@\"🕉️\",\n            @\"medical_symbol\" :@\"⚕️\",\n            @\"on\" :@\"🔛\",\n            @\"cat\" :@\"🐱\",\n            @\"sun_behind_rain_cloud\" :@\"🌦️\",\n            @\"open_book\" :@\"📖\",\n            @\"singer\" :@\"🧑‍🎤\",\n            @\"man_with_probing_cane\" :@\"👨‍🦯\",\n            @\"philippines\" :@\"🇵🇭\",\n            @\"present\" :@\"🎁\",\n            @\"british_virgin_islands\" :@\"🇻🇬\",\n            @\"woman_in_tuxedo\" :@\"🤵‍♀️\",\n            @\"confused\" :@\"😕\",\n            @\"phew\" :@\"😥\",\n            @\"seedling\" :@\"🌱\",\n            @\"bronze\" :@\"🥉\",\n            @\"x_ray\" :@\"🩻\",\n            @\"long_drum\" :@\"🪘\",\n            @\"kiss\" :@\"💋\",\n            @\"colombia\" :@\"🇨🇴\",\n            @\"ab\" :@\"🆎\",\n            @\"ox\" :@\"🐂\",\n            @\"womans_clothes\" :@\"👚\",\n            @\"twisted_rightwards_arrows\" :@\"🔀\",\n            @\"stuck_out_tongue\" :@\"😛\",\n            @\"kangaroo\" :@\"🦘\",\n            @\"cheese\" :@\"🧀\",\n            @\"prosper\" :@\"🖖\",\n            @\"man_farmer\" :@\"👨‍🌾\",\n            @\"jersey\" :@\"🇯🇪\",\n            @\"raising_hand_woman\" :@\"🙋‍♀️\",\n            @\"hankey\" :@\"💩\",\n            @\"jellyfish\" :@\"🪼\",\n            @\"speech_balloon\" :@\"💬\",\n            @\"heart\" :@\"💘\",\n            @\"arrow_upper_left\" :@\"↖️\",\n            @\"gear\" :@\"⚙️\",\n            @\"feather\" :@\"🪶\",\n            @\"brunei\" :@\"🇧🇳\",\n            @\"milky_way\" :@\"🌌\",\n            @\"luxembourg\" :@\"🇱🇺\",\n            @\"latin_cross\" :@\"✝️\",\n            @\"purple_heart\" :@\"💜\",\n            @\"superhero\" :@\"🦸\",\n            @\"call\" :@\"📲\",\n            @\"karl\" :@\"🌁\",\n            @\"maracas\" :@\"🪇\",\n            @\"orange_square\" :@\"🟧\",\n            @\"t-rex\" :@\"🦖\",\n            @\"black_nib\" :@\"✒️\",\n            @\"blue_book\" :@\"📘\",\n            @\"minidisc\" :@\"💽\",\n            @\"chair\" :@\"🪑\",\n            @\"doctor\" :@\"👨‍⚕️\",\n            @\"nurse\" :@\"👨‍⚕️\",\n            @\"luggage\" :@\"🧳\",\n            @\"woman_juggling\" :@\"🤹‍♀️\",\n            @\"bullettrain_front\" :@\"🚅\",\n            @\"skunk\" :@\"🦨\",\n            @\"cake\" :@\"🍰\",\n            @\"running\" :@\"🏃\",\n            @\"hammer_and_pick\" :@\"⚒️\",\n            @\"star_and_crescent\" :@\"☪️\",\n            @\"lemon\" :@\"🍋\",\n            @\"school\" :@\"👨‍🏫\",\n            @\"hedgehog\" :@\"🦔\",\n            @\"tennis\" :@\"🎾\",\n            @\"pencil2\" :@\"✏️\",\n            @\"sweat_drops\" :@\"💦\",\n            @\"reminder_ribbon\" :@\"🎗️\",\n            @\"flower\" :@\"🌸\",\n            @\"leftwards_pushing_hand\" :@\"🫷\",\n            @\"noodle\" :@\"🍜\",\n            @\"love_hotel\" :@\"🏩\",\n            @\"oncoming_automobile\" :@\"🚘\",\n            @\"helmet\" :@\"👷\",\n            @\"woman_singer\" :@\"👩‍🎤\",\n            @\"summer\" :@\"🍹\",\n            @\"sassy_woman\" :@\"💁‍♀️\",\n            @\"rooster\" :@\"🐓\",\n            @\"denied\" :@\"🙅\",\n            @\"repeat\" :@\"🔁\",\n            @\"dna\" :@\"🧬\",\n            @\"money_mouth_face\" :@\"🤑\",\n            @\"lantern\" :@\"🏮\",\n            @\"guitar\" :@\"🎸\",\n            @\"clipboard\" :@\"📋\",\n            @\"bouncing_ball_woman\" :@\"⛹️‍♀️\",\n            @\"wheelchair\" :@\"♿\",\n            @\"play_or_pause_button\" :@\"⏯️\",\n            @\"genie_man\" :@\"🧞‍♂️\",\n            @\"france\" :@\"🇫🇷\",\n            @\"bouncing_ball_person\" :@\"⛹️\",\n            @\"sun_behind_small_cloud\" :@\"🌤️\",\n            @\"exploding_head\" :@\"🤯\",\n            @\"shaved_ice\" :@\"🍧\",\n            @\"football\" :@\"🏈\",\n            @\"construction_worker\" :@\"👷\",\n            @\"family_woman_girl\" :@\"👩‍👧\",\n            @\"safety_vest\" :@\"🦺\",\n            @\"package\" :@\"📦\",\n            @\"shoe\" :@\"👞\",\n            @\"farmer\" :@\"🧑‍🌾\",\n            @\"mechanic\" :@\"🧑‍🔧\",\n            @\"waning_gibbous_moon\" :@\"🌖\",\n            @\"ambulance\" :@\"🚑\",\n            @\"couch_and_lamp\" :@\"🛋️\",\n            @\"bathtub\" :@\"🛁\",\n            @\"congratulations\" :@\"㊗️\",\n            @\"st_pierre_miquelon\" :@\"🇵🇲\",\n            @\"justice\" :@\"👨‍⚖️\",\n            @\"judge\" :@\"🧑‍⚖️\",\n            @\"fast_forward\" :@\"⏩\",\n            @\"bikini\" :@\"👙\",\n            @\"man_office_worker\" :@\"👨‍💼\",\n            @\"medal_sports\" :@\"🏅\",\n            @\"artist\" :@\"🧑‍🎨\",\n            @\"camera_flash\" :@\"📸\",\n            @\"marathon\" :@\"🏃\",\n            @\"password\" :@\"🔑\",\n            @\"kuwait\" :@\"🇰🇼\",\n            @\"sleuth\" :@\"🕵️\",\n            @\"mailbox\" :@\"📫\",\n            @\"woman_student\" :@\"👩‍🎓\",\n            @\"bicyclist\" :@\"🚴\",\n            @\"whew\" :@\"😌\",\n            @\"anchor\" :@\"⚓\",\n            @\"loudspeaker\" :@\"📢\",\n            @\"palms_up_together\" :@\"🤲\",\n            @\"necktie\" :@\"👔\",\n            @\"chocolate_bar\" :@\"🍫\",\n            @\"zombie_woman\" :@\"🧟‍♀️\",\n            @\"morning\" :@\"⏰\",\n            @\"expressionless\" :@\"😑\",\n            @\"chess_pawn\" :@\"♟️\",\n            @\"save\" :@\"💾\",\n            @\"film_projector\" :@\"📽️\",\n            @\"green_book\" :@\"📗\",\n            @\"swim_brief\" :@\"🩲\",\n            @\"south_georgia_south_sandwich_islands\" :@\"🇬🇸\",\n            @\"rowboat\" :@\"🚣\",\n            @\"arrow_lower_right\" :@\"↘️\",\n            @\"guatemala\" :@\"🇬🇹\",\n            @\"broom\" :@\"🧹\",\n            @\"bags\" :@\"🛍️\",\n            @\"brazil\" :@\"🇧🇷\",\n            @\"symbols\" :@\"🔣\",\n            @\"workout\" :@\"💦\",\n            @\"cameroon\" :@\"🇨🇲\",\n            @\"mouse_trap\" :@\"🪤\",\n            @\"woman_office_worker\" :@\"👩‍💼\",\n            @\"person_in_tuxedo\" :@\"🤵\",\n            @\"diya_lamp\" :@\"🪔\",\n            @\"sierra_leone\" :@\"🇸🇱\",\n            @\"angola\" :@\"🇦🇴\",\n            @\"point_left\" :@\"👈\",\n            @\"hourglass_flowing_sand\" :@\"⏳\",\n            @\"stop_sign\" :@\"🛑\",\n            @\"family_man_man_girl\" :@\"👨‍👨‍👧\",\n            @\"lotion_bottle\" :@\"🧴\",\n            @\"mobile\" :@\"📱\",\n            @\"rock\" :@\"🪨\",\n            @\"hammer_and_wrench\" :@\"🛠️\",\n            @\"clock1\" :@\"🕐\",\n            @\"tshirt\" :@\"👕\",\n            @\"skating\" :@\"⛸️\",\n            @\"microbe\" :@\"🦠\",\n            @\"cream\" :@\"💰\",\n            @\"india\" :@\"🇮🇳\",\n            @\"stop\" :@\"✋\",\n            @\"funeral\" :@\"⚰️\",\n            @\"steamy\" :@\"🧖\",\n            @\"gold\" :@\"🏅\",\n            @\"russia\" :@\"🇷🇺\",\n            @\"fungus\" :@\"🍄\",\n            @\"point_right\" :@\"👉\",\n            @\"security\" :@\"🔒\",\n            @\"sweet\" :@\"🍬\",\n            @\"disguised_face\" :@\"🥸\",\n            @\"pouch\" :@\"👝\",\n            @\"truck\" :@\"🚚\",\n            @\"u6307\" :@\"🈯\",\n            @\"guardsman\" :@\"💂‍♂️\",\n            @\"clock2\" :@\"🕑\",\n            @\"cricket\" :@\"🦗\",\n            @\"construction_worker_woman\" :@\"👷‍♀️\",\n            @\"peanuts\" :@\"🥜\",\n            @\"golf\" :@\"⛳\",\n            @\"us_virgin_islands\" :@\"🇻🇮\",\n            @\"sensu\" :@\"🪭\",\n            @\"hearts\" :@\"♥️\",\n            @\"man_with_turban\" :@\"👳‍♂️\",\n            @\"french\" :@\"🇫🇷\",\n            @\"eye\" :@\"👁️\",\n            @\"breast_feeding\" :@\"🤱\",\n            @\"raising_hand_man\" :@\"🙋‍♂️\",\n            @\"footprints\" :@\"👣\",\n            @\"card_file_box\" :@\"🗃️\",\n            @\"cold_sweat\" :@\"😰\",\n            @\"smug\" :@\"😏\",\n            @\"whine\" :@\"😫\",\n            @\"rice_scene\" :@\"🎑\",\n            @\"inbox_tray\" :@\"📥\",\n            @\"smiling_face_with_tear\" :@\"🥲\",\n            @\"handbag\" :@\"👜\",\n            @\"lotus\" :@\"🪷\",\n            @\"fleur_de_lis\" :@\"⚜️\",\n            @\"five\" :@\"5️⃣\",\n            @\"dessert\" :@\"🍰\",\n            @\"drop_of_blood\" :@\"🩸\",\n            @\"libra\" :@\"♎\",\n            @\"weapon\" :@\"🔫\",\n            @\"coconut\" :@\"🥥\",\n            @\"hope\" :@\"🙏\",\n            @\"hamsa\" :@\"🪬\",\n            @\"u7a7a\" :@\"🈳\",\n            @\"fried_shrimp\" :@\"🍤\",\n            @\"shushing_face\" :@\"🤫\",\n            @\"clock3\" :@\"🕒\",\n            @\"wind_face\" :@\"🌬️\",\n            @\"arrow_lower_left\" :@\"↙️\",\n            @\"skateboard\" :@\"🛹\",\n            @\"point_up\" :@\"☝️\",\n            @\"canned_food\" :@\"🥫\",\n            @\"scotland\" :@\"🏴󠁧󠁢󠁳󠁣󠁴󠁿\",\n            @\"dress\" :@\"💃\",\n            @\"scream_cat\" :@\"🙀\",\n            @\"meditation\" :@\"🧘\",\n            @\"drum\" :@\"🥁\",\n            @\"robot\" :@\"🤖\",\n            @\"chad\" :@\"🇹🇩\",\n            @\"fishing_pole_and_fish\" :@\"🎣\",\n            @\"champagne\" :@\"🍾\",\n            @\"student\" :@\"🧑‍🎓\",\n            @\"icecream\" :@\"🍦\",\n            @\"slow\" :@\"🐢\",\n            @\"massage_man\" :@\"💆‍♂️\",\n            @\"person_in_motorized_wheelchair\" :@\"🧑‍🦼\",\n            @\"busts_in_silhouette\" :@\"👥\",\n            @\"toolbox\" :@\"🧰\",\n            @\"file_folder\" :@\"📁\",\n            @\"bangladesh\" :@\"🇧🇩\",\n            @\"swimming_man\" :@\"🏊‍♂️\",\n            @\"antigua_barbuda\" :@\"🇦🇬\",\n            @\"joy_cat\" :@\"😹\",\n            @\"alembic\" :@\"⚗️\",\n            @\"ballot_box_with_check\" :@\"☑️\",\n            @\"slot_machine\" :@\"🎰\",\n            @\"seychelles\" :@\"🇸🇨\",\n            @\"euro\" :@\"💶\",\n            @\"clock4\" :@\"🕓\",\n            @\"ok_man\" :@\"🙆‍♂️\",\n            @\"gibraltar\" :@\"🇬🇮\",\n            @\"rabbit2\" :@\"🐇\",\n            @\"zombie_man\" :@\"🧟‍♂️\",\n            @\"kneeling_person\" :@\"🧎\",\n            @\"beans\" :@\"🫘\",\n            @\"whoops\" :@\"🤭\",\n            @\"sun_with_face\" :@\"🌞\",\n            @\"pancakes\" :@\"🥞\",\n            @\"sa\" :@\"🈂️\",\n            @\"prayer_beads\" :@\"📿\",\n            @\"hotel\" :@\"🏨\",\n            @\"mobile_phone_off\" :@\"📴\",\n            @\"water_polo\" :@\"🤽\",\n            @\"guernsey\" :@\"🇬🇬\",\n            @\"family_man_woman_girl_girl\" :@\"👨‍👩‍👧‍👧\",\n            @\"studio_microphone\" :@\"🎙️\",\n            @\"parasol_on_ground\" :@\"⛱️\",\n            @\"woman_dancing\" :@\"💃\",\n            @\"bermuda\" :@\"🇧🇲\",\n            @\"mozambique\" :@\"🇲🇿\",\n            @\"male_detective\" :@\"🕵️‍♂️\",\n            @\"mx_claus\" :@\"🧑‍🎄\",\n            @\"beer\" :@\"🍺\",\n            @\"astronaut\" :@\"🧑‍🚀\",\n            @\"hotdog\" :@\"🌭\",\n            @\"hat\" :@\"🎩\",\n            @\"abacus\" :@\"🧮\",\n            @\"pouring_liquid\" :@\"🫗\",\n            @\"paint\" :@\"🎨\",\n            @\"police_car\" :@\"🚓\",\n            @\"sagittarius\" :@\"♐\",\n            @\"new_caledonia\" :@\"🇳🇨\",\n            @\"dvd\" :@\"📀\",\n            @\"king\" :@\"👑\",\n            @\"clock5\" :@\"🕔\",\n            @\"yarn\" :@\"🧶\",\n            @\"bowling\" :@\"🎳\",\n            @\"birthday\" :@\"🥳\",\n            @\"blossom\" :@\"🌼\",\n            @\"cloud_with_lightning\" :@\"🌩️\",\n            @\"vertical_traffic_light\" :@\"🚦\",\n            @\"crush\" :@\"😍\",\n            @\"grapes\" :@\"🍇\",\n            @\"explode\" :@\"💥\",\n            @\"please\" :@\"🙏\",\n            @\"sandal\" :@\"👡\",\n            @\"electric_plug\" :@\"🔌\",\n            @\"sassy_man\" :@\"💁‍♂️\",\n            @\"san_marino\" :@\"🇸🇲\",\n            @\"taiwan\" :@\"🇹🇼\",\n            @\"drama\" :@\"🎭\",\n            @\"swaziland\" :@\"🇸🇿\",\n            @\"trash\" :@\"🗑️\",\n            @\"service_dog\" :@\"🐕‍🦺\",\n            @\"woman_playing_handball\" :@\"🤾‍♀️\",\n            @\"andorra\" :@\"🇦🇩\",\n            @\"diamonds\" :@\"♦️\",\n            @\"play\" :@\"🎮\",\n            @\"congo_kinshasa\" :@\"🇨🇩\",\n            @\"man_juggling\" :@\"🤹‍♂️\",\n            @\"ice_cream\" :@\"🍨\",\n            @\"environment\" :@\"♻️\",\n            @\"samoa\" :@\"🇼🇸\",\n            @\"star_struck\" :@\"🤩\",\n            @\"clock6\" :@\"🕕\",\n            @\"palm_tree\" :@\"🌴\",\n            @\"lady_beetle\" :@\"🐞\",\n            @\"tired_face\" :@\"😫\",\n            @\"balloon\" :@\"🎈\",\n            @\"small_orange_diamond\" :@\"🔸\",\n            @\"frowning_woman\" :@\"🙍‍♀️\",\n            @\"avocado\" :@\"🥑\",\n            @\"camera\" :@\"📷\",\n            @\"curly_haired_man\" :@\"👨‍🦱\",\n            @\"thanksgiving\" :@\"🦃\",\n            @\"cop\" :@\"👮\",\n            @\"mauritania\" :@\"🇲🇷\",\n            @\"man_singer\" :@\"👨‍🎤\",\n            @\"telescope\" :@\"🔭\",\n            @\"man_teacher\" :@\"👨‍🏫\",\n            @\"joy\" :@\"😃\",\n            @\"mountain_biking_man\" :@\"🚵‍♂️\",\n            @\"jigsaw\" :@\"🧩\",\n            @\"clap\" :@\"👏\",\n            @\"indonesia\" :@\"🇮🇩\",\n            @\"taurus\" :@\"♉\",\n            @\"panda_face\" :@\"🐼\",\n            @\"mirror_ball\" :@\"🪩\",\n            @\"american_samoa\" :@\"🇦🇸\",\n            @\"taxi\" :@\"🚕\",\n            @\"folding_hand_fan\" :@\"🪭\",\n            @\"martial_arts_uniform\" :@\"🥋\",\n            @\"hook\" :@\"🪝\",\n            @\"wheel_of_dharma\" :@\"☸️\",\n            @\"taste\" :@\"👅\",\n            @\"warning\" :@\"⚠️\",\n            @\"clock7\" :@\"🕖\",\n            @\"classy\" :@\"🎩\",\n            @\"es\" :@\"🇪🇸\",\n            @\"cow\" :@\"🐮\",\n            @\"billiards\" :@\"🎱\",\n            @\"kaaba\" :@\"🕋\",\n            @\"family_woman_woman_girl\" :@\"👩‍👩‍👧\",\n            @\"metro\" :@\"🚇\",\n            @\"eu\" :@\"🇪🇺\",\n            @\"ill\" :@\"😷\",\n            @\"speedboat\" :@\"🚤\",\n            @\"hear\" :@\"👂\",\n            @\"man_dancing\" :@\"🕺\",\n            @\"bagel\" :@\"🥯\",\n            @\"shipping\" :@\"📦\",\n            @\"one_piece_swimsuit\" :@\"🩱\",\n            @\"fruit\" :@\"🍌\",\n            @\"girls\" :@\"👩\",\n            @\"denmark\" :@\"🇩🇰\",\n            @\"toilet\" :@\"🚽\",\n            @\"genie_woman\" :@\"🧞‍♀️\",\n            @\"potato\" :@\"🥔\",\n            @\"contest\" :@\"🏆\",\n            @\"lock\" :@\"🔒\",\n            @\"back\" :@\"🔙\",\n            @\"heat\" :@\"🥵\",\n            @\"fuelpump\" :@\"⛽\",\n            @\"clock8\" :@\"🕗\",\n            @\"toast\" :@\"🍞\",\n            @\"lebanon\" :@\"🇱🇧\",\n            @\"whale\" :@\"🐳\",\n            @\"smile\" :@\"😀\",\n            @\"satellite\" :@\"📡\",\n            @\"sauna_woman\" :@\"🧖‍♀️\",\n            @\"-1\" :@\"👎\",\n            @\"photo\" :@\"📷\",\n            @\"flirt\" :@\"😉\",\n            @\"portugal\" :@\"🇵🇹\",\n            @\"tiger\" :@\"🐯\",\n            @\"north_korea\" :@\"🇰🇵\",\n            @\"baguette_bread\" :@\"🥖\",\n            @\"flat_shoe\" :@\"🥿\",\n            @\"ng_woman\" :@\"🙅‍♀️\",\n            @\"green_apple\" :@\"🍏\",\n            @\"space\" :@\"👨‍🚀\",\n            @\"kissing_cat\" :@\"😽\",\n            @\"ring\" :@\"💍\",\n            @\"tractor\" :@\"🚜\",\n            @\"tonga\" :@\"🇹🇴\",\n            @\"festival\" :@\"🎆\",\n            @\"auto_rickshaw\" :@\"🛺\",\n            @\"full_moon\" :@\"🌕\",\n            @\"film_strip\" :@\"🎞️\",\n            @\"clock9\" :@\"🕘\",\n            @\"tumbler_glass\" :@\"🥃\",\n            @\"incoming\" :@\"📲\",\n            @\"comment\" :@\"💬\",\n            @\"mountain_biking_woman\" :@\"🚵‍♀️\",\n            @\"crayon\" :@\"🖍️\",\n            @\"standing_woman\" :@\"🧍‍♀️\",\n            @\"pout\" :@\"😡\",\n            @\"honk\" :@\"🪿\",\n            @\"cold_face\" :@\"🥶\",\n            @\"stopwatch\" :@\"⏱️\",\n            @\"cafe\" :@\"☕\",\n            @\"freezing\" :@\"🥶\",\n            @\"email\" :@\"💌\",\n            @\"family_man_man_boy_boy\" :@\"👨‍👨‍👦‍👦\",\n            @\"oncoming_bus\" :@\"🚍\",\n            @\"ghana\" :@\"🇬🇭\",\n            @\"hong_kong\" :@\"🇭🇰\",\n            @\"tram\" :@\"🚊\",\n            @\"family_man_boy_boy\" :@\"👨‍👦‍👦\",\n            @\"trackball\" :@\"🖲️\",\n            @\"woman_health_worker\" :@\"👩‍⚕️\",\n            @\"arrow_heading_down\" :@\"⤵️\",\n            @\"two_women_holding_hands\" :@\"👭\",\n            @\"flower_playing_cards\" :@\"🎴\",\n            @\"oman\" :@\"🇴🇲\",\n            @\"hand_with_index_finger_and_thumb_crossed\" :@\"🫰\",\n            @\"dolls\" :@\"🎎\",\n            @\"signal\" :@\"📡\",\n            @\"sleeping_bed\" :@\"🛌\",\n            @\"home\" :@\"👪\",\n            @\"rhinoceros\" :@\"🦏\",\n            @\"beers\" :@\"🍻\",\n            @\"pasta\" :@\"🍝\",\n            @\"bricks\" :@\"🧱\",\n            @\"subscription\" :@\"💳\",\n            @\"shield\" :@\"🛡️\",\n            @\"rocket\" :@\"🚀\",\n            @\"weight_lifting_man\" :@\"🏋️‍♂️\",\n            @\"biking_man\" :@\"🚴‍♂️\",\n            @\"oops\" :@\"😨\",\n            @\"skull_and_crossbones\" :@\"☠️\",\n            @\"desktop\" :@\"💻\",\n            @\"professor\" :@\"👨‍🏫\",\n            @\"sari\" :@\"🥻\",\n            @\"struggling\" :@\"😣\",\n            @\"baby_chick\" :@\"🐤\",\n            @\"trademark\" :@\"™️\",\n            @\"wizard\" :@\"🧙\",\n            @\"laboratory\" :@\"🔬\",\n            @\"fish\" :@\"🐟\",\n            @\"puppy\" :@\"🥺\",\n            @\"beverage_box\" :@\"🧃\",\n            @\"heard_mcdonald_islands\" :@\"🇭🇲\",\n            @\"envelope_with_arrow\" :@\"📩\",\n            @\"liberia\" :@\"🇱🇷\",\n            @\"trolleybus\" :@\"🚎\",\n            @\"thought_balloon\" :@\"💭\",\n            @\"lying_face\" :@\"🤥\",\n            @\"chart_with_upwards_trend\" :@\"📈\",\n            @\"stunned\" :@\"😧\",\n            @\"mute\" :@\"😶\",\n            @\"house\" :@\"🏠\",\n            @\"orbit\" :@\"🛰️\",\n            @\"ufo\" :@\"👽\",\n            @\"wifi\" :@\"📶\",\n            @\"face_with_peeking_eye\" :@\"🫣\",\n            @\"tag\" :@\"🏷️\",\n            @\"groom\" :@\"🤵\",\n            @\"identification_card\" :@\"🪪\",\n            @\"flipper\" :@\"🐬\",\n            @\"3rd_place_medal\" :@\"🥉\",\n            @\"cigarette\" :@\"🚬\",\n            @\"timor_leste\" :@\"🇹🇱\",\n            @\"bahamas\" :@\"🇧🇸\",\n            @\"limit\" :@\"⛔\",\n            @\"guardswoman\" :@\"💂‍♀️\",\n            @\"mate\" :@\"🧉\",\n            @\"makeup\" :@\"💄\",\n            @\"cut\" :@\"🔪\",\n            @\"sloth\" :@\"🦥\",\n            @\"libya\" :@\"🇱🇾\",\n            @\"cayman_islands\" :@\"🇰🇾\",\n            @\"mad\" :@\"😠\",\n            @\"waxing_crescent_moon\" :@\"🌒\",\n            @\"marriage\" :@\"🤵\",\n            @\"facepunch\" :@\"👊\",\n            @\"virgo\" :@\"♍\",\n            @\"doughnut\" :@\"🍩\",\n            @\"clubs\" :@\"♣️\",\n            @\"running_shirt_with_sash\" :@\"🎽\",\n            @\"brown_circle\" :@\"🟤\",\n            @\"capricorn\" :@\"♑\",\n            @\"mag\" :@\"🔍\",\n            @\"fire\" :@\"🔥\",\n            @\"moyai\" :@\"🗿\",\n            @\"telephone_receiver\" :@\"📞\",\n            @\"guyana\" :@\"🇬🇾\",\n            @\"medicine\" :@\"💊\",\n            @\"call_me_hand\" :@\"🤙\",\n            @\"anguished\" :@\"😧\",\n            @\"family_woman_boy\" :@\"👩‍👦\",\n            @\"clipperton_island\" :@\"🇨🇵\",\n            @\"hole\" :@\"🕳️\",\n            @\"pride\" :@\"🏳️‍🌈\",\n            @\"parrot\" :@\"🦜\",\n            @\"pinched_fingers\" :@\"🤌\",\n            @\"curly_loop\" :@\"➰\",\n            @\"malta\" :@\"🇲🇹\",\n            @\"banana\" :@\"🍌\",\n            @\"rotating_light\" :@\"🚨\",\n            @\"ginger_root\" :@\"🫚\",\n            @\"pregnant_person\" :@\"🫄\",\n            @\"motor_scooter\" :@\"🛵\",\n            @\"abcd\" :@\"🔡\",\n            @\"germany\" :@\"🇩🇪\",\n            @\"department_store\" :@\"🏬\",\n            @\"parents\" :@\"👪\",\n            @\"scissors\" :@\"✂️\",\n            @\"thermometer\" :@\"🌡️\",\n            @\"tangerine\" :@\"🍊\",\n            @\"heart_on_fire\" :@\"❤️‍🔥\",\n            @\"dread\" :@\"🫠\",\n            @\"nauseated_face\" :@\"🤢\",\n            @\"derelict_house\" :@\"🏚️\",\n            @\"heavy_check_mark\" :@\"✔️\",\n            @\"brown_square\" :@\"🟫\",\n            @\"white_medium_small_square\" :@\"◽\",\n            @\"ringed_planet\" :@\"🪐\",\n            @\"heart_eyes\" :@\"😍\",\n            @\"microphone\" :@\"🎤\",\n            @\"central_african_republic\" :@\"🇨🇫\",\n            @\"man\" :@\"👨\",\n            @\"pirate_flag\" :@\"🏴‍☠️\",\n            @\"shamrock\" :@\"☘️\",\n            @\"relaxed\" :@\"☺️\",\n            @\"black_flag\" :@\"🏴\",\n            @\"tea\" :@\"🍵\",\n            @\"fairy_woman\" :@\"🧚‍♀️\",\n            @\"black_square_button\" :@\"🔲\",\n            @\"togo\" :@\"🇹🇬\",\n            @\"station\" :@\"🚉\",\n            @\"horns\" :@\"😈\",\n            @\"book\" :@\"📖\",\n            @\"baby\" :@\"👶\",\n            @\"mirror\" :@\"🪞\",\n            @\"empty_nest\" :@\"🪹\",\n            @\"fist\" :@\"✊\",\n            @\"drink\" :@\"🍸\",\n            @\"information\" :@\"💁‍♂️\",\n            @\"butterfly\" :@\"🦋\",\n            @\"woman_cook\" :@\"👩‍🍳\",\n            @\"family_man_woman_girl_boy\" :@\"👨‍👩‍👧‍👦\",\n            @\"smiley_cat\" :@\"😺\",\n            @\"lips\" :@\"👄\",\n            @\"lab_coat\" :@\"🥼\",\n            @\"ghost\" :@\"👻\",\n            @\"person_white_hair\" :@\"🧑‍🦳\",\n            @\"ramen\" :@\"🍜\",\n            @\"wc\" :@\"🚽\",\n            @\"fast\" :@\"💨\",\n            @\"woman_with_headscarf\" :@\"🧕\",\n            @\"page_with_curl\" :@\"📃\",\n            @\"uganda\" :@\"🇺🇬\",\n            @\"bear\" :@\"🐻\",\n            @\"boom\" :@\"💥\",\n            @\"first_quarter_moon_with_face\" :@\"🌛\",\n            @\"red_square\" :@\"🟥\",\n            @\"trinidad_tobago\" :@\"🇹🇹\",\n            @\"older_adult\" :@\"🧓\",\n            @\"sri_lanka\" :@\"🇱🇰\",\n            @\"grimacing\" :@\"😬\",\n            @\"baby_bottle\" :@\"🍼\",\n            @\"metal\" :@\"🤘\",\n            @\"rabbit\" :@\"🐰\",\n            @\"kneeling_woman\" :@\"🧎‍♀️\",\n            @\"magic_wand\" :@\"🪄\",\n            @\"bone\" :@\"🦴\",\n            @\"life preserver\" :@\"🛟\",\n            @\"family_man_girl_boy\" :@\"👨‍👧‍👦\",\n            @\"listen\" :@\"👂\",\n            @\"microscope\" :@\"🔬\",\n            @\"mag_right\" :@\"🔎\",\n            @\"bangbang\" :@\"‼️\",\n            @\"finish\" :@\"🏁\",\n            @\"brain\" :@\"🧠\",\n            @\"family_man_girl_girl\" :@\"👨‍👧‍👧\",\n            @\"climbing_woman\" :@\"🧗‍♀️\",\n            @\"european_castle\" :@\"🏰\",\n            @\"leftwards_arrow_with_hook\" :@\"↩️\",\n            @\"customs\" :@\"🛃\",\n            @\"put_litter_in_its_place\" :@\"🚮\",\n            @\"vatican_city\" :@\"🇻🇦\",\n            @\"standing_person\" :@\"🧍\",\n            @\"pick\" :@\"⛏️\",\n            @\"lion\" :@\"🦁\",\n            @\"men_wrestling\" :@\"🤼‍♂️\",\n            @\"level_slider\" :@\"🎚️\",\n            @\"no_good\" :@\"🙅\",\n            @\"french_guiana\" :@\"🇬🇫\",\n            @\"jordan\" :@\"🇯🇴\",\n            @\"framed_picture\" :@\"🖼️\",\n            @\"coffin\" :@\"⚰️\",\n            @\"wrench\" :@\"🔧\",\n            @\"u55b6\" :@\"🈺\",\n            @\"cloud_with_lightning_and_rain\" :@\"⛈️\",\n            @\"crocodile\" :@\"🐊\",\n            @\"khanda\" :@\"🪯\",\n            @\"desert\" :@\"🐪\",\n            @\"united\" :@\"🇺🇸\",\n            @\"boxing_glove\" :@\"🥊\",\n            @\"mask\" :@\"😷\",\n            @\"nail_care\" :@\"💅\",\n            @\"sauropod\" :@\"🦕\",\n            @\"large_blue_diamond\" :@\"🔷\",\n            @\"scared\" :@\"😨\",\n            @\"skull\" :@\"💀\",\n            @\"meh\" :@\"😐\",\n            @\"id\" :@\"🆔\",\n            @\"palestinian_territories\" :@\"🇵🇸\",\n            @\"yemen\" :@\"🇾🇪\",\n            @\"penguin\" :@\"🐧\",\n            @\"guard\" :@\"💂\",\n            @\"two_hearts\" :@\"💕\",\n            @\"bottle\" :@\"🍾\",\n            @\"education\" :@\"🎓\",\n            @\"fax\" :@\"📠\",\n            @\"eyeglasses\" :@\"👓\",\n            @\"2nd_place_medal\" :@\"🥈\",\n            @\"zero\" :@\"0️⃣\",\n            @\"loud_sound\" :@\"🔊\",\n            @\"christmas_island\" :@\"🇨🇽\",\n            @\"poodle\" :@\"🐩\",\n            @\"namibia\" :@\"🇳🇦\",\n            @\"face_with_head_bandage\" :@\"🤕\",\n            @\"unamused\" :@\"😒\",\n            @\"boot\" :@\"👢\",\n            @\"racehorse\" :@\"🐎\",\n            @\"bomb\" :@\"💣\",\n            @\"hot\" :@\"😅\",\n            @\"underage\" :@\"🔞\",\n            @\"ship\" :@\"⚓\",\n            @\"fortune_cookie\" :@\"🥠\",\n            @\"heavy_minus_sign\" :@\"➖\",\n            @\"zambia\" :@\"🇿🇲\",\n            @\"onion\" :@\"🧅\",\n            @\"score\" :@\"💯\",\n            @\"gift_heart\" :@\"💝\",\n            @\"dove\" :@\"🕊️\",\n            @\"perfect\" :@\"💯\",\n            @\"ok_hand\" :@\"👌\",\n            @\"laos\" :@\"🇱🇦\",\n            @\"link\" :@\"🔗\",\n            @\"post_office\" :@\"🏣\",\n            @\"mans_shoe\" :@\"👞\",\n            @\"italy\" :@\"🇮🇹\",\n            @\"no_pedestrians\" :@\"🚷\",\n            @\"spoon\" :@\"🥄\",\n            @\"swan\" :@\"🦢\",\n            @\"it\" :@\"🇮🇹\",\n            @\"sunflower\" :@\"🌻\",\n            @\"writing_hand\" :@\"✍️\",\n            @\"ear_with_hearing_aid\" :@\"🦻\",\n            @\"applause\" :@\"👏\",\n            @\"unlock\" :@\"🔓\",\n            @\"no_mouth\" :@\"😶\",\n            @\"crown\" :@\"🤴\",\n            @\"open_file_folder\" :@\"📂\",\n            @\"bouvet_island\" :@\"🇧🇻\",\n            @\"austria\" :@\"🇦🇹\",\n            @\"swimming_woman\" :@\"🏊‍♀️\",\n            @\"number\" :@\"#️⃣\",\n            @\"face_with_open_eyes_and_hand_over_mouth\" :@\"🫢\",\n            @\"couple_with_heart\" :@\"💑\",\n            @\"raised_hand\" :@\"✋\",\n            @\"shit\" :@\"💩\",\n            @\"achoo\" :@\"🤧\",\n            @\"people_hugging\" :@\"🫂\",\n            @\"pig_nose\" :@\"🐽\",\n            @\"couplekiss_man_man\" :@\"👨‍❤️‍💋‍👨\",\n            @\"cuba\" :@\"🇨🇺\",\n            @\"princess\" :@\"👸\",\n            @\"drooling_face\" :@\"🤤\",\n            @\"man_scientist\" :@\"👨‍🔬\",\n            @\"record_button\" :@\"⏺️\",\n            @\"left_right_arrow\" :@\"↔️\",\n            @\"soap\" :@\"🧼\"\n        };\n    }\n    return self;\n}\n\n- (NSString *)emojiWithName:(NSString *)name {\n    if ([name isKindOfClass:NSString.class] && name.length > 0) {\n        NSString *cleanName = [name stringByReplacingOccurrencesOfString:@\":\" withString:@\"\"];\n        return self.emojiMap[cleanName];\n    }\n    return nil;\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMGradient.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n#import <AntMarkdown/AMDrawable.h>\n#import <AntMarkdown/AMUnderline.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMGradient : NSObject <AMDrawable, AMUnderlineDrawable>\n@property (nonatomic) NSArray <UIColor *> *colors;\n@property (nonatomic, nullable) NSArray <NSNumber *> *locations;\n@property (nonatomic) CGPoint startPoint, endPoint;\n@property (nonatomic, nullable) NSNumber *degree;  // angle，0 is from top to bottom，clockwise\n@property (nonatomic, readonly) CGGradientRef CGGradient;\n\n+ (instancetype)gradientWithColors:(NSArray <UIColor *> *)colors;\n+ (instancetype)gradientWithColors:(NSArray <UIColor *> *)colors \n                        startPoint:(CGPoint)start\n                          endPoint:(CGPoint)end;\n+ (instancetype)gradientWithColors:(NSArray <UIColor *> *)colors\n                         locations:(NSArray<NSNumber *> * _Nullable)locations\n                        startPoint:(CGPoint)start\n                          endPoint:(CGPoint)end;\n+ (instancetype)gradientWithColors:(NSArray <UIColor *> *)colors\n                         locations:(NSArray<NSNumber *> * _Nullable)locations\n                           degree:(CGFloat)degree;\n\n- (BOOL)isEqualToGradient:(AMGradient *)gradient;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMGradient.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMGradient.h\"\n#import \"AMUtils.h\"\n\n@implementation AMGradient\n{\n    \n}\n\n+ (instancetype)gradientWithColors:(NSArray<UIColor *> *)colors {\n    return [self gradientWithColors:colors locations:nil \n                         startPoint:CGPointMake(0.5, 0)\n                           endPoint:CGPointMake(0.5, 1)];\n}\n\n+ (instancetype)gradientWithColors:(NSArray<UIColor *> *)colors \n                        startPoint:(CGPoint)start\n                          endPoint:(CGPoint)end\n{\n    return [self gradientWithColors:colors locations:nil \n                         startPoint:start endPoint:end];\n}\n\n+ (instancetype)gradientWithColors:(NSArray<UIColor *> *)colors \n                         locations:(NSArray<NSNumber *> *)locations\n                        startPoint:(CGPoint)start\n                          endPoint:(CGPoint)end\n{\n    AMGradient *g = [self new];\n    g.colors = colors;\n    g.locations = locations;\n    g.startPoint = start;\n    g.endPoint = end;\n    return g;\n}\n\n+ (instancetype)gradientWithColors:(NSArray<UIColor *> *)colors\n                         locations:(NSArray<NSNumber *> *)locations\n                            degree:(CGFloat)degree {\n    AMGradient *g = [self new];\n    g.colors = colors;\n    g.locations = locations;\n    g.degree = @(degree);\n    return g;\n}\n\n- (void)drawInRect:(CGRect)rect clipEdges:(UIRectEdge)edges {\n    \n    CGPoint startPoint = self.startPoint;\n    CGPoint endPoint = self.endPoint;\n    if (self.degree != nil) {\n        UIBezierPath* rectanglePath = [UIBezierPath bezierPathWithRect: rect];\n        UIBezierPath* rectangleRotatedPath = [rectanglePath copy];\n        CGAffineTransform transform = CGAffineTransformMakeRotation(-self.degree.doubleValue / 180 * M_PI + M_PI_2);\n        [rectangleRotatedPath applyTransform: transform];\n        CGRect rectangleBounds = CGPathGetPathBoundingBox(rectangleRotatedPath.CGPath);\n        transform = CGAffineTransformInvert(transform);\n        \n        startPoint = CGPointApplyAffineTransform(CGPointMake(CGRectGetMinX(rectangleBounds), CGRectGetMidY(rectangleBounds)), transform);\n        endPoint = CGPointApplyAffineTransform(CGPointMake(CGRectGetMaxX(rectangleBounds), CGRectGetMidY(rectangleBounds)), transform);\n    }\n    CGContextRef context = UIGraphicsGetCurrentContext();\n    CGContextSaveGState(context);\n    CGContextClipToRect(context, rect);\n    CGContextDrawLinearGradient(context, self.CGGradient, startPoint, endPoint, 0);\n    CGContextRestoreGState(context);\n}\n\n- (void)drawInRect:(CGRect)rect underlineStyle:(NSUnderlineStyle)type baselineOffset:(CGFloat)offset\n{\n    [self drawInRect:rect clipEdges:UIRectEdgeNone];\n}\n\n- (CGGradientRef)CGGradient {\n    CGFloat locations[10] = {0};\n    CGFloat *locationRef = NULL;\n    const int maxCount = sizeof(locations) / sizeof(locations[0]);\n    const bool needMalloc = self.locations.count > maxCount;\n    if (self.locations.count > 0) {\n        locationRef = needMalloc ? malloc(self.locations.count * sizeof(*locationRef)) : locations;\n        [self.locations enumerateObjectsUsingBlock:^(NSNumber * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {\n            locationRef[idx] = obj.doubleValue;\n        }];\n    }\n    \n    CGGradientRef gradient = CGGradientCreateWithColors(nil, (__bridge CFArrayRef)[self.colors mapWithBlock_ant_mark:^id _Nonnull(UIColor * _Nonnull obj) {\n        return (id)obj.CGColor;\n    }], locationRef);\n    \n    if (needMalloc) {\n        free(locationRef);\n    }\n    return (CGGradientRef)CFAutorelease(gradient);\n}\n\n- (BOOL)isEqual:(nullable id)object {\n    if (object == nil) {\n        return NO;\n    }\n    \n    if (self == object) {\n        return YES;\n    }\n    \n    if (![object isKindOfClass:[self class]]) {\n        return NO;\n    }\n    \n    return [self isEqualToGradient:(AMGradient *)object];\n}\n\n- (BOOL)isEqualToGradient:(AMGradient *)gradient\n{\n    return [self.colors isEqualToArray:gradient.colors]\n    && (self.locations == gradient.locations || [self.locations isEqualToArray:gradient.locations])\n    && CGPointEqualToPoint(self.startPoint, gradient.startPoint)\n    && CGPointEqualToPoint(self.endPoint, gradient.endPoint)\n    && self.degree == gradient.degree;\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMGradientLayer.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <QuartzCore/QuartzCore.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMGradientLayer : CAGradientLayer\n\n@property(nonatomic,assign) BOOL isFadeComplete;\n\n@property(nonatomic,assign) NSUInteger lineIndex;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMGradientLayer.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMGradientLayer.h\"\n\n@implementation AMGradientLayer\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMGradientView.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <UIKit/UIKit.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMGradientView : UIView\n@property (nonatomic) NSArray<UIColor *> *colors;\n@property (nonatomic, nullable) NSArray<NSNumber *> *locations;\n@property (nonatomic) CGPoint startPoint, endPoint;\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMGradientView.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMGradientView.h\"\n#import \"AMUtils.h\"\n\n@interface AMGradientView ()\n@property(nonatomic, readonly, strong) CAGradientLayer *layer;\n@end\n\n@implementation AMGradientView\n@dynamic layer;\n\n+ (Class)layerClass\n{\n    return [CAGradientLayer class];\n}\n\n- (instancetype)initWithFrame:(CGRect)frame\n{\n    self = [super initWithFrame:frame];\n    if (self) {\n        self.startPoint = CGPointMake(0, 0.5);\n        self.endPoint = CGPointMake(1, 0.5);\n    }\n    return self;\n}\n\n- (void)setStartPoint:(CGPoint)startPoint\n{\n    _startPoint = startPoint;\n    self.layer.startPoint = startPoint;\n}\n\n- (void)setEndPoint:(CGPoint)endPoint\n{\n    _endPoint = endPoint;\n    self.layer.endPoint = endPoint;\n}\n\n- (void)setColors:(NSArray<UIColor *> *)colors\n{\n    _colors = colors;\n    self.layer.colors = [colors mapWithBlock_ant_mark:^id _Nonnull(UIColor * _Nonnull obj) {\n        return (id)obj.CGColor;\n    }];\n}\n\n- (void)setLocations:(NSArray<NSNumber *> *)locations\n{\n    _locations = locations;\n    self.layer.locations = locations;\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMHTMLTransformer.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <AntMarkdown/CMHTMLElementTransformer.h>\n#import <AntMarkdown/CMHTMLUnderlineTransformer.h>\n#import <AntMarkdown/AMTextStyles.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMHTMLTransformer : NSObject <CMHTMLElementTransformer>\n@property (nonatomic, readonly, weak) AMTextStyles *styles;\n\n- (instancetype)initWithStyles:(AMTextStyles *)styles;\n\n@end\n\n@interface AMHTMLMarkTransformer : AMHTMLTransformer\n\n@end\n\n@interface AMHTMLSpanTransformer : AMHTMLTransformer\n\n@end\n\n@interface AMHTMLCiteTransformer : AMHTMLTransformer\n\n@end\n\n@interface AMHTMLDelTransformer : AMHTMLTransformer\n\n@end\n\n@interface AMHTMLFontTransformer : AMHTMLTransformer\n\n@end\n\n@interface AMHTMLUnderlineTransformer : CMHTMLUnderlineTransformer\n\n- (instancetype)initWithStyle:(NSUnderlineStyle)style\n                        color:(UIColor *)color\n                    lineWidth:(CGFloat)width\n                       offset:(CGFloat)offset NS_DESIGNATED_INITIALIZER;\n\n@end\n\n@interface AMHTMLDefaultTransformer : AMHTMLTransformer\n\n@end\n\n@interface AMHTMLTextLabelTransformer : AMHTMLTransformer\n\n@end\n@interface AMHTMLImgTransformer : AMHTMLTransformer\n\n@end\n@interface AMHTMLIconLinkTransformer : AMHTMLTransformer\n\n@end\n@interface AMHTMLIconTransformer : AMHTMLTransformer\n\n@end\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMHTMLTransformer.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMHTMLTransformer.h\"\n#import \"CMCascadingAttributeStack.h\"\n#import \"ONOXMLDocument.h\"\n#import \"AMUtils.h\"\n#import \"AMDrawable.h\"\n#import \"AMUnderline.h\"\n#import \"AMImageTextAttachment.h\"\n#import \"AMTextBackground.h\"\n#import \"AMIconLinkAttachment.h\"\n#import \"NSString+AntMarkdown.h\"\n#import \"AMUtils.h\"\n#import \"AMIconAttachment.h\"\nconst int kHTMLDefaultFontSize = 20;\n@implementation AMHTMLTransformer\n\n- (NSAttributedString *)attributedStringForElement:(ONOXMLElement *)element attributes:(NSDictionary *)attributes {\n    \n    NSMutableDictionary *allAttributes = [attributes mutableCopy];\n    \n    NSString *className = element.attributes[@\"class\"];\n    if (className.length) {\n        CMStyleAttributes *styles = [self.styles attributesForClass:className];\n        \n        if (styles.stringAttributes.count > 0) {\n            [allAttributes addEntriesFromDictionary:styles.stringAttributes];\n        }\n        \n        if (styles.fontAttributes.count > 0) {\n            UIFont *baseFont = allAttributes[NSFontAttributeName];\n            UIFont *adjustedFont = nil;\n            if (baseFont != nil) {\n                adjustedFont = [baseFont fontByAddingCMAttributes:styles.fontAttributes];\n            }\n            else {\n                UIFontDescriptor * adjustedFontDescriptor = [UIFontDescriptor fontDescriptorWithFontAttributes:styles.fontAttributes];\n                if (adjustedFontDescriptor != nil) {\n                    adjustedFont = [CMFont fontWithDescriptor:adjustedFontDescriptor size:adjustedFontDescriptor.pointSize];\n                }\n            }\n            if (adjustedFont != nil) {\n                allAttributes[NSFontAttributeName] = adjustedFont;\n            }\n        }\n        \n        // Set paragraph style attributes\n        if (styles.paragraphStyleAttributes.count > 0) {\n            NSParagraphStyle* baseParagraphStyle = allAttributes[NSParagraphStyleAttributeName];\n            NSParagraphStyle* adjustedParagraphStyle = nil;\n            if (baseParagraphStyle != nil) {\n                adjustedParagraphStyle = [baseParagraphStyle paragraphStyleByAddingCMAttributes:styles.paragraphStyleAttributes];\n            }\n            else {\n                adjustedParagraphStyle = [NSParagraphStyle paragraphStyleWithCMAttributes:styles.paragraphStyleAttributes];\n            }\n            if (adjustedParagraphStyle != nil) {\n                allAttributes[NSParagraphStyleAttributeName] = adjustedParagraphStyle;\n            }\n        }\n    }\n    \n    NSString *styleString = element.attributes[@\"style\"];\n    \n    if (styleString.length) {\n        static dispatch_once_t onceToken;\n        static NSDictionary <NSString *, void (^)(NSMutableDictionary *dictionary, NSString *value) > *attributeUpdater = nil;\n        dispatch_once(&onceToken, ^{\n            attributeUpdater = @{\n                @\"color\": ^(NSMutableDictionary *dictionary, NSString *value) {\n                    UIColor *color = [UIColor colorWithCSSString_ant_mark:value];\n                    if (color) {\n                        dictionary[NSForegroundColorAttributeName] = color;\n                    }\n                },\n                @\"background-color\": ^(NSMutableDictionary *dictionary, NSString *value) {\n                    UIColor *color = [UIColor colorWithCSSString_ant_mark:value];\n                    if (color) {\n                        dictionary[NSBackgroundColorAttributeName] = color;\n                    }\n                },\n            };\n        });\n        \n        NSCharacterSet *set = [NSCharacterSet whitespaceCharacterSet];\n        [[styleString componentsSeparatedByString:@\";\"] enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {\n            NSArray <NSString *> *kvPair = [[obj stringByTrimmingCharactersInSet:set] componentsSeparatedByString:@\":\"];\n            if (kvPair.count == 2) {\n                NSString *key = [kvPair[0] stringByTrimmingCharactersInSet:set];\n                NSString *value = [kvPair[1] stringByTrimmingCharactersInSet:set];\n                if (value.length) {\n                    (attributeUpdater[key.localizedLowercaseString] ?: ^(NSMutableDictionary *dictionary, NSString *value) {})(allAttributes, value);\n                }\n            }\n        }];\n    }\n    \n    return [[NSAttributedString alloc] initWithString:element.stringValue attributes:allAttributes];\n}\n\n+ (NSString *)tagName {\n    return @\"div\";\n}\n\n\n- (nonnull instancetype)initWithStyles:(nonnull AMTextStyles *)styles {\n    self = [super init];\n    if (self) {\n        _styles = styles;\n    }\n    return self;\n}\n\n@end\n\n@implementation AMHTMLMarkTransformer\n\n+ (NSString *)tagName {\n    return @\"mark\";\n}\n\n- (NSAttributedString *)attributedStringForElement:(ONOXMLElement *)element attributes:(NSDictionary *)attributes {\n    NSMutableAttributedString *attri = [[super attributedStringForElement:element attributes:attributes] mutableCopy];\n    NSDictionary<NSAttributedStringKey, id> *attr = attri.length > 0 ? [attri attributesAtIndex:0 effectiveRange:NULL] : @{};\n    if (!element.attributes[@\"class\"] && !element.attributes[@\"style\"] && !attributes[NSBackgroundColorAttributeName] && !attr[NSBackgroundColorAttributeName]) {\n        [attri addAttributes:@{\n            NSBackgroundColorAttributeName: UIColor.yellowColor\n        } range:NSMakeRange(0, attri.length)];\n    }\n    return attri.copy;\n}\n\n@end\n\n@implementation AMHTMLSpanTransformer\n\n- (NSAttributedString *)attributedStringForElement:(ONOXMLElement *)element attributes:(NSDictionary *)attributes {\n    \n    NSMutableDictionary *allAttributes = [attributes mutableCopy];\n    \n    NSString *className = element.attributes[@\"class\"];\n    if (className.length) {\n        CMStyleAttributes *styles = [self.styles attributesForClass:className];\n        \n        if (styles.stringAttributes.count > 0) {\n            [allAttributes addEntriesFromDictionary:styles.stringAttributes];\n        }\n        \n        if (styles.fontAttributes.count > 0) {\n            UIFont *baseFont = allAttributes[NSFontAttributeName];\n            UIFont *adjustedFont = nil;\n            if (baseFont != nil) {\n                adjustedFont = [baseFont fontByAddingCMAttributes:styles.fontAttributes];\n            }\n            else {\n                UIFontDescriptor * adjustedFontDescriptor = [UIFontDescriptor fontDescriptorWithFontAttributes:styles.fontAttributes];\n                if (adjustedFontDescriptor != nil) {\n                    adjustedFont = [CMFont fontWithDescriptor:adjustedFontDescriptor size:adjustedFontDescriptor.pointSize];\n                }\n            }\n            if (adjustedFont != nil) {\n                allAttributes[NSFontAttributeName] = adjustedFont;\n            }\n        }\n        \n        // Set paragraph style attributes\n        if (styles.paragraphStyleAttributes.count > 0) {\n            NSParagraphStyle* baseParagraphStyle = allAttributes[NSParagraphStyleAttributeName];\n            NSParagraphStyle* adjustedParagraphStyle = nil;\n            if (baseParagraphStyle != nil) {\n                adjustedParagraphStyle = [baseParagraphStyle paragraphStyleByAddingCMAttributes:styles.paragraphStyleAttributes];\n            }\n            else {\n                adjustedParagraphStyle = [NSParagraphStyle paragraphStyleWithCMAttributes:styles.paragraphStyleAttributes];\n            }\n            if (adjustedParagraphStyle != nil) {\n                allAttributes[NSParagraphStyleAttributeName] = adjustedParagraphStyle;\n            }\n        }\n    }\n    \n    NSString *styleString = element.attributes[@\"style\"];\n    \n    if (styleString.length) {\n        static dispatch_once_t onceToken;\n        static NSDictionary <NSString *, void (^)(NSMutableDictionary *dictionary, NSString *value) > *attributeUpdater = nil;\n        dispatch_once(&onceToken, ^{\n            attributeUpdater = @{\n                @\"color\": ^(NSMutableDictionary *dictionary, NSString *value) {\n                    UIColor *color = [UIColor colorWithCSSString_ant_mark:value];\n                    if (color) {\n                        dictionary[NSForegroundColorAttributeName] = color;\n                    }\n                },\n                @\"background-color\": ^(NSMutableDictionary *dictionary, NSString *value) {\n                    UIColor *color = [UIColor colorWithCSSString_ant_mark:value];\n                    if (color) {\n                        dictionary[NSBackgroundColorAttributeName] = color;\n                    }\n                },\n            };\n        });\n        \n        NSCharacterSet *set = [NSCharacterSet whitespaceCharacterSet];\n        [[styleString componentsSeparatedByString:@\";\"] enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {\n            NSArray <NSString *> *kvPair = [[obj stringByTrimmingCharactersInSet:set] componentsSeparatedByString:@\":\"];\n            if (kvPair.count == 2) {\n                NSString *key = [kvPair[0] stringByTrimmingCharactersInSet:set];\n                NSString *value = [kvPair[1] stringByTrimmingCharactersInSet:set];\n                if (value.length) {\n                    (attributeUpdater[key.localizedLowercaseString] ?: ^(NSMutableDictionary *dictionary, NSString *value) {})(allAttributes, value);\n                }\n            }\n        }];\n    }\n    NSMutableAttributedString* attrString = [[NSMutableAttributedString alloc] initWithAttributedString:[element.stringValue markdownToAttributedStringWithStyles_ant_mark:self.styles]];\n    [attrString addAttributes:allAttributes range:NSMakeRange(0, attrString.string.length)];\n    return attrString;\n}\n\n\n\n+ (NSString *)tagName {\n    return @\"span\";\n}\n\n@end\n\n@implementation AMHTMLCiteTransformer\n\n- (NSAttributedString *)attributedStringForElement:(ONOXMLElement *)element attributes:(NSDictionary *)attributes\n{\n    NSMutableAttributedString *attri = [[super attributedStringForElement:element attributes:attributes] mutableCopy];\n    \n    [attri addAttributes:@{\n        NSObliquenessAttributeName: @(0.3),\n    } range:NSMakeRange(0, attri.length)];\n    \n    \n    return [attri copy];\n}\n\n+ (NSString *)tagName {\n    return @\"cite\";\n}\n\n@end\n\n@implementation AMHTMLDelTransformer\n\n- (NSAttributedString *)attributedStringForElement:(ONOXMLElement *)element attributes:(NSDictionary *)attributes\n{\n    NSMutableAttributedString *attri = [[super attributedStringForElement:element attributes:attributes] mutableCopy];\n    \n    [attri addAttributes:@{\n        NSStrikethroughStyleAttributeName: @(NSUnderlineStyleSingle)\n    } range:NSMakeRange(0, attri.length)];\n    \n    \n    return [attri copy];\n}\n\n+ (NSString *)tagName {\n    return @\"del\";\n}\n\n@end\n\n\n@implementation AMHTMLFontTransformer\n\n+ (NSString *)tagName {\n    return @\"font\";\n}\n\n- (NSAttributedString *)attributedStringForElement:(ONOXMLElement *)element attributes:(NSDictionary *)attributes {\n    \n    NSMutableDictionary *allAttributes = [attributes mutableCopy];\n    \n    NSString *colorString = element.attributes[@\"color\"];\n    NSString *sizeString = element.attributes[@\"size\"];\n    UIColor *color = [UIColor colorWithCSSString_ant_mark:colorString];\n    \n    if (color) {\n        allAttributes[NSForegroundColorAttributeName] = color;\n    }\n    \n    if (sizeString.length > 0) {\n        unichar ch = [sizeString characterAtIndex:0];\n        CGFloat value = [sizeString doubleValue];\n        UIFont *baseFont = allAttributes[NSFontAttributeName];\n        if (ch == '-' || ch == '+') {\n            if (baseFont) {\n                CGFloat pointSize = baseFont.pointSize;\n                pointSize += value;\n                allAttributes[NSFontAttributeName] = [baseFont fontWithSize:pointSize];\n            }\n        } else {\n            allAttributes[NSFontAttributeName] = baseFont ? [baseFont fontWithSize:value] : [UIFont systemFontOfSize:value];\n        }\n    }\n    \n    return [[NSAttributedString alloc] initWithString:element.stringValue attributes:allAttributes];\n}\n\n@end\n\n@implementation AMHTMLUnderlineTransformer\n{\n    AMUnderline     * _underline;\n}\n\n- (instancetype)initWithStyle:(NSUnderlineStyle)style\n                        color:(UIColor *)color\n                    lineWidth:(CGFloat)width\n                       offset:(CGFloat)offset\n{\n    self = [super initWithUnderlineStyle:NSUnderlineStyleSingle color:[UIColor clearColor]];\n    if (self) {\n        _underline = [[AMUnderline alloc] initWithColor:color lineWidth:width offset:offset];\n    }\n    return self;\n}\n\n- (NSAttributedString *)attributedStringForElement:(ONOXMLElement *)element attributes:(NSDictionary *)attributes\n{\n    NSMutableAttributedString *attri = [[super attributedStringForElement:element attributes:attributes] mutableCopy];\n    \n    if (_underline) {\n        [attri addAttributes:@{\n            AMUnderlineDrawableAttributeName: _underline,\n        } range:NSMakeRange(0, attri.length)];\n    }\n    \n    return [attri copy];\n}\n\n@end\n\n\n@implementation AMHTMLDefaultTransformer\n\n+ (NSString *)tagName {\n    return @\"p\";\n}\n- (NSAttributedString *)attributedStringForElement:(ONOXMLElement *)element attributes:(NSDictionary *)attributes\n{\n    return nil;\n}\n@end\n\n\n@implementation AMHTMLTextLabelTransformer\n\n+ (NSString *)tagName {\n    return @\"p\";\n}\n\n- (NSAttributedString *)attributedStringForElement:(ONOXMLElement *)element attributes:(NSDictionary *)attributes\n{\n    NSString *html = @\"\";\n    return [[NSAttributedString alloc] initWithData:[html dataUsingEncoding:NSUnicodeStringEncoding] options:@{NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType} documentAttributes:nil error:nil];\n\n}\n\n@end\n@implementation AMHTMLImgTransformer\n\n+ (NSString *)tagName {\n    return @\"img\";\n}\n- (NSAttributedString *)attributedStringForElement:(ONOXMLElement *)element attributes:(NSDictionary *)attributes {\n    NSLog(@\"\");\n    NSString* ttt = element.attributes[@\"src\"];\n    NSString* strWidth = element.attributes[@\"width\"];\n    NSString* strHeight = element.attributes[@\"height\"];\n    CGSize imgSize = CGSizeMake(strWidth ? [strWidth floatValue] : 0, strHeight ? [strHeight floatValue] : 0);\n    \n    NSTextAttachment* textAttachment = [[AMImageTextAttachment alloc] initWithImageURL:[NSURL URLWithString:ttt] title:@\"\" size:imgSize];\n    NSMutableDictionary *allAttributes = [attributes mutableCopy];\n    allAttributes[NSAttachmentAttributeName] = textAttachment;\n    const unichar attachmentChar = NSAttachmentCharacter;\n    return [[NSAttributedString alloc] initWithString:[NSString stringWithCharacters:&attachmentChar length:1] attributes:allAttributes];\n}\n@end\n@interface AMHTMLIconLinkTransformer()\n{\n    NSString*   _linkUrl;\n}\n@end\n@implementation AMHTMLIconLinkTransformer\n\n+ (NSString *)tagName {\n    return @\"iconlink\";\n}\n-(NSDictionary*)getParams {\n    return _linkUrl ? @{@\"linkUrl\":_linkUrl} : nil;\n}\n- (NSAttributedString *)attributedStringForElement:(ONOXMLElement *)element attributes:(NSDictionary *)attributes {\n    \n    NSMutableDictionary *alltextAttributes = [attributes mutableCopy];\n    NSMutableDictionary *allAttributes = [attributes mutableCopy];\n    NSString *styleString = element.attributes[@\"style\"];\n  \n    UIColor* backgroundColor = nil;\n    UIColor* textColor = nil;\n    NSString* url = element.attributes[@\"src\"];\n    _linkUrl = element.attributes[@\"link\"];\n    UIFont *baseFont = alltextAttributes[NSFontAttributeName];\n    UIFont* subFont = [UIFont systemFontOfSize:kHTMLDefaultFontSize];\n    if (styleString.length) {\n        NSArray<NSString *> * styles = [styleString componentsSeparatedByString:@\";\"];\n        if ([styles count] > 0) {\n            NSCharacterSet *set = [NSCharacterSet whitespaceCharacterSet];\n            for (NSString* subStyle in styles) {\n                NSArray <NSString *> *kvPair = [[subStyle stringByTrimmingCharactersInSet:set] componentsSeparatedByString:@\":\"];\n                if (kvPair.count == 2) {\n                    NSString *key = [kvPair[0] stringByTrimmingCharactersInSet:set];\n                    NSString *value = [kvPair[1] stringByTrimmingCharactersInSet:set];\n                    if ([key isEqualToString:@\"background-color\"] && value.length) {\n                        backgroundColor = [UIColor colorWithCSSString_ant_mark_alpha:value];\n                    } else if ([key isEqualToString:@\"color\"] && value.length) {\n                        textColor = [UIColor colorWithCSSString_ant_mark:value];\n                        alltextAttributes[NSForegroundColorAttributeName] = textColor;\n                    } else if ([key isEqualToString:@\"font-size\"] && value.length) {\n                        int fontSize = [value intValue];\n                        if (baseFont) {\n                            subFont = [baseFont fontWithSize:AUFVS(fontSize)];\n                        } else {\n                            subFont = [UIFont systemFontOfSize:AUFVS(fontSize)];\n                        }\n                        alltextAttributes[NSFontAttributeName] = subFont;\n                        allAttributes[NSFontAttributeName] = subFont;\n                        \n                    }\n                   \n                }\n            }\n            \n        }\n    }\n    \n    \n    \n    NSAttributedString* pureText = [[NSAttributedString alloc] initWithString:element.stringValue attributes:alltextAttributes];\n    NSTextAttachment* textAttachment = [[AMIconLinkAttachment alloc] initWithText:pureText url:url bgColor:backgroundColor textColor:textColor subFont:subFont baseFont:baseFont];\n    \n    allAttributes[NSAttachmentAttributeName] = textAttachment;\n    allAttributes[NSLinkAttributeName] = _linkUrl;\n    const unichar attachmentChar = NSAttachmentCharacter;\n    return [[NSAttributedString alloc] initWithString:[NSString stringWithCharacters:&attachmentChar length:1] attributes:allAttributes];\n}\n-(NSString*)getLinkUrl {\n    return _linkUrl;\n}\n@end\n@implementation AMHTMLIconTransformer\n\n+ (NSString *)tagName {\n    return @\"icon\";\n}\n- (NSAttributedString *)attributedStringForElement:(ONOXMLElement *)element attributes:(NSDictionary *)attributes {\n \n    NSMutableDictionary *alltextAttributes = [attributes mutableCopy];\n    NSMutableDictionary *allAttributes = [attributes mutableCopy];\n  \n    NSString* url = element.attributes[@\"src\"];\n   \n    UIFont *baseFont = alltextAttributes[NSFontAttributeName];\n    if (url.length) {\n        AMIconAttachment* textAttachment = [[AMIconAttachment alloc] init];\n        textAttachment = [[AMIconAttachment alloc] init];\n        textAttachment.path = url;\n        textAttachment.baseFont = baseFont;\n        textAttachment.attachmentSize = CGSizeMake(baseFont.pointSize, baseFont.pointSize);\n        \n        allAttributes[NSAttachmentAttributeName] = textAttachment;\n    }\n\n    const unichar attachmentChar = NSAttachmentCharacter;\n    return [[NSAttributedString alloc] initWithString:[NSString stringWithCharacters:&attachmentChar length:1] attributes:allAttributes];\n}\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMIconAttachment.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n\n#import \"CocoaMarkdown.h\"\n#import \"AMViewAttachment.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMIconAttachment : NSTextAttachment\n@property (nonatomic, nullable) NSString *path;\n@property (nonatomic, nullable) NSString *text;\n@property (nonatomic) UIFont *baseFont;\n@property (nonatomic) UIColor *textColor;\n@property (nonatomic, assign) NSInteger textSize;\n@property (nonatomic, assign)NSTextAlignment textAlignment;\n@property (nonatomic) CGSize attachmentSize;\n@property (nonatomic) CGFloat marginLeft;\n@property (nonatomic) CGFloat marginRight;\n@property (nonatomic) BOOL boldText;\n\n- (instancetype)init;\n- (void)setNeedsUpdate;\n\n- (BOOL)isEqualToAttachment:(AMIconAttachment *)attach;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMIconAttachment.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMIconAttachment.h\"\n\n#import \"CMImageTextAttachment.h\"\n#import \"AMImageTextAttachment.h\"\n#import <CoreText/CoreText.h>\n#import \"AMUtils.h\"\n\n#if TARGET_OS_IPHONE\n#import <MobileCoreServices/MobileCoreServices.h> // For UTType...\n#endif\n\n@implementation AMIconAttachment\n\n{\n    __weak NSTextContainer *_textContainer;\n    NSURLSessionDataTask* _downloadTask;\n    NSURL       * _imageURL;\n    CGSize      _imageSize;\n    UIImage* _iconImage;\n    BOOL _isLoaded;\n}\n- (instancetype)init {\n    self = [self initWithData:nil ofType:nil];\n    if (self) {\n    }\n    return self;\n}\n\n- (void)setNeedsUpdate {\n    [_textContainer.layoutManager setNeedsLayoutForAttachment:self];\n}\n- (void)downloadImage:(NSURL *)imageURL completion:(void(^)(NSError * _Nullable error, NSData * _Nullable data))block {\n    // Not a file URL and no download task in progress: use an URL-data-task to get the data\n    _downloadTask = [NSURLSession.sharedSession dataTaskWithURL:imageURL\n                                              completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {\n        block(error, data);\n        \n        self->_downloadTask = nil;\n    }];\n    \n    [_downloadTask resume];\n}\n- (BOOL)isEqual:(nullable id)object {\n    if (object == nil) {\n        return NO;\n    }\n    \n    if (self == object) {\n        return YES;\n    }\n    \n    if (![object isKindOfClass:[self class]]) {\n        return NO;\n    }\n    \n    return [self isEqualToAttachment:(AMIconAttachment *)object];\n}\n\n- (BOOL)isEqualToAttachment:(AMIconAttachment *)attach\n{\n    return [self.path isEqual:attach.path] && [self.text isEqualToString:attach.text];\n}\n- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer\n                      proposedLineFragment:(CGRect)lineFrag\n                             glyphPosition:(CGPoint)position\n                            characterIndex:(NSUInteger)charIndex {\n    _textContainer = textContainer;\n    NSInteger height = _attachmentSize.height > 0 ? _attachmentSize.height : _baseFont.ascender;\n    return CGRectMake(0, (_baseFont.capHeight - height) / 2.0 , height + _marginLeft + _marginRight, height);\n}\n- (void)imageResize:(UIImage *)image scaledToSize:(CGSize)newSize {\n    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);\n    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];\n    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();\n    UIGraphicsEndImageContext();\n    _iconImage = newImage;\n}\n- (void) setImageWithData:(NSData*)imageData\n{\n    NSString* imageUti = (__bridge_transfer NSString*) UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)_imageURL.pathExtension, kUTTypeData);\n    self.fileType = imageUti;\n    self.contents = imageData;\n    \n    CGSize currentImageSize = self.image.size;\n    \n#if TARGET_OS_IPHONE\n    _iconImage = [UIImage imageWithData: imageData];\n#else\n    _iconImage = [[NSImage alloc] initWithData:imageData];\n#endif\n    \n    if (_iconImage != nil) {\n        if (_imageSize.width != 0 && _imageSize.height !=0) {\n            [self imageResize:_iconImage scaledToSize:_imageSize];\n        }\n        if (! CGSizeEqualToSize(self.image.size, currentImageSize)) {\n             // The layout needs to be refreshed\n            [_textContainer.layoutManager setNeedsLayoutForAttachment:self];\n        }\n        else {\n            // The image display should be refreshed\n            [_textContainer.layoutManager setNeedsDisplayForAttachment:self];\n        }\n    }\n    \n    [[AMSimpleImageCache sharedCache] setImageData:imageData forURL:_imageURL];\n}\n- (void) setImageWithUIImage:(UIImage*)image\n{\n    self.image = image;\n    \n    CGSize currentImageSize = self.image.size;\n    \n#if TARGET_OS_IPHONE\n    _iconImage = image;\n#else\n    _iconImage = [[NSImage alloc] initWithData:imageData];\n#endif\n    \n    if (_iconImage != nil) {\n        if (_imageSize.width != 0 && _imageSize.height !=0) {\n            [self imageResize:_iconImage scaledToSize:_imageSize];\n        }\n        if (! CGSizeEqualToSize(self.image.size, currentImageSize)) {\n             // The layout needs to be refreshed\n            [_textContainer.layoutManager setNeedsLayoutForAttachment:self];\n        }\n        else {\n            // The image display should be refreshed\n            [_textContainer.layoutManager setNeedsDisplayForAttachment:self];\n        }\n    }\n}\n+ (BOOL)isNetworkPath:(NSString *)path {\n    return [path hasPrefix:@\"http://\"] || [path hasPrefix:@\"https://\"];\n}\n- (void)loadLocalImage:(NSString *)path\n            completion:(void(^)(NSError * _Nullable error, UIImage * _Nullable image))block\n{\n    UIImage *image = nil;\n    NSError *error = nil;\n    NSString* iOSPath = nil;\n    if (!path || path.length == 0)\n        return;\n    if ([path hasPrefix:@\"localResource:\"]) {\n        // eg: \"localResource://loadImage?Android=android-phone-wallet-socialcardwidget$com.alipay.mobile.socialcardwidget$feedback&iOS=HomeCard.bundle/more.png&Harmony=cardres/haibao.jpg\"\n        NSRange range = [path rangeOfString:@\"?\"];\n        if (range.location == NSNotFound) {\n            return;\n        }\n        NSString* localPath = [path substringFromIndex:range.location];\n        NSArray* strArray = [localPath componentsSeparatedByString:@\"&\"];\n        \n        for (NSString* subStr in strArray) {\n            NSRange subrange = [subStr rangeOfString:@\"=\"];\n            if (subrange.location == NSNotFound) {\n                continue;\n            }\n            NSString* prefix = [subStr substringToIndex:subrange.location];\n            if ([prefix isEqualToString:@\"iOS\"]) {\n                iOSPath = [subStr substringFromIndex:subrange.location + 1];\n            }\n        }\n    } else {\n        iOSPath = path;\n    }\n    \n    if (!iOSPath) {\n        return;\n    }\n    NSRange iOSRange = [iOSPath rangeOfString:@\"/\"];\n    if (iOSRange.location == NSNotFound) {\n        return;\n    }\n \n    NSString *bundlePart = [iOSPath substringToIndex:iOSRange.location];\n    NSString *imagePart = [iOSPath substringFromIndex:iOSRange.location + 1];\n        \n    image = [UIImage imageNamed_ant_bundle:bundlePart name:imagePart];\n    \n    if (image) {\n        block(nil, image);\n    } else {\n        error = [NSError errorWithDomain:@\"ImageLoader\"\n                                 code:404\n                             userInfo:@{NSLocalizedDescriptionKey: @\"Local image not found\"}];\n        block(error, nil);\n    }\n}\n- (UIImage *)imageForBounds:(CGRect)imageBounds textContainer:(NSTextContainer *)textContainer characterIndex:(NSUInteger)charIndex\n{\n    if (!self.image && [NSThread isMainThread]) {\n        if (!_isLoaded) {\n            NSData *data = nil;\n            if ([AMIconAttachment isNetworkPath:self.path]) {\n                data = [[AMSimpleImageCache sharedCache] imageDataForURL:[NSURL URLWithString:self.path]];\n            }\n            if (data) {\n                [self setImageWithData:data];\n                _isLoaded = YES;\n            } else {\n                if ([AMIconAttachment isNetworkPath:self.path]) {\n                    _imageURL = [NSURL URLWithString:self.path];\n                    [self downloadImage:_imageURL\n                             completion:^(NSError * _Nullable error, NSData * _Nullable data) {\n                        if ((error == nil) && (data.length > 0)) {\n                            dispatch_async(dispatch_get_main_queue(), ^{\n                                [self setImageWithData:data];\n                                _isLoaded = YES;\n                            });\n                        }\n                    }];\n                } else {\n                    [self loadLocalImage:self.path completion:^(NSError * _Nullable error, UIImage * _Nullable image) {\n                                            if ((error == nil) && image) {\n                                                [self setImageWithUIImage:image];\n                                                _isLoaded = YES;\n                                            }\n                    }];\n                }\n                \n            }\n            \n        }\n        \n        \n        UIGraphicsBeginImageContextWithOptions(CGSizeMake(imageBounds.size.width, imageBounds.size.height), NO, 0.0);\n        CGContextRef con = UIGraphicsGetCurrentContext();\n        CGRect iconRect = CGRectMake(_marginLeft, 0, imageBounds.size.width - _marginLeft - _marginRight, imageBounds.size.height);\n        if (_iconImage) {\n            [self drawImage:con rect:iconRect];\n        }\n        if (self.text && ![self.text isEqualToString:@\"\"]) {\n            UILabel *label = [[UILabel alloc] initWithFrame:iconRect];\n            label.backgroundColor = [UIColor clearColor];\n            label.layer.masksToBounds = YES;\n            label.textAlignment = _textAlignment;\n\n            label.textColor = _textColor ? : [UIColor whiteColor];\n            label.font = _boldText ? [UIFont boldSystemFontOfSize:_textSize] : [UIFont systemFontOfSize:_textSize];\n            label.text = self.text;\n            label.lineBreakMode = NSLineBreakByTruncatingTail;\n            label.numberOfLines = 1;\n\n            [label layoutIfNeeded];\n            [label.layer renderInContext:con];\n        }\n        \n        self.image = UIGraphicsGetImageFromCurrentImageContext();\n        UIGraphicsEndImageContext();\n    }\n    return self.image;\n}\n\n-(void)drawImage:(CGContextRef)context rect:(CGRect)rect{\n    CGContextSaveGState(context);\n    CGContextClip(context);\n    [_iconImage drawInRect:rect];\n    CGContextRestoreGState(context);\n}\n\n- (void)setNeedsLayout\n{\n    NSLayoutManager *mgr = _textContainer.layoutManager;\n    if (mgr) {\n        [mgr setNeedsLayoutForAttachment:self];\n    }\n}\n\n@end\n\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMIconLinkAttachment.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMIconLinkAttachment : NSTextAttachment\n@property (nonatomic, nullable) NSAttributedString *text;\n\n- (instancetype)initWithText:(nullable NSAttributedString *)text url:(NSString*)url bgColor:(UIColor*)bgColor textColor:(UIColor*)textColor subFont:(UIFont*)subFont baseFont:(UIFont*)baseFont;\n- (void)setNeedsUpdate;\n\n- (BOOL)isEqualToAttachment:(AMIconLinkAttachment *)attach;\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMIconLinkAttachment.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMIconLinkAttachment.h\"\n#import \"CMImageTextAttachment.h\"\n#import \"AMImageTextAttachment.h\"\n#import <CoreText/CoreText.h>\n#import \"AMUtils.h\"\n\n#if TARGET_OS_IPHONE\n#import <MobileCoreServices/MobileCoreServices.h> // For UTType...\n#endif\n#define kIconLinkRadius 8\n#define kIconLinkPaddingLeft 0\n#define kIconLinkPaddingRight 0\n#define kIconLinkInterval 1\n#define kIconLinkMarginLeft 1\n#define kIconLinkMarginRight 0\n#define kIconLinkPaddingRatio 0\n@implementation AMIconLinkAttachment\n\n{\n    __weak NSTextContainer *_textContainer;\n    NSURLSessionDataTask* _downloadTask;\n    NSURL       * _imageURL;\n    CGSize      _imageSize;\n    UIImage* _iconImage;\n    BOOL _isLoaded;\n    CTLineRef _line;\n    CGFloat _paddingLeft;\n    CGFloat _paddingRight;\n    CGFloat _paddingTop;\n    CGFloat _paddingBottom;\n    CGFloat _marginLeft;\n    CGFloat _marginRight;\n    CGFloat _radius;\n    CGFloat _interval;\n    UIColor* _backgroundColor;\n    UIColor* _textColor;\n    UIFont* _font;\n    UIFont* _baseFont;\n    CGFloat descent;\n    \n}\n\n- (instancetype)initWithText:(NSAttributedString *)text url:(NSString*)url bgColor:(UIColor*)bgColor textColor:(UIColor*)textColor subFont:(UIFont*)subFont baseFont:(UIFont*)baseFont{\n    self = [self initWithData:nil ofType:nil];\n    if (self) {\n        self.text = text;\n        _imageURL = [NSURL URLWithString:[url stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]];\n        _isLoaded = NO;\n        _line = CTLineCreateWithAttributedString((__bridge CFAttributedStringRef)(text));\n        _paddingLeft = kIconLinkPaddingLeft;\n        _paddingRight = kIconLinkPaddingRight;\n        _paddingTop = subFont.pointSize  * kIconLinkPaddingRatio;\n        _paddingBottom = subFont.pointSize * kIconLinkPaddingRatio;\n        _interval = kIconLinkInterval;\n        _marginLeft = kIconLinkMarginLeft;\n        _marginRight = kIconLinkMarginRight;\n        _radius = kIconLinkRadius;\n        _backgroundColor = bgColor;\n        _textColor = textColor;\n        _font = subFont;\n        _baseFont = baseFont;\n    }\n    return self;\n}\n- (void)setNeedsUpdate {\n    [_textContainer.layoutManager setNeedsLayoutForAttachment:self];\n}\n- (void)downloadImage:(NSURL *)imageURL completion:(void(^)(NSError * _Nullable error, NSData * _Nullable data))block {\n    // Not a file URL and no download task in progress: use an URL-data-task to get the data\n    _downloadTask = [NSURLSession.sharedSession dataTaskWithURL:imageURL\n                                              completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {\n        block(error, data);\n        \n        self->_downloadTask = nil;\n    }];\n    \n    [_downloadTask resume];\n}\n- (BOOL)isEqual:(nullable id)object {\n    if (object == nil) {\n        return NO;\n    }\n    \n    if (self == object) {\n        return YES;\n    }\n    \n    if (![object isKindOfClass:[self class]]) {\n        return NO;\n    }\n    \n    return [self isEqualToAttachment:(AMIconLinkAttachment *)object];\n}\n\n- (BOOL)isEqualToAttachment:(AMIconLinkAttachment *)attach\n{\n    return [self.text isEqual:attach.text];\n}\n\n-(BOOL)isIos6Supported{\n    static BOOL initialized = false;\n    static BOOL supported = false;\n    if (!initialized) {\n#if TARGET_OS_IPHONE\n        NSString *reqSysVer = @\"6.0\";\n        NSString *currSysVer = [UIDevice currentDevice].systemVersion;\n        \n        if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending) {\n            supported = true;\n        }\n#else\n        supported = true;\n#endif\n        \n        initialized = true;\n    }\n    return supported;\n}\n- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer\n                      proposedLineFragment:(CGRect)lineFrag\n                             glyphPosition:(CGPoint)position\n                            characterIndex:(NSUInteger)charIndex {\n    _textContainer = textContainer;\n    CGFloat ascent;\n    CGFloat leading;\n    double textWidth = CTLineGetTypographicBounds(_line, &ascent, &descent, &leading);\n    double textHeight = ascent + descent + leading;\n    double height = textHeight + _paddingTop + _paddingBottom;\n    double width = textWidth + textHeight + _paddingLeft + _paddingRight + _interval + _marginLeft + _marginRight;\n    return CGRectMake(0, (_baseFont.capHeight - height)/2 , width, height);\n}\n- (void)imageResize:(UIImage *)image scaledToSize:(CGSize)newSize {\n    AMUIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);\n    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];\n    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();\n    UIGraphicsEndImageContext();\n    _iconImage = newImage;\n}\n- (void) setImageWithData:(NSData*)imageData\n{\n    NSString* imageUti = (__bridge_transfer NSString*) UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)_imageURL.pathExtension, kUTTypeData);\n    self.fileType = imageUti;\n    self.contents = imageData;\n    \n    CGSize currentImageSize = self.image.size;\n    \n#if TARGET_OS_IPHONE\n    _iconImage = [UIImage imageWithData: imageData];\n#else\n    _iconImage = [[NSImage alloc] initWithData:imageData];\n#endif\n    \n    if (_iconImage != nil) {\n        if (_imageSize.width != 0 && _imageSize.height !=0) {\n            [self imageResize:_iconImage scaledToSize:_imageSize];\n        }\n        if (! CGSizeEqualToSize(self.image.size, currentImageSize)) {\n             // The layout needs to be refreshed\n            [_textContainer.layoutManager setNeedsLayoutForAttachment:self];\n        }\n        else {\n            // The image display should be refreshed\n            [_textContainer.layoutManager setNeedsDisplayForAttachment:self];\n        }\n    }\n    \n    [[AMSimpleImageCache sharedCache] setImageData:imageData forURL:_imageURL];\n}\n- (UIImage *)imageForBounds:(CGRect)imageBounds textContainer:(NSTextContainer *)textContainer characterIndex:(NSUInteger)charIndex\n{\n    if (!self.image && [NSThread isMainThread]) {\n        if (!_isLoaded) {\n            NSData *data = [[AMSimpleImageCache sharedCache] imageDataForURL:_imageURL];\n            if (data) {\n                [self setImageWithData:data];\n                _isLoaded = YES;\n            } else {\n                [self downloadImage:_imageURL\n                         completion:^(NSError * _Nullable error, NSData * _Nullable data) {\n                    if ((error == nil) && (data.length > 0)) {\n                        dispatch_async(dispatch_get_main_queue(), ^{\n                            [self setImageWithData:data];\n                            _isLoaded = YES;\n                        });\n                    }\n                }];\n            }\n            \n        }\n        \n        CGSize size = CGSizeMake(imageBounds.size.width, imageBounds.size.height);\n        AMUIGraphicsBeginImageContextWithOptions(size, NO, 0.0);\n        CGRect rect = CGRectMake(_marginLeft, 0, size.width - _marginLeft - _marginRight, size.height);\n        CGContextRef con = UIGraphicsGetCurrentContext();\n        [self drawBackground:con rect:rect];\n        CGRect iconRect = CGRectMake(rect.origin.x + _paddingLeft, _paddingTop, rect.size.height - (_paddingTop + _paddingBottom), rect.size.height - (_paddingTop + _paddingBottom));\n        if (_iconImage) {\n            [self drawImage:con rect:iconRect];\n        }\n        [AMIconLinkAttachment setTransformContextForCoreText:con frame:rect];\n        [self drawText:con pt:CGPointMake(iconRect.origin.x + iconRect.size.width + _interval, iconRect.origin.y+descent)];\n        self.image = UIGraphicsGetImageFromCurrentImageContext();\n        UIGraphicsEndImageContext();\n    }\n    return self.image;\n}\n-(void)drawBackground:(CGContextRef)context rect:(CGRect)rect{\n    CGColorRef fillColor = _backgroundColor.CGColor;\n\n    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:_radius];\n\n    CGContextSetFillColorWithColor(context, fillColor);\n    [path fill];\n}\n-(void)drawImage:(CGContextRef)context rect:(CGRect)rect{\n    CGContextSaveGState(context);\n    CGContextAddEllipseInRect(context, rect);\n    CGContextClip(context);\n    [_iconImage drawInRect:rect];\n    CGContextRestoreGState(context);\n}\n-(void)drawText:(CGContextRef)context pt:(CGPoint)pt{\n    CGContextSetTextPosition(context, pt.x, pt.y);\n    CTLineDraw(_line, context);\n}\n- (void)setNeedsLayout\n{\n    NSLayoutManager *mgr = _textContainer.layoutManager;\n    if (mgr) {\n        [mgr setNeedsLayoutForAttachment:self];\n        \n        NSNotification *noti = [[NSNotification alloc] initWithName:AMTextAttachmentSizeDidUpdateNotification\n                                                             object:mgr.textStorage\n                                                           userInfo:@{\n            NSAttachmentAttributeName: self,\n        }];\n        [[NSNotificationQueue defaultQueue] enqueueNotification:noti\n                                                   postingStyle:NSPostWhenIdle\n                                                   coalesceMask:NSNotificationCoalescingOnSender\n                                                       forModes:nil];\n    }\n}\n+ (void)setTransformContextForCoreText:(CGContextRef)context frame:(CGRect)frame\n{\n    CGContextSetTextMatrix(context, CGAffineTransformScale(CGAffineTransformIdentity, 1.f, 1.f));\n    CGAffineTransform transform = CGAffineTransformScale(CGAffineTransformMakeTranslation(0, frame.size.height), 1.f, -1.f);\n    CGContextConcatCTM(context, transform);\n}\n-(void)dealloc {\n    if (_line) {\n        CFRelease(_line);\n    }\n}\n@end\n\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMImageTextAttachment.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <AntMarkdown/CocoaMarkdown.h>\n#import <AntMarkdown/AMViewAttachment.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMSimpleImageCache : NSObject\n\n+ (instancetype)sharedCache;\n\n- (nullable NSData *)imageDataForURL:(NSURL *)url;\n- (void)setImageData:(NSData *)data forURL:(NSURL *)url;\n\n@end\n\n@interface AMImageTextAttachment : CMImageTextAttachment <AMAttachmentUpdatable>\n@property (nonatomic) BOOL enableImageCache;\n\n- (void)setNeedsLayout;\n- (void)setNeedsDisplay;\n\n- (BOOL)isEqualToAttachment:(AMImageTextAttachment *)attach;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMImageTextAttachment.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMImageTextAttachment.h\"\n#import \"AMViewAttachment.h\"\n#import \"AMUtils.h\"\n\n@implementation AMImageTextAttachment\n{\n    CGRect  _usedRect;\n}\n\n- (instancetype) initWithImageURL:(NSURL*)imageURL title:(NSString*)title\n{\n    self = [super initWithImageURL:imageURL title:title];\n    if (self) {\n        _usedRect = CGRectNull;\n    }\n    return self;\n}\n\n- (void)setImageWithData:(NSData *)imageData\n{\n    [super setImageWithData:imageData];\n    if ([self enableImageCache]) {\n        [[AMSimpleImageCache sharedCache] setImageData:imageData forURL:self.imageURL];\n    }\n    [self setNeedsLayout];\n}\n\n- (void)setNeedsLayout\n{\n    NSLayoutManager *mgr = self.textContainer.layoutManager;\n    if (mgr) {\n        [mgr setNeedsLayoutForAttachment:self];\n        \n        NSNotification *noti = [[NSNotification alloc] initWithName:AMTextAttachmentSizeDidUpdateNotification\n                                                             object:mgr.textStorage\n                                                           userInfo:@{\n            NSAttachmentAttributeName: self,\n        }];\n        [[NSNotificationQueue defaultQueue] enqueueNotification:noti\n                                                   postingStyle:NSPostWhenIdle\n                                                   coalesceMask:NSNotificationCoalescingOnSender\n                                                       forModes:nil];\n    }\n}\n\n- (void)setNeedsDisplay\n{\n    [self.textContainer.layoutManager setNeedsDisplayForAttachment:self];\n}\n\n- (BOOL)isEqualToAttachment:(AMImageTextAttachment *)attach\n{\n    return [self.imageURL isEqual:attach.imageURL];\n}\n\n- (void)updateAttachmentFromAttachment:(AMImageTextAttachment *)attach\n{\n    if (![self isEqualToAttachment:attach]) {\n        _imageURL = attach.imageURL;\n        self.isImageLoaded = NO;\n    }\n}\n\n- (UIImage *)imageForBounds:(CGRect)imageBounds \n              textContainer:(NSTextContainer *)textContainer\n             characterIndex:(NSUInteger)charIndex\n{\n    if (self.enableImageCache && !self.isImageLoaded) {\n        NSData *data = [[AMSimpleImageCache sharedCache] imageDataForURL:self.imageURL];\n        if (data) {\n            [self setImageWithData:data];\n            self.isImageLoaded = YES;\n        }\n    }\n    UIImage *image = [super imageForBounds:imageBounds textContainer:textContainer characterIndex:charIndex];\n    return image;\n}\n\n- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer\n                      proposedLineFragment:(CGRect)lineFrag\n                             glyphPosition:(CGPoint)position\n                            characterIndex:(NSUInteger)charIndex\n{\n    CGSize attachmentImageSize = self.image.size;\n    \n    CGFloat maxWidth = lineFrag.size.width - textContainer.lineFragmentPadding * 2;\n\n    \n    if (attachmentImageSize.width > maxWidth) {\n        attachmentImageSize = CGSizeMake(maxWidth, attachmentImageSize.height * maxWidth / attachmentImageSize.width);\n    }\n    \n    CGRect attachmentBounds;\n    attachmentBounds.origin = CGPointZero;\n    attachmentBounds.size = attachmentImageSize;\n    return attachmentBounds;\n}\n\n@end\n\n@implementation AMSimpleImageCache\n{\n    NSLock      * _lock;\n    NSURLCache  * _cache;\n}\n\n+ (instancetype)sharedCache\n{\n    static dispatch_once_t onceToken;\n    static id instance = nil;\n    dispatch_once(&onceToken, ^{\n        instance = [self new];\n    });\n    return instance;\n}\n\n- (instancetype)init\n{\n    self = [super init];\n    if (self) {\n        _lock = [[NSLock alloc] init];\n        \n        NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@\"ImageAttachmentCache\"];\n        _cache = [[NSURLCache alloc] initWithMemoryCapacity:20 * 1024 * 1024\n                                               diskCapacity:50 * 1024 * 1024\n                                                   diskPath:cachePath];\n    }\n    return self;\n}\n\n- (NSData *)imageDataForURL:(NSURL *)url\n{\n    [_lock lock];\n    NSCachedURLResponse *res = [_cache cachedResponseForRequest:[NSURLRequest requestWithURL:url]];\n    [_lock unlock];\n    return res.data;\n}\n\n- (void)setImageData:(NSData *)data forURL:(NSURL *)url\n{\n    [_lock lock];\n    [_cache storeCachedResponse:[[NSCachedURLResponse alloc] initWithResponse:[[NSURLResponse alloc] initWithURL:url\n                                                                                                        MIMEType:@\"application/image\"\n                                                                                           expectedContentLength:data.length\n                                                                                                textEncodingName:nil]\n                                                                         data:data]\n                     forRequest:[NSURLRequest requestWithURL:url]];\n    [_lock unlock];\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMInlineMathAttachment.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <AntMarkdown/CMInlineTextAttachment.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMMathStyle : NSObject\n@property (nonatomic) UIFont *font;\n@property (nonatomic, readonly) CGFloat fontSize;\n@property (nonatomic) UIColor *textColor;\n@property (nonatomic) UIColor *backgroundColor;\n@property (nonatomic) UIControlContentVerticalAlignment verticalAlignment;\n@property (nonatomic) UIControlContentHorizontalAlignment horizontalAlignment;\n@property (nonatomic) CGFloat height;   // Default 0. Auto\n@property (nonatomic,copy) NSParagraphStyle* paragraphStyle;\n\n@property (nonatomic,copy) NSParagraphStyle* paragraphStyleBreakLine;\n\n+ (instancetype)defaultStyle;\n\n+ (instancetype)defaultBlockStyle;\n\n@end\n\n@interface AMInlineMathAttachment : CMInlineTextAttachment\n\n@property (nonatomic, nullable, strong) NSError *error;\n\n- (instancetype)initWithText:(nullable NSString *)text\n                       style:(AMMathStyle *)style NS_DESIGNATED_INITIALIZER;\n\n- (NSAttributedString *)attributedString;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMInlineMathAttachment.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMInlineMathAttachment.h\"\n#import \"IosMath.h\"\n#import \"MTTypesetter.h\"\n#import \"MTFontManager.h\"\n#import \"AMUtils.h\"\n#import \"CMTextAttributes.h\"\n#import \"CMCascadingAttributeStack.h\"\n\n@implementation AMMathStyle\n\n- (CGFloat)fontSize\n{\n    return self.font.pointSize;\n}\n\n+ (instancetype)defaultStyle {\n    AMMathStyle *style = [self new];\n    style.font = [UIFont systemFontOfSize:20];\n    style.verticalAlignment = UIControlContentVerticalAlignmentCenter;\n    style.textColor = [UIColor blackColor];\n    return style;\n}\n\n+ (instancetype)defaultBlockStyle {\n    AMMathStyle *style = [self new];\n    style.font = [UIFont systemFontOfSize:24];\n    style.verticalAlignment = UIControlContentVerticalAlignmentCenter;\n    style.horizontalAlignment = UIControlContentHorizontalAlignmentCenter;\n    style.textColor = [UIColor blackColor];\n    style.paragraphStyle =  [NSParagraphStyle paragraphStyleWithCMAttributes:@{\n        CMParagraphStyleAttributeParagraphSpacingBefore: @(12)\n        ,CMParagraphStyleAttributeParagraphSpacing: @0\n        ,CMParagraphStyleAttributeFirstLineHeadExtraIndent:@(0)\n        ,CMParagraphStyleAttributeHeadExtraIndent:@(0)\n        ,CMParagraphStyleAttributeTailExtraIndent:@(0)\n    }];\n    style.paragraphStyleBreakLine = [NSParagraphStyle paragraphStyleWithCMAttributes:@{\n        CMParagraphStyleAttributeParagraphSpacingBefore: @(0)\n        ,CMParagraphStyleAttributeParagraphSpacing: @0\n        ,CMParagraphStyleAttributeMaximumLineHeight: @1\n        ,CMParagraphStyleAttributeFirstLineHeadExtraIndent:@(0)\n        ,CMParagraphStyleAttributeHeadExtraIndent:@(0)\n        ,CMParagraphStyleAttributeTailExtraIndent:@(0)\n    }];\n    return style;\n}\n\n@end\n\n@implementation AMInlineMathAttachment\n{\n    MTMathList * _mathList;\n    MTMathListDisplay * _displayList;\n    NSAttributedString * _mathCodeAttrText;\n    BOOL  _isImageZeroSize;\n}\n\n- (instancetype)initWithText:(NSString *)text style:(AMMathStyle *)style {\n    NSError *error = nil;\n    NSMutableString *mathText = [text mutableCopy];\n    if ([mathText hasPrefix:@\"\\\\(\"]) {\n        [mathText deleteCharactersInRange:NSMakeRange(0, 2)];\n    }\n    if ([mathText hasSuffix:@\"\\\\)\"]) {\n        [mathText deleteCharactersInRange:NSMakeRange(mathText.length - 2, 2)];\n    }\n    MTMathList *mathList = [MTMathListBuilder buildFromString:mathText ?: @\"\"\n                                                        error:&error];\n    // 如果发生错误,绘制原公式文本\n    if (error) {\n        NSAttributedString* attrText = [[NSAttributedString alloc]initWithString:text attributes:@{\n            NSFontAttributeName:[UIFont systemFontOfSize:style.fontSize],\n            NSForegroundColorAttributeName:style.textColor?:[UIColor blackColor],\n        }];\n        self = [super initWithText:text size:CGSizeZero];\n        if (self) {\n            self.error = error;\n            _mathCodeAttrText = attrText;\n        }\n        return self;\n    }\n    \n    style = style ?: [AMMathStyle defaultStyle];\n    \n    @try {\n        MTMathListDisplay *displayList = [MTTypesetter createLineForMathList:mathList\n                                                                        font:[[MTFontManager fontManager] xitsFontWithSize:style.fontSize]\n                                                                       style:kMTLineStyleText];\n        displayList.textColor = style.textColor;\n        \n        const CGFloat contentHeight = displayList.ascent + displayList.descent;\n        CGFloat totalHeight = style.height;\n        if (totalHeight <= 0) {\n            totalHeight = contentHeight;\n        }\n        displayList.position = CGPointMake(0, (totalHeight - contentHeight) / 2 + displayList.descent);\n        \n        self = [super initWithText:text size:CGSizeMake(displayList.width, totalHeight)];\n        if (self) {\n            _mathList = mathList;\n            _displayList = displayList;\n            \n            CGRect rect = self.bounds;\n            switch (style.verticalAlignment) {\n                case UIControlContentVerticalAlignmentCenter: {\n                    rect.origin.y = -displayList.descent;\n                }\n                    break;\n                case UIControlContentVerticalAlignmentBottom: {\n                    rect.origin.y = -rect.size.height;\n                }\n                    break;\n                case UIControlContentVerticalAlignmentTop: {\n                    rect.origin.y = 0;\n                }\n                    break;\n                default:\n                    break;\n            }\n            self.bounds = rect;\n        }\n        return self;\n    } @catch (NSException *exception) {\n        self = [super initWithData:nil ofType:nil];\n        if (self) {\n            self.text = text;\n            self.error = [NSError errorWithDomain:@\"MathDisplayError\"\n                                             code:404\n                                         userInfo:exception.userInfo];\n            \n            AMLogDebug(@\"math display line exception: %@,text = %@\", exception,text);\n\n        }\n        return self;\n    }\n}\n\n- (void)drawImage {\n    const CGSize size = self.bounds.size;\n    UIGraphicsImageRenderer *re = [[UIGraphicsImageRenderer alloc] initWithSize:size];\n    self.image = [re imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) {\n        CGContextRef context = rendererContext.CGContext;\n        CGContextTranslateCTM(context, 0, size.height);\n        CGContextScaleCTM(context, 1.0, -1.0);\n        [_displayList draw:context];\n    }];\n}\n\n- (UIImage *)imageForBounds:(CGRect)imageBounds textContainer:(NSTextContainer *)textContainer characterIndex:(NSUInteger)charIndex\n{\n    if (!self.image && [NSThread isMainThread]) {\n        [self drawImage];\n    }\n    return self.image;\n}\n\n- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer\n                      proposedLineFragment:(CGRect)lineFrag\n                             glyphPosition:(CGPoint)position\n                            characterIndex:(NSUInteger)charIndex {\n    CGRect rect = [super attachmentBoundsForTextContainer:textContainer\n                              proposedLineFragment:lineFrag\n                                     glyphPosition:position\n                                    characterIndex:charIndex];\n    const CGFloat width = rect.size.width;\n\n    if ((ceil(width) != ceil(self.image.size.width)) && [NSThread isMainThread]) {\n       [self drawImage];\n    }\n\n    if (!self.image) {\n        [self drawImage];\n    }\n\n    if(_isImageZeroSize)\n    {\n        rect.size = CGSizeZero;\n    }\n    return rect;\n}\n\n- (NSAttributedString *)attributedString\n{\n    if(self.error)\n    {\n        return [[NSAttributedString alloc] initWithString:@\" \"];\n    }\n    return [NSAttributedString attributedStringWithAttachment:self];\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMLayoutManager+Quote.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMLayoutManager.h\"\n\n@protocol AMDrawable;\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMQuoteLayoutContext : NSObject\n\n@property (nonatomic, assign) CGFloat originX;\n@property (nonatomic, assign) CGFloat originY;\n@property (nonatomic, assign) NSInteger level;\n\n@end\n\n@interface AMLayoutManager (Quote)\n\n- (BOOL)handleQuoteDraw:(CGContextRef)context\n           quoteContext:(AMQuoteLayoutContext *)quoteContext\n               drawable:(id<AMDrawable>)drawable\n                  range:(NSRange)range;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMLayoutManager+Quote.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMLayoutManager+Quote.h\"\n#import \"AMTextBackground.h\"\n#import \"AMTextStyles.h\"\n\n@implementation AMQuoteLayoutContext\n@end\n\n@implementation AMLayoutManager (Quote)\n\n- (BOOL)handleQuoteDraw:(CGContextRef)context\n           quoteContext:(AMQuoteLayoutContext *)quoteContext\n               drawable:(id<AMDrawable>)drawable\n                  range:(NSRange)range {\n    if (![drawable isKindOfClass:AMTextBackground.class] ||\n        !((AMTextBackground *)drawable).isQuote) {\n        return NO;\n    }\n    \n    NSMutableDictionary<CMParagraphStyleAttributeName, id> *quoteParaStyle = [AMTextStyles getAMStylesWithId:self.styleId].blockQuoteAttributes.paragraphStyleAttributes;\n    \n    CGFloat firstHeadIndent = [self _getSizeValue:quoteParaStyle\n                                              key:CMParagraphStyleAttributeFirstLineHeadExtraIndent\n                                       defaultVal:10];\n    \n    CGFloat headIndent = [self _getSizeValue:quoteParaStyle\n                                         key:CMParagraphStyleAttributeHeadExtraIndent\n                                  defaultVal:10];\n    \n    if (firstHeadIndent != headIndent) {\n        return NO;\n    }\n    \n    __block BOOL success = YES;\n    [self enumerateLineFragmentsForGlyphRange:range\n                                   usingBlock:^(CGRect rect, CGRect usedRect, NSTextContainer * _Nonnull textContainer, NSRange glyphRange, BOOL * _Nonnull stop) {\n        NSRange intersectRange = NSIntersectionRange(range, glyphRange);\n        CGRect bounds = [self boundingRectForGlyphRange:intersectRange inTextContainer:textContainer];\n        UIRectEdge edges = UIRectEdgeNone;\n        if (NSEqualRanges(intersectRange, range)) {\n            edges = UIRectEdgeNone;\n        } else if (intersectRange.location == range.location && intersectRange.length < range.location) {\n            edges = UIRectEdgeRight;\n        } else if (intersectRange.location > range.location && NSMaxRange(intersectRange) < NSMaxRange(range)) {\n            edges = UIRectEdgeRight | UIRectEdgeLeft;\n        } else if (intersectRange.location > range.location && NSMaxRange(intersectRange) == NSMaxRange(range)) {\n            edges = UIRectEdgeLeft;\n        }\n        \n        NSInteger iFirstHeadIndent = firstHeadIndent;\n        CGFloat gap =(bounds.origin.x - usedRect.origin.x);\n        BOOL hasOtherContent = ((gap > firstHeadIndent) ||\n                                (bounds.origin.x < usedRect.origin.x) ||\n                                (((NSInteger)bounds.origin.x) % iFirstHeadIndent > 0) ||\n                                (((NSInteger)gap) % iFirstHeadIndent) > 0);\n        \n        NSInteger quoteLevel = (usedRect.origin.x / firstHeadIndent);\n        \n        if (quoteContext.originY == bounds.origin.y && quoteContext.level == quoteLevel) {\n            return;\n        }\n        if (!hasOtherContent) {\n            quoteContext.originX = bounds.origin.x;\n            quoteContext.level = quoteLevel;\n        }\n        \n        if (quoteLevel > 0) {\n            CGContextSaveGState(context);\n            for (NSInteger index = 0; index < quoteContext.level; ++index) {\n                CGFloat w = bounds.size.width;\n                CGFloat h = rect.size.height;\n                CGFloat x = (quoteContext.originX - (index + 1) * firstHeadIndent);;\n                CGFloat y = rect.origin.y;\n                if (index == 0) {\n                    y = bounds.origin.y;\n                }\n                CGRect newBounds = CGRectMake(x, y, w, h);\n                [drawable drawInRect:newBounds clipEdges:edges];\n            }\n            CGContextRestoreGState(context);\n        } else {\n            success = NO;\n        }\n    }];\n    return success;\n}\n\n- (CGFloat)_getSizeValue:(NSDictionary *)dic key:(NSString *)key defaultVal:(CGFloat)defaultVal {\n    if (![dic isKindOfClass:NSDictionary.class] ||\n        ![key isKindOfClass:NSString.class] ||\n        ![dic[key] isKindOfClass:NSNumber.class]) {\n        return defaultVal;\n    }\n    return [dic[key] floatValue];\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMLayoutManager.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <UIKit/UIKit.h>\n\nNS_ASSUME_NONNULL_BEGIN\n@protocol CMAttributedStringRendererDelegate;\n@interface AMLayoutManager : NSLayoutManager\n@property (nonatomic, weak)id<CMAttributedStringRendererDelegate> delegate;\n@property (nonatomic, strong)NSMutableArray* locArray;\n@property (nonatomic, strong)NSMutableDictionary* attachmentDic;\n@property (nonatomic, copy)NSString* styleId;\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMLayoutManager.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMLayoutManager.h\"\n#import \"AMDrawable.h\"\n#import \"AMViewAttachment.h\"\n#import \"AMLayoutManager+Quote.h\"\n#import \"AMIconLinkAttachment.h\"\n#import \"AMImageTextAttachment.h\"\n\n@implementation AMLayoutManager\n\n- (void)drawBackgroundForGlyphRange:(NSRange)glyphsToShow\n                            atPoint:(CGPoint)origin\n{\n    [super drawBackgroundForGlyphRange:glyphsToShow atPoint:origin];\n    \n    CGContextRef context = UIGraphicsGetCurrentContext();\n    CGContextSaveGState(context);\n    CGContextTranslateCTM(context, origin.x, origin.y);\n    \n    NSRange charactorRange = [self characterRangeForGlyphRange:glyphsToShow\n                                              actualGlyphRange:NULL];\n    \n    AMQuoteLayoutContext *quoteContext = [AMQuoteLayoutContext new];\n    [self.textStorage enumerateAttribute:AMBackgroundDrawableAttributeName\n                                 inRange:charactorRange\n                                 options:0\n                              usingBlock:^(id  _Nullable value, NSRange range, BOOL * _Nonnull stop) {\n        if ([value conformsToProtocol:@protocol(AMDrawable)]) {\n            id<AMDrawable> drawable = (id<AMDrawable>)value;\n            BOOL isInline = YES;\n            if ([drawable respondsToSelector:@selector(isInline)]) {\n                isInline = [drawable isInline];\n            }\n            \n            if ([self handleQuoteDraw:context\n                         quoteContext:quoteContext\n                             drawable:drawable\n                                range:range]) {\n                return;\n            }\n            \n            if (isInline) {\n                [self enumerateLineFragmentsForGlyphRange:range\n                                               usingBlock:^(CGRect rect, CGRect usedRect, NSTextContainer * _Nonnull textContainer, NSRange glyphRange, BOOL * _Nonnull stop) {\n                    NSRange intersectRange = NSIntersectionRange(range, glyphRange);\n                    CGRect bounds = [self boundingRectForGlyphRange:intersectRange inTextContainer:textContainer];\n                    UIRectEdge edges = UIRectEdgeNone;\n                    if (NSEqualRanges(intersectRange, range)) {\n                        edges = UIRectEdgeNone;\n                    } else if (intersectRange.location == range.location && intersectRange.length < range.location) {\n                        edges = UIRectEdgeRight;\n                    } else if (intersectRange.location > range.location && NSMaxRange(intersectRange) < NSMaxRange(range)) {\n                        edges = UIRectEdgeRight | UIRectEdgeLeft;\n                    } else if (intersectRange.location > range.location && NSMaxRange(intersectRange) == NSMaxRange(range)) {\n                        edges = UIRectEdgeLeft;\n                    }\n                    CGContextSaveGState(context);\n                    [drawable drawInRect:bounds clipEdges:edges];\n                    CGContextRestoreGState(context);\n                }];\n            } else {\n                __block CGRect bounds = CGRectNull;\n                [self enumerateLineFragmentsForGlyphRange:range\n                                               usingBlock:^(CGRect rect, CGRect usedRect, NSTextContainer * _Nonnull textContainer, NSRange glyphRange, BOOL * _Nonnull stop) {\n                    if (CGRectIsNull(bounds)) {\n                        bounds = UIEdgeInsetsInsetRect(rect, UIEdgeInsetsMake(0, textContainer.lineFragmentPadding, 0, textContainer.lineFragmentPadding));\n                    } else {\n                        bounds = CGRectUnion(bounds, UIEdgeInsetsInsetRect(rect, UIEdgeInsetsMake(0, textContainer.lineFragmentPadding, 0, textContainer.lineFragmentPadding)));\n                    }\n                }];\n                CGContextSaveGState(context);\n                [drawable drawInRect:bounds clipEdges:UIRectEdgeNone];\n                CGContextRestoreGState(context);\n            }\n        }\n    }];\n    CGContextRestoreGState(context);\n}\n\n- (void)drawStrikethroughForGlyphRange:(NSRange)glyphRange\n                     strikethroughType:(NSUnderlineStyle)strikethroughVal\n                        baselineOffset:(CGFloat)baselineOffset\n                      lineFragmentRect:(CGRect)lineRect\n                lineFragmentGlyphRange:(NSRange)lineGlyphRange\n                       containerOrigin:(CGPoint)containerOrigin\n{\n    [super drawStrikethroughForGlyphRange:glyphRange\n                        strikethroughType:strikethroughVal\n                           baselineOffset:baselineOffset\n                         lineFragmentRect:lineRect\n                   lineFragmentGlyphRange:lineGlyphRange\n                          containerOrigin:containerOrigin];\n}\n\n- (void)drawUnderlineForGlyphRange:(NSRange)glyphRange\n                     underlineType:(NSUnderlineStyle)underlineVal\n                    baselineOffset:(CGFloat)baselineOffset\n                  lineFragmentRect:(CGRect)lineRect\n            lineFragmentGlyphRange:(NSRange)lineGlyphRange\n                   containerOrigin:(CGPoint)containerOrigin\n{\n    [super drawUnderlineForGlyphRange:glyphRange\n                        underlineType:underlineVal\n                       baselineOffset:baselineOffset\n                     lineFragmentRect:lineRect\n               lineFragmentGlyphRange:lineGlyphRange\n                      containerOrigin:containerOrigin];\n    \n    CGContextRef context = UIGraphicsGetCurrentContext();\n    CGContextSaveGState(context);\n    \n    NSRange charactorRange = [self characterRangeForGlyphRange:glyphRange\n                                              actualGlyphRange:NULL];\n    \n    [self.textStorage enumerateAttribute:AMUnderlineDrawableAttributeName\n                                 inRange:charactorRange\n                                 options:0\n                              usingBlock:^(id  _Nullable value, NSRange range, BOOL * _Nonnull stop) {\n        if ([value conformsToProtocol:@protocol(AMUnderlineDrawable)]) {\n            id<AMUnderlineDrawable> drawable = (id<AMUnderlineDrawable>)value;\n            CGRect bounds = [self boundingRectForGlyphRange:range inTextContainer:[self textContainerForGlyphAtIndex:range.location effectiveRange:NULL]];\n            CGPoint location = [self locationForGlyphAtIndex:range.location];\n            CGContextSaveGState(context);\n            [drawable drawInRect:CGRectMake(lineRect.origin.x + containerOrigin.x + location.x, lineRect.origin.y + containerOrigin.y, bounds.size.width, location.y)\n                  underlineStyle:underlineVal\n                  baselineOffset:baselineOffset];\n            CGContextRestoreGState(context);\n        }\n    }];\n    CGContextRestoreGState(context);\n}\n\n- (void)drawGlyphsForGlyphRange:(NSRange)glyphsToShow atPoint:(CGPoint)origin\n{\n    [super drawGlyphsForGlyphRange:glyphsToShow atPoint:origin];\n    \n    NSRange charactorRange = [self characterRangeForGlyphRange:glyphsToShow\n                                              actualGlyphRange:NULL];\n    if (!self.locArray) {\n        self.locArray = [[NSMutableArray alloc] init];\n    }\n    if (!self.attachmentDic) {\n        self.attachmentDic = [[NSMutableDictionary alloc] init];\n    }\n    \n    \n    [self.textStorage enumerateAttributesInRange:charactorRange options:0 usingBlock:^(NSDictionary<NSAttributedStringKey, id> *attrs, NSRange range, BOOL *stop) {\n        if ([attrs.allKeys containsObject:NSAttachmentAttributeName]) {\n            NSObject* attrValue = [attrs objectForKey:NSAttachmentAttributeName];\n            if ([attrValue isKindOfClass:[AMIconLinkAttachment class]] || [attrValue isKindOfClass:[AMImageTextAttachment class]]) {\n                ;\n                if ([self.attachmentDic objectForKey:[NSString stringWithFormat:@\"%p\",attrValue]]) {\n                    return;\n                }\n                CGRect rect = [self boundingRectForGlyphRange:range\n                                              inTextContainer:[self textContainerForGlyphAtIndex:range.location\n                                                                                  effectiveRange:NULL]];\n                rect.origin.x += origin.x;\n                rect.origin.y += origin.y;\n                [self.locArray addObject:[NSValue valueWithCGRect:rect]];\n                [self.attachmentDic setObject:attrValue forKey:[NSString stringWithFormat:@\"%p\",attrValue]];\n            } else if ([attrValue conformsToProtocol:@protocol(AMViewAttachment)]) {\n                id<AMViewAttachment> attach = (id<AMViewAttachment>)attrValue;\n                \n                CGRect rect = [self boundingRectForGlyphRange:range\n                                              inTextContainer:[self textContainerForGlyphAtIndex:range.location\n                                                                                  effectiveRange:NULL]];\n                rect.origin.x += origin.x;\n                rect.origin.y += origin.y;\n                attach.view.frame = rect;\n                attach.view.hidden = NO;\n            }\n        } else if ([attrs.allKeys containsObject:NSLinkAttributeName]) {\n            if ([self.attachmentDic objectForKey:[NSString stringWithFormat:@\"%p\",[attrs objectForKey:NSLinkAttributeName]]]) {\n                return;\n            }\n            CGRect rect = [self boundingRectForGlyphRange:range\n                                          inTextContainer:[self textContainerForGlyphAtIndex:range.location\n                                                                              effectiveRange:NULL]];\n            rect.origin.x += origin.x;\n            rect.origin.y += origin.y;\n            [self.locArray addObject:[NSValue valueWithCGRect:rect]];\n            [self.attachmentDic setObject:[attrs objectForKey:NSLinkAttributeName] forKey:[NSString stringWithFormat:@\"%p\",[attrs objectForKey:NSLinkAttributeName]]];\n        }\n    }];\n    \n    if (self.delegate) {\n        [self.delegate notifyNodeLocation:self.locArray];\n    }\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMMarkDownTableViewBlowUpControllerViewController.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <UIKit/UIKit.h>\n#import \"AMMarkdownTableView.h\"\n#import \"AMTextStyles.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMMarkDownTableViewBlowUpControllerViewController : UIViewController\n\n@property (nonatomic) CMTable *table;\n\n@property (nonatomic) BOOL partialUpdate;\n\n@property (nonatomic) AMTextStyles *styles;\n\n@property (nonatomic) CGSize collectionSize;\n\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMMarkDownTableViewBlowUpControllerViewController.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMMarkDownTableViewBlowUpControllerViewController.h\"\n#import \"AMUtils.h\"\n#import \"AMGradientView.h\"\n#import \"AMMarkdownTableLayout.h\"\n#import \"UITextView+AntMarkdown.h\"\n\nconst CGFloat AMTableCellMinimumLineLandScapeSpacing = 1;\nconst CGFloat AMTableMinimumLandScapeRowHeight = 35;\nconst UIEdgeInsets AMTableLandScapeCellInset = {10, 40, 8, 40};\n\n@interface AMMarkdownTableRowBackgroundLandScapeView : UICollectionReusableView\n\n@end\n\n@implementation AMMarkdownTableRowBackgroundLandScapeView\n@end\n\n@interface AMMarkdownLandScapeTableCell : UICollectionViewCell <AMMarkdownTableCell>\n@property (nonatomic) UITextView *textview;\n@property (nonatomic) UIEdgeInsets contentInsets;\n@property (nonatomic) BOOL partialUpdate;\n\n+ (CGSize)sizeForCell:(CMTableCell *)cell;\n\n@end\n\n@implementation AMMarkdownLandScapeTableCell\n@synthesize cellData = _cellData;\n\n+ (CGSize)sizeForCell:(CMTableCell *)cell\n{\n    return [self sizeForCell:cell constrainedWidth:CGFLOAT_MAX];\n}\n\n+ (CGSize)sizeForCell:(CMTableCell *)cell constrainedWidth:(CGFloat)width\n{\n    const CGFloat paddingHorizontal = AMTableLandScapeCellInset.left + AMTableLandScapeCellInset.right;\n    const CGFloat paddingVertical = AMTableLandScapeCellInset.top + AMTableLandScapeCellInset.bottom;\n    CGSize size = CGRectIntegral([cell.content boundingRectWithSize:CGSizeMake(width - paddingHorizontal, CGFLOAT_MAX)\n                                                            options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading\n                                                            context:nil]).size;\n    CGSize size2 = CGRectIntegral([cell.content boundingRectWithSize:CGSizeMake(width - paddingHorizontal, CGFLOAT_MAX)\n                                                            options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesDeviceMetrics\n                                                            context:nil]).size;\n\n    return CGSizeMake(MIN(width, size.width + paddingHorizontal), MAX(size.height, size2.height) + paddingVertical);\n}\n\n- (instancetype)initWithFrame:(CGRect)frame\n{\n    self = [super initWithFrame:frame];\n    if (self) {\n        self.textview = [[UITextView alloc] initWithFrame_ant_mark:UIEdgeInsetsInsetRect(self.bounds, self.contentInsets)];\n        self.textview.font = [UIFont systemFontOfSize:14];\n        self.textview.scrollEnabled = YES;\n        self.textview.selectable = NO;\n        self.textview.editable = NO;\n        self.textview.backgroundColor = [UIColor clearColor];\n        self.textview.textContainerInset = UIEdgeInsetsZero;\n        self.textview.textContainer.lineFragmentPadding = 0;\n        [self.contentView addSubview:self.textview];\n        \n        self.textview.translatesAutoresizingMaskIntoConstraints = NO;\n        [self.contentView addConstraints:@[\n            [NSLayoutConstraint constraintWithItem:self.textview\n                                         attribute:NSLayoutAttributeLeft\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.textview.superview\n                                         attribute:NSLayoutAttributeLeft\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:self.textview\n                                         attribute:NSLayoutAttributeRight\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.textview.superview\n                                         attribute:NSLayoutAttributeRight\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:self.textview\n                                         attribute:NSLayoutAttributeTop\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.textview.superview\n                                         attribute:NSLayoutAttributeTop\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:self.textview\n                                         attribute:NSLayoutAttributeBottom\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.textview.superview\n                                         attribute:NSLayoutAttributeBottom\n                                        multiplier:1\n                                          constant:0],\n        ]];\n        \n        self.contentInsets = AMTableLandScapeCellInset;\n        \n        \n        [NSNotificationCenter.defaultCenter addObserver:self\n                                               selector:@selector(onSizeUpdate:)\n                                                   name:AMTextAttachmentSizeDidUpdateNotification\n                                                 object:nil];\n    }\n    return self;\n}\n\n- (void)dealloc\n{\n    [NSNotificationCenter.defaultCenter removeObserver:self];\n}\n\n- (void)onSizeUpdate:(NSNotification *)noti\n{\n    if ([noti.object isKindOfClass:[NSAttributedString class]]) {\n        NSAttributedString *attri = (NSAttributedString *)noti.object;\n        if ([attri.string isEqual:self.cellData.content.string]) {\n            UICollectionView *collectionView = (UICollectionView *)self.superview;\n            while (![collectionView isKindOfClass:[UICollectionView class]]) {\n                collectionView = (UICollectionView *)collectionView.superview;\n            }\n            if ([collectionView isKindOfClass:[UICollectionView class]]) {\n                NSIndexPath *indexPath = [collectionView indexPathForCell:self];\n                UICollectionViewLayoutInvalidationContext *context = [[UICollectionViewLayoutInvalidationContext alloc] init];\n                if (indexPath) {\n                    [context invalidateItemsAtIndexPaths:@[indexPath]];\n                } else {\n                    \n                }\n                \n                [collectionView.collectionViewLayout invalidateLayout];\n            }\n        }\n    }\n}\n\n- (void)prepareForReuse\n{\n    [super prepareForReuse];\n    \n    self.textview.attributedText = nil;\n}\n\n- (void)setCellData:(CMTableCell *)cellData\n{\n    if (_cellData != cellData) {\n        _cellData = cellData;\n        \n        self.textview.textAlignment = cellData.alignment;\n        if (self.partialUpdate) {\n            [self.textview setAttributedTextPartialUpdate_ant_mark:cellData.content];\n        } else {\n            [self.textview setAttributedText_ant_mark:cellData.content];\n        }\n    }\n}\n\n- (void)setContentInsets:(UIEdgeInsets)contentInsets {\n    if (!UIEdgeInsetsEqualToEdgeInsets(_contentInsets, contentInsets)) {\n        _contentInsets = contentInsets;\n        self.textview.textContainerInset = contentInsets;\n    }\n}\n\n@end\n\n\n@interface AMMarkDownTableViewBlowUpControllerViewController ()<UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>\n\n@property (nonatomic) AMMarkdownTableLayout *layout;\n\n@property (nonatomic) UICollectionView * collectionView;\n\n@property (nonatomic) CGFloat maximumColumnWidth;\n\n@property (nonatomic) UIColor *borderColor;\n\n@property (nonatomic) CGFloat borderWidth;\n\n@property (nonatomic) AMGradientView *rightGradientView, *leftGradientView;\n\n@property (nonatomic)UIScrollView *scrollView;\n\n@property (nonatomic)NSLayoutConstraint* collectionNSLayoutConstraint;\n@property (nonatomic)NSLayoutConstraint* scrollViewNSLayoutConstraint;\n\n\n@end\n\n@implementation AMMarkDownTableViewBlowUpControllerViewController\n\n- (void)viewDidLoad {\n    [super viewDidLoad];\n    self.view.backgroundColor = [UIColor whiteColor];\n    self.borderColor = self.styles.tableTitleAttributes.stringAttributes[NSBackgroundColorAttributeName]? : [UIColor colorWithHex_ant_mark:0x1f3b6329];\n    self.borderWidth = self.styles.tableAttributes.stringAttributes[@\"borderWidth\"] ? [self.styles.tableAttributes.stringAttributes[@\"borderWidth\"] floatValue] : 0;\n    [self setupUI];\n}\n\n- (void)setupUI {\n    \n    UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];\n    backButton.titleLabel.font = [UIFont systemFontOfSize:12];\n    [backButton setImage:[UIImage imageNamed_ant_mark:@\"icon_back\"] forState:UIControlStateNormal];\n    [backButton addTarget:self action:@selector(onBack:) forControlEvents:UIControlEventTouchUpInside];\n    backButton.translatesAutoresizingMaskIntoConstraints = NO;\n    [self.view addSubview:backButton];\n    [self.view addConstraints:@[\n        [NSLayoutConstraint constraintWithItem:backButton\n                                     attribute:NSLayoutAttributeLeft\n                                     relatedBy:NSLayoutRelationEqual\n                                        toItem:self.view\n                                     attribute:NSLayoutAttributeLeft\n                                    multiplier:1\n                                      constant:20],\n        [NSLayoutConstraint constraintWithItem:backButton\n                                     attribute:NSLayoutAttributeTop\n                                     relatedBy:NSLayoutRelationEqual\n                                        toItem:self.view\n                                     attribute:NSLayoutAttributeTop\n                                    multiplier:1\n                                      constant:20],\n        [NSLayoutConstraint constraintWithItem:backButton\n                                     attribute:NSLayoutAttributeWidth\n                                     relatedBy:NSLayoutRelationEqual\n                                        toItem:nil\n                                     attribute:NSLayoutAttributeNotAnAttribute\n                                    multiplier:1\n                                      constant:70],\n        [NSLayoutConstraint constraintWithItem:backButton\n                                     attribute:NSLayoutAttributeHeight\n                                     relatedBy:NSLayoutRelationEqual\n                                        toItem:nil\n                                     attribute:NSLayoutAttributeNotAnAttribute\n                                    multiplier:1\n                                      constant:30],\n    ]];\n    \n    CGFloat maxHeight = self.view.bounds.size.width - 80;\n    CGFloat width = self.view.bounds.size.height - 100;\n    CGFloat height = self.collectionSize.height > maxHeight ? maxHeight : self.collectionSize.height;\n    \n    _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, width, height)];\n    [self.view addSubview:_scrollView];\n    _scrollView.translatesAutoresizingMaskIntoConstraints = NO;\n    _scrollViewNSLayoutConstraint = [NSLayoutConstraint constraintWithItem:_scrollView\n                                                                 attribute:NSLayoutAttributeHeight\n                                                                 relatedBy:NSLayoutRelationEqual\n                                                                    toItem:nil\n                                                                 attribute:NSLayoutAttributeNotAnAttribute\n                                                                multiplier:1\n                                                                  constant:height];\n    [self.view addConstraints:@[\n        [NSLayoutConstraint constraintWithItem:_scrollView\n                                     attribute:NSLayoutAttributeTop\n                                     relatedBy:NSLayoutRelationEqual\n                                        toItem:backButton\n                                     attribute:NSLayoutAttributeBottom\n                                    multiplier:1\n                                      constant:14],\n        [NSLayoutConstraint constraintWithItem:_scrollView\n                                     attribute:NSLayoutAttributeCenterX\n                                     relatedBy:NSLayoutRelationEqual\n                                        toItem:self.view\n                                     attribute:NSLayoutAttributeCenterX\n                                    multiplier:1\n                                      constant:0],\n        [NSLayoutConstraint constraintWithItem:_scrollView\n                                     attribute:NSLayoutAttributeWidth\n                                     relatedBy:NSLayoutRelationEqual\n                                        toItem:nil\n                                     attribute:NSLayoutAttributeNotAnAttribute\n                                    multiplier:1\n                                      constant:width],\n        _scrollViewNSLayoutConstraint,\n    ]];\n    \n    \n    self.layout = [[AMMarkdownTableLayout alloc] init];\n    self.layout.minimumLineSpacing = AMTableCellMinimumLineLandScapeSpacing;\n    self.layout.minimumInteritemSpacing = 1;\n    self.layout.minimumRowHeight = AMTableMinimumLandScapeRowHeight;\n    self.layout.itemSize = CGSizeMake(105, 35);\n    \n    self.maximumColumnWidth = 300;\n    \n    self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, width, height)\n                                             collectionViewLayout:self.layout];\n    [self.collectionView registerClass:[AMMarkdownLandScapeTableCell class]\n            forCellWithReuseIdentifier:CLSSTR(AMMarkdownLandScapeTableCell)];\n    [self.collectionView registerClass:[AMMarkdownTableRowBackgroundLandScapeView class]\n            forSupplementaryViewOfKind:@\"Background\"\n                   withReuseIdentifier:CLSSTR(AMMarkdownTableRowBackgroundLandScapeView)];\n    self.collectionView.bounces = NO;\n    self.collectionView.scrollsToTop = NO;\n    self.collectionView.contentInset = UIEdgeInsetsMake(1, 0, 0, 0);\n    self.collectionView.backgroundColor = self.borderColor;\n    self.collectionView.alwaysBounceHorizontal = NO;\n    self.collectionView.alwaysBounceVertical = NO;\n#if __IPHONE_11_0 && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0\n    if (@available(iOS 11.0, *)) {\n        self.collectionView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;\n    } else {\n        // Fallback on earlier versions\n    }\n#endif\n    \n    \n#if __IPHONE_17_4 && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_17_4\n    if (@available(iOS 17.4, *)) {\n        self.collectionView.bouncesHorizontally = NO;\n        self.collectionView.bouncesVertically = NO;\n    } else {\n        // Fallback on earlier versions\n    }\n#endif\n    self.collectionView.delegate = self;\n    self.collectionView.dataSource = self;\n    self.collectionView.layer.borderWidth = self.borderWidth;\n    self.collectionView.layer.borderColor = self.borderColor.CGColor;\n    self.collectionView.layer.cornerRadius = 12;\n    [_scrollView addSubview:self.collectionView];\n    self.collectionView.translatesAutoresizingMaskIntoConstraints = NO;\n    \n    self.rightGradientView = [[AMGradientView alloc] init];\n    self.rightGradientView.colors = @[\n        [UIColor colorWithHex_ant_mark:0x201f3b63].transparentColor_ant_mark,\n        [UIColor colorWithHex_ant_mark:0x201f3b63],\n    ];\n    self.rightGradientView.layer.actions = @{\n        KEYPATH(CALayer *, opacity): [NSNull null],\n        KEYPATH(CALayer *, hidden): [NSNull null],\n    };\n    self.rightGradientView.hidden = YES;\n    self.rightGradientView.translatesAutoresizingMaskIntoConstraints = NO;\n    [_scrollView addSubview:self.rightGradientView];\n    \n    self.leftGradientView = [[AMGradientView alloc] init];\n    self.leftGradientView.colors = @[\n        [UIColor colorWithHex_ant_mark:0x201f3b63],\n        [UIColor colorWithHex_ant_mark:0x201f3b63].transparentColor_ant_mark,\n    ];\n    self.leftGradientView.layer.actions = @{\n        KEYPATH(CALayer *, opacity): [NSNull null],\n        KEYPATH(CALayer *, hidden): [NSNull null],\n    };\n    self.leftGradientView.hidden = YES;\n    self.leftGradientView.translatesAutoresizingMaskIntoConstraints = NO;\n    [_scrollView addSubview:self.leftGradientView];\n    _collectionNSLayoutConstraint = [NSLayoutConstraint constraintWithItem:self.collectionView\n                                                                                    attribute:NSLayoutAttributeHeight\n                                                                                    relatedBy:NSLayoutRelationGreaterThanOrEqual\n                                                                                       toItem:nil\n                                                                                    attribute:NSLayoutAttributeNotAnAttribute\n                                                                                   multiplier:1\n                                                                                     constant:height];\n    [_scrollView addConstraints:@[\n        [NSLayoutConstraint constraintWithItem:self.collectionView\n                                     attribute:NSLayoutAttributeWidth\n                                     relatedBy:NSLayoutRelationGreaterThanOrEqual\n                                        toItem:nil\n                                     attribute:NSLayoutAttributeNotAnAttribute\n                                    multiplier:1\n                                      constant:width],\n        _collectionNSLayoutConstraint,\n        [NSLayoutConstraint constraintWithItem:self.rightGradientView\n                                     attribute:NSLayoutAttributeTop\n                                     relatedBy:NSLayoutRelationEqual\n                                        toItem:_scrollView\n                                     attribute:NSLayoutAttributeTop\n                                    multiplier:1\n                                      constant:0],\n        [NSLayoutConstraint constraintWithItem:self.rightGradientView\n                                     attribute:NSLayoutAttributeBottom\n                                     relatedBy:NSLayoutRelationEqual\n                                        toItem:_scrollView\n                                     attribute:NSLayoutAttributeBottom\n                                    multiplier:1\n                                      constant:0],\n        [NSLayoutConstraint constraintWithItem:self.rightGradientView\n                                     attribute:NSLayoutAttributeWidth\n                                     relatedBy:NSLayoutRelationEqual\n                                        toItem:nil\n                                     attribute:NSLayoutAttributeNotAnAttribute\n                                    multiplier:1\n                                      constant:18],\n        [NSLayoutConstraint constraintWithItem:self.collectionView\n                                     attribute:NSLayoutAttributeLeft\n                                     relatedBy:NSLayoutRelationEqual\n                                        toItem:self.leftGradientView\n                                     attribute:NSLayoutAttributeLeft\n                                    multiplier:1\n                                      constant:0],\n        [NSLayoutConstraint constraintWithItem:self.leftGradientView\n                                     attribute:NSLayoutAttributeTop\n                                     relatedBy:NSLayoutRelationEqual\n                                        toItem:self.collectionView\n                                     attribute:NSLayoutAttributeTop\n                                    multiplier:1\n                                      constant:0],\n        [NSLayoutConstraint constraintWithItem:self.leftGradientView\n                                     attribute:NSLayoutAttributeBottom\n                                     relatedBy:NSLayoutRelationEqual\n                                        toItem:_scrollView\n                                     attribute:NSLayoutAttributeBottom\n                                    multiplier:1\n                                      constant:0],\n        [NSLayoutConstraint constraintWithItem:self.leftGradientView\n                                     attribute:NSLayoutAttributeWidth\n                                     relatedBy:NSLayoutRelationEqual\n                                        toItem:nil\n                                     attribute:NSLayoutAttributeNotAnAttribute\n                                    multiplier:1\n                                      constant:18],\n    ]];\n    \n    [self.collectionView addObserver:self\n                          forKeyPath:KEYPATH(self.collectionView, contentSize)\n                             options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld\n                             context:nil];\n    [self scrollViewDidScroll:self.collectionView];\n}\n\n- (void)scrollViewDidScroll:(UIScrollView *)scrollView\n{\n    if (scrollView.contentOffset.x + scrollView.bounds.size.width >= scrollView.contentSize.width - 1) {\n        if (![self.rightGradientView.layer animationForKey:@\"Fadeout\"]) {\n            CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:KEYPATH(self.rightGradientView.layer, opacity)];\n            anim.duration = 0.15;\n            anim.toValue = @0;\n            anim.fillMode = kCAFillModeBoth;\n            anim.removedOnCompletion = NO;\n            [self.rightGradientView.layer addAnimation:anim forKey:@\"Fadeout\"];\n        }\n        self.rightGradientView.alpha = 0;\n    } else {\n        if ([self.rightGradientView.layer animationForKey:@\"Fadeout\"]) {\n            [self.rightGradientView.layer removeAnimationForKey:@\"Fadeout\"];\n            if (scrollView.isDragging) {\n                CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:KEYPATH(self.rightGradientView.layer, opacity)];\n                anim.duration = 0.15;\n                anim.fromValue = @0;\n                anim.removedOnCompletion = YES;\n                [self.rightGradientView.layer addAnimation:anim forKey:@\"Fadein\"];\n            }\n        }\n        self.rightGradientView.alpha = 1;\n    }\n    \n    if (scrollView.contentOffset.x < 1) {\n        if (![self.leftGradientView.layer animationForKey:@\"Fadeout\"]) {\n            CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:KEYPATH(self.leftGradientView.layer, opacity)];\n            anim.duration = 0.15;\n            anim.toValue = @0;\n            anim.fillMode = kCAFillModeBoth;\n            anim.removedOnCompletion = NO;\n            [self.leftGradientView.layer addAnimation:anim forKey:@\"Fadeout\"];\n        }\n        self.leftGradientView.alpha = 0;\n    } else {\n        if ([self.leftGradientView.layer animationForKey:@\"Fadeout\"]) {\n            [self.leftGradientView.layer removeAnimationForKey:@\"Fadeout\"];\n            if (scrollView.isDragging) {\n                CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:KEYPATH(self.leftGradientView.layer, opacity)];\n                anim.duration = 0.15;\n                anim.fromValue = @0;\n                anim.removedOnCompletion = YES;\n                [self.leftGradientView.layer addAnimation:anim forKey:@\"Fadein\"];\n            }\n        }\n        self.leftGradientView.alpha = 1;\n    }\n}\n\n- (void)observeValueForKeyPath:(NSString *)keyPath\n                      ofObject:(id)object\n                        change:(NSDictionary<NSKeyValueChangeKey,id> *)change\n                       context:(void *)context\n{\n    if (object == self.collectionView) {\n        CGSize oldSize = [change[NSKeyValueChangeOldKey] CGSizeValue];\n        CGSize newSize = [change[NSKeyValueChangeNewKey] CGSizeValue];\n        \n        self.rightGradientView.hidden = self.leftGradientView.hidden = newSize.width < self.collectionView.bounds.size.width + 1;\n        if (!self.rightGradientView.isHidden) {\n            [self scrollViewDidScroll:self.collectionView];\n        }\n        if (!CGSizeEqualToSize(oldSize, newSize)) {\n            // layout\n            CGFloat maxHeight = self.view.bounds.size.height - 100;\n            CGFloat height = newSize.height > maxHeight ? maxHeight : newSize.height;\n            CGRect oldFrame = [_scrollView frame];\n            [_scrollView setFrame:CGRectMake(oldFrame.origin.x, oldFrame.origin.y, oldFrame.size.width, height)];\n            [_collectionView setFrame:CGRectMake(oldFrame.origin.x, oldFrame.origin.y, oldFrame.size.width, height)];\n            [_scrollView removeConstraint:_collectionNSLayoutConstraint];\n            [self.view removeConstraint:_scrollViewNSLayoutConstraint];\n            NSLayoutConstraint* newNSLayoutConstraint = [NSLayoutConstraint constraintWithItem:self.collectionView\n                                                                                            attribute:NSLayoutAttributeHeight\n                                                                                            relatedBy:NSLayoutRelationGreaterThanOrEqual\n                                                                                               toItem:nil\n                                                                                            attribute:NSLayoutAttributeNotAnAttribute\n                                                                                           multiplier:1\n                                                                                             constant:height];\n            NSLayoutConstraint* newscrollNSLayoutConstraint = [NSLayoutConstraint constraintWithItem:_scrollView\n                                                                                           attribute:NSLayoutAttributeHeight\n                                                                                           relatedBy:NSLayoutRelationEqual\n                                                                                              toItem:nil\n                                                                                           attribute:NSLayoutAttributeNotAnAttribute\n                                                                                          multiplier:1\n                                                                                            constant:height];\n            [_scrollView addConstraint:newNSLayoutConstraint];\n            [self.view addConstraint:newscrollNSLayoutConstraint];\n        }\n    }\n}\n\n- (void)dealloc\n{\n    [self.collectionView removeObserver:self\n                             forKeyPath:KEYPATH(self.collectionView, contentSize)];\n}\n\n- (UIInterfaceOrientationMask)supportedInterfaceOrientations {\n    return UIInterfaceOrientationMaskLandscape;\n}\n\n- (BOOL)shouldAutorotate {\n    return YES;\n}\n\n- (void)viewWillAppear:(BOOL)animated {\n    [super viewWillAppear:animated];\n    [self forceLandscapeOrientation];\n}\n\n- (void)viewWillDisappear:(BOOL)animated {\n    [super viewWillDisappear:animated];\n    [self forceOrientationPortrait];\n}\n\n- (void)forceOrientationPortrait {\n    NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];\n    [[UIDevice currentDevice] setValue:value forKey:@\"orientation\"];\n    [UIViewController attemptRotationToDeviceOrientation];\n}\n\n- (void)forceLandscapeOrientation {\n    NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];\n    [[UIDevice currentDevice] setValue:value forKey:@\"orientation\"];\n    [UIViewController attemptRotationToDeviceOrientation];\n}\n\n\n- (void)onBack:(id)sender {\n    [self dismissViewControllerAnimated:NO completion:nil];\n}\n\n# pragma UICollectionViewDelegateFlowLayout\n- (CGSize)collectionView:(UICollectionView *)collectionView\n                  layout:(UICollectionViewLayout*)collectionViewLayout\n  sizeForItemAtIndexPath:(NSIndexPath *)indexPath\n{\n    CMTableCell *cellData = [self.table cellAtIndexPath:indexPath];\n    return [[AMMarkdownLandScapeTableCell class] sizeForCell:cellData constrainedWidth:self.maximumColumnWidth];\n}\n\n- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section\n{\n    return UIEdgeInsetsZero;\n}\n\n- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section\n{\n    return 2;\n}\n\n- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section\n{\n    return 2;\n}\n\n- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section\n{\n    return CGSizeZero;\n}\n\n- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section\n{\n    return CGSizeZero;\n}\n\n\n# pragma UICollectionViewDataSource\n\n- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {\n    return self.table.numberOfColumns;\n}\n\n- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {\n    AMMarkdownLandScapeTableCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CLSSTR(AMMarkdownLandScapeTableCell)\n                                                                                                forIndexPath:indexPath];\n    CMTableCell *cellData = [self.table cellAtIndexPath:indexPath];\n    cell.cellData = cellData;\n    if ([cell isKindOfClass:[AMMarkdownLandScapeTableCell class]]) {\n        ((AMMarkdownLandScapeTableCell *)cell).partialUpdate = self.partialUpdate;\n    }\n    cell.backgroundColor = [UIColor whiteColor];\n    cell.contentView.backgroundColor = [UIColor clearColor];\n    if ([self.table isHeaderAtIndexPath:indexPath]) {\n        UIColor *color = self.styles.tableHeaderAttributes.stringAttributes[@\"contentBgColor\"] ?: [UIColor colorWithHex_ant_mark:0x141f3b63];\n        if ([color isKindOfClass:[UIColor class]]) {\n            cell.contentView.backgroundColor = color;\n        }\n    }\n    return cell;\n}\n\n- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {\n    return self.table.numberOfRows;\n}\n\n\n- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView\n           viewForSupplementaryElementOfKind:(NSString *)kind\n                                 atIndexPath:(NSIndexPath *)indexPath {\n    if ([kind isEqualToString:@\"Background\"]) {\n        AMMarkdownTableRowBackgroundLandScapeView *view = [collectionView dequeueReusableSupplementaryViewOfKind:kind\n                                                                                    withReuseIdentifier:CLSSTR(AMMarkdownTableRowBackgroundLandScapeView)\n                                                                                           forIndexPath:indexPath];\n        return view;\n    }\n    return nil;\n}\n\n\n\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMMarkdownCodeView.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <UIKit/UIKit.h>\n#import <AntMarkdown/AMCodeViewAttachment.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMMarkdownCodeView : UIView <AMCodeView, AMAttachedView>\n@property (nonatomic) UILabel *languageLabel;\n@property (nonatomic) UIButton *codeCopyButton;\n@property (nonatomic) BOOL partialUpdate;\n\n@property (nonatomic) CGFloat maximumHeight;    // Default is Screen Height / 2\n\n- (instancetype)initWithStyles:(AMTextStyles *)styles;\n\n- (void)didCopyCode:(NSString *)code;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMMarkdownCodeView.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMMarkdownCodeView.h\"\n#import \"UITextView+AntMarkdown.h\"\n#import \"AMUtils.h\"\n#import \"AMTextStyles.h\"\n#import \"CMCascadingAttributeStack.h\"\n\nconst CGFloat AMCodeHeaderHeight = 40.0;\nconst UIEdgeInsets AMCodeViewInset = {.top = 4, .left = 12, .bottom = 10, .right = 12};\n\n@interface AMMarkdownCodeView ()\n@property (nonatomic) AMTextStyles *styles;\n@property (nonatomic, strong) UITextView *textView;\n@property (nonatomic, strong) NSLayoutConstraint *heightConstraint;\n\n@end\n\n@implementation AMMarkdownCodeView\n@synthesize attachment = _attachment;\n\n- (instancetype)initWithStyles:(AMTextStyles *)styles\n{\n    self = [super initWithFrame:CGRectMake(0, 0, UIScreen.mainScreen.bounds.size.width, AMCodeHeaderHeight)];\n    if (self) {\n        self.styles = styles;\n        \n        self.textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, UIScreen.mainScreen.bounds.size.width, 60)];\n        self.textView.contentInset = UIEdgeInsetsZero;\n        self.textView.textContainer.lineFragmentPadding = 0;\n        self.textView.textContainerInset = AMCodeViewInset;\n        self.textView.editable = NO;\n        self.textView.selectable = NO;\n        self.textView.scrollEnabled = YES;\n        self.textView.bounces = NO;\n        self.textView.scrollsToTop = NO;\n        \n        UIFont *font = self.styles.codeBlockAttributes.stringAttributes[NSFontAttributeName] ?: [UIFont fontWithName:@\"Courier\" size:13];\n        self.textView.font = font;\n        self.textView.textColor = self.styles.baseTextAttributes.stringAttributes[NSForegroundColorAttributeName] ?: [UIColor blackColor];\n        if (self.styles.codeBlockAttributes.stringAttributes[NSForegroundColorAttributeName]) {\n            self.textView.textColor = self.styles.codeBlockAttributes.stringAttributes[NSForegroundColorAttributeName];\n        }\n        [self.textView addObserver:self\n                        forKeyPath:KEYPATH(self.textView, contentSize)\n                           options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld\n                           context:nil];\n        if (self.styles.codeBlockAttributes.stringAttributes[@\"backgroundColor\"]) {\n            self.textView.backgroundColor = self.styles.codeBlockAttributes.stringAttributes[@\"backgroundColor\"];\n        }\n       \n        self.backgroundColor = [UIColor whiteColor];\n        self.layer.cornerRadius = 12;\n        self.layer.masksToBounds = YES;\n        self.layer.borderWidth = [self.styles.codeBlockAttributes.stringAttributes[@\"borderWidth\"] floatValue] ? : 0;\n        self.layer.borderColor = self.styles.codeBlockAttributes.stringAttributes[@\"borderColor\"] ? ((UIColor*)self.styles.codeBlockAttributes.stringAttributes[@\"borderColor\"]).CGColor : [UIColor clearColor].CGColor;\n        \n        UIView *head = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, AMCodeHeaderHeight)];\n        head.backgroundColor = self.styles.codeBlockAttributes.stringAttributes[@\"headerBackgroundColor\"] ? : [UIColor colorWithHex_ant_mark:0xa1f3b63];\n        head.translatesAutoresizingMaskIntoConstraints = NO;\n        [self addSubview:head];\n        \n        UIView *separator = [[UIView alloc] initWithFrame:CGRectMake(0, AMCodeHeaderHeight - 1, self.bounds.size.width, 1)];\n        separator.backgroundColor = [UIColor colorWithHex_ant_mark:0x291f3b63];\n        separator.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;\n        separator.translatesAutoresizingMaskIntoConstraints = YES;\n        [head addSubview:separator];\n        \n        self.languageLabel = [UILabel new];\n        self.languageLabel.font = self.styles.codeBlockAttributes.stringAttributes[@\"titleFont\"] ? : [UIFont boldSystemFontOfSize:13];\n        self.languageLabel.textColor =  self.styles.baseTextAttributes.stringAttributes[NSForegroundColorAttributeName] ?: self.styles.paragraphAttributes.stringAttributes[NSForegroundColorAttributeName];\n        if (self.styles.codeBlockAttributes.stringAttributes[@\"titleFontColor\"]) {\n            self.languageLabel.textColor = self.styles.codeBlockAttributes.stringAttributes[@\"titleFontColor\"];\n        }\n        self.languageLabel.translatesAutoresizingMaskIntoConstraints = NO;\n        [head addSubview:self.languageLabel];\n        [head addConstraints:@[\n            [NSLayoutConstraint constraintWithItem:head\n                                         attribute:NSLayoutAttributeLeft\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.languageLabel\n                                         attribute:NSLayoutAttributeLeft\n                                        multiplier:1\n                                          constant:-12],\n            [NSLayoutConstraint constraintWithItem:head\n                                         attribute:NSLayoutAttributeCenterY\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.languageLabel\n                                         attribute:NSLayoutAttributeCenterY\n                                        multiplier:1\n                                          constant:0],\n        ]];\n        \n        self.codeCopyButton = [UIButton buttonWithType:UIButtonTypeCustom];\n        self.codeCopyButton.titleLabel.font = [UIFont systemFontOfSize:12];\n        if (self.styles.codeBlockAttributes.stringAttributes[@\"operationIcon\"]) {\n            NSString* iconPath = self.styles.codeBlockAttributes.stringAttributes[@\"operationIcon\"];\n            NSRange iOSRange = [iconPath rangeOfString:@\"/\"];\n            if (iOSRange.location != NSNotFound) {\n                 \n                NSString *bundlePart = [iconPath substringToIndex:iOSRange.location];\n                NSString *imagePart = [iconPath substringFromIndex:iOSRange.location + 1];\n                [self.codeCopyButton setImage:[UIImage imageNamed_ant_bundle:bundlePart name:imagePart] forState:UIControlStateNormal];\n            }\n        } else {\n            [self.codeCopyButton setImage:[UIImage imageNamed_ant_mark:@\"code_copy_old\"] forState:UIControlStateNormal];\n        }\n        \n        [self.codeCopyButton addTarget:self\n                                action:@selector(_onCopyCode:)\n                      forControlEvents:UIControlEventTouchUpInside];\n        self.codeCopyButton.translatesAutoresizingMaskIntoConstraints = NO;\n        [head addSubview:self.codeCopyButton];\n        [head addConstraints:@[\n            [NSLayoutConstraint constraintWithItem:head\n                                         attribute:NSLayoutAttributeRight\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.codeCopyButton\n                                         attribute:NSLayoutAttributeRight\n                                        multiplier:1\n                                          constant:10],\n            [NSLayoutConstraint constraintWithItem:head\n                                         attribute:NSLayoutAttributeCenterY\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.codeCopyButton\n                                         attribute:NSLayoutAttributeCenterY\n                                        multiplier:1\n                                          constant:0],\n        ]];\n        \n        self.textView.translatesAutoresizingMaskIntoConstraints = NO;\n        [self addSubview:self.textView];\n        \n        [self.textView setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];\n        self.heightConstraint = [NSLayoutConstraint constraintWithItem:self.textView\n                                                                         attribute:NSLayoutAttributeHeight\n                                                                         relatedBy:NSLayoutRelationEqual\n                                                                            toItem:nil\n                                                                         attribute:NSLayoutAttributeNotAnAttribute\n                                                                        multiplier:1\n                                                              constant:AMCodeHeaderHeight];\n        self.heightConstraint.priority = UILayoutPriorityDefaultHigh -1;\n        \n        [self.textView addConstraints:@[self.heightConstraint]];\n        \n        [self addConstraints:@[\n            [NSLayoutConstraint constraintWithItem:self\n                                         attribute:NSLayoutAttributeTop\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:head\n                                         attribute:NSLayoutAttributeTop\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:self\n                                         attribute:NSLayoutAttributeLeft\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:head\n                                         attribute:NSLayoutAttributeLeft\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:self\n                                         attribute:NSLayoutAttributeRight\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:head\n                                         attribute:NSLayoutAttributeRight\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:head\n                                         attribute:NSLayoutAttributeHeight\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:nil\n                                         attribute:NSLayoutAttributeNotAnAttribute\n                                        multiplier:1\n                                          constant:AMCodeHeaderHeight],\n            [NSLayoutConstraint constraintWithItem:self\n                                         attribute:NSLayoutAttributeLeft\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.textView\n                                         attribute:NSLayoutAttributeLeft\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:self\n                                         attribute:NSLayoutAttributeRight\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.textView\n                                         attribute:NSLayoutAttributeRight\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:self\n                                         attribute:NSLayoutAttributeBottom\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.textView\n                                         attribute:NSLayoutAttributeBottom\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:head\n                                         attribute:NSLayoutAttributeBottom\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.textView\n                                         attribute:NSLayoutAttributeTop\n                                        multiplier:1\n                                          constant:0],\n        ]];\n    }\n    return self;\n}\n\n- (void)dealloc\n{\n    [self.textView removeObserver:self forKeyPath:KEYPATH(self.textView, contentSize)];\n}\n\n- (void)observeValueForKeyPath:(NSString *)keyPath\n                      ofObject:(id)object\n                        change:(NSDictionary<NSKeyValueChangeKey,id> *)change\n                       context:(void *)context\n{\n    if (object == self.textView) {\n        CGSize old = [change[NSKeyValueChangeOldKey] CGSizeValue];\n        CGSize new = [change[NSKeyValueChangeNewKey] CGSizeValue];\n        if (!CGSizeEqualToSize(old, new)) {\n            if(self.partialUpdate)\n            {\n                @weakify(self);\n                dispatch_async(dispatch_get_main_queue(), ^{\n                    @strongify(self);\n                    self.heightConstraint.constant = new.height;\n                    [self.textView removeConstraint:self.heightConstraint];\n                    [self.textView addConstraint:self.heightConstraint];\n                    [self.textView updateConstraintsIfNeeded];\n                    [self.textView layoutIfNeeded];\n                    [self.attachment setNeedsLayout];\n                });\n            }\n            else\n            {\n                if ([self.attachment respondsToSelector:@selector(setNeedsLayout)]) {\n                    self.heightConstraint.constant = new.height;\n                    [self.textView removeConstraint:self.heightConstraint];\n                    [self.textView addConstraint:self.heightConstraint];\n                    [self.textView updateConstraintsIfNeeded];\n                    [self.textView layoutIfNeeded];\n                    [self.attachment setNeedsLayout];\n                }\n            }\n        }\n    }\n}\n\n- (void)_onCopyCode:(id)sender\n{\n    [self didCopyCode:self.textView.attributedText.string ?: self.textView.text];\n}\n\n- (void)setPlainCodeText:(NSString *)codeText\n{\n    self.textView.attributedText = [[NSAttributedString alloc] initWithString:codeText ?: @\"\"\n                                                                   attributes:@{\n        NSFontAttributeName: self.textView.font,\n        NSForegroundColorAttributeName: self.textView.textColor,\n        NSParagraphStyleAttributeName: [NSParagraphStyle paragraphStyleWithCMAttributes:self.styles.codeBlockAttributes.paragraphStyleAttributes],\n    }];\n}\n\n- (void)setLanguage:(nullable NSString *)lang {\n    self.languageLabel.text = lang.length ? lang : @\"文本\";\n}\n\n- (void)setAttributedCodeText:(NSAttributedString *)codeText\n{\n    if (self.partialUpdate) {\n        [self.textView setAttributedTextPartialUpdate_ant_mark:codeText];\n    } else {\n        [self.textView setAttributedText:codeText];\n    }\n    if (codeText.length > 0) {\n//        UIColor *bgColor = [codeText attribute:NSBackgroundColorAttributeName\n//                                       atIndex:0\n//                                effectiveRange:NULL];\n//        if ([bgColor isKindOfClass:[UIColor class]]) {\n//            self.backgroundColor = bgColor;\n//        }\n    }\n    \n    if([NSThread isMainThread])\n    {\n        [self.textView layoutSubviews];\n    }\n}\n\n- (void)didCopyCode:(NSString *)code\n{\n    \n}\n\n+ (CGSize)sizeThatFits:(CGSize)size \n                  code:(NSString *)code\n              language:(NSString *)lang\n                styles:(AMTextStyles *)styles\n{\n    size = [code boundingRectWithSize:CGSizeMake(size.width - AMCodeViewInset.left - AMCodeViewInset.right, size.height)\n                              options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading\n                           attributes:@{\n        NSFontAttributeName: styles.codeBlockAttributes.stringAttributes[NSFontAttributeName] ?: [UIFont fontWithName:@\"Courier\" size:13],\n        NSParagraphStyleAttributeName: [NSParagraphStyle paragraphStyleWithCMAttributes:styles.codeBlockAttributes.paragraphStyleAttributes],\n    } context:nil].size;\n    size.height = ceil(size.height) + AMCodeHeaderHeight + AMCodeViewInset.top + AMCodeViewInset.bottom;\n    return size;\n}\n\n- (CGSize)sizeThatFits:(CGSize)size\n{\n    size = [self.textView.attributedText boundingRectWithSize:CGSizeMake(size.width - AMCodeViewInset.left - AMCodeViewInset.right, size.height)\n                                                      options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading\n                                                      context:nil].size;\n    \n    size.height = ceil(size.height) + AMCodeHeaderHeight + AMCodeViewInset.top + AMCodeViewInset.bottom;\n    if (self.maximumHeight > 0) {\n        size.height = MIN(size.height, self.maximumHeight);\n    }\n    return size;\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMMarkdownTableLayout.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <UIKit/UIKit.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMMarkdownTableLayout : UICollectionViewLayout\n@property (nonatomic) CGFloat minimumLineSpacing;   // Default 1\n@property (nonatomic) CGFloat minimumInteritemSpacing;  // Default 1\n@property (nonatomic) CGSize itemSize;\n\n@property (nonatomic) BOOL fillWidth;               // Default YES\n@property (nonatomic) CGFloat minimumRowHeight;     // Default 35\n@property (nonatomic) CGFloat maximumColumnWidth;   // Default 360\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMMarkdownTableLayout.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMMarkdownTableLayout.h\"\n\n\n@interface AMSizeConstraint : NSObject\n@property (nonatomic) CGSize minSize;\n@property (nonatomic) CGSize maxSize;\n@end\n\n@implementation AMSizeConstraint\n\n- (instancetype)init\n{\n    self = [super init];\n    if (self) {\n        self.minSize = CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX);\n        self.maxSize = CGSizeZero;\n    }\n    return self;\n}\n\n- (void)updateSize:(CGSize)size\n{\n    CGSize s = self.minSize;\n    s.width = MIN(self.minSize.width, size.width);\n    s.height = MIN(self.minSize.height, size.height);\n    self.minSize = s;\n    \n    s = self.maxSize;\n    s.width = MAX(self.maxSize.width, size.width);\n    s.height = MAX(self.maxSize.height, size.height);\n    self.maxSize = s;\n}\n\n- (NSString *)description\n{\n    return [NSString stringWithFormat:@\"min: %@, max: %@\", NSStringFromCGSize(self.minSize), NSStringFromCGSize(self.maxSize)];\n}\n\n@end\n\n\n@implementation AMMarkdownTableLayout\n{\n    NSMutableArray <AMSizeConstraint *> * _columnConstraint;\n    NSMutableArray <AMSizeConstraint *> * _rowConstraint;\n    NSMutableDictionary <NSIndexPath *, NSValue *> * _sizeCache;\n    NSMutableArray <NSArray <UICollectionViewLayoutAttributes *> *> * _allAttributes;\n    CGSize  _contentSize;\n}\n\n- (instancetype)init\n{\n    self = [super init];\n    if (self) {\n        _columnConstraint = [NSMutableArray array];\n        _rowConstraint = [NSMutableArray array];\n        _sizeCache = [NSMutableDictionary dictionary];\n        _allAttributes = [NSMutableArray array];\n        \n        _minimumLineSpacing = 1;\n        _minimumInteritemSpacing = 1;\n        _minimumRowHeight = 35;\n        _maximumColumnWidth = 360;\n        _fillWidth = YES;\n    }\n    return self;\n}\n\n- (void)setMaximumColumnWidth:(CGFloat)maximumColumnWidth\n{\n    if (_maximumColumnWidth != maximumColumnWidth) {\n        _maximumColumnWidth = maximumColumnWidth;\n        [self invalidateLayout];\n    }\n}\n\n- (void)setMinimumRowHeight:(CGFloat)minimumRowHeight\n{\n    if (_minimumRowHeight != _minimumRowHeight) {\n        _minimumRowHeight = minimumRowHeight;\n        [self invalidateLayout];\n    }\n}\n\n- (void)setFillWidth:(BOOL)fillWidth\n{\n    if (_fillWidth != fillWidth) {\n        _fillWidth = fillWidth;\n        [self invalidateLayout];\n    }\n}\n\n- (void)setMinimumLineSpacing:(CGFloat)minimumLineSpacing\n{\n    if (_minimumLineSpacing != minimumLineSpacing) {\n        _minimumLineSpacing = minimumLineSpacing;\n        [self invalidateLayout];\n    }\n}\n\n- (void)setMinimumInteritemSpacing:(CGFloat)minimumInteritemSpacing\n{\n    if (_minimumInteritemSpacing != minimumInteritemSpacing) {\n        _minimumInteritemSpacing = minimumInteritemSpacing;\n        [self invalidateLayout];\n    }\n}\n\n- (void)prepareLayout\n{\n    [super prepareLayout];\n    \n    [_columnConstraint removeAllObjects];\n    [_rowConstraint removeAllObjects];\n    [_sizeCache removeAllObjects];\n    [_allAttributes removeAllObjects];\n    \n    CGSize contentSize = CGSizeZero;\n    \n    NSInteger sections = self.collectionView.numberOfSections;\n    NSInteger columns = 0;\n    for (int s = 0; s < sections; s ++) {\n        NSInteger col = [self.collectionView.dataSource collectionView:self.collectionView numberOfItemsInSection:s];\n        \n        for (int c = 0; c < col; c ++) {\n            NSIndexPath *indexPath = [NSIndexPath indexPathForItem:c inSection:s];\n            CGSize size = [(id<UICollectionViewDelegateFlowLayout>)self.collectionView.delegate collectionView:self.collectionView\n                                                                                                        layout:self\n                                                                                        sizeForItemAtIndexPath:indexPath];\n            _sizeCache[indexPath] = [NSValue valueWithCGSize:size];\n        }\n        \n        if (columns < col) {\n            columns = col;\n        }\n    }\n    \n    CGFloat totalWidth = 0;\n    for (int c = 0; c < columns; c ++) {\n        AMSizeConstraint *constraint = [[AMSizeConstraint alloc] init];\n        for (int s = 0; s < sections; s ++) {\n            NSIndexPath *indexPath = [NSIndexPath indexPathForItem:c inSection:s];\n            CGSize size = _sizeCache[indexPath].CGSizeValue;\n            [constraint updateSize:size];\n        }\n        totalWidth += constraint.maxSize.width + self.minimumInteritemSpacing;\n        [_columnConstraint addObject:constraint];\n    }\n    totalWidth -= self.minimumInteritemSpacing;\n    \n    for (int s = 0; s < sections; s ++) {\n        AMSizeConstraint *constraint = [[AMSizeConstraint alloc] init];\n        for (int c = 0; c < columns; c ++) {\n            NSIndexPath *indexPath = [NSIndexPath indexPathForItem:c inSection:s];\n            CGSize size = _sizeCache[indexPath].CGSizeValue;\n            [constraint updateSize:size];\n        }\n        [_rowConstraint addObject:constraint];\n    }\n    \n    const CGFloat fullWidth = UIEdgeInsetsInsetRect(self.collectionView.bounds, self.collectionView.contentInset).size.width;\n    BOOL ignoreMaxWidth = NO;\n\n    if (totalWidth < fullWidth && self.fillWidth) {\n        ignoreMaxWidth = YES;\n        const CGFloat spacing = self.minimumInteritemSpacing * (columns - 1);\n        for (int c = 0; c < columns; c ++) {\n            AMSizeConstraint *constraint = _columnConstraint[c];\n            CGSize size = constraint.maxSize;\n            size.width = size.width / (totalWidth - spacing) * (fullWidth - spacing);\n            [constraint updateSize:size];\n        }\n    }\n    \n    const CGPoint initialOffset = CGPointZero;\n    CGPoint offset = initialOffset;\n    for (int s = 0; s < sections; s ++) {\n        NSInteger col = [self.collectionView.dataSource collectionView:self.collectionView numberOfItemsInSection:s];\n        AMSizeConstraint *rowConstraint = _rowConstraint[s];\n        const CGFloat height = MAX(rowConstraint.maxSize.height, self.minimumRowHeight);\n        \n        NSMutableArray<UICollectionViewLayoutAttributes *> *arr = [NSMutableArray arrayWithCapacity:columns];\n        for (int c = 0; c < col; c ++) {\n            NSIndexPath *indexPath = [NSIndexPath indexPathForItem:c inSection:s];\n            AMSizeConstraint *colConstraint = _columnConstraint[c];\n            const CGFloat width = MIN(colConstraint.maxSize.width, ignoreMaxWidth ? CGFLOAT_MAX : self.maximumColumnWidth);\n            UICollectionViewLayoutAttributes *attr = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];\n            attr.frame = CGRectMake(offset.x, offset.y, width, height);\n            [arr addObject:attr];\n            \n            offset.x += width + self.minimumInteritemSpacing;\n        }\n        contentSize.width = MAX(contentSize.width, offset.x - self.minimumInteritemSpacing);\n        \n        offset.x = initialOffset.x;\n        offset.y += height + self.minimumLineSpacing;\n        [_allAttributes addObject:arr.copy];\n    }\n    contentSize.height = offset.y - self.minimumLineSpacing;\n    \n    _contentSize = contentSize;\n}\n\n- (NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect\n{\n    NSMutableArray <UICollectionViewLayoutAttributes *> * result = [NSMutableArray array];\n    [_allAttributes enumerateObjectsUsingBlock:^(NSArray<UICollectionViewLayoutAttributes *> * _Nonnull section, NSUInteger idx, BOOL * _Nonnull stop) {\n        [section enumerateObjectsUsingBlock:^(UICollectionViewLayoutAttributes * _Nonnull item, NSUInteger idx, BOOL * _Nonnull stop) {\n            if (CGRectIntersectsRect(rect, item.frame)) {\n                [result addObject:item];\n            }\n        }];\n    }];\n    return [result copy];\n}\n\n- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath\n{\n    return _allAttributes[indexPath.section][indexPath.item];\n}\n\n- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds\n{\n    if (CGSizeEqualToSize(newBounds.size, self.collectionView.bounds.size)) {\n        return NO;\n    }\n    return self.fillWidth;\n}\n\n- (CGSize)collectionViewContentSize\n{\n    CGSize size = _contentSize;\n    return size;\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMMarkdownTableView.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <UIKit/UIKit.h>\n#import <AntMarkdown/AMTableViewAttachment.h>\n\n@class CMTableCell;\n\nNS_ASSUME_NONNULL_BEGIN\n\n@protocol AMMarkdownTableCell <NSObject>\n@property (nonatomic, nullable) CMTableCell *cellData;\n\n+ (CGSize)sizeForCell:(CMTableCell *)cell\n     constrainedWidth:(CGFloat)width;\n\n@end\n\n@interface AMMarkdownLabelTableCell : UICollectionViewCell <AMMarkdownTableCell>\n@property (nonatomic) UILabel * label;\n@property (nonatomic) UIEdgeInsets contentInsets;\n\n+ (CGSize)sizeForCell:(CMTableCell *)cell;\n\n@end\n\n@interface AMMarkdownTableCell : UICollectionViewCell <AMMarkdownTableCell>\n@property (nonatomic) UITextView *textview;\n@property (nonatomic) UIEdgeInsets contentInsets;\n@property (nonatomic) BOOL partialUpdate;\n\n+ (CGSize)sizeForCell:(CMTableCell *)cell;\n\n@end\n\n@interface AMMarkdownTableView : UIView <AMTableView, AMAttachedView>\n@property (nonatomic) CGFloat maximumColumnWidth;\n@property (nonatomic, readonly) UICollectionView *collectionView;\n@property (nonatomic, copy) NSArray<UIView *> *tableOperationViews;\n@property (nonatomic) BOOL partialUpdate;\n\n@property (nonatomic) UIColor *borderColor;\n\n- (instancetype)initWithStyles:(AMTextStyles *)styles NS_DESIGNATED_INITIALIZER;\n\n- (void)didSelectTableCell:(UICollectionView<AMMarkdownTableCell> *)cell content:(CMTableCell *)content;\n\n/**\n * Default is \\c AMMarkdownLabelTableCell\n */\n+ (Class<AMMarkdownTableCell>)cellClass;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMMarkdownTableView.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMMarkdownTableView.h\"\n#import \"AMUtils.h\"\n#import \"CocoaMarkdown.h\"\n#import \"AMGradientView.h\"\n#import \"AMMarkdownTableLayout.h\"\n#import \"AMTextStyles.h\"\n#import \"UILabel+AntMarkdown.h\"\n#import \"UITextView+AntMarkdown.h\"\n#import \"AMMarkDownTableViewBlowUpControllerViewController.h\"\n\nconst CGFloat AMTableHeaderHeight = 39;\nconst CGFloat AMTableMaximumColumnWidth = 300;\nCGFloat AMTableCellMinimumLineSpacing = 0.5;\nCGFloat AMTableCellMinimumInteritemSpacing = 0.5;\nconst CGFloat AMTableMinimumRowHeight = 35;\nUIEdgeInsets AMTableCellInset = {10, 12, 8, 12};\n\n@interface AMTableCellStyles : NSObject\n@property (nonatomic) UIColor *borderColor;\n@property (nonatomic) CGFloat borderWidth;\n@end\n\n@interface AMMarkdownTableDatasource : NSObject <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>\n@property (nonatomic) CMTable *table;\n@property (nonatomic) AMTextStyles *styles;\n@property (nonatomic) BOOL partialUpdate;\n@end\n\n@interface AMMarkdownTableRowBackgroundView : UICollectionReusableView\n\n@end\n\n@interface AMMarkdownTableView() <UICollectionViewDelegate>\n@property (nonatomic) AMMarkdownTableDatasource *dataSource;\n@property (nonatomic) UIView *headerView;\n@property (nonatomic) UIStackView *operationView;\n@property (nonatomic) UILabel *titleView;\n@property (nonatomic) UICollectionView *collectionView;\n@property (nonatomic) AMGradientView *rightGradientView, *leftGradientView;\n@property (nonatomic) AMMarkdownTableLayout *layout;\n@property (nonatomic) AMTextStyles *styles;\n@end\n\n@implementation AMMarkdownTableView\n@synthesize table = _table;\n@synthesize attachment = _attachment;\n\n+ (Class<AMMarkdownTableCell>)cellClass\n{\n    return [AMMarkdownTableCell class];\n}\n- (instancetype)initWithCoder:(NSCoder *)coder\n{\n    self = [self initWithStyles:[AMTextStyles defaultStyles]];\n    if (self) {\n        \n    }\n    return self;\n}\n\n- (instancetype)initWithStyles:(AMTextStyles *)styles\n{\n    self = [super initWithFrame:CGRectMake(0, 0, UIScreen.mainScreen.bounds.size.width, 80)];\n    if (self) {\n        self.backgroundColor = [UIColor whiteColor];\n        self.styles = styles;\n        if (self.styles.tableCellAttributes.stringAttributes[@\"cellPadding\"]) {\n            AMTableCellInset.top = [self.styles.tableCellAttributes.stringAttributes[@\"cellPadding\"] UIEdgeInsetsValue].top;\n            AMTableCellInset.bottom = [self.styles.tableCellAttributes.stringAttributes[@\"cellPadding\"] UIEdgeInsetsValue].bottom;\n            AMTableCellInset.left = [self.styles.tableCellAttributes.stringAttributes[@\"cellPadding\"] UIEdgeInsetsValue].left;\n            AMTableCellInset.right = [self.styles.tableCellAttributes.stringAttributes[@\"cellPadding\"] UIEdgeInsetsValue].right;\n        }\n        if (self.styles.tableAttributes.stringAttributes[@\"rowSpacing\"]) {\n            AMTableCellMinimumLineSpacing = [self.styles.tableAttributes.stringAttributes[@\"rowSpacing\"] floatValue];\n        }\n        if (self.styles.tableAttributes.stringAttributes[@\"columnSpacing\"]) {\n            AMTableCellMinimumInteritemSpacing = [self.styles.tableAttributes.stringAttributes[@\"columnSpacing\"] floatValue];\n        }\n    \n        self.borderColor = self.styles.tableTitleAttributes.stringAttributes[NSBackgroundColorAttributeName] ? : [UIColor colorWithHex_ant_mark:0x1f3b6329];\n        self.layer.borderColor = self.borderColor.CGColor;\n        self.layer.borderWidth = self.styles.tableAttributes.stringAttributes[@\"borderWidth\"] ? [self.styles.tableAttributes.stringAttributes[@\"borderWidth\"] floatValue] : 0;\n        self.layer.cornerRadius = 12;\n        self.layer.masksToBounds = YES;\n        \n        self.dataSource = [[AMMarkdownTableDatasource alloc] init];\n        self.dataSource.styles = self.styles;\n        self.dataSource.partialUpdate = self.partialUpdate;\n        \n        self.headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, AMTableHeaderHeight)];\n        self.headerView.backgroundColor = self.styles.tableTitleAttributes.stringAttributes[NSBackgroundColorAttributeName] ? : [UIColor whiteColor];\n        self.headerView.translatesAutoresizingMaskIntoConstraints = NO;\n        [self.headerView addConstraint:[NSLayoutConstraint constraintWithItem:self.headerView\n                                                                    attribute:NSLayoutAttributeHeight\n                                                                    relatedBy:NSLayoutRelationEqual\n                                                                       toItem:nil\n                                                                    attribute:NSLayoutAttributeNotAnAttribute\n                                                                   multiplier:1\n                                                                     constant:39]];\n        [self addSubview:self.headerView];\n        [self addConstraints:@[\n            [NSLayoutConstraint constraintWithItem:self\n                                         attribute:NSLayoutAttributeLeft\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.headerView\n                                         attribute:NSLayoutAttributeLeft\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:self\n                                         attribute:NSLayoutAttributeTop\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.headerView\n                                         attribute:NSLayoutAttributeTop\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:self\n                                         attribute:NSLayoutAttributeRight\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.headerView\n                                         attribute:NSLayoutAttributeRight\n                                        multiplier:1\n                                          constant:0],\n        ]];\n        \n        self.titleView = [UILabel new];\n        self.titleView.text = @\"表格\";\n        CGFloat titleSize = self.styles.tableTitleAttributes.fontAttributes[UIFontDescriptorSizeAttribute] ? [self.styles.tableTitleAttributes.fontAttributes[UIFontDescriptorSizeAttribute] floatValue]: 13;\n        self.titleView.font = [UIFont boldSystemFontOfSize:titleSize];\n        self.titleView.textColor = self.styles.baseTextAttributes.stringAttributes[NSForegroundColorAttributeName] ?: self.styles.paragraphAttributes.stringAttributes[NSForegroundColorAttributeName];\n        if (self.styles.tableTitleAttributes.stringAttributes[NSForegroundColorAttributeName]) {\n            self.titleView.textColor = self.styles.tableTitleAttributes.stringAttributes[NSForegroundColorAttributeName];\n        }\n        self.titleView.translatesAutoresizingMaskIntoConstraints = NO;\n        [self.headerView addSubview:self.titleView];\n        \n        self.operationView = [[UIStackView alloc] initWithArrangedSubviews:@[]];\n        self.operationView.alignment = UIStackViewAlignmentCenter;\n        self.operationView.axis = UILayoutConstraintAxisHorizontal;\n        self.operationView.distribution = UIStackViewDistributionFillEqually;\n        self.operationView.spacing = 12;\n        self.operationView.translatesAutoresizingMaskIntoConstraints = NO;\n        [self.headerView addSubview:self.operationView];\n        \n        [self.headerView addConstraints:@[\n            [NSLayoutConstraint constraintWithItem:self.headerView\n                                         attribute:NSLayoutAttributeLeft\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.titleView\n                                         attribute:NSLayoutAttributeLeft\n                                        multiplier:1\n                                          constant:-12],\n            [NSLayoutConstraint constraintWithItem:self.headerView\n                                         attribute:NSLayoutAttributeCenterY\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.titleView\n                                         attribute:NSLayoutAttributeCenterY\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:self.titleView\n                                         attribute:NSLayoutAttributeRight\n                                         relatedBy:NSLayoutRelationLessThanOrEqual\n                                            toItem:self.operationView\n                                         attribute:NSLayoutAttributeLeft\n                                        multiplier:1\n                                          constant:10],\n            [NSLayoutConstraint constraintWithItem:self.operationView\n                                         attribute:NSLayoutAttributeTop\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.headerView\n                                         attribute:NSLayoutAttributeTop\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:self.operationView\n                                         attribute:NSLayoutAttributeBottom\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.headerView\n                                         attribute:NSLayoutAttributeBottom\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:self.operationView\n                                         attribute:NSLayoutAttributeRight\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.headerView\n                                         attribute:NSLayoutAttributeRight\n                                        multiplier:1\n                                          constant:-12],\n        ]];\n        \n        UIButton *blowUpButton = [UIButton buttonWithType:UIButtonTypeCustom];\n        blowUpButton.titleLabel.font = [UIFont systemFontOfSize:12];\n        if (self.styles.tableAttributes.stringAttributes[@\"operationIcon\"]) {\n            NSString* iconPath = self.styles.tableAttributes.stringAttributes[@\"operationIcon\"];\n            NSRange iOSRange = [iconPath rangeOfString:@\"/\"];\n            if (iOSRange.location != NSNotFound) {\n                NSString *bundlePart = [iconPath substringToIndex:iOSRange.location];\n                NSString *imagePart = [iconPath substringFromIndex:iOSRange.location + 1];\n                [blowUpButton setImage:[UIImage imageNamed_ant_bundle:bundlePart name:imagePart] forState:UIControlStateNormal];\n            }\n        } else {\n            [blowUpButton setImage:[UIImage imageNamed_ant_mark:@\"blow_up_old\"] forState:UIControlStateNormal];\n        }\n        [blowUpButton addTarget:self action:@selector(_onBlowUp:) forControlEvents:UIControlEventTouchUpInside];\n        blowUpButton.translatesAutoresizingMaskIntoConstraints = NO;\n        [self setTableOperationViews:@[blowUpButton]];\n        \n        self.layout = [[AMMarkdownTableLayout alloc] init];\n        self.layout.minimumLineSpacing = AMTableCellMinimumLineSpacing;\n        self.layout.minimumInteritemSpacing = AMTableCellMinimumInteritemSpacing;\n        self.layout.minimumRowHeight = AMTableMinimumRowHeight;\n        self.layout.itemSize = CGSizeMake(80, 35);\n        \n        self.maximumColumnWidth = 300;\n        \n        self.collectionView = [[UICollectionView alloc] initWithFrame:self.bounds\n                                                 collectionViewLayout:self.layout];\n        [self.collectionView registerClass:[self.class cellClass]\n                forCellWithReuseIdentifier:CLSSTR(AMMarkdownTableCell)];\n        [self.collectionView registerClass:[AMMarkdownTableRowBackgroundView class]\n                forSupplementaryViewOfKind:@\"Background\"\n                       withReuseIdentifier:CLSSTR(AMMarkdownTableRowBackgroundView)];\n        self.collectionView.bounces = NO;\n        self.collectionView.scrollsToTop = NO;\n        self.collectionView.contentInset = UIEdgeInsetsMake(1, 0, 0, 0);\n        self.collectionView.backgroundColor = self.borderColor;\n        self.collectionView.alwaysBounceHorizontal = NO;\n        self.collectionView.alwaysBounceVertical = NO;\n#if __IPHONE_17_4 && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_17_4\n        if (@available(iOS 17.4, *)) {\n            self.collectionView.bouncesHorizontally = NO;\n            self.collectionView.bouncesVertically = NO;\n        } else {\n            // Fallback on earlier versions\n        }\n#endif\n        self.collectionView.delegate = self;\n        self.collectionView.dataSource = self.dataSource;\n        [self addSubview:self.collectionView];\n        self.collectionView.translatesAutoresizingMaskIntoConstraints = NO;\n        \n        self.rightGradientView = [[AMGradientView alloc] init];\n        self.rightGradientView.colors = @[\n            [UIColor colorWithHex_ant_mark:0x201f3b63].transparentColor_ant_mark,\n            [UIColor colorWithHex_ant_mark:0x201f3b63],\n        ];\n        self.rightGradientView.layer.actions = @{\n            KEYPATH(CALayer *, opacity): [NSNull null],\n            KEYPATH(CALayer *, hidden): [NSNull null],\n        };\n        self.rightGradientView.hidden = YES;\n        self.rightGradientView.translatesAutoresizingMaskIntoConstraints = NO;\n        [self addSubview:self.rightGradientView];\n        \n        self.leftGradientView = [[AMGradientView alloc] init];\n        self.leftGradientView.colors = @[\n            [UIColor colorWithHex_ant_mark:0x201f3b63],\n            [UIColor colorWithHex_ant_mark:0x201f3b63].transparentColor_ant_mark,\n        ];\n        self.leftGradientView.layer.actions = @{\n            KEYPATH(CALayer *, opacity): [NSNull null],\n            KEYPATH(CALayer *, hidden): [NSNull null],\n        };\n        self.leftGradientView.hidden = YES;\n        self.leftGradientView.translatesAutoresizingMaskIntoConstraints = NO;\n        [self addSubview:self.leftGradientView];\n        \n        [self addConstraints:@[\n            [NSLayoutConstraint constraintWithItem:self.collectionView\n                                         attribute:NSLayoutAttributeLeft\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.collectionView.superview\n                                         attribute:NSLayoutAttributeLeft\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:self.collectionView\n                                         attribute:NSLayoutAttributeRight\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.collectionView.superview\n                                         attribute:NSLayoutAttributeRight\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:self.collectionView\n                                         attribute:NSLayoutAttributeTop\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.headerView\n                                         attribute:NSLayoutAttributeBottom\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:self.collectionView\n                                         attribute:NSLayoutAttributeBottom\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.collectionView.superview\n                                         attribute:NSLayoutAttributeBottom\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:self.collectionView\n                                         attribute:NSLayoutAttributeRight\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.rightGradientView\n                                         attribute:NSLayoutAttributeRight\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:self.rightGradientView\n                                         attribute:NSLayoutAttributeTop\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.collectionView\n                                         attribute:NSLayoutAttributeTop\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:self.rightGradientView\n                                         attribute:NSLayoutAttributeBottom\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.collectionView\n                                         attribute:NSLayoutAttributeBottom\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:self.rightGradientView\n                                         attribute:NSLayoutAttributeWidth\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:nil\n                                         attribute:NSLayoutAttributeNotAnAttribute\n                                        multiplier:1\n                                          constant:18],\n            [NSLayoutConstraint constraintWithItem:self.collectionView\n                                         attribute:NSLayoutAttributeLeft\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.leftGradientView\n                                         attribute:NSLayoutAttributeLeft\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:self.leftGradientView\n                                         attribute:NSLayoutAttributeTop\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.collectionView\n                                         attribute:NSLayoutAttributeTop\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:self.leftGradientView\n                                         attribute:NSLayoutAttributeBottom\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.collectionView\n                                         attribute:NSLayoutAttributeBottom\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:self.leftGradientView\n                                         attribute:NSLayoutAttributeWidth\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:nil\n                                         attribute:NSLayoutAttributeNotAnAttribute\n                                        multiplier:1\n                                          constant:18],\n        ]];\n        \n        [self.collectionView addObserver:self\n                              forKeyPath:KEYPATH(self.collectionView, contentSize)\n                                 options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld\n                                 context:nil];\n        [self scrollViewDidScroll:self.collectionView];\n    }\n    return self;\n}\n\n- (instancetype)initWithFrame:(CGRect)frame\n{\n    return [self initWithStyles:[AMTextStyles defaultStyles]];\n}\n\n- (void)_onBlowUp:(id)sender {\n    UIResponder *responder = self;\n    UIViewController *vc = nil;\n    while (responder) {\n        if ([responder isKindOfClass:[UIViewController class]]) {\n            vc = (UIViewController *)responder;\n            break;\n        }\n        responder = [responder nextResponder];\n    }\n    if (vc) {\n        AMMarkDownTableViewBlowUpControllerViewController *tableVC = [[AMMarkDownTableViewBlowUpControllerViewController alloc] init];\n        tableVC.styles = self.styles;\n        tableVC.table = self.table;\n        tableVC.partialUpdate = self.partialUpdate;\n        tableVC.collectionSize = self.collectionView.bounds.size;\n        tableVC.modalPresentationStyle = UIModalPresentationFullScreen;\n        [vc presentViewController:tableVC animated:NO completion:nil];\n    }\n}\n\n- (void)dealloc\n{\n    [self.collectionView removeObserver:self\n                             forKeyPath:KEYPATH(self.collectionView, contentSize)];\n}\n\n- (void)setPartialUpdate:(BOOL)partialUpdate\n{\n    _partialUpdate = partialUpdate;\n    self.dataSource.partialUpdate = partialUpdate;\n}\n\n- (void)removeFromSuperview\n{\n    [super removeFromSuperview];\n}\n\n- (void)observeValueForKeyPath:(NSString *)keyPath\n                      ofObject:(id)object\n                        change:(NSDictionary<NSKeyValueChangeKey,id> *)change\n                       context:(void *)context\n{\n    if (object == self.collectionView) {\n        CGSize oldSize = [change[NSKeyValueChangeOldKey] CGSizeValue];\n        CGSize newSize = [change[NSKeyValueChangeNewKey] CGSizeValue];\n        \n        self.rightGradientView.hidden = self.leftGradientView.hidden = newSize.width < self.collectionView.bounds.size.width + 1;\n        if (!self.rightGradientView.isHidden) {\n            [self scrollViewDidScroll:self.collectionView];\n        }\n        \n        if (!CGSizeEqualToSize(oldSize, newSize)) {\n            if ([self.attachment respondsToSelector:@selector(setNeedsLayout)]) {\n                [self.attachment setNeedsLayout];\n            }\n        }\n    }\n}\n\n- (void)setTableOperationViews:(NSArray<UIView *> *)tableOperationViews\n{\n    if (![_tableOperationViews isEqualToArray:tableOperationViews]) {\n        _tableOperationViews = tableOperationViews;\n        [self.operationView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];\n        [tableOperationViews enumerateObjectsUsingBlock:^(UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {\n            [self.operationView addArrangedSubview:obj];\n        }];\n    }\n}\n\n- (void)setBorderColor:(UIColor *)borderColor\n{\n    _borderColor = borderColor;\n    self.collectionView.backgroundColor = borderColor;\n}\n\n- (void)setTable:(CMTable *)table\n{\n    if (![_table isEqualToTable:table]) {\n        _table = table;\n        self.dataSource.table = table;\n        [self invalidateIntrinsicContentSize];\n        [self setNeedsLayout];\n        [self.collectionView reloadData];\n    }\n}\n\n- (void)setMaximumColumnWidth:(CGFloat)maximumColumnWidth\n{\n    _maximumColumnWidth = maximumColumnWidth;\n    self.layout.maximumColumnWidth = maximumColumnWidth;\n}\n\n- (void)didSelectTableCell:(UICollectionView<AMMarkdownTableCell> *)cell content:(CMTableCell *)content\n{\n    \n}\n\n- (CGSize)sizeThatFits:(CGSize)size {\n    [self.collectionView layoutIfNeeded];\n    CGSize contentSize = self.layout.collectionViewContentSize;\n    size.width = MIN(size.width, contentSize.width + self.collectionView.contentInset.left + self.collectionView.contentInset.right);\n    size.height = contentSize.height + self.headerView.bounds.size.height + self.collectionView.contentInset.top + self.collectionView.contentInset.bottom;\n    return size;\n}\n\n+ (CGSize)sizeThatFits:(CGSize)size table:(CMTable *)table styles:(AMTextStyles *)styles\n{\n    size.height = AMTableHeaderHeight;\n    for (int row = 0; row < table.numberOfRows; row ++) {\n        CGFloat height = AMTableMinimumRowHeight;\n        for (int col = 0; col < table.numberOfColumns; col ++) {\n            CMTableCell *cell = [table cellAtIndexPath:[NSIndexPath indexPathForItem:col inSection:row]];\n            CGFloat constraintWidth = AMTableMaximumColumnWidth;\n            if (col == 0) {\n                if ([styles.tableCellAttributes.stringAttributes objectForKey:@\"firstMaxWidth\"]) {\n                    constraintWidth = [styles.tableCellAttributes.stringAttributes[@\"firstMaxWidth\"] floatValue];\n                }\n            } else {\n                if ([styles.tableCellAttributes.stringAttributes objectForKey:@\"defaultMaxWidth\"]) {\n                    constraintWidth = [styles.tableCellAttributes.stringAttributes[@\"defaultMaxWidth\"] floatValue];\n                }\n            }\n            CGSize cellSize = [AMMarkdownTableCell sizeForCell:cell constrainedWidth:constraintWidth];\n            height = MAX(height, cellSize.height);\n        }\n        size.height += height;\n    }\n    size.height += AMTableCellMinimumLineSpacing * (table.numberOfRows - 1);\n    return size;\n}\n\n- (void)scrollViewDidScroll:(UIScrollView *)scrollView\n{\n    if (scrollView.contentOffset.x + scrollView.bounds.size.width >= scrollView.contentSize.width - 1) {\n        if (![self.rightGradientView.layer animationForKey:@\"Fadeout\"]) {\n            CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:KEYPATH(self.rightGradientView.layer, opacity)];\n            anim.duration = 0.15;\n            anim.toValue = @0;\n            anim.fillMode = kCAFillModeBoth;\n            anim.removedOnCompletion = NO;\n            [self.rightGradientView.layer addAnimation:anim forKey:@\"Fadeout\"];\n        }\n        self.rightGradientView.alpha = 0;\n    } else {\n        if ([self.rightGradientView.layer animationForKey:@\"Fadeout\"]) {\n            [self.rightGradientView.layer removeAnimationForKey:@\"Fadeout\"];\n            if (scrollView.isDragging) {\n                CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:KEYPATH(self.rightGradientView.layer, opacity)];\n                anim.duration = 0.15;\n                anim.fromValue = @0;\n                anim.removedOnCompletion = YES;\n                [self.rightGradientView.layer addAnimation:anim forKey:@\"Fadein\"];\n            }\n        }\n        self.rightGradientView.alpha = 1;\n    }\n    \n    if (scrollView.contentOffset.x < 1) {\n        if (![self.leftGradientView.layer animationForKey:@\"Fadeout\"]) {\n            CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:KEYPATH(self.leftGradientView.layer, opacity)];\n            anim.duration = 0.15;\n            anim.toValue = @0;\n            anim.fillMode = kCAFillModeBoth;\n            anim.removedOnCompletion = NO;\n            [self.leftGradientView.layer addAnimation:anim forKey:@\"Fadeout\"];\n        }\n        self.leftGradientView.alpha = 0;\n    } else {\n        if ([self.leftGradientView.layer animationForKey:@\"Fadeout\"]) {\n            [self.leftGradientView.layer removeAnimationForKey:@\"Fadeout\"];\n            if (scrollView.isDragging) {\n                CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:KEYPATH(self.leftGradientView.layer, opacity)];\n                anim.duration = 0.15;\n                anim.fromValue = @0;\n                anim.removedOnCompletion = YES;\n                [self.leftGradientView.layer addAnimation:anim forKey:@\"Fadein\"];\n            }\n        }\n        self.leftGradientView.alpha = 1;\n    }\n}\n\n- (CGSize)collectionView:(UICollectionView *)collectionView\n                  layout:(UICollectionViewLayout*)collectionViewLayout\n  sizeForItemAtIndexPath:(NSIndexPath *)indexPath\n{\n    CMTableCell *cellData = [self.table cellAtIndexPath:indexPath];\n    CGFloat constraintWidth = self.maximumColumnWidth;\n    if (indexPath.row == 0) {\n        if ([self.styles.tableCellAttributes.stringAttributes objectForKey:@\"firstMaxWidth\"]) {\n            constraintWidth = [self.styles.tableCellAttributes.stringAttributes[@\"firstMaxWidth\"] floatValue];\n        }\n    } else {\n        if ([self.styles.tableCellAttributes.stringAttributes objectForKey:@\"defaultMaxWidth\"]) {\n            constraintWidth = [self.styles.tableCellAttributes.stringAttributes[@\"defaultMaxWidth\"] floatValue];\n        }\n    }\n    return [[self.class cellClass] sizeForCell:cellData constrainedWidth:constraintWidth];\n}\n\n- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView\n                        layout:(UICollectionViewLayout*)collectionViewLayout\n        insetForSectionAtIndex:(NSInteger)section\n{\n    return UIEdgeInsetsZero;\n}\n\n- (CGFloat)collectionView:(UICollectionView *)collectionView\n                   layout:(UICollectionViewLayout*)collectionViewLayout\nminimumLineSpacingForSectionAtIndex:(NSInteger)section\n{\n    return 2;\n}\n\n- (CGFloat)collectionView:(UICollectionView *)collectionView\n                   layout:(UICollectionViewLayout*)collectionViewLayout\nminimumInteritemSpacingForSectionAtIndex:(NSInteger)section\n{\n    return 2;\n}\n\n- (CGSize)collectionView:(UICollectionView *)collectionView\n                  layout:(UICollectionViewLayout*)collectionViewLayout\nreferenceSizeForHeaderInSection:(NSInteger)section\n{\n    return CGSizeZero;\n}\n\n- (CGSize)collectionView:(UICollectionView *)collectionView\n                  layout:(UICollectionViewLayout*)collectionViewLayout\nreferenceSizeForFooterInSection:(NSInteger)section\n{\n    return CGSizeZero;\n}\n\n- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath\n{\n    UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];\n    CMTableCell *cellData = [self.table cellAtIndexPath:indexPath];\n    [collectionView deselectItemAtIndexPath:indexPath animated:NO];\n    [self didSelectTableCell:(UICollectionView<AMMarkdownTableCell> *)cell\n                     content:cellData];\n}\n\n@end\n\n@implementation AMMarkdownLabelTableCell\n@synthesize cellData = _cellData;\n\n+ (CGSize)sizeForCell:(CMTableCell *)cell\n{\n    return [self sizeForCell:cell constrainedWidth:CGFLOAT_MAX];\n}\n\n+ (CGSize)sizeForCell:(CMTableCell *)cell constrainedWidth:(CGFloat)width\n{\n    static dispatch_once_t onceToken;\n    static AMMarkdownLabelTableCell *view = nil;\n    dispatch_once(&onceToken, ^{\n        view = [[AMMarkdownLabelTableCell alloc] initWithFrame:CGRectZero];\n    });\n    view.label.preferredMaxLayoutWidth = width;\n    [view.label setAttributedText_ant_mark:cell.content];\n    return [view systemLayoutSizeFittingSize:CGSizeMake(width, CGFLOAT_MAX)\n               withHorizontalFittingPriority:UILayoutPriorityFittingSizeLevel\n                     verticalFittingPriority:UILayoutPriorityFittingSizeLevel];\n}\n\n- (instancetype)initWithFrame:(CGRect)frame\n{\n    self = [super initWithFrame:frame];\n    if (self) {\n        self.contentInsets = UIEdgeInsetsMake(4, 12, 4, 12);\n        \n        self.label = [[UILabel alloc] initWithFrame:self.bounds];\n        self.label.font = [UIFont systemFontOfSize:14];\n        self.label.numberOfLines = 0;\n        [self.contentView addSubview:self.label];\n        \n        self.label.translatesAutoresizingMaskIntoConstraints = NO;\n        [self updateConstraintsIfNeeded];\n    }\n    return self;\n}\n\n- (void)setCellData:(CMTableCell *)cellData\n{\n    if (_cellData != cellData) {\n        _cellData = cellData;\n        \n        self.label.textAlignment = cellData.alignment;\n        [self.label setAttributedText_ant_mark:cellData.content];\n    }\n}\n\n- (void)setContentInsets:(UIEdgeInsets)contentInsets {\n    if (!UIEdgeInsetsEqualToEdgeInsets(_contentInsets, contentInsets)) {\n        _contentInsets = contentInsets;\n        [self setNeedsUpdateConstraints];\n    }\n}\n\n- (void)updateConstraints\n{\n    [self.contentView removeConstraints:[self.contentView constraints]];\n    [self.contentView addConstraints:@[\n        [NSLayoutConstraint constraintWithItem:self.label\n                                     attribute:NSLayoutAttributeLeft\n                                     relatedBy:NSLayoutRelationEqual\n                                        toItem:self.label.superview\n                                     attribute:NSLayoutAttributeLeft\n                                    multiplier:1\n                                      constant:self.contentInsets.left],\n        [NSLayoutConstraint constraintWithItem:self.label\n                                     attribute:NSLayoutAttributeRight\n                                     relatedBy:NSLayoutRelationEqual\n                                        toItem:self.label.superview\n                                     attribute:NSLayoutAttributeRight\n                                    multiplier:1\n                                      constant:-self.contentInsets.right],\n        [NSLayoutConstraint constraintWithItem:self.label\n                                     attribute:NSLayoutAttributeTop\n                                     relatedBy:NSLayoutRelationEqual\n                                        toItem:self.label.superview\n                                     attribute:NSLayoutAttributeTop\n                                    multiplier:1\n                                      constant:self.contentInsets.top],\n        [NSLayoutConstraint constraintWithItem:self.label\n                                     attribute:NSLayoutAttributeBottom\n                                     relatedBy:NSLayoutRelationEqual\n                                        toItem:self.label.superview\n                                     attribute:NSLayoutAttributeBottom\n                                    multiplier:1\n                                      constant:-self.contentInsets.bottom],\n    ]];\n    \n    [super updateConstraints];\n}\n\n@end\n\n\n@implementation AMMarkdownTableCell\n@synthesize cellData = _cellData;\n\n+ (CGSize)sizeForCell:(CMTableCell *)cell\n{\n    return [self sizeForCell:cell constrainedWidth:CGFLOAT_MAX];\n}\n\n+ (CGSize)sizeForCell:(CMTableCell *)cell constrainedWidth:(CGFloat)width\n{\n    const CGFloat paddingHorizontal = AMTableCellInset.left + AMTableCellInset.right;\n    const CGFloat paddingVertical = AMTableCellInset.top + AMTableCellInset.bottom;\n    CGSize size = CGRectIntegral([cell.content boundingRectWithSize:CGSizeMake(width - paddingHorizontal, CGFLOAT_MAX)\n                                                            options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading\n                                                            context:nil]).size;\n    \n    CGSize size2 = CGRectIntegral([cell.content boundingRectWithSize:CGSizeMake(width - paddingHorizontal, CGFLOAT_MAX)\n                                                            options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesDeviceMetrics\n                                                            context:nil]).size;\n\n    return CGSizeMake(MIN(width, size.width + paddingHorizontal), MAX(size.height, size2.height) + paddingVertical);\n}\n\n- (instancetype)initWithFrame:(CGRect)frame\n{\n    self = [super initWithFrame:frame];\n    if (self) {\n        self.textview = [[UITextView alloc] initWithFrame_ant_mark:UIEdgeInsetsInsetRect(self.bounds, self.contentInsets)];\n        self.textview.font = [UIFont systemFontOfSize:14];\n        self.textview.scrollEnabled = YES;\n        self.textview.selectable = NO;\n        self.textview.editable = NO;\n        self.textview.backgroundColor = [UIColor clearColor];\n        self.textview.textContainerInset = UIEdgeInsetsZero;\n        self.textview.textContainer.lineFragmentPadding = 0;\n        [self.contentView addSubview:self.textview];\n        \n        self.textview.translatesAutoresizingMaskIntoConstraints = NO;\n        [self.contentView addConstraints:@[\n            [NSLayoutConstraint constraintWithItem:self.textview\n                                         attribute:NSLayoutAttributeLeft\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.textview.superview\n                                         attribute:NSLayoutAttributeLeft\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:self.textview\n                                         attribute:NSLayoutAttributeRight\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.textview.superview\n                                         attribute:NSLayoutAttributeRight\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:self.textview\n                                         attribute:NSLayoutAttributeTop\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.textview.superview\n                                         attribute:NSLayoutAttributeTop\n                                        multiplier:1\n                                          constant:0],\n            [NSLayoutConstraint constraintWithItem:self.textview\n                                         attribute:NSLayoutAttributeBottom\n                                         relatedBy:NSLayoutRelationEqual\n                                            toItem:self.textview.superview\n                                         attribute:NSLayoutAttributeBottom\n                                        multiplier:1\n                                          constant:0],\n        ]];\n        \n        self.contentInsets = AMTableCellInset;\n        \n        \n        [NSNotificationCenter.defaultCenter addObserver:self\n                                               selector:@selector(onSizeUpdate:)\n                                                   name:AMTextAttachmentSizeDidUpdateNotification\n                                                 object:nil];\n    }\n    return self;\n}\n\n- (void)dealloc\n{\n    [NSNotificationCenter.defaultCenter removeObserver:self];\n}\n\n- (void)onSizeUpdate:(NSNotification *)noti\n{\n    if ([noti.object isKindOfClass:[NSAttributedString class]]) {\n        NSAttributedString *attri = (NSAttributedString *)noti.object;\n        if ([attri.string isEqual:self.cellData.content.string]) {\n            UICollectionView *collectionView = (UICollectionView *)self.superview;\n            while (![collectionView isKindOfClass:[UICollectionView class]]) {\n                collectionView = (UICollectionView *)collectionView.superview;\n            }\n            if ([collectionView isKindOfClass:[UICollectionView class]]) {\n                NSIndexPath *indexPath = [collectionView indexPathForCell:self];\n                UICollectionViewLayoutInvalidationContext *context = [[UICollectionViewLayoutInvalidationContext alloc] init];\n                if (indexPath) {\n                    [context invalidateItemsAtIndexPaths:@[indexPath]];\n                } else {\n                    \n                }\n                \n                [collectionView.collectionViewLayout invalidateLayout];\n            }\n        }\n    }\n}\n\n- (void)prepareForReuse\n{\n    [super prepareForReuse];\n    \n    self.textview.attributedText = nil;\n}\n\n- (void)setCellData:(CMTableCell *)cellData\n{\n    if (_cellData != cellData || (!self.textview.attributedText || [self.textview.attributedText length] <= 0)) {\n        _cellData = cellData;\n        \n        self.textview.textAlignment = cellData.alignment;\n        if (self.partialUpdate) {\n            [self.textview setAttributedTextPartialUpdate_ant_mark:cellData.content];\n        } else {\n            [self.textview setAttributedText_ant_mark:cellData.content];\n        }\n    }\n}\n\n- (void)setContentInsets:(UIEdgeInsets)contentInsets {\n    if (!UIEdgeInsetsEqualToEdgeInsets(_contentInsets, contentInsets)) {\n        _contentInsets = contentInsets;\n        self.textview.textContainerInset = contentInsets;\n    }\n}\n\n@end\n\n@implementation AMMarkdownTableDatasource\n\n- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {\n    return self.table.numberOfColumns;\n}\n\n// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:\n- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {\n    UICollectionViewCell<AMMarkdownTableCell> *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CLSSTR(AMMarkdownTableCell)\n                                                                                                forIndexPath:indexPath];\n    CMTableCell *cellData = [self.table cellAtIndexPath:indexPath];\n    cell.cellData = cellData;\n    if ([cell isKindOfClass:[AMMarkdownTableCell class]]) {\n        ((AMMarkdownTableCell *)cell).partialUpdate = self.partialUpdate;\n    }\n    cell.backgroundColor = [UIColor whiteColor];\n    cell.contentView.backgroundColor = [UIColor clearColor];\n    if ([self.table isHeaderAtIndexPath:indexPath]) {\n        UIColor *color = self.styles.tableHeaderAttributes.stringAttributes[@\"contentBgColor\"] ?: [UIColor colorWithHex_ant_mark:0x141f3b63];\n        if ([color isKindOfClass:[UIColor class]]) {\n            cell.contentView.backgroundColor = color;\n        }\n    } else {\n        UIColor *color = self.styles.tableCellAttributes.stringAttributes[@\"contentBgColor\"];\n        if ([color isKindOfClass:[UIColor class]]) {\n            cell.contentView.backgroundColor = color;\n        }\n    }\n    return cell;\n}\n\n- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {\n    return self.table.numberOfRows;\n}\n\n// The view that is returned must be retrieved from a call to -dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:\n- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView \n           viewForSupplementaryElementOfKind:(NSString *)kind\n                                 atIndexPath:(NSIndexPath *)indexPath {\n    if ([kind isEqualToString:@\"Background\"]) {\n        AMMarkdownTableRowBackgroundView *view = [collectionView dequeueReusableSupplementaryViewOfKind:kind\n                                                                                    withReuseIdentifier:CLSSTR(AMMarkdownTableRowBackgroundView)\n                                                                                           forIndexPath:indexPath];\n        return view;\n    }\n    return nil;\n}\n\n@end\n\n@implementation AMMarkdownTableRowBackgroundView\n\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMTableViewAttachment.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <AntMarkdown/AMViewAttachment.h>\n\n@class CMTable;\n@class AMTextStyles;\n\nNS_ASSUME_NONNULL_BEGIN\n\n@protocol AMTableView <NSObject>\n@property (nonatomic) CMTable *table;\n\n@optional\n- (instancetype)initWithStyles:(AMTextStyles *)styles;\n\n+ (CGSize)sizeThatFits:(CGSize)size table:(CMTable *)table styles:(AMTextStyles *)styles;\n\n@end\n\n@interface AMTableViewAttachment : AMViewAttachment\n@property (nonatomic, readonly, nullable) UIView<AMTableView> *view;\n@property (nonatomic) BOOL partialUpdate;\n@property (nonatomic) CMTable *table;\n@property (nonatomic, readonly, nullable) AMTextStyles *styles;\n\n+ (Class<AMTableView>)tableViewClass;    // Default is AMMarkdownTableView\n\n- (instancetype)initWithTable:(CMTable *)table styles:(AMTextStyles *)styles;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMTableViewAttachment.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMTableViewAttachment.h\"\n#import \"AMMarkdownTableView.h\"\n#import \"AMTextStyles.h\"\n\n@implementation AMTableViewAttachment\n{\n    UIView<AMTableView> * _tableView;\n}\n\n+ (Class)tableViewClass\n{\n    return [AMMarkdownTableView class];\n}\n\n- (instancetype)initWithTable:(nonnull CMTable *)table styles:(nonnull AMTextStyles *)styles {\n    self = [super init];\n    if (self) {\n        self.table = table;\n        _styles = styles;\n    }\n    return self;\n}\n\n- (UIView<AMTableView> *)view {\n    if (!_tableView) {\n        Class cls = [self.class tableViewClass];\n        if ([cls instancesRespondToSelector:@selector(initWithStyles:)]) {\n            _tableView = [[cls alloc] initWithStyles:_styles ?: [AMTextStyles defaultStyles]];\n        } else {\n            _tableView = [[cls alloc] initWithFrame:CGRectZero];\n        }\n        NSAssert([_tableView conformsToProtocol:@protocol(AMTableView)], @\"Class %@ must confirms to AMTableView\", cls);\n        _tableView.table = self.table;\n    }\n    return _tableView;\n}\n\n- (__kindof UIView<AMAttachedView> *)viewIfLoaded\n{\n    return _tableView;\n}\n\n- (void)setTable:(CMTable *)table\n{\n    _table = table;\n    _tableView.table = table;\n}\n\n- (CGSize)sizeThatFits:(CGSize)size\n{\n    if ([NSThread isMainThread] && [self viewIfLoaded]) {\n        return [self.view sizeThatFits:size];\n    } else {\n        Class cls = [self.class tableViewClass];\n        if ([cls respondsToSelector:@selector(sizeThatFits:table:styles:)]) {\n            return [cls sizeThatFits:size table:self.table styles:_styles];\n        } else {\n            return [self.view sizeThatFits:size];\n        }\n    }\n}\n\n- (BOOL)isEqualToAttachment:(AMTableViewAttachment *)attach\n{\n    return [self.styles isEqual:attach.styles] && [self.table isEqual:attach.table];\n}\n\n- (void)updateAttachmentFromAttachment:(AMTableViewAttachment *)attach\n{\n    [super updateAttachmentFromAttachment:attach];\n    self.partialUpdate = YES;\n    if ([_tableView isKindOfClass:[AMMarkdownTableView class]]) {\n        ((AMMarkdownTableView *)_tableView).partialUpdate = self.partialUpdate;\n    }\n    self.table = attach.table;\n}\n- (NSAttributedString *)attributedString {\n    NSMutableAttributedString *attr = [[NSAttributedString attributedStringWithAttachment:self] mutableCopy];\n    if (self.fullWidth) {\n        NSParagraphStyle *paragraph = ({\n            NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];\n            style.paragraphSpacing = _styles.tableAttributes.paragraphStyleAttributes[CMParagraphStyleAttributeParagraphSpacing] ?  [_styles.tableAttributes.paragraphStyleAttributes[CMParagraphStyleAttributeParagraphSpacing] floatValue] : 0;\n            style.paragraphSpacingBefore = _styles.tableAttributes.paragraphStyleAttributes[CMParagraphStyleAttributeParagraphSpacingBefore] ?  [_styles.tableAttributes.paragraphStyleAttributes[CMParagraphStyleAttributeParagraphSpacingBefore] floatValue] : 10;\n            style.lineSpacing = 0;\n            style.lineHeightMultiple = 1;\n            style.lineBreakStrategy = NSLineBreakStrategyPushOut;\n            style.firstLineHeadIndent = 0;\n            style;\n        });\n        [attr appendAttributedString:[[NSAttributedString alloc] initWithString:@\"\\n\"]];\n        [attr addAttribute:NSParagraphStyleAttributeName value:paragraph range:NSMakeRange(0, attr.length)];\n    }\n    return [attr copy];\n}\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMTextBackground.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n#import <AntMarkdown/AMDrawable.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMBorder : NSObject\n@property (nonatomic) CGFloat borderWidth;\n@property (nonatomic) UIColor * borderColor;\n@property (nonatomic) CGLineCap lineCap;\n\n- (BOOL)isEqualToBorder:(AMBorder *)border;\n\n@end\n\n@interface AMTextBackground : NSObject <AMDrawable>\n@property (nonatomic) BOOL isInline;\n@property (nonatomic, nullable) UIColor *backgroundColor;\n@property (nonatomic) CGFloat cornerRadius;\n@property (nonatomic) UIEdgeInsets contentInset;\n@property (nonatomic, nullable) AMBorder *leftBorder, *rightBorder, *topBorder, *bottomBorder;\n@property (nonatomic, assign) BOOL isQuote;\n\n- (BOOL)isEqualToBackground:(AMTextBackground *)background;\n\n+ (instancetype)leftBorderColor:(UIColor *)color width:(CGFloat)width;\n+ (instancetype)topBorderColor:(UIColor *)color width:(CGFloat)width;\n+ (instancetype)rightBorderColor:(UIColor *)color width:(CGFloat)width;\n+ (instancetype)bottomBorderColor:(UIColor *)color width:(CGFloat)width;\n\n+ (instancetype)leftColor:(UIColor * _Nullable)leftColor leftWidth:(CGFloat)leftWidth\n                 topColor:(UIColor * _Nullable)topColor topWidth:(CGFloat)topWidth\n               rightColor:(UIColor * _Nullable)rightColor rightWidth:(CGFloat)rightWidth\n              bottomColor:(UIColor * _Nullable)bottomColor bottomWidth:(CGFloat)bottomWidth;\n\n+ (instancetype)backgroundWithColor:(UIColor *)color radius:(CGFloat)radius;\n+ (instancetype)backgroundWithColor:(UIColor *)color radius:(CGFloat)radius insets:(UIEdgeInsets)insets;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMTextBackground.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMTextBackground.h\"\n\n@implementation AMBorder\n\n- (instancetype)init\n{\n    self = [super init];\n    if (self) {\n        self.lineCap = kCGLineCapButt;\n    }\n    return self;\n}\n\n- (BOOL)isEqual:(nullable id)object {\n    if (object == nil) {\n        return NO;\n    }\n    \n    if (self == object) {\n        return YES;\n    }\n    \n    if (![object isKindOfClass:[self class]]) {\n        return NO;\n    }\n    \n    return [self isEqualToBorder:(AMBorder *)object];\n}\n\n- (BOOL)isEqualToBorder:(AMBorder *)border\n{\n    return self.borderWidth == border.borderWidth\n    && [self.borderColor isEqual:border.borderColor]\n    && self.lineCap == border.lineCap;\n}\n\n@end\n\n@implementation AMTextBackground\n\n+ (instancetype)leftBorderColor:(UIColor *)color width:(CGFloat)width\n{\n    AMTextBackground *b = [self new];\n    b.leftBorder = ({\n        AMBorder *d = [AMBorder new];\n        d.borderColor = color;\n        d.borderWidth = width;\n        d;\n    });\n    return b;\n}\n\n+ (instancetype)topBorderColor:(UIColor *)color width:(CGFloat)width\n{\n    AMTextBackground *b = [self new];\n    b.topBorder = ({\n        AMBorder *d = [AMBorder new];\n        d.borderColor = color;\n        d.borderWidth = width;\n        d;\n    });\n    return b;\n}\n\n+ (instancetype)rightBorderColor:(UIColor *)color width:(CGFloat)width\n{\n    AMTextBackground *b = [self new];\n    b.rightBorder = ({\n        AMBorder *d = [AMBorder new];\n        d.borderColor = color;\n        d.borderWidth = width;\n        d;\n    });\n    return b;\n}\n\n+ (instancetype)bottomBorderColor:(UIColor *)color width:(CGFloat)width\n{\n    AMTextBackground *b = [self new];\n    b.bottomBorder = ({\n        AMBorder *d = [AMBorder new];\n        d.borderColor = color;\n        d.borderWidth = width;\n        d;\n    });\n    return b;\n}\n\n+ (instancetype)leftColor:(UIColor *)leftColor\n                leftWidth:(CGFloat)leftWidth\n                 topColor:(UIColor *)topColor\n                 topWidth:(CGFloat)topWidth\n               rightColor:(UIColor *)rightColor\n               rightWidth:(CGFloat)rightWidth\n              bottomColor:(UIColor *)bottomColor\n              bottomWidth:(CGFloat)bottomWidth\n{\n    AMTextBackground *b = [self new];\n    if (leftWidth > 0) {\n        b.leftBorder = ({\n            AMBorder *d = [AMBorder new];\n            d.borderColor = leftColor;\n            d.borderWidth = leftWidth;\n            d;\n        });\n    }\n    if (topWidth > 0) {\n        b.topBorder = ({\n            AMBorder *d = [AMBorder new];\n            d.borderColor = topColor;\n            d.borderWidth = topWidth;\n            d;\n        });\n    }\n    if (rightWidth > 0) {\n        b.rightBorder = ({\n            AMBorder *d = [AMBorder new];\n            d.borderColor = rightColor;\n            d.borderWidth = rightWidth;\n            d;\n        });\n    }\n    if (bottomWidth > 0) {\n        b.bottomBorder = ({\n            AMBorder *d = [AMBorder new];\n            d.borderColor = bottomColor;\n            d.borderWidth = bottomWidth;\n            d;\n        });\n    }\n    return b;\n}\n\n+ (instancetype)backgroundWithColor:(UIColor *)color radius:(CGFloat)radius\n{\n    return [self backgroundWithColor:color radius:radius insets:UIEdgeInsetsZero];\n}\n\n+ (instancetype)backgroundWithColor:(UIColor *)color radius:(CGFloat)radius insets:(UIEdgeInsets)insets\n{\n    AMTextBackground *b = [self new];\n    b.backgroundColor = color;\n    b.cornerRadius = radius;\n    b.isInline = YES;\n    b.contentInset = insets;\n    return b;\n}\n\n- (instancetype)init\n{\n    self = [super init];\n    if (self) {\n        self.isInline = NO;\n    }\n    return self;\n}\n\n- (BOOL)isEqual:(nullable id)object {\n    if (object == nil) {\n        return NO;\n    }\n    \n    if (self == object) {\n        return YES;\n    }\n    \n    if (![object isKindOfClass:[self class]]) {\n        return NO;\n    }\n    \n    return [self isEqualToBackground:(AMTextBackground *)object];\n}\n\n- (BOOL)isEqualToBackground:(AMTextBackground *)background\n{\n    return self.isInline == background.isInline\n    && ((self.backgroundColor == background.backgroundColor) || [self.backgroundColor isEqual:background.backgroundColor])\n    && self.cornerRadius == background.cornerRadius\n    && ((self.leftBorder == background.leftBorder) || [self.leftBorder isEqualToBorder:background.leftBorder])\n    && ((self.rightBorder == background.rightBorder) || [self.rightBorder isEqualToBorder:background.rightBorder])\n    && ((self.topBorder == background.topBorder) || [self.topBorder isEqualToBorder:background.topBorder])\n    && ((self.bottomBorder == background.bottomBorder) || [self.bottomBorder isEqualToBorder:background.bottomBorder]);\n}\n\n- (void)drawInRect:(CGRect)rect clipEdges:(UIRectEdge)edges\n{\n    CGContextRef context = UIGraphicsGetCurrentContext();\n    rect = UIEdgeInsetsInsetRect(rect, self.contentInset);\n    if (self.cornerRadius > 0) {\n        UIRectCorner corners = UIRectCornerAllCorners;\n        if (edges & UIRectEdgeRight) {\n            corners &= ~(UIRectCornerTopRight | UIRectCornerBottomRight);\n        }\n        if (edges & UIRectEdgeLeft) {\n            corners &= ~(UIRectCornerTopLeft | UIRectCornerBottomLeft);\n        }\n        UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect\n                                                   byRoundingCorners:corners\n                                                         cornerRadii:CGSizeMake(self.cornerRadius, self.cornerRadius)];\n        [path addClip];\n        [self.backgroundColor setFill];\n        [path fill];\n    } else {\n        [self.backgroundColor drawInRect:rect clipEdges:edges];\n    }\n    \n    \n    CGPoint points[2] = {0};\n    if (self.leftBorder) {\n        const CGFloat lineWidth = self.leftBorder.borderWidth;\n        CGContextSetLineCap(context, self.leftBorder.lineCap);\n        CGContextSetLineWidth(context, lineWidth);\n        [self.leftBorder.borderColor setStroke];\n        \n        points[0] = points[1] = rect.origin;\n        points[0].x += lineWidth / 2;\n        points[1].x += lineWidth / 2;\n        points[1].y = CGRectGetMaxY(rect);\n        CGContextStrokeLineSegments(context, points, 2);\n    }\n    if (self.topBorder) {\n        const CGFloat lineWidth = self.topBorder.borderWidth;\n        CGContextSetLineCap(context, self.topBorder.lineCap);\n        CGContextSetLineWidth(context, lineWidth);\n        [self.topBorder.borderColor setStroke];\n        \n        points[0] = points[1] = rect.origin;\n        points[0].y += lineWidth / 2;\n        points[1].y += lineWidth / 2;\n        points[1].x = CGRectGetMaxX(rect);\n        CGContextStrokeLineSegments(context, points, 2);\n    }\n    if (self.rightBorder) {\n        const CGFloat lineWidth = self.rightBorder.borderWidth;\n        CGContextSetLineCap(context, self.rightBorder.lineCap);\n        CGContextSetLineWidth(context, lineWidth);\n        [self.rightBorder.borderColor setStroke];\n        \n        points[0] = CGPointMake(CGRectGetMaxX(rect), CGRectGetMinY(rect));\n        points[1] = CGPointMake(CGRectGetMaxX(rect), CGRectGetMaxY(rect));\n        points[0].x -= lineWidth / 2;\n        points[1].x -= lineWidth / 2;\n        CGContextStrokeLineSegments(context, points, 2);\n    }\n    if (self.bottomBorder) {\n        const CGFloat lineWidth = self.bottomBorder.borderWidth;\n        CGContextSetLineCap(context, self.bottomBorder.lineCap);\n        CGContextSetLineWidth(context, lineWidth);\n        [self.bottomBorder.borderColor setStroke];\n        \n        points[0] = CGPointMake(CGRectGetMinX(rect), CGRectGetMaxY(rect));\n        points[1] = CGPointMake(CGRectGetMaxX(rect), CGRectGetMaxY(rect));\n        points[0].y -= lineWidth / 2;\n        points[1].y -= lineWidth / 2;\n        CGContextStrokeLineSegments(context, points, 2);\n    }\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMTextStyles.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n\n#import <AntMarkdown/CocoaMarkdown.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@protocol AMViewAttachment;\n@class AMTextStyles;\n@class CMTable;\n\n@protocol AMImageAttachmentBuilder <NSObject>\n\n- (NSTextAttachment *)buildWithURL:(NSURL *)url\n                             title:(nullable NSString *)title\n                            styles:(AMTextStyles *)styles;\n\n@end\n\n@protocol AMTableAttachmentBuilder <NSObject>\n\n- (NSTextAttachment<AMViewAttachment> *)buildWithTable:(CMTable *)table\n                                                styles:(AMTextStyles *)styles;\n\n@end\n\n@protocol AMCodeAttachmentBuilder <NSObject>\n\n- (NSTextAttachment<AMViewAttachment> *)buildWithCode:(NSString *)code\n                                             language:(nullable NSString *)language\n                                               styles:(AMTextStyles *)styles;\n\n@end\n\n@protocol AMFootnoteRefBuilder <NSObject>\n\n- (NSAttributedString *)buildWithReference:(NSString *)reference\n                                     title:(NSString *)title\n                                     index:(NSInteger)index\n                                    styles:(AMTextStyles *)styles;\n\n@end\n\n@interface AMBuilderBlock : NSObject\n\n+ (id<AMTableAttachmentBuilder>)tableBuilder:(NSTextAttachment<AMViewAttachment> *(^)(CMTable *table, AMTextStyles *styles))block;\n+ (id<AMImageAttachmentBuilder>)imageBuilder:(NSTextAttachment *(^)(NSURL *url, NSString * _Nullable title, AMTextStyles *styles))block;\n+ (id<AMCodeAttachmentBuilder>)codeBuilder:(NSTextAttachment<AMViewAttachment> *(^)(NSString *code, NSString * _Nullable lang, AMTextStyles *styles))block;\n+ (id<AMFootnoteRefBuilder>)footnoteBuilder:(NSAttributedString *(^)(NSString * ref, NSString * title, NSInteger index, AMTextStyles *styles))block;\n\n@end\n\ntypedef CMStyleAttributes * _Nonnull (^AMStyleProvider)(NSInteger level);\n\nUIKIT_EXTERN AMStyleProvider AMDefaultProvider(void);\n\n@interface AMTextStyles : CMTextAttributes\n\n+ (instancetype)defaultStyles;\n/**\n *  Attributes used to style underline text.\n */\n@property (nonatomic) CMStyleAttributes *underlineAttributes;\n/**\n *  Attributes used to style strikethrough text.\n */\n@property (nonatomic) CMStyleAttributes *strikethroughAttributes;\n\n/**\n *  Attributes used to style foot note reference text.\n */\n@property (nonatomic) CMStyleAttributes *footNoteRefAttributes;\n\n/**\n *  Attributes used to style foot note defination text.\n */\n@property (nonatomic) CMStyleAttributes *footNoteAttributes;\n\n/**\n *  Attributes used to style table header text.\n */\n@property (nonatomic) CMStyleAttributes *tableAttributes;\n@property (nonatomic) CMStyleAttributes *tableTitleAttributes;\n@property (nonatomic) CMStyleAttributes *tableHeaderAttributes;\n@property (nonatomic) CMStyleAttributes *tableCellAttributes;\n\n@property (nonatomic) CMStyleAttributes *listBulletAttributes;\n\n/**\n * when set, the \\c orderedListAttributes and \\c orderedSublistAttributes is \\b ignored\n */\n@property (nonatomic, copy, nullable) AMStyleProvider ordererListAttributesProvider;\n\n@property (nonatomic, copy, nullable) AMStyleProvider unordererListAttributesProvider;\n\n/**\n * set class style for html，eg:<span class='highlight'>text</span>\n */\n- (void)setAttributes:(CMStyleAttributes *)attributes forClass:(NSString *)className;\n\n- (CMStyleAttributes *)attributesForClass:(NSString *)className;\n\n- (void)addStringAttributes:(NSDictionary<NSAttributedStringKey, id> *)stringAttributes forClass:(NSString *)className;\n\n- (void)addFontAttributes:(NSDictionary<CMFontDescriptorAttributeName, id>*)fontAttributes forClass:(NSString *)className;\n\n- (void)addParagraphStyleAttributes:(NSDictionary<CMParagraphStyleAttributeName, id> *)paragraphAttributes forClass:(NSString *)className;\n\n/**\n * HTML element transformer, you can set custom transformer to instead the default one\n * <s></s> <sup></sup> <sub></sub> <div></div> <mark></mark> <span></span> \n */\n@property (nonatomic, readonly, copy) NSArray <id<CMHTMLElementTransformer> > * elementTransformers;\n\n- (void)addTransformer:(id<CMHTMLElementTransformer>)transformer;\n\n@property (nonatomic, readonly, nullable) id<AMCodeAttachmentBuilder> codeBuilder;\n\n- (void)registerCodeBlockAttachmentBuilder:(id<AMCodeAttachmentBuilder>)builder;\n\n@property (nonatomic, readonly, nullable) id<AMTableAttachmentBuilder> tableBuilder;\n\n- (void)registerTableBlockAttachmentBuilder:(id<AMTableAttachmentBuilder>)builder;\n\n@property (nonatomic, readonly, nullable) id<AMImageAttachmentBuilder> imageBuilder;\n\n- (void)registerImageAttachmentBuilder:(id<AMImageAttachmentBuilder>)builder;\n\n@property (nonatomic, readonly, nullable) id<AMFootnoteRefBuilder> footnoteRefBuilder;\n\n- (void)registerFootnoteRefBuilder:(id<AMFootnoteRefBuilder>)builder;\n\n@property (nonatomic) BOOL highlightCodeOnRender;\n\n/**\n set style object with id\n */\n+ (void)setAMStylesWithId:(NSString*)styleId styles:(AMTextStyles*)styles;\n/**\n get style object with id\n */\n+ (instancetype)getAMStylesWithId:(NSString*)styleId;\n/**\n remove style object with id\n */\n+ (void)removeAMStylesWithId:(NSString*)styleId;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMTextStyles.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <CoreText/CoreText.h>\n\n#import \"AMTextStyles.h\"\n#import \"AMUtils.h\"\n#import \"AMDrawable.h\"\n#import \"AMTextBackground.h\"\nNSMutableDictionary* stylesForId;\nAMStyleProvider AMDefaultProvider(void) {\n    return ^CMStyleAttributes * (NSInteger level) {\n        CMStyleAttributes *styles = [[CMStyleAttributes alloc] init];\n        [styles.stringAttributes addEntriesFromDictionary:@{\n            NSParagraphStyleAttributeName: ({\n            NSMutableParagraphStyle *paragraphStyles = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];\n            paragraphStyles.tabStops = @[\n                [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentCenter\n                                                location:13 + (level - 1) * 20\n                                                 options:@{}],\n                [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentLeft\n                                                location:30 + (level - 1) * 20\n                                                 options:@{}],\n            ];\n            paragraphStyles.lineBreakMode = NSLineBreakByWordWrapping;\n            paragraphStyles.paragraphSpacingBefore = 8;\n            paragraphStyles.lineSpacing = 2;\n            paragraphStyles.firstLineHeadIndent = 0;\n            paragraphStyles.headIndent = 30 + (level - 1) * 20;\n            [paragraphStyles copy];\n        }),\n        }];\n        \n        [styles.paragraphStyleAttributes addEntriesFromDictionary:@{\n            CMParagraphStyleAttributeFirstLineHeadExtraIndent: @0,\n            CMParagraphStyleAttributeHeadExtraIndent: @0,\n            CMParagraphStyleAttributeListItemLabelIndent: [NSNull null],\n            CMParagraphStyleAttributeListItemNumberFormat: @\"\\t%ld.\",\n            CMParagraphStyleAttributeListItemBulletString: @\"\\t●\",\n        }];\n        return styles;\n    };\n}\n\n@interface AMTextStyles ()\n@property (nonatomic) NSMutableDictionary<NSString *, CMStyleAttributes *> *classAttributes;\n@property (nonatomic) NSMutableArray<id<CMHTMLElementTransformer> > *transformers;\n@end\n\n@implementation AMTextStyles\n\n+ (instancetype)defaultStyles {\n    AMTextStyles *styles = [[self alloc] init];\n    \n    [styles.baseTextAttributes.stringAttributes addEntriesFromDictionary:@{\n        NSFontAttributeName: [UIFont systemFontOfSize:15],\n        NSForegroundColorAttributeName: [UIColor colorWithHex_ant_mark:0x1F3B63],\n    }];\n    [styles.baseTextAttributes.fontAttributes addEntriesFromDictionary:@{\n        \n    }];\n    [styles.baseTextAttributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeAlignment: @(NSTextAlignmentNatural),\n        CMParagraphStyleAttributeParagraphSpacing: @4,\n        CMParagraphStyleAttributeParagraphSpacingBefore: @4,\n        CMParagraphStyleAttributeHeadExtraIndent: @0,\n        CMParagraphStyleAttributeLineHeightMultiple: @1.08,\n        CMParagraphStyleAttributeHyphenationFactor: @1,\n        CMParagraphStyleAttributeLineBreakMode: @(NSLineBreakByWordWrapping),\n    }];\n    \n    [styles.paragraphAttributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeParagraphSpacingBefore: @10,\n    }];\n    \n    [styles.orderedListAttributes.stringAttributes addEntriesFromDictionary:@{\n        NSParagraphStyleAttributeName: ({\n        NSMutableParagraphStyle *paragraphStyles = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];\n        paragraphStyles.defaultTabInterval = 30;\n        paragraphStyles.tabStops = @[\n            [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentRight\n                                            location:20\n                                             options:@{}],\n            [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentLeft\n                                            location:20 + 6\n                                             options:@{}],\n        ];\n        paragraphStyles.paragraphSpacingBefore = 10;\n        paragraphStyles.paragraphSpacing = 0;\n        paragraphStyles.lineBreakMode = NSLineBreakByWordWrapping;\n        paragraphStyles.lineSpacing = 2;\n        paragraphStyles.firstLineHeadIndent = 0;\n        paragraphStyles.headIndent = 26;\n        [paragraphStyles copy];\n    }),\n    }];\n    \n    [styles.orderedListAttributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeFirstLineHeadExtraIndent: @0,\n        CMParagraphStyleAttributeHeadExtraIndent: @0,\n        CMParagraphStyleAttributeListItemLabelIndent: [NSNull null],\n        CMParagraphStyleAttributeListItemNumberFormat: @\"\\t%ld.\",\n    }];\n    \n    [styles.orderedSublistAttributes.stringAttributes addEntriesFromDictionary:@{\n        NSParagraphStyleAttributeName: ({\n        NSMutableParagraphStyle *paragraphStyles = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];\n        paragraphStyles.defaultTabInterval = 30;\n        paragraphStyles.tabStops = @[\n            [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentRight\n                                            location:20 + 26\n                                             options:@{}],\n            [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentLeft\n                                            location:20 + 26 + 6\n                                             options:@{}],\n        ];\n        paragraphStyles.paragraphSpacingBefore = 10;\n        paragraphStyles.paragraphSpacing = 0;\n        paragraphStyles.lineBreakMode = NSLineBreakByWordWrapping;\n        paragraphStyles.lineSpacing = 2;\n        paragraphStyles.firstLineHeadIndent = 0;\n        paragraphStyles.headIndent = 20 + 26 + 6;\n        [paragraphStyles copy];\n    })\n    }];\n    \n    [styles.orderedSublistAttributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeFirstLineHeadExtraIndent: @0,\n        CMParagraphStyleAttributeHeadExtraIndent: @0,\n        CMParagraphStyleAttributeListItemLabelIndent: [NSNull null],\n        CMParagraphStyleAttributeListItemNumberFormat: @\"\\t%ld.\",\n    }];\n    \n    [styles.unorderedListAttributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeFirstLineHeadExtraIndent: @10,\n        CMParagraphStyleAttributeHeadExtraIndent: @20,\n        CMParagraphStyleAttributeListItemLabelIndent: @10,\n        CMParagraphStyleAttributeListItemBulletString: @\"\\t●\",\n    }];\n    \n    [styles.unorderedSublistAttributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeFirstLineHeadExtraIndent: @20,\n        CMParagraphStyleAttributeHeadExtraIndent: @36,\n        CMParagraphStyleAttributeListItemLabelIndent: @16,\n        CMParagraphStyleAttributeListItemBulletString: @\"\\t●\",\n    }];\n    \n    styles.ordererListAttributesProvider = AMDefaultProvider();\n    styles.unordererListAttributesProvider = AMDefaultProvider();\n    \n    [styles.blockQuoteAttributes.stringAttributes addEntriesFromDictionary:@{\n        AMBackgroundDrawableAttributeName: [AMTextBackground leftBorderColor:[UIColor colorWithHex_ant_mark:0xd1d9e0]\n                                                                       width:4],\n    }];\n    [styles.blockQuoteAttributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeFirstLineHeadExtraIndent: @20,\n        CMParagraphStyleAttributeHeadExtraIndent: @20,\n        CMParagraphStyleAttributeParagraphSpacingBefore: @10,\n        CMParagraphStyleAttributeParagraphSpacing: @10,\n    }];\n    \n    [styles.listBulletAttributes.stringAttributes addEntriesFromDictionary:@{\n        NSBaselineOffsetAttributeName: @3,\n    }];\n    \n    [styles.listBulletAttributes.fontAttributes addEntriesFromDictionary:@{\n        UIFontDescriptorSizeAttribute: @8,\n    }];\n    \n    [styles.inlineCodeAttributes.stringAttributes addEntriesFromDictionary:@{\n        AMBackgroundDrawableAttributeName: [AMTextBackground backgroundWithColor:[UIColor colorWithHex_ant_mark:0x1f1f3b63]\n                                                                          radius:4\n                                                                          insets:UIEdgeInsetsMake(6, 2, 0, 2)],\n        NSForegroundColorAttributeName: [UIColor colorWithHex_ant_mark:0xFF1F3B63],\n    }];\n    [styles.inlineCodeAttributes.fontAttributes addEntriesFromDictionary:@{\n        UIFontDescriptorNameAttribute: @\"Menlo-Regular\",\n        UIFontDescriptorCascadeListAttribute: @[\n            [UIFontDescriptor fontDescriptorWithFontAttributes:@{\n                UIFontDescriptorNameAttribute: @\"Courier\"\n            }],\n            [UIFontDescriptor fontDescriptorWithFontAttributes:@{\n                UIFontDescriptorNameAttribute: @\"Courier New\"\n            }]\n        ],\n    }];\n    [styles.inlineCodeAttributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeLineBreakMode: @(NSLineBreakByCharWrapping),\n    }];\n    \n    [styles.codeBlockAttributes.stringAttributes addEntriesFromDictionary:@{\n        NSFontAttributeName: [UIFont fontWithDescriptor:[UIFontDescriptor fontDescriptorWithFontAttributes:@{\n            UIFontDescriptorNameAttribute: @\"Courier\",\n            UIFontDescriptorCascadeListAttribute: @[\n                [UIFontDescriptor fontDescriptorWithFontAttributes:@{\n                    UIFontDescriptorNameAttribute: @\"Courier New\"\n                }],\n                [UIFontDescriptor fontDescriptorWithFontAttributes:@{\n                    UIFontDescriptorNameAttribute: @\"Menlo\"\n                }],\n            ]\n        }]\n                                                   size:13],\n    }];\n    [styles.codeBlockAttributes.fontAttributes addEntriesFromDictionary:@{\n        \n    }];\n    [styles.codeBlockAttributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeHeadExtraIndent: @0,\n        CMParagraphStyleAttributeFirstLineHeadExtraIndent: @0,\n        CMParagraphStyleAttributeParagraphSpacingBefore: @0,\n        CMParagraphStyleAttributeLineHeightMultiple: @1.4,\n    }];\n    \n    [styles.tableHeaderAttributes.stringAttributes addEntriesFromDictionary:@{\n        \n    }];\n    [styles.tableCellAttributes.fontAttributes addEntriesFromDictionary:@{\n        UIFontDescriptorSizeAttribute: @13,\n    }];\n    \n    return styles;\n}\n\n- (instancetype)init\n{\n    self = [super init];\n    if (self) {\n        self.classAttributes = [NSMutableDictionary new];\n        self.transformers = [NSMutableArray array];\n        \n        self.orderedListItemAttributes = [[CMStyleAttributes alloc] init];\n        self.unorderedListItemAttributes = [[CMStyleAttributes alloc] init];\n        self.underlineAttributes = [[CMStyleAttributes alloc] init];\n        self.strikethroughAttributes = [[CMStyleAttributes alloc] init];\n        [self.strikethroughAttributes.stringAttributes addEntriesFromDictionary:@{\n            NSStrikethroughStyleAttributeName: @(NSUnderlineStyleSingle),\n        }];\n        self.tableAttributes = [[CMStyleAttributes alloc] init];\n        self.tableTitleAttributes = [[CMStyleAttributes alloc] init];\n        self.tableHeaderAttributes = [self.strongAttributes copy];\n        self.tableCellAttributes = [self.paragraphAttributes copy];\n        \n        self.listBulletAttributes = [[CMStyleAttributes alloc] init];\n        \n        self.footNoteRefAttributes = [self.linkAttributes copy];\n        [self.footNoteRefAttributes.stringAttributes addEntriesFromDictionary:@{\n            NSBaselineOffsetAttributeName: @6,\n        }];\n        [self.footNoteRefAttributes.fontAttributes addEntriesFromDictionary:@{\n            UIFontDescriptorSizeAttribute: @10,\n        }];\n        \n        self.footNoteAttributes = [self.orderedListItemAttributes copy];\n        \n    }\n    return self;\n}\n\n- (CMStyleAttributes *)attributesForClass:(NSString *)className {\n    CMStyleAttributes *attributes = self.classAttributes[className];\n    if (!attributes) {\n        attributes = [CMStyleAttributes new];\n        self.classAttributes[className] = attributes;\n    }\n    return attributes;\n}\n\n- (void)setAttributes:(CMStyleAttributes *)attributes forClass:(NSString *)className {\n    self.classAttributes[className] = attributes;\n}\n\n- (void)addFontAttributes:(NSDictionary<CMFontDescriptorAttributeName,id> *)fontAttributes forClass:(NSString *)className {\n    CMStyleAttributes *attributes = [self attributesForClass:className];\n    [attributes.fontAttributes addEntriesFromDictionary:fontAttributes];\n}\n\n- (void)addStringAttributes:(NSDictionary<NSAttributedStringKey,id> *)stringAttributes forClass:(NSString *)className {\n    CMStyleAttributes *attributes = [self attributesForClass:className];\n    [attributes.stringAttributes addEntriesFromDictionary:stringAttributes];\n}\n\n- (void)addParagraphStyleAttributes:(NSDictionary<CMParagraphStyleAttributeName,id> *)paragraphAttributes forClass:(NSString *)className {\n    CMStyleAttributes *attributes = [self attributesForClass:className];\n    [attributes.paragraphStyleAttributes addEntriesFromDictionary:paragraphAttributes];\n}\n\n- (NSArray<id<CMHTMLElementTransformer>> *)elementTransformers\n{\n    return [self.transformers copy];\n}\n\n- (void)addTransformer:(id<CMHTMLElementTransformer>)transformer\n{\n    [self.transformers addObject:transformer];\n}\n\n- (void)registerImageAttachmentBuilder:(nonnull id<AMImageAttachmentBuilder>)builder {\n    _imageBuilder = builder;\n}\n\n- (void)registerTableBlockAttachmentBuilder:(nonnull id<AMTableAttachmentBuilder>)builder {\n    _tableBuilder = builder;\n}\n\n- (void)registerCodeBlockAttachmentBuilder:(nonnull id<AMCodeAttachmentBuilder>)builder {\n    _codeBuilder = builder;\n}\n\n- (void)registerFootnoteRefBuilder:(id<AMFootnoteRefBuilder>)builder\n{\n    _footnoteRefBuilder = builder;\n}\n+ (void)setAMStylesWithId:(NSString*)styleId styles:(AMTextStyles*)styles\n{\n    if (!stylesForId) {\n        stylesForId = [[NSMutableDictionary alloc] init];\n    }\n    stylesForId[styleId] = styles;\n}\n+ (instancetype)getAMStylesWithId:(NSString*)styleId\n{\n    if (!stylesForId) {\n        stylesForId = [[NSMutableDictionary alloc] init];\n    }\n    return [stylesForId objectForKey:styleId];\n}\n+ (void)removeAMStylesWithId:(NSString*)styleId\n{\n    if (!stylesForId) {\n        stylesForId = [[NSMutableDictionary alloc] init];\n    }\n    [stylesForId removeObjectForKey:styleId];\n}\n@end\n\n@interface AMBuilderBlock () <AMTableAttachmentBuilder, AMCodeAttachmentBuilder, AMImageAttachmentBuilder, AMFootnoteRefBuilder>\n@property (nonatomic, copy) id(^builderBlock)(void);\n@end\n\n@implementation AMBuilderBlock\n\n+ (id<AMTableAttachmentBuilder>)tableBuilder:(NSTextAttachment<AMViewAttachment> * _Nonnull (^)(CMTable * _Nonnull, AMTextStyles * _Nonnull))block\n{\n    AMBuilderBlock *builder = [self new];\n    builder.builderBlock = (id(^)(void))block;\n    return builder;\n}\n\n+ (id<AMCodeAttachmentBuilder>)codeBuilder:(NSTextAttachment<AMViewAttachment> * _Nonnull (^)(NSString * _Nonnull, NSString * _Nullable, AMTextStyles * _Nonnull))block\n{\n    AMBuilderBlock *builder = [self new];\n    builder.builderBlock = (id(^)(void))block;\n    return builder;\n}\n\n+ (id<AMFootnoteRefBuilder>)footnoteBuilder:(NSAttributedString * _Nonnull (^)(NSString * _Nonnull, NSString * _Nonnull, NSInteger, AMTextStyles * _Nonnull))block\n{\n    AMBuilderBlock *builder = [self new];\n    builder.builderBlock = (id(^)(void))block;\n    return builder;\n}\n\n+ (id<AMImageAttachmentBuilder>)imageBuilder:(NSTextAttachment * _Nonnull (^)(NSURL * _Nonnull, NSString * _Nullable, AMTextStyles * _Nonnull))block\n{\n    AMBuilderBlock *builder = [self new];\n    builder.builderBlock = (id(^)(void))block;\n    return builder;\n}\n\n- (nonnull NSTextAttachment<AMViewAttachment> *)buildWithTable:(nonnull CMTable *)table \n                                                        styles:(nonnull AMTextStyles *)styles {\n    return ((NSTextAttachment<AMViewAttachment> *(^)(CMTable * _Nonnull, AMTextStyles * _Nonnull))self.builderBlock)(table, styles);\n}\n\n- (nonnull NSTextAttachment<AMViewAttachment> *)buildWithCode:(nonnull NSString *)code language:(nullable NSString *)language styles:(nonnull AMTextStyles *)styles { \n    return ((NSTextAttachment<AMViewAttachment> *(^)(NSString * _Nonnull, NSString * _Nullable, AMTextStyles * _Nonnull))self.builderBlock)(code, language, styles);\n}\n\n- (nonnull NSTextAttachment *)buildWithURL:(nonnull NSURL *)url title:(nullable NSString *)title styles:(nonnull AMTextStyles *)styles { \n    return ((NSTextAttachment * _Nonnull (^)(NSURL * _Nonnull, NSString * _Nullable, AMTextStyles * _Nonnull))self.builderBlock)(url, title, styles);\n}\n\n- (nonnull NSAttributedString *)buildWithReference:(nonnull NSString *)reference title:(nonnull NSString *)title index:(NSInteger)index styles:(nonnull AMTextStyles *)styles { \n    return ((NSAttributedString * _Nonnull (^)(NSString * _Nonnull, NSString * _Nonnull, NSInteger, AMTextStyles * _Nonnull))self.builderBlock)(reference, title, index, styles);\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMUnderline.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n#import <AntMarkdown/AMDrawable.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMUnderline : NSObject <AMUnderlineDrawable>\n\n- (instancetype)initWithColor:(UIColor *)color lineWidth:(CGFloat)width offset:(CGFloat)offset;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMUnderline.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMUnderline.h\"\n\n@implementation AMUnderline\n{\n    UIColor     * _color;\n    CGFloat       _width, _offset;\n}\n\n- (instancetype)initWithColor:(UIColor *)color lineWidth:(CGFloat)width offset:(CGFloat)offset\n{\n    self = [super init];\n    if (self) {\n        _color = color;\n        _width = width;\n        _offset = offset;\n    }\n    return self;\n}\n\n- (void)drawInRect:(CGRect)rect underlineStyle:(NSUnderlineStyle)type baselineOffset:(CGFloat)offset\n{\n    rect.origin.y = CGRectGetMaxY(rect) - _width;\n    rect.size.height = _width;\n    rect = CGRectOffset(rect, 0, _offset);\n    [_color setFill];\n    CGContextRef context = UIGraphicsGetCurrentContext();\n    CGContextFillRect(context, rect);\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMUtils.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n#import <pthread/pthread.h>\n\n#ifndef CLSSTR\n#define CLSSTR(cls) (((void)(NO && ((void)NSStringFromClass(cls.class), NO)), @# cls))\n#endif\n\n#ifndef SELSTR\n#define SELSTR(sel) (((void)(NO && ((void)NSStringFromSelector(sel), NO)), @# sel))\n#endif\n\n#ifndef KEYPATH\n#define KEYPATH(OBJ, PATH) (((void)(NO && ((void)(((typeof(OBJ))nil).PATH), NO)), @# PATH))\n#endif\n\n#ifndef weakify\n#define weakify(OBJ) keywordify __weak typeof(OBJ) weak##OBJ = OBJ;\n#endif\n\n#ifndef strongify\n#define strongify(OBJ) keywordify __strong typeof(weak##OBJ) OBJ = weak##OBJ;\n#endif\n\n#ifndef strongifyOrReturn\n#define strongifyOrReturn(OBJ) \\\n    keywordify \\\n    __strong typeof(weakSelf) OBJ = weakSelf;\\\n    if (!OBJ) { \\\n        return; \\\n    }\n#endif\n\n\n#if defined(DEBUG) && !defined(NDEBUG)\n#define keywordify autoreleasepool {}\n#else\n#define keywordify try {} @catch (...) {}\n#endif\n\n#ifndef AMLogDebug\n#define AMLogDebug(log, ...) NSLog(@\"[AntMarkdown] \" log, __VA_ARGS__)\n#endif\n\nstatic inline void dispatch_async_on_main_queue(void (^block)()) {\n    if(!block) return;\n    dispatch_async(dispatch_get_main_queue(), block);\n}\n\nstatic inline void dispatch_sync_on_main_queue(void (^block)()) {\n    if(!block) return;\n\n    if (pthread_main_np()) {\n        block();\n    } else {\n        dispatch_sync(dispatch_get_main_queue(), block);\n    }\n}\n\nstatic inline bool dispatch_is_main_queue() {\n    return pthread_main_np() != 0;\n}\n\nstatic inline void delayRun(NSTimeInterval delayTime,dispatch_block_t _Nullable block){\n    if(!block) return;\n    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayTime * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{\n        block();\n    });\n\n}\nstatic inline  void APTMainCall(NSInteger bizType, const char* _Nullable tag, double delayTime, NSOperationQueuePriority priority, dispatch_block_t _Nullable block)\n{\n    assert(block != nil);\n    assert(delayTime >= 0 && delayTime < 3600 * 24 * 7);\n    \n    do\n    {\n        static long count = 0;\n        static long lastTime = 0;\n        ++count;\n        if(count == 1)\n        {\n            lastTime = time(0);\n        }\n        else\n        {\n            if(count >= 200)\n            {\n                long dt = time(0) - lastTime;\n                if(dt < 60 * 10)\n                {\n                    if(count == 200)\n                    {\n                        NSLog(@\"#THM %@\", @\"APTMainCall-omit...\");\n                    }\n                    break;\n                }\n                else\n                {\n                    lastTime = time(0);\n                    count = 0;\n                }\n            }\n        }\n        NSLog(@\"#THM APTMainCall-%d,%s,%lf,%d\", (int)bizType, tag?tag:\"\", delayTime, (int)priority);\n    }while (0);\n    \n    \n    if(delayTime > 0)\n    {\n        if(delayTime >= 1000000)\n        {\n            delayTime /= NSEC_PER_SEC;\n        }\n        \n        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayTime * NSEC_PER_SEC)), dispatch_get_main_queue(), block);\n    }\n    else\n    {\n        if ([NSThread isMainThread])\n        {\n            block();\n            return;\n        }\n        dispatch_async(dispatch_get_main_queue(), block);\n    }\n}\nstatic inline CGFloat AUCommonUIGetScreenWidthForPortrait()\n{\n    CGSize size = [UIScreen mainScreen].bounds.size;\n    return MIN(size.width, size.height);\n}\nstatic inline CGFloat AUUIGetOnePixel()\n{\n    static CGFloat onePx = 1.0;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        onePx = onePx/[UIScreen mainScreen].scale;\n        if(onePx == 0){\n            onePx = 1.0;\n        }\n    });\n    return onePx;\n}\nstatic inline CGFloat AUFVS(CGFloat value) {\n    static dispatch_once_t onceToken;\n    static CGFloat scale;\n    \n    dispatch_once(&onceToken, ^{\n        scale = AUCommonUIGetScreenWidthForPortrait() / 375;\n    });\n  \n     \n    CGFloat px = value * scale;\n    \n    long new = floorf( px / AUUIGetOnePixel());\n    //不相等取大值\n    if(fabs(new * AUUIGetOnePixel() - px) > 0.00001){\n       new++;\n    }\n    \n    //NSLog(@\"Fitting :%lf,%lf\", value,0.10909 +  1.10909 * value);\n    \n    return (new * AUUIGetOnePixel());\n}\n\n\nstatic CGFloat AMScale(void) {\n    static dispatch_once_t onceToken;\n    static CGFloat scale = 1;\n    dispatch_once(&onceToken, ^{\n        scale = [UIScreen mainScreen].scale;\n    });\n    return scale;\n}\n\nstatic inline CGFloat AMFloor(CGFloat value) {\n    return floor(value * AMScale()) / AMScale();\n}\n\nstatic inline CGFloat AMCeil(CGFloat value) {\n    return ceil(value * AMScale()) / AMScale();\n}\n\nstatic inline CGSize AMSize(CGFloat width, CGFloat height) {\n    return CGSizeMake(AMCeil(width), AMCeil(height));\n}\n\nstatic inline CGSize AMSizeIntegral(CGSize size) {\n    return CGSizeMake(AMCeil(size.width), AMCeil(size.height));\n}\n\nstatic inline CGRect AMRectIntegral(CGRect rect) {\n    return CGRectMake(AMFloor(rect.origin.x), AMFloor(rect.origin.y), AMCeil(rect.size.width), AMCeil(rect.size.height));\n}\nstatic inline void AMUIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale) {\n    if (@available(iOS 17.0, *)) {\n        if (size.width <= 0 || size.height <= 0) {\n            CGSize s = CGSizeMake(size.width > 0 ? size.width : 0.01, size.height > 0 ? size.height : 0.01);\n            UIGraphicsBeginImageContextWithOptions(s, opaque, scale);\n        } else {\n            UIGraphicsBeginImageContextWithOptions(size, opaque, scale);\n        }\n    } else {\n        UIGraphicsBeginImageContextWithOptions(size, opaque, scale);\n    }\n}\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMUtils : NSObject\n+ (UIColor *)colorWithString:(NSString *)stringToConvert;\n+ (id)JSONValue:(id)object;\n+ (CGFloat)fontValue:(NSString*)fontStr;\n@end\n\n@interface UIColor (AMUtils)\n\n// ARGB 格式\n+ (instancetype)colorWithHex_ant_mark:(NSUInteger)ARGB __attribute__((const));\n\n+ (instancetype)colorWithHex_ant_mark_alpha:(NSUInteger)ARGB __attribute__((const));\n\n/// #RRGGBB #RRGGBBAA #RGB #RGBA\n+ (nullable instancetype)colorWithCSSString_ant_mark:(NSString *)cssColor __attribute__((const));\n\n+ (instancetype)colorWithCSSString_ant_mark_alpha:(NSString *)cssColor\n__attribute__((const));\n\n- (instancetype)transparentColor_ant_mark __attribute__((const));;\n\n@end\n\n@interface UIImage (AMUtils)\n\n\n/// create a image with gradient\n/// - Parameters:\n///   - colors: gradient value\n///   - locations: gradient location\n///   - size: image size\n///   - direction: gradient angle，0  is from top to bottom，clockwise\n+ (instancetype)imageWithGradient_ant_mark:(NSArray <UIColor *> *)colors\n                                 locations:(nullable NSArray <NSNumber *> *)locations\n                                      size:(CGSize)size\n                                 direction:(CGFloat)direction;\n\n+ (instancetype)imageNamed_ant_mark:(NSString *)name;\n+ (instancetype)imageNamed_ant_bundle:(NSString *)bundlePath name:(NSString*)name;\n\n@end\n\n@interface NSArray<ObjectType> (AMUtils)\n\n- (NSArray<id> *)mapWithBlock_ant_mark:(id (NS_NOESCAPE ^)(ObjectType obj))block __attribute__((const));\n\n@end\n\n@protocol AMDiffable <NSObject>\n\n@required\n- (BOOL)isEqualToDiffableObject:(nullable id<AMDiffable>)object;\n\n@end\n\n@interface NSParagraphStyle (AMUtils) <AMDiffable>\n@end\n\n@interface NSDictionary<Key, Value> (AMUtils)\n\n- (BOOL)includesDictionary_ant_mark:(NSDictionary<Key, Value> *)otherDictionary;\n- (NSString *)stringForKey_ap:(id)aKey;\n- (NSString *)stringOrEmptyStringForKey_ap:(id)akey ;\n- (NSString *)stringForKey_ap:(id)aKey defaultValue:(NSString *)defaultValue;\n\n@end\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMUtils.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMUtils.h\"\n\n@implementation AMUtils\n+ (UIColor *)colorWithOctString:(NSString *)stringToConvert\n{\n    NSString *cString = [[stringToConvert stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString];\n    NSArray * components = [cString componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@\"(,)\"]];\n    if ([components count] < 3) return [UIColor clearColor];\n\n    NSString *rString = components[0];\n    NSString *gString = components[1];\n    NSString *bString = components[2];\n\n    NSString *alpha = @\"1.0\";\n    if (components.count>=4) {\n        alpha = components[3];\n    }\n    \n    return [UIColor colorWithRed:((float) [rString integerValue] / 255.0f)\n                           green:((float) [gString integerValue] / 255.0f)\n                            blue:((float) [bString integerValue] / 255.0f)\n                           alpha:alpha.floatValue];\n}\n\n+ (UIColor *)colorWithHexString:(NSString *)stringToConvert\n{\n    NSString *cString = [[stringToConvert stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] lowercaseString];\n    \n    // String should be 6 or 8 characters\n    if ([cString length] < 6) return [UIColor clearColor];\n    \n    // strip 0X if it appears\n    if ([cString hasPrefix:@\"0x\"]) cString = [cString substringFromIndex:2];\n    if ([cString hasPrefix:@\"#\"]) cString = [cString substringFromIndex:1];\n    if ([cString length] != 6 && [cString length] != 8) return [UIColor clearColor];\n    // Separate into r, g, b substrings\n    NSRange range;\n    range.location = 0;\n    range.length = 2;\n    NSString *rString = [cString substringWithRange:range];\n    \n    range.location = 2;\n    NSString *gString = [cString substringWithRange:range];\n    \n    range.location = 4;\n    NSString *bString = [cString substringWithRange:range];\n    \n    // Scan values\n    unsigned int r, g, b;\n    [[NSScanner scannerWithString:rString] scanHexInt:&r];\n    [[NSScanner scannerWithString:gString] scanHexInt:&g];\n    [[NSScanner scannerWithString:bString] scanHexInt:&b];\n    \n    CGFloat alpha = 1.0;\n    if ([cString length] == 8) {\n        range.location = 6;\n        NSString *aString = [cString substringWithRange:range];\n        unsigned int a;\n        [[NSScanner scannerWithString:aString] scanHexInt:&a];\n        alpha = ((float) a / 255.0f);\n    }\n    \n    return [UIColor colorWithRed:((float) r / 255.0f)\n                           green:((float) g / 255.0f)\n                            blue:((float) b / 255.0f)\n                           alpha:alpha];\n}\n+ (UIColor *)colorWithString:(NSString *)stringToConvert\n{\n    NSString *cString = [stringToConvert lowercaseString];\n    if ([cString hasPrefix:@\"rgb\"]) {\n        NSString *trimString = [cString stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@\"rgba()\"]];\n        return [self colorWithOctString:trimString];\n    } else if([cString hasPrefix:@\"0x\"] || [cString hasPrefix:@\"#\"]) {\n        return [self colorWithHexString:cString];\n    }\n\n    UIColor *color = [UIColor clearColor];\n    NSDictionary *colorMap = @{@\"grey\":[UIColor grayColor],\n                               @\"gray\":[UIColor grayColor],\n                               @\"darkgray\":[UIColor darkGrayColor],\n                               @\"lightgray\":[UIColor lightGrayColor],\n                               @\"black\":[UIColor blackColor],\n                               @\"white\":[UIColor whiteColor],\n                               @\"red\":[UIColor redColor],\n                               @\"blue\":[UIColor blueColor],\n                               @\"green\":[UIColor greenColor],\n                               @\"yellow\":[UIColor yellowColor],\n                               @\"brown\":[UIColor brownColor],\n                               @\"orange\":[UIColor orangeColor]};\n    if (colorMap[cString]) {\n        color = colorMap[cString];\n    }\n    return color;\n}\n+ (id)JSONValue:(id)object {\n    if ([object isKindOfClass:[NSString class]]) {\n        NSData* data = [object dataUsingEncoding:NSUTF8StringEncoding];\n        if (data) {\n            return [self JSONValue:data];\n        } else {\n            return nil;\n        }\n    } else if ([object isKindOfClass:[NSData class]]) {\n        id result = nil;\n        @try {\n            NSError* error = nil;\n            result = [NSJSONSerialization JSONObjectWithData:object options:0 error:&error];\n            if (result == nil) {\n                NSLog(@\"-JSONValue failed. Error is: %@\", error);\n            }\n        } @catch (NSException *exception) {\n            NSLog(@\"-JSONValue failed. Exception: %@\", exception);\n        }\n        return result;\n    } else {\n        return nil;\n    }\n}\n+ (CGSize)screenXY {\n    static CGSize size;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        CGFloat width = MIN([UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);\n        CGFloat height = MAX([UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);\n        size = CGSizeMake(width, height);\n    });\n    return size;\n}\n+ (CGFloat)fontValue:(NSString*)fontStr {\n    if (!fontStr.length || [fontStr isEqualToString:@\"(null)\"]) {\n        return 0;\n    }\n    \n    CGFloat fontFloatValue = [fontStr floatValue];\n    \n    CGFloat ratio = 1;\n    \n    CGFloat scale = 1;\n    scale = [self screenXY].width / 375.f;\n    if ([fontStr hasSuffix:@\"sip\"]) {\n        fontFloatValue *= scale;\n    }\n    else if ([fontStr hasSuffix:@\"sp\"]) {\n        fontFloatValue *= (scale*ratio);\n    }\n    else if ([fontStr hasSuffix:@\"np\"]) {\n        fontFloatValue *= ratio;\n    }\n    else if ([fontStr hasSuffix:@\"pt\"]) {\n        fontFloatValue *= ratio;\n    }\n    \n    \n    else if ([fontStr hasSuffix:@\"dip\"]) {\n        fontFloatValue *= 1;\n    }\n    else if ([fontStr hasSuffix:@\"pit\"]) {\n        fontFloatValue *= 1;\n    }\n    else if ([fontStr hasSuffix:@\"apx\"]) {\n        fontFloatValue *= (1.f/[UIScreen mainScreen].scale);\n    }\n    else {\n        if ([fontStr hasSuffix:@\"px\"]) {\n            fontFloatValue *= 1;\n        }\n        else if ([fontStr hasSuffix:@\"rpx\"]) {\n            fontFloatValue *= ([self screenXY].width /750.f);\n        }\n    }\n    \n    return fontFloatValue;\n}\n@end\n\n@implementation UIColor (AMUtils)\n\n+ (instancetype)colorWithHex_ant_mark:(NSUInteger)hexColor {\n    NSInteger a,r,g,b;\n    a = (hexColor & 0xFF000000) >> 24;\n    r = (hexColor & 0x00FF0000) >> 16;\n    g = (hexColor & 0x0000FF00) >>  8;\n    b = (hexColor & 0x000000FF) >>  0;\n    if (a == 0) {\n        a = 0xFF;\n    }\n    return [UIColor colorWithRed:1.0 * r / 255\n                           green:1.0 * g / 255\n                            blue:1.0 * b / 255\n                           alpha:1.0 * a / 255];\n}\n+ (instancetype)colorWithHex_ant_mark_alpha:(NSUInteger)hexColor {\n    NSInteger a,r,g,b;\n    a = (hexColor & 0xFF000000) >> 24;\n    r = (hexColor & 0x00FF0000) >> 16;\n    g = (hexColor & 0x0000FF00) >>  8;\n    b = (hexColor & 0x000000FF) >>  0;\n    return [UIColor colorWithRed:1.0 * r / 255\n                           green:1.0 * g / 255\n                            blue:1.0 * b / 255\n                           alpha:1.0 * a / 255];\n}\n+ (instancetype)colorWithCSSString_ant_mark_alpha:(NSString *)cssColor {\n    cssColor = [cssColor stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];\n    if ([cssColor hasPrefix:@\"#\"]) {\n        NSScanner *scaner = [[NSScanner alloc] initWithString:[cssColor substringFromIndex:1]];\n      \n        if (cssColor.length == 9) {\n            NSUInteger value = 0;\n            [scaner scanHexInt:(uint *)&value];\n            \n            // RGBA to ARGB\n            NSInteger a = value & 0xFF;\n            value = (value >> 8) | (a << 24);\n            return [self colorWithHex_ant_mark_alpha:value];\n        }\n        if (cssColor.length == 7) {\n            NSUInteger value = 0;\n            [scaner scanHexInt:(uint *)&value];\n            return [self colorWithHex_ant_mark:value];\n        }\n        else if (cssColor.length == 5) {\n            NSUInteger value = 0;\n            [scaner scanHexInt:(uint *)&value];\n            NSInteger a,r,g,b;\n            r = (value & 0xF000) >> 12;\n            g = (value & 0x0F00) >>  8;\n            b = (value & 0x00F0) >>  4;\n            a = (value & 0x000F) >>  0;\n            value = ((a * 0x11) << 24) | ((r * 0x11) << 16) | ((g * 0x11) << 8) | ((b * 0x11) << 0);\n            return [self colorWithHex_ant_mark_alpha:value];\n        }\n        else if (cssColor.length == 4) {\n            NSUInteger value = 0;\n            [scaner scanHexInt:(uint *)&value];\n            NSInteger r,g,b;\n            r = (value & 0x0F00) >>  8;\n            g = (value & 0x00F0) >>  4;\n            b = (value & 0x000F) >>  0;\n            value = ((r * 0x11) << 16) | ((g * 0x11) << 8) | ((b * 0x11) << 0);\n            return [self colorWithHex_ant_mark:value];\n        }\n    }\n    return nil;\n}\n+ (instancetype)colorWithCSSString_ant_mark:(NSString *)cssColor\n{\n    cssColor = [cssColor stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];\n    if ([cssColor hasPrefix:@\"#\"]) {\n        NSScanner *scaner = [[NSScanner alloc] initWithString:[cssColor substringFromIndex:1]];\n        if (cssColor.length == 9) {\n            NSUInteger value = 0;\n            [scaner scanHexInt:(uint *)&value];\n            \n            // RGBA to ARGB\n            NSInteger a = value & 0xFF;\n            value = (value >> 8) | (a << 24);\n            return [self colorWithHex_ant_mark:value];\n        }\n        if (cssColor.length == 7) {\n            NSUInteger value = 0;\n            [scaner scanHexInt:(uint *)&value];\n            return [self colorWithHex_ant_mark:value];\n        }\n        else if (cssColor.length == 5) {\n            NSUInteger value = 0;\n            [scaner scanHexInt:(uint *)&value];\n            NSInteger a,r,g,b;\n            r = (value & 0xF000) >> 12;\n            g = (value & 0x0F00) >>  8;\n            b = (value & 0x00F0) >>  4;\n            a = (value & 0x000F) >>  0;\n            value = ((a * 0x11) << 24) | ((r * 0x11) << 16) | ((g * 0x11) << 8) | ((b * 0x11) << 0);\n            return [self colorWithHex_ant_mark:value];\n        }\n        else if (cssColor.length == 4) {\n            NSUInteger value = 0;\n            [scaner scanHexInt:(uint *)&value];\n            NSInteger r,g,b;\n            r = (value & 0x0F00) >>  8;\n            g = (value & 0x00F0) >>  4;\n            b = (value & 0x000F) >>  0;\n            value = ((r * 0x11) << 16) | ((g * 0x11) << 8) | ((b * 0x11) << 0);\n            return [self colorWithHex_ant_mark:value];\n        }\n    }\n    return nil;\n}\n\n- (instancetype)transparentColor_ant_mark\n{\n    CGFloat r,g,b,a;\n    if ([self getRed:&r green:&g blue:&b alpha:&a]) {\n        return [UIColor colorWithRed:r green:g blue:b alpha:0];\n    } else if ([self getWhite:&r alpha:&a]) {\n        return [UIColor colorWithWhite:r alpha:0];\n    } else {\n        return [UIColor clearColor];\n    }\n}\n\n@end\n\n@implementation UIImage (AMUtils)\n\n+ (instancetype)imageWithGradient_ant_mark:(NSArray<UIColor *> *)colors\n                                 locations:(NSArray<NSNumber *> *)locations\n                                      size:(CGSize)size\n                                 direction:(CGFloat)direction {\n    UIGraphicsBeginImageContextWithOptions(size, NO, 0);\n    \n    CGContextRef context = UIGraphicsGetCurrentContext();\n    \n    NSMutableArray *arr = [NSMutableArray array];\n    [colors enumerateObjectsUsingBlock:^(UIColor * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {\n        [arr addObject:(id)obj.CGColor];\n    }];\n    \n    CGFloat stackLocs[10] = {0};\n    CGFloat *locs = stackLocs;\n    BOOL needMalloc = locations.count > 10;\n    if (locations.count) {\n        locs = needMalloc ? malloc(locations.count * sizeof(CGFloat)) : stackLocs;\n        [locations enumerateObjectsUsingBlock:^(NSNumber * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {\n            locs[idx] = [obj doubleValue];\n        }];\n    }\n    CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();\n    CGGradientRef gradient = CGGradientCreateWithColors(space, (__bridge CFArrayRef)arr, locs);\n    \n    \n    CGRect rect = CGRectMake(0, 0, size.width, size.height);\n    CGPoint startPoint = CGPointZero;\n    CGPoint endPoint = CGPointZero;\n    \n    UIBezierPath* rectanglePath = [UIBezierPath bezierPathWithRect: rect];\n    UIBezierPath* rectangleRotatedPath = [rectanglePath copy];\n    CGAffineTransform transform = CGAffineTransformMakeRotation(-direction / 180 * M_PI + M_PI_2);\n    [rectangleRotatedPath applyTransform: transform];\n    CGRect rectangleBounds = CGPathGetPathBoundingBox(rectangleRotatedPath.CGPath);\n    transform = CGAffineTransformInvert(transform);\n    \n    startPoint = CGPointApplyAffineTransform(CGPointMake(CGRectGetMinX(rectangleBounds), CGRectGetMidY(rectangleBounds)), transform);\n    endPoint = CGPointApplyAffineTransform(CGPointMake(CGRectGetMaxX(rectangleBounds), CGRectGetMidY(rectangleBounds)), transform);\n    \n    CGContextSaveGState(context);\n    CGContextClipToRect(context, rect);\n    CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);\n    CGContextRestoreGState(context);\n    \n    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();\n    UIGraphicsEndImageContext();\n    \n    CGColorSpaceRelease(space);\n    CGGradientRelease(gradient);\n    if (needMalloc) {\n        free(locs);\n    }\n    \n    return image;\n}\n\n+ (instancetype)imageNamed_ant_mark:(NSString *)name\n{\n    static dispatch_once_t onceToken;\n    static NSBundle *bundle = nil;\n    dispatch_once(&onceToken, ^{\n        NSBundle *main = [NSBundle mainBundle];\n        NSString *resourcePath = [[NSBundle bundleForClass:[AMUtils class]] pathForResource:@\"AntMarkdown\" ofType:@\"bundle\"];\n        if (!resourcePath) {\n            resourcePath = [main pathForResource:@\"AntMarkdown\"\n                                          ofType:@\"bundle\"];\n        }\n        bundle = main;\n        if (resourcePath) {\n            bundle = [NSBundle bundleWithPath:resourcePath] ?: main;\n        }\n    });\n    UIImage * image = [self imageNamed:name\n                              inBundle:bundle\n         compatibleWithTraitCollection:nil] ?: [self imageNamed:[NSString stringWithFormat:@\"AntMarkdown.bundle/%@\", name]];\n    return image;\n}\n+ (instancetype)imageNamed_ant_bundle:(NSString *)bundlePath name:(NSString*)name\n{\n    \n    NSString* resourcePath = [[NSBundle mainBundle] pathForResource:bundlePath ofType:@\"bundle\"];\n    if (!resourcePath) {\n        return nil;\n    }\n    NSBundle* bundle = [NSBundle bundleWithPath:resourcePath];\n    UIImage *image = [UIImage imageNamed:name\n                                inBundle:bundle\n           compatibleWithTraitCollection:nil];\n    return image;\n}\n@end\n\n@implementation NSArray (AMUtils)\n\n- (NSArray<id> *)mapWithBlock_ant_mark:(id  _Nonnull (NS_NOESCAPE ^)(id _Nonnull))block {\n    NSMutableArray *arr = [NSMutableArray arrayWithCapacity:self.count];\n    [self enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {\n        [arr addObject:block(obj)];\n    }];\n    return [arr copy];\n}\n\n@end\n\n@implementation NSParagraphStyle (AMUtils)\n\n- (BOOL)isEqualToDiffableObject:(NSParagraphStyle *)object\n{\n    if (![object isKindOfClass:self.class]) {\n        return NO;\n    }\n    \n    if (![self isEqual:object]) {\n        NSMutableParagraphStyle *style = [self mutableCopy];\n        style.lineBreakMode = object.lineBreakMode;\n        return [style isEqual:object];\n    }\n    return YES;\n}\n\n@end\n\n@implementation NSDictionary (AMUtils)\n\n- (BOOL)includesDictionary_ant_mark:(NSDictionary *)otherDictionary\n{\n    if (otherDictionary.count > self.count) {\n        return NO;\n    }\n    __block BOOL included = YES;\n    [otherDictionary enumerateKeysAndObjectsWithOptions:NSEnumerationConcurrent\n                                             usingBlock:^(id  _Nonnull key, id  _Nonnull value, BOOL * _Nonnull stop) {\n        id obj = self[key];\n        if ([value isKindOfClass:[NSDictionary class]]) {\n            NSDictionary * dict = obj;\n            if ([dict isKindOfClass:[NSDictionary class]]) {\n                if (![dict includesDictionary_ant_mark:value]) {\n                    included = NO;\n                    *stop = YES;\n                }\n            } else {\n                included = NO;\n                *stop = YES;\n            }\n        } else {\n            if ([obj conformsToProtocol:@protocol(AMDiffable)] && [value conformsToProtocol:@protocol(AMDiffable)]) {\n                if (![(id<AMDiffable>)obj isEqualToDiffableObject:(id<AMDiffable>)value]) {\n                    included = NO;\n                    *stop = YES;\n                }\n            }\n            else if (![obj isEqual:value]) {\n                included = NO;\n                *stop = YES;\n            }\n        }\n    }];\n    return included;\n}\n- (NSString *)stringForKey_ap:(id)aKey {\n    return [self stringForKey_ap:aKey defaultValue:@\"\"];\n}\n- (NSString *)stringOrEmptyStringForKey_ap:(id)akey {\n    return [self stringForKey_ap:akey defaultValue:@\"\"];\n}\n- (NSString *)stringForKey_ap:(id)aKey defaultValue:(NSString *)defaultValue {\n    id object = [self objectForKey:aKey];\n    if (!object || object == [NSNull null]) {\n        return defaultValue;\n    }\n    if ([object isKindOfClass:[NSString class]]) {\n        return (NSString *)object;\n    }\n    return [object description];\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMViewAttachment.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <UIKit/UIKit.h>\n\n@protocol AMViewAttachment;\n\nNS_ASSUME_NONNULL_BEGIN\n\n@protocol AMAttachedView <NSObject>\n\n@optional\n@property (nonatomic, weak) id<AMViewAttachment> attachment;\n\n@end\n\n@protocol AMAttachmentUpdatable <NSObject>\n\n@optional\n- (void)updateAttachmentFromAttachment:(NSTextAttachment *)attach;\n\n@end\n\n@protocol AMViewAttachment <AMAttachmentUpdatable>\n\n- (nullable __kindof UIView<AMAttachedView> *)view;\n- (nullable __kindof UIView<AMAttachedView> *)viewIfLoaded;\n\n@optional\n- (NSAttributedString *)attributedString;\n\n- (void)setNeedsLayout;\n- (void)setNeedsDisplay;\n- (void)setForceNeedsLayout;\n\n@end\n\n/**\n \\c object is \\c NSAttributedString itself, \\c userInfo is:\n \\code\n @{\n NSAttachmentAttributeName: attachment instance,\n }\n \\endcode\n */\nUIKIT_EXTERN NSString *const AMTextAttachmentSizeDidUpdateNotification;\n\n\n@interface AMViewAttachment : NSTextAttachment <AMViewAttachment>\n@property (nonatomic, readonly, nullable) __kindof UIView<AMAttachedView> *view;\n@property (nonatomic) BOOL fullWidth;   // Default YES\n\n- (void)setNeedsUpdate DEPRECATED_MSG_ATTRIBUTE(\"use setNeedsLayout instead\");\n- (void)setNeedsLayout;\n- (void)setNeedsDisplay;\n\n- (NSAttributedString *)attributedString;\n\n- (CGSize)sizeThatFits:(CGSize)size;\n\n- (BOOL)isEqualToAttachment:(AMViewAttachment *)attach;\n\n- (void)updateAttachmentFromAttachment:(AMViewAttachment *)attach NS_REQUIRES_SUPER;\n\n@end\n\n\ntypedef void(^ButtonAction)(void);\n\n@interface AMButtonViewAttachment : AMViewAttachment\n@property (nonatomic, strong) UIButton *button;\n\n- (instancetype)initWithTitle:(NSString *)title action:(nullable ButtonAction)action NS_DESIGNATED_INITIALIZER;\n\n@end\n\n@interface UIView (AMAttachedView) <AMAttachedView>\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AMViewAttachment.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMViewAttachment.h\"\n#import \"CMImageTextAttachment.h\"\n#import \"AMUtils.h\"\n\nNSString *const AMTextAttachmentSizeDidUpdateNotification = @\"AMTextAttachmentSizeDidUpdateNotification\";\n\n@interface AMViewAttachment ()\n@property (nonatomic) CGRect cachedBounds;\n@end\n\n@implementation AMViewAttachment\n{\n    __weak NSTextContainer *_textContainer;\n}\n@dynamic view;\n\n- (void)dealloc\n{\n    if([NSThread isMainThread])\n    {\n        [self.viewIfLoaded removeFromSuperview];\n    }\n    else\n    {\n        UIView* view = self.viewIfLoaded;\n        dispatch_async(dispatch_get_main_queue(), ^{\n            [view removeFromSuperview];\n        });\n    }\n}\n\n- (instancetype)initWithData:(NSData *)contentData ofType:(NSString *)uti {\n    self = [super initWithData:nil ofType:nil];\n    if (self) {\n        self.fullWidth = YES;\n    }\n    return self;\n}\n\n- (__kindof UIView<AMAttachedView> *)view {\n    return nil;\n}\n\n- (__kindof UIView<AMAttachedView> *)viewIfLoaded\n{\n    return nil;\n}\n\n- (void)setNeedsUpdate\n{\n    [self setNeedsLayout];\n}\n\n- (void)setForceNeedsLayout\n{\n    NSLayoutManager *mgr = _textContainer.layoutManager;\n    if (mgr) {\n        self.cachedBounds = CGRectNull;\n        \n        dispatch_async(dispatch_get_main_queue(), ^{\n            [mgr setNeedsLayoutForAttachment:self];\n            \n            NSNotification *noti = [[NSNotification alloc] initWithName:AMTextAttachmentSizeDidUpdateNotification\n                                                                 object:mgr.textStorage\n                                                               userInfo:@{\n                NSAttachmentAttributeName: self,\n            }];\n            [[NSNotificationQueue defaultQueue] enqueueNotification:noti\n                                                       postingStyle:NSPostWhenIdle\n                                                       coalesceMask:NSNotificationCoalescingOnSender\n                                                           forModes:nil];\n        });\n    }\n}\n\n- (void)setNeedsLayout\n{\n    if (CGRectIsNull(self.cachedBounds)) {\n        return;\n    }\n    [self setForceNeedsLayout];\n}\n\n- (void)setNeedsDisplay\n{\n    [_textContainer.layoutManager setNeedsDisplayForAttachment:self];\n}\n\n- (BOOL)isEqual:(nullable id)object {\n    if (object == nil) {\n        return NO;\n    }\n    \n    if (self == object) {\n        return YES;\n    }\n    \n    if (![object isKindOfClass:[self class]]) {\n        return NO;\n    }\n    \n    return [self isEqualToAttachment:(AMViewAttachment *)object];\n}\n\n- (BOOL)isEqualToAttachment:(AMViewAttachment *)attach\n{\n    return self.fullWidth == attach.fullWidth && [self.view isEqual:attach.view];\n}\n\n- (void)updateAttachmentFromAttachment:(AMViewAttachment *)attach\n{\n    self.fullWidth = attach.fullWidth;\n    self.cachedBounds = CGRectZero;\n}\n\n- (NSAttributedString *)attributedString\n{\n    NSMutableAttributedString *attr = [[NSAttributedString attributedStringWithAttachment:self] mutableCopy];\n    if (self.fullWidth) {\n        NSParagraphStyle *paragraph = ({\n            NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];\n            style.paragraphSpacing = 0;\n            style.paragraphSpacingBefore = 10;\n            style.lineSpacing = 0;\n            style.lineHeightMultiple = 1;\n            style.lineBreakStrategy = NSLineBreakStrategyPushOut;\n            style.firstLineHeadIndent = 0;\n            style;\n        });\n\n        [attr appendAttributedString:[[NSAttributedString alloc] initWithString:@\"\\n\"]];\n        [attr addAttribute:NSParagraphStyleAttributeName value:paragraph range:NSMakeRange(0, attr.length)];\n    }\n    return [attr copy];\n}\n\n- (CGSize)sizeThatFits:(CGSize)size\n{\n    return [self.view sizeThatFits:size];\n}\n\n- (UIImage *)imageForBounds:(CGRect)imageBounds\n              textContainer:(NSTextContainer *)textContainer\n             characterIndex:(NSUInteger)charIndex {\n    return nil;\n}\n\n- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer\n                      proposedLineFragment:(CGRect)lineFrag\n                             glyphPosition:(CGPoint)position\n                            characterIndex:(NSUInteger)charIndex {\n    _textContainer = textContainer;\n    \n    const CGFloat width = textContainer.size.width - textContainer.lineFragmentPadding * 2;\n    \n    if (!CGRectIsEmpty(self.cachedBounds) && (!self.fullWidth || self.cachedBounds.size.width == width)) {\n        return self.cachedBounds;\n    }\n    CGRect rect = [super attachmentBoundsForTextContainer:textContainer\n                                     proposedLineFragment:lineFrag\n                                            glyphPosition:position\n                                           characterIndex:charIndex];\n    rect.size = [self sizeThatFits:CGSizeMake(width, CGFLOAT_MAX)];\n    if (self.fullWidth) {\n        rect.size.width = width;\n    }\n    self.cachedBounds = rect;\n    return rect;\n}\n\n@end\n\n@interface AMButtonViewAttachment ()\n@property (nonatomic, copy, nullable) ButtonAction buttonAction;\n@end\n\n@implementation AMButtonViewAttachment\n\n- (instancetype)initWithData:(NSData *)contentData ofType:(NSString *)uti {\n    return [self initWithTitle:@\"\" action:nil];\n}\n\n- (instancetype)initWithTitle:(NSString *)title action:(ButtonAction)action\n{\n    self = [super initWithData:nil ofType:nil];\n    if (self) {\n        self.fullWidth = NO;\n        self.buttonAction = action;\n        self.button = [UIButton buttonWithType:UIButtonTypeCustom];\n        self.button.titleLabel.font = [UIFont systemFontOfSize:10];\n        [self.button setTitle:title forState:UIControlStateNormal];\n        [self.button setTitleColor:[UIColor colorWithHex_ant_mark:0x1F3B63]\n                          forState:UIControlStateNormal];\n        [self.button addTarget:self\n                        action:@selector(onButton:)\n              forControlEvents:UIControlEventTouchUpInside];\n        [self.button sizeToFit];\n    }\n    return self;\n}\n\n- (__kindof UIView<AMAttachedView> *)view\n{\n    return self.button;\n}\n\n- (void)onButton:(id)sender\n{\n    !self.buttonAction ?: self.buttonAction();\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/AntMarkdown.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n\n#import <UIKit/UIKit.h>\n#import <AntMarkdown/AMAttributedStringRenderer.h>\n#import <AntMarkdown/AMBlockMathAttachment.h>\n#import <AntMarkdown/AMCodeHighlighter.h>\n#import <AntMarkdown/AMCodeViewAttachment.h>\n#import <AntMarkdown/AMDrawable.h>\n#import <AntMarkdown/AMGradient.h>\n#import <AntMarkdown/AMGradientView.h>\n#import <AntMarkdown/AMHTMLTransformer.h>\n#import <AntMarkdown/AMImageTextAttachment.h>\n#import <AntMarkdown/AMIconLinkAttachment.h>\n#import <AntMarkdown/AMInlineMathAttachment.h>\n#import <AntMarkdown/AMLayoutManager.h>\n#import <AntMarkdown/AMMarkdownCodeView.h>\n#import <AntMarkdown/AMMarkdownTableLayout.h>\n#import <AntMarkdown/AMMarkdownTableView.h>\n#import <AntMarkdown/AMTableViewAttachment.h>\n#import <AntMarkdown/AMTextBackground.h>\n#import <AntMarkdown/AMTextStyles.h>\n#import <AntMarkdown/AMUnderline.h>\n#import <AntMarkdown/AMUtils.h>\n#import <AntMarkdown/AMViewAttachment.h>\n#import <AntMarkdown/NSMutableAttributedString+AntMarkdown.h>\n#import <AntMarkdown/NSString+AntMarkdown.h>\n#import <AntMarkdown/UILabel+AntMarkdown.h>\n#import <AntMarkdown/UITextView+AntMarkdown.h>\n#import <AntMarkdown/CMAttributedStringRenderer.h>\n#import <AntMarkdown/CMAttributeRun.h>\n#import <AntMarkdown/CMBlockTextAttachment.h>\n#import <AntMarkdown/CMCascadingAttributeStack.h>\n#import <AntMarkdown/CMDocument+AttributedStringAdditions.h>\n#import <AntMarkdown/CMDocument+HTMLAdditions.h>\n#import <AntMarkdown/CMDocument.h>\n#import <AntMarkdown/CMHTMLElement.h>\n#import <AntMarkdown/CMHTMLElementTransformer.h>\n#import <AntMarkdown/CMHTMLRenderer.h>\n#import <AntMarkdown/CMHTMLScriptTransformer.h>\n#import <AntMarkdown/CMHTMLStrikethroughTransformer.h>\n#import <AntMarkdown/CMHTMLSubscriptTransformer.h>\n#import <AntMarkdown/CMHTMLSuperscriptTransformer.h>\n#import <AntMarkdown/CMHTMLUnderlineTransformer.h>\n#import <AntMarkdown/CMHTMLUtilities.h>\n#import <AntMarkdown/CMImageTextAttachment.h>\n#import <AntMarkdown/CMInlineTextAttachment.h>\n#import <AntMarkdown/CMIterator.h>\n#import <AntMarkdown/CMNode+Table.h>\n#import <AntMarkdown/CMNode.h>\n#import <AntMarkdown/CMParser.h>\n#import <AntMarkdown/CMPlatformDefines.h>\n#import <AntMarkdown/CMStack.h>\n#import <AntMarkdown/CMTextAttributes.h>\n#import <AntMarkdown/CocoaMarkdown.h>\n#import <AntMarkdown/Ono.h>\n\n//! Project version number for AntMarkdown.\nFOUNDATION_EXPORT double AntMarkdownVersionNumber;\n\n//! Project version string for AntMarkdown.\nFOUNDATION_EXPORT const unsigned char AntMarkdownVersionString[];\n\n\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/NSMutableAttributedString+AntMarkdown.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface NSMutableAttributedString (AntMarkdown)\n\n- (void)setAttributedStringPartialUpdate_ant_mark:(NSAttributedString *)attrString;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/NSMutableAttributedString+AntMarkdown.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"NSMutableAttributedString+AntMarkdown.h\"\n#import \"AMLayoutManager.h\"\n#import \"AMViewAttachment.h\"\n#import \"AMUtils.h\"\n\n@implementation NSMutableAttributedString (AntMarkdown)\n\n- (void)setAttributedStringPartialUpdate_ant_mark:(NSAttributedString *)attributedText {    \n    __block NSUInteger location = 0;\n    // find the diffrent location,from ending to beginning\n    [self enumerateAttributesInRange:NSMakeRange(0, MIN(self.length, attributedText.length))\n                             options:NSAttributedStringEnumerationReverse\n                          usingBlock:^(NSDictionary<NSAttributedStringKey,id> * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) {\n        if ([[attributedText attributedSubstringFromRange:range] isEqualToAttributedString:[self attributedSubstringFromRange:range]]) {\n            location = NSMaxRange(range);\n            *stop = YES;\n        }\n    }];\n    \n    // update at the diffrent point\n    [self beginEditing];\n    if (attributedText.length > location) {\n        [attributedText enumerateAttributesInRange:NSMakeRange(location, attributedText.length - location)\n                                           options:0\n                                        usingBlock:^(NSDictionary<NSAttributedStringKey,id> * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) {\n            NSRange currentRange = range;\n            // the length of the string is long enough, replace it\n            if (self.length > range.location) {\n                NSDictionary<NSAttributedStringKey,id> * currentAttrs = [self attributesAtIndex:range.location\n                                                                          longestEffectiveRange:&currentRange\n                                                                                        inRange:NSMakeRange(range.location, MIN(range.length, self.length - range.location))];\n                NSTextAttachment *oldAttach = currentAttrs[NSAttachmentAttributeName];\n                NSTextAttachment *newAttach = attrs[NSAttachmentAttributeName];\n                \n                if ((range.location < currentRange.location || NSMaxRange(range) > NSMaxRange(currentRange)) || ![currentAttrs includesDictionary_ant_mark:attrs]) {\n                    BOOL shouldReplace = YES;\n                    if ([oldAttach conformsToProtocol:@protocol(AMAttachmentUpdatable)]) {\n                        id<AMAttachmentUpdatable> attach = (id<AMAttachmentUpdatable>)oldAttach;\n                        if ([attach respondsToSelector:@selector(updateAttachmentFromAttachment:)] && [newAttach isKindOfClass:attach.class]) {\n                            shouldReplace = currentRange.length != range.length;\n                            [attach updateAttachmentFromAttachment:newAttach];\n                        }\n                    }\n                    \n                    if (shouldReplace) {\n                        \n                        [self replaceCharactersInRange:NSMakeRange(range.location, self.length - range.location)\n                                  withAttributedString:[attributedText attributedSubstringFromRange:range]];\n                    }\n                }\n            } else {    // the length of the string is not long enough, append it\n                [self appendAttributedString:[attributedText attributedSubstringFromRange:range]];\n            }\n        }];\n    }\n    if (attributedText.length < self.length) {\n        NSRange rangeToDelete = NSMakeRange(attributedText.length, self.length - attributedText.length);\n        [self deleteCharactersInRange:rangeToDelete];\n    }\n    [self endEditing];\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/NSString+AntMarkdown.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n\n@class AMTextStyles;\n@protocol CMAttributedStringRendererDelegate;\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface NSString (AntMarkdown)\n\n- (NSAttributedString *)markdownToAttributedString_ant_mark;\n- (NSAttributedString *)markdownToAttributedStringWithStyles_ant_mark:(AMTextStyles *)styles;\n- (NSAttributedString *)markdownToAttributedStringWithStyles_ant_mark:(AMTextStyles *)styles delegate:(nullable id<CMAttributedStringRendererDelegate>)delegate;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/NSString+AntMarkdown.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"NSString+AntMarkdown.h\"\n#import \"AMTextStyles.h\"\n#import \"AMAttributedStringRenderer.h\"\n\nconst CMDocumentOptions AMDefaultDocumentOptions \n= CMDocumentOptionsNormalize | CMDocumentOptionsUnsafe | CMDocumentOptionsFootNotes\n| CMDocumentOptionsFootNotesWithoutDefinition | CMDocumentOptionsStrikeThrough;\n\n@implementation NSString (AntMarkdown)\n\n- (NSAttributedString *)markdownToAttributedString_ant_mark\n{\n    return [self markdownToAttributedStringWithStyles_ant_mark:[AMTextStyles defaultStyles]];\n}\n\n- (NSAttributedString *)markdownToAttributedStringWithStyles_ant_mark:(AMTextStyles *)styles\n{\n    CMDocument *document = [[CMDocument alloc] initWithString:self options:AMDefaultDocumentOptions];\n    \n    AMAttributedStringRenderer *renderer = [[AMAttributedStringRenderer alloc] initWithDocument:document\n                                                                                     attributes:styles];\n    return renderer.render;\n}\n- (NSAttributedString *)markdownToAttributedStringWithStyles_ant_mark:(AMTextStyles *)styles delegate:(id<CMAttributedStringRendererDelegate>)delegate;\n{\n    CMDocument *document = [[CMDocument alloc] initWithString:self options:AMDefaultDocumentOptions];\n    \n    AMAttributedStringRenderer *renderer = [[AMAttributedStringRenderer alloc] initWithDocument:document\n                                                                                     attributes:styles delegate:delegate];\n    NSAttributedString* rst = renderer.render;\n    [delegate notifyNodeUpdate:[renderer clickableObjs]];\n    return rst;\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/UILabel+AntMarkdown.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <UIKit/UIKit.h>\n\n@class AMTextStyles;\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface UILabel (AntMarkdown)\n\n- (void)setAttributedText_ant_mark:(NSAttributedString *)attributedText;\n\n- (void)setMarkdownText_ant_mark:(NSString *)text;\n\n- (void)setMarkdownText_ant_mark:(NSString *)text styles:(AMTextStyles *)styles;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/UILabel+AntMarkdown.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"UILabel+AntMarkdown.h\"\n#import \"NSString+AntMarkdown.h\"\n#import \"CocoaMarkdown.h\"\n#import \"AMTextStyles.h\"\n#import \"AMAttributedStringRenderer.h\"\n#import \"AMHTMLTransformer.h\"\n#import \"AMViewAttachment.h\"\n\n@implementation UILabel (AntMarkdown)\n\n- (void)setAttributedText_ant_mark:(NSAttributedString *)attributedText {\n    [self.attributedText enumerateAttribute:NSAttachmentAttributeName\n                                    inRange:NSMakeRange(0, self.attributedText.length)\n                                    options:0\n                                 usingBlock:^(id  _Nullable value, NSRange range, BOOL * _Nonnull stop) {\n        if ([value conformsToProtocol:@protocol(AMViewAttachment)]) {\n            id<AMViewAttachment> attach = (id<AMViewAttachment>)value;\n            UIView<AMViewAttachment> *view = [attach view];\n            if (view.superview == self) {\n                if ([view respondsToSelector:@selector(setAttachment:)]) {\n                    view.attachment = nil;\n                }\n                [view removeFromSuperview];\n            }\n        }\n    }];\n    \n    [self setAttributedText:attributedText];\n    \n    [attributedText enumerateAttribute:NSAttachmentAttributeName\n                               inRange:NSMakeRange(0, attributedText.length)\n                               options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired\n                            usingBlock:^(id  _Nullable value, NSRange range, BOOL * _Nonnull stop) {\n        if ([value conformsToProtocol:@protocol(AMViewAttachment)]) {\n            id<AMViewAttachment> attach = (id<AMViewAttachment>)value;\n            UIView<AMViewAttachment> *view = [attach view];\n            if (view) {\n                if ([view respondsToSelector:@selector(setAttachment:)]) {\n                    view.attachment = attach;\n                }\n                view.hidden = YES;\n                if (view.superview != self) {\n                    [self addSubview:view];\n                }\n            }\n        }\n    }];\n}\n\n- (void)setMarkdownText_ant_mark:(NSString *)text {\n    [self setMarkdownText_ant_mark:text styles:[AMTextStyles defaultStyles]];\n}\n\n- (void)setMarkdownText_ant_mark:(NSString *)text styles:(AMTextStyles *)styles {\n    [self setAttributedText_ant_mark:[text markdownToAttributedStringWithStyles_ant_mark:styles]];\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/UITextView+AntMarkdown.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <UIKit/UIKit.h>\n\n@class AMTextStyles;\n@protocol CMAttributedStringRendererDelegate;\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface UITextView (AntMarkdown)\n\n- (instancetype)initWithFrame_ant_mark:(CGRect)frame;\n\n- (instancetype)initWithFrame_ant_mark:(CGRect)frame delegate:(id<CMAttributedStringRendererDelegate>)delegate;\n\n- (void)setAttributedText_ant_mark:(nullable NSAttributedString *)attributedText;\n\n- (void)setAttributedTextPartialUpdate_ant_mark:(NSAttributedString *)attributedText;\n\n- (void)setAttributedTextPartialUpdate_ant_mark:(NSAttributedString *)attributedText animated:(BOOL)animated;\n\n- (void)setMarkdownText_ant_mark:(NSString *)text;\n\n- (void)setMarkdownText_ant_mark:(NSString *)text styles:(AMTextStyles *)styles;\n\n- (void)setMarkdownTextPartialUpdate_ant_mark:(NSString *)text styles:(AMTextStyles *)styles;\n\n- (void)setMarkdownTextPartialUpdate_ant_mark:(NSString *)text styles:(AMTextStyles *)styles animated:(BOOL)animated;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/AntMarkdown/Sources/Public/UITextView+AntMarkdown.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"UITextView+AntMarkdown.h\"\n#import \"NSString+AntMarkdown.h\"\n#import \"CocoaMarkdown.h\"\n#import \"AMTextStyles.h\"\n#import \"AMAttributedStringRenderer.h\"\n#import \"AMHTMLTransformer.h\"\n#import \"AMLayoutManager.h\"\n#import \"AMViewAttachment.h\"\n#import \"AMUtils.h\"\n#import \"AMGradientLayer.h\"\n#import \"AMCodeViewAttachment.h\"\n\n@interface _AMAnimationDelegate : NSObject <CAAnimationDelegate>\n@property (nonatomic, copy) void(^didStartBlock)(CAAnimation *anim);\n@property (nonatomic, copy) void(^didEndBlock)(CAAnimation *anim, BOOL flag);\n@end\n\n@implementation _AMAnimationDelegate\n\n+ (instancetype)delegateWithStart:(void(^)(CAAnimation *anim))start end:(void(^)(CAAnimation *anim, BOOL flag))end {\n    _AMAnimationDelegate *obj = [_AMAnimationDelegate new];\n    obj.didStartBlock = start;\n    obj.didEndBlock = end;\n    return obj;\n}\n\n+ (instancetype)delegateWithEnd:(void(^)(CAAnimation *anim, BOOL flag))end {\n    _AMAnimationDelegate *obj = [_AMAnimationDelegate new];\n    obj.didEndBlock = end;\n    return obj;\n}\n\n#pragma mark - CAAnimationDelegate\n\n- (void)animationDidStart:(CAAnimation *)anim\n{\n    !self.didStartBlock ?: self.didStartBlock(anim);\n}\n\n- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag\n{\n    !self.didEndBlock ?: self.didEndBlock(anim, flag);\n}\n\n@end\n\n@implementation UITextView (AntMarkdown)\n\n- (instancetype)initWithFrame_ant_mark:(CGRect)frame {\n    NSTextContainer *container = [[NSTextContainer alloc] init];\n    AMLayoutManager *mgr = [AMLayoutManager new];\n    NSTextStorage *storage = [[NSTextStorage alloc] init];\n    [storage addLayoutManager:mgr];\n    [mgr addTextContainer:container];\n    \n    self = [self initWithFrame:frame textContainer:container];\n    if (self) {\n        self.editable = NO;\n        self.selectable = NO;\n        self.textContainerInset = UIEdgeInsetsZero;\n        self.textContainer.lineFragmentPadding = 0;\n        if (@available(iOS 16.0, *)) {\n            self.findInteractionEnabled = NO;\n        } else {\n            // Fallback on earlier versions\n        }\n    }\n    return self;\n}\n- (instancetype)initWithFrame_ant_mark:(CGRect)frame delegate:(id<CMAttributedStringRendererDelegate>)delegate {\n    NSTextContainer *container = [[NSTextContainer alloc] init];\n    AMLayoutManager *mgr = [AMLayoutManager new];\n    mgr.delegate = delegate;\n    NSTextStorage *storage = [[NSTextStorage alloc] init];\n    [storage addLayoutManager:mgr];\n    [mgr addTextContainer:container];\n    \n    self = [self initWithFrame:frame textContainer:container];\n    if (self) {\n        self.editable = NO;\n        self.selectable = NO;\n        self.textContainerInset = UIEdgeInsetsZero;\n        self.textContainer.lineFragmentPadding = 0;\n        if (@available(iOS 16.0, *)) {\n            self.findInteractionEnabled = NO;\n        } else {\n            // Fallback on earlier versions\n        }\n    }\n    \n    return self;\n}\n- (void)setAttributedTextPartialUpdate_ant_mark:(NSAttributedString *)attributedText\n{\n    [self setAttributedTextPartialUpdate_ant_mark:attributedText animated:NO];\n}\n\n- (void)setAttributedTextPartialUpdate_ant_mark:(NSAttributedString *)attributedText animated:(BOOL)animated {\n    const NSUInteger textLength = self.textStorage.length;\n    \n    __block NSUInteger location = 0;\n    // find the diffrent location,from ending to beginning\n    [self.textStorage enumerateAttributesInRange:NSMakeRange(0, MIN(textLength, attributedText.length))\n                                       options:NSAttributedStringEnumerationReverse\n                                    usingBlock:^(NSDictionary<NSAttributedStringKey,id> * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) {\n        if ([[attributedText attributedSubstringFromRange:range] isEqualToAttributedString:[self.textStorage attributedSubstringFromRange:range]]) {\n            location = NSMaxRange(range);\n            *stop = YES;\n        }\n    }];\n    \n    // update at the diffrent point\n    [self.textStorage beginEditing];\n    if (attributedText.length > location) {\n        [attributedText enumerateAttributesInRange:NSMakeRange(location, attributedText.length - location)\n                                           options:0\n                                        usingBlock:^(NSDictionary<NSAttributedStringKey,id> * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) {\n            NSRange currentRange = range;\n            // the length of the string is long enough, replace it\n            if (self.textStorage.mutableString.length > range.location) {\n                NSDictionary<NSAttributedStringKey,id> * currentAttrs = [self.textStorage attributesAtIndex:range.location\n                                                                                      longestEffectiveRange:&currentRange\n                                                                                                    inRange:NSMakeRange(range.location, MIN(range.length, self.textStorage.length - range.location))];\n                NSTextAttachment *oldAttach = currentAttrs[NSAttachmentAttributeName];\n                NSTextAttachment *newAttach = attrs[NSAttachmentAttributeName];\n                \n                if ((range.location < currentRange.location || NSMaxRange(range) > NSMaxRange(currentRange)) || ![currentAttrs includesDictionary_ant_mark:attrs]) {\n                    BOOL shouldReplace = YES;\n                    if ([oldAttach conformsToProtocol:@protocol(AMAttachmentUpdatable)]) {\n                        id<AMAttachmentUpdatable> attach = (id<AMAttachmentUpdatable>)oldAttach;\n                        if ([attach respondsToSelector:@selector(updateAttachmentFromAttachment:)] &&\n                            [newAttach isKindOfClass:attach.class]) {\n                            shouldReplace = currentRange.length != range.length;\n                          \n                            if ([attach isKindOfClass:AMCodeViewAttachment.class]) {\n                                dispatch_async(dispatch_get_main_queue(), ^{\n                                    [attach updateAttachmentFromAttachment:newAttach];\n                                });\n                            } else {\n                                [attach updateAttachmentFromAttachment:newAttach];\n                            }\n                        }\n                    }\n                    \n                    if (shouldReplace) {\n                        if ([oldAttach conformsToProtocol:@protocol(AMViewAttachment)]) {\n                            id<AMViewAttachment> attach = (id<AMViewAttachment>)oldAttach;\n                            UIView<AMViewAttachment> *view = [attach view];\n                            if (view.superview == self) {\n                                if ([view respondsToSelector:@selector(setAttachment:)]) {\n                                    view.attachment = nil;\n                                }\n                                [view removeFromSuperview];\n                            }\n                        }\n                        NSRange rangeToReplace = NSMakeRange(range.location, self.textStorage.length - range.location);\n                        \n                        [self.textStorage enumerateAttribute:NSAttachmentAttributeName\n                                                     inRange:rangeToReplace\n                                                     options:0\n                                                  usingBlock:^(id  _Nullable value, NSRange range, BOOL * _Nonnull stop) {\n                            NSTextAttachment *oldAttach = value;\n                            if ([oldAttach conformsToProtocol:@protocol(AMViewAttachment)]) {\n                                id<AMViewAttachment> attach = (id<AMViewAttachment>)oldAttach;\n                                UIView<AMViewAttachment> *view = [attach view];\n                                if (view.superview == self) {\n                                    if ([view respondsToSelector:@selector(setAttachment:)]) {\n                                        view.attachment = nil;\n                                    }\n                                    [view removeFromSuperview];\n                                }\n                            }\n                        }];\n                        \n                        [self.textStorage replaceCharactersInRange:rangeToReplace\n                                              withAttributedString:[attributedText attributedSubstringFromRange:range]];\n                        \n                        if ([newAttach conformsToProtocol:@protocol(AMViewAttachment)]) {\n                            id<AMViewAttachment> attach = (id<AMViewAttachment>)newAttach;\n                            UIView<AMViewAttachment> *view = [attach view];\n                            if (view) {\n                                if ([view respondsToSelector:@selector(setAttachment:)]) {\n                                    view.attachment = attach;\n                                }\n                                view.hidden = YES;\n                                if (view.superview != self) {\n                                    [self addSubview:view];\n                                }\n                            }\n                        }\n                    }\n                }\n            } else {    // the length of the string is not long enough, append it\n                [self.textStorage appendAttributedString:[attributedText attributedSubstringFromRange:range]];\n                \n                NSTextAttachment *newAttach = attrs[NSAttachmentAttributeName];\n                if ([newAttach conformsToProtocol:@protocol(AMViewAttachment)]) {\n                    id<AMViewAttachment> attach = (id<AMViewAttachment>)newAttach;\n                    UIView<AMViewAttachment> *view = [attach view];\n                    if (view) {\n                        if ([view respondsToSelector:@selector(setAttachment:)]) {\n                            view.attachment = attach;\n                        }\n                        view.hidden = YES;\n                        if (view.superview != self) {\n                            [self addSubview:view];\n                        }\n                    }\n                }\n            }\n        }];\n    }\n    if (attributedText.length < self.textStorage.length) {\n        NSRange rangeToDelete = NSMakeRange(attributedText.length, self.textStorage.length - attributedText.length);\n        [self.textStorage enumerateAttribute:NSAttachmentAttributeName\n                                     inRange:rangeToDelete\n                                     options:0\n                                  usingBlock:^(id  _Nullable value, NSRange range, BOOL * _Nonnull stop) {\n            if ([value conformsToProtocol:@protocol(AMViewAttachment)]) {\n                id<AMViewAttachment> attach = (id<AMViewAttachment>)value;\n                UIView<AMViewAttachment> *view = [attach view];\n                if (view.superview == self) {\n                    if ([view respondsToSelector:@selector(setAttachment:)]) {\n                        view.attachment = nil;\n                    }\n                    [view removeFromSuperview];\n                }\n            }\n        }];\n        [self.textStorage deleteCharactersInRange:rangeToDelete];\n    }\n    [self.textStorage endEditing];\n\n    \n    NSInteger totalCount = [attributedText length];\n    if (animated) {\n        CALayer *mask = self.layer.mask;\n        if (!mask) {\n            mask = [CALayer layer];\n            mask.actions = @{\n                KEYPATH(CALayer *, bounds): [NSNull null],\n                KEYPATH(CALayer *, position): [NSNull null],\n                KEYPATH(CALayer *, frame): [NSNull null],\n                KEYPATH(CALayer *, sublayerTransform): [NSNull null],\n                @\"transition\": [NSNull null],\n            };\n            self.layer.mask = mask;\n            \n            CALayer *sub = [CALayer layer];\n            sub.backgroundColor = [UIColor blackColor].CGColor;\n            sub.actions = @{\n                KEYPATH(CALayer *, bounds): [NSNull null],\n                KEYPATH(CALayer *, position): [NSNull null],\n                KEYPATH(CALayer *, frame): [NSNull null],\n                @\"transition\": [NSNull null],\n            };\n            [mask addSublayer:sub];\n        }\n        CALayer *firstSublayer = mask.sublayers.firstObject;\n        // make a black canvas，the mask part is not transparent\n        mask.frame = CGRectMake(self.contentOffset.x, self.contentOffset.y, self.bounds.size.width, self.bounds.size.height);\n        // sublayer transform\n        mask.sublayerTransform = CATransform3DMakeTranslation(self.contentOffset.x, -self.contentOffset.y, 0);\n        // compute change area\n        NSRange changedRange = NSMakeRange(location, self.textStorage.length - location);\n        NSLog(@\"=fade= begin animated totalCount = %ld, changedRange = %@\",totalCount, NSStringFromRange(changedRange));\n        if (changedRange.length == 0) {\n            firstSublayer.frame = self.layer.mask.bounds;\n        }\n        __block BOOL hasViewAttachment = NO;\n        [self.textStorage enumerateAttribute:NSAttachmentAttributeName\n                                     inRange:changedRange\n                                     options:NSAttributedStringEnumerationReverse\n                                  usingBlock:^(id  _Nullable value, NSRange range, BOOL * _Nonnull stop) {\n            if ([value conformsToProtocol:@protocol(AMViewAttachment)]) {\n                hasViewAttachment = YES;\n                *stop = YES;\n            }\n        }];\n        \n        __block NSInteger lineIndex = 0;\n        // traverse area in each line\n        [self.layoutManager enumerateLineFragmentsForGlyphRange:changedRange\n                                                     usingBlock:^(CGRect rect, CGRect usedRect, NSTextContainer * _Nonnull textContainer, NSRange glyphRange, BOOL * _Nonnull stop) {\n            \n            if (!textContainer) {\n                rect = [self.layoutManager lineFragmentRectForGlyphAtIndex:glyphRange.location effectiveRange:nil withoutAdditionalLayout:NO];\n                usedRect = [self.layoutManager lineFragmentUsedRectForGlyphAtIndex:glyphRange.location effectiveRange:nil withoutAdditionalLayout:NO];\n                if (CGRectEqualToRect(rect, CGRectZero)) {\n                    firstSublayer.frame = self.layer.mask.bounds;\n                    return;\n                }\n            }\n            lineIndex++;\n            // it is the last line\n            if (NSMaxRange(changedRange) == NSMaxRange(glyphRange)) {\n                if (hasViewAttachment) {\n                    CGRect maskRect = CGRectMake(0, 0, rect.size.width, CGRectGetMaxY(rect));\n                    firstSublayer.frame = maskRect;\n                    return;\n                }\n                \n                // the front part of the last line is transparent\n                CGRect maskRect = CGRectMake(0, 0, rect.size.width, CGRectGetMinY(rect));\n                firstSublayer.frame = maskRect;\n                \n                CALayer *layerInSameLine = nil;\n                \n                NSMutableArray* lineSubLayer = [NSMutableArray array];\n                \n                NSArray *sublayers = [mask.sublayers copy];\n                for (CALayer *l in sublayers) {\n                    CGRect lineRect = CGRectMake(floor(rect.origin.x), floor(rect.origin.y), ceil(rect.size.width), ceil(rect.size.height+1));\n                    lineRect.size.width = ceil(CGRectGetMaxX(usedRect)) - CGRectGetMinX(lineRect);\n                    if ([l isKindOfClass:[AMGradientLayer class]]) {\n                        if (CGRectContainsRect(lineRect, l.frame)) {\n                            [lineSubLayer addObject:l];\n                            if (!layerInSameLine) {\n                                layerInSameLine = l;\n                            } else if (CGRectGetMaxX(l.frame) > CGRectGetMaxX(layerInSameLine.frame)) {\n                                layerInSameLine = l;\n                            }\n                        } else {\n                            [l removeFromSuperlayer];\n                        }\n                    }\n                }\n                \n                // make gradient from the begining of the lase line\n                CGFloat x = rect.origin.x;\n                // if there is a gradient layer already, then make gradient from the right of the layer\n                if (layerInSameLine) {\n                    x = CGRectGetMaxX(layerInSameLine.frame);\n                }\n                \n                \n                CGRect newLayerFrame = CGRectMake(x, rect.origin.y,\n                                                  CGRectGetMaxX(usedRect) - x,\n                                                  rect.size.height);\n                \n                BOOL hasSameFadeLayer = NO;\n                // if there is a same layer, then drop it\n                for (CALayer *l in lineSubLayer) {\n                        if ([l isKindOfClass:[AMGradientLayer class]]) {\n                            if(CGRectEqualToRect(CGRectIntegral(l.frame), CGRectIntegral(newLayerFrame)))\n                            {\n                                hasSameFadeLayer = YES;\n                                break;\n                            }\n                        }\n                }\n\n                NSLog(@\"=fade= hasSameFadeLayer = %d, lineHasLayerCount = %ld\",hasSameFadeLayer,[lineSubLayer count]);\n                \n                if(!hasSameFadeLayer\n                   && newLayerFrame.size.width > 0.001\n                   && newLayerFrame.size.height > 0.001)\n                {\n                    AMGradientLayer *layer = [AMGradientLayer layer];\n                    layer.lineIndex = lineIndex;\n                    layer.startPoint = CGPointMake(0, 0.5);\n                    layer.endPoint = CGPointMake(1, 0.5);\n                    layer.frame = newLayerFrame;\n                    layer.colors = @[(id)[UIColor blueColor].CGColor, (id)[UIColor blueColor].CGColor];\n                    @weakify(layer);\n                    [layer addAnimation:({\n                        CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@\"colors\"];\n                        anim.values = @[\n                            @[(id)[UIColor clearColor].CGColor, (id)[UIColor clearColor].CGColor],\n                            @[(id)[UIColor blueColor].CGColor, (id)[UIColor clearColor].CGColor],\n                            @[(id)[UIColor blueColor].CGColor, (id)[UIColor blueColor].CGColor]];\n                        anim.calculationMode = kCAAnimationLinear;\n                        anim.fillMode = kCAFillModeBoth;\n                        anim.duration = 0.15;\n                        anim.removedOnCompletion = YES;\n                        anim.delegate = [_AMAnimationDelegate delegateWithEnd:^(CAAnimation *anim, BOOL flag) {\n                            @strongify(layer);\n                            layer.isFadeComplete = YES;\n                            if (flag) {\n                                // [layer removeFromSuperlayer];\n                            }\n                        }];\n                        anim;\n                    }) forKey:@\"fadeIn\"];\n                    [mask addSublayer:layer];\n                    NSLog(@\"=fade= addSublayer = %@, lineIndex = %ld, chRange = %@, text = %@\",NSStringFromCGRect(newLayerFrame),lineIndex,NSStringFromRange(changedRange),[[attributedText attributedSubstringFromRange:changedRange] string]);\n                }\n            }\n        }];\n    } else {\n        self.layer.mask = nil;\n    }\n}\n\n- (void)setAttributedText_ant_mark:(NSAttributedString *)attributedText {\n    \n    [self.attributedText enumerateAttribute:NSAttachmentAttributeName\n                                    inRange:NSMakeRange(0, self.attributedText.length)\n                                    options:0\n                                 usingBlock:^(id  _Nullable value, NSRange range, BOOL * _Nonnull stop) {\n        if ([value conformsToProtocol:@protocol(AMViewAttachment)]) {\n            id<AMViewAttachment> attach = (id<AMViewAttachment>)value;\n            UIView<AMViewAttachment> *view = [attach view];\n            if (view.superview == self) {\n                if ([view respondsToSelector:@selector(setAttachment:)]) {\n                    view.attachment = nil;\n                }\n                [view removeFromSuperview];\n            }\n        }\n    }];\n\n    self.layer.mask = nil;\n    \n    [self setAttributedText:attributedText];\n    \n    [attributedText enumerateAttribute:NSAttachmentAttributeName\n                               inRange:NSMakeRange(0, attributedText.length)\n                               options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired\n                            usingBlock:^(id  _Nullable value, NSRange range, BOOL * _Nonnull stop) {\n        if ([value conformsToProtocol:@protocol(AMViewAttachment)]) {\n            id<AMViewAttachment> attach = (id<AMViewAttachment>)value;\n            UIView<AMViewAttachment> *view = [attach view];\n            if (view) {\n                if ([view respondsToSelector:@selector(setAttachment:)]) {\n                    view.attachment = attach;\n                }\n                view.hidden = YES;\n                if (view.superview != self) {\n                    [self addSubview:view];\n                }\n            }\n        }\n    }];\n}\n\n- (void)setMarkdownText_ant_mark:(NSString *)text {\n    [self setMarkdownText_ant_mark:text styles:[AMTextStyles defaultStyles]];\n}\n\n- (void)setMarkdownText_ant_mark:(NSString *)text styles:(AMTextStyles *)styles {\n    [self setAttributedText_ant_mark:[text markdownToAttributedStringWithStyles_ant_mark:styles]];\n}\n\n- (void)setMarkdownTextPartialUpdate_ant_mark:(NSString *)text styles:(AMTextStyles *)styles\n{\n    [self setMarkdownTextPartialUpdate_ant_mark:text styles:styles animated:NO];\n}\n\n- (void)setMarkdownTextPartialUpdate_ant_mark:(NSString *)text styles:(AMTextStyles *)styles animated:(BOOL)animated\n{\n    [self setAttributedTextPartialUpdate_ant_mark:[text markdownToAttributedStringWithStyles_ant_mark:styles] animated:animated];\n}\n\n@end\n"
  },
  {
    "path": "iOS/AntMarkdown/SupportingFiles/AntMarkdown-Framework.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>AccessGroup</key>\n\t<array/>\n\t<key>Group</key>\n\t<string>AntMarkdown</string>\n\t<key>Level</key>\n\t<string>product</string>\n\t<key>Privacy</key>\n\t<array/>\n\t<key>Version</key>\n\t<string>2.0</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "iOS/AntMarkdown/SupportingFiles/AntMarkdown-Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>English</string>\n\t<key>CFBundleExecutable</key>\n\t<string>${EXECUTABLE_NAME}</string>\n\t<key>CFBundleIconFile</key>\n\t<string></string>\n\t<key>CFBundleIdentifier</key>\n\t<string>com.alipay.${PRODUCT_NAME:rfc1034identifier}</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>${PRODUCT_NAME}</string>\n\t<key>CFBundlePackageType</key>\n\t<string>BNDL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>CFPlugInDynamicRegisterFunction</key>\n\t<string></string>\n\t<key>CFPlugInDynamicRegistration</key>\n\t<string>NO</string>\n\t<key>CFPlugInFactories</key>\n\t<dict>\n\t\t<key>00000000-0000-0000-0000-000000000000</key>\n\t\t<string>MyFactoryFunction</string>\n\t</dict>\n\t<key>CFPlugInTypes</key>\n\t<dict>\n\t\t<key>00000000-0000-0000-0000-000000000000</key>\n\t\t<array>\n\t\t\t<string>00000000-0000-0000-0000-000000000000</string>\n\t\t</array>\n\t</dict>\n\t<key>CFPlugInUnloadFunction</key>\n\t<string></string>\n\t<key>NSHumanReadableCopyright</key>\n\t<string>Copyright © 2013年 Alipay. All rights reserved.</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "iOS/AntMarkdown/SupportingFiles/AntMarkdown-Prefix.pch",
    "content": "//\n// Prefix header for all source files of the 'AntMarkdown' target in the 'AntMarkdown' project\n//\n\n#ifdef __OBJC__\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\n#endif\n"
  },
  {
    "path": "iOS/AntMarkdown/SupportingFiles/en.lproj/InfoPlist.strings",
    "content": "/* Localized versions of Info.plist keys */\n\n"
  },
  {
    "path": "iOS/AntMarkdown/project.yml",
    "content": "name: AntMarkdown2\noptions:\n  bundleIdPrefix: com.alipay.$(PRODUCT_NAME:rfc1034identifier)\n  deploymentTarget:\n    iOS: \"12.0\"\n  usesTabs: false\n  tabWidth: 4\n  indentWidth: 4\n  defaultConfig: Release\nsettings:\n  base:\n    LD_RUNPATH_SEARCH_PATHS:\n      - /usr/lib/swift\n      - $(inherited)\n    LIBRARY_SEARCH_PATHS:\n      - $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\n      - $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)\n      - $(inherited)\n    CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED: true\n    GCC_C_LANGUAGE_STANDARD: gnu99\n    CLANG_CXX_LANGUAGE_STANDARD: gnu++0x\n  configs:\n    Debug:\n      COPY_PHASE_STRIP: false\n      GCC_SYMBOLS_PRIVATE_EXTERN: false\n      MTL_ENABLE_DEBUG_INFO: true\n    Release:\n      COPY_PHASE_STRIP: true\n      MTL_ENABLE_DEBUG_INFO: false\ntargets:\n  AntMarkdown:\n    type: framework\n    platform: iOS\n    sources:\n      - Sources\n      - path: Sources\n        includes: \n          - Sources/**/*.h\n          - Sources/**/*.c\n          - Sources/**/*.m\n          - Sources/**/*.mm\n      - path: Sources/Public/AntMarkdown.h\n        buildPhase: headers\n        headerVisibility: public\n    headers:\n    resources:\n      - Resources\n      - path: Resources\n"
  },
  {
    "path": "iOS/FluidMarkdown/AppDelegate.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n\n#import <UIKit/UIKit.h>\n\n@interface AppDelegate : UIResponder <UIApplicationDelegate>\n\n\n@end\n\n"
  },
  {
    "path": "iOS/FluidMarkdown/AppDelegate.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n\n#import \"AppDelegate.h\"\n\n@interface AppDelegate ()\n\n@end\n\n@implementation AppDelegate\n\n\n- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {\n    // Override point for customization after application launch.\n    return YES;\n}\n\n\n#pragma mark - UISceneSession lifecycle\n\n\n- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options {\n    // Called when a new scene session is being created.\n    // Use this method to select a configuration to create the new scene with.\n    return [[UISceneConfiguration alloc] initWithName:@\"Default Configuration\" sessionRole:connectingSceneSession.role];\n}\n\n\n- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet<UISceneSession *> *)sceneSessions {\n    // Called when the user discards a scene session.\n    // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.\n    // Use this method to release any resources that were specific to the discarded scenes, as they will not return.\n}\n\n\n@end\n"
  },
  {
    "path": "iOS/FluidMarkdown/Assets.xcassets/AccentColor.colorset/Contents.json",
    "content": "{\n  \"colors\" : [\n    {\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "iOS/FluidMarkdown/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"platform\" : \"ios\",\n      \"size\" : \"1024x1024\"\n    },\n    {\n      \"appearances\" : [\n        {\n          \"appearance\" : \"luminosity\",\n          \"value\" : \"dark\"\n        }\n      ],\n      \"idiom\" : \"universal\",\n      \"platform\" : \"ios\",\n      \"size\" : \"1024x1024\"\n    },\n    {\n      \"appearances\" : [\n        {\n          \"appearance\" : \"luminosity\",\n          \"value\" : \"tinted\"\n        }\n      ],\n      \"idiom\" : \"universal\",\n      \"platform\" : \"ios\",\n      \"size\" : \"1024x1024\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "iOS/FluidMarkdown/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "iOS/FluidMarkdown/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"13122.16\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" xcode11CocoaTouchSystemColor=\"systemBackgroundColor\" cocoaTouchSystemColor=\"whiteColor\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FluidMarkdown/Base.lproj/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"13122.16\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"BYZ-38-t0r\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"13104.12\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"tne-QT-ifu\">\n            <objects>\n                <viewController id=\"BYZ-38-t0r\" customClass=\"ViewController\" customModuleProvider=\"\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"8bC-Xf-vdC\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" xcode11CocoaTouchSystemColor=\"systemBackgroundColor\" cocoaTouchSystemColor=\"whiteColor\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"6Tk-OE-BBY\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"dkx-z0-nzr\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "iOS/FluidMarkdown/Example/AIChatViewController.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AIChatViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate>\n\n@property (nonatomic, strong) UITableView *tableView;\n@property (nonatomic, strong) NSMutableArray *sendMessages;\n@property (nonatomic, strong) NSMutableArray *reciveMessages;\n@property (nonatomic, strong) UIView *inputView;\n@property (nonatomic, strong) UITextField *messageField;\n@property (nonatomic, strong) UIButton *sendButton;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/FluidMarkdown/Example/AIChatViewController.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n\n#import \"AIChatViewController.h\"\n#import \"AMXRenderService.h\"\n#import \"AMXMarkdownTextView.h\"\n\n@interface AIChatViewController ()<AMXMarkdownTextViewDelegate, UITextFieldDelegate>\n@property (nonatomic, assign) CGFloat keyboardHeight;\n@property (nonatomic, strong) NSString* markdownStr;\n@property (nonatomic, assign) NSInteger total;\n@property (nonatomic, strong) NSMutableArray* dataArray;\n@property (nonatomic, strong) NSMutableArray* markdownViewArray;\n@property (nonatomic, assign)int dataIndex;\n@end\n\n@implementation AIChatViewController\n\n- (void)viewDidLoad {\n    [super viewDidLoad];\n    [self setupUI];\n    self.markdownViewArray = [NSMutableArray array];\n    self.dataArray = [NSMutableArray array];\n    for (int i = 0; i < 3; i++) {\n        NSString* fileName = [NSString stringWithFormat:@\"data%d\", (i + 1) ];\n        NSString *filePath = [[NSBundle mainBundle] pathForResource:fileName ofType:@\"txt\"];\n                \n        if (!filePath) {\n            NSLog(@\"not exist\");\n        } else {\n            [self.dataArray addObject:[AIChatViewController readTextDataFromFile:filePath]];\n        }\n    }\n    \n    [self registerKeyboardNotifications];\n    self.sendMessages = [NSMutableArray array];\n    self.reciveMessages = [NSMutableArray array];\n    \n}\n- (void)setMarkdown {\n    \n    [[AMXRenderService shared] setMarkdownStyleWithId:[AMXMarkdownStyleConfig defaultConfig] styleId:@\"chat\"];\n    AMXMarkdownTextView* markdownView = [[AMXMarkdownTextView alloc] initWithFrame_ant_mark:CGRectMake(20, 0, self.view.frame.size.width - 80, 1) ];\n    markdownView.styleId = @\"chat\";\n    markdownView.textColor = [UIColor blackColor];\n    markdownView.font = [UIFont systemFontOfSize:16];\n    markdownView.textViewDelegate = self;\n    [self.markdownViewArray addObject:markdownView];\n    \n    \n}\n- (void)setupUI {\n    self.navigationItem.title = @\"chat\";\n    self.view.backgroundColor = [UIColor whiteColor];\n    \n    self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height - 50) style:UITableViewStylePlain];\n    self.tableView.delegate = self;\n    self.tableView.dataSource = self;\n    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;\n    [self.view addSubview:self.tableView];\n\n    self.inputView = [[UIView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height - 50, self.view.frame.size.width, 50)];\n    self.inputView.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1.0];\n    [self.view addSubview:self.inputView];\n\n    self.messageField = [[UITextField alloc] initWithFrame:CGRectMake(10, 10, self.view.frame.size.width - 80, 30)];\n    self.messageField.borderStyle = UITextBorderStyleRoundedRect;\n    self.messageField.delegate = self;\n    [self.inputView addSubview:self.messageField];\n\n    self.sendButton = [UIButton buttonWithType:UIButtonTypeSystem];\n    self.sendButton.frame = CGRectMake(self.view.frame.size.width - 70, 10, 60, 30);\n    [self.sendButton setTitle:@\"send\" forState:UIControlStateNormal];\n    [self.sendButton addTarget:self action:@selector(sendMessage) forControlEvents:UIControlEventTouchUpInside];\n    [self.inputView addSubview:self.sendButton];\n}\n\n- (void)sendMessage {\n    if (self.messageField.text.length > 0) {\n        [self.sendMessages addObject:@{@\"text\": self.messageField.text, @\"isMe\": @YES}];\n        [self.tableView reloadData];\n        [self totalContent];\n        self.messageField.text = @\"\";\n\n        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{\n            [self setMarkdown];\n            [self.reciveMessages addObject:[self.dataArray objectAtIndex:self.dataIndex]];\n            self.markdownStr = [self.dataArray objectAtIndex:self.dataIndex];\n            \n            [self totalContent];\n            [[self.markdownViewArray objectAtIndex:self.dataIndex] startStreamingWithContent:[self.dataArray objectAtIndex:self.dataIndex]];\n            [self.tableView reloadData];\n            self.dataIndex++;\n            \n        });\n        [[[UIApplication sharedApplication] keyWindow] endEditing:YES];\n    }\n}\n\n- (void)totalContent {\n    self.total = self.sendMessages.count + self.reciveMessages.count;\n}\n\n#pragma mark - TableView DataSource\n\n- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {\n    return self.total;\n}\n\n- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {\n    NSString *cellIdentifier = @\"\";\n    if (indexPath.row % 2 == 0) {\n        cellIdentifier = @\"sendMsgIdentifier\";\n    } else {\n        // Markdown view will not be reused, if you want, you should control the data and state by yourself.\n        cellIdentifier = [NSString stringWithFormat:@\"%@%ld\",@\"reciveMsgIdentifier\",indexPath.row];\n    }\n    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];\n    \n    if (!cell) {\n        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];\n        cell.selectionStyle = UITableViewCellSelectionStyleNone;\n    }\n    if (indexPath.row % 2 == 0) {\n        // send\n        NSDictionary *sendMessage = self.sendMessages[indexPath.row / 2];\n        cell.textLabel.text = sendMessage[@\"text\"];\n        cell.textLabel.numberOfLines = 0;\n        \n        if ([sendMessage[@\"isMe\"] boolValue]) {\n            cell.textLabel.textAlignment = NSTextAlignmentRight;\n            cell.textLabel.textColor = [UIColor blueColor];\n            cell.textLabel.layoutMargins = UIEdgeInsetsMake(20, 0, 20, 0);\n        }\n    } else {\n        // recive\n        AMXMarkdownTextView* markdownView = [self.markdownViewArray objectAtIndex:(indexPath.row/ 2)];\n        if (![markdownView superview]) {\n            [cell.contentView addSubview:markdownView];\n        }\n        [cell setFrame:CGRectMake(cell.frame.origin.x, cell.frame.origin.y, markdownView.frame.size.width, markdownView.frame.size.height)];\n    }\n    \n    return cell;\n}\n\n- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {\n    if (indexPath.row % 2 == 0) {\n        // send\n        NSDictionary *message = self.sendMessages[indexPath.row / 2];\n        NSString *text = message[@\"text\"];\n        \n        CGSize size = [text boundingRectWithSize:CGSizeMake(self.view.frame.size.width - 40, CGFLOAT_MAX)\n                                         options:NSStringDrawingUsesLineFragmentOrigin\n                                      attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17]}\n                                         context:nil].size;\n        return size.height + 20;\n    } else {\n        AMXMarkdownTextView* markdownView = [self.markdownViewArray objectAtIndex:(indexPath.row / 2)];\n        return markdownView.frame.size.height;\n    }\n    \n}\n\n#pragma mark - Keyboard Handling\n\n- (void)registerKeyboardNotifications {\n    [[NSNotificationCenter defaultCenter] addObserver:self\n                                             selector:@selector(keyboardWillShow:)\n                                                 name:UIKeyboardWillShowNotification\n                                               object:nil];\n    \n    [[NSNotificationCenter defaultCenter] addObserver:self\n                                             selector:@selector(keyboardWillHide:)\n                                                 name:UIKeyboardWillHideNotification\n                                               object:nil];\n}\n\n- (void)keyboardWillShow:(NSNotification *)notification {\n    NSDictionary *userInfo = [notification userInfo];\n    CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;\n    self.keyboardHeight = keyboardSize.height;\n    \n    [UIView animateWithDuration:0.3 animations:^{\n        CGRect frame = self.inputView.frame;\n        frame.origin.y = self.view.frame.size.height - frame.size.height - keyboardSize.height;\n        self.inputView.frame = frame;\n        \n        frame = self.tableView.frame;\n        frame.size.height = self.view.frame.size.height - self.inputView.frame.size.height - keyboardSize.height;\n        self.tableView.frame = frame;\n    }];\n    \n    [self totalContent];\n    if (self.dataIndex > 0) {\n        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:(self.dataIndex * 2 - 1) inSection:0];\n        [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:NO];\n    }\n}\n\n- (void)keyboardWillHide:(NSNotification *)notification {\n    [UIView animateWithDuration:0.3 animations:^{\n        CGRect frame = self.inputView.frame;\n        frame.origin.y = self.view.frame.size.height - frame.size.height;\n        self.inputView.frame = frame;\n        \n        frame = self.tableView.frame;\n        frame.size.height = self.view.frame.size.height - self.inputView.frame.size.height;\n        self.tableView.frame = frame;\n    }];\n}\n\n- (BOOL)textFieldShouldReturn:(UITextField *)textField {\n    [self sendMessage];\n    return YES;\n}\n\n- (void)dealloc {\n    [[NSNotificationCenter defaultCenter] removeObserver:self];\n}\n- (void)didChangeState:(AMXMarkdownPrintState)state {\n\n}\n\n- (void)onError:(nonnull NSError *)error {\n    \n}\n\n- (void)onSizeChange:(CGSize)size {\n    AMXMarkdownTextView* markdownView = [self.markdownViewArray objectAtIndex:(self.dataIndex - 1)];\n    [markdownView setFrame:CGRectMake(20, 0, markdownView.frame.size.width, size.height)];\n    [markdownView.superview setFrame:CGRectMake(markdownView.superview.frame.origin.x, markdownView.superview.frame.origin.y, size.width, size.height)];\n    [self.tableView reloadData];\n    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:(self.dataIndex * 2 - 1) inSection:0];\n    [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:NO];\n}\n\n- (void)onTap:(AMXMarkdownTapType)type content:(nonnull id)content gesture:(nonnull UITapGestureRecognizer *)gesture attachment:(nonnull NSTextAttachment *)attachment tapIndex:(NSUInteger)tapIndex attrString:(nonnull NSAttributedString *)attrString {\n    \n}\n\n- (void)onUpdateExposureElement:(nonnull NSArray<AMXMarkdownCustomRenderEventModel *> *)elements {\n    \n}\n\n+ (NSString *)readTextDataFromFile:(NSString *)filePath {\n    NSError *error = nil;\n    NSString *fileContents = [NSString stringWithContentsOfFile:filePath\n                                                      encoding:NSUTF8StringEncoding\n                                                         error:&error];\n    \n    if (error) {\n        NSLog(@\"read file error: %@\", error.localizedDescription);\n        return nil;\n    }\n    NSMutableArray *textLines = [[NSMutableArray alloc] init];\n    [textLines addObject:fileContents];\n    return fileContents;\n}\n@end\n\n"
  },
  {
    "path": "iOS/FluidMarkdown/Example/MenuViewController.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface MenuViewController:UIViewController <UITableViewDelegate, UITableViewDataSource>\n@property (strong, nonatomic) NSArray *menuItems;\n@property (strong, nonatomic) UITableView *tableView;\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/FluidMarkdown/Example/MenuViewController.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n\n#import \"MenuViewController.h\"\n#import \"StreamPreviewViewController.h\"\n#import \"AIChatViewController.h\"\n\n\n@implementation MenuViewController\n- (void)viewDidLoad {\n    [super viewDidLoad];\n    \n    self.menuItems = @[@\"stream print preview\", @\"AI conversation scenario simulation\"];\n   \n    self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];\n    self.tableView.delegate = self;\n    self.tableView.dataSource = self;\n    [self.view addSubview:self.tableView];\n}\n\n#pragma mark - UITableView dataSource\n- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {\n    return self.menuItems.count;\n}\n\n- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {\n    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@\"cell\"];\n    if (!cell) {\n        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@\"cell\"];\n    }\n    cell.textLabel.text = self.menuItems[indexPath.row];\n    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;\n    return cell;\n}\n\n#pragma mark - UITableView delegate\n- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {\n    [tableView deselectRowAtIndexPath:indexPath animated:YES];\n    if (indexPath.row == 0) {\n        StreamPreviewViewController *previewVC = [[StreamPreviewViewController alloc] init];\n        [self.navigationController pushViewController:previewVC animated:YES];\n    } else if (indexPath.row == 1) {\n        AIChatViewController *chatVC = [[AIChatViewController alloc] init];\n        [self.navigationController pushViewController:chatVC animated:YES];\n    }\n}\n@end\n"
  },
  {
    "path": "iOS/FluidMarkdown/Example/StreamPreviewViewController.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <UIKit/UIKit.h>\n#import <Foundation/Foundation.h>\n#import \"AMXMarkdownWidget.h\"\n@interface CustomButton : UIButton\n\n\n- (instancetype)initWithFrame:(CGRect)frame\n                   title:(NSString *)title\n              titleColor:(UIColor *)titleColor\n           gradientStart:(UIColor *)startColor\n             gradientEnd:(UIColor *)endColor;\n\n\n@property (nonatomic, assign) CGFloat cornerRadius;\n\n@property (nonatomic, assign) CGSize shadowOffset;\n@property (nonatomic, assign) CGFloat shadowOpacity;\n@property (nonatomic, strong) UIColor *shadowColor;\n\n@end\n\n@interface StreamPreviewViewController : UIViewController\n\n@property (nonatomic, strong) CustomButton *actionStartButton;\n@property (nonatomic, strong) CustomButton *actionPauseButton;\n@property (nonatomic, strong) CustomButton *actionResumeButton;\n@property (nonatomic, strong) CustomButton *actionStopButton;\n@property (nonatomic, strong) CustomButton *actionAppendButton;\n@property (nonatomic, strong) CustomButton *oneceButton;\n@property (nonatomic, strong) UITextView *inputView;\n@property (nonatomic, strong) AMXMarkdownTextView *contentTextView;\n@property (nonatomic, strong) UIScrollView* containerView;\n\n@end\n\n"
  },
  {
    "path": "iOS/FluidMarkdown/Example/StreamPreviewViewController.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"StreamPreviewViewController.h\"\n#import \"ToastView.h\"\nCGFloat buttonHeight = 40;\n@implementation CustomButton {\n    CAGradientLayer *_gradientLayer;\n}\n\n- (instancetype)initWithFrame:(CGRect)frame\n                   title:(NSString *)title\n              titleColor:(UIColor *)titleColor\n           gradientStart:(UIColor *)startColor\n             gradientEnd:(UIColor *)endColor {\n    self = [super initWithFrame:frame];\n    if (self) {\n        [self setTitle:title forState:UIControlStateNormal];\n        [self setTitleColor:titleColor forState:UIControlStateNormal];\n        self.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold];\n        \n        _cornerRadius = 12.0;\n        _shadowOffset = CGSizeMake(0, 4);\n        _shadowOpacity = 0.2;\n        _shadowColor = [UIColor blackColor];\n        \n        _gradientLayer = [CAGradientLayer layer];\n        _gradientLayer.colors = @[(id)startColor.CGColor, (id)endColor.CGColor];\n        _gradientLayer.startPoint = CGPointMake(0, 0.5);\n        _gradientLayer.endPoint = CGPointMake(1, 0.5);\n        [self.layer insertSublayer:_gradientLayer atIndex:0];\n    }\n    return self;\n}\n\n- (void)layoutSubviews {\n    [super layoutSubviews];\n    _gradientLayer.frame = self.bounds;\n    _gradientLayer.cornerRadius = _cornerRadius;\n    self.layer.cornerRadius = _cornerRadius;\n}\n\n@end\n\n@interface StreamPreviewViewController ()<AMXMarkdownTextViewDelegate, UITextFieldDelegate>\n@property(nonatomic, assign)NSInteger printState;\n@property(nonatomic, assign)BOOL isFinish;\n@end\n\n@implementation StreamPreviewViewController\n-(void)initUI\n{\n    self.view.backgroundColor = [UIColor whiteColor];\n    CGFloat screenWidht = [UIScreen mainScreen].bounds.size.width;\n    CGFloat buttonWidth = (screenWidht - 20 * 4)/3;\n    \n    self.actionStartButton = [[CustomButton alloc]\n                              initWithFrame:CGRectMake(20, 50 + self.navigationController.navigationBar.frame.size.height, buttonWidth, buttonHeight)\n                         title:@\"start print\"\n                         titleColor:[UIColor whiteColor]\n                         gradientStart:[UIColor colorWithRed:0.10 green:0.68 blue:1.00 alpha:1.0]\n                         gradientEnd:[UIColor colorWithRed:0.20 green:0.40 blue:0.95 alpha:1.0]];\n\n    self.actionStartButton.cornerRadius = 10;\n    self.actionStartButton.shadowOffset = CGSizeMake(0, 6);\n    self.actionStartButton.shadowOpacity = 0.3;\n    self.actionStartButton.backgroundColor = [UIColor lightGrayColor];\n    [self.actionStartButton addTarget:self action:@selector(buttonTappedStart) forControlEvents:UIControlEventTouchUpInside];\n    [self.view addSubview:self.actionStartButton];\n\n    \n    self.actionPauseButton = [[CustomButton alloc]\n                              initWithFrame:CGRectMake(self.actionStartButton.frame.origin.x + buttonWidth + 20, 50 + self.navigationController.navigationBar.frame.size.height, buttonWidth, buttonHeight)\n                         title:@\"pause\"\n                         titleColor:[UIColor whiteColor]\n                         gradientStart:[UIColor colorWithRed:0.10 green:0.68 blue:1.00 alpha:1.0]\n                         gradientEnd:[UIColor colorWithRed:0.20 green:0.40 blue:0.95 alpha:1.0]];\n\n    self.actionPauseButton.cornerRadius = 10;\n    self.actionPauseButton.shadowOffset = CGSizeMake(0, 6);\n    self.actionPauseButton.shadowOpacity = 0.3;\n    self.actionPauseButton.backgroundColor = [UIColor lightGrayColor];\n    [self.actionPauseButton addTarget:self action:@selector(buttonTappedPause) forControlEvents:UIControlEventTouchUpInside];\n    [self.view addSubview:self.actionPauseButton];\n    \n    self.actionResumeButton = [[CustomButton alloc]\n                               initWithFrame:CGRectMake(self.actionPauseButton.frame.origin.x + buttonWidth + 20, 50 + self.navigationController.navigationBar.frame.size.height, buttonWidth, buttonHeight)\n                         title:@\"continue\"\n                         titleColor:[UIColor whiteColor]\n                         gradientStart:[UIColor colorWithRed:0.10 green:0.68 blue:1.00 alpha:1.0]\n                         gradientEnd:[UIColor colorWithRed:0.20 green:0.40 blue:0.95 alpha:1.0]];\n\n    self.actionResumeButton.cornerRadius = 10;\n    self.actionResumeButton.shadowOffset = CGSizeMake(0, 6);\n    self.actionResumeButton.shadowOpacity = 0.3;\n    self.actionResumeButton.backgroundColor = [UIColor lightGrayColor];\n    [self.actionResumeButton addTarget:self action:@selector(buttonTappedResume) forControlEvents:UIControlEventTouchUpInside];\n    [self.view addSubview:self.actionResumeButton];\n    \n    self.actionStopButton = [[CustomButton alloc]\n                             initWithFrame:CGRectMake(20, self.actionStartButton.frame.origin.y + buttonHeight + 20, buttonWidth, buttonHeight)\n                         title:@\"stop\"\n                         titleColor:[UIColor whiteColor]\n                         gradientStart:[UIColor colorWithRed:0.10 green:0.68 blue:1.00 alpha:1.0]\n                         gradientEnd:[UIColor colorWithRed:0.20 green:0.40 blue:0.95 alpha:1.0]];\n\n    self.actionStopButton.cornerRadius = 10;\n    self.actionStopButton.shadowOffset = CGSizeMake(0, 6);\n    self.actionStopButton.shadowOpacity = 0.3;\n    self.actionStopButton.backgroundColor = [UIColor lightGrayColor];\n    [self.actionStopButton addTarget:self action:@selector(buttonTappedStop) forControlEvents:UIControlEventTouchUpInside];\n    [self.view addSubview:self.actionStopButton];\n    \n    self.actionAppendButton = [[CustomButton alloc]\n                               initWithFrame:CGRectMake(self.actionStopButton.frame.origin.x + buttonWidth + 20, self.actionStartButton.frame.origin.y + buttonHeight + 20, buttonWidth, buttonHeight)\n                         title:@\"append\"\n                         titleColor:[UIColor whiteColor]\n                         gradientStart:[UIColor colorWithRed:0.10 green:0.68 blue:1.00 alpha:1.0]\n                         gradientEnd:[UIColor colorWithRed:0.20 green:0.40 blue:0.95 alpha:1.0]];\n\n    self.actionAppendButton.cornerRadius = 10;\n    self.actionAppendButton.shadowOffset = CGSizeMake(0, 6);\n    self.actionAppendButton.shadowOpacity = 0.3;\n    self.actionAppendButton.backgroundColor = [UIColor lightGrayColor];\n    [self.actionAppendButton addTarget:self action:@selector(buttonTappedAppend) forControlEvents:UIControlEventTouchUpInside];\n    [self.view addSubview:self.actionAppendButton];\n    \n    self.oneceButton = [[CustomButton alloc]\n                               initWithFrame:CGRectMake(self.actionAppendButton.frame.origin.x + buttonWidth + 20, self.actionStartButton.frame.origin.y + buttonHeight + 20, buttonWidth, buttonHeight)\n                         title:@\"onece render\"\n                         titleColor:[UIColor whiteColor]\n                         gradientStart:[UIColor colorWithRed:0.10 green:0.68 blue:1.00 alpha:1.0]\n                         gradientEnd:[UIColor colorWithRed:0.20 green:0.40 blue:0.95 alpha:1.0]];\n\n    self.oneceButton.cornerRadius = 10;\n    self.oneceButton.shadowOffset = CGSizeMake(0, 6);\n    self.oneceButton.shadowOpacity = 0.3;\n    self.oneceButton.backgroundColor = [UIColor lightGrayColor];\n    [self.oneceButton addTarget:self action:@selector(buttonTappedOnce) forControlEvents:UIControlEventTouchUpInside];\n    [self.view addSubview:self.oneceButton];\n}\n- (void)viewDidLoad {\n    [super viewDidLoad];\n    [self initStyle];\n    \n    CGFloat screenWidht = [UIScreen mainScreen].bounds.size.width;\n    CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;\n\n    [self initUI];\n    \n    \n    self.inputView = [[UITextView alloc] init];\n    self.inputView.font = [UIFont systemFontOfSize:16.0];\n    self.inputView.autocorrectionType = UITextAutocorrectionTypeNo;\n    self.inputView.layer.borderColor = [UIColor lightGrayColor].CGColor;\n    self.inputView.layer.borderWidth = 0.5;\n    self.inputView.translatesAutoresizingMaskIntoConstraints = NO;\n    self.inputView.scrollEnabled = YES;\n    self.inputView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;\n    self.inputView.delegate = self;\n    [self.inputView setFrame:CGRectMake(20, self.oneceButton.frame.origin.y + self.oneceButton.frame.size.height + 20 , screenWidht - 20 * 2, 200)];\n    [self.view addSubview:self.inputView];\n    \n    self.containerView = [[UIScrollView alloc] initWithFrame:CGRectMake(20, self.inputView.frame.origin.y + self.inputView.frame.size.height + 20, screenWidht - 20 * 2, screenHeight - (self.inputView.frame.origin.y + self.inputView.frame.size.height + 20 + 40))];\n\n    self.contentTextView = [[AMXMarkdownTextView alloc] initWithFrame_ant_mark:CGRectMake(0, 0, screenWidht - 20 * 2, 1)];\n    self.contentTextView.styleId = @\"demo\";\n    self.contentTextView.textColor = [UIColor blackColor];\n    self.contentTextView.font = [UIFont systemFontOfSize:16];\n    self.contentTextView.textViewDelegate = self;\n    [self.view addSubview:self.containerView];\n    [self.containerView addSubview:self.contentTextView];\n}\n-(void)initStyle\n{\n    [[AMXRenderService shared] setMarkdownStyleWithId:[AMXMarkdownStyleConfig defaultConfig] styleId:@\"demo\"];\n}\n- (void)buttonTappedStart {\n    [UIView animateWithDuration:0.1 animations:^{\n        self.actionStartButton.transform = CGAffineTransformMakeScale(0.95, 0.95);\n    } completion:^(BOOL finished) {\n        [UIView animateWithDuration:0.1 animations:^{\n            self.actionStartButton.transform = CGAffineTransformIdentity;\n        }];\n    }];\n    [self.contentTextView startStreamingWithContent:_inputView.text];\n\n    [[[UIApplication sharedApplication] keyWindow] endEditing:YES];\n}\n- (void)buttonTappedPause {\n    [UIView animateWithDuration:0.1 animations:^{\n        self.actionPauseButton.transform = CGAffineTransformMakeScale(0.95, 0.95);\n    } completion:^(BOOL finished) {\n        [UIView animateWithDuration:0.1 animations:^{\n            self.actionPauseButton.transform = CGAffineTransformIdentity;\n        }];\n    }];\n    [self.contentTextView pause];\n    [[[UIApplication sharedApplication] keyWindow] endEditing:YES];\n}\n- (void)buttonTappedResume {\n    [UIView animateWithDuration:0.1 animations:^{\n        self.actionResumeButton.transform = CGAffineTransformMakeScale(0.95, 0.95);\n    } completion:^(BOOL finished) {\n        [UIView animateWithDuration:0.1 animations:^{\n            self.actionResumeButton.transform = CGAffineTransformIdentity;\n        }];\n    }];\n    [ToastView showToastInView:self.view withText:@\"continue\" duration:2.0];\n    [self.contentTextView resume];\n    [[[UIApplication sharedApplication] keyWindow] endEditing:YES];\n}\n- (void)buttonTappedStop {\n    [UIView animateWithDuration:0.1 animations:^{\n        self.actionStopButton.transform = CGAffineTransformMakeScale(0.95, 0.95);\n    } completion:^(BOOL finished) {\n        [UIView animateWithDuration:0.1 animations:^{\n            self.actionStopButton.transform = CGAffineTransformIdentity;\n        }];\n    }];\n    [self.contentTextView stop];\n    [[[UIApplication sharedApplication] keyWindow] endEditing:YES];\n}\n- (void)buttonTappedAppend {\n    [UIView animateWithDuration:0.1 animations:^{\n        self.actionAppendButton.transform = CGAffineTransformMakeScale(0.95, 0.95);\n    } completion:^(BOOL finished) {\n        [UIView animateWithDuration:0.1 animations:^{\n            self.actionAppendButton.transform = CGAffineTransformIdentity;\n        }];\n    }];\n    [ToastView showToastInView:self.view withText:@\"append string：**潇珺测试内容**\" duration:2.0];\n    [self.contentTextView addStreamContent:@\"**潇珺测试内容**\"];\n    [[[UIApplication sharedApplication] keyWindow] endEditing:YES];\n}\n-(void)buttonTappedOnce {\n    [UIView animateWithDuration:0.1 animations:^{\n        self.oneceButton.transform = CGAffineTransformMakeScale(0.95, 0.95);\n    } completion:^(BOOL finished) {\n        [UIView animateWithDuration:0.1 animations:^{\n            self.oneceButton.transform = CGAffineTransformIdentity;\n        }];\n    }];\n    [self.contentTextView renderCompleteContent:_inputView.text];\n    [[[UIApplication sharedApplication] keyWindow] endEditing:YES];\n}\n-(void)onSizeChange:(CGSize)size\n{\n    [self.contentTextView setFrame:CGRectMake(0, 0, self.contentTextView.frame.size.width, size.height)];\n    [self.containerView setContentSize:size];\n    CGPoint bottomOffset = CGPointMake(0, self.containerView.contentSize.height - self.containerView.bounds.size.height);\n    if (bottomOffset.y > 0) {\n        [self.containerView setContentOffset:bottomOffset animated:NO];\n    }\n}\n-(void)onError:(NSError*)error {\n    NSLog(@\"\");\n}\n-(void)didChangeState:(AMXMarkdownPrintState)state\n{\n    if (state == AMXMarkdownPrintStateStopped) {\n        dispatch_async(dispatch_get_main_queue(), ^{\n            CGPoint bottomOffset = CGPointMake(0, self.containerView.contentSize.height - self.containerView.bounds.size.height);\n            if (bottomOffset.y > 0) {\n                [self.containerView setContentOffset:bottomOffset animated:NO];\n            }\n            [ToastView showToastInView:self.view withText:@\"stop\" duration:2.0];\n            self.printState = 0;\n            self.isFinish = YES;\n        });\n    }\n    if (state == AMXMarkdownPrintStatePaused) {\n        dispatch_async(dispatch_get_main_queue(), ^{\n            [ToastView showToastInView:self.view withText:@\"pause\" duration:2.0];\n        });\n    }\n}\n-(void)start\n{\n    [ToastView showToastInView:self.view withText:@\"start\" duration:2.0];\n    NSString* contentStr = [self markdownReplaceBr:self.inputView.text];\n    [self.contentTextView startStreamingWithContent:contentStr];\n}\n-(void)stop\n{\n    [self.contentTextView stop];\n}\n-(void)continuePrint\n{\n    [self.contentTextView resume];\n}\n- (NSString*)markdownReplaceBr:(NSString *)markdown {\n    if(!(markdown && [markdown isKindOfClass:[NSString class]] && ![@\"\" isEqualToString:markdown]))\n        return markdown;\n        \n    NSString* resStr = [markdown stringByReplacingOccurrencesOfString:@\"<br/>\" withString:@\"\\n\"];\n    \n    NSString *pattern = @\"\\\\\\\\\\\\[([\\\\s\\\\S]*?)\\\\\\\\\\\\]\";\n    \n    \n    NSError *error = nil;\n    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];\n    \n    if (error) {\n        return resStr;\n    }\n    \n    NSString *replacementString = @\"$$$1$$\";\n    NSString *resultString = [regex stringByReplacingMatchesInString:resStr options:0 range:NSMakeRange(0, resStr.length) withTemplate:replacementString];\n    \n    \n    NSString *pattern2 = @\"\\\\\\\\\\\\((.*?)\\\\\\\\\\\\)\";\n\n    NSRegularExpression *regex2 = [NSRegularExpression regularExpressionWithPattern:pattern2 options:0 error:&error];\n    \n    if (error) {\n        NSLog(@\"regular exception: %@\", error.localizedDescription);\n        return resultString;\n    }\n    \n    NSString *replacementString2 = @\"$$1$\";\n    NSString *resultString2 = [regex2 stringByReplacingMatchesInString:resultString options:0 range:NSMakeRange(0, resultString.length) withTemplate:replacementString2];\n    \n    return resultString2;\n}\n-(void)onUpdateExposureElement:(NSArray<AMXMarkdownCustomRenderEventModel*>*)elements\n{\n    NSLog(@\"onUpdateExposureElement %ld\", elements.count);\n}\n-(void)onTap:(AMXMarkdownTapType)type content:(id)content gesture:(UITapGestureRecognizer *)gesture attachment:(NSTextAttachment*)attachment tapIndex:(NSUInteger)tapIndex attrString:(NSAttributedString*)attrString\n{\n   \n}\n@end\n"
  },
  {
    "path": "iOS/FluidMarkdown/Example/ToastView.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\nNS_ASSUME_NONNULL_BEGIN\n\n@interface ToastView : NSObject\n+ (void)showToastInView:(UIView *)view withText:(NSString *)text duration:(NSTimeInterval)duration;\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/FluidMarkdown/Example/ToastView.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"ToastView.h\"\n\n@implementation ToastView\n\n+ (void)showToastInView:(UIView *)view withText:(NSString *)text duration:(NSTimeInterval)duration {\n\n    UIView *toastView = [[UIView alloc] init];\n    toastView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.7];\n    toastView.layer.cornerRadius = 10;\n    toastView.alpha = 0;\n \n    UILabel *label = [[UILabel alloc] init];\n    label.text = text;\n    label.textColor = [UIColor whiteColor];\n    label.textAlignment = NSTextAlignmentCenter;\n    label.numberOfLines = 0;\n    [label sizeToFit];\n    \n    CGFloat padding = 16;\n    CGRect labelFrame = label.frame;\n    toastView.frame = CGRectMake(0, 0, labelFrame.size.width + padding*2, labelFrame.size.height + padding*2);\n    label.center = CGPointMake(toastView.frame.size.width/2, toastView.frame.size.height/2);\n    \n    [toastView addSubview:label];\n    toastView.center = CGPointMake(view.frame.size.width/2, view.frame.size.height*0.8);\n    [view addSubview:toastView];\n    \n    [UIView animateWithDuration:0.3 animations:^{\n        toastView.alpha = 1;\n    } completion:^(BOOL finished) {\n        [UIView animateWithDuration:0.3 delay:duration options:UIViewAnimationOptionCurveEaseInOut animations:^{\n            toastView.alpha = 0;\n        } completion:^(BOOL finished) {\n            [toastView removeFromSuperview];\n        }];\n    }];\n}\n\n@end\n"
  },
  {
    "path": "iOS/FluidMarkdown/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>UIApplicationSceneManifest</key>\n\t<dict>\n\t\t<key>UIApplicationSupportsMultipleScenes</key>\n\t\t<false/>\n\t\t<key>UISceneConfigurations</key>\n\t\t<dict>\n\t\t\t<key>UIWindowSceneSessionRoleApplication</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>UISceneConfigurationName</key>\n\t\t\t\t\t<string>Default Configuration</string>\n\t\t\t\t\t<key>UISceneDelegateClassName</key>\n\t\t\t\t\t<string>SceneDelegate</string>\n\t\t\t\t\t<key>UISceneStoryboardFile</key>\n\t\t\t\t\t<string>Main</string>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t</dict>\n</dict>\n</plist>\n"
  },
  {
    "path": "iOS/FluidMarkdown/SceneDelegate.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n\n#import <UIKit/UIKit.h>\n\n@interface SceneDelegate : UIResponder <UIWindowSceneDelegate>\n\n@property (strong, nonatomic) UIWindow * window;\n\n@end\n\n"
  },
  {
    "path": "iOS/FluidMarkdown/SceneDelegate.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n\n#import \"SceneDelegate.h\"\n#import <AntMarkdown/AntMarkdown.h>\n#import \"MenuViewController.h\"\n\n@interface SceneDelegate ()\n\n@end\n\n@implementation SceneDelegate\n\n\n- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {\n    // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.\n    // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.\n    // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).\n    UIWindowScene *windowScene = (UIWindowScene *)scene;\n        self.window = [[UIWindow alloc] initWithWindowScene:windowScene];\n        self.window.frame = windowScene.coordinateSpace.bounds;\n        \n    MenuViewController *rootVC = [[MenuViewController alloc] init];\n        self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:rootVC];\n        [self.window makeKeyAndVisible];\n}\n\n\n- (void)sceneDidDisconnect:(UIScene *)scene {\n    // Called as the scene is being released by the system.\n    // This occurs shortly after the scene enters the background, or when its session is discarded.\n    // Release any resources associated with this scene that can be re-created the next time the scene connects.\n    // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).\n}\n\n\n- (void)sceneDidBecomeActive:(UIScene *)scene {\n    // Called when the scene has moved from an inactive state to an active state.\n    // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.\n//    NSString* text = @\"\";\n//    [text markdownToAttributedStringWithStyles_ant_mark:nil delegate:nil];\n//    AMTextStyles* styles;\n//    [styles.blockQuoteAttributes.stringAttributes addEntriesFromDictionary:@{\n//        AMBackgroundDrawableAttributeName: [AMTextBackground leftBorderColor:[UIColor colorWithHex_ant_mark:0xd1d9e0]\n//                                                                       width:4],\n//    }];\n}\n\n\n- (void)sceneWillResignActive:(UIScene *)scene {\n    // Called when the scene will move from an active state to an inactive state.\n    // This may occur due to temporary interruptions (ex. an incoming phone call).\n}\n\n\n- (void)sceneWillEnterForeground:(UIScene *)scene {\n    // Called as the scene transitions from the background to the foreground.\n    // Use this method to undo the changes made on entering the background.\n}\n\n\n- (void)sceneDidEnterBackground:(UIScene *)scene {\n    // Called as the scene transitions from the foreground to the background.\n    // Use this method to save data, release shared resources, and store enough scene-specific state information\n    // to restore the scene back to its current state.\n}\n\n\n@end\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/API/AMXMarkdownWidget.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#ifndef AMXMarkdownWidget_h\n#define AMXMarkdownWidget_h\n\n#import \"AMXRenderService.h\"\n#import \"AMXMarkdownStyle.h\"\n#import \"AMXMarkdownTextView.h\"\n\n#endif /* AMXMarkdownWidget_h */\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Markdown/AMTextStyles+CardUIPlugins.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <AntMarkdown/AntMarkdown.h>\n#import \"AMXMarkdownImageTextAttachment.h\"\n#import \"AMXMarkdownImageAttachmentBuilder.h\"\n#import \"AMXMarkdownCodeViewAttachment.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMTextStyles (CardUIPlugins)\n\n+ (instancetype)cpl_cardDefaultTextStyles;\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Markdown/AMTextStyles+CardUIPlugins.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMTextStyles+CardUIPlugins.h\"\n#import <AntMarkDown/AntMarkDown.h>\n#import \"AMXMarkdownImageTextAttachment.h\"\n#import \"AMXMarkdownImageAttachmentBuilder.h\"\n#import \"AMXMarkdownCodeViewAttachment.h\"\n#import <AntMarkdown/CMTextAttributes.h>\n#import \"AMXFootnodeBuilder.h\"\n#import <AntMarkdown/AMUtils.h>\n#import \"AMXMarkdownDefine.h\"\nAMStyleProvider AMOrderListProviderForAISearch(void) {\n    return ^CMStyleAttributes * (NSInteger level) {\n        CMStyleAttributes *styles = [[CMStyleAttributes alloc] init];\n        [styles.stringAttributes addEntriesFromDictionary:@{\n            NSParagraphStyleAttributeName: ({\n            NSMutableParagraphStyle *paragraphStyles = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];\n            paragraphStyles.tabStops = @[\n                [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentLeft\n                                                location:7 + (level - 1) * 20\n                                                 options:@{}],\n                [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentLeft\n                                                location:30 + (level - 1) * 20\n                                                 options:@{}],\n            ];\n            paragraphStyles.lineBreakMode = NSLineBreakByWordWrapping;\n            paragraphStyles.paragraphSpacingBefore = 8;\n            paragraphStyles.lineSpacing = 2;\n            paragraphStyles.firstLineHeadIndent = 0;\n            paragraphStyles.headIndent = 30 + (level - 1) * 20;\n            [paragraphStyles copy];\n        }),\n        }];\n        \n        [styles.paragraphStyleAttributes addEntriesFromDictionary:@{\n            CMParagraphStyleAttributeFirstLineHeadExtraIndent: @0,\n            CMParagraphStyleAttributeHeadExtraIndent: @0,\n            CMParagraphStyleAttributeListItemLabelIndent: [NSNull null],\n            CMParagraphStyleAttributeListItemNumberFormat: @\"\\t%ld.\",\n            CMParagraphStyleAttributeListItemBulletString: @\"\\t●\",\n        }];\n        return styles;\n    };\n}\nAMStyleProvider AMUnorderListProviderForAISearch(void) {\n    return ^CMStyleAttributes * (NSInteger level) {\n        CMStyleAttributes *styles = [[CMStyleAttributes alloc] init];\n        [styles.stringAttributes addEntriesFromDictionary:@{\n            NSParagraphStyleAttributeName: ({\n            NSMutableParagraphStyle *paragraphStyles = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];\n            paragraphStyles.tabStops = @[\n                [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentCenter\n                                                location:13 + (level - 1) * 20\n                                                 options:@{}],\n                [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentLeft\n                                                location:23.5 + (level - 1) * 20\n                                                 options:@{}],\n            ];\n            paragraphStyles.lineBreakMode = NSLineBreakByWordWrapping;\n            paragraphStyles.paragraphSpacingBefore = 8;\n            paragraphStyles.lineSpacing = 2;\n            paragraphStyles.firstLineHeadIndent = 0;\n            paragraphStyles.headIndent = 23.5 + (level - 1) * 20;\n            [paragraphStyles copy];\n        }),\n        }];\n        \n        [styles.paragraphStyleAttributes addEntriesFromDictionary:@{\n            CMParagraphStyleAttributeFirstLineHeadExtraIndent: @0,\n            CMParagraphStyleAttributeHeadExtraIndent: @0,\n            CMParagraphStyleAttributeListItemLabelIndent: [NSNull null],\n            CMParagraphStyleAttributeListItemNumberFormat: @\"\\t%ld.\",\n            CMParagraphStyleAttributeListItemBulletString: @\"\\t●\",\n        }];\n        return styles;\n    };\n}\n@implementation AMTextStyles (CardUIPlugins)\n\n+ (instancetype)cpl_cardDefaultTextStyles {\n    AMTextStyles *style = [AMTextStyles defaultStyles];\n    style.baseTextAttributes = [[CMStyleAttributes alloc] init];\n    [style registerImageAttachmentBuilder:[[AMXMarkdownImageAttachmentBuilder alloc] init]];\n    \n    [style registerCodeBlockAttachmentBuilder:[[AMXMarkdownCodeViewAttachment alloc] init]];\n\n    [style cpl_registerDefaultCssClass];\n    \n    [style registerFootnoteRefBuilder:[[AMXFootnodeBuilder alloc] init]];\n    [style.footNoteRefAttributes.stringAttributes addEntriesFromDictionary:@{\n        NSFontAttributeName: [UIFont systemFontOfSize: 12.0],\n        NSBaselineOffsetAttributeName: @(6),\n        NSForegroundColorAttributeName:[AMUtils colorWithString:@\"0x0e489a\"]}];\n\n    [style.baseTextAttributes.stringAttributes addEntriesFromDictionary:@{\n        NSFontAttributeName: kCUPLMarkdownTextFont,\n        NSForegroundColorAttributeName:kCUPLMarkdownCommonTextColor,\n        NSKernAttributeName: @(0.25)\n    }];\n    \n    [style.paragraphAttributes.paragraphStyleAttributes addEntriesFromDictionary:@{ CMParagraphStyleAttributeParagraphSpacingBefore: @12,\n        CMParagraphStyleAttributeMinimumLineHeight:@(kCUPLMarkdownTextLineHeight),\n        CMParagraphStyleAttributeLineBreakMode:@(NSLineBreakByWordWrapping),\n     }];\n    \n    [style.imageParagraphAttributes.paragraphStyleAttributes addEntriesFromDictionary:@{ CMParagraphStyleAttributeParagraphSpacingBefore: @12,\n        CMParagraphStyleAttributeAlignment: @(NSTextAlignmentLeft),\n        CMParagraphStyleAttributeLineSpacing:@(0)}];\n\n    [style.linkAttributes.stringAttributes addEntriesFromDictionary:@{ \n        NSForegroundColorAttributeName: [AMUtils colorWithString:@\"#1677FF\"],\n        NSBaselineOffsetAttributeName: @(0.0)\n    }];\n    \n    [style.h1Attributes.stringAttributes addEntriesFromDictionary:@{\n        NSFontAttributeName: kCUPLMarkdownTextBoldFont,\n        NSForegroundColorAttributeName:kCUPLMarkdownCommonTextColor,\n        NSKernAttributeName: @(0.25)\n    }];\n    [style.h2Attributes.stringAttributes addEntriesFromDictionary:@{\n        NSFontAttributeName: kCUPLMarkdownTextBoldFont,\n        NSForegroundColorAttributeName:kCUPLMarkdownCommonTextColor,\n        NSKernAttributeName: @(0.25)\n    }];\n    [style.h3Attributes.stringAttributes addEntriesFromDictionary:@{\n        NSFontAttributeName: kCUPLMarkdownTextBoldFont,\n        NSForegroundColorAttributeName:kCUPLMarkdownCommonTextColor,\n        NSKernAttributeName: @(0.25)\n    }];\n    [style.h4Attributes.stringAttributes addEntriesFromDictionary:@{\n        NSFontAttributeName: kCUPLMarkdownTextBoldFont,\n        NSForegroundColorAttributeName:kCUPLMarkdownCommonTextColor,\n        NSKernAttributeName: @(0.25)\n    }];\n    [style.h5Attributes.stringAttributes addEntriesFromDictionary:@{\n        NSFontAttributeName: kCUPLMarkdownTextBoldFont,\n        NSForegroundColorAttributeName:kCUPLMarkdownCommonTextColor,\n        NSKernAttributeName: @(0.25)\n    }];\n    [style.h6Attributes.stringAttributes addEntriesFromDictionary:@{\n        NSFontAttributeName: kCUPLMarkdownTextBoldFont,\n        NSForegroundColorAttributeName:kCUPLMarkdownCommonTextColor,\n        NSKernAttributeName: @(0.25)\n    }];\n\n    AMStyleProvider styleProvide = AMDefaultProvider();\n\n    style.ordererListAttributesProvider = ^CMStyleAttributes * _Nonnull(NSInteger level) {\n        CMStyleAttributes *attr = styleProvide(level);\n        [attr.paragraphStyleAttributes addEntriesFromDictionary:@{\n            CMParagraphStyleAttributeListItemLabelIndent: [NSNull null],\n            CMParagraphStyleAttributeListItemBulletString: @\"\\t●\",\n            CMParagraphStyleAttributeListItemNumberFormat: @\"\\t%ld.\",\n            CMParagraphStyleAttributeMinimumLineHeight:@(kCUPLMarkdownTextLineHeight)\n        }];\n        return attr;\n    };\n    \n    style.unordererListAttributesProvider = ^CMStyleAttributes * _Nonnull(NSInteger level) {\n        CMStyleAttributes *attr = styleProvide(level);\n        [attr.paragraphStyleAttributes addEntriesFromDictionary:@{\n            CMParagraphStyleAttributeListItemLabelIndent: [NSNull null],\n            CMParagraphStyleAttributeListItemBulletString: @\"\\t●\",\n            CMParagraphStyleAttributeListItemNumberFormat: @\"\\t%ld.\",\n            CMParagraphStyleAttributeMinimumLineHeight:@(kCUPLMarkdownTextLineHeight)\n        }];\n        return attr;\n    };\n    \n    [style.orderedListItemAttributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeListItemParagraphPrefix:@\"\\t\\t\",\n    }];\n    \n    if (!style.unorderedListItemAttributes) {\n        style.unorderedListItemAttributes = [[CMStyleAttributes alloc] init];\n    }\n    [style.unorderedListItemAttributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeListItemParagraphPrefix:@\"\\t\\t\",\n    }];\n        \n    return style;\n}\n- (void)cpl_registerDefaultCssClass {\n    [self addStringAttributes:@{\n        NSForegroundColorAttributeName: [UIColor colorWithHex_ant_mark:0xe62c3b],\n    }\n                       forClass:@\"up\"];\n    [self addStringAttributes:@{\n        NSForegroundColorAttributeName: [UIColor colorWithHex_ant_mark:0xe62c3b],\n    }\n                       forClass:@\"markdown-red-color\"];\n    [self addStringAttributes:@{\n        NSForegroundColorAttributeName: [UIColor colorWithHex_ant_mark:0x0e9976],\n    }\n                       forClass:@\"down\"];\n    [self addStringAttributes:@{\n        NSForegroundColorAttributeName: [UIColor colorWithHex_ant_mark:0x0e9976],\n    }\n                       forClass:@\"markdown-green-color\"];\n\n    [self addStringAttributes:@{\n        AMUnderlineDrawableAttributeName: [[AMUnderline alloc] initWithColor:[AMUtils colorWithString:@\"#1677FF52\"] lineWidth:6 offset:4],\n        NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle),\n        NSUnderlineColorAttributeName: [UIColor clearColor],\n    }\n                     forClass:@\"highlight\"];\n    \n    [self addStringAttributes:@{\n        AMUnderlineDrawableAttributeName: [[AMUnderline alloc] initWithColor:[AMUtils colorWithString:@\"#1677FF52\"] lineWidth:6 offset:4],\n        NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle),\n        NSUnderlineColorAttributeName: [UIColor clearColor],\n    }\n                       forClass:@\"poi\"];\n    [self addStringAttributes:@{\n        NSForegroundColorAttributeName: [UIColor colorWithHex_ant_mark:0x0E489A],\n    }\n                       forClass:@\"related-entity\"];\n}\n\n@end\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Markdown/AMXFootnodeBuilder.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n#import <AntMarkdown/AMTextStyles.h>\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMXFootnodeBuilder : NSObject<AMFootnoteRefBuilder>\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Markdown/AMXFootnodeBuilder.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMXFootnodeBuilder.h\"\n#import <AntMarkdown/AMUtils.h>\n\n@interface AMXFootNoteAttachment : NSTextAttachment\n\n@property(nonatomic,assign)NSInteger noteIndex;\n@property(nonatomic,copy)NSString *noteTitle;\n\n@end\n\n@implementation AMXFootNoteAttachment\n\n- (BOOL)isEqual:(id)object\n{\n    if([super isEqual:object])\n        return YES;\n    \n    if(![object isKindOfClass:[self class]])\n    {\n        return NO;\n    }\n    AMXFootNoteAttachment* other = (AMXFootNoteAttachment*)object;\n    if(self.noteIndex == other.noteIndex && ( self.noteTitle == other.noteTitle || [self.noteTitle isEqualToString:other.noteTitle] ))\n    {\n        return YES;\n    }\n    return NO;\n}\n\n@end\n\n@implementation AMXFootnodeBuilder\n\n- (NSAttributedString *)buildWithReference:(NSString *)reference\n                                     title:(NSString *)title\n                                     index:(NSInteger)index\n                                    styles:(AMTextStyles *)styles{\n    return [AMXFootnodeBuilder footnoteWithTitle:title index:index styles:styles];\n}\n\n+ (NSAttributedString *)footnoteWithTitle:(NSString *)title index:(NSInteger)index styles:(AMTextStyles*)styles{\n\n    if (!(title && [title isKindOfClass:[NSString class]] && ![@\"\" isEqualToString:title])) {\n        return nil;\n    }\n    \n    __block UIImage *image = nil;\n    if ([title isEqualToString:@\"”\"]) {\n        image = [UIImage imageNamed:@\"CardUIPlugins.bundle/footnote\"];\n    }else {\n        if(![NSThread currentThread].isMainThread) {\n            dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);\n            APTMainCall(0, __FUNCTION__, 0, 0, ^{\n                image = [AMXFootnodeBuilder convertTitleToImage:title styles:styles];\n                dispatch_semaphore_signal(semaphore);\n            });\n            dispatch_time_t waitTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC));\n            dispatch_semaphore_wait(semaphore, waitTime);\n        }\n        else\n        {\n            image = [AMXFootnodeBuilder convertTitleToImage:title styles:styles];\n        }\n    }\n    \n    AMXFootNoteAttachment *textAttachment = [[AMXFootNoteAttachment alloc] init];\n    textAttachment.noteIndex = index;\n    textAttachment.noteTitle = title;\n    \n    textAttachment.image = image;\n    UIFont *font = [UIFont systemFontOfSize:AUFVS(15.0)];\n    \n    CGFloat yOffset = (font.capHeight - image.size.height) / 2.0;\n    textAttachment.bounds = CGRectMake(0, yOffset, image.size.width, image.size.height);\n    \n    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] init];\n    NSString *zeroWidthSpace = @\"\\u200B\"; \n    CGFloat desiredLeftMargin = 4.0;\n    CGSize zeroWidthSize = [zeroWidthSpace sizeWithAttributes:@{NSFontAttributeName: font}];\n    CGFloat kernValue = desiredLeftMargin - zeroWidthSize.width;\n    NSAttributedString *spaceString = [[NSAttributedString alloc]\n                                       initWithString:zeroWidthSpace\n                                       attributes:@{\n        NSFontAttributeName: font,\n        NSForegroundColorAttributeName: [UIColor clearColor],\n        NSKernAttributeName: @(kernValue)\n    }];\n    [attributedString appendAttributedString:spaceString];\n    [attributedString appendAttributedString:[NSAttributedString attributedStringWithAttachment:textAttachment]];\n    NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@\"action://type=footnote&index=%ld&title=%@\",index,title]];\n    if (url) {\n        [attributedString addAttribute:NSLinkAttributeName\n                                 value:url\n                                 range:NSMakeRange(attributedString.length-1, 1)];\n    }\n    return [attributedString copy];\n}\n\n+ (UIImage*)convertTitleToImage:(NSString*)title styles:(AMTextStyles*)styles\n{\n    CGFloat labelSize = styles.footNoteAttributes.stringAttributes[@\"labelSize\"] ? [styles.footNoteAttributes.stringAttributes[@\"labelSize\"] floatValue] : 18.f;\n    UIFont* textFont = styles.footNoteAttributes.stringAttributes[NSFontAttributeName] ? ((UIFont*)styles.footNoteAttributes.stringAttributes[NSFontAttributeName])  : [UIFont boldSystemFontOfSize:AUFVS(11.0)];\n    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0.f, 0.f, labelSize, labelSize)];\n    label.backgroundColor = styles.footNoteAttributes.stringAttributes[NSBackgroundColorAttributeName] ? : [AMUtils colorWithString:@\"#1677ff1e\"];\n    label.layer.cornerRadius = 9;\n    label.layer.masksToBounds = YES;\n    label.textAlignment = NSTextAlignmentCenter;\n\n    label.textColor = styles.footNoteAttributes.stringAttributes[NSForegroundColorAttributeName] ? : [AMUtils colorWithString:@\"#0e489a\"];\n    label.font = textFont;\n    label.text = title;\n\n    [label layoutIfNeeded];\n    return [AMXFootnodeBuilder imageFromView:label];\n}\n\n+ (UIImage *)imageFromView:(UIView *)view {\n    UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, [UIScreen mainScreen].scale);\n    [view.layer renderInContext:UIGraphicsGetCurrentContext()];\n    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();\n    UIGraphicsEndImageContext();\n    return image;\n}\n\n@end\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Markdown/AMXMarkdownCodeView.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <AntMarkdown/AntMarkdown.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMXMarkdownCodeView : AMMarkdownCodeView\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Markdown/AMXMarkdownCodeView.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMXMarkdownCodeView.h\"\n\n@implementation AMXMarkdownCodeView\n\n- (void)didCopyCode:(NSString *)code {\n    if ([code length] > 0) {\n        if ([self copyToPasteboard:code]) {\n            // copy success\n        }\n    }\n}\n\n- (BOOL)copyToPasteboard:(NSString *)copyText {\n    // Need to implement copy logic\n    return NO;\n}\n\n@end\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Markdown/AMXMarkdownCodeViewAttachment.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <AntMarkdown/AntMarkdown.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMXMarkdownCodeViewAttachment : AMCodeViewAttachment<AMCodeAttachmentBuilder>\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Markdown/AMXMarkdownCodeViewAttachment.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMXMarkdownCodeViewAttachment.h\"\n#import \"AMXMarkdownCodeView.h\"\n\n@interface AMXMarkdownCodeViewAttachment ()\n\n@end\n\n@implementation AMXMarkdownCodeViewAttachment\n\n+ (Class<AMCodeView>)codeViewClass {\n    return [AMXMarkdownCodeView class];\n}\n\n#pragma mark AMCodeAttachmentBuilder\n\n- (NSTextAttachment<AMViewAttachment> *)buildWithCode:(NSString *)code\n                                             language:(nullable NSString *)language\n                                               styles:(AMTextStyles *)styles {\n    return [AMXMarkdownCodeViewAttachment attachmentWithCode:code\n                                                    language:language\n                                                      styles:styles];\n}\n\n@end\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Markdown/AMXMarkdownCustomRenderEventModel.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMXMarkdownCustomRenderEventModel : NSObject\n@property (nonatomic, copy)NSString* contentUrl;\n@property (nonatomic, copy)NSString* contentType;\n@property (nonatomic, copy)NSString* contentName;\n@property (nonatomic, assign)NSInteger exposurePercent;\n@property (nonatomic, assign) CGRect bounds;\n@property (nonatomic, strong)NSDictionary* extParam;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Markdown/AMXMarkdownCustomRenderEventModel.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMXMarkdownCustomRenderEventModel.h\"\n\n@implementation AMXMarkdownCustomRenderEventModel\n-(instancetype)init\n{\n    if (self = [super init]) {\n        self.exposurePercent = 100;\n    }\n    return self;\n}\n@end\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Markdown/AMXMarkdownHelper.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n#import \"AMXMarkdownStyle.h\"\n\n@class AMTextStyles;\n@protocol CMAttributedStringRendererDelegate;\n\nNS_ASSUME_NONNULL_BEGIN\n\n@protocol AMXImageAttachmentProtocol <NSObject>\n\n- (nullable UIImage *)getImageFromCacheIfExist:(NSString *)url;\n\n- (void)onImageLoadFinish:(UIImage *)image url:(NSString *)url;\n\n@end\n\n@interface AMXMarkdownHelper : NSObject\n\n\n+ (nullable NSMutableAttributedString *)mdToAttrString:(NSString *)text\n                                         defaultStyles:(nullable AMTextStyles *)defaultStyles;\n+ (nullable NSMutableAttributedString *)mdToAttrString:(NSString *)text\n                                         defaultStyles:(nullable AMTextStyles *)defaultStyles\n                                              delegate:(id<CMAttributedStringRendererDelegate>)delegate\n                                              textView:(UITextView*)textView;\n+ (void)setImageAttachListener:(NSMutableAttributedString *)attrText\n                      delegate:(id<AMXImageAttachmentProtocol>)delegate;\n+ (void)transformParagraph:(AMTextStyles*)defalutStyle customStyle:(AMXMarkdownStyleConfig*)config;\n+ (void)transformTitle:(AMTextStyles*)defalutStyle customStyle:(AMXMarkdownStyleConfig*)config;\n+ (void)transformHRule:(AMTextStyles*)defalutStyle customStyle:(AMXMarkdownStyleConfig*)config;\n+ (void)transformTable:(AMTextStyles*)defalutStyle customStyle:(AMXMarkdownStyleConfig*)config;\n+ (void)transformOrderList:(AMTextStyles*)defalutStyle customStyle:(AMXMarkdownStyleConfig*)config;\n+ (void)transformUnorderList:(AMTextStyles*)defalutStyle customStyle:(AMXMarkdownStyleConfig*)config;\n+ (void)transformFootNote:(AMTextStyles*)defaultStyle customStyle:(AMXMarkdownStyleConfig*)config;\n+ (void)transformLink:(AMTextStyles*)defaultStyle customStyle:(AMXMarkdownStyleConfig*)config textView:(UITextView*)textView;\n+ (void)transformInlineCode:(AMTextStyles*)defaultStyle customStyle:(AMXMarkdownStyleConfig*)config;\n+ (void)transformCodeBlock:(AMTextStyles*)defaultStyle customStyle:(AMXMarkdownStyleConfig*)config;\n+ (void)transformUnderLine:(AMTextStyles*)defaultStyle customStyle:(AMXMarkdownStyleConfig*)config;\n+ (void)transformBlockQuote:(AMTextStyles*)defaultStyle customStyle:(AMXMarkdownStyleConfig*)config;\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Markdown/AMXMarkdownHelper.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMXMarkdownHelper.h\"\n#import <AntMarkDown/AntMarkDown.h>\n#import \"AMXMarkdownImageTextAttachment.h\"\n#import \"AMTextStyles+CardUIPlugins.h\"\n#import \"AMXMarkdownTextView.h\"\n#import \"AMXMarkdownDefine.h\"\nAMStyleProvider AMCustomProvider(void) {\n    return ^CMStyleAttributes * (NSInteger level) {\n        CMStyleAttributes *styles = [[CMStyleAttributes alloc] init];\n        [styles.stringAttributes addEntriesFromDictionary:@{\n            NSParagraphStyleAttributeName: ({\n            NSMutableParagraphStyle *paragraphStyles = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];\n            paragraphStyles.tabStops = @[\n                [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentLeft\n                                                location:1 + (level - 1) * 12\n                                                 options:@{}],\n                [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentLeft\n                                                location:30 + (level - 1) * 20\n                                                 options:@{}],\n            ];\n            paragraphStyles.lineBreakMode = NSLineBreakByWordWrapping;\n            paragraphStyles.paragraphSpacingBefore = 8;\n            paragraphStyles.lineSpacing = 0;\n            paragraphStyles.firstLineHeadIndent = 0;\n            paragraphStyles.headIndent = 30 + (level - 1) * 20;\n            [paragraphStyles copy];\n        }),\n        }];\n        [styles.paragraphStyleAttributes addEntriesFromDictionary:@{\n            CMParagraphStyleAttributeListItemLabelIndent: [NSNull null],\n            CMParagraphStyleAttributeMinimumLineHeight:@(kCUPLMarkdownTextLineHeight)\n        }];\n        return styles;\n    };\n}\n\n@implementation AMXMarkdownHelper\n\n\n+ (NSMutableAttributedString *)mdToAttrString:(NSString *)text\n                                defaultStyles:(AMTextStyles *)defaultStyles {\n    if (![text isKindOfClass:NSString.class] || (text.length == 0)) {\n        return nil;\n    }\n    AMTextStyles *styles = defaultStyles ?: [AMTextStyles cpl_cardDefaultTextStyles];\n    if (styles) {\n        @try {\n            return [[text markdownToAttributedStringWithStyles_ant_mark:styles] mutableCopy];\n        } @catch (NSException *exception) {\n            CPLLogInfo(@\"get attribute string failed: %@\", exception.description);\n        }\n    }\n    return nil;\n}\n+ (nullable NSMutableAttributedString *)mdToAttrString:(NSString *)text\n                                         defaultStyles:(nullable AMTextStyles *)defaultStyles\n                                              delegate:(id<CMAttributedStringRendererDelegate>)delegate\n                                              textView:(UITextView*)textView\n{\n    if (![text isKindOfClass:NSString.class] || (text.length == 0)) {\n        return nil;\n    }\n    AMTextStyles *styles = defaultStyles ?: [AMTextStyles cpl_cardDefaultTextStyles];\n    if (styles) {\n        @try {\n            return [[text markdownToAttributedStringWithStyles_ant_mark:styles delegate:delegate] mutableCopy];\n        } @catch (NSException *exception) {\n            CPLLogInfo(@\"get attribute string failed: %@\", exception.description);\n            if ([textView isKindOfClass:[AMXMarkdownTextView class]] && ((AMXMarkdownTextView*)textView).textViewDelegate) {\n                if ([((AMXMarkdownTextView*)textView).textViewDelegate respondsToSelector:@selector(onError:)]) {\n                    NSError* error = [NSError errorWithDomain:@\"AMStreamRender\"\n                                                         code:1002\n                                                     userInfo:@{NSLocalizedDescriptionKey: exception.description}];\n                    [((AMXMarkdownTextView*)textView).textViewDelegate onError:error];\n                }\n            }\n        }\n    }\n    return nil;\n}\n\n+ (void)setImageAttachListener:(NSMutableAttributedString *)attrText\n                      delegate:(id<AMXImageAttachmentProtocol>)delegate {\n    [attrText enumerateAttribute:NSAttachmentAttributeName\n                         inRange:NSMakeRange(0, attrText.length)\n                         options:0\n                      usingBlock:^(id value, NSRange range, BOOL *stop) {\n        if ([value isKindOfClass:[AMXMarkdownImageTextAttachment class]]) {\n            AMXMarkdownImageTextAttachment *attachment = (AMXMarkdownImageTextAttachment *)value;\n            attachment.imgDelegate = delegate;\n            [attachment refreshImageIfNeed];\n        }\n    }];\n}\n\n+ (void)transformParagraph:(AMTextStyles*)defalutStyle customStyle:(AMXMarkdownStyleConfig*)config {\n    [defalutStyle.paragraphAttributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeMinimumLineHeight:@([config getLineHeight:AMXElementTypeParagraph])\n    }];\n    [defalutStyle.paragraphAttributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeParagraphSpacingBefore: @([config getSpacingConfig:AMXElementTypeParagraph].paragraphSpacingBefore)\n    }];\n    [defalutStyle.paragraphAttributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeParagraphSpacing: @([config getSpacingConfig:AMXElementTypeParagraph].paragraphSpacing)\n    }];\n    [defalutStyle.paragraphAttributes.stringAttributes addEntriesFromDictionary:@{\n        NSFontAttributeName: [config getFontConfig:AMXElementTypeParagraph].font,\n    }];\n    [defalutStyle.baseTextAttributes.stringAttributes addEntriesFromDictionary:@{\n        NSFontAttributeName: [config getFontConfig:AMXElementTypeParagraph].font,\n    }];\n    [defalutStyle.paragraphAttributes.stringAttributes addEntriesFromDictionary:@{\n        NSForegroundColorAttributeName : [config getFontConfig:AMXElementTypeParagraph].fontColor\n    }];\n}\n+ (void)transformTitle:(AMTextStyles*)defalutStyle customStyle:(AMXMarkdownStyleConfig*)config {\n    AMXFontConfig* font1 = [config getFontConfig:AMXElementTypeHeader1];\n    [defalutStyle.h1Attributes.stringAttributes addEntriesFromDictionary:@{\n        NSForegroundColorAttributeName: font1.fontColor,\n        NSKernAttributeName: @(0.25),\n        NSFontAttributeName: font1.font\n    }];\n    AMXSpacingConfig* space1 = [config getSpacingConfig:AMXElementTypeHeader1];\n    [defalutStyle.h1Attributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeParagraphSpacingBefore: @(space1.paragraphSpacingBefore),\n        CMParagraphStyleAttributeParagraphSpacing: @(space1.paragraphSpacing)\n    }];\n    [defalutStyle.h1Attributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeMinimumLineHeight:@([config getLineHeight:AMXElementTypeHeader1])\n    }];\n    AMXFontConfig* font2 = [config getFontConfig:AMXElementTypeHeader2];\n    [defalutStyle.h2Attributes.stringAttributes addEntriesFromDictionary:@{\n        NSForegroundColorAttributeName: font2.fontColor,\n        NSKernAttributeName: @(0.25),\n        NSFontAttributeName: font2.font\n    }];\n    AMXSpacingConfig* space2 = [config getSpacingConfig:AMXElementTypeHeader2];\n    [defalutStyle.h2Attributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeParagraphSpacingBefore: @(space2.paragraphSpacingBefore),\n        CMParagraphStyleAttributeParagraphSpacing: @(space2.paragraphSpacing)\n    }];\n    [defalutStyle.h2Attributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeMinimumLineHeight:@([config getLineHeight:AMXElementTypeHeader2])\n    }];\n    AMXFontConfig* font3 = [config getFontConfig:AMXElementTypeHeader3];\n    [defalutStyle.h3Attributes.stringAttributes addEntriesFromDictionary:@{\n        NSForegroundColorAttributeName: font3.fontColor,\n        NSKernAttributeName: @(0.25),\n        NSFontAttributeName: font3.font\n    }];\n    AMXSpacingConfig* space3 = [config getSpacingConfig:AMXElementTypeHeader3];\n    [defalutStyle.h3Attributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeParagraphSpacingBefore: @(space3.paragraphSpacingBefore),\n        CMParagraphStyleAttributeParagraphSpacing: @(space3.paragraphSpacing)\n    }];\n    [defalutStyle.h3Attributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeMinimumLineHeight:@([config getLineHeight:AMXElementTypeHeader3])\n    }];\n    AMXFontConfig* font4 = [config getFontConfig:AMXElementTypeHeader4];\n    [defalutStyle.h4Attributes.stringAttributes addEntriesFromDictionary:@{\n        NSForegroundColorAttributeName: font4.fontColor,\n        NSKernAttributeName: @(0.25),\n        NSFontAttributeName: font4.font\n    }];\n    AMXSpacingConfig* space4 = [config getSpacingConfig:AMXElementTypeHeader4];\n    [defalutStyle.h4Attributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeParagraphSpacingBefore: @(space4.paragraphSpacingBefore),\n        CMParagraphStyleAttributeParagraphSpacing: @(space4.paragraphSpacing)\n    }];\n    [defalutStyle.h4Attributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeMinimumLineHeight:@([config getLineHeight:AMXElementTypeHeader4])\n    }];\n    AMXFontConfig* font5 = [config getFontConfig:AMXElementTypeHeader5];\n    [defalutStyle.h5Attributes.stringAttributes addEntriesFromDictionary:@{\n        NSForegroundColorAttributeName: font5.fontColor,\n        NSKernAttributeName: @(0.25),\n        NSFontAttributeName: font5.font\n    }];\n    AMXSpacingConfig* space5 = [config getSpacingConfig:AMXElementTypeHeader5];\n    [defalutStyle.h5Attributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeParagraphSpacingBefore: @(space5.paragraphSpacingBefore),\n        CMParagraphStyleAttributeParagraphSpacing: @(space5.paragraphSpacing)\n    }];\n    [defalutStyle.h5Attributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeMinimumLineHeight:@([config getLineHeight:AMXElementTypeHeader5])\n    }];\n    AMXFontConfig* font6 = [config getFontConfig:AMXElementTypeHeader6];\n    [defalutStyle.h6Attributes.stringAttributes addEntriesFromDictionary:@{\n        NSForegroundColorAttributeName: font6.fontColor,\n        NSKernAttributeName: @(0.25),\n        NSFontAttributeName: font6.font\n    }];\n    AMXSpacingConfig* space6 = [config getSpacingConfig:AMXElementTypeHeader6];\n    [defalutStyle.h6Attributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeParagraphSpacingBefore: @(space6.paragraphSpacingBefore),\n        CMParagraphStyleAttributeParagraphSpacing: @(space6.paragraphSpacing)\n    }];\n    [defalutStyle.h6Attributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeMinimumLineHeight:@([config getLineHeight:AMXElementTypeHeader6])\n    }];\n    \n}\n+ (void)transformHRule:(AMTextStyles*)defalutStyle customStyle:(AMXMarkdownStyleConfig*)config {\n    [defalutStyle.horizontalRuleAttributes.stringAttributes addEntriesFromDictionary:@{CMHorizontalRuleThickness:@(config.hRuleConfig.height)}];\n    [defalutStyle.horizontalRuleAttributes.stringAttributes addEntriesFromDictionary:@{\n        NSForegroundColorAttributeName : config.hRuleConfig.color\n    }];\n    AMXSpacingConfig* spacing = [config getSpacingConfig:AMXElementTypeHRule];\n    [defalutStyle.horizontalRuleAttributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeParagraphSpacingBefore: @(spacing.paragraphSpacingBefore)\n    }];\n    [defalutStyle.horizontalRuleAttributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeParagraphSpacing: @(spacing.paragraphSpacing)\n    }];\n}\n+ (void)transformTable:(AMTextStyles*)defalutStyle customStyle:(AMXMarkdownStyleConfig*)config {\n    AMXTableStyleConfig* tableConfig = config.tableConfig;\n    \n    [defalutStyle.tableCellAttributes.stringAttributes addEntriesFromDictionary:@{@\"defaultMaxWidth\":@(tableConfig.columnMaxWidth)}];\n    [defalutStyle.tableCellAttributes.stringAttributes addEntriesFromDictionary:@{@\"firstMaxWidth\":@(tableConfig.firstColumnMaxWidth)}];\n    [defalutStyle.tableCellAttributes.stringAttributes addEntriesFromDictionary:@{@\"cellPadding\":@(tableConfig.contentStyle.padding)}];\n    \n    [defalutStyle.tableHeaderAttributes.stringAttributes addEntriesFromDictionary:@{@\"contentBgColor\":tableConfig.headerStyle.backgroundColor}];\n    [defalutStyle.tableHeaderAttributes.stringAttributes addEntriesFromDictionary:@{NSBackgroundColorAttributeName:[UIColor clearColor]}];\n    [defalutStyle.tableHeaderAttributes.fontAttributes addEntriesFromDictionary:@{\n        UIFontDescriptorSizeAttribute: @(tableConfig.headerStyle.font.font.pointSize),\n    }];\n    [defalutStyle.tableHeaderAttributes.stringAttributes addEntriesFromDictionary:@{NSForegroundColorAttributeName:tableConfig.headerStyle.font.fontColor}];\n    [defalutStyle.tableCellAttributes.stringAttributes addEntriesFromDictionary:@{@\"contentBgColor\":tableConfig.contentStyle.backgroundColor}];\n    [defalutStyle.tableCellAttributes.stringAttributes addEntriesFromDictionary:@{NSBackgroundColorAttributeName:[UIColor clearColor]}];\n    [defalutStyle.tableCellAttributes.fontAttributes addEntriesFromDictionary:@{\n        UIFontDescriptorSizeAttribute: @(tableConfig.contentStyle.font.font.pointSize),\n    }];\n    [defalutStyle.tableCellAttributes.stringAttributes addEntriesFromDictionary:@{NSForegroundColorAttributeName:tableConfig.contentStyle.font.fontColor}];\n    [defalutStyle.tableTitleAttributes.stringAttributes addEntriesFromDictionary:@{NSBackgroundColorAttributeName:tableConfig.titleBackgroundColor}];\n    [defalutStyle.tableTitleAttributes.fontAttributes addEntriesFromDictionary:@{\n        UIFontDescriptorSizeAttribute: @(tableConfig.titlefont.font.pointSize),\n    }];\n    [defalutStyle.tableTitleAttributes.stringAttributes addEntriesFromDictionary:@{NSForegroundColorAttributeName:tableConfig.titlefont.fontColor}];\n    AMXSpacingConfig* spacing = [config getSpacingConfig:AMXElementTypeTable];\n    [defalutStyle.tableAttributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeParagraphSpacingBefore: @(spacing.paragraphSpacingBefore)\n     }];\n    [defalutStyle.tableAttributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n        CMParagraphStyleAttributeParagraphSpacing: @(spacing.paragraphSpacing)\n     }];\n    [defalutStyle.tableAttributes.stringAttributes addEntriesFromDictionary:@{@\"rowSpacing\":@(tableConfig.rowSpacing)}];\n    [defalutStyle.tableAttributes.stringAttributes addEntriesFromDictionary:@{@\"columnSpacing\":@(tableConfig.columnSpacing)}];\n    [defalutStyle.tableAttributes.stringAttributes addEntriesFromDictionary:@{@\"borderWidth\":@(tableConfig.borderWidth)}];\n     [defalutStyle.tableAttributes.stringAttributes addEntriesFromDictionary:@{@\"operationIcon\":tableConfig.operationIconPath}];\n}\n+ (void)transformOrderList:(AMTextStyles*)defalutStyle customStyle:(AMXMarkdownStyleConfig*)config {\n    NSDictionary* dic = [config getAllLevelOrderListConfigs];\n    AMXSpacingConfig* space = [config getSpacingConfig:AMXElementTypeOrderedList];\n    AMXFontConfig* font = [config getFontConfig:AMXElementTypeOrderedList];\n    CGFloat lineHeight = [config getLineHeight:AMXElementTypeOrderedList];\n    CGFloat firstLevelIndent = 0;\n    NSMutableDictionary* arrayStrDic = [[NSMutableDictionary alloc] init];\n    NSMutableDictionary* arrayParaDic = [[NSMutableDictionary alloc] init];\n    for (NSString* tmpKey in dic.allKeys) {\n        NSInteger indexLevel = [tmpKey intValue];\n        if (indexLevel > 0) {\n            AMXListLevelConfig* listConfig = [dic objectForKey:tmpKey];\n            if (indexLevel == 1) {\n                firstLevelIndent = listConfig.symbolIndentation;\n            }\n            NSMutableDictionary* subStrDic = [[NSMutableDictionary alloc] init];\n            NSMutableDictionary* subParaDic = [[NSMutableDictionary alloc] init];\n            [subParaDic addEntriesFromDictionary:@{CMParagraphStyleAttributeParagraphSpacingBefore:@(space.paragraphSpacingBefore)}];\n            [subParaDic addEntriesFromDictionary:@{CMParagraphStyleAttributeParagraphSpacing:@(space.paragraphSpacing)}];\n            [subStrDic addEntriesFromDictionary:@{NSForegroundColorAttributeName:font.fontColor}];\n            [subParaDic addEntriesFromDictionary:@{CMParagraphStyleAttributeMinimumLineHeight:@(lineHeight)}];\n            [subStrDic addEntriesFromDictionary:@{CMListLevelIndent:@(listConfig.symbolIndentation)}];\n            if (listConfig.prefixType == AMXListPrefixTypeCharacter) {\n                [subParaDic addEntriesFromDictionary:@{CMParagraphStyleAttributeListItemNumberFormat: listConfig.prefixSymbol}];\n                \n                [subStrDic addEntriesFromDictionary:@{CMListInternalSpace:@(listConfig.prefixSpacing),\n                                            CMListSingleDigitSize:@(listConfig.symbolSize.width),\n                                            CMListTwoDigitSize:@(listConfig.symbolSize.width + 9),\n                                            CMListThreeDigitSize:@(listConfig.symbolSize.width + 18)}];\n            } else {\n\n                [subStrDic addEntriesFromDictionary:@{CMParagraphStyleAttributeListItemLabelIcon:listConfig.prefixSymbolPath}];\n                \n                [subStrDic addEntriesFromDictionary:@{CMListInternalSpace:@(listConfig.prefixSpacing),\n                                            CMParagraphStyleAttributeListItemLabelIconSize:@(listConfig.symbolSize.width)}];\n            }\n            \n            [arrayStrDic setObject:subStrDic forKey:tmpKey];\n            [arrayParaDic setObject:subParaDic forKey:tmpKey];\n        }\n    }\n    \n    [defalutStyle.orderedListItemAttributes.stringAttributes addEntriesFromDictionary:@{NSForegroundColorAttributeName:font.fontColor}];\n    [defalutStyle.orderedListItemAttributes.stringAttributes addEntriesFromDictionary:@{\n        NSFontAttributeName: font.font,\n    }];\n    \n    AMStyleProvider styleProvide = AMCustomProvider();\n    defalutStyle.ordererListAttributesProvider = ^CMStyleAttributes * _Nonnull(NSInteger level) {\n        CMStyleAttributes *attr = styleProvide(level);\n        NSString* subKey = [NSString stringWithFormat:@\"%ld\", (long)level];\n        NSDictionary* indexParaDic = [arrayParaDic objectForKey:subKey];\n        NSDictionary* indexStrDic = [arrayStrDic objectForKey:subKey];\n        if (indexParaDic && [indexParaDic count] > 0) {\n            [attr.paragraphStyleAttributes addEntriesFromDictionary:indexParaDic];\n        }\n        if (indexStrDic && [indexStrDic count] > 0) {\n            [attr.stringAttributes addEntriesFromDictionary:indexStrDic];\n        }\n\n        return attr;\n    };\n}\n+ (void)transformUnorderList:(AMTextStyles*)defalutStyle customStyle:(AMXMarkdownStyleConfig*)config {\n    NSDictionary* dic = [config getAllLevelUnorderListConfigs];\n    AMXSpacingConfig* space = [config getSpacingConfig:AMXElementTypeUnorderedList];\n    AMXFontConfig* font = [config getFontConfig:AMXElementTypeUnorderedList];\n    CGFloat lineHeight = [config getLineHeight:AMXElementTypeUnorderedList];\n    CGFloat firstLevelIndent = 0;\n    CGFloat symbolSize = 0;\n    NSMutableDictionary* arrayStrDic = [[NSMutableDictionary alloc] init];\n    NSMutableDictionary* arrayParaDic = [[NSMutableDictionary alloc] init];\n    for (NSString* tmpKey in dic.allKeys) {\n        NSInteger indexLevel = [tmpKey intValue];\n        if (indexLevel > 0) {\n            AMXListLevelConfig* listConfig = [dic objectForKey:tmpKey];\n            if (indexLevel == 1) {\n                symbolSize = listConfig.symbolSize.width;\n                firstLevelIndent = listConfig.symbolIndentation;\n            }\n            NSMutableDictionary* subStrDic = [[NSMutableDictionary alloc] init];\n            NSMutableDictionary* subParaDic = [[NSMutableDictionary alloc] init];\n            [subParaDic addEntriesFromDictionary:@{CMParagraphStyleAttributeParagraphSpacingBefore:@(space.paragraphSpacingBefore)}];\n            [subParaDic addEntriesFromDictionary:@{CMParagraphStyleAttributeParagraphSpacing:@(space.paragraphSpacing)}];\n            [subStrDic addEntriesFromDictionary:@{NSForegroundColorAttributeName:font.fontColor}];\n            [subParaDic addEntriesFromDictionary:@{CMParagraphStyleAttributeMinimumLineHeight:@(lineHeight)}];\n            [subStrDic addEntriesFromDictionary:@{CMListLevelIndent:@(listConfig.symbolIndentation)}];\n            if (listConfig.prefixType == AMXListPrefixTypeCharacter) {\n                [subParaDic addEntriesFromDictionary:@{CMParagraphStyleAttributeListItemBulletString:listConfig.prefixSymbol}];\n                \n                [subStrDic addEntriesFromDictionary:@{CMListInternalSpace:@(listConfig.prefixSpacing),\n                                            CMListSingleDigitSize:@(listConfig.symbolSize.width)}];\n            } else {\n                \n                [subStrDic addEntriesFromDictionary:@{CMParagraphStyleAttributeListItemLabelIcon:listConfig.prefixSymbolPath}];\n                \n                [subStrDic addEntriesFromDictionary:@{CMListInternalSpace:@(listConfig.prefixSpacing),\n                                            CMParagraphStyleAttributeListItemLabelIconSize:@(listConfig.symbolSize.width)}];\n            }\n            \n            [arrayStrDic setObject:subStrDic forKey:tmpKey];\n            [arrayParaDic setObject:subParaDic forKey:tmpKey];\n        }\n    }\n    [defalutStyle.listBulletAttributes.fontAttributes addEntriesFromDictionary:@{\n        UIFontDescriptorSizeAttribute: @(symbolSize),\n    }];\n    [defalutStyle.unorderedListItemAttributes.stringAttributes addEntriesFromDictionary:@{NSForegroundColorAttributeName:font.fontColor}];\n    [defalutStyle.unorderedListItemAttributes.stringAttributes addEntriesFromDictionary:@{\n        NSFontAttributeName: font.font,\n    }];\n\n    AMStyleProvider styleProvide = AMCustomProvider();\n    defalutStyle.unordererListAttributesProvider = ^CMStyleAttributes * _Nonnull(NSInteger level) {\n        CMStyleAttributes *attr = styleProvide(level);\n        NSString* subKey = [NSString stringWithFormat:@\"%ld\", (long)level];\n        NSDictionary* indexParaDic = [arrayParaDic objectForKey:subKey];\n        NSDictionary* indexStrDic = [arrayStrDic objectForKey:subKey];\n        if (indexParaDic && [indexParaDic count] > 0) {\n            [attr.paragraphStyleAttributes addEntriesFromDictionary:indexParaDic];\n        }\n        if (indexStrDic && [indexStrDic count] > 0) {\n            [attr.stringAttributes addEntriesFromDictionary:indexStrDic];\n        }\n\n        return attr;\n    };\n}\n+ (void)transformFootNote:(AMTextStyles *)defaultStyle customStyle:(AMXMarkdownStyleConfig *)config\n{\n    AMXFontConfig* font = [config getFontConfig:AMXElementTypeFootNote];\n    [defaultStyle.footNoteAttributes.stringAttributes addEntriesFromDictionary:@{\n        NSFontAttributeName: font.font,\n    }];\n    [defaultStyle.footNoteAttributes.stringAttributes addEntriesFromDictionary:@{\n        @\"labelSize\": @(config.footNoteConfig.size.width),\n    }];\n    [defaultStyle.footNoteAttributes.stringAttributes addEntriesFromDictionary:@{\n        NSBackgroundColorAttributeName : config.footNoteConfig.backgroundColor\n    }];\n    [defaultStyle.footNoteAttributes.stringAttributes addEntriesFromDictionary:@{\n        NSForegroundColorAttributeName : font.fontColor\n    }];\n   \n}\n+ (void)transformLink:(AMTextStyles*)defaultStyle customStyle:(AMXMarkdownStyleConfig*)config textView:(UITextView*)textView\n{\n    AMXFontConfig* font = [config getFontConfig:AMXElementTypeLink];\n    AMXLinkConfig* linkConfig = config.linkConfig;\n    [defaultStyle.linkAttributes.stringAttributes addEntriesFromDictionary:@{\n        NSForegroundColorAttributeName: font.fontColor,\n        NSBaselineOffsetAttributeName: @(0.0)\n    }];\n    if (textView) {\n        textView.linkTextAttributes = @{NSForegroundColorAttributeName:font.fontColor,NSUnderlineColorAttributeName:linkConfig.underLine ? font.fontColor : [UIColor clearColor]};\n    }\n  \n    if (linkConfig.iconPath) {\n        [defaultStyle.linkAttributes.stringAttributes addEntriesFromDictionary:@{CMLinkIconSpace:@(linkConfig.spacing)}];\n        if (linkConfig.prefixOrSuffix == 1) {\n            [defaultStyle.linkAttributes.stringAttributes addEntriesFromDictionary:@{CMLinkIconPrefix: linkConfig.iconPath}];\n        } else if (linkConfig.prefixOrSuffix == 2) {\n            [defaultStyle.linkAttributes.stringAttributes addEntriesFromDictionary:@{CMLinkIconSuffix: linkConfig.iconPath}];\n        }\n        \n    }\n}\n+ (void)transformInlineCode:(AMTextStyles*)defaultStyle customStyle:(AMXMarkdownStyleConfig*)config\n{\n    if (config.inlineCodeConfig.backgroundColor) {\n        [defaultStyle.inlineCodeAttributes.stringAttributes addEntriesFromDictionary:@{\n            AMBackgroundDrawableAttributeName: [AMTextBackground backgroundWithColor:config.inlineCodeConfig.backgroundColor\n                                                                              radius:4\n                                                                              insets:UIEdgeInsetsMake(5.5,2,-1,2)],\n        }];\n    }\n    \n    if (config.inlineCodeConfig.codeFont) {\n        if (config.inlineCodeConfig.codeFont.font) {\n            [defaultStyle.inlineCodeAttributes.fontAttributes addEntriesFromDictionary:@{\n                UIFontDescriptorSizeAttribute: @(config.inlineCodeConfig.codeFont.font.pointSize)\n            }];\n        }\n        \n        if (config.inlineCodeConfig.codeFont.fontColor) {\n            [defaultStyle.inlineCodeAttributes.stringAttributes addEntriesFromDictionary:@{\n                NSForegroundColorAttributeName: config.inlineCodeConfig.codeFont.fontColor\n            }];\n        }\n    }\n}\n+ (void)transformCodeBlock:(AMTextStyles*)defaultStyle customStyle:(AMXMarkdownStyleConfig*)config\n{\n    AMXCodeBlockConfig* codeConfig = config.codeBlockConfig;\n    if (codeConfig.titleBackgroundColor) {\n        [defaultStyle.codeBlockAttributes.stringAttributes addEntriesFromDictionary:@{@\"headerBackgroundColor\":codeConfig.titleBackgroundColor}];\n    }\n    if (codeConfig.titleFont) {\n        [defaultStyle.codeBlockAttributes.stringAttributes addEntriesFromDictionary:@{@\"titleFont\":codeConfig.titleFont.font}];\n        [defaultStyle.codeBlockAttributes.stringAttributes addEntriesFromDictionary:@{@\"titleFontColor\":codeConfig.titleFont.fontColor}];\n    \n    }\n    if (codeConfig.borderColor) {\n        [defaultStyle.codeBlockAttributes.stringAttributes addEntriesFromDictionary:@{@\"borderColor\":codeConfig.borderColor}];\n    }\n    if (codeConfig.borderWidth) {\n        [defaultStyle.codeBlockAttributes.stringAttributes addEntriesFromDictionary:@{@\"borderWidth\":@(codeConfig.borderWidth)}];\n    }\n    if (codeConfig.backgroundColor) {\n        [defaultStyle.codeBlockAttributes.stringAttributes addEntriesFromDictionary:@{@\"backgroundColor\":codeConfig.backgroundColor}];\n        [defaultStyle.codeBlockAttributes.stringAttributes addEntriesFromDictionary:@{NSBackgroundColorAttributeName:codeConfig.backgroundColor}];\n    }\n    [defaultStyle.codeBlockAttributes.stringAttributes addEntriesFromDictionary:@{@\"operationIcon\":codeConfig.operationIconPath}];\n    \n}\n\n+ (void)transformUnderLine:(AMTextStyles*)defaultStyle customStyle:(AMXMarkdownStyleConfig*)config\n{\n    AMXUnderLineConfig* underlineConfig = config.underlineConfig;\n    if (underlineConfig.lineColor) {\n        [defaultStyle.underlineAttributes.stringAttributes addEntriesFromDictionary:@{NSForegroundColorAttributeName:underlineConfig.lineColor}];\n    }\n    [defaultStyle.underlineAttributes.stringAttributes addEntriesFromDictionary:@{\n                                                                                  @\"lineWidth\":@(underlineConfig.lineWidth),\n                                                                                  @\"lineOffset\":@(underlineConfig.lineOffset)}];\n}\n+ (void)transformBlockQuote:(AMTextStyles*)defaultStyle customStyle:(AMXMarkdownStyleConfig*)config\n{\n    AMXBlockquoteStyle* blockQuote = config.blockQuoteConfig;\n    if (blockQuote) {\n        [defaultStyle.blockQuoteAttributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n            CMParagraphStyleAttributeFirstLineHeadExtraIndent: @(blockQuote.indentation)\n        }];\n        [defaultStyle.blockQuoteAttributes.paragraphStyleAttributes addEntriesFromDictionary:@{\n            CMParagraphStyleAttributeHeadExtraIndent: @(blockQuote.indentation)\n        }];\n        \n        [defaultStyle.blockQuoteAttributes.stringAttributes addEntriesFromDictionary:@{\n            AMBackgroundDrawableAttributeName: [AMTextBackground leftBorderColor:blockQuote.lineColor                    width:blockQuote.lineWidth],\n        }];\n        \n    }\n    AMXFontConfig* font = [config getFontConfig:AMXElementTypeBlockQuote];\n    if (font) {\n        [defaultStyle.blockQuoteAttributes.stringAttributes addEntriesFromDictionary:@{\n            NSForegroundColorAttributeName : font.fontColor\n        }];\n        [defaultStyle.blockQuoteAttributes.stringAttributes addEntriesFromDictionary:@{NSFontAttributeName:font.font}];\n    }\n    AMXSpacingConfig* spaceConfig = [config getSpacingConfig:AMXElementTypeBlockQuote];\n    if (spaceConfig) {\n        [defaultStyle.blockQuoteAttributes.paragraphStyleAttributes addEntriesFromDictionary:@{CMParagraphStyleAttributeParagraphSpacing:@(spaceConfig.paragraphSpacing),CMParagraphStyleAttributeParagraphSpacingBefore:@(spaceConfig.paragraphSpacingBefore)}];\n    }\n}\n@end\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Markdown/AMXMarkdownImageAttachmentBuilder.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n#import <AntMarkdown/AMTextStyles.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMXMarkdownImageAttachmentBuilder : NSObject<AMImageAttachmentBuilder>\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Markdown/AMXMarkdownImageAttachmentBuilder.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMXMarkdownImageAttachmentBuilder.h\"\n#import \"AMXMarkdownImageTextAttachment.h\"\n\n@implementation AMXMarkdownImageAttachmentBuilder\n\n- (NSTextAttachment *)buildWithURL:(NSURL *)url\n                             title:(nullable NSString *)title\n                            styles:(AMTextStyles *)styles {\n    AMXMarkdownImageTextAttachment *textAttachment = [[AMXMarkdownImageTextAttachment alloc] initWithImageURL:url];\n    return textAttachment;\n}\n\n@end\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Markdown/AMXMarkdownImageTextAttachment.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <UIKit/UIKit.h>\n#import <AntMarkdown/AntMarkdown.h>\n#import <AntMarkdown/AMImageTextAttachment.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@protocol AMXMarkDownImageAttachmentProtocol <NSObject>\n\n- (UIImage *)getImageFromCacheIfExist:(NSString *)url;\n\n- (void)onImageLoadFinish:(UIImage *)image url:(NSString *)url;\n\n@end\n\n@interface AMXMarkdownImageTextAttachment : AMImageTextAttachment<AMImageAttachmentBuilder>\n\n@property (nonatomic, weak) id<AMXMarkDownImageAttachmentProtocol> imgDelegate;\n\n- (void)refreshImageIfNeed;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Markdown/AMXMarkdownImageTextAttachment.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMXMarkdownImageTextAttachment.h\"\n\n@interface AMXMarkdownImageTextAttachment ()\n{\n    BOOL _isImageLoaded_ap;\n    NSURLSessionDataTask* _downloadTask;\n    NSURL       * _imageURL;\n}\n\n@property(nonatomic,assign)CGSize imgSize;\n\n@property(nonatomic,assign)BOOL isDownloading;\n\n@end\n\n@implementation AMXMarkdownImageTextAttachment\n\n- (NSTextAttachment *)buildWithURL:(NSURL *)url\n                             title:(nullable NSString *)title\n                            styles:(AMTextStyles *)styles;\n{\n    return [[AMXMarkdownImageTextAttachment alloc] initWithImageURL:url];\n}\n\n- (void)downloadImage:(NSURL *)imageURL \n           completion:(void(^)(NSError * _Nullable error, NSData * _Nullable data))block {\n    // Not a file URL and no download task in progress: use an URL-data-task to get the data\n    [self downloadImage];\n}\n\n- (void)downloadImage\n{\n    if (self.isDownloading) {\n        return;\n    }\n    __weak typeof(self) weakSelf = self;\n    self.isDownloading = YES;\n    _downloadTask = [NSURLSession.sharedSession dataTaskWithURL:self.imageURL\n                                              completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {\n        if ((error == nil) && (data.length > 0)) {\n            UIImage* image = [UIImage imageWithData:data];\n            [weakSelf setImageWithImage:image];\n            if (weakSelf.imgDelegate &&\n                [weakSelf.imgDelegate respondsToSelector:@selector(onImageLoadFinish:url:)]) {\n                [weakSelf.imgDelegate onImageLoadFinish:[UIImage imageWithData:data] url:[weakSelf.imageURL absoluteString]];\n            }\n        }\n        \n        self->_downloadTask = nil;\n        self.isDownloading = NO;\n    }];\n    \n    [_downloadTask resume];\n}\n\n- (void)setImageWithImage:(UIImage *)image {\n    if (!image) {\n        return;\n    }\n    CGSize currentImageSize = (self.image == nil) ? CGSizeZero : self.image.size;\n    self.image = image;\n    self.imgSize = self.image.size;\n    if (self.image != nil) {\n        dispatch_async(dispatch_get_main_queue(), ^{\n            if (!CGSizeEqualToSize(self.image.size, currentImageSize)) {\n                 // The layout needs to be refreshed\n                [self.textContainer.layoutManager setNeedsLayoutForAttachment:self];\n            } else {\n                // The image display should be refreshed\n                [self.textContainer.layoutManager setNeedsDisplayForAttachment:self];\n            }\n        });\n    }\n    self.isImageLoaded = YES;\n}\n\n- (void)refreshImageIfNeed {\n    if ([self.imgDelegate respondsToSelector:@selector(getImageFromCacheIfExist:)]) {\n        UIImage *img = [self.imgDelegate getImageFromCacheIfExist:[self.imageURL absoluteString]];\n        if (img) {\n            self.image = img;\n            self.imgSize = self.image.size;\n            self.isImageLoaded = YES;\n        }\n    }\n}\n\n@end\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Markdown/AMXMarkdownLogModel.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMXMarkdownLogModel : NSObject\n/// The id of the log\n@property (nonatomic, copy) NSString *spm;\n\n/// Extra parameters\n@property (nonatomic, strong) NSDictionary *extraParams;\n\n/// The unique style id\n@property (nonatomic, copy) NSString *styleId;\n\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Markdown/AMXMarkdownLogModel.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMXMarkdownLogModel.h\"\n\n@implementation AMXMarkdownLogModel\n\n@end\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Markdown/AMXMarkdownTextView.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n#import <AntMarkdown/CMAttributedStringRenderer.h>\n#import \"AMXMarkdownLogModel.h\"\n#import \"AMXMarkdownCustomRenderEventModel.h\"\n\nNS_ASSUME_NONNULL_BEGIN;\n\n/**\n Clickable elemant type\n */\ntypedef enum : NSUInteger {\n    AMXMarkdownTapIconLink,\n    AMXMarkdownTapLink,\n    AMXMarkdownTapImage,\n    AMXMarkdownTapTable,\n} AMXMarkdownTapType;\n/**\n Printing state\n */\ntypedef enum : NSUInteger {\n    AMXMarkdownPrintStateInitial,\n    AMXMarkdownPrintStateRunning,\n    AMXMarkdownPrintStatePaused,\n    AMXMarkdownPrintStateStopped,\n} AMXMarkdownPrintState;\n\n@protocol AMXMarkdownTextViewDelegate <NSObject>\n/**\n MarkdownView size change\n */\n-(void)onSizeChange:(CGSize)size;\n/**\n Markdown printing state change\n */\n-(void)didChangeState:(AMXMarkdownPrintState)state;\n/**\n The delagate of tap action\n */\n-(void)onTap:(AMXMarkdownTapType)type content:(id)content gesture:(UITapGestureRecognizer *)gesture attachment:(NSTextAttachment*)attachment tapIndex:(NSUInteger)tapIndex attrString:(NSAttributedString*)attrString;\n/**\n The delagate of exposure element\n */\n-(void)onUpdateExposureElement:(NSArray<AMXMarkdownCustomRenderEventModel*>*)elements;\n\n/**\n Exception\n */\n-(void)onError:(NSError*)error;\n\n@end\n\n@interface AMXMarkdownTextView : UITextView\n\n@property (nonatomic, weak, nullable) id<AMXMarkdownTextViewDelegate> textViewDelegate;\n/**\n Time interval of printing（unit：s），default is  0.025\n */\n@property (nonatomic, assign) NSTimeInterval typingSpeed;\n/**\n The step length of printing，default is 1\n */\n@property (nonatomic, assign) NSInteger chunkSize;\n/**\n The unique style id of markdownView instance\n */\n@property (nonatomic, strong) NSString* styleId;\n\n/**\n Log model\n */\n@property (nonatomic, strong) AMXMarkdownLogModel   *logModel;\n\n/**\n Init with frame, it will change while printing\n */\n- (instancetype)initWithFrame_ant_mark:(CGRect)frame;\n/**\n Start print with content.\n */\n- (void)startStreamingWithContent:(NSString*)content;\n\n/**\n Start print with content, and you can set the index of printing action.\n */\n- (void)startStreamingWithContent:(NSString*)content printIndex:(NSInteger)printIndex;\n/**\n Append markdown data\n */\n- (void)addStreamContent:(NSString *)text;\n/**\n Pause, it will continue when run continue function with the previous string\n */\n- (void)pause;\n/**\n Continue, it will continue after pause function with the previous string\n */\n- (void)resume;\n/**\n Stop print，it will stop and clear previous string data\n */\n- (void)stop;\n/**\n Reset, all state recover\n */\n- (void)reset;\n\n/**\n Render the markdown string directly without printing process\n */\n- (void)renderCompleteContent:(NSString *)text;\n/**\n Calculate ths markdownView size with string and style\n */\n+ (CGSize)caculateContentSize:(NSString *)markdownText constrainSize:(CGSize)constrainSize styleId:(NSString*)styleId;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Markdown/AMXMarkdownTextView.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMXMarkdownTextView.h\"\n#import \"AMXMarkdownTimer.h\"\n#import <AntMarkdown/AMTextStyles.h>\n#import \"AMTextStyles+CardUIPlugins.h\"\n#import \"AMXMarkdownHelper.h\"\n#import \"AMXRenderService.h\"\n#import <AntMarkdown/AMUtils.h>\n#import \"AMXMarkdownUtil.h\"\n#import \"AMXMarkdownDefine.h\"\n#import \"AMXMarkdownCustomRenderEventModel.h\"\n#import \"AMXMarkdownLogModel.h\"\n\nstatic AMXMarkdownTextView* _caculateContentView;\n\n@interface AMXMarkdownTextView()<UITextViewDelegate, UIGestureRecognizerDelegate,CMAttributedStringRendererDelegate, AMXMarkdownTimerDelegate, AMXImageAttachmentProtocol>\n@property (nonatomic, strong) AMXMarkdownTimer  *timer;\n@property (nonatomic, strong) dispatch_queue_t    queue;\n@property (atomic, strong) NSMutableAttributedString *markdownAttrStr;\n@property (atomic, strong) NSMutableAttributedString *preloadMarkdownAttrStr;\n@property (atomic, assign) NSInteger              timerCountIndex;\n@property (nonatomic, assign)AMXMarkdownPrintState state;\n@property (nonatomic, strong)AMTextStyles* nativeStyles;\n@property (atomic, strong) NSMutableArray    *clickableObjs;\n@property (atomic, strong) NSMutableArray    *clickableLocationObjs;\n@property (atomic, strong) NSMutableDictionary    *cacheImgDic;\n@property (atomic, strong) NSString    *contentStr;\n@end\n\n@implementation AMXMarkdownTextView\n- (instancetype)initWithFrame_ant_mark:(CGRect)frame {\n    if (self = [super initWithFrame_ant_mark:frame delegate:self]) {\n        self.queue = dispatch_queue_create(\"AMXMarkdownWidget\", DISPATCH_QUEUE_SERIAL);\n        self.typingSpeed = 0.025;\n        self.chunkSize = 1;\n        self.cacheImgDic = NSMutableDictionary.new;\n        self.state = AMXMarkdownPrintStateInitial;\n        self.logModel = [[AMXMarkdownLogModel alloc] init];\n        // This is an example.\n        self.logModel.spm = @\"a235\";\n        self.logModel.styleId = @\"demo\";\n        self.textContainerInset = UIEdgeInsetsZero;\n        self.textContainer.lineFragmentPadding = 0;\n        self.backgroundColor = UIColor.clearColor;\n        \n        self.userInteractionEnabled = YES;\n        self.scrollEnabled = NO;\n        \n        self.editable = NO;\n        self.delegate = self;\n        self.multipleTouchEnabled = NO;\n        \n        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self\n                                                                              action:@selector(handleTap:)];\n        tap.delegate = self;\n        [[NSNotificationCenter defaultCenter] addObserver:self\n                                                 selector:@selector(onSizeChanged:)\n                                                     name:AMTextAttachmentSizeDidUpdateNotification\n                                                   object:nil];\n        [self addGestureRecognizer:tap];\n    }\n    return self;\n}\n-(void)setStyleId:(NSString *)styleId\n{\n    _styleId = styleId;\n    ((AMLayoutManager*)self.layoutManager).styleId = styleId;\n}\n- (void)renderCompleteContent:(NSString *)text\n{\n    NSMutableAttributedString* attrStr = [self markdowmMutableAttributedStringFromValue:text];\n    [AMXMarkdownHelper setImageAttachListener:attrStr delegate:self];\n    [self setAttributedTextPartialUpdate_ant_mark:attrStr];\n    [self updateSize];\n}\n- (void)startStreamingWithContent:(NSString*)content\n{\n    if (self.state != AMXMarkdownPrintStateStopped && self.state != AMXMarkdownPrintStateInitial) {\n        NSError* error = [NSError errorWithDomain:@\"AMStreamPrinter\"\n                                             code:1001\n                                         userInfo:@{NSLocalizedDescriptionKey: @\"Invalid state transition\"}];\n        [self notifyError:error];\n        return;\n    }\n    \n    if (self.typingSpeed == 0) {\n        NSError* error = [NSError errorWithDomain:@\"AMStreamPrinter\"\n                                             code:1001\n                                         userInfo:@{NSLocalizedDescriptionKey: @\"Invalid speed param\"}];\n        [self notifyError:error];\n        return;\n    }\n    self.state = AMXMarkdownPrintStateRunning;\n    self.preloadMarkdownAttrStr = [self markdowmMutableAttributedStringFromValue:content];\n    self.contentStr = content;\n    [self startTimer];\n}\n- (void)startStreamingWithContent:(NSString*)content printIndex:(NSInteger)printIndex\n{\n    if (printIndex >= (content.length - 1)) {\n        [self renderCompleteContent:content];\n        return;\n    }\n    if (self.state != AMXMarkdownPrintStateStopped && self.state != AMXMarkdownPrintStateInitial) {\n        NSError* error = [NSError errorWithDomain:@\"AMStreamPrinter\"\n                                             code:1001\n                                         userInfo:@{NSLocalizedDescriptionKey: @\"Invalid state transition\"}];\n        [self notifyError:error];\n        return;\n    }\n    \n    if (self.typingSpeed == 0) {\n        NSError* error = [NSError errorWithDomain:@\"AMStreamPrinter\"\n                                             code:1001\n                                         userInfo:@{NSLocalizedDescriptionKey: @\"Invalid speed param\"}];\n        [self notifyError:error];\n        return;\n    }\n    self.state = AMXMarkdownPrintStateRunning;\n    self.preloadMarkdownAttrStr = [self markdowmMutableAttributedStringFromValue:content];\n    self.contentStr = content;\n    [self renderCompleteContent:[content substringToIndex:printIndex]];\n    self.timerCountIndex = printIndex;\n    [self startTimer];\n}\n- (void)addStreamContent:(NSString *)text\n{\n    if (self.state != AMXMarkdownPrintStateRunning && self.state != AMXMarkdownPrintStatePaused) {\n        return;\n    }\n    self.contentStr = [self.contentStr stringByAppendingString:text];\n    self.preloadMarkdownAttrStr = [self markdowmMutableAttributedStringFromValue:self.contentStr];\n    if (self.state == AMXMarkdownPrintStatePaused) {\n        [self resume];\n    }\n}\n- (void)pause\n{\n    if (self.state == AMXMarkdownPrintStateRunning) {\n        self.state = AMXMarkdownPrintStatePaused;\n        [self.textViewDelegate didChangeState:AMXMarkdownPrintStatePaused];\n    }\n    [self stopTimer];\n    __weak typeof(self) weakSelf = self;\n    dispatch_async_on_main_queue(^{\n        __strong typeof(weakSelf) strongSelf = weakSelf;\n        // render all data without animation to remove the animation maksk layer\n        [strongSelf setAttributedTextPartialUpdate_ant_mark:strongSelf.preloadMarkdownAttrStr];\n    });\n}\n- (void)resume\n{\n    if (self.state == AMXMarkdownPrintStatePaused) {\n        self.state = AMXMarkdownPrintStateRunning;\n        [self.textViewDelegate didChangeState:AMXMarkdownPrintStateRunning];\n    }\n    [self startTimer];\n}\n- (void)stop\n{\n    if (self.state != AMXMarkdownPrintStateRunning && self.state != AMXMarkdownPrintStatePaused) {\n        return;\n    }\n    [self.timer stopTimer];\n    self.timer = nil;\n    \n    NSMutableAttributedString *attrStr = self.markdownAttrStr.mutableCopy;\n    __weak typeof(self) weakSelf = self;\n    dispatch_async(self.queue, ^{\n        [AMXMarkdownHelper setImageAttachListener:attrStr delegate:self];\n        dispatch_async_on_main_queue(^{\n            __strong typeof(weakSelf) strongSelf = weakSelf;\n            // render all data without animation to remove the animation maksk layer\n            [strongSelf setAttributedTextPartialUpdate_ant_mark:strongSelf.preloadMarkdownAttrStr];\n            [strongSelf updateSize];\n            [strongSelf reset];\n            [strongSelf.textViewDelegate didChangeState:AMXMarkdownPrintStateStopped];\n        });\n    });\n}\n- (void)reset\n{\n    [self stopTimer];\n    self.timerCountIndex = 0;\n    self.preloadMarkdownAttrStr = nil;\n    self.markdownAttrStr = nil;\n    self.clickableObjs = nil;\n    self.clickableLocationObjs = nil;\n    self.state = AMXMarkdownPrintStateStopped;\n}\n- (void)onTimer {\n    if (!self.timer) {\n        return;\n    }\n    if (self.preloadMarkdownAttrStr.length == 0) {\n        return;\n    }\n    \n    if (self.timerCountIndex <= self.preloadMarkdownAttrStr.length) {\n        [self timerRenderUI];\n        self.timerCountIndex += self.chunkSize;\n        if (self.timerCountIndex > self.preloadMarkdownAttrStr.length) {\n            [self pause];\n        }\n    } else {\n        [self pause];\n    }\n}\n- (void)startTimer {\n    if(!self.timer) {\n        self.timer = [[AMXMarkdownTimer alloc] initWithConfig:self.typingSpeed*1000 queue:self.queue];\n        self.timer.delegate = self;\n    }\n    [self.timer startTimer];\n}\n- (void)stopTimer {\n    [self.timer stopTimer];\n    self.timer = nil;\n}\n- (void)timerRenderUI {\n    NSMutableAttributedString *attrStr = [self timerUpdateRenderAttrText];\n    self.markdownAttrStr = attrStr;\n    \n    __weak typeof(self) weakSelf = self;\n    if (attrStr.string.length > 0) {\n        NSLog(@\"self: %@, attr: %@, length: %ld\", self, attrStr.string, attrStr.length);\n        [AMXMarkdownHelper setImageAttachListener:attrStr delegate:weakSelf];\n    }else {\n        NSLog(@\"ignore for null attrStr\");\n        return;\n    }\n    \n    dispatch_async_on_main_queue(^{\n        __strong typeof(weakSelf) strongSelf = weakSelf;\n        [strongSelf setAttributedTextPartialUpdate_ant_mark:attrStr animated:YES];\n        [strongSelf updateSize];\n    });\n}\n- (NSMutableAttributedString *)timerUpdateRenderAttrText {\n   \n    NSMutableAttributedString *markdownAttrStr = [self.preloadMarkdownAttrStr attributedSubstringFromRange:NSMakeRange(0, MIN(self.timerCountIndex, self.preloadMarkdownAttrStr.length))].mutableCopy;\n    if (!markdownAttrStr || markdownAttrStr.length <= 0) {\n        markdownAttrStr = self.markdownAttrStr;\n    }\n    return markdownAttrStr;\n}\n-(void)notifyError:(NSError*)error\n{\n    if (self.textViewDelegate && [self.textViewDelegate respondsToSelector:@selector(onError:)]) {\n        [self.textViewDelegate onError:error];\n    }\n}\n- (void)onSizeChanged:(NSNotification *)noti {\n    if ([noti.object isKindOfClass:[NSAttributedString class]]) {\n        NSAttributedString *object = (NSAttributedString *)noti.object;\n        if ([object.string isEqualToString:self.markdownAttrStr.string]) {\n            [self updateSize];\n        }\n    }\n}\n-(void)updateSize\n{\n    dispatch_sync_on_main_queue(^{\n        CGFloat maxLabelW = self.frame.size.width;\n        CGSize limitSize = CGSizeMake(maxLabelW, MAXFLOAT);\n        CGSize contentSize = [AMXMarkdownTextView calculateSizeWithLayoutManager:self limitSize:limitSize];\n        if ([self.textViewDelegate respondsToSelector:@selector(onSizeChange:)]) {\n            [self.textViewDelegate onSizeChange:contentSize];\n        }\n    });\n    \n}\n- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {\n    return NO;\n}\n\n- (NSMutableAttributedString *)markdowmMutableAttributedStringFromValue:(NSString *)value {\n    if (value.length <= 0) {\n        return NSMutableAttributedString.new;\n    }\n    if (!self.nativeStyles) {\n        AMXMarkdownStyleConfig* style = [[AMXRenderService shared] getMarkdownStyleWithId:self.styleId];\n        self.nativeStyles = [AMXMarkdownTextView XRMarkdownStyle2AMTextStyle:style textView:self];\n        [AMTextStyles setAMStylesWithId:self.styleId styles:self.nativeStyles];\n    }\n    \n    return [AMXMarkdownHelper mdToAttrString:value\n                               defaultStyles:self.nativeStyles\n                                    delegate:self\n                                    textView:self];\n}\n-(void)notifyNodeLocation:(NSArray*)locArray {\n    if (!self.logModel.spm || [self.logModel.spm isEqualToString:@\"\"]) {\n        return;\n    }\n    if (!locArray || [locArray count] == [self.clickableLocationObjs count]) {\n        return;\n    }\n    if (!self.clickableLocationObjs) {\n        self.clickableLocationObjs = [[NSMutableArray alloc] initWithArray:locArray];\n    } else {\n        NSInteger addCnt = [locArray count] - [self.clickableLocationObjs count];\n        if (addCnt > 0) {\n            for (NSInteger i = [self.clickableLocationObjs count]; i < [locArray count]; i++) {\n                [self.clickableLocationObjs addObject:[locArray objectAtIndex:i]];\n            }\n        }\n    }\n    [self updateBounds];\n    if ([self.textViewDelegate respondsToSelector:@selector(onUpdateExposureElement:)]) {\n        [self.textViewDelegate onUpdateExposureElement:self.clickableObjs];\n    }\n}\n-(void)notifyNodeUpdate:(NSArray*)dataArray {\n    if (!dataArray || [dataArray count] == [self.clickableObjs count]) {\n        return;\n    }\n    if (!self.clickableObjs) {\n        self.clickableObjs = [self generateAllEventModelWithClickableObjs:dataArray];\n    } else {\n        NSInteger addCnt = [dataArray count] - [self.clickableObjs count];\n        if (addCnt > 0) {\n            for (NSInteger i = [self.clickableObjs count]; i < [dataArray count]; i++) {\n                NSDictionary* dic = [dataArray objectAtIndex:i];\n                if (dic) {\n                    AMXMarkdownCustomRenderEventModel* model = [self generateEventModel:dic];\n                    if (model) {\n                        [self.clickableObjs addObject:model];\n                    }\n                }\n            }\n        }\n    }\n    if ([self.textViewDelegate respondsToSelector:@selector(onUpdateExposureElement:)]) {\n        [self.textViewDelegate onUpdateExposureElement:self.clickableObjs];\n    }\n}\n- (void)updateBounds {\n    int index = 0;\n    for (NSValue* value in self.clickableLocationObjs) {\n        CGRect bounds = [value CGRectValue];\n        if (index < self.clickableObjs.count) {\n            AMXMarkdownCustomRenderEventModel* model = self.clickableObjs[index];\n            model.bounds = bounds;\n            index++;\n        }\n    }\n}\n-(AMXMarkdownCustomRenderEventModel*)generateEventModel:(NSString*)type url:(NSString*)url obj:(NSDictionary*)obj{\n    if (!type || !url) {\n        return nil;\n    }\n    AMXMarkdownCustomRenderEventModel * model = [[AMXMarkdownCustomRenderEventModel alloc] init];\n    model.extParam = self.logModel.extraParams;\n    model.contentUrl = url;\n    model.contentType = type;\n    model.exposurePercent = 0;\n    return model;\n}\n-(AMXMarkdownCustomRenderEventModel*)generateEventModel:(NSDictionary*)dic{\n    NSString* url = [dic objectForKey:@\"url\"];\n    NSString* type = nil;\n    CMNodeType nodeType = [[dic objectForKey:@\"type\"] intValue];\n    if (nodeType == CMNodeTypeImage) {\n        type = @\"image\";\n    }\n    if (nodeType == CMNodeTypeLink) {\n        type = @\"link\";\n    }\n    if (nodeType == CMNodeTypeInlineHTML && [[[dic objectForKey:@\"tag\"] stringValue] isEqualToString:@\"iconLink\"]) {\n        type = @\"iconLink\";\n    }\n    if (!type || !url) {\n        return nil;\n    }\n    AMXMarkdownCustomRenderEventModel* model = [self generateEventModel:type url:url obj:dic];\n    return model;\n}\n-(NSMutableArray*)generateAllEventModelWithClickableObjs:(NSArray*)clickObjs {\n    if (!self.logModel.spm || [self.logModel.spm isEqualToString:@\"\"]) {\n        return nil;\n    }\n    NSMutableArray* modelArray = [[NSMutableArray alloc] init];\n    for (NSDictionary* dic in clickObjs) {\n        AMXMarkdownCustomRenderEventModel* model = [self generateEventModel:dic];\n        if (model) {\n            [modelArray addObject:model];\n        }\n    }\n    return modelArray;\n}\n- (void)updateMarkdowmMutableAttributedString:(NSMutableAttributedString *)attStr {\n    self.markdownAttrStr = attStr;\n    [AMXMarkdownHelper setImageAttachListener:attStr delegate:self];\n    [self _updateMarkdowmAttributedString:attStr];\n    [self sizeToFit];\n}\n- (void)_updateMarkdowmAttributedString:(NSAttributedString *)attStr {\n    [self setAttributedText_ant_mark:attStr];\n}\n-(void)dealloc\n{\n    if (self.timer) {\n        [self.timer stopTimer];\n        self.timer = nil;\n    }\n    [AMTextStyles removeAMStylesWithId:self.styleId];\n}\n+ (CGSize)caculateContentSize:(NSString *)markdownText constrainSize:(CGSize)constrainSize styleId:(NSString*)styleId{\n    AMTextStyles* textStyle = [AMTextStyles cpl_cardDefaultTextStyles];\n    \n    AMXMarkdownStyleConfig* config = [[AMXRenderService shared] getMarkdownStyleWithId:styleId];\n    if (config) {\n        textStyle = [AMXMarkdownTextView XRMarkdownStyle2AMTextStyle:config textView:nil];\n        [AMTextStyles setAMStylesWithId:styleId styles:textStyle];\n    }\n    NSMutableAttributedString *attStr = [AMXMarkdownHelper mdToAttrString:markdownText\n                                                            defaultStyles:textStyle];\n    CGSize limitSize = CGSizeMake(constrainSize.width, MAXFLOAT);\n    __block CGSize contentSize;\n    dispatch_sync_on_main_queue(^{\n        if (!_caculateContentView) {\n            _caculateContentView = [[AMXMarkdownTextView alloc] initWithFrame_ant_mark:CGRectMake(0, 0, constrainSize.width, constrainSize.height)];\n            _caculateContentView.textContainerInset = UIEdgeInsetsZero;\n            _caculateContentView.textContainer.lineFragmentPadding = 0;\n            _caculateContentView.font = kCUPLMarkdownTextFont;\n        }\n        [_caculateContentView setAttributedTextPartialUpdate_ant_mark:attStr];\n        contentSize = [AMXMarkdownTextView calculateSizeWithLayoutManager:_caculateContentView limitSize:limitSize];\n    });\n    CGRect contentRect = CGRectIntegral(CGRectMake(0, 0, contentSize.width, contentSize.height));\n    CGFloat tmpWidth = kCUPLMarkdownTextFontSize;\n    CGFloat tmpHeight = kCUPLMarkdownTextLineHeight;\n    contentRect.size.width =  (contentRect.size.width < tmpWidth) ? tmpWidth : contentRect.size.width;\n    contentRect.size.height = (contentRect.size.height < tmpHeight) ? tmpHeight : contentRect.size.height;\n    return contentRect.size;\n}\n+ (CGSize)calculateSizeWithLayoutManager:(UITextView *)textView limitSize:(CGSize)limitSize {\n    textView.textContainer.size = CGSizeMake(limitSize.width, CGFLOAT_MAX);\n    [textView.layoutManager ensureLayoutForTextContainer:textView.textContainer];\n    CGRect usedRect = [textView.layoutManager usedRectForTextContainer:textView.textContainer];\n    return CGSizeMake(ceil(usedRect.size.width), ceil(usedRect.size.height));\n}\n-(void)willRemoveSubview:(UIView *)subview\n{\n    [super willRemoveSubview:subview];\n}\n\n\n- (void)handleTap:(UITapGestureRecognizer *)gesture {\n    CGPoint tapLocation = [gesture locationInView:gesture.view];\n    NSUInteger tappedCharacterIndex = -1;\n    NSAttributedString *attributedText = nil;\n    \n    UITextView *textView = (UITextView*)gesture.view;\n    \n    attributedText = textView.attributedText;\n    NSTextContainer *textContainer = textView.textContainer;\n    NSLayoutManager *layoutManager = textView.layoutManager;\n    \n    tapLocation.x -= textView.textContainerInset.left;\n    tapLocation.y -= textView.textContainerInset.top;\n    \n    tappedCharacterIndex = [layoutManager characterIndexForPoint:tapLocation\n                                                 inTextContainer:textContainer\n                        fractionOfDistanceBetweenInsertionPoints:nil];\n\n    if (tappedCharacterIndex >= 0 && tappedCharacterIndex < attributedText.length) {\n        // Check if the tapped character is an attachment\n        NSRange range = {0};\n        NSDictionary *attributes = [attributedText attributesAtIndex:tappedCharacterIndex\n                                                      effectiveRange:&range];\n        NSTextAttachment *attachment = attributes[NSAttachmentAttributeName];\n        id linkValue = attributes[NSLinkAttributeName];\n        if (![self.textViewDelegate respondsToSelector:@selector(onTap:content:gesture:attachment:tapIndex:attrString:)]) {\n            return;\n        }\n        if (linkValue) {\n            if (attachment && [attachment isKindOfClass:[AMIconLinkAttachment class]]) {\n                [self.textViewDelegate onTap:AMXMarkdownTapIconLink content:linkValue gesture:gesture attachment:attachment tapIndex:tappedCharacterIndex attrString:attributedText];\n            } else {\n                [self.textViewDelegate onTap:AMXMarkdownTapLink content:linkValue gesture:gesture attachment:attachment tapIndex:tappedCharacterIndex attrString:attributedText];\n            }\n        } else if(attachment && [attachment isKindOfClass:[CMImageTextAttachment class]]) {\n            [self.textViewDelegate onTap:AMXMarkdownTapImage content:linkValue gesture:gesture attachment:attachment tapIndex:tappedCharacterIndex attrString:attributedText];\n        } else if(attachment && [attachment isKindOfClass:[AMTableViewAttachment class]]) {\n            [self.textViewDelegate onTap:AMXMarkdownTapTable content:linkValue gesture:gesture attachment:attachment tapIndex:tappedCharacterIndex attrString:attributedText];\n        }\n    }\n}\n- (void)handleTableClick:(UITapGestureRecognizer *)gesture tableView:(AMMarkdownTableView*)tableView {\n    if (![tableView isKindOfClass:[AMMarkdownTableView class]])\n        return;\n    CGPoint tapLocation = [gesture locationInView:gesture.view];\n    NSArray *cells = [tableView.collectionView visibleCells];\n    if ([cells isKindOfClass:NSArray.class] && cells.count > 0) {\n        for (AMMarkdownTableCell *cell in cells) {\n            if (![cell isKindOfClass:[AMMarkdownTableCell class]])\n                continue;\n            CGRect childFrameInGrandparent = [cell.textview convertRect:cell.textview.bounds toView:gesture.view];\n            if(CGRectContainsPoint(childFrameInGrandparent, tapLocation)) {\n                [self handleCellViewClick:gesture textView:cell.textview];\n            }\n        }\n    }\n}\n\n- (void)handleCellViewClick:(UITapGestureRecognizer *)gesture textView:(UITextView *)textView {\n    if(![textView isKindOfClass:[UITextView class]])\n        return;\n    CGPoint tapLocation = [gesture locationInView:textView];\n    \n    NSUInteger tappedCharacterIndex = 0;\n    NSAttributedString *attributedText = nil;\n    attributedText = textView.attributedText;\n    \n    NSTextContainer *textContainer = textView.textContainer;\n    NSLayoutManager *layoutManager = textView.layoutManager;\n    \n    tapLocation.x -= textView.textContainerInset.left;\n    tapLocation.y -= textView.textContainerInset.top;\n    tappedCharacterIndex = [layoutManager characterIndexForPoint:tapLocation inTextContainer:textContainer fractionOfDistanceBetweenInsertionPoints:nil];\n\n    if (tappedCharacterIndex >= 0 && tappedCharacterIndex < attributedText.length) {\n        // Check if the tapped character is an attachment\n        NSRange range = {0};\n        NSDictionary *attributes = [attributedText attributesAtIndex:tappedCharacterIndex\n                                                      effectiveRange:&range];\n        NSTextAttachment *attachment = attributes[NSAttachmentAttributeName];\n        id linkValue = attributes[NSLinkAttributeName];\n        if (![self.textViewDelegate respondsToSelector:@selector(onTap:content:gesture:attachment:tapIndex:attrString:)]) {\n            return;\n        }\n        if (linkValue) {\n            if (attachment && [attachment isKindOfClass:[AMIconLinkAttachment class]]) {\n                [self.textViewDelegate onTap:AMXMarkdownTapIconLink content:linkValue gesture:gesture attachment:attachment tapIndex:tappedCharacterIndex attrString:attributedText];\n            } else {\n                [self.textViewDelegate onTap:AMXMarkdownTapLink content:linkValue gesture:gesture attachment:attachment tapIndex:tappedCharacterIndex attrString:attributedText];\n            }\n        } else if(attachment && [attachment isKindOfClass:[CMImageTextAttachment class]]) {\n            [self.textViewDelegate onTap:AMXMarkdownTapImage content:linkValue gesture:gesture attachment:attachment tapIndex:tappedCharacterIndex attrString:attributedText];\n        } else if(attachment && [attachment isKindOfClass:[AMTableViewAttachment class]]) {\n            [self.textViewDelegate onTap:AMXMarkdownTapTable content:linkValue gesture:gesture attachment:attachment tapIndex:tappedCharacterIndex attrString:attributedText];\n        }\n    }\n}\n\n#pragma mark - Selectable\n\n\n- (NSDictionary *)textViewSelectedInfo\n{\n    return @{\n        CS_NATIVE_WIDGET_EVENT_PAYLOAD_MAKRDOWN_SELECTED_TEXT: [self.text substringWithRange:self.selectedRange]?:@\"\",\n        CS_NATIVE_WIDGET_EVENT_PAYLOAD_MAKRDOWN_START_SELECTED_RECT: [NSValue valueWithCGRect:[self firstRectForRange:[self textRangeFromPosition:self.selectedTextRange.start toPosition:self.selectedTextRange.start]]],\n        CS_NATIVE_WIDGET_EVENT_PAYLOAD_MAKRDOWN_END_SELECTED_RECT: [NSValue valueWithCGRect:[self firstRectForRange:[self textRangeFromPosition:self.selectedTextRange.end toPosition:self.selectedTextRange.end]]],\n        CS_NATIVE_WIDGET_EVENT_PAYLOAD_MAKRDOWN_SELECTED_RECT: [NSValue valueWithCGRect:[self firstRectForRange:self.selectedTextRange]],\n    };\n}\n- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer\n{\n    return YES;\n}\n\n+(AMTextStyles*)XRMarkdownStyle2AMTextStyle:(AMXMarkdownStyleConfig*)config textView:(UITextView*)textView{\n    AMTextStyles* styles = [AMTextStyles cpl_cardDefaultTextStyles];\n    [AMXMarkdownHelper transformParagraph:styles customStyle:config];\n    [AMXMarkdownHelper transformTitle:styles customStyle:config];\n    [AMXMarkdownHelper transformOrderList:styles customStyle:config];\n    [AMXMarkdownHelper transformUnorderList:styles customStyle:config];\n    [AMXMarkdownHelper transformTable:styles customStyle:config];\n    [AMXMarkdownHelper transformHRule:styles customStyle:config];\n    [AMXMarkdownHelper transformFootNote:styles customStyle:config];\n    [AMXMarkdownHelper transformLink:styles customStyle:config textView:textView];\n    [AMXMarkdownHelper transformInlineCode:styles customStyle:config];\n    [AMXMarkdownHelper transformCodeBlock:styles customStyle:config];\n    [AMXMarkdownHelper transformUnderLine:styles customStyle:config];\n    [AMXMarkdownHelper transformBlockQuote:styles customStyle:config];\n    return styles;\n}\n+ (BOOL)isEmptyStringOrNotString:(id)value {\n    return !value || ![value isKindOfClass:NSString.class] || ((NSString *)value).length < 1;\n}\n#pragma mark CPLImageAttachmentProtocol\n\n- (UIImage *)getImageFromCacheIfExist:(NSString *)url {\n    UIImage *img = nil;\n    if(![AMXMarkdownTextView isEmptyStringOrNotString:url]) {\n        img = [self.cacheImgDic objectForKey:url];\n    }\n    return img;\n}\n\n- (void)onImageLoadFinish:(UIImage *)image url:(NSString *)url {\n    if (image &&\n       ![AMXMarkdownTextView isEmptyStringOrNotString:url]) {\n        [self.cacheImgDic setObject:image forKey:url];\n    }\n    \n    @weakify(self)\n    dispatch_async_on_main_queue(^{\n        @strongify(self)\n        [self updateSize];\n    });\n}\n\n@end\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Markdown/AMXMarkdownTimer.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n\n@protocol AMXMarkdownTimerDelegate <NSObject>\n\n@required\n- (void)onTimer;\n\n@end\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMXMarkdownTimer : NSObject\n- (instancetype)initWithConfig:(NSInteger)intervalTime queue:(dispatch_queue_t)queue;\n\n- (void)startTimer;\n\n- (void)stopTimer;\n\n- (BOOL)isRuning;\n\n@property(nonatomic,weak)id<AMXMarkdownTimerDelegate> delegate;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Markdown/AMXMarkdownTimer.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMXMarkdownTimer.h\"\n\n@interface AMXMarkdownTimer ()\n{\n    dispatch_source_t _timer;\n}\n@property(nonatomic,assign)BOOL isRun;\n@property(nonatomic,assign)NSInteger intervalTime; //microsecond\n@property(nonatomic, strong) dispatch_queue_t queue;\n@end\n\n@implementation AMXMarkdownTimer\n\n- (instancetype)initWithConfig:(NSInteger)intervalTime queue:(dispatch_queue_t)queue\n{\n    self = [super init];\n    if (self) {\n        self.queue = queue;\n        self.intervalTime = intervalTime;\n    }\n    return self;\n}\n\n- (void)startTimer\n{\n    if(self.isRun)\n        return;\n\n    if(_timer)\n    {\n        return;\n    }\n    _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.queue);\n    dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.intervalTime * NSEC_PER_MSEC));\n    uint64_t intervalTime = (uint64_t)(self.intervalTime * NSEC_PER_MSEC);\n    dispatch_source_set_timer(_timer, start, intervalTime, 0);\n    \n    __weak AMXMarkdownTimer* weakSelf = self;\n    dispatch_source_set_event_handler(_timer, ^{\n        if (weakSelf.isRun) {\n            [weakSelf onTimer];\n        }\n    });\n    \n    dispatch_resume(_timer);\n\n    self.isRun = YES;\n}\n\n- (void)stopTimer\n{\n\n    self.isRun = NO;\n}\n\n- (void)onTimer\n{\n    [self.delegate onTimer];\n}\n\n- (BOOL)isRuning\n{\n    return self.isRun;\n}\n\n@end\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Style/AMXMarkdownStyle.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n#import <UIKit/UIKit.h>\n\nNS_ASSUME_NONNULL_BEGIN\n/// MarkdownElementType\ntypedef NS_ENUM(NSUInteger, AMXElementType) {\n    AMXElementTypeParagraph,    // base paragraph\n    AMXElementTypeHeader1,      // title 1\n    AMXElementTypeHeader2,      // title 2\n    AMXElementTypeHeader3,      // title 3\n    AMXElementTypeHeader4,      // title 4\n    AMXElementTypeHeader5,      // title 5\n    AMXElementTypeHeader6,      // title 6\n    AMXElementTypeUnorderedList,// unorder list\n    AMXElementTypeOrderedList,  // order list\n    AMXElementTypeTable,         // table\n    AMXElementTypeBlockQuote,        // quote\n    AMXElementTypeHRule,         // horizon rule\n    AMXElementTypeLink,         // link\n    AMXElementTypeFootNote,         // foot note\n    AMXElementTypeInlineCode,         // inline code\n    AMXElementTypeCodeBlock        // code block\n};\ntypedef NS_ENUM(NSUInteger, AMXListPrefixType) {\n    AMXListPrefixTypeCharacter,  // character\n    AMXListPrefixTypeImage,      // image\n};\n\n@interface AMXFontConfig : NSObject\n@property(nonatomic, strong) UIFont *font;\n@property(nonatomic, strong)UIColor* fontColor;\n@end\n\n@interface AMXSpacingConfig : NSObject\n@property(nonatomic, assign)CGFloat paragraphSpacing;\n@property(nonatomic, assign)CGFloat lineSpacing;\n@property(nonatomic, assign)CGFloat paragraphSpacingBefore;\n@end\n\n@interface AMXListLevelConfig : NSObject\n@property (nonatomic, assign) AMXListPrefixType prefixType;\n@property (nonatomic, assign) CGFloat symbolIndentation;  // the indentation of the prefix\n@property (nonatomic, strong) NSString *prefixSymbol;   // effective when prefixType is AMXListPrefixTypeCharacter\n@property (nonatomic, strong) NSString *prefixSymbolPath;  // effective when prefixType is AMXListPrefixTypeImage\n@property (nonatomic,  assign) CGSize symbolSize;   //\n@property (nonatomic,  assign) CGFloat prefixSpacing;   // interval between prefix and the first character\n+ (instancetype)defaultStyle:(NSInteger)level;\n@end\n\n@interface AMXTableCellStyle : NSObject\n@property (nonatomic, strong) AMXFontConfig *font;\n@property (nonatomic, strong) UIColor *backgroundColor;\n@property (nonatomic, assign) UIEdgeInsets padding;\n@end\n\n@interface AMXTableStyleConfig : NSObject\n@property (nonatomic, assign) CGFloat rowSpacing;\n@property (nonatomic, assign) CGFloat columnSpacing;\n@property (nonatomic, assign) CGFloat borderWidth;\n@property (nonatomic, assign) CGFloat maxWidth;\n@property (nonatomic, assign) CGFloat maxHeight;\n@property (nonatomic, assign) CGFloat firstColumnMaxWidth;\n@property (nonatomic, assign) CGFloat columnMaxWidth;\n@property (nonatomic, strong) NSString* operationIconPath;// bundleName/iconName\n@property (nonatomic, strong) AMXFontConfig *titlefont;\n@property (nonatomic, strong) UIColor *titleBackgroundColor;\n@property (nonatomic, strong) AMXTableCellStyle *headerStyle; // header\n@property (nonatomic, strong) AMXTableCellStyle *contentStyle; // content cell\n\n+ (instancetype)defaultStyle;\n@end\n\n@interface AMXHRuleConfig : NSObject\n@property (nonatomic, strong) UIColor *color;\n@property (nonatomic, assign) CGFloat height;\n\n+ (instancetype)defaultStyle;\n@end\n\n@interface AMXLinkConfig : NSObject\n@property (nonatomic, assign) CGFloat spacing;\n@property (nonatomic, strong) NSString *iconPath;\n@property (nonatomic, assign) BOOL underLine;\n@property (nonatomic, assign) NSInteger prefixOrSuffix;// prefix is 1; suffix is 2\n\n+ (instancetype)defaultStyle;\n@end\n\n@interface AMXFootNoteConfig : NSObject\n@property (nonatomic, assign)CGSize size;\n@property (nonatomic, strong)UIColor* backgroundColor;\n\n+ (instancetype)defaultStyle;\n@end\n\n@interface AMXBlockquoteStyle : NSObject\n@property (nonatomic, strong) UIColor *lineColor;\n@property (nonatomic, assign) CGFloat lineWidth;\n@property (nonatomic, assign) CGFloat indentation;\n\n+ (instancetype)defaultStyle;\n@end\n\n@interface AMXInlineCodeConfig : NSObject\n@property(nonatomic, strong)UIColor* backgroundColor;\n@property(nonatomic, strong)AMXFontConfig* codeFont;\n+ (instancetype)defaultStyle;\n@end\n\n@interface AMXCodeBlockConfig : NSObject\n@property(nonatomic, strong)UIColor* titleBackgroundColor;\n@property(nonatomic, strong)AMXFontConfig *titleFont;\n@property(nonatomic, strong)UIColor* backgroundColor;\n@property(nonatomic, assign)CGFloat borderWidth;\n@property(nonatomic, strong)UIColor* borderColor;\n@property (nonatomic, strong) NSString* operationIconPath;// bundleName/iconName\n+ (instancetype)defaultStyle;\n@end\n\n@interface AMXUnderLineConfig : NSObject\n@property(nonatomic, strong)UIColor* lineColor;\n@property(nonatomic, assign)CGFloat lineWidth;\n@property(nonatomic, assign)CGFloat lineOffset;\n+ (instancetype)defaultStyle;\n@end\n\n@interface AMXMarkdownStyleConfig : NSObject\n@property(nonatomic, strong)AMXTableStyleConfig* tableConfig;\n@property(nonatomic, strong)AMXHRuleConfig* hRuleConfig;\n@property(nonatomic, strong)AMXFootNoteConfig* footNoteConfig;\n@property(nonatomic, strong)AMXLinkConfig* linkConfig;\n@property(nonatomic, strong)AMXInlineCodeConfig* inlineCodeConfig;\n@property(nonatomic, strong)AMXCodeBlockConfig* codeBlockConfig;\n@property(nonatomic, strong)AMXUnderLineConfig* underlineConfig;\n@property(nonatomic, strong)AMXBlockquoteStyle* blockQuoteConfig;\n\n// Global default config\n+ (instancetype)defaultConfig;\n\n// Font config with element type\n- (void)setFontConfig:(AMXFontConfig *)config forElementType:(AMXElementType)type;\n\n// Spacing config with element type\n- (void)setSpacingConfig:(AMXSpacingConfig *)config forElementType:(AMXElementType)type;\n\n// LineHeight config with element type\n- (void)setLineHeightConfig:(CGFloat)lineHeight forElementType:(AMXElementType)type;\n\n// The style of order list with level\n- (void)addOrderListConfig:(AMXListLevelConfig *)config forLevel:(NSUInteger)level;\n\n// The style of unorder list with level\n- (void)addUnorderListConfig:(AMXListLevelConfig *)config forLevel:(NSUInteger)level;\n\n- (AMXFontConfig*)getFontConfig:(AMXElementType)type;\n- (AMXSpacingConfig*)getSpacingConfig:(AMXElementType)type;\n- (CGFloat)getLineHeight:(AMXElementType)type;\n- (NSDictionary*)getAllLevelOrderListConfigs;\n- (AMXListLevelConfig *)getOrderListConfig:(NSUInteger)level;\n- (NSDictionary*)getAllLevelUnorderListConfigs;\n- (AMXListLevelConfig *)getUnorderListConfig:(NSUInteger)level;\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Style/AMXMarkdownStyle.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMXMarkdownStyle.h\"\n#import <AntMarkdown/AMUtils.h>\n@implementation AMXFontConfig\n@end\n\n@implementation AMXSpacingConfig\n@end\n\n@implementation AMXListLevelConfig\n+ (instancetype)defaultStyle:(NSInteger)level{\n    AMXListLevelConfig* config = [AMXListLevelConfig new];\n    config.prefixType = AMXListPrefixTypeCharacter;\n    config.prefixSymbol = @\"\\t●\";\n    config.symbolIndentation = 0;\n    return config;\n}\n@end\n@implementation AMXTableCellStyle\n\n@end\n@implementation AMXTableStyleConfig\n+ (instancetype)defaultStyle {\n    AMXTableStyleConfig *config = [AMXTableStyleConfig new];\n    AMXTableCellStyle* headerStyle = [AMXTableCellStyle new];\n    \n    AMXFontConfig* font = [AMXFontConfig new];\n    font.font = [UIFont systemFontOfSize:13];\n    font.fontColor = [AMUtils colorWithString:@\"#333333\"];\n    \n    headerStyle.font = font;\n    headerStyle.backgroundColor = [AMUtils colorWithString:@\"#1F3B630A\"];\n    headerStyle.padding = UIEdgeInsetsMake(8, 12, 8, 12);\n    \n    AMXFontConfig* titlefont = [AMXFontConfig new];\n    titlefont.font = [UIFont systemFontOfSize:13];\n    titlefont.fontColor = [AMUtils colorWithString:@\"#999999\"];\n    config.titlefont = titlefont;\n    config.titleBackgroundColor = [AMUtils colorWithString:@\"#1F3B6314\"];\n    \n    AMXTableCellStyle* contentStyle = [AMXTableCellStyle new];\n    contentStyle.font = font;\n    contentStyle.backgroundColor = [UIColor whiteColor];\n    contentStyle.padding = UIEdgeInsetsMake(8, 12, 8, 12);\n    \n    config.headerStyle = headerStyle;\n    config.contentStyle = contentStyle;\n    \n    config.borderWidth = 1;\n    config.rowSpacing = 1;\n    config.columnSpacing = 1;\n    config.firstColumnMaxWidth = 90;\n    config.columnMaxWidth = 210;\n    config.maxWidth = 319;\n    config.maxHeight = -1;\n    config.operationIconPath = @\"AntMarkdown/blow_up\";\n\n    return config;\n}\n\n@end\n@implementation AMXHRuleConfig\n+ (instancetype)defaultStyle {\n    AMXHRuleConfig *config = [AMXHRuleConfig new];\n    config.height = 2;\n    config.color = [AMUtils colorWithString:@\"#D6DEF2\"];\n    return config;\n}\n\n@end\n@implementation AMXLinkConfig\n+ (instancetype)defaultStyle {\n    AMXLinkConfig *config = [AMXLinkConfig new];\n    config.spacing = 1;\n    config.underLine = NO;\n    return config;\n}\n\n@end\n\n@implementation AMXFootNoteConfig\n+ (instancetype)defaultStyle {\n    AMXFootNoteConfig *config = [AMXFootNoteConfig new];\n    config.backgroundColor = [AMUtils colorWithString:@\"#1f3b6314\"];\n    config.size = CGSizeMake(18, 18);\n    return config;\n}\n@end\n\n@implementation AMXBlockquoteStyle\n+ (instancetype)defaultStyle {\n    AMXBlockquoteStyle* config = [AMXBlockquoteStyle new];\n    config.lineColor = [AMUtils colorWithString:@\"#DFE1EC\"];\n    config.lineWidth = 2;\n    config.indentation = 10;\n    return config;\n}\n@end\n@implementation AMXInlineCodeConfig : NSObject\n+ (instancetype)defaultStyle {\n    AMXInlineCodeConfig* config = [AMXInlineCodeConfig new];\n    AMXFontConfig *codeFont = [[AMXFontConfig alloc] init];\n    codeFont.fontColor = [AMUtils colorWithString:@\"#333333\"];\n    \n    UIFont* codeFont1 = [UIFont systemFontOfSize:15];\n    codeFont.font = codeFont1;\n    config.codeFont = codeFont;\n    config.backgroundColor = [AMUtils colorWithString:@\"#1F3B631E\"];\n    return config;\n}\n@end\n@implementation AMXCodeBlockConfig : NSObject\n\n+ (instancetype)defaultStyle {\n    AMXCodeBlockConfig* config = [AMXCodeBlockConfig new];\n    config.titleBackgroundColor = [AMUtils colorWithString:@\"#1F3B6314\"];\n    \n    AMXFontConfig *titleFont = [[AMXFontConfig alloc] init];\n    titleFont.font = [UIFont boldSystemFontOfSize:AUFVS(13.0)];\n    titleFont.fontColor = [AMUtils colorWithString:@\"#999999\"];\n   \n    config.titleFont = titleFont;\n    config.borderWidth = 1;\n    config.borderColor = [AMUtils colorWithString:@\"#33333329\"];\n    config.operationIconPath = @\"AntMarkdown/code_copy\";\n    return config;\n}\n@end\n@implementation AMXUnderLineConfig : NSObject\n+ (instancetype)defaultStyle {\n    AMXUnderLineConfig* config = [AMXUnderLineConfig new];\n    config.lineWidth = 6;\n    config.lineOffset = 4;\n    config.lineColor = [AMUtils colorWithString:@\"#1677FF80\"];\n    return config;\n}\n@end\n@interface AMXMarkdownStyleConfig()\n@property (nonatomic, strong) NSMutableDictionary<NSNumber *, AMXFontConfig *> *fontConfigs;\n@property (nonatomic, strong) NSMutableDictionary<NSNumber *, AMXSpacingConfig *> *spacingConfigs;\n@property (nonatomic, strong) NSMutableDictionary<NSNumber *, NSNumber*> *lineHeightConfigs;\n@property (nonatomic, strong) NSMutableDictionary<NSString *, AMXListLevelConfig *> *orderListConfigs;\n@property (nonatomic, strong) NSMutableDictionary<NSString *, AMXListLevelConfig *> *unorderListConfigs;\n@end\n\n@implementation AMXMarkdownStyleConfig\n- (instancetype)init {\n    if (self = [super init]) {\n        _fontConfigs = [[NSMutableDictionary alloc] init];\n        _spacingConfigs = [[NSMutableDictionary alloc] init];\n        _lineHeightConfigs = [[NSMutableDictionary alloc] init];\n        _orderListConfigs = [[NSMutableDictionary alloc] init];\n        _unorderListConfigs = [[NSMutableDictionary alloc] init];\n    }\n    return self;\n}\n+ (instancetype)defaultConfig {\n    AMXMarkdownStyleConfig *config = [[AMXMarkdownStyleConfig alloc] init];\n    \n    AMXFontConfig *defaultFont = [[AMXFontConfig alloc] init];\n    defaultFont.font = [UIFont systemFontOfSize:AUFVS(15.0)];\n    defaultFont.fontColor = [AMUtils colorWithString:@\"#333333\"];\n  \n    AMXFontConfig *defaultBoldFont = [[AMXFontConfig alloc] init];\n    defaultBoldFont.font = [UIFont boldSystemFontOfSize:AUFVS(15.0)];\n                             defaultBoldFont.fontColor = [AMUtils colorWithString:@\"#333333\"];\n    [config setFontConfig:defaultFont forElementType:AMXElementTypeParagraph];\n    [config setFontConfig:defaultBoldFont forElementType:AMXElementTypeHeader1];\n    [config setFontConfig:defaultBoldFont forElementType:AMXElementTypeHeader2];\n    [config setFontConfig:defaultBoldFont forElementType:AMXElementTypeHeader3];\n    [config setFontConfig:defaultBoldFont forElementType:AMXElementTypeHeader4];\n    [config setFontConfig:defaultBoldFont forElementType:AMXElementTypeHeader5];\n    [config setFontConfig:defaultBoldFont forElementType:AMXElementTypeHeader6];\n    [config setFontConfig:defaultFont forElementType:AMXElementTypeOrderedList];\n    [config setFontConfig:defaultFont forElementType:AMXElementTypeUnorderedList];\n    [config setFontConfig:defaultFont forElementType:AMXElementTypeBlockQuote];\n    \n    AMXFontConfig *codeBlockFont = [[AMXFontConfig alloc] init];\n    codeBlockFont.font = [UIFont boldSystemFontOfSize:AUFVS(13.0)];\n    defaultBoldFont.fontColor = [AMUtils colorWithString:@\"#333333\"];\n    [config setFontConfig:defaultFont forElementType:AMXElementTypeCodeBlock];\n    \n    AMXFontConfig *defaultFootNoteFont = [[AMXFontConfig alloc] init];\n    defaultFootNoteFont.font = [UIFont boldSystemFontOfSize:AUFVS(10.0)];\n    defaultFootNoteFont.fontColor = [AMUtils colorWithString:@\"#999999\"];\n    [config setFontConfig:defaultFootNoteFont forElementType:AMXElementTypeFootNote];\n    \n    AMXFontConfig *defaultLinkFont = [[AMXFontConfig alloc] init];\n    defaultLinkFont.font = [UIFont systemFontOfSize:AUFVS(15.0)];\n    defaultLinkFont.fontColor = [AMUtils colorWithString:@\"#1677FF\"];\n    [config setFontConfig:defaultLinkFont forElementType:AMXElementTypeLink];\n    \n    AMXSpacingConfig *defaultSpacing = [[AMXSpacingConfig alloc] init];\n    defaultSpacing.paragraphSpacingBefore = 10;\n    defaultSpacing.paragraphSpacing = 0;\n    defaultSpacing.lineSpacing = 0;\n\n    for (NSInteger i = 0; i <= AMXElementTypeHRule; i++) {\n        [config setSpacingConfig:defaultSpacing forElementType:i];\n        [config setLineHeightConfig:AUFVS(24.0) forElementType:i];\n    }\n    AMXSpacingConfig *defaultTitleSpacing = [[AMXSpacingConfig alloc] init];\n    defaultTitleSpacing.paragraphSpacingBefore = 14;\n    defaultTitleSpacing.paragraphSpacing = 0;\n    defaultTitleSpacing.lineSpacing = 0;\n    for (NSInteger i = AMXElementTypeHeader1; i <= AMXElementTypeHeader6; i++) {\n        [config setSpacingConfig:defaultTitleSpacing forElementType:i];\n    }\n    \n    [config setSpacingConfig:defaultSpacing forElementType:AMXElementTypeCodeBlock];\n    [config setLineHeightConfig:AUFVS(18.5) forElementType:AMXElementTypeCodeBlock];\n    \n    for (NSInteger i = 0; i <= 4; i++) {\n        AMXListLevelConfig* orderListConfig = [AMXListLevelConfig defaultStyle:i];\n        orderListConfig.symbolSize = CGSizeMake(13.5, 13.5);\n        orderListConfig.prefixSpacing = 5;\n        orderListConfig.prefixSymbol = @\"\\t%ld.\";\n        [config addOrderListConfig:orderListConfig forLevel:i];\n    }\n    for (NSInteger i = 0; i <= 4; i++) {\n        AMXListLevelConfig* unorderListConfig = [AMXListLevelConfig defaultStyle:i];\n        unorderListConfig.symbolSize = CGSizeMake(7, 7);\n        unorderListConfig.prefixSpacing = 6;\n        unorderListConfig.prefixSymbol = @\"\\t●\";\n        [config addUnorderListConfig:unorderListConfig forLevel:i];\n    }\n    AMXTableStyleConfig* tableConfig = [AMXTableStyleConfig defaultStyle];\n    config.tableConfig = tableConfig;\n    \n    AMXHRuleConfig* hruleConfig = [AMXHRuleConfig defaultStyle];\n    config.hRuleConfig = hruleConfig;\n\n    AMXFootNoteConfig* footNoteConfig = [AMXFootNoteConfig defaultStyle];\n    config.footNoteConfig = footNoteConfig;\n    \n    AMXLinkConfig* linkConfig = [AMXLinkConfig defaultStyle];\n    config.linkConfig = linkConfig;\n    \n    AMXInlineCodeConfig* inlineCodeConfig = [AMXInlineCodeConfig defaultStyle];\n    config.inlineCodeConfig = inlineCodeConfig;\n    \n    AMXCodeBlockConfig* codeBlockConfig = [AMXCodeBlockConfig defaultStyle];\n    config.codeBlockConfig = codeBlockConfig;\n    \n    AMXUnderLineConfig* underlineConfig = [AMXUnderLineConfig defaultStyle];\n    config.underlineConfig = underlineConfig;\n    \n    AMXBlockquoteStyle* blockQuote = [AMXBlockquoteStyle defaultStyle];\n    config.blockQuoteConfig = blockQuote;\n    \n    return config;\n}\n- (void)setFontConfig:(AMXFontConfig *)config forElementType:(AMXElementType)type {\n    self.fontConfigs[@(type)] = config;\n}\n\n- (void)setSpacingConfig:(AMXSpacingConfig *)config forElementType:(AMXElementType)type {\n    self.spacingConfigs[@(type)] = config;\n}\n- (void)setLineHeightConfig:(CGFloat)lineHeight forElementType:(AMXElementType)type {\n    self.lineHeightConfigs[@(type)] = [NSNumber numberWithFloat:lineHeight];\n}\n- (void)addOrderListConfig:(AMXListLevelConfig *)config forLevel:(NSUInteger)level {\n    NSMutableDictionary *mutableConfigs = [self.orderListConfigs mutableCopy];\n    mutableConfigs[[NSString stringWithFormat:@\"%ld\", level]] = config;\n    self.orderListConfigs = [mutableConfigs copy];\n}\n- (void)addUnorderListConfig:(AMXListLevelConfig *)config forLevel:(NSUInteger)level {\n    NSMutableDictionary *mutableConfigs = [self.unorderListConfigs mutableCopy];\n    mutableConfigs[[NSString stringWithFormat:@\"%ld\", level]] = config;\n    self.unorderListConfigs = [mutableConfigs copy];\n}\n- (AMXFontConfig*)getFontConfig:(AMXElementType)type {\n    return [self.fontConfigs objectForKey:@(type)];\n}\n- (AMXSpacingConfig*)getSpacingConfig:(AMXElementType)type {\n    return [self.spacingConfigs objectForKey:@(type)];\n}\n- (CGFloat)getLineHeight:(AMXElementType)type {\n    return [[self.lineHeightConfigs objectForKey:@(type)] floatValue];\n}\n- (NSDictionary*)getAllLevelOrderListConfigs {\n    return [self.orderListConfigs mutableCopy];\n}\n- (AMXListLevelConfig *)getOrderListConfig:(NSUInteger)level {\n    return [self.orderListConfigs objectForKey:[NSString stringWithFormat:@\"%ld\", level]];;\n}\n- (NSDictionary*)getAllLevelUnorderListConfigs {\n    return [self.unorderListConfigs mutableCopy];\n}\n- (AMXListLevelConfig *)getUnorderListConfig:(NSUInteger)level {\n    return [self.unorderListConfigs objectForKey:[NSString stringWithFormat:@\"%ld\", level]];;\n}\n@end\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Style/AMXRenderService.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n#import \"AMXMarkdownStyle.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface AMXRenderService : NSObject\n+ (instancetype)shared;\n/**\n Set a style with a unique ID and assign the ID to AMXMarkdownTextView to render markdown data using that style\n */\n-(void)setMarkdownStyleWithId:(AMXMarkdownStyleConfig*)styleConfig styleId:(NSString*)styleId;\n/**\n Get the custom style with id\n */\n-(AMXMarkdownStyleConfig*)getMarkdownStyleWithId:(NSString*)styleId;\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Style/AMXRenderService.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import \"AMXRenderService.h\"\n@interface AMXMarkdownExtendEngine : NSObject\n{\n    @private\n    dispatch_semaphore_t _configMapLock;\n}\n@property (nonatomic, strong) NSMutableDictionary *styleConfigMap;\n-(void)setCustomStyleWithId:(AMXMarkdownStyleConfig*)styleConfig styleId:(NSString*)styleId;\n-(AMXMarkdownStyleConfig*)getStyleConfigWithId:(NSString*)styleId;\n@end\n\n@implementation AMXMarkdownExtendEngine\n-(instancetype)init {\n    if (self = [super init]) {\n        _configMapLock = dispatch_semaphore_create(1);\n        _styleConfigMap = [[NSMutableDictionary alloc] init];\n    }\n    return self;\n}\n\n-(void)setCustomStyleWithId:(AMXMarkdownStyleConfig*)styleConfig styleId:(NSString*)styleId {\n    dispatch_semaphore_wait(self->_configMapLock, DISPATCH_TIME_FOREVER);\n    self.styleConfigMap[styleId] = styleConfig;\n    dispatch_semaphore_signal(self->_configMapLock);\n}\n-(AMXMarkdownStyleConfig*)getStyleConfigWithId:(NSString*)styleId {\n    dispatch_semaphore_wait(self->_configMapLock, DISPATCH_TIME_FOREVER);\n    AMXMarkdownStyleConfig* config = self.styleConfigMap[styleId];\n    dispatch_semaphore_signal(self->_configMapLock);\n    return config;\n}\n@end\n@interface AMXRenderService()\n@property (nonatomic, strong)AMXMarkdownExtendEngine* extendEngine;\n@end\n@implementation AMXRenderService\n+ (instancetype)shared {\n    static AMXRenderService *_shared = nil;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        _shared = AMXRenderService.new;\n    });\n    return _shared;\n}\n-(instancetype)init {\n    self = [super init];\n    if (self) {\n        self.extendEngine = [[AMXMarkdownExtendEngine alloc] init];\n    }\n    return self;\n}\n-(void)setMarkdownStyleWithId:(AMXMarkdownStyleConfig*)styleConfig styleId:(NSString*)styleId\n{\n    [self.extendEngine setCustomStyleWithId:styleConfig styleId:styleId];\n}\n-(AMXMarkdownStyleConfig*)getMarkdownStyleWithId:(NSString*)styleId {\n    return [self.extendEngine getStyleConfigWithId:styleId];\n}\n@end\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Util/AMXMarkdownDefine.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <AntMarkdown/AMUtils.h>\n#ifndef AMXMarkdownDefine_h\n#define AMXMarkdownDefine_h\n#ifdef __OBJC__\n\n#ifndef CARD_UI_PLUGINS_MARKDOWN_LOG_PURE_ATTRSTRING\n#define CARD_UI_PLUGINS_MARKDOWN_LOG_PURE_ATTRSTRING 0\n#endif\n\n#ifdef PRODUCT_ZHIXIAOBAO\n  #define kCPLGMarkDownEnable  1\n#endif\n\n#ifdef PRODUCT_ANZHENER\n  #define kCPLGMarkDownEnable  0\n#endif\n\n#ifdef PRODUCT_WALLET\n  #define kPaladinEnable  1\n  #define kCPLGMarkDownEnable  1\n#endif\n\n#ifdef PRODUCT_WEALTH\n  #define kCPLGMarkDownEnable  1\n#endif\n\n#ifdef PRODUCT_AIJK\n  #define kCPLGMarkDownEnable  1\n#endif\n\n\n#import <Foundation/Foundation.h>\n\n\n#define CPL_AIGC_BIZCODE  @\"CPL-CHAT-LLM\"\n\n#define CPLLogInfo(format, ...) \\\ndo { \\\nNSLog(@\"[FluidMarkdown] %@\", [NSString stringWithFormat:format, ##__VA_ARGS__]); \\\n} while(0)\n\n#define kCUPLMarkdownTextFont            [UIFont systemFontOfSize:AUFVS(16.0)]\n#define kCUPLMarkdownTextBoldFont        [UIFont boldSystemFontOfSize:AUFVS(16.0)]\n#define kCUPLMarkdownCommonTextColor     [AMUtils colorWithString:@\"#333333\"]\n#define kCUPLMarkdownTextFontSize        AUFVS(16.0)\n\n#define kCUPLMarkdownTextLineHeight      AUFVS(25.0)\n\n\n#define CPL_LOG_TAG (@\"#CPL#\")\n#define cpl_log_i(format, ...) \\\n    NSLog(CPL_LOG_TAG, @\"%s %@\", __FUNCTION__, [NSString stringWithFormat:format, ##__VA_ARGS__])\n\n#define cpl_log_d(format, ...) \\\n    NSLog(CPL_LOG_TAG, @\"%s %@\", __FUNCTION__, [NSString stringWithFormat:format, ##__VA_ARGS__])\n\n#endif\n\n#endif /* AMXMarkdownDefine_h */\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Util/AMXMarkdownUtil.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n#pragma mark Native Widget Method\n\nextern const NSString *CS_NATIVE_WIDGET_METHOD_NAME_MARKDOWN_CANCEL_SELECTED ;\nextern const NSString *CS_NATIVE_WIDGET_METHOD_NAME_MARKDOWN_SELECT_PARAGRAPH;\nextern const NSString *CS_NATIVE_WIDGET_METHOD_NAME_MARKDOWN_SELECT_ALL;\nextern const NSString *CS_NATIVE_WIDGET_METHOD_NAME_MARKDOWN_CONTENT_VIEW;\nextern const NSString *CS_NATIVE_WIDGET_METHOD_NAME_MARKDOWN_IS_PRINTING;\nextern const NSString *CS_NATIVE_WIDGET_METHOD_PARAMS_MARKDOWN_POINT;\nextern const NSString *CS_NATIVE_WIDGET_METHOD_RETURN_DATA;\n\n#pragma mark Native Widget Delegate\n\nextern const NSString *CS_NATIVE_WIDGET_EVENT_NAME_MARKDOWN_STRING_CHANGE;\nextern const NSString *CS_NATIVE_WIDGET_EVENT_NAME_MARKDOWN_ENABLE_SELECTABLE;\nextern const NSString *CS_NATIVE_WIDGET_EVENT_NAME_MARKDOWN_GESTURE_LONGPRESS;\nextern const NSString *CS_NATIVE_WIDGET_EVENT_NAME_MARKDOWN_GESTURE_TAP;\nextern const NSString *CS_NATIVE_WIDGET_EVENT_NAME_MARKDOWN_GESTURE_PAN;\nextern const NSString *CS_NATIVE_WIDGET_EVENT_NAME_MARKDOWN_SELECTED_CHANGE ;\nextern const NSString *CS_NATIVE_WIDGET_EVENT_NAME_MARKDOWN_ENABLE_AUTO_SCROLL;\nextern const NSString *CS_NATIVE_WIDGET_EVENT_NAME_MARKDOWN_AUTO_SCROLL_OPTION_FOR_SELECTING;\nextern const NSString *CS_NATIVE_WIDGET_EVENT_NAME_MARKDOWN_LONGPRESS_GESTURE_SHOULD_BEGIN;\nextern const NSString *CS_NATIVE_WIDGET_EVENT_NAME_MARKDOWN_TAP_GESTURE_SHOULD_BEGIN;\nextern const NSString *CS_NATIVE_WIDGET_EVENT_PAYLOAD_MAKRDOWN_SELECTED_TEXT ;\nextern const NSString *CS_NATIVE_WIDGET_EVENT_PAYLOAD_MAKRDOWN_START_SELECTED_RECT;\nextern const NSString *CS_NATIVE_WIDGET_EVENT_PAYLOAD_MAKRDOWN_END_SELECTED_RECT;\nextern const NSString *CS_NATIVE_WIDGET_EVENT_PAYLOAD_MAKRDOWN_SELECTED_RECT ;\nextern const NSString *CS_NATIVE_WIDGET_EVENT_PAYLOAD_MAKRDOWN_GESTURE_POINT ;\nextern const NSString *CS_NATIVE_WIDGET_EVENT_PAYLOAD_MAKRDOWN_GESTURE_STATE ;\nextern const NSString *CS_NATIVE_WIDGET_EVENT_PAYLOAD_MARKDOWN_CONTENT_VIEW ;\nextern const NSString *CS_NATIVE_WIDGET_EVENT_PAYLOAD_MARKDOWN_PURE_STRING;\nextern const NSString *CS_NATIVE_WIDGET_EVENT_PAYLOAD_MARKDOWN_GESTURE;\nextern const NSString *CS_NATIVE_WIDGET_EVENT_RETURN_DATA;\nextern const NSString *CS_NATIVE_WIDGET_EVENT_RETURN_SCROLL_VIEW;\nextern const NSString *CS_NATIVE_WIDGET_EVENT_PAYLOAD_MARKDOWN_EVENT_FROM;\nextern const NSString *CS_NATIVE_WIDGET_EVENT_PAYLOAD_MARKDOWN_EVENT_FROM_SCREENSHOT;\n\n\n@interface AMXMarkdownUtil : NSObject\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "iOS/FluidMarkdown/Sources/Util/AMXMarkdownUtil.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n#import \"AMXMarkdownUtil.h\"\n\n@implementation AMXMarkdownUtil\n\n@end\n#pragma mark Native Widget Method\n\nconst NSString *CS_NATIVE_WIDGET_METHOD_NAME_MARKDOWN_CANCEL_SELECTED = @\"markdown_cancel_selected\";\nconst NSString *CS_NATIVE_WIDGET_METHOD_NAME_MARKDOWN_SELECT_PARAGRAPH = @\"markdown_select_paragraph\";\nconst NSString *CS_NATIVE_WIDGET_METHOD_NAME_MARKDOWN_SELECT_ALL = @\"markdown_select_all\";\nconst NSString *CS_NATIVE_WIDGET_METHOD_NAME_MARKDOWN_CONTENT_VIEW = @\"markdown_content_view\";\nconst NSString *CS_NATIVE_WIDGET_METHOD_NAME_MARKDOWN_IS_PRINTING = @\"markdown_is_printing\";\nconst NSString *CS_NATIVE_WIDGET_METHOD_PARAMS_MARKDOWN_POINT = @\"markdown_point\";\nconst NSString *CS_NATIVE_WIDGET_METHOD_RETURN_DATA = @\"data\";\n\n#pragma mark Native Widget Delegate\n\nconst NSString *CS_NATIVE_WIDGET_EVENT_NAME_MARKDOWN_STRING_CHANGE = @\"markdown_string_change\";\nconst NSString *CS_NATIVE_WIDGET_EVENT_NAME_MARKDOWN_ENABLE_SELECTABLE = @\"markdown_enable_selectable\";\nconst NSString *CS_NATIVE_WIDGET_EVENT_NAME_MARKDOWN_GESTURE_LONGPRESS = @\"markdown_gesture_longpress\";\nconst NSString *CS_NATIVE_WIDGET_EVENT_NAME_MARKDOWN_GESTURE_TAP = @\"markdown_gesture_tap\";\nconst NSString *CS_NATIVE_WIDGET_EVENT_NAME_MARKDOWN_GESTURE_PAN = @\"markdown_gesture_pan\";\nconst NSString *CS_NATIVE_WIDGET_EVENT_NAME_MARKDOWN_SELECTED_CHANGE = @\"markdown_selected_change\";\nconst NSString *CS_NATIVE_WIDGET_EVENT_NAME_MARKDOWN_ENABLE_AUTO_SCROLL = @\"markdown_enable_auto_scroll\";\nconst NSString *CS_NATIVE_WIDGET_EVENT_NAME_MARKDOWN_AUTO_SCROLL_OPTION_FOR_SELECTING = @\"markdown_auto_scroll_option_for_selecting\";\nconst NSString *CS_NATIVE_WIDGET_EVENT_NAME_MARKDOWN_LONGPRESS_GESTURE_SHOULD_BEGIN = @\"markdown_longpress_gesture_should_begin\";\nconst NSString *CS_NATIVE_WIDGET_EVENT_NAME_MARKDOWN_TAP_GESTURE_SHOULD_BEGIN = @\"markdown_tap_gesture_should_begin\";\nconst NSString *CS_NATIVE_WIDGET_EVENT_PAYLOAD_MAKRDOWN_SELECTED_TEXT = @\"markdown_selected_text\";\nconst NSString *CS_NATIVE_WIDGET_EVENT_PAYLOAD_MAKRDOWN_START_SELECTED_RECT = @\"markdown_start_selected_rect\";\nconst NSString *CS_NATIVE_WIDGET_EVENT_PAYLOAD_MAKRDOWN_END_SELECTED_RECT = @\"markdown_end_selected_rect\";\nconst NSString *CS_NATIVE_WIDGET_EVENT_PAYLOAD_MAKRDOWN_SELECTED_RECT = @\"markdown_selected_rect\";\nconst NSString *CS_NATIVE_WIDGET_EVENT_PAYLOAD_MAKRDOWN_GESTURE_POINT = @\"markdown_gesture_point\";\nconst NSString *CS_NATIVE_WIDGET_EVENT_PAYLOAD_MAKRDOWN_GESTURE_STATE = @\"markdown_gesture_state\";\nconst NSString *CS_NATIVE_WIDGET_EVENT_PAYLOAD_MARKDOWN_CONTENT_VIEW = @\"markdown_content_view\";\nconst NSString *CS_NATIVE_WIDGET_EVENT_PAYLOAD_MARKDOWN_PURE_STRING = @\"markdown_pure_string\";\nconst NSString *CS_NATIVE_WIDGET_EVENT_PAYLOAD_MARKDOWN_GESTURE = @\"markdown_gesture\";\nconst NSString *CS_NATIVE_WIDGET_EVENT_RETURN_DATA = @\"data\";\nconst NSString *CS_NATIVE_WIDGET_EVENT_RETURN_SCROLL_VIEW = @\"scroll_view\";\nconst NSString *CS_NATIVE_WIDGET_EVENT_PAYLOAD_MARKDOWN_EVENT_FROM = @\"markdown_event_from\";\nconst NSString *CS_NATIVE_WIDGET_EVENT_PAYLOAD_MARKDOWN_EVENT_FROM_SCREENSHOT = @\"screenshot\";\n\n"
  },
  {
    "path": "iOS/FluidMarkdown/ViewController.h",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n\n#import <UIKit/UIKit.h>\n\n@interface ViewController : UIViewController\n\n\n@end\n\n"
  },
  {
    "path": "iOS/FluidMarkdown/ViewController.m",
    "content": "// Copyright 2025 The FluidMarkdown Authors. All rights reserved.\n// Use of this source code is governed by a Apache 2.0 license that can be\n// found in the LICENSE file.\n\n\n#import \"ViewController.h\"\n\n@interface ViewController ()\n\n@end\n\n@implementation ViewController\n\n- (void)viewDidLoad {\n    [super viewDidLoad];\n    // Do any additional setup after loading the view.\n}\n\n\n@end\n"
  },
  {
    "path": "iOS/FluidMarkdown/main.m",
    "content": "//\n//  main.m\n//  FluidMarkdown\n//\n//  Created by hejin on 2025/9/15.\n//\n\n#import <UIKit/UIKit.h>\n#import \"AppDelegate.h\"\n\nint main(int argc, char * argv[]) {\n    NSString * appDelegateClassName;\n    @autoreleasepool {\n        // Setup code that might create autoreleased objects goes here.\n        appDelegateClassName = NSStringFromClass([AppDelegate class]);\n    }\n    return UIApplicationMain(argc, argv, nil, appDelegateClassName);\n}\n"
  },
  {
    "path": "iOS/FluidMarkdown.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 77;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t774C570F2E77BAED003034DC /* highlightjs.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 774C570C2E77BAED003034DC /* highlightjs.bundle */; };\n\t\t774C57102E77BAED003034DC /* data3.txt in Resources */ = {isa = PBXBuildFile; fileRef = 774C570B2E77BAED003034DC /* data3.txt */; };\n\t\t774C57112E77BAED003034DC /* mathFonts.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 774C570D2E77BAED003034DC /* mathFonts.bundle */; };\n\t\t774C57122E77BAED003034DC /* data1.txt in Resources */ = {isa = PBXBuildFile; fileRef = 774C57092E77BAED003034DC /* data1.txt */; };\n\t\t774C57132E77BAED003034DC /* AntMarkdown.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 774C57082E77BAED003034DC /* AntMarkdown.bundle */; };\n\t\t774C57142E77BAED003034DC /* data2.txt in Resources */ = {isa = PBXBuildFile; fileRef = 774C570A2E77BAED003034DC /* data2.txt */; };\n\t\t77AF91272E77D0890047A558 /* AntMarkdown.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 77AF91242E77D07E0047A558 /* AntMarkdown.framework */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXContainerItemProxy section */\n\t\t77AF91232E77D07E0047A558 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 77AF911F2E77D07E0047A558 /* AntMarkdown.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = A2E9D38A170BD37D00B11F5E;\n\t\t\tremoteInfo = AntMarkdown;\n\t\t};\n\t\t77AF91252E77D0850047A558 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 77AF911F2E77D07E0047A558 /* AntMarkdown.xcodeproj */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = A2E9D389170BD37D00B11F5E;\n\t\t\tremoteInfo = AntMarkdown;\n\t\t};\n/* End PBXContainerItemProxy section */\n\n/* Begin PBXFileReference section */\n\t\t774C563F2E77B5B4003034DC /* FluidMarkdown.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FluidMarkdown.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t774C57082E77BAED003034DC /* AntMarkdown.bundle */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.plug-in\"; path = AntMarkdown.bundle; sourceTree = \"<group>\"; };\n\t\t774C57092E77BAED003034DC /* data1.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = data1.txt; sourceTree = \"<group>\"; };\n\t\t774C570A2E77BAED003034DC /* data2.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = data2.txt; sourceTree = \"<group>\"; };\n\t\t774C570B2E77BAED003034DC /* data3.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = data3.txt; sourceTree = \"<group>\"; };\n\t\t774C570C2E77BAED003034DC /* highlightjs.bundle */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.plug-in\"; path = highlightjs.bundle; sourceTree = \"<group>\"; };\n\t\t774C570D2E77BAED003034DC /* mathFonts.bundle */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.plug-in\"; path = mathFonts.bundle; sourceTree = \"<group>\"; };\n\t\t77AF911F2E77D07E0047A558 /* AntMarkdown.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.pb-project\"; name = AntMarkdown.xcodeproj; path = AntMarkdown/AntMarkdown.xcodeproj; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */\n\t\t774C56562E77B5B5003034DC /* Exceptions for \"FluidMarkdown\" folder in \"FluidMarkdown\" target */ = {\n\t\t\tisa = PBXFileSystemSynchronizedBuildFileExceptionSet;\n\t\t\tmembershipExceptions = (\n\t\t\t\tInfo.plist,\n\t\t\t);\n\t\t\ttarget = 774C563E2E77B5B4003034DC /* FluidMarkdown */;\n\t\t};\n/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */\n\n/* Begin PBXFileSystemSynchronizedRootGroup section */\n\t\t774C56412E77B5B4003034DC /* FluidMarkdown */ = {\n\t\t\tisa = PBXFileSystemSynchronizedRootGroup;\n\t\t\texceptions = (\n\t\t\t\t774C56562E77B5B5003034DC /* Exceptions for \"FluidMarkdown\" folder in \"FluidMarkdown\" target */,\n\t\t\t);\n\t\t\tpath = FluidMarkdown;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXFileSystemSynchronizedRootGroup section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t774C563C2E77B5B4003034DC /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t77AF91272E77D0890047A558 /* AntMarkdown.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t774C56362E77B5B4003034DC = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t77AF911F2E77D07E0047A558 /* AntMarkdown.xcodeproj */,\n\t\t\t\t774C570E2E77BAED003034DC /* Resources */,\n\t\t\t\t774C56412E77B5B4003034DC /* FluidMarkdown */,\n\t\t\t\t774C56C92E77B9EF003034DC /* Frameworks */,\n\t\t\t\t774C56402E77B5B4003034DC /* Products */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t774C56402E77B5B4003034DC /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t774C563F2E77B5B4003034DC /* FluidMarkdown.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t774C56C92E77B9EF003034DC /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t774C570E2E77BAED003034DC /* Resources */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t774C57082E77BAED003034DC /* AntMarkdown.bundle */,\n\t\t\t\t774C57092E77BAED003034DC /* data1.txt */,\n\t\t\t\t774C570A2E77BAED003034DC /* data2.txt */,\n\t\t\t\t774C570B2E77BAED003034DC /* data3.txt */,\n\t\t\t\t774C570C2E77BAED003034DC /* highlightjs.bundle */,\n\t\t\t\t774C570D2E77BAED003034DC /* mathFonts.bundle */,\n\t\t\t);\n\t\t\tpath = Resources;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t77AF91202E77D07E0047A558 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t77AF91242E77D07E0047A558 /* AntMarkdown.framework */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t774C563E2E77B5B4003034DC /* FluidMarkdown */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 774C56572E77B5B5003034DC /* Build configuration list for PBXNativeTarget \"FluidMarkdown\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t774C563B2E77B5B4003034DC /* Sources */,\n\t\t\t\t774C563C2E77B5B4003034DC /* Frameworks */,\n\t\t\t\t774C563D2E77B5B4003034DC /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t77AF91262E77D0850047A558 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tfileSystemSynchronizedGroups = (\n\t\t\t\t774C56412E77B5B4003034DC /* FluidMarkdown */,\n\t\t\t);\n\t\t\tname = FluidMarkdown;\n\t\t\tpackageProductDependencies = (\n\t\t\t);\n\t\t\tproductName = FluidMarkdown;\n\t\t\tproductReference = 774C563F2E77B5B4003034DC /* FluidMarkdown.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t774C56372E77B5B4003034DC /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tBuildIndependentTargetsInParallel = 1;\n\t\t\t\tLastUpgradeCheck = 1620;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t774C563E2E77B5B4003034DC = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 16.2;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 774C563A2E77B5B4003034DC /* Build configuration list for PBXProject \"FluidMarkdown\" */;\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 774C56362E77B5B4003034DC;\n\t\t\tminimizedProjectReferenceProxies = 1;\n\t\t\tpreferredProjectObjectVersion = 77;\n\t\t\tproductRefGroup = 774C56402E77B5B4003034DC /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectReferences = (\n\t\t\t\t{\n\t\t\t\t\tProductGroup = 77AF91202E77D07E0047A558 /* Products */;\n\t\t\t\t\tProjectRef = 77AF911F2E77D07E0047A558 /* AntMarkdown.xcodeproj */;\n\t\t\t\t},\n\t\t\t);\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t774C563E2E77B5B4003034DC /* FluidMarkdown */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXReferenceProxy section */\n\t\t77AF91242E77D07E0047A558 /* AntMarkdown.framework */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = wrapper.framework;\n\t\t\tpath = AntMarkdown.framework;\n\t\t\tremoteRef = 77AF91232E77D07E0047A558 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n/* End PBXReferenceProxy section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t774C563D2E77B5B4003034DC /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t774C570F2E77BAED003034DC /* highlightjs.bundle in Resources */,\n\t\t\t\t774C57102E77BAED003034DC /* data3.txt in Resources */,\n\t\t\t\t774C57112E77BAED003034DC /* mathFonts.bundle in Resources */,\n\t\t\t\t774C57122E77BAED003034DC /* data1.txt in Resources */,\n\t\t\t\t774C57132E77BAED003034DC /* AntMarkdown.bundle in Resources */,\n\t\t\t\t774C57142E77BAED003034DC /* data2.txt in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t774C563B2E77B5B4003034DC /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXTargetDependency section */\n\t\t77AF91262E77D0850047A558 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\tname = AntMarkdown;\n\t\t\ttargetProxy = 77AF91252E77D0850047A558 /* PBXContainerItemProxy */;\n\t\t};\n/* End PBXTargetDependency section */\n\n/* Begin XCBuildConfiguration section */\n\t\t774C56582E77B5B5003034DC /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tARCHS = (\n\t\t\t\t\t\"$(ARCHS_STANDARD)\",\n\t\t\t\t\tx86_64,\n\t\t\t\t);\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEVELOPMENT_TEAM = D4NA563L94;\n\t\t\t\tEXCLUDED_ARCHS = \"\";\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGENERATE_INFOPLIST_FILE = YES;\n\t\t\t\tINFOPLIST_FILE = FluidMarkdown/Info.plist;\n\t\t\t\tINFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;\n\t\t\t\tINFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;\n\t\t\t\tINFOPLIST_KEY_UIMainStoryboardFile = Main;\n\t\t\t\tINFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = \"UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight\";\n\t\t\t\tINFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = \"UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 15.6;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMARKETING_VERSION = 1.0;\n\t\t\t\tOTHER_LDFLAGS = \"-ObjC\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.alipay.card.FluidMarkdown;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_EMIT_LOC_STRINGS = YES;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t774C56592E77B5B5003034DC /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tARCHS = (\n\t\t\t\t\t\"$(ARCHS_STANDARD)\",\n\t\t\t\t\tx86_64,\n\t\t\t\t);\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEVELOPMENT_TEAM = D4NA563L94;\n\t\t\t\tEXCLUDED_ARCHS = \"\";\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGENERATE_INFOPLIST_FILE = YES;\n\t\t\t\tINFOPLIST_FILE = FluidMarkdown/Info.plist;\n\t\t\t\tINFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;\n\t\t\t\tINFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;\n\t\t\t\tINFOPLIST_KEY_UIMainStoryboardFile = Main;\n\t\t\t\tINFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = \"UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight\";\n\t\t\t\tINFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = \"UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 15.6;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMARKETING_VERSION = 1.0;\n\t\t\t\tOTHER_LDFLAGS = \"-ObjC\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.alipay.card.FluidMarkdown;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_EMIT_LOC_STRINGS = YES;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t774C565A2E77B5B5003034DC /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tARCHS = (\n\t\t\t\t\t\"$(ARCHS_STANDARD)\",\n\t\t\t\t\tx86_64,\n\t\t\t\t);\n\t\t\t\tASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++20\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tENABLE_USER_SCRIPT_SANDBOXING = YES;\n\t\t\t\tEXCLUDED_ARCHS = arm64;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu17;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 18.2;\n\t\t\t\tLOCALIZATION_PREFERS_STRING_CATALOGS = YES;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t774C565B2E77B5B5003034DC /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tARCHS = (\n\t\t\t\t\t\"$(ARCHS_STANDARD)\",\n\t\t\t\t\tx86_64,\n\t\t\t\t);\n\t\t\t\tASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++20\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_USER_SCRIPT_SANDBOXING = YES;\n\t\t\t\tEXCLUDED_ARCHS = arm64;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu17;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 18.2;\n\t\t\t\tLOCALIZATION_PREFERS_STRING_CATALOGS = YES;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t774C563A2E77B5B4003034DC /* Build configuration list for PBXProject \"FluidMarkdown\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t774C565A2E77B5B5003034DC /* Debug */,\n\t\t\t\t774C565B2E77B5B5003034DC /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t774C56572E77B5B5003034DC /* Build configuration list for PBXNativeTarget \"FluidMarkdown\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t774C56582E77B5B5003034DC /* Debug */,\n\t\t\t\t774C56592E77B5B5003034DC /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 774C56372E77B5B4003034DC /* Project object */;\n}\n"
  },
  {
    "path": "iOS/FluidMarkdown.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "iOS/FluidMarkdown.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"group:FluidMarkdown.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "iOS/Resources/AntMarkdown.bundle/Images.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "iOS/Resources/data1.txt",
    "content": "看到你头疼，真的很想帮你缓解这种不适！头疼确实很烦人，但别担心，有很多方法可以尝试缓解。我来分享一些实用建议，希望能帮到你：\n\n## 🧐 第一步：自我评估（这很重要！）\n\n1.  **疼痛性质：** 是胀痛、跳痛、钝痛、刺痛还是紧箍感？哪个部位最痛（前额、太阳穴、后脑勺、整个头）？\n2.  **严重程度：** 疼痛有多剧烈？（1-10分，你打几分？）\n3.  **伴随症状：** 有没有恶心、呕吐、畏光、怕吵、视力模糊、头晕、脖子僵硬、发烧？\n4.  **诱因：** 最近有没有睡眠不足、压力大、用眼过度（看电脑/手机太久）、没喝水、没吃饭、喝了酒、吃了特定食物、闻到特殊气味、天气变化、女性是否在经期前后？\n5.  **类型：** 是偶尔一次，还是经常发生？如果是经常性的，有没有规律？（比如[偏头痛]、紧张性头痛等）\n\n## 🛌 第二步：尝试家庭缓解方法（适用于轻度到中度、没有危险信号的头痛）\n\n1.  **休息：**\n    *   **找个安静、黑暗的环境躺下：** 闭上眼睛，放松身心。光线和噪音往往是头痛的\"帮凶\"，尤其是偏头痛时。\n    *   **短暂小睡（15-30分钟）：** 有时候小睡一会儿就能让紧绷的神经放松下来，但别睡太久，否则醒来可能更难受。\n\n2.  **冷敷或热敷：**\n    *   **冷敷：** 用冰袋（或包裹的冷冻蔬菜）敷在额头、太阳穴或脖子后面，每次15-20分钟。对偏头痛、发烧引起的头痛效果较好。冷敷能收缩血管，减轻搏动性疼痛。\n    *   **热敷：** 用热毛巾敷在脖子后部或肩部，对紧张性头痛（感觉头被带子勒紧）效果较好。热敷能放松紧张的肌肉。洗个热水澡或淋浴也有帮助。\n\n3.  **补充水分：** 脱水是常见诱因。**慢慢喝一大杯水**，看看是否有改善。平时也要记得规律饮水，别等渴了才喝。\n\n4.  **适量[咖啡因]：** 对于**偶尔**的头痛，一杯茶或咖啡可能有助于收缩血管缓解疼痛（尤其对某些偏头痛有效）。但如果你经常喝咖啡，突然不喝反而可能引起头痛（戒断性头痛）。**不要过量！**\n\n5.  **轻柔按摩：**\n    *   按摩太阳穴、额头、后颈和肩部肌肉。用指腹轻轻打圈按压，力度适中。\n    *   试试按压合谷穴（手背，拇指和食指骨头交汇的凹陷处）和内关穴（手腕内侧，腕横纹上三横指，两筋之间）。\n\n6.  **放松技巧：**\n    *   **深呼吸：** 用鼻子深吸气4秒，屏住2秒，再用嘴缓慢呼气6秒。重复几次。\n    *   **渐进式肌肉放松：** 依次绷紧再放松身体各部位肌肉（脚趾、小腿、大腿、腹部、手、手臂、肩膀、面部）。\n    *   **冥想或正念：** 专注呼吸或当下感受，让思绪平静下来。手机上有不少冥想APP可以引导你。\n\n7.  **非处方止痛药：** (请务必按说明书服用，注意禁忌症)\n    *   **[对乙酰氨基酚]：** 如泰诺林、必理通等。相对温和，对胃刺激小，但注意不要超量（每天不超过4克），过量伤肝。\n    *   **[布洛芬]/萘普生：** 如芬必得（布洛芬）、Aleve（萘普生）等。有抗炎作用，对紧张性头痛、炎症相关头痛可能更有效，但可能刺激胃，有胃病者慎用。\n    *   **阿司匹林：** 也有抗炎作用，但同样可能刺激胃，儿童青少年病毒感染期间禁用（有瑞氏综合征风险）。\n    *   **注意：**\n        *   不要频繁或过量使用止痛药（一周超过2-3天），否则可能导致**药物过度使用性头痛**，形成恶性循环。\n        *   仔细阅读说明书，了解禁忌症（如[胃溃疡]、肝[肾功能不全]、哮喘、怀孕等）和最大剂量。\n        *   如果一种药无效，不要立即叠加另一种，先咨询医生或药师。\n\n8.  **调整环境：** 确保房间通风良好，温度适宜。太闷热或太冷的环境都可能诱发头痛。\n\n9.  **吃点东西：** 低血糖也可能导致头痛。如果有一段时间没进食，吃点健康的零食（如坚果、水果、全麦饼干）。\n\n## 🚨 第三步：什么情况下必须立即就医？\n\n如果头痛伴随以下**任何一项**，请**立即**去急诊或拨打急救电话：\n\n*   **突然发生的、极其剧烈的头痛（\"一生中最严重的头痛\"）：** 像被雷劈了一样突然剧痛。\n*   **头痛伴有：**\n    *   高烧不退。\n    *   颈部僵硬、疼痛。\n    *   精神混乱、意识模糊、行为异常、说话不清、理解困难。\n    *   视力突然丧失、模糊、重影。\n    *   身体一侧麻木、无力（脸、手臂、腿）。\n    *   行走困难、失去平衡、协调性差。\n    *   抽搐。\n*   **头部受伤后出现的头痛，尤其是伴有恶心、呕吐、嗜睡或意识丧失。**\n*   **50岁后新发的头痛。**\n*   **头痛模式发生显著改变（如频率、强度、性质突然加剧）。**\n*   **咳嗽、用力、弯腰或性生活时诱发或加重的剧烈头痛。**\n*   **癌症患者或免疫系统受损者（如HIV/AIDS）出现新发头痛。**\n\n## 🩺 第四步：什么情况下建议尽快看医生（非急诊，但需要专业评估）\n\n*   **头痛频繁发作（一周超过一次），影响生活和工作。**\n*   **家庭处理方法无效或效果越来越差。**\n*   **需要越来越频繁或越来越大量地服用止痛药才能控制。**\n*   **怀孕期间出现新发头痛或头痛加重。**\n*   **怀疑头痛与特定药物有关。**\n*   **有慢性疾病（如高血压、自身免疫病）且头痛情况有变化。**\n\n## 🌿 长期管理和预防\n\n*   **规律作息：** 保证充足且规律的睡眠。每天尽量在同一时间入睡和起床，周末也不要差太多。\n*   **管理压力：** 学习并实践压力管理技巧（运动、冥想、瑜伽、兴趣爱好、心理咨询等）。压力是头痛最常见的诱因之一。\n*   **健康饮食：** 规律进食，避免可能诱发头痛的食物（常见诱因包括：陈年奶酪、加工肉类、味精、过量咖啡因、酒精尤其是红酒、某些人工甜味剂）。记录饮食日记可能有帮助。\n*   **充足饮水：** 保持身体水分充足。\n*   **规律运动：** 适度有氧运动（如快走、游泳、骑自行车）有助于预防头痛，但避免在头痛发作时剧烈运动。\n*   **注意姿势：** 尤其是长时间伏案工作或使用电脑时，保持良好坐姿，定时活动颈肩。\n*   **管理用眼：** 避免长时间盯着屏幕，定时休息（20-20-20法则：每20分钟看20英尺外物体20秒），保证眼镜度数合适。\n*   **记录头痛日记：** 记录每次头痛的时间、强度、持续时间、可能的诱因、伴随症状、服用的药物及效果。这有助于你和医生找出规律和诱因。\n*   **遵医嘱：** 如果医生诊断为偏头痛、紧张性头痛等并开了预防性或急性期治疗药物，务必遵医嘱服用。\n\n**总结一下：**\n\n*   **轻度偶发头痛：** 优先尝试休息、冷/热敷、喝水、按摩、放松、非处方止痛药（谨慎使用）。\n*   **频繁或严重头痛、伴随危险信号：** **立即就医！**\n*   **慢性或困扰生活的头痛：** **及时看医生**查找原因并制定管理方案。\n\n**希望这些方法能帮你缓解不适！但如果疼痛持续或加重，千万别硬撑，及时寻求专业帮助才是明智之举。照顾好自己，愿你早日摆脱头痛的困扰！** 🌈\n"
  },
  {
    "path": "iOS/Resources/data2.txt",
    "content": "以下是一个科学、安全的减肥方法表格，结合饮食、运动和生活习惯调整，供参考：\n\n---\n\n### **减肥方法一览表**\n\n| **类别**       | **具体建议**                                                                 | **注意事项**                                                                 |\n|----------------|-----------------------------------------------------------------------------|-----------------------------------------------------------------------------|\n| **饮食调整**   | 1. **控制热量摄入**：每日减少300-500大卡（如减少1碗米饭或1块炸鸡）           | 不要极端节食（男性不低于1500大卡/天，女性不低于1200大卡/天）               |\n|                | 2. **均衡饮食**：每餐包含蛋白质（鸡蛋/鱼/豆类）+蔬菜（占餐盘1/2）+适量碳水    | 避免完全断碳（可能导致脱发、月经失调）                                      |\n|                | 3. **减少高热量食物**：避免含糖饮料、油炸食品、甜点，用水果替代零食           | 水果每天200-300克（约1个苹果量），避免过量                                 |\n| **运动建议**   | 1. **每周150分钟中等强度运动**：如快走、游泳、骑自行车（可分5天，每天30分钟）  | 体重基数大者避免跑步、跳绳（伤膝盖），可改为椭圆机、游泳                   |\n|                | 2. **加入力量训练**：每周2次深蹲、平板支撑、哑铃训练（维持肌肉量，提高代谢）    | 运动后补充蛋白质（如鸡蛋、牛奶），避免空腹运动                              |\n| **生活习惯**   | 1. **保证睡眠**：每天7-9小时睡眠（睡眠不足会升高饥饿激素）                     | 睡前2小时避免剧烈运动或大量进食                                             |\n|                | 2. **饭前喝1杯水**：减少过量进食可能                                         | 避免边看视频边吃饭（易无意识吃多）                                          |\n|                | 3. **规律三餐**：定时定量，避免暴饮暴食                                       | 可少量多餐（如分4-5餐），但需控制总热量                                     |\n| **心理调节**   | 1. **设定合理目标**：每周减0.5-1公斤（每月2-4公斤）                           | 体重波动时保持耐心，避免因短期变化焦虑                                      |\n|                | 2. **记录饮食和运动**：用APP或笔记本追踪，提高执行效率                         | 不要因偶尔放纵自责，及时调整后续计划                                        |\n\n---\n\n### **关键提醒**\n1. **循序渐进**：快速减肥易反弹，且可能引发脱发、月经紊乱等问题。\n2. **个体化调整**：如有疾病（如[糖尿病]、甲减）或特殊情况（如哺乳期），建议先咨询医生或营养师。\n3. **平台期应对**：调整运动方式（如增加间歇性训练）或重新计算每日所需热量（随体重下降而减少）。\n4. **关注身体信号**：如出现头晕、乏力、月经异常等，及时就医排查原因。\n\n科学减脂需要耐心，健康的生活方式比短期瘦身更重要。如有需要，可到正规医院营养科或内分泌科制定个性化方案。\n"
  },
  {
    "path": "iOS/Resources/data3.txt",
    "content": "在Markdown或HTML中，有序列表嵌套无序列表的实现方式如下：\n\n### Markdown实现示例\n```markdown\n1. 有序列表第一项\n   - 无序子项A\n   - 无序子项B\n2. 有序列表第二项\n   * 无序子项C\n   + 无序子项D\n```\n渲染效果为：\n1. 有序列表第一项\n   - 无序子项A\n   - 无序子项B\n2. 有序列表第二项\n   * 无序子项C\n   + 无序子项D\n\n**关键点**：\n- 无序子项需缩进至少2-4个空格（或1个Tab）[5][8]\n- 支持使用`-`、`*`或`+`作为无序列表标记[8]\n\n### HTML实现示例\n```html\n<ol>\n  <li>有序列表第一项\n    <ul>\n      <li>无序子项A</li>\n      <li>无序子项B</li>\n    </ul>\n  </li>\n  <li>有序列表第二项\n    <ul type=\"square\">\n      <li>无序子项C</li>\n      <li>无序子项D</li>\n    </ul>\n  </li>\n</ol>\n```\n**特性**：\n- 可通过`type`属性自定义无序列表符号（如`disc`、`circle`、`square`）[2][9]\n- 嵌套需确保`<ul>`或`<ol>`标签包含在`<li>`标签内[6]\n\n### 应用场景\n这种结构适用于需要分步骤说明且包含并列细节的场景，如教程步骤中的注意事项或任务分解[1][7]。\n"
  },
  {
    "path": "iOS/Resources/mathFonts.bundle/xits-math.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>accents</key>\n\t<dict>\n\t\t<key>A</key>\n\t\t<integer>361</integer>\n\t\t<key>B</key>\n\t\t<integer>305</integer>\n\t\t<key>C</key>\n\t\t<integer>360</integer>\n\t\t<key>D</key>\n\t\t<integer>350</integer>\n\t\t<key>E</key>\n\t\t<integer>304</integer>\n\t\t<key>F</key>\n\t\t<integer>294</integer>\n\t\t<key>G</key>\n\t\t<integer>376</integer>\n\t\t<key>H</key>\n\t\t<integer>360</integer>\n\t\t<key>I</key>\n\t\t<integer>166</integer>\n\t\t<key>J</key>\n\t\t<integer>214</integer>\n\t\t<key>K</key>\n\t\t<integer>368</integer>\n\t\t<key>L</key>\n\t\t<integer>151</integer>\n\t\t<key>M</key>\n\t\t<integer>438</integer>\n\t\t<key>N</key>\n\t\t<integer>360</integer>\n\t\t<key>O</key>\n\t\t<integer>361</integer>\n\t\t<key>P</key>\n\t\t<integer>279</integer>\n\t\t<key>Q</key>\n\t\t<integer>358</integer>\n\t\t<key>R</key>\n\t\t<integer>272</integer>\n\t\t<key>S</key>\n\t\t<integer>267</integer>\n\t\t<key>T</key>\n\t\t<integer>305</integer>\n\t\t<key>U</key>\n\t\t<integer>390</integer>\n\t\t<key>V</key>\n\t\t<integer>388</integer>\n\t\t<key>W</key>\n\t\t<integer>456</integer>\n\t\t<key>X</key>\n\t\t<integer>397</integer>\n\t\t<key>Y</key>\n\t\t<integer>396</integer>\n\t\t<key>Z</key>\n\t\t<integer>304</integer>\n\t\t<key>a</key>\n\t\t<integer>222</integer>\n\t\t<key>b</key>\n\t\t<integer>112</integer>\n\t\t<key>breve</key>\n\t\t<integer>168</integer>\n\t\t<key>c</key>\n\t\t<integer>244</integer>\n\t\t<key>caron</key>\n\t\t<integer>166</integer>\n\t\t<key>circumflex</key>\n\t\t<integer>166</integer>\n\t\t<key>d</key>\n\t\t<integer>367</integer>\n\t\t<key>dotaccent</key>\n\t\t<integer>168</integer>\n\t\t<key>dotlessi</key>\n\t\t<integer>134</integer>\n\t\t<key>e</key>\n\t\t<integer>224</integer>\n\t\t<key>f</key>\n\t\t<integer>264</integer>\n\t\t<key>g</key>\n\t\t<integer>233</integer>\n\t\t<key>h</key>\n\t\t<integer>116</integer>\n\t\t<key>hungarumlaut</key>\n\t\t<integer>186</integer>\n\t\t<key>i</key>\n\t\t<integer>132</integer>\n\t\t<key>j</key>\n\t\t<integer>144</integer>\n\t\t<key>k</key>\n\t\t<integer>116</integer>\n\t\t<key>l</key>\n\t\t<integer>138</integer>\n\t\t<key>m</key>\n\t\t<integer>396</integer>\n\t\t<key>n</key>\n\t\t<integer>250</integer>\n\t\t<key>o</key>\n\t\t<integer>250</integer>\n\t\t<key>p</key>\n\t\t<integer>238</integer>\n\t\t<key>periodcentered</key>\n\t\t<integer>126</integer>\n\t\t<key>q</key>\n\t\t<integer>256</integer>\n\t\t<key>r</key>\n\t\t<integer>170</integer>\n\t\t<key>ring</key>\n\t\t<integer>166</integer>\n\t\t<key>s</key>\n\t\t<integer>200</integer>\n\t\t<key>t</key>\n\t\t<integer>116</integer>\n\t\t<key>tilde</key>\n\t\t<integer>166</integer>\n\t\t<key>u</key>\n\t\t<integer>234</integer>\n\t\t<key>u1D400</key>\n\t\t<integer>345</integer>\n\t\t<key>u1D401</key>\n\t\t<integer>318</integer>\n\t\t<key>u1D402</key>\n\t\t<integer>368</integer>\n\t\t<key>u1D403</key>\n\t\t<integer>352</integer>\n\t\t<key>u1D404</key>\n\t\t<integer>328</integer>\n\t\t<key>u1D405</key>\n\t\t<integer>300</integer>\n\t\t<key>u1D406</key>\n\t\t<integer>396</integer>\n\t\t<key>u1D407</key>\n\t\t<integer>390</integer>\n\t\t<key>u1D408</key>\n\t\t<integer>195</integer>\n\t\t<key>u1D409</key>\n\t\t<integer>310</integer>\n\t\t<key>u1D40A</key>\n\t\t<integer>410</integer>\n\t\t<key>u1D40B</key>\n\t\t<integer>192</integer>\n\t\t<key>u1D40C</key>\n\t\t<integer>468</integer>\n\t\t<key>u1D40D</key>\n\t\t<integer>358</integer>\n\t\t<key>u1D40E</key>\n\t\t<integer>389</integer>\n\t\t<key>u1D40F</key>\n\t\t<integer>308</integer>\n\t\t<key>u1D410</key>\n\t\t<integer>389</integer>\n\t\t<key>u1D411</key>\n\t\t<integer>323</integer>\n\t\t<key>u1D412</key>\n\t\t<integer>274</integer>\n\t\t<key>u1D413</key>\n\t\t<integer>334</integer>\n\t\t<key>u1D414</key>\n\t\t<integer>420</integer>\n\t\t<key>u1D415</key>\n\t\t<integer>424</integer>\n\t\t<key>u1D416</key>\n\t\t<integer>540</integer>\n\t\t<key>u1D417</key>\n\t\t<integer>402</integer>\n\t\t<key>u1D418</key>\n\t\t<integer>415</integer>\n\t\t<key>u1D419</key>\n\t\t<integer>331</integer>\n\t\t<key>u1D41A</key>\n\t\t<integer>256</integer>\n\t\t<key>u1D41B</key>\n\t\t<integer>139</integer>\n\t\t<key>u1D41C</key>\n\t\t<integer>261</integer>\n\t\t<key>u1D41D</key>\n\t\t<integer>400</integer>\n\t\t<key>u1D41E</key>\n\t\t<integer>235</integer>\n\t\t<key>u1D41F</key>\n\t\t<integer>246</integer>\n\t\t<key>u1D420</key>\n\t\t<integer>240</integer>\n\t\t<key>u1D421</key>\n\t\t<integer>130</integer>\n\t\t<key>u1D422</key>\n\t\t<integer>136</integer>\n\t\t<key>u1D422.dtls</key>\n\t\t<integer>139</integer>\n\t\t<key>u1D423</key>\n\t\t<integer>189</integer>\n\t\t<key>u1D423.dtls</key>\n\t\t<integer>190</integer>\n\t\t<key>u1D424</key>\n\t\t<integer>140</integer>\n\t\t<key>u1D425</key>\n\t\t<integer>136</integer>\n\t\t<key>u1D426</key>\n\t\t<integer>414</integer>\n\t\t<key>u1D427</key>\n\t\t<integer>280</integer>\n\t\t<key>u1D428</key>\n\t\t<integer>250</integer>\n\t\t<key>u1D429</key>\n\t\t<integer>272</integer>\n\t\t<key>u1D42A</key>\n\t\t<integer>285</integer>\n\t\t<key>u1D42B</key>\n\t\t<integer>231</integer>\n\t\t<key>u1D42C</key>\n\t\t<integer>193</integer>\n\t\t<key>u1D42D</key>\n\t\t<integer>176</integer>\n\t\t<key>u1D42E</key>\n\t\t<integer>249</integer>\n\t\t<key>u1D42F</key>\n\t\t<integer>288</integer>\n\t\t<key>u1D430</key>\n\t\t<integer>407</integer>\n\t\t<key>u1D431</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D432</key>\n\t\t<integer>265</integer>\n\t\t<key>u1D433</key>\n\t\t<integer>220</integer>\n\t\t<key>u1D434</key>\n\t\t<integer>510</integer>\n\t\t<key>u1D435</key>\n\t\t<integer>476</integer>\n\t\t<key>u1D436</key>\n\t\t<integer>492</integer>\n\t\t<key>u1D437</key>\n\t\t<integer>494</integer>\n\t\t<key>u1D438</key>\n\t\t<integer>490</integer>\n\t\t<key>u1D439</key>\n\t\t<integer>490</integer>\n\t\t<key>u1D43A</key>\n\t\t<integer>488</integer>\n\t\t<key>u1D43B</key>\n\t\t<integer>556</integer>\n\t\t<key>u1D43C</key>\n\t\t<integer>388</integer>\n\t\t<key>u1D43D</key>\n\t\t<integer>478</integer>\n\t\t<key>u1D43E</key>\n\t\t<integer>536</integer>\n\t\t<key>u1D43F</key>\n\t\t<integer>387</integer>\n\t\t<key>u1D440</key>\n\t\t<integer>624</integer>\n\t\t<key>u1D441</key>\n\t\t<integer>536</integer>\n\t\t<key>u1D442</key>\n\t\t<integer>475</integer>\n\t\t<key>u1D443</key>\n\t\t<integer>477</integer>\n\t\t<key>u1D444</key>\n\t\t<integer>490</integer>\n\t\t<key>u1D445</key>\n\t\t<integer>474</integer>\n\t\t<key>u1D446</key>\n\t\t<integer>469</integer>\n\t\t<key>u1D447</key>\n\t\t<integer>382</integer>\n\t\t<key>u1D448</key>\n\t\t<integer>440</integer>\n\t\t<key>u1D449</key>\n\t\t<integer>438</integer>\n\t\t<key>u1D44A</key>\n\t\t<integer>574</integer>\n\t\t<key>u1D44B</key>\n\t\t<integer>530</integer>\n\t\t<key>u1D44C</key>\n\t\t<integer>391</integer>\n\t\t<key>u1D44D</key>\n\t\t<integer>521</integer>\n\t\t<key>u1D44E</key>\n\t\t<integer>324</integer>\n\t\t<key>u1D44F</key>\n\t\t<integer>240</integer>\n\t\t<key>u1D450</key>\n\t\t<integer>304</integer>\n\t\t<key>u1D451</key>\n\t\t<integer>470</integer>\n\t\t<key>u1D452</key>\n\t\t<integer>299</integer>\n\t\t<key>u1D453</key>\n\t\t<integer>528</integer>\n\t\t<key>u1D454</key>\n\t\t<integer>324</integer>\n\t\t<key>u1D456</key>\n\t\t<integer>208</integer>\n\t\t<key>u1D457</key>\n\t\t<integer>322</integer>\n\t\t<key>u1D458</key>\n\t\t<integer>234</integer>\n\t\t<key>u1D459</key>\n\t\t<integer>222</integer>\n\t\t<key>u1D45A</key>\n\t\t<integer>399</integer>\n\t\t<key>u1D45B</key>\n\t\t<integer>306</integer>\n\t\t<key>u1D45C</key>\n\t\t<integer>293</integer>\n\t\t<key>u1D45D</key>\n\t\t<integer>320</integer>\n\t\t<key>u1D45E</key>\n\t\t<integer>340</integer>\n\t\t<key>u1D45F</key>\n\t\t<integer>244</integer>\n\t\t<key>u1D460</key>\n\t\t<integer>268</integer>\n\t\t<key>u1D461</key>\n\t\t<integer>214</integer>\n\t\t<key>u1D462</key>\n\t\t<integer>277</integer>\n\t\t<key>u1D463</key>\n\t\t<integer>319</integer>\n\t\t<key>u1D464</key>\n\t\t<integer>481</integer>\n\t\t<key>u1D465</key>\n\t\t<integer>304</integer>\n\t\t<key>u1D466</key>\n\t\t<integer>319</integer>\n\t\t<key>u1D467</key>\n\t\t<integer>300</integer>\n\t\t<key>u1D468</key>\n\t\t<integer>518</integer>\n\t\t<key>u1D469</key>\n\t\t<integer>486</integer>\n\t\t<key>u1D46A</key>\n\t\t<integer>494</integer>\n\t\t<key>u1D46B</key>\n\t\t<integer>478</integer>\n\t\t<key>u1D46C</key>\n\t\t<integer>492</integer>\n\t\t<key>u1D46D</key>\n\t\t<integer>491</integer>\n\t\t<key>u1D46E</key>\n\t\t<integer>510</integer>\n\t\t<key>u1D46F</key>\n\t\t<integer>564</integer>\n\t\t<key>u1D470</key>\n\t\t<integer>404</integer>\n\t\t<key>u1D471</key>\n\t\t<integer>490</integer>\n\t\t<key>u1D472</key>\n\t\t<integer>554</integer>\n\t\t<key>u1D473</key>\n\t\t<integer>399</integer>\n\t\t<key>u1D474</key>\n\t\t<integer>630</integer>\n\t\t<key>u1D475</key>\n\t\t<integer>537</integer>\n\t\t<key>u1D476</key>\n\t\t<integer>493</integer>\n\t\t<key>u1D477</key>\n\t\t<integer>460</integer>\n\t\t<key>u1D478</key>\n\t\t<integer>483</integer>\n\t\t<key>u1D479</key>\n\t\t<integer>455</integer>\n\t\t<key>u1D47A</key>\n\t\t<integer>474</integer>\n\t\t<key>u1D47B</key>\n\t\t<integer>404</integer>\n\t\t<key>u1D47C</key>\n\t\t<integer>473</integer>\n\t\t<key>u1D47D</key>\n\t\t<integer>462</integer>\n\t\t<key>u1D47E</key>\n\t\t<integer>598</integer>\n\t\t<key>u1D47F</key>\n\t\t<integer>529</integer>\n\t\t<key>u1D480</key>\n\t\t<integer>410</integer>\n\t\t<key>u1D481</key>\n\t\t<integer>512</integer>\n\t\t<key>u1D482</key>\n\t\t<integer>330</integer>\n\t\t<key>u1D483</key>\n\t\t<integer>244</integer>\n\t\t<key>u1D484</key>\n\t\t<integer>328</integer>\n\t\t<key>u1D485</key>\n\t\t<integer>502</integer>\n\t\t<key>u1D486</key>\n\t\t<integer>338</integer>\n\t\t<key>u1D487</key>\n\t\t<integer>528</integer>\n\t\t<key>u1D488</key>\n\t\t<integer>338</integer>\n\t\t<key>u1D489</key>\n\t\t<integer>246</integer>\n\t\t<key>u1D48A</key>\n\t\t<integer>234</integer>\n\t\t<key>u1D48A.dtls</key>\n\t\t<integer>178</integer>\n\t\t<key>u1D48B</key>\n\t\t<integer>348</integer>\n\t\t<key>u1D48B.dtls</key>\n\t\t<integer>345</integer>\n\t\t<key>u1D48C</key>\n\t\t<integer>247</integer>\n\t\t<key>u1D48D</key>\n\t\t<integer>238</integer>\n\t\t<key>u1D48E</key>\n\t\t<integer>380</integer>\n\t\t<key>u1D48F</key>\n\t\t<integer>318</integer>\n\t\t<key>u1D490</key>\n\t\t<integer>340</integer>\n\t\t<key>u1D491</key>\n\t\t<integer>354</integer>\n\t\t<key>u1D492</key>\n\t\t<integer>368</integer>\n\t\t<key>u1D493</key>\n\t\t<integer>264</integer>\n\t\t<key>u1D494</key>\n\t\t<integer>289</integer>\n\t\t<key>u1D495</key>\n\t\t<integer>243</integer>\n\t\t<key>u1D496</key>\n\t\t<integer>298</integer>\n\t\t<key>u1D497</key>\n\t\t<integer>342</integer>\n\t\t<key>u1D498</key>\n\t\t<integer>486</integer>\n\t\t<key>u1D499</key>\n\t\t<integer>332</integer>\n\t\t<key>u1D49A</key>\n\t\t<integer>335</integer>\n\t\t<key>u1D49B</key>\n\t\t<integer>308</integer>\n\t\t<key>u1D49C</key>\n\t\t<integer>800</integer>\n\t\t<key>u1D49C.cal</key>\n\t\t<integer>642</integer>\n\t\t<key>u1D49E</key>\n\t\t<integer>697</integer>\n\t\t<key>u1D49E.cal</key>\n\t\t<integer>444</integer>\n\t\t<key>u1D49F</key>\n\t\t<integer>725</integer>\n\t\t<key>u1D49F.cal</key>\n\t\t<integer>500</integer>\n\t\t<key>u1D4A2</key>\n\t\t<integer>642</integer>\n\t\t<key>u1D4A2.cal</key>\n\t\t<integer>452</integer>\n\t\t<key>u1D4A5</key>\n\t\t<integer>662</integer>\n\t\t<key>u1D4A5.cal</key>\n\t\t<integer>612</integer>\n\t\t<key>u1D4A6</key>\n\t\t<integer>772</integer>\n\t\t<key>u1D4A6.cal</key>\n\t\t<integer>500</integer>\n\t\t<key>u1D4A9</key>\n\t\t<integer>740</integer>\n\t\t<key>u1D4A9.cal</key>\n\t\t<integer>636</integer>\n\t\t<key>u1D4AA</key>\n\t\t<integer>519</integer>\n\t\t<key>u1D4AA.cal</key>\n\t\t<integer>466</integer>\n\t\t<key>u1D4AB</key>\n\t\t<integer>710</integer>\n\t\t<key>u1D4AB.cal</key>\n\t\t<integer>391</integer>\n\t\t<key>u1D4AC</key>\n\t\t<integer>520</integer>\n\t\t<key>u1D4AC.cal</key>\n\t\t<integer>456</integer>\n\t\t<key>u1D4AE</key>\n\t\t<integer>562</integer>\n\t\t<key>u1D4AE.cal</key>\n\t\t<integer>477</integer>\n\t\t<key>u1D4AF</key>\n\t\t<integer>605</integer>\n\t\t<key>u1D4AF.cal</key>\n\t\t<integer>396</integer>\n\t\t<key>u1D4B0</key>\n\t\t<integer>552</integer>\n\t\t<key>u1D4B0.cal</key>\n\t\t<integer>536</integer>\n\t\t<key>u1D4B1</key>\n\t\t<integer>660</integer>\n\t\t<key>u1D4B1.cal</key>\n\t\t<integer>433</integer>\n\t\t<key>u1D4B2</key>\n\t\t<integer>756</integer>\n\t\t<key>u1D4B2.cal</key>\n\t\t<integer>574</integer>\n\t\t<key>u1D4B3</key>\n\t\t<integer>602</integer>\n\t\t<key>u1D4B3.cal</key>\n\t\t<integer>510</integer>\n\t\t<key>u1D4B4</key>\n\t\t<integer>648</integer>\n\t\t<key>u1D4B4.cal</key>\n\t\t<integer>495</integer>\n\t\t<key>u1D4B5</key>\n\t\t<integer>652</integer>\n\t\t<key>u1D4B5.cal</key>\n\t\t<integer>496</integer>\n\t\t<key>u1D4B6</key>\n\t\t<integer>499</integer>\n\t\t<key>u1D4B7</key>\n\t\t<integer>497</integer>\n\t\t<key>u1D4B8</key>\n\t\t<integer>487</integer>\n\t\t<key>u1D4B9</key>\n\t\t<integer>782</integer>\n\t\t<key>u1D4BB</key>\n\t\t<integer>600</integer>\n\t\t<key>u1D4BD</key>\n\t\t<integer>511</integer>\n\t\t<key>u1D4BE</key>\n\t\t<integer>443</integer>\n\t\t<key>u1D4BE.dtls</key>\n\t\t<integer>317</integer>\n\t\t<key>u1D4BF</key>\n\t\t<integer>671</integer>\n\t\t<key>u1D4BF.dtls</key>\n\t\t<integer>554</integer>\n\t\t<key>u1D4C0</key>\n\t\t<integer>513</integer>\n\t\t<key>u1D4C1</key>\n\t\t<integer>511</integer>\n\t\t<key>u1D4C2</key>\n\t\t<integer>603</integer>\n\t\t<key>u1D4C3</key>\n\t\t<integer>455</integer>\n\t\t<key>u1D4C5</key>\n\t\t<integer>545</integer>\n\t\t<key>u1D4C6</key>\n\t\t<integer>492</integer>\n\t\t<key>u1D4C7</key>\n\t\t<integer>404</integer>\n\t\t<key>u1D4C8</key>\n\t\t<integer>376</integer>\n\t\t<key>u1D4C9</key>\n\t\t<integer>422</integer>\n\t\t<key>u1D4CA</key>\n\t\t<integer>433</integer>\n\t\t<key>u1D4CB</key>\n\t\t<integer>393</integer>\n\t\t<key>u1D4CC</key>\n\t\t<integer>525</integer>\n\t\t<key>u1D4CD</key>\n\t\t<integer>454</integer>\n\t\t<key>u1D4CE</key>\n\t\t<integer>434</integer>\n\t\t<key>u1D4CF</key>\n\t\t<integer>399</integer>\n\t\t<key>u1D4D0</key>\n\t\t<integer>900</integer>\n\t\t<key>u1D4D0.cal</key>\n\t\t<integer>651</integer>\n\t\t<key>u1D4D1</key>\n\t\t<integer>856</integer>\n\t\t<key>u1D4D1.cal</key>\n\t\t<integer>553</integer>\n\t\t<key>u1D4D2</key>\n\t\t<integer>744</integer>\n\t\t<key>u1D4D2.cal</key>\n\t\t<integer>519</integer>\n\t\t<key>u1D4D3</key>\n\t\t<integer>799</integer>\n\t\t<key>u1D4D3.cal</key>\n\t\t<integer>511</integer>\n\t\t<key>u1D4D4</key>\n\t\t<integer>657</integer>\n\t\t<key>u1D4D4.cal</key>\n\t\t<integer>460</integer>\n\t\t<key>u1D4D5</key>\n\t\t<integer>719</integer>\n\t\t<key>u1D4D5.cal</key>\n\t\t<integer>474</integer>\n\t\t<key>u1D4D6</key>\n\t\t<integer>667</integer>\n\t\t<key>u1D4D6.cal</key>\n\t\t<integer>481</integer>\n\t\t<key>u1D4D7</key>\n\t\t<integer>787</integer>\n\t\t<key>u1D4D7.cal</key>\n\t\t<integer>502</integer>\n\t\t<key>u1D4D8</key>\n\t\t<integer>726</integer>\n\t\t<key>u1D4D8.cal</key>\n\t\t<integer>418</integer>\n\t\t<key>u1D4D9</key>\n\t\t<integer>631</integer>\n\t\t<key>u1D4D9.cal</key>\n\t\t<integer>622</integer>\n\t\t<key>u1D4DA</key>\n\t\t<integer>843</integer>\n\t\t<key>u1D4DA.cal</key>\n\t\t<integer>516</integer>\n\t\t<key>u1D4DB</key>\n\t\t<integer>906</integer>\n\t\t<key>u1D4DB.cal</key>\n\t\t<integer>493</integer>\n\t\t<key>u1D4DC</key>\n\t\t<integer>1006</integer>\n\t\t<key>u1D4DC.cal</key>\n\t\t<integer>707</integer>\n\t\t<key>u1D4DD</key>\n\t\t<integer>827</integer>\n\t\t<key>u1D4DD.cal</key>\n\t\t<integer>654</integer>\n\t\t<key>u1D4DE</key>\n\t\t<integer>562</integer>\n\t\t<key>u1D4DE.cal</key>\n\t\t<integer>482</integer>\n\t\t<key>u1D4DF</key>\n\t\t<integer>816</integer>\n\t\t<key>u1D4DF.cal</key>\n\t\t<integer>462</integer>\n\t\t<key>u1D4E0</key>\n\t\t<integer>562</integer>\n\t\t<key>u1D4E0.cal</key>\n\t\t<integer>473</integer>\n\t\t<key>u1D4E1</key>\n\t\t<integer>816</integer>\n\t\t<key>u1D4E1.cal</key>\n\t\t<integer>474</integer>\n\t\t<key>u1D4E2</key>\n\t\t<integer>606</integer>\n\t\t<key>u1D4E2.cal</key>\n\t\t<integer>487</integer>\n\t\t<key>u1D4E3</key>\n\t\t<integer>715</integer>\n\t\t<key>u1D4E3.cal</key>\n\t\t<integer>411</integer>\n\t\t<key>u1D4E4</key>\n\t\t<integer>624</integer>\n\t\t<key>u1D4E4.cal</key>\n\t\t<integer>549</integer>\n\t\t<key>u1D4E5</key>\n\t\t<integer>722</integer>\n\t\t<key>u1D4E5.cal</key>\n\t\t<integer>438</integer>\n\t\t<key>u1D4E6</key>\n\t\t<integer>936</integer>\n\t\t<key>u1D4E6.cal</key>\n\t\t<integer>580</integer>\n\t\t<key>u1D4E7</key>\n\t\t<integer>666</integer>\n\t\t<key>u1D4E7.cal</key>\n\t\t<integer>534</integer>\n\t\t<key>u1D4E8</key>\n\t\t<integer>634</integer>\n\t\t<key>u1D4E8.cal</key>\n\t\t<integer>522</integer>\n\t\t<key>u1D4E9</key>\n\t\t<integer>676</integer>\n\t\t<key>u1D4E9.cal</key>\n\t\t<integer>513</integer>\n\t\t<key>u1D4EA</key>\n\t\t<integer>585</integer>\n\t\t<key>u1D4EB</key>\n\t\t<integer>525</integer>\n\t\t<key>u1D4EC</key>\n\t\t<integer>560</integer>\n\t\t<key>u1D4ED</key>\n\t\t<integer>848</integer>\n\t\t<key>u1D4EE</key>\n\t\t<integer>523</integer>\n\t\t<key>u1D4EF</key>\n\t\t<integer>642</integer>\n\t\t<key>u1D4F0</key>\n\t\t<integer>557</integer>\n\t\t<key>u1D4F1</key>\n\t\t<integer>557</integer>\n\t\t<key>u1D4F2</key>\n\t\t<integer>469</integer>\n\t\t<key>u1D4F2.dtls</key>\n\t\t<integer>354</integer>\n\t\t<key>u1D4F3</key>\n\t\t<integer>758</integer>\n\t\t<key>u1D4F3.dtls</key>\n\t\t<integer>651</integer>\n\t\t<key>u1D4F4</key>\n\t\t<integer>555</integer>\n\t\t<key>u1D4F5</key>\n\t\t<integer>525</integer>\n\t\t<key>u1D4F6</key>\n\t\t<integer>648</integer>\n\t\t<key>u1D4F7</key>\n\t\t<integer>481</integer>\n\t\t<key>u1D4F8</key>\n\t\t<integer>576</integer>\n\t\t<key>u1D4F9</key>\n\t\t<integer>636</integer>\n\t\t<key>u1D4FA</key>\n\t\t<integer>562</integer>\n\t\t<key>u1D4FB</key>\n\t\t<integer>452</integer>\n\t\t<key>u1D4FC</key>\n\t\t<integer>375</integer>\n\t\t<key>u1D4FD</key>\n\t\t<integer>475</integer>\n\t\t<key>u1D4FE</key>\n\t\t<integer>475</integer>\n\t\t<key>u1D4FF</key>\n\t\t<integer>464</integer>\n\t\t<key>u1D500</key>\n\t\t<integer>622</integer>\n\t\t<key>u1D501</key>\n\t\t<integer>488</integer>\n\t\t<key>u1D502</key>\n\t\t<integer>500</integer>\n\t\t<key>u1D503</key>\n\t\t<integer>391</integer>\n\t\t<key>u1D526.dtls</key>\n\t\t<integer>177</integer>\n\t\t<key>u1D527.dtls</key>\n\t\t<integer>199</integer>\n\t\t<key>u1D538.bi</key>\n\t\t<integer>467</integer>\n\t\t<key>u1D538.it</key>\n\t\t<integer>434</integer>\n\t\t<key>u1D539.bi</key>\n\t\t<integer>496</integer>\n\t\t<key>u1D539.it</key>\n\t\t<integer>476</integer>\n\t\t<key>u1D53B.bi</key>\n\t\t<integer>484</integer>\n\t\t<key>u1D53B.it</key>\n\t\t<integer>460</integer>\n\t\t<key>u1D53C.bi</key>\n\t\t<integer>490</integer>\n\t\t<key>u1D53C.it</key>\n\t\t<integer>470</integer>\n\t\t<key>u1D53D.bi</key>\n\t\t<integer>490</integer>\n\t\t<key>u1D53D.it</key>\n\t\t<integer>471</integer>\n\t\t<key>u1D53E.bi</key>\n\t\t<integer>501</integer>\n\t\t<key>u1D53E.it</key>\n\t\t<integer>498</integer>\n\t\t<key>u1D540.bi</key>\n\t\t<integer>346</integer>\n\t\t<key>u1D540.it</key>\n\t\t<integer>315</integer>\n\t\t<key>u1D541.bi</key>\n\t\t<integer>461</integer>\n\t\t<key>u1D541.it</key>\n\t\t<integer>435</integer>\n\t\t<key>u1D542.bi</key>\n\t\t<integer>522</integer>\n\t\t<key>u1D542.it</key>\n\t\t<integer>503</integer>\n\t\t<key>u1D543.bi</key>\n\t\t<integer>423</integer>\n\t\t<key>u1D543.it</key>\n\t\t<integer>401</integer>\n\t\t<key>u1D544.bi</key>\n\t\t<integer>614</integer>\n\t\t<key>u1D544.it</key>\n\t\t<integer>588</integer>\n\t\t<key>u1D546.bi</key>\n\t\t<integer>514</integer>\n\t\t<key>u1D546.it</key>\n\t\t<integer>504</integer>\n\t\t<key>u1D54A.bi</key>\n\t\t<integer>500</integer>\n\t\t<key>u1D54A.it</key>\n\t\t<integer>440</integer>\n\t\t<key>u1D54B.bi</key>\n\t\t<integer>344</integer>\n\t\t<key>u1D54B.it</key>\n\t\t<integer>373</integer>\n\t\t<key>u1D54C.bi</key>\n\t\t<integer>525</integer>\n\t\t<key>u1D54C.it</key>\n\t\t<integer>504</integer>\n\t\t<key>u1D54D.bi</key>\n\t\t<integer>409</integer>\n\t\t<key>u1D54D.it</key>\n\t\t<integer>397</integer>\n\t\t<key>u1D54E.bi</key>\n\t\t<integer>598</integer>\n\t\t<key>u1D54E.it</key>\n\t\t<integer>581</integer>\n\t\t<key>u1D54F.bi</key>\n\t\t<integer>549</integer>\n\t\t<key>u1D54F.it</key>\n\t\t<integer>503</integer>\n\t\t<key>u1D550.bi</key>\n\t\t<integer>410</integer>\n\t\t<key>u1D550.it</key>\n\t\t<integer>387</integer>\n\t\t<key>u1D552.bi</key>\n\t\t<integer>417</integer>\n\t\t<key>u1D552.it</key>\n\t\t<integer>380</integer>\n\t\t<key>u1D553.bi</key>\n\t\t<integer>426</integer>\n\t\t<key>u1D553.it</key>\n\t\t<integer>392</integer>\n\t\t<key>u1D554.bi</key>\n\t\t<integer>395</integer>\n\t\t<key>u1D554.it</key>\n\t\t<integer>360</integer>\n\t\t<key>u1D555.it</key>\n\t\t<integer>437</integer>\n\t\t<key>u1D556.bi</key>\n\t\t<integer>392</integer>\n\t\t<key>u1D556.it</key>\n\t\t<integer>362</integer>\n\t\t<key>u1D557.bi</key>\n\t\t<integer>431</integer>\n\t\t<key>u1D557.it</key>\n\t\t<integer>373</integer>\n\t\t<key>u1D558.bi</key>\n\t\t<integer>435</integer>\n\t\t<key>u1D558.it</key>\n\t\t<integer>390</integer>\n\t\t<key>u1D559.bi</key>\n\t\t<integer>425</integer>\n\t\t<key>u1D559.it</key>\n\t\t<integer>385</integer>\n\t\t<key>u1D55A.bi</key>\n\t\t<integer>302</integer>\n\t\t<key>u1D55A.dtls</key>\n\t\t<integer>129</integer>\n\t\t<key>u1D55A.it</key>\n\t\t<integer>286</integer>\n\t\t<key>u1D55B.bi</key>\n\t\t<integer>341</integer>\n\t\t<key>u1D55B.dtls</key>\n\t\t<integer>182</integer>\n\t\t<key>u1D55B.it</key>\n\t\t<integer>313</integer>\n\t\t<key>u1D55C.bi</key>\n\t\t<integer>425</integer>\n\t\t<key>u1D55C.it</key>\n\t\t<integer>377</integer>\n\t\t<key>u1D55D.bi</key>\n\t\t<integer>323</integer>\n\t\t<key>u1D55D.it</key>\n\t\t<integer>291</integer>\n\t\t<key>u1D55E.bi</key>\n\t\t<integer>566</integer>\n\t\t<key>u1D55E.it</key>\n\t\t<integer>519</integer>\n\t\t<key>u1D55F.bi</key>\n\t\t<integer>425</integer>\n\t\t<key>u1D55F.it</key>\n\t\t<integer>385</integer>\n\t\t<key>u1D560.bi</key>\n\t\t<integer>354</integer>\n\t\t<key>u1D560.it</key>\n\t\t<integer>314</integer>\n\t\t<key>u1D561.bi</key>\n\t\t<integer>424</integer>\n\t\t<key>u1D561.it</key>\n\t\t<integer>396</integer>\n\t\t<key>u1D562.bi</key>\n\t\t<integer>437</integer>\n\t\t<key>u1D562.it</key>\n\t\t<integer>407</integer>\n\t\t<key>u1D563.bi</key>\n\t\t<integer>385</integer>\n\t\t<key>u1D563.it</key>\n\t\t<integer>347</integer>\n\t\t<key>u1D564.bi</key>\n\t\t<integer>376</integer>\n\t\t<key>u1D564.it</key>\n\t\t<integer>351</integer>\n\t\t<key>u1D565.bi</key>\n\t\t<integer>322</integer>\n\t\t<key>u1D565.it</key>\n\t\t<integer>274</integer>\n\t\t<key>u1D566.bi</key>\n\t\t<integer>436</integer>\n\t\t<key>u1D566.it</key>\n\t\t<integer>343</integer>\n\t\t<key>u1D567.bi</key>\n\t\t<integer>319</integer>\n\t\t<key>u1D567.it</key>\n\t\t<integer>300</integer>\n\t\t<key>u1D568.bi</key>\n\t\t<integer>446</integer>\n\t\t<key>u1D568.it</key>\n\t\t<integer>403</integer>\n\t\t<key>u1D569.bi</key>\n\t\t<integer>356</integer>\n\t\t<key>u1D569.it</key>\n\t\t<integer>348</integer>\n\t\t<key>u1D56A.bi</key>\n\t\t<integer>417</integer>\n\t\t<key>u1D56A.it</key>\n\t\t<integer>343</integer>\n\t\t<key>u1D56B.bi</key>\n\t\t<integer>414</integer>\n\t\t<key>u1D56B.it</key>\n\t\t<integer>375</integer>\n\t\t<key>u1D58E.dtls</key>\n\t\t<integer>199</integer>\n\t\t<key>u1D58F.dtls</key>\n\t\t<integer>206</integer>\n\t\t<key>u1D5A0</key>\n\t\t<integer>333</integer>\n\t\t<key>u1D5A1</key>\n\t\t<integer>250</integer>\n\t\t<key>u1D5A2</key>\n\t\t<integer>364</integer>\n\t\t<key>u1D5A3</key>\n\t\t<integer>365</integer>\n\t\t<key>u1D5A4</key>\n\t\t<integer>307</integer>\n\t\t<key>u1D5A5</key>\n\t\t<integer>298</integer>\n\t\t<key>u1D5A6</key>\n\t\t<integer>371</integer>\n\t\t<key>u1D5A7</key>\n\t\t<integer>329</integer>\n\t\t<key>u1D5A8</key>\n\t\t<integer>200</integer>\n\t\t<key>u1D5A9</key>\n\t\t<integer>264</integer>\n\t\t<key>u1D5AA</key>\n\t\t<integer>280</integer>\n\t\t<key>u1D5AB</key>\n\t\t<integer>318</integer>\n\t\t<key>u1D5AC</key>\n\t\t<integer>421</integer>\n\t\t<key>u1D5AD</key>\n\t\t<integer>337</integer>\n\t\t<key>u1D5AE</key>\n\t\t<integer>357</integer>\n\t\t<key>u1D5AF</key>\n\t\t<integer>261</integer>\n\t\t<key>u1D5B0</key>\n\t\t<integer>360</integer>\n\t\t<key>u1D5B1</key>\n\t\t<integer>261</integer>\n\t\t<key>u1D5B2</key>\n\t\t<integer>256</integer>\n\t\t<key>u1D5B3</key>\n\t\t<integer>304</integer>\n\t\t<key>u1D5B4</key>\n\t\t<integer>330</integer>\n\t\t<key>u1D5B5</key>\n\t\t<integer>327</integer>\n\t\t<key>u1D5B6</key>\n\t\t<integer>460</integer>\n\t\t<key>u1D5B7</key>\n\t\t<integer>350</integer>\n\t\t<key>u1D5B8</key>\n\t\t<integer>315</integer>\n\t\t<key>u1D5B9</key>\n\t\t<integer>315</integer>\n\t\t<key>u1D5BA</key>\n\t\t<integer>213</integer>\n\t\t<key>u1D5BB</key>\n\t\t<integer>264</integer>\n\t\t<key>u1D5BC</key>\n\t\t<integer>227</integer>\n\t\t<key>u1D5BD</key>\n\t\t<integer>232</integer>\n\t\t<key>u1D5BE</key>\n\t\t<integer>225</integer>\n\t\t<key>u1D5BF</key>\n\t\t<integer>244</integer>\n\t\t<key>u1D5C0</key>\n\t\t<integer>244</integer>\n\t\t<key>u1D5C1</key>\n\t\t<integer>243</integer>\n\t\t<key>u1D5C2</key>\n\t\t<integer>110</integer>\n\t\t<key>u1D5C2.dtls</key>\n\t\t<integer>110</integer>\n\t\t<key>u1D5C3</key>\n\t\t<integer>141</integer>\n\t\t<key>u1D5C3.dtls</key>\n\t\t<integer>139</integer>\n\t\t<key>u1D5C4</key>\n\t\t<integer>257</integer>\n\t\t<key>u1D5C5</key>\n\t\t<integer>102</integer>\n\t\t<key>u1D5C6</key>\n\t\t<integer>378</integer>\n\t\t<key>u1D5C7</key>\n\t\t<integer>243</integer>\n\t\t<key>u1D5C8</key>\n\t\t<integer>249</integer>\n\t\t<key>u1D5C9</key>\n\t\t<integer>268</integer>\n\t\t<key>u1D5CA</key>\n\t\t<integer>231</integer>\n\t\t<key>u1D5CB</key>\n\t\t<integer>195</integer>\n\t\t<key>u1D5CC</key>\n\t\t<integer>199</integer>\n\t\t<key>u1D5CD</key>\n\t\t<integer>124</integer>\n\t\t<key>u1D5CE</key>\n\t\t<integer>246</integer>\n\t\t<key>u1D5CF</key>\n\t\t<integer>237</integer>\n\t\t<key>u1D5D0</key>\n\t\t<integer>351</integer>\n\t\t<key>u1D5D1</key>\n\t\t<integer>241</integer>\n\t\t<key>u1D5D2</key>\n\t\t<integer>260</integer>\n\t\t<key>u1D5D3</key>\n\t\t<integer>221</integer>\n\t\t<key>u1D5D4</key>\n\t\t<integer>345</integer>\n\t\t<key>u1D5D5</key>\n\t\t<integer>273</integer>\n\t\t<key>u1D5D6</key>\n\t\t<integer>368</integer>\n\t\t<key>u1D5D7</key>\n\t\t<integer>377</integer>\n\t\t<key>u1D5D8</key>\n\t\t<integer>338</integer>\n\t\t<key>u1D5D9</key>\n\t\t<integer>325</integer>\n\t\t<key>u1D5DA</key>\n\t\t<integer>392</integer>\n\t\t<key>u1D5DB</key>\n\t\t<integer>357</integer>\n\t\t<key>u1D5DC</key>\n\t\t<integer>220</integer>\n\t\t<key>u1D5DD</key>\n\t\t<integer>344</integer>\n\t\t<key>u1D5DE</key>\n\t\t<integer>333</integer>\n\t\t<key>u1D5DF</key>\n\t\t<integer>333</integer>\n\t\t<key>u1D5E0</key>\n\t\t<integer>456</integer>\n\t\t<key>u1D5E1</key>\n\t\t<integer>362</integer>\n\t\t<key>u1D5E2</key>\n\t\t<integer>389</integer>\n\t\t<key>u1D5E3</key>\n\t\t<integer>290</integer>\n\t\t<key>u1D5E4</key>\n\t\t<integer>394</integer>\n\t\t<key>u1D5E5</key>\n\t\t<integer>298</integer>\n\t\t<key>u1D5E6</key>\n\t\t<integer>273</integer>\n\t\t<key>u1D5E7</key>\n\t\t<integer>320</integer>\n\t\t<key>u1D5E8</key>\n\t\t<integer>349</integer>\n\t\t<key>u1D5E9</key>\n\t\t<integer>345</integer>\n\t\t<key>u1D5EA</key>\n\t\t<integer>498</integer>\n\t\t<key>u1D5EB</key>\n\t\t<integer>370</integer>\n\t\t<key>u1D5EC</key>\n\t\t<integer>347</integer>\n\t\t<key>u1D5ED</key>\n\t\t<integer>324</integer>\n\t\t<key>u1D5EE</key>\n\t\t<integer>225</integer>\n\t\t<key>u1D5EF</key>\n\t\t<integer>271</integer>\n\t\t<key>u1D5F0</key>\n\t\t<integer>233</integer>\n\t\t<key>u1D5F1</key>\n\t\t<integer>244</integer>\n\t\t<key>u1D5F2</key>\n\t\t<integer>229</integer>\n\t\t<key>u1D5F3</key>\n\t\t<integer>242</integer>\n\t\t<key>u1D5F4</key>\n\t\t<integer>259</integer>\n\t\t<key>u1D5F5</key>\n\t\t<integer>255</integer>\n\t\t<key>u1D5F6</key>\n\t\t<integer>122</integer>\n\t\t<key>u1D5F6.dtls</key>\n\t\t<integer>122</integer>\n\t\t<key>u1D5F7</key>\n\t\t<integer>106</integer>\n\t\t<key>u1D5F7.dtls</key>\n\t\t<integer>195</integer>\n\t\t<key>u1D5F8</key>\n\t\t<integer>280</integer>\n\t\t<key>u1D5F9</key>\n\t\t<integer>117</integer>\n\t\t<key>u1D5FA</key>\n\t\t<integer>388</integer>\n\t\t<key>u1D5FB</key>\n\t\t<integer>255</integer>\n\t\t<key>u1D5FC</key>\n\t\t<integer>250</integer>\n\t\t<key>u1D5FD</key>\n\t\t<integer>271</integer>\n\t\t<key>u1D5FE</key>\n\t\t<integer>241</integer>\n\t\t<key>u1D5FF</key>\n\t\t<integer>230</integer>\n\t\t<key>u1D600</key>\n\t\t<integer>191</integer>\n\t\t<key>u1D601</key>\n\t\t<integer>189</integer>\n\t\t<key>u1D602</key>\n\t\t<integer>259</integer>\n\t\t<key>u1D603</key>\n\t\t<integer>231</integer>\n\t\t<key>u1D604</key>\n\t\t<integer>350</integer>\n\t\t<key>u1D605</key>\n\t\t<integer>253</integer>\n\t\t<key>u1D606</key>\n\t\t<integer>236</integer>\n\t\t<key>u1D607</key>\n\t\t<integer>219</integer>\n\t\t<key>u1D608</key>\n\t\t<integer>499</integer>\n\t\t<key>u1D609</key>\n\t\t<integer>436</integer>\n\t\t<key>u1D60A</key>\n\t\t<integer>536</integer>\n\t\t<key>u1D60B</key>\n\t\t<integer>412</integer>\n\t\t<key>u1D60C</key>\n\t\t<integer>470</integer>\n\t\t<key>u1D60D</key>\n\t\t<integer>472</integer>\n\t\t<key>u1D60E</key>\n\t\t<integer>544</integer>\n\t\t<key>u1D60F</key>\n\t\t<integer>472</integer>\n\t\t<key>u1D610</key>\n\t\t<integer>352</integer>\n\t\t<key>u1D611</key>\n\t\t<integer>424</integer>\n\t\t<key>u1D612</key>\n\t\t<integer>468</integer>\n\t\t<key>u1D613</key>\n\t\t<integer>430</integer>\n\t\t<key>u1D614</key>\n\t\t<integer>584</integer>\n\t\t<key>u1D615</key>\n\t\t<integer>526</integer>\n\t\t<key>u1D616</key>\n\t\t<integer>527</integer>\n\t\t<key>u1D617</key>\n\t\t<integer>436</integer>\n\t\t<key>u1D618</key>\n\t\t<integer>525</integer>\n\t\t<key>u1D619</key>\n\t\t<integer>420</integer>\n\t\t<key>u1D61A</key>\n\t\t<integer>426</integer>\n\t\t<key>u1D61B</key>\n\t\t<integer>454</integer>\n\t\t<key>u1D61C</key>\n\t\t<integer>489</integer>\n\t\t<key>u1D61D</key>\n\t\t<integer>492</integer>\n\t\t<key>u1D61E</key>\n\t\t<integer>626</integer>\n\t\t<key>u1D61F</key>\n\t\t<integer>510</integer>\n\t\t<key>u1D620</key>\n\t\t<integer>480</integer>\n\t\t<key>u1D621</key>\n\t\t<integer>486</integer>\n\t\t<key>u1D622</key>\n\t\t<integer>333</integer>\n\t\t<key>u1D623</key>\n\t\t<integer>304</integer>\n\t\t<key>u1D624</key>\n\t\t<integer>355</integer>\n\t\t<key>u1D625</key>\n\t\t<integer>458</integer>\n\t\t<key>u1D626</key>\n\t\t<integer>350</integer>\n\t\t<key>u1D627</key>\n\t\t<integer>414</integer>\n\t\t<key>u1D628</key>\n\t\t<integer>352</integer>\n\t\t<key>u1D629</key>\n\t\t<integer>286</integer>\n\t\t<key>u1D62A</key>\n\t\t<integer>268</integer>\n\t\t<key>u1D62A.dtls</key>\n\t\t<integer>219</integer>\n\t\t<key>u1D62B</key>\n\t\t<integer>303</integer>\n\t\t<key>u1D62B.dtls</key>\n\t\t<integer>244</integer>\n\t\t<key>u1D62C</key>\n\t\t<integer>309</integer>\n\t\t<key>u1D62D</key>\n\t\t<integer>268</integer>\n\t\t<key>u1D62E</key>\n\t\t<integer>512</integer>\n\t\t<key>u1D62F</key>\n\t\t<integer>360</integer>\n\t\t<key>u1D630</key>\n\t\t<integer>360</integer>\n\t\t<key>u1D631</key>\n\t\t<integer>396</integer>\n\t\t<key>u1D632</key>\n\t\t<integer>360</integer>\n\t\t<key>u1D633</key>\n\t\t<integer>335</integer>\n\t\t<key>u1D634</key>\n\t\t<integer>310</integer>\n\t\t<key>u1D635</key>\n\t\t<integer>278</integer>\n\t\t<key>u1D636</key>\n\t\t<integer>346</integer>\n\t\t<key>u1D637</key>\n\t\t<integer>349</integer>\n\t\t<key>u1D638</key>\n\t\t<integer>439</integer>\n\t\t<key>u1D639</key>\n\t\t<integer>343</integer>\n\t\t<key>u1D63A</key>\n\t\t<integer>355</integer>\n\t\t<key>u1D63B</key>\n\t\t<integer>351</integer>\n\t\t<key>u1D63C</key>\n\t\t<integer>517</integer>\n\t\t<key>u1D63D</key>\n\t\t<integer>468</integer>\n\t\t<key>u1D63E</key>\n\t\t<integer>570</integer>\n\t\t<key>u1D63F</key>\n\t\t<integer>494</integer>\n\t\t<key>u1D640</key>\n\t\t<integer>496</integer>\n\t\t<key>u1D641</key>\n\t\t<integer>504</integer>\n\t\t<key>u1D642</key>\n\t\t<integer>564</integer>\n\t\t<key>u1D643</key>\n\t\t<integer>524</integer>\n\t\t<key>u1D644</key>\n\t\t<integer>408</integer>\n\t\t<key>u1D645</key>\n\t\t<integer>506</integer>\n\t\t<key>u1D646</key>\n\t\t<integer>512</integer>\n\t\t<key>u1D647</key>\n\t\t<integer>440</integer>\n\t\t<key>u1D648</key>\n\t\t<integer>620</integer>\n\t\t<key>u1D649</key>\n\t\t<integer>548</integer>\n\t\t<key>u1D64A</key>\n\t\t<integer>561</integer>\n\t\t<key>u1D64B</key>\n\t\t<integer>458</integer>\n\t\t<key>u1D64C</key>\n\t\t<integer>562</integer>\n\t\t<key>u1D64D</key>\n\t\t<integer>467</integer>\n\t\t<key>u1D64E</key>\n\t\t<integer>444</integer>\n\t\t<key>u1D64F</key>\n\t\t<integer>507</integer>\n\t\t<key>u1D650</key>\n\t\t<integer>522</integer>\n\t\t<key>u1D651</key>\n\t\t<integer>513</integer>\n\t\t<key>u1D652</key>\n\t\t<integer>666</integer>\n\t\t<key>u1D653</key>\n\t\t<integer>536</integer>\n\t\t<key>u1D654</key>\n\t\t<integer>515</integer>\n\t\t<key>u1D655</key>\n\t\t<integer>531</integer>\n\t\t<key>u1D656</key>\n\t\t<integer>353</integer>\n\t\t<key>u1D657</key>\n\t\t<integer>304</integer>\n\t\t<key>u1D658</key>\n\t\t<integer>371</integer>\n\t\t<key>u1D659</key>\n\t\t<integer>443</integer>\n\t\t<key>u1D65A</key>\n\t\t<integer>355</integer>\n\t\t<key>u1D65B</key>\n\t\t<integer>412</integer>\n\t\t<key>u1D65C</key>\n\t\t<integer>372</integer>\n\t\t<key>u1D65D</key>\n\t\t<integer>298</integer>\n\t\t<key>u1D65E</key>\n\t\t<integer>284</integer>\n\t\t<key>u1D65E.dtls</key>\n\t\t<integer>233</integer>\n\t\t<key>u1D65F</key>\n\t\t<integer>351</integer>\n\t\t<key>u1D65F.dtls</key>\n\t\t<integer>306</integer>\n\t\t<key>u1D660</key>\n\t\t<integer>327</integer>\n\t\t<key>u1D661</key>\n\t\t<integer>263</integer>\n\t\t<key>u1D662</key>\n\t\t<integer>534</integer>\n\t\t<key>u1D663</key>\n\t\t<integer>362</integer>\n\t\t<key>u1D664</key>\n\t\t<integer>371</integer>\n\t\t<key>u1D665</key>\n\t\t<integer>367</integer>\n\t\t<key>u1D666</key>\n\t\t<integer>359</integer>\n\t\t<key>u1D667</key>\n\t\t<integer>373</integer>\n\t\t<key>u1D668</key>\n\t\t<integer>311</integer>\n\t\t<key>u1D669</key>\n\t\t<integer>332</integer>\n\t\t<key>u1D66A</key>\n\t\t<integer>367</integer>\n\t\t<key>u1D66B</key>\n\t\t<integer>345</integer>\n\t\t<key>u1D66C</key>\n\t\t<integer>464</integer>\n\t\t<key>u1D66D</key>\n\t\t<integer>361</integer>\n\t\t<key>u1D66E</key>\n\t\t<integer>349</integer>\n\t\t<key>u1D66F</key>\n\t\t<integer>347</integer>\n\t\t<key>u1D670</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D671</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D672</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D673</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D674</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D675</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D676</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D677</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D678</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D679</key>\n\t\t<integer>360</integer>\n\t\t<key>u1D67A</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D67B</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D67C</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D67D</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D67E</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D67F</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D680</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D681</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D682</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D683</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D684</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D685</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D686</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D687</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D688</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D689</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D68A</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D68B</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D68C</key>\n\t\t<integer>308</integer>\n\t\t<key>u1D68D</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D68E</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D68F</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D690</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D691</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D692</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D692.dtls</key>\n\t\t<integer>206</integer>\n\t\t<key>u1D693</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D693.dtls</key>\n\t\t<integer>253</integer>\n\t\t<key>u1D694</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D695</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D696</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D697</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D698</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D699</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D69A</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D69B</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D69C</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D69D</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D69E</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D69F</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D6A0</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D6A1</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D6A2</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D6A3</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D6A4</key>\n\t\t<integer>179</integer>\n\t\t<key>u1D6A5</key>\n\t\t<integer>193</integer>\n\t\t<key>u1D6A8</key>\n\t\t<integer>343</integer>\n\t\t<key>u1D6A9</key>\n\t\t<integer>318</integer>\n\t\t<key>u1D6AA</key>\n\t\t<integer>304</integer>\n\t\t<key>u1D6AB</key>\n\t\t<integer>326</integer>\n\t\t<key>u1D6AC</key>\n\t\t<integer>328</integer>\n\t\t<key>u1D6AD</key>\n\t\t<integer>331</integer>\n\t\t<key>u1D6AE</key>\n\t\t<integer>390</integer>\n\t\t<key>u1D6AF</key>\n\t\t<integer>389</integer>\n\t\t<key>u1D6B0</key>\n\t\t<integer>195</integer>\n\t\t<key>u1D6B1</key>\n\t\t<integer>410</integer>\n\t\t<key>u1D6B2</key>\n\t\t<integer>336</integer>\n\t\t<key>u1D6B3</key>\n\t\t<integer>468</integer>\n\t\t<key>u1D6B4</key>\n\t\t<integer>358</integer>\n\t\t<key>u1D6B5</key>\n\t\t<integer>312</integer>\n\t\t<key>u1D6B6</key>\n\t\t<integer>389</integer>\n\t\t<key>u1D6B7</key>\n\t\t<integer>390</integer>\n\t\t<key>u1D6B8</key>\n\t\t<integer>308</integer>\n\t\t<key>u1D6B9</key>\n\t\t<integer>389</integer>\n\t\t<key>u1D6BA</key>\n\t\t<integer>320</integer>\n\t\t<key>u1D6BB</key>\n\t\t<integer>334</integer>\n\t\t<key>u1D6BC</key>\n\t\t<integer>403</integer>\n\t\t<key>u1D6BD</key>\n\t\t<integer>418</integer>\n\t\t<key>u1D6BE</key>\n\t\t<integer>400</integer>\n\t\t<key>u1D6BF</key>\n\t\t<integer>394</integer>\n\t\t<key>u1D6C0</key>\n\t\t<integer>379</integer>\n\t\t<key>u1D6C1</key>\n\t\t<integer>336</integer>\n\t\t<key>u1D6C2</key>\n\t\t<integer>256</integer>\n\t\t<key>u1D6C3</key>\n\t\t<integer>284</integer>\n\t\t<key>u1D6C4</key>\n\t\t<integer>256</integer>\n\t\t<key>u1D6C5</key>\n\t\t<integer>252</integer>\n\t\t<key>u1D6C6</key>\n\t\t<integer>228</integer>\n\t\t<key>u1D6C7</key>\n\t\t<integer>230</integer>\n\t\t<key>u1D6C8</key>\n\t\t<integer>278</integer>\n\t\t<key>u1D6C9</key>\n\t\t<integer>250</integer>\n\t\t<key>u1D6CA</key>\n\t\t<integer>136</integer>\n\t\t<key>u1D6CB</key>\n\t\t<integer>290</integer>\n\t\t<key>u1D6CC</key>\n\t\t<integer>141</integer>\n\t\t<key>u1D6CD</key>\n\t\t<integer>282</integer>\n\t\t<key>u1D6CE</key>\n\t\t<integer>255</integer>\n\t\t<key>u1D6CF</key>\n\t\t<integer>231</integer>\n\t\t<key>u1D6D0</key>\n\t\t<integer>250</integer>\n\t\t<key>u1D6D1</key>\n\t\t<integer>314</integer>\n\t\t<key>u1D6D2</key>\n\t\t<integer>280</integer>\n\t\t<key>u1D6D3</key>\n\t\t<integer>234</integer>\n\t\t<key>u1D6D4</key>\n\t\t<integer>277</integer>\n\t\t<key>u1D6D5</key>\n\t\t<integer>238</integer>\n\t\t<key>u1D6D6</key>\n\t\t<integer>282</integer>\n\t\t<key>u1D6D7</key>\n\t\t<integer>326</integer>\n\t\t<key>u1D6D8</key>\n\t\t<integer>304</integer>\n\t\t<key>u1D6D9</key>\n\t\t<integer>382</integer>\n\t\t<key>u1D6DA</key>\n\t\t<integer>367</integer>\n\t\t<key>u1D6DB</key>\n\t\t<integer>258</integer>\n\t\t<key>u1D6DC</key>\n\t\t<integer>228</integer>\n\t\t<key>u1D6DD</key>\n\t\t<integer>316</integer>\n\t\t<key>u1D6DE</key>\n\t\t<integer>279</integer>\n\t\t<key>u1D6DF</key>\n\t\t<integer>326</integer>\n\t\t<key>u1D6E0</key>\n\t\t<integer>256</integer>\n\t\t<key>u1D6E1</key>\n\t\t<integer>476</integer>\n\t\t<key>u1D6E2</key>\n\t\t<integer>508</integer>\n\t\t<key>u1D6E2.ss</key>\n\t\t<integer>499</integer>\n\t\t<key>u1D6E3</key>\n\t\t<integer>464</integer>\n\t\t<key>u1D6E3.ss</key>\n\t\t<integer>436</integer>\n\t\t<key>u1D6E4</key>\n\t\t<integer>492</integer>\n\t\t<key>u1D6E4.ss</key>\n\t\t<integer>443</integer>\n\t\t<key>u1D6E5</key>\n\t\t<integer>453</integer>\n\t\t<key>u1D6E5.ss</key>\n\t\t<integer>498</integer>\n\t\t<key>u1D6E6</key>\n\t\t<integer>492</integer>\n\t\t<key>u1D6E6.ss</key>\n\t\t<integer>470</integer>\n\t\t<key>u1D6E7</key>\n\t\t<integer>503</integer>\n\t\t<key>u1D6E7.ss</key>\n\t\t<integer>486</integer>\n\t\t<key>u1D6E8</key>\n\t\t<integer>560</integer>\n\t\t<key>u1D6E8.ss</key>\n\t\t<integer>472</integer>\n\t\t<key>u1D6E9</key>\n\t\t<integer>463</integer>\n\t\t<key>u1D6E9.ss</key>\n\t\t<integer>490</integer>\n\t\t<key>u1D6EA</key>\n\t\t<integer>360</integer>\n\t\t<key>u1D6EA.ss</key>\n\t\t<integer>352</integer>\n\t\t<key>u1D6EB</key>\n\t\t<integer>540</integer>\n\t\t<key>u1D6EB.ss</key>\n\t\t<integer>468</integer>\n\t\t<key>u1D6EC</key>\n\t\t<integer>510</integer>\n\t\t<key>u1D6EC.ss</key>\n\t\t<integer>492</integer>\n\t\t<key>u1D6ED</key>\n\t\t<integer>614</integer>\n\t\t<key>u1D6ED.ss</key>\n\t\t<integer>584</integer>\n\t\t<key>u1D6EE</key>\n\t\t<integer>538</integer>\n\t\t<key>u1D6EE.ss</key>\n\t\t<integer>526</integer>\n\t\t<key>u1D6EF</key>\n\t\t<integer>476</integer>\n\t\t<key>u1D6EF.ss</key>\n\t\t<integer>495</integer>\n\t\t<key>u1D6F0</key>\n\t\t<integer>465</integer>\n\t\t<key>u1D6F0.ss</key>\n\t\t<integer>490</integer>\n\t\t<key>u1D6F1</key>\n\t\t<integer>554</integer>\n\t\t<key>u1D6F1.ss</key>\n\t\t<integer>504</integer>\n\t\t<key>u1D6F2</key>\n\t\t<integer>477</integer>\n\t\t<key>u1D6F2.ss</key>\n\t\t<integer>436</integer>\n\t\t<key>u1D6F3</key>\n\t\t<integer>465</integer>\n\t\t<key>u1D6F3.ss</key>\n\t\t<integer>490</integer>\n\t\t<key>u1D6F4</key>\n\t\t<integer>509</integer>\n\t\t<key>u1D6F4.ss</key>\n\t\t<integer>463</integer>\n\t\t<key>u1D6F5</key>\n\t\t<integer>348</integer>\n\t\t<key>u1D6F5.ss</key>\n\t\t<integer>392</integer>\n\t\t<key>u1D6F6</key>\n\t\t<integer>358</integer>\n\t\t<key>u1D6F6.ss</key>\n\t\t<integer>396</integer>\n\t\t<key>u1D6F7</key>\n\t\t<integer>464</integer>\n\t\t<key>u1D6F7.ss</key>\n\t\t<integer>486</integer>\n\t\t<key>u1D6F8</key>\n\t\t<integer>530</integer>\n\t\t<key>u1D6F8.ss</key>\n\t\t<integer>510</integer>\n\t\t<key>u1D6F9</key>\n\t\t<integer>386</integer>\n\t\t<key>u1D6F9.ss</key>\n\t\t<integer>456</integer>\n\t\t<key>u1D6FA</key>\n\t\t<integer>546</integer>\n\t\t<key>u1D6FA.ss</key>\n\t\t<integer>539</integer>\n\t\t<key>u1D6FB</key>\n\t\t<integer>321</integer>\n\t\t<key>u1D6FC</key>\n\t\t<integer>284</integer>\n\t\t<key>u1D6FC.ss</key>\n\t\t<integer>393</integer>\n\t\t<key>u1D6FD</key>\n\t\t<integer>424</integer>\n\t\t<key>u1D6FD.ss</key>\n\t\t<integer>427</integer>\n\t\t<key>u1D6FE</key>\n\t\t<integer>246</integer>\n\t\t<key>u1D6FE.ss</key>\n\t\t<integer>351</integer>\n\t\t<key>u1D6FF</key>\n\t\t<integer>342</integer>\n\t\t<key>u1D6FF.ss</key>\n\t\t<integer>376</integer>\n\t\t<key>u1D700</key>\n\t\t<integer>291</integer>\n\t\t<key>u1D700.ss</key>\n\t\t<integer>347</integer>\n\t\t<key>u1D701</key>\n\t\t<integer>334</integer>\n\t\t<key>u1D701.ss</key>\n\t\t<integer>336</integer>\n\t\t<key>u1D702</key>\n\t\t<integer>288</integer>\n\t\t<key>u1D702.ss</key>\n\t\t<integer>346</integer>\n\t\t<key>u1D703</key>\n\t\t<integer>323</integer>\n\t\t<key>u1D703.ss</key>\n\t\t<integer>359</integer>\n\t\t<key>u1D704</key>\n\t\t<integer>164</integer>\n\t\t<key>u1D704.ss</key>\n\t\t<integer>248</integer>\n\t\t<key>u1D705</key>\n\t\t<integer>300</integer>\n\t\t<key>u1D705.ss</key>\n\t\t<integer>336</integer>\n\t\t<key>u1D706</key>\n\t\t<integer>348</integer>\n\t\t<key>u1D706.ss</key>\n\t\t<integer>368</integer>\n\t\t<key>u1D707</key>\n\t\t<integer>374</integer>\n\t\t<key>u1D707.ss</key>\n\t\t<integer>380</integer>\n\t\t<key>u1D708</key>\n\t\t<integer>284</integer>\n\t\t<key>u1D708.ss</key>\n\t\t<integer>288</integer>\n\t\t<key>u1D709</key>\n\t\t<integer>308</integer>\n\t\t<key>u1D709.ss</key>\n\t\t<integer>349</integer>\n\t\t<key>u1D70A</key>\n\t\t<integer>293</integer>\n\t\t<key>u1D70A.ss</key>\n\t\t<integer>366</integer>\n\t\t<key>u1D70B</key>\n\t\t<integer>370</integer>\n\t\t<key>u1D70B.ss</key>\n\t\t<integer>382</integer>\n\t\t<key>u1D70C</key>\n\t\t<integer>333</integer>\n\t\t<key>u1D70C.ss</key>\n\t\t<integer>367</integer>\n\t\t<key>u1D70D</key>\n\t\t<integer>250</integer>\n\t\t<key>u1D70D.ss</key>\n\t\t<integer>318</integer>\n\t\t<key>u1D70E</key>\n\t\t<integer>294</integer>\n\t\t<key>u1D70E.ss</key>\n\t\t<integer>403</integer>\n\t\t<key>u1D70F</key>\n\t\t<integer>295</integer>\n\t\t<key>u1D70F.ss</key>\n\t\t<integer>334</integer>\n\t\t<key>u1D710</key>\n\t\t<integer>238</integer>\n\t\t<key>u1D710.ss</key>\n\t\t<integer>357</integer>\n\t\t<key>u1D711</key>\n\t\t<integer>340</integer>\n\t\t<key>u1D711.ss</key>\n\t\t<integer>432</integer>\n\t\t<key>u1D712</key>\n\t\t<integer>438</integer>\n\t\t<key>u1D712.ss</key>\n\t\t<integer>357</integer>\n\t\t<key>u1D713</key>\n\t\t<integer>370</integer>\n\t\t<key>u1D713.ss</key>\n\t\t<integer>427</integer>\n\t\t<key>u1D714</key>\n\t\t<integer>392</integer>\n\t\t<key>u1D714.ss</key>\n\t\t<integer>415</integer>\n\t\t<key>u1D715</key>\n\t\t<integer>314</integer>\n\t\t<key>u1D715.ss</key>\n\t\t<integer>368</integer>\n\t\t<key>u1D716</key>\n\t\t<integer>309</integer>\n\t\t<key>u1D716.ss</key>\n\t\t<integer>331</integer>\n\t\t<key>u1D717</key>\n\t\t<integer>348</integer>\n\t\t<key>u1D717.ss</key>\n\t\t<integer>367</integer>\n\t\t<key>u1D718</key>\n\t\t<integer>300</integer>\n\t\t<key>u1D719</key>\n\t\t<integer>442</integer>\n\t\t<key>u1D719.ss</key>\n\t\t<integer>458</integer>\n\t\t<key>u1D71A</key>\n\t\t<integer>350</integer>\n\t\t<key>u1D71A.ss</key>\n\t\t<integer>368</integer>\n\t\t<key>u1D71B</key>\n\t\t<integer>504</integer>\n\t\t<key>u1D71B.ss</key>\n\t\t<integer>497</integer>\n\t\t<key>u1D71C</key>\n\t\t<integer>518</integer>\n\t\t<key>u1D71D</key>\n\t\t<integer>496</integer>\n\t\t<key>u1D71E</key>\n\t\t<integer>532</integer>\n\t\t<key>u1D71F</key>\n\t\t<integer>464</integer>\n\t\t<key>u1D720</key>\n\t\t<integer>512</integer>\n\t\t<key>u1D721</key>\n\t\t<integer>518</integer>\n\t\t<key>u1D722</key>\n\t\t<integer>560</integer>\n\t\t<key>u1D723</key>\n\t\t<integer>485</integer>\n\t\t<key>u1D724</key>\n\t\t<integer>366</integer>\n\t\t<key>u1D725</key>\n\t\t<integer>558</integer>\n\t\t<key>u1D726</key>\n\t\t<integer>520</integer>\n\t\t<key>u1D727</key>\n\t\t<integer>632</integer>\n\t\t<key>u1D728</key>\n\t\t<integer>523</integer>\n\t\t<key>u1D729</key>\n\t\t<integer>495</integer>\n\t\t<key>u1D72A</key>\n\t\t<integer>483</integer>\n\t\t<key>u1D72B</key>\n\t\t<integer>558</integer>\n\t\t<key>u1D72C</key>\n\t\t<integer>526</integer>\n\t\t<key>u1D72D</key>\n\t\t<integer>485</integer>\n\t\t<key>u1D72E</key>\n\t\t<integer>526</integer>\n\t\t<key>u1D72F</key>\n\t\t<integer>364</integer>\n\t\t<key>u1D730</key>\n\t\t<integer>376</integer>\n\t\t<key>u1D731</key>\n\t\t<integer>482</integer>\n\t\t<key>u1D732</key>\n\t\t<integer>535</integer>\n\t\t<key>u1D733</key>\n\t\t<integer>406</integer>\n\t\t<key>u1D734</key>\n\t\t<integer>548</integer>\n\t\t<key>u1D735</key>\n\t\t<integer>322</integer>\n\t\t<key>u1D736</key>\n\t\t<integer>337</integer>\n\t\t<key>u1D737</key>\n\t\t<integer>462</integer>\n\t\t<key>u1D738</key>\n\t\t<integer>274</integer>\n\t\t<key>u1D739</key>\n\t\t<integer>369</integer>\n\t\t<key>u1D73A</key>\n\t\t<integer>280</integer>\n\t\t<key>u1D73B</key>\n\t\t<integer>369</integer>\n\t\t<key>u1D73C</key>\n\t\t<integer>336</integer>\n\t\t<key>u1D73D</key>\n\t\t<integer>378</integer>\n\t\t<key>u1D73E</key>\n\t\t<integer>164</integer>\n\t\t<key>u1D73F</key>\n\t\t<integer>316</integer>\n\t\t<key>u1D740</key>\n\t\t<integer>346</integer>\n\t\t<key>u1D741</key>\n\t\t<integer>404</integer>\n\t\t<key>u1D742</key>\n\t\t<integer>372</integer>\n\t\t<key>u1D743</key>\n\t\t<integer>348</integer>\n\t\t<key>u1D744</key>\n\t\t<integer>340</integer>\n\t\t<key>u1D745</key>\n\t\t<integer>384</integer>\n\t\t<key>u1D746</key>\n\t\t<integer>398</integer>\n\t\t<key>u1D747</key>\n\t\t<integer>404</integer>\n\t\t<key>u1D748</key>\n\t\t<integer>324</integer>\n\t\t<key>u1D749</key>\n\t\t<integer>308</integer>\n\t\t<key>u1D74A</key>\n\t\t<integer>284</integer>\n\t\t<key>u1D74B</key>\n\t\t<integer>429</integer>\n\t\t<key>u1D74C</key>\n\t\t<integer>444</integer>\n\t\t<key>u1D74D</key>\n\t\t<integer>394</integer>\n\t\t<key>u1D74E</key>\n\t\t<integer>398</integer>\n\t\t<key>u1D74F</key>\n\t\t<integer>404</integer>\n\t\t<key>u1D750</key>\n\t\t<integer>326</integer>\n\t\t<key>u1D751</key>\n\t\t<integer>398</integer>\n\t\t<key>u1D752</key>\n\t\t<integer>309</integer>\n\t\t<key>u1D753</key>\n\t\t<integer>454</integer>\n\t\t<key>u1D754</key>\n\t\t<integer>370</integer>\n\t\t<key>u1D755</key>\n\t\t<integer>506</integer>\n\t\t<key>u1D790</key>\n\t\t<integer>517</integer>\n\t\t<key>u1D791</key>\n\t\t<integer>468</integer>\n\t\t<key>u1D792</key>\n\t\t<integer>501</integer>\n\t\t<key>u1D793</key>\n\t\t<integer>534</integer>\n\t\t<key>u1D794</key>\n\t\t<integer>496</integer>\n\t\t<key>u1D795</key>\n\t\t<integer>531</integer>\n\t\t<key>u1D796</key>\n\t\t<integer>524</integer>\n\t\t<key>u1D797</key>\n\t\t<integer>559</integer>\n\t\t<key>u1D798</key>\n\t\t<integer>417</integer>\n\t\t<key>u1D799</key>\n\t\t<integer>512</integer>\n\t\t<key>u1D79A</key>\n\t\t<integer>507</integer>\n\t\t<key>u1D79B</key>\n\t\t<integer>620</integer>\n\t\t<key>u1D79C</key>\n\t\t<integer>548</integer>\n\t\t<key>u1D79D</key>\n\t\t<integer>513</integer>\n\t\t<key>u1D79E</key>\n\t\t<integer>561</integer>\n\t\t<key>u1D79F</key>\n\t\t<integer>532</integer>\n\t\t<key>u1D7A0</key>\n\t\t<integer>458</integer>\n\t\t<key>u1D7A1</key>\n\t\t<integer>559</integer>\n\t\t<key>u1D7A2</key>\n\t\t<integer>504</integer>\n\t\t<key>u1D7A3</key>\n\t\t<integer>520</integer>\n\t\t<key>u1D7A4</key>\n\t\t<integer>465</integer>\n\t\t<key>u1D7A5</key>\n\t\t<integer>561</integer>\n\t\t<key>u1D7A6</key>\n\t\t<integer>536</integer>\n\t\t<key>u1D7A7</key>\n\t\t<integer>535</integer>\n\t\t<key>u1D7A8</key>\n\t\t<integer>548</integer>\n\t\t<key>u1D7A9</key>\n\t\t<integer>454</integer>\n\t\t<key>u1D7AA</key>\n\t\t<integer>439</integer>\n\t\t<key>u1D7AB</key>\n\t\t<integer>436</integer>\n\t\t<key>u1D7AC</key>\n\t\t<integer>362</integer>\n\t\t<key>u1D7AD</key>\n\t\t<integer>391</integer>\n\t\t<key>u1D7AE</key>\n\t\t<integer>352</integer>\n\t\t<key>u1D7AF</key>\n\t\t<integer>402</integer>\n\t\t<key>u1D7B0</key>\n\t\t<integer>366</integer>\n\t\t<key>u1D7B1</key>\n\t\t<integer>380</integer>\n\t\t<key>u1D7B2</key>\n\t\t<integer>262</integer>\n\t\t<key>u1D7B3</key>\n\t\t<integer>368</integer>\n\t\t<key>u1D7B4</key>\n\t\t<integer>387</integer>\n\t\t<key>u1D7B5</key>\n\t\t<integer>397</integer>\n\t\t<key>u1D7B6</key>\n\t\t<integer>362</integer>\n\t\t<key>u1D7B7</key>\n\t\t<integer>392</integer>\n\t\t<key>u1D7B8</key>\n\t\t<integer>371</integer>\n\t\t<key>u1D7B9</key>\n\t\t<integer>416</integer>\n\t\t<key>u1D7BA</key>\n\t\t<integer>380</integer>\n\t\t<key>u1D7BB</key>\n\t\t<integer>358</integer>\n\t\t<key>u1D7BC</key>\n\t\t<integer>407</integer>\n\t\t<key>u1D7BD</key>\n\t\t<integer>361</integer>\n\t\t<key>u1D7BE</key>\n\t\t<integer>375</integer>\n\t\t<key>u1D7BF</key>\n\t\t<integer>441</integer>\n\t\t<key>u1D7C0</key>\n\t\t<integer>387</integer>\n\t\t<key>u1D7C1</key>\n\t\t<integer>451</integer>\n\t\t<key>u1D7C2</key>\n\t\t<integer>478</integer>\n\t\t<key>u1D7C3</key>\n\t\t<integer>374</integer>\n\t\t<key>u1D7C4</key>\n\t\t<integer>334</integer>\n\t\t<key>u1D7C5</key>\n\t\t<integer>389</integer>\n\t\t<key>u1D7C6</key>\n\t\t<integer>423</integer>\n\t\t<key>u1D7C7</key>\n\t\t<integer>489</integer>\n\t\t<key>u1D7C8</key>\n\t\t<integer>372</integer>\n\t\t<key>u1D7C9</key>\n\t\t<integer>544</integer>\n\t\t<key>uni0237</key>\n\t\t<integer>150</integer>\n\t\t<key>uni02C8</key>\n\t\t<integer>139</integer>\n\t\t<key>uni02C9</key>\n\t\t<integer>166</integer>\n\t\t<key>uni02CA</key>\n\t\t<integer>206</integer>\n\t\t<key>uni02CB</key>\n\t\t<integer>136</integer>\n\t\t<key>uni02CC</key>\n\t\t<integer>139</integer>\n\t\t<key>uni02CD</key>\n\t\t<integer>167</integer>\n\t\t<key>uni02CE</key>\n\t\t<integer>137</integer>\n\t\t<key>uni02CF</key>\n\t\t<integer>196</integer>\n\t\t<key>uni02F3</key>\n\t\t<integer>166</integer>\n\t\t<key>uni02F7</key>\n\t\t<integer>166</integer>\n\t\t<key>uni0300</key>\n\t\t<integer>-259</integer>\n\t\t<key>uni0301</key>\n\t\t<integer>-259</integer>\n\t\t<key>uni0302</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0302.size1</key>\n\t\t<integer>280</integer>\n\t\t<key>uni0302.size2</key>\n\t\t<integer>489</integer>\n\t\t<key>uni0302.size3</key>\n\t\t<integer>730</integer>\n\t\t<key>uni0302.size4</key>\n\t\t<integer>943</integer>\n\t\t<key>uni0302.size5</key>\n\t\t<integer>1164</integer>\n\t\t<key>uni0303</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0303.size1</key>\n\t\t<integer>280</integer>\n\t\t<key>uni0303.size2</key>\n\t\t<integer>489</integer>\n\t\t<key>uni0303.size3</key>\n\t\t<integer>730</integer>\n\t\t<key>uni0303.size4</key>\n\t\t<integer>943</integer>\n\t\t<key>uni0303.size5</key>\n\t\t<integer>1164</integer>\n\t\t<key>uni0304</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0305</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0305.size1</key>\n\t\t<integer>500</integer>\n\t\t<key>uni0305.size2</key>\n\t\t<integer>750</integer>\n\t\t<key>uni0305.size3</key>\n\t\t<integer>1000</integer>\n\t\t<key>uni0305.size4</key>\n\t\t<integer>1250</integer>\n\t\t<key>uni0305.size5</key>\n\t\t<integer>1500</integer>\n\t\t<key>uni0306</key>\n\t\t<integer>-232</integer>\n\t\t<key>uni0307</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0308</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0309</key>\n\t\t<integer>-212</integer>\n\t\t<key>uni030A</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni030B</key>\n\t\t<integer>-212</integer>\n\t\t<key>uni030C</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni030C.size1</key>\n\t\t<integer>280</integer>\n\t\t<key>uni030C.size2</key>\n\t\t<integer>489</integer>\n\t\t<key>uni030C.size3</key>\n\t\t<integer>730</integer>\n\t\t<key>uni030C.size4</key>\n\t\t<integer>943</integer>\n\t\t<key>uni030C.size5</key>\n\t\t<integer>1164</integer>\n\t\t<key>uni030D</key>\n\t\t<integer>-222</integer>\n\t\t<key>uni030E</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni030F</key>\n\t\t<integer>-212</integer>\n\t\t<key>uni0310</key>\n\t\t<integer>-232</integer>\n\t\t<key>uni0311</key>\n\t\t<integer>-232</integer>\n\t\t<key>uni0312</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0313</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0314</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0315</key>\n\t\t<integer>-16</integer>\n\t\t<key>uni0316</key>\n\t\t<integer>-239</integer>\n\t\t<key>uni0317</key>\n\t\t<integer>-259</integer>\n\t\t<key>uni0318</key>\n\t\t<integer>-304</integer>\n\t\t<key>uni0319</key>\n\t\t<integer>-174</integer>\n\t\t<key>uni031A</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni031B</key>\n\t\t<integer>4</integer>\n\t\t<key>uni031C</key>\n\t\t<integer>-296</integer>\n\t\t<key>uni031D</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni031E</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni031F</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0320</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0321</key>\n\t\t<integer>-117</integer>\n\t\t<key>uni0322</key>\n\t\t<integer>64</integer>\n\t\t<key>uni0323</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0324</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0325</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0326</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0327</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0328</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0329</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni032A</key>\n\t\t<integer>-229</integer>\n\t\t<key>uni032B</key>\n\t\t<integer>-228</integer>\n\t\t<key>uni032C</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni032D</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni032E</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni032F</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0330</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0330.size1</key>\n\t\t<integer>280</integer>\n\t\t<key>uni0330.size2</key>\n\t\t<integer>489</integer>\n\t\t<key>uni0330.size3</key>\n\t\t<integer>730</integer>\n\t\t<key>uni0330.size4</key>\n\t\t<integer>943</integer>\n\t\t<key>uni0330.size5</key>\n\t\t<integer>1164</integer>\n\t\t<key>uni0331</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0332</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0332.size1</key>\n\t\t<integer>500</integer>\n\t\t<key>uni0332.size2</key>\n\t\t<integer>750</integer>\n\t\t<key>uni0332.size3</key>\n\t\t<integer>1000</integer>\n\t\t<key>uni0332.size4</key>\n\t\t<integer>1250</integer>\n\t\t<key>uni0332.size5</key>\n\t\t<integer>1500</integer>\n\t\t<key>uni0333</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0334</key>\n\t\t<integer>-236</integer>\n\t\t<key>uni0335</key>\n\t\t<integer>-231</integer>\n\t\t<key>uni0336</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0337</key>\n\t\t<integer>-210</integer>\n\t\t<key>uni0338</key>\n\t\t<integer>-174</integer>\n\t\t<key>uni0338.size1</key>\n\t\t<integer>-339</integer>\n\t\t<key>uni0338.size2</key>\n\t\t<integer>-339</integer>\n\t\t<key>uni0338.size3</key>\n\t\t<integer>-340</integer>\n\t\t<key>uni0338.size4</key>\n\t\t<integer>-330</integer>\n\t\t<key>uni0338.size5</key>\n\t\t<integer>-343</integer>\n\t\t<key>uni0338.size6</key>\n\t\t<integer>-486</integer>\n\t\t<key>uni0339</key>\n\t\t<integer>-216</integer>\n\t\t<key>uni033A</key>\n\t\t<integer>-229</integer>\n\t\t<key>uni033B</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni033C</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni033D</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni033E</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni033F</key>\n\t\t<integer>-230</integer>\n\t\t<key>uni0346</key>\n\t\t<integer>-209</integer>\n\t\t<key>uni034C</key>\n\t\t<integer>-221</integer>\n\t\t<key>uni034D</key>\n\t\t<integer>239</integer>\n\t\t<key>uni0359</key>\n\t\t<integer>-222</integer>\n\t\t<key>uni035C</key>\n\t\t<integer>-39</integer>\n\t\t<key>uni0360</key>\n\t\t<integer>-15</integer>\n\t\t<key>uni0361</key>\n\t\t<integer>-39</integer>\n\t\t<key>uni0362</key>\n\t\t<integer>-20</integer>\n\t\t<key>uni0391</key>\n\t\t<integer>361</integer>\n\t\t<key>uni0392</key>\n\t\t<integer>305</integer>\n\t\t<key>uni0393</key>\n\t\t<integer>294</integer>\n\t\t<key>uni0394</key>\n\t\t<integer>362</integer>\n\t\t<key>uni0395</key>\n\t\t<integer>304</integer>\n\t\t<key>uni0396</key>\n\t\t<integer>304</integer>\n\t\t<key>uni0397</key>\n\t\t<integer>360</integer>\n\t\t<key>uni0398</key>\n\t\t<integer>361</integer>\n\t\t<key>uni0399</key>\n\t\t<integer>166</integer>\n\t\t<key>uni039A</key>\n\t\t<integer>370</integer>\n\t\t<key>uni039B</key>\n\t\t<integer>349</integer>\n\t\t<key>uni039C</key>\n\t\t<integer>438</integer>\n\t\t<key>uni039D</key>\n\t\t<integer>360</integer>\n\t\t<key>uni039E</key>\n\t\t<integer>322</integer>\n\t\t<key>uni039F</key>\n\t\t<integer>361</integer>\n\t\t<key>uni03A0</key>\n\t\t<integer>360</integer>\n\t\t<key>uni03A1</key>\n\t\t<integer>279</integer>\n\t\t<key>uni03A3</key>\n\t\t<integer>315</integer>\n\t\t<key>uni03A4</key>\n\t\t<integer>305</integer>\n\t\t<key>uni03A5</key>\n\t\t<integer>390</integer>\n\t\t<key>uni03A6</key>\n\t\t<integer>382</integer>\n\t\t<key>uni03A7</key>\n\t\t<integer>401</integer>\n\t\t<key>uni03A8</key>\n\t\t<integer>373</integer>\n\t\t<key>uni03A9</key>\n\t\t<integer>372</integer>\n\t\t<key>uni03B1</key>\n\t\t<integer>279</integer>\n\t\t<key>uni03B2</key>\n\t\t<integer>260</integer>\n\t\t<key>uni03B3</key>\n\t\t<integer>227</integer>\n\t\t<key>uni03B4</key>\n\t\t<integer>250</integer>\n\t\t<key>uni03B5</key>\n\t\t<integer>216</integer>\n\t\t<key>uni03B6</key>\n\t\t<integer>221</integer>\n\t\t<key>uni03B7</key>\n\t\t<integer>231</integer>\n\t\t<key>uni03B8</key>\n\t\t<integer>248</integer>\n\t\t<key>uni03B9</key>\n\t\t<integer>144</integer>\n\t\t<key>uni03BA</key>\n\t\t<integer>255</integer>\n\t\t<key>uni03BB</key>\n\t\t<integer>136</integer>\n\t\t<key>uni03BC</key>\n\t\t<integer>254</integer>\n\t\t<key>uni03BD</key>\n\t\t<integer>232</integer>\n\t\t<key>uni03BE</key>\n\t\t<integer>221</integer>\n\t\t<key>uni03BF</key>\n\t\t<integer>254</integer>\n\t\t<key>uni03C0</key>\n\t\t<integer>246</integer>\n\t\t<key>uni03C1</key>\n\t\t<integer>260</integer>\n\t\t<key>uni03C2</key>\n\t\t<integer>234</integer>\n\t\t<key>uni03C3</key>\n\t\t<integer>274</integer>\n\t\t<key>uni03C4</key>\n\t\t<integer>240</integer>\n\t\t<key>uni03C5</key>\n\t\t<integer>255</integer>\n\t\t<key>uni03C6</key>\n\t\t<integer>311</integer>\n\t\t<key>uni03C7</key>\n\t\t<integer>272</integer>\n\t\t<key>uni03C8</key>\n\t\t<integer>352</integer>\n\t\t<key>uni03C9</key>\n\t\t<integer>312</integer>\n\t\t<key>uni03D0</key>\n\t\t<integer>232</integer>\n\t\t<key>uni03D1</key>\n\t\t<integer>242</integer>\n\t\t<key>uni03D2</key>\n\t\t<integer>398</integer>\n\t\t<key>uni03D5</key>\n\t\t<integer>311</integer>\n\t\t<key>uni03D6</key>\n\t\t<integer>406</integer>\n\t\t<key>uni03D8</key>\n\t\t<integer>361</integer>\n\t\t<key>uni03D9</key>\n\t\t<integer>250</integer>\n\t\t<key>uni03DA</key>\n\t\t<integer>441</integer>\n\t\t<key>uni03DB</key>\n\t\t<integer>236</integer>\n\t\t<key>uni03DC</key>\n\t\t<integer>278</integer>\n\t\t<key>uni03DD</key>\n\t\t<integer>258</integer>\n\t\t<key>uni03F0</key>\n\t\t<integer>278</integer>\n\t\t<key>uni03F1</key>\n\t\t<integer>250</integer>\n\t\t<key>uni03F4</key>\n\t\t<integer>361</integer>\n\t\t<key>uni03F5</key>\n\t\t<integer>216</integer>\n\t\t<key>uni03F6</key>\n\t\t<integer>223</integer>\n\t\t<key>uni203E</key>\n\t\t<integer>250</integer>\n\t\t<key>uni203E.size1</key>\n\t\t<integer>500</integer>\n\t\t<key>uni203E.size2</key>\n\t\t<integer>750</integer>\n\t\t<key>uni203E.size3</key>\n\t\t<integer>1000</integer>\n\t\t<key>uni203E.size4</key>\n\t\t<integer>1250</integer>\n\t\t<key>uni203E.size5</key>\n\t\t<integer>1500</integer>\n\t\t<key>uni20D0</key>\n\t\t<integer>218</integer>\n\t\t<key>uni20D1</key>\n\t\t<integer>218</integer>\n\t\t<key>uni20D2</key>\n\t\t<integer>-217</integer>\n\t\t<key>uni20D2.size1</key>\n\t\t<integer>-217</integer>\n\t\t<key>uni20D2.size2</key>\n\t\t<integer>-217</integer>\n\t\t<key>uni20D2.size3</key>\n\t\t<integer>-217</integer>\n\t\t<key>uni20D2.size4</key>\n\t\t<integer>-217</integer>\n\t\t<key>uni20D2.size5</key>\n\t\t<integer>-217</integer>\n\t\t<key>uni20D2.size6</key>\n\t\t<integer>-217</integer>\n\t\t<key>uni20D6</key>\n\t\t<integer>218</integer>\n\t\t<key>uni20D7</key>\n\t\t<integer>218</integer>\n\t\t<key>uni20DB</key>\n\t\t<integer>-214</integer>\n\t\t<key>uni20DC</key>\n\t\t<integer>-252</integer>\n\t\t<key>uni20DD</key>\n\t\t<integer>-250</integer>\n\t\t<key>uni20DE</key>\n\t\t<integer>-250</integer>\n\t\t<key>uni20DF</key>\n\t\t<integer>-248</integer>\n\t\t<key>uni20E1</key>\n\t\t<integer>239</integer>\n\t\t<key>uni20E4</key>\n\t\t<integer>-249</integer>\n\t\t<key>uni20E5</key>\n\t\t<integer>-235</integer>\n\t\t<key>uni20E6</key>\n\t\t<integer>-218</integer>\n\t\t<key>uni20E7</key>\n\t\t<integer>-242</integer>\n\t\t<key>uni20E8</key>\n\t\t<integer>-214</integer>\n\t\t<key>uni20E9</key>\n\t\t<integer>-214</integer>\n\t\t<key>uni20EA</key>\n\t\t<integer>-270</integer>\n\t\t<key>uni20EB</key>\n\t\t<integer>-128</integer>\n\t\t<key>uni20EC</key>\n\t\t<integer>218</integer>\n\t\t<key>uni20ED</key>\n\t\t<integer>218</integer>\n\t\t<key>uni20EE</key>\n\t\t<integer>218</integer>\n\t\t<key>uni20EF</key>\n\t\t<integer>218</integer>\n\t\t<key>uni20F0</key>\n\t\t<integer>-222</integer>\n\t\t<key>uni2102.bi</key>\n\t\t<integer>458</integer>\n\t\t<key>uni2102.it</key>\n\t\t<integer>468</integer>\n\t\t<key>uni210A</key>\n\t\t<integer>491</integer>\n\t\t<key>uni210B</key>\n\t\t<integer>700</integer>\n\t\t<key>uni210B.cal</key>\n\t\t<integer>509</integer>\n\t\t<key>uni210D.bi</key>\n\t\t<integer>502</integer>\n\t\t<key>uni210D.it</key>\n\t\t<integer>492</integer>\n\t\t<key>uni210E</key>\n\t\t<integer>246</integer>\n\t\t<key>uni210F</key>\n\t\t<integer>246</integer>\n\t\t<key>uni2110</key>\n\t\t<integer>647</integer>\n\t\t<key>uni2110.cal</key>\n\t\t<integer>411</integer>\n\t\t<key>uni2112</key>\n\t\t<integer>850</integer>\n\t\t<key>uni2112.cal</key>\n\t\t<integer>476</integer>\n\t\t<key>uni2113</key>\n\t\t<integer>506</integer>\n\t\t<key>uni2115.bi</key>\n\t\t<integer>497</integer>\n\t\t<key>uni2115.it</key>\n\t\t<integer>490</integer>\n\t\t<key>uni2119.bi</key>\n\t\t<integer>454</integer>\n\t\t<key>uni2119.it</key>\n\t\t<integer>451</integer>\n\t\t<key>uni211A.bi</key>\n\t\t<integer>458</integer>\n\t\t<key>uni211A.it</key>\n\t\t<integer>474</integer>\n\t\t<key>uni211B</key>\n\t\t<integer>770</integer>\n\t\t<key>uni211B.cal</key>\n\t\t<integer>427</integer>\n\t\t<key>uni211D.bi</key>\n\t\t<integer>458</integer>\n\t\t<key>uni211D.it</key>\n\t\t<integer>451</integer>\n\t\t<key>uni2124.bi</key>\n\t\t<integer>554</integer>\n\t\t<key>uni2124.it</key>\n\t\t<integer>478</integer>\n\t\t<key>uni212C</key>\n\t\t<integer>808</integer>\n\t\t<key>uni212C.cal</key>\n\t\t<integer>512</integer>\n\t\t<key>uni212F</key>\n\t\t<integer>463</integer>\n\t\t<key>uni2130</key>\n\t\t<integer>633</integer>\n\t\t<key>uni2130.cal</key>\n\t\t<integer>446</integer>\n\t\t<key>uni2131</key>\n\t\t<integer>658</integer>\n\t\t<key>uni2131.cal</key>\n\t\t<integer>410</integer>\n\t\t<key>uni2133</key>\n\t\t<integer>867</integer>\n\t\t<key>uni2133.cal</key>\n\t\t<integer>713</integer>\n\t\t<key>uni2145</key>\n\t\t<integer>460</integer>\n\t\t<key>uni2146</key>\n\t\t<integer>437</integer>\n\t\t<key>uni2147</key>\n\t\t<integer>362</integer>\n\t\t<key>uni2148</key>\n\t\t<integer>286</integer>\n\t\t<key>uni2148.dtls</key>\n\t\t<integer>206</integer>\n\t\t<key>uni2149</key>\n\t\t<integer>313</integer>\n\t\t<key>uni2149.dtls</key>\n\t\t<integer>248</integer>\n\t\t<key>uni2202</key>\n\t\t<integer>232</integer>\n\t\t<key>uni2202.rtlm</key>\n\t\t<integer>201</integer>\n\t\t<key>uni2202.ss</key>\n\t\t<integer>349</integer>\n\t\t<key>uni220F</key>\n\t\t<integer>500</integer>\n\t\t<key>uni220F.display</key>\n\t\t<integer>678</integer>\n\t\t<key>uni2210</key>\n\t\t<integer>500</integer>\n\t\t<key>uni2210.display</key>\n\t\t<integer>678</integer>\n\t\t<key>uni2211</key>\n\t\t<integer>457</integer>\n\t\t<key>uni2211.display</key>\n\t\t<integer>646</integer>\n\t\t<key>uni22C5</key>\n\t\t<integer>143</integer>\n\t\t<key>uni23B4.size1</key>\n\t\t<integer>532</integer>\n\t\t<key>uni23B4.size2</key>\n\t\t<integer>803</integer>\n\t\t<key>uni23B4.size3</key>\n\t\t<integer>1074</integer>\n\t\t<key>uni23B4.size4</key>\n\t\t<integer>1346</integer>\n\t\t<key>uni23B4.size5</key>\n\t\t<integer>1618</integer>\n\t\t<key>uni23B5.size1</key>\n\t\t<integer>530</integer>\n\t\t<key>uni23B5.size2</key>\n\t\t<integer>803</integer>\n\t\t<key>uni23B5.size3</key>\n\t\t<integer>1074</integer>\n\t\t<key>uni23B5.size4</key>\n\t\t<integer>1346</integer>\n\t\t<key>uni23B5.size5</key>\n\t\t<integer>1618</integer>\n\t\t<key>uni23DC.size1</key>\n\t\t<integer>463</integer>\n\t\t<key>uni23DC.size2</key>\n\t\t<integer>730</integer>\n\t\t<key>uni23DC.size3</key>\n\t\t<integer>943</integer>\n\t\t<key>uni23DC.size4</key>\n\t\t<integer>1164</integer>\n\t\t<key>uni23DC.size5</key>\n\t\t<integer>1618</integer>\n\t\t<key>uni23DD.size1</key>\n\t\t<integer>463</integer>\n\t\t<key>uni23DD.size2</key>\n\t\t<integer>730</integer>\n\t\t<key>uni23DD.size3</key>\n\t\t<integer>943</integer>\n\t\t<key>uni23DD.size4</key>\n\t\t<integer>1164</integer>\n\t\t<key>uni23DD.size5</key>\n\t\t<integer>1618</integer>\n\t\t<key>uni23DE.size1</key>\n\t\t<integer>462</integer>\n\t\t<key>uni23DE.size2</key>\n\t\t<integer>730</integer>\n\t\t<key>uni23DE.size3</key>\n\t\t<integer>943</integer>\n\t\t<key>uni23DE.size4</key>\n\t\t<integer>1164</integer>\n\t\t<key>uni23DE.size5</key>\n\t\t<integer>1619</integer>\n\t\t<key>uni23DF.size1</key>\n\t\t<integer>462</integer>\n\t\t<key>uni23DF.size2</key>\n\t\t<integer>730</integer>\n\t\t<key>uni23DF.size3</key>\n\t\t<integer>943</integer>\n\t\t<key>uni23DF.size4</key>\n\t\t<integer>1164</integer>\n\t\t<key>uni23DF.size5</key>\n\t\t<integer>1619</integer>\n\t\t<key>uni23E0.size1</key>\n\t\t<integer>730</integer>\n\t\t<key>uni23E0.size2</key>\n\t\t<integer>943</integer>\n\t\t<key>uni23E0.size3</key>\n\t\t<integer>1156</integer>\n\t\t<key>uni23E0.size4</key>\n\t\t<integer>1369</integer>\n\t\t<key>uni23E0.size5</key>\n\t\t<integer>1582</integer>\n\t\t<key>uni23E1.size1</key>\n\t\t<integer>730</integer>\n\t\t<key>uni23E1.size2</key>\n\t\t<integer>943</integer>\n\t\t<key>uni23E1.size3</key>\n\t\t<integer>1156</integer>\n\t\t<key>uni23E1.size4</key>\n\t\t<integer>1369</integer>\n\t\t<key>uni23E1.size5</key>\n\t\t<integer>1582</integer>\n\t\t<key>v</key>\n\t\t<integer>276</integer>\n\t\t<key>w</key>\n\t\t<integer>358</integer>\n\t\t<key>x</key>\n\t\t<integer>254</integer>\n\t\t<key>y</key>\n\t\t<integer>284</integer>\n\t\t<key>z</key>\n\t\t<integer>246</integer>\n\t</dict>\n\t<key>constants</key>\n\t<dict>\n\t\t<key>AccentBaseHeight</key>\n\t\t<integer>450</integer>\n\t\t<key>AxisHeight</key>\n\t\t<integer>250</integer>\n\t\t<key>DelimitedSubFormulaMinHeight</key>\n\t\t<integer>1500</integer>\n\t\t<key>DisplayOperatorMinHeight</key>\n\t\t<integer>1450</integer>\n\t\t<key>FlattenedAccentBaseHeight</key>\n\t\t<integer>662</integer>\n\t\t<key>FractionDenomDisplayStyleGapMin</key>\n\t\t<integer>198</integer>\n\t\t<key>FractionDenominatorDisplayStyleShiftDown</key>\n\t\t<integer>700</integer>\n\t\t<key>FractionDenominatorGapMin</key>\n\t\t<integer>66</integer>\n\t\t<key>FractionDenominatorShiftDown</key>\n\t\t<integer>480</integer>\n\t\t<key>FractionNumDisplayStyleGapMin</key>\n\t\t<integer>198</integer>\n\t\t<key>FractionNumeratorDisplayStyleShiftUp</key>\n\t\t<integer>580</integer>\n\t\t<key>FractionNumeratorGapMin</key>\n\t\t<integer>66</integer>\n\t\t<key>FractionNumeratorShiftUp</key>\n\t\t<integer>480</integer>\n\t\t<key>FractionRuleThickness</key>\n\t\t<integer>66</integer>\n\t\t<key>LowerLimitBaselineDropMin</key>\n\t\t<integer>600</integer>\n\t\t<key>LowerLimitGapMin</key>\n\t\t<integer>150</integer>\n\t\t<key>MathLeading</key>\n\t\t<integer>150</integer>\n\t\t<key>MinConnectorOverlap</key>\n\t\t<integer>50</integer>\n\t\t<key>OverbarExtraAscender</key>\n\t\t<integer>66</integer>\n\t\t<key>OverbarRuleThickness</key>\n\t\t<integer>66</integer>\n\t\t<key>OverbarVerticalGap</key>\n\t\t<integer>198</integer>\n\t\t<key>RadicalDegreeBottomRaisePercent</key>\n\t\t<integer>70</integer>\n\t\t<key>RadicalDisplayStyleVerticalGap</key>\n\t\t<integer>186</integer>\n\t\t<key>RadicalExtraAscender</key>\n\t\t<integer>66</integer>\n\t\t<key>RadicalKernAfterDegree</key>\n\t\t<integer>-555</integer>\n\t\t<key>RadicalKernBeforeDegree</key>\n\t\t<integer>277</integer>\n\t\t<key>RadicalRuleThickness</key>\n\t\t<integer>66</integer>\n\t\t<key>RadicalVerticalGap</key>\n\t\t<integer>82</integer>\n\t\t<key>ScriptPercentScaleDown</key>\n\t\t<integer>75</integer>\n\t\t<key>ScriptScriptPercentScaleDown</key>\n\t\t<integer>60</integer>\n\t\t<key>SkewedFractionHorizontalGap</key>\n\t\t<integer>300</integer>\n\t\t<key>SkewedFractionVerticalGap</key>\n\t\t<integer>66</integer>\n\t\t<key>SpaceAfterScript</key>\n\t\t<integer>41</integer>\n\t\t<key>StackBottomDisplayStyleShiftDown</key>\n\t\t<integer>900</integer>\n\t\t<key>StackBottomShiftDown</key>\n\t\t<integer>800</integer>\n\t\t<key>StackDisplayStyleGapMin</key>\n\t\t<integer>462</integer>\n\t\t<key>StackGapMin</key>\n\t\t<integer>198</integer>\n\t\t<key>StackTopDisplayStyleShiftUp</key>\n\t\t<integer>580</integer>\n\t\t<key>StackTopShiftUp</key>\n\t\t<integer>480</integer>\n\t\t<key>StretchStackBottomShiftDown</key>\n\t\t<integer>600</integer>\n\t\t<key>StretchStackGapAboveMin</key>\n\t\t<integer>150</integer>\n\t\t<key>StretchStackGapBelowMin</key>\n\t\t<integer>150</integer>\n\t\t<key>StretchStackTopShiftUp</key>\n\t\t<integer>300</integer>\n\t\t<key>SubSuperscriptGapMin</key>\n\t\t<integer>264</integer>\n\t\t<key>SubscriptBaselineDropMin</key>\n\t\t<integer>50</integer>\n\t\t<key>SubscriptShiftDown</key>\n\t\t<integer>250</integer>\n\t\t<key>SubscriptTopMax</key>\n\t\t<integer>400</integer>\n\t\t<key>SuperscriptBaselineDropMax</key>\n\t\t<integer>375</integer>\n\t\t<key>SuperscriptBottomMaxWithSubscript</key>\n\t\t<integer>400</integer>\n\t\t<key>SuperscriptBottomMin</key>\n\t\t<integer>125</integer>\n\t\t<key>SuperscriptShiftUp</key>\n\t\t<integer>400</integer>\n\t\t<key>SuperscriptShiftUpCramped</key>\n\t\t<integer>275</integer>\n\t\t<key>UnderbarExtraDescender</key>\n\t\t<integer>66</integer>\n\t\t<key>UnderbarRuleThickness</key>\n\t\t<integer>66</integer>\n\t\t<key>UnderbarVerticalGap</key>\n\t\t<integer>198</integer>\n\t\t<key>UpperLimitBaselineRiseMin</key>\n\t\t<integer>300</integer>\n\t\t<key>UpperLimitGapMin</key>\n\t\t<integer>150</integer>\n\t</dict>\n\t<key>h_variants</key>\n\t<dict>\n\t\t<key>uni0302</key>\n\t\t<array>\n\t\t\t<string>uni0302</string>\n\t\t\t<string>uni0302.size1</string>\n\t\t\t<string>uni0302.size2</string>\n\t\t\t<string>uni0302.size3</string>\n\t\t\t<string>uni0302.size4</string>\n\t\t\t<string>uni0302.size5</string>\n\t\t</array>\n\t\t<key>uni0303</key>\n\t\t<array>\n\t\t\t<string>uni0303</string>\n\t\t\t<string>uni0303.size1</string>\n\t\t\t<string>uni0303.size2</string>\n\t\t\t<string>uni0303.size3</string>\n\t\t\t<string>uni0303.size4</string>\n\t\t\t<string>uni0303.size5</string>\n\t\t</array>\n\t\t<key>uni0305</key>\n\t\t<array>\n\t\t\t<string>uni0305</string>\n\t\t\t<string>uni0305.size1</string>\n\t\t\t<string>uni0305.size2</string>\n\t\t\t<string>uni0305.size3</string>\n\t\t\t<string>uni0305.size4</string>\n\t\t\t<string>uni0305.size5</string>\n\t\t</array>\n\t\t<key>uni030C</key>\n\t\t<array>\n\t\t\t<string>uni030C</string>\n\t\t\t<string>uni030C.size1</string>\n\t\t\t<string>uni030C.size2</string>\n\t\t\t<string>uni030C.size3</string>\n\t\t\t<string>uni030C.size4</string>\n\t\t\t<string>uni030C.size5</string>\n\t\t</array>\n\t\t<key>uni0330</key>\n\t\t<array>\n\t\t\t<string>uni0330</string>\n\t\t\t<string>uni0330.size1</string>\n\t\t\t<string>uni0330.size2</string>\n\t\t\t<string>uni0330.size3</string>\n\t\t\t<string>uni0330.size4</string>\n\t\t\t<string>uni0330.size5</string>\n\t\t</array>\n\t\t<key>uni0332</key>\n\t\t<array>\n\t\t\t<string>uni0332</string>\n\t\t\t<string>uni0332.size1</string>\n\t\t\t<string>uni0332.size2</string>\n\t\t\t<string>uni0332.size3</string>\n\t\t\t<string>uni0332.size4</string>\n\t\t\t<string>uni0332.size5</string>\n\t\t</array>\n\t\t<key>uni034D</key>\n\t\t<array>\n\t\t\t<string>uni034D</string>\n\t\t</array>\n\t\t<key>uni203E</key>\n\t\t<array>\n\t\t\t<string>uni203E</string>\n\t\t\t<string>uni203E.size1</string>\n\t\t\t<string>uni203E.size2</string>\n\t\t\t<string>uni203E.size3</string>\n\t\t\t<string>uni203E.size4</string>\n\t\t\t<string>uni203E.size5</string>\n\t\t</array>\n\t\t<key>uni20D0</key>\n\t\t<array>\n\t\t\t<string>uni20D0</string>\n\t\t</array>\n\t\t<key>uni20D1</key>\n\t\t<array>\n\t\t\t<string>uni20D1</string>\n\t\t</array>\n\t\t<key>uni20D6</key>\n\t\t<array>\n\t\t\t<string>uni20D6</string>\n\t\t</array>\n\t\t<key>uni20D7</key>\n\t\t<array>\n\t\t\t<string>uni20D7</string>\n\t\t</array>\n\t\t<key>uni20E1</key>\n\t\t<array>\n\t\t\t<string>uni20E1</string>\n\t\t</array>\n\t\t<key>uni20E9</key>\n\t\t<array>\n\t\t\t<string>uni20E9</string>\n\t\t</array>\n\t\t<key>uni20EC</key>\n\t\t<array>\n\t\t\t<string>uni20EC</string>\n\t\t</array>\n\t\t<key>uni20ED</key>\n\t\t<array>\n\t\t\t<string>uni20ED</string>\n\t\t</array>\n\t\t<key>uni20EE</key>\n\t\t<array>\n\t\t\t<string>uni20EE</string>\n\t\t</array>\n\t\t<key>uni20EF</key>\n\t\t<array>\n\t\t\t<string>uni20EF</string>\n\t\t</array>\n\t\t<key>uni2190</key>\n\t\t<array/>\n\t\t<key>uni2192</key>\n\t\t<array/>\n\t\t<key>uni2194</key>\n\t\t<array/>\n\t\t<key>uni21A4</key>\n\t\t<array/>\n\t\t<key>uni21A6</key>\n\t\t<array/>\n\t\t<key>uni21BC</key>\n\t\t<array/>\n\t\t<key>uni21BD</key>\n\t\t<array/>\n\t\t<key>uni21C0</key>\n\t\t<array/>\n\t\t<key>uni21D0</key>\n\t\t<array/>\n\t\t<key>uni21D2</key>\n\t\t<array/>\n\t\t<key>uni21D4</key>\n\t\t<array/>\n\t\t<key>uni21DA</key>\n\t\t<array/>\n\t\t<key>uni21DB</key>\n\t\t<array/>\n\t\t<key>uni23B4</key>\n\t\t<array>\n\t\t\t<string>uni23B4</string>\n\t\t\t<string>uni23B4.size1</string>\n\t\t\t<string>uni23B4.size2</string>\n\t\t\t<string>uni23B4.size3</string>\n\t\t\t<string>uni23B4.size4</string>\n\t\t\t<string>uni23B4.size5</string>\n\t\t</array>\n\t\t<key>uni23B5</key>\n\t\t<array>\n\t\t\t<string>uni23B5</string>\n\t\t\t<string>uni23B5.size1</string>\n\t\t\t<string>uni23B5.size2</string>\n\t\t\t<string>uni23B5.size3</string>\n\t\t\t<string>uni23B5.size4</string>\n\t\t\t<string>uni23B5.size5</string>\n\t\t</array>\n\t\t<key>uni23DC</key>\n\t\t<array>\n\t\t\t<string>uni23DC</string>\n\t\t\t<string>uni23DC.size1</string>\n\t\t\t<string>uni23DC.size2</string>\n\t\t\t<string>uni23DC.size3</string>\n\t\t\t<string>uni23DC.size4</string>\n\t\t\t<string>uni23DC.size5</string>\n\t\t</array>\n\t\t<key>uni23DD</key>\n\t\t<array>\n\t\t\t<string>uni23DD</string>\n\t\t\t<string>uni23DD.size1</string>\n\t\t\t<string>uni23DD.size2</string>\n\t\t\t<string>uni23DD.size3</string>\n\t\t\t<string>uni23DD.size4</string>\n\t\t\t<string>uni23DD.size5</string>\n\t\t</array>\n\t\t<key>uni23DE</key>\n\t\t<array>\n\t\t\t<string>uni23DE</string>\n\t\t\t<string>uni23DE.size1</string>\n\t\t\t<string>uni23DE.size2</string>\n\t\t\t<string>uni23DE.size3</string>\n\t\t\t<string>uni23DE.size4</string>\n\t\t\t<string>uni23DE.size5</string>\n\t\t</array>\n\t\t<key>uni23DF</key>\n\t\t<array>\n\t\t\t<string>uni23DF</string>\n\t\t\t<string>uni23DF.size1</string>\n\t\t\t<string>uni23DF.size2</string>\n\t\t\t<string>uni23DF.size3</string>\n\t\t\t<string>uni23DF.size4</string>\n\t\t\t<string>uni23DF.size5</string>\n\t\t</array>\n\t\t<key>uni23E0</key>\n\t\t<array>\n\t\t\t<string>uni23E0</string>\n\t\t\t<string>uni23E0.size1</string>\n\t\t\t<string>uni23E0.size2</string>\n\t\t\t<string>uni23E0.size3</string>\n\t\t\t<string>uni23E0.size4</string>\n\t\t\t<string>uni23E0.size5</string>\n\t\t</array>\n\t\t<key>uni23E1</key>\n\t\t<array>\n\t\t\t<string>uni23E1</string>\n\t\t\t<string>uni23E1.size1</string>\n\t\t\t<string>uni23E1.size2</string>\n\t\t\t<string>uni23E1.size3</string>\n\t\t\t<string>uni23E1.size4</string>\n\t\t\t<string>uni23E1.size5</string>\n\t\t</array>\n\t\t<key>uni2B45</key>\n\t\t<array/>\n\t\t<key>uni2B46</key>\n\t\t<array/>\n\t</dict>\n\t<key>italic</key>\n\t<dict>\n\t\t<key>f</key>\n\t\t<integer>100</integer>\n\t\t<key>r</key>\n\t\t<integer>60</integer>\n\t\t<key>t</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D41F</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D42B</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D42D</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D431</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D432</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D433</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D435</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D436</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D437</key>\n\t\t<integer>15</integer>\n\t\t<key>u1D438</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D439</key>\n\t\t<integer>145</integer>\n\t\t<key>u1D43A</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D43B</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D43C</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D43D</key>\n\t\t<integer>120</integer>\n\t\t<key>u1D43E</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D440</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D441</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D442</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D443</key>\n\t\t<integer>150</integer>\n\t\t<key>u1D446</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D447</key>\n\t\t<integer>160</integer>\n\t\t<key>u1D448</key>\n\t\t<integer>110</integer>\n\t\t<key>u1D449</key>\n\t\t<integer>225</integer>\n\t\t<key>u1D44A</key>\n\t\t<integer>225</integer>\n\t\t<key>u1D44B</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D44C</key>\n\t\t<integer>200</integer>\n\t\t<key>u1D44D</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D450</key>\n\t\t<integer>50</integer>\n\t\t<key>u1D451</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D453</key>\n\t\t<integer>120</integer>\n\t\t<key>u1D454</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D457</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D459</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D45E</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D469</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D46A</key>\n\t\t<integer>84</integer>\n\t\t<key>u1D46B</key>\n\t\t<integer>68</integer>\n\t\t<key>u1D46C</key>\n\t\t<integer>62</integer>\n\t\t<key>u1D46D</key>\n\t\t<integer>155</integer>\n\t\t<key>u1D46E</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D46F</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D470</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D471</key>\n\t\t<integer>128</integer>\n\t\t<key>u1D472</key>\n\t\t<integer>84</integer>\n\t\t<key>u1D474</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D475</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D476</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D477</key>\n\t\t<integer>161</integer>\n\t\t<key>u1D479</key>\n\t\t<integer>25</integer>\n\t\t<key>u1D47A</key>\n\t\t<integer>73</integer>\n\t\t<key>u1D47B</key>\n\t\t<integer>172</integer>\n\t\t<key>u1D47C</key>\n\t\t<integer>117</integer>\n\t\t<key>u1D47D</key>\n\t\t<integer>244</integer>\n\t\t<key>u1D47E</key>\n\t\t<integer>244</integer>\n\t\t<key>u1D47F</key>\n\t\t<integer>62</integer>\n\t\t<key>u1D480</key>\n\t\t<integer>216</integer>\n\t\t<key>u1D481</key>\n\t\t<integer>73</integer>\n\t\t<key>u1D484</key>\n\t\t<integer>50</integer>\n\t\t<key>u1D485</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D487</key>\n\t\t<integer>120</integer>\n\t\t<key>u1D48B</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D492</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D49C</key>\n\t\t<integer>125</integer>\n\t\t<key>u1D49E</key>\n\t\t<integer>145</integer>\n\t\t<key>u1D49E.cal</key>\n\t\t<integer>62</integer>\n\t\t<key>u1D49F</key>\n\t\t<integer>125</integer>\n\t\t<key>u1D4A2</key>\n\t\t<integer>145</integer>\n\t\t<key>u1D4A5</key>\n\t\t<integer>185</integer>\n\t\t<key>u1D4A5.cal</key>\n\t\t<integer>198</integer>\n\t\t<key>u1D4A6</key>\n\t\t<integer>125</integer>\n\t\t<key>u1D4A9</key>\n\t\t<integer>245</integer>\n\t\t<key>u1D4A9.cal</key>\n\t\t<integer>152</integer>\n\t\t<key>u1D4AA</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D4AB</key>\n\t\t<integer>245</integer>\n\t\t<key>u1D4AB.cal</key>\n\t\t<integer>87</integer>\n\t\t<key>u1D4AC</key>\n\t\t<integer>45</integer>\n\t\t<key>u1D4AE</key>\n\t\t<integer>145</integer>\n\t\t<key>u1D4AE.cal</key>\n\t\t<integer>82</integer>\n\t\t<key>u1D4AF</key>\n\t\t<integer>245</integer>\n\t\t<key>u1D4AF.cal</key>\n\t\t<integer>266</integer>\n\t\t<key>u1D4B0</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D4B0.cal</key>\n\t\t<integer>178</integer>\n\t\t<key>u1D4B1</key>\n\t\t<integer>245</integer>\n\t\t<key>u1D4B1.cal</key>\n\t\t<integer>87</integer>\n\t\t<key>u1D4B2</key>\n\t\t<integer>245</integer>\n\t\t<key>u1D4B2.cal</key>\n\t\t<integer>87</integer>\n\t\t<key>u1D4B3</key>\n\t\t<integer>125</integer>\n\t\t<key>u1D4B3.cal</key>\n\t\t<integer>92</integer>\n\t\t<key>u1D4B4</key>\n\t\t<integer>125</integer>\n\t\t<key>u1D4B4.cal</key>\n\t\t<integer>89</integer>\n\t\t<key>u1D4B5</key>\n\t\t<integer>125</integer>\n\t\t<key>u1D4BB</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D4BE</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D4BF</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D4C1</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D4C9</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D4D2.cal</key>\n\t\t<integer>47</integer>\n\t\t<key>u1D4D3.cal</key>\n\t\t<integer>51</integer>\n\t\t<key>u1D4D4.cal</key>\n\t\t<integer>62</integer>\n\t\t<key>u1D4D5.cal</key>\n\t\t<integer>138</integer>\n\t\t<key>u1D4D7.cal</key>\n\t\t<integer>54</integer>\n\t\t<key>u1D4D8.cal</key>\n\t\t<integer>47</integer>\n\t\t<key>u1D4D9.cal</key>\n\t\t<integer>211</integer>\n\t\t<key>u1D4DD.cal</key>\n\t\t<integer>146</integer>\n\t\t<key>u1D4DE.cal</key>\n\t\t<integer>55</integer>\n\t\t<key>u1D4DF.cal</key>\n\t\t<integer>131</integer>\n\t\t<key>u1D4E2.cal</key>\n\t\t<integer>77</integer>\n\t\t<key>u1D4E3.cal</key>\n\t\t<integer>245</integer>\n\t\t<key>u1D4E4.cal</key>\n\t\t<integer>194</integer>\n\t\t<key>u1D4E5.cal</key>\n\t\t<integer>99</integer>\n\t\t<key>u1D4E6.cal</key>\n\t\t<integer>99</integer>\n\t\t<key>u1D4E7.cal</key>\n\t\t<integer>106</integer>\n\t\t<key>u1D4E8.cal</key>\n\t\t<integer>98</integer>\n\t\t<key>u1D4EF</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D4F2</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D4F3</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D4F5</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D4FD</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D53B.it</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D53C.bi</key>\n\t\t<integer>68</integer>\n\t\t<key>u1D53C.it</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D53D</key>\n\t\t<integer>140</integer>\n\t\t<key>u1D53D.bf</key>\n\t\t<integer>166</integer>\n\t\t<key>u1D53D.bi</key>\n\t\t<integer>274</integer>\n\t\t<key>u1D53D.it</key>\n\t\t<integer>240</integer>\n\t\t<key>u1D540.bi</key>\n\t\t<integer>74</integer>\n\t\t<key>u1D540.it</key>\n\t\t<integer>75</integer>\n\t\t<key>u1D541.bi</key>\n\t\t<integer>86</integer>\n\t\t<key>u1D541.it</key>\n\t\t<integer>78</integer>\n\t\t<key>u1D542.it</key>\n\t\t<integer>75</integer>\n\t\t<key>u1D544.bi</key>\n\t\t<integer>76</integer>\n\t\t<key>u1D544.it</key>\n\t\t<integer>79</integer>\n\t\t<key>u1D54A.bi</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D54A.it</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D54B</key>\n\t\t<integer>140</integer>\n\t\t<key>u1D54B.bf</key>\n\t\t<integer>134</integer>\n\t\t<key>u1D54B.bi</key>\n\t\t<integer>253</integer>\n\t\t<key>u1D54B.it</key>\n\t\t<integer>264</integer>\n\t\t<key>u1D54C.bi</key>\n\t\t<integer>91</integer>\n\t\t<key>u1D54C.it</key>\n\t\t<integer>113</integer>\n\t\t<key>u1D54D</key>\n\t\t<integer>130</integer>\n\t\t<key>u1D54D.bf</key>\n\t\t<integer>122</integer>\n\t\t<key>u1D54D.bi</key>\n\t\t<integer>246</integer>\n\t\t<key>u1D54D.it</key>\n\t\t<integer>231</integer>\n\t\t<key>u1D54E</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D54E.bf</key>\n\t\t<integer>64</integer>\n\t\t<key>u1D54E.bi</key>\n\t\t<integer>145</integer>\n\t\t<key>u1D54E.it</key>\n\t\t<integer>198</integer>\n\t\t<key>u1D54F.bi</key>\n\t\t<integer>118</integer>\n\t\t<key>u1D54F.it</key>\n\t\t<integer>165</integer>\n\t\t<key>u1D550</key>\n\t\t<integer>150</integer>\n\t\t<key>u1D550.bf</key>\n\t\t<integer>132</integer>\n\t\t<key>u1D550.bi</key>\n\t\t<integer>297</integer>\n\t\t<key>u1D550.it</key>\n\t\t<integer>245</integer>\n\t\t<key>u1D555.it</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D557</key>\n\t\t<integer>105</integer>\n\t\t<key>u1D557.bf</key>\n\t\t<integer>107</integer>\n\t\t<key>u1D557.bi</key>\n\t\t<integer>225</integer>\n\t\t<key>u1D557.it</key>\n\t\t<integer>233</integer>\n\t\t<key>u1D55A.it</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D55B.it</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D55D.bi</key>\n\t\t<integer>86</integer>\n\t\t<key>u1D55D.it</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D563</key>\n\t\t<integer>145</integer>\n\t\t<key>u1D563.bf</key>\n\t\t<integer>151</integer>\n\t\t<key>u1D563.bi</key>\n\t\t<integer>180</integer>\n\t\t<key>u1D563.it</key>\n\t\t<integer>180</integer>\n\t\t<key>u1D565.bi</key>\n\t\t<integer>64</integer>\n\t\t<key>u1D567</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D567.bf</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D567.bi</key>\n\t\t<integer>102</integer>\n\t\t<key>u1D567.it</key>\n\t\t<integer>112</integer>\n\t\t<key>u1D568</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D568.bi</key>\n\t\t<integer>75</integer>\n\t\t<key>u1D568.it</key>\n\t\t<integer>96</integer>\n\t\t<key>u1D569.bi</key>\n\t\t<integer>72</integer>\n\t\t<key>u1D56A</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D56A.bf</key>\n\t\t<integer>111</integer>\n\t\t<key>u1D56A.bi</key>\n\t\t<integer>104</integer>\n\t\t<key>u1D56A.it</key>\n\t\t<integer>112</integer>\n\t\t<key>u1D5BF</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D5F3</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D609</key>\n\t\t<integer>77</integer>\n\t\t<key>u1D60A</key>\n\t\t<integer>124</integer>\n\t\t<key>u1D60B</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D60C</key>\n\t\t<integer>135</integer>\n\t\t<key>u1D60D</key>\n\t\t<integer>184</integer>\n\t\t<key>u1D60E</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D60F</key>\n\t\t<integer>130</integer>\n\t\t<key>u1D610</key>\n\t\t<integer>150</integer>\n\t\t<key>u1D611</key>\n\t\t<integer>112</integer>\n\t\t<key>u1D612</key>\n\t\t<integer>135</integer>\n\t\t<key>u1D614</key>\n\t\t<integer>130</integer>\n\t\t<key>u1D615</key>\n\t\t<integer>130</integer>\n\t\t<key>u1D616</key>\n\t\t<integer>105</integer>\n\t\t<key>u1D617</key>\n\t\t<integer>153</integer>\n\t\t<key>u1D618</key>\n\t\t<integer>103</integer>\n\t\t<key>u1D619</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D61A</key>\n\t\t<integer>96</integer>\n\t\t<key>u1D61B</key>\n\t\t<integer>180</integer>\n\t\t<key>u1D61C</key>\n\t\t<integer>106</integer>\n\t\t<key>u1D61D</key>\n\t\t<integer>174</integer>\n\t\t<key>u1D61E</key>\n\t\t<integer>176</integer>\n\t\t<key>u1D61F</key>\n\t\t<integer>146</integer>\n\t\t<key>u1D620</key>\n\t\t<integer>184</integer>\n\t\t<key>u1D621</key>\n\t\t<integer>166</integer>\n\t\t<key>u1D625</key>\n\t\t<integer>160</integer>\n\t\t<key>u1D627</key>\n\t\t<integer>240</integer>\n\t\t<key>u1D628</key>\n\t\t<integer>120</integer>\n\t\t<key>u1D629</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D62A</key>\n\t\t<integer>145</integer>\n\t\t<key>u1D62B</key>\n\t\t<integer>140</integer>\n\t\t<key>u1D62C</key>\n\t\t<integer>120</integer>\n\t\t<key>u1D62D</key>\n\t\t<integer>160</integer>\n\t\t<key>u1D62E</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D62F</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D630</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D631</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D632</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D633</key>\n\t\t<integer>140</integer>\n\t\t<key>u1D634</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D635</key>\n\t\t<integer>120</integer>\n\t\t<key>u1D636</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D637</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D638</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D639</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D63A</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D63B</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D63D</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D63E</key>\n\t\t<integer>114</integer>\n\t\t<key>u1D63F</key>\n\t\t<integer>103</integer>\n\t\t<key>u1D640</key>\n\t\t<integer>133</integer>\n\t\t<key>u1D641</key>\n\t\t<integer>183</integer>\n\t\t<key>u1D642</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D643</key>\n\t\t<integer>128</integer>\n\t\t<key>u1D644</key>\n\t\t<integer>134</integer>\n\t\t<key>u1D645</key>\n\t\t<integer>133</integer>\n\t\t<key>u1D646</key>\n\t\t<integer>144</integer>\n\t\t<key>u1D648</key>\n\t\t<integer>128</integer>\n\t\t<key>u1D649</key>\n\t\t<integer>128</integer>\n\t\t<key>u1D64A</key>\n\t\t<integer>102</integer>\n\t\t<key>u1D64B</key>\n\t\t<integer>145</integer>\n\t\t<key>u1D64C</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D64D</key>\n\t\t<integer>68</integer>\n\t\t<key>u1D64E</key>\n\t\t<integer>123</integer>\n\t\t<key>u1D64F</key>\n\t\t<integer>184</integer>\n\t\t<key>u1D650</key>\n\t\t<integer>133</integer>\n\t\t<key>u1D651</key>\n\t\t<integer>183</integer>\n\t\t<key>u1D652</key>\n\t\t<integer>178</integer>\n\t\t<key>u1D653</key>\n\t\t<integer>153</integer>\n\t\t<key>u1D654</key>\n\t\t<integer>188</integer>\n\t\t<key>u1D655</key>\n\t\t<integer>156</integer>\n\t\t<key>u1D657</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D658</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D659</key>\n\t\t<integer>140</integer>\n\t\t<key>u1D65A</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D65B</key>\n\t\t<integer>240</integer>\n\t\t<key>u1D65C</key>\n\t\t<integer>140</integer>\n\t\t<key>u1D65D</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D65E</key>\n\t\t<integer>140</integer>\n\t\t<key>u1D65F</key>\n\t\t<integer>140</integer>\n\t\t<key>u1D660</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D661</key>\n\t\t<integer>140</integer>\n\t\t<key>u1D662</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D663</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D664</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D665</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D666</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D667</key>\n\t\t<integer>120</integer>\n\t\t<key>u1D668</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D669</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D66A</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D66B</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D66C</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D66D</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D66E</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D66F</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D6E3</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D6E4</key>\n\t\t<integer>145</integer>\n\t\t<key>u1D6E4.ss</key>\n\t\t<integer>148</integer>\n\t\t<key>u1D6E6</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D6E6.ss</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D6E7</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D6E7.ss</key>\n\t\t<integer>107</integer>\n\t\t<key>u1D6E8</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D6E8.ss</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D6E9</key>\n\t\t<integer>15</integer>\n\t\t<key>u1D6EA</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D6EA.ss</key>\n\t\t<integer>115</integer>\n\t\t<key>u1D6EB</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D6EB.ss</key>\n\t\t<integer>129</integer>\n\t\t<key>u1D6ED</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D6ED.ss</key>\n\t\t<integer>73</integer>\n\t\t<key>u1D6EE</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D6EE.ss</key>\n\t\t<integer>73</integer>\n\t\t<key>u1D6EF</key>\n\t\t<integer>75</integer>\n\t\t<key>u1D6EF.ss</key>\n\t\t<integer>77</integer>\n\t\t<key>u1D6F0</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D6F1</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D6F1.ss</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D6F2</key>\n\t\t<integer>150</integer>\n\t\t<key>u1D6F2.ss</key>\n\t\t<integer>131</integer>\n\t\t<key>u1D6F3</key>\n\t\t<integer>15</integer>\n\t\t<key>u1D6F4</key>\n\t\t<integer>65</integer>\n\t\t<key>u1D6F4.ss</key>\n\t\t<integer>97</integer>\n\t\t<key>u1D6F5</key>\n\t\t<integer>160</integer>\n\t\t<key>u1D6F5.ss</key>\n\t\t<integer>119</integer>\n\t\t<key>u1D6F6</key>\n\t\t<integer>160</integer>\n\t\t<key>u1D6F6.ss</key>\n\t\t<integer>177</integer>\n\t\t<key>u1D6F7</key>\n\t\t<integer>15</integer>\n\t\t<key>u1D6F8</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D6F8.ss</key>\n\t\t<integer>118</integer>\n\t\t<key>u1D6F9</key>\n\t\t<integer>113</integer>\n\t\t<key>u1D6F9.ss</key>\n\t\t<integer>138</integer>\n\t\t<key>u1D6FA</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D6FB</key>\n\t\t<integer>15</integer>\n\t\t<key>u1D6FC</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D6FC.ss</key>\n\t\t<integer>75</integer>\n\t\t<key>u1D6FD</key>\n\t\t<integer>65</integer>\n\t\t<key>u1D6FD.ss</key>\n\t\t<integer>69</integer>\n\t\t<key>u1D6FE</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D6FE.ss</key>\n\t\t<integer>69</integer>\n\t\t<key>u1D6FF</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D6FF.ss</key>\n\t\t<integer>85</integer>\n\t\t<key>u1D701</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D701.ss</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D702</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D703</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D705</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D705.ss</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D707</key>\n\t\t<integer>30</integer>\n\t\t<key>u1D708</key>\n\t\t<integer>50</integer>\n\t\t<key>u1D708.ss</key>\n\t\t<integer>85</integer>\n\t\t<key>u1D709</key>\n\t\t<integer>50</integer>\n\t\t<key>u1D709.ss</key>\n\t\t<integer>75</integer>\n\t\t<key>u1D70B</key>\n\t\t<integer>50</integer>\n\t\t<key>u1D70B.ss</key>\n\t\t<integer>69</integer>\n\t\t<key>u1D70D</key>\n\t\t<integer>65</integer>\n\t\t<key>u1D70D.ss</key>\n\t\t<integer>109</integer>\n\t\t<key>u1D70E</key>\n\t\t<integer>50</integer>\n\t\t<key>u1D70E.ss</key>\n\t\t<integer>63</integer>\n\t\t<key>u1D70F</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D70F.ss</key>\n\t\t<integer>63</integer>\n\t\t<key>u1D712</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D712.ss</key>\n\t\t<integer>83</integer>\n\t\t<key>u1D713</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D713.ss</key>\n\t\t<integer>96</integer>\n\t\t<key>u1D714.ss</key>\n\t\t<integer>51</integer>\n\t\t<key>u1D715</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D716</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D718</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D71B</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D71B.ss</key>\n\t\t<integer>61</integer>\n\t\t<key>u1D71D</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D71E</key>\n\t\t<integer>155</integer>\n\t\t<key>u1D720</key>\n\t\t<integer>62</integer>\n\t\t<key>u1D721</key>\n\t\t<integer>73</integer>\n\t\t<key>u1D722</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D723</key>\n\t\t<integer>68</integer>\n\t\t<key>u1D724</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D725</key>\n\t\t<integer>84</integer>\n\t\t<key>u1D727</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D728</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D729</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D72A</key>\n\t\t<integer>18</integer>\n\t\t<key>u1D72B</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D72C</key>\n\t\t<integer>161</integer>\n\t\t<key>u1D72D</key>\n\t\t<integer>12</integer>\n\t\t<key>u1D72E</key>\n\t\t<integer>68</integer>\n\t\t<key>u1D72F</key>\n\t\t<integer>172</integer>\n\t\t<key>u1D730</key>\n\t\t<integer>172</integer>\n\t\t<key>u1D731</key>\n\t\t<integer>12</integer>\n\t\t<key>u1D732</key>\n\t\t<integer>18</integer>\n\t\t<key>u1D733</key>\n\t\t<integer>127</integer>\n\t\t<key>u1D734</key>\n\t\t<integer>20</integer>\n\t\t<key>u1D735</key>\n\t\t<integer>10</integer>\n\t\t<key>u1D736</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D737</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D738</key>\n\t\t<integer>53</integer>\n\t\t<key>u1D73B</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D73F</key>\n\t\t<integer>50</integer>\n\t\t<key>u1D742</key>\n\t\t<integer>50</integer>\n\t\t<key>u1D743</key>\n\t\t<integer>50</integer>\n\t\t<key>u1D745</key>\n\t\t<integer>50</integer>\n\t\t<key>u1D747</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D748</key>\n\t\t<integer>50</integer>\n\t\t<key>u1D749</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D74C</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D74D</key>\n\t\t<integer>95</integer>\n\t\t<key>u1D74F</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D750</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D752</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D755</key>\n\t\t<integer>50</integer>\n\t\t<key>u1D7AA</key>\n\t\t<integer>65</integer>\n\t\t<key>u1D7AB</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D7AC</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D7AD</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D7AF</key>\n\t\t<integer>120</integer>\n\t\t<key>u1D7B3</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D7B6</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D7B7</key>\n\t\t<integer>90</integer>\n\t\t<key>u1D7B9</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D7BB</key>\n\t\t<integer>80</integer>\n\t\t<key>u1D7BC</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D7BD</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D7C0</key>\n\t\t<integer>110</integer>\n\t\t<key>u1D7C1</key>\n\t\t<integer>100</integer>\n\t\t<key>u1D7C3</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D7C4</key>\n\t\t<integer>40</integer>\n\t\t<key>u1D7C6</key>\n\t\t<integer>60</integer>\n\t\t<key>u1D7C9</key>\n\t\t<integer>70</integer>\n\t\t<key>u1D7E2.ss</key>\n\t\t<integer>123</integer>\n\t\t<key>u1D7E4.ss</key>\n\t\t<integer>119</integer>\n\t\t<key>u1D7E5.ss</key>\n\t\t<integer>89</integer>\n\t\t<key>u1D7E6.ss</key>\n\t\t<integer>92</integer>\n\t\t<key>u1D7E7.ss</key>\n\t\t<integer>171</integer>\n\t\t<key>u1D7E8.ss</key>\n\t\t<integer>162</integer>\n\t\t<key>u1D7E9.ss</key>\n\t\t<integer>161</integer>\n\t\t<key>u1D7EA.ss</key>\n\t\t<integer>105</integer>\n\t\t<key>u1D7EB.ss</key>\n\t\t<integer>124</integer>\n\t\t<key>u1D7EC.ss</key>\n\t\t<integer>123</integer>\n\t\t<key>u1D7EE.ss</key>\n\t\t<integer>126</integer>\n\t\t<key>u1D7EF.ss</key>\n\t\t<integer>131</integer>\n\t\t<key>u1D7F0.ss</key>\n\t\t<integer>128</integer>\n\t\t<key>u1D7F1.ss</key>\n\t\t<integer>196</integer>\n\t\t<key>u1D7F2.ss</key>\n\t\t<integer>183</integer>\n\t\t<key>u1D7F3.ss</key>\n\t\t<integer>184</integer>\n\t\t<key>u1D7F4.ss</key>\n\t\t<integer>139</integer>\n\t\t<key>u1D7F5.ss</key>\n\t\t<integer>133</integer>\n\t\t<key>uni03C3.ss</key>\n\t\t<integer>61</integer>\n\t\t<key>uni03C7.ss</key>\n\t\t<integer>86</integer>\n\t\t<key>uni03C8</key>\n\t\t<integer>40</integer>\n\t\t<key>uni210B</key>\n\t\t<integer>145</integer>\n\t\t<key>uni210B.cal</key>\n\t\t<integer>59</integer>\n\t\t<key>uni2110</key>\n\t\t<integer>195</integer>\n\t\t<key>uni2110.cal</key>\n\t\t<integer>61</integer>\n\t\t<key>uni2112</key>\n\t\t<integer>125</integer>\n\t\t<key>uni211B</key>\n\t\t<integer>45</integer>\n\t\t<key>uni212C</key>\n\t\t<integer>45</integer>\n\t\t<key>uni2130</key>\n\t\t<integer>105</integer>\n\t\t<key>uni2130.cal</key>\n\t\t<integer>91</integer>\n\t\t<key>uni2131</key>\n\t\t<integer>195</integer>\n\t\t<key>uni2131.cal</key>\n\t\t<integer>103</integer>\n\t\t<key>uni2133</key>\n\t\t<integer>45</integer>\n\t\t<key>uni213E</key>\n\t\t<integer>130</integer>\n\t\t<key>uni2145</key>\n\t\t<integer>20</integer>\n\t\t<key>uni2146</key>\n\t\t<integer>80</integer>\n\t\t<key>uni2148</key>\n\t\t<integer>80</integer>\n\t\t<key>uni2149</key>\n\t\t<integer>80</integer>\n\t\t<key>uni222B</key>\n\t\t<integer>180</integer>\n\t\t<key>uni222B.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni222B.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni222B.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni222B.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni222B.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni222B.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni222C</key>\n\t\t<integer>180</integer>\n\t\t<key>uni222C.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni222C.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni222C.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni222C.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni222C.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni222C.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni222D</key>\n\t\t<integer>180</integer>\n\t\t<key>uni222D.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni222D.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni222D.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni222D.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni222D.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni222D.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni222E</key>\n\t\t<integer>180</integer>\n\t\t<key>uni222E.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni222E.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni222E.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni222E.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni222E.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni222E.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni222F</key>\n\t\t<integer>180</integer>\n\t\t<key>uni222F.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni222F.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni222F.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni222F.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni222F.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni222F.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2230</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2230.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2230.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2230.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2230.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2230.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2230.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2231</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2231.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2231.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2231.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2231.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2231.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2231.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2232</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2232.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2232.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2232.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2232.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2232.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2232.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2233</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2233.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2233.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2233.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2233.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2233.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2233.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A0B</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A0B.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A0B.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A0B.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A0B.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A0B.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A0B.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A0C</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A0C.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A0C.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A0C.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A0C.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A0C.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A0C.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A0D</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A0D.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A0D.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A0D.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A0D.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A0D.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A0D.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A0E</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A0E.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A0E.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A0E.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A0E.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A0E.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A0E.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A0F</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A0F.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A0F.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A0F.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A0F.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A0F.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A0F.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A10</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A10.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A10.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A10.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A10.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A10.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A10.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A11</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A11.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A11.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A11.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A11.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A11.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A11.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A12</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A12.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A12.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A12.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A12.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A12.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A12.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A13</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A13.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A13.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A13.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A13.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A13.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A13.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A14</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A14.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A14.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A14.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A14.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A14.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A14.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A15</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A15.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A15.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A15.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A15.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A15.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A15.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A16</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A16.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A16.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A16.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A16.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A16.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A16.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A17</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A17.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A17.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A17.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A17.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A17.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A17.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A18</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A18.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A18.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A18.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A18.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A18.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A18.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A19</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A19.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A19.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A19.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A19.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A19.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A19.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A1A</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A1A.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A1A.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A1A.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A1A.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A1A.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A1A.up.display</key>\n\t\t<integer>145</integer>\n\t\t<key>uni2A1B</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A1B.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A1B.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A1B.rtlm.display</key>\n\t\t<integer>550</integer>\n\t\t<key>uni2A1B.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A1B.up</key>\n\t\t<integer>142</integer>\n\t\t<key>uni2A1B.up.display</key>\n\t\t<integer>140</integer>\n\t\t<key>uni2A1C</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A1C.display</key>\n\t\t<integer>300</integer>\n\t\t<key>uni2A1C.rtlm</key>\n\t\t<integer>180</integer>\n\t\t<key>uni2A1C.rtlm.display</key>\n\t\t<integer>300</integer>\n\t\t<key>uni2A1C.small</key>\n\t\t<integer>160</integer>\n\t\t<key>uni2A1C.up</key>\n\t\t<integer>50</integer>\n\t\t<key>uni2A1C.up.display</key>\n\t\t<integer>-200</integer>\n\t\t<key>y</key>\n\t\t<integer>20</integer>\n\t</dict>\n\t<key>v_assembly</key>\n\t<dict>\n\t\t<key>bar</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>879</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>400</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>bar</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>879</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>bar</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>400</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>braceleft</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>600</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A9</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>200</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23AA</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>600</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>200</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A8</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>200</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>600</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23AA</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>200</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A7</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>600</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>braceright</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>600</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23AD</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>200</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23AA</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>600</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>200</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23AC</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>200</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>600</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23AA</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>200</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23AB</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>600</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>bracketleft</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>950</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A3</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>500</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A2</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>500</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A1</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>950</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>bracketright</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>950</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A6</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>500</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A5</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>500</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A4</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>950</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>parenleft</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>150</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni239D</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>150</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni239C</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>150</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni239B</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>150</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>parenright</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>150</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A0</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>150</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni239F</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>150</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni239E</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>150</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni2016</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>879</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>400</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2016</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>879</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2016</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>400</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni2191</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23D0</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2191</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni2193</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2193</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23D0</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni2195</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2193</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23D0</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2191</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni21BE</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23D0</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni21BE</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni21BF</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23D0</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni21BF</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni21C2</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni21C2</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23D0</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni21C3</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni21C3</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23D0</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni21D1</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni21D1.ex</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni21D1</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni21D3</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni21D3</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni21D1.ex</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni21D5</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni21D3</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni21D1.ex</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni21D1</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni221A</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1855</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>600</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23B7</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>635</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>300</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni221A.ex</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>300</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>626</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni221A.top</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>500</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni221A.rtlm</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1855</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>600</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni221A.rtlm.bot</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>635</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>300</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni221A.rtlm.ex</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>300</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>626</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni221A.rtlm.top</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>500</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni221B</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1855</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>600</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni221B.base</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>635</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>300</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni221A.ex</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>300</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>626</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni221A.top</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>500</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni221C</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1855</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>600</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni221C.base</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>635</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>300</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni221A.ex</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>300</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>626</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni221A.top</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>600</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni2223</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>879</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>293</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2223</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>293</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>879</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>293</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2223</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>293</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni2225</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>879</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>293</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2225</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>293</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>879</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>293</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2225</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>293</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni2308</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>337</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A2</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>337</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>335</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A1</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>335</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni2309</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>337</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A5</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>337</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>335</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A4</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>335</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni230A</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>335</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A3</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>335</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>337</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A2</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>337</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni230B</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>335</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A6</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>335</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>337</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A5</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>337</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni23B0</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23AD</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23AA</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A7</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni23B1</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A9</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23AA</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23AB</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni27EE</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni239D</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni239C</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni239B</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni27EF</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni23A0</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1010</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni239F</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>1005</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni239E</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>90</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni27F0</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni27F0.ex</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni27F0</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni27F1</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni27F1</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni27F0.ex</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni290A</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni290A.ex</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni290A</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni290B</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>818</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni290B</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>273</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>304</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni290A.ex</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>101</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni2980</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>879</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>400</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2980</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>879</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>0</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2980</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>400</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t\t<key>uni2AF4</key>\n\t\t<dict>\n\t\t\t<key>italic</key>\n\t\t\t<integer>0</integer>\n\t\t\t<key>parts</key>\n\t\t\t<array>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>884</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>295</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<false/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2AF4</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>295</integer>\n\t\t\t\t</dict>\n\t\t\t\t<dict>\n\t\t\t\t\t<key>advance</key>\n\t\t\t\t\t<integer>884</integer>\n\t\t\t\t\t<key>endConnector</key>\n\t\t\t\t\t<integer>295</integer>\n\t\t\t\t\t<key>extender</key>\n\t\t\t\t\t<true/>\n\t\t\t\t\t<key>glyph</key>\n\t\t\t\t\t<string>uni2AF4</string>\n\t\t\t\t\t<key>startConnector</key>\n\t\t\t\t\t<integer>295</integer>\n\t\t\t\t</dict>\n\t\t\t</array>\n\t\t</dict>\n\t</dict>\n\t<key>v_variants</key>\n\t<dict>\n\t\t<key>uni232A</key>\n\t\t<array>\n\t\t\t<string>uni232A</string>\n\t\t\t<string>uni27E9.size1</string>\n\t\t\t<string>uni27E9.size2</string>\n\t\t\t<string>uni27E9.size3</string>\n\t\t\t<string>uni27E9.size4</string>\n\t\t</array>\n\t\t<key>uni2329</key>\n\t\t<array>\n\t\t\t<string>uni2329</string>\n\t\t\t<string>uni27E8.size1</string>\n\t\t\t<string>uni27E8.size2</string>\n\t\t\t<string>uni27E8.size3</string>\n\t\t\t<string>uni27E8.size4</string>\n\t\t</array>\n\t\t<key>backslash</key>\n\t\t<array>\n\t\t\t<string>backslash</string>\n\t\t\t<string>backslash.size1</string>\n\t\t\t<string>backslash.size2</string>\n\t\t\t<string>backslash.size3</string>\n\t\t\t<string>backslash.size4</string>\n\t\t</array>\n\t\t<key>bar</key>\n\t\t<array>\n\t\t\t<string>bar</string>\n\t\t\t<string>bar.size1</string>\n\t\t\t<string>bar.size2</string>\n\t\t\t<string>bar.size3</string>\n\t\t\t<string>bar.size4</string>\n\t\t</array>\n\t\t<key>braceleft</key>\n\t\t<array>\n\t\t\t<string>braceleft</string>\n\t\t\t<string>braceleft.size1</string>\n\t\t\t<string>braceleft.size2</string>\n\t\t\t<string>braceleft.size3</string>\n\t\t\t<string>braceleft.size4</string>\n\t\t</array>\n\t\t<key>braceright</key>\n\t\t<array>\n\t\t\t<string>braceright</string>\n\t\t\t<string>braceright.size1</string>\n\t\t\t<string>braceright.size2</string>\n\t\t\t<string>braceright.size3</string>\n\t\t\t<string>braceright.size4</string>\n\t\t</array>\n\t\t<key>bracketleft</key>\n\t\t<array>\n\t\t\t<string>bracketleft</string>\n\t\t\t<string>bracketleft.size1</string>\n\t\t\t<string>bracketleft.size2</string>\n\t\t\t<string>bracketleft.size3</string>\n\t\t\t<string>bracketleft.size4</string>\n\t\t</array>\n\t\t<key>bracketright</key>\n\t\t<array>\n\t\t\t<string>bracketright</string>\n\t\t\t<string>bracketright.size1</string>\n\t\t\t<string>bracketright.size2</string>\n\t\t\t<string>bracketright.size3</string>\n\t\t\t<string>bracketright.size4</string>\n\t\t</array>\n\t\t<key>fraction</key>\n\t\t<array>\n\t\t\t<string>fraction</string>\n\t\t\t<string>slash.size1</string>\n\t\t\t<string>slash.size2</string>\n\t\t\t<string>slash.size3</string>\n\t\t\t<string>slash.size4</string>\n\t\t</array>\n\t\t<key>parenleft</key>\n\t\t<array>\n\t\t\t<string>parenleft</string>\n\t\t\t<string>parenleft.size1</string>\n\t\t\t<string>parenleft.size2</string>\n\t\t\t<string>parenleft.size3</string>\n\t\t\t<string>parenleft.size4</string>\n\t\t</array>\n\t\t<key>parenright</key>\n\t\t<array>\n\t\t\t<string>parenright</string>\n\t\t\t<string>parenright.size1</string>\n\t\t\t<string>parenright.size2</string>\n\t\t\t<string>parenright.size3</string>\n\t\t\t<string>parenright.size4</string>\n\t\t</array>\n\t\t<key>slash</key>\n\t\t<array>\n\t\t\t<string>slash</string>\n\t\t\t<string>slash.size1</string>\n\t\t\t<string>slash.size2</string>\n\t\t\t<string>slash.size3</string>\n\t\t\t<string>slash.size4</string>\n\t\t</array>\n\t\t<key>uni0338</key>\n\t\t<array>\n\t\t\t<string>uni0338</string>\n\t\t\t<string>uni0338.size1</string>\n\t\t\t<string>uni0338.size2</string>\n\t\t\t<string>uni0338.size3</string>\n\t\t\t<string>uni0338.size4</string>\n\t\t\t<string>uni0338.size5</string>\n\t\t\t<string>uni0338.size6</string>\n\t\t</array>\n\t\t<key>uni0606</key>\n\t\t<array>\n\t\t\t<string>uni0606</string>\n\t\t\t<string>uni0606.size1</string>\n\t\t\t<string>uni0606.size2</string>\n\t\t\t<string>uni0606.size3</string>\n\t\t</array>\n\t\t<key>uni0607</key>\n\t\t<array>\n\t\t\t<string>uni0607</string>\n\t\t\t<string>uni0607.size1</string>\n\t\t\t<string>uni0607.size2</string>\n\t\t\t<string>uni0607.size3</string>\n\t\t</array>\n\t\t<key>uni2016</key>\n\t\t<array>\n\t\t\t<string>uni2016</string>\n\t\t\t<string>uni2016.size1</string>\n\t\t\t<string>uni2016.size2</string>\n\t\t\t<string>uni2016.size3</string>\n\t\t\t<string>uni2016.size4</string>\n\t\t</array>\n\t\t<key>uni20D2</key>\n\t\t<array>\n\t\t\t<string>uni20D2</string>\n\t\t\t<string>uni20D2.size1</string>\n\t\t\t<string>uni20D2.size2</string>\n\t\t\t<string>uni20D2.size3</string>\n\t\t\t<string>uni20D2.size4</string>\n\t\t\t<string>uni20D2.size5</string>\n\t\t\t<string>uni20D2.size6</string>\n\t\t</array>\n\t\t<key>uni2140</key>\n\t\t<array>\n\t\t\t<string>uni2140</string>\n\t\t\t<string>uni2140.display</string>\n\t\t</array>\n\t\t<key>uni2140.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2140.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2191</key>\n\t\t<array/>\n\t\t<key>uni2193</key>\n\t\t<array/>\n\t\t<key>uni2195</key>\n\t\t<array/>\n\t\t<key>uni21BE</key>\n\t\t<array/>\n\t\t<key>uni21BF</key>\n\t\t<array/>\n\t\t<key>uni21C2</key>\n\t\t<array/>\n\t\t<key>uni21C3</key>\n\t\t<array/>\n\t\t<key>uni21D1</key>\n\t\t<array/>\n\t\t<key>uni21D3</key>\n\t\t<array/>\n\t\t<key>uni21D5</key>\n\t\t<array/>\n\t\t<key>uni220F</key>\n\t\t<array>\n\t\t\t<string>uni220F</string>\n\t\t\t<string>uni220F.display</string>\n\t\t</array>\n\t\t<key>uni2210</key>\n\t\t<array>\n\t\t\t<string>uni2210</string>\n\t\t\t<string>uni2210.display</string>\n\t\t</array>\n\t\t<key>uni2211</key>\n\t\t<array>\n\t\t\t<string>uni2211</string>\n\t\t\t<string>uni2211.display</string>\n\t\t</array>\n\t\t<key>uni2211.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2211.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni221A</key>\n\t\t<array>\n\t\t\t<string>uni221A</string>\n\t\t\t<string>uni221A.size1</string>\n\t\t\t<string>uni221A.size2</string>\n\t\t\t<string>uni221A.size3</string>\n\t\t</array>\n\t\t<key>uni221A.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni221A.rtlm.size1</string>\n\t\t\t<string>uni221A.rtlm.size2</string>\n\t\t\t<string>uni221A.rtlm.size3</string>\n\t\t</array>\n\t\t<key>uni221B</key>\n\t\t<array>\n\t\t\t<string>uni221B</string>\n\t\t\t<string>uni221B.size1</string>\n\t\t\t<string>uni221B.size2</string>\n\t\t\t<string>uni221B.size3</string>\n\t\t</array>\n\t\t<key>uni221B.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni221B.rtlm.size1</string>\n\t\t\t<string>uni221B.rtlm.size2</string>\n\t\t\t<string>uni221B.rtlm.size3</string>\n\t\t</array>\n\t\t<key>uni221C</key>\n\t\t<array>\n\t\t\t<string>uni221C</string>\n\t\t\t<string>uni221C.size1</string>\n\t\t\t<string>uni221C.size2</string>\n\t\t\t<string>uni221C.size3</string>\n\t\t</array>\n\t\t<key>uni221C.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni221C.rtlm.size1</string>\n\t\t\t<string>uni221C.rtlm.size2</string>\n\t\t\t<string>uni221C.rtlm.size3</string>\n\t\t</array>\n\t\t<key>uni2223</key>\n\t\t<array/>\n\t\t<key>uni2225</key>\n\t\t<array/>\n\t\t<key>uni222B</key>\n\t\t<array>\n\t\t\t<string>uni222B</string>\n\t\t\t<string>uni222B.display</string>\n\t\t</array>\n\t\t<key>uni222B.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni222B.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni222B.up</key>\n\t\t<array>\n\t\t\t<string>uni222B.up</string>\n\t\t\t<string>uni222B.up.display</string>\n\t\t</array>\n\t\t<key>uni222C</key>\n\t\t<array>\n\t\t\t<string>uni222C</string>\n\t\t\t<string>uni222C.display</string>\n\t\t</array>\n\t\t<key>uni222C.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni222C.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni222C.up</key>\n\t\t<array>\n\t\t\t<string>uni222C.up</string>\n\t\t\t<string>uni222C.up.display</string>\n\t\t</array>\n\t\t<key>uni222D</key>\n\t\t<array>\n\t\t\t<string>uni222D</string>\n\t\t\t<string>uni222D.display</string>\n\t\t</array>\n\t\t<key>uni222D.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni222D.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni222D.up</key>\n\t\t<array>\n\t\t\t<string>uni222D.up</string>\n\t\t\t<string>uni222D.up.display</string>\n\t\t</array>\n\t\t<key>uni222E</key>\n\t\t<array>\n\t\t\t<string>uni222E</string>\n\t\t\t<string>uni222E.display</string>\n\t\t</array>\n\t\t<key>uni222E.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni222E.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni222E.up</key>\n\t\t<array>\n\t\t\t<string>uni222E.up</string>\n\t\t\t<string>uni222E.up.display</string>\n\t\t</array>\n\t\t<key>uni222F</key>\n\t\t<array>\n\t\t\t<string>uni222F</string>\n\t\t\t<string>uni222F.display</string>\n\t\t</array>\n\t\t<key>uni222F.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni222F.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni222F.up</key>\n\t\t<array>\n\t\t\t<string>uni222F.up</string>\n\t\t\t<string>uni222F.up.display</string>\n\t\t</array>\n\t\t<key>uni2230</key>\n\t\t<array>\n\t\t\t<string>uni2230</string>\n\t\t\t<string>uni2230.display</string>\n\t\t</array>\n\t\t<key>uni2230.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2230.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2230.up</key>\n\t\t<array>\n\t\t\t<string>uni2230.up</string>\n\t\t\t<string>uni2230.up.display</string>\n\t\t</array>\n\t\t<key>uni2231</key>\n\t\t<array>\n\t\t\t<string>uni2231</string>\n\t\t\t<string>uni2231.display</string>\n\t\t</array>\n\t\t<key>uni2231.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2231.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2231.up</key>\n\t\t<array>\n\t\t\t<string>uni2231.up</string>\n\t\t\t<string>uni2231.up.display</string>\n\t\t</array>\n\t\t<key>uni2232</key>\n\t\t<array>\n\t\t\t<string>uni2232</string>\n\t\t\t<string>uni2232.display</string>\n\t\t</array>\n\t\t<key>uni2232.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2232.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2232.up</key>\n\t\t<array>\n\t\t\t<string>uni2232.up</string>\n\t\t\t<string>uni2232.up.display</string>\n\t\t</array>\n\t\t<key>uni2233</key>\n\t\t<array>\n\t\t\t<string>uni2233</string>\n\t\t\t<string>uni2233.display</string>\n\t\t</array>\n\t\t<key>uni2233.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2233.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2233.up</key>\n\t\t<array>\n\t\t\t<string>uni2233.up</string>\n\t\t\t<string>uni2233.up.display</string>\n\t\t</array>\n\t\t<key>uni22C0</key>\n\t\t<array>\n\t\t\t<string>uni22C0</string>\n\t\t\t<string>uni22C0.display</string>\n\t\t</array>\n\t\t<key>uni22C1</key>\n\t\t<array>\n\t\t\t<string>uni22C1</string>\n\t\t\t<string>uni22C1.display</string>\n\t\t</array>\n\t\t<key>uni22C2</key>\n\t\t<array>\n\t\t\t<string>uni22C2</string>\n\t\t\t<string>uni22C2.display</string>\n\t\t</array>\n\t\t<key>uni22C3</key>\n\t\t<array>\n\t\t\t<string>uni22C3</string>\n\t\t\t<string>uni22C3.display</string>\n\t\t</array>\n\t\t<key>uni2308</key>\n\t\t<array>\n\t\t\t<string>uni2308</string>\n\t\t\t<string>uni2308.size1</string>\n\t\t\t<string>uni2308.size2</string>\n\t\t\t<string>uni2308.size3</string>\n\t\t\t<string>uni2308.size4</string>\n\t\t</array>\n\t\t<key>uni2309</key>\n\t\t<array>\n\t\t\t<string>uni2309</string>\n\t\t\t<string>uni2309.size1</string>\n\t\t\t<string>uni2309.size2</string>\n\t\t\t<string>uni2309.size3</string>\n\t\t\t<string>uni2309.size4</string>\n\t\t</array>\n\t\t<key>uni230A</key>\n\t\t<array>\n\t\t\t<string>uni230A</string>\n\t\t\t<string>uni230A.size1</string>\n\t\t\t<string>uni230A.size2</string>\n\t\t\t<string>uni230A.size3</string>\n\t\t\t<string>uni230A.size4</string>\n\t\t</array>\n\t\t<key>uni230B</key>\n\t\t<array>\n\t\t\t<string>uni230B</string>\n\t\t\t<string>uni230B.size1</string>\n\t\t\t<string>uni230B.size2</string>\n\t\t\t<string>uni230B.size3</string>\n\t\t\t<string>uni230B.size4</string>\n\t\t</array>\n\t\t<key>uni23B0</key>\n\t\t<array>\n\t\t\t<string>uni23B0</string>\n\t\t</array>\n\t\t<key>uni23B1</key>\n\t\t<array>\n\t\t\t<string>uni23B1</string>\n\t\t</array>\n\t\t<key>uni2772</key>\n\t\t<array>\n\t\t\t<string>uni2772</string>\n\t\t\t<string>uni2772.size1</string>\n\t\t\t<string>uni2772.size2</string>\n\t\t\t<string>uni2772.size3</string>\n\t\t\t<string>uni2772.size4</string>\n\t\t</array>\n\t\t<key>uni2773</key>\n\t\t<array>\n\t\t\t<string>uni2773</string>\n\t\t\t<string>uni2773.size1</string>\n\t\t\t<string>uni2773.size2</string>\n\t\t\t<string>uni2773.size3</string>\n\t\t\t<string>uni2773.size4</string>\n\t\t</array>\n\t\t<key>uni27E6</key>\n\t\t<array>\n\t\t\t<string>uni27E6</string>\n\t\t\t<string>uni27E6.size1</string>\n\t\t\t<string>uni27E6.size2</string>\n\t\t\t<string>uni27E6.size3</string>\n\t\t\t<string>uni27E6.size4</string>\n\t\t</array>\n\t\t<key>uni27E7</key>\n\t\t<array>\n\t\t\t<string>uni27E7</string>\n\t\t\t<string>uni27E7.size1</string>\n\t\t\t<string>uni27E7.size2</string>\n\t\t\t<string>uni27E7.size3</string>\n\t\t\t<string>uni27E7.size4</string>\n\t\t</array>\n\t\t<key>uni27E8</key>\n\t\t<array>\n\t\t\t<string>uni27E8</string>\n\t\t\t<string>uni27E8.size1</string>\n\t\t\t<string>uni27E8.size2</string>\n\t\t\t<string>uni27E8.size3</string>\n\t\t\t<string>uni27E8.size4</string>\n\t\t</array>\n\t\t<key>uni27E9</key>\n\t\t<array>\n\t\t\t<string>uni27E9</string>\n\t\t\t<string>uni27E9.size1</string>\n\t\t\t<string>uni27E9.size2</string>\n\t\t\t<string>uni27E9.size3</string>\n\t\t\t<string>uni27E9.size4</string>\n\t\t</array>\n\t\t<key>uni27EA</key>\n\t\t<array>\n\t\t\t<string>uni27EA</string>\n\t\t\t<string>uni27EA.size1</string>\n\t\t\t<string>uni27EA.size2</string>\n\t\t\t<string>uni27EA.size3</string>\n\t\t\t<string>uni27EA.size4</string>\n\t\t</array>\n\t\t<key>uni27EB</key>\n\t\t<array>\n\t\t\t<string>uni27EB</string>\n\t\t\t<string>uni27EB.size1</string>\n\t\t\t<string>uni27EB.size2</string>\n\t\t\t<string>uni27EB.size3</string>\n\t\t\t<string>uni27EB.size4</string>\n\t\t</array>\n\t\t<key>uni27EE</key>\n\t\t<array>\n\t\t\t<string>uni27EE</string>\n\t\t</array>\n\t\t<key>uni27EF</key>\n\t\t<array>\n\t\t\t<string>uni27EF</string>\n\t\t</array>\n\t\t<key>uni27F0</key>\n\t\t<array/>\n\t\t<key>uni27F1</key>\n\t\t<array/>\n\t\t<key>uni290A</key>\n\t\t<array/>\n\t\t<key>uni290B</key>\n\t\t<array/>\n\t\t<key>uni2980</key>\n\t\t<array>\n\t\t\t<string>uni2980</string>\n\t\t\t<string>uni2980.size1</string>\n\t\t\t<string>uni2980.size2</string>\n\t\t\t<string>uni2980.size3</string>\n\t\t\t<string>uni2980.size4</string>\n\t\t</array>\n\t\t<key>uni2983</key>\n\t\t<array>\n\t\t\t<string>uni2983</string>\n\t\t\t<string>uni2983.size1</string>\n\t\t\t<string>uni2983.size2</string>\n\t\t\t<string>uni2983.size3</string>\n\t\t\t<string>uni2983.size4</string>\n\t\t</array>\n\t\t<key>uni2984</key>\n\t\t<array>\n\t\t\t<string>uni2984</string>\n\t\t\t<string>uni2984.size1</string>\n\t\t\t<string>uni2984.size2</string>\n\t\t\t<string>uni2984.size3</string>\n\t\t\t<string>uni2984.size4</string>\n\t\t</array>\n\t\t<key>uni2985</key>\n\t\t<array>\n\t\t\t<string>uni2985</string>\n\t\t\t<string>uni2985.size1</string>\n\t\t\t<string>uni2985.size2</string>\n\t\t\t<string>uni2985.size3</string>\n\t\t\t<string>uni2985.size4</string>\n\t\t</array>\n\t\t<key>uni2986</key>\n\t\t<array>\n\t\t\t<string>uni2986</string>\n\t\t\t<string>uni2986.size1</string>\n\t\t\t<string>uni2986.size2</string>\n\t\t\t<string>uni2986.size3</string>\n\t\t\t<string>uni2986.size4</string>\n\t\t</array>\n\t\t<key>uni29F8</key>\n\t\t<array>\n\t\t\t<string>uni29F8</string>\n\t\t\t<string>uni29F8.size1</string>\n\t\t</array>\n\t\t<key>uni29F9</key>\n\t\t<array>\n\t\t\t<string>uni29F9</string>\n\t\t\t<string>uni29F9.size1</string>\n\t\t</array>\n\t\t<key>uni2A00</key>\n\t\t<array>\n\t\t\t<string>uni2A00</string>\n\t\t\t<string>uni2A00.display</string>\n\t\t</array>\n\t\t<key>uni2A01</key>\n\t\t<array>\n\t\t\t<string>uni2A01</string>\n\t\t\t<string>uni2A01.display</string>\n\t\t</array>\n\t\t<key>uni2A02</key>\n\t\t<array>\n\t\t\t<string>uni2A02</string>\n\t\t\t<string>uni2A02.display</string>\n\t\t</array>\n\t\t<key>uni2A03</key>\n\t\t<array>\n\t\t\t<string>uni2A03</string>\n\t\t\t<string>uni2A03.display</string>\n\t\t</array>\n\t\t<key>uni2A04</key>\n\t\t<array>\n\t\t\t<string>uni2A04</string>\n\t\t\t<string>uni2A04.display</string>\n\t\t</array>\n\t\t<key>uni2A05</key>\n\t\t<array>\n\t\t\t<string>uni2A05</string>\n\t\t\t<string>uni2A05.display</string>\n\t\t</array>\n\t\t<key>uni2A06</key>\n\t\t<array>\n\t\t\t<string>uni2A06</string>\n\t\t\t<string>uni2A06.display</string>\n\t\t</array>\n\t\t<key>uni2A07</key>\n\t\t<array>\n\t\t\t<string>uni2A07</string>\n\t\t\t<string>uni2A07.display</string>\n\t\t</array>\n\t\t<key>uni2A08</key>\n\t\t<array>\n\t\t\t<string>uni2A08</string>\n\t\t\t<string>uni2A08.display</string>\n\t\t</array>\n\t\t<key>uni2A09</key>\n\t\t<array>\n\t\t\t<string>uni2A09</string>\n\t\t\t<string>uni2A09.display</string>\n\t\t</array>\n\t\t<key>uni2A0A</key>\n\t\t<array>\n\t\t\t<string>uni2A0A</string>\n\t\t\t<string>uni2A0A.display</string>\n\t\t</array>\n\t\t<key>uni2A0A.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A0A.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A0B</key>\n\t\t<array>\n\t\t\t<string>uni2A0B</string>\n\t\t\t<string>uni2A0B.display</string>\n\t\t</array>\n\t\t<key>uni2A0B.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A0B.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A0B.up</key>\n\t\t<array>\n\t\t\t<string>uni2A0B.up</string>\n\t\t\t<string>uni2A0B.up.display</string>\n\t\t</array>\n\t\t<key>uni2A0C</key>\n\t\t<array>\n\t\t\t<string>uni2A0C</string>\n\t\t\t<string>uni2A0C.display</string>\n\t\t</array>\n\t\t<key>uni2A0C.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A0C.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A0C.up</key>\n\t\t<array>\n\t\t\t<string>uni2A0C.up</string>\n\t\t\t<string>uni2A0C.up.display</string>\n\t\t</array>\n\t\t<key>uni2A0D</key>\n\t\t<array>\n\t\t\t<string>uni2A0D</string>\n\t\t\t<string>uni2A0D.display</string>\n\t\t</array>\n\t\t<key>uni2A0D.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A0D.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A0D.up</key>\n\t\t<array>\n\t\t\t<string>uni2A0D.up</string>\n\t\t\t<string>uni2A0D.up.display</string>\n\t\t</array>\n\t\t<key>uni2A0E</key>\n\t\t<array>\n\t\t\t<string>uni2A0E</string>\n\t\t\t<string>uni2A0E.display</string>\n\t\t</array>\n\t\t<key>uni2A0E.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A0E.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A0E.up</key>\n\t\t<array>\n\t\t\t<string>uni2A0E.up</string>\n\t\t\t<string>uni2A0E.up.display</string>\n\t\t</array>\n\t\t<key>uni2A0F</key>\n\t\t<array>\n\t\t\t<string>uni2A0F</string>\n\t\t\t<string>uni2A0F.display</string>\n\t\t</array>\n\t\t<key>uni2A0F.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A0F.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A0F.up</key>\n\t\t<array>\n\t\t\t<string>uni2A0F.up</string>\n\t\t\t<string>uni2A0F.up.display</string>\n\t\t</array>\n\t\t<key>uni2A10</key>\n\t\t<array>\n\t\t\t<string>uni2A10</string>\n\t\t\t<string>uni2A10.display</string>\n\t\t</array>\n\t\t<key>uni2A10.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A10.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A10.up</key>\n\t\t<array>\n\t\t\t<string>uni2A10.up</string>\n\t\t\t<string>uni2A10.up.display</string>\n\t\t</array>\n\t\t<key>uni2A11</key>\n\t\t<array>\n\t\t\t<string>uni2A11</string>\n\t\t\t<string>uni2A11.display</string>\n\t\t</array>\n\t\t<key>uni2A11.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A11.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A11.up</key>\n\t\t<array>\n\t\t\t<string>uni2A11.up</string>\n\t\t\t<string>uni2A11.up.display</string>\n\t\t</array>\n\t\t<key>uni2A12</key>\n\t\t<array>\n\t\t\t<string>uni2A12</string>\n\t\t\t<string>uni2A12.display</string>\n\t\t</array>\n\t\t<key>uni2A12.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A12.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A12.up</key>\n\t\t<array>\n\t\t\t<string>uni2A12.up</string>\n\t\t\t<string>uni2A12.up.display</string>\n\t\t</array>\n\t\t<key>uni2A13</key>\n\t\t<array>\n\t\t\t<string>uni2A13</string>\n\t\t\t<string>uni2A13.display</string>\n\t\t</array>\n\t\t<key>uni2A13.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A13.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A13.up</key>\n\t\t<array>\n\t\t\t<string>uni2A13.up</string>\n\t\t\t<string>uni2A13.up.display</string>\n\t\t</array>\n\t\t<key>uni2A14</key>\n\t\t<array>\n\t\t\t<string>uni2A14</string>\n\t\t\t<string>uni2A14.display</string>\n\t\t</array>\n\t\t<key>uni2A14.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A14.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A14.up</key>\n\t\t<array>\n\t\t\t<string>uni2A14.up</string>\n\t\t\t<string>uni2A14.up.display</string>\n\t\t</array>\n\t\t<key>uni2A15</key>\n\t\t<array>\n\t\t\t<string>uni2A15</string>\n\t\t\t<string>uni2A15.display</string>\n\t\t</array>\n\t\t<key>uni2A15.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A15.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A15.up</key>\n\t\t<array>\n\t\t\t<string>uni2A15.up</string>\n\t\t\t<string>uni2A15.up.display</string>\n\t\t</array>\n\t\t<key>uni2A16</key>\n\t\t<array>\n\t\t\t<string>uni2A16</string>\n\t\t\t<string>uni2A16.display</string>\n\t\t</array>\n\t\t<key>uni2A16.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A16.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A16.up</key>\n\t\t<array>\n\t\t\t<string>uni2A16.up</string>\n\t\t\t<string>uni2A16.up.display</string>\n\t\t</array>\n\t\t<key>uni2A17</key>\n\t\t<array>\n\t\t\t<string>uni2A17</string>\n\t\t\t<string>uni2A17.display</string>\n\t\t</array>\n\t\t<key>uni2A17.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A17.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A17.up</key>\n\t\t<array>\n\t\t\t<string>uni2A17.up</string>\n\t\t\t<string>uni2A17.up.display</string>\n\t\t</array>\n\t\t<key>uni2A18</key>\n\t\t<array>\n\t\t\t<string>uni2A18</string>\n\t\t\t<string>uni2A18.display</string>\n\t\t</array>\n\t\t<key>uni2A18.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A18.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A18.up</key>\n\t\t<array>\n\t\t\t<string>uni2A18.up</string>\n\t\t\t<string>uni2A18.up.display</string>\n\t\t</array>\n\t\t<key>uni2A19</key>\n\t\t<array>\n\t\t\t<string>uni2A19</string>\n\t\t\t<string>uni2A19.display</string>\n\t\t</array>\n\t\t<key>uni2A19.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A19.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A19.up</key>\n\t\t<array>\n\t\t\t<string>uni2A19.up</string>\n\t\t\t<string>uni2A19.up.display</string>\n\t\t</array>\n\t\t<key>uni2A1A</key>\n\t\t<array>\n\t\t\t<string>uni2A1A</string>\n\t\t\t<string>uni2A1A.display</string>\n\t\t</array>\n\t\t<key>uni2A1A.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A1A.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A1A.up</key>\n\t\t<array>\n\t\t\t<string>uni2A1A.up</string>\n\t\t\t<string>uni2A1A.up.display</string>\n\t\t</array>\n\t\t<key>uni2A1B</key>\n\t\t<array>\n\t\t\t<string>uni2A1B</string>\n\t\t\t<string>uni2A1B.display</string>\n\t\t</array>\n\t\t<key>uni2A1B.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A1B.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A1B.up</key>\n\t\t<array>\n\t\t\t<string>uni2A1B.up</string>\n\t\t\t<string>uni2A1B.up.display</string>\n\t\t</array>\n\t\t<key>uni2A1C</key>\n\t\t<array>\n\t\t\t<string>uni2A1C</string>\n\t\t\t<string>uni2A1C.display</string>\n\t\t</array>\n\t\t<key>uni2A1C.rtlm</key>\n\t\t<array>\n\t\t\t<string>uni2A1C.rtlm.display</string>\n\t\t</array>\n\t\t<key>uni2A1C.up</key>\n\t\t<array>\n\t\t\t<string>uni2A1C.up</string>\n\t\t\t<string>uni2A1C.up.display</string>\n\t\t</array>\n\t\t<key>uni2AF4</key>\n\t\t<array/>\n\t\t<key>uni2AFC</key>\n\t\t<array>\n\t\t\t<string>uni2AFC</string>\n\t\t\t<string>uni2AFC.display</string>\n\t\t</array>\n\t\t<key>uni2AFF</key>\n\t\t<array>\n\t\t\t<string>uni2AFF</string>\n\t\t\t<string>uni2AFF.display</string>\n\t\t</array>\n\t</dict>\n\t<key>version</key>\n\t<string>1.3</string>\n</dict>\n</plist>\n"
  }
]