openfree commited on
Commit
e86e389
Β·
verified Β·
1 Parent(s): dfd67fc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +309 -29
app.py CHANGED
@@ -3,6 +3,8 @@ import pandas as pd
3
  import numpy as np
4
  from datetime import datetime
5
  import plotly.graph_objects as go
 
 
6
 
7
  class StartupValuationCalculator:
8
  def __init__(self):
@@ -34,20 +36,31 @@ class StartupValuationCalculator:
34
  "retention": 0.2,
35
  "payback": 0.2
36
  }
 
 
 
 
 
 
 
 
 
 
 
37
 
38
  def calculate_arr(self, monthly_revenue, revenue_type):
39
  """μ›” λ§€μΆœμ„ μ—°κ°„ 반볡 맀좜(ARR)둜 λ³€ν™˜"""
40
  if revenue_type == "κ΅¬λ…ν˜• (SaaS)":
41
  return monthly_revenue * 12
42
  elif revenue_type == "κ±°λž˜μˆ˜μˆ˜λ£Œν˜•":
43
- return monthly_revenue * 12 * 0.8 # κ±°λž˜μˆ˜μˆ˜λ£ŒλŠ” 변동성 κ³ λ €
44
  else:
45
- return monthly_revenue * 12 * 0.6 # μΌνšŒμ„± λ§€μΆœμ€ 더 할인
46
 
47
  def calculate_ltv(self, arpu, gross_margin, monthly_churn):
48
  """LTV 계산"""
49
  if monthly_churn == 0:
50
- monthly_churn = 0.01 # μ΅œμ†Œ μ΄νƒˆλ₯ 
51
  return arpu * (gross_margin / 100) / monthly_churn
52
 
53
  def calculate_cac(self, monthly_marketing, monthly_sales, new_customers):
@@ -74,6 +87,118 @@ class StartupValuationCalculator:
74
  total_score = sum(scores[key] * self.unit_economics_weights[key] for key in scores)
75
  return total_score
76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  def get_growth_category(self, growth_rate):
78
  """μ„±μž₯λ₯  μΉ΄ν…Œκ³ λ¦¬ κ²°μ •"""
79
  if growth_rate < 20:
@@ -87,7 +212,7 @@ class StartupValuationCalculator:
87
  else:
88
  return "200%+"
89
 
90
- def calculate_valuation(self, data):
91
  """μ’…ν•© κ°€μΉ˜ν‰κ°€ 계산"""
92
  # ARR 계산
93
  arr = self.calculate_arr(data["monthly_revenue"], data["revenue_type"])
@@ -103,11 +228,17 @@ class StartupValuationCalculator:
103
  ltv_cac_ratio, data["gross_margin"], data["retention_rate"], payback
104
  )
105
 
 
 
 
 
 
 
106
  # κΈ°λ³Έ λ©€ν‹°ν”Œ 선택
107
  multiples = self.industry_multiples[data["industry"]]
108
- if ue_score >= 80:
109
  base_multiple = multiples["high"]
110
- elif ue_score >= 50:
111
  base_multiple = multiples["mid"]
112
  else:
113
  base_multiple = multiples["low"]
@@ -123,7 +254,11 @@ class StartupValuationCalculator:
123
  "μ„±μž₯ 단계": 1.0,
124
  "μˆ˜μ΅μ„± 확보": 1.2
125
  }
126
- final_multiple = adjusted_multiple * stage_adj[data["stage"]]
 
 
 
 
127
 
128
  # μ΅œμ’… κ°€μΉ˜ν‰κ°€
129
  valuation = arr * final_multiple
@@ -140,6 +275,9 @@ class StartupValuationCalculator:
140
  "ltv_cac_ratio": ltv_cac_ratio,
141
  "payback": payback,
142
  "ue_score": ue_score,
 
 
 
143
  "runway": runway
144
  }
145
 
@@ -172,6 +310,33 @@ class StartupValuationCalculator:
172
  )
173
 
174
  return fig
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
 
176
  def create_ui():
177
  calculator = StartupValuationCalculator()
@@ -180,11 +345,16 @@ def create_ui():
180
  company_name, founded_year, industry, stage, revenue_type,
181
  monthly_revenue, growth_rate, arpu, gross_margin, monthly_churn,
182
  retention_rate, new_customers, monthly_marketing, monthly_sales,
183
- cash_balance, burn_rate
 
 
 
 
 
184
  ):
185
  # μž…λ ₯κ°’ 검증
186
  if monthly_revenue <= 0:
