|
After Width: | Height: | Size: 444 KiB |
@ -0,0 +1,511 @@ |
|||
If you come from plain ASP.NET Core and open your first ABP solution, the initial reaction is often the same: *why are there so many projects, layers, DTOs, interfaces and base classes just to build a simple feature?* 🤔 |
|||
|
|||
That reaction is normal 👌 |
|||
|
|||
ABP Framework gives you a lot on day one: modularity, DDD-friendly structure, application services, repositories, auto API controllers, authorization, auditing, multi-tenancy and UI integration patterns. |
|||
The upside is speed and consistency on serious business apps. |
|||
The downside is that beginners can hit an abstraction wall before they see the payoff. |
|||
|
|||
After reviewing recent discussions, one pattern is clear: most developers do not struggle with C# or ASP.NET Core itself. |
|||
They struggle with *where code is supposed to go* in ABP and *which parts are essential versus optional*. |
|||
|
|||
In this post, I'll focus on that gap. If you are new to ABP, here is what actually helps. |
|||
|
|||
## The biggest learning barrier is not syntax! It is responsibility boundaries |
|||
|
|||
The hardest part for most newcomers is not learning one more framework API. |
|||
It's understanding the architectural split: |
|||
|
|||
- What belongs in the **Domain** layer? |
|||
- What belongs in **Application** services? |
|||
- Why do **DTOs** exist if you already have entities? |
|||
- When do you need a **repository**? |
|||
- Why are there separate projects like `Application.Contracts`, `Domain.Shared` and `EntityFrameworkCore`? |
|||
|
|||
In plain ASP.NET Core apps, many developers put a lot of this logic in controllers, services or even EF Core models. |
|||
ABP forces you toward clearer separation. |
|||
|
|||
A practical mental model: |
|||
|
|||
- **Entity / Aggregate Root**: business state and core invariants |
|||
- **Domain Service**: domain logic that does not naturally belong to a single entity |
|||
- **Repository**: persistence access for aggregates |
|||
- **Application Service**: use-case orchestration, authorization, DTO mapping, transaction boundary |
|||
- **DTO**: data contract for input/output |
|||
- **UI / API layer**: presentation concerns only |
|||
|
|||
> That sounds clean on paper... |
|||
> The confusion starts when you build something real 🥴 |
|||
|
|||
### A simple example: where should validation go? |
|||
|
|||
Suppose you are creating an `Order`. |
|||
|
|||
- If the rule is "order total must be greater than zero," **that's domain logic**. |
|||
- If the rule is "only users with the Orders.Create permission can create an order," **that belongs in the application layer**. |
|||
- If the rule is "customer name is required on this page," **that may exist in DTO validation too**. |
|||
|
|||
New ABP developers often ask which layer owns relationships, validation and business rules. |
|||
|
|||
> The honest answer is: different validation lives in different places. |
|||
|
|||
That is the first ABP lesson worth learning👍 |
|||
|
|||
|
|||
|
|||
 |
