Merge branch 'refs/heads/main' into split-audit

# Conflicts:
#	pnpm-lock.yaml
This commit is contained in:
Andrea Vos 2024-12-31 19:45:30 +01:00
commit 7c49f14368
25 changed files with 3179 additions and 2734 deletions

View File

@ -178,6 +178,14 @@ so to test them, you have to build a production build (`make deploy` and `nuxt s
### Troubleshooting
#### Invalid caches after changing code
Due to how [caches in Nitro](https://nitro.build/guide/cache) work, they automatically invalidate during development
when their function changes. However, this heuristic does not cover other functions the cached function depends on.
You can manually clear caches:
```bash
rm -rf .nuxt/cache
```
#### Module did not self-register
If you encounter an error `Module did not self-register`, triggered by the `canvas` dependency,

View File

@ -71,11 +71,11 @@ export default {
data: {
labels: this.isMultiDataset(this.data)
? Array.from(Object.values(this.data).reduce((carry, item) => {
for (const key in item) {
carry.add(key);
}
return carry;
}, new Set()))
for (const key in item) {
carry.add(key);
}
return carry;
}, new Set()))
: Object.keys(this.data),
datasets: this.isMultiDataset(this.data)
? Object.entries(this.data).map(([key, data]) => this.buildDataset(data, key, COLOURS[colourIndex++ % COLOURS.length]))

View File

@ -44,9 +44,12 @@ const { floatingStyles, placement: calculatedPlacement, middlewareData } = useFl
const visible = ref(false);
const slots = useSlots();
const slots = defineSlots<{
default(): VNode;
content(): VNode[];
}>();
const hasContent = computed((): boolean => {
return !!slots.content?.()[0];
return !!slots.content()[0];
});
const arrowStyles = computed((): CSSProperties | undefined => {

View File

@ -66,9 +66,9 @@ const longPath = computed((): string => {
return base
? Compressor.compress(
selectedPronoun.value.toArray().map((x) => x.split('|')[0]),
base.toArray().map((x) => x.split('|')[0]),
).join(',')
selectedPronoun.value.toArray().map((x) => x.split('|')[0]),
base.toArray().map((x) => x.split('|')[0]),
).join(',')
: selectedPronoun.value.toString();
});
const path = computed((): string | null => {

View File

@ -0,0 +1,72 @@
# التمثيل الجرافيكي للغات؟
<small>2024-08-18 | [@andrea](/@andrea)، مُترجَمة من قِبَل الفريق العربي.</small>
![تجميع لمجموعة من الطرق المذكورة لاحقًا في المقالة (قائمة باللغات مع حروف الهجاء، خريطة، أعلام دولينجو، أعلام مجمعة...))](/img-local/blog/graphical-languages/graphical-languages.png)
يعد وضع العناصر الجرافيكية بجانب التسميات النصية خدعة تصميمية رائعة - فهي تساعد عقلك على تخطي بعض الخطوات عند
التنقل في واجهة المستخدم: فبدلًا من قراءة التسمية يتمكن معرفة ما يفعله الزر على الفور بمجرد إلقاء نظرة على الأيقونة.
هذا هو السبب وراء وجود أيقونة مرافقة لمعظم الأزرار في موقعنا الإلكتروني ويمكنك فقط تخيل مدى سهولة
ذلك في العمل على المشروع! أستطيع التنقل بسهولة عبر *أي* نسخة لغوية دون فهم كلمة واحدة منها، فقط
لأنني أتذكر الأيقونات التي تميز كل زر.
هذا أيضًا سبب وضع العديد من واجهات المستخدم أعلامًا بجانب أسماء اللغات. لكن هل هو حقًا نهج جيد؟
فبعد كل شيء، تمثل الأعلام الدول وليس اللغات وإذا لم تقنعك التعقيدات الأيديولوجية والسياسية لخلط هذين المفهومين، فالمشاكل العملية ربما ستفعل: اللغات ببساطة لا يمكن أن تُطابق واحدًا لواحد مع الدول.
أول مثال يخطر على البال: أي علم يجب أن يمثل اللغة الإنجليزية؟
لقد نشأت في 🏴 إنجلترا، لكنها تُتحدث أيضًا أو تعد رسمية في باقي المملكة المتحدة 🇬🇧، وفي الولايات المتحدة 🇺🇸، وأستراليا 🇦🇺، وكندا 🇨🇦، والهند 🇮🇳، وغيرها الكثير.
لماذا نختار واحدًا على الآخر؟ إذا اخترنا مكان المنشأ، فهل سيعرف معظم الناس علم إنجلترا؟ وإذا اخترنا حسب حجم السكان، ألن يعتقد الناس أن علم الهند يشير إلى اللغة الهندية بدلاً من الإنجليزية؟
تظهر قضايا مشابهة مع لغات أخرى. أي علم يجب أن يمثل الإسبانية؟ 🇪🇸 إسبانيا، 🇲🇽 المكسيك، 🇦🇷 الأرجنتين، 🇨🇴 كولومبيا؟
وأي علم يجب أن يمثل البرتغالية؟ 🇵🇹 البرتغال، 🇧🇷 البرازيل؟ وأي علم يمثل العربية؟ 🇸🇦 السعودية، 🇪🇬 مصر، 🇮🇶 العراق، 🇱🇧 لبنان؟
هناك العديد من اللغات التي لا تُعترف بها كلغات رسمية في أي دولة. بعض مجموعات المتحدثين، مثل السليزيين أو الباسك، لديهم علم لمنطقتهم، بينما آخرون، مثل متحدثي اللادينو، لا يمتلكون ذلك بل لا يقطنون حتى في منطقة واحدة.
بعض اللغات المصطنعة قد تمتلك علَمًا، مثل الإسبرانتو، لكن البعض الآخر ببساطة لا يمتلك. وحتى إذا وُجد مرشح جيد ليمثل علَمًا، فقد لا يكون مقبولًا عالميًا من قبل متحدثي اللغة، وقد يكون من الصعب استخدامه على سبيل المثال،
كان بإمكاني بسهولة إضافة رموز أعلام الدول في هذا النص، ولكن تضمين علم الإسبرانتو أو الباسك في نص يتطلب مجهودًا أكبر بكثير.
لقد قام الناس بتصميم أعلام لتمثيل اللغات بشكل أفضل من أعلام الدول على سبيل المثال من خلال دمج عناصر من أعلام الدول التي تُتحدث فيها اللغة. إليك فيديو ممتع يستعرض مجموعة من الأفكار:
{embed=//youtube.com/embed/2I3UJkDmMco=What are "Language Flags?" (And Should They Exist?)}
مع ازدياد عدد النسخ اللغوية لمشروعنا، كنا نناقش أفكارًا لجعل العثور على النسخة المطلوبة أسهل بدون استخدام أعلام الدول.
لقد أنشأت نموذجًا أوليًا لنهج نقوم فيه باختيار حرف واحد من لغة معينة يمكن أن يمثلها على سبيل المثال `ß` للألمانية، `ñ` للإسبانية أو `ą` للبولندية ونضعه على خلفية بلون يمثل عائلة اللغة مثل الجرمانية، الرومانسية أو السلافية.
![النسخ اللغوية الأخرى: ß Deutsch, ñ Español, õ Eesti keel, , ç Français, ny Ladino (Djudezmo), ij Nederlands, æ Norsk (Bokmål), ą Polski, ã Português, ă Română, å Svenska, ớ Tiếng Việt, ش العربية (الفصحى), й Русский, ї Українська, の 日本語, 人 中文](/img-local/blog/graphical-languages/graphemes.png)
هذا النهج ليس مثاليًا أيضًا. إنه لا يزال اختيارًا تعسفيًا جدًا: لماذا لا نستخدم `ł` للبولندية؟ هل ينبغي أن تحصل السويدية على `å`، أم يجب أن تحصل النرويجية؟
الأبجدية الإنجليزية مملة نوعًا ما، فهل نختار حرفًا لاتينيًا عشوائيًا، أم ربما نغامر بعدم الفهم ونستخدم الحرف التاريخي `þ`؟
هذه الأحرف أقل قابلية للتعرف عليها من الأعلام التي اعتدنا رؤيتها تمثل اللغات وبينما قد تكون فكرة جيدة على المدى الطويل، فإنها لا تساعد كثيرًا على المدى القصي
نهج آخر قمنا بالبحث فيه كان استخدام خريطة. بينما يمكن أن يتواجد متحدثو أي لغة في أي مكان، فمن الممكن عمومًا تحديد منطقة عامة حيث تُتحدث اللغة بشكل شائع.
لسوء الحظ، العثور على مجموعة بيانات مفتوحة المصدر لهذه المناطق ليس بالأمر السهل، وحتى لو كان لدينا ذلك، لا يزال يتعين علينا التعامل مع قضايا مثل التداخل بين المناطق، أو بعض المناطق التي تكون صغيرة جدًا للنقر عليها بينما تغطي مناطق أخرى قارات بأكملها.
بدلًا من ذلك، جربنا استخدام مجموعة بيانات من إحداثيات خط العرض/خط الطول البسيطة لكل لغة من [الأطلس العالمي لهياكل اللغة](https://wals.info/)، حيث يتم تمثيل كل لغة بنقطة واحدة على خريطة، في "مركز الثقل" العام كما اختاره اللغويون الذين أنشأوا تلك المجموعة.
ولكننا لا نزال لم نتخلص فعليًا من المشكلة الرئيسية في خلط اللغات مع الدول بينما قد يساعد ذلك متحدثي البولندية على العثور بسرعة على النقطة في وسط بولندا، ربما لن يكون من الواضح للمستخدمين من الولايات المتحدة البحث حول إنجلترا.
وأين نضع حتى لغات مثل الإسبرانتو أو توكي بونا؟
![خريطة العالم مع عدد من الدوائر تمثل المواقع العامة للغات](/img-local/blog/graphical-languages/map.png)
هذه الخريطة ليست مخصصة لرسم خريطة دقيقة للغات، بل الفكرة كانت أن تكون أداة إضافية للمساعدة في تقليل الارتباك عند زيارة الصفحة ورؤية قائمة متزايدة من اللغات دون أي أدوات رسومية إضافية (مثل الأعلام).
يمكن لبعض المستخدمين العثور فورًا على اللغة التي يبحثون عنها بمجرد إلقاء نظرة على الخريطة بينما يمكن للآخرين الاعتماد على قائمة بسيطة للغات.
ولكن في النهاية، قررنا أن هذا النهج بعيد جدًا عن الجيد ليتم وضعه فعليًا على الموقع.
ما انتهى بنا المطاف بتنفيذه على الصفحة الرئيسية في [pronouns.page](https://pronouns.page)، هو ببساطة إضافة بعض الأدوات المساعدة إلى قائمة اللغات "الخام" الموجودة.
يمكننا استخدام قائمة اللغات المفضلة كما حددها المستخدم في إعدادات متصفحه وإظهار بعض الاقتراحات في الأعلى؛ بهذه الطريقة، من المرجح جدًا أن يروا ما يبحثون عنه على الفور.
تحتها، توجد قائمة كاملة بدون أي عناصر رسومية إضافية، ولكن الآن تحصل على عامل تصفية يمكن للمرء فقط البدء بكتابة اسم اللغة التي يبحث عنها (إما [الاسم الداخلي أو الخارجي](https://en.wikipedia.org/wiki/Endonym_and_exonym)) أو رمز ISO الخاص بها وسيجدها مباشرة.
![لقطة شاشة لمحدد اللغة: في الأعلى بعض الاقتراحات بناءً على إعدادات المتصفح، وأسفلها القائمة الكاملة مع حقل تصفية](/img-local/blog/graphical-languages/filtering.png)
القائمة ليست مثالية أيضًا. كيف يمكنك حتى فرز اللغات أبجديًا إذا كانت تستخدم كتابات مختلفة؟
يمكنك استخدام الترجمة الحرفية لأسمائها، كما تفعل ويكيبيديا، ولكنه لا يزال نهجًا أوروبيًا بعض الشيء ولا يأخذ بعين الاعتبار اللغات التي لها عدة ترجمات حرفية مثل التايلاندية.
يمكننا فرز اللغات حسب شعبيتها (على سبيل المثال، عدد البطاقات في قاعدة بياناتنا)، ولكن بينما قد يجعل ذلك من _الأكثر احتمالًا_ العثور بسهولة على لغتك لعدد أكبر من الناس في المتوسط، فإنه لن يجعل العثور عليها سهلًا في العموم.
حاليًا، نحن نعالج النصوص اللاتينية وغير اللاتينية بشكل مختلف، بسبب تكوين وشعبية اللغات الحالية، ولكن من المحتمل أن يتغير ذلك مع ظهور المزيد من النسخ.
![لقطة شاشة لـ wikipedia.org: قائمة اللغات مرتبة أولاً حسب عدد المقالات (1,000,000+، 100,000+، إلخ)، ثم مرتبة حسب الترجمة الحرفية (مثل Azərbaycanca, Български, 閩南語 / Bân-lâm-gú, বাংলা, Беларуская, Català)](/img-local/blog/graphical-languages/wikipedia.png)
بالطبع، نحن لسنا قريبين من ويكيبيديا. مع وجود 18 نسخة لغوية لـ Pronouns.page منشورة حاليًا، كل هذا ليس مشكلة _ضخمة_، يمكن للناس بسهولة فحص القائمة بالكامل والعثور على ما يبحثون عنه.
ولكن بالنظر إلى أن هناك أيضًا 47 قناة لغوية على خادم Discord الخاص بنا، في مراحل مختلفة من الإكمال، فإن السؤال أصبح أكثر أهمية مع مرور الوقت.
لن تحل أي من الأدوات المذكورة أعلاه المشكلة بالكامل، ولكن بمجرد دمجها جميعًا معًا، يمكن أن تجعل تجربة المستخدم أسهل بكثير.
إذاً، ما رأيكم جميعاً في هذه المسألة؟ هل لديكم أفكار أفضل؟
هل هناك نهج من شأنه أن يحل جميع المشاكل ويصبح معيارًا مفيدًا لإدراج اللغات في واجهات المستخدم؟
نحن منفتحون جدًا على التجارب!

View File

@ -0,0 +1,20 @@
# الانستجرام والفيسبوك يحظرون روابطنا 🙄
<small>2023-03-27 | [@andrea](/@andrea)، مُترجَمة من قِبَل الفريق العربي.</small>
![لقطة شاشة لرسالة الحظر مع النص: الروابط المراد إزالتها: pronouns.page. نقوم بإزالة الروابط التي تحتوي على: - البريد العشوائي؛ دعم أو الإشادة بالإرهاب أو الجريمة المنظمة أو جماعات الكراهية. - التماس الخدمات الجنسية؛ - بيع الأسلحة النارية والمخدرات](/img-local/blog/instagram-ban.png)
في يوم الأحد 26 مارس، علمنا أن إنستجرام وفيسبوك بدأتا بحظر روابط صفحتنا ومطالبة المستخدمين بحذفها من ملفاتهم الشخصية.
نحن حزينون ومنزعجون من هذا الوضع. لا علاقة لبوابتنا بالرسائل غير المرغوب فيها، الإرهاب، الجرائم، جماعات الكراهية، الخدمات الجنسية، الأسلحة النارية، أو المخدرات.
من الواضح أن هذه الاتهامات سخيفة. إن [شروط الخدمة](/الشروط) الخاصة بنا واضحة ونحن نعمل بلا كلل للإشراف على المحتوى الذي لا يتبع القواعد.
ولكن في هذه المرحلة ليس لدينا أي أسباب للاعتقاد بأن هذا الحظر كان مقصودًا أو رهابًا من المثليين -
من المحتمل أن يكون الروبوت الخاص بهم قد عثر على بطاقة ذات محتوى مشكوك فيه لم يتم حظره بعد من قبل المشرفين لدينا
ثم قام تلقائيًا بوضع علامة على النطاق بأكمله على أنه مشبوه.
خاصةً وأن نطاقاتنا الأخرى (zaimki.pl و pronoms.fr و pronombr.es) يبدو أنها لم تتأثر.
لقد تقدمنا بالفعل بشكوى من خلال [مصحح أخطاء المشاركة التابع لميتا](https://developers.facebook.com/tools/debug/?q=https%3A%2F%2Fpronouns.page),
والآن علينا فقط أن ننتظر أن يراجع إنسان ما خطأ الروبوت ويصلحه.
> **تحديث:** يبدو أن الحظر قد تم رفعه 😉

View File

@ -0,0 +1,83 @@
# بين الشذوذ ومجتمع المثلية
<small>2024-09-22 | [@andrea](/@andrea)، مُترجَمة من قِبَل الفريق العربي.</small>
![علمان يلوحان في مهب الريح على خلفية سماء زرقاء: فخر التقدم والفوضى المثلية](/img-local/blog/queer-lgbtq.png)
<p style="margin-top: -.75rem"><small class="text-muted">تأثير التلويح بالعلم مصنوع من خلال <a href="https://krikienoid.github.io/flagwaver/" target="_blank" rel="noopener">Flagwaver</a>. صورة الخلفية بواسطة <a href="https://unsplash.com/@sklepacki">Stephanie Klepacki</a> على <a href="https://unsplash.com/photos/white-clouds-and-blue-sky-gXG_2TpSBOch" target="_blank" rel="noopener">Unsplash</a></small></p>
لقد أدركت أنه قد مر وقت طويل منذ أن وصفت نفسي "عضوًا في مجتمع المثلية" (LGBTQIA+) وبدلاً من ذلك، أصبحت أطلق على نفسي "شاذ (كوير)" فقط.
وبالطبع، جزء من السبب هو سهولة نطق الكلمة بالمقارنة؛
وجزء آخر من السبب هو المعارك المستمرة حول أي الحروف يجب تضمينها في الاختصار وأيها لا.
ولكن الأهم من ذلك _هذه المصطلحات ليست مترادفة ببساطة_.
بالرغم من وجود تداخل كبير بين الاثنين، أجد أن الفروق بينهما كبيرة جدًا.
وأحدهما يصفني بشكل أفضل من الآخر.
ولكن ما الفرق بالضبط، قد يتسائل البعض؟ حسنًا، كنت أطرح على نفسي نفس السؤال:
لماذا يبدو أحدهما أكثر تناسبًا لي من الآخر؟ كيف يمكنني تعريف هذين المصطلحين؟ أحدهما واضح للغاية:
> **مجتمع المثلية** يشمل المثليات، المثليين، مزدوجي التوجه الجنسي، المتحولين جنسيًا، الكوير (الشواذ)، المستفسرين، ثنائيي الجنس، اللاجنسيين، اللارومانسيين، وغيرهم.
> وهو يشمل عمومًا كل من لا يتبع النظام السائد، مثل غير المغايرين جنسيًا أو حب الجنس الآخر وما إلى ذلك.
هذا المصطلح واضح بحد ذاته؛ فهو مجرد قائمة للمجموعات من الأقليات الجنسية والرومانسية والتوجهات الجنسية التي تتحد تحت راية قوس قزح.
الحقيقة البسيطة أن هويتك ليست "سائدة" تجعلك مشمولًا في هذا المصطلح.
وإذا [قرأنا ويكيبيديا](https://ar.wikipedia.org/wiki/%D8%AD%D8%B1_%D8%A7%D9%84%D8%AC%D9%86%D8%B3)، قد يظن البعض أن الكوير (الشاذ) يعني الشيء نفسه.
ففي النهاية: "كوير قد تستخدم من قبل الذين يرفضون الهويات الجنسية التقليدية أوسع، أقل تمثلاً، وكبديل مبهم عمدًا للإل جي بي تي.."
لكن بعض الملاحظات من حياتي جعلتني أتأمل السؤال بعمق أكبر.
أولًا، دائرة أصدقائي تميل إلى التمركز حول الكويريين. بالطبع.
نحن نتشارك نضالات وأهداف ورؤى متشابهة. يجعلونني أشعر بالفهم والأمان.
هناك _إحساس_ مميز بيننا. بين الأشخاص الكويريين يمكنني ببساطة أن أكون نفسي.
ولكن هناك ملاحظة هامة لم أستطع تحديدها حتى مؤخرًا.
هناك أشخاص في مجتمع المثلية لا أشعر بهذا الاتصال معهم على الإطلاق وهناك أيضًا أشخاص أشعر فورًا بهذا الإحساس معهم،
حتى لو لم تُطرح مسألة جنسهم أو توجههم، ولا أهتم بذلك. لماذا؟
رغم وجود _تداخل كبير_ بين هذا الاتصال وكونك عضوًا في مجموعة مهمشة، فإن الدوائر لا تتداخل _بشكل كامل_.
أُخبرت ذات مرة من قبل شخص مثلي الجنس أنه إذا أراد المثليين في بولندا الحصول على اتحادات مدنية (وبالخصوصة المساواة في الزواج)،
فعليهم التوقف عن التباهي بغرابتهم، وبدلاً من ذلك... التطوع للعمل مجانًا في حصاد البطاطس وربما حينها سيمنحهم المجتمع بعض الحقوق بكرم.
لا، شكرًا... افعل ما تريد، لكنني سأغيب، شكرًا جزيلاً.
قد يشمل مجتمع المثلية كل شخص ذو هوية غير سائدة، لكن **الشذوذ هو أيضًا ضد الاندماج في القوالب.**
والملاحظة الأخرى هي مدى الأشياء غير الشاذة التي أشاركها مع أصدقائي الكويريين.
ليس الأمر مجرد هذا القاسم المشترك الوحيد بيننا جميعًا ولكننا أيضًا عمومًا نميل إلى أن نكون يساريين، مناهضين للرأسمالية،
نسويين، مناهضين للعنصرية، مناهضين للتمييز ضد ذوي الاحتياجات الخاصة، وما إلى ذلك.
لقد كنا دائمًا في الجانب المهمش من المجتمع، وندرك أنه حتى نكون جميعًا أحرارًا، لن يكون أي منا حرًا.
قد يشمل مجتمع المثلية كل شخص ذو هوية غير سائدة، لكن **الكوير أيضًا متقاطع.**
تحت [منشور على Reddit](https://www.reddit.com/r/polyamory/comments/1fados7/gender_identity_of_the_poly_pool/)
يطلب أفكارًا عن سبب كون الأشخاص المتعددين العلاقات أكثر احتمالًا لأن يكونوا شواذ، وقد وجدت العديد من التعليقات التي قالت الشيء نفسه تقريبًا،
لكن هذا التعليق وضعه بأفضل طريقة:
> مخطط ڤين لتعدد العلاقات، الغرابة الجنسية، الشذوذ، والتنوع العصبي أصبح تقريبًا دائرة في هذه المرحلة هههه.
> على الأقل هكذا تمزح دائرتي الاجتماعية عنه. في تجربتي، هؤلاء الأشخاص يميلون أيضًا لأن يكونوا يساريين سياسيًا،
> من الليبراليين إلى الاشتراكيين إلى الفوضويين. وأيضًا الكثير من الأشخاص ذوي الإعاقات.
> أشكال التهميش (المسافة / الاستبعاد / الاغتراب عن المجتمع السائد™️) تميل إلى التداخل بشكل متزايد مع تراكمها.
> إنها فكرة "بديهية" إذا فكرت فيها لمدة 5+ دقائق. ومن هنا يأتي التقاطع.
> أشكال المقاومة ضد (أي عدم المشاركة في) المجتمع السائد™️ تميل أيضًا إلى التداخل مع الوقت.
> ليس قفزة كبيرة أن تشكك في جميع القواعد الاجتماعية الأخرى بمجرد أن تشكك / تحرر نفسك من بعضها.
لذلك، مع كل هذا في الاعتبار، توصلت إلى تعريفي للكوير.
تنويه صغير، بالطبع: إنه مجرد تعريفي الشخصي بناءً على فهمي للمجتمعات التي أنتمي إليها؛
قد يتم فهم الكوير بشكل مختلف في دول ومجتمعات مختلفة، وقد تختلف معهم وهذا جيد تمامًا.
أنا هنا فقط لأشارك وجهة نظري، وليس لأروِّج لأي حقائق شاملة.
على أي حال:
> **الكوير هو التمرد النشط على النظام البطريركي (الأبوي).**
مع هذا التعريف لـ"الكوير"، بدأت الأمور تبدو منطقية بالنسبة لي.
رجل مثلي متميز في علاقة أحادية يحاول أن يكون "طبيعيًا" قدر الإمكان، ليندمج ويتم قبوله من قبل المجتمع السائد،
والذي ينتهي نضاله من أجل الحقوق المتساوية عند الحد الأدنى الذي يحتاجه هو نفسه،
دون اعتبار لاحتياجات بقية مجتمعه هذا ليس شخصي.
إنه لا يتمرد على النظام، بل يندمج فيه.
ومع ذلك، فإن الرجل الذي يشارك في الدوائر النسوية،
ويطلي أظافره، ويذهب إلى الاحتجاجات ضد الإبادة الجماعية في جزء آخر من العالم،
ويشارك في مجموعات الدعم المتبادل، وما إلى ذلك لا أهتم بهويته لأعتبره كويرًا في كتابي.
إنه يتمرد بنشاط على النظام البطريركي.
لا أهتم بالنقاشات التي لا تنتهي حول ما إذا كان تعدد العلاقات هو هوية أم خيار نمط حياة،
أو ما إذا كان يجب اعتبار الأشخاص المتعددين العلاقات جزءًا من مجتمع المثلية.
تعدد العلاقات هو تمرد نشط على النظام البطريركي إنه كوير في كتابي.
الكوير هو حركة، وليس مجرد هوية.
الكوير هو فعل.

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 473 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 845 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 743 KiB

View File

@ -35,6 +35,7 @@ home:
base: 'Surbaze de'
alt: 'Vi povas ankaŭ enigi interŝanĝeblajn formojn en ĉiun kampo aparte, ekz. <code>li&ŝi</code> = «li» aŭ «ŝi».'
pronunciation: ~
compressedAlternative: 'Uzi kompaktigitan format-alternativon'
whatisit: 'Pri kio temas ĉiuj ĉi pronomoj?'
mission:
header: 'Niaj celoj'
@ -78,8 +79,16 @@ pronouns:
null:
button: 'Generi ligilon kun nomo aŭ inicialo'
base: 'Nomo aŭ inicialo'
description: >
Iuj homoj preferas uzi neniujn ajn pronomojn, anstataŭe esti priparolataj per nomo, inicialoj,
pronom-evitado, pasivaj formoj kaj restrukturigitaj frazoj. Vidu (angle):
{https://web.archive.org/web/20211214214513/https://twitter.com/lypomania/status/1290274971642544128=Gvidilo
de lypomania},
{https://web.archive.org/web/20230326021305/https://www.lgbtqia.wiki/wiki/Nullpronominal=Nulpronomaj ĉe LGBTA
Wiki}
emoji:
button: 'Generi ligilon kun emoĝio'
base: 'Entajpi emoĝiojn (memoru elekti emoĝi-klavaron ĉe via aparato)'
pronunciation:
play: 'Ludi sonpecon'
@ -457,6 +466,9 @@ contact:
support:
header: 'Subteno'
bankAccount: 'Banka ĝiro'
description: >
Se vi volas ĵeti moneron por la servilo, domajnoj, glumaroj ktp., aŭ simple aĉeti bieron por aŭtoroj, vi povas
uzi ligilojn sube:
user:
header: 'Konto'
@ -481,6 +493,14 @@ user:
La retejo konservas neniujn pasvortojn. {https://avris.it/blog/passwords-are-passé=Pli da informoj.}
deprecated: 'Evitinda'
broken: 'Aj ve, kara! Rompite 😢'
instancePlaceholder: 'Apero'
oauthError: 'Dum aŭtentigado okazis eraro… Bonvolu reprovi aŭ uzi alian metodon de aŭtentigo.'
depreciationNotice: >
Ĉi tio ne estas fidinda provizanto de aŭtentigo. <a href="%link%" target="_blank" rel="noopener">Alklaku ĉi
tien por legi pli</a>. Ni tre rekomendas certigi, ke vi povas uzi alian metodon de aŭtentigo.
brokenNotice: >
Ni havas teknikajn problemojn pri la metodo de aŭtentigo… Se ĝi ne funkcias por vi, bonvolu ensaluti per via
retpoŝtadreso (aŭ alia metodo).
code:
action: 'Validigi'
invalid: 'Nevalida kodo.'
@ -527,12 +547,21 @@ user:
recovery:
header: 'Realira kodo'
enter: 'Enigu realiran kodon'
saved: 'Bone, mi konservis ilin!'
save: >
Konservu jenajn restaŭrajn kodojn en sekura loko. Vi povos uzi ilin por preterpasi PlAŭ-on, se vi iam
perdos la aŭtentigantan ilon.
cancel: 'Nuligi ensalutadon'
enabled: 'Ebligita'
disable: 'Malebligi PlAŭ-on.'
disableConfirm: 'Ĉu vi certas, ke vi volas malebligi PlAŭ-on?'
qr:
header: 'QR-kodo'
download: 'Elŝuti QR-kodon'
modMessage:
subject: 'Mesaĝo de moderiganto'
intro: 'Sal! Unu el niaj moderigantoj sendis al vi ĉi tiun mesaĝon:'
respond: 'Se vi volas respondi, simple respondu al ĉi tiu retpoŝtmesaĝo.'
socialLookup: 'Ebligi mian profilon esti elserĉata per soci-retejaj traktiloj / identigiloj'
socialLookupWhy: '(tio taŭgas por integrado, al diskordaj robotoj, retumilaj etendoj, …)'
accountSwitch:
@ -541,6 +570,7 @@ user:
Unukonte vi povas havi nur unu karton po lingvo kaj tiuj kartoj estas ligitaj per la komuna @uzantnomo. Tamen
eble vi volus krei ankaŭ multajn sendependajn kontojn, ekzemple unu por laboro kaj alian apartan por via
amikaro. Se vi aldonos la kontojn ĉi tien, vi povos rapide ŝanĝadi inter ili.
profile:
description: 'Priskribo'
names: 'Nomoj'
@ -571,6 +601,9 @@ profile:
Europe: 'Eŭropo'
Indian: 'Hindoceano'
Pacific: 'Pacifiko'
info: >
Se vi plenigos ĉi tiun kampon, via karto montros <strong>la tempon en via loĝloko</strong>. Vi povas, sed ne
devas, decidi montri ankaŭ vian proksimuman lokon.
flags: 'Flagoj'
flagsInfo: 'Ŝovu kaj demetu viajn fierflagojn en ĉi tiun kadron.'
flagsCustom: 'Alŝuti viajn flagojn'
@ -760,6 +793,11 @@ crud:
copy: 'Kopii ligilon'
alt: 'Alternativa teksto'
english:
description: >
If you don't speak Esperanto, yet still are interested in how this language tries to cope with the omnipresent
binaries, we've prepared a short overview of those ideas in English.
footer:
license: >
{https://gitlab.com/PronounsPage/PronounsPage=La fontkodo} kaj la enhavoj estas licenitaj per {/license=la

View File

@ -951,6 +951,12 @@ crud:
alt: 'Альтернативное описание'
loadAll: 'Загрузка...'
search:
header: 'Поиск'
tooShort: 'Чтобы начать поиск введите минимум три знака, как поисковой запрос'
tooLong: 'Поисковой запрос не может превышать 256 знаков'
noResults: 'Не найдено результатов для «%query%»'
footer:
license: >
{https://gitlab.com/PronounsPage/PronounsPage=Исходный код} и содержимое лицензированы {/license=OQL}.

View File

@ -155,6 +155,13 @@ export default defineNuxtConfig({
authToken: process.env.SENTRY_AUTH_TOKEN,
}),
],
css: {
preprocessorOptions: {
scss: {
api: 'legacy',
},
},
},
resolve: {
alias: {
'~@fortawesome': path.resolve(__dirname, 'node_modules/@fortawesome'),

View File

@ -19,14 +19,14 @@
"@aws-sdk/client-polly": "^3.525.0",
"@aws-sdk/client-s3": "^3.525.0",
"@floating-ui/vue": "^1.1.5",
"@nuxt/eslint": "^0.6.1",
"@nuxtjs/plausible": "^1.0.0",
"@pinia/nuxt": "^0.5.1",
"@nuxt/eslint": "^0.7.4",
"@nuxtjs/plausible": "^1.2.0",
"@pinia/nuxt": "^0.9.0",
"@sentry/browser": "^7.109.0",
"@sentry/cli": "^2.31.0",
"@sentry/node": "^7.109.0",
"@sentry/vue": "^7.109.0",
"@vite-pwa/nuxt": "^0.10.1",
"@vite-pwa/nuxt": "^0.10.6",
"@vuepic/vue-datepicker": "^8.8.1",
"@vueuse/core": "^12.2.0",
"abort-controller": "^3.0.0",
@ -63,7 +63,7 @@
"nepali-calendar-js": "https://github.com/pixunil/nepali-calendar-js",
"node-fetch": "^2.6.12",
"nodemailer": "^6.7.8",
"nuxt": "^3.14.159",
"nuxt": "^3.15.0",
"pageres": "^8.1.0",
"papaparse": "^5.4.1",
"plausible-api": "https://github.com/avo7/plausible-api.git#main",
@ -90,7 +90,7 @@
"@babel/eslint-parser": "^7.24.5",
"@babel/plugin-syntax-import-assertions": "^7.24.1",
"@fortawesome/fontawesome-pro": "git+ssh://git@gitlab.com:Avris/FontAwesomePro.git",
"@nuxt/test-utils": "^3.14.1",
"@nuxt/test-utils": "^3.15.1",
"@rollup/plugin-replace": "^5.0.7",
"@rollup/plugin-yaml": "^4.1.2",
"@sentry/types": "^7.109.0",
@ -107,7 +107,7 @@
"@types/luxon": "^1.27.1",
"@types/markdown-it": "^14.0.1",
"@types/multer": "1.4.5",
"@types/node": "^20.11.5",
"@types/node": "^20.16.5",
"@types/node-fetch": "^2.6.11",
"@types/nodemailer": "^6.4.14",
"@types/papaparse": "^5.3.14",
@ -115,7 +115,7 @@
"@types/sharp": "^0.31.1",
"@types/speakeasy": "^2.0.10",
"@types/uuid": "8.3.2",
"@vitest/coverage-v8": "^2.0.3",
"@vitest/coverage-v8": "^2.1.8",
"@vue/test-utils": "^2.4.6",
"avris-daemonise": "^0.0.2",
"bootstrap": "^5.3.1",
@ -137,11 +137,10 @@
"sharp": "^0.33.4",
"ts-json-schema-generator": "^1.5.0",
"tsconfig-paths": "3.14.2",
"typescript": "^5.5.2",
"vite": "^5.3.5",
"vitest": "^2.0.3",
"typescript": "^5.7.2",
"vitest": "^2.1.8",
"vue-component-type-helpers": "^2.1.6",
"vue-tsc": "^2.1.10"
"vue-tsc": "^2.2.0"
},
"peerDependencies": {
"postcss": "^8.0.0"

5615
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -90,7 +90,7 @@ const selectFragment = (sourcesMap: Record<string, SourceRow>, keyAndFragment: s
const fragments = source.fragments
? source.fragments.replace(/\\@/g, '###').split('@')
.map((x) => x.replace(/###/g, '@'))
.map((x) => x.replace(/###/g, '@'))
: [];
source.fragments = fragments[parseInt(fragment) - 1];

View File

@ -1118,7 +1118,7 @@ router.post('/profile/import', handleErrorAsync(async (req, res) => {
return res.status(401).json({ error: 'One file expected' });
}
const contentParts = zlib.gunzipSync(files[0].data).toString('utf-8')
const contentParts = zlib.gunzipSync(files[0].data as zlib.InputType).toString('utf-8')
.split('\n');
if (contentParts.length !== 2) {
return res.status(401).json({ error: 'profile.backup.error.signature' });

View File

@ -227,9 +227,9 @@ const applyTemplate = (
} else {
return context === 'html'
? Object.keys(value).map((s) => `<li><strong>${s}:</strong> ${value[s]}</li>`)
.join('')
.join('')
: Object.keys(value).map((s) => ` - ${s}: ${value[s]}`)
.join('\n');
.join('\n');
}
}
if (key.startsWith('nl2br:')) {

View File

@ -91,9 +91,9 @@ export class Example {
: pronoun.config.pronunciation?.ipa && morpheme
? morpheme.split('').map((c) => [' ', ',', '.', ':', ';', '', '-'].includes(c)
? c
: `/${c}/`)
.join('')
? c
: `/${c}/`)
.join('')
: morpheme
;
};
@ -237,8 +237,8 @@ export class Source implements Entry {
this.year = year;
this.fragments = fragments
? fragments.replace(/\|/g, '\n').replace(/\\@/g, '###')
.split('@')
.map((x) => x.replace(/###/g, '@'))
.split('@')
.map((x) => x.replace(/###/g, '@'))
: [];
this.comment = comment;
this.link = link;