187
- return "μ›” λ§€μΆœμ„ μž…λ ₯ν•΄μ£Όμ„Έμš”.", None, None
188
 
189
  # 데이터 μ€€λΉ„
190
  data = {
@@ -193,7 +363,7 @@ def create_ui():
193
  "industry": industry,
194
  "stage": stage,
195
  "revenue_type": revenue_type,
196
- "monthly_revenue": monthly_revenue * 1000, # 천 λ‹¬λŸ¬ λ‹¨μœ„λ‘œ μž…λ ₯λ°›μŒ
197
  "growth_rate": growth_rate,
198
  "arpu": arpu,
199
  "gross_margin": gross_margin,
@@ -206,8 +376,27 @@ def create_ui():
206
  "burn_rate": burn_rate * 1000
207
  }
208
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
  # κ°€μΉ˜ν‰κ°€ 계산
210
- results = calculator.calculate_valuation(data)
211
 
212
  # κ²°κ³Ό ν¬λ§·νŒ…
213
  valuation_text = f"""
@@ -225,6 +414,19 @@ def create_ui():
225
  - **Payback Period**: {results['payback']:.1f}κ°œμ›”
226
  - **λ‹¨μœ„κ²½μ œ 점수**: {results['ue_score']:.0f}/100
227
 
 
 
 
 
 
 
 
 
 
 
 
 
 
228
  ## πŸƒ 재무 건전성
229
  - **ν˜„κΈˆ λŸ°μ›¨μ΄**: {results['runway']:.1f}κ°œμ›”
230
  - **μ›”κ°„ 번레이트**: ${burn_rate}K
@@ -243,27 +445,34 @@ def create_ui():
243
  if gross_margin < 60:
244
  valuation_text += "- πŸ“ˆ 맀좜총이읡λ₯  κ°œμ„  μ—¬μ§€κ°€ μžˆμŠ΅λ‹ˆλ‹€. (업계 평균: 70-80%)\n"
245
 
 
 
 
246
  # 비ꡐ 차트 생성
247
  comparison_chart = calculator.create_comparison_chart(
248
  results['valuation'], industry, results['arr']
249
  )
250
 
 
 
 
251
  # 상세 뢄석 ν…Œμ΄λΈ”
252
  metrics_df = pd.DataFrame({
253
- "μ§€ν‘œ": ["μ›” 맀좜", "μ—° μ„±μž₯λ₯ ", "맀좜총이읡λ₯ ", "μ›” μ΄νƒˆλ₯ ", "고객 μœ μ§€μœ¨"],
254
  "ν˜„μž¬ κ°’": [f"${monthly_revenue}K", f"{growth_rate}%", f"{gross_margin}%",
255
- f"{monthly_churn}%", f"{retention_rate}%"],
256
- "업계 평균": ["N/A", "50-100%", "70-80%", "2-5%", "80-90%"]
257
  })
258
 
259
- return valuation_text, comparison_chart, metrics_df
260
 
261
  # Gradio UI
262
  with gr.Blocks(title="μŠ€νƒ€νŠΈμ—… κ°€μΉ˜ν‰κ°€ 계산기", theme=gr.themes.Soft()) as demo:
263
  gr.Markdown("""
264
- # πŸ¦„ μŠ€νƒ€νŠΈμ—… κ°€μΉ˜ν‰κ°€ μžλ™ν™” μ‹œμŠ€ν…œ
265
 
266
  κ°„λ‹¨ν•œ 정보 μž…λ ₯만으둜 κ·€μ‚¬μ˜ μ˜ˆμƒ κΈ°μ—…κ°€μΉ˜λ₯Ό μ‚°μΆœν•˜κ³  동쒅업계와 λΉ„κ΅ν•΄λ“œλ¦½λ‹ˆλ‹€.
 