|||
|
|||
## Why ABP Feels Heavy at First! |
|||
|
|||
**ABP is opinionated**. It's not trying to be the thinnest possible wrapper over ASP.NET Core. |
|||
|
|||
What beginners usually experience as "**too much structure**" comes from 4 things: |
|||
|
|||
### 1. Project and layer count |
|||
|
|||
A typical ABP solution can include: |
|||
|
|||
- `Domain` |
|||
- `Domain.Shared` |
|||
- `Application` |
|||
- `Application.Contracts` |
|||
- `EntityFrameworkCore` |
|||
- `HttpApi` |
|||
- `HttpApi.Client` |
|||
- UI project such as MVC, Razor Pages, Blazor or Angular |
|||
- Test projects |
|||
|
|||
For a small feature, that can feel excessive... **For a long-lived business system, it starts to make sense**. |
|||
|
|||
### 2. Generated convenience hides the mechanics |
|||
|
|||
ABP can generate a lot of CRUD plumbing and generic base classes like `CrudAppService` reduce repetitive code. |
|||
That's useful, but it can also hide how things connect. |
|||
|
|||
<u>A beginner sees a working page and API without fully understanding:</u> |
|||
|
|||
- how the application service is exposed as an API |
|||
- where repository methods are coming from |
|||
- how DTO mapping works |
|||
- why the UI calls application contracts instead of entities |
|||
|
|||
### 3. DDD terminology raises the entry cost |
|||
|
|||
You do not need to become a DDD master to use ABP well... But ABP definitely assumes some familiarity with: |
|||
|
|||
- entities |
|||
- aggregate roots |
|||
- repositories |
|||
- value objects |
|||
- domain services |
|||
- bounded contexts and modules |
|||
|
|||
If those ideas are new, ABP can feel harder than it really is. |
|||
|
|||
### 4. UI integration is not always obvious |
|||
|
|||
Newcomers also get stuck on the end-to-end flow: |
|||
|
|||
1. User clicks a button on a Razor Page or Blazor page |
|||
2. UI sends data to an application service or HTTP API |
|||
3. Application service validates permissions and input |
|||
4. Domain and repository code runs |
|||
5. DTO comes back to the UI |
|||
|
|||
Once you understand that flow, ABP becomes much more predictable. |
|||
|
|||
## Start with CRUD, but do not stop there |
|||
|
|||
A common question is whether beginners should start with simple CRUD or jump straight into a realistic business module. |
|||
|
|||
My view: **start with CRUD, then quickly move to a business feature with real rules**. |
|||
|
|||
### Why CRUD is the right first step |
|||
|
|||
CRUD teaches the ABP basics with low cognitive load: |
|||
|
|||
- project structure |
|||
- entity definition |
|||
- DTOs |
|||
- repositories |
|||
- application services |
|||
- permissions |
|||
- UI page wiring |
|||
- migrations and database updates |
|||
|
|||
This is why the [ABP BookStore tutorial](https://abp.io/docs/latest/tutorials/book-store) is a useful starting point. |
|||
|
|||
### Why CRUD alone is not enough |
|||
|
|||
Pure CRUD can give you a false sense of understanding. |
|||
|
|||
A generated Create / Read / Update / Delete screen does not force you to deal with: |
|||
|
|||
- aggregate boundaries |
|||
- child collections |
|||
- business invariants |
|||
- cross-entity rules |
|||
- domain services |
|||
- richer authorization scenarios |
|||
- multi-tenancy behavior |
|||
- auditing decisions |
|||
|
|||
Those are the areas where ABP starts to justify its structure. |
|||
|
|||
### A better learning sequence |
|||
|
|||
Use this progression: |
|||
|
|||
1. Build one very small CRUD module |
|||
2. Rebuild part of it manually instead of relying only on generation |
|||
3. Build one realistic business module with at least one non-trivial rule |
|||
4. Add authorization, validation and a relationship |
|||
5. Add tests around the domain or application service |
|||
|
|||
That path keeps the early win while exposing the real architecture. |
|||
|
|||
|
|||
|
|||
 |
|||
|
|||
## Generated CRUD vs manual CRUD: learn both |
|||
|
|||
This is one of the most useful mindset shifts for ABP beginners. |
|||
|
|||
**Generated CRUD is for productivity. Manual CRUD is for understanding.** |
|||
|
|||
You need both. |
|||
|
|||
### When generated CRUD helps |
|||
|
|||
ABP Suite and ABP base services can save time when the feature is mostly standard admin functionality: |
|||
|
|||
- back-office reference data |
|||
- simple management screens |
|||
- low-risk maintenance pages |
|||
- conventional DTO/entity flows |
|||
|
|||
If the goal is shipping business software efficiently, generated code is not cheating. It is leverage. |
|||
|
|||
### When manual implementation matters |
|||
|
|||
You should manually implement at least one feature end to end so you understand: |
|||
|
|||
- how `CrudAppService` reduces boilerplate |
|||
- what repository methods are doing |
|||
- where validation belongs |
|||
- how authorization is applied |
|||
- how auto API controllers expose application services |
|||
|
|||
A lot of Reddit confusion around ABP comes from learning generated patterns before understanding the underlying manual version. |
|||
|
|||
### A good exercise |
|||
|
|||
Build `Product` management twice: |
|||
|
|||
- First with `CrudAppService` |
|||
- Then manually with custom application service methods and domain rules |
|||
|
|||
Compare both implementations. That single exercise teaches more than reading docs for hours. |
|||
|
|||
## Which DDD patterns real ABP teams often simplify |
|||
|
|||
This is where many beginners get relief: **not every ABP project uses full-strength DDD all the time.** |
|||
|
|||
Real teams often simplify the model, especially early on. |
|||
|
|||
### Patterns teams commonly keep |
|||
|
|||
These tend to deliver value quickly in ABP: |
|||
|
|||
- clear application service boundaries |
|||
- entities and aggregate roots |
|||
- repositories |
|||
- DTO separation |
|||
- modular structure |
|||
- permission-based authorization |
|||
|
|||
### Patterns teams often delay or reduce |
|||
|
|||
These are useful in the right context, but many teams do not force them into every feature: |
|||
|
|||
- dedicated domain services for very simple logic |
|||
- value objects for every tiny concept |
|||
- specification pattern everywhere |
|||
- excessive interface layering where no variation is expected |
|||
- over-splitting modules too early |
|||
|
|||
### A practical rule of thumb |
|||
|
|||
Use the simplest thing that preserves clarity. |
|||
|
|||
For example: |
|||
|
|||
- If a rule is trivial and local to one use case, putting it in an application service may be fine. |
|||
- If a rule protects business invariants and must hold regardless of caller, move it into the domain model. |
|||
- If a concept has behavior and invariants of its own, a value object may help. |
|||
- If it is just a shared enum or constant, `Domain.Shared` is often enough. |
|||
|
|||
ABP supports rich DDD patterns, but it does not require ceremony for ceremony's sake. |
|||
|
|||
|
|||
|
|||
 |
|||
|
|||
## A concrete “ASP.NET Core to ABP” learning path |
|||
|
|||
If I had to design a practical learning path for experienced ASP.NET Core developers, it would look like this. |
|||
|
|||
### Step 1: Know what ABP is adding on top of ASP.NET Core |
|||
|
|||
Before touching templates, be comfortable with: |
|||
|
|||
- dependency injection |
|||
- configuration |
|||
- middleware basics |
|||
- EF Core or MongoDB |
|||
- controllers or Razor Pages or Blazor basics |
|||
- validation and authorization in ASP.NET Core |
|||
|
|||
> ABP builds on top of these. It does not replace the need to understand them. |
|||
|
|||
### Step 2: Learn the ABP solution structure |
|||
|
|||
Let's see each layer's goal: |
|||
|
|||
- `Domain`: core business model |
|||
- `Domain.Shared`: shared enums, constants, localization resources, simple shared types |
|||
- `Application.Contracts`: DTOs and service contracts |
|||
- `Application`: use cases and orchestration |
|||
- `EntityFrameworkCore`: database mappings and repository implementation details |
|||
- `HttpApi`: API exposure |
|||
- UI project: user interaction |
|||
|
|||
### Step 3: Understand modules and dependencies |
|||
|
|||
ABP's modularity is a major feature, but beginners often treat modules like folders with extra steps. |
|||
|
|||
They are more than that. |
|||
|
|||
A module defines: |
|||
|
|||
- dependency boundaries |
|||
- service registration scope |
|||
- reusable feature packaging |
|||
- initialization points via module lifecycle methods and `[DependsOn]` |
|||
|
|||
At first, use modules as organizational boundaries inside a modular monolith. Do not rush into distributed or microservice-style decomposition. |
|||
|
|||
### Step 4: Build one CRUD feature the ABP way |
|||
|
|||
Create a simple feature such as Books, Products or Categories. |
|||
|
|||
Make sure you understand: |
|||
|
|||
- entity creation |
|||
- migration flow |
|||
- DTO mapping |
|||
- application service methods |
|||
- permission checks |
|||
- how the UI or API calls the application layer |
|||
|
|||
### Step 5: Rebuild one part manually |
|||
|
|||
Now remove the training wheels for one feature. |
|||
|
|||
Instead of only leaning on base classes, explicitly write: |
|||
|
|||
- a custom application service method |
|||
- a custom repository query if needed |
|||
- domain validation or invariants |
|||
- a tailored DTO instead of generic CRUD shapes |
|||
|
|||
This is where ABP usually clicks. |
|||
|
|||
### Step 6: Build a realistic business module |
|||
|
|||
A good example is `Order Management`, `Leave Requests` or `Inventory Transfer`. |
|||
|
|||
Choose something with: |
|||
|
|||
- one-to-many relationship |
|||
- status transitions |
|||
- authorization rules |
|||
- at least one business invariant |
|||
- audit visibility |
|||
|
|||
That reveals why ABP's layered structure exists. |
|||
|
|||
### Step 7: Add built-in ABP concerns on purpose |
|||
|
|||
ABP shines when you use its built-in platform features intentionally: |
|||
|
|||
- authorization |
|||
- auditing |
|||
- validation |
|||
- localization |
|||
- multi-tenancy |
|||
- settings and permissions |
|||
|
|||
Do not treat these as advanced extras. They are part of the framework's real value. |
|||
|
|||
### Step 8: Learn testing by layer |
|||
|
|||
Even if you do not build a full testing strategy immediately, understand the testing shape: |
|||
|
|||
- domain tests for invariants and business rules |
|||
- application tests for use cases and permissions |
|||
- integration tests for persistence and module wiring |
|||
|
|||
A lot of ABP's architecture pays off once you start testing behavior in isolation. |
|||
|
|||
## A small example of responsibility split |
|||
|
|||
Here is a deliberately small example to make the layering less abstract. |
|||
|
|||
Suppose you have a leave request system. |
|||
|
|||
**Domain** concerns: |
|||
|
|||
- a leave request cannot be approved after rejection |
|||
- end date cannot be before start date |
|||
- total leave days must be positive |
|||
|
|||
**Application** concerns: |
|||
|
|||
- only managers can approve requests |
|||
- map input DTO to entity operations |
|||
- return a DTO shaped for the UI |
|||
- coordinate repository access and unit of work |
|||
|
|||
**UI** concerns: |
|||
|
|||
- disable approve button when user lacks permission |
|||
- show validation messages |
|||
- render status badges and filters |
|||
|
|||
That split is the heart of ABP. Once you start seeing features this way, the framework becomes much easier to navigate. |
|||
|
|||
## When to use ABP and when not to |
|||
|
|||
**ABP is powerful, but <u>it is not automatically the right default</u> for every ASP.NET Core project.** |
|||
|
|||
### When to use ABP |
|||
|
|||
ABP is a strong fit when you are building: |
|||
|
|||
- line-of-business applications |
|||
- admin-heavy platforms |
|||
- SaaS or multi-tenant systems |
|||
- modular monoliths that may grow over time |
|||
- systems that need built-in authorization, auditing, localization and consistent conventions |
|||
- teams that benefit from standardized architecture |
|||
|
|||
### When NOT to use ABP |
|||
|
|||
ABP may be excessive in the following situations: |
|||
|
|||
- a tiny API with minimal business logic |
|||
- a short-lived internal tool where framework structure would dominate the workload |
|||
- a team with no interest in layered architecture or DDD-style thinking |
|||
- a highly custom architecture where ABP conventions would mostly be bypassed |
|||
|
|||
The main cost of ABP is not performance or syntax 🤜 It is **architectural overhead**. |
|||
<u>If the app is too small, that overhead may not pay back.</u> |
|||
|
|||
--- |
|||
|
|||
|
|||
|
|||
## Common mistakes new ABP developers make |
|||
|
|||
These are the mistakes I see most often in early ABP learning. |
|||
|
|||
### 1. Trying to understand everything before building anything |
|||
|
|||
Do not wait until every project, package and abstraction makes sense. Build one feature first. |
|||
|
|||
### 2. Using generated code without reading it |
|||
|
|||
Generated CRUD is useful, but inspect what it created. Otherwise you will stay dependent on tooling. |
|||
|
|||
### 3. Forcing textbook DDD into every feature |
|||
|
|||
Not every screen needs aggregates, value objects, domain services and custom repositories all at once. |
|||
|
|||
### 4. Putting all business logic in application services |
|||
|
|||
This works for a while, but you eventually lose domain consistency. Protect important invariants closer to the domain model. |
|||
|
|||
### 5. Splitting into too many modules too early |
|||
|
|||
Start with a modular monolith mindset. Extract boundaries when they become meaningful. |
|||
|
|||
### 6. Ignoring built-in ABP features |
|||
|
|||
If you manually rebuild authorization, auditing or tenant-aware behavior without understanding ABP's built-ins, you are fighting the framework. |
|||
|
|||
|
|||
|
|||
## The learning path I would actually recommend to a new team |
|||
|
|||
If a team asked me for a practical ABP onboarding sequence, I would keep it simple: |
|||
|
|||
### 📚 Week 1: Basics and orientation |
|||
|
|||
- Review ABP solution structure |
|||
- Build the BookStore-style tutorial once |
|||
- Identify what each layer is responsible for |
|||
|
|||
### 📚 Week 2: Manual feature implementation |
|||
|
|||
- Build one small module manually |
|||
- Avoid too much generation |
|||
- Trace one request from UI to application service to repository to database |
|||
|
|||
### 📚 Week 3: Real business rules |
|||
|
|||
- Add relationships |
|||
- Add authorization |
|||
- Add a workflow or state transition |
|||
- Write tests for a few business rules |
|||
|
|||
### 📚 Week 4: Productivity and conventions |
|||
|
|||
- Reintroduce generated tooling where it saves time |
|||
- Standardize module patterns |
|||
- Decide which DDD patterns the team will use by default and which are optional |
|||
|
|||
That sequence teaches both the architecture and the productivity side of ABP. |
|||
|
|||
--- |
|||
|
|||
|
|||
|
|||
## Final perspective: learn the intent, not just the template |
|||
|
|||
ABP can feel complicated when approached as a collection of projects and base classes. It gets easier when you see the intent behind the structure: |
|||
|
|||
- protect business rules |
|||
- standardize application boundaries |
|||
- make common enterprise features reusable |
|||
- keep large apps maintainable |
|||
|
|||
If you are new to ABP, do not aim to master every pattern immediately. Aim to answer these four questions clearly for each feature: |
|||
|
|||
- What is the business rule? |
|||
- Which layer owns it? |
|||
- What data crosses the boundary? |
|||
- Which ABP feature already solves part of this problem? |
|||
|
|||
Once those answers become natural, ABP stops feeling heavy and starts feeling productive. |
|||
|
|||
--- |
|||
|
|||
## As a Summary |
|||
|
|||
- **The biggest ABP learning barrier is** understanding responsibility boundaries between domain, application services, DTOs, repositories and UI. |
|||
- **Start with a small CRUD feature**, but move quickly to a realistic business module with rules, relationships and permissions. |
|||
- **Learn both generated and manual CRUD**; one gives productivity, the other gives understanding. |
|||
- Real ABP teams often simplify DDD and adopt advanced patterns **only when the complexity justifies them**. |
|||
- **The best learning path is ASP.NET Core basics first**, then ABP layers, one manual feature, one real module and built-in features like authorization and auditing. |
|||
|
After Width: | Height: | Size: 1010 KiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 145 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
@ -0,0 +1,314 @@ |
|||
# OSS Sustainability in .NET: Commercialization of Key Projects & What’s Next |
|||
|
|||
For years, many .NET teams treated core open source libraries as stable background infrastructure: useful, battle-tested, and effectively free forever. That assumption is starting to break. |
|||
|
|||
When widely used projects like IdentityServer, AutoMapper, and MediatR move toward commercial or more restrictive licensing, the discussion is no longer just about one package or one maintainer. It becomes a bigger question about how the .NET ecosystem pays for the software it depends on. |
|||
|
|||
This matters because modern .NET applications are built on layers of third-party dependencies. If one of those layers changes its pricing, support model, or license terms, the impact is not theoretical. It affects procurement, architecture, upgrade strategy, compliance, and long-term maintenance. |
|||
|
|||
This article looks at what these commercialization moves signal, why they are happening, where the community friction comes from, and what development teams should do next. |
|||
|
|||
## The pattern is no longer isolated |
|||
|
|||
A few years ago, licensing changes in .NET could still be dismissed as exceptions. That is getting harder. |
|||
|
|||
Several important projects now illustrate the same underlying tension: software that became critical infrastructure was often maintained with a funding model better suited to side projects than production-critical systems. |
|||
|
|||
### Duende IdentityServer is the clearest example |
|||
|
|||
The IdentityServer story is probably the most visible case in .NET. What started as a widely adopted open source identity solution evolved into Duende IdentityServer, which requires paid licenses for production use, while free usage is limited to development, testing, personal projects, or qualifying community scenarios. |
|||
|
|||
More recently, Duende moved again with its v8 generation and introduced a more tiered licensing model, including Lite, Standard, Advanced, and Custom options, plus paid add-ons for additional capabilities. At the same time, support windows are clearly tied to .NET versions, making the product feel even more like managed commercial infrastructure than community software. |
|||
|
|||
That is not necessarily a bad thing. Identity is security-critical software. It is expensive to maintain, expensive to support, and risky to underfund. But it does mark a major shift in expectations for teams that still think of it primarily as an OSS building block. |
|||
|
|||
### AutoMapper and MediatR point to a broader shift |
|||
|
|||
AutoMapper and MediatR are different kinds of libraries, but their direction matters just as much. |
|||
|
|||
These are not niche components. They are deeply embedded in enterprise codebases, tutorials, templates, and architectural conventions. So when they move toward dual licensing, commercial terms, or more restrictive licensing, the message is clear: even highly popular and culturally central .NET libraries may no longer fit the old "free and permissive forever" model. |
|||
|
|||
AutoMapper's move away from .NET Foundation membership after adopting a non-permissive license is especially notable because it highlights a governance boundary. The ecosystem may celebrate OSS, but institutions such as the .NET Foundation still rely on clear licensing rules. Once a project changes those terms, it often changes its place in the ecosystem too. |
|||
|
|||
## Why maintainers are doing this |
|||
|
|||
The easy reaction is to call commercialization a betrayal. The more honest reaction is to admit that many maintainers have been subsidizing the industry for years. |
|||
|
|||
A project can be free for users and still very expensive for its authors. |
|||
|
|||
Maintaining a popular library often means: |
|||
|
|||
- triaging issues from thousands of downstream users |
|||
- keeping up with new .NET releases |
|||
- patching security problems |
|||
- maintaining documentation and samples |
|||
- answering support requests that are really consulting work in disguise |
|||
- dealing with dependency, CI, hosting, and release overhead |
|||
|
|||
Once a library becomes critical infrastructure, users expect reliability similar to commercial software. But expectations usually rise faster than funding. |
|||
|
|||
That imbalance creates a predictable outcome: maintainers either burn out, slow down, seek sponsorship, or commercialize. |
|||
|
|||
### Open source popularity does not automatically create sustainability |
|||
|
|||
This is the part many teams still underestimate. |
|||
|
|||
A package can have massive adoption and still be financially fragile. Downloads, GitHub stars, and conference mentions do not pay for maintenance. In fact, popularity often increases the burden without improving sustainability. |
|||
|
|||
From a maintainer's perspective, commercialization can be a rational correction: |
|||
|
|||
- charge the organizations getting the most value |
|||
- fund long-term maintenance |
|||
- offer support contracts and SLAs |
|||
- justify time spent on roadmap work |
|||
- reduce dependence on unpaid labor |
|||
|
|||
In other words, the move to commercial licensing is often less about greed than about replacing an unrealistic business model. |
|||
|
|||
|
|||
|
|||
 |
|||
|
|||
## Why the community reaction is so mixed |
|||
|
|||
Even if the economics make sense, the backlash is real. And frankly, some of it is justified. |
|||
|
|||
The friction usually comes from the gap between legal reality and social expectation. |
|||
|
|||
Legally, maintainers can often change how future versions are licensed. Socially, users feel that a trusted community dependency has changed the rules after becoming embedded in thousands of systems. |
|||
|
|||
### What bothers teams most |
|||
|
|||
In practice, teams are not only reacting to cost. They are reacting to uncertainty. |
|||
|
|||
The common concerns are familiar: |
|||
|
|||
- unexpected licensing costs appearing in mature products |
|||
- fear of future pricing increases |
|||
- procurement delays for something developers previously installed with `dotnet add package` |
|||
- license compatibility and compliance reviews |
|||
- vendor lock-in around foundational infrastructure |
|||
- migration costs if a team decides to leave later |
|||
- concern that previously core features move behind paid tiers |
|||
|
|||
This is why the strongest reactions usually happen when the library is infrastructural rather than optional. Authentication, mapping, messaging, and mediator patterns sit close to the core of many architectures. Replacing them is possible, but rarely cheap. |
|||
|
|||
### Suddenness matters as much as pricing |
|||
|
|||
A reasonable commercial model can still create anger if the transition feels abrupt. |
|||
|
|||
Teams generally accept that maintainers need funding. What they do not accept as easily is: |
|||
|
|||
- vague roadmap communication |
|||
- surprise license changes |
|||
- unclear grandfathering rules |
|||
- unclear distinctions between old and new versions |
|||
- feature packaging that feels like a trap for existing users |
|||
|
|||
That trust dimension matters. In OSS, the license is not the whole relationship. Predictability is part of the product. |
|||
|
|||
## What this signals for the .NET ecosystem |
|||
|
|||
The larger lesson is not simply that some maintainers want to get paid. It is that the .NET ecosystem is maturing into one where critical libraries are increasingly treated like products, not just repositories. |
|||
|
|||
That has several consequences. |
|||
|
|||
### 1. Dependency selection is now a governance decision |
|||
|
|||
Choosing a package is no longer only a technical choice. |
|||
|
|||
Teams need to ask: |
|||
|
|||
- Who maintains this project? |
|||
- Under what license? |
|||
- Is the current license likely to remain stable? |
|||
- Is there a company behind it? |
|||
- What is the monetization path? |
|||
- How hard would migration be if the terms changed? |
|||
|
|||
This does not mean avoiding all commercially backed OSS. It means evaluating dependencies the same way you evaluate databases, cloud services, or authentication providers. |
|||
|
|||
### 2. Foundation membership and community trust will matter more |
|||
|
|||
When a project leaves a permissive governance environment, it sends a signal, even if the software remains technically strong. |
|||
|
|||
Developers increasingly care about: |
|||
|
|||
- whether governance is independent or company-led |
|||
- whether contribution rights are broad or concentrated |
|||
- whether licensing changes can happen unilaterally |
|||
- whether a community fallback exists if trust breaks down |
|||
|
|||
The .NET Foundation's stance on permissive licensing creates a useful boundary here. It does not solve commercialization, but it helps clarify which projects still fit traditional OSS expectations. |
|||
|
|||
### 3. Forks and alternatives will become more common |
|||
|
|||
When licensing changes upset users, forks appear. That is a normal OSS response. |
|||
|
|||
But forks are not magic. A fork only becomes a real alternative if it can attract: |
|||
|
|||
- active maintainers |
|||
- release discipline |
|||
- user trust |
|||
- documentation |
|||
- a credible long-term roadmap |
|||
|
|||
A reactive fork may help teams buy time, but it does not automatically become sustainable infrastructure. In many cases, the fork inherits the same funding problem that triggered the original commercialization. |
|||
|
|||
## The practical risk for engineering teams |
|||
|
|||
The biggest mistake teams can make is treating this as community drama instead of delivery risk. |
|||
|
|||
If your application depends on a library that changes licensing, the consequences can show up in very concrete ways: |
|||
|
|||
- you may need legal review before your next upgrade |
|||
- procurement may block adoption of a new major version |
|||
- architecture plans may change because premium features alter total cost |
|||
- your support lifecycle may compress if older versions lose support sooner |
|||
- migration work may compete with product roadmap work |
|||
|
|||
This is especially relevant for organizations with long-lived internal platforms or multi-tenant SaaS products, where one dependency can affect dozens of services. |
|||
|
|||
### A realistic example |
|||
|
|||
Imagine a company running an internal platform and several customer-facing .NET applications. |
|||
|
|||
- The identity layer uses IdentityServer. |
|||
- Multiple services use MediatR for application-layer orchestration. |
|||
- Older codebases rely heavily on AutoMapper profiles. |
|||
|
|||
If all three become cost, licensing, or governance concerns at the same time, the company suddenly has a portfolio-level problem rather than a package-level problem. |
|||
|
|||
Now the questions are not just technical: |
|||
|
|||
- Which products justify paid licenses? |
|||
- Which codebases should be migrated away? |
|||
- Which teams absorb the rewrite cost? |
|||
- Which versions remain supportable under current policy? |
|||
|
|||
That is architecture, budgeting, and compliance converging in one decision. |
|||
|
|||
|
|||
|
|||
 |
|||
|
|||
## How teams should respond |
|||
|
|||
Panic is not useful. Blind trust is not useful either. |
|||
|
|||
A better response is to become more deliberate about dependency management. |
|||
|
|||
### Build a dependency review habit |
|||
|
|||
For critical packages, review more than API quality. |
|||
|
|||
Check: |
|||
|
|||
- license type and any production-use restrictions |
|||
- support policy and end-of-support dates |
|||
- governance model |
|||
- release cadence |
|||
- issue responsiveness |
|||
- whether the project has a business sponsor |
|||
- likelihood of future lock-in |
|||
- migration complexity |
|||
|
|||
If a package sits in authentication, authorization, persistence, messaging, or application architecture, the review should be stricter than for a small utility library. |
|||
|
|||
### Categorize dependencies by replacement cost |
|||
|
|||
Not every package deserves the same scrutiny. |
|||
|
|||
A useful model is: |
|||
|
|||
- low replacement cost: small utilities, isolated helpers |
|||
- medium replacement cost: libraries used across one bounded context |
|||
- high replacement cost: foundational cross-cutting libraries used everywhere |
|||
|
|||
Commercialization risk matters most in the third category. If replacing the library means touching every service, pipeline, or authentication flow, that risk belongs on the architecture radar early. |
|||
|
|||
### Budget for critical OSS |
|||
|
|||
Many companies are comfortable paying for cloud hosting but still resist paying for the libraries that shape their actual application architecture. |
|||
|
|||
That mindset is becoming outdated. |
|||
|
|||
If a dependency is business-critical, teams should assume one of these will eventually be required: |
|||
|
|||
- direct licensing fees |
|||
- support subscriptions |
|||
- engineering budget for migration |
|||
- internal effort to maintain an alternative |
|||
|
|||
You will pay somehow. The only real question is whether you pay proactively or reactively. |
|||
|
|||
## When to use commercially backed OSS and when not to |
|||
|
|||
Commercialization is not automatically a reason to avoid a project. |
|||
|
|||
## When to use it |
|||
|
|||
Commercially backed OSS can be a good fit when: |
|||
|
|||
- the project solves a difficult problem better than in-house code |
|||
- the vendor has a strong maintenance and support track record |
|||
- your team values SLAs or formal support channels |
|||
- the cost is small compared to migration or security risk |
|||
- the licensing terms are clear and stable |
|||
- the project sits in an area where reliability matters more than ideological purity |
|||
|
|||
Identity infrastructure is the obvious example. A mature, well-supported identity product may be worth paying for if the alternative is building and maintaining security-sensitive code yourself. |
|||
|
|||
## When NOT to use it |
|||
|
|||
Be cautious when: |
|||
|
|||
- the library is deeply coupled to all services and hard to replace |
|||
- the licensing model is unclear or changes frequently |
|||
- procurement overhead is likely to block upgrades |
|||
- your budget cannot support future commercial terms |
|||
- there is a simpler architectural option with fewer dependencies |
|||
- the library adds convenience more than strategic value |
|||
|
|||
This is where some teams may rethink packages like object mappers or mediator frameworks. If the dependency is mostly ergonomic and the long-term governance risk is rising, simpler code may be the better tradeoff. |
|||
|
|||
## What this means for maintainers, companies, and the community |
|||
|
|||
The ecosystem now needs more honest expectations on all sides. |
|||
|
|||
### For maintainers |
|||
|
|||
If your library underpins production systems, sustainability needs to be part of the strategy early. Commercialization is easier to accept when it is transparent, gradual, and communicated as part of a long-term model rather than a sudden pivot. |
|||
|
|||
### For companies |
|||
|
|||
If your business depends on OSS, treating maintainers as an infinite free resource is no longer credible. Critical dependencies should have owners, budgets, and risk reviews. |
|||
|
|||
### For the .NET community |
|||
|
|||
The community may need to become more selective about what it normalizes as default architecture. If a pattern depends heavily on a few centralized libraries, then a licensing change in one project can ripple widely. Simpler stacks are often more resilient. |
|||
|
|||
## A likely next phase for .NET OSS |
|||
|
|||
The next few years will probably bring more segmentation across the .NET ecosystem. |
|||
|
|||
Expect to see more of this: |
|||
|
|||
- permissive OSS for broad adoption |
|||
- commercial tiers for production-grade support and advanced features |
|||
- stricter license boundaries around enterprise capabilities |
|||
- forks created in response to monetization |
|||
- increased attention to SBOM, compliance, and license scanning |
|||
- more internal architecture reviews before package adoption |
|||
|
|||
That does not mean open source in .NET is weakening. It means the ecosystem is facing the same sustainability pressures seen elsewhere: maintenance is expensive, infrastructure software has real business value, and someone eventually has to fund it. |
|||
|
|||
The healthiest outcome is not pretending commercialization should never happen. It is making sure it happens with predictable governance, fair communication, and realistic expectations from users. |
|||
|
|||
## TL;DR |
|||
|
|||
- Commercialization of key .NET libraries is a sustainability signal, not an isolated incident. |
|||
- Teams should evaluate dependencies by license, governance, support policy, and replacement cost. |
|||
- Commercial OSS can be the right choice for critical infrastructure, especially where support and security matter. |
|||
- The real risk is not paying for software; it is being surprised by cost, lock-in, or migration pressure too late. |
|||
- .NET teams should treat dependency strategy as an architectural and business decision, not just a NuGet decision. |
|||
|
After Width: | Height: | Size: 2.5 MiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 1.4 MiB |
@ -0,0 +1,13 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"GivenTenantIsNotExist": "지정된 테넌트가 존재하지 않습니다: {0}", |
|||
"GivenTenantIsNotAvailable": "지정된 테넌트를 사용할 수 없습니다: {0}", |
|||
"Tenant": "테넌트", |
|||
"Switch": "전환", |
|||
"Name": "이름", |
|||
"SwitchTenantHint": "호스트 측으로 전환하려면 이름 필드를 비워 두세요.", |
|||
"SwitchTenant": "테넌트 전환", |
|||
"NotSelected": "선택되지 않음" |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"Volo.Authorization:010001": "권한 부여에 실패했습니다! 지정된 정책에서 권한이 부여되지 않았습니다.", |
|||
"Volo.Authorization:010002": "권한 부여에 실패했습니다! 지정된 정책에서 권한이 부여되지 않았습니다: {PolicyName}", |
|||
"Volo.Authorization:010003": "권한 부여에 실패했습니다! 지정된 리소스에 대해 정책에서 권한이 부여되지 않았습니다: {ResourceName}", |
|||
"Volo.Authorization:010004": "권한 부여에 실패했습니다! 지정된 리소스에 대해 요구 사항이 충족되지 않았습니다: {ResourceName}", |
|||
"Volo.Authorization:010005": "권한 부여에 실패했습니다! 지정된 리소스에 대해 요구 사항들이 충족되지 않았습니다: {ResourceName}" |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"MaxResultCountExceededExceptionMessage": "{0}은(는) {1}보다 클 수 없습니다! 더 많은 결과를 허용하려면 서버 측에서 {2}.{3}을(를) 늘리십시오." |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"DisplayName:Abp.Mailing.DefaultFromAddress": "기본 발신자 주소", |
|||
"DisplayName:Abp.Mailing.DefaultFromDisplayName": "기본 발신자 표시 이름", |
|||
"DisplayName:Abp.Mailing.Smtp.Host": "호스트", |
|||
"DisplayName:Abp.Mailing.Smtp.Port": "포트", |
|||
"DisplayName:Abp.Mailing.Smtp.UserName": "사용자 이름", |
|||
"DisplayName:Abp.Mailing.Smtp.Password": "비밀번호", |
|||
"DisplayName:Abp.Mailing.Smtp.Domain": "도메인", |
|||
"DisplayName:Abp.Mailing.Smtp.EnableSsl": "SSL 사용", |
|||
"DisplayName:Abp.Mailing.Smtp.UseDefaultCredentials": "기본 자격 증명 사용", |
|||
"Description:Abp.Mailing.DefaultFromAddress": "기본 발신자 주소입니다.", |
|||
"Description:Abp.Mailing.DefaultFromDisplayName": "기본 발신자 표시 이름입니다.", |
|||
"Description:Abp.Mailing.Smtp.Host": "SMTP 통신에 사용되는 호스트 이름 또는 IP 주소입니다.", |
|||
"Description:Abp.Mailing.Smtp.Port": "SMTP 통신에 사용되는 포트입니다.", |
|||
"Description:Abp.Mailing.Smtp.UserName": "자격 증명에 연결된 사용자 이름입니다.", |
|||
"Description:Abp.Mailing.Smtp.Password": "자격 증명에 연결된 사용자 이름의 비밀번호입니다.", |
|||
"Description:Abp.Mailing.Smtp.Domain": "자격 증명을 인증하는 도메인 또는 컴퓨터 이름입니다.", |
|||
"Description:Abp.Mailing.Smtp.EnableSsl": "SmtpClient가 SSL(Secure Sockets Layer)을 사용하여 연결을 암호화할지 여부입니다.", |
|||
"Description:Abp.Mailing.Smtp.UseDefaultCredentials": "요청과 함께 DefaultCredentials를 전송할지 여부입니다.", |
|||
"TextTemplate:StandardEmailTemplates.Layout": "기본 이메일 레이아웃 템플릿", |
|||
"TextTemplate:StandardEmailTemplates.Message": "이메일용 단순 메시지 템플릿" |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"InternalServerErrorMessage": "요청을 처리하는 동안 내부 오류가 발생했습니다!", |
|||
"ValidationErrorMessage": "요청이 유효하지 않습니다!", |
|||
"ValidationNarrativeErrorMessageTitle": "유효성 검사 중 다음 오류가 발견되었습니다.", |
|||
"DefaultErrorMessage": "오류가 발생했습니다!", |
|||
"DefaultErrorMessageDetail": "서버에서 오류 세부 정보를 보내지 않았습니다.", |
|||
"DefaultErrorMessage401": "인증되지 않았습니다!", |
|||
"DefaultErrorMessage401Detail": "이 작업을 수행하려면 로그인해야 합니다.", |
|||
"DefaultErrorMessage403": "권한이 없습니다!", |
|||
"DefaultErrorMessage403Detail": "이 작업을 수행할 권한이 없습니다!", |
|||
"DefaultErrorMessage404": "리소스를 찾을 수 없습니다!", |
|||
"DefaultErrorMessage404Detail": "서버에서 요청한 리소스를 찾을 수 없습니다!", |
|||
"EntityNotFoundErrorMessage": "{0} 엔터티 중 ID가 {1}인 항목이 없습니다!", |
|||
"EntityNotFoundErrorMessageWithoutId": "{0} 엔터티가 없습니다!", |
|||
"AbpDbConcurrencyErrorMessage": "제출한 데이터가 이미 다른 사용자에 의해 변경되었습니다. 변경 사항을 취소하고 다시 시도해 주세요.", |
|||
"Error": "오류", |
|||
"UnhandledException": "처리되지 않은 예외가 발생했습니다!", |
|||
"Authorizing": "권한을 확인하는 중…", |
|||
"401Message": "인증되지 않음", |
|||
"403Message": "접근 금지", |
|||
"404Message": "페이지를 찾을 수 없음", |
|||
"500Message": "내부 서버 오류", |
|||
"403MessageDetail": "이 작업을 수행할 권한이 없습니다!", |
|||
"404MessageDetail": "죄송합니다. 이 주소에 해당하는 페이지가 없습니다.", |
|||
"Unauthorized": "인증되지 않음", |
|||
"invalid_token": "유효하지 않은 토큰", |
|||
"SessionExpired": "세션이 만료되었습니다. 애플리케이션을 계속 사용하려면 다시 로그인해 주세요." |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"Volo.Feature:010001": "기능이 활성화되지 않았습니다: {FeatureName}", |
|||
"Volo.Feature:010002": "필수 기능이 활성화되지 않았습니다. 다음 기능을 모두 활성화해야 합니다: {FeatureNames}", |
|||
"Volo.Feature:010003": "필수 기능이 활성화되지 않았습니다. 다음 기능 중 하나 이상을 활성화해야 합니다: {FeatureNames}" |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"Volo.GlobalFeature:010001": "'{ServiceName}' 서비스에서 '{GlobalFeatureName}' 기능을 활성화해야 합니다." |
|||
} |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"DisplayName:Abp.Ldap.Ldaps": "SSL을 통한 LDAP", |
|||
"Description:Abp.Ldap.Ldaps": "SSL을 통한 LDAP", |
|||
"DisplayName:Abp.Ldap.ServerHost": "서버 호스트", |
|||
"Description:Abp.Ldap.ServerHost": "서버 호스트", |
|||
"DisplayName:Abp.Ldap.ServerPort": "서버 포트", |
|||
"Description:Abp.Ldap.ServerPort": "서버 포트", |
|||
"DisplayName:Abp.Ldap.BaseDc": "기본 도메인 구성 요소", |
|||
"Description:Abp.Ldap.BaseDc": "기본 도메인 구성 요소", |
|||
"DisplayName:Abp.Ldap.Domain": "도메인", |
|||
"Description:Abp.Ldap.Domain": "도메인", |
|||
"DisplayName:Abp.Ldap.UserName": "사용자 이름", |
|||
"Description:Abp.Ldap.UserName": "사용자 이름", |
|||
"DisplayName:Abp.Ldap.Password": "비밀번호", |
|||
"Description:Abp.Ldap.Password": "비밀번호" |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"DisplayName:Abp.Localization.DefaultLanguage": "기본 언어", |
|||
"Description:Abp.Localization.DefaultLanguage": "애플리케이션의 기본 언어입니다." |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"TenantNotFoundMessage": "테넌트를 찾을 수 없습니다!", |
|||
"TenantNotFoundDetails": "다음 테넌트 ID 또는 이름에 해당하는 테넌트가 없습니다: {0}", |
|||
"TenantNotActiveMessage": "테넌트가 활성 상태가 아닙니다!", |
|||
"TenantNotActiveDetails": "다음 테넌트 ID 또는 이름에 해당하는 테넌트가 활성 상태가 아닙니다: {0}" |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"DisplayName:Abp.Timing.Timezone": "시간대", |
|||
"Description:Abp.Timing.Timezone": "애플리케이션 시간대" |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"Menu:Administration": "관리" |
|||
} |
|||
} |
|||
@ -0,0 +1,68 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"Languages": "언어", |
|||
"AreYouSure": "계속하시겠습니까?", |
|||
"Cancel": "취소", |
|||
"Clear": "지우기", |
|||
"Yes": "예", |
|||
"No": "아니요", |
|||
"Ok": "확인", |
|||
"Close": "닫기", |
|||
"Save": "저장", |
|||
"SavingWithThreeDot": "저장 중...", |
|||
"Actions": "작업", |
|||
"Delete": "삭제", |
|||
"CreatedSuccessfully": "생성되었습니다.", |
|||
"SavedSuccessfully": "저장되었습니다.", |
|||
"DeletedSuccessfully": "삭제되었습니다.", |
|||
"Edit": "편집", |
|||
"Refresh": "새로 고침", |
|||
"Language": "언어", |
|||
"LoadMore": "더 보기", |
|||
"ProcessingWithThreeDot": "처리 중...", |
|||
"LoadingWithThreeDot": "불러오는 중...", |
|||
"Welcome": "환영합니다.", |
|||
"Login": "로그인", |
|||
"Register": "회원가입", |
|||
"Logout": "로그아웃", |
|||
"Submit": "제출", |
|||
"Back": "뒤로", |
|||
"PagerSearch": "검색", |
|||
"PagerNext": "다음", |
|||
"PagerPrevious": "이전", |
|||
"PagerFirst": "처음", |
|||
"PagerLast": "마지막", |
|||
"PagerInfo": "총 _TOTAL_개 항목 중 _START_~_END_개를 표시합니다.", |
|||
"PagerInfo{0}{1}{2}": "총 {2}개 항목 중 {0}~{1}개를 표시합니다.", |
|||
"PagerInfoEmpty": "총 0개 항목 중 0~0개를 표시합니다.", |
|||
"PagerInfoFiltered": "(총 _MAX_개 항목에서 필터링됨)", |
|||
"NoDataAvailableInDatatable": "사용 가능한 데이터가 없습니다.", |
|||
"ErrorLoadingDatatable": "요청 중 오류가 발생했습니다. 자세한 내용은 메시지를 확인하십시오.", |
|||
"Total": "전체", |
|||
"Selected": "선택됨", |
|||
"PagerShowMenuEntries": "_MENU_개 항목 표시", |
|||
"DatatableActionDropdownDefaultText": "작업", |
|||
"ChangePassword": "비밀번호 변경", |
|||
"PersonalInfo": "내 프로필", |
|||
"AreYouSureYouWantToCancelEditingWarningMessage": "저장하지 않은 변경 사항이 있습니다.", |
|||
"GoHomePage": "홈페이지로 이동", |
|||
"GoBack": "뒤로 이동", |
|||
"Search": "검색", |
|||
"ItemWillBeDeletedMessageWithFormat": "{0}이(가) 삭제됩니다!", |
|||
"ItemWillBeDeletedMessage": "이 항목이 삭제됩니다!", |
|||
"ManageYourAccount": "계정 관리", |
|||
"OthersGroup": "기타", |
|||
"Today": "오늘", |
|||
"Apply": "적용", |
|||
"InternetConnectionInfo": "현재 인터넷에 연결되어 있지 않아 작업을 수행할 수 없습니다.", |
|||
"CopiedToTheClipboard": "클립보드에 복사되었습니다.", |
|||
"AddNew": "새로 추가", |
|||
"ProfilePicture": "프로필 사진", |
|||
"Theme": "테마", |
|||
"NotAssigned": "할당되지 않음", |
|||
"EntityActionsDisabledTooltip": "작업을 수행할 권한이 없습니다.", |
|||
"ResourcePermissions": "권한", |
|||
"ShowPassword": "비밀번호 표시" |
|||
} |
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"'{0}' and '{1}' do not match.": "'{0}'와(과) '{1}'이(가) 일치하지 않습니다.", |
|||
"The {0} field is not a valid credit card number.": "{0} 필드는 유효한 신용카드 번호가 아닙니다.", |
|||
"{0} is not valid.": "{0}은(는) 유효하지 않습니다.", |
|||
"The {0} field is not a valid e-mail address.": "{0} 필드는 유효한 이메일 주소가 아닙니다.", |
|||
"The {0} field only accepts files with the following extensions: {1}": "{0} 필드는 다음 확장자를 가진 파일만 허용합니다: {1}", |
|||
"The field {0} must be a string or array type with a maximum length of '{1}'.": "{0} 필드는 최대 길이가 '{1}'인 문자열 또는 배열 형식이어야 합니다.", |
|||
"The field {0} must be a string or array type with a minimum length of '{1}'.": "{0} 필드는 최소 길이가 '{1}'인 문자열 또는 배열 형식이어야 합니다.", |
|||
"The {0} field is not a valid phone number.": "{0} 필드는 유효한 전화번호가 아닙니다.", |
|||
"The field {0} must be between {1} and {2}.": "{0} 필드는 {1}에서 {2} 사이여야 합니다.", |
|||
"The field {0} must match the regular expression '{1}'.": "{0} 필드는 정규식 '{1}'과(와) 일치해야 합니다.", |
|||
"The {0} field is required.": "{0} 필드는 필수입니다.", |
|||
"The field {0} must be a string with a maximum length of {1}.": "{0} 필드는 최대 길이가 {1}인 문자열이어야 합니다.", |
|||
"The field {0} must be a string with a minimum length of {2} and a maximum length of {1}.": "{0} 필드는 최소 길이가 {2}, 최대 길이가 {1}인 문자열이어야 합니다.", |
|||
"The {0} field is not a valid fully-qualified http, https, or ftp URL.": "{0} 필드는 유효한 완전한 형식의 http, https 또는 ftp URL이 아닙니다.", |
|||
"The field {0} is invalid.": "{0} 필드가 유효하지 않습니다.", |
|||
"The value '{0}' is invalid.": "값 '{0}'은(는) 유효하지 않습니다.", |
|||
"The field {0} must be a number.": "{0} 필드는 숫자여야 합니다.", |
|||
"The field must be a number.": "이 필드는 숫자여야 합니다.", |
|||
"ThisFieldIsNotAValidCreditCardNumber.": "이 필드는 유효한 신용카드 번호가 아닙니다.", |
|||
"ThisFieldIsNotValid.": "이 필드는 유효하지 않습니다.", |
|||
"ThisFieldIsNotAValidEmailAddress.": "이 필드는 유효한 이메일 주소가 아닙니다.", |
|||
"ThisFieldOnlyAcceptsFilesWithTheFollowingExtensions:{0}": "이 필드는 다음 확장자를 가진 파일만 허용합니다: {0}", |
|||
"ThisFieldMustBeAStringOrArrayTypeWithAMaximumLengthOf{0}": "이 필드는 최대 '{0}'자여야 합니다.", |
|||
"ThisFieldMustBeAStringOrArrayTypeWithAMinimumLengthOf{0}": "이 필드는 최소 '{0}'자여야 합니다.", |
|||
"ThisFieldIsNotAValidPhoneNumber.": "이 필드는 유효한 전화번호가 아닙니다.", |
|||
"ThisFieldMustBeBetween{0}And{1}": "이 필드는 {0}에서 {1} 사이여야 합니다.", |
|||
"ThisFieldMustBeGreaterThanOrEqual{0}": "이 필드는 {0} 이상이어야 합니다.", |
|||
"ThisFieldMustBeLessOrEqual{0}": "이 필드는 {0} 이하여야 합니다.", |
|||
"ThisFieldMustMatchTheRegularExpression{0}": "이 필드는 정규식 '{0}'과(와) 일치해야 합니다.", |
|||
"ThisFieldIsRequired.": "이 필드는 필수입니다.", |
|||
"ThisFieldMustBeAStringWithAMaximumLengthOf{0}": "이 필드는 최대 '{0}'자여야 합니다.", |
|||
"ThisFieldMustBeAStringWithAMinimumLengthOf{1}AndAMaximumLengthOf{0}": "이 필드는 최소 {1}자, 최대 {0}자여야 합니다.", |
|||
"ThisFieldIsNotAValidFullyQualifiedHttpHttpsOrFtpUrl": "이 필드는 유효한 완전한 형식의 http, https 또는 ftp URL이 아닙니다.", |
|||
"ThisFieldIsInvalid.": "이 필드는 유효하지 않습니다." |
|||
} |
|||
} |
|||
@ -0,0 +1,75 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"Menu:Account": "계정", |
|||
"UserName": "사용자 이름", |
|||
"EmailAddress": "이메일 주소", |
|||
"UserNameOrEmailAddress": "사용자 이름 또는 이메일 주소", |
|||
"Password": "비밀번호", |
|||
"RememberMe": "로그인 상태 유지", |
|||
"UseAnotherServiceToLogin": "다른 서비스를 사용하여 로그인", |
|||
"UserLockedOutMessage": "잘못된 로그인 시도로 인해 사용자 계정이 잠겼습니다. 잠시 후 다시 시도해 주세요.", |
|||
"InvalidUserNameOrPassword": "사용자 이름 또는 비밀번호가 올바르지 않습니다!", |
|||
"LoginIsNotAllowed": "로그인할 수 없습니다! 계정이 비활성 상태이거나 이메일 또는 전화번호 확인이 필요합니다.", |
|||
"SelfRegistrationDisabledMessage": "이 애플리케이션에서는 자체 회원가입이 비활성화되어 있습니다. 새 사용자를 등록하려면 애플리케이션 관리자에게 문의해 주세요.", |
|||
"LocalLoginDisabledMessage": "이 애플리케이션에서는 로컬 로그인이 비활성화되어 있습니다.", |
|||
"Login": "로그인", |
|||
"Cancel": "취소", |
|||
"Register": "회원가입", |
|||
"AreYouANewUser": "신규 사용자이신가요?", |
|||
"AlreadyRegistered": "이미 가입하셨나요?", |
|||
"InvalidLoginRequest": "잘못된 로그인 요청", |
|||
"ThereAreNoLoginSchemesConfiguredForThisClient": "이 클라이언트에 구성된 로그인 스키마가 없습니다.", |
|||
"LogInUsingYourProviderAccount": "{0} 계정으로 로그인", |
|||
"DisplayName:CurrentPassword": "현재 비밀번호", |
|||
"DisplayName:NewPassword": "새 비밀번호", |
|||
"DisplayName:NewPasswordConfirm": "새 비밀번호 확인", |
|||
"PasswordChangedMessage": "비밀번호가 변경되었습니다.", |
|||
"DisplayName:UserName": "사용자 이름", |
|||
"DisplayName:Email": "이메일", |
|||
"DisplayName:Name": "이름", |
|||
"DisplayName:Surname": "성", |
|||
"DisplayName:Password": "비밀번호", |
|||
"DisplayName:EmailAddress": "이메일 주소", |
|||
"DisplayName:PhoneNumber": "전화번호", |
|||
"PersonalSettings": "개인 설정", |
|||
"PersonalSettingsSaved": "개인 설정이 저장되었습니다.", |
|||
"PersonalSettingsChangedConfirmationModalTitle": "개인 정보 변경됨", |
|||
"PersonalSettingsChangedConfirmationModalDescription": "변경 사항은 다시 로그인한 후 반영됩니다. 지금 로그아웃하시겠습니까?", |
|||
"PasswordChanged": "비밀번호 변경됨", |
|||
"NewPasswordConfirmFailed": "새 비밀번호를 확인해 주세요.", |
|||
"NewPasswordSameAsOld": "새 비밀번호는 기존 비밀번호와 달라야 합니다.", |
|||
"Manage": "관리", |
|||
"MyAccount": "내 계정", |
|||
"DisplayName:Abp.Account.IsSelfRegistrationEnabled": "자체 회원가입 활성화 여부", |
|||
"Description:Abp.Account.IsSelfRegistrationEnabled": "사용자가 직접 계정을 등록할 수 있는지 여부입니다.", |
|||
"DisplayName:Abp.Account.EnableLocalLogin": "로컬 계정으로 인증", |
|||
"Description:Abp.Account.EnableLocalLogin": "서버에서 사용자의 로컬 계정 인증을 허용할지 여부를 나타냅니다.", |
|||
"LoggedOutTitle": "로그아웃됨", |
|||
"LoggedOutText": "로그아웃되었습니다. 잠시 후 리디렉션됩니다.", |
|||
"ReturnToText": "애플리케이션으로 돌아가려면 여기를 클릭하세요.", |
|||
"OrLoginWith": "또는 다음 계정으로 로그인:", |
|||
"ForgotPassword": "비밀번호를 잊으셨나요?", |
|||
"SendPasswordResetLink_Information": "비밀번호 재설정 링크가 이메일로 전송됩니다. 몇 분 이내에 이메일을 받지 못한 경우 다시 시도해 주세요.", |
|||
"PasswordResetMailSentMessage": "계정 복구 이메일을 이메일 주소로 전송했습니다. 15분 이내에 받은편지함에서 이메일을 찾을 수 없다면 스팸 메일함을 확인해 주세요. 스팸 메일함에서 찾은 경우 스팸이 아닌 것으로 표시해 주세요. ", |
|||
"ResetPassword": "비밀번호 재설정", |
|||
"ConfirmPassword": "비밀번호 확인", |
|||
"ResetPassword_Information": "새 비밀번호를 입력해 주세요.", |
|||
"YourPasswordIsSuccessfullyReset": "비밀번호가 재설정되었습니다.", |
|||
"GoToTheApplication": "애플리케이션으로 이동", |
|||
"BackToLogin": "로그인으로 돌아가기", |
|||
"ProfileTab:Password": "비밀번호 변경", |
|||
"ProfileTab:PersonalInfo": "개인 정보", |
|||
"ReturnToApplication": "애플리케이션으로 돌아가기", |
|||
"Volo.Account:InvalidEmailAddress": "지정한 이메일 주소를 찾을 수 없습니다: {0}", |
|||
"PasswordReset": "비밀번호 재설정", |
|||
"PasswordResetInfoInEmail": "계정 복구 요청이 접수되었습니다! 본인이 요청한 경우 다음 링크를 클릭하여 비밀번호를 재설정하세요.", |
|||
"ResetMyPassword": "내 비밀번호 재설정", |
|||
"AccessDenied": "액세스가 거부되었습니다!", |
|||
"AccessDeniedMessage": "이 리소스에 액세스할 권한이 없습니다.", |
|||
"OrRegisterWith": "또는 다음 계정으로 회원가입", |
|||
"RegisterUsingYourProviderAccount": "{0} 계정으로 회원가입", |
|||
"RequireMigrateSeedTitle": "관리자 사용자를 찾을 수 없습니다.", |
|||
"RequireMigrateSeedMessage": "데이터베이스 시드가 실행되었는지 확인해 주세요. 해결 방법은 <a target=\"_blank\" href=\"https://abp.io/kb/0003\">문서</a>를 참조하세요." |
|||
} |
|||
} |
|||
@ -0,0 +1,118 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"Permission:AuditLogging": "감사 로깅", |
|||
"Permission:AuditLogs": "감사 로그", |
|||
"Menu:AuditLogging": "감사 로그", |
|||
"AuditLogs": "감사 로그", |
|||
"HttpStatus": "HTTP 상태", |
|||
"HttpMethod": "HTTP 메서드", |
|||
"HttpMethodFilter": "HTTP 메서드 필터", |
|||
"HttpRequest": "HTTP 요청", |
|||
"User": "사용자", |
|||
"UserNameFilter": "사용자 필터", |
|||
"HasException": "예외 발생 여부", |
|||
"IpAddress": "IP 주소", |
|||
"Time": "시간", |
|||
"Date": "날짜", |
|||
"Duration": "소요 시간", |
|||
"Detail": "세부 정보", |
|||
"Overall": "전체", |
|||
"Actions": "작업", |
|||
"ClientIpAddress": "클라이언트 IP 주소", |
|||
"ClientName": "클라이언트 이름", |
|||
"BrowserInfo": "브라우저 정보", |
|||
"Url": "URL", |
|||
"UserName": "사용자 이름", |
|||
"TenantImpersonator": "테넌트 가장 사용자", |
|||
"UserImpersonator": "사용자 가장 사용자", |
|||
"UrlFilter": "URL 필터", |
|||
"Exceptions": "예외", |
|||
"Comments": "설명", |
|||
"HttpStatusCode": "HTTP 상태 코드", |
|||
"HttpStatusCodeFilter": "HTTP 상태 코드 필터", |
|||
"ServiceName": "서비스", |
|||
"MethodName": "메서드", |
|||
"CorrelationId": "상관관계 ID", |
|||
"ApplicationName": "애플리케이션 이름", |
|||
"ExecutionDuration": "실행 시간", |
|||
"ExtraProperties": "추가 속성", |
|||
"MaxDuration": "최대 소요 시간", |
|||
"MinDuration": "최소 소요 시간", |
|||
"MinMaxDuration": "소요 시간(최소~최대)", |
|||
"{0}Milliseconds": "{0}밀리초", |
|||
"ExecutionTime": "실행 시간", |
|||
"Parameters": "매개변수", |
|||
"EntityTypeFullName": "엔터티 형식 전체 이름", |
|||
"Entity": "엔터티", |
|||
"ChangeType": "변경 형식", |
|||
"ChangeTime": "변경 시간", |
|||
"NewValue": "새 값", |
|||
"OriginalValue": "이전 값", |
|||
"PropertyName": "속성 이름", |
|||
"PropertyTypeFullName": "속성 형식 전체 이름", |
|||
"Yes": "예", |
|||
"No": "아니요", |
|||
"Changes": "변경 사항", |
|||
"AverageExecutionDurationInLogsPerDay": "평균 실행 시간", |
|||
"AverageExecutionDurationInMilliseconds": "평균 실행 시간(밀리초)", |
|||
"ErrorRateInLogs": "로그 오류율", |
|||
"Success": "성공", |
|||
"Fault": "실패", |
|||
"NoChanges": "변경 사항 없음", |
|||
"EntityChanges": "엔터티 변경 사항", |
|||
"EntityId": "엔터티 ID", |
|||
"EntityChangeStartTime": "최소 변경 날짜", |
|||
"EntityChangeEndTime": "최대 변경 날짜", |
|||
"EntityHistory": "엔터티 기록", |
|||
"DaysAgoTitle": "{0} {1}.", |
|||
"DaysAgoWithUserTitle": "{0} {1}, {2} 사용자가 수행했습니다.", |
|||
"MinutesAgo": "{0}분 전", |
|||
"HoursAgo": "{0}시간 전", |
|||
"DaysAgo": "{0}일 전", |
|||
"Created": "생성함", |
|||
"Updated": "수정함", |
|||
"Deleted": "삭제함", |
|||
"ChangeHistory": "변경 기록", |
|||
"FullChangeHistory": "전체 변경 기록", |
|||
"ChangeDetails": "변경 세부 정보", |
|||
"DurationMs": "소요 시간(ms)", |
|||
"StartDate": "시작 날짜", |
|||
"EndDate": "종료 날짜", |
|||
"Feature:AuditLoggingGroup": "감사 로깅", |
|||
"Feature:AuditLoggingEnable": "감사 로그 페이지 사용", |
|||
"Feature:AuditLoggingEnableDescription": "애플리케이션에서 감사 로그 페이지를 사용합니다.", |
|||
"Feature:AuditLoggingSettingManagementEnable": "감사 로그 설정 관리 사용", |
|||
"Feature:AuditLoggingSettingManagementEnableDescription": "애플리케이션에서 감사 로그 설정 관리를 구성할 수 있습니다.", |
|||
"InvalidAuditLogDeletionSettings": "감사 로그 삭제 설정이 올바르지 않습니다. 삭제를 사용하는 경우 기간은 0일보다 커야 합니다.", |
|||
"AuditLogSettingsGeneral": "일반", |
|||
"AuditLogSettingsGlobal": "전역", |
|||
"DisplayName:IsPeriodicDeleterEnabled": "시스템 전체에서 정리 서비스 사용", |
|||
"Description:IsPeriodicDeleterEnabled": "이 옵션을 사용하지 않으면 주기적 삭제 서비스가 작동하지 않으며 감사 로그가 자동으로 삭제되지 않습니다.", |
|||
"DisplayName:GlobalIsExpiredDeleterEnabled": "모든 테넌트와 호스트에 정리 서비스 사용", |
|||
"Description:GlobalIsExpiredDeleterEnabled": "이 옵션을 사용하면 별도 설정이 없는 모든 테넌트와 호스트의 만료된 항목이 자동으로 삭제됩니다.", |
|||
"DisplayName:IsExpiredDeleterEnabled": "정리 서비스 사용", |
|||
"Description:IsExpiredDeleterEnabled": "이 옵션을 사용하면 만료된 항목이 자동으로 삭제됩니다.", |
|||
"DisplayName:ExpiredDeleterPeriod": "만료 항목 삭제 기간", |
|||
"Description:ExpiredDeleterPeriod": "만료된 항목이 자동으로 삭제될 때까지의 일수를 설정합니다.", |
|||
"ExpiredDeleterPeriodUnit": "일", |
|||
"AuditLogsBeforeXWillBeDeleted": "{0} 이전의 감사 로그가 삭제됩니다.", |
|||
"TenantId": "테넌트 ID", |
|||
"Permission:Export": "감사 로그 내보내기", |
|||
"ExportToExcel": "Excel로 내보내기", |
|||
"Exporting": "내보내는 중", |
|||
"ExportCompleted": "내보내기가 완료되었습니다.", |
|||
"ExportFailed": "내보내기에 실패했습니다.", |
|||
"ThereWereNoRecordsToExport": "내보낼 레코드가 없습니다.", |
|||
"ExportJobQueued": "{0}개 레코드에 대한 내보내기 작업이 대기열에 추가되었습니다. 내보내기가 완료되면 이메일을 보내드립니다.", |
|||
"ExportReady": "{0}개 레코드 내보내기가 완료되어 다운로드할 수 있습니다.", |
|||
"FileName": "파일 이름", |
|||
"TotalRecords": "전체 레코드 수", |
|||
"ExcelFileAttachedMessage": "Excel 파일이 이 이메일에 첨부되어 있습니다.", |
|||
"EntityChangeExportCompletedSubject": "엔터티 변경 사항 내보내기 완료", |
|||
"AuditLogExportCompletedSubject": "감사 로그 내보내기 완료", |
|||
"DownloadLinkExplanation": "{0}(UTC)까지 아래 링크를 사용하여 파일을 다운로드할 수 있습니다.", |
|||
"DownloadNow": "지금 다운로드", |
|||
"TryAgainMessage": "다시 시도해 주세요. 문제가 계속되면 지원팀에 문의해 주세요." |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"MyAccount": "내 계정" |
|||
} |
|||
} |
|||
@ -0,0 +1,93 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"Menu:Blogs": "블로그", |
|||
"Menu:BlogManagement": "블로그 관리", |
|||
"Permission:Management": "관리", |
|||
"Permission:Edit": "편집", |
|||
"Permission:Create": "생성", |
|||
"Permission:Delete": "삭제", |
|||
"Permission:Blogging": "블로그", |
|||
"Permission:Blogs": "블로그", |
|||
"Permission:Posts": "게시물", |
|||
"Permission:Tags": "태그", |
|||
"Permission:Comments": "댓글", |
|||
"Permission:ClearCache": "캐시 지우기", |
|||
"Title": "제목", |
|||
"Delete": "삭제", |
|||
"Reply": "답글", |
|||
"ReplyTo": "{0}에 답글 달기", |
|||
"ContinueReading": "계속 읽기", |
|||
"DaysAgo": "{0}일 전", |
|||
"DayAgo": "{0}일 전", |
|||
"YearsAgo": "{0}년 전", |
|||
"YearAgo": "{0}년 전", |
|||
"MonthsAgo": "{0}개월 전", |
|||
"MonthAgo": "{0}개월 전", |
|||
"WeeksAgo": "{0}주 전", |
|||
"WeekAgo": "{0}주 전", |
|||
"MinutesAgo": "{0}분 전", |
|||
"MinuteAgo": "{0}분 전", |
|||
"SecondsAgo": "{0}초 전", |
|||
"SecondAgo": "{0}초 전", |
|||
"HoursAgo": "{0}시간 전", |
|||
"HourAgo": "{0}시간 전", |
|||
"Now": "지금", |
|||
"Content": "내용", |
|||
"SeeAll": "모두 보기", |
|||
"PopularTags": "인기 태그", |
|||
"WiewsWithCount": "조회수 {0}회", |
|||
"LastPosts": "최신 게시물", |
|||
"LeaveComment": "댓글 남기기", |
|||
"TagsInThisArticle": "이 글의 태그", |
|||
"Posts": "게시물", |
|||
"Edit": "편집", |
|||
"BLOG": "블로그", |
|||
"CommentDeletionWarningMessage": "댓글이 삭제됩니다.", |
|||
"PostDeletionWarningMessage": "게시물이 삭제됩니다.", |
|||
"BlogDeletionWarningMessage": "블로그가 삭제됩니다.", |
|||
"AreYouSure": "계속하시겠습니까?", |
|||
"CommentWithCount": "댓글 {0}개", |
|||
"Comment": "댓글", |
|||
"ShareOnTwitter": "트위터에 공유", |
|||
"CoverImage": "커버 이미지", |
|||
"CreateANewPost": "새 게시물 만들기", |
|||
"CreateANewBlog": "새 블로그 만들기", |
|||
"WhatIsNew": "새로운 소식", |
|||
"Name": "이름", |
|||
"ShortName": "짧은 이름", |
|||
"CreationTime": "생성 시간", |
|||
"Description": "설명", |
|||
"Blogs": "블로그", |
|||
"Tags": "태그", |
|||
"ShareOn": "공유", |
|||
"TitleLengthWarning": "SEO에 적합하도록 제목을 60자 이내로 작성해야 합니다.", |
|||
"ClearCache": "캐시 지우기", |
|||
"ClearCacheConfirmationMessage": "캐시를 지우시겠습니까?", |
|||
"MarkdownSupported": "Markdown을 지원합니다.", |
|||
"FileUploadInfo": "이미지를 끌어다 놓거나 복사한 이미지를 붙여넣을 수 있습니다.", |
|||
"PostDescriptionHint": "* 게시물 링크 미리 보기에 표시되며 HTML을 지원합니다.", |
|||
"ReadMore": "계속 읽기", |
|||
"MemberNotPublishedPostYet": "아직 게시물이 없습니다!", |
|||
"UpdateUserWebSiteInfo": "예: https://johndoe.com", |
|||
"UpdateUserTwitterInfo": "예: johndoe", |
|||
"UpdateUserGithubInfo": "예: johndoe", |
|||
"UpdateUserLinkedinInfo": "예: https://www.linkedin.com/...", |
|||
"UpdateUserCompanyInfo": "예: Volosoft", |
|||
"UpdateUserJobTitleInfo": "예: 소프트웨어 개발자", |
|||
"WebSite": "웹사이트", |
|||
"UserName": "사용자 이름", |
|||
"FullURL": "전체 URL", |
|||
"JobTitle": "직책", |
|||
"PersonalWebsite": "개인 웹사이트", |
|||
"EditProfile": "프로필 편집", |
|||
"MoreFromBlog": "블로그의 다른 글", |
|||
"MoreFromUser": "{0}님의 다른 글", |
|||
"BlogPosts": "게시물", |
|||
"Views": "조회수", |
|||
"Biography": "소개", |
|||
"Social": "소셜 미디어", |
|||
"NewBlogPost": "새 블로그 게시물", |
|||
"BlogMemberMetaDescription": ".NET 개발, 크로스 플랫폼, ASP.NET 애플리케이션 템플릿, ABP 관련 소식 등을 다루는 ABP 블로그입니다." |
|||
} |
|||
} |
|||
@ -0,0 +1,290 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"AddSubMenuItem": "하위 메뉴 항목 추가", |
|||
"AreYouSure": "계속하시겠습니까?", |
|||
"AverageRating": "평균 평점", |
|||
"BlogDeletionConfirmationMessage": "블로그 '{0}'을(를) 삭제합니다. 계속하시겠습니까?", |
|||
"BlogFeatureNotAvailable": "현재 이 기능을 사용할 수 없습니다. 사용하려면 'GlobalFeatureManager'에서 활성화하세요.", |
|||
"BlogId": "블로그", |
|||
"BlogPostDeletionConfirmationMessage": "블로그 게시물 '{0}'을(를) 삭제합니다. 계속하시겠습니까?", |
|||
"BlogPosts": "블로그 게시물", |
|||
"Blogs": "블로그", |
|||
"ChoosePreference": "환경 설정 선택...", |
|||
"Cms": "CMS", |
|||
"CmsKit.Comments": "댓글", |
|||
"CmsKit.Ratings": "평점", |
|||
"CmsKit.Reactions": "반응", |
|||
"CmsKit.Tags": "태그", |
|||
"CmsKit.MarkedItems": "표시된 항목", |
|||
"CmsKit:0002": "콘텐츠가 이미 존재합니다!", |
|||
"CmsKit:0003": "엔터티 {0}은(는) 태그를 지정할 수 없습니다.", |
|||
"CmsKit:Blog:0001": "지정한 슬러그({Slug})가 이미 존재합니다!", |
|||
"CmsKit:BlogPost:0001": "지정한 슬러그가 이미 존재합니다!", |
|||
"CmsKit:Comments:0001": "엔터티 {EntityType}에는 댓글을 작성할 수 없습니다.", |
|||
"CmsKit:Media:0001": "'{Name}'은(는) 유효한 미디어 이름이 아닙니다.", |
|||
"CmsKit:Media:0002": "이 엔터티에는 미디어를 추가할 수 없습니다.", |
|||
"CmsKit:Page:0001": "지정한 URL({Slug})이(가) 이미 존재합니다. 다른 URL을 사용하세요.", |
|||
"CmsKit:Rating:0001": "엔터티 {EntityType}에는 평점을 매길 수 없습니다.", |
|||
"CmsKit:Reaction:0001": "엔터티 {EntityType}에는 반응을 추가할 수 없습니다.", |
|||
"CmsKit:Tag:0002": "이 엔터티에는 태그를 지정할 수 없습니다!", |
|||
"CmsKit:MarkedItem:ToggleConfirmation": "표시된 항목 상태를 전환하시겠습니까?", |
|||
"ToggleFavorite": "즐겨찾기 추가/제거", |
|||
"FavoritesFilterMessage": "즐겨찾기를 필터링하려면 로그인하세요.", |
|||
"FilterOnFavorites": "즐겨찾기로 필터링", |
|||
"CommentAuthorizationExceptionMessage": "해당 댓글은 공개적으로 표시할 수 없습니다.", |
|||
"CmsKit:Modals:Login": "로그인", |
|||
"CmsKit:Modals:LoginModalDefaultMessage": "계속하려면 로그인하세요!", |
|||
"CmsKit:Modals:YouAreNotAuthenticated": "이 작업을 수행할 권한이 없습니다.", |
|||
"CommentDeletionConfirmationMessage": "이 댓글과 모든 답글을 삭제합니다!", |
|||
"CmsKit:MarkedItem:0001": "엔터티 {EntityType}은(는) 표시할 수 없습니다.", |
|||
"CmsKit:MarkedItem:0002": "엔터티 유형 '{EntityType}'에 대한 정의를 찾을 수 없습니다.", |
|||
"CmsKit:MarkedItem:0003": "엔터티 유형 '{EntityType}'에 대한 정의가 이미 존재합니다. 각 엔터티 유형에는 하나의 정의만 있어야 합니다.", |
|||
"CmsKit:MarkedItem:LoginMessage": "이 항목을 표시하려면 로그인하세요.", |
|||
"Comments": "댓글", |
|||
"Content": "콘텐츠", |
|||
"ContentDeletionConfirmationMessage": "이 콘텐츠를 삭제하시겠습니까?", |
|||
"Contents": "콘텐츠", |
|||
"CoverImage": "표지 이미지", |
|||
"CreateBlogPostPage": "새 블로그 게시물", |
|||
"CreationTime": "생성 시간", |
|||
"Delete": "삭제", |
|||
"Detail": "상세 정보", |
|||
"Details": "상세 정보", |
|||
"DisplayName": "표시 이름", |
|||
"DoYouPreferAdditionalEmails": "추가 이메일을 받으시겠습니까?", |
|||
"Edit": "편집", |
|||
"EndDate": "종료일", |
|||
"EntityId": "엔터티 ID", |
|||
"EntityType": "엔터티 유형", |
|||
"ExportCSV": "CSV 내보내기", |
|||
"Features": "기능", |
|||
"GenericDeletionConfirmationMessage": "'{0}'을(를) 삭제하시겠습니까?", |
|||
"IsActive": "활성", |
|||
"LastModification": "마지막 수정", |
|||
"LastModificationTime": "마지막 수정 시간", |
|||
"LoginToAddComment": "댓글을 작성하려면 로그인하세요.", |
|||
"LoginToRate": "평점을 매기려면 로그인하세요.", |
|||
"LoginToReact": "반응을 남기려면 로그인하세요.", |
|||
"LoginToReply": "답글을 작성하려면 로그인하세요.", |
|||
"MainMenu": "주 메뉴", |
|||
"MakeMainMenu": "주 메뉴로 설정", |
|||
"Menu:CMS": "CMS", |
|||
"Menus": "메뉴", |
|||
"MenuDeletionConfirmationMessage": "메뉴 '{0}'을(를) 삭제합니다. 계속하시겠습니까?", |
|||
"MenuItemDeletionConfirmationMessage": "이 메뉴 항목을 삭제하시겠습니까?", |
|||
"MenuItemMoveConfirmMessage": "'{0}'을(를) '{1}' 아래로 이동하시겠습니까?", |
|||
"MenuItems": "메뉴 항목", |
|||
"Message": "메시지", |
|||
"MessageDeletionConfirmationMessage": "이 댓글을 완전히 삭제합니다.", |
|||
"NewBlog": "새 블로그", |
|||
"NewBlogPost": "새 블로그 게시물", |
|||
"NewMenu": "새 메뉴", |
|||
"NewMenuItem": "새 루트 메뉴 항목", |
|||
"NewPage": "새 페이지", |
|||
"NewTag": "새 태그", |
|||
"NoMenuItems": "아직 메뉴 항목이 없습니다!", |
|||
"OK": "확인", |
|||
"PageDeletionConfirmationMessage": "이 페이지를 삭제하시겠습니까?", |
|||
"PageId": "페이지", |
|||
"Pages": "페이지", |
|||
"PageSlugInformation": "슬러그는 URL에 사용됩니다. URL은 '/{{slug}}' 형식입니다.", |
|||
"BlogSlugInformation": "슬러그는 URL에 사용됩니다. URL은 '/{0}/{{slug}}' 형식입니다.", |
|||
"Permission:BlogManagement": "블로그 관리", |
|||
"Permission:BlogManagement.Create": "생성", |
|||
"Permission:BlogManagement.Delete": "삭제", |
|||
"Permission:BlogManagement.Features": "기능", |
|||
"Permission:BlogManagement.Update": "수정", |
|||
"Permission:BlogPostManagement": "블로그 게시물 관리", |
|||
"Permission:BlogPostManagement.Create": "생성", |
|||
"Permission:BlogPostManagement.Delete": "삭제", |
|||
"Permission:BlogPostManagement.Update": "수정", |
|||
"Permission:BlogPostManagement.Publish": "게시", |
|||
"Permission:CmsKit": "CmsKit 관리", |
|||
"Permission:Comments": "댓글 관리", |
|||
"Permission:Comments.Delete": "삭제", |
|||
"Permission:Comments.Update": "수정", |
|||
"Permission:Comments.SettingManagement": "설정 관리", |
|||
"Permission:Contents": "콘텐츠 관리", |
|||
"Permission:Contents.Create": "콘텐츠 생성", |
|||
"Permission:Contents.Delete": "콘텐츠 삭제", |
|||
"Permission:Contents.Update": "콘텐츠 수정", |
|||
"Permission:MediaDescriptorManagement": "미디어 관리", |
|||
"Permission:MediaDescriptorManagement:Create": "생성", |
|||
"Permission:MediaDescriptorManagement:Delete": "삭제", |
|||
"Permission:MenuItemManagement": "메뉴 항목 관리", |
|||
"Permission:MenuItemManagement.Create": "생성", |
|||
"Permission:MenuItemManagement.Delete": "삭제", |
|||
"Permission:MenuItemManagement.Update": "수정", |
|||
"Permission:MenuManagement": "메뉴 관리", |
|||
"Permission:MenuManagement.Create": "생성", |
|||
"Permission:MenuManagement.Delete": "삭제", |
|||
"Permission:MenuManagement.Update": "수정", |
|||
"Permission:Menus": "메뉴 관리", |
|||
"Permission:Menus.Create": "생성", |
|||
"Permission:Menus.Delete": "삭제", |
|||
"Permission:Menus.Update": "수정", |
|||
"Permission:PageManagement": "페이지 관리", |
|||
"Permission:PageManagement:Create": "생성", |
|||
"Permission:PageManagement:Delete": "삭제", |
|||
"Permission:PageManagement:Update": "수정", |
|||
"Permission:PageManagement:SetAsHomePage": "홈 페이지로 설정", |
|||
"Permission:TagManagement": "태그 관리", |
|||
"Permission:TagManagement.Create": "생성", |
|||
"Permission:TagManagement.Delete": "삭제", |
|||
"Permission:TagManagement.Update": "수정", |
|||
"Permission:GlobalResources": "전역 리소스", |
|||
"Permission:CmsKitPublic": "CmsKit 공개 기능", |
|||
"Permission:Comments.DeleteAll": "모두 삭제", |
|||
"PickYourReaction": "반응 선택", |
|||
"Rating": "평점", |
|||
"RatingUndoMessage": "평점이 취소됩니다.", |
|||
"Reactions": "반응", |
|||
"Read": "읽기", |
|||
"RepliesToThisComment": "이 댓글의 답글", |
|||
"Reply": "답글", |
|||
"ReplyTo": "답글 대상", |
|||
"SamplePageMessage": "Pro 모듈의 샘플 페이지", |
|||
"SaveChanges": "변경 사항 저장", |
|||
"Script": "스크립트", |
|||
"SelectLayout": "레이아웃 선택", |
|||
"SelectAll": "모두 선택", |
|||
"Send": "보내기", |
|||
"SendMessage": "메시지 보내기", |
|||
"SelectedAuthor": "작성자", |
|||
"ShortDescription": "간단한 설명", |
|||
"Slug": "슬러그", |
|||
"Source": "소스", |
|||
"SourceUrl": "소스 URL", |
|||
"Star": "별점", |
|||
"StartDate": "시작일", |
|||
"Style": "스타일", |
|||
"Subject": "제목", |
|||
"SubjectPlaceholder": "제목을 입력하세요.", |
|||
"Submit": "제출", |
|||
"Subscribe": "구독", |
|||
"SavedSuccessfully": "저장되었습니다!", |
|||
"TagDeletionConfirmationMessage": "태그 '{0}'을(를) 삭제하시겠습니까?", |
|||
"Tags": "태그", |
|||
"Text": "텍스트", |
|||
"ThankYou": "감사합니다.", |
|||
"Title": "제목", |
|||
"TotalRatings": "총 평점 수", |
|||
"Undo": "실행 취소", |
|||
"Update": "수정", |
|||
"UpdatePreferenceSuccessMessage": "환경 설정이 저장되었습니다.", |
|||
"UpdateYourEmailPreferences": "이메일 환경 설정 업데이트", |
|||
"UnMakeMainMenu": "주 메뉴 설정 해제", |
|||
"UploadFailedMessage": "업로드에 실패했습니다.", |
|||
"UserId": "사용자 ID", |
|||
"Username": "사용자 이름", |
|||
"YourComment": "내 댓글", |
|||
"YourEmailAddress": "이메일 주소", |
|||
"YourFullName": "전체 이름", |
|||
"YourMessage": "내 메시지", |
|||
"YourReply": "내 답글", |
|||
"MarkdownSupported": "<a href=\"https://www.markdownguide.org/basic-syntax/\">Markdown</a>을 지원합니다.", |
|||
"GlobalResources": "전역 리소스", |
|||
"CmsKit.BlogPost.Status.0": "초안", |
|||
"CmsKit.BlogPost.Status.1": "게시됨", |
|||
"CmsKit.BlogPost.Status.2": "검토 대기 중", |
|||
"BlogPostPublishConfirmationMessage": "블로그 게시물 \"{0}\"을(를) 게시하시겠습니까?", |
|||
"SuccessfullyPublished": "게시되었습니다!", |
|||
"Draft": "초안", |
|||
"Publish": "게시", |
|||
"BlogPostDraftConfirmationMessage": "블로그 게시물 \"{0}\"을(를) 초안으로 설정하시겠습니까?", |
|||
"BlogPostSendToReviewConfirmationMessage": "블로그 게시물 \"{0}\"을(를) 게시하기 위해 관리자 검토로 보내시겠습니까?", |
|||
"SaveAsDraft": "초안으로 저장", |
|||
"SendToReview": "검토 요청", |
|||
"SendToReviewToPublish": "게시 검토 요청", |
|||
"BlogPostSendToReviewSuccessMessage": "블로그 게시물 \"{0}\"이(가) 게시를 위한 관리자 검토로 전송되었습니다.", |
|||
"HasBlogPostWaitingForReviewMessage": "검토 대기 중인 블로그 게시물이 있습니다. 목록을 보려면 클릭하세요.", |
|||
"SelectAStatus": "상태 선택", |
|||
"Status": "상태", |
|||
"CmsKit.BlogPost.ScrollIndex": "블로그 게시물 빠른 탐색 모음", |
|||
"CmsKit.BlogPost.PreventXssFeature": "XSS 방지", |
|||
"Add": "추가", |
|||
"AddWidget": "위젯 추가", |
|||
"PleaseConfigureWidgets": "위젯을 구성하세요.", |
|||
"SelectAnAuthor": "작성자 선택", |
|||
"InThisDocument": "이 문서에서", |
|||
"GoToTop": "맨 위로 이동", |
|||
"SetAsHomePage": "홈 페이지 상태 변경", |
|||
"CompletedSettingAsHomePage": "홈 페이지로 설정됨", |
|||
"IsHomePage": "홈 페이지 여부", |
|||
"RemovedSettingAsHomePage": "홈 페이지 설정이 해제됨", |
|||
"Feature:CmsKitGroup": "CMS Kit", |
|||
"Feature:BlogEnable": "블로그 게시물", |
|||
"Feature:BlogEnableDescription": "애플리케이션에서 블로그와 게시물을 동적으로 생성할 수 있는 CMS Kit 블로그 게시물 시스템입니다.", |
|||
"Feature:CommentEnable": "댓글", |
|||
"Feature:CommentEnableDescription": "BlogPost와 같은 엔터티에 댓글을 작성할 수 있는 CMS Kit 댓글 시스템입니다.", |
|||
"Feature:GlobalResourceEnable": "전역 리소스", |
|||
"Feature:GlobalResourceEnableDescription": "전역 스타일과 스크립트를 관리할 수 있는 CMS Kit 전역 리소스 기능입니다.", |
|||
"Feature:MenuEnable": "메뉴", |
|||
"Feature:MenuEnableDescription": "애플리케이션 메뉴를 동적으로 추가하거나 제거할 수 있는 CMS Kit 동적 메뉴 시스템입니다.", |
|||
"Feature:PageEnable": "페이지", |
|||
"Feature:PageEnableDescription": "특정 URL을 사용하는 정적 페이지를 생성할 수 있는 CMS Kit 페이지 시스템입니다.", |
|||
"Feature:RatingEnable": "평점", |
|||
"Feature:RatingEnableDescription": "사용자가 BlogPost와 같은 엔터티에 평점을 매길 수 있는 CMS Kit 평점 시스템입니다.", |
|||
"Feature:ReactionEnable": "반응", |
|||
"Feature:ReactionEnableDescription": "사용자가 BlogPost, Comment 등의 엔터티에 반응을 남길 수 있는 CMS Kit 반응 시스템입니다.", |
|||
"Feature:TagEnable": "태그 지정", |
|||
"Feature:TagEnableDescription": "BlogPost와 같은 엔터티에 태그를 지정할 수 있는 CMS Kit 태그 시스템입니다.", |
|||
"Feature:MarkedItemEnable": "표시된 항목", |
|||
"Feature:MarkedItemEnableDescription": "사용자가 엔터티를 즐겨찾기로 표시할 수 있는 CMS Kit 표시 시스템입니다.", |
|||
"DeleteBlogPostMessage": "블로그를 삭제합니다. 계속하시겠습니까?", |
|||
"CaptchaCode": "CAPTCHA 코드", |
|||
"CommentTextRequired": "댓글은 필수입니다.", |
|||
"CaptchaCodeErrorMessage": "입력한 CAPTCHA 답변이 올바르지 않습니다. 다시 시도하세요.", |
|||
"CaptchaCodeMissingMessage": "CAPTCHA 코드가 누락되었습니다!", |
|||
"UnAllowedExternalUrlMessage": "허용되지 않은 외부 URL이 포함되어 있습니다. 외부 URL을 제거하고 다시 시도하세요.", |
|||
"URL": "URL", |
|||
"PopularTags": "인기 태그", |
|||
"RemoveCoverImageConfirmationMessage": "표지 이미지를 제거하시겠습니까?", |
|||
"RemoveCoverImage": "표지 이미지 제거", |
|||
"CssClass": "CSS 클래스", |
|||
"TagsHelpText": "태그는 쉼표로 구분해야 합니다(예: tag1, tag2, tag3).", |
|||
"ThisPartOfContentCouldntBeLoaded": "콘텐츠의 이 부분을 불러올 수 없습니다.", |
|||
"DuplicateCommentAttemptMessage": "중복 댓글 작성 시도가 감지되었습니다. 댓글이 이미 제출되었습니다.", |
|||
"NoBlogPostYet": "아직 블로그 게시물이 없습니다!", |
|||
"CmsKit:Comment": "댓글", |
|||
"CmsKitCommentOptions:RequireApprovement": "댓글 승인 필요", |
|||
"CmsKitCommentOptions:RequireApprovementDescription": "활성화하면 댓글을 게시하기 전에 승인이 필요합니다.", |
|||
"CommentFilter:ApproveState": "승인 상태", |
|||
"ApproveState": "승인 상태", |
|||
"CommentFilter:0": "전체", |
|||
"CommentFilter:1": "승인됨", |
|||
"CommentFilter:2": "승인 거부됨", |
|||
"CommentFilter:4": "대기 중", |
|||
"ApprovedSuccessfully": "승인되었습니다.", |
|||
"ApprovalRevokedSuccessfully": "승인이 취소되었습니다.", |
|||
"Approve": "승인", |
|||
"Disapproved": "승인 거부됨", |
|||
"CommentAlertMessage": "승인 대기 중인 댓글이 {0}개 있습니다.", |
|||
"Settings:Menu:CmsKit": "CMS", |
|||
"CommentsAwaitingApproval": "승인 대기 중인 댓글", |
|||
"JustNow": "방금", |
|||
"MinuteAgo": "1분 전", |
|||
"MinutesAgo": "{0}분 전", |
|||
"HourAgo": "1시간 전", |
|||
"HoursAgo": "{0}시간 전", |
|||
"YesterdayAt": "어제 {0}", |
|||
"DayAt": "{0} {1}", |
|||
"MonthDayAt": "{0} {1} {2}", |
|||
"FullDate": "{0} {1} {2}", |
|||
"Minute": "분", |
|||
"Hour": "시간", |
|||
"Day": "일", |
|||
"Week": "주", |
|||
"CommentSubmittedForApproval": "댓글이 승인 요청으로 제출되었습니다.", |
|||
"ChooseAnActionForBlog": "블로그 작업 선택", |
|||
"AssignBlogPostsToOtherBlog": "블로그 게시물을 다른 블로그에 할당", |
|||
"SelectAnBlogToAssign": "할당할 블로그 선택", |
|||
"DeleteAllBlogPostsOfThisBlog": "이 블로그의 모든 게시물 삭제", |
|||
"RequiredPermissionName": "필수 권한 이름", |
|||
"Enum:PageStatus:0": "초안", |
|||
"Enum:PageStatus:1": "게시", |
|||
"AllPosts": "모든 게시물", |
|||
"IsReadOnly": "읽기 전용" |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"DocsTitle": "VoloDocs", |
|||
"WelcomeVoloDocs": "VoloDocs에 오신 것을 환영합니다!", |
|||
"NoProjectWarning": "아직 정의된 프로젝트가 없습니다!", |
|||
"CreateYourFirstProject": "첫 번째 프로젝트를 시작하려면 여기를 클릭하세요.", |
|||
"NoProject": "프로젝트가 없습니다!" |
|||
} |
|||
} |
|||
@ -0,0 +1,74 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"Permission:DocumentManagement": "문서 관리", |
|||
"Permission:Projects": "프로젝트", |
|||
"Permission:Edit": "편집", |
|||
"Permission:Delete": "삭제", |
|||
"Permission:Create": "생성", |
|||
"Permission:Documents": "문서", |
|||
"Menu:Documents": "문서", |
|||
"Menu:DocumentManagement": "문서", |
|||
"Menu:ProjectManagement": "프로젝트", |
|||
"CreateANewProject": "새 프로젝트 생성", |
|||
"Edit": "편집", |
|||
"Create": "생성", |
|||
"Pull": "가져오기", |
|||
"Projects": "프로젝트", |
|||
"Name": "이름", |
|||
"ShortName": "단축 이름", |
|||
"DocumentStoreType": "문서 저장소 유형", |
|||
"Format": "형식", |
|||
"ShortNameInfoText": "고유 URL에 사용됩니다.", |
|||
"DisplayName:Name": "이름", |
|||
"DisplayName:ShortName": "단축 이름", |
|||
"DisplayName:Format": "형식", |
|||
"DisplayName:DefaultDocumentName": "기본 문서 이름", |
|||
"DisplayName:NavigationDocumentName": "탐색 문서 이름", |
|||
"DisplayName:MinimumVersion": "최소 버전", |
|||
"DisplayName:MainWebsiteUrl": "메인 웹사이트 URL", |
|||
"DisplayName:LatestVersionBranchName": "최신 버전 브랜치 이름", |
|||
"DisplayName:GitHubRootUrl": "GitHub 루트 URL", |
|||
"DisplayName:GitHubAccessToken": "GitHub 액세스 토큰", |
|||
"DisplayName:GitHubUserAgent": "GitHub 사용자 에이전트", |
|||
"DisplayName:GithubVersionProviderSource": "GitHub 버전 공급자 소스", |
|||
"DisplayName:VersionBranchPrefix": "버전 브랜치 접두사", |
|||
"DisplayName:All": "모두 가져오기", |
|||
"DisplayName:LanguageCode": "언어 코드", |
|||
"DisplayName:Version": "버전", |
|||
"Documents": "문서", |
|||
"RemoveFromCache": "캐시에서 제거하고 재인덱싱", |
|||
"Reindex": "재인덱싱", |
|||
"ReindexCompleted": "재인덱싱 완료", |
|||
"RemovedFromCache": "캐시에서 제거하고 재인덱싱했습니다.", |
|||
"RemoveFromCacheConfirmation": "이 항목을 캐시에서 제거하시겠습니까?", |
|||
"ReIndexDocumentConfirmation": "문서 \"{0}\"을(를) 재인덱싱하시겠습니까?", |
|||
"DeleteFromDatabase": "데이터베이스에서 삭제", |
|||
"Deleted": "삭제됨", |
|||
"Search": "검색", |
|||
"StartDate": "시작일", |
|||
"EndDate": "종료일", |
|||
"CreationTime": "생성 시간", |
|||
"LastUpdateTime": "마지막 업데이트", |
|||
"LastSignificantUpdateTime": "마지막 주요 업데이트", |
|||
"Version": "버전", |
|||
"LanguageCode": "언어 코드", |
|||
"FileName": "파일 이름", |
|||
"LastCachedTime": "캐시 시간", |
|||
"Project": "프로젝트", |
|||
"AdvancedFilters": "고급 필터", |
|||
"RemoveCacheAndReIndexConfirmation": "문서 \"{0}\"을(를) 캐시에서 제거하고 재인덱싱합니다. 계속하시겠습니까?", |
|||
"GeneratePdf": "PDF 생성", |
|||
"Generating": "생성 중...", |
|||
"Language": "언어", |
|||
"ForceToGenerateNewPdf": "새 PDF 강제 생성", |
|||
"PdfGeneratedSuccessfully": "PDF가 생성되었습니다.", |
|||
"GenerateAndDownloadPdf": "PDF 생성 및 다운로드", |
|||
"PdfFileDeletionWarningMessage": "PDF 파일 \"{0}\"을(를) 삭제하시겠습니까?", |
|||
"ManagePdfFiles": "PDF 파일 관리", |
|||
"Permission:ManagePdfFiles": "PDF 파일 관리", |
|||
"PdfDeletedSuccessfully": "PDF 파일이 삭제되었습니다.", |
|||
"PdfGenerationStarted": "PDF 생성을 시작했습니다.", |
|||
"PdfGenerationStartedInfoMessage": "PDF 생성을 시작했습니다. 완료되면 PDF 파일 섹션에 파일이 추가되었는지 확인할 수 있습니다." |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"Permission:DocumentManagement.Common": "문서 관리 공통", |
|||
"Permission:PdfDownload": "PDF 다운로드" |
|||
} |
|||
} |
|||
@ -0,0 +1,51 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"Documents": "문서", |
|||
"BackToWebsite": "웹사이트로 돌아가기", |
|||
"Contributors": "기여자", |
|||
"ShareOn": "공유", |
|||
"Version": "버전", |
|||
"Edit": "편집", |
|||
"LastEditTime": "마지막 편집", |
|||
"Delete": "삭제", |
|||
"ClearCache": "캐시 지우기", |
|||
"ClearCacheConfirmationMessage": "프로젝트 \"{0}\"의 모든 캐시를 지우시겠습니까?", |
|||
"ReIndexAllProjects": "모든 프로젝트 다시 인덱싱", |
|||
"ReIndexProject": "프로젝트 다시 인덱싱", |
|||
"ReIndexProjectConfirmationMessage": "프로젝트 \"{0}\"을(를) 다시 인덱싱하시겠습니까?", |
|||
"SuccessfullyReIndexProject": "다시 인덱싱했습니다: \"{0}\"", |
|||
"ReIndexAllProjectConfirmationMessage": "모든 프로젝트를 다시 인덱싱하시겠습니까?", |
|||
"SuccessfullyReIndexAllProject": "모든 프로젝트를 다시 인덱싱했습니다.", |
|||
"InThisDocument": "이 문서에서", |
|||
"GoToTop": "맨 위로 이동", |
|||
"Projects": "프로젝트", |
|||
"NoProjectWarning": "아직 프로젝트가 없습니다!", |
|||
"DocumentNotFound": "요청한 문서를 찾을 수 없습니다!", |
|||
"ProjectNotFound": "요청한 프로젝트를 찾을 수 없습니다!", |
|||
"NavigationDocumentNotFound": "이 버전에는 탐색 문서가 없습니다!", |
|||
"DocumentNotFoundInSelectedLanguage": "요청한 언어의 문서를 찾을 수 없어 기본 언어의 문서를 표시합니다.", |
|||
"FilterTopics": "주제 필터링", |
|||
"FullSearch": "문서에서 검색", |
|||
"Volo.Docs.Domain:010001": "Elasticsearch가 활성화되어 있지 않습니다.", |
|||
"MultipleVersionDocumentInfo": "이 문서에는 여러 버전이 있습니다. 가장 적합한 옵션을 선택하세요.", |
|||
"DocumentOptions": "문서 옵션", |
|||
"New": "신규", |
|||
"Upd": "업데이트", |
|||
"NewExplanation": "최근 2주 이내에 생성되었습니다.", |
|||
"UpdatedExplanation": "최근 2주 이내에 업데이트되었습니다.", |
|||
"Volo.Docs.Domain:010002": "단축 이름 {ShortName}이(가) 이미 존재합니다.", |
|||
"Preview": "미리 보기", |
|||
"Search": "검색", |
|||
"SearchResults": "검색 결과", |
|||
"SearchInTheAllDocuments": "모든 문서에서 검색", |
|||
"Next": "다음", |
|||
"Previous": "이전", |
|||
"ProjectDeletionWarningMessage": "프로젝트가 삭제됩니다.", |
|||
"Docs_Page_Title": "ABP 문서", |
|||
"Docs_Page_Description": "ABP 문서에서 포괄적인 가이드와 API 참조를 확인하여 개발 및 문제 해결에 활용할 수 있습니다.", |
|||
"GoogleTranslate": "Google 번역", |
|||
"DownloadPDF": "PDF 다운로드", |
|||
"PdfFileGeneratedSuccessfully": "PDF 파일이 생성되었습니다." |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"Features": "기능", |
|||
"NoFeatureFoundMessage": "사용 가능한 기능이 없습니다.", |
|||
"ManageHostFeatures": "호스트 기능 관리", |
|||
"ManageHostFeaturesText": "다음 버튼을 클릭하여 호스트 측 기능을 관리할 수 있습니다.", |
|||
"Permission:FeatureManagement": "기능 관리", |
|||
"Permission:FeatureManagement.ManageHostFeatures": "호스트 기능 관리", |
|||
"Volo.Abp.FeatureManagement:InvalidFeatureValue": "{0} 기능 값이 유효하지 않습니다!", |
|||
"Menu:FeatureManagement": "기능 관리", |
|||
"ResetToDefault": "기본값으로 재설정", |
|||
"ResetedToDefault": "기본값으로 재설정됨", |
|||
"AreYouSure": "계속하시겠습니까?", |
|||
"AreYouSureToResetToDefault": "기본값으로 재설정하시겠습니까?" |
|||
} |
|||
} |
|||
@ -0,0 +1,143 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"Menu:IdentityManagement": "ID 관리", |
|||
"Users": "사용자", |
|||
"NewUser": "새 사용자", |
|||
"UserName": "사용자 이름", |
|||
"Surname": "성", |
|||
"EmailAddress": "이메일 주소", |
|||
"PhoneNumber": "전화번호", |
|||
"UserInformations": "사용자 정보", |
|||
"DisplayName:IsDefault": "기본값", |
|||
"DisplayName:IsStatic": "정적", |
|||
"DisplayName:IsPublic": "공개", |
|||
"Roles": "역할", |
|||
"Password": "비밀번호", |
|||
"PersonalInfo": "내 프로필", |
|||
"PersonalSettings": "개인 설정", |
|||
"UserDeletionConfirmationMessage": "사용자 '{0}'을(를) 삭제합니다. 계속하시겠습니까?", |
|||
"RoleDeletionConfirmationMessage": "역할 '{0}'을(를) 삭제합니다. 계속하시겠습니까?", |
|||
"DisplayName:RoleName": "역할 이름", |
|||
"DisplayName:UserName": "사용자 이름", |
|||
"DisplayName:Name": "이름", |
|||
"DisplayName:Surname": "성", |
|||
"DisplayName:Password": "비밀번호", |
|||
"DisplayName:Email": "이메일 주소", |
|||
"DisplayName:PhoneNumber": "전화번호", |
|||
"DisplayName:TwoFactorEnabled": "2단계 인증", |
|||
"DisplayName:IsActive": "활성", |
|||
"DisplayName:LockoutEnabled": "계정 잠금", |
|||
"Description:LockoutEnabled": "로그인 실패 시 계정을 잠급니다.", |
|||
"NewRole": "새 역할", |
|||
"RoleName": "역할 이름", |
|||
"CreationTime": "생성 시간", |
|||
"Permissions": "권한", |
|||
"DisplayName:CurrentPassword": "현재 비밀번호", |
|||
"DisplayName:NewPassword": "새 비밀번호", |
|||
"DisplayName:NewPasswordConfirm": "새 비밀번호 확인", |
|||
"PasswordChangedMessage": "비밀번호가 변경되었습니다.", |
|||
"PersonalSettingsSavedMessage": "개인 설정이 저장되었습니다.", |
|||
"Volo.Abp.Identity:DefaultError": "알 수 없는 오류가 발생했습니다.", |
|||
"Volo.Abp.Identity:ConcurrencyFailure": "낙관적 동시성 검사에 실패했습니다. 작업 중인 엔터티가 다른 사용자에 의해 수정되었습니다. 변경 내용을 취소하고 다시 시도하십시오.", |
|||
"Volo.Abp.Identity:DuplicateEmail": "이메일 주소 '{0}'은(는) 이미 사용 중입니다.", |
|||
"Volo.Abp.Identity:DuplicateRoleName": "역할 이름 '{0}'은(는) 이미 사용 중입니다.", |
|||
"Volo.Abp.Identity:DuplicateUserName": "사용자 이름 '{0}'은(는) 이미 사용 중입니다.", |
|||
"Volo.Abp.Identity:InvalidEmail": "이메일 주소 '{0}'은(는) 유효하지 않습니다.", |
|||
"Volo.Abp.Identity:InvalidPasswordHasherCompatibilityMode": "제공된 PasswordHasherCompatibilityMode가 유효하지 않습니다.", |
|||
"Volo.Abp.Identity:InvalidPasswordHasherIterationCount": "반복 횟수는 양의 정수여야 합니다.", |
|||
"Volo.Abp.Identity:InvalidRoleName": "역할 이름 '{0}'은(는) 유효하지 않습니다.", |
|||
"Volo.Abp.Identity:InvalidToken": "토큰이 유효하지 않습니다.", |
|||
"Volo.Abp.Identity:InvalidUserName": "사용자 이름 '{0}'은(는) 유효하지 않습니다.", |
|||
"Volo.Abp.Identity:LoginAlreadyAssociated": "이 로그인 정보와 연결된 사용자가 이미 존재합니다.", |
|||
"Volo.Abp.Identity:PasswordMismatch": "비밀번호가 올바르지 않습니다.", |
|||
"Volo.Abp.Identity:PasswordRequiresDigit": "비밀번호에는 숫자('0'~'9')가 하나 이상 포함되어야 합니다.", |
|||
"Volo.Abp.Identity:PasswordRequiresLower": "비밀번호에는 소문자('a'~'z')가 하나 이상 포함되어야 합니다.", |
|||
"Volo.Abp.Identity:PasswordRequiresNonAlphanumeric": "비밀번호에는 영숫자가 아닌 문자가 하나 이상 포함되어야 합니다.", |
|||
"Volo.Abp.Identity:PasswordRequiresUpper": "비밀번호에는 대문자('A'~'Z')가 하나 이상 포함되어야 합니다.", |
|||
"Volo.Abp.Identity:PasswordTooShort": "비밀번호는 {0}자 이상이어야 합니다.", |
|||
"Volo.Abp.Identity:PasswordRequiresUniqueChars": "비밀번호에는 서로 다른 문자가 {0}개 이상 사용되어야 합니다.", |
|||
"Volo.Abp.Identity:PasswordInHistory": "최근 {0}개의 비밀번호와 동일한 비밀번호는 사용할 수 없습니다.", |
|||
"Volo.Abp.Identity:RoleNotFound": "역할 {0}이(가) 존재하지 않습니다.", |
|||
"Volo.Abp.Identity:UserAlreadyHasPassword": "사용자에게 이미 비밀번호가 설정되어 있습니다.", |
|||
"Volo.Abp.Identity:UserAlreadyInRole": "사용자가 이미 역할 '{0}'에 속해 있습니다.", |
|||
"Volo.Abp.Identity:UserLockedOut": "사용자가 잠겼습니다.", |
|||
"Volo.Abp.Identity:UserLockoutNotEnabled": "이 사용자는 잠금 기능이 활성화되어 있지 않습니다.", |
|||
"Volo.Abp.Identity:UserNameNotFound": "사용자 {0}이(가) 존재하지 않습니다.", |
|||
"Volo.Abp.Identity:UserNotInRole": "사용자가 역할 '{0}'에 속해 있지 않습니다.", |
|||
"Volo.Abp.Identity:PasswordConfirmationFailed": "비밀번호와 비밀번호 확인 값이 일치하지 않습니다.", |
|||
"Volo.Abp.Identity:NullSecurityStamp": "사용자 보안 스탬프는 null일 수 없습니다.", |
|||
"Volo.Abp.Identity:RecoveryCodeRedemptionFailed": "복구 코드를 사용하는 데 실패했습니다.", |
|||
"Volo.Abp.Identity:010001": "자신의 계정은 삭제할 수 없습니다!", |
|||
"Volo.Abp.Identity:010002": "사용자에게 {MaxUserMembershipCount}개를 초과하는 조직 단위를 설정할 수 없습니다!", |
|||
"Volo.Abp.Identity:010003": "외부 로그인을 사용하는 사용자의 비밀번호는 변경할 수 없습니다!", |
|||
"Volo.Abp.Identity:010004": "이름이 {0}인 조직 단위가 이미 존재합니다. 같은 수준에 동일한 이름의 조직 단위를 두 개 만들 수 없습니다.", |
|||
"Volo.Abp.Identity:010005": "정적 역할의 이름은 변경할 수 없습니다.", |
|||
"Volo.Abp.Identity:010006": "정적 역할은 삭제할 수 없습니다.", |
|||
"Volo.Abp.Identity:010007": "자신의 2단계 인증 설정은 변경할 수 없습니다.", |
|||
"Volo.Abp.Identity:010008": "2단계 인증 설정 변경은 허용되지 않습니다.", |
|||
"Volo.Abp.Identity:010009": "자신에게 위임할 수 없습니다.", |
|||
"Volo.Abp.Identity:010010": "상위 조직 단위('{ParentId}')가 존재하지 않거나 다른 테넌트에 속해 있습니다.", |
|||
"Volo.Abp.Identity:010021": "이름이 이미 존재합니다: '{0}'.", |
|||
"Volo.Abp.Identity:010022": "정적 클레임 유형은 업데이트할 수 없습니다.", |
|||
"Volo.Abp.Identity:010023": "정적 클레임 유형은 삭제할 수 없습니다.", |
|||
"Identity.OrganizationUnit.MaxUserMembershipCount": "사용자에게 허용되는 최대 조직 단위 멤버십 수", |
|||
"ThisUserIsNotActiveMessage": "이 사용자는 활성 상태가 아닙니다.", |
|||
"Permission:IdentityManagement": "ID 관리", |
|||
"Permission:RoleManagement": "역할 관리", |
|||
"Permission:Create": "생성", |
|||
"Permission:Edit": "편집", |
|||
"Permission:Delete": "삭제", |
|||
"Permission:ChangePermissions": "권한 변경", |
|||
"Permission:ManageRoles": "역할 관리", |
|||
"Permission:UserManagement": "사용자 관리", |
|||
"Permission:UserLookup": "사용자 조회", |
|||
"DisplayName:Abp.Identity.Password.RequiredLength": "필수 길이", |
|||
"DisplayName:Abp.Identity.Password.RequiredUniqueChars": "필수 고유 문자 수", |
|||
"DisplayName:Abp.Identity.Password.RequireNonAlphanumeric": "필수 영숫자 이외 문자", |
|||
"DisplayName:Abp.Identity.Password.RequireLowercase": "필수 소문자", |
|||
"DisplayName:Abp.Identity.Password.RequireUppercase": "필수 대문자", |
|||
"DisplayName:Abp.Identity.Password.RequireDigit": "필수 숫자", |
|||
"DisplayName:Abp.Identity.Password.ForceUsersToPeriodicallyChangePassword": "사용자의 정기적인 비밀번호 변경 강제", |
|||
"DisplayName:Abp.Identity.Password.PasswordChangePeriodDays": "비밀번호 변경 주기(일)", |
|||
"DisplayName:Abp.Identity.Password.EnablePreventPasswordReuse": "비밀번호 재사용 방지 활성화", |
|||
"DisplayName:Abp.Identity.Password.PreventPasswordReuseCount": "재사용할 수 없는 이전 비밀번호 수", |
|||
"DisplayName:Abp.Identity.Lockout.AllowedForNewUsers": "새 사용자에게 활성화", |
|||
"DisplayName:Abp.Identity.Lockout.LockoutDuration": "잠금 기간(초)", |
|||
"DisplayName:Abp.Identity.Lockout.MaxFailedAccessAttempts": "최대 접근 실패 횟수", |
|||
"DisplayName:Abp.Identity.SignIn.RequireConfirmedEmail": "로그인 시 이메일 인증 강제", |
|||
"DisplayName:Abp.Identity.SignIn.EnablePhoneNumberConfirmation": "사용자의 전화번호 인증 허용", |
|||
"DisplayName:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "로그인 시 전화번호 인증 강제", |
|||
"DisplayName:Abp.Identity.User.IsUserNameUpdateEnabled": "사용자의 사용자 이름 변경 허용", |
|||
"DisplayName:Abp.Identity.User.IsEmailUpdateEnabled": "사용자의 이메일 주소 변경 허용", |
|||
"Description:Abp.Identity.Password.RequiredLength": "비밀번호에 필요한 최소 길이입니다.", |
|||
"Description:Abp.Identity.Password.RequiredUniqueChars": "비밀번호에 포함되어야 하는 서로 다른 문자의 최소 개수입니다.", |
|||
"Description:Abp.Identity.Password.RequireNonAlphanumeric": "비밀번호에 영숫자가 아닌 문자가 포함되어야 하는지 여부입니다.", |
|||
"Description:Abp.Identity.Password.RequireLowercase": "비밀번호에 ASCII 소문자가 포함되어야 하는지 여부입니다.", |
|||
"Description:Abp.Identity.Password.RequireUppercase": "비밀번호에 ASCII 대문자가 포함되어야 하는지 여부입니다.", |
|||
"Description:Abp.Identity.Password.RequireDigit": "비밀번호에 숫자가 포함되어야 하는지 여부입니다.", |
|||
"Description:Abp.Identity.Password.ForceUsersToPeriodicallyChangePassword": "사용자가 정기적으로 비밀번호를 변경하도록 강제할지 여부입니다.", |
|||
"Description:Abp.Identity.Password.PasswordChangePeriodDays": "사용자 비밀번호가 유효한 기간(일)입니다.", |
|||
"Description:Abp.Identity.Password.EnablePreventPasswordReuse": "사용자가 이전 비밀번호를 재사용하지 못하도록 할지 여부입니다.", |
|||
"Description:Abp.Identity.Password.PreventPasswordReuseCount": "재사용할 수 없는 이전 비밀번호의 개수입니다.", |
|||
"Description:Abp.Identity.Lockout.AllowedForNewUsers": "새 사용자를 잠글 수 있는지 여부입니다.", |
|||
"Description:Abp.Identity.Lockout.LockoutDuration": "잠금이 발생했을 때 사용자가 잠기는 기간입니다.", |
|||
"Description:Abp.Identity.Lockout.MaxFailedAccessAttempts": "잠금이 활성화된 경우 사용자가 잠기기 전까지 허용되는 접근 실패 횟수입니다.", |
|||
"Description:Abp.Identity.SignIn.RequireConfirmedEmail": "사용자는 계정을 만들 수 있지만 이메일 주소를 인증하기 전에는 로그인할 수 없습니다.", |
|||
"Description:Abp.Identity.SignIn.EnablePhoneNumberConfirmation": "사용자가 전화번호를 인증할 수 있습니다. SMS 연동이 필요합니다.", |
|||
"Description:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "사용자는 계정을 만들 수 있지만 전화번호를 인증하기 전에는 로그인할 수 없습니다.", |
|||
"Description:Abp.Identity.User.IsUserNameUpdateEnabled": "사용자가 사용자 이름을 변경할 수 있는지 여부입니다.", |
|||
"Description:Abp.Identity.User.IsEmailUpdateEnabled": "사용자가 이메일 주소를 변경할 수 있는지 여부입니다.", |
|||
"DisplayName:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "등록 시 이메일 인증 강제", |
|||
"Description:Abp.Identity.SignIn.RequireEmailVerificationToRegister": "이메일 주소를 인증하지 않으면 사용자 계정이 생성되지 않습니다.", |
|||
"Details": "세부 정보", |
|||
"CreatedBy": "생성자", |
|||
"ModifiedBy": "수정자", |
|||
"ModificationTime": "수정 시간", |
|||
"PasswordUpdateTime": "비밀번호 변경 시간", |
|||
"LockoutEndTime": "잠금 종료 시간", |
|||
"FailedAccessCount": "접근 실패 횟수", |
|||
"UserResourcePermissionProviderKeyLookupService": "사용자", |
|||
"RoleResourcePermissionProviderKeyLookupService": "역할" |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"Volo.IdentityServer:DuplicateIdentityResourceName": "ID 리소스 이름이 이미 존재합니다: {Name}", |
|||
"Volo.IdentityServer:DuplicateApiResourceName": "API 리소스 이름이 이미 존재합니다: {Name}", |
|||
"Volo.IdentityServer:DuplicateApiScopeName": "API 범위 이름이 이미 존재합니다: {Name}", |
|||
"Volo.IdentityServer:DuplicateClientId": "클라이언트 ID가 이미 존재합니다: {ClientId}", |
|||
"UserLockedOut": "잘못된 로그인 시도로 인해 사용자 계정이 잠겼습니다. 잠시 후 다시 시도해 주세요.", |
|||
"InvalidUserNameOrPassword": "사용자 이름 또는 비밀번호가 올바르지 않습니다!", |
|||
"LoginIsNotAllowed": "로그인할 수 없습니다! 계정이 비활성 상태이거나 이메일 또는 전화번호 확인이 필요합니다.", |
|||
"InvalidUsername": "사용자 이름 또는 비밀번호가 올바르지 않습니다!", |
|||
"InvalidAuthenticatorCode": "인증 코드가 올바르지 않습니다!", |
|||
"InvalidRecoveryCode": "복구 코드가 올바르지 않습니다!", |
|||
"TheTargetUserIsNotLinkedToYou": "대상 사용자가 현재 사용자와 연결되어 있지 않습니다!", |
|||
"ClientResourcePermissionProviderKeyLookupService": "클라이언트" |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"TheOpenIDConnectRequestCannotBeRetrieved": "OpenID Connect 요청을 가져올 수 없습니다.", |
|||
"TheUserDetailsCannotBbeRetrieved": "사용자 세부 정보를 가져올 수 없습니다.", |
|||
"TheApplicationDetailsCannotBeFound": "애플리케이션 세부 정보를 찾을 수 없습니다.", |
|||
"DetailsConcerningTheCallingClientApplicationCannotBeFound": "호출한 클라이언트 애플리케이션의 세부 정보를 찾을 수 없습니다.", |
|||
"TheSpecifiedGrantTypeIsNotImplemented": "지정된 권한 부여 유형 {0}은(는) 구현되어 있지 않습니다.", |
|||
"Authorization": "권한 부여", |
|||
"DoYouWantToGrantAccessToYourData": "{0}에게 데이터 접근 권한을 부여하시겠습니까?", |
|||
"ScopesRequested": "요청된 범위", |
|||
"Accept": "허용", |
|||
"Deny": "거부", |
|||
"ApplicationResourcePermissionProviderKeyLookupService": "클라이언트" |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"Permissions": "권한", |
|||
"OnlyProviderPermissons": "이 프로바이더만", |
|||
"All": "모두", |
|||
"SelectAllInAllTabs": "모든 권한 부여", |
|||
"SelectAllInThisTab": "모두 선택", |
|||
"SaveWithoutAnyPermissionsWarningMessage": "권한을 하나도 부여하지 않고 저장하시겠습니까?", |
|||
"PermissionGroup": "권한 그룹", |
|||
"Filter": "필터", |
|||
"ResourcePermissions": "권한", |
|||
"ResourcePermissionTarget": "대상", |
|||
"ResourcePermissionPermissions": "권한", |
|||
"AddResourcePermission": "권한 추가", |
|||
"ResourcePermissionDeletionConfirmationMessage": "모든 권한을 삭제하시겠습니까?", |
|||
"UpdateResourcePermission": "권한 업데이트", |
|||
"GrantAllResourcePermissions": "모두 부여", |
|||
"NoResourceProviderKeyLookupServiceFound": "프로바이더 키 조회 서비스를 찾을 수 없습니다.", |
|||
"NoResourcePermissionFound": "정의된 권한이 없습니다.", |
|||
"UpdatePermission": "권한 업데이트", |
|||
"NoPermissionsAssigned": "할당된 권한이 없습니다.", |
|||
"SelectProvider": "프로바이더 선택", |
|||
"SearchProviderKey": "프로바이더 키 검색", |
|||
"Provider": "프로바이더", |
|||
"ErrorLoadingPermissions": "권한을 불러오는 중 오류가 발생했습니다.", |
|||
"PleaseSelectProviderAndPermissions": "프로바이더와 권한을 선택해 주세요." |
|||
} |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"Settings": "설정", |
|||
"SavedSuccessfully": "성공적으로 저장되었습니다.", |
|||
"Permission:SettingManagement": "설정 관리", |
|||
"Permission:Emailing": "이메일", |
|||
"Permission:EmailingTest": "이메일 테스트", |
|||
"Permission:TimeZone": "시간대", |
|||
"SendTestEmail": "테스트 이메일 보내기", |
|||
"SenderEmailAddress": "발신자 이메일 주소", |
|||
"TargetEmailAddress": "수신자 이메일 주소", |
|||
"Subject": "제목", |
|||
"Body": "본문", |
|||
"TestEmailSubject": "테스트 이메일 {0}", |
|||
"TestEmailBody": "테스트 이메일 본문 메시지입니다.", |
|||
"SentSuccessfully": "성공적으로 전송되었습니다.", |
|||
"MailSendingFailed": "이메일 전송에 실패했습니다. 이메일 설정을 확인한 후 다시 시도해 주세요.", |
|||
"Send": "보내기", |
|||
"Menu:Settings": "설정", |
|||
"Menu:Emailing": "이메일", |
|||
"Menu:TimeZone": "시간대", |
|||
"DisplayName:Timezone": "시간대", |
|||
"TimezoneHelpText": "이 기능을 사용하면 서버의 기본 시간대를 설정할 수 있으며, 사용자는 각자 자신의 시간대를 선택할 수 있습니다. 사용자의 시간대가 서버 시간대와 다르면 모든 시간이 이에 맞게 조정됩니다. 예를 들어 서버가 Europe/London(00:00)으로 설정되어 있고 사용자가 Europe/Paris(+01:00)에 있는 경우, 해당 사용자의 시간은 1시간 조정됩니다. '기본 시간대'를 선택하면 서버 또는 브라우저의 시간대가 자동으로 사용됩니다.", |
|||
"DefaultTimeZone": "기본 시간대", |
|||
"SmtpHost": "호스트", |
|||
"SmtpPort": "포트", |
|||
"SmtpUserName": "사용자 이름", |
|||
"SmtpPassword": "비밀번호", |
|||
"SmtpDomain": "도메인", |
|||
"SmtpEnableSsl": "SSL 사용", |
|||
"SmtpUseDefaultCredentials": "기본 자격 증명 사용", |
|||
"DefaultFromAddress": "기본 발신자 주소", |
|||
"DefaultFromDisplayName": "기본 발신자 표시 이름", |
|||
"Feature:SettingManagementGroup": "설정 관리", |
|||
"Feature:SettingManagementEnable": "설정 관리 사용", |
|||
"Feature:SettingManagementEnableDescription": "애플리케이션에서 설정 관리 시스템을 사용합니다.", |
|||
"Feature:AllowChangingEmailSettings": "이메일 설정 변경 허용", |
|||
"Feature:AllowChangingEmailSettingsDescription": "이메일 설정 변경을 허용합니다.", |
|||
"SmtpPasswordPlaceholder": "비밀번호를 변경하려면 값을 입력하세요.", |
|||
"NoSettingsAvailable": "표시할 설정이 없습니다." |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"Volo.Abp.TenantManagement:DuplicateTenantName": "테넌트 이름이 이미 존재합니다: {Name}", |
|||
"Menu:TenantManagement": "테넌트 관리", |
|||
"Tenants": "테넌트", |
|||
"NewTenant": "새 테넌트", |
|||
"TenantName": "테넌트 이름", |
|||
"DisplayName:TenantName": "테넌트 이름", |
|||
"TenantDeletionConfirmationMessage": "테넌트 '{0}'이(가) 삭제됩니다. 계속하시겠습니까?", |
|||
"ConnectionStrings": "연결 문자열", |
|||
"DisplayName:DefaultConnectionString": "기본 연결 문자열", |
|||
"DisplayName:UseSharedDatabase": "공유 데이터베이스 사용", |
|||
"Permission:TenantManagement": "테넌트 관리", |
|||
"Permission:Create": "생성", |
|||
"Permission:Edit": "편집", |
|||
"Permission:Delete": "삭제", |
|||
"Permission:ManageConnectionStrings": "연결 문자열 관리", |
|||
"Permission:ManageFeatures": "기능", |
|||
"DisplayName:AdminEmailAddress": "관리자 이메일 주소", |
|||
"DisplayName:AdminPassword": "관리자 비밀번호" |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
{ |
|||
"culture": "ko", |
|||
"texts": { |
|||
"VirtualFileExplorer": "가상 파일 탐색기", |
|||
"VirtualFileType": "가상 파일 형식", |
|||
"Menu:VirtualFileExplorer": "가상 파일 탐색기", |
|||
"LastUpdateTime": "마지막 업데이트 시간", |
|||
"VirtualFileName": "가상 파일 이름", |
|||
"FileContent": "파일 내용", |
|||
"Size": "크기", |
|||
"BackToRoot": "루트로 돌아가기", |
|||
"EmptyFileInfoList": "가상 파일이 없습니다.", |
|||
"Permission:AbpVirtualFileExplorer": "가상 파일 탐색기", |
|||
"Permission:AbpVirtualFileExplorer:View": "보기" |
|||
} |
|||
} |
|||
@ -1 +1 @@ |
|||
<abp-breadcrumb-items [items]="segments"></abp-breadcrumb-items> |
|||
<abp-breadcrumb-items [items]="segments()" /> |
|||
|
|||