var SS = require('../vendor/skin-score'), UI = require('../vendor/report-ui'), api = require('./api'); function mapURL(value) { if (typeof value !== 'string') return ''; if (/^data:image\/(png|jpeg);base64,/.test(value)) return value; if (value.indexOf('/9j/') === 0) return 'data:image/jpeg;base64,' + value; if (value.indexOf('iVBOR') === 0) return 'data:image/png;base64,' + value; return ''; } function model(payload, photos, profile) { var vm = payload.vm || SS.buildViewModel(payload.result, payload.side, { realAge: profile.real_age, skinType: profile.daily_skin_type }); vm = SS.withDisplayRecommendation(vm, payload.result); var presentation = UI.forDisplay(vm, payload.result, payload.presentation); var total = SS.weightedTotal(vm.dims), skinAge = SS.reportSkinAge(vm, payload.result); var focus = UI.focusOf(vm); var views = presentation.views.map(function (view) { return { key: view.key, name: view.name, text: UI.customerText(view), score: UI.dimensionScore(view.S), level: view.level || '', dim: view.key === 'wrinkles', alpha: view.key === 'color' ? 0.3 : 1, marks: [] }; }); var difference = skinAge != null && vm.realAge != null ? skinAge - vm.realAge : null; return { total: total, skinAge: skinAge, ageNote: difference == null ? '' : difference === 0 ? '与实际年龄相当' : difference < 0 ? '比实际年龄年轻' + -difference + '岁' : '比实际年龄大' + difference + '岁', dims: ['firm', 'vita', 'stab'].map(function (key) { var d = vm.dims[key] || {}, value = UI.dimensionScore(d.S), parts = value.split('.'); return { key: key, name: UI.dimNames[key], int: parts[0], dec: parts[1] || '', level: UI.levelForScore(d.S) || '', rank: focus && focus.key === key ? 'worst' : '', barWidth: d.S == null ? 0 : Math.min(100, d.S * 10) }; }), focusName: focus ? focus.name : '', focusSlogan: focus ? focus.tip : '', views: views, viewIndex: 0, frontPhoto: photos[0] || '', activeLayers: [], careAdvice: presentation.care || [], product: presentation.product ? Object.assign({}, presentation.product, { image: api.assetUrl(presentation.product.image) }) : null }; } function marks(result, key, width, height) { if (!(width > 0 && height > 0)) return []; var defs = key === 'acne' ? [['closed_comedones', '#E8A13D'], ['acne', '#D30C0C'], ['acne_pustule', '#D30C0C'], ['acne_nodule', '#8E0000'], ['acne_mark', '#8750C8']] : key === 'color' ? [['melanin_mark', '#9F641F'], ['melasma', '#E68A2E'], ['freckle', '#8750C8']] : []; var out = []; defs.forEach(function (def) { var source = result[def[0]] || {}, rectangles = (source.rectangle || []).slice(); (source.polygon || []).forEach(function (points) { points = points.filter(function (p) { return p && typeof p.x === 'number' && typeof p.y === 'number'; }); if (points.length < 3) return; var xs = points.map(function (p) { return p.x; }), ys = points.map(function (p) { return p.y; }); var left = Math.min.apply(Math, xs), top = Math.min.apply(Math, ys); rectangles.push({ left: left, top: top, width: Math.max.apply(Math, xs) - left, height: Math.max.apply(Math, ys) - top }); }); rectangles.forEach(function (r) { if (![r.left, r.top, r.width, r.height].every(function (n) { return typeof n === 'number' && isFinite(n); }) || r.left < 0 || r.top < 0 || r.width <= 0 || r.height <= 0 || r.left + r.width > width || r.top + r.height > height) return; out.push({ id: out.length, left: 100 * r.left / width, top: 100 * r.top / height, width: 100 * r.width / width, height: 100 * r.height / height, color: def[1] }); }); }); return out; } function layers(result, key) { var fields = { wrinkles: ['texture_enhanced_lines'], smooth: ['texture_enhanced_pores', 'texture_enhanced_blackheads'], color: ['brown_area'], water: ['water_area'], sens: ['red_area'] }; return (fields[key] || []).map(function (field) { return mapURL((result.face_maps || {})[field]); }).filter(Boolean); } module.exports = { model: model, mapURL: mapURL, marks: marks, layers: layers };