267
  """)
268
 
269
  with gr.Tab("κΈ°λ³Έ 정보"):
@@ -315,6 +524,53 @@ def create_ui():
315
  monthly_marketing = gr.Number(label="μ›” λ§ˆμΌ€νŒ… λΉ„μš© ($K)", value=20)
316
  monthly_sales = gr.Number(label="μ›” μ˜μ—… λΉ„μš© ($K)", value=15)
317
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
318
  with gr.Tab("재무 ν˜„ν™©"):
319
  gr.Markdown("### πŸ’Έ ν˜„κΈˆ 상황 (λ‹¨μœ„: 천 λ‹¬λŸ¬)")
320
  with gr.Row():
@@ -331,7 +587,9 @@ def create_ui():
331
  with gr.Column(scale=1):
332
  metrics_table = gr.DataFrame(label="μ£Όμš” μ§€ν‘œ 비ꡐ")
333
 
334
- comparison_chart = gr.Plot(label="동쒅업계 비ꡐ")
 
 
335
 
336
  # 이벀트 μ—°κ²°
337
  evaluate_btn.click(
@@ -340,41 +598,63 @@ def create_ui():
340
  company_name, founded_year, industry, stage, revenue_type,
341
  monthly_revenue, growth_rate, arpu, gross_margin, monthly_churn,
342
  retention_rate, new_customers, monthly_marketing, monthly_sales,
343
- cash_balance, burn_rate
 
 
 
 
344
  ],
345
- outputs=[valuation_output, comparison_chart, metrics_table]
346
  )
347
 
348
  # μ˜ˆμ‹œ 데이터 λ²„νŠΌλ“€
349
  gr.Markdown("### πŸ“ μ˜ˆμ‹œ λ°μ΄ν„°λ‘œ ν…ŒμŠ€νŠΈν•˜κΈ°")
350
  with gr.Row():
351
- gr.Button("SaaS μŠ€νƒ€νŠΈμ—… μ˜ˆμ‹œ").click(
352
  lambda: [
353
- "ν…Œν¬ μŠ€νƒ€νŠΈμ—…", 2021, "SaaS - B2B", "μ„±μž₯ 단계", "κ΅¬λ…ν˜• (SaaS)",
354
  100, 150, 200, 75, 2,
355
  90, 40, 30, 20,
356
- 2000, 120
 
 
 
 
 
357
  ],
358
  outputs=[
359
  company_name, founded_year, industry, stage, revenue_type,
360
  monthly_revenue, growth_rate, arpu, gross_margin, monthly_churn,
361
  retention_rate, new_customers, monthly_marketing, monthly_sales,
362
- cash_balance, burn_rate
 
 
 
 
363
  ]
364
  )
365
 
366
- gr.Button("이컀머슀 μ˜ˆμ‹œ").click(
367
  lambda: [
368
- "온라인 μ‡Όν•‘λͺ°", 2022, "이컀머슀", "초기 맀좜", "μΌνšŒμ„± 판맀",
369
- 80, 80, 50, 40, 5,
370
- 70, 100, 25, 10,
371
- 500, 70
 
 
 
 
 
372
  ],
373
  outputs=[
374
  company_name, founded_year, industry, stage, revenue_type,
375
  monthly_revenue, growth_rate, arpu, gross_margin, monthly_churn,
376
  retention_rate, new_customers, monthly_marketing, monthly_sales,
377
- cash_balance, burn_rate
 
 
 
 
378
  ]
379
  )
380
 
 
3
  import numpy as np
4
  from datetime import datetime
5
  import plotly.graph_objects as go
6
+ import re
7
+ from urllib.parse import urlparse
8
 
9
  class StartupValuationCalculator:
10
  def __init__(self):
 
36
  "retention": 0.2,
37
  "payback": 0.2
38
  }
39
+
40
+ # IP μžμ‚° κ°€μΉ˜ κ°€μ€‘μΉ˜
41
+ self.ip_asset_weights = {
42
+ "patents": 0.25,
43
+ "papers": 0.15,
44
+ "domains": 0.15,
45
+ "trademarks": 0.10,
46
+ "github": 0.10,
47
+ "awards": 0.10,
48
+ "team": 0.15
49
+ }
50
 
51
  def calculate_arr(self, monthly_revenue, revenue_type):
52
  """μ›” λ§€μΆœμ„ μ—°κ°„ 반볡 맀좜(ARR)둜 λ³€ν™˜"""
53
  if revenue_type == "κ΅¬λ…ν˜• (SaaS)":
54
  return monthly_revenue * 12
55
  elif revenue_type == "κ±°λž˜μˆ˜μˆ˜λ£Œν˜•":
56
+ return monthly_revenue * 12 * 0.8
57
  else:
58
+ return monthly_revenue * 12 * 0.6
59
 
60
  def calculate_ltv(self, arpu, gross_margin, monthly_churn):
61
  """LTV 계산"""
62
  if monthly_churn == 0:
63
+ monthly_churn = 0.01
64
  return arpu * (gross_margin / 100) / monthly_churn
65
 
66
  def calculate_cac(self, monthly_marketing, monthly_sales, new_customers):
 
87
  total_score = sum(scores[key] * self.unit_economics_weights[key] for key in scores)
88
  return total_score
89
 
90
+ def evaluate_domain(self, domains):
91
+ """도메인 κ°€μΉ˜ 평가"""
92
+ if not domains:
93
+ return 0
94
+
95
+ domain_list = [d.strip() for d in domains.split(',') if d.strip()]
96
+ score = 0
97
+
98
+ for domain in domain_list:
99
+ parsed = urlparse(domain if domain.startswith('http') else f'http://{domain}')
100
+ domain_name = parsed.netloc or parsed.path
101
+
102
+ # .com 도메인 가산점
103
+ if domain_name.endswith('.com'):
104
+ score += 30
105
+ elif domain_name.endswith(('.io', '.ai', '.tech')):
106
+ score += 20
107
+ else:
108
+ score += 10
109
+
110
+ # 짧은 도메인 가산점
111
+ name_length = len(domain_name.split('.')[0])
112
+ if name_length <= 5:
113
+ score += 20
114
+ elif name_length <= 8:
115
+ score += 10
116
+
117
+ return min(100, score / len(domain_list))
118
+
119
+ def evaluate_patents(self, patent_filed, patent_granted):
120
+ """νŠΉν—ˆ κ°€μΉ˜ 평가"""
121
+ score = 0
122
+ score += patent_filed * 15 # μΆœμ› νŠΉν—ˆλ‹Ή 15점
123
+ score += patent_granted * 30 # 등둝 νŠΉν—ˆλ‹Ή 30점
124
+ return min(100, score)
125
+
126
+ def evaluate_papers(self, papers):
127
+ """λ…Όλ¬Έ κ°€μΉ˜ 평가"""
128
+ if not papers:
129
+ return 0
130
+
131
+ paper_count = len([p.strip() for p in papers.split('\n') if p.strip()])
132
+ score = paper_count * 20 # λ…Όλ¬Έλ‹Ή 20점
133
+
134
+ # μ£Όμš” ν•™νšŒ/저널 ν‚€μ›Œλ“œ 체크
135
+ prestigious_keywords = ['Nature', 'Science', 'IEEE', 'ACM', 'CVPR', 'NeurIPS', 'ICML']
136
+ for keyword in prestigious_keywords:
137
+ if keyword.lower() in papers.lower():
138
+ score += 10
139
+
140
+ return min(100, score)
141
+
142
+ def evaluate_github(self, github_url, github_stars):
143
+ """GitHub μ €μž₯μ†Œ 평가"""
144
+ if not github_url:
145
+ return 0
146
+
147
+ score = 0
148
+ if github_stars >= 1000:
149
+ score = 80
150
+ elif github_stars >= 500:
151
+ score = 60
152
+ elif github_stars >= 100:
153
+ score = 40
154
+ elif github_stars >= 50:
155
+ score = 20
156
+ else:
157
+ score = 10
158
+
159
+ return score
160
+
161
+ def evaluate_team(self, team_size, phd_count, serial_entrepreneurs, big_tech_experience):
162
+ """νŒ€ μ—­λŸ‰ 평가"""
163
+ score = 0
164
+
165
+ # νŒ€ 규λͺ¨
166
+ if team_size >= 20:
167
+ score += 20
168
+ elif team_size >= 10:
169
+ score += 15
170
+ elif team_size >= 5:
171
+ score += 10
172
+
173
+ # 박사 ν•™μœ„
174
+ score += min(30, phd_count * 10)
175
+
176
+ # 연쇄창업가
177
+ score += min(30, serial_entrepreneurs * 15)
178
+
179
+ # λΉ…ν…Œν¬ κ²½ν—˜
180
+ score += min(20, big_tech_experience * 5)
181
+
182
+ return min(100, score)
183
+
184
+ def calculate_ip_score(self, ip_data):
185
+ """μ§€μ μž¬μ‚° μ’…ν•© 점수 계산"""
186
+ scores = {
187
+ "patents": self.evaluate_patents(ip_data["patent_filed"], ip_data["patent_granted"]),
188
+ "papers": self.evaluate_papers(ip_data["papers"]),
189
+ "domains": self.evaluate_domain(ip_data["domains"]),
190
+ "trademarks": min(100, ip_data["trademarks"] * 20),
191
+ "github": self.evaluate_github(ip_data["github_url"], ip_data["github_stars"]),
192
+ "awards": min(100, ip_data["awards"] * 25),
193
+ "team": self.evaluate_team(
194
+ ip_data["team_size"], ip_data["phd_count"],
195
+ ip_data["serial_entrepreneurs"], ip_data["big_tech_experience"]
196
+ )
197
+ }
198
+
199
+ total_score = sum(scores[key] * self.ip_asset_weights[key] for key in scores)
200
+ return total_score, scores
201
+
202
  def get_growth_category(self, growth_rate):
203
  """μ„±μž₯λ₯  μΉ΄ν…Œκ³ λ¦¬ κ²°μ •"""
204
  if growth_rate < 20:
 
212
  else:
213
  return "200%+"
214
 
215
+ def calculate_valuation(self, data, ip_data):
216
  """μ’…ν•© κ°€μΉ˜ν‰κ°€ 계산"""
217
  # ARR 계산
218
  arr = self.calculate_arr(data["monthly_revenue"], data["revenue_type"])
 
228
  ltv_cac_ratio, data["gross_margin"], data["retention_rate"], payback
229
  )
230
 
231
+ # IP μžμ‚° 점수
232
+ ip_score, ip_breakdown = self.calculate_ip_score(ip_data)
233
+
234
+ # μ’…ν•© 점수 (λ‹¨μœ„κ²½μ œ 60%, IP 40%)
235
+ combined_score = ue_score * 0.6 + ip_score * 0.4
236
+
237
  # κΈ°λ³Έ λ©€ν‹°ν”Œ 선택
238
  multiples = self.industry_multiples[data["industry"]]
239
+ if combined_score >= 80:
240
  base_multiple = multiples["high"]
241
+ elif combined_score >= 50:
242
  base_multiple = multiples["mid"]
243
  else:
244
  base_multiple = multiples["low"]
 
254
  "μ„±μž₯ 단계": 1.0,
255
  "μˆ˜μ΅μ„± 확보": 1.2
256
  }
257
+
258
+ # IP μžμ‚° 프리미엄 (μ΅œλŒ€ 20%)
259
+ ip_premium = 1 + (ip_score / 100 * 0.2)
260
+
261
+ final_multiple = adjusted_multiple * stage_adj[data["stage"]] * ip_premium
262
 
263
  # μ΅œμ’… κ°€μΉ˜ν‰κ°€
264
  valuation = arr * final_multiple
 
275
  "ltv_cac_ratio": ltv_cac_ratio,
276
  "payback": payback,
277
  "ue_score": ue_score,
278
+ "ip_score": ip_score,
279
+ "ip_breakdown": ip_breakdown,
280
+ "combined_score": combined_score,
281
  "runway": runway
282
  }
283
 
 
310
  )
311
 
312
  return fig
313
+
314
+ def create_ip_breakdown_chart(self, ip_breakdown):
315
+ """IP μžμ‚° 뢄석 차트"""
316
+ categories = list(ip_breakdown.keys())
317
+ values = list(ip_breakdown.values())
318
+
319
+ fig = go.Figure(data=[
320
+ go.Radar(
321
+ r=values,
322
+ theta=categories,
323
+ fill='toself',
324
+ name='IP μžμ‚° 점수'
325
+ )
326
+ ])
327
+
328
+ fig.update_layout(
329
+ polar=dict(
330
+ radialaxis=dict(
331
+ visible=True,
332
+ range=[0, 100]
333
+ )
334
+ ),
335
+ showlegend=False,
336
+ title="μ§€μ μž¬μ‚° μžμ‚° 뢄석"
337
+ )
338
+
339
+ return fig
340
 
341
  def create_ui():
342
  calculator = StartupValuationCalculator()
 
345
  company_name, founded_year, industry, stage, revenue_type,
346
  monthly_revenue, growth_rate, arpu, gross_margin, monthly_churn,
347
  retention_rate, new_customers, monthly_marketing, monthly_sales,
348
+ cash_balance, burn_rate,
349
+ # IP κ΄€λ ¨ μž…λ ₯
350
+ domains, patent_filed, patent_granted, papers, trademarks,
351
+ github_url, github_stars, awards, partnerships,
352
+ team_size, phd_count, serial_entrepreneurs, big_tech_experience,
353
+ media_coverage, app_downloads, social_followers
354
  ):
355
  # μž…λ ₯κ°’ 검증
356
  if monthly_revenue <= 0:
357
+ return "μ›” λ§€μΆœμ„ μž…λ ₯ν•΄μ£Όμ„Έμš”.", None, None, None
358
 
359
  # 데이터 μ€€λΉ„
360
  data = {
 
363
  "industry": industry,
364
  "stage": stage,
365
  "revenue_type": revenue_type,
366
+ "monthly_revenue": monthly_revenue * 1000,
367
  "growth_rate": growth_rate,
368
  "arpu": arpu,
369
  "gross_margin": gross_margin,
 
376
  "burn_rate": burn_rate * 1000
377
  }
378
 
379
+ ip_data = {
380
+ "domains": domains,
381
+ "patent_filed": patent_filed,
382
+ "patent_granted": patent_granted,
383
+ "papers": papers,
384
+ "trademarks": trademarks,
385
+ "github_url": github_url,
386
+ "github_stars": github_stars,
387
+ "awards": awards,
388
+ "partnerships": partnerships,
389
+ "team_size": team_size,
390
+ "phd_count": phd_count,
391
+ "serial_entrepreneurs": serial_entrepreneurs,
392
+ "big_tech_experience": big_tech_experience,
393
+ "media_coverage": media_coverage,
394
+ "app_downloads": app_downloads,
395
+ "social_followers": social_followers
396
+ }
397
+
398
  # κ°€μΉ˜ν‰κ°€ 계산
399
+ results = calculator.calculate_valuation(data, ip_data)
400
 
401
  # κ²°κ³Ό ν¬λ§·νŒ…
402
  valuation_text = f"""
 
414
  - **Payback Period**: {results['payback']:.1f}κ°œμ›”
415
  - **λ‹¨μœ„κ²½μ œ 점수**: {results['ue_score']:.0f}/100
416
 
417
+ ## 🎯 μ§€μ μž¬μ‚° 및 λ¬΄ν˜•μžμ‚°
418
+ - **IP μžμ‚° 점수**: {results['ip_score']:.0f}/100
419
+ - **μ’…ν•© 점수**: {results['combined_score']:.0f}/100
420
+
421
+ ### IP μžμ‚° μ„ΈλΆ€ 평가:
422
+ - νŠΉν—ˆ: {results['ip_breakdown']['patents']:.0f}/100
423
+ - λ…Όλ¬Έ: {results['ip_breakdown']['papers']:.0f}/100
424
+ - 도메인: {results['ip_breakdown']['domains']:.0f}/100
425
+ - μƒν‘œκΆŒ: {results['ip_breakdown']['trademarks']:.0f}/100
426
+ - μ˜€ν”ˆμ†ŒμŠ€: {results['ip_breakdown']['github']:.0f}/100
427
+ - μˆ˜μƒμ‹€μ : {results['ip_breakdown']['awards']:.0f}/100
428
+ - νŒ€ μ—­λŸ‰: {results['ip_breakdown']['team']:.0f}/100
429
+
430
  ## πŸƒ 재무 건전성
431
  - **ν˜„κΈˆ λŸ°μ›¨μ΄**: {results['runway']:.1f}κ°œμ›”
432
  - **μ›”κ°„ 번레이트**: ${burn_rate}K
 
445
  if gross_margin < 60:
446
  valuation_text += "- πŸ“ˆ 맀좜총이읡λ₯  κ°œμ„  μ—¬μ§€κ°€ μžˆμŠ΅λ‹ˆλ‹€. (업계 평균: 70-80%)\n"
447
 
448
+ if results['ip_score'] > 70:
449
+ valuation_text += "- πŸ† κ°•λ ₯ν•œ IP 포트폴리였λ₯Ό λ³΄μœ ν•˜κ³  μžˆμ–΄ κ°€μΉ˜ν‰κ°€μ— 프리미엄이 μ μš©λ˜μ—ˆμŠ΅λ‹ˆλ‹€.\n"
450
+
451
  # 비ꡐ 차트 생성
452
  comparison_chart = calculator.create_comparison_chart(
453
  results['valuation'], industry, results['arr']
454
  )
455
 
456
+ # IP 뢄석 차트
457
+ ip_chart = calculator.create_ip_breakdown_chart(results['ip_breakdown'])
458
+
459
  # 상세 뢄석 ν…Œμ΄λΈ”
460
  metrics_df = pd.DataFrame({
461
+ "μ§€ν‘œ": ["μ›” 맀좜", "μ—° μ„±μž₯λ₯ ", "맀좜총이읡λ₯ ", "μ›” μ΄νƒˆλ₯ ", "고객 μœ μ§€μœ¨", "IP μžμ‚° 점수"],
462
  "ν˜„μž¬ κ°’": [f"${monthly_revenue}K", f"{growth_rate}%", f"{gross_margin}%",
463
+ f"{monthly_churn}%", f"{retention_rate}%", f"{results['ip_score']:.0f}/100"],
464
+ "업계 평균": ["N/A", "50-100%", "70-80%", "2-5%", "80-90%", "50/100"]
465
  })
466
 
467
+ return valuation_text, comparison_chart, ip_chart, metrics_df
468
 
469
  # Gradio UI
470
  with gr.Blocks(title="μŠ€νƒ€νŠΈμ—… κ°€μΉ˜ν‰κ°€ 계산기", theme=gr.themes.Soft()) as demo:
471
  gr.Markdown("""
472
+ # πŸ¦„ μŠ€νƒ€νŠΈμ—… κ°€μΉ˜ν‰κ°€ μžλ™ν™” μ‹œμŠ€ν…œ v2.0
473
 
474
  κ°„λ‹¨ν•œ 정보 μž…λ ₯만으둜 κ·€μ‚¬μ˜ μ˜ˆμƒ κΈ°μ—…κ°€μΉ˜λ₯Ό μ‚°μΆœν•˜κ³  동쒅업계와 λΉ„κ΅ν•΄λ“œλ¦½λ‹ˆλ‹€.
475
+ 이제 μ§€μ μž¬μ‚°κ³Ό λ¬΄ν˜•μžμ‚°κΉŒμ§€ μ’…ν•©μ μœΌλ‘œ ν‰κ°€ν•©λ‹ˆλ‹€.
476
  """)
477
 
478
  with gr.Tab("κΈ°λ³Έ 정보"):
 
524
  monthly_marketing = gr.Number(label="μ›” λ§ˆμΌ€νŒ… λΉ„μš© ($K)", value=20)
525
  monthly_sales = gr.Number(label="μ›” μ˜μ—… λΉ„μš© ($K)", value=15)
526
 
527
+ with gr.Tab("μ§€μ μž¬μ‚° 및 기술"):
528
+ gr.Markdown("### πŸ“š νŠΉν—ˆ 및 λ…Όλ¬Έ")
529
+ with gr.Row():
530
+ patent_filed = gr.Number(label="μΆœμ› νŠΉν—ˆ 수", value=2)
531
+ patent_granted = gr.Number(label="등둝 νŠΉν—ˆ 수", value=1)
532
+ trademarks = gr.Number(label="μƒν‘œκΆŒ 수", value=1)
533
+
534
+ papers = gr.Textbox(
535
+ label="λ°œν‘œ λ…Όλ¬Έ (ν•œ 쀄에 ν•˜λ‚˜μ”©, URL 포함 κ°€λŠ₯)",
536
+ lines=3,
537
+ placeholder="예: https://arxiv.org/abs/2301.12345 - AI Model Optimization\nICML 2023 - Novel Approach to Machine Learning"
538
+ )
539
+
540
+ gr.Markdown("### 🌐 λ””μ§€ν„Έ μžμ‚°")
541
+ domains = gr.Textbox(
542
+ label="보유 도메인 (μ‰Όν‘œλ‘œ ꡬ뢄)",
543
+ placeholder="예: mycompany.com, mycompany.ai, myproduct.io"
544
+ )
545
+
546
+ with gr.Row():
547
+ github_url = gr.Textbox(
548
+ label="GitHub μ €μž₯μ†Œ URL",
549
+ placeholder="https://github.com/yourcompany/yourrepo"
550
+ )
551
+ github_stars = gr.Number(label="GitHub μŠ€νƒ€ 수", value=100)
552
+
553
+ gr.Markdown("### πŸ† 인증 및 μˆ˜μƒ")
554
+ with gr.Row():
555
+ awards = gr.Number(label="μ£Όμš” μˆ˜μƒ 싀적 수", value=1)
556
+ partnerships = gr.Number(label="μ „λž΅μ  νŒŒνŠΈλ„ˆμ‹­ 수", value=2)
557
+
558
+ with gr.Tab("νŒ€ 및 λΈŒλžœλ“œ"):
559
+ gr.Markdown("### πŸ‘₯ νŒ€ ꡬ성")
560
+ with gr.Row():
561
+ team_size = gr.Number(label="전체 νŒ€ 규λͺ¨", value=10)
562
+ phd_count = gr.Number(label="박사 ν•™μœ„ 보유자 수", value=1)
563
+
564
+ with gr.Row():
565
+ serial_entrepreneurs = gr.Number(label="연쇄창업가 수", value=1)
566
+ big_tech_experience = gr.Number(label="λΉ…ν…Œν¬ μΆœμ‹  인원", value=2)
567
+
568
+ gr.Markdown("### πŸ“± λΈŒλžœλ“œ 및 μ‚¬μš©μž 기반")
569
+ with gr.Row():
570
+ media_coverage = gr.Number(label="μ£Όμš” μ–Έλ‘  보도 수", value=5)
571
+ app_downloads = gr.Number(label="μ•± λ‹€μš΄λ‘œλ“œ 수 (만)", value=10)
572
+ social_followers = gr.Number(label="μ†Œμ…œλ―Έλ””μ–΄ νŒ”λ‘œμ›Œ (천)", value=50)
573
+
574
  with gr.Tab("재무 ν˜„ν™©"):
575
  gr.Markdown("### πŸ’Έ ν˜„κΈˆ 상황 (λ‹¨μœ„: 천 λ‹¬λŸ¬)")
576
  with gr.Row():
 
587
  with gr.Column(scale=1):
588
  metrics_table = gr.DataFrame(label="μ£Όμš” μ§€ν‘œ 비ꡐ")
589
 
590
+ with gr.Row():
591
+ comparison_chart = gr.Plot(label="동쒅업계 비ꡐ")
592
+ ip_chart = gr.Plot(label="IP μžμ‚° 뢄석")
593
 
594
  # 이벀트 μ—°κ²°
595
  evaluate_btn.click(
 
598
  company_name, founded_year, industry, stage, revenue_type,
599
  monthly_revenue, growth_rate, arpu, gross_margin, monthly_churn,
600
  retention_rate, new_customers, monthly_marketing, monthly_sales,
601
+ cash_balance, burn_rate,
602
+ domains, patent_filed, patent_granted, papers, trademarks,
603
+ github_url, github_stars, awards, partnerships,
604
+ team_size, phd_count, serial_entrepreneurs, big_tech_experience,
605
+ media_coverage, app_downloads, social_followers
606
  ],
607
+ outputs=[valuation_output, comparison_chart, ip_chart, metrics_table]
608
  )
609
 
610
  # μ˜ˆμ‹œ 데이터 λ²„νŠΌλ“€
611
  gr.Markdown("### πŸ“ μ˜ˆμ‹œ λ°μ΄ν„°λ‘œ ν…ŒμŠ€νŠΈν•˜κΈ°")
612
  with gr.Row():
613
+ gr.Button("AI μŠ€νƒ€νŠΈμ—… μ˜ˆμ‹œ").click(
614
  lambda: [
615
+ "AI Tech Corp", 2021, "AI/λ”₯ν…Œν¬", "μ„±μž₯ 단계", "κ΅¬λ…ν˜• (SaaS)",
616
  100, 150, 200, 75, 2,
617
  90, 40, 30, 20,
618
+ 2000, 120,
619
+ "aitech.com, aitech.ai", 5, 2,
620
+ "NeurIPS 2023 - Novel AI Architecture\nhttps://arxiv.org/abs/2023.12345", 3,
621
+ "https://github.com/aitech/core", 500, 3, 5,
622
+ 15, 3, 2, 4,
623
+ 10, 50, 100
624
  ],
625
  outputs=[
626
  company_name, founded_year, industry, stage, revenue_type,
627
  monthly_revenue, growth_rate, arpu, gross_margin, monthly_churn,
628
  retention_rate, new_customers, monthly_marketing, monthly_sales,
629
+ cash_balance, burn_rate,
630
+ domains, patent_filed, patent_granted, papers, trademarks,
631
+ github_url, github_stars, awards, partnerships,
632
+ team_size, phd_count, serial_entrepreneurs, big_tech_experience,
633
+ media_coverage, app_downloads, social_followers
634
  ]
635
  )
636
 
637
+ gr.Button("λ°”μ΄μ˜€ν…Œν¬ μ˜ˆμ‹œ").click(
638
  lambda: [
639
+ "BioHealth Inc", 2020, "ν—¬μŠ€μΌ€μ–΄", "초기 맀좜", "κ΅¬λ…ν˜• (SaaS)",
640
+ 80, 200, 500, 85, 1,
641
+ 95, 20, 40, 30,
642
+ 3000, 150,
643
+ "biohealth.com, biohealth.health", 8, 4,
644
+ "Nature Medicine 2023 - Breakthrough in Drug Discovery\nScience 2023 - Novel Biomarker", 5,
645
+ "https://github.com/biohealth/research", 200, 5, 3,
646
+ 25, 8, 1, 3,
647
+ 15, 5, 30
648
  ],
649
  outputs=[
650
  company_name, founded_year, industry, stage, revenue_type,
651
  monthly_revenue, growth_rate, arpu, gross_margin, monthly_churn,
652
  retention_rate, new_customers, monthly_marketing, monthly_sales,
653
+ cash_balance, burn_rate,
654
+ domains, patent_filed, patent_granted, papers, trademarks,
655
+ github_url, github_stars, awards, partnerships,
656
+ team_size, phd_count, serial_entrepreneurs, big_tech_experience,
657
+ media_coverage, app_downloads, social_followers
658
  ]
659
  )